Newer
Older
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief QGC Map Background
* @author Gus Grubba <mavlink@grubba.com>
*/
import QtLocation 5.3
import QtPositioning 5.3
import QGroundControl.FlightMap 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.Vehicle 1.0
property real latitude: 0
property real longitude: 0
property real heading: 0
property bool interactive: true
property string mapName: 'defaultMap'
property alias mapMenu: mapTypeMenu
property alias mapWidgets: controlWidgets
property bool isSatelliteMap: false
property real lon: (longitude >= -180 && longitude <= 180) ? longitude : 0
property real lat: (latitude >= -90 && latitude <= 90) ? latitude : 0
anchors.fill: parent
zoomLevel: 18
center: QtPositioning.coordinate(lat, lon)
gesture.flickDeceleration: 3000
gesture.enabled: interactive
plugin: Plugin { name: "QGroundControl" }
Component.onCompleted: mapTypeMenu.update()
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.right: parent.right
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelWidth / 2
//-- Menu to select supported map types
Menu {
id: mapTypeMenu
title: "Map Type..."
ExclusiveGroup { id: currMapType }
function setCurrentMap(mapID) {
for (var i = 0; i < _map.supportedMapTypes.length; i++) {
if (mapID === _map.supportedMapTypes[i].name) {
_map.activeMapType = _map.supportedMapTypes[i]
multiVehicleManager.saveSetting(_map.mapName + "/currentMapType", mapID);
return;
}
}
}
function addMap(mapID, checked) {
var mItem = mapTypeMenu.addItem(mapID);
mItem.checkable = true
mItem.checked = checked
mItem.exclusiveGroup = currMapType
var menuSlot = function() {setCurrentMap(mapID);};
mItem.triggered.connect(menuSlot);
}
function update() {
clear()
var mapID = ''
if (_map.supportedMapTypes.length > 0)
mapID = _map.activeMapType.name;
mapID = multiVehicleManager.loadSetting(_map.mapName + "/currentMapType", mapID);
for (var i = 0; i < _map.supportedMapTypes.length; i++) {
var name = _map.supportedMapTypes[i].name;
addMap(name, mapID === name);
}
if(mapID != '')
setCurrentMap(mapID);
}
}
QGCButton {
id: optionsButton
text: "Options"
menu: mapTypeMenu
}
Row {
layoutDirection: Qt.RightToLeft
spacing: ScreenTools.defaultFontPixelWidth / 2
readonly property real _zoomIncrement: 1.0
property real _buttonWidth: (optionsButton.width - spacing) / 2
NumberAnimation {
id: animateZoom
property real startZoom
property real endZoom
properties: "zoomLevel"
from: startZoom
to: endZoom
duration: 500
easing {
type: Easing.OutExpo
}
}
var endZoomLevel = _map.zoomLevel + parent._zoomIncrement
if (endZoomLevel > _map.maximumZoomLevel) {
endZoomLevel = _map.maximumZoomLevel
animateZoom.startZoom = _map.zoomLevel
animateZoom.endZoom = endZoomLevel
animateZoom.start()
}
var endZoomLevel = _map.zoomLevel - parent._zoomIncrement
if (endZoomLevel < _map.minimumZoomLevel) {
endZoomLevel = _map.minimumZoomLevel
animateZoom.startZoom = _map.zoomLevel
animateZoom.endZoom = endZoomLevel
animateZoom.start()
}
} // Row - +/- buttons
} // Column - Map control widgets
/*
The slider and scale display are commented out for now to try to save real estate - DonLakeFlyer
Not sure if I'll bring them back or not. Need room for waypoint list at bottom
property variant scaleLengths: [5, 10, 25, 50, 100, 150, 250, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000]
function formatDistance(meters)
{
var dist = Math.round(meters)
if (dist > 1000 ){
if (dist > 100000){
dist = Math.round(dist / 1000)
}
else{
dist = Math.round(dist / 100)
dist = dist / 10
}
dist = dist + " km"
else{
dist = dist + " m"
}
return dist
onWidthChanged: {
scaleTimer.restart()
}
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
onHeightChanged: {
scaleTimer.restart()
}
onZoomLevelChanged:{
scaleTimer.restart()
}
function calculateScale() {
var coord1, coord2, dist, text, f
f = 0
coord1 = map.toCoordinate(Qt.point(0,scale.y))
coord2 = 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 = formatDistance(dist)
scaleImage.width = (scaleImage.sourceSize.width * f) - 2 * scaleImageLeft.sourceSize.width
scaleText.text = text
}
QGCSlider {
id: zoomSlider;
minimum: map.minimumZoomLevel;
maximum: map.maximumZoomLevel;
opacity: 1
visible: parent.visible
bottomMargin: ScreenTools.defaultFontPixelSize * (1.25)
rightMargin: ScreenTools.defaultFontPixelSize * (1.66)
leftMargin: ScreenTools.defaultFontPixelSize * (1.66)
left: parent.left
}
width: parent.width - anchors.rightMargin - anchors.leftMargin
value: map.zoomLevel
Binding {
target: zoomSlider; property: "value"; value: map.zoomLevel
}
onValueChanged: {
map.zoomLevel = value
}
}
Item {
id: scale
parent: zoomSlider.parent
source: "/qmlimages/scale_end.png"
anchors.bottom: parent.bottom
anchors.left: parent.left
}
Image {
id: scaleImage
source: "/qmlimages/scale.png"
anchors.bottom: parent.bottom
anchors.left: scaleImageLeft.right
}
Image {
id: scaleImageRight
source: "/qmlimages/scale_end.png"
anchors.bottom: parent.bottom
anchors.left: scaleImage.right
}
id: scaleText
color: "white"
font.weight: Font.DemiBold
horizontalAlignment: Text.AlignHCenter
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: ScreenTools.defaultFontPixelSize * (0.83)
text: "0 m"
}
Component.onCompleted: {
map.calculateScale();
}
}
Timer {
id: scaleTimer
interval: 100
running: false
repeat: false
onTriggered: {
map.calculateScale()
}
}