Warning, /utilities/kirogi/src/ui/NavigationMap.qml is written in an unsupported language. File is not indexed.

0001 /*
0002  * Copyright 2019 Eike Hein <hein@kde.org>
0003  *
0004  * This program is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU General Public License as
0006  * published by the Free Software Foundation; either version 2 of
0007  * the License or (at your option) version 3 or any later version
0008  * accepted by the membership of KDE e.V. (or its successor approved
0009  * by the membership of KDE e.V.), which shall act as a proxy
0010  * defined in Section 14 of version 3 of the license.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  * GNU General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU General Public License
0018  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 
0021 import QtQuick 2.12
0022 import QtLocation 5.6
0023 import QtPositioning 5.6
0024 import QtQuick.Window 2.12
0025 import QtQuick.Controls 2.12 as QQC2
0026 import QtQuick.Shapes 1.12
0027 
0028 import QtGraphicalEffects 1.12
0029 
0030 import org.kde.kirigami 2.6 as Kirigami
0031 
0032 Kirigami.Page {
0033     id: page
0034 
0035     readonly property var eVoffice: QtPositioning.coordinate(52.5035334, 13.4091622) // KDE e.V. office.
0036 
0037     leftPadding: 0
0038     rightPadding: 0
0039     topPadding: 0
0040     bottomPadding: 0
0041 
0042     Connections {
0043         target: kirogi.currentVehicle
0044 
0045         onGpsPositionChanged: {
0046             if (kirogi.currentVehicle.gpsPosition.isValid
0047                 && (kirogi.currentPage != page || map.center == eVoffice)) {
0048                 map.center = kirogi.currentVehicle.gpsPosition;
0049             }
0050         }
0051 
0052         onMaxDistanceChanged: geoFence.radius = kirogi.currentVehicle.maxDistance
0053     }
0054 
0055     Connections {
0056         target: kirogi
0057 
0058         onPositionChanged: {
0059             if (kirogi.position != null
0060                 && (kirogi.currentPage != page || map.center == eVoffice)
0061                 && (!kirogi.currentVehicle || !kirogi.currentVehicle.gpsPosition.isValid)) {
0062                 map.center = kirogi.position;
0063             }
0064         }
0065     }
0066 
0067     Map {
0068         id: map
0069 
0070         anchors.fill: parent
0071 
0072         center: eVoffice
0073         zoomLevel: 19
0074 
0075         gesture.acceptedGestures: MapGestureArea.PinchGesture | MapGestureArea.PanGesture | MapGestureArea.FlickGesture
0076 
0077         plugin: Plugin {
0078             preferred: ["osm"]
0079 
0080             PluginParameter {
0081                 name: "osm.mapping.highdpi_tiles"
0082                 value: Screen.devicePixelRatio > 1 ? "true" : "false"
0083             }
0084             PluginParameter {
0085                 name: "osm.mapping.providersrepository.address"
0086                 value: "https://autoconfig.kde.org/qtlocation/"
0087             }
0088             PluginParameter {
0089                 name: "osm.useragent"
0090                 value: Qt.application.name + "/" + Qt.application.version + " (hein@kde.org)"
0091             }
0092         }
0093 
0094         onMapReadyChanged: {
0095 // FIXME TODO: Preferably get a satellite map.
0096 //             if (mapReady) {
0097 //                 for (var i = 0; i < supportedMapTypes.length; i++) {
0098 //                     if (supportedMapTypes[i].style == MapType.SatelliteMapDay) {
0099 //                         activeMapType = supportedMapTypes[i];
0100 //                         break;
0101 //                     }
0102 //                 }
0103 //             }
0104 
0105             addMapItem(geoFence);
0106             addMapItem(droneLocationMarker);
0107             addMapItem(deviceLocationMarker);
0108         }
0109 
0110         TapHandler {
0111             onTapped: {
0112                 if (kirogi.flying && kirogi.currentVehicle.gpsFix
0113                     && kirogi.currentVehicle.gpsPosition.isValid) {
0114                     var coord = map.toCoordinate(eventPoint.position, true);
0115                     coord.altitude = kirogi.currentVehicle.gpsPosition.altitude;
0116                     kirogi.currentVehicle.requestMoveTo(coord);
0117                 }
0118             }
0119         }
0120     }
0121 
0122     MapCircle {
0123         id: geoFence
0124 
0125         visible: (kirogi.currentVehicle && kirogi.currentVehicle.geofence
0126             && kirogi.currentVehicle.gpsPosition.isValid)
0127 
0128         center: (kirogi.currentVehicle && kirogi.currentVehicle.gpsPosition.isValid
0129             ? kirogi.currentVehicle.gpsPosition : map.center)
0130 
0131         border.width: Kirigami.Units.devicePixelRatio
0132         border.color: Kirigami.Theme.negativeTextColor
0133     }
0134 
0135     MapQuickItem {
0136         id: droneLocationMarker
0137 
0138         visible: (kirogi.currentVehicle && kirogi.currentVehicle.gpsSupported
0139             && kirogi.currentVehicle.gpsPosition.isValid)
0140 
0141         coordinate: (kirogi.currentVehicle && kirogi.currentVehicle.gpsPosition.isValid
0142             ? kirogi.currentVehicle.gpsPosition : map.center)
0143         anchorPoint: Qt.point(sourceItem.width / 2, sourceItem.height / 2)
0144 
0145         sourceItem: Kirigami.Icon {
0146             width: Kirigami.Units.iconSizes.medium
0147             height: width
0148             source: centerOnDroneButton.icon
0149 
0150             LinearGradient {
0151                 anchors.fill: parent
0152                 source: parent
0153                 start: Qt.point(0, 0)
0154                 end: Qt.point(0, height)
0155                 gradient: Gradient {
0156                     GradientStop { position: 0.49; color: "green" }
0157                     GradientStop { position: 0.51; color: "red" }
0158                 }
0159                 transform: Rotation {
0160                     origin.x: droneLocationMarker.width / 2
0161                     origin.y: droneLocationMarker.height / 2
0162                     angle: kirogi.currentVehicle.yaw * 180 / 3.1415}
0163             }
0164         }
0165     }
0166 
0167     MapQuickItem {
0168         id: deviceLocationMarker
0169 
0170         visible: kirogi.position != null
0171 
0172         coordinate: kirogi.position != null ? kirogi.position : map.center
0173         anchorPoint: Qt.point(sourceItem.width / 2, sourceItem.height / 2)
0174 
0175         sourceItem: Kirigami.Icon {
0176             width: Kirigami.Units.iconSizes.medium
0177             height: width
0178 
0179             color: "blue"
0180             source: centerOnDeviceButton.icon
0181         }
0182     }
0183 
0184     PillBox {
0185         visible: mapHeading.text
0186 
0187         anchors.top: parent.top
0188         anchors.topMargin: Kirigami.Units.gridUnit
0189         anchors.horizontalCenter: parent.horizontalCenter
0190 
0191         width: mapHeading.implicitWidth + Kirigami.Units.largeSpacing * 4
0192         height: 2 * Math.round((Math.max(Kirigami.Units.iconSizes.small, fontMetrics.height) + Kirigami.Units.smallSpacing * 3) / 2);
0193 
0194         background: map
0195         backgroundColor: Kirigami.Theme.negativeTextColor
0196         backgroundOpacity: 0.4
0197         borderColor: Kirigami.Theme.negativeTextColor
0198 
0199         QQC2.Label {
0200             id: mapHeading
0201 
0202             anchors.horizontalCenter: parent.horizontalCenter
0203 
0204             height: parent.height
0205 
0206             verticalAlignment: Text.AlignVCenter
0207 
0208             color: Kirigami.Theme.negativeTextColor
0209             font.bold: true
0210 
0211             text: {
0212                 if (map.error == Map.ConnectionError) {
0213                     return i18n("Unable to load map.");
0214                 } else if (kirogi.currentVehicle && !kirogi.currentVehicle.gpsSupported) {
0215                     return i18n("%1 does not support GPS.", kirogi.currentVehicle.name);
0216                 } else if (kirogi.currentVehicle && (!kirogi.currentVehicle.gpsFix || !kirogi.currentVehicle.gpsPosition.isValid)) {
0217                     return i18n("%1 does not have a GPS fix.", kirogi.currentVehicle.name);
0218                 } else if (kirogi.position == null) {
0219                     return i18n("No device location available.");
0220                 }
0221 
0222                 return "";
0223             }
0224         }
0225     }
0226 
0227     TouchButton {
0228         anchors.top: parent.top
0229         anchors.topMargin: Kirigami.Units.gridUnit
0230         anchors.left: parent.left
0231         anchors.leftMargin: Kirigami.Units.gridUnit
0232 
0233         background: map
0234 
0235         icon: "transform-move"
0236         toolTipText: i18nc("%1 = Keyboard shortcut", "Flight Controls (%1)", flightControlsPageAction.shortcut)
0237 
0238         onTapped: switchApplicationPage(flightControlsPage)
0239     }
0240 
0241     TouchButton {
0242         id: centerOnDroneButton
0243 
0244         enabled: kirogi.currentVehicle && kirogi.currentVehicle.gpsSupported && kirogi.currentVehicle.gpsPosition.isValid
0245 
0246         anchors.bottom: centerOnDeviceButton.top
0247         anchors.bottomMargin: Kirigami.Units.largeSpacing
0248         anchors.right: parent.right
0249         anchors.rightMargin: Kirigami.Units.gridUnit
0250 
0251         background: map
0252 
0253         icon: kirogi.currentVehicle ? kirogi.currentVehicle.iconName : "uav"
0254         toolTipText: i18n("Center Map on Drone")
0255 
0256         onTapped: map.center = kirogi.currentVehicle.gpsPosition
0257     }
0258 
0259     TouchButton {
0260         id: centerOnDeviceButton
0261 
0262         enabled: kirogi.position != null
0263 
0264         anchors.bottom: parent.bottom
0265         anchors.bottomMargin: Kirigami.Units.gridUnit
0266         anchors.right: parent.right
0267         anchors.rightMargin: Kirigami.Units.gridUnit
0268 
0269         background: map
0270 
0271         icon: Kirigami.Settings.isMobile ? "phone-symbolic" : "computer-symbolic"
0272         toolTipText: i18n("Center Map on Device")
0273 
0274         onTapped: map.center = kirogi.position
0275     }
0276 }