地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
10 KiB

/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/**
* @file
* @brief QGC Map Background
* @author Gus Grubba <mavlink@grubba.com>
*/
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtLocation 5.3
import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.Mavlink 1.0
Map {
id: _map
property string mapName: 'defaultMap'
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1
readonly property real maxZoomLevel: 20
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
}
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
}
zoomLevel: 18
center: QGroundControl.lastKnownHomePosition
gesture.flickDeceleration: 3000
plugin: Plugin { name: "QGroundControl" }
ExclusiveGroup { id: mapTypeGroup }
property bool _initialMapPositionSet: false
Connections {
target: mainWindow
onGcsPositionChanged: {
if (!_initialMapPositionSet) {
_initialMapPositionSet = true
center = mainWindow.gcsPosition
}
}
}
function updateActiveMapType() {
var fullMapName = QGroundControl.flightMapSettings.mapProvider + " " + QGroundControl.flightMapSettings.mapType
for (var i = 0; i < _map.supportedMapTypes.length; i++) {
if (fullMapName === _map.supportedMapTypes[i].name) {
_map.activeMapType = _map.supportedMapTypes[i]
return
}
}
}
Component.onCompleted: updateActiveMapType()
Connections {
target: QGroundControl.flightMapSettings
onMapTypeChanged: updateActiveMapType()
}
MapQuickItem {
anchorPoint.x: sourceItem.width / 2
anchorPoint.y: sourceItem.height / 2
visible: mainWindow.gcsPosition.isValid
coordinate: mainWindow.gcsPosition
sourceItem: MissionItemIndexLabel {
label: "Q"
}
}
//---- Polygon drawing code
//
// Usage:
//
// Connections {
// target: map.polygonDraw
//
// onPolygonStarted: {
// // Polygon creation has started
// }
//
// onPolygonFinished: {
// // Polygon capture complete, coordinates signal variable contains the polygon points
// }
// }
//
// map.polygonDraqw.startPolgyon() - begin capturing a new polygon
// map.polygonDraqw.endPolygon() - end capture (right-click will also end capture)
// Not sure why this is needed, but trying to reference polygonDrawer directly from other code doesn't work
property alias polygonDraw: polygonDrawer
QGCLabel {
id: polygonHelp
anchors.topMargin: parent.height - ScreenTools.availableHeight
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
horizontalAlignment: Text.AlignHCenter
text: qsTr("Click to add point %1").arg(ScreenTools.isMobile || !polygonDrawer.polygonReady ? "" : qsTr("- Right Click to end polygon"))
visible: polygonDrawer.drawingPolygon
}
MouseArea {
id: polygonDrawer
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
visible: drawingPolygon
z: 1000 // Hack to fix MouseArea layering for now
property alias drawingPolygon: polygonDrawer.hoverEnabled
property bool polygonReady: polygonDrawerPolygon.path.length > 3 ///< true: enough points have been captured to create a closed polygon
/// New polygon capture has started
signal polygonStarted
/// Polygon capture is complete
/// @param coordinates Map coordinates for the polygon points
signal polygonFinished(var coordinates)
/// Begin capturing a new polygon
/// polygonStarted will be signalled
function startPolygon() {
polygonDrawer.drawingPolygon = true
polygonDrawer._clearPolygon()
polygonDrawer.polygonStarted()
}
/// Finish capturing the polygon
/// polygonFinished will be signalled
/// @return true: polygon completed, false: not enough points to complete polygon
function finishPolygon() {
if (!polygonDrawer.polygonReady) {
return false
}
var polygonPath = polygonDrawerPolygon.path
polygonPath.pop() // get rid of drag coordinate
polygonDrawer._clearPolygon()
polygonDrawer.drawingPolygon = false
polygonDrawer.polygonFinished(polygonPath)
return true
}
function _clearPolygon() {
// Simpler methods to clear the path simply don't work due to bugs. This craziness does.
var bogusCoord = _map.toCoordinate(Qt.point(height/2, width/2))
polygonDrawerPolygon.path = [ bogusCoord, bogusCoord ]
polygonDrawerNextPoint.path = [ bogusCoord, bogusCoord ]
polygonDrawerPolygon.path = [ ]
polygonDrawerNextPoint.path = [ ]
}
onClicked: {
if (mouse.button == Qt.LeftButton) {
if (polygonDrawerPolygon.path.length > 2) {
// Make sure the new line doesn't intersect the existing polygon
var lastSegment = polygonDrawerPolygon.path.length - 2
var newLineA = _map.fromCoordinate(polygonDrawerPolygon.path[lastSegment], false /* clipToViewPort */)
var newLineB = _map.fromCoordinate(polygonDrawerPolygon.path[lastSegment+1], false /* clipToViewPort */)
for (var i=0; i<lastSegment; i++) {
var oldLineA = _map.fromCoordinate(polygonDrawerPolygon.path[i], false /* clipToViewPort */)
var oldLineB = _map.fromCoordinate(polygonDrawerPolygon.path[i+1], false /* clipToViewPort */)
if (QGroundControl.linesIntersect(newLineA, newLineB, oldLineA, oldLineB)) {
return;
}
}
}
var clickCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y))
var polygonPath = polygonDrawerPolygon.path
if (polygonPath.length == 0) {
// Add first coordinate
polygonPath.push(clickCoordinate)
} else {
// Update finalized coordinate
polygonPath[polygonDrawerPolygon.path.length - 1] = clickCoordinate
}
// Add next drag coordinate
polygonPath.push(clickCoordinate)
polygonDrawerPolygon.path = polygonPath
} else if (polygonDrawer.polygonReady) {
finishPolygon()
}
}
onPositionChanged: {
if (polygonDrawerPolygon.path.length) {
var dragCoordinate = _map.toCoordinate(Qt.point(mouse.x, mouse.y))
// Update drag line
polygonDrawerNextPoint.path = [ polygonDrawerPolygon.path[polygonDrawerPolygon.path.length - 2], dragCoordinate ]
// Update drag coordinate
var polygonPath = polygonDrawerPolygon.path
polygonPath[polygonDrawerPolygon.path.length - 1] = dragCoordinate
polygonDrawerPolygon.path = polygonPath
}
}
}
MapPolygon {
id: polygonDrawerPolygon
color: "blue"
opacity: 0.5
visible: polygonDrawer.drawingPolygon
}
MapPolyline {
id: polygonDrawerNextPoint
line.color: "green"
line.width: 5
visible: polygonDrawer.drawingPolygon
}
//---- End Polygon Drawing code
} // Map