// Copyright (C) 2022 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause import QtQuick import QtQuick.Controls import QtLocation import QtPositioning import "../helper.js" as Helper //! [top] MapView { id: view //! [top] property variant markers property variant mapItems property int markerCounter: 0 // counter for total amount of markers. Resets to 0 when number of markers = 0 property int currentMarker property bool followme: false property variant scaleLengths: [5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000] property alias routeQuery: routeQuery property alias routeModel: routeModel property alias geocodeModel: geocodeModel property alias slidersExpanded: sliders.expanded property variant unfinishedItem: 'undefined' signal showGeocodeInfo() signal geocodeFinished() signal routeError() signal coordinatesCaptured(double latitude, double longitude) signal showMainMenu(variant coordinate) signal showMarkerMenu(variant coordinate) signal showRouteMenu(variant coordinate) signal showPointMenu(variant coordinate) signal showRouteList() function geocodeMessage() { var street, district, city, county, state, countryCode, country, postalCode, latitude, longitude, text latitude = Math.round(geocodeModel.get(0).coordinate.latitude * 10000) / 10000 longitude =Math.round(geocodeModel.get(0).coordinate.longitude * 10000) / 10000 street = geocodeModel.get(0).address.street district = geocodeModel.get(0).address.district city = geocodeModel.get(0).address.city county = geocodeModel.get(0).address.county state = geocodeModel.get(0).address.state countryCode = geocodeModel.get(0).address.countryCode country = geocodeModel.get(0).address.country postalCode = geocodeModel.get(0).address.postalCode text = "Latitude: " + latitude + "
" text +="Longitude: " + longitude + "
" + "
" if (street) text +="Street: "+ street + "
" if (district) text +="District: "+ district +"
" if (city) text +="City: "+ city + "
" if (county) text +="County: "+ county + "
" if (state) text +="State: "+ state + "
" if (countryCode) text +="Country code: "+ countryCode + "
" if (country) text +="Country: "+ country + "
" if (postalCode) text +="PostalCode: "+ postalCode + "
" return text } function calculateScale() { var coord1, coord2, dist, text, f f = 0 coord1 = view.map.toCoordinate(Qt.point(0,scale.y)) coord2 = view.map.toCoordinate(Qt.point(0+scaleImage.sourceSize.width,scale.y)) dist = Math.round(coord1.distanceTo(coord2)) if (dist === 0) { // not visible } else { for (var i = 0; i < scaleLengths.length-1; i++) { if (dist < (scaleLengths[i] + scaleLengths[i+1]) / 2 ) { f = scaleLengths[i] / dist dist = scaleLengths[i] break; } } if (f === 0) { f = dist / scaleLengths[i] dist = scaleLengths[i] } } text = Helper.formatDistance(dist) scaleImage.width = (scaleImage.sourceSize.width * f) - 2 * scaleImageLeft.sourceSize.width scaleText.text = text } function deleteMarkers() { var count = view.markers.length for (var i = count-1; i>=0; i--){ view.map.removeMapItem(view.markers[i]) } view.markers = [] } function deleteMapItems() { var count = view.mapItems.length for (var i = count-1; i>=0; i--){ view.map.removeMapItem(view.mapItems[i]) } view.mapItems = [] } function addMarker() { var count = view.markers.length markerCounter++ var marker = Qt.createQmlObject ('Marker {}', map) view.map.addMapItem(marker) marker.z = view.map.z+1 marker.coordinate = tapHandler.lastCoordinate markers.push(marker) } function addGeoItem(item) { var count = view.map.mapItems.length var co = Qt.createComponent(item+'.qml') if (co.status === Component.Ready) { unfinishedItem = co.createObject(map) unfinishedItem.setGeometry(tapHandler.lastCoordinate) unfinishedItem.addGeometry(hoverHandler.currentCoordinate, false) view.map.addMapItem(unfinishedItem) mapItems.push(unfinishedItem) } else { console.log(item + " is not supported right now, please call us later.") } } function deleteMarker(index) { //update list of markers var myArray = [] var count = view.markers.length for (var i = 0; i { if (event.key === Qt.Key_Plus) { view.map.zoomLevel++; } else if (event.key === Qt.Key_Minus) { view.map.zoomLevel--; } else if (event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Up || event.key === Qt.Key_Down) { var dx = 0; var dy = 0; switch (event.key) { case Qt.Key_Left: dx = view.map.width / 4; break; case Qt.Key_Right: dx = -view.map.width / 4; break; case Qt.Key_Up: dy = view.map.height / 4; break; case Qt.Key_Down: dy = -view.map.height / 4; break; } var mapCenterPoint = Qt.point(view.map.width / 2.0 - dx, view.map.height / 2.0 - dy); view.map.center = view.map.toCoordinate(mapCenterPoint); } else if (event.key === Qt.Key_Escape) { mapview.unfinishedItem.finishAddGeometry() mapview.unfinishedItem = 'undefined' } } /* @todo Binding { target: map property: 'center' value: positionSource.position.coordinate when: followme }*/ PositionSource{ id: positionSource active: followme onPositionChanged: { view.map.center = positionSource.position.coordinate } } MapQuickItem { id: poiTheQtComapny parent: view.map sourceItem: Rectangle { width: 14; height: 14; color: "#e41e25"; border.width: 2; border.color: "white"; smooth: true; radius: 7 } coordinate { latitude: 59.9485 longitude: 10.7686 } opacity: 1.0 anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2) } MapQuickItem { parent: view.map sourceItem: Text{ text: "The Qt Company" color:"#242424" font.bold: true styleColor: "#ECECEC" style: Text.Outline } coordinate: poiTheQtComapny.coordinate anchorPoint: Qt.point(-poiTheQtComapny.sourceItem.width * 0.5,poiTheQtComapny.sourceItem.height * 1.5) } MapSliders { id: sliders z: view.map.z + 3 mapSource: map edge: Qt.LeftEdge } Item { id: scale z: view.map.z + 3 visible: scaleText.text !== "0 m" anchors.bottom: parent.bottom; anchors.right: parent.right anchors.margins: 20 height: scaleText.height * 2 width: scaleImage.width Image { id: scaleImageLeft source: "../resources/scale_end.png" anchors.bottom: parent.bottom anchors.right: scaleImage.left } Image { id: scaleImage source: "../resources/scale.png" anchors.bottom: parent.bottom anchors.right: scaleImageRight.left } Image { id: scaleImageRight source: "../resources/scale_end.png" anchors.bottom: parent.bottom anchors.right: parent.right } Label { id: scaleText color: "#004EAE" anchors.centerIn: parent text: "0 m" } Component.onCompleted: { view.calculateScale(); } } //! [routemodel0] RouteModel { id: routeModel plugin : view.map.plugin query: RouteQuery { id: routeQuery } onStatusChanged: { if (status == RouteModel.Ready) { switch (count) { case 0: // technically not an error view.routeError() break case 1: view.showRouteList() break } } else if (status == RouteModel.Error) { view.routeError() } } } //! [routemodel0] //! [routedelegate0] Component { id: routeDelegate MapRoute { id: route route: routeData line.color: "#46a2da" line.width: 5 smooth: true opacity: 0.8 //! [routedelegate0] TapHandler { acceptedButtons: Qt.LeftButton | Qt.RightButton onLongPressed: showRouteMenu(view.map.toCoordinate(tapHandler.point.position)) onSingleTapped: (eventPoint, button) => { if (button === Qt.RightButton) showRouteMenu(view.map.toCoordinate(tapHandler.point.position)) } } } } //! [geocodemodel0] GeocodeModel { id: geocodeModel plugin: view.map.plugin onStatusChanged: { if ((status == GeocodeModel.Ready) || (status == GeocodeModel.Error)) view.geocodeFinished() } onLocationsChanged: { if (count === 1) { view.map.center.latitude = get(0).coordinate.latitude view.map.center.longitude = get(0).coordinate.longitude } } } //! [geocodemodel0] //! [pointdel0] Component { id: pointDelegate MapCircle { id: point parent: view.map radius: 1000 color: "#46a2da" border.color: "#190a33" border.width: 2 smooth: true opacity: 0.25 center: locationData.coordinate //! [pointdel0] /* TapHandler { point.onPositionChanged: { if (Math.abs(view.map.pressX - parent.x - point.position.x) > view.map.jitterThreshold || Math.abs(view.map.pressY - parent.y - point.position.y) > view.map.jitterThreshold) { if (pressed) parent.radius = parent.center.distanceTo(view.map.toCoordinate(point.position)) } } onLongPressed: showPointMenu(view.map.toCoordinate(point.position)) }*/ //! [pointdel1] } } //! [pointdel1] //! [routeview0] MapItemView { parent: view.map model: routeModel delegate: routeDelegate //! [routeview0] autoFitViewport: true } //! [geocodeview] MapItemView { parent: view.map model: geocodeModel delegate: pointDelegate } //! [geocodeview] Timer { id: scaleTimer interval: 100 running: false repeat: false onTriggered: view.calculateScale() } HoverHandler { id: hoverHandler property variant currentCoordinate grabPermissions: PointerHandler.CanTakeOverFromItems | PointerHandler.CanTakeOverFromHandlersOfDifferentType onPointChanged: { currentCoordinate = view.map.toCoordinate(hoverHandler.point.position) if (mapview.unfinishedItem !== 'undefined') mapview.unfinishedItem.addGeometry(view.map.toCoordinate(hoverHandler.point.position), true) } } TapHandler { id: tapHandler property variant lastCoordinate acceptedButtons: Qt.LeftButton | Qt.RightButton onPressedChanged: (eventPoint, button) => { if (pressed) { lastCoordinate = view.map.toCoordinate(tapHandler.point.position) } } onSingleTapped: (eventPoint, button) => { if (button === Qt.RightButton) { if (mapview.unfinishedItem !== 'undefined') { mapview.unfinishedItem.finishAddGeometry() mapview.unfinishedItem = 'undefined' } else showMainMenu(lastCoordinate) } else if (button === Qt.LeftButton) { if (mapview.unfinishedItem !== 'undefined') { if (mapview.unfinishedItem.addGeometry(view.map.toCoordinate(tapHandler.point.position), false)) { mapview.unfinishedItem.finishAddGeometry() mapview.unfinishedItem = 'undefined' } } } } onDoubleTapped: (eventPoint, button) => { var preZoomPoint = view.map.toCoordinate(eventPoint.position); if (button === Qt.LeftButton) { view.map.zoomLevel = Math.floor(view.map.zoomLevel + 1) } else if (button === Qt.RightButton) { 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); } } //! [end] } //! [end]