// Copyright (C) 2019 Julian Sherollari // Copyright (C) 2021 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick import QtQuick.Dialogs import QtQuick.Controls import QtPositioning import QtLocation import QtCore import Qt.GeoJson import "mapitems" ApplicationWindow { id: win visible: true width: 512 height: 512 menuBar: mainMenu title: qsTr("GeoJSON Viewer: ") + view.map.center + " zoom " + view.map.zoomLevel.toFixed(3) + " min " + view.map.minimumZoomLevel + " max " + view.map.maximumZoomLevel FileDialog { visible: false id: fileDialog title: "Choose a GeoJSON file" fileMode: FileDialog.OpenFile currentFolder: dataPath nameFilters: ["GeoJSON files (*.geojson *.json)"] onAccepted: { view.clearAllItems() geoJsoner.load(fileDialog.selectedFile) } } FileDialog { visible: false id: fileWriteDialog title: "Write your geometry to a file" fileMode: FileDialog.SaveFile currentFolder: StandardPaths.writableLocation(StandardPaths.TempLocation) nameFilters: ["GeoJSON files (*.geojson *.json)"] //! [Write File] onAccepted: { geoJsoner.dumpGeoJSON(geoJsoner.toVariant(miv), fileWriteDialog.selectedFile); } //! [Write File] } FileDialog { visible: false id: debugWriteDialog title: "Write Qvariant debug view" fileMode: FileDialog.SaveFile currentFolder: StandardPaths.writableLocation(StandardPaths.TempLocation) nameFilters: ["GeoJSON files (*.geojson *.json)"] onAccepted: { geoJsoner.writeDebug(geoJsoner.toVariant(miv), debugWriteDialog.selectedFile); } } MenuBar { id: mainMenu Menu { title: "&File" id : geoJsonMenu MenuItem { text: "&Open" onTriggered: { fileDialog.open() } } MenuItem { text: "&Export" onTriggered: { fileWriteDialog.open() } } MenuItem { text: "&Clear" onTriggered: { view.clearAllItems() } } MenuItem { text: "E&xit" onTriggered: Qt.quit() } } Menu { title: "&Debug" id : debugMenu MenuItem { text: "Print debug data to &file" onTriggered: { debugWriteDialog.open() } } MenuItem { text: "&Print debug data" onTriggered: { geoJsoner.print(miv) } } } } GeoJsoner { id: geoJsoner } Shortcut { enabled: view.map.zoomLevel < view.map.maximumZoomLevel sequence: StandardKey.ZoomIn onActivated: view.map.zoomLevel = Math.round(view.map.zoomLevel + 1) } Shortcut { enabled: view.map.zoomLevel > view.map.minimumZoomLevel sequence: StandardKey.ZoomOut onActivated: view.map.zoomLevel = Math.round(view.map.zoomLevel - 1) } //! [MapView Creation] MapView { id: view anchors.fill: parent map.plugin: Plugin { name: "osm" } map.zoomLevel: 4 //! [MapView Creation] property variant unfinishedItem: undefined signal showMainMenu(variant coordinate) //! [add item] function addGeoItem(item) { 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) } else { console.log(item + " is not supported right now, please call us later.") } } //! [add item] //! [finish item] function finishGeoItem() { unfinishedItem.finishAddGeometry() geoJsoner.addItem(unfinishedItem) map.removeMapItem(unfinishedItem) unfinishedItem = undefined } //! [finish item] //! [clearAllItems] function clearAllItems() { geoJsoner.clear(); } //! [clearAllItems] //! [MapItemView] MapItemView { id: miv parent: view.map //! [MapItemView] //! [MapItemView Model] model: geoJsoner.model //! [MapItemView Model] //! [MapItemView Delegate] delegate: GeoJsonDelegate { } //! [MapItemView Delegate] } 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 Map] 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) } } //! [Hoverhandler Map] TapHandler { id: tapHandler property variant lastCoordinate acceptedButtons: Qt.LeftButton | Qt.RightButton //! [Taphandler Map] onSingleTapped: (eventPoint, button) => { lastCoordinate = view.map.toCoordinate(tapHandler.point.position) if (button === Qt.RightButton) { if (view.unfinishedItem !== undefined) { view.finishGeoItem() } 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.finishGeoItem() } } } } //! [Taphandler Map] } TapHandler { acceptedButtons: Qt.LeftButton | Qt.RightButton onDoubleTapped: (eventPoint, button) => { var preZoomPoint = view.map.toCoordinate(eventPoint.position); if (button === Qt.LeftButton) view.map.zoomLevel = Math.floor(view.map.zoomLevel + 1) else 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); } } } }