7import QGroundControl.Controls
8import QGroundControl.FlightMap
10/// GeoFence map visuals
13 z: QGroundControl.zOrderMapItems
16 property var myGeoFenceController
17 property bool interactive: false ///< true: user can interact with items
18 property bool planView: false ///< true: visuals showing in plan view
19 property var homePosition
21 property var _breachReturnPointComponent
22 property var _breachReturnDragComponent
23 property var _paramCircleFenceComponent
24 property var _polygons: myGeoFenceController.polygons
25 property var _circles: myGeoFenceController.circles
26 property color _borderColor: "orange"
27 property int _borderWidthInclusion: 2
28 property int _borderWidthExclusion: 0
29 property color _interiorColorExclusion: "orange"
30 property color _interiorColorInclusion: "transparent"
31 property real _interiorOpacityExclusion: 0.2 * opacity
32 property real _interiorOpacityInclusion: 1 * opacity
34 function addPolygon(inclusionPolygon) {
35 // Initial polygon is inset to take 2/3rds space
36 var rect = Qt.rect(map.centerViewport.x, map.centerViewport.y, map.centerViewport.width, map.centerViewport.height)
37 rect.x += (rect.width * 0.25) / 2
38 rect.y += (rect.height * 0.25) / 2
42 var centerCoord = map.toCoordinate(Qt.point(rect.x + (rect.width / 2), rect.y + (rect.height / 2)), false /* clipToViewPort */)
43 var topLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y), false /* clipToViewPort */)
44 var topRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y), false /* clipToViewPort */)
45 var bottomLeftCoord = map.toCoordinate(Qt.point(rect.x, rect.y + rect.height), false /* clipToViewPort */)
46 var bottomRightCoord = map.toCoordinate(Qt.point(rect.x + rect.width, rect.y + rect.height), false /* clipToViewPort */)
48 // Initial polygon has max width and height of 3000 meters
49 var halfWidthMeters = Math.min(topLeftCoord.distanceTo(topRightCoord), 3000) / 2
50 var halfHeightMeters = Math.min(topLeftCoord.distanceTo(bottomLeftCoord), 3000) / 2
51 topLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 0)
52 topRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 0)
53 bottomLeftCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, -90).atDistanceAndAzimuth(halfHeightMeters, 180)
54 bottomRightCoord = centerCoord.atDistanceAndAzimuth(halfWidthMeters, 90).atDistanceAndAzimuth(halfHeightMeters, 180)
56 console.log(map.center)
57 console.log(topLeftCoord)
58 console.log(bottomRightCoord)
60 if (inclusionPolygon) {
61 myGeoFenceController.addInclusion(topLeftCoord, bottomRightCoord)
63 myGeoFenceController.addExclusion(topLeftCoord, bottomRightCoord)
67 Component.onCompleted: {
68 _breachReturnPointComponent = breachReturnPointComponent.createObject(map)
69 map.addMapItem(_breachReturnPointComponent)
70 _breachReturnDragComponent = breachReturnDragComponent.createObject(map, { "itemIndicator": _breachReturnPointComponent })
71 _paramCircleFenceComponent = paramCircleFenceComponent.createObject(map)
72 map.addMapItem(_paramCircleFenceComponent)
75 Component.onDestruction: {
76 _breachReturnPointComponent.destroy()
77 _breachReturnDragComponent.destroy()
78 _paramCircleFenceComponent.destroy()
81 // By default the parent for Instantiator.delegate item is the Instatiator itself. By there is a bug
82 // in Qt which will cause a crash if this delete item has Menu item within it. Since the Menu item
83 // doesn't like having a non-visual item as parent. This is likely related to hybrid QQuickWidtget+QML
84 // Hence Qt folks are going to care. In order to workaround you have to parent the item to _root Item instead.
88 delegate : QGCMapPolygonVisuals {
92 borderWidth: object.inclusion ? _borderWidthInclusion : _borderWidthExclusion
93 borderColor: _borderColor
94 interiorColor: object.inclusion ? _interiorColorInclusion : _interiorColorExclusion
95 interiorOpacity: object.inclusion ? _interiorOpacityInclusion : _interiorOpacityExclusion
96 interactive: _root.interactive && mapPolygon && mapPolygon.interactive
103 delegate : QGCMapCircleVisuals {
107 borderWidth: object.inclusion ? _borderWidthInclusion : _borderWidthExclusion
108 borderColor: _borderColor
109 interiorColor: object.inclusion ? _interiorColorInclusion : _interiorColorExclusion
110 interiorOpacity: object.inclusion ? _interiorOpacityInclusion : _interiorOpacityExclusion
111 interactive: _root.interactive && mapCircle && mapCircle.interactive
115 // Circular geofence specified from parameter
117 id: paramCircleFenceComponent
120 color: _interiorColorInclusion
121 opacity: _interiorOpacityInclusion
122 border.color: _borderColor
123 border.width: _borderWidthInclusion
126 visible: homePosition.isValid && _radius > 0
128 property real _radius: myGeoFenceController.paramCircularFence
130 on_RadiusChanged: console.log("_radius", _radius, homePosition.isValid, homePosition)
135 id: breachReturnDragComponent
137 MissionItemIndicatorDrag {
139 itemCoordinate: myGeoFenceController.breachReturnPoint
140 visible: _root.interactive
142 onItemCoordinateChanged: myGeoFenceController.breachReturnPoint = itemCoordinate
147 // Breach return point
149 id: breachReturnPointComponent
152 anchorPoint.x: sourceItem.anchorPointX
153 anchorPoint.y: sourceItem.anchorPointY
154 z: QGroundControl.zOrderMapItems
155 coordinate: myGeoFenceController.breachReturnPoint
156 opacity: _root.opacity
158 sourceItem: MissionItemIndexLabel {
159 label: qsTr("B", "Breach Return Point item indicator")