/**************************************************************************** * * (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 /// Fixed Wing Landing Pattern map visuals Item { id: _root property var map ///< Map control to place item in signal clicked(int sequenceNumber) readonly property real _landingWidthMeters: 15 readonly property real _landingLengthMeters: 100 property var _missionItem: object property var _itemVisuals: [ ] property var _mouseArea property var _dragAreas: [ ] property var _flightPath property real _landingAreaBearing: _missionItem.landingCoordinate.azimuthTo(_missionItem.loiterTangentCoordinate) property var _loiterPointObject property var _landingPointObject function hideItemVisuals() { for (var i=0; i<_itemVisuals.length; i++) { _itemVisuals[i].destroy() } _itemVisuals = [ ] } function showItemVisuals() { if (_itemVisuals.length === 0) { var itemVisual = loiterPointComponent.createObject(map) map.addMapItem(itemVisual) _itemVisuals.push(itemVisual) _loiterPointObject = itemVisual itemVisual = landingPointComponent.createObject(map) map.addMapItem(itemVisual) _itemVisuals.push(itemVisual) _landingPointObject = itemVisual var rgComponents = [ flightPathComponent, loiterRadiusComponent, landingAreaComponent, landingAreaLabelComponent, glideSlopeComponent, glideSlopeLabelComponent ] for (var i=0; i 180) { _adjustedBearing -= 180 } _adjustedBearing -= 90 if (_adjustedBearing < 0) { _adjustedBearing += 360 } } transform: Rotation { origin.x: landingAreaLabel.width / 2 origin.y: landingAreaLabel.height / 2 angle: landingAreaLabel._adjustedBearing } } } } Component { id: glideSlopeLabelComponent MapQuickItem { anchorPoint.x: 0 anchorPoint.y: sourceItem.contentHeight / 2 z: QGroundControl.zOrderMapItems visible: _missionItem.isCurrentItem sourceItem: QGCLabel { id: glideSlopeLabel text: qsTr("Glide Slope") color: "white" property real _rawBearing: _landingAreaBearing property real _adjustedBearing on_RawBearingChanged: { _adjustedBearing = _rawBearing if (_adjustedBearing > 180) { _adjustedBearing -= 180 } _adjustedBearing -= 90 if (_adjustedBearing < 0) { _adjustedBearing += 360 } } transform: Rotation { origin.x: 0 origin.y: glideSlopeLabel.contentHeight / 2 angle: glideSlopeLabel._adjustedBearing } } function recalc() { coordinate = _missionItem.landingCoordinate.atDistanceAndAzimuth(_landingLengthMeters / 2 + 2, _landingAreaBearing) } Component.onCompleted: recalc() Connections { target: _missionItem onLandingCoordinateChanged: recalc() onLoiterTangentCoordinateChanged: recalc() } } } Component { id: landingAreaComponent MapPolygon { z: QGroundControl.zOrderMapItems border.width: 1 border.color: "black" color: "green" opacity: 0.5 readonly property real angleRadians: Math.atan((_landingWidthMeters / 2) / (_landingLengthMeters / 2)) readonly property real angleDegrees: (angleRadians * (180 / Math.PI)) readonly property real hypotenuse: (_landingWidthMeters / 2) / Math.sin(angleRadians) function recalc() { path = [ ] addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing - angleDegrees)) addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing + angleDegrees)) addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing + (180 - angleDegrees))) addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing - (180 - angleDegrees))) } Component.onCompleted: recalc() Connections { target: _missionItem onLandingCoordinateChanged: recalc() onLoiterTangentCoordinateChanged: recalc() } } } Component { id: glideSlopeComponent MapPolygon { z: QGroundControl.zOrderMapItems border.width: 1 border.color: "black" color: "orange" opacity: 0.5 readonly property real angleRadians: Math.atan((_landingWidthMeters / 2) / (_landingLengthMeters / 2)) readonly property real angleDegrees: (angleRadians * (180 / Math.PI)) readonly property real hypotenuse: (_landingWidthMeters / 2) / Math.sin(angleRadians) function recalc() { path = [ ] addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing - angleDegrees)) addCoordinate(_missionItem.landingCoordinate.atDistanceAndAzimuth(hypotenuse, _landingAreaBearing + angleDegrees)) addCoordinate(_missionItem.loiterTangentCoordinate) } Component.onCompleted: recalc() Connections { target: _missionItem onLandingCoordinateChanged: recalc() onLoiterTangentCoordinateChanged: recalc() } } } }