/**************************************************************************** * * (c) 2009-2016 QGROUNDCONTROL PROJECT * * QGroundControl is licensed according to the terms in the file * COPYING.md in the root of the source code directory. * ****************************************************************************/ import QtQuick 2.3 import QtQuick.Controls 1.2 import QtLocation 5.3 import QtPositioning 5.3 import QGroundControl 1.0 import QGroundControl.ScreenTools 1.0 import QGroundControl.Palette 1.0 import QGroundControl.Controls 1.0 import QGroundControl.FlightMap 1.0 /// Survey Complex Mission Item visuals Item { id: _root property var map: undefined ///< Map control to place item in property var _missionItem: object property bool _editing: _missionItem.editing property var _generator: _missionItem.generator property var _routeObject: undefined property var _entryCoordinateObject: undefined property var _exitCoordinateObject: undefined property var _generatorObject: undefined property var _entryArrowObject: undefined property var _exitArrowObject: undefined property bool _isCurrentItem: _missionItem.isCurrentItem signal clicked(int sequenceNumber) // on_EditingChanged: { // if (_editing){ // _destroyEntryCoordinate() // _destroyExitCoordinate() // _destroyTransectsComponent() // _destroyGeneratorVisuals() // } else { // _addEntryCoordinate() // _addExitCoordinate() // _addTransectsComponent() // _addGeneratorVisuals() // } // } Component.onCompleted: { console.assert(map != undefined, "please set the map property") if (!_missionItem.initialized()){ var bbox = boundingBox() _missionItem.initialize(bbox[0], bbox[1]) } // _addEntryCoordinate() // _addExitCoordinate() _addTransects() _addGeneratorVisuals() _addEntryArrow() _addExitArrow() } Component.onDestruction: { // _destroyEntryCoordinate() // _destroyExitCoordinate() _destroyTransects() _destroyGeneratorVisuals() _destroyEntryArrow() _destroyExitArrow() } on_GeneratorChanged: { _destroyGeneratorVisuals() _addGeneratorVisuals() } // Transect lines Component { id: visualTransectsComponent MapPolyline { visible: !_missionItem.editing line.color: "white" line.width: 2 path: _missionItem.route z: QGroundControl.zOrderMapItems-1 } } // Entry point Component { id: entryPointComponent MapQuickItem { anchorPoint.x: sourceItem.anchorPointX anchorPoint.y: sourceItem.anchorPointY z: QGroundControl.zOrderMapItems coordinate: _missionItem.coordinate visible: _missionItem.exitCoordinate.isValid sourceItem: MissionItemIndexLabel { index: _missionItem.sequenceNumber label: "Entry" checked: _missionItem.isCurrentItem onClicked: _root.clicked(_missionItem.sequenceNumber) } } } // Exit point Component { id: exitPointComponent MapQuickItem { anchorPoint.x: sourceItem.anchorPointX anchorPoint.y: sourceItem.anchorPointY z: QGroundControl.zOrderMapItems coordinate: _missionItem.exitCoordinate visible: _missionItem.exitCoordinate.isValid sourceItem: MissionItemIndexLabel { index: _missionItem.lastSequenceNumber label: "Exit" checked: _missionItem.isCurrentItem onClicked: _root.clicked(_missionItem.sequenceNumber) } } } // Entry arrow Component { id: entryArrowComponent MapLineArrow { property int length: _missionItem.route.length property var route: _missionItem.route fromCoord: length > 1 ? route[0] : QtPositioning.coordinate() toCoord: length > 1 ? route[1] : QtPositioning.coordinate() arrowPosition: 2 visible: length > 1 && !_missionItem.editing opacity: _root.opacity } } // Exit arrow Component { id: exitArrowComponent MapLineArrow { property int length: _missionItem.route.length property var route: _missionItem.route fromCoord: length > 3 ? route[length-2] : QtPositioning.coordinate() toCoord: length > 3 ? route[length-1] : QtPositioning.coordinate() arrowPosition: 2 visible: length > 3 && !_missionItem.editing opacity: _root.opacity } } // GeoAreas Repeater { model: _missionItem.areaData.areaList delegate: GeoAreaVisualLoader { map: _root.map geoArea: object } } // Generator visuals function _addGeneratorVisuals(){ if (_generator && _generator.mapVisualQml && !_generatorObject) { var component = Qt.createComponent(_generator.mapVisualQml) if (component.status === Component.Error) { console.log("Error loading Qml: ", _generator.mapVisualQml, component.errorString()) } else { _generatorObject = component.createObject(_root, { "map": _root.map, "generator": _root._generator, "checked": Qt.binding(function(){return _root._isCurrentItem}) }) _generatorObject.clicked.connect( function(){_root.clicked(_missionItem.sequenceNumber)}) } } } function _destroyGeneratorVisuals(){ if(_generatorObject){ _generatorObject.destroy() _generatorObject = undefined } } function _addTransects(){ if (!_routeObject){ _routeObject= visualTransectsComponent.createObject(_root) map.addMapItem(_routeObject) } } function _addExitCoordinate(){ if (!_exitCoordinateObject){ _exitCoordinateObject = exitPointComponent.createObject(_root) map.addMapItem(_exitCoordinateObject) } } function _addEntryCoordinate(){ if (!_entryCoordinateObject){ _entryCoordinateObject = entryPointComponent.createObject(_root) map.addMapItem(_entryCoordinateObject) } } function _addEntryArrow(){ if (!_entryArrowObject){ _entryArrowObject = entryArrowComponent.createObject(_root) map.addMapItem(_entryArrowObject) } } function _addExitArrow(){ if (!_exitArrowObject){ _exitArrowObject = exitArrowComponent.createObject(_root) map.addMapItem(_exitArrowObject) } } function _destroyEntryCoordinate(){ if (_entryCoordinateObject){ map.removeMapItem(_entryCoordinateObject) _entryCoordinateObject.destroy() _entryCoordinateObject = undefined } } function _destroyExitCoordinate(){ if (_exitCoordinateObject){ map.removeMapItem(_exitCoordinateObject) _exitCoordinateObject.destroy() _exitCoordinateObject = undefined } } function _destroyTransects(){ if (_routeObject){ map.removeMapItem(_routeObject) _routeObject.destroy() _routeObject= undefined } } function _destroyEntryArrow(){ if (_entryArrowObject){ map.removeMapItem(_entryArrowObject) _entryArrowObject.destroy() _entryArrowObject = undefined } } function _destroyExitArrow(){ if (_exitArrowObject){ map.removeMapItem(_exitArrowObject) _exitArrowObject.destroy() _exitArrowObject = undefined } } function boundingBox() { // Initial polygon is inset to take 2/3rds space var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height) rect.x += (rect.width * 0.25) / 2 rect.y += (rect.height * 0.25) / 2 rect.width *= 0.75 rect.height *= 0.75 var centerCoord = map.toCoordinate(Qt.point(rect.x + (rect.width / 2), rect.y + (rect.height / 2)), false /* clipToViewPort */) var topRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y), false /* clipToViewPort */) var bottomLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y + rect.height), false /* clipToViewPort */) var topLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y), false /* clipToViewPort */) var bottomRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y + rect.height), false /* clipToViewPort */) // Initial polygon has max width and height of 3000 meters var halfWidthMeters = Math.min(topLeftCoord.distanceTo(topRightCoord), 3000) / 2 var halfHeightMeters = Math.min(topLeftCoord.distanceTo(bottomLeftCoord), 3000) / 2 topRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 0) bottomLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 180) return [ bottomLeftCoord, topRightCoord ] } }