summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Rauter <matthias.rauter@qt.io>2023-02-21 11:48:13 +0100
committerVolker Hilsheimer <volker.hilsheimer@qt.io>2023-02-22 12:54:37 +0000
commit0d7a0d92c64a906748b0676ea502ec3d6ccf27d0 (patch)
tree2f61236aa057fb82c2914ddf600ecffae61620ae
parentf19a0b27d4945ef633ca6602d4af63abad88f134 (diff)
downloadqtlocation-0d7a0d92c64a906748b0676ea502ec3d6ccf27d0.tar.gz
Add drawing of mapItems to GeoJson viewer example
Pick-to: 6.5 Change-Id: I362acbb6a428e83c3490742824b54aa68890c47f Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
-rw-r--r--examples/location/geojson_viewer/CMakeLists.txt4
-rw-r--r--examples/location/geojson_viewer/GeoJsonDelegate.qml2
-rw-r--r--examples/location/geojson_viewer/main.cpp30
-rw-r--r--examples/location/geojson_viewer/main.qml124
-rw-r--r--examples/location/geojson_viewer/mapitems/CircleItem.qml30
-rw-r--r--examples/location/geojson_viewer/mapitems/PolygonItem.qml34
-rw-r--r--examples/location/geojson_viewer/mapitems/PolylineItem.qml32
-rw-r--r--examples/location/geojson_viewer/mapitems/RectangleItem.qml28
8 files changed, 279 insertions, 5 deletions
diff --git a/examples/location/geojson_viewer/CMakeLists.txt b/examples/location/geojson_viewer/CMakeLists.txt
index 0b452a7c..994e5d4b 100644
--- a/examples/location/geojson_viewer/CMakeLists.txt
+++ b/examples/location/geojson_viewer/CMakeLists.txt
@@ -41,6 +41,10 @@ target_link_libraries(qml_location_geojsonviewer PUBLIC
set(qml_resource_files
"GeoJsonDelegate.qml"
"main.qml"
+ "mapitems/CircleItem.qml"
+ "mapitems/PolygonItem.qml"
+ "mapitems/PolylineItem.qml"
+ "mapitems/RectangleItem.qml"
)
qt6_add_resources(qml_location_geojsonviewer "qml"
diff --git a/examples/location/geojson_viewer/GeoJsonDelegate.qml b/examples/location/geojson_viewer/GeoJsonDelegate.qml
index 3e2cd257..81d23c54 100644
--- a/examples/location/geojson_viewer/GeoJsonDelegate.qml
+++ b/examples/location/geojson_viewer/GeoJsonDelegate.qml
@@ -19,7 +19,7 @@ DelegateChooser {
property string geojsonType: "Point"
property var props: modelData.properties
geoShape: modelData.data
- radius: 20*1000
+ radius: (props && props.radius) || 20*1000
border.width: 3
border.color: hh.hovered ? "magenta" : "black"
opacity: dc.defaultOpacity
diff --git a/examples/location/geojson_viewer/main.cpp b/examples/location/geojson_viewer/main.cpp
index 97364c3e..ba390c7d 100644
--- a/examples/location/geojson_viewer/main.cpp
+++ b/examples/location/geojson_viewer/main.cpp
@@ -75,8 +75,24 @@ public:
QVariantMap pt;
pt["type"] = "Point";
pt["data"] = QVariant::fromValue(mapCircle->geoShape());
- if (hasProperties(mapCircle))
- pt["properties"] = mapCircle->property("props").toMap();
+ QVariantMap propMap = mapCircle->property("props").toMap();
+ propMap["radius"] = mapCircle->radius();
+ pt["properties"] = propMap;
+ return pt;
+ }
+ static QVariantMap toVariant(QDeclarativeRectangleMapItem *mapRectangle)
+ {
+ QVariantMap pt;
+ pt["type"] = "Polygon";
+ QGeoRectangle rectanlge = mapRectangle->geoShape();
+ QGeoPolygon poly;
+ poly.addCoordinate(rectanlge.topLeft());
+ poly.addCoordinate(rectanlge.topRight());
+ poly.addCoordinate(rectanlge.bottomRight());
+ poly.addCoordinate(rectanlge.bottomLeft());
+ pt["data"] = QVariant::fromValue(poly);
+ if (hasProperties(mapRectangle))
+ pt["properties"] = mapRectangle->property("props").toMap();
return pt;
}
@@ -110,13 +126,19 @@ public:
entry = toVariant(polygon);
} else if (QDeclarativeCircleMapItem *circle = qobject_cast<QDeclarativeCircleMapItem *>(kid)) {
entry = toVariant(circle); // If GeoJSON Point type is visualized in other ways, handle those types here instead.
+ } else if (QDeclarativeRectangleMapItem *rectangle = qobject_cast<QDeclarativeRectangleMapItem *>(kid)) {
+ entry = toVariant(rectangle); // For the self-drawn rectangles. Will be exported as Polygons
+
}
features.append(entry);
}
- if (nodeType.isEmpty()) { // Dirty hack to handle (=skip) the first MIV used to process the fictitious list with 1 element
+ if (nodeType.isEmpty()) {
if (features.isEmpty())
return root;
- return features.first().toMap();
+ else if (features.size() == 1)
+ return features.first().toMap();
+ else
+ root["type"] = "FeatureCollection";
}
root["data"] = features;
return root;
diff --git a/examples/location/geojson_viewer/main.qml b/examples/location/geojson_viewer/main.qml
index e5d87040..d514ef1e 100644
--- a/examples/location/geojson_viewer/main.qml
+++ b/examples/location/geojson_viewer/main.qml
@@ -9,6 +9,7 @@ import QtPositioning
import QtLocation
import QtCore
import Qt.GeoJson
+import "mapitems"
ApplicationWindow {
id: win
@@ -29,6 +30,7 @@ ApplicationWindow {
currentFolder: dataPath
nameFilters: ["GeoJSON files (*.geojson *.json)"]
onAccepted: {
+ view.clearAllItems()
geoJsoner.load(fileDialog.selectedFile)
}
}
@@ -120,6 +122,35 @@ ApplicationWindow {
map.plugin: Plugin { name: "osm" }
map.zoomLevel: 4
+ property variant unfinishedItem: 'undefined'
+
+ signal showMainMenu(variant coordinate)
+
+ function addGeoItem(item)
+ {
+ var count = view.map.mapItems.length
+ var co = Qt.createComponent('mapitems/'+item+'.qml')
+ if (co.status === Component.Ready) {
+ unfinishedItem = co.createObject(map)
+ unfinishedItem.setGeometry(tapHandler.lastCoordinate)
+ unfinishedItem.addGeometry(hoverHandler.currentCoordinate, false)
+ view.map.addMapItem(unfinishedItem)
+ unfinishedItem.parent = miv
+ } else {
+ console.log(item + " is not supported right now, please call us later.")
+ }
+ }
+
+ function clearAllItems()
+ {
+ var count = view.map.mapItems.length
+ for (var i = count-1; i>=0; i--){
+ var item = view.map.mapItems[i]
+ item.parent = view.map
+ view.map.removeMapItem(item)
+ }
+ }
+
MapItemView {
id: miv
parent: view.map
@@ -127,5 +158,98 @@ ApplicationWindow {
delegate: GeoJsonDelegate {
}
}
+
+ Menu {
+ id: mapPopupMenu
+
+ property variant coordinate
+
+ MenuItem {
+ text: qsTr("Rectangle")
+ onTriggered: view.addGeoItem("RectangleItem")
+ }
+ MenuItem {
+ text: qsTr("Circle")
+ onTriggered: view.addGeoItem("CircleItem")
+ }
+ MenuItem {
+ text: qsTr("Polyline")
+ onTriggered: view.addGeoItem("PolylineItem")
+ }
+ MenuItem {
+ text: qsTr("Polygon")
+ onTriggered: view.addGeoItem("PolygonItem")
+ }
+ MenuItem {
+ text: qsTr("Clear all")
+ onTriggered: view.clearAllItems()
+ }
+
+ function show(coordinate) {
+ mapPopupMenu.coordinate = coordinate
+ mapPopupMenu.popup()
+ }
+ }
+
+ HoverHandler {
+ id: hoverHandler
+ property variant currentCoordinate
+ grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType
+
+ onPointChanged: {
+ currentCoordinate = view.map.toCoordinate(hoverHandler.point.position)
+ if (view.unfinishedItem !== 'undefined')
+ view.unfinishedItem.addGeometry(view.map.toCoordinate(hoverHandler.point.position), true)
+ }
+
+ }
+
+ TapHandler {
+ id: tapHandler
+ property variant lastCoordinate
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+
+ onSingleTapped: (eventPoint, button) => {
+ lastCoordinate = view.map.toCoordinate(tapHandler.point.position)
+ if (button === Qt.RightButton) {
+ if (view.unfinishedItem !== 'undefined') {
+ view.unfinishedItem.finishAddGeometry()
+ view.unfinishedItem = 'undefined'
+ } else
+ mapPopupMenu.show(lastCoordinate)
+ } else if (button === Qt.LeftButton) {
+ if (view.unfinishedItem !== 'undefined') {
+ if (view.unfinishedItem.addGeometry(view.map.toCoordinate(tapHandler.point.position), false)) {
+ view.unfinishedItem.finishAddGeometry()
+ view.unfinishedItem = 'undefined'
+ }
+ }
+ }
+ }
+ }
+ TapHandler {
+ acceptedButtons: Qt.LeftButton
+ onDoubleTapped: (eventPoint, button) => {
+ var preZoomPoint = view.map.toCoordinate(eventPoint.position);
+ view.map.zoomLevel = Math.floor(view.map.zoomLevel + 1)
+ var postZoomPoint = view.map.toCoordinate(eventPoint.position);
+ var dx = postZoomPoint.latitude - preZoomPoint.latitude;
+ var dy = postZoomPoint.longitude - preZoomPoint.longitude;
+ view.map.center = QtPositioning.coordinate(view.map.center.latitude - dx,
+ view.map.center.longitude - dy);
+ }
+ }
+ TapHandler {
+ acceptedButtons: Qt.RightButton
+ onDoubleTapped: (eventPoint, button) => {
+ var preZoomPoint = view.map.toCoordinate(eventPoint.position);
+ view.map.zoomLevel = Math.floor(view.map.zoomLevel - 1)
+ var postZoomPoint = view.map.toCoordinate(eventPoint.position);
+ var dx = postZoomPoint.latitude - preZoomPoint.latitude;
+ var dy = postZoomPoint.longitude - preZoomPoint.longitude;
+ view.map.center = QtPositioning.coordinate(view.map.center.latitude - dx,
+ view.map.center.longitude - dy);
+ }
+ }
}
}
diff --git a/examples/location/geojson_viewer/mapitems/CircleItem.qml b/examples/location/geojson_viewer/mapitems/CircleItem.qml
new file mode 100644
index 00000000..08709357
--- /dev/null
+++ b/examples/location/geojson_viewer/mapitems/CircleItem.qml
@@ -0,0 +1,30 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtLocation
+
+MapCircle {
+ color: "#da5546"
+ border.color: "#330a0a"
+ border.width: 2
+ smooth: true
+ opacity: 0.75
+ autoFadeIn: false
+
+ property string geojsonType: "Point"
+
+ function setGeometry(anchorCoordinate) {
+ center = anchorCoordinate
+ }
+
+ function addGeometry(newCoordinate, changeLast){
+ radius = center.distanceTo(newCoordinate)
+ return true
+ }
+
+ function finishAddGeometry(){
+ color = "#46a2da"
+ border.color = "#190a33"
+ opacity = 0.25
+ }
+}
diff --git a/examples/location/geojson_viewer/mapitems/PolygonItem.qml b/examples/location/geojson_viewer/mapitems/PolygonItem.qml
new file mode 100644
index 00000000..b17c4c84
--- /dev/null
+++ b/examples/location/geojson_viewer/mapitems/PolygonItem.qml
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtLocation
+
+MapPolygon {
+ color: "#da5546"
+ border.color: "#330a0a"
+ border.width: 2
+ smooth: true
+ opacity: 0.75
+ autoFadeIn: false
+
+ property string geojsonType: "Polygon"
+
+ function setGeometry(anchorCoordinate){
+ addCoordinate(anchorCoordinate)
+ }
+
+ function addGeometry(newCoordinate, changeLast){
+ if (changeLast && path.length > 0)
+ removeCoordinate(path[path.length-1])
+ addCoordinate(newCoordinate)
+ return false
+ }
+
+ function finishAddGeometry(){
+ if (path.length > 0)
+ removeCoordinate(path[path.length-1])
+ color = "#46a2da"
+ border.color = "#190a33"
+ opacity = 0.25
+ }
+}
diff --git a/examples/location/geojson_viewer/mapitems/PolylineItem.qml b/examples/location/geojson_viewer/mapitems/PolylineItem.qml
new file mode 100644
index 00000000..f2922d26
--- /dev/null
+++ b/examples/location/geojson_viewer/mapitems/PolylineItem.qml
@@ -0,0 +1,32 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtLocation
+
+MapPolyline {
+ line.color: "#330a0a"
+ line.width: 4
+ opacity: 0.75
+ smooth: true
+ autoFadeIn: false
+
+ property string geojsonType: "Polyline"
+
+ function setGeometry(anchorCoordinate){
+ addCoordinate(anchorCoordinate)
+ }
+
+ function addGeometry(newCoordinate, changeLast){
+ if (changeLast)
+ replaceCoordinate(pathLength()-1, newCoordinate)
+ else
+ addCoordinate(newCoordinate)
+ return false
+ }
+
+ function finishAddGeometry(){
+ removeCoordinate(pathLength()-1)
+ line.color = "#46a2da"
+ opacity = 0.5
+ }
+}
diff --git a/examples/location/geojson_viewer/mapitems/RectangleItem.qml b/examples/location/geojson_viewer/mapitems/RectangleItem.qml
new file mode 100644
index 00000000..51b6d538
--- /dev/null
+++ b/examples/location/geojson_viewer/mapitems/RectangleItem.qml
@@ -0,0 +1,28 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+import QtQuick
+import QtLocation
+
+MapRectangle {
+ color: "#da5546"
+ border.color: "#330a0a"
+ border.width: 2
+ smooth: true
+ opacity: 0.75
+ autoFadeIn: false
+
+ function setGeometry(anchorCoordinate) {
+ topLeft = anchorCoordinate
+ }
+
+ function addGeometry(newCoordinate, changeLast){
+ bottomRight = newCoordinate
+ return true //finished
+ }
+
+ function finishAddGeometry(){
+ color = "#46a2da"
+ border.color = "#190a33"
+ opacity = 0.25
+ }
+}