mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 07:50:04 +00:00
Creating reference map widget
This commit is contained in:
parent
760e8a52a1
commit
b1e00cca83
8 changed files with 631 additions and 30 deletions
|
|
@ -43,20 +43,37 @@ find_package(Qt${QT_VERSION_MAJOR}
|
||||||
|
|
||||||
include(qt6-linguist.cmake)
|
include(qt6-linguist.cmake)
|
||||||
|
|
||||||
|
set(HDR_MAIN source/scwx/qt/main/main_window.hpp)
|
||||||
|
set(SRC_MAIN source/scwx/qt/main/main.cpp
|
||||||
|
source/scwx/qt/main/main_window.cpp)
|
||||||
|
set(UI_MAIN source/scwx/qt/main/main_window.ui)
|
||||||
|
set(HDR_MAP source/scwx/qt/map/map_widget.hpp)
|
||||||
|
set(SRC_MAP source/scwx/qt/map/map_widget.cpp)
|
||||||
|
|
||||||
set(TS_FILES ts/scwx_en_US.ts)
|
set(TS_FILES ts/scwx_en_US.ts)
|
||||||
|
|
||||||
set(PROJECT_SOURCES
|
set(PROJECT_SOURCES ${HDR_MAIN}
|
||||||
source/scwx/qt/main.cpp
|
${SRC_MAIN}
|
||||||
source/scwx/qt/main_window.cpp
|
${UI_MAIN}
|
||||||
source/scwx/qt/main_window.hpp
|
${HDR_MAP}
|
||||||
source/scwx/qt/main_window.ui
|
${SRC_MAP}
|
||||||
${TS_FILES}
|
${TS_FILES})
|
||||||
)
|
|
||||||
|
source_group("Header Files\\main" FILES ${HDR_MAIN})
|
||||||
|
source_group("Source Files\\main" FILES ${SRC_MAIN})
|
||||||
|
source_group("UI Files\\main" FILES ${UI_MAIN})
|
||||||
|
source_group("Header Files\\map" FILES ${HDR_MAP})
|
||||||
|
source_group("Source Files\\map" FILES ${SRC_MAP})
|
||||||
|
source_group("I18N Files" FILES ${TS_FILES})
|
||||||
|
|
||||||
qt_add_executable(scwx-qt
|
qt_add_executable(scwx-qt
|
||||||
${PROJECT_SOURCES}
|
${PROJECT_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
qt6_create_translation_scwx(QM_FILES ${PROJECT_SOURCE_DIR} ${TS_FILES})
|
qt6_create_translation_scwx(QM_FILES ${scwx-qt_SOURCE_DIR} ${TS_FILES})
|
||||||
|
|
||||||
target_link_libraries(scwx-qt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)
|
target_include_directories(scwx-qt PRIVATE ${scwx-qt_SOURCE_DIR}/source)
|
||||||
|
|
||||||
|
target_link_libraries(scwx-qt PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||||
|
Qt${QT_VERSION_MAJOR}::OpenGLWidgets
|
||||||
|
qmapboxgl)
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,23 @@
|
||||||
#include "main_window.hpp"
|
#include "main_window.hpp"
|
||||||
#include "./ui_main_window.h"
|
#include "./ui_main_window.h"
|
||||||
|
|
||||||
|
#include <scwx/qt/map/map_widget.hpp>
|
||||||
|
|
||||||
namespace scwx
|
namespace scwx
|
||||||
{
|
{
|
||||||
namespace qt
|
namespace qt
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename... Types>
|
|
||||||
class variant
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
template<typename T>
|
|
||||||
inline variant(T&& value)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
using ValueBase = variant<float, double>;
|
|
||||||
|
|
||||||
struct Value : ValueBase
|
|
||||||
{
|
|
||||||
using ValueBase::ValueBase;
|
|
||||||
};
|
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget* parent) :
|
MainWindow::MainWindow(QWidget* parent) :
|
||||||
QMainWindow(parent), ui(new Ui::MainWindow)
|
QMainWindow(parent), ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
|
||||||
Value(0.0f);
|
QMapboxGLSettings settings;
|
||||||
Value(0.0);
|
settings.setCacheDatabasePath("/tmp/mbgl-cache.db");
|
||||||
|
settings.setCacheDatabaseMaximumSize(20 * 1024 * 1024);
|
||||||
|
|
||||||
|
ui->centralwidget->layout()->addWidget(new MapWidget(settings));
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWindow::~MainWindow()
|
MainWindow::~MainWindow()
|
||||||
|
|
@ -14,7 +14,20 @@
|
||||||
<string>MainWindow</string>
|
<string>MainWindow</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout"/>
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar">
|
<widget class="QMenuBar" name="menubar">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
527
scwx-qt/source/scwx/qt/map/map_widget.cpp
Normal file
527
scwx-qt/source/scwx/qt/map/map_widget.cpp
Normal file
|
|
@ -0,0 +1,527 @@
|
||||||
|
#include "map_widget.hpp"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QColor>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QIcon>
|
||||||
|
#include <QKeyEvent>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
|
||||||
|
MapWidget::MapWidget(const QMapboxGLSettings& settings) : settings_(settings)
|
||||||
|
{
|
||||||
|
setFocusPolicy(Qt::StrongFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
MapWidget::~MapWidget()
|
||||||
|
{
|
||||||
|
// Make sure we have a valid context so we
|
||||||
|
// can delete the QMapboxGL.
|
||||||
|
makeCurrent();
|
||||||
|
}
|
||||||
|
|
||||||
|
qreal MapWidget::pixelRatio()
|
||||||
|
{
|
||||||
|
return devicePixelRatioF();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::changeStyle()
|
||||||
|
{
|
||||||
|
static uint8_t currentStyleIndex;
|
||||||
|
|
||||||
|
auto& styles = QMapbox::defaultStyles();
|
||||||
|
|
||||||
|
map_->setStyleUrl(styles[currentStyleIndex].first);
|
||||||
|
setWindowTitle(QString("Mapbox GL: ") + styles[currentStyleIndex].second);
|
||||||
|
|
||||||
|
if (++currentStyleIndex == styles.size())
|
||||||
|
{
|
||||||
|
currentStyleIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceAdded_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::keyPressEvent(QKeyEvent* ev)
|
||||||
|
{
|
||||||
|
switch (ev->key())
|
||||||
|
{
|
||||||
|
case Qt::Key_S: changeStyle(); break;
|
||||||
|
case Qt::Key_L:
|
||||||
|
{
|
||||||
|
if (sourceAdded_)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceAdded_ = true;
|
||||||
|
|
||||||
|
// Not in all styles, but will work on streets
|
||||||
|
QString before = "waterway-label";
|
||||||
|
|
||||||
|
QFile geojson(":source1.geojson");
|
||||||
|
geojson.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
// The data source for the route line and markers
|
||||||
|
QVariantMap routeSource;
|
||||||
|
routeSource["type"] = "geojson";
|
||||||
|
routeSource["data"] = geojson.readAll();
|
||||||
|
map_->addSource("routeSource", routeSource);
|
||||||
|
|
||||||
|
// The route case, painted before the route
|
||||||
|
QVariantMap routeCase;
|
||||||
|
routeCase["id"] = "routeCase";
|
||||||
|
routeCase["type"] = "line";
|
||||||
|
routeCase["source"] = "routeSource";
|
||||||
|
map_->addLayer(routeCase, before);
|
||||||
|
|
||||||
|
map_->setPaintProperty("routeCase", "line-color", QColor("white"));
|
||||||
|
map_->setPaintProperty("routeCase", "line-width", 20.0);
|
||||||
|
map_->setLayoutProperty("routeCase", "line-join", "round");
|
||||||
|
map_->setLayoutProperty("routeCase", "line-cap", "round");
|
||||||
|
|
||||||
|
// The route, painted on top of the route case
|
||||||
|
QVariantMap route;
|
||||||
|
route["id"] = "route";
|
||||||
|
route["type"] = "line";
|
||||||
|
route["source"] = "routeSource";
|
||||||
|
map_->addLayer(route, before);
|
||||||
|
|
||||||
|
map_->setPaintProperty("route", "line-color", QColor("blue"));
|
||||||
|
map_->setPaintProperty("route", "line-width", 8.0);
|
||||||
|
map_->setLayoutProperty("route", "line-join", "round");
|
||||||
|
map_->setLayoutProperty("route", "line-cap", "round");
|
||||||
|
|
||||||
|
QVariantList lineDashArray;
|
||||||
|
lineDashArray.append(1);
|
||||||
|
lineDashArray.append(2);
|
||||||
|
|
||||||
|
map_->setPaintProperty("route", "line-dasharray", lineDashArray);
|
||||||
|
|
||||||
|
// Markers at the beginning and end of the route
|
||||||
|
map_->addImage("label-arrow", QImage(":label-arrow.svg"));
|
||||||
|
map_->addImage("label-background", QImage(":label-background.svg"));
|
||||||
|
|
||||||
|
QVariantMap markerArrow;
|
||||||
|
markerArrow["id"] = "markerArrow";
|
||||||
|
markerArrow["type"] = "symbol";
|
||||||
|
markerArrow["source"] = "routeSource";
|
||||||
|
map_->addLayer(markerArrow);
|
||||||
|
|
||||||
|
map_->setLayoutProperty("markerArrow", "icon-image", "label-arrow");
|
||||||
|
map_->setLayoutProperty("markerArrow", "icon-size", 0.5);
|
||||||
|
map_->setLayoutProperty("markerArrow", "icon-ignore-placement", true);
|
||||||
|
|
||||||
|
QVariantList arrowOffset;
|
||||||
|
arrowOffset.append(0.0);
|
||||||
|
arrowOffset.append(-15.0);
|
||||||
|
map_->setLayoutProperty("markerArrow", "icon-offset", arrowOffset);
|
||||||
|
|
||||||
|
QVariantMap markerBackground;
|
||||||
|
markerBackground["id"] = "markerBackground";
|
||||||
|
markerBackground["type"] = "symbol";
|
||||||
|
markerBackground["source"] = "routeSource";
|
||||||
|
map_->addLayer(markerBackground);
|
||||||
|
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"markerBackground", "icon-image", "label-background");
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-field", "{name}");
|
||||||
|
map_->setLayoutProperty("markerBackground", "icon-text-fit", "both");
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"markerBackground", "icon-ignore-placement", true);
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"markerBackground", "text-ignore-placement", true);
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-anchor", "left");
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-size", 16.0);
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-padding", 0.0);
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-line-height", 1.0);
|
||||||
|
map_->setLayoutProperty("markerBackground", "text-max-width", 8.0);
|
||||||
|
|
||||||
|
QVariantList iconTextFitPadding;
|
||||||
|
iconTextFitPadding.append(15.0);
|
||||||
|
iconTextFitPadding.append(10.0);
|
||||||
|
iconTextFitPadding.append(15.0);
|
||||||
|
iconTextFitPadding.append(10.0);
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"markerBackground", "icon-text-fit-padding", iconTextFitPadding);
|
||||||
|
|
||||||
|
QVariantList backgroundOffset;
|
||||||
|
backgroundOffset.append(-0.5);
|
||||||
|
backgroundOffset.append(-1.5);
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"markerBackground", "text-offset", backgroundOffset);
|
||||||
|
|
||||||
|
map_->setPaintProperty("markerBackground", "text-color", QColor("white"));
|
||||||
|
|
||||||
|
QVariantList filterExpression;
|
||||||
|
filterExpression.append("==");
|
||||||
|
filterExpression.append("$type");
|
||||||
|
filterExpression.append("Point");
|
||||||
|
|
||||||
|
QVariantList filter;
|
||||||
|
filter.append(filterExpression);
|
||||||
|
|
||||||
|
map_->setFilter("markerArrow", filter);
|
||||||
|
map_->setFilter("markerBackground", filter);
|
||||||
|
|
||||||
|
// Tilt the labels when tilting the map and make them larger
|
||||||
|
map_->setLayoutProperty("road-label-large", "text-size", 30.0);
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"road-label-large", "text-pitch-alignment", "viewport");
|
||||||
|
|
||||||
|
map_->setLayoutProperty("road-label-medium", "text-size", 30.0);
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"road-label-medium", "text-pitch-alignment", "viewport");
|
||||||
|
|
||||||
|
map_->setLayoutProperty(
|
||||||
|
"road-label-small", "text-pitch-alignment", "viewport");
|
||||||
|
map_->setLayoutProperty("road-label-small", "text-size", 30.0);
|
||||||
|
|
||||||
|
// Buildings extrusion
|
||||||
|
QVariantMap buildings;
|
||||||
|
buildings["id"] = "3d-buildings";
|
||||||
|
buildings["source"] = "composite";
|
||||||
|
buildings["source-layer"] = "building";
|
||||||
|
buildings["type"] = "fill-extrusion";
|
||||||
|
buildings["minzoom"] = 15.0;
|
||||||
|
map_->addLayer(buildings);
|
||||||
|
|
||||||
|
QVariantList buildingsFilterExpression;
|
||||||
|
buildingsFilterExpression.append("==");
|
||||||
|
buildingsFilterExpression.append("extrude");
|
||||||
|
buildingsFilterExpression.append("true");
|
||||||
|
|
||||||
|
QVariantList buildingsFilter;
|
||||||
|
buildingsFilter.append(buildingsFilterExpression);
|
||||||
|
|
||||||
|
map_->setFilter("3d-buildings", buildingsFilterExpression);
|
||||||
|
|
||||||
|
QString fillExtrusionColorJSON = R"JSON(
|
||||||
|
[
|
||||||
|
"interpolate",
|
||||||
|
["linear"],
|
||||||
|
["get", "height"],
|
||||||
|
0.0, "blue",
|
||||||
|
20.0, "royalblue",
|
||||||
|
40.0, "cyan",
|
||||||
|
60.0, "lime",
|
||||||
|
80.0, "yellow",
|
||||||
|
100.0, "red"
|
||||||
|
]
|
||||||
|
)JSON";
|
||||||
|
|
||||||
|
map_->setPaintProperty(
|
||||||
|
"3d-buildings", "fill-extrusion-color", fillExtrusionColorJSON);
|
||||||
|
map_->setPaintProperty("3d-buildings", "fill-extrusion-opacity", .6);
|
||||||
|
|
||||||
|
QVariantMap extrusionHeight;
|
||||||
|
extrusionHeight["type"] = "identity";
|
||||||
|
extrusionHeight["property"] = "height";
|
||||||
|
|
||||||
|
map_->setPaintProperty(
|
||||||
|
"3d-buildings", "fill-extrusion-height", extrusionHeight);
|
||||||
|
|
||||||
|
QVariantMap extrusionBase;
|
||||||
|
extrusionBase["type"] = "identity";
|
||||||
|
extrusionBase["property"] = "min_height";
|
||||||
|
|
||||||
|
map_->setPaintProperty(
|
||||||
|
"3d-buildings", "fill-extrusion-base", extrusionBase);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_1:
|
||||||
|
{
|
||||||
|
if (symbolAnnotationId_.isNull())
|
||||||
|
{
|
||||||
|
QMapbox::Coordinate coordinate = map_->coordinate();
|
||||||
|
QMapbox::SymbolAnnotation symbol {coordinate, "default_marker"};
|
||||||
|
map_->addAnnotationIcon("default_marker",
|
||||||
|
QImage(":default_marker.svg"));
|
||||||
|
symbolAnnotationId_ = map_->addAnnotation(
|
||||||
|
QVariant::fromValue<QMapbox::SymbolAnnotation>(symbol));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map_->removeAnnotation(symbolAnnotationId_.toUInt());
|
||||||
|
symbolAnnotationId_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_2:
|
||||||
|
{
|
||||||
|
if (lineAnnotationId_.isNull())
|
||||||
|
{
|
||||||
|
QMapbox::Coordinates coordinates;
|
||||||
|
coordinates.push_back(map_->coordinateForPixel({0, 0}));
|
||||||
|
coordinates.push_back(map_->coordinateForPixel(
|
||||||
|
{qreal(size().width()), qreal(size().height())}));
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollection collection;
|
||||||
|
collection.push_back(coordinates);
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollections lineGeometry;
|
||||||
|
lineGeometry.push_back(collection);
|
||||||
|
|
||||||
|
QMapbox::ShapeAnnotationGeometry annotationGeometry(
|
||||||
|
QMapbox::ShapeAnnotationGeometry::LineStringType, lineGeometry);
|
||||||
|
|
||||||
|
QMapbox::LineAnnotation line;
|
||||||
|
line.geometry = annotationGeometry;
|
||||||
|
line.opacity = 0.5f;
|
||||||
|
line.width = 1.0f;
|
||||||
|
line.color = Qt::red;
|
||||||
|
lineAnnotationId_ = map_->addAnnotation(
|
||||||
|
QVariant::fromValue<QMapbox::LineAnnotation>(line));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map_->removeAnnotation(lineAnnotationId_.toUInt());
|
||||||
|
lineAnnotationId_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_3:
|
||||||
|
{
|
||||||
|
if (fillAnnotationId_.isNull())
|
||||||
|
{
|
||||||
|
QMapbox::Coordinates coordinates;
|
||||||
|
coordinates.push_back(
|
||||||
|
map_->coordinateForPixel({qreal(size().width()), 0}));
|
||||||
|
coordinates.push_back(map_->coordinateForPixel(
|
||||||
|
{qreal(size().width()), qreal(size().height())}));
|
||||||
|
coordinates.push_back(
|
||||||
|
map_->coordinateForPixel({0, qreal(size().height())}));
|
||||||
|
coordinates.push_back(map_->coordinateForPixel({0, 0}));
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollection collection;
|
||||||
|
collection.push_back(coordinates);
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollections fillGeometry;
|
||||||
|
fillGeometry.push_back(collection);
|
||||||
|
|
||||||
|
QMapbox::ShapeAnnotationGeometry annotationGeometry(
|
||||||
|
QMapbox::ShapeAnnotationGeometry::PolygonType, fillGeometry);
|
||||||
|
|
||||||
|
QMapbox::FillAnnotation fill;
|
||||||
|
fill.geometry = annotationGeometry;
|
||||||
|
fill.opacity = 0.5f;
|
||||||
|
fill.color = Qt::green;
|
||||||
|
fill.outlineColor = QVariant::fromValue<QColor>(QColor(Qt::black));
|
||||||
|
fillAnnotationId_ = map_->addAnnotation(
|
||||||
|
QVariant::fromValue<QMapbox::FillAnnotation>(fill));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map_->removeAnnotation(fillAnnotationId_.toUInt());
|
||||||
|
fillAnnotationId_.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_5:
|
||||||
|
{
|
||||||
|
if (map_->layerExists("circleLayer"))
|
||||||
|
{
|
||||||
|
map_->removeLayer("circleLayer");
|
||||||
|
map_->removeSource("circleSource");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QMapbox::Coordinates coordinates;
|
||||||
|
coordinates.push_back(map_->coordinate());
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollection collection;
|
||||||
|
collection.push_back(coordinates);
|
||||||
|
|
||||||
|
QMapbox::CoordinatesCollections point;
|
||||||
|
point.push_back(collection);
|
||||||
|
|
||||||
|
QMapbox::Feature feature(QMapbox::Feature::PointType, point, {}, {});
|
||||||
|
|
||||||
|
QVariantMap circleSource;
|
||||||
|
circleSource["type"] = "geojson";
|
||||||
|
circleSource["data"] = QVariant::fromValue<QMapbox::Feature>(feature);
|
||||||
|
map_->addSource("circleSource", circleSource);
|
||||||
|
|
||||||
|
QVariantMap circle;
|
||||||
|
circle["id"] = "circleLayer";
|
||||||
|
circle["type"] = "circle";
|
||||||
|
circle["source"] = "circleSource";
|
||||||
|
map_->addLayer(circle);
|
||||||
|
|
||||||
|
map_->setPaintProperty("circleLayer", "circle-radius", 10.0);
|
||||||
|
map_->setPaintProperty("circleLayer", "circle-color", QColor("black"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Qt::Key_6:
|
||||||
|
{
|
||||||
|
if (map_->layerExists("innerCirclesLayer") ||
|
||||||
|
map_->layerExists("outerCirclesLayer"))
|
||||||
|
{
|
||||||
|
map_->removeLayer("innerCirclesLayer");
|
||||||
|
map_->removeLayer("outerCirclesLayer");
|
||||||
|
map_->removeSource("innerCirclesSource");
|
||||||
|
map_->removeSource("outerCirclesSource");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto makePoint = [&](double dx, double dy, const QString& color) {
|
||||||
|
auto coordinate = map_->coordinate();
|
||||||
|
coordinate.first += dx;
|
||||||
|
coordinate.second += dy;
|
||||||
|
return QMapbox::Feature {QMapbox::Feature::PointType,
|
||||||
|
{{{coordinate}}},
|
||||||
|
{{"color", color}},
|
||||||
|
{}};
|
||||||
|
};
|
||||||
|
|
||||||
|
// multiple features by QVector<QMapbox::Feature>
|
||||||
|
QVector<QMapbox::Feature> inner {makePoint(0.001, 0, "red"),
|
||||||
|
makePoint(0, 0.001, "green"),
|
||||||
|
makePoint(0, -0.001, "blue")};
|
||||||
|
|
||||||
|
map_->addSource(
|
||||||
|
"innerCirclesSource",
|
||||||
|
{{"type", "geojson"}, {"data", QVariant::fromValue(inner)}});
|
||||||
|
map_->addLayer({{"id", "innerCirclesLayer"},
|
||||||
|
{"type", "circle"},
|
||||||
|
{"source", "innerCirclesSource"}});
|
||||||
|
|
||||||
|
// multiple features by QList<QMapbox::Feature>
|
||||||
|
QList<QMapbox::Feature> outer {makePoint(0.002, 0.002, "cyan"),
|
||||||
|
makePoint(-0.002, 0.002, "magenta"),
|
||||||
|
makePoint(0.002, -0.002, "yellow"),
|
||||||
|
makePoint(-0.002, -0.002, "black")};
|
||||||
|
|
||||||
|
map_->addSource(
|
||||||
|
"outerCirclesSource",
|
||||||
|
{{"type", "geojson"}, {"data", QVariant::fromValue(outer)}});
|
||||||
|
map_->addLayer({{"id", "outerCirclesLayer"},
|
||||||
|
{"type", "circle"},
|
||||||
|
{"source", "outerCirclesSource"}});
|
||||||
|
|
||||||
|
QVariantList getColor {"get", "color"};
|
||||||
|
map_->setPaintProperty("innerCirclesLayer", "circle-radius", 10.0);
|
||||||
|
map_->setPaintProperty("innerCirclesLayer", "circle-color", getColor);
|
||||||
|
map_->setPaintProperty("outerCirclesLayer", "circle-radius", 15.0);
|
||||||
|
map_->setPaintProperty("outerCirclesLayer", "circle-color", getColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::mousePressEvent(QMouseEvent* ev)
|
||||||
|
{
|
||||||
|
lastPos_ = ev->position();
|
||||||
|
|
||||||
|
if (ev->type() == QEvent::MouseButtonPress)
|
||||||
|
{
|
||||||
|
if (ev->buttons() == (Qt::LeftButton | Qt::RightButton))
|
||||||
|
{
|
||||||
|
changeStyle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ev->type() == QEvent::MouseButtonDblClick)
|
||||||
|
{
|
||||||
|
if (ev->buttons() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
map_->scaleBy(2.0, lastPos_);
|
||||||
|
}
|
||||||
|
else if (ev->buttons() == Qt::RightButton)
|
||||||
|
{
|
||||||
|
map_->scaleBy(0.5, lastPos_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::mouseMoveEvent(QMouseEvent* ev)
|
||||||
|
{
|
||||||
|
QPointF delta = ev->position() - lastPos_;
|
||||||
|
|
||||||
|
if (!delta.isNull())
|
||||||
|
{
|
||||||
|
if (ev->buttons() == Qt::LeftButton &&
|
||||||
|
ev->modifiers() & Qt::ShiftModifier)
|
||||||
|
{
|
||||||
|
map_->pitchBy(delta.y());
|
||||||
|
}
|
||||||
|
else if (ev->buttons() == Qt::LeftButton)
|
||||||
|
{
|
||||||
|
map_->moveBy(delta);
|
||||||
|
}
|
||||||
|
else if (ev->buttons() == Qt::RightButton)
|
||||||
|
{
|
||||||
|
map_->rotateBy(lastPos_, ev->position());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPos_ = ev->position();
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::wheelEvent(QWheelEvent* ev)
|
||||||
|
{
|
||||||
|
if (ev->angleDelta().y() == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
float factor = ev->angleDelta().y() / 1200.;
|
||||||
|
if (ev->angleDelta().y() < 0)
|
||||||
|
{
|
||||||
|
factor = factor > -1 ? factor : 1 / factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
|
||||||
|
map_->scaleBy(1 + factor, ev->position());
|
||||||
|
#else
|
||||||
|
map_->scaleBy(1 + factor, ev->pos());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ev->accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::initializeGL()
|
||||||
|
{
|
||||||
|
map_.reset(new QMapboxGL(nullptr, settings_, size(), pixelRatio()));
|
||||||
|
connect(map_.data(), SIGNAL(needsRendering()), this, SLOT(update()));
|
||||||
|
|
||||||
|
// Set default location to KLSX.
|
||||||
|
map_->setCoordinateZoom(QMapbox::Coordinate(38.6986, -90.6828), 14);
|
||||||
|
|
||||||
|
QString styleUrl = qgetenv("MAPBOX_STYLE_URL");
|
||||||
|
if (styleUrl.isEmpty())
|
||||||
|
{
|
||||||
|
changeStyle();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
map_->setStyleUrl(styleUrl);
|
||||||
|
setWindowTitle(QString("Mapbox GL: ") + styleUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MapWidget::paintGL()
|
||||||
|
{
|
||||||
|
frameDraws_++;
|
||||||
|
map_->resize(size());
|
||||||
|
map_->setFramebufferObject(defaultFramebufferObject(),
|
||||||
|
size() * pixelRatio());
|
||||||
|
map_->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
56
scwx-qt/source/scwx/qt/map/map_widget.hpp
Normal file
56
scwx-qt/source/scwx/qt/map/map_widget.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QMapboxGL>
|
||||||
|
|
||||||
|
#include <QOpenGLWidget>
|
||||||
|
#include <QPropertyAnimation>
|
||||||
|
#include <QScopedPointer>
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
class QKeyEvent;
|
||||||
|
class QMouseEvent;
|
||||||
|
class QWheelEvent;
|
||||||
|
|
||||||
|
namespace scwx
|
||||||
|
{
|
||||||
|
namespace qt
|
||||||
|
{
|
||||||
|
|
||||||
|
class MapWidget : public QOpenGLWidget
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MapWidget(const QMapboxGLSettings&);
|
||||||
|
~MapWidget();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void changeStyle();
|
||||||
|
qreal pixelRatio();
|
||||||
|
|
||||||
|
// QWidget implementation.
|
||||||
|
void keyPressEvent(QKeyEvent* ev) override final;
|
||||||
|
void mousePressEvent(QMouseEvent* ev) override final;
|
||||||
|
void mouseMoveEvent(QMouseEvent* ev) override final;
|
||||||
|
void wheelEvent(QWheelEvent* ev) override final;
|
||||||
|
|
||||||
|
// QOpenGLWidget implementation.
|
||||||
|
void initializeGL() override final;
|
||||||
|
void paintGL() override final;
|
||||||
|
|
||||||
|
QPointF lastPos_;
|
||||||
|
|
||||||
|
QMapboxGLSettings settings_;
|
||||||
|
QScopedPointer<QMapboxGL> map_;
|
||||||
|
|
||||||
|
uint64_t frameDraws_ = 0;
|
||||||
|
|
||||||
|
QVariant symbolAnnotationId_;
|
||||||
|
QVariant lineAnnotationId_;
|
||||||
|
QVariant fillAnnotationId_;
|
||||||
|
|
||||||
|
bool sourceAdded_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace qt
|
||||||
|
} // namespace scwx
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
<context>
|
<context>
|
||||||
<name>MainWindow</name>
|
<name>MainWindow</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../source/scwx/qt/main_window.ui" line="14"/>
|
<location filename="../source/scwx/qt/main/main_window.ui" line="14"/>
|
||||||
<source>MainWindow</source>
|
<source>MainWindow</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue