From 812ee27236101debeccdeaf38ad2df3a1669d595 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Sat, 10 Oct 2015 20:59:41 -0700 Subject: [PATCH] Cut over 100% to new Map/Mission code - Delete all old map code --- QGCApplication.pro | 66 - QGCExternalLibs.pri | 10 - libs/opmapcontrol/opmapcontrol.h | 1 - libs/opmapcontrol/opmapcontrol.pri | 1 - libs/opmapcontrol/opmapcontrol.pro | 4 - libs/opmapcontrol/opmapcontrol_external.pri | 113 -- libs/opmapcontrol/src/common.pri | 10 - libs/opmapcontrol/src/core/accessmode.h | 86 -- .../opmapcontrol/src/core/alllayersoftype.cpp | 87 -- libs/opmapcontrol/src/core/alllayersoftype.h | 43 - libs/opmapcontrol/src/core/cache.cpp | 196 --- libs/opmapcontrol/src/core/cache.h | 62 - libs/opmapcontrol/src/core/cacheitemqueue.cpp | 79 -- libs/opmapcontrol/src/core/cacheitemqueue.h | 69 - libs/opmapcontrol/src/core/core.pro | 40 - libs/opmapcontrol/src/core/debugheader.h | 13 - libs/opmapcontrol/src/core/diagnostics.cpp | 31 - libs/opmapcontrol/src/core/diagnostics.h | 47 - libs/opmapcontrol/src/core/geodecoderstatus.h | 131 -- libs/opmapcontrol/src/core/kibertilecache.cpp | 69 - libs/opmapcontrol/src/core/kibertilecache.h | 58 - libs/opmapcontrol/src/core/languagetype.cpp | 100 -- libs/opmapcontrol/src/core/languagetype.h | 133 -- libs/opmapcontrol/src/core/maptype.h | 129 -- libs/opmapcontrol/src/core/memorycache.cpp | 60 - libs/opmapcontrol/src/core/memorycache.h | 51 - libs/opmapcontrol/src/core/opmaps.cpp | 286 ---- libs/opmapcontrol/src/core/opmaps.h | 94 -- libs/opmapcontrol/src/core/placemark.cpp | 28 - libs/opmapcontrol/src/core/placemark.h | 54 - libs/opmapcontrol/src/core/point.cpp | 65 - libs/opmapcontrol/src/core/point.h | 78 -- .../opmapcontrol/src/core/providerstrings.cpp | 88 -- libs/opmapcontrol/src/core/providerstrings.h | 85 -- libs/opmapcontrol/src/core/pureimage.cpp | 46 - libs/opmapcontrol/src/core/pureimage.h | 44 - libs/opmapcontrol/src/core/pureimagecache.cpp | 358 ----- libs/opmapcontrol/src/core/pureimagecache.h | 67 - libs/opmapcontrol/src/core/rawtile.cpp | 76 - libs/opmapcontrol/src/core/rawtile.h | 56 - libs/opmapcontrol/src/core/size.cpp | 33 - libs/opmapcontrol/src/core/size.h | 58 - libs/opmapcontrol/src/core/tilecachequeue.cpp | 102 -- libs/opmapcontrol/src/core/tilecachequeue.h | 57 - libs/opmapcontrol/src/core/urlfactory.cpp | 707 ---------- libs/opmapcontrol/src/core/urlfactory.h | 89 -- .../src/internals/MouseWheelZoomType.cpp | 32 - .../src/internals/copyrightstrings.h | 41 - libs/opmapcontrol/src/internals/core.cpp | 725 ---------- libs/opmapcontrol/src/internals/core.h | 286 ---- libs/opmapcontrol/src/internals/debugheader.h | 8 - libs/opmapcontrol/src/internals/internals.pro | 35 - libs/opmapcontrol/src/internals/loadtask.cpp | 35 - libs/opmapcontrol/src/internals/loadtask.h | 65 - .../src/internals/mousewheelzoomtype.h | 89 -- .../src/internals/pointlatlng.cpp | 55 - libs/opmapcontrol/src/internals/pointlatlng.h | 130 -- .../internals/projections/lks94projection.cpp | 799 ----------- .../internals/projections/lks94projection.h | 72 - .../projections/mercatorprojection.cpp | 98 -- .../projections/mercatorprojection.h | 55 - .../projections/mercatorprojectionyandex.cpp | 127 -- .../projections/mercatorprojectionyandex.h | 59 - .../projections/platecarreeprojection.cpp | 97 -- .../projections/platecarreeprojection.h | 56 - .../platecarreeprojectionpergo.cpp | 96 -- .../projections/platecarreeprojectionpergo.h | 56 - .../src/internals/pureprojection.cpp | 233 ---- .../src/internals/pureprojection.h | 112 -- libs/opmapcontrol/src/internals/rectangle.cpp | 79 -- libs/opmapcontrol/src/internals/rectangle.h | 158 --- .../opmapcontrol/src/internals/rectlatlng.cpp | 48 - libs/opmapcontrol/src/internals/rectlatlng.h | 264 ---- .../opmapcontrol/src/internals/sizelatlng.cpp | 60 - libs/opmapcontrol/src/internals/sizelatlng.h | 136 -- libs/opmapcontrol/src/internals/tile.cpp | 60 - libs/opmapcontrol/src/internals/tile.h | 67 - .../opmapcontrol/src/internals/tilematrix.cpp | 145 -- libs/opmapcontrol/src/internals/tilematrix.h | 54 - .../src/mapwidget/configuration.cpp | 60 - .../src/mapwidget/configuration.h | 186 --- libs/opmapcontrol/src/mapwidget/gpsitem.cpp | 220 --- libs/opmapcontrol/src/mapwidget/gpsitem.h | 227 --- libs/opmapcontrol/src/mapwidget/homeitem.cpp | 99 -- libs/opmapcontrol/src/mapwidget/homeitem.h | 77 -- .../src/mapwidget/images/EasystarBlue.png | Bin 1490 -> 0 bytes .../src/mapwidget/images/airplane.png | Bin 1747 -> 0 bytes .../src/mapwidget/images/airplane.svg | 113 -- .../src/mapwidget/images/airplanepip.png | Bin 13242 -> 0 bytes .../src/mapwidget/images/bigMarkerGreen.png | Bin 894 -> 0 bytes .../src/mapwidget/images/compas.svg | 248 ---- .../src/mapwidget/images/dragons1.jpg | Bin 171656 -> 0 bytes .../src/mapwidget/images/dragons2.jpeg | Bin 93157 -> 0 bytes .../src/mapwidget/images/home.png | Bin 5273 -> 0 bytes .../src/mapwidget/images/home.svg | 126 -- .../src/mapwidget/images/home2.svg | 80 -- .../src/mapwidget/images/mapquad.png | Bin 1044 -> 0 bytes .../src/mapwidget/images/marker.png | Bin 858 -> 0 bytes .../src/mapwidget/mapgraphicitem.cpp | 604 -------- .../src/mapwidget/mapgraphicitem.h | 240 ---- .../src/mapwidget/mapresources.qrc | 21 - .../opmapcontrol/src/mapwidget/mapripform.cpp | 53 - libs/opmapcontrol/src/mapwidget/mapripform.h | 51 - libs/opmapcontrol/src/mapwidget/mapripform.ui | 71 - libs/opmapcontrol/src/mapwidget/mapripper.cpp | 134 -- libs/opmapcontrol/src/mapwidget/mapripper.h | 64 - libs/opmapcontrol/src/mapwidget/mapwidget.pro | 50 - .../src/mapwidget/opmapwidget.cpp | 510 ------- libs/opmapcontrol/src/mapwidget/opmapwidget.h | 533 -------- libs/opmapcontrol/src/mapwidget/trailitem.cpp | 59 - libs/opmapcontrol/src/mapwidget/trailitem.h | 63 - .../src/mapwidget/traillineitem.cpp | 56 - .../src/mapwidget/traillineitem.h | 62 - libs/opmapcontrol/src/mapwidget/uavitem.cpp | 223 --- libs/opmapcontrol/src/mapwidget/uavitem.h | 230 ---- .../src/mapwidget/uavmapfollowtype.h | 86 -- .../opmapcontrol/src/mapwidget/uavtrailtype.h | 90 -- .../src/mapwidget/waypointitem.cpp | 316 ----- .../opmapcontrol/src/mapwidget/waypointitem.h | 220 --- .../src/mapwidget/waypointlineitem.cpp | 91 -- .../src/mapwidget/waypointlineitem.h | 43 - libs/opmapcontrol/src/src.pro | 6 - qgroundcontrol.qrc | 3 - resources/styles/style-dark.css | 18 - resources/styles/style-light.css | 16 - src/FlightMap/qmldir | 2 - src/MissionItemTest.cc | 1 + src/MissionItemTest.h | 2 + src/MissionManager/MissionManagerTest.h | 2 + src/QGCApplication.cc | 9 - src/QGCApplication.h | 3 - src/Vehicle/MultiVehicleManager.cc | 13 - src/Vehicle/MultiVehicleManager.h | 5 - src/Vehicle/Vehicle.cc | 40 +- src/Vehicle/Vehicle.h | 3 - src/comm/MAVLinkProtocol.cc | 1 - src/comm/QGCFlightGearLink.cc | 1 + src/main.cc | 1 - src/uas/FileManager.h | 1 + src/uas/UAS.cc | 161 +-- src/uas/UAS.h | 7 - src/uas/UASInterface.h | 4 - src/uas/UASWaypointManager.cc | 1218 ----------------- src/uas/UASWaypointManager.h | 200 --- src/ui/MainWindow.cc | 61 +- src/ui/MainWindow.h | 10 +- src/ui/MainWindow.ui | 12 - src/ui/QGCWaypointListMulti.cc | 82 -- src/ui/QGCWaypointListMulti.h | 39 - src/ui/QGCWaypointListMulti.ui | 27 - src/ui/WaypointEditableView.cc | 623 --------- src/ui/WaypointEditableView.h | 141 -- src/ui/WaypointEditableView.ui | 290 ---- src/ui/WaypointList.cc | 702 ---------- src/ui/WaypointList.h | 155 --- src/ui/WaypointList.ui | 388 ------ src/ui/WaypointViewOnlyView.cc | 386 ------ src/ui/WaypointViewOnlyView.h | 39 - src/ui/WaypointViewOnlyView.ui | 570 -------- src/ui/map/MAV2DIcon.cc | 275 ---- src/ui/map/MAV2DIcon.h | 72 - src/ui/map/QGCMapTool.cc | 33 - src/ui/map/QGCMapTool.h | 43 - src/ui/map/QGCMapTool.ui | 60 - src/ui/map/QGCMapToolBar.cc | 258 ---- src/ui/map/QGCMapToolBar.h | 49 - src/ui/map/QGCMapToolBar.ui | 132 -- src/ui/map/QGCMapWidget.cc | 902 ------------ src/ui/map/QGCMapWidget.h | 185 --- src/ui/map/Waypoint2DIcon.cc | 318 ----- src/ui/map/Waypoint2DIcon.h | 54 - src/ui/mapdisplay/MapDisplay.qml | 170 --- src/ui/mapdisplay/QGCMapDisplay.cc | 93 -- src/ui/mapdisplay/QGCMapDisplay.h | 65 - src/ui/mission/QGCMissionConditionDelay.cc | 22 - src/ui/mission/QGCMissionConditionDelay.h | 26 - src/ui/mission/QGCMissionConditionDelay.ui | 91 -- src/ui/mission/QGCMissionDoFinishSearch.cc | 34 - src/ui/mission/QGCMissionDoFinishSearch.h | 25 - src/ui/mission/QGCMissionDoFinishSearch.ui | 129 -- src/ui/mission/QGCMissionDoJump.cc | 24 - src/ui/mission/QGCMissionDoJump.h | 26 - src/ui/mission/QGCMissionDoJump.ui | 134 -- src/ui/mission/QGCMissionDoStartSearch.cc | 34 - src/ui/mission/QGCMissionDoStartSearch.h | 26 - src/ui/mission/QGCMissionDoStartSearch.ui | 92 -- src/ui/mission/QGCMissionNavLand.cc | 68 - src/ui/mission/QGCMissionNavLand.h | 29 - src/ui/mission/QGCMissionNavLand.ui | 319 ----- src/ui/mission/QGCMissionNavLoiterTime.cc | 68 - src/ui/mission/QGCMissionNavLoiterTime.h | 29 - src/ui/mission/QGCMissionNavLoiterTime.ui | 384 ------ src/ui/mission/QGCMissionNavLoiterTurns.cc | 68 - src/ui/mission/QGCMissionNavLoiterTurns.h | 29 - src/ui/mission/QGCMissionNavLoiterTurns.ui | 384 ------ src/ui/mission/QGCMissionNavLoiterUnlim.cc | 68 - src/ui/mission/QGCMissionNavLoiterUnlim.h | 29 - src/ui/mission/QGCMissionNavLoiterUnlim.ui | 350 ----- src/ui/mission/QGCMissionNavReturnToLaunch.cc | 16 - src/ui/mission/QGCMissionNavReturnToLaunch.h | 26 - src/ui/mission/QGCMissionNavReturnToLaunch.ui | 52 - src/ui/mission/QGCMissionNavSweep.cc | 80 -- src/ui/mission/QGCMissionNavSweep.h | 29 - src/ui/mission/QGCMissionNavSweep.ui | 470 ------- src/ui/mission/QGCMissionNavTakeoff.cc | 68 - src/ui/mission/QGCMissionNavTakeoff.h | 29 - src/ui/mission/QGCMissionNavTakeoff.ui | 365 ----- src/ui/mission/QGCMissionNavWaypoint.cc | 69 - src/ui/mission/QGCMissionNavWaypoint.h | 29 - src/ui/mission/QGCMissionNavWaypoint.ui | 370 ----- src/ui/mission/QGCMissionOther.cc | 36 - src/ui/mission/QGCMissionOther.h | 26 - src/ui/mission/QGCMissionOther.ui | 239 ---- src/ui/toolbar/MainToolBar.cc | 6 +- src/ui/toolbar/MainToolBar.h | 2 +- 215 files changed, 26 insertions(+), 26223 deletions(-) delete mode 100644 libs/opmapcontrol/opmapcontrol.h delete mode 100644 libs/opmapcontrol/opmapcontrol.pri delete mode 100644 libs/opmapcontrol/opmapcontrol.pro delete mode 100644 libs/opmapcontrol/opmapcontrol_external.pri delete mode 100644 libs/opmapcontrol/src/common.pri delete mode 100644 libs/opmapcontrol/src/core/accessmode.h delete mode 100644 libs/opmapcontrol/src/core/alllayersoftype.cpp delete mode 100644 libs/opmapcontrol/src/core/alllayersoftype.h delete mode 100644 libs/opmapcontrol/src/core/cache.cpp delete mode 100644 libs/opmapcontrol/src/core/cache.h delete mode 100644 libs/opmapcontrol/src/core/cacheitemqueue.cpp delete mode 100644 libs/opmapcontrol/src/core/cacheitemqueue.h delete mode 100644 libs/opmapcontrol/src/core/core.pro delete mode 100644 libs/opmapcontrol/src/core/debugheader.h delete mode 100644 libs/opmapcontrol/src/core/diagnostics.cpp delete mode 100644 libs/opmapcontrol/src/core/diagnostics.h delete mode 100644 libs/opmapcontrol/src/core/geodecoderstatus.h delete mode 100644 libs/opmapcontrol/src/core/kibertilecache.cpp delete mode 100644 libs/opmapcontrol/src/core/kibertilecache.h delete mode 100644 libs/opmapcontrol/src/core/languagetype.cpp delete mode 100644 libs/opmapcontrol/src/core/languagetype.h delete mode 100644 libs/opmapcontrol/src/core/maptype.h delete mode 100644 libs/opmapcontrol/src/core/memorycache.cpp delete mode 100644 libs/opmapcontrol/src/core/memorycache.h delete mode 100644 libs/opmapcontrol/src/core/opmaps.cpp delete mode 100644 libs/opmapcontrol/src/core/opmaps.h delete mode 100644 libs/opmapcontrol/src/core/placemark.cpp delete mode 100644 libs/opmapcontrol/src/core/placemark.h delete mode 100644 libs/opmapcontrol/src/core/point.cpp delete mode 100644 libs/opmapcontrol/src/core/point.h delete mode 100644 libs/opmapcontrol/src/core/providerstrings.cpp delete mode 100644 libs/opmapcontrol/src/core/providerstrings.h delete mode 100644 libs/opmapcontrol/src/core/pureimage.cpp delete mode 100644 libs/opmapcontrol/src/core/pureimage.h delete mode 100644 libs/opmapcontrol/src/core/pureimagecache.cpp delete mode 100644 libs/opmapcontrol/src/core/pureimagecache.h delete mode 100644 libs/opmapcontrol/src/core/rawtile.cpp delete mode 100644 libs/opmapcontrol/src/core/rawtile.h delete mode 100644 libs/opmapcontrol/src/core/size.cpp delete mode 100644 libs/opmapcontrol/src/core/size.h delete mode 100644 libs/opmapcontrol/src/core/tilecachequeue.cpp delete mode 100644 libs/opmapcontrol/src/core/tilecachequeue.h delete mode 100644 libs/opmapcontrol/src/core/urlfactory.cpp delete mode 100644 libs/opmapcontrol/src/core/urlfactory.h delete mode 100644 libs/opmapcontrol/src/internals/MouseWheelZoomType.cpp delete mode 100644 libs/opmapcontrol/src/internals/copyrightstrings.h delete mode 100644 libs/opmapcontrol/src/internals/core.cpp delete mode 100644 libs/opmapcontrol/src/internals/core.h delete mode 100644 libs/opmapcontrol/src/internals/debugheader.h delete mode 100644 libs/opmapcontrol/src/internals/internals.pro delete mode 100644 libs/opmapcontrol/src/internals/loadtask.cpp delete mode 100644 libs/opmapcontrol/src/internals/loadtask.h delete mode 100644 libs/opmapcontrol/src/internals/mousewheelzoomtype.h delete mode 100644 libs/opmapcontrol/src/internals/pointlatlng.cpp delete mode 100644 libs/opmapcontrol/src/internals/pointlatlng.h delete mode 100644 libs/opmapcontrol/src/internals/projections/lks94projection.cpp delete mode 100644 libs/opmapcontrol/src/internals/projections/lks94projection.h delete mode 100644 libs/opmapcontrol/src/internals/projections/mercatorprojection.cpp delete mode 100644 libs/opmapcontrol/src/internals/projections/mercatorprojection.h delete mode 100644 libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.cpp delete mode 100644 libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.h delete mode 100644 libs/opmapcontrol/src/internals/projections/platecarreeprojection.cpp delete mode 100644 libs/opmapcontrol/src/internals/projections/platecarreeprojection.h delete mode 100644 libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.cpp delete mode 100644 libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.h delete mode 100644 libs/opmapcontrol/src/internals/pureprojection.cpp delete mode 100644 libs/opmapcontrol/src/internals/pureprojection.h delete mode 100644 libs/opmapcontrol/src/internals/rectangle.cpp delete mode 100644 libs/opmapcontrol/src/internals/rectangle.h delete mode 100644 libs/opmapcontrol/src/internals/rectlatlng.cpp delete mode 100644 libs/opmapcontrol/src/internals/rectlatlng.h delete mode 100644 libs/opmapcontrol/src/internals/sizelatlng.cpp delete mode 100644 libs/opmapcontrol/src/internals/sizelatlng.h delete mode 100644 libs/opmapcontrol/src/internals/tile.cpp delete mode 100644 libs/opmapcontrol/src/internals/tile.h delete mode 100644 libs/opmapcontrol/src/internals/tilematrix.cpp delete mode 100644 libs/opmapcontrol/src/internals/tilematrix.h delete mode 100644 libs/opmapcontrol/src/mapwidget/configuration.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/configuration.h delete mode 100644 libs/opmapcontrol/src/mapwidget/gpsitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/gpsitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/homeitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/homeitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/images/EasystarBlue.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/airplane.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/airplane.svg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/airplanepip.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/bigMarkerGreen.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/compas.svg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/dragons1.jpg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/dragons2.jpeg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/home.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/home.svg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/home2.svg delete mode 100644 libs/opmapcontrol/src/mapwidget/images/mapquad.png delete mode 100644 libs/opmapcontrol/src/mapwidget/images/marker.png delete mode 100644 libs/opmapcontrol/src/mapwidget/mapgraphicitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/mapgraphicitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/mapresources.qrc delete mode 100644 libs/opmapcontrol/src/mapwidget/mapripform.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/mapripform.h delete mode 100644 libs/opmapcontrol/src/mapwidget/mapripform.ui delete mode 100644 libs/opmapcontrol/src/mapwidget/mapripper.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/mapripper.h delete mode 100644 libs/opmapcontrol/src/mapwidget/mapwidget.pro delete mode 100644 libs/opmapcontrol/src/mapwidget/opmapwidget.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/opmapwidget.h delete mode 100644 libs/opmapcontrol/src/mapwidget/trailitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/trailitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/traillineitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/traillineitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/uavitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/uavitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/uavmapfollowtype.h delete mode 100644 libs/opmapcontrol/src/mapwidget/uavtrailtype.h delete mode 100644 libs/opmapcontrol/src/mapwidget/waypointitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/waypointitem.h delete mode 100644 libs/opmapcontrol/src/mapwidget/waypointlineitem.cpp delete mode 100644 libs/opmapcontrol/src/mapwidget/waypointlineitem.h delete mode 100644 libs/opmapcontrol/src/src.pro delete mode 100644 src/uas/UASWaypointManager.cc delete mode 100644 src/uas/UASWaypointManager.h delete mode 100644 src/ui/QGCWaypointListMulti.cc delete mode 100644 src/ui/QGCWaypointListMulti.h delete mode 100644 src/ui/QGCWaypointListMulti.ui delete mode 100644 src/ui/WaypointEditableView.cc delete mode 100644 src/ui/WaypointEditableView.h delete mode 100644 src/ui/WaypointEditableView.ui delete mode 100644 src/ui/WaypointList.cc delete mode 100644 src/ui/WaypointList.h delete mode 100644 src/ui/WaypointList.ui delete mode 100644 src/ui/WaypointViewOnlyView.cc delete mode 100644 src/ui/WaypointViewOnlyView.h delete mode 100644 src/ui/WaypointViewOnlyView.ui delete mode 100644 src/ui/map/MAV2DIcon.cc delete mode 100644 src/ui/map/MAV2DIcon.h delete mode 100644 src/ui/map/QGCMapTool.cc delete mode 100644 src/ui/map/QGCMapTool.h delete mode 100644 src/ui/map/QGCMapTool.ui delete mode 100644 src/ui/map/QGCMapToolBar.cc delete mode 100644 src/ui/map/QGCMapToolBar.h delete mode 100644 src/ui/map/QGCMapToolBar.ui delete mode 100644 src/ui/map/QGCMapWidget.cc delete mode 100644 src/ui/map/QGCMapWidget.h delete mode 100644 src/ui/map/Waypoint2DIcon.cc delete mode 100644 src/ui/map/Waypoint2DIcon.h delete mode 100644 src/ui/mapdisplay/MapDisplay.qml delete mode 100644 src/ui/mapdisplay/QGCMapDisplay.cc delete mode 100644 src/ui/mapdisplay/QGCMapDisplay.h delete mode 100644 src/ui/mission/QGCMissionConditionDelay.cc delete mode 100644 src/ui/mission/QGCMissionConditionDelay.h delete mode 100644 src/ui/mission/QGCMissionConditionDelay.ui delete mode 100644 src/ui/mission/QGCMissionDoFinishSearch.cc delete mode 100644 src/ui/mission/QGCMissionDoFinishSearch.h delete mode 100644 src/ui/mission/QGCMissionDoFinishSearch.ui delete mode 100644 src/ui/mission/QGCMissionDoJump.cc delete mode 100644 src/ui/mission/QGCMissionDoJump.h delete mode 100644 src/ui/mission/QGCMissionDoJump.ui delete mode 100644 src/ui/mission/QGCMissionDoStartSearch.cc delete mode 100644 src/ui/mission/QGCMissionDoStartSearch.h delete mode 100644 src/ui/mission/QGCMissionDoStartSearch.ui delete mode 100644 src/ui/mission/QGCMissionNavLand.cc delete mode 100644 src/ui/mission/QGCMissionNavLand.h delete mode 100644 src/ui/mission/QGCMissionNavLand.ui delete mode 100644 src/ui/mission/QGCMissionNavLoiterTime.cc delete mode 100644 src/ui/mission/QGCMissionNavLoiterTime.h delete mode 100644 src/ui/mission/QGCMissionNavLoiterTime.ui delete mode 100644 src/ui/mission/QGCMissionNavLoiterTurns.cc delete mode 100644 src/ui/mission/QGCMissionNavLoiterTurns.h delete mode 100644 src/ui/mission/QGCMissionNavLoiterTurns.ui delete mode 100644 src/ui/mission/QGCMissionNavLoiterUnlim.cc delete mode 100644 src/ui/mission/QGCMissionNavLoiterUnlim.h delete mode 100644 src/ui/mission/QGCMissionNavLoiterUnlim.ui delete mode 100644 src/ui/mission/QGCMissionNavReturnToLaunch.cc delete mode 100644 src/ui/mission/QGCMissionNavReturnToLaunch.h delete mode 100644 src/ui/mission/QGCMissionNavReturnToLaunch.ui delete mode 100644 src/ui/mission/QGCMissionNavSweep.cc delete mode 100644 src/ui/mission/QGCMissionNavSweep.h delete mode 100644 src/ui/mission/QGCMissionNavSweep.ui delete mode 100644 src/ui/mission/QGCMissionNavTakeoff.cc delete mode 100644 src/ui/mission/QGCMissionNavTakeoff.h delete mode 100644 src/ui/mission/QGCMissionNavTakeoff.ui delete mode 100644 src/ui/mission/QGCMissionNavWaypoint.cc delete mode 100644 src/ui/mission/QGCMissionNavWaypoint.h delete mode 100644 src/ui/mission/QGCMissionNavWaypoint.ui delete mode 100644 src/ui/mission/QGCMissionOther.cc delete mode 100644 src/ui/mission/QGCMissionOther.h delete mode 100644 src/ui/mission/QGCMissionOther.ui diff --git a/QGCApplication.pro b/QGCApplication.pro index 16dda5483..725204412 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -166,23 +166,8 @@ FORMS += \ src/ui/Linechart.ui \ src/ui/LogReplayLinkConfigurationWidget.ui \ src/ui/MainWindow.ui \ - src/ui/map/QGCMapTool.ui \ - src/ui/map/QGCMapToolBar.ui \ src/ui/mavlink/QGCMAVLinkMessageSender.ui \ src/ui/MAVLinkSettingsWidget.ui \ - src/ui/mission/QGCMissionConditionDelay.ui \ - src/ui/mission/QGCMissionDoFinishSearch.ui \ - src/ui/mission/QGCMissionDoJump.ui \ - src/ui/mission/QGCMissionDoStartSearch.ui \ - src/ui/mission/QGCMissionNavLand.ui \ - src/ui/mission/QGCMissionNavLoiterTime.ui \ - src/ui/mission/QGCMissionNavLoiterTurns.ui \ - src/ui/mission/QGCMissionNavLoiterUnlim.ui \ - src/ui/mission/QGCMissionNavReturnToLaunch.ui \ - src/ui/mission/QGCMissionNavSweep.ui \ - src/ui/mission/QGCMissionNavTakeoff.ui \ - src/ui/mission/QGCMissionNavWaypoint.ui \ - src/ui/mission/QGCMissionOther.ui \ src/ui/QGCCommConfiguration.ui \ src/ui/QGCDataPlot2D.ui \ src/ui/QGCLinkConfiguration.ui \ @@ -195,7 +180,6 @@ FORMS += \ src/ui/QGCUASFileView.ui \ src/ui/QGCUASFileViewMulti.ui \ src/ui/QGCUDPLinkConfiguration.ui \ - src/ui/QGCWaypointListMulti.ui \ src/ui/SettingsDialog.ui \ src/ui/uas/QGCUnconnectedInfoWidget.ui \ src/ui/uas/UASMessageView.ui \ @@ -203,9 +187,6 @@ FORMS += \ src/ui/uas/UASQuickViewItemSelect.ui \ src/ui/UASInfo.ui \ src/ui/UASRawStatusView.ui \ - src/ui/WaypointEditableView.ui \ - src/ui/WaypointList.ui \ - src/ui/WaypointViewOnlyView.ui \ !iOSBuild { FORMS += \ @@ -272,7 +253,6 @@ HEADERS += \ src/uas/UAS.h \ src/uas/UASInterface.h \ src/uas/UASMessageHandler.h \ - src/uas/UASWaypointManager.h \ src/ui/linechart/ChartPlot.h \ src/ui/linechart/IncrementalPlot.h \ src/ui/linechart/LinechartPlot.h \ @@ -283,27 +263,9 @@ HEADERS += \ src/ui/LogReplayLinkConfigurationWidget.h \ src/ui/MainWindow.h \ src/ui/map/MAV2DIcon.h \ - src/ui/map/QGCMapTool.h \ - src/ui/map/QGCMapToolBar.h \ - src/ui/map/QGCMapWidget.h \ - src/ui/map/Waypoint2DIcon.h \ - src/ui/mapdisplay/QGCMapDisplay.h \ src/ui/mavlink/QGCMAVLinkMessageSender.h \ src/ui/MAVLinkDecoder.h \ src/ui/MAVLinkSettingsWidget.h \ - src/ui/mission/QGCMissionConditionDelay.h \ - src/ui/mission/QGCMissionDoFinishSearch.h \ - src/ui/mission/QGCMissionDoJump.h \ - src/ui/mission/QGCMissionDoStartSearch.h \ - src/ui/mission/QGCMissionNavLand.h \ - src/ui/mission/QGCMissionNavLoiterTime.h \ - src/ui/mission/QGCMissionNavLoiterTurns.h \ - src/ui/mission/QGCMissionNavLoiterUnlim.h \ - src/ui/mission/QGCMissionNavReturnToLaunch.h \ - src/ui/mission/QGCMissionNavSweep.h \ - src/ui/mission/QGCMissionNavTakeoff.h \ - src/ui/mission/QGCMissionNavWaypoint.h \ - src/ui/mission/QGCMissionOther.h \ src/ui/QGCCommConfiguration.h \ src/ui/QGCDataPlot2D.h \ src/ui/QGCLinkConfiguration.h \ @@ -317,7 +279,6 @@ HEADERS += \ src/ui/QGCUASFileView.h \ src/ui/QGCUASFileViewMulti.h \ src/ui/QGCUDPLinkConfiguration.h \ - src/ui/QGCWaypointListMulti.h \ src/ui/SettingsDialog.h \ src/ui/toolbar/MainToolBar.h \ src/ui/uas/QGCUnconnectedInfoWidget.h \ @@ -329,9 +290,6 @@ HEADERS += \ src/ui/uas/UASQuickViewItemSelect.h \ src/ui/uas/UASQuickViewTextItem.h \ src/ui/UASRawStatusView.h \ - src/ui/WaypointEditableView.h \ - src/ui/WaypointList.h \ - src/ui/WaypointViewOnlyView.h \ src/ViewWidgets/CustomCommandWidget.h \ src/ViewWidgets/CustomCommandWidgetController.h \ src/ViewWidgets/ViewWidgetController.h \ @@ -401,7 +359,6 @@ SOURCES += \ src/uas/FileManager.cc \ src/uas/UAS.cc \ src/uas/UASMessageHandler.cc \ - src/uas/UASWaypointManager.cc \ src/ui/linechart/ChartPlot.cc \ src/ui/linechart/IncrementalPlot.cc \ src/ui/linechart/LinechartPlot.cc \ @@ -411,28 +368,9 @@ SOURCES += \ src/ui/linechart/ScrollZoomer.cc \ src/ui/LogReplayLinkConfigurationWidget.cc \ src/ui/MainWindow.cc \ - src/ui/map/MAV2DIcon.cc \ - src/ui/map/QGCMapTool.cc \ - src/ui/map/QGCMapToolBar.cc \ - src/ui/map/QGCMapWidget.cc \ - src/ui/map/Waypoint2DIcon.cc \ - src/ui/mapdisplay/QGCMapDisplay.cc \ src/ui/mavlink/QGCMAVLinkMessageSender.cc \ src/ui/MAVLinkDecoder.cc \ src/ui/MAVLinkSettingsWidget.cc \ - src/ui/mission/QGCMissionConditionDelay.cc \ - src/ui/mission/QGCMissionDoFinishSearch.cc \ - src/ui/mission/QGCMissionDoJump.cc \ - src/ui/mission/QGCMissionDoStartSearch.cc \ - src/ui/mission/QGCMissionNavLand.cc \ - src/ui/mission/QGCMissionNavLoiterTime.cc \ - src/ui/mission/QGCMissionNavLoiterTurns.cc \ - src/ui/mission/QGCMissionNavLoiterUnlim.cc \ - src/ui/mission/QGCMissionNavReturnToLaunch.cc \ - src/ui/mission/QGCMissionNavSweep.cc \ - src/ui/mission/QGCMissionNavTakeoff.cc \ - src/ui/mission/QGCMissionNavWaypoint.cc \ - src/ui/mission/QGCMissionOther.cc \ src/ui/QGCCommConfiguration.cc \ src/ui/QGCDataPlot2D.cc \ src/ui/QGCLinkConfiguration.cc \ @@ -446,7 +384,6 @@ SOURCES += \ src/ui/QGCUASFileView.cc \ src/ui/QGCUASFileViewMulti.cc \ src/ui/QGCUDPLinkConfiguration.cc \ - src/ui/QGCWaypointListMulti.cc \ src/ui/SettingsDialog.cc \ src/ui/toolbar/MainToolBar.cc \ src/ui/uas/QGCUnconnectedInfoWidget.cc \ @@ -458,9 +395,6 @@ SOURCES += \ src/ui/uas/UASQuickViewItemSelect.cc \ src/ui/uas/UASQuickViewTextItem.cc \ src/ui/UASRawStatusView.cpp \ - src/ui/WaypointEditableView.cc \ - src/ui/WaypointList.cc \ - src/ui/WaypointViewOnlyView.cc \ src/ViewWidgets/CustomCommandWidget.cc \ src/ViewWidgets/CustomCommandWidgetController.cc \ src/ViewWidgets/ViewWidgetController.cc \ diff --git a/QGCExternalLibs.pri b/QGCExternalLibs.pri index 0e73c3afd..e54883804 100644 --- a/QGCExternalLibs.pri +++ b/QGCExternalLibs.pri @@ -61,16 +61,6 @@ exists($$MAVLINKPATH/common) { INCLUDEPATH += libs/eigen DEFINES += NOMINMAX -# -# [REQUIRED] OPMapControl library from OpenPilot. Provides 2D mapping functionality. -# -include(libs/opmapcontrol/opmapcontrol_external.pri) - -INCLUDEPATH += \ - libs/utils \ - libs \ - libs/opmapcontrol - # # [REQUIRED] QWT plotting library dependency. Provides plotting capabilities. # diff --git a/libs/opmapcontrol/opmapcontrol.h b/libs/opmapcontrol/opmapcontrol.h deleted file mode 100644 index 4add132fd..000000000 --- a/libs/opmapcontrol/opmapcontrol.h +++ /dev/null @@ -1 +0,0 @@ -#include "src/mapwidget/opmapwidget.h" diff --git a/libs/opmapcontrol/opmapcontrol.pri b/libs/opmapcontrol/opmapcontrol.pri deleted file mode 100644 index 9c0188c30..000000000 --- a/libs/opmapcontrol/opmapcontrol.pri +++ /dev/null @@ -1 +0,0 @@ -LIBS *= -l$$qtLibraryTarget(opmapwidget) diff --git a/libs/opmapcontrol/opmapcontrol.pro b/libs/opmapcontrol/opmapcontrol.pro deleted file mode 100644 index dee478c28..000000000 --- a/libs/opmapcontrol/opmapcontrol.pro +++ /dev/null @@ -1,4 +0,0 @@ -TEMPLATE = subdirs - - -SUBDIRS = src \ diff --git a/libs/opmapcontrol/opmapcontrol_external.pri b/libs/opmapcontrol/opmapcontrol_external.pri deleted file mode 100644 index 3e4b6b804..000000000 --- a/libs/opmapcontrol/opmapcontrol_external.pri +++ /dev/null @@ -1,113 +0,0 @@ -###################################################################### -# Automatically generated by qmake (2.01a) Sa. Mrz 19 17:12:54 2011 -###################################################################### - -# HACK! BIG TIME! -DEFINES += EXTERNAL_USE - -DEPENDPATH += $$PWD/src/core $$PWD/src/internals $$PWD/src/mapwidget $$PWD/src/internals/projections -INCLUDEPATH += $$PWD/src/core $$PWD/src/internals $$PWD/src/internals/projections $$PWD/src/mapwidget - -# Input -HEADERS += $$PWD/opmapcontrol.h \ - $$PWD/src/core/accessmode.h \ - $$PWD/src/core/alllayersoftype.h \ - $$PWD/src/core/cache.h \ - $$PWD/src/core/cacheitemqueue.h \ - $$PWD/src/core/debugheader.h \ - $$PWD/src/core/diagnostics.h \ - $$PWD/src/core/geodecoderstatus.h \ - $$PWD/src/core/kibertilecache.h \ - $$PWD/src/core/languagetype.h \ - $$PWD/src/core/maptype.h \ - $$PWD/src/core/memorycache.h \ - $$PWD/src/core/opmaps.h \ - $$PWD/src/core/placemark.h \ - $$PWD/src/core/point.h \ - $$PWD/src/core/providerstrings.h \ - $$PWD/src/core/pureimage.h \ - $$PWD/src/core/pureimagecache.h \ - $$PWD/src/core/rawtile.h \ - $$PWD/src/core/size.h \ - $$PWD/src/core/tilecachequeue.h \ - $$PWD/src/core/urlfactory.h \ - $$PWD/src/internals/copyrightstrings.h \ - $$PWD/src/internals/core.h \ - $$PWD/src/internals/debugheader.h \ - $$PWD/src/internals/loadtask.h \ - $$PWD/src/internals/mousewheelzoomtype.h \ - $$PWD/src/internals/pointlatlng.h \ - $$PWD/src/internals/pureprojection.h \ - $$PWD/src/internals/rectangle.h \ - $$PWD/src/internals/rectlatlng.h \ - $$PWD/src/internals/sizelatlng.h \ - $$PWD/src/internals/tile.h \ - $$PWD/src/internals/tilematrix.h \ - $$PWD/src/mapwidget/configuration.h \ - $$PWD/src/mapwidget/gpsitem.h \ - $$PWD/src/mapwidget/homeitem.h \ - $$PWD/src/mapwidget/mapgraphicitem.h \ - $$PWD/src/mapwidget/mapripform.h \ - $$PWD/src/mapwidget/mapripper.h \ - $$PWD/src/mapwidget/opmapwidget.h \ - $$PWD/src/mapwidget/trailitem.h \ - $$PWD/src/mapwidget/traillineitem.h \ - $$PWD/src/mapwidget/uavitem.h \ - $$PWD/src/mapwidget/uavmapfollowtype.h \ - $$PWD/src/mapwidget/uavtrailtype.h \ - $$PWD/src/mapwidget/waypointitem.h \ - $$PWD/src/internals/projections/lks94projection.h \ - $$PWD/src/internals/projections/mercatorprojection.h \ - $$PWD/src/internals/projections/mercatorprojectionyandex.h \ - $$PWD/src/internals/projections/platecarreeprojection.h \ - $$PWD/src/internals/projections/platecarreeprojectionpergo.h \ - $$PWD/src/mapwidget/waypointlineitem.h - -FORMS += $$PWD/src/mapwidget/mapripform.ui - -SOURCES += $$PWD/src/core/alllayersoftype.cpp \ - $$PWD/src/core/cache.cpp \ - $$PWD/src/core/cacheitemqueue.cpp \ - $$PWD/src/core/diagnostics.cpp \ - $$PWD/src/core/kibertilecache.cpp \ - $$PWD/src/core/languagetype.cpp \ - $$PWD/src/core/memorycache.cpp \ - $$PWD/src/core/opmaps.cpp \ - $$PWD/src/core/placemark.cpp \ - $$PWD/src/core/point.cpp \ - $$PWD/src/core/providerstrings.cpp \ - $$PWD/src/core/pureimage.cpp \ - $$PWD/src/core/pureimagecache.cpp \ - $$PWD/src/core/rawtile.cpp \ - $$PWD/src/core/size.cpp \ - $$PWD/src/core/tilecachequeue.cpp \ - $$PWD/src/core/urlfactory.cpp \ - $$PWD/src/internals/core.cpp \ - $$PWD/src/internals/loadtask.cpp \ - $$PWD/src/internals/MouseWheelZoomType.cpp \ - $$PWD/src/internals/pointlatlng.cpp \ - $$PWD/src/internals/pureprojection.cpp \ - $$PWD/src/internals/rectangle.cpp \ - $$PWD/src/internals/rectlatlng.cpp \ - $$PWD/src/internals/sizelatlng.cpp \ - $$PWD/src/internals/tile.cpp \ - $$PWD/src/internals/tilematrix.cpp \ - $$PWD/src/mapwidget/configuration.cpp \ - $$PWD/src/mapwidget/gpsitem.cpp \ - $$PWD/src/mapwidget/homeitem.cpp \ - $$PWD/src/mapwidget/mapgraphicitem.cpp \ - $$PWD/src/mapwidget/mapripform.cpp \ - $$PWD/src/mapwidget/mapripper.cpp \ - $$PWD/src/mapwidget/opmapwidget.cpp \ - $$PWD/src/mapwidget/trailitem.cpp \ - $$PWD/src/mapwidget/traillineitem.cpp \ - $$PWD/src/mapwidget/uavitem.cpp \ - $$PWD/src/mapwidget/waypointitem.cpp \ - $$PWD/src/internals/projections/lks94projection.cpp \ - $$PWD/src/internals/projections/mercatorprojection.cpp \ - $$PWD/src/internals/projections/mercatorprojectionyandex.cpp \ - $$PWD/src/internals/projections/platecarreeprojection.cpp \ - $$PWD/src/internals/projections/platecarreeprojectionpergo.cpp \ - $$PWD/src/mapwidget/waypointlineitem.cpp - -RESOURCES += $$PWD/src/mapwidget/mapresources.qrc diff --git a/libs/opmapcontrol/src/common.pri b/libs/opmapcontrol/src/common.pri deleted file mode 100644 index a7889f5e8..000000000 --- a/libs/opmapcontrol/src/common.pri +++ /dev/null @@ -1,10 +0,0 @@ -DESTDIR = ../build - -QT += network -QT += sql -CONFIG += staticlib -TEMPLATE = lib -UI_DIR = uics -MOC_DIR = mocs -OBJECTS_DIR = objs -INCLUDEPATH +=../../../../libs/ diff --git a/libs/opmapcontrol/src/core/accessmode.h b/libs/opmapcontrol/src/core/accessmode.h deleted file mode 100644 index 3da564fa4..000000000 --- a/libs/opmapcontrol/src/core/accessmode.h +++ /dev/null @@ -1,86 +0,0 @@ -/** -****************************************************************************** -* -* @file accessmode.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef ACCESSMODE_H -#define ACCESSMODE_H - -#include "debugheader.h" -#include -#include -#include -#include -namespace core { - class AccessMode:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - /// - /// access only server - /// - ServerOnly, - - /// - /// access first server and caches localy - /// - ServerAndCache, - - /// - /// access only cache - /// - CacheOnly - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = AccessMode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = AccessMode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = AccessMode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;x AllLayersOfType::GetAllLayersOfType(const MapType::Types &type) - { - QVector types; - { - switch(type) - { - case MapType::GoogleHybrid: - { - - types.append(MapType::GoogleSatellite); - types.append(MapType::GoogleLabels); - } - break; - - case MapType::GoogleHybridChina: - { - types.append(MapType::GoogleSatelliteChina); - types.append(MapType::GoogleLabelsChina); - } - break; - - case MapType::GoogleHybridKorea: - { - types.append(MapType::GoogleSatelliteKorea); - types.append(MapType::GoogleLabelsKorea); - } - break; - - case MapType::YahooHybrid: - { - types.append(MapType::YahooSatellite); - types.append(MapType::YahooLabels); - } - break; - - case MapType::ArcGIS_MapsLT_Map_Hybrid: - { - types.append(MapType::ArcGIS_MapsLT_OrtoFoto); - types.append(MapType::ArcGIS_MapsLT_Map_Labels); - } - break; - - default: - { - types.append(type); - } - break; - } - } - - return types; - - } -} diff --git a/libs/opmapcontrol/src/core/alllayersoftype.h b/libs/opmapcontrol/src/core/alllayersoftype.h deleted file mode 100644 index 4d6c39f9a..000000000 --- a/libs/opmapcontrol/src/core/alllayersoftype.h +++ /dev/null @@ -1,43 +0,0 @@ -/** -****************************************************************************** -* -* @file alllayersoftype.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef ALLLAYERSOFTYPE_H -#define ALLLAYERSOFTYPE_H - -#include "maptype.h" -#include -#include - -namespace core { - class AllLayersOfType - { - public: - AllLayersOfType(); - QVector GetAllLayersOfType(const MapType::Types &type); - }; - -} -#endif // ALLLAYERSOFTYPE_H diff --git a/libs/opmapcontrol/src/core/cache.cpp b/libs/opmapcontrol/src/core/cache.cpp deleted file mode 100644 index 0a0066987..000000000 --- a/libs/opmapcontrol/src/core/cache.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/** -****************************************************************************** -* -* @file cache.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "cache.h" -#include - -namespace core { - Cache* Cache::m_pInstance=0; - - Cache* Cache::Instance() - { - if(!m_pInstance) - m_pInstance=new Cache; - return m_pInstance; - } - - void Cache::setCacheLocation(const QString& value) - { - cache=value; - routeCache = cache + "RouteCache/"; - geoCache = cache + "GeocoderCache/"; - placemarkCache = cache + "PlacemarkCache/"; - ImageCache.setGtileCache(value); - } - QString Cache::CacheLocation() - { - return cache; - } - Cache::Cache() - { - if(cache.isNull()|cache.isEmpty()) - { - cache = QDir::homePath() + "/mapscache/"; - setCacheLocation(cache); - } - } - QString Cache::GetGeocoderFromCache(const QString &urlEnd) - { -#ifdef DEBUG_GetGeocoderFromCache - qDebug()<<"Entered GetGeocoderFromCache"; -#endif - QString ret=QString::null; - QString filename=geoCache+QString(urlEnd)+".geo"; -#ifdef DEBUG_GetGeocoderFromCache - qDebug()<<"GetGeocoderFromCache: Does file exist?:"<>ret; - } - } -#ifdef DEBUG_GetGeocoderFromCache - qDebug()<<"GetGeocoderFromCache:Returning:"<>ret; - } - } -#ifdef DEBUG_CACHE - qDebug()<<"GetPlacemarkFromCache:Returning:"< - - - -namespace core { - class CacheItemQueue - { - public: - CacheItemQueue(const MapType::Types &Type,const core::Point &Pos,const QByteArray &Img,const int &Zoom); - CacheItemQueue(){}; - CacheItemQueue(const CacheItemQueue &cSource) - { - img=cSource.img; - pos=cSource.pos; - type=cSource.type; - zoom=cSource.zoom; - } - CacheItemQueue& operator= (const CacheItemQueue &cSource); - bool operator== (const CacheItemQueue &cSource); - void SetMapType(const MapType::Types &value); - void SetPosition(const core::Point &value); - void SetImg(const QByteArray &value); - MapType::Types GetMapType(); - core::Point GetPosition(); - QByteArray GetImg(); - int GetZoom(){return zoom;}; - void SetZoom(const int &value) {zoom=value;}; - private: - - - MapType::Types type; - core::Point pos; - QByteArray img; - int zoom; - }; - -} -#endif // CACHEITEMQUEUE_H diff --git a/libs/opmapcontrol/src/core/core.pro b/libs/opmapcontrol/src/core/core.pro deleted file mode 100644 index d606082a1..000000000 --- a/libs/opmapcontrol/src/core/core.pro +++ /dev/null @@ -1,40 +0,0 @@ -include (../common.pri) - -SOURCES += opmaps.cpp \ - pureimagecache.cpp \ - pureimage.cpp \ - rawtile.cpp \ - memorycache.cpp \ - cache.cpp \ - languagetype.cpp \ - providerstrings.cpp \ - cacheitemqueue.cpp \ - tilecachequeue.cpp \ - alllayersoftype.cpp \ - urlfactory.cpp \ - placemark.cpp \ - point.cpp \ - size.cpp \ - kibertilecache.cpp \ - diagnostics.cpp -HEADERS += opmaps.h \ - size.h \ - maptype.h \ - pureimagecache.h \ - pureimage.h \ - rawtile.h \ - memorycache.h \ - cache.h \ - accessmode.h \ - languagetype.h \ - providerstrings.h \ - cacheitemqueue.h \ - tilecachequeue.h \ - alllayersoftype.h \ - urlfactory.h \ - geodecoderstatus.h \ - placemark.h \ - point.h \ - kibertilecache.h \ - debugheader.h \ - diagnostics.h diff --git a/libs/opmapcontrol/src/core/debugheader.h b/libs/opmapcontrol/src/core/debugheader.h deleted file mode 100644 index 9b410c9c2..000000000 --- a/libs/opmapcontrol/src/core/debugheader.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef DEBUGHEADER_H -#define DEBUGHEADER_H - -//#define DEBUG_MEMORY_CACHE -//#define DEBUG_CACHE -//#define DEBUG_GMAPS -//#define DEBUG_PUREIMAGECACHE -//#define DEBUG_TILECACHEQUEUE -//#define DEBUG_URLFACTORY -//#define DEBUG_MEMORY_CACHE -//#define DEBUG_GetGeocoderFromCache - -#endif // DEBUGHEADER_H diff --git a/libs/opmapcontrol/src/core/diagnostics.cpp b/libs/opmapcontrol/src/core/diagnostics.cpp deleted file mode 100644 index 82220fe55..000000000 --- a/libs/opmapcontrol/src/core/diagnostics.cpp +++ /dev/null @@ -1,31 +0,0 @@ -/** -****************************************************************************** -* -* @file diagnostics.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "diagnostics.h" - -diagnostics::diagnostics():networkerrors(0),emptytiles(0),timeouts(0),runningThreads(0),tilesFromMem(0),tilesFromNet(0),tilesFromDB(0) -{ -} diff --git a/libs/opmapcontrol/src/core/diagnostics.h b/libs/opmapcontrol/src/core/diagnostics.h deleted file mode 100644 index febbb3a9d..000000000 --- a/libs/opmapcontrol/src/core/diagnostics.h +++ /dev/null @@ -1,47 +0,0 @@ -/** -****************************************************************************** -* -* @file diagnostics.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef DIAGNOSTICS_H -#define DIAGNOSTICS_H -#include -struct diagnostics -{ - diagnostics(); - int networkerrors; - int emptytiles; - int timeouts; - int runningThreads; - int tilesFromMem; - int tilesFromNet; - int tilesFromDB; - QString toString() - { - return QString("Network errors:%1\nEmpty Tiles:%2\nTimeOuts:%3\nRunningThreads:%4\nTilesFromMem:%5\nTilesFromNet:%6\nTilesFromDB:%7").arg(networkerrors).arg(emptytiles).arg(timeouts).arg(runningThreads).arg(tilesFromMem).arg(tilesFromNet).arg(tilesFromDB); - ; - } -}; - -#endif // DIAGNOSTICS_H diff --git a/libs/opmapcontrol/src/core/geodecoderstatus.h b/libs/opmapcontrol/src/core/geodecoderstatus.h deleted file mode 100644 index 6688aa841..000000000 --- a/libs/opmapcontrol/src/core/geodecoderstatus.h +++ /dev/null @@ -1,131 +0,0 @@ -/** -****************************************************************************** -* -* @file geodecoderstatus.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef GEODECODERSTATUS_H -#define GEODECODERSTATUS_H - -#include -#include -#include -#include -namespace core { - class GeoCoderStatusCode:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - /// - /// unknow response - /// - Unknow = -1, - - /// - /// No errors occurred; the address was successfully parsed and its geocode has been returned. - /// - G_GEO_SUCCESS=200, - - /// - /// A directions request could not be successfully parsed. - /// For example, the request may have been rejected if it contained more than the maximum number of waypoints allowed. - /// - G_GEO_BAD_REQUEST=400, - - /// - /// A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known. - /// - G_GEO_SERVER_ERROR=500, - - /// - /// The HTTP q parameter was either missing or had no value. - /// For geocoding requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input. - /// - G_GEO_MISSING_QUERY=601, - - /// - /// Synonym for G_GEO_MISSING_QUERY. - /// - G_GEO_MISSING_ADDRESS=601, - - /// - /// No corresponding geographic location could be found for the specified address. - /// This may be due to the fact that the address is relatively new, or it may be incorrect. - /// - G_GEO_UNKNOWN_ADDRESS=602, - - /// - /// The geocode for the given address or the route for the given directions query cannot be returned due to legal or contractual reasons. - /// - G_GEO_UNAVAILABLE_ADDRESS=603, - - /// - /// The GDirections object could not compute directions between the points mentioned in the query. - /// This is usually because there is no route available between the two points, or because we do not have data for routing in that region. - /// - G_GEO_UNKNOWN_DIRECTIONS=604, - - /// - /// The given key is either invalid or does not match the domain for which it was given. - /// - G_GEO_BAD_KEY=610, - - /// - /// The given key has gone over the requests limit in the 24 hour period or has submitted too many requests in too short a period of time. - /// If you're sending multiple requests in parallel or in a tight loop, use a timer or pause in your code to make sure you don't send the requests too quickly. - /// - G_GEO_TOO_MANY_QUERIES=620 - - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = GeoCoderStatusCode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = GeoCoderStatusCode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = GeoCoderStatusCode().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;xMemoryCacheCapacity()) - { - if(cachequeue.count()>0 && list.count()>0) - { -#ifdef DEBUG_MEMORY_CACHE - qDebug()<<"Cleaning Memory cache="<<" started with "< -#include -#include -#include -#include "debugheader.h" -namespace core { - class KiberTileCache - { - public: - KiberTileCache(); - - void setMemoryCacheCapacity(const int &value); - int MemoryCacheCapacity(); - double MemoryCacheSize(){return memoryCacheSize/1048576.0;} - void RemoveMemoryOverload(); - QReadWriteLock kiberCacheLock; - QHash cachequeue; - QQueue list; - long memoryCacheSize; - private: - int _MemoryCacheCapacity; - - }; - - - -} -#endif // KIBERTILECACHE_H diff --git a/libs/opmapcontrol/src/core/languagetype.cpp b/libs/opmapcontrol/src/core/languagetype.cpp deleted file mode 100644 index f1c8cfd39..000000000 --- a/libs/opmapcontrol/src/core/languagetype.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/** -****************************************************************************** -* -* @file languagetype.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "languagetype.h" - - - -namespace core { - LanguageType::LanguageType() - { - list - <<"ar" - <<"bg" - <<"bn" - <<"ca" - <<"cs" - <<"da" - <<"de" - <<"el" - <<"en" - <<"en-AU" - <<"en-GB" - <<"es" - <<"eu" - <<"fi" - <<"fil" - <<"fr" - <<"gl" - <<"gu" - <<"hi" - <<"hr" - <<"hu" - <<"id" - <<"it" - <<"iw" - <<"ja" - <<"kn" - <<"ko" - <<"lt" - <<"lv" - <<"ml" - <<"mr" - <<"nl" - <<"nn" - <<"no" - <<"or" - <<"pl" - <<"pt" - <<"pt-BR" - <<"pt-PT" - <<"rm" - <<"ro" - <<"ru" - <<"sk" - <<"sl" - <<"sr" - <<"sv" - <<"ta" - <<"te" - <<"th" - <<"tr" - <<"uk" - <<"vi" - <<"zh-CN" - <<"zh-TW"; - - } - QString LanguageType::toShortString(Types type) - { - return list[type]; - } - LanguageType::~LanguageType() - { - list.clear(); - } - -} diff --git a/libs/opmapcontrol/src/core/languagetype.h b/libs/opmapcontrol/src/core/languagetype.h deleted file mode 100644 index 4aaf88ce9..000000000 --- a/libs/opmapcontrol/src/core/languagetype.h +++ /dev/null @@ -1,133 +0,0 @@ -/** -****************************************************************************** -* -* @file languagetype.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef LANGUAGETYPE_H -#define LANGUAGETYPE_H - -#include -#include -#include -#include - - -namespace core { - class LanguageType:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - Arabic, - Bulgarian, - Bengali, - Catalan, - Czech, - Danish, - German, - Greek, - English, - EnglishAustralian, - EnglishGreatBritain, - Spanish, - Basque, - Finnish, - Filipino, - French, - Galician, - Gujarati, - Hindi, - Croatian, - Hungarian, - Indonesian, - Italian, - Hebrew, - Japanese, - Kannada, - Korean, - Lithuanian, - Latvian, - Malayalam, - Marathi, - Dutch, - NorwegianNynorsk, - Norwegian, - Oriya, - Polish, - Portuguese, - PortugueseBrazil, - PortuguesePortugal, - Romansch, - Romanian, - Russian, - Slovak, - Slovenian, - Serbian, - Swedish, - Tamil, - Telugu, - Thai, - Turkish, - Ukrainian, - Vietnamese, - ChineseSimplified, - ChineseTraditional - }; - - static QString StrByType(Types const& value) - { - QMetaObject metaObject = LanguageType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = LanguageType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = LanguageType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;x -#include -#include - -namespace core { - class MapType:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - GoogleMap=1, - GoogleSatellite=4, - GoogleLabels=8, - GoogleTerrain=16, - GoogleHybrid=20, - - GoogleMapChina=22, - GoogleSatelliteChina=24, - GoogleLabelsChina=26, - GoogleTerrainChina=28, - GoogleHybridChina=29, - - OpenStreetMap=32, - OpenStreetOsm=33, - OpenStreetMapSurfer=34, - OpenStreetMapSurferTerrain=35, - - YahooMap=64, - YahooSatellite=128, - YahooLabels=256, - YahooHybrid=333, - - BingMap=444, - BingSatellite=555, - BingHybrid=666, - - ArcGIS_Map=777, - ArcGIS_Satellite=788, - ArcGIS_ShadedRelief=799, - ArcGIS_Terrain=811, - - // use these numbers to clean up old stuff - //ArcGIS_MapsLT_Map_Old= 877, - //ArcGIS_MapsLT_OrtoFoto_Old = 888, - //ArcGIS_MapsLT_Map_Labels_Old = 890, - //ArcGIS_MapsLT_Map_Hybrid_Old = 899, - //ArcGIS_MapsLT_Map=977, - //ArcGIS_MapsLT_OrtoFoto=988, - //ArcGIS_MapsLT_Map_Labels=990, - //ArcGIS_MapsLT_Map_Hybrid=999, - //ArcGIS_MapsLT_Map=978, - //ArcGIS_MapsLT_OrtoFoto=989, - //ArcGIS_MapsLT_Map_Labels=991, - //ArcGIS_MapsLT_Map_Hybrid=998, - - ArcGIS_MapsLT_Map=1000, - ArcGIS_MapsLT_OrtoFoto=1001, - ArcGIS_MapsLT_Map_Labels=1002, - ArcGIS_MapsLT_Map_Hybrid=1003, - - PergoTurkeyMap = 2001, - SigPacSpainMap = 3001, - - GoogleMapKorea=4001, - GoogleSatelliteKorea=4002, - GoogleLabelsKorea=4003, - GoogleHybridKorea=4005, - - YandexMapRu = 5000 - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = MapType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = MapType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = MapType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;x -#include -#include -#include "kibertilecache.h" -#include -#include "debugheader.h" -namespace core { - class MemoryCache - { - public: - MemoryCache(); - - KiberTileCache TilesInMemory; - QByteArray GetTileFromMemoryCache(const RawTile &tile); - void AddTileToMemoryCache(const RawTile &tile, const QByteArray &pic); - QReadWriteLock kiberCacheLock; - }; - - -} -#endif // MEMORYCACHE_H diff --git a/libs/opmapcontrol/src/core/opmaps.cpp b/libs/opmapcontrol/src/core/opmaps.cpp deleted file mode 100644 index b2db6747d..000000000 --- a/libs/opmapcontrol/src/core/opmaps.cpp +++ /dev/null @@ -1,286 +0,0 @@ -/** -****************************************************************************** -* -* @file OPMaps.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "opmaps.h" - - -namespace core { - OPMaps* OPMaps::m_pInstance=0; - - OPMaps* OPMaps::Instance() - { - if(!m_pInstance) - m_pInstance=new OPMaps; - return m_pInstance; - } - OPMaps::OPMaps():RetryLoadTile(2),useMemoryCache(true) - { - accessmode=AccessMode::ServerAndCache; - Language=LanguageType::PortuguesePortugal; - LanguageStr=LanguageType().toShortString(Language); - Cache::Instance(); - - } - - - OPMaps::~OPMaps() - { - TileDBcacheQueue.wait(); - } - - - - QByteArray OPMaps::GetImageFrom(const MapType::Types &type,const Point &pos,const int &zoom) - { -#ifdef DEBUG_TIMINGS - QTime time; - time.restart(); -#endif -#ifdef DEBUG_GMAPS - qDebug()<<"Entered GetImageFrom"; -#endif //DEBUG_GMAPS - QByteArray ret; - - if(useMemoryCache) - { -#ifdef DEBUG_GMAPS - qDebug()<<"Try Tile from memory:Size="<ImageCache.GetImageFromCache(type,pos,zoom); - if(!ret.isEmpty()) - { - errorvars.lock(); - ++diag.tilesFromDB; - errorvars.unlock(); -#ifdef DEBUG_GMAPS - qDebug()<<"Tile found in Database"; -#endif //DEBUG_GMAPS - if(useMemoryCache) - { -#ifdef DEBUG_GMAPS - qDebug()<<"Add Tile to memory"; -#endif //DEBUG_GMAPS - AddTileToMemoryCache(RawTile(type,pos,zoom),ret); - } - return ret; - } - } - if(accessmode!=AccessMode::CacheOnly) - { - QEventLoop q; - QNetworkReply *reply; - QNetworkRequest qheader; - QNetworkAccessManager network; - QTimer tT; - tT.setSingleShot(true); - connect(&network, SIGNAL(finished(QNetworkReply*)), - &q, SLOT(quit())); - connect(&tT, SIGNAL(timeout()), &q, SLOT(quit())); - network.setProxy(Proxy); -#ifdef DEBUG_GMAPS - qDebug()<<"Try Tile from the Internet"; -#endif //DEBUG_GMAPS -#ifdef DEBUG_TIMINGS - qDebug()<<"opmaps before make image url"<error()!=QNetworkReply::NoError)) - { - errorvars.lock(); - ++diag.networkerrors; - errorvars.unlock(); - reply->deleteLater(); - return ret; - } - ret=reply->readAll(); - reply->deleteLater();//TODO can't this be global?? - if(ret.isEmpty()) - { -#ifdef DEBUG_GMAPS - qDebug()<<"Invalid Tile"; -#endif //DEBUG_GMAPS - errorvars.lock(); - ++diag.emptytiles; - errorvars.unlock(); - return ret; - } -#ifdef DEBUG_GMAPS - qDebug()<<"Received Tile from the Internet"; -#endif //DEBUG_GMAPS - errorvars.lock(); - ++diag.tilesFromNet; - errorvars.unlock(); - if (useMemoryCache) - { -#ifdef DEBUG_GMAPS - qDebug()<<"Add Tile to memory cache"; -#endif //DEBUG_GMAPS - AddTileToMemoryCache(RawTile(type,pos,zoom),ret); - } - if(accessmode!=AccessMode::ServerOnly) - { -#ifdef DEBUG_GMAPS - qDebug()<<"Add tile to DataBase"; -#endif //DEBUG_GMAPS - CacheItemQueue * item=new CacheItemQueue(type,pos,ret,zoom); - TileDBcacheQueue.EnqueueCacheTask(item); - } - - - } - } -#ifdef DEBUG_GMAPS - qDebug()<<"Entered GetImageFrom"; -#endif //DEBUG_GMAPS - return ret; - } - - bool OPMaps::ExportToGMDB(const QString &file) - { - return Cache::Instance()->ImageCache.ExportMapDataToDB(Cache::Instance()->ImageCache.GtileCache()+QDir::separator()+"Data.qmdb",file); - } - bool OPMaps::ImportFromGMDB(const QString &file) - { - return Cache::Instance()->ImageCache.ExportMapDataToDB(file,Cache::Instance()->ImageCache.GtileCache()+QDir::separator()+"Data.qmdb"); - } - - diagnostics OPMaps::GetDiagnostics() - { - diagnostics i; - errorvars.lock(); - i=diag; - errorvars.unlock(); - return i; - } -} - diff --git a/libs/opmapcontrol/src/core/opmaps.h b/libs/opmapcontrol/src/core/opmaps.h deleted file mode 100644 index 723f967f4..000000000 --- a/libs/opmapcontrol/src/core/opmaps.h +++ /dev/null @@ -1,94 +0,0 @@ -/** -****************************************************************************** -* -* @file OPMaps.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef OPMaps_H -#define OPMaps_H - - -#include "debugheader.h" -#include "memorycache.h" -#include "rawtile.h" -#include "cache.h" -#include "accessmode.h" -#include "languagetype.h" -#include "cacheitemqueue.h" -#include "tilecachequeue.h" -#include "pureimagecache.h" -#include "alllayersoftype.h" -#include "urlfactory.h" -#include "diagnostics.h" - -//#include "point.h" - - -namespace core { - class OPMaps: public MemoryCache,public AllLayersOfType,public UrlFactory - { - - - public: - - ~OPMaps(); - - static OPMaps* Instance(); - bool ImportFromGMDB(const QString &file); - bool ExportToGMDB(const QString &file); - /// - /// timeout for map connections - /// - - - QByteArray GetImageFrom(const MapType::Types &type,const core::Point &pos,const int &zoom); - bool UseMemoryCache(){return useMemoryCache;}//TODO - void setUseMemoryCache(const bool& value){useMemoryCache=value;} - void setLanguage(const LanguageType::Types& language){Language=language;}//TODO - LanguageType::Types GetLanguage(){return Language;}//TODO - AccessMode::Types GetAccessMode()const{return accessmode;} - void setAccessMode(const AccessMode::Types& mode){accessmode=mode;} - int RetryLoadTile; - diagnostics GetDiagnostics(); - - private: - bool useMemoryCache; - LanguageType::Types Language; - AccessMode::Types accessmode; - // PureImageCache ImageCacheLocal;//TODO Criar acesso Get Set - TileCacheQueue TileDBcacheQueue; - OPMaps(); - //OPMaps(OPMaps const&){} - OPMaps& operator=(OPMaps const&){ return *this; } - static OPMaps* m_pInstance; - diagnostics diag; - QMutex errorvars; - protected: - // MemoryCache TilesInMemory; - - - - }; - -} -#endif // OPMaps_H diff --git a/libs/opmapcontrol/src/core/placemark.cpp b/libs/opmapcontrol/src/core/placemark.cpp deleted file mode 100644 index 3a4827095..000000000 --- a/libs/opmapcontrol/src/core/placemark.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/** -****************************************************************************** -* -* @file placemark.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "placemark.h" - diff --git a/libs/opmapcontrol/src/core/placemark.h b/libs/opmapcontrol/src/core/placemark.h deleted file mode 100644 index 2b197edc5..000000000 --- a/libs/opmapcontrol/src/core/placemark.h +++ /dev/null @@ -1,54 +0,0 @@ -/** -****************************************************************************** -* -* @file placemark.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PLACEMARK_H -#define PLACEMARK_H - -#include - - -namespace core { - class Placemark - { - public: - Placemark(const QString &address) - { - this->address = address; - } - QString Address(){return address;} - int Accuracy(){return accuracy;} - void SetAddress(const QString &adr){address=adr;} - void SetAccuracy(const int &value){accuracy=value;} - private: - - QString address; - int accuracy; - protected: - - - }; -} -#endif // PLACEMARK_H diff --git a/libs/opmapcontrol/src/core/point.cpp b/libs/opmapcontrol/src/core/point.cpp deleted file mode 100644 index fd12396f4..000000000 --- a/libs/opmapcontrol/src/core/point.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/** -****************************************************************************** -* -* @file point.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "point.h" -#include "size.h" - -namespace core { - Point::Point(int dw) - { - this->x=(short)Point::loWord(dw); - this->y=(short)Point::hiWord(dw); - empty=false; - } - Point::Point(Size sz) - { - this->x=sz.Width(); - this->y=sz.Height(); - empty=false; - } - Point::Point(int x, int y) - { - this->x=x; - this->y=y; - empty=false; - } - Point::Point():x(0),y(0),empty(true) - {} - uint qHash(Point const& point) - { - return point.x^point.y; - } - bool operator==(Point const &lhs,Point const &rhs) - { - return (lhs.x==rhs.x && lhs.y==rhs.y); - } - bool operator!=(Point const &lhs,Point const &rhs) - { - return !(lhs==rhs); - } - Point Point::Empty=Point(); - -} diff --git a/libs/opmapcontrol/src/core/point.h b/libs/opmapcontrol/src/core/point.h deleted file mode 100644 index b28146043..000000000 --- a/libs/opmapcontrol/src/core/point.h +++ /dev/null @@ -1,78 +0,0 @@ -/** -****************************************************************************** -* -* @file point.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef OPOINT_H -#define OPOINT_H - -#include - -namespace core { - struct Size; - struct Point - { - friend uint qHash(Point const& point); - friend bool operator==(Point const& lhs,Point const& rhs); - friend bool operator!=(Point const& lhs,Point const& rhs); - public: - - Point(); - Point(int x,int y); - Point(Size sz); - Point(int dw); - bool IsEmpty(){return empty;} - int X()const{return this->x;} - int Y()const{return this->y;} - void SetX(const int &value){x=value;empty=false;} - void SetY(const int &value){y=value;empty=false;} - QString ToString()const{return "{"+QString::number(x)+","+QString::number(y)+"}";} - - static Point Empty; - void Offset(const int &dx,const int &dy) - { - x += dx; - y += dy; - } - void Offset(Point p) - { - Offset(p.x, p.y); - } - static int hiWord(int n) - { - return (n >> 16) & 0xffff; - } - - static int loWord(int n) - { - return n & 0xffff; - } - - private: - int x; - int y; - bool empty; - }; -} -#endif // POINT_H diff --git a/libs/opmapcontrol/src/core/providerstrings.cpp b/libs/opmapcontrol/src/core/providerstrings.cpp deleted file mode 100644 index 4242a2a76..000000000 --- a/libs/opmapcontrol/src/core/providerstrings.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/** -****************************************************************************** -* -* @file providerstrings.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "providerstrings.h" - - -namespace core { - const QString ProviderStrings::levelsForSigPacSpainMap[] = {"0", "1", "2", "3", "4", - "MTNSIGPAC", - "MTN2000", "MTN2000", "MTN2000", "MTN2000", "MTN2000", - "MTN200", "MTN200", "MTN200", - "MTN25", "MTN25", - "ORTOFOTOS","ORTOFOTOS","ORTOFOTOS","ORTOFOTOS"}; - - ProviderStrings::ProviderStrings() - { -// VersionGoogleMap = "m@132"; -// VersionGoogleSatellite = "71"; -// VersionGoogleLabels = "h@132"; -// VersionGoogleTerrain = "t@125,r@132"; - // Google version strings - VersionGoogleMap = "m@132"; - VersionGoogleSatellite = "71"; - VersionGoogleLabels = "h@132"; - VersionGoogleTerrain = "t@125,r@132"; - SecGoogleWord = "Galileo"; - - // Google (China) version strings - VersionGoogleMapChina = "m@132"; - VersionGoogleSatelliteChina = "s@71"; - VersionGoogleLabelsChina = "h@132"; - VersionGoogleTerrainChina = "t@125,r@132"; - - // Google (Korea) version strings - VersionGoogleMapKorea = "kr1.12"; - VersionGoogleSatelliteKorea = "66"; - VersionGoogleLabelsKorea = "kr1t.12"; - - /// - /// Google Maps API generated using http://greatmaps.codeplex.com/ - /// from http://code.google.com/intl/en-us/apis/maps/signup.html - /// - GoogleMapsAPIKey = "ABQIAAAA5Q6wxQ6lxKS8haLVdUJaqhSjosg_0jiTTs2iXtkDVG0n0If1mBRHzhWw5VqBZX-j4NuzoVpU-UaHVg"; - - // Yahoo version strings - VersionYahooMap = "4.3"; - VersionYahooSatellite = "1.9"; - VersionYahooLabels = "4.3"; - - // BingMaps - VersionBingMaps = "563"; - - // YandexMap - VersionYandexMap = "2.16.0"; - //VersionYandexSatellite = "1.19.0"; - //////////////////// - - /// - /// Bing Maps Customer Identification, more info here - /// http://msdn.microsoft.com/en-us/library/bb924353.aspx - /// - BingMapsClientToken = ""; - - } -} diff --git a/libs/opmapcontrol/src/core/providerstrings.h b/libs/opmapcontrol/src/core/providerstrings.h deleted file mode 100644 index be66a3b86..000000000 --- a/libs/opmapcontrol/src/core/providerstrings.h +++ /dev/null @@ -1,85 +0,0 @@ -/** -****************************************************************************** -* -* @file providerstrings.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PROVIDERSTRINGS_H -#define PROVIDERSTRINGS_H - -#include - - -namespace core { - class ProviderStrings - { - public: - ProviderStrings(); - static const QString levelsForSigPacSpainMap[]; - QString GoogleMapsAPIKey; - // Google version strings - QString VersionGoogleMap; - QString VersionGoogleSatellite; - QString VersionGoogleLabels; - QString VersionGoogleTerrain; - QString SecGoogleWord; - - // Google (China) version strings - QString VersionGoogleMapChina; - QString VersionGoogleSatelliteChina; - QString VersionGoogleLabelsChina; - QString VersionGoogleTerrainChina; - - // Google (Korea) version strings - QString VersionGoogleMapKorea; - QString VersionGoogleSatelliteKorea; - QString VersionGoogleLabelsKorea; - - /// - /// Google Maps API generated using http://greatmaps.codeplex.com/ - /// from http://code.google.com/intl/en-us/apis/maps/signup.html - /// - - - // Yahoo version strings - QString VersionYahooMap; - QString VersionYahooSatellite; - QString VersionYahooLabels; - - // BingMaps - QString VersionBingMaps; - - // YandexMap - QString VersionYandexMap; - - - - /// - /// Bing Maps Customer Identification, more info here - /// http://msdn.microsoft.com/en-us/library/bb924353.aspx - /// - QString BingMapsClientToken; - }; - -} -#endif // PROVIDERSTRINGS_H diff --git a/libs/opmapcontrol/src/core/pureimage.cpp b/libs/opmapcontrol/src/core/pureimage.cpp deleted file mode 100644 index d47b30d12..000000000 --- a/libs/opmapcontrol/src/core/pureimage.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** -****************************************************************************** -* -* @file pureimage.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "pureimage.h" - - - -namespace core { -PureImageProxy::PureImageProxy() -{ - -} - -QPixmap PureImageProxy::FromStream(const QByteArray &array) -{ - return QPixmap::fromImage(QImage::fromData(array)); -} -bool PureImageProxy::Save(const QByteArray &array, QPixmap &pic) -{ - pic=QPixmap::fromImage(QImage::fromData(array)); - return true; -} -} diff --git a/libs/opmapcontrol/src/core/pureimage.h b/libs/opmapcontrol/src/core/pureimage.h deleted file mode 100644 index 22a5c0d65..000000000 --- a/libs/opmapcontrol/src/core/pureimage.h +++ /dev/null @@ -1,44 +0,0 @@ -/** -****************************************************************************** -* -* @file pureimage.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PUREIMAGE_H -#define PUREIMAGE_H - -#include -#include - - -namespace core { - class PureImageProxy - { - public: - PureImageProxy(); - static QPixmap FromStream(const QByteArray &array); - static bool Save(const QByteArray &array,QPixmap &pic); - }; - -} -#endif // PUREIMAGE_H diff --git a/libs/opmapcontrol/src/core/pureimagecache.cpp b/libs/opmapcontrol/src/core/pureimagecache.cpp deleted file mode 100644 index 9cdd0cdd0..000000000 --- a/libs/opmapcontrol/src/core/pureimagecache.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/** -****************************************************************************** -* -* @file pureimagecache.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "pureimagecache.h" -#include -#include -//#define DEBUG_PUREIMAGECACHE -namespace core { - static QMutex addDatabaseMutex; // QSqlDatabase::addDatabase is not thread safe when loadingn plugins - - qlonglong PureImageCache::ConnCounter=0; - - PureImageCache::PureImageCache() - { - - } - - void PureImageCache::setGtileCache(const QString &value) - { - lock.lockForWrite(); - gtilecache=value; - QDir d; - if(!d.exists(gtilecache)) - { - d.mkdir(gtilecache); -#ifdef DEBUG_PUREIMAGECACHE - qDebug()<<"Create Cache directory"; -#endif //DEBUG_PUREIMAGECACHE - } - { - QString db=gtilecache+"Data.qmdb"; - if(!QFileInfo(db).exists()) - { -#ifdef DEBUG_PUREIMAGECACHE - qDebug()<<"Try to create EmptyDB"; -#endif //DEBUG_PUREIMAGECACHE - CreateEmptyDB(db); - } - } - lock.unlock(); - } - QString PureImageCache::GtileCache() - { - return gtilecache; - } - - - bool PureImageCache::CreateEmptyDB(const QString &file) - { -#ifdef DEBUG_PUREIMAGECACHE - qDebug()<<"Create database at!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!:"< add; - bool ret=true; - QString dir=gtilecache; - { - QString db=dir+"Data.qmdb"; - ret=QFileInfo(db).exists(); - if(ret) - { - Mcounter.lock(); - qlonglong id=++ConnCounter; - Mcounter.unlock(); - addDatabaseMutex.lock(); - QSqlDatabase cn(QSqlDatabase::addDatabase("QSQLITE",QString::number(id))); - addDatabaseMutex.unlock(); - cn.setDatabaseName(db); - cn.setConnectOptions("QSQLITE_ENABLE_SHARED_CACHE"); - if(cn.open()) - { - { - QSqlQuery query(cn); - query.exec(QString("SELECT id, X, Y, Zoom, Type, Date FROM Tiles")); - while(query.next()) - { - if(QDateTime::fromString(query.value(5).toString()).daysTo(QDateTime::currentDateTime())>days) - add.append(query.value(0).toLongLong()); - } - foreach(long i,add) - { - query.exec(QString("DELETE FROM Tiles WHERE id = %1;").arg(i)); - } - } - - cn.close(); - } - QSqlDatabase::removeDatabase(QString::number(id)); - } - } - } - // PureImageCache::ExportMapDataToDB("C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data.qmdb","C:/Users/Xapo/Documents/mapcontrol/debug/mapscache/data2.qmdb"); - bool PureImageCache::ExportMapDataToDB(QString sourceFile, QString destFile) - { - bool ret=true; - QList add; - if(!QFileInfo(destFile).exists()) - { -#ifdef DEBUG_PUREIMAGECACHE - qDebug()<<"Try to create EmptyDB"; -#endif //DEBUG_PUREIMAGECACHE - ret=CreateEmptyDB(destFile); - } - if(!ret) return false; - addDatabaseMutex.lock(); - QSqlDatabase ca(QSqlDatabase::addDatabase("QSQLITE","ca")); - addDatabaseMutex.unlock(); - ca.setDatabaseName(sourceFile); - - if(ca.open()) - { - addDatabaseMutex.lock(); - QSqlDatabase cb(QSqlDatabase::addDatabase("QSQLITE","cb")); - addDatabaseMutex.unlock(); - cb.setDatabaseName(destFile); - if(cb.open()) - { - QSqlQuery queryb(cb); - queryb.exec(QString("ATTACH DATABASE \"%1\" AS Source").arg(sourceFile)); - QSqlQuery querya(ca); - querya.exec("SELECT id, X, Y, Zoom, Type, Date FROM Tiles"); - while(querya.next()) - { - long id=querya.value(0).toLongLong(); - queryb.exec(QString("SELECT id FROM Tiles WHERE X=%1 AND Y=%2 AND Zoom=%3 AND Type=%4;").arg(querya.value(1).toLongLong()).arg(querya.value(2).toLongLong()).arg(querya.value(3).toLongLong()).arg(querya.value(4).toLongLong())); - if(!queryb.next()) - { - add.append(id); - } - - } - long f; - foreach(f,add) - { - queryb.exec(QString("INSERT INTO Tiles(X, Y, Zoom, Type, Date) SELECT X, Y, Zoom, Type, Date FROM Source.Tiles WHERE id=%1").arg(f)); - queryb.exec(QString("INSERT INTO TilesData(id, Tile) Values((SELECT last_insert_rowid()), (SELECT Tile FROM Source.TilesData WHERE id=%1))").arg(f)); - } - add.clear(); - ca.close(); - cb.close(); - - } - else return false; - } - else return false; - QSqlDatabase::removeDatabase("ca"); - QSqlDatabase::removeDatabase("cb"); - return true; - - } - -} diff --git a/libs/opmapcontrol/src/core/pureimagecache.h b/libs/opmapcontrol/src/core/pureimagecache.h deleted file mode 100644 index 7d8942b31..000000000 --- a/libs/opmapcontrol/src/core/pureimagecache.h +++ /dev/null @@ -1,67 +0,0 @@ -/** -****************************************************************************** -* -* @file pureimagecache.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PUREIMAGECACHE_H -#define PUREIMAGECACHE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include "maptype.h" -#include "point.h" -#include -#include "pureimage.h" -#include -#include -#include -namespace core { - class PureImageCache - { - - public: - PureImageCache(); - static bool CreateEmptyDB(const QString &file); - bool PutImageToCache(const QByteArray &tile,const MapType::Types &type,const core::Point &pos, const int &zoom); - QByteArray GetImageFromCache(MapType::Types type, core::Point pos, int zoom); - QString GtileCache(); - void setGtileCache(const QString &value); - static bool ExportMapDataToDB(QString sourceFile, QString destFile); - void deleteOlderTiles(int const& days); - private: - QString gtilecache; - QMutex Mcounter; - QReadWriteLock lock; - static qlonglong ConnCounter; - - }; - -} -#endif // PUREIMAGECACHE_H diff --git a/libs/opmapcontrol/src/core/rawtile.cpp b/libs/opmapcontrol/src/core/rawtile.cpp deleted file mode 100644 index 570140b0a..000000000 --- a/libs/opmapcontrol/src/core/rawtile.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/** -****************************************************************************** -* -* @file rawtile.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "rawtile.h" - - -namespace core { -RawTile::RawTile(const MapType::Types &Type, const Point &Pos, const int &Zoom) -{ - zoom=Zoom; - type=Type; - pos=Pos; -} -QString RawTile::ToString() -{ - return QString("%1 at zoom %2, pos:%3,%4").arg(type).arg(zoom).arg(pos.X()).arg(pos.Y()); -} -Point RawTile::Pos() -{ - return pos; -} -MapType::Types RawTile::Type() -{ - return type; -} -int RawTile::Zoom() -{ - return zoom; -} -void RawTile::setType(const MapType::Types &value) -{ - type=value; -} -void RawTile::setPos(const Point &value) -{ - pos=value; -} -void RawTile::setZoom(const int &value) -{ - zoom=value; -} -uint qHash(RawTile const& tile) -{ - // RawTile tile=tilee; - quint64 tmp=(((quint64)(tile.zoom))<<54)+(((quint64)(tile.type))<<36)+(((quint64)(tile.pos.X()))<<18)+(((quint64)(tile.pos.Y()))); - // quint64 tmp5=tmp+tmp2+tmp3+tmp4; - return ::qHash(tmp); -} -bool operator==(RawTile const &lhs,RawTile const &rhs) -{ - return (lhs.pos==rhs.pos && lhs.zoom==rhs.zoom && lhs.type==rhs.type); -} -} diff --git a/libs/opmapcontrol/src/core/rawtile.h b/libs/opmapcontrol/src/core/rawtile.h deleted file mode 100644 index 1eba2be79..000000000 --- a/libs/opmapcontrol/src/core/rawtile.h +++ /dev/null @@ -1,56 +0,0 @@ -/** -****************************************************************************** -* -* @file rawtile.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef RAWTILE_H -#define RAWTILE_H - -#include "maptype.h" -#include "point.h" -#include -#include - -namespace core { - class RawTile - { - friend uint qHash(RawTile const& tile); - friend bool operator==(RawTile const& lhs,RawTile const& rhs); - - public: - RawTile(const MapType::Types &Type,const core::Point &Pos,const int &Zoom); - QString ToString(void); - MapType::Types Type(); - core::Point Pos(); - int Zoom(); - void setType(const MapType::Types &value); - void setPos(const core::Point &value); - void setZoom(const int &value); - private: - MapType::Types type; - core::Point pos; - int zoom; - }; -} -#endif // RAWTILE_H diff --git a/libs/opmapcontrol/src/core/size.cpp b/libs/opmapcontrol/src/core/size.cpp deleted file mode 100644 index 536900213..000000000 --- a/libs/opmapcontrol/src/core/size.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/** -****************************************************************************** -* -* @file size.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "size.h" - - -namespace core { -Size::Size():width(0),height(0) -{} -} diff --git a/libs/opmapcontrol/src/core/size.h b/libs/opmapcontrol/src/core/size.h deleted file mode 100644 index 276e148ea..000000000 --- a/libs/opmapcontrol/src/core/size.h +++ /dev/null @@ -1,58 +0,0 @@ -/** -****************************************************************************** -* -* @file size.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef SIZE_H -#define SIZE_H - -#include "point.h" -#include -#include - -namespace core { - struct Size - { - - Size(); - Size(Point pt){width=pt.X(); height=pt.Y();}; - Size(int Width,int Height){width=Width; height=Height;}; - friend uint qHash(Size const& size); - // friend bool operator==(Size const& lhs,Size const& rhs); - Size operator-(const Size &sz1){return Size(width-sz1.width,height-sz1.height);} - Size operator+(const Size &sz1){return Size(sz1.width+width,sz1.height+height);} - - int GetHashCode(){return width^height;} - uint qHash(Size const& /*rect*/){return width^height;} - QString ToString(){return "With="+QString::number(width)+" ,Height="+QString::number(height);} - int Width()const {return width;} - int Height()const {return height;} - void SetWidth(int const& value){width=value;} - void SetHeight(int const& value){height=value;} - private: - int width; - int height; - }; -} -#endif // SIZE_H diff --git a/libs/opmapcontrol/src/core/tilecachequeue.cpp b/libs/opmapcontrol/src/core/tilecachequeue.cpp deleted file mode 100644 index d50755d8e..000000000 --- a/libs/opmapcontrol/src/core/tilecachequeue.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** -****************************************************************************** -* -* @file tilecachequeue.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "tilecachequeue.h" - - -//#define DEBUG_TILECACHEQUEUE - -#ifndef DEBUG_TILECACHEQUEUE -#undef qDebug -#define qDebug QT_NO_QDEBUG_MACRO -#endif - -namespace core { -TileCacheQueue::TileCacheQueue() -{ - -} - -TileCacheQueue::~TileCacheQueue() -{ - quit(); - _waitc.wakeAll(); - wait(); - this->deleteLater(); -} - -void TileCacheQueue::EnqueueCacheTask(CacheItemQueue *task) -{ - qDebug()<<"DB Do I EnqueueCacheTask"<GetPosition().X()<<","<GetPosition().Y(); - if(!_tileCacheQueue.contains(task)) { - qDebug()<<"EnqueueCacheTask"<GetPosition().X()<<","<GetPosition().Y(); - _mutex.lock(); - _tileCacheQueue.enqueue(task); - _mutex.unlock(); - if(this->isRunning()) { - qDebug()<<"Wake Thread"; - _waitc.wakeAll(); - } else { - qDebug()<<"Start Thread"; - this->start(QThread::NormalPriority); - } - } - -} -void TileCacheQueue::run() -{ - qDebug()<<"Cache Engine Start"; - while(true) { - CacheItemQueue *task = NULL; - qDebug() << "Cache"; - if(_tileCacheQueue.count() > 0) { - _mutex.lock(); - task = _tileCacheQueue.dequeue(); - _mutex.unlock(); - Q_ASSERT(task); - qDebug() << "Cache engine Put:" << task->GetPosition().X() << "," << task->GetPosition().Y(); - Cache* cache = Cache::Instance(); - if(cache) { - cache->ImageCache.PutImageToCache(task->GetImg(), task->GetMapType(), task->GetPosition(), task->GetZoom()); - } - usleep(44); - delete task; - } else { - qDebug() << "Cache engine BEGIN WAIT"; - _waitmutex.lock(); - _waitc.wait(&_waitmutex); - qDebug() << "Cache engine WOKE UP"; - if(!this->isRunning()) { - _waitmutex.unlock(); - break; - } - _waitmutex.unlock(); - } - } - qDebug() << "Cache Engine Stopped"; -} - -} diff --git a/libs/opmapcontrol/src/core/tilecachequeue.h b/libs/opmapcontrol/src/core/tilecachequeue.h deleted file mode 100644 index 45230a386..000000000 --- a/libs/opmapcontrol/src/core/tilecachequeue.h +++ /dev/null @@ -1,57 +0,0 @@ -/** -****************************************************************************** -* -* @file tilecachequeue.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef TILECACHEQUEUE_H -#define TILECACHEQUEUE_H - -#include -#include "cacheitemqueue.h" -#include -#include -#include -#include -#include -#include "pureimagecache.h" -#include "cache.h" - -namespace core { - class TileCacheQueue:public QThread - { - Q_OBJECT - public: - TileCacheQueue(); - ~TileCacheQueue(); - void EnqueueCacheTask(CacheItemQueue *task); - - private: - void run(); - QMutex _mutex; - QMutex _waitmutex; - QWaitCondition _waitc; - QQueue _tileCacheQueue; - }; -} -#endif // TILECACHEQUEUE_H diff --git a/libs/opmapcontrol/src/core/urlfactory.cpp b/libs/opmapcontrol/src/core/urlfactory.cpp deleted file mode 100644 index 6dd8cad66..000000000 --- a/libs/opmapcontrol/src/core/urlfactory.cpp +++ /dev/null @@ -1,707 +0,0 @@ -/** -****************************************************************************** -* -* @file urlfactory.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "urlfactory.h" -#include -#include - -namespace core { - - const double UrlFactory::EarthRadiusKm = 6378.137; // WGS-84 - - UrlFactory::UrlFactory() - { - /// - /// timeout for map connections - /// - QNetworkProxyFactory::setUseSystemConfiguration(true); - - - /// - /// Gets or sets the value of the User-agent HTTP header. - /// - UserAgent = QString("Mozilla/5.0 (Windows NT 6.1; WOW64; rv:%1.0) Gecko/%2%3%4 Firefox/%5.0.%6").arg(QString::number(Random(3,14)), QString::number(Random(QDate().currentDate().year() - 4, QDate().currentDate().year())), QString::number(Random(11,12)), QString::number(Random(10,30)), QString::number(Random(3,14)), QString::number(Random(1,10))).toLatin1(); - - Timeout = 5 * 1000; - CorrectGoogleVersions=true; - isCorrectedGoogleVersions = false; - UseGeocoderCache=true; - UsePlacemarkCache=true; - } - UrlFactory::~UrlFactory() - { - } - int UrlFactory::Random(int low, int high) - { - return low + qrand() % (high - low); - } - QString UrlFactory::TileXYToQuadKey(const int &tileX,const int &tileY,const int &levelOfDetail) const - { - QString quadKey; - for(int i = levelOfDetail; i > 0; i--) - { - char digit = '0'; - int mask = 1 << (i - 1); - if((tileX & mask) != 0) - { - digit++; - } - if((tileY & mask) != 0) - { - digit++; - digit++; - } - quadKey.append(digit); - } - return quadKey; - } - int UrlFactory::GetServerNum(const Point &pos,const int &max) const - { - return (pos.X() + 2 * pos.Y()) % max; - } - void UrlFactory::setIsCorrectGoogleVersions(bool value) - { - isCorrectedGoogleVersions=value; - } - - bool UrlFactory::IsCorrectGoogleVersions() - { - return isCorrectedGoogleVersions; - } - - void UrlFactory::TryCorrectGoogleVersions() - { - static bool versionRetrieved = false; - - if (versionRetrieved) - { - return; - } - QMutexLocker locker(&mutex); - if(CorrectGoogleVersions && !IsCorrectGoogleVersions()) - { - QNetworkReply *reply; - QNetworkRequest qheader; - QNetworkAccessManager network; - QEventLoop q; - QTimer tT; - tT.setSingleShot(true); - connect(&network, SIGNAL(finished(QNetworkReply*)), - &q, SLOT(quit())); - connect(&tT, SIGNAL(timeout()), &q, SLOT(quit())); - network.setProxy(Proxy); -#ifdef DEBUG_URLFACTORY - qDebug()<<"Correct GoogleVersion"; -#endif //DEBUG_URLFACTORY - setIsCorrectGoogleVersions(true); - QString url = "http://maps.google.com"; - - qheader.setUrl(QUrl(url)); - qheader.setRawHeader("User-Agent",UserAgent); - reply=network.get(qheader); - tT.start(Timeout); - q.exec(); - if(!tT.isActive()) - return; - tT.stop(); - if( (reply->error()!=QNetworkReply::NoError)) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"Try corrected version withou abort or error:"<errorString(); -#endif //DEBUG_URLFACTORY - return; - } - QString html=QString(reply->readAll()); - QRegExp reg("\"*http://mt0.google.com/vt/lyrs=m@(\\d*)",Qt::CaseInsensitive); - if(reg.indexIn(html)!=-1) - { - QStringList gc=reg.capturedTexts(); - VersionGoogleMap = QString("m@%1").arg(gc[1]); - VersionGoogleMapChina = VersionGoogleMap; - -#ifdef DEBUG_URLFACTORY - qDebug()<<"TryCorrectGoogleVersions, VersionGoogleMap: "<deleteLater(); - - } - - } - - QString UrlFactory::MakeImageUrl(const MapType::Types &type,const Point &pos,const int &zoom,const QString &language) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"Entered MakeImageUrl"; -#endif //DEBUG_URLFACTORY - switch(type) - { - case MapType::GoogleMap: - { - QString server = "mts"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - - return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMap).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleSatellite: - { - QString server = "khms"; - QString request = "kh"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - //this does not yield good results in practice return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatellite).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - return QString("http://mt1.google.com/vt/lyrs=y&x=%1%2&y=%3&z=%4").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom); - } - break; - case MapType::GoogleLabels: - { - QString server = "mts"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - - return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabels).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleTerrain: - { - QString server = "mts"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - return QString("http://%1%2.google.com/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrain).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleMapChina: - { - QString server = "mt"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - // http://mt0.google.cn/vt/v=w2.101&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga - - return QString("http://%1%2.google.cn/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleSatelliteChina: - { - QString server = "mt"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - // TryCorrectGoogleVersions(); - // http://khm0.google.cn/kh/v=46&x=12&y=6&z=4&s=Ga - - return QString("http://%1%2.google.cn/%3/lyrs=%4&gl=cn&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteChina).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleLabelsChina: - { - QString server = "mt"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - // http://mt0.google.cn/vt/v=w2t.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga - - return QString("http://%1%2.google.cn/%3/imgtp=png32&lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleTerrainChina: - { - QString server = "mt"; - QString request = "vt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - TryCorrectGoogleVersions(); - - // http://mt0.google.cn/vt/v=w2p.110&hl=zh-CN&gl=cn&x=12&y=6&z=4&s=Ga - - return QString("http://%1%2.google.com/%3/lyrs=%4&hl=%5&gl=cn&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleTerrainChina).arg("zh-CN").arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleMapKorea: - { - QString server = "mt"; - QString request = "mt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - - //http://mt3.gmaptiles.co.kr/mt/v=kr1.11&hl=lt&x=109&y=49&z=7&s= - - QString ret = QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleMapKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - return ret; - } - break; - case MapType::GoogleSatelliteKorea: - { - QString server = "khm"; - QString request = "kh"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - - // http://khm1.google.co.kr/kh/v=54&x=109&y=49&z=7&s= - - return QString("http://%1%2.google.co.kr/%3/v=%4&x=%5%6&y=%7&z=%8&s=%9").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleSatelliteKorea).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::GoogleLabelsKorea: - { - QString server = "mt"; - QString request = "mt"; - QString sec1 = ""; // after &x=... - QString sec2 = ""; // after &zoom=... - GetSecGoogleWords(pos, sec1, sec2); - - // http://mt1.gmaptiles.co.kr/mt/v=kr1t.11&hl=lt&x=109&y=50&z=7&s=G - - return QString("http://%1%2.gmaptiles.co.kr/%3/v=%4&hl=%5&x=%6%7&y=%8&z=%9&s=%10").arg(server).arg(GetServerNum(pos, 4)).arg(request).arg(VersionGoogleLabelsKorea).arg(language).arg(pos.X()).arg(sec1).arg(pos.Y()).arg(zoom).arg(sec2); - } - break; - case MapType::YahooMap: - { - return QString("http://maps%1.yimg.com/hx/tl?v=%2&.intl=%3&x=%4&y=%5&z=%6&r=1").arg(((GetServerNum(pos, 2)) + 1)).arg(VersionYahooMap).arg(language).arg(pos.X()).arg((((1 << zoom) >> 1) - 1 - pos.Y())).arg((zoom + 1)); - } - - case MapType::YahooSatellite: - { - return QString("http://maps%1.yimg.com/ae/ximg?v=%2&t=a&s=256&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("3").arg(VersionYahooSatellite).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1); - } - break; - case MapType::YahooLabels: - { - return QString("http://maps%1.yimg.com/hx/tl?v=%2&t=h&.intl=%3&x=%4&y=%5&z=%6&r=1").arg("1").arg(VersionYahooLabels).arg(language).arg(pos.X()).arg(((1 << zoom) >> 1) - 1 - pos.Y()).arg(zoom + 1); - } - break; - case MapType::OpenStreetMap: - { - char letter= "abc"[GetServerNum(pos, 3)]; - return QString("http://%1.tile.openstreetmap.org/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y()); - } - break; - case MapType::OpenStreetOsm: - { - char letter = "abc"[GetServerNum(pos, 3)]; - return QString("http://%1.tah.openstreetmap.org/Tiles/tile/%2/%3/%4.png").arg(letter).arg(zoom).arg(pos.X()).arg(pos.Y()); - } - break; - case MapType::OpenStreetMapSurfer: - { - // http://tiles1.mapsurfer.net/tms_r.ashx?x=37378&y=20826&z=16 - - return QString("http://tiles1.mapsurfer.net/tms_r.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); - } - break; - case MapType::OpenStreetMapSurferTerrain: - { - // http://tiles2.mapsurfer.net/tms_t.ashx?x=9346&y=5209&z=14 - - return QString("http://tiles2.mapsurfer.net/tms_t.ashx?x=%1&y=%2&z=%3").arg(pos.X()).arg(pos.Y()).arg(zoom); - } - break; - case MapType::BingMap: - { - QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom); - return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/r%2.png?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString("")); - } - break; - case MapType::BingSatellite: - { - QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom); - return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/a%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString("")); - } - break; - case MapType::BingHybrid: - { - QString key = TileXYToQuadKey(pos.X(), pos.Y(), zoom); - return QString("http://ecn.t%1.tiles.virtualearth.net/tiles/h%2.jpeg?g=%3&mkt=%4%5").arg(GetServerNum(pos, 4)).arg(key).arg(VersionBingMaps).arg(language).arg(!(BingMapsClientToken.isNull()|BingMapsClientToken.isEmpty()) ? "&token=" + BingMapsClientToken : QString("")); - } - - case MapType::ArcGIS_Map: - { - // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/0/0/0.jpg - - return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_StreetMap_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X()); - } - break; - case MapType::ArcGIS_Satellite: - { - // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/1/0/1.jpg - - return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_Imagery_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X()); - } - break; - case MapType::ArcGIS_ShadedRelief: - { - // http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/1/0/1.jpg - - return QString("http://server.arcgisonline.com/ArcGIS/rest/services/ESRI_ShadedRelief_World_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X()); - } - break; - case MapType::ArcGIS_Terrain: - { - // http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/4/3/15 - - return QString("http://server.arcgisonline.com/ArcGIS/rest/services/NGS_Topo_US_2D/MapServer/tile/%1/%2/%3").arg(zoom).arg(pos.Y()).arg(pos.X()); - } - break; - case MapType::ArcGIS_MapsLT_OrtoFoto: - { - // http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg - // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13 - // return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X()); - // http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001c/C00000029.jpg - // return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X()); - // http://dc1.maps.lt/cache/mapslt_ortofoto_512/map/_alllayers/L03/R0000001d/C0000002a.jpg - //TODO verificar - return QString("http://dc1.maps.lt/cache/mapslt_ortofoto/map/_alllayers/L%1/R%2/C%3.jpg").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0'); - } - break; - case MapType::ArcGIS_MapsLT_Map: - { - // http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L02/R0000001b/C00000028.jpg - // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto/MapServer/tile/0/9/13 - // return string.Format("http://www.maps.lt/ortofoto/mapslt_ortofoto_vector_512/map/_alllayers/L{0:00}/R{1:x8}/C{2:x8}.jpg", zoom, pos.Y(), pos.X()); - // http://arcgis.maps.lt/ArcGIS/rest/services/mapslt/MapServer/tile/7/1162/1684.png - // http://dc1.maps.lt/cache/mapslt_512/map/_alllayers/L03/R0000001b/C00000029.png - //TODO verificar - // http://dc1.maps.lt/cache/mapslt/map/_alllayers/L02/R0000001c/C00000029.png - return QString("http://dc1.maps.lt/cache/mapslt/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0'); - } - break; - case MapType::ArcGIS_MapsLT_Map_Labels: - { - //http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/0/9/13 - //return string.Format("http://arcgis.maps.lt/ArcGIS/rest/services/mapslt_ortofoto_overlay/MapServer/tile/{0}/{1}/{2}", zoom, pos.Y(), pos.X()); - //http://dc1.maps.lt/cache/mapslt_ortofoto_overlay_512/map/_alllayers/L03/R0000001d/C00000029.png - //TODO verificar - return QString("http://dc1.maps.lt/cache/mapslt_ortofoto_overlay/map/_alllayers/L%1/R%2/C%3.png").arg(zoom,2,10,(QChar)'0').arg(pos.Y(),8,16,(QChar)'0').arg(pos.X(),8,16,(QChar)'0'); - } - break; - case MapType::PergoTurkeyMap: - { - // http://{domain}/{layerName}/{zoomLevel}/{first3LetterOfTileX}/{second3LetterOfTileX}/{third3LetterOfTileX}/{first3LetterOfTileY}/{second3LetterOfTileY}/{third3LetterOfTileXY}.png - - // http://map3.pergo.com.tr/tile/00/000/000/001/000/000/000.png - // That means: Zoom Level: 0 TileX: 1 TileY: 0 - - // http://domain/tile/14/000/019/371/000/011/825.png - // That means: Zoom Level: 14 TileX: 19371 TileY:11825 - - // string x = pos.X().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/001 - // string y = pos.Y().ToString("000000000").Insert(3, "/").Insert(7, "/"); // - 000/000/000 - QString x=QString("%1").arg(QString::number(pos.X()),9,(QChar)'0'); - x.insert(3,"/").insert(7,"/"); - QString y=QString("%1").arg(QString::number(pos.Y()),9,(QChar)'0'); - y.insert(3,"/").insert(7,"/"); - //"http://map03.pergo.com.tr/tile/2/000/000/003/000/000/002.png" - return QString("http://map%1.pergo.com.tr/tile/%2/%3/%4.png").arg(GetServerNum(pos, 4)).arg(zoom,2,10,(QChar)'0').arg(x).arg(y); - } - break; - case MapType::SigPacSpainMap: - { - return QString("http://sigpac.mapa.es/kmlserver/raster/%1@3785/%2.%3.%4.img").arg(levelsForSigPacSpainMap[zoom]).arg(zoom).arg(pos.X()).arg((2 << (zoom - 1)) - pos.Y() - 1); - } - break; - - case MapType::YandexMapRu: - { - QString server = "vec"; - - //http://vec01.maps.yandex.ru/tiles?l=map&v=2.10.2&x=1494&y=650&z=11 - - return QString("http://%1").arg(server)+QString("0%2.maps.yandex.ru/tiles?l=map&v=%3&x=%4&y=%5&z=%6").arg(GetServerNum(pos, 4)+1).arg(VersionYandexMap).arg(pos.X()).arg(pos.Y()).arg(zoom); - } - break; - default: - break; - } - - return QString::null; - } - void UrlFactory::GetSecGoogleWords(const Point &pos, QString &sec1, QString &sec2) - { - sec1 = ""; // after &x=... - sec2 = ""; // after &zoom=... - int seclen = ((pos.X() * 3) + pos.Y()) % 8; - sec2 = SecGoogleWord.left(seclen); - if(pos.Y() >= 10000 && pos.Y() < 100000) - { - sec1 = "&s="; - } - } - QString UrlFactory::MakeGeocoderUrl(QString keywords) - { - QString key = keywords.replace(' ', '+'); - return QString("http://maps.google.com/maps/geo?q=%1&output=csv&key=%2").arg(key).arg(GoogleMapsAPIKey); - } - QString UrlFactory::MakeReverseGeocoderUrl(internals::PointLatLng &pt,const QString &language) - { - - return QString("http://maps.google.com/maps/geo?hl=%1&ll=%2,%3&output=csv&key=%4").arg(language).arg(QString::number(pt.Lat())).arg(QString::number(pt.Lng())).arg(GoogleMapsAPIKey); - - } - internals::PointLatLng UrlFactory::GetLatLngFromGeodecoder(const QString &keywords, GeoCoderStatusCode::Types &status) - { - return GetLatLngFromGeocoderUrl(MakeGeocoderUrl(keywords),UseGeocoderCache,status); - } - internals::PointLatLng UrlFactory::GetLatLngFromGeocoderUrl(const QString &url, const bool &useCache, GeoCoderStatusCode::Types &status) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"Entered GetLatLngFromGeocoderUrl:"; -#endif //DEBUG_URLFACTORY - status = GeoCoderStatusCode::Unknow; - internals::PointLatLng ret(0,0); - QString urlEnd = url.mid(url.indexOf("geo?q=")+6); - urlEnd.replace( QRegExp( - "[^" - "A-Z,a-z,0-9," - "\\^,\\&,\\',\\@," - "\\{,\\},\\[,\\]," - "\\,,\\$,\\=,\\!," - "\\-,\\#,\\(,\\)," - "\\%,\\.,\\+,\\~,\\_" - "]"), "_" ); - - QString geo = useCache ? Cache::Instance()->GetGeocoderFromCache(urlEnd) : ""; - - if(geo.isNull()|geo.isEmpty()) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet"; -#endif //DEBUG_URLFACTORY - QNetworkReply *reply; - QNetworkRequest qheader; - QNetworkAccessManager network; - network.setProxy(Proxy); - qheader.setUrl(QUrl(url)); - qheader.setRawHeader("User-Agent",UserAgent); - reply=network.get(qheader); -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:URL="<isFinished()) || (time.elapsed()>(6*Timeout))) ){QCoreApplication::processEvents(QEventLoop::AllEvents);} -#ifdef DEBUG_URLFACTORY - qDebug()<<"Finished?"<error()<<" abort?"<<(time.elapsed()>Timeout*6); -#endif //DEBUG_URLFACTORY - if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6)) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl::Network error"; -#endif //DEBUG_URLFACTORY - return internals::PointLatLng(0,0); - } - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok"; -#endif //DEBUG_URLFACTORY - geo=reply->readAll(); - - - // cache geocoding - if(useCache && geo.startsWith("200")) - { - Cache::Instance()->CacheGeocoder(urlEnd, geo); - } - } - reply->deleteLater(); - } - - - // parse values - // true : 200,4,56.1451640,22.0681787 - // false: 602,0,0,0 - { - QStringList values = geo.split(','); - if(values.count() == 4) - { - status = (GeoCoderStatusCode::Types) QString(values[0]).toInt(); - if(status == GeoCoderStatusCode::G_GEO_SUCCESS) - { - double lat = QString(values[2]).toDouble(); - double lng = QString(values[3]).toDouble(); - - ret = internals::PointLatLng(lat, lng); -#ifdef DEBUG_URLFACTORY - qDebug()<<"Lat="<GetPlacemarkFromCache(urlEnd) : ""; - - if(reverse.isNull()|reverse.isEmpty()) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:Not in cache going internet"; -#endif //DEBUG_URLFACTORY - QNetworkReply *reply; - QNetworkRequest qheader; - QNetworkAccessManager network; - network.setProxy(Proxy); - qheader.setUrl(QUrl(url)); - qheader.setRawHeader("User-Agent",UserAgent); - reply=network.get(qheader); -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:URL="<isFinished()) || (time.elapsed()>(6*Timeout))) ){QCoreApplication::processEvents(QEventLoop::AllEvents);} -#ifdef DEBUG_URLFACTORY - qDebug()<<"Finished?"<error()<<" abort?"<<(time.elapsed()>Timeout*6); -#endif //DEBUG_URLFACTORY - if( (reply->error()!=QNetworkReply::NoError) | (time.elapsed()>Timeout*6)) - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl::Network error"; -#endif //DEBUG_URLFACTORY - return ret; - } - { -#ifdef DEBUG_URLFACTORY - qDebug()<<"GetLatLngFromGeocoderUrl:Reply ok"; -#endif //DEBUG_URLFACTORY - QByteArray a=(reply->readAll()); - QTextCodec *codec = QTextCodec::codecForName("UTF-8"); - reverse = codec->toUnicode(a); -#ifdef DEBUG_URLFACTORY - qDebug()<CachePlacemark(urlEnd, reverse); - } - } - reply->deleteLater(); - } - - - // parse values - // true : 200,4,56.1451640,22.0681787 - // false: 602,0,0,0 - if(reverse.startsWith("200")) - { - QString acc = reverse.left(reverse.indexOf('\"')); - ret = Placemark(reverse.remove(reverse.indexOf('\"'))); - ret.SetAccuracy ((int) (( (QString) acc.split(',')[1]).toInt()) ); - - } - return ret; - } - double UrlFactory::GetDistance(internals::PointLatLng p1, internals::PointLatLng p2) - { - double dLat1InRad = p1.Lat() * (M_PI / 180); - double dLong1InRad = p1.Lng() * (M_PI / 180); - double dLat2InRad = p2.Lat() * (M_PI / 180); - double dLong2InRad = p2.Lng() * (M_PI / 180); - double dLongitude = dLong2InRad - dLong1InRad; - double dLatitude = dLat2InRad - dLat1InRad; - double a = pow(sin(dLatitude / 2), 2) + cos(dLat1InRad) * cos(dLat2InRad) * pow(sin(dLongitude / 2), 2); - double c = 2 * atan2(sqrt(a), sqrt(1 - a)); - double dDistance = EarthRadiusKm * c; - return dDistance; - } -} diff --git a/libs/opmapcontrol/src/core/urlfactory.h b/libs/opmapcontrol/src/core/urlfactory.h deleted file mode 100644 index 7ff86ce9b..000000000 --- a/libs/opmapcontrol/src/core/urlfactory.h +++ /dev/null @@ -1,89 +0,0 @@ -/** -****************************************************************************** -* -* @file urlfactory.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef URLFACTORY_H -#define URLFACTORY_H - -#include -#include -#include -#include -#include -#include -#include -#include "providerstrings.h" -#include "pureimagecache.h" -#include "../internals/pointlatlng.h" -#include "geodecoderstatus.h" -#include -#include "cache.h" -#include "placemark.h" -#include -#include "cmath" - -namespace core { - class UrlFactory: public QObject,public ProviderStrings - { - Q_OBJECT - public: - /// - /// Gets or sets the value of the User-agent HTTP header. - /// - QByteArray UserAgent; - QNetworkProxy Proxy; - UrlFactory(); - ~UrlFactory(); - QString MakeImageUrl(const MapType::Types &type,const core::Point &pos,const int &zoom,const QString &language); - internals::PointLatLng GetLatLngFromGeodecoder(const QString &keywords,GeoCoderStatusCode::Types &status); - Placemark GetPlacemarkFromGeocoder(internals::PointLatLng location); - int Timeout; - private: - int Random(int low, int high); - void GetSecGoogleWords(const core::Point &pos, QString &sec1, QString &sec2); - int GetServerNum(const core::Point &pos,const int &max) const; - void TryCorrectGoogleVersions(); - bool isCorrectedGoogleVersions; - QString TileXYToQuadKey(const int &tileX,const int &tileY,const int &levelOfDetail) const; - bool CorrectGoogleVersions; - bool UseGeocoderCache; //TODO GetSet - bool UsePlacemarkCache;//TODO GetSet - static const double EarthRadiusKm; - double GetDistance(internals::PointLatLng p1,internals::PointLatLng p2); - QMutex mutex; - - protected: - static short timelapse; - QString LanguageStr; - bool IsCorrectGoogleVersions(); - void setIsCorrectGoogleVersions(bool value); - QString MakeGeocoderUrl(QString keywords); - QString MakeReverseGeocoderUrl(internals::PointLatLng &pt,const QString &language); - internals::PointLatLng GetLatLngFromGeocoderUrl(const QString &url,const bool &useCache, GeoCoderStatusCode::Types &status); - Placemark GetPlacemarkFromReverseGeocoderUrl(const QString &url,const bool &useCache); - }; - -} -#endif // URLFACTORY_H diff --git a/libs/opmapcontrol/src/internals/MouseWheelZoomType.cpp b/libs/opmapcontrol/src/internals/MouseWheelZoomType.cpp deleted file mode 100644 index 3871a30cc..000000000 --- a/libs/opmapcontrol/src/internals/MouseWheelZoomType.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/** -****************************************************************************** -* -* @file MouseWheelZoomType.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "mousewheelzoomtype.h" - - -namespace internals { - -} diff --git a/libs/opmapcontrol/src/internals/copyrightstrings.h b/libs/opmapcontrol/src/internals/copyrightstrings.h deleted file mode 100644 index 1334d27be..000000000 --- a/libs/opmapcontrol/src/internals/copyrightstrings.h +++ /dev/null @@ -1,41 +0,0 @@ -/** -****************************************************************************** -* -* @file copyrightstrings.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef COPYRIGHTSTRINGS_H -#define COPYRIGHTSTRINGS_H - -#include -#include - -namespace internals { -static const QString googleCopyright = QString("(c)%1 Google - Map data (c)%1 Tele Atlas, Imagery (c)%1 TerraMetrics").arg(QDate::currentDate().year()); -static const QString openStreetMapCopyright = QString("(c) OpenStreetMap - Map data (c)%1 OpenStreetMap").arg(QDate::currentDate().year()); -static const QString yahooMapCopyright = QString("(c) Yahoo! Inc. - Map data & Imagery (c)%1 NAVTEQ").arg(QDate::currentDate().year()); -static const QString virtualEarthCopyright = QString("(c)%1 Microsoft Corporation, (c)%1 NAVTEQ, (c)%1 Image courtesy of NASA").arg(QDate::currentDate().year()); -static const QString arcGisCopyright = QString("(c)%1 ESRI - Map data (c)%1 ArcGIS").arg(QDate::currentDate().year()); - -} -#endif // COPYRIGHTSTRINGS_H diff --git a/libs/opmapcontrol/src/internals/core.cpp b/libs/opmapcontrol/src/internals/core.cpp deleted file mode 100644 index 10459eb1e..000000000 --- a/libs/opmapcontrol/src/internals/core.cpp +++ /dev/null @@ -1,725 +0,0 @@ -/** -****************************************************************************** -* -* @file core.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "core.h" - -#ifdef DEBUG_CORE -qlonglong internals::Core::debugcounter=0; -#endif - -using namespace projections; - -namespace internals { - Core::Core() : - MouseWheelZooming(false), - currentPosition(0,0), - currentPositionPixel(0,0), - LastLocationInBounds(-1,-1), - sizeOfMapArea(0,0), - minOfTiles(0,0), - maxOfTiles(0,0), - zoom(0), - projection(NULL), - isDragging(false), - TooltipTextPadding(10,10), - mapType(MapType::GoogleMap), - loaderLimit(5), - maxzoom(21), - runningThreads(0), - started(false) - { - mousewheelzoomtype=MouseWheelZoomType::MousePositionAndCenter; - SetProjection(new MercatorProjection()); - this->setAutoDelete(false); - ProcessLoadTaskCallback.setMaxThreadCount(10); - renderOffset=Point(0,0); - dragPoint=Point(0,0); - CanDragMap=true; - tilesToload=0; - OPMaps::Instance(); - } - Core::~Core() - { - if (projection) { - delete projection; - } - ProcessLoadTaskCallback.waitForDone(); - } - - void Core::run() - { - MrunningThreads.lock(); - ++runningThreads; - MrunningThreads.unlock(); -#ifdef DEBUG_CORE - qlonglong debug; - Mdebug.lock(); - debug=++debugcounter; - Mdebug.unlock(); - qDebug()<<"core:run"<<" ID="< 0) - { - task = tileLoadQueue.dequeue(); - { - - last = (tileLoadQueue.count() == 0); -#ifdef DEBUG_CORE - qDebug()<<"TileLoadQueue: " << tileLoadQueue.count()<<" Point:"<GetPos().ToString()<<" now has "<Overlays.count()<<" overlays"<<" ID="<RetryLoadTile > 0) - { -#ifdef DEBUG_CORE - qDebug()<<"ProcessLoadTask: " << task.ToString()<< " -> empty tile, retry " << retry<<" ID="<RetryLoadTile); - } - - if(t->Overlays.count() > 0) - { - Matrix.SetTileAt(task.Pos,t); - emit OnNeedInvalidation(); - -#ifdef DEBUG_CORE - qDebug()<<"Core::run add tile "<GetPos().ToString()<<" to matrix index "<Overlays.count()<<" ID="<kiberCacheLock.lockForWrite(); - OPMaps::Instance()->TilesInMemory.RemoveMemoryOverload(); - OPMaps::Instance()->kiberCacheLock.unlock(); - - MtileDrawingList.lock(); - { - Matrix.ClearPointsNotIn(tileDrawingList); - } - MtileDrawingList.unlock(); - - - emit OnTileLoadComplete(); - - - emit OnNeedInvalidation(); - - } - } - - - - } -#ifdef DEBUG_CORE - qDebug()<<"loaderLimit release:"+loaderLimit.available()<<" ID="<GetDiagnostics(); - diag.runningThreads=runningThreads; - MrunningThreads.unlock(); - return diag; - } - - void Core::SetZoom(const int &value) - { - if (!isDragging) - { - zoom=value; - minOfTiles=Projection()->GetTileMatrixMinXY(value); - maxOfTiles=Projection()->GetTileMatrixMaxXY(value); - currentPositionPixel=Projection()->FromLatLngToPixel(currentPosition,value); - if(started) - { - MtileLoadQueue.lock(); - tileLoadQueue.clear(); - MtileLoadQueue.unlock(); - MtileToload.lock(); - tilesToload=0; - MtileToload.unlock(); - Matrix.Clear(); - GoToCurrentPositionOnZoom(); - UpdateBounds(); - emit OnMapDrag(); - emit OnMapZoomChanged(); - emit OnNeedInvalidation(); - } - } - } - - void Core::SetCurrentPosition(const PointLatLng &value) - { - if(!IsDragging()) - { - currentPosition = value; - SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(value, Zoom())); - - if(started) - { - GoToCurrentPosition(); - emit OnCurrentPositionChanged(currentPosition); - } - } - else - { - currentPosition = value; - SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(value, Zoom())); - - if(started) - { - emit OnCurrentPositionChanged(currentPosition); - } - } - } - void Core::SetMapType(const MapType::Types &value) - { - - if(value != GetMapType()) - { - mapType = value; - - switch(value) - { - - - case MapType::ArcGIS_Map: - case MapType::ArcGIS_Satellite: - case MapType::ArcGIS_ShadedRelief: - case MapType::ArcGIS_Terrain: - { - if(Projection()->Type()!="PlateCarreeProjection") - { - SetProjection(new PlateCarreeProjection()); - maxzoom=13; - } - } - break; - - case MapType::ArcGIS_MapsLT_Map_Hybrid: - case MapType::ArcGIS_MapsLT_Map_Labels: - case MapType::ArcGIS_MapsLT_Map: - case MapType::ArcGIS_MapsLT_OrtoFoto: - { - if(Projection()->Type()!="LKS94Projection") - { - SetProjection(new LKS94Projection()); - maxzoom=11; - } - } - break; - - case MapType::PergoTurkeyMap: - { - if(Projection()->Type()!="PlateCarreeProjectionPergo") - { - SetProjection(new PlateCarreeProjectionPergo()); - maxzoom=17; - } - } - break; - - case MapType::YandexMapRu: - { - if(Projection()->Type()!="MercatorProjectionYandex") - { - SetProjection(new MercatorProjectionYandex()); - maxzoom=13; - } - } - break; - - case MapType::BingHybrid: - case MapType::BingMap: - case MapType::BingSatellite: - { - if(Projection()->Type()!="MercatorProjection") - { - SetProjection(new MercatorProjection()); - } - maxzoom=21; - } - break; - - default: - { - if(Projection()->Type()!="MercatorProjection") - { - SetProjection(new MercatorProjection()); - } - maxzoom=20; - } - break; - } - - minOfTiles = Projection()->GetTileMatrixMinXY(Zoom()); - maxOfTiles = Projection()->GetTileMatrixMaxXY(Zoom()); - SetCurrentPositionGPixel(Projection()->FromLatLngToPixel(CurrentPosition(), Zoom())); - - if(started) - { - CancelAsyncTasks(); - OnMapSizeChanged(Width, Height); - GoToCurrentPosition(); - ReloadMap(); - GoToCurrentPosition(); - emit OnMapTypeChanged(value); - - } - } - - } - void Core::StartSystem() - { - if(!started) - { - started = true; - - ReloadMap(); - GoToCurrentPosition(); - } - } - - void Core::UpdateCenterTileXYLocation() - { - PointLatLng center = FromLocalToLatLng(Width/2, Height/2); - Point centerPixel = Projection()->FromLatLngToPixel(center, Zoom()); - centerTileXYLocation = Projection()->FromPixelToTileXY(centerPixel); - } - - void Core::OnMapSizeChanged(int const& width, int const& height) - { - Width = width; - Height = height; - - sizeOfMapArea.SetWidth(1 + (Width/Projection()->TileSize().Width())/2); - sizeOfMapArea.SetHeight(1 + (Height/Projection()->TileSize().Height())/2); - - UpdateCenterTileXYLocation(); - - if(started) - { - UpdateBounds(); - - emit OnCurrentPositionChanged(currentPosition); - } - } - void Core::OnMapClose() - { - // if(waitOnEmptyTasks != null) - // { - // try - // { - // waitOnEmptyTasks.Set(); - // waitOnEmptyTasks.Close(); - // } - // catch - // { - // } - // } - - CancelAsyncTasks(); - } - GeoCoderStatusCode::Types Core::SetCurrentPositionByKeywords(QString const& keys) - { - GeoCoderStatusCode::Types status = GeoCoderStatusCode::Unknow; - PointLatLng pos = OPMaps::Instance()->GetLatLngFromGeodecoder(keys, status); - if(!pos.IsEmpty() && (status == GeoCoderStatusCode::G_GEO_SUCCESS)) - { - SetCurrentPosition(pos); - } - - return status; - } - RectLatLng Core::CurrentViewArea() - { - PointLatLng p = Projection()->FromPixelToLatLng(-renderOffset.X(), -renderOffset.Y(), Zoom()); - double rlng = Projection()->FromPixelToLatLng(-renderOffset.X() + Width, -renderOffset.Y(), Zoom()).Lng(); - double blat = Projection()->FromPixelToLatLng(-renderOffset.X(), -renderOffset.Y() + Height, Zoom()).Lat(); - return RectLatLng::FromLTRB(p.Lng(), p.Lat(), rlng, blat); - - } - PointLatLng Core::FromLocalToLatLng(int const& x, int const& y) - { - return Projection()->FromPixelToLatLng(Point(x - renderOffset.X(), y - renderOffset.Y()), Zoom()); - } - - - Point Core::FromLatLngToLocal(PointLatLng const& latlng) - { - Point pLocal = Projection()->FromLatLngToPixel(latlng, Zoom()); - pLocal.Offset(renderOffset); - return pLocal; - } - int Core::GetMaxZoomToFitRect(RectLatLng const& rect) - { - int zoom = 0; - - for(int i = 1; i <= MaxZoom(); i++) - { - Point p1 = Projection()->FromLatLngToPixel(rect.LocationTopLeft(), i); - Point p2 = Projection()->FromLatLngToPixel(rect.Bottom(), rect.Right(), i); - - if(((p2.X() - p1.X()) <= Width+10) && (p2.Y() - p1.Y()) <= Height+10) - { - zoom = i; - } - else - { - break; - } - } - - return zoom; - } - void Core::BeginDrag(Point const& pt) - { - dragPoint.SetX(pt.X() - renderOffset.X()); - dragPoint.SetY(pt.Y() - renderOffset.Y()); - isDragging = true; - } - void Core::EndDrag() - { - isDragging = false; - emit OnNeedInvalidation(); - - } - void Core::ReloadMap() - { - if(started) - { -#ifdef DEBUG_CORE - qDebug()<<"------------------"; -#endif //DEBUG_CORE - - MtileLoadQueue.lock(); - { - tileLoadQueue.clear(); - } - MtileLoadQueue.unlock(); - MtileToload.lock(); - tilesToload=0; - MtileToload.unlock(); - Matrix.Clear(); - - emit OnNeedInvalidation(); - - } - } - void Core::GoToCurrentPosition() - { - // reset stuff - renderOffset = Point::Empty; - centerTileXYLocationLast = Point::Empty; - dragPoint = Point::Empty; - - // goto location - Drag(Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2))); - } - void Core::GoToCurrentPositionOnZoom() - { - // reset stuff - renderOffset = Point::Empty; - centerTileXYLocationLast = Point::Empty; - dragPoint = Point::Empty; - - // goto location and centering - if(MouseWheelZooming) - { - if(mousewheelzoomtype != MouseWheelZoomType::MousePositionWithoutCenter) - { - Point pt = Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2)); - renderOffset.SetX(pt.X() - dragPoint.X()); - renderOffset.SetY(pt.Y() - dragPoint.Y()); - } - else // without centering - { - renderOffset.SetX(-GetcurrentPositionGPixel().X() - dragPoint.X()); - renderOffset.SetY(-GetcurrentPositionGPixel().Y() - dragPoint.Y()); - renderOffset.Offset(mouseLastZoom); - } - } - else // use current map center - { - mouseLastZoom = Point::Empty; - - Point pt = Point(-(GetcurrentPositionGPixel().X() - Width/2), -(GetcurrentPositionGPixel().Y() - Height/2)); - renderOffset.SetX(pt.X() - dragPoint.X()); - renderOffset.SetY(pt.Y() - dragPoint.Y()); - } - - UpdateCenterTileXYLocation(); - } - void Core::DragOffset(Point const& offset) - { - renderOffset.Offset(offset); - - UpdateCenterTileXYLocation(); - - if(centerTileXYLocation != centerTileXYLocationLast) - { - centerTileXYLocationLast = centerTileXYLocation; - UpdateBounds(); - } - - { - LastLocationInBounds = CurrentPosition(); - SetCurrentPosition (FromLocalToLatLng((int) Width/2, (int) Height/2)); - } - - emit OnNeedInvalidation(); - emit OnMapDrag(); - } - void Core::Drag(Point const& pt) - { - renderOffset.SetX(pt.X() - dragPoint.X()); - renderOffset.SetY(pt.Y() - dragPoint.Y()); - - UpdateCenterTileXYLocation(); - - if(centerTileXYLocation != centerTileXYLocationLast) - { - centerTileXYLocationLast = centerTileXYLocation; - UpdateBounds(); - } - - if(IsDragging()) - { - LastLocationInBounds = CurrentPosition(); - SetCurrentPosition(FromLocalToLatLng((int) Width/2, (int) Height/2)); - } - - emit OnNeedInvalidation(); - - - emit OnMapDrag(); - - } - void Core::CancelAsyncTasks() - { - if(started) - { - ProcessLoadTaskCallback.waitForDone(); - MtileLoadQueue.lock(); - { - tileLoadQueue.clear(); - //tilesToload=0; - } - MtileLoadQueue.unlock(); - MtileToload.lock(); - tilesToload=0; - MtileToload.unlock(); - // ProcessLoadTaskCallback.waitForDone(); - } - } - void Core::UpdateBounds() - { - MtileDrawingList.lock(); - { - FindTilesAround(tileDrawingList); - -#ifdef DEBUG_CORE - qDebug()<<"OnTileLoadStart: " << tileDrawingList.count() << " tiles to load at zoom " << Zoom() << ", time: " << QDateTime::currentDateTime().date(); -#endif //DEBUG_CORE - - emit OnTileLoadStart(); - - - foreach(Point p,tileDrawingList) - { - LoadTask task = LoadTask(p, Zoom()); - { - MtileLoadQueue.lock(); - { - if(!tileLoadQueue.contains(task)) - { - MtileToload.lock(); - ++tilesToload; - MtileToload.unlock(); - tileLoadQueue.enqueue(task); -#ifdef DEBUG_CORE - qDebug()<<"Core::UpdateBounds new Task"< &list) - { - list.clear();; - for(int i = -sizeOfMapArea.Width(); i <= sizeOfMapArea.Width(); i++) - { - for(int j = -sizeOfMapArea.Height(); j <= sizeOfMapArea.Height(); j++) - { - Point p = centerTileXYLocation; - p.SetX(p.X() + i); - p.SetY(p.Y() + j); - - //if(p.X < minOfTiles.Width) - //{ - // p.X += (maxOfTiles.Width + 1); - //} - - //if(p.X > maxOfTiles.Width) - //{ - // p.X -= (maxOfTiles.Width + 1); - //} - - if(p.X() >= minOfTiles.Width() && p.Y() >= minOfTiles.Height() && p.X() <= maxOfTiles.Width() && p.Y() <= maxOfTiles.Height()) - { - if(!list.contains(p)) - { - list.append(p); - } - } - } - } - - - } - void Core::UpdateGroundResolution() - { - double rez = Projection()->GetGroundResolution(Zoom(), CurrentPosition().Lat()); - pxRes100m = (int) (100.0 / rez); // 100 meters - pxRes1000m = (int) (1000.0 / rez); // 1km - pxRes10km = (int) (10000.0 / rez); // 10km - pxRes100km = (int) (100000.0 / rez); // 100km - pxRes1000km = (int) (1000000.0 / rez); // 1000km - pxRes5000km = (int) (5000000.0 / rez); // 5000km - } -} diff --git a/libs/opmapcontrol/src/internals/core.h b/libs/opmapcontrol/src/internals/core.h deleted file mode 100644 index c8c50bf0a..000000000 --- a/libs/opmapcontrol/src/internals/core.h +++ /dev/null @@ -1,286 +0,0 @@ -/** -****************************************************************************** -* -* @file core.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef CORE_H -#define CORE_H - -#include "debugheader.h" - -#include "../internals/pointlatlng.h" -#include "mousewheelzoomtype.h" -#include "../core/size.h" -#include "../core/point.h" - -#include "../core/maptype.h" -#include "rectangle.h" -#include "QThreadPool" -#include "tilematrix.h" -#include -#include "loadtask.h" -#include "copyrightstrings.h" -#include "rectlatlng.h" -#include "../internals/projections/lks94projection.h" -#include "../internals/projections/mercatorprojection.h" -#include "../internals/projections/mercatorprojectionyandex.h" -#include "../internals/projections/platecarreeprojection.h" -#include "../internals/projections/platecarreeprojectionpergo.h" -#include "../core/geodecoderstatus.h" -#include "../core/opmaps.h" -#include "../core/diagnostics.h" - -#include -#include -#include - -#include - -namespace mapcontrol -{ - class OPMapControl; - class MapGraphicItem; -} - -namespace internals { - - class Core:public QObject,public QRunnable - { - Q_OBJECT - - friend class mapcontrol::OPMapControl; - friend class mapcontrol::MapGraphicItem; - public: - Core(); - ~Core(); - void run(); - PointLatLng CurrentPosition()const{return currentPosition;} - - void SetCurrentPosition(const PointLatLng &value); - - core::Point GetcurrentPositionGPixel(){return currentPositionPixel;} - void SetcurrentPositionGPixel(const core::Point &value){currentPositionPixel=value;} - - core::Point GetrenderOffset(){return renderOffset;} - void SetrenderOffset(const core::Point &value){renderOffset=value;} - - core::Point GetcenterTileXYLocation(){return centerTileXYLocation;} - void SetcenterTileXYLocation(const core::Point &value){centerTileXYLocation=value;} - - core::Point GetcenterTileXYLocationLast(){return centerTileXYLocationLast;} - void SetcenterTileXYLocationLast(const core::Point &value){centerTileXYLocationLast=value;} - - core::Point GetdragPoint(){return dragPoint;} - void SetdragPoint(const core::Point &value){dragPoint=value;} - - core::Point GetmouseDown(){return mouseDown;} - void SetmouseDown(const core::Point &value){mouseDown=value;} - - core::Point GetmouseCurrent(){return mouseCurrent;} - void SetmouseCurrent(const core::Point &value){mouseCurrent=value;} - - core::Point GetmouseLastZoom(){return mouseLastZoom;} - void SetmouseLastZoom(const core::Point &value){mouseLastZoom=value;} - - MouseWheelZoomType::Types GetMouseWheelZoomType(){return mousewheelzoomtype;} - void SetMouseWheelZoomType(const MouseWheelZoomType::Types &value){mousewheelzoomtype=value;} - - PointLatLng GetLastLocationInBounds(){return LastLocationInBounds;} - void SetLastLocationInBounds(const PointLatLng &value){LastLocationInBounds=value;} - - Size GetsizeOfMapArea(){return sizeOfMapArea;} - void SetsizeOfMapArea(const Size &value){sizeOfMapArea=value;} - - Size GetminOfTiles(){return minOfTiles;} - void SetminOfTiles(const Size &value){minOfTiles=value;} - - Size GetmaxOfTiles(){return maxOfTiles;} - void SetmaxOfTiles(const Size &value){maxOfTiles=value;} - - Rectangle GettileRect(){return tileRect;} - void SettileRect(const Rectangle &value){tileRect=value;} - - core::Point GettilePoint(){return tilePoint;} - void SettilePoint(const core::Point &value){tilePoint=value;} - - Rectangle GetCurrentRegion(){return CurrentRegion;} - void SetCurrentRegion(const Rectangle &value){CurrentRegion=value;} - - QList tileDrawingList; - - PureProjection* Projection() - { - return projection; - } - void SetProjection(PureProjection* value) - { - if (projection) { - delete projection; - } - projection=value; - tileRect=Rectangle(core::Point(0,0),value->TileSize()); - } - bool IsDragging()const{return isDragging;} - - int Zoom()const{return zoom;} - void SetZoom(int const& value); - - int MaxZoom()const{return maxzoom;} - - void UpdateBounds(); - - MapType::Types GetMapType(){return mapType;} - void SetMapType(MapType::Types const& value); - - void StartSystem(); - - void UpdateCenterTileXYLocation(); - - void OnMapSizeChanged(int const& width, int const& height);//TODO had as slot - - void OnMapClose();//TODO had as slot - - GeoCoderStatusCode::Types SetCurrentPositionByKeywords(QString const& keys); - - RectLatLng CurrentViewArea(); - - PointLatLng FromLocalToLatLng(int const& x, int const& y); - - Point FromLatLngToLocal(PointLatLng const& latlng); - - int GetMaxZoomToFitRect(RectLatLng const& rect); - - void BeginDrag(core::Point const& pt); - - void EndDrag(); - - void ReloadMap(); - - void GoToCurrentPosition(); - - bool MouseWheelZooming; - - void DragOffset(core::Point const& offset); - - void Drag(core::Point const& pt); - - void CancelAsyncTasks(); - - void FindTilesAround(QList &list); - - void UpdateGroundResolution(); - - TileMatrix Matrix; - - bool isStarted(){return started;} - - diagnostics GetDiagnostics(); - signals: - void OnCurrentPositionChanged(internals::PointLatLng point); - void OnTileLoadComplete(); - void OnTilesStillToLoad(int number); - void OnTileLoadStart(); - void OnMapDrag(); - void OnMapZoomChanged(); - void OnMapTypeChanged(MapType::Types type); - void OnEmptyTileError(int zoom, core::Point pos); - void OnNeedInvalidation(); - - private: - - - PointLatLng currentPosition; - core::Point currentPositionPixel; - core::Point renderOffset; - core::Point centerTileXYLocation; - core::Point centerTileXYLocationLast; - core::Point dragPoint; - Rectangle tileRect; - core::Point mouseDown; - bool CanDragMap; - core::Point mouseCurrent; - PointLatLng LastLocationInBounds; - core::Point mouseLastZoom; - - MouseWheelZoomType::Types mousewheelzoomtype; - - - Size sizeOfMapArea; - Size minOfTiles; - Size maxOfTiles; - - core::Point tilePoint; - - Rectangle CurrentRegion; - - QQueue tileLoadQueue; - - int zoom; - - PureProjection* projection; - - bool isDragging; - - QMutex MtileLoadQueue; - - QMutex Moverlays; - - QMutex MtileDrawingList; -#ifdef DEBUG_CORE - QMutex Mdebug; - static qlonglong debugcounter; -#endif - Size TooltipTextPadding; - - MapType::Types mapType; - - QSemaphore loaderLimit; - - QThreadPool ProcessLoadTaskCallback; - QMutex MtileToload; - int tilesToload; - - int maxzoom; - QMutex MrunningThreads; - int runningThreads; - diagnostics diag; - - protected: - bool started; - - int Width; - int Height; - int pxRes100m; // 100 meters - int pxRes1000m; // 1km - int pxRes10km; // 10km - int pxRes100km; // 100km - int pxRes1000km; // 1000km - int pxRes5000km; // 5000km - void SetCurrentPositionGPixel(core::Point const& value){currentPositionPixel = value;} - void GoToCurrentPositionOnZoom(); - - }; - -} -#endif // CORE_H diff --git a/libs/opmapcontrol/src/internals/debugheader.h b/libs/opmapcontrol/src/internals/debugheader.h deleted file mode 100644 index 50ae028f8..000000000 --- a/libs/opmapcontrol/src/internals/debugheader.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef DEBUGHEADER_H -#define DEBUGHEADER_H - -//#define DEBUG_CORE -//#define DEBUG_TILE -//#define DEBUG_TILEMATRIX - -#endif // DEBUGHEADER_H diff --git a/libs/opmapcontrol/src/internals/internals.pro b/libs/opmapcontrol/src/internals/internals.pro deleted file mode 100644 index 787e6ca5c..000000000 --- a/libs/opmapcontrol/src/internals/internals.pro +++ /dev/null @@ -1,35 +0,0 @@ -include (../common.pri) -HEADERS += core.h \ - mousewheelzoomtype.h \ - rectangle.h \ - tile.h \ - tilematrix.h \ - loadtask.h \ - copyrightstrings.h \ - pureprojection.h \ - pointlatlng.h \ - rectlatlng.h \ - sizelatlng.h \ - debugheader.h -SOURCES += core.cpp \ - rectangle.cpp \ - tile.cpp \ - tilematrix.cpp \ - pureprojection.cpp \ - rectlatlng.cpp \ - sizelatlng.cpp \ - pointlatlng.cpp \ - loadtask.cpp \ - mousewheelzoomtype.cpp -HEADERS += ./projections/lks94projection.h \ - ./projections/mercatorprojection.h \ - ./projections/mercatorprojectionyandex.h \ - ./projections/platecarreeprojection.h \ - ./projections/platecarreeprojectionpergo.h -SOURCES += ./projections/lks94projection.cpp \ - ./projections/mercatorprojection.cpp \ - ./projections/mercatorprojectionyandex.cpp \ - ./projections/platecarreeprojection.cpp \ - ./projections/platecarreeprojectionpergo.cpp -LIBS += -L../build \ - -lcore diff --git a/libs/opmapcontrol/src/internals/loadtask.cpp b/libs/opmapcontrol/src/internals/loadtask.cpp deleted file mode 100644 index 2a8ec767f..000000000 --- a/libs/opmapcontrol/src/internals/loadtask.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/** -****************************************************************************** -* -* @file loadtask.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "loadtask.h" - - -namespace internals { -bool operator==(LoadTask const& lhs,LoadTask const& rhs) -{ - return ((lhs.Pos==rhs.Pos)&&(lhs.Zoom==rhs.Zoom)); -} -} diff --git a/libs/opmapcontrol/src/internals/loadtask.h b/libs/opmapcontrol/src/internals/loadtask.h deleted file mode 100644 index d642992aa..000000000 --- a/libs/opmapcontrol/src/internals/loadtask.h +++ /dev/null @@ -1,65 +0,0 @@ -/** -****************************************************************************** -* -* @file loadtask.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef LOADTASK_H -#define LOADTASK_H - -#include -#include "../core/point.h" - -using namespace core; -namespace internals -{ -struct LoadTask - { - friend bool operator==(LoadTask const& lhs,LoadTask const& rhs); - public: - core::Point Pos; - int Zoom; - - - LoadTask(Point pos, int zoom) - { - Pos = pos; - Zoom = zoom; - } - LoadTask() - { - Pos=core::Point(-1,-1); - Zoom=-1; - } - bool HasValue() - { - return !(Zoom==-1); - } - - QString ToString()const - { - return QString::number(Zoom) + " - " + Pos.ToString(); - } - }; -} -#endif // LOADTASK_H diff --git a/libs/opmapcontrol/src/internals/mousewheelzoomtype.h b/libs/opmapcontrol/src/internals/mousewheelzoomtype.h deleted file mode 100644 index d22eb6b38..000000000 --- a/libs/opmapcontrol/src/internals/mousewheelzoomtype.h +++ /dev/null @@ -1,89 +0,0 @@ -/** -****************************************************************************** -* -* @file mousewheelzoomtype.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MOUSEWHEELZOOMTYPE_H -#define MOUSEWHEELZOOMTYPE_H -#include -#include -#include -#include -#include -namespace internals { - class MouseWheelZoomType:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - /// - /// zooms map to current mouse position and makes it map center - /// - MousePositionAndCenter, - - /// - /// zooms to current mouse position, but doesn't make it map center, - /// google/bing style ;} - /// - MousePositionWithoutCenter, - - /// - /// zooms map to current view center - /// - ViewCenter - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = MouseWheelZoomType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = MouseWheelZoomType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = MouseWheelZoomType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;x -#include -#include "sizelatlng.h" - -namespace internals { -struct PointLatLng -{ - //friend uint qHash(PointLatLng const& point); - friend bool operator==(PointLatLng const& lhs,PointLatLng const& rhs); - friend bool operator!=(PointLatLng const& left, PointLatLng const& right); - friend PointLatLng operator+(PointLatLng pt, SizeLatLng sz); - friend PointLatLng operator-(PointLatLng pt, SizeLatLng sz); - - //TODO Sizelatlng friend PointLatLng operator+(PointLatLng pt, SizeLatLng sz); - - private: - double lat; - double lng; - bool empty; - public: - PointLatLng(); - - - static PointLatLng Empty; - - PointLatLng(const double &lat,const double &lng) - { - this->lat = lat; - this->lng = lng; - empty=false; - } - - bool IsEmpty() - { - return empty; - } - - double Lat()const - { - return this->lat; - } - - void SetLat(const double &value) - { - this->lat = value; - empty=false; - } - - - double Lng()const - { - return this->lng; - } - void SetLng(const double &value) - { - this->lng = value; - empty=false; - } - - - - - - static PointLatLng Add(PointLatLng const& pt, SizeLatLng const& sz) - { - return PointLatLng(pt.Lat() - sz.HeightLat(), pt.Lng() + sz.WidthLng()); - } - - static PointLatLng Subtract(PointLatLng const& pt, SizeLatLng const& sz) - { - return PointLatLng(pt.Lat() + sz.HeightLat(), pt.Lng() - sz.WidthLng()); - } - - - void Offset(PointLatLng const& pos) - { - this->Offset(pos.Lat(), pos.Lng()); - } - - void Offset(double const& lat, double const& lng) - { - this->lng += lng; - this->lat -= lat; - } - - - QString ToString()const - { - return QString("{Lat=%1, Lng=%2}").arg(this->lat).arg(this->lng); - } - -//// static PointLatLng() -//// { -//// Empty = new PointLatLng(); -//// } - }; - - -// -} -#endif // POINTLATLNG_H diff --git a/libs/opmapcontrol/src/internals/projections/lks94projection.cpp b/libs/opmapcontrol/src/internals/projections/lks94projection.cpp deleted file mode 100644 index 4b72d57ce..000000000 --- a/libs/opmapcontrol/src/internals/projections/lks94projection.cpp +++ /dev/null @@ -1,799 +0,0 @@ -/** -****************************************************************************** -* -* @file lks94projection.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "lks94projection.h" -#include - - -// These pragmas are local modifications to this third party library to silence warnings -#ifdef Q_OS_LINUX -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#endif - -namespace projections { -LKS94Projection::LKS94Projection():MinLatitude (53.33 ), MaxLatitude (56.55 ), MinLongitude (20.22 ), -MaxLongitude (27.11 ), orignX (5122000 ), orignY (10000100 ),tileSize(256, 256) -{ -} - -Size LKS94Projection::TileSize() const -{ - return tileSize; -} -double LKS94Projection::Axis() const -{ - return 6378137; -} -double LKS94Projection::Flattening() const -{ - - return (1.0 / 298.257222101); - -} - -Point LKS94Projection::FromLatLngToPixel(double lat, double lng, int const& zoom) -{ - Point ret; - - lat = Clip(lat, MinLatitude, MaxLatitude); - lng = Clip(lng, MinLongitude, MaxLongitude); - QVector lks(3); - lks[0]=lng; - lks[1]=lat; - lks = DTM10(lks); - lks = MTD10(lks); - lks = DTM00(lks); - - double res = GetTileMatrixResolution(zoom); - - ret.SetX((int) floor((lks[0] + orignX) / res)); - ret.SetY((int) floor((orignY - lks[1]) / res)); - - return ret; -} - -internals::PointLatLng LKS94Projection::FromPixelToLatLng(int const& x, int const& y, int const& zoom) -{ - internals::PointLatLng ret;// = internals::PointLatLng::Empty; - - double res = GetTileMatrixResolution(zoom); - - QVector lks(2); - lks[0]=(x * res) - orignX; - lks[1]=-(y * res) + orignY; - lks = MTD11(lks); - lks = DTM10(lks); - lks = MTD10(lks); - ret.SetLat(Clip(lks[1], MinLatitude, MaxLatitude)); - ret.SetLng(Clip(lks[0], MinLongitude, MaxLongitude)); - return ret; -} - -QVector LKS94Projection::DTM10(const QVector & lonlat) -{ - double es; // Eccentricity squared : (a^2 - b^2)/a^2 - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3142451793; // minor axis - double ab; // Semi_major / semi_minor - double ba; // Semi_minor / semi_major - double ses; // Second eccentricity squared : (a^2 - b^2)/b^2 - - es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); //e^2 - ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2); - ba = semiMinor / semiMajor; - ab = semiMajor / semiMinor; - - // ... - - double lon = DegreesToRadians(lonlat[0]); - double lat = DegreesToRadians(lonlat[1]); - double h = lonlat.count() < 3 ? 0 : (lonlat[2] != lonlat[2]) ? 0 : lonlat[2];//TODO NAN - double v = semiMajor / sqrt(1 - es * pow(sin(lat), 2)); - double x = (v + h) * cos(lat) * cos(lon); - double y = (v + h) * cos(lat) * sin(lon); - double z = ((1 - es) * v + h) * sin(lat); - QVector ret(3); - ret[0]=x; - ret[1]=y; - ret[2]=z; - return ret; -} -QVector LKS94Projection::MTD10(QVector & pnt) -{ - QVector ret(3); - const double COS_67P5 = 0.38268343236508977; // cosine of 67.5 degrees - const double AD_C = 1.0026000; // Toms region 1 constant - - double es; // Eccentricity squared : (a^2 - b^2)/a^2 - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3141403561; // minor axis - double ab; // Semi_major / semi_minor - double ba; // Semi_minor / semi_major - double ses; // Second eccentricity squared : (a^2 - b^2)/b^2 - - es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); //e^2 - ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2); - ba = semiMinor / semiMajor; - ab = semiMajor / semiMinor; - - // ... - - bool AtPole = false; // is location in polar region - double Z = pnt.count() < 3 ? 0 : (pnt[2] != pnt[2]) ? 0 : pnt[2];//TODO NaN - - double lon = 0; - double lat = 0; - double Height = 0; - if(pnt[0] != 0.0) - { - lon = atan2(pnt[1], pnt[0]); - } - else - { - if(pnt[1] > 0) - { - lon = M_PI / 2; - } - else - if(pnt[1] < 0) - { - lon = -M_PI * 0.5; - } - else - { - AtPole = true; - lon = 0.0; - if(Z > 0.0) // north pole - { - lat = M_PI * 0.5; - } - else - if(Z < 0.0) // south pole - { - lat = -M_PI * 0.5; - } - else // center of earth - { - ret[0]=RadiansToDegrees(lon); - ret[1]=RadiansToDegrees(M_PI * 0.5); - ret[2]=-semiMinor; - return ret; - } - } - } - double W2 = pnt[0] * pnt[0] + pnt[1] * pnt[1]; // Square of distance from Z axis - double W = sqrt(W2); // distance from Z axis - double T0 = Z * AD_C; // initial estimate of vertical component - double S0 = sqrt(T0 * T0 + W2); // initial estimate of horizontal component - double Sin_B0 = T0 / S0; // sin(B0), B0 is estimate of Bowring aux variable - double Cos_B0 = W / S0; // cos(B0) - double Sin3_B0 = pow(Sin_B0, 3); - double T1 = Z + semiMinor * ses * Sin3_B0; // corrected estimate of vertical component - double Sum = W - semiMajor * es * Cos_B0 * Cos_B0 * Cos_B0; // numerator of cos(phi1) - double S1 = sqrt(T1 * T1 + Sum * Sum); // corrected estimate of horizontal component - double Sin_p1 = T1 / S1; // sin(phi1), phi1 is estimated latitude - double Cos_p1 = Sum / S1; // cos(phi1) - double Rn = semiMajor / sqrt(1.0 - es * Sin_p1 * Sin_p1); // Earth radius at location - if(Cos_p1 >= COS_67P5) - { - Height = W / Cos_p1 - Rn; - } - else - if(Cos_p1 <= -COS_67P5) - { - Height = W / -Cos_p1 - Rn; - } - else - { - Height = Z / Sin_p1 + Rn * (es - 1.0); - } - - if(!AtPole) - { - lat = atan(Sin_p1 / Cos_p1); - } - ret[0]=RadiansToDegrees(lon); - ret[1]=RadiansToDegrees(lat); - ret[2]=Height; - return ret; -} -QVector LKS94Projection::DTM00(QVector & lonlat) -{ - double scaleFactor = 0.9998; // scale factor - double centralMeridian = 0.41887902047863912; // Center qlonglongitude (projection center) */ - double latOrigin = 0.0; // center latitude - double falseNorthing = 0.0; // y offset in meters - double falseEasting = 500000.0; // x offset in meters - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3141403561; // minor axis - double metersPerUnit = 1.0; - - double e0, e1, e2, e3; // eccentricity constants - double e, es, esp; // eccentricity constants - double ml0; // small value m - - es = 1.0 - pow(semiMinor / semiMajor, 2); - e = sqrt(es); - e0 = e0fn(es); - e1 = e1fn(es); - e2 = e2fn(es); - e3 = e3fn(es); - ml0 = semiMajor * mlfn(e0, e1, e2, e3, latOrigin); - esp = es / (1.0 - es); - - // ... - - double lon = DegreesToRadians(lonlat[0]); - double lat = DegreesToRadians(lonlat[1]); - - double delta_lon = 0.0; // Delta qlonglongitude (Given qlonglongitude - center) - double sin_phi, cos_phi; // sin and cos value - double al, als; // temporary values - double c, t, tq; // temporary values - double con, n, ml; // cone constant, small m - - delta_lon = LKS94Projection::AdjustLongitude(lon - centralMeridian); - LKS94Projection::SinCos(lat, sin_phi, cos_phi); - - al = cos_phi * delta_lon; - als = pow(al, 2); - c = pow(cos_phi, 2); - tq = tan(lat); - t = pow(tq, 2); - con = 1.0 - es * pow(sin_phi, 2); - n = semiMajor / sqrt(con); - ml = semiMajor * mlfn(e0, e1, e2, e3, lat); - - double x = scaleFactor * n * al * (1.0 + als / 6.0 * (1.0 - t + c + als / 20.0 * - (5.0 - 18.0 * t + pow(t, 2) + 72.0 * c - 58.0 * esp))) + falseEasting; - - double y = scaleFactor * (ml - ml0 + n * tq * (als * (0.5 + als / 24.0 * - (5.0 - t + 9.0 * c + 4.0 * pow(c, 2) + als / 30.0 * (61.0 - 58.0 * t - + pow(t, 2) + 600.0 * c - 330.0 * esp))))) + falseNorthing; - - if(lonlat.count() < 3) - { - QVector ret(2); - ret[0]= x / metersPerUnit; - ret[1]= y / metersPerUnit; - return ret; - } - else - { - QVector ret(3); - ret[0]= x / metersPerUnit; - ret[1]= y / metersPerUnit; - ret[2]=lonlat[2]; - return ret; - } -} - -QVector LKS94Projection::DTM01(QVector & lonlat) -{ - double es; // Eccentricity squared : (a^2 - b^2)/a^2 - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3141403561; // minor axis - double ab; // Semi_major / semi_minor - double ba; // Semi_minor / semi_major - double ses; // Second eccentricity squared : (a^2 - b^2)/b^2 - - es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); - ses = (pow(semiMajor, 2) -pow(semiMinor, 2)) / pow(semiMinor, 2); - ba = semiMinor / semiMajor; - ab = semiMajor / semiMinor; - - // ... - - double lon = DegreesToRadians(lonlat[0]); - double lat = DegreesToRadians(lonlat[1]); - double h = lonlat.count() < 3 ? 0 : (lonlat[2] != lonlat[2]) ? 0 : lonlat[2];//TODO NaN - double v = semiMajor / sqrt(1 - es * pow(sin(lat), 2.0)); - double x = (v + h) * cos(lat) * cos(lon); - double y = (v + h) * cos(lat) * sin(lon); - double z = ((1 - es) * v + h) * sin(lat); - QVector ret(3); - ret[0]=x; - ret[1]=y; - ret[2]=z; - return ret; -} -QVector LKS94Projection::MTD01(QVector & pnt) -{ - const double COS_67P5 = 0.38268343236508977; // cosine of 67.5 degrees - const double AD_C = 1.0026000; // Toms region 1 constant - - double es; // Eccentricity squared : (a^2 - b^2)/a^2 - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3142451793; // minor axis - double ab; // Semi_major / semi_minor - double ba; // Semi_minor / semi_major - double ses; // Second eccentricity squared : (a^2 - b^2)/b^2 - - es = 1.0 - (semiMinor * semiMinor) / (semiMajor * semiMajor); - ses = (pow(semiMajor, 2) - pow(semiMinor, 2)) / pow(semiMinor, 2); - ba = semiMinor / semiMajor; - ab = semiMajor / semiMinor; - - // ... - - bool At_Pole = false; // is location in polar region - double Z = pnt.count() < 3 ? 0 : (pnt[2] != pnt[2]) ? 0 : pnt[2];//TODO NaN - - double lon = 0; - double lat = 0; - double Height = 0; - if(pnt[0] != 0.0) - { - lon = atan2(pnt[1], pnt[0]); - } - else - { - if(pnt[1] > 0) - { - lon = M_PI / 2; - } - else - if(pnt[1] < 0) - { - lon = -M_PI * 0.5; - } - else - { - At_Pole = true; - lon = 0.0; - if(Z > 0.0) // north pole - { - lat = M_PI * 0.5; - } - else - if(Z < 0.0) // south pole - { - lat = -M_PI * 0.5; - } - else // center of earth - { - QVector ret(3); - ret[0]=RadiansToDegrees(lon); - ret[1]=RadiansToDegrees(M_PI * 0.5); - ret[2]=-semiMinor; - return ret; - } - } - } - - double W2 = pnt[0] * pnt[0] + pnt[1] * pnt[1]; // Square of distance from Z axis - double W = sqrt(W2); // distance from Z axis - double T0 = Z * AD_C; // initial estimate of vertical component - double S0 = sqrt(T0 * T0 + W2); //initial estimate of horizontal component - double Sin_B0 = T0 / S0; // sin(B0), B0 is estimate of Bowring aux variable - double Cos_B0 = W / S0; // cos(B0) - double Sin3_B0 = pow(Sin_B0, 3); - double T1 = Z + semiMinor * ses * Sin3_B0; //corrected estimate of vertical component - double Sum = W - semiMajor * es * Cos_B0 * Cos_B0 * Cos_B0; // numerator of cos(phi1) - double S1 = sqrt(T1 * T1 + Sum * Sum); // corrected estimate of horizontal component - double Sin_p1 = T1 / S1; // sin(phi1), phi1 is estimated latitude - double Cos_p1 = Sum / S1; // cos(phi1) - double Rn = semiMajor / sqrt(1.0 - es * Sin_p1 * Sin_p1); // Earth radius at location - - if(Cos_p1 >= COS_67P5) - { - Height = W / Cos_p1 - Rn; - } - else - if(Cos_p1 <= -COS_67P5) - { - Height = W / -Cos_p1 - Rn; - } - else - { - Height = Z / Sin_p1 + Rn * (es - 1.0); - } - - if(!At_Pole) - { - lat = atan(Sin_p1 / Cos_p1); - } - QVector ret(3); - ret[0]=RadiansToDegrees(lon); - ret[1]=RadiansToDegrees(lat); - ret[2]=Height; - return ret; -} -QVector LKS94Projection::MTD11(QVector & p) -{ - double scaleFactor = 0.9998; // scale factor - double centralMeridian = 0.41887902047863912; // Center qlonglongitude (projection center) - double latOrigin = 0.0; // center latitude - double falseNorthing = 0.0; // y offset in meters - double falseEasting = 500000.0; // x offset in meters - double semiMajor = 6378137.0; // major axis - double semiMinor = 6356752.3141403561; // minor axis - double metersPerUnit = 1.0; - - double e0, e1, e2, e3; // eccentricity constants - double e, es, esp; // eccentricity constants - double ml0; // small value m - - es =(semiMinor * semiMinor) / (semiMajor * semiMajor); - es=1.0-es; - e = sqrt(es); - e0 = e0fn(es); - e1 = e1fn(es); - e2 = e2fn(es); - e3 = e3fn(es); - ml0 = semiMajor * mlfn(e0, e1, e2, e3, latOrigin); - esp = es / (1.0 - es); - - // ... - - double con, phi; - double delta_phi; - qlonglong i; - double sin_phi, cos_phi, tan_phi; - double c, cs, t, ts, n, r, d, ds; - qlonglong max_iter = 6; - - double x = p[0] * metersPerUnit - falseEasting; - double y = p[1] * metersPerUnit - falseNorthing; - - con = (ml0 + y / scaleFactor) / semiMajor; - phi = con; - for(i = 0; ; i++) - { - delta_phi = ((con + e1 * sin(2.0 * phi) - e2 * sin(4.0 * phi) + e3 * sin(6.0 * phi)) / e0) - phi; - phi += delta_phi; - if(fabs(delta_phi) <= EPSLoN) - break; - - if(i >= max_iter) - throw "Latitude failed to converge"; - } - - if(fabs(phi) < HALF_PI) - { - SinCos(phi, sin_phi, cos_phi); - tan_phi = tan(phi); - c = esp * pow(cos_phi, 2); - cs = pow(c, 2); - t = pow(tan_phi, 2); - ts = pow(t, 2); - con = 1.0 - es * pow(sin_phi, 2); - n = semiMajor / sqrt(con); - r = n * (1.0 - es) / con; - d = x / (n * scaleFactor); - ds = pow(d, 2); - - double lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24.0 * (5.0 + 3.0 * t + - 10.0 * c - 4.0 * cs - 9.0 * esp - ds / 30.0 * (61.0 + 90.0 * t + - 298.0 * c + 45.0 * ts - 252.0 * esp - 3.0 * cs))); - - double lon = AdjustLongitude(centralMeridian + (d * (1.0 - ds / 6.0 * (1.0 + 2.0 * t + - c - ds / 20.0 * (5.0 - 2.0 * c + 28.0 * t - 3.0 * cs + 8.0 * esp + - 24.0 * ts))) / cos_phi)); - - if(p.count() < 3) - { - QVector ret(2); - ret[0]= RadiansToDegrees(lon); - ret[1]= RadiansToDegrees(lat); - return ret; - } - else - { - QVector ret(3); - ret[0]= RadiansToDegrees(lon); - ret[1]= RadiansToDegrees(lat); - ret[2]=p[2]; - return ret; - //return new double[] { RadiansToDegrees(lon), RadiansToDegrees(lat), p[2] }; - } - } - else - { - if(p.count() < 3) - { - QVector ret(2); - ret[0]= RadiansToDegrees(HALF_PI * Sign(y)); - ret[1]= RadiansToDegrees(centralMeridian); - return ret; - } - - else - { - QVector ret(3); - ret[0]= RadiansToDegrees(HALF_PI * Sign(y)); - ret[1]= RadiansToDegrees(centralMeridian); - ret[2]=p[2]; - return ret; - } - - } -} - -double LKS94Projection::Clip(double const& n, double const& minValue, double const& maxValue) -{ - return qMin(qMax(n, minValue), maxValue); -} -double LKS94Projection::GetTileMatrixResolution(int const& zoom) -{ - double ret = 0; - - switch(zoom) - { - case 0: - { - ret = 1587.50317500635; - } - break; - - case 1: - { - ret = 793.751587503175; - } - break; - - case 2: - { - ret = 529.167725002117; - } - break; - - case 3: - { - ret = 264.583862501058; - } - break; - - case 4: - { - ret = 132.291931250529; - } - break; - - case 5: - { - ret = 52.9167725002117; - } - break; - - case 6: - { - ret = 26.4583862501058; - } - break; - - case 7: - { - ret = 13.2291931250529; - } - break; - - case 8: - { - ret = 6.61459656252646; - } - break; - - case 9: - { - ret = 2.64583862501058; - } - break; - - case 10: - { - ret = 1.32291931250529; - } - break; - - case 11: - { - ret = 0.529167725002117; - } - break; - - } - - return ret; -} -double LKS94Projection::GetGroundResolution(int const& zoom, double const& latitude) -{ - Q_UNUSED(zoom); - Q_UNUSED(latitude); - return GetTileMatrixResolution(zoom); -} -Size LKS94Projection::GetTileMatrixMinXY(int const& zoom) -{ - Size ret; - - switch(zoom) - { - - case 0: - { - ret = Size(12, 8); - } - break; - - case 1: - { - ret = Size(24, 17); - } - break; - - case 2: - { - ret = Size(37, 25); - } - break; - - case 3: - { - ret = Size(74, 51); - } - break; - - case 4: - { - ret = Size(149, 103); - } - break; - - case 5: - { - ret = Size(374, 259); - } - break; - - case 6: - { - ret = Size(749, 519); - } - break; - - case 7: - { - ret = Size(1594, 1100); - } - break; - - case 8: - { - ret = Size(3188, 2201); - } - break; - - case 9: - { - ret = Size(7971, 5502); - } - break; - - case 10: - { - ret = Size(15943, 11005); - } - break; - - case 11: - { - ret = Size(39858, 27514); - } - break; - } - - return ret; -} - -Size LKS94Projection::GetTileMatrixMaxXY(int const& zoom) -{ - Size ret; - - switch(zoom) - { - case 0: - { - ret = Size(14, 10); - } - break; - - case 1: - { - ret = Size(30, 20); - } - break; - - case 2: - { - ret = Size(45, 31); - } - break; - - case 3: - { - ret = Size(90, 62); - } - break; - - case 4: - { - ret = Size(181, 125); - } - break; - - case 5: - { - ret = Size(454, 311); - } - break; - - case 6: - { - ret = Size(903, 623); - } - break; - - case 7: - { - ret = Size(1718, 1193); - } - break; - - case 8: - { - ret = Size(3437, 2386); - } - break; - - case 9: - { - ret = Size(8594, 5966); - } - break; - - case 10: - { - ret = Size(17189, 11932); - } - break; - - case 11: - { - ret = Size(42972, 29831); - } - break; - } - - return ret; -} - -} - -#ifdef Q_OS_LINUX -#pragma GCC diagnostic pop -#endif - diff --git a/libs/opmapcontrol/src/internals/projections/lks94projection.h b/libs/opmapcontrol/src/internals/projections/lks94projection.h deleted file mode 100644 index 8e5d5efb6..000000000 --- a/libs/opmapcontrol/src/internals/projections/lks94projection.h +++ /dev/null @@ -1,72 +0,0 @@ -/** -****************************************************************************** -* -* @file lks94projection.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef LKS94PROJECTION_H -#define LKS94PROJECTION_H -#include -#include "cmath" -#include "../pureprojection.h" - - -namespace projections { -class LKS94Projection:public internals::PureProjection -{ -public: - LKS94Projection(); - double GetTileMatrixResolution(int const& zoom); - virtual QString Type(){return "LKS94Projection";} - virtual Size TileSize() const; - virtual double Axis() const; - virtual double Flattening() const; - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom); - virtual internals::PointLatLng FromPixelToLatLng(int const& x, int const& y, int const& zoom); - virtual double GetGroundResolution(int const& zoom, double const& latitude); - virtual Size GetTileMatrixMinXY(int const& zoom); - virtual Size GetTileMatrixMaxXY(int const& zoom); - -private: - const double MinLatitude; - const double MaxLatitude; - const double MinLongitude; - const double MaxLongitude; - const double orignX; - const double orignY; - Size tileSize; - QVector DTM10(const QVector & lonlat); - QVector MTD10(QVector & pnt); - QVector DTM00(QVector & lonlat); - QVector DTM01(QVector & lonlat); - QVector MTD01(QVector & pnt); - QVector MTD11(QVector & p); - double Clip(double const& n, double const& minValue, double const& maxValue); -}; - -} -#endif // LKS94PROJECTION_H - - - - diff --git a/libs/opmapcontrol/src/internals/projections/mercatorprojection.cpp b/libs/opmapcontrol/src/internals/projections/mercatorprojection.cpp deleted file mode 100644 index aa286ca20..000000000 --- a/libs/opmapcontrol/src/internals/projections/mercatorprojection.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/** -****************************************************************************** -* -* @file mercatorprojection.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "mercatorprojection.h" -#include - -namespace projections { -MercatorProjection::MercatorProjection():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-177), -MaxLongitude(177), tileSize(256, 256) -{ -} -Point MercatorProjection::FromLatLngToPixel(double lat, double lng, const int &zoom) -{ - Point ret;// = Point.Empty; - - lat = Clip(lat, MinLatitude, MaxLatitude); - lng = Clip(lng, MinLongitude, MaxLongitude); - - double x = (lng + 180) / 360; - double sinLatitude = sin(lat * M_PI / 180); - double y = 0.5 - log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * M_PI); - - Size s = GetTileMatrixSizePixel(zoom); - int mapSizeX = s.Width(); - int mapSizeY = s.Height(); - - ret.SetX((int) Clip(x * mapSizeX + 0.5, 0, mapSizeX - 1)); - ret.SetY((int) Clip(y * mapSizeY + 0.5, 0, mapSizeY - 1)); - - return ret; -} -internals::PointLatLng MercatorProjection::FromPixelToLatLng(const int &x, const int &y, const int &zoom) -{ - internals::PointLatLng ret;// = internals::PointLatLng.Empty; - - Size s = GetTileMatrixSizePixel(zoom); - double mapSizeX = s.Width(); - double mapSizeY = s.Height(); - - double xx = (Clip(x, 0, mapSizeX - 1) / mapSizeX) - 0.5; - double yy = 0.5 - (Clip(y, 0, mapSizeY - 1) / mapSizeY); - - ret.SetLat(90 - 360 * atan(exp(-yy * 2 * M_PI)) / M_PI); - ret.SetLng(360 * xx); - - return ret; -} -double MercatorProjection::Clip(const double &n, const double &minValue, const double &maxValue) const -{ - return qMin(qMax(n, minValue), maxValue); -} -Size MercatorProjection::TileSize() const -{ - return tileSize; -} -double MercatorProjection::Axis() const -{ - return 6378137; -} -double MercatorProjection::Flattening() const -{ - return (1.0 / 298.257223563); -} -Size MercatorProjection::GetTileMatrixMaxXY(const int &zoom) -{ - Q_UNUSED(zoom); - int xy = (1 << zoom); - return Size(xy - 1, xy - 1); -} -Size MercatorProjection::GetTileMatrixMinXY(const int &zoom) -{ - Q_UNUSED(zoom); - return Size(0, 0); -} -} diff --git a/libs/opmapcontrol/src/internals/projections/mercatorprojection.h b/libs/opmapcontrol/src/internals/projections/mercatorprojection.h deleted file mode 100644 index 6409b0878..000000000 --- a/libs/opmapcontrol/src/internals/projections/mercatorprojection.h +++ /dev/null @@ -1,55 +0,0 @@ -/** -****************************************************************************** -* -* @file mercatorprojection.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MERCATORPROJECTION_H -#define MERCATORPROJECTION_H -#include "../pureprojection.h" - - -namespace projections { - class MercatorProjection:public internals::PureProjection -{ -public: - MercatorProjection(); - virtual QString Type(){return "MercatorProjection";} - virtual Size TileSize() const; - virtual double Axis() const; - virtual double Flattening()const; - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom); - virtual internals::PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom); - virtual Size GetTileMatrixMinXY(const int &zoom); - virtual Size GetTileMatrixMaxXY(const int &zoom); -private: - const double MinLatitude; - const double MaxLatitude; - const double MinLongitude; - const double MaxLongitude; - double Clip(double const& n, double const& minValue, double const& maxValue)const; - Size tileSize; -}; - -} -#endif // MERCATORPROJECTION_H diff --git a/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.cpp b/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.cpp deleted file mode 100644 index 81b47b6d7..000000000 --- a/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.cpp +++ /dev/null @@ -1,127 +0,0 @@ -/** -****************************************************************************** -* -* @file mercatorprojectionyandex.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "mercatorprojectionyandex.h" -#include - - -namespace projections { -MercatorProjectionYandex::MercatorProjectionYandex():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-177), -MaxLongitude(177), RAD_DEG(180 / M_PI),DEG_RAD(M_PI / 180),MathPiDiv4(M_PI / 4),tileSize(256, 256) -{ -} -Point MercatorProjectionYandex::FromLatLngToPixel(double lat, double lng, const int &zoom) -{ - lat = Clip(lat, MinLatitude, MaxLatitude); - lng = Clip(lng, MinLongitude, MaxLongitude); - - double rLon = lng * DEG_RAD; // Math.PI / 180; - double rLat = lat * DEG_RAD; // Math.PI / 180; - - double a = 6378137; - double k = 0.0818191908426; - - double z = tan(MathPiDiv4 + rLat / 2) / pow((tan(MathPiDiv4 + asin(k * sin(rLat)) / 2)), k); - double z1 = pow(2.0, 23 - zoom); - - double DX = ((20037508.342789 + a * rLon) * 53.5865938 / z1); - double DY = ((20037508.342789 - a * log(z)) * 53.5865938 / z1); - - Point ret;// = Point.Empty; - ret.SetX((int) DX); - ret.SetY((int) DY); - - return ret; - -} - -// These pragmas are local modifications to this third party library to silence warnings -#ifdef Q_OS_LINUX -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" -#elif defined(Q_OS_MAC) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" -#endif - -internals::PointLatLng MercatorProjectionYandex::FromPixelToLatLng(const int &x, const int &y, const int &zoom) -{ - Size s = GetTileMatrixSizePixel(zoom); - - //double mapSizeX = s.Width(); - //double mapSizeY = s.Height(); - - double a = 6378137; - double c1 = 0.00335655146887969; - double c2 = 0.00000657187271079536; - double c3 = 0.00000001764564338702; - double c4 = 0.00000000005328478445; - double z1 = (23 - zoom); - double mercX = (x * pow(2, z1)) / 53.5865938 - 20037508.342789; - double mercY = 20037508.342789 - (y *pow(2, z1)) / 53.5865938; - - double g = M_PI /2 - 2 *atan(1 / exp(mercY /a)); - double z = g + c1 * sin(2 * g) + c2 * sin(4 * g) + c3 * sin(6 * g) + c4 * sin(8 * g); - - internals::PointLatLng ret;// = internals::PointLatLng.Empty; - ret.SetLat(z * RAD_DEG); - ret.SetLng (mercX / a * RAD_DEG); - - return ret; -} - -#ifndef Q_OS_WIN -#pragma GCC diagnostic pop -#endif - -double MercatorProjectionYandex::Clip(const double &n, const double &minValue, const double &maxValue) const -{ - return qMin(qMax(n, minValue), maxValue); -} -Size MercatorProjectionYandex::TileSize() const -{ - return tileSize; -} -double MercatorProjectionYandex::Axis() const -{ - return 6356752.3142; -} -double MercatorProjectionYandex::Flattening() const -{ - return (1.0 / 298.257223563); -} -Size MercatorProjectionYandex::GetTileMatrixMaxXY(const int &zoom) -{ - int xy = (1 << zoom); - return Size(xy - 1, xy - 1); -} - -Size MercatorProjectionYandex::GetTileMatrixMinXY(const int &zoom) -{ - Q_UNUSED(zoom); - return Size(0, 0); -} -} diff --git a/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.h b/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.h deleted file mode 100644 index 0102797e2..000000000 --- a/libs/opmapcontrol/src/internals/projections/mercatorprojectionyandex.h +++ /dev/null @@ -1,59 +0,0 @@ -/** -****************************************************************************** -* -* @file mercatorprojectionyandex.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MERCATORPROJECTIONYANDEX_H -#define MERCATORPROJECTIONYANDEX_H - -#include "../pureprojection.h" - - -namespace projections { - class MercatorProjectionYandex:public internals::PureProjection -{ -public: - MercatorProjectionYandex(); - virtual QString Type(){return "MercatorProjectionYandex";} - virtual Size TileSize() const; - virtual double Axis() const; - virtual double Flattening()const; - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom); - virtual internals::PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom); - virtual Size GetTileMatrixMinXY(const int &zoom); - virtual Size GetTileMatrixMaxXY(const int &zoom); -private: - const double MinLatitude; - const double MaxLatitude; - const double MinLongitude; - const double MaxLongitude; - const double RAD_DEG; - const double DEG_RAD; - const double MathPiDiv4; - double Clip(double const& n, double const& minValue, double const& maxValue)const; - Size tileSize; -}; - -} -#endif // MERCATORPROJECTIONYANDEX_H diff --git a/libs/opmapcontrol/src/internals/projections/platecarreeprojection.cpp b/libs/opmapcontrol/src/internals/projections/platecarreeprojection.cpp deleted file mode 100644 index dcab6afb1..000000000 --- a/libs/opmapcontrol/src/internals/projections/platecarreeprojection.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/** -****************************************************************************** -* -* @file platecarreeprojection.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "platecarreeprojection.h" - - - -namespace projections { -PlateCarreeProjection::PlateCarreeProjection():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-180), -MaxLongitude(180), tileSize(512, 512) -{ -} -Point PlateCarreeProjection::FromLatLngToPixel(double lat, double lng, const int &zoom) -{ - Point ret;// = Point.Empty; - - lat = Clip(lat, MinLatitude, MaxLatitude); - lng = Clip(lng, MinLongitude, MaxLongitude); - - Size s = GetTileMatrixSizePixel(zoom); - double mapSizeX = s.Width(); - //double mapSizeY = s.Height(); - - double scale = 360.0 / mapSizeX; - - ret.SetY((int) ((90.0 - lat) / scale)); - ret.SetX((int) ((lng + 180.0) / scale)); - - return ret; - -} -internals::PointLatLng PlateCarreeProjection::FromPixelToLatLng(const int &x, const int &y, const int &zoom) -{ - internals::PointLatLng ret;// = internals::PointLatLng.Empty; - - Size s = GetTileMatrixSizePixel(zoom); - double mapSizeX = s.Width(); - //double mapSizeY = s.Height(); - - double scale = 360.0 / mapSizeX; - - ret.SetLat(90 - (y * scale)); - ret.SetLng((x * scale) - 180); - - return ret; -} -double PlateCarreeProjection::Clip(const double &n, const double &minValue, const double &maxValue) const -{ - return qMin(qMax(n, minValue), maxValue); -} -Size PlateCarreeProjection::TileSize() const -{ - return tileSize; -} -double PlateCarreeProjection::Axis() const -{ - return 6378137; -} -double PlateCarreeProjection::Flattening() const -{ - return (1.0 / 298.257223563); -} -Size PlateCarreeProjection::GetTileMatrixMaxXY(const int &zoom) -{ - int y = (int) pow(2.0f, zoom); - return Size((2*y) - 1, y - 1); -} - -Size PlateCarreeProjection::GetTileMatrixMinXY(const int &zoom) -{ - Q_UNUSED(zoom); - return Size(0, 0); -} -} diff --git a/libs/opmapcontrol/src/internals/projections/platecarreeprojection.h b/libs/opmapcontrol/src/internals/projections/platecarreeprojection.h deleted file mode 100644 index d0715c10a..000000000 --- a/libs/opmapcontrol/src/internals/projections/platecarreeprojection.h +++ /dev/null @@ -1,56 +0,0 @@ -/** -****************************************************************************** -* -* @file platecarreeprojection.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PLATECARREEPROJECTION_H -#define PLATECARREEPROJECTION_H - -#include "../pureprojection.h" - - -namespace projections { -class PlateCarreeProjection:public internals::PureProjection -{ -public: - PlateCarreeProjection(); - virtual QString Type(){return "PlateCarreeProjection";} - virtual Size TileSize() const; - virtual double Axis() const; - virtual double Flattening()const; - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom); - virtual internals::PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom); - virtual Size GetTileMatrixMinXY(const int &zoom); - virtual Size GetTileMatrixMaxXY(const int &zoom); -private: - const double MinLatitude; - const double MaxLatitude; - const double MinLongitude; - const double MaxLongitude; - - double Clip(double const& n, double const& minValue, double const& maxValue)const; - Size tileSize; -}; -} -#endif // PLATECARREEPROJECTION_H diff --git a/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.cpp b/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.cpp deleted file mode 100644 index b41916aa4..000000000 --- a/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/** -****************************************************************************** -* -* @file platecarreeprojectionpergo.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "platecarreeprojectionpergo.h" - - -namespace projections { -PlateCarreeProjectionPergo::PlateCarreeProjectionPergo():MinLatitude(-85.05112878), MaxLatitude(85.05112878),MinLongitude(-180), -MaxLongitude(180), tileSize(256, 256) -{ -} -Point PlateCarreeProjectionPergo::FromLatLngToPixel(double lat, double lng, const int &zoom) -{ - Point ret;// = Point.Empty; - - lat = Clip(lat, MinLatitude, MaxLatitude); - lng = Clip(lng, MinLongitude, MaxLongitude); - - Size s = GetTileMatrixSizePixel(zoom); - double mapSizeX = s.Width(); - //double mapSizeY = s.Height(); - - double scale = 360.0 / mapSizeX; - - ret.SetY((int) ((90.0 - lat) / scale)); - ret.SetX((int) ((lng + 180.0) / scale)); - - return ret; -} -internals::PointLatLng PlateCarreeProjectionPergo::FromPixelToLatLng(const int &x, const int &y, const int &zoom) -{ - internals::PointLatLng ret;// = internals::PointLatLng.Empty; - - Size s = GetTileMatrixSizePixel(zoom); - double mapSizeX = s.Width(); - //double mapSizeY = s.Height(); - - double scale = 360.0 / mapSizeX; - - ret.SetLat(90 - (y * scale)); - ret.SetLng((x * scale) - 180); - - return ret; -} - -double PlateCarreeProjectionPergo::Clip(const double &n, const double &minValue, const double &maxValue) const -{ - return qMin(qMax(n, minValue), maxValue); -} -Size PlateCarreeProjectionPergo::TileSize() const -{ - return tileSize; -} -double PlateCarreeProjectionPergo::Axis() const -{ - return 6378137; -} -double PlateCarreeProjectionPergo::Flattening() const -{ - return (1.0 / 298.257223563); -} -Size PlateCarreeProjectionPergo::GetTileMatrixMaxXY(const int &zoom) -{ - int y = (int) pow(2.0f, zoom); - return Size((2*y) - 1, y - 1); -} - -Size PlateCarreeProjectionPergo::GetTileMatrixMinXY(const int &zoom) -{ - Q_UNUSED(zoom); - return Size(0, 0); -} -} diff --git a/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.h b/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.h deleted file mode 100644 index 9e8bfaa2d..000000000 --- a/libs/opmapcontrol/src/internals/projections/platecarreeprojectionpergo.h +++ /dev/null @@ -1,56 +0,0 @@ -/** -****************************************************************************** -* -* @file platecarreeprojectionpergo.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PLATECARREEPROJECTIONPERGO_H -#define PLATECARREEPROJECTIONPERGO_H - -#include "../pureprojection.h" - - -namespace projections { -class PlateCarreeProjectionPergo:public internals::PureProjection -{ -public: - PlateCarreeProjectionPergo(); - virtual QString Type(){return "PlateCarreeProjectionPergo";} - virtual Size TileSize() const; - virtual double Axis() const; - virtual double Flattening()const; - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom); - virtual internals::PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom); - virtual Size GetTileMatrixMinXY(const int &zoom); - virtual Size GetTileMatrixMaxXY(const int &zoom); -private: - const double MinLatitude; - const double MaxLatitude; - const double MinLongitude; - const double MaxLongitude; - - double Clip(double const& n, double const& minValue, double const& maxValue)const; - Size tileSize; -}; -} -#endif // PLATECARREEPROJECTIONPERGO_H diff --git a/libs/opmapcontrol/src/internals/pureprojection.cpp b/libs/opmapcontrol/src/internals/pureprojection.cpp deleted file mode 100644 index d86bf26ae..000000000 --- a/libs/opmapcontrol/src/internals/pureprojection.cpp +++ /dev/null @@ -1,233 +0,0 @@ -/** -****************************************************************************** -* -* @file pureprojection.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "pureprojection.h" -#include - - - - - - -namespace internals { - -const double PureProjection::PI = M_PI; -const double PureProjection::HALF_PI = (M_PI * 0.5); -const double PureProjection::TWO_PI= (M_PI * 2.0); -const double PureProjection::EPSLoN= 1.0e-10; -const double PureProjection::MAX_VAL= 4; -const double PureProjection::maxLong= 2147483647; -const double PureProjection::DBLLONG= 4.61168601e18; -const double PureProjection::R2D=180/M_PI; -const double PureProjection::D2R=M_PI/180; - -Point PureProjection::FromLatLngToPixel(const PointLatLng &p,const int &zoom) - { - return FromLatLngToPixel(p.Lat(), p.Lng(), zoom); - } - - - PointLatLng PureProjection::FromPixelToLatLng(const Point &p,const int &zoom) - { - return FromPixelToLatLng(p.X(), p.Y(), zoom); - } - - Point PureProjection::FromPixelToTileXY(const Point &p) - { - return Point((int) (p.X() / TileSize().Width()), (int) (p.Y() / TileSize().Height())); - } - - Point PureProjection::FromTileXYToPixel(const Point &p) - { - return Point((p.X() * TileSize().Width()), (p.Y() * TileSize().Height())); - } - - Size PureProjection::GetTileMatrixSizeXY(const int &zoom) - { - Size sMin = GetTileMatrixMinXY(zoom); - Size sMax = GetTileMatrixMaxXY(zoom); - - return Size(sMax.Width() - sMin.Width() + 1, sMax.Height() - sMin.Height() + 1); - } - int PureProjection::GetTileMatrixItemCount(const int &zoom) - { - Size s = GetTileMatrixSizeXY(zoom); - return (s.Width() * s.Height()); - } - Size PureProjection::GetTileMatrixSizePixel(const int &zoom) - { - Size s = GetTileMatrixSizeXY(zoom); - return Size(s.Width() * TileSize().Width(), s.Height() * TileSize().Height()); - } - QList PureProjection::GetAreaTileList(const RectLatLng &rect,const int &zoom,const int &padding) - { - QList ret; - - Point topLeft = FromPixelToTileXY(FromLatLngToPixel(rect.LocationTopLeft(), zoom)); - Point rightBottom = FromPixelToTileXY(FromLatLngToPixel(rect.Bottom(), rect.Right(), zoom)); - - for(int x = (topLeft.X() - padding); x <= (rightBottom.X() + padding); x++) - { - for(int y = (topLeft.Y() - padding); y <= (rightBottom.Y() + padding); y++) - { - Point p = Point(x, y); - if(!ret.contains(p) && p.X() >= 0 && p.Y() >= 0) - { - ret.append(p); - } - } - } - //ret.TrimExcess(); - - return ret; - } - double PureProjection::GetGroundResolution(const int &zoom,const double &latitude) - { - return (cos(latitude * (PI / 180)) * 2 * PI * Axis()) / GetTileMatrixSizePixel(zoom).Width(); - } - - double PureProjection::Sign(const double &x) - { - if(x < 0.0) - return (-1); - else - return (1); - } - - double PureProjection::AdjustLongitude(double x) - { - qlonglong count = 0; - while(true) - { - if(qAbs(x) <= PI) - break; - else - if(((qlonglong) qAbs(x / PI)) < 2) - x = x - (Sign(x) * TWO_PI); - - else - if(((qlonglong) qAbs(x / TWO_PI)) < maxLong) - { - x = x - (((qlonglong) (x / TWO_PI)) * TWO_PI); - } - else - if(((qlonglong) qAbs(x / (maxLong * TWO_PI))) < maxLong) - { - x = x - (((qlonglong) (x / (maxLong * TWO_PI))) * (TWO_PI * maxLong)); - } - else - if(((qlonglong) qAbs(x / (DBLLONG * TWO_PI))) < maxLong) - { - x = x - (((qlonglong) (x / (DBLLONG * TWO_PI))) * (TWO_PI * DBLLONG)); - } - else - x = x - (Sign(x) * TWO_PI); - count++; - if(count > MAX_VAL) - break; - } - return (x); - } - - void PureProjection::SinCos(const double &val, double &si, double &co) - { - si = sin(val); - co = cos(val); - } - - double PureProjection::e0fn(const double &x) - { - return (1.0 - 0.25 * x * (1.0 + x / 16.0 * (3.0 + 1.25 * x))); - } - - double PureProjection::e1fn(const double &x) - { - return (0.375 * x * (1.0 + 0.25 * x * (1.0 + 0.46875 * x))); - } - - double PureProjection::e2fn(const double &x) - { - return (0.05859375 * x * x * (1.0 + 0.75 * x)); - } - - double PureProjection::e3fn(const double &x) - { - return (x * x * x * (35.0 / 3072.0)); - } - - double PureProjection::mlfn(const double &e0,const double &e1,const double &e2,const double &e3,const double &phi) - { - return (e0 * phi - e1 * sin(2.0 * phi) + e2 * sin(4.0 * phi) - e3 * sin(6.0 * phi)); - } - - qlonglong PureProjection::GetUTMzone(const double &lon) - { - return ((qlonglong) (((lon + 180.0) / 6.0) + 1.0)); - } - - - void PureProjection::FromGeodeticToCartesian(double Lat,double Lng,double Height, double &X, double &Y, double &Z) - { - Lat = (PI / 180) * Lat; - Lng = (PI / 180) * Lng; - - double B = Axis() * (1.0 - Flattening()); - double ee = 1.0 - (B / Axis()) * (B / Axis()); - double N = (Axis() / sqrt(1.0 - ee * sin(Lat) * sin(Lat))); - - X = (N + Height) * cos(Lat) * cos(Lng); - Y = (N + Height) * cos(Lat) * sin(Lng); - Z = (N * (B / Axis()) * (B / Axis()) + Height) * sin(Lat); - } - void PureProjection::FromCartesianTGeodetic(const double &X,const double &Y,const double &Z, double &Lat, double &Lng) - { - double E = Flattening() * (2.0 - Flattening()); - Lng = atan2(Y, X); - - double P = sqrt(X * X + Y * Y); - double Theta = atan2(Z, (P * (1.0 - Flattening()))); - double st = sin(Theta); - double ct = cos(Theta); - Lat = atan2(Z + E / (1.0 - Flattening()) * Axis() * st * st * st, P - E * Axis() * ct * ct * ct); - - Lat /= (PI / 180); - Lng /= (PI / 180); - } - double PureProjection::DistanceBetweenLatLng(PointLatLng const& p1,PointLatLng const& p2) - { - double R = 6371; // km - double lat1=p1.Lat(); - double lat2=p2.Lat(); - double lon1=p1.Lng(); - double lon2=p2.Lng(); - double dLat = (lat2-lat1)* (PI / 180); - double dLon = (lon2-lon1)* (PI / 180); - double a = sin(dLat/2) * sin(dLat/2) + cos(lat1* (PI / 180)) * cos(lat2* (PI / 180)) * sin(dLon/2) * sin(dLon/2); - double c = 2 * atan2(sqrt(a), sqrt(1-a)); - double d = R * c; - return d; - } -} diff --git a/libs/opmapcontrol/src/internals/pureprojection.h b/libs/opmapcontrol/src/internals/pureprojection.h deleted file mode 100644 index b75389c7a..000000000 --- a/libs/opmapcontrol/src/internals/pureprojection.h +++ /dev/null @@ -1,112 +0,0 @@ -/** -****************************************************************************** -* -* @file pureprojection.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef PUREPROJECTION_H -#define PUREPROJECTION_H - -#include "../core/size.h" -#include "../core/point.h" -#include "../internals/pointlatlng.h" -#include "pointlatlng.h" -#include "cmath" -#include "rectlatlng.h" - -using namespace core; - -namespace internals -{ - -class PureProjection -{ - -public: - virtual ~PureProjection() {} - - virtual Size TileSize()const=0; - - virtual double Axis()const=0; - - virtual double Flattening()const=0; - - virtual core::Point FromLatLngToPixel(double lat, double lng, int const& zoom)=0; - - virtual PointLatLng FromPixelToLatLng(const int &x,const int &y,const int &zoom)=0; - - virtual QString Type(){return "PureProjection";} - core::Point FromLatLngToPixel(const PointLatLng &p,const int &zoom); - - PointLatLng FromPixelToLatLng(const Point &p,const int &zoom); - virtual core::Point FromPixelToTileXY(const core::Point &p); - virtual core::Point FromTileXYToPixel(const core::Point &p); - virtual Size GetTileMatrixMinXY(const int &zoom)=0; - virtual Size GetTileMatrixMaxXY(const int &zoom)=0; - virtual Size GetTileMatrixSizeXY(const int &zoom); - int GetTileMatrixItemCount(const int &zoom); - virtual Size GetTileMatrixSizePixel(const int &zoom); - QList GetAreaTileList(const RectLatLng &rect,const int &zoom,const int &padding); - virtual double GetGroundResolution(const int &zoom,const double &latitude); - - double DegreesToRadians(const double °)const - { - return (D2R * deg); - } - - double RadiansToDegrees(const double &rad)const - { - return (R2D * rad); - } - void FromGeodeticToCartesian(double Lat,double Lng,double Height, double &X, double &Y, double &Z); - void FromCartesianTGeodetic(const double &X,const double &Y,const double &Z, double &Lat, double &Lng); - static double DistanceBetweenLatLng(PointLatLng const& p1,PointLatLng const& p2); - -protected: - - static const double PI; - static const double HALF_PI; - static const double TWO_PI; - static const double EPSLoN; - static const double MAX_VAL; - static const double maxLong; - static const double DBLLONG; - static const double R2D; - static const double D2R; - - static double Sign(const double &x); - - static double AdjustLongitude(double x); - static void SinCos(const double &val, double &sin, double &cos); - static double e0fn(const double &x); - static double e1fn(const double &x); - static double e2fn(const double &x); - static double e3fn(const double &x); - static double mlfn(const double &e0,const double &e1,const double &e2,const double &e3,const double &phi); - static qlonglong GetUTMzone(const double &lon); - -}; -} - - -#endif // PUREPROJECTION_H diff --git a/libs/opmapcontrol/src/internals/rectangle.cpp b/libs/opmapcontrol/src/internals/rectangle.cpp deleted file mode 100644 index 1f63096f1..000000000 --- a/libs/opmapcontrol/src/internals/rectangle.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/** -****************************************************************************** -* -* @file rectangle.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "rectangle.h" - -namespace internals { -Rectangle Rectangle::Empty=Rectangle(); -Rectangle Rectangle::FromLTRB(int left, int top, int right, int bottom) - { - return Rectangle(left, - top, - right - left, - bottom - top); - } -Rectangle Rectangle::Inflate(Rectangle rect, int x, int y) - { - Rectangle r = rect; - r.Inflate(x, y); - return r; - } -Rectangle Rectangle::Intersect(Rectangle a, Rectangle b) - { - int x1 = std::max(a.X(), b.X()); - int x2 = std::min(a.X() + a.Width(), b.X() + b.Width()); - int y1 = std::max(a.Y(), b.Y()); - int y2 = std::min(a.Y() + a.Height(), b.Y() + b.Height()); - - if(x2 >= x1 - && y2 >= y1) - { - - return Rectangle(x1, y1, x2 - x1, y2 - y1); - } - return Rectangle::Empty; - } -Rectangle Rectangle::Union(const Rectangle &a,const Rectangle &b) - { - int x1 = std::min(a.x, b.x); - int x2 = std::max(a.x + a.width, b.x + b.width); - int y1 = std::min(a.y, b.y); - int y2 = std::max(a.y + a.height, b.y + b.height); - - return Rectangle(x1, y1, x2 - x1, y2 - y1); - } -bool operator==(Rectangle const& lhs,Rectangle const& rhs) -{ - return (lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height); -} -uint qHash(Rectangle const& rect) - { - return (int) ((quint32) rect.x ^ - (((quint32) rect.y << 13) | ((quint32) rect.y >> 19)) ^ - (((quint32) rect.width << 26) | ((quint32) rect.width >> 6)) ^ - (((quint32) rect.height << 7) | ((quint32) rect.height >> 25))); - } -} diff --git a/libs/opmapcontrol/src/internals/rectangle.h b/libs/opmapcontrol/src/internals/rectangle.h deleted file mode 100644 index e72a46f05..000000000 --- a/libs/opmapcontrol/src/internals/rectangle.h +++ /dev/null @@ -1,158 +0,0 @@ -/** -****************************************************************************** -* -* @file rectangle.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef RECTANGLE_H -#define RECTANGLE_H -//#include -#include "../core/size.h" -#include "math.h" -using namespace core; -namespace internals -{ -struct Rectangle -{ - - friend uint qHash(Rectangle const& rect); - friend bool operator==(Rectangle const& lhs,Rectangle const& rhs); -public: - static Rectangle Empty; - static Rectangle FromLTRB(int left, int top, int right, int bottom); - Rectangle(){x=0; y=0; width=0; height=0; }; - Rectangle(int x, int y, int width, int height) - { - this->x = x; - this->y = y; - this->width = width; - this->height = height; - } - Rectangle(core::Point location, core::Size size) - { - this->x = location.X(); - this->y = location.Y(); - this->width = size.Width(); - this->height = size.Height(); - } - core::Point GetLocation() { - return core::Point(x, y); - } - void SetLocation(const core::Point &value) - { - x = value.X(); - y = value.Y(); - } - int X(){return x;} - int Y(){return y;} - void SetX(const int &value){x=value;} - void SetY(const int &value){y=value;} - int Width(){return width;} - void SetWidth(const int &value){width=value;} - int Height(){return height;} - void SetHeight(const int &value){height=value;} - int Left(){return x;} - int Top(){return y;} - int Right(){return x+width;} - int Bottom(){return y+height;} - bool IsEmpty(){return (height==0 && width==0 && x==0 && y==0);} - bool operator==(const Rectangle &cSource) - { - return (cSource.x == x && cSource.y == y && cSource.width == width && cSource.height == height); - } - - - bool operator!=(const Rectangle &cSource){return !(*this==cSource);} - bool Contains(const int &x,const int &y) - { - return this->x<=x && xx+this->width && this->y<=y && yy+this->height; - } - bool Contains(const core::Point &pt) - { - return Contains(pt.X(),pt.Y()); - } - bool Contains(const Rectangle &rect) - { - return (this->x <= rect.x) && - ((rect.x + rect.width) <= (this->x + this->width)) && - (this->y <= rect.y) && - ((rect.y + rect.height) <= (this->y + this->height)); - } - - - void Inflate(const int &width,const int &height) - { - this->x -= width; - this->y -= height; - this->width += 2*width; - this->height += 2*height; - } - void Inflate(Size &size) - { - - Inflate(size.Width(), size.Height()); - } - static Rectangle Inflate(Rectangle rect, int x, int y); - - void Intersect(const Rectangle &rect) - { - Rectangle result = Rectangle::Intersect(rect, *this); - - this->x = result.X(); - this->y = result.Y(); - this->width = result.Width(); - this->height = result.Height(); - } - static Rectangle Intersect(Rectangle a, Rectangle b); - bool IntersectsWith(const Rectangle &rect) - { - return (rect.x < this->x + this->width) && - (this->x < (rect.x + rect.width)) && - (rect.y < this->y + this->height) && - (this->y < rect.y + rect.height); - } - static Rectangle Union(const Rectangle &a,const Rectangle &b); - void Offset(const core::Point &pos) - { - Offset(pos.X(), pos.Y()); - } - - void Offset(const int &x,const int &y) - { - this->x += x; - this->y += y; - } - QString ToString() - { - return "{X=" + QString::number(x) + ",Y=" + QString::number(y) + - ",Width=" + QString::number(width) + - ",Height=" +QString::number(height) +"}"; - } -private: - int x; - int y; - int width; - int height; -}; -} -#endif // RECTANGLE_H diff --git a/libs/opmapcontrol/src/internals/rectlatlng.cpp b/libs/opmapcontrol/src/internals/rectlatlng.cpp deleted file mode 100644 index 9e9e1a95e..000000000 --- a/libs/opmapcontrol/src/internals/rectlatlng.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/** -****************************************************************************** -* -* @file rectlatlng.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "rectlatlng.h" - - - -namespace internals { -RectLatLng RectLatLng::Empty=RectLatLng(); -uint qHash(RectLatLng const& rect) -{ - return (int) (((((uint) rect.Lng()) ^ ((((uint) rect.Lat()) << 13) | (((uint) rect.Lat()) >> 0x13))) ^ ((((uint) rect.WidthLng()) << 0x1a) | (((uint) rect.WidthLng()) >> 6))) ^ ((((uint) rect.HeightLat()) << 7) | (((uint) rect.HeightLat()) >> 0x19))); -} - -bool operator==(RectLatLng const& left,RectLatLng const& right) -{ - return ((((left.Lng() == right.Lng()) && (left.Lat() == right.Lat())) && (left.WidthLng() == right.WidthLng())) && (left.HeightLat() == right.HeightLat())); -} - -bool operator!=(RectLatLng const& left,RectLatLng const& right) -{ - return !(left == right); -} - -} diff --git a/libs/opmapcontrol/src/internals/rectlatlng.h b/libs/opmapcontrol/src/internals/rectlatlng.h deleted file mode 100644 index a951cf1e6..000000000 --- a/libs/opmapcontrol/src/internals/rectlatlng.h +++ /dev/null @@ -1,264 +0,0 @@ -/** -****************************************************************************** -* -* @file rectlatlng.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef RECTLATLNG_H -#define RECTLATLNG_H - -//#include "pointlatlng.h" -#include "../internals/pointlatlng.h" -#include "math.h" -#include -#include "sizelatlng.h" - -namespace internals { -struct RectLatLng -{ -public: - static RectLatLng Empty; - friend uint qHash(RectLatLng const& rect); - friend bool operator==(RectLatLng const& left,RectLatLng const& right); - friend bool operator!=(RectLatLng const& left,RectLatLng const& right); - RectLatLng(double const& lat, double const& lng, double const& widthLng, double const& heightLat) - { - this->lng = lng; - this->lat = lat; - this->widthLng = widthLng; - this->heightLat = heightLat; - isempty=false; - } - RectLatLng(PointLatLng const& location, SizeLatLng const& size) - { - this->lng = location.Lng(); - this->lat = location.Lat(); - this->widthLng = size.WidthLng(); - this->heightLat = size.HeightLat(); - isempty=false; - } - RectLatLng() - { - this->lng = 0; - this->lat = 0; - this->widthLng = 0; - this->heightLat = 0; - isempty=true; - } - - static RectLatLng FromLTRB(double const& lng, double const& lat, double const& rightLng, double const& bottomLat) - { - return RectLatLng(lat, lng, rightLng - lng, lat - bottomLat); - } - PointLatLng LocationTopLeft()const - { - return PointLatLng(this->lat, this->lng); - } - void SetLocationTopLeft(PointLatLng const& value) - { - this->lng = value.Lng(); - this->lat = value.Lat(); - isempty=false; - } - PointLatLng LocationRightBottom() - { - - PointLatLng ret = PointLatLng(this->lat, this->lng); - ret.Offset(HeightLat(), WidthLng()); - return ret; - } - SizeLatLng Size() - { - return SizeLatLng(this->HeightLat(), this->WidthLng()); - } - void SetSize(SizeLatLng const& value) - { - this->widthLng = value.WidthLng(); - this->heightLat = value.HeightLat(); - isempty=false; - } - double Lng()const - { - return this->lng; - } - void SetLng(double const& value) - { - this->lng = value; - isempty=false; - } - - - double Lat()const - { - return this->lat; - } - void SetLat(double const& value) - { - this->lat = value; - isempty=false; - } - - double WidthLng()const - { - return this->widthLng; - } - void SetWidthLng(double const& value) - { - this->widthLng = value; - isempty=false; - } - double HeightLat()const - { - return this->heightLat; - } - void SetHeightLat(double const& value) - { - this->heightLat = value; - isempty=false; - } - double Left()const - { - return this->Lng(); - } - - double Top()const - { - return this->Lat(); - } - - double Right()const - { - return (this->Lng() + this->WidthLng()); - } - - double Bottom()const - { - return (this->Lat() - this->HeightLat()); - } - bool IsEmpty()const - { - return isempty; - } - bool Contains(double const& lat, double const& lng) - { - return ((((this->Lng() <= lng) && (lng < (this->Lng() + this->WidthLng()))) && (this->Lat() >= lat)) && (lat > (this->Lat() - this->HeightLat()))); - } - - bool Contains(PointLatLng const& pt) - { - return this->Contains(pt.Lat(), pt.Lng()); - } - - bool Contains(RectLatLng const& rect) - { - return ((((this->Lng() <= rect.Lng()) && ((rect.Lng() + rect.WidthLng()) <= (this->Lng() + this->WidthLng()))) && (this->Lat() >= rect.Lat())) && ((rect.Lat() - rect.HeightLat()) >= (this->Lat() - this->HeightLat()))); - } - void Inflate(double const& lat, double const& lng) - { - this->lng -= lng; - this->lat += lat; - this->widthLng += (double)2 * lng; - this->heightLat +=(double)2 * lat; - } - - void Inflate(SizeLatLng const& size) - { - this->Inflate(size.HeightLat(), size.WidthLng()); - } - - static RectLatLng Inflate(RectLatLng const& rect, double const& lat, double const& lng) - { - RectLatLng ef = rect; - ef.Inflate(lat, lng); - return ef; - } - - void Intersect(RectLatLng const& rect) - { - RectLatLng ef = Intersect(rect, *this); - this->lng = ef.Lng(); - this->lat = ef.Lat(); - this->widthLng = ef.WidthLng(); - this->heightLat = ef.HeightLat(); - } - static RectLatLng Intersect(RectLatLng const& a, RectLatLng const& b) - { - double lng = qMax(a.Lng(), b.Lng()); - double num2 = qMin((double) (a.Lng() + a.WidthLng()), (double) (b.Lng() + b.WidthLng())); - - double lat = qMax(a.Lat(), b.Lat()); - double num4 = qMin((double) (a.Lat() + a.HeightLat()), (double) (b.Lat() + b.HeightLat())); - - if((num2 >= lng) && (num4 >= lat)) - { - return RectLatLng(lng, lat, num2 - lng, num4 - lat); - } - return Empty; - } - bool IntersectsWith(RectLatLng const& rect) - { - return ((((rect.Lng() < (this->Lng() + this->WidthLng())) && (this->Lng() < (rect.Lng() + rect.WidthLng()))) && (rect.Lat() < (this->Lat() + this->HeightLat()))) && (this->Lat() < (rect.Lat() + rect.HeightLat()))); - } - - static RectLatLng Union(RectLatLng const& a, RectLatLng const& b) - { - double lng = qMin(a.Lng(), b.Lng()); - double num2 = qMax((double) (a.Lng() + a.WidthLng()), (double) (b.Lng() + b.WidthLng())); - double lat = qMin(a.Lat(), b.Lat()); - double num4 = qMax((double) (a.Lat() + a.HeightLat()), (double) (b.Lat() + b.HeightLat())); - return RectLatLng(lng, lat, num2 - lng, num4 - lat); - } - void Offset(PointLatLng const& pos) - { - this->Offset(pos.Lat(), pos.Lng()); - } - - void Offset(double const& lat, double const& lng) - { - this->lng += lng; - this->lat -= lat; - } - - QString ToString() const - { - return ("{Lat=" + QString::number(this->Lat()) + ",Lng=" + QString::number(this->Lng()) + ",WidthLng=" + QString::number(this->WidthLng()) + ",HeightLat=" + QString::number(this->HeightLat()) + "}"); - } - -private: - double lng; - double lat; - double widthLng; - double heightLat; - bool isempty; -}; - -} -#endif // RECTLATLNG_H - - - -// static RectLatLng() -// { -// Empty = new RectLatLng(); -// } -// } diff --git a/libs/opmapcontrol/src/internals/sizelatlng.cpp b/libs/opmapcontrol/src/internals/sizelatlng.cpp deleted file mode 100644 index 6975d9936..000000000 --- a/libs/opmapcontrol/src/internals/sizelatlng.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** -****************************************************************************** -* -* @file sizelatlng.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "sizelatlng.h" -#include "pointlatlng.h" - -namespace internals { -SizeLatLng::SizeLatLng():heightLat(0),widthLng(0) -{ - -} -SizeLatLng::SizeLatLng(PointLatLng const& pt) -{ - this->heightLat = pt.Lat(); - this->widthLng = pt.Lng(); -} -SizeLatLng operator+(SizeLatLng const& sz1, SizeLatLng const& sz2) -{ - return SizeLatLng::Add(sz1, sz2); -} - -SizeLatLng operator-(SizeLatLng const& sz1, SizeLatLng const& sz2) -{ - return SizeLatLng::Subtract(sz1, sz2); -} - -bool operator==(SizeLatLng const& sz1, SizeLatLng const& sz2) -{ - return ((sz1.WidthLng() == sz2.WidthLng()) && (sz1.HeightLat() == sz2.HeightLat())); -} - -bool operator!=(SizeLatLng const& sz1, SizeLatLng const& sz2) -{ - return !(sz1 == sz2); -} -SizeLatLng SizeLatLng::Empty=SizeLatLng(); -} diff --git a/libs/opmapcontrol/src/internals/sizelatlng.h b/libs/opmapcontrol/src/internals/sizelatlng.h deleted file mode 100644 index 937aa2dc4..000000000 --- a/libs/opmapcontrol/src/internals/sizelatlng.h +++ /dev/null @@ -1,136 +0,0 @@ -/** -****************************************************************************** -* -* @file sizelatlng.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef SIZELATLNG_H -#define SIZELATLNG_H - - -#include - - -namespace internals { -struct PointLatLng; -struct SizeLatLng -{ -public: - SizeLatLng(); - static SizeLatLng Empty; - - SizeLatLng(SizeLatLng const& size) - { - this->widthLng = size.widthLng; - this->heightLat = size.heightLat; - } - - SizeLatLng(PointLatLng const& pt); - - - SizeLatLng(double const& heightLat, double const& widthLng) - { - this->heightLat = heightLat; - this->widthLng = widthLng; - } - - friend SizeLatLng operator+(SizeLatLng const& sz1, SizeLatLng const& sz2); - friend SizeLatLng operator-(SizeLatLng const& sz1, SizeLatLng const& sz2); - friend bool operator==(SizeLatLng const& sz1, SizeLatLng const& sz2); - friend bool operator!=(SizeLatLng const& sz1, SizeLatLng const& sz2); - - -// static explicit operator PointLatLng(SizeLatLng size) -// { -// return new PointLatLng(size.HeightLat(), size.WidthLng()); -// } - - - bool IsEmpty()const - { - return ((this->widthLng == 0) && (this->heightLat == 0)); - } - - double WidthLng()const - { - return this->widthLng; - } - void SetWidthLng(double const& value) - { - this->widthLng = value; - } - - - double HeightLat()const - { - return this->heightLat; - } - void SetHeightLat(double const& value) - { - this->heightLat = value; - } - - static SizeLatLng Add(SizeLatLng const& sz1, SizeLatLng const& sz2) - { - return SizeLatLng(sz1.HeightLat() + sz2.HeightLat(), sz1.WidthLng() + sz2.WidthLng()); - } - - static SizeLatLng Subtract(SizeLatLng const& sz1, SizeLatLng const& sz2) - { - return SizeLatLng(sz1.HeightLat() - sz2.HeightLat(), sz1.WidthLng() - sz2.WidthLng()); - } - -// override bool Equals(object obj) -// { -// if(!(obj is SizeLatLng)) -// { -// return false; -// } -// SizeLatLng ef = (SizeLatLng) obj; -// return (((ef.WidthLng == this->WidthLng) && (ef.HeightLat == this->HeightLat)) && ef.GetType().Equals(base.GetType())); -// } - -// override int GetHashCode() -// { -// return base.GetHashCode(); -// } - -// PointLatLng ToPointLatLng() -// { -// return (PointLatLng) this; -// } - - QString ToString() - { - return ("{WidthLng=" + QString::number(this->widthLng) + ", HeightLng=" + QString::number(this->heightLat) + "}"); - } - - -private: - double heightLat; - double widthLng; -}; - -} -#endif // SIZELATLNG_H - diff --git a/libs/opmapcontrol/src/internals/tile.cpp b/libs/opmapcontrol/src/internals/tile.cpp deleted file mode 100644 index bf2a9d729..000000000 --- a/libs/opmapcontrol/src/internals/tile.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** -****************************************************************************** -* -* @file tile.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "tile.h" - - -namespace internals { -Tile::Tile(int zoom, Point pos) -{ - this->zoom=zoom; - this->pos=pos; -} -void Tile::Clear() -{ -#ifdef DEBUG_TILE - qDebug()<<"Tile:Clear Overlays"; -#endif //DEBUG_TILE - mutex.lock(); - foreach(QByteArray img, Overlays) - { - img.~QByteArray(); - } - Overlays.clear(); - mutex.unlock(); -} -Tile::Tile():zoom(0),pos(0,0) -{ - -} -Tile& Tile::operator =(const Tile &cSource) -{ - this->zoom=cSource.zoom; - this->pos=cSource.pos; - return *this; -} - -} diff --git a/libs/opmapcontrol/src/internals/tile.h b/libs/opmapcontrol/src/internals/tile.h deleted file mode 100644 index ff345731a..000000000 --- a/libs/opmapcontrol/src/internals/tile.h +++ /dev/null @@ -1,67 +0,0 @@ -/** -****************************************************************************** -* -* @file tile.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef TILE_H -#define TILE_H - -#include "QList" -#include -#include "../core/point.h" -#include -#include -#include "debugheader.h" -using namespace core; -namespace internals -{ -class Tile -{ -public: - Tile(int zoom,core::Point pos); - Tile(); - void Clear(); - int GetZoom(){return zoom;} - core::Point GetPos(){return pos;} - void SetZoom(const int &value){zoom=value;} - void SetPos(const core::Point &value){pos=value;} - Tile& operator= (const Tile &cSource); - Tile(const Tile &cSource) - { - this->zoom=cSource.zoom; - this->pos=cSource.pos; - } - bool HasValue(){return !(zoom==0);} - QList Overlays; -protected: - - QMutex mutex; -private: - int zoom; - core::Point pos; - - -}; -} -#endif // TILE_H diff --git a/libs/opmapcontrol/src/internals/tilematrix.cpp b/libs/opmapcontrol/src/internals/tilematrix.cpp deleted file mode 100644 index ce96a1a7d..000000000 --- a/libs/opmapcontrol/src/internals/tilematrix.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/** -****************************************************************************** -* -* @file tilematrix.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "tilematrix.h" - - -namespace internals { -TileMatrix::TileMatrix() -{ -} -void TileMatrix::Clear() -{ - mutex.lock(); - foreach(Tile* t,matrix.values()) - { - delete t; - t=0; - } - matrix.clear(); - mutex.unlock(); -} -//void TileMatrix::RebuildToUpperZoom() -//{ -// mutex.lock(); -// QList newtiles; -// foreach(Tile* t,matrix.values()) -// { -// Point point=Point(t->GetPos().X()*2,t->GetPos().Y()*2); -// Tile* tile1=new Tile(t->GetZoom()+1,point); -// Tile* tile2=new Tile(t->GetZoom()+1,Point(point.X()+1,point.Y()+0)); -// Tile* tile3=new Tile(t->GetZoom()+1,Point(point.X()+0,point.Y()+1)); -// Tile* tile4=new Tile(t->GetZoom()+1,Point(point.X()+1,point.Y()+1)); -// -// foreach(QByteArray arr, t->Overlays) -// { -// QImage ima=QImage::fromData(arr); -// QImage ima1=ima.copy(0,0,ima.width()/2,ima.height()/2); -// QImage ima2=ima.copy(ima.width()/2,0,ima.width()/2,ima.height()/2); -// QImage ima3=ima.copy(0,ima.height()/2,ima.width()/2,ima.height()/2); -// QImage ima4=ima.copy(ima.width()/2,ima.height()/2,ima.width()/2,ima.height()/2); -// QByteArray ba; -// QBuffer buf(&ba); -// ima1.scaled(QSize(ima.width(),ima.height())).save(&buf,"PNG"); -// tile1->Overlays.append(ba); -// QByteArray ba1; -// QBuffer buf1(&ba1); -// ima2.scaled(QSize(ima.width(),ima.height())).save(&buf1,"PNG"); -// tile2->Overlays.append(ba1); -// QByteArray ba2; -// QBuffer buf2(&ba2); -// ima3.scaled(QSize(ima.width(),ima.height())).save(&buf2,"PNG"); -// tile3->Overlays.append(ba2); -// QByteArray ba3; -// QBuffer buf3(&ba3); -// ima4.scaled(QSize(ima.width(),ima.height())).save(&buf3,"PNG"); -// tile4->Overlays.append(ba3); -// newtiles.append(tile1); -// newtiles.append(tile2); -// newtiles.append(tile3); -// newtiles.append(tile4); -// } -// } -// foreach(Tile* t,matrix.values()) -// { -// delete t; -// t=0; -// } -// matrix.clear(); -// foreach(Tile* t,newtiles) -// { -// matrix.insert(t->GetPos(),t); -// } -// -// mutex.unlock(); -//} - -void TileMatrix::ClearPointsNotIn(QListlist) -{ - removals.clear(); - QMutexLocker lock(&mutex); - foreach(Point p, matrix.keys()) - { - if(!list.contains(p)) - { - removals.append(p); - } - } - foreach(Point p,removals) - { - Tile* t=matrix.value(p, 0); - if(t!=0) - { - delete t; - t=0; - matrix.remove(p); - } - - } - removals.clear(); -} -Tile* TileMatrix::TileAt(const Point &p) -{ - -#ifdef DEBUG_TILEMATRIX - qDebug()<<"TileMatrix:TileAt:"< -#include "tile.h" -#include -#include "../core/point.h" -#include "debugheader.h" -#include -namespace internals { -class TileMatrix -{ -public: - TileMatrix(); - void Clear(); - void ClearPointsNotIn(QList list); - Tile* TileAt(const core::Point &p); - void SetTileAt(const core::Point &p,Tile* tile); - int count()const{return matrix.count();} - // void RebuildToUpperZoom(); -protected: - QHash matrix; - QList removals; - QMutex mutex; -}; - -} -#endif // TILEMATRIX_H diff --git a/libs/opmapcontrol/src/mapwidget/configuration.cpp b/libs/opmapcontrol/src/mapwidget/configuration.cpp deleted file mode 100644 index ac6a4c50f..000000000 --- a/libs/opmapcontrol/src/mapwidget/configuration.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/** -****************************************************************************** -* -* @file configuration.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A class that centralizes most of the mapcontrol configurations -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "configuration.h" -namespace mapcontrol -{ -Configuration::Configuration() -{ - EmptytileBrush = Qt::cyan; - MissingDataFont =QFont ("Times",10,QFont::Bold); - EmptyTileText = "We are sorry, but we don't\nhave imagery at this zoom\nlevel for this region."; - EmptyTileBorders = QPen(Qt::white); - ScalePen = QPen(Qt::blue); - SelectionPen = QPen(Qt::blue); - DragButton = Qt::LeftButton; -} -void Configuration::SetAccessMode(core::AccessMode::Types const& type) -{ - core::OPMaps::Instance()->setAccessMode(type); -} -core::AccessMode::Types Configuration::AccessMode() -{ - return core::OPMaps::Instance()->GetAccessMode(); -} -void Configuration::SetLanguage(core::LanguageType::Types const& type) -{ - core::OPMaps::Instance()->setLanguage(type); -} -core::LanguageType::Types Configuration::Language() -{ - return core::OPMaps::Instance()->GetLanguage(); -} -void Configuration::SetUseMemoryCache(bool const& value) -{ - core::OPMaps::Instance()->setUseMemoryCache(value); -} -} diff --git a/libs/opmapcontrol/src/mapwidget/configuration.h b/libs/opmapcontrol/src/mapwidget/configuration.h deleted file mode 100644 index 9107fba77..000000000 --- a/libs/opmapcontrol/src/mapwidget/configuration.h +++ /dev/null @@ -1,186 +0,0 @@ -/** -****************************************************************************** -* -* @file configuration.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A class that centralizes most of the mapcontrol configurations -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef CONFIGURATION_H -#define CONFIGURATION_H - -#include -#include -#include -#include -#include "../core/opmaps.h" -#include "../core/accessmode.h" -#include "../core/cache.h" -namespace mapcontrol -{ - -/** -* @brief A class that centralizes most of the mapcontrol configurations -* -* @class Configuration configuration.h "configuration.h" -*/ -class Configuration -{ -public: - Configuration(); - /** - * @brief Used to draw empty map tiles - * - * @var EmptytileBrush - */ - QBrush EmptytileBrush; - /** - * @brief Used for empty tiles text - * - * @var EmptyTileText - */ - QString EmptyTileText; - /** - * @brief Used to draw empty tile borders - * - * @var EmptyTileBorders - */ - QPen EmptyTileBorders; - /** - * @brief Used to Draw the maps scale - * - * @var ScalePen - */ - QPen ScalePen; - /** - * @brief Used to draw selection box - * - * @var SelectionPen - */ - QPen SelectionPen; - /** - * @brief - * - * @var MissingDataFont - */ - QFont MissingDataFont; - - /** - * @brief Button used for dragging - * - * @var DragButton - */ - Qt::MouseButton DragButton; - - /** - * @brief Sets the access mode for the map (cache only, server and cache...) - * - * @param type access mode - */ - void SetAccessMode(core::AccessMode::Types const& type); - /** - * @brief Returns the access mode for the map (cache only, server and cache...) - * - * @return core::AccessMode::Types access mode for the map - */ - core::AccessMode::Types AccessMode(); - - /** - * @brief Sets the language used for geocaching - * - * @param type The language to be used - */ - void SetLanguage(core::LanguageType::Types const& type); - /** - * @brief Returns the language used for geocaching - * - * @return core::LanguageType::Types - */ - core::LanguageType::Types Language(); - - /** - * @brief Used to allow disallow use of memory caching - * - * @param value - * @return - */ - void SetUseMemoryCache(bool const& value); - /** - * @brief Return if memory caching is in use - * - * @return - */ - bool UseMemoryCache(){return core::OPMaps::Instance()->UseMemoryCache();} - - /** - * @brief Returns the currently used memory for tiles - * - * @return - */ - double TileMemoryUsed()const{return core::OPMaps::Instance()->TilesInMemory.MemoryCacheSize();} - - /** - * @brief Sets the size of the memory for tiles - * - * @param value size in Mb to use for tiles - * @return - */ - void SetTileMemorySize(int const& value){core::OPMaps::Instance()->TilesInMemory.setMemoryCacheCapacity(value);} - - /** - * @brief Sets the location for the SQLite Database used for caching and the geocoding cache files - * - * @param dir The path location for the cache file-IMPORTANT Must end with closing slash "/" - */ - void SetCacheLocation(QString const& dir) - { - core::Cache::Instance()->setCacheLocation(dir); - - } - - /** - * @brief Deletes tiles in DataBase older than "days" days - * - * @param days - * @return - */ - void DeleteTilesOlderThan(int const& days){core::Cache::Instance()->ImageCache.deleteOlderTiles(days);} - - /** - * @brief Exports tiles from one DB to another. Only new tiles are added. - * - * @param sourceDB the source DB - * @param destDB the destination DB. If it doesnt exhist it will be created. - * @return - */ - void ExportMapDataToDB(QString const& sourceDB, QString const& destDB)const{core::PureImageCache::ExportMapDataToDB(sourceDB,destDB);} - /** - * @brief Returns the location for the SQLite Database used for caching and the geocoding cache files - * - * @return - */ - QString CacheLocation(){return core::Cache::Instance()->CacheLocation();} - - -}; -} -#endif // CONFIGURATION_H diff --git a/libs/opmapcontrol/src/mapwidget/gpsitem.cpp b/libs/opmapcontrol/src/mapwidget/gpsitem.cpp deleted file mode 100644 index c13a1f50a..000000000 --- a/libs/opmapcontrol/src/mapwidget/gpsitem.cpp +++ /dev/null @@ -1,220 +0,0 @@ -/** -****************************************************************************** -* -* @file gpsitem.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a UAV -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "../internals/pureprojection.h" -#include "gpsitem.h" -namespace mapcontrol -{ - GPSItem::GPSItem(MapGraphicItem* map,OPMapWidget* parent,QString uavPic):map(map),mapwidget(parent),showtrail(true),showtrailline(true),trailtime(5),traildistance(50),autosetreached(true) - ,autosetdistance(100) - { - pic.load(uavPic); - // Don't scale but trust the image we are given - // pic=pic.scaled(50,33,Qt::IgnoreAspectRatio); - localposition=map->FromLatLngToLocal(mapwidget->CurrentPosition()); - this->setPos(localposition.X(),localposition.Y()); - this->setZValue(4); - trail=new QGraphicsItemGroup(); - trail->setParentItem(map); - trailLine=new QGraphicsItemGroup(); - trailLine->setParentItem(map); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - mapfollowtype=UAVMapFollowType::None; - trailtype=UAVTrailType::ByDistance; - timer.start(); - } - GPSItem::~GPSItem() - { - delete trail; - } - - void GPSItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - // painter->rotate(-90); - painter->drawPixmap(-pic.width()/2,-pic.height()/2,pic); - // painter->drawRect(QRectF(-pic.width()/2,-pic.height()/2,pic.width()-1,pic.height()-1)); - } - QRectF GPSItem::boundingRect()const - { - return QRectF(-pic.width()/2,-pic.height()/2,pic.width(),pic.height()); - } - void GPSItem::SetUAVPos(const internals::PointLatLng &position, const int &altitude) - { - if(coord.IsEmpty()) - lastcoord=coord; - if(coord!=position) - { - - if(trailtype==UAVTrailType::ByTimeElapsed) - { - if(timer.elapsed()>trailtime*1000) - { - trail->addToGroup(new TrailItem(position,altitude,Qt::green,this)); - if(!lasttrailline.IsEmpty()) - trailLine->addToGroup((new TrailLineItem(lasttrailline,position,Qt::green,map))); - lasttrailline=position; - timer.restart(); - } - - } - else if(trailtype==UAVTrailType::ByDistance) - { - if(qAbs(internals::PureProjection::DistanceBetweenLatLng(lastcoord,position)*1000)>traildistance) - { - trail->addToGroup(new TrailItem(position,altitude,Qt::green,this)); - if(!lasttrailline.IsEmpty()) - - trailLine->addToGroup((new TrailLineItem(lasttrailline,position,Qt::green,this))); - lasttrailline=position; - lastcoord=position; - } - } - coord=position; - this->altitude=altitude; - RefreshPos(); - /*if(mapfollowtype==UAVMapFollowType::CenterAndRotateMap||mapfollowtype==UAVMapFollowType::CenterMap) - { - mapwidget->SetCurrentPosition(coord); - }*/ - this->update(); - /*if(autosetreached) - { - foreach(QGraphicsItem* i,map->childItems()) - { - WayPointItem* wp=qgraphicsitem_cast(i); - if(wp) - { - if(Distance3D(wp->Coord(),wp->Altitude())SetReached(true); - emit UAVReachedWayPoint(wp->Number(),wp); - } - } - } - } - if(mapwidget->Home!=0) - { - //verify if the UAV is inside the safety bouble - if(Distance3D(mapwidget->Home->Coord(),mapwidget->Home->Altitude())>mapwidget->Home->SafeArea()) - { - if(mapwidget->Home->safe!=false) - { - mapwidget->Home->safe=false; - mapwidget->Home->update(); - emit UAVLeftSafetyBouble(this->coord); - } - } - else - { - if(mapwidget->Home->safe!=true) - { - mapwidget->Home->safe=true; - mapwidget->Home->update(); - } - } - - }*/ - } - } - - /** - * Rotate the UAV Icon on the map, or rotate the map - * depending on the display mode - */ - void GPSItem::SetUAVHeading(const qreal &value) - { - if(mapfollowtype==UAVMapFollowType::CenterAndRotateMap) - { - mapwidget->SetRotate(-value); - } - else { - if (this->rotation() != value) - this->setRotation(value); - } - } - - - int GPSItem::type()const - { - return Type; - } - - - void GPSItem::RefreshPos() - { - localposition=map->FromLatLngToLocal(coord); - this->setPos(localposition.X(),localposition.Y()); - foreach(QGraphicsItem* i,trail->childItems()) - { - TrailItem* w=qgraphicsitem_cast(i); - if(w) - w->setPos(map->FromLatLngToLocal(w->coord).X(),map->FromLatLngToLocal(w->coord).Y()); - } - foreach(QGraphicsItem* i,trailLine->childItems()) - { - TrailLineItem* ww=qgraphicsitem_cast(i); - if(ww) - ww->setLine(map->FromLatLngToLocal(ww->coord1).X(),map->FromLatLngToLocal(ww->coord1).Y(),map->FromLatLngToLocal(ww->coord2).X(),map->FromLatLngToLocal(ww->coord2).Y()); - } - - } - void GPSItem::SetTrailType(const UAVTrailType::Types &value) - { - trailtype=value; - if(trailtype==UAVTrailType::ByTimeElapsed) - timer.restart(); - } - void GPSItem::SetShowTrail(const bool &value) - { - showtrail=value; - trail->setVisible(value); - - } - void GPSItem::SetShowTrailLine(const bool &value) - { - showtrailline=value; - trailLine->setVisible(value); - } - void GPSItem::DeleteTrail()const - { - foreach(QGraphicsItem* i,trail->childItems()) - delete i; - foreach(QGraphicsItem* i,trailLine->childItems()) - delete i; - } - double GPSItem::Distance3D(const internals::PointLatLng &coord, const int &altitude) - { - return sqrt(pow(internals::PureProjection::DistanceBetweenLatLng(this->coord,coord)*1000,2)+ - pow(static_cast(this->altitude-altitude),2)); - - } - void GPSItem::SetUavPic(QString UAVPic) - { - pic.load(":/uavs/images/"+UAVPic); - } -} diff --git a/libs/opmapcontrol/src/mapwidget/gpsitem.h b/libs/opmapcontrol/src/mapwidget/gpsitem.h deleted file mode 100644 index 64931ea7f..000000000 --- a/libs/opmapcontrol/src/mapwidget/gpsitem.h +++ /dev/null @@ -1,227 +0,0 @@ -/** -****************************************************************************** -* -* @file gpsitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef GPSITEM_H -#define GPSITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include "mapgraphicitem.h" -#include "waypointitem.h" -#include -#include "uavmapfollowtype.h" -#include "uavtrailtype.h" -#include -#include "opmapwidget.h" -#include "trailitem.h" -#include "traillineitem.h" -namespace mapcontrol -{ - class WayPointItem; - class OPMapWidget; - /** -* @brief A QGraphicsItem representing the UAV -* -* @class UAVItem gpsitem.h "mapwidget/gpsitem.h" -*/ - class GPSItem:public QObject,public QGraphicsItem - { - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - enum { Type = UserType + 6 }; - GPSItem(MapGraphicItem* map,OPMapWidget* parent, QString uavPic=QString::fromUtf8(":/uavs/images/mapquad.png")); - ~GPSItem(); - /** - * @brief Sets the UAV position - * - * @param position LatLng point - * @param altitude altitude in meters - */ - void SetUAVPos(internals::PointLatLng const& position,int const& altitude); - /** - * @brief Sets the UAV heading - * - * @param value heading angle (north=0deg) - */ - void SetUAVHeading(qreal const& value); - /** - * @brief Returns the UAV position - * - * @return internals::PointLatLng - */ - internals::PointLatLng UAVPos()const{return coord;} - /** - * @brief Sets the Map follow type - * - * @param value can be "none"(map doesnt follow UAV), "CenterMap"(map moves to keep UAV centered) or "CenterAndRotateMap"(map moves and rotates to keep UAV centered and straight) - */ - void SetMapFollowType(UAVMapFollowType::Types const& value){mapfollowtype=value;} - /** - * @brief Sets the trail type - * - * @param value can be "NoTrail"(no trail is plotted), "ByTimeElapsed"(a trail point is plotted each TrailTime()) or ByDistance(a trail point is plotted if the distance between the UAV and the last trail point is bigger than TrailDistance()) - */ - void SetTrailType(UAVTrailType::Types const& value); - /** - * @brief Returns the map follow method used - * - * @return UAVMapFollowType::Types - */ - UAVMapFollowType::Types GetMapFollowType()const{return mapfollowtype;} - /** - * @brief Returns the UAV trail type. It can be plotted by time elapsed or distance - * - * @return UAVTrailType::Types - */ - UAVTrailType::Types GetTrailType()const{return trailtype;} - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - void RefreshPos(); - QRectF boundingRect() const; - /** - * @brief Sets the trail time to be used if TrailType is ByTimeElapsed - * - * @param seconds the UAV trail time elapsed value. If the trail type is time elapsed - * a trail point will be plotted each "value returned" seconds. - */ - void SetTrailTime(int const& seconds){trailtime=seconds;} - /** - * @brief Returns the UAV trail time elapsed value. If the trail type is time elapsed - * a trail point will be plotted each "value returned" seconds. - * - * @return int - */ - int TrailTime()const{return trailtime;} - /** - * @brief Sets the trail distance to be used if TrailType is ByDistance - * - * @param distance the UAV trail plot distance. - * If the trail type is ByDistance a trail dot is plotted if - * the distance between the current UAV position and the last trail point - * is bigger than the returned value - */ - void SetTrailDistance(int const& distance){traildistance=distance;} - /** - * @brief Returns the UAV trail plot distance. - * If the trail type is distance diference a trail dot is plotted if - * the distance between the current UAV position and the last trail point - * is bigger than the returned value - * - * @return int - */ - int TrailDistance()const{return traildistance;} - /** - * @brief Returns true if UAV trail is shown - * - * @return bool - */ - bool ShowTrail()const{return showtrail;} - /** - * @brief Returns true if UAV trail line is shown - * - * @return bool - */ - bool ShowTrailLine()const{return showtrailline;} - /** - * @brief Used to define if the UAV displays a trail - * - * @param value - */ - void SetShowTrail(bool const& value); - /** - * @brief Used to define if the UAV displays a trail line - * - * @param value - */ - void SetShowTrailLine(bool const& value); - /** - * @brief Deletes all the trail points - */ - void DeleteTrail()const; - /** - * @brief Returns true if the UAV automaticaly sets WP reached value (changing its color) - * - * @return bool - */ - bool AutoSetReached()const{return autosetreached;} - /** - * @brief Defines if the UAV can set the WP's "reached" value automaticaly. - * - * @param value - */ - void SetAutoSetReached(bool const& value){autosetreached=value;} - /** - * @brief Returns the 3D distance in meters necessary for the UAV to set WP's to "reached" - * - * @return double - */ - double AutoSetDistance()const{return autosetdistance;} - /** - * @brief Sets the the 3D distance in meters necessary for the UAV to set WP's to "reached" - * - * @param value - */ - void SetAutoSetDistance(double const& value){autosetdistance=value;} - - int type() const; - - void SetUavPic(QString UAVPic); - private: - MapGraphicItem* map; - - int altitude; - UAVMapFollowType::Types mapfollowtype; - UAVTrailType::Types trailtype; - internals::PointLatLng coord; - internals::PointLatLng lastcoord; - QPixmap pic; - core::Point localposition; - OPMapWidget* mapwidget; - QGraphicsItemGroup* trail; - QGraphicsItemGroup * trailLine; - internals::PointLatLng lasttrailline; - QTime timer; - bool showtrail; - bool showtrailline; - int trailtime; - int traildistance; - bool autosetreached; - double Distance3D(internals::PointLatLng const& coord, int const& altitude); - double autosetdistance; - // QRectF rect; - - public slots: - - signals: - void UAVReachedWayPoint(int const& waypointnumber,WayPointItem* waypoint); - void UAVLeftSafetyBouble(internals::PointLatLng const& position); - }; -} -#endif // GPSITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/homeitem.cpp b/libs/opmapcontrol/src/mapwidget/homeitem.cpp deleted file mode 100644 index 543322764..000000000 --- a/libs/opmapcontrol/src/mapwidget/homeitem.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/** -****************************************************************************** -* -* @file homeitem.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a trail point -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "homeitem.h" -namespace mapcontrol -{ - HomeItem::HomeItem(MapGraphicItem* map,OPMapWidget* parent):safe(true),map(map),mapwidget(parent),showsafearea(true),safearea(1000),altitude(0) - { - pic.load(QString::fromUtf8(":/markers/images/home2.svg")); - pic=pic.scaled(30,30,Qt::IgnoreAspectRatio); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - localposition=map->FromLatLngToLocal(mapwidget->CurrentPosition()); - this->setPos(localposition.X(),localposition.Y()); - this->setZValue(4); - coord=internals::PointLatLng(50,50); - -// this->setFlag(QGraphicsItem::ItemIsMovable,true); -// this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); -// this->setFlag(QGraphicsItem::ItemIsSelectable,true); - } - - void HomeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - painter->drawPixmap(-pic.width()/2,-pic.height()/2,pic); - if(showsafearea) - { - if(safe) - painter->setPen(Qt::green); - else - painter->setPen(Qt::red); - painter->drawEllipse(QPointF(0,0),localsafearea,localsafearea); - // painter->drawRect(QRectF(-localsafearea,-localsafearea,localsafearea*2,localsafearea*2)); - } - - } - QRectF HomeItem::boundingRect()const - { - if(!showsafearea) - return QRectF(-pic.width()/2,-pic.height()/2,pic.width(),pic.height()); - else - return QRectF(-localsafearea,-localsafearea,localsafearea*2,localsafearea*2); - } - - - int HomeItem::type()const - { - return Type; - } - void HomeItem::RefreshPos() - { - prepareGeometryChange(); - localposition=map->FromLatLngToLocal(coord); - this->setPos(localposition.X(),localposition.Y()); - if(showsafearea) - localsafearea=safearea/map->Projection()->GetGroundResolution(map->ZoomTotal(),coord.Lat()); - - } - -// void HomeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -// { -// if(event->button()==Qt::LeftButton) -// { -// coord=map->FromLocalToLatLng(this->pos().x(),this->pos().y()); -// QString coord_str = " " + QString::number(coord.Lat(), 'f', 6) + " " + QString::number(coord.Lng(), 'f', 6); -// qDebug() << "WP MOVE:" << coord_str << __FILE__ << __LINE__; -// isDragging=false; -// RefreshToolTip(); - -// emit WPValuesChanged(this); -// } -// QGraphicsItem::mouseReleaseEvent(event); -// } - -} diff --git a/libs/opmapcontrol/src/mapwidget/homeitem.h b/libs/opmapcontrol/src/mapwidget/homeitem.h deleted file mode 100644 index 15ad9597b..000000000 --- a/libs/opmapcontrol/src/mapwidget/homeitem.h +++ /dev/null @@ -1,77 +0,0 @@ -/** -****************************************************************************** -* -* @file homeitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef HOMEITEM_H -#define HOMEITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include -#include "opmapwidget.h" -namespace mapcontrol -{ - - class HomeItem:public QObject,public QGraphicsItem - { - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - enum { Type = UserType + 4 }; - HomeItem(MapGraphicItem* map,OPMapWidget* parent); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - QRectF boundingRect() const; - int type() const; - void RefreshPos(); - bool ShowSafeArea()const{return showsafearea;} - void SetShowSafeArea(bool const& value){showsafearea=value;} - int SafeArea()const{return safearea;} - void SetSafeArea(int const& value){safearea=value;} - bool safe; - void SetCoord(internals::PointLatLng const& value){coord=value;} - internals::PointLatLng Coord()const{return coord;} - void SetAltitude(int const& value){altitude=value;} - int Altitude()const{return altitude;} - private: - MapGraphicItem* map; - OPMapWidget* mapwidget; - QPixmap pic; - core::Point localposition; - internals::PointLatLng coord; - bool showsafearea; - int safearea; - int localsafearea; - int altitude; - - public slots: - - signals: - - }; -} -#endif // HOMEITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/images/EasystarBlue.png b/libs/opmapcontrol/src/mapwidget/images/EasystarBlue.png deleted file mode 100644 index 4e44eaed96650f7970eddc009bb53146be3e50a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1490 zcmV;@1ugoCP)3lkH)z7bn3%?eLSUmVT#%rNA&NvHm>5G; zNR$v$YawYzT9i^+W;*T6ypMBS3|J~Hop!hw{crAl_uX^P`Mvwjedm#gK$nP!4jnxB zwd=a-mA!i(6OlldFH_gT0I+}m{*7&IZ5x>x`}XbI0N|7^UrN`)0MOjr+;Xem(b3VW z)0b9|cs$;GTmQccV%v7KudfgN0|T%uE27hv)*Lx~`t$>5&YZ!c>(_&n3hVTxbw_%8 zdus>)h``MHjz?$)0l>F9L7?sA1)v!unM@8jjsw?qVOf?|5-R0`NJJHjmaeOd)V3@N z#~Pw`MLc4Ksv@QnjVQx%NSQV%(;;QpM21~#m7Q$7w!CXitc#g(>Zgg5=TfyjBJ2tW zu1HX9*)ItDE(c!0FN|lsd^+n+j%IV2!SU?K#p~C9|NfeYOwJo5(Y`fazv9U!Dr%Ok zwVc=*WrbQyt1@DSqLwm3AezThN}vDb)h)b|neqM!vxj4y?WNj^0377u=f^$Yo5-@4 zzvvY*XD7!7e*Cld_=zh$pO4N6QW0s*x74nB>d;rQ`jtrl z2m-fcfV(N6P+dNsfl>-SLW>OFo!jWHDgs%Rbq#ebo4TE7V)x?qEsy`v^TmisMD*}8 zM-ErkwI-(kfbt-UwhS>m&x2tYV2BX}-n4)grYYOXy4GZ3)w73*XqVa6)x9U0=-lc1 zv+u%u^5S-T=754A01<&XP}3h&=`b_De#OCPqH||kSN9&%j@GYR=uS)rywi@^S5qK9 zP4_cBpxFbSO;eNYX#F}9hP8TfY~V`Z=ldk^E(63MG65JwWCCOWWP)G-WD>{#!30PF zFhMjme)F1&_YJ?0ahUA{Gh=eB|El4{@_+;)@KO9X@dXk9^7l0$47q(A#TF8Xhz}ru zh!2P&!)i3lP%8{;wK+QQ-Nz%nUw$w-+Fx!a-XS8Yw0D1Y!!%8E?1#ObsZ?tCUi+ws zH`%o-Ha}m|2XUbyBJ0zmN7I&NIoo#Zs1}iNUB0xIC?eu{zVEuO>jEg~^rf|o2LNIA zJZ1&Jn{#p*(hmZ7BBDg+JB<4P0udJ?<&_8}NdJzAxbnXNDYs}VLH8v`Afo$ER6j`I z`@V=6y8UPe86F;nlvnPSB<&!~?1AQ2KQBc0q(mViW7XCJo2%B|6s za8=`s_PNYpDs%P1>t~NV_enW%lm+tO+80`z9(nDo6^d2OHYb-J1OSAq8fKdUzc8Ln zo%?W2-?#7ly3kn4$`LENWLqvXbRj!(DFuQ7QejfcAyHvc6arM(bJGz3@bcqX0q4Pz s6XKjO7a*Ji5GX6W)CkA716VM~Uy`CH1E&K2cK`qY07*qoM6N<$g3t}1&;S4c diff --git a/libs/opmapcontrol/src/mapwidget/images/airplane.png b/libs/opmapcontrol/src/mapwidget/images/airplane.png deleted file mode 100644 index 81c73a7c4c64b6cd051923f31a1f552ea262d79d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1747 zcmV;^1}yoBP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn z4jTXf02y>eSaefwW^{L9a%BK_cXuvnZfkR6VQ^(GZ*pgw?mQX*00uKjL_t(|UhQ2u zODszmEl0iX8@PiY3W_VDfr8mcny7)>y@9xE zASej#`)<8D{cg)R_DuK8^y})9DyXTR?yqY(r}nC^noz;b>gpgL5cw}~b#+DF-`{mT zl4R&Y`Sxw#D-5JL2?d{F5EN?*}$?zt(2L=Z6#@KN9 zLXzRlq=6*Ea9;3D&}hkUIK;|pV#W3^cSgww3JUU#ZBB3f?-PYjPfz6W@sX%5u3<5E zgs!JA?&akrIXXHr1X+4|I*E&m`(k5bW53;tjEp3qp`mWA71f<48R)}fDggSXdZsZf>UY^Yh=E zRYf#8Iav~6ArUHJSy@?>P46g#pkbw@rKOSx4n(Mg)YsQj)=pD0IXNkb;7Ei@2wN

s%x3{-PF=-{M9sjExBN(#9D%#f8 zMqgiFzmtJGSkGv0Z>P|2Fyf(<@r}5;x;nbCvEhC_!}-bV>@2OSs-j>|0`42&uDC&~ zsuQ3da5kHO5+&;DC(r7q$u50mZ=qs@f@ph zJih4lhJ=@w7ljn;0*9+w{KuL%cJN^h9ag<|b+Nkx&sEp?8uwT|N^Wm&72;uWjjfvg zn(**&W&JriI$Cj=3L3#i16PYJKDdWnnvA)d~<`nQ%7n>V=FcVCw}X$d-v=Og7HQ`3B8_y$ZJ(oqBh>blc7~IBpIA4VOcUb0k0M8Pb(R= z(a(VX#s2<2+1lD7?5H@!o}8R03OG=d(Qe4oRJe@11v zk&&C5Yc!6Q%T-iVSRN+V5qL>SiETG0S5{VXA%j~3juvukY|M7ODMkdnzP{$tfO91S zDc;%Hp}oDmw79sKvW*1XdRI7pyrrc@In0KavCRlvtru{bC{8|bKH|dNHF{$>DFNqZ z!9ekTX=zD0qXYMF^o1u^J(dE>{!rrQZEQz|w}7A{fGHFhv_tIs;NE&+8+mTMDYFph p>FH7Cn-UTdNOyO)S>AH-=U+6Ht#G<=BFF#$002ovPDHLkV1iYQC*A-6 diff --git a/libs/opmapcontrol/src/mapwidget/images/airplane.svg b/libs/opmapcontrol/src/mapwidget/images/airplane.svg deleted file mode 100644 index da6977bec..000000000 --- a/libs/opmapcontrol/src/mapwidget/images/airplane.svg +++ /dev/null @@ -1,113 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - diff --git a/libs/opmapcontrol/src/mapwidget/images/airplanepip.png b/libs/opmapcontrol/src/mapwidget/images/airplanepip.png deleted file mode 100644 index d9b2279fc6e0e54a2e98d0b18349f5731f1afbdb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13242 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/libs/opmapcontrol/src/mapwidget/images/dragons1.jpg b/libs/opmapcontrol/src/mapwidget/images/dragons1.jpg deleted file mode 100644 index 8e6a416bf7e8b66d68d8901898b19099cc98946e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171656 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 diff --git a/libs/opmapcontrol/src/mapwidget/images/dragons2.jpeg b/libs/opmapcontrol/src/mapwidget/images/dragons2.jpeg deleted file mode 100644 index 7fadce4056a486a109bb66beb2fd921b745cef85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93157 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 - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - - diff --git a/libs/opmapcontrol/src/mapwidget/images/home2.svg b/libs/opmapcontrol/src/mapwidget/images/home2.svg deleted file mode 100644 index 4eef55159..000000000 --- a/libs/opmapcontrol/src/mapwidget/images/home2.svg +++ /dev/null @@ -1,80 +0,0 @@ - - - - - - - - - - - image/svg+xml - - - - - - - - - - diff --git a/libs/opmapcontrol/src/mapwidget/images/mapquad.png b/libs/opmapcontrol/src/mapwidget/images/mapquad.png deleted file mode 100644 index 8f968a277295e44cce698127fd1a4dd36d57976e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1044 zcmV+v1nc{WP)9CoLLg8ddQOj_2OkQ%PBoV9CMlFq=%EC3a2mC^kQ&F1ZC2H;cV7@6DT!dAxZuv&77hg>Bmdnx++q=rRB>^UCh-ZfR<2YF*Yh$qE!g zWB_~vz-Xgf0N!^osS~fN>Jm$4p>&eu^Z8`}6#{~&FKkyrP72c7OoZpRZ(ocrFV_IT$>oN| zo;>-p8-BYc@He8A4r~B`2lQWI-t2~7=@9?lI1?y~Gl8=BK%fvJZrk=bBBGBigowzt z?Q`w5o0u6whzv7Nw-o-ms;W!*e17?;m7q$L@PQWqpaLUV=Ix^jE0@bT-}i3-hyegI z*NAArG|g4AENej5_4_#Z$W$>+vwW0^000lD8Id^-{=;$)LWn$o@dGH=^SnozrfG#% zaW0e2K{NCOnz;MJufIQiHL%rbf}L2yU%Qvx#tcn^@ht#ghGy}Y7t-_9L|?r}?KF0B zcs-d*DiaKD&Zi(Sh`o?DG)*f|sZ@FhAQcVzWg~H`9;k!S_w%=(VfEjhjw?WfYORs| z3V-7@fG@)Czi=LxhI*VcDNxY=l`_-hIkK{bgN}^BPOx{ O000064nq=pa)DvOC(e%Pok4KS#%2QOGzf_1_@zp2K0iM zm1IirS}u*IzJnz+(Rx;-t7egISjho?e`%{1hYo2-5hG>sd$7%)Oa;cZ849vn8b#{v zAnIx->TGkT%S^mBYip(&m6E03K)$DJBY1OIsi41|CZcOTM4sTBdB}C@OqPBCu}g*B zsYr9mY7|!`TfEzLn!Rvd%#4p^X`f3b2cHKjOC71KTIK@RJglx@;gqumf<8(TP7|gE ze&}u|Pqx)l_x`<u&Hdue-c%p)y4Z zuMe_tje0R%~p$ty%QhZhkkm znSNeu5moVVEbL#}DN-<2i)zpFFz`s-CrA~4E;_6G3CKMAIfql%=c>`C7NRSr<%KAO zaaSJ8rom2s6Q=>V84VN~62d~Q5MVrU3=S3|^&U+T%ian>giaP2 zN#CtTN4kY6Ni4h_j4*+VGpetpX-gADgoUxNSO_v+-K{94QN503UqN)R!oh|exzu~0 zn1wHdbqJ#d?+gAM@ti1uhBiGehO%Yx5S{H-v>w7l@Y^X= kt%ooId<5elZl#m|0Vk{&vLebb#Q*>R07*qoM6N<$fSetCurrentRegion(internals::Rectangle(0, 0, maprect.width(), maprect.height())); - core->SetMapType(MapType::GoogleHybrid); - this->SetZoom(2); - connect(core,SIGNAL(OnNeedInvalidation()),this,SLOT(Core_OnNeedInvalidation())); - connect(core,SIGNAL(OnMapDrag()),this,SLOT(ChildPosRefresh())); - connect(core,SIGNAL(OnMapZoomChanged()),this,SLOT(ChildPosRefresh())); - //resize(); - } - void MapGraphicItem::start() - { - core->StartSystem(); - } - - void MapGraphicItem::resize(const QRectF &rect) - { - Q_UNUSED(rect); - { - this->prepareGeometryChange(); - maprect=boundingBox(scene()->sceneRect(),rotation); - this->setTransform(QTransform().translate(-(maprect.width()-scene()->width())/2,-(maprect.height()-scene()->height())/2)); - this->setTransformOriginPoint(maprect.center().x(),maprect.center().y()); - this->setRotation(rotation); - } - - core->OnMapSizeChanged(maprect.width(),maprect.height()); - core->SetCurrentRegion(internals::Rectangle(0, 0, maprect.width(), maprect.height())); - if(isVisible()) - { - core->GoToCurrentPosition(); - } - } - - QRectF MapGraphicItem::boundingRect() const - { - const int Margin = 1; - return maprect.adjusted(-Margin, -Margin, +Margin, +Margin); - } - void MapGraphicItem::Core_OnNeedInvalidation() - { - this->update(); - foreach(QGraphicsItem* i,this->childItems()) - { - WayPointItem* w=qgraphicsitem_cast(i); - if(w) - w->RefreshPos(); - UAVItem* ww=qgraphicsitem_cast(i); - if(ww) - ww->RefreshPos(); - HomeItem* www=qgraphicsitem_cast(i); - if(www) - www->RefreshPos(); - GPSItem* wwww=qgraphicsitem_cast(i); - if(wwww) - wwww->RefreshPos(); - - emit mapChanged(); - } - } - void MapGraphicItem::ChildPosRefresh() - { - foreach(QGraphicsItem* i,this->childItems()) - { - WayPointItem* w=qgraphicsitem_cast(i); - if(w) - w->RefreshPos(); - UAVItem* ww=qgraphicsitem_cast(i); - if(ww) - ww->RefreshPos(); - HomeItem* www=qgraphicsitem_cast(i); - if(www) - www->RefreshPos(); - GPSItem* wwww=qgraphicsitem_cast(i); - if(wwww) - wwww->RefreshPos(); - - emit mapChanged(); - } - } - void MapGraphicItem::ConstructLastImage(int const& zoomdiff) - { - QImage temp; - QSize size=boundingRect().size().toSize(); - size.setWidth(size.width()*2*zoomdiff); - size.setHeight(size.height()*2*zoomdiff); - temp=QImage(size, - QImage::Format_ARGB32_Premultiplied); - temp.fill(0); - if (!temp.isNull()) { - QPainter imagePainter(&temp); - imagePainter.translate(-boundingRect().topLeft()); - imagePainter.scale(2*zoomdiff,2*zoomdiff); - paintImage(&imagePainter); - imagePainter.end(); - lastimagepoint=Point(core->GetrenderOffset().X()*2*zoomdiff,core->GetrenderOffset().Y()*2*zoomdiff); - lastimage=temp; - } - } - void MapGraphicItem::paintImage(QPainter *painter) - { - - if(MapRenderTransform!=1) - { - QTransform transform; - transform.translate(-((boundingRect().width()*MapRenderTransform)-(boundingRect().width()))/2,-((boundingRect().height()*MapRenderTransform)-(boundingRect().height()))/2); - transform.scale(MapRenderTransform,MapRenderTransform); - painter->setWorldTransform(transform); - { - DrawMap2D(painter); - } - painter->resetTransform(); - } - else - { - DrawMap2D(painter); - } - //painter->drawRect(maprect); - } - void MapGraphicItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - - if(MapRenderTransform!=1) - { - QTransform transform; - transform.translate(-((boundingRect().width()*MapRenderTransform)-(boundingRect().width()))/2,-((boundingRect().height()*MapRenderTransform)-(boundingRect().height()))/2); - transform.scale(MapRenderTransform,MapRenderTransform); - - painter->setWorldTransform(transform); - painter->setRenderHint(QPainter::SmoothPixmapTransform,true); - painter->setRenderHint(QPainter::HighQualityAntialiasing,true); - - { - DrawMap2D(painter); - } - painter->resetTransform(); - } - else - { - DrawMap2D(painter); - } - } - void MapGraphicItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) - { - if(core->IsDragging()) - { - if(MapRenderTransform!=1) - { - qreal dx= (event->pos().x()-core->mouseDown.X())/(MapRenderTransform); - qreal dy= (event->pos().y()-core->mouseDown.Y())/(MapRenderTransform); - qreal nx=core->mouseDown.X()+dx; - qreal ny=core->mouseDown.Y()+dy; - core->mouseCurrent.SetX(nx); - core->mouseCurrent.SetY(ny); - } - else - { - core->mouseCurrent.SetX(event->pos().x()); - core->mouseCurrent.SetY(event->pos().y()); - } - { - core->Drag(core->mouseCurrent); - } - - } - else if(isSelected && !selectionStart.IsEmpty() && (event->modifiers() == Qt::AltModifier || event->modifiers() == Qt::ShiftModifier)) - { - selectionEnd = FromLocalToLatLng(event->pos().x(), event->pos().y()); - { - internals::PointLatLng p1 = selectionStart; - internals::PointLatLng p2 = selectionEnd; - - double x1 = qMin(p1.Lng(), p2.Lng()); - double y1 = qMax(p1.Lat(), p2.Lat()); - double x2 = qMax(p1.Lng(), p2.Lng()); - double y2 = qMin(p1.Lat(), p2.Lat()); - - SetSelectedArea(internals::RectLatLng(y1, x1, x2 - x1, y1 - y2)); - } - } - QGraphicsItem::mouseMoveEvent(event); - } - void MapGraphicItem::mousePressEvent(QGraphicsSceneMouseEvent *event) - { - - - - if(!IsMouseOverMarker()) - { - if(event->button() == config->DragButton && CanDragMap()&& !((event->modifiers()==Qt::AltModifier)||(event->modifiers()==Qt::ShiftModifier))) - { - core->mouseDown.SetX(event->pos().x()); - core->mouseDown.SetY(event->pos().y()); - - - this->setCursor(Qt::SizeAllCursor); - - core->BeginDrag(core->mouseDown); - this->update(); - - } - else if(!isSelected && ((event->modifiers()==Qt::AltModifier)||(event->modifiers()==Qt::ShiftModifier))) - { - isSelected = true; - SetSelectedArea (internals::RectLatLng::Empty); - selectionEnd = internals::PointLatLng::Empty; - selectionStart = FromLocalToLatLng(event->pos().x(), event->pos().y()); - } - } - - } - void MapGraphicItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) - { - if(isSelected) - { - isSelected = false; - } - - if(core->IsDragging()) - { - core->EndDrag(); - - this->setCursor(Qt::ArrowCursor); - if(!BoundsOfMap.IsEmpty() && !BoundsOfMap.Contains(core->CurrentPosition())) - { - if(!core->LastLocationInBounds.IsEmpty()) - { - core->SetCurrentPosition(core->LastLocationInBounds); - } - } - } - else - { - if(!selectionEnd.IsEmpty() && !selectionStart.IsEmpty()) - { - if(!selectedArea.IsEmpty() && event->modifiers() == Qt::ShiftModifier) - { - SetZoomToFitRect(SelectedArea()); - } - } - - } - } - bool MapGraphicItem::SetZoomToFitRect(internals::RectLatLng const& rect) - { - int maxZoom = core->GetMaxZoomToFitRect(rect); - if(maxZoom > 0) - { - internals::PointLatLng center=internals::PointLatLng(rect.Lat()-(rect.HeightLat()/2), rect.Lng()+(rect.WidthLng()/2)); - core->SetCurrentPosition(center); - - if(maxZoom > MaxZoom()) - { - maxZoom = MaxZoom(); - } - - if((int) Zoom() != maxZoom) - { - SetZoom(maxZoom); - } - - return true; - } - return false; - } - - void MapGraphicItem::wheelEvent(QGraphicsSceneWheelEvent *event) - { - - if(!IsMouseOverMarker() && !IsDragging()) - { - if(core->GetmouseLastZoom().X() != event->pos().x() && core->mouseLastZoom.Y() != event->pos().y()) - { - if(GetMouseWheelZoomType() == internals::MouseWheelZoomType::MousePositionAndCenter) - { - core->SetCurrentPosition(FromLocalToLatLng(event->pos().x(), event->pos().y())); - } - else if(GetMouseWheelZoomType() == internals::MouseWheelZoomType::ViewCenter) - { - core->SetCurrentPosition(FromLocalToLatLng((int) maprect.width()/2, (int) maprect.height()/2)); - } - else if(GetMouseWheelZoomType() == internals::MouseWheelZoomType::MousePositionWithoutCenter) - { - core->SetCurrentPosition(FromLocalToLatLng(event->pos().x(), event->pos().y())); - - } - - core->mouseLastZoom.SetX((event->pos().x())); - core->mouseLastZoom.SetY((event->pos().y())); - } - - // set mouse position to map center - if(GetMouseWheelZoomType() != internals::MouseWheelZoomType::MousePositionWithoutCenter) - { - { - // System.Drawing.Point p = PointToScreen(new System.Drawing.Point(Width/2, Height/2)); - // Stuff.SetCursorPos((int) p.X, (int) p.Y); - } - } - - core->MouseWheelZooming = true; - - if(event->delta() > 0) - { - SetZoom(ZoomTotal()+1); - } - else if(event->delta() < 0) - { - SetZoom(ZoomTotal()-1); - } - - core->MouseWheelZooming = false; - } - } - void MapGraphicItem::DrawMap2D(QPainter *painter) - { - painter->setBackground(QBrush(Qt::black)); - if(!lastimage.isNull()) - painter->drawImage(core->GetrenderOffset().X()-lastimagepoint.X(),core->GetrenderOffset().Y()-lastimagepoint.Y(),lastimage); - - for(int i = -core->GetsizeOfMapArea().Width(); i <= core->GetsizeOfMapArea().Width(); i++) - { - for(int j = -core->GetsizeOfMapArea().Height(); j <= core->GetsizeOfMapArea().Height(); j++) - { - core->SettilePoint (core->GetcenterTileXYLocation()); - core->SettilePoint(Point(core->GettilePoint().X()+ i,core->GettilePoint().Y()+j)); - { - internals::Tile* t = core->Matrix.TileAt(core->GettilePoint()); - if(true) - { - core->tileRect.SetX(core->GettilePoint().X()*core->tileRect.Width()); - core->tileRect.SetY(core->GettilePoint().Y()*core->tileRect.Height()); - core->tileRect.Offset(core->GetrenderOffset()); - if(core->GetCurrentRegion().IntersectsWith(core->tileRect)) - { - bool found = false; - - // render tile - //lock(t.Overlays) - if(t!=0) - { - foreach(QByteArray img,t->Overlays) - { - if(img.count()!=0) - { - if(!found) - found = true; - { - painter->drawPixmap(core->tileRect.X(),core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height(),PureImageProxy::FromStream(img)); - // qDebug()<<"tile:"<tileRect.X()<tileRect.Y(); - } - } - } - } - - if(showTileGridLines) - { - painter->setPen(config->EmptyTileBorders); - painter->drawRect(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()); - { - painter->setFont(config->MissingDataFont); - painter->setPen(Qt::red); - painter->drawText(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()),Qt::AlignCenter,(core->GettilePoint() == core->GetcenterTileXYLocation()? "CENTER: " :"TILE: ")+core->GettilePoint().ToString()); - //qDebug()<<"ShowTileGridLine:"<GettilePoint().ToString()<<"=="<GetcenterTileXYLocation().ToString(); - } - } - - // add text if tile is missing - if(false) - { - - painter->fillRect(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()),config->EmptytileBrush); - painter->setFont(config->MissingDataFont); - painter->drawText(QRectF(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()),config->EmptyTileText); - - - - painter->setPen(config->EmptyTileBorders); - painter->drawRect(core->tileRect.X(), core->tileRect.Y(), core->tileRect.Width(), core->tileRect.Height()); - - // raise error - - } - if(!SelectedArea().IsEmpty()) - { - core::Point p1 = FromLatLngToLocal(SelectedArea().LocationTopLeft()); - core::Point p2 = FromLatLngToLocal(SelectedArea().LocationRightBottom()); - int x1 = p1.X(); - int y1 = p1.Y(); - int x2 = p2.X(); - int y2 = p2.Y(); - painter->setPen(Qt::black); - painter->setBrush(QBrush(QColor(50,50,100,20))); - painter->drawRect(x1,y1,x2-x1,y2-y1); - } - } - } - } - } - } - // painter->drawRect(core->GetrenderOffset().X()-lastimagepoint.X()-3,core->GetrenderOffset().Y()-lastimagepoint.Y()-3,lastimage.width(),lastimage.height()); -// painter->setPen(Qt::red); -// painter->drawLine(-10,-10,10,10); -// painter->drawLine(10,10,-10,-10); -// painter->drawRect(boundingRect().adjusted(100,100,-100,-100)); - } - - - core::Point MapGraphicItem::FromLatLngToLocal(internals::PointLatLng const& point) - { - core::Point ret = core->FromLatLngToLocal(point); - if(MapRenderTransform!=1) - { - ret.SetX((int) (ret.X() * MapRenderTransform)); - ret.SetY((int) (ret.Y() * MapRenderTransform)); - ret.SetX(ret.X()-((boundingRect().width()*MapRenderTransform)-(boundingRect().width()))/2); - ret.SetY(ret.Y()-((boundingRect().height()*MapRenderTransform)-(boundingRect().height()))/2); - - - } - return ret; - } - internals::PointLatLng MapGraphicItem::FromLocalToLatLng(int x, int y) - { - if(MapRenderTransform!=1) - { - x=x+((boundingRect().width()*MapRenderTransform)-(boundingRect().width()))/2; - y=y+((boundingRect().height()*MapRenderTransform)-(boundingRect().height()))/2; - - x = (int) (x / MapRenderTransform); - y = (int) (y / MapRenderTransform); - } - return core->FromLocalToLatLng(x, y); - } - float MapGraphicItem::metersToPixels(double meters, internals::PointLatLng coord) - { - return meters/this->Projection()->GetGroundResolution(this->ZoomTotal(),coord.Lat()); - } - - - double MapGraphicItem::Zoom() - { - return zoomReal; - } - double MapGraphicItem::ZoomDigi() - { - return zoomDigi; - } - double MapGraphicItem::ZoomTotal() - { - return zoomDigi+zoomReal; - } - - void MapGraphicItem::SetZoom(double const& value) - { - if(ZoomTotal() != value) - { - if(value > MaxZoom()) - { - zoomReal = MaxZoom(); - zoomDigi =value-MaxZoom(); - } - else - if(value < MinZoom()) - { - zoomDigi=0; - zoomReal = MinZoom(); - } - else - { - zoomDigi=0; - zoomReal = value; - } - double integer; - double remainder = modf (value , &integer); - if(zoomDigi!=0||remainder != 0) - { - float scaleValue = zoomDigi+remainder + 1; - { - MapRenderTransform = scaleValue; - // qDebug()<<"scale="<MaxZoom()) - integer=MaxZoom(); - SetZoomStep((qint32)(integer)); - // core->GoToCurrentPositionOnZoom(); - this->update(); - - } - else - { - - MapRenderTransform = 1; - - SetZoomStep ((qint32)(value)); - zoomReal = ZoomStep(); - this->update(); - } - } - } - int MapGraphicItem::ZoomStep()const - { - return core->Zoom(); - } - void MapGraphicItem::SetZoomStep(int const& value) - { - if(value-core->Zoom()>0 && value<= MaxZoom()) - ConstructLastImage(value-core->Zoom()); - else if(value!=MaxZoom()) - lastimage=QImage(); - if(value > MaxZoom()) - { - core->SetZoom(MaxZoom()); - emit zoomChanged(MaxZoom()+ZoomDigi(),Zoom(),ZoomDigi()); - } - else if(value < MinZoom()) - { - core->SetZoom(MinZoom()); - emit zoomChanged(MinZoom()+ZoomDigi(),Zoom(),ZoomDigi()); - } - else - { - core->SetZoom(value); - emit zoomChanged(value+ZoomDigi(),Zoom(),ZoomDigi());; - } - - } - - void MapGraphicItem::Offset(int const& x, int const& y) - { - core->DragOffset(Point(x, y)); - } - void MapGraphicItem::mapRotate(qreal angle) - { - if (rotation != angle) { - rotation=angle; - resize(scene()->sceneRect()); - } - } - QRectF MapGraphicItem::boundingBox(const QRectF &rect, const qreal &angle) - { - QRectF ret(rect); - float c=cos(angle*2*M_PI/360); - float s=sin(angle*2*M_PI/360); - ret.setHeight(rect.height()*fabs(c)+rect.width()*fabs(s)); - ret.setWidth(rect.width()*fabs(c)+rect.height()*fabs(s)); - return ret; - } - QSize MapGraphicItem::sizeHint()const - { - core::Size size=core->projection->GetTileMatrixMaxXY(MinZoom()); - core::Size tilesize=core->projection->TileSize(); - QSize rsize((size.Width()+1)*tilesize.Width(),(size.Height()+1)*tilesize.Height()); - return rsize; - } -} diff --git a/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h b/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h deleted file mode 100644 index ff06e6096..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapgraphicitem.h +++ /dev/null @@ -1,240 +0,0 @@ -/** -****************************************************************************** -* -* @file mapgraphicitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief The main graphicsItem used on the widget, contains the map and map logic -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MAPGRAPHICITEM_H -#define MAPGRAPHICITEM_H - -#include -#include -#include "../internals/core.h" -//#include "../internals/point.h" -#include "../core/diagnostics.h" -#include "configuration.h" -#include -#include -#include -#include -#include -#include -#include "waypointitem.h" -//#include "uavitem.h" -namespace mapcontrol -{ - class OPMapWidget; - /** - * @brief The main graphicsItem used on the widget, contains the map and map logic - * - * @class MapGraphicItem mapgraphicitem.h "mapgraphicitem.h" - */ - class MapGraphicItem:public QObject,public QGraphicsItem - { - friend class mapcontrol::OPMapWidget; - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - - - /** - * @brief Contructer - * - * @param core - * @param configuration the configuration to be used - * @return - */ - MapGraphicItem(internals::Core *core,Configuration *configuration); - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - - QSize sizeHint()const; - /** - * @brief Convertes LatLong coordinates to local item coordinates - * - * @param point LatLong point to be converted - * @return core::Point Local item point - */ - core::Point FromLatLngToLocal(internals::PointLatLng const& point); - /** - * @brief Converts from local item coordinates to LatLong point - * - * @param x x local coordinate - * @param y y local coordinate - * @return internals::PointLatLng LatLng coordinate - */ - internals::PointLatLng FromLocalToLatLng(int x, int y); - /** - * @brief Converts from meters at one location to pixels - * - * @param meters Distance to convert - * @param coord Coordinate close to the distance measure - * @return float Distance in pixels - */ - float metersToPixels(double meters, internals::PointLatLng coord); - /** - * @brief Returns true if map is being dragged - * - * @return - */ - bool IsDragging()const{return core->IsDragging();} - - QImage lastimage; -// QPainter* imagePainter; - core::Point lastimagepoint; - void paintImage(QPainter* painter); - void ConstructLastImage(int const& zoomdiff); - internals::PureProjection* Projection()const{return core->Projection();} - double Zoom(); - double ZoomDigi(); - double ZoomTotal(); - - /** - * @brief The area currently selected by the user - * - * @return The rectangle in lat/lon coordinates currently selected - */ - internals::RectLatLng SelectedArea()const{return selectedArea;} - - public slots: - void SetSelectedArea(internals::RectLatLng const& value){selectedArea = value;this->update();} - - protected: - void mouseMoveEvent ( QGraphicsSceneMouseEvent * event ); - void mousePressEvent ( QGraphicsSceneMouseEvent * event ); - void wheelEvent ( QGraphicsSceneWheelEvent * event ); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - bool IsMouseOverMarker()const{return isMouseOverMarker;} - - /** - * @brief Returns current map zoom - * - * @return int Current map zoom - */ - int ZoomStep()const; - /** - * @brief Sets map zoom - * - * @param value zoom value - */ - void SetZoomStep(int const& value); - - /** - * @brief Ask Stacey - * - * @param value - */ - void SetShowDragons(bool const& value); - private: - bool showDragons; - bool SetZoomToFitRect(internals::RectLatLng const& rect); - internals::Core *core; - Configuration *config; - bool showTileGridLines; - qreal MapRenderTransform; - void DrawMap2D(QPainter *painter); - /** - * @brief Maximum possible zoom - * - * @var maxZoom - */ - int maxZoom; - /** - * @brief Minimum possible zoom - * - * @var minZoom - */ - int minZoom; - internals::RectLatLng selectedArea; - internals::PointLatLng selectionStart; - internals::PointLatLng selectionEnd; - double zoomReal; - qreal rotation; - double zoomDigi; - QRectF maprect; - bool isSelected; - bool isMouseOverMarker; - QPixmap dragons; - void SetIsMouseOverMarker(bool const& value){isMouseOverMarker = value;} - - - /** - * @brief Creates a rectangle that represents the "view" of the cuurent map, to compensate - * rotation - * - * @param rect original rectangle - * @param angle angle of rotation - * @return QRectF - */ - QRectF boundingBox(QRectF const& rect, qreal const& angle); - /** - * @brief Returns the maximum allowed zoom - * - * @return int - */ - int MaxZoom()const{return core->MaxZoom();} - /** - * @brief Returns the minimum allowed zoom - * - * @return int - */ - int MinZoom()const{return minZoom;} - internals::MouseWheelZoomType::Types GetMouseWheelZoomType(){return core->GetMouseWheelZoomType();} - internals::RectLatLng BoundsOfMap; - void Offset(int const& x, int const& y); - bool CanDragMap()const{return core->CanDragMap;} - void SetCanDragMap(bool const& value){core->CanDragMap = value;} - - void SetZoom(double const& value); - void mapRotate ( qreal angle ); - void start(); - void ReloadMap(){core->ReloadMap();} - GeoCoderStatusCode::Types SetCurrentPositionByKeywords(QString const& keys){return core->SetCurrentPositionByKeywords(keys);} - MapType::Types GetMapType(){return core->GetMapType();} - void SetMapType(MapType::Types const& value){core->SetMapType(value);} - private slots: - void Core_OnNeedInvalidation(); - void ChildPosRefresh(); - public slots: - /** - * @brief To be called when the scene size changes - * - * @param rect - */ - void resize ( QRectF const &rect=QRectF() ); - signals: - /** - * @brief Fired when the current zoom is changed - * - * @param zoom - */ - void zoomChanged(double zoomtotal,double zoomreal,double zoomdigi); - - /** - * @brief Fired when map changes in any visible way - */ - void mapChanged(); - }; -} -#endif // MAPGRAPHICITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/mapresources.qrc b/libs/opmapcontrol/src/mapwidget/mapresources.qrc deleted file mode 100644 index cfb7f5131..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapresources.qrc +++ /dev/null @@ -1,21 +0,0 @@ - - - images/bigMarkerGreen.png - images/marker.png - images/airplane.svg - images/home.png - images/home.svg - images/home2.svg - images/airplanepip.png - images/EasystarBlue.png - images/mapquad.png - images/dragons1.jpg - images/dragons2.jpeg - images/compas.svg - - - images/airplanepip.png - images/EasystarBlue.png - images/mapquad.png - - diff --git a/libs/opmapcontrol/src/mapwidget/mapripform.cpp b/libs/opmapcontrol/src/mapwidget/mapripform.cpp deleted file mode 100644 index 4c143ba3d..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapripform.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/** -****************************************************************************** -* -* @file mapripform.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief Form to be used with the MapRipper class -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "mapripform.h" -#include "ui_mapripform.h" - -MapRipForm::MapRipForm(QWidget *parent) : - QWidget(parent), - ui(new Ui::MapRipForm) -{ - ui->setupUi(this); -} - -MapRipForm::~MapRipForm() -{ - delete ui; -} -void MapRipForm::SetPercentage(const int &perc) -{ - ui->progressBar->setValue(perc); -} -void MapRipForm::SetProvider(const QString &prov,const int &zoom) -{ - ui->mainlabel->setText(QString("Currently ripping from:%1 at Zoom level %2").arg(prov).arg(zoom)); -} -void MapRipForm::SetNumberOfTiles(const int &total, const int &actual) -{ - ui->statuslabel->setText(QString("Downloading tile %1 of %2").arg(actual).arg(total)); -} diff --git a/libs/opmapcontrol/src/mapwidget/mapripform.h b/libs/opmapcontrol/src/mapwidget/mapripform.h deleted file mode 100644 index 8af4c9663..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapripform.h +++ /dev/null @@ -1,51 +0,0 @@ -/** -****************************************************************************** -* -* @file mapripform.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief Form to be used with the MapRipper class -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MAPRIPFORM_H -#define MAPRIPFORM_H - -#include - -namespace Ui { - class MapRipForm; -} - -class MapRipForm : public QWidget -{ - Q_OBJECT - -public: - explicit MapRipForm(QWidget *parent = 0); - ~MapRipForm(); -public slots: - void SetPercentage(int const& perc); - void SetProvider(QString const& prov,int const& zoom); - void SetNumberOfTiles(int const& total,int const& actual); -private: - Ui::MapRipForm *ui; -}; - -#endif // MAPRIPFORM_H diff --git a/libs/opmapcontrol/src/mapwidget/mapripform.ui b/libs/opmapcontrol/src/mapwidget/mapripform.ui deleted file mode 100644 index ed1ce2602..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapripform.ui +++ /dev/null @@ -1,71 +0,0 @@ - - - MapRipForm - - - - 0 - 0 - 392 - 133 - - - - MapRipper - - - - - 20 - 60 - 371 - 23 - - - - 0 - - - - - - 30 - 10 - 321 - 16 - - - - Currently ripping from: - - - - - - 30 - 40 - 341 - 16 - - - - Downloading tile - - - - - - 280 - 100 - 75 - 23 - - - - Cancel - - - - - - diff --git a/libs/opmapcontrol/src/mapwidget/mapripper.cpp b/libs/opmapcontrol/src/mapwidget/mapripper.cpp deleted file mode 100644 index 7dc3004ff..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapripper.cpp +++ /dev/null @@ -1,134 +0,0 @@ -/** -****************************************************************************** -* -* @file mapripper.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A class that allows ripping of a selection of the map -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "mapripper.h" - -#include - -namespace mapcontrol -{ - - MapRipper::MapRipper(internals::Core * core, const internals::RectLatLng & rect):sleep(100),cancel(false),progressForm(0),core(core) - { - if(!rect.IsEmpty()) - { - type=core->GetMapType(); - progressForm=new MapRipForm; - area=rect; - zoom=core->Zoom(); - maxzoom=core->MaxZoom(); - points=core->Projection()->GetAreaTileList(area,zoom,0); - this->start(); - progressForm->show(); - connect(this,SIGNAL(percentageChanged(int)),progressForm,SLOT(SetPercentage(int))); - connect(this,SIGNAL(numberOfTilesChanged(int,int)),progressForm,SLOT(SetNumberOfTiles(int,int))); - connect(this,SIGNAL(providerChanged(QString,int)),progressForm,SLOT(SetProvider(QString,int))); - connect(this,SIGNAL(finished()),this,SLOT(finish())); - emit numberOfTilesChanged(0,0); - } - } - void MapRipper::finish() - { - if(zoomProjection()->GetAreaTileList(area,zoom,0); - this->start(); - } - else - { - progressForm->close(); - delete progressForm; - this->deleteLater(); - } - } - else - { - progressForm->close(); - delete progressForm; - this->deleteLater(); - } - } - - - void MapRipper::run() - { - int countOk = 0; - bool goodtile=false; - // Stuff.Shuffle(ref list); - QVector types = OPMaps::Instance()->GetAllLayersOfType(type); - int all=points.count(); - for(int i = 0; i < all; i++) - { - emit numberOfTilesChanged(all,i+1); - if(cancel) - break; - - core::Point p = points[i]; - { - //qDebug()<<"offline fetching:"<GetImageFrom(type, p, zoom); - if(img.length()!=0) - { - goodtile=true; - img=NULL; - } - else - goodtile=false; - } - if(goodtile) - { - countOk++; - } - else - { - i--; - QThread::msleep(1000); - continue; - } - } - emit percentageChanged((int) ((i+1)*100/all));//, i+1); - // worker.ReportProgress((int) ((i+1)*100/all), i+1); - - QThread::msleep(sleep); - } - } -} diff --git a/libs/opmapcontrol/src/mapwidget/mapripper.h b/libs/opmapcontrol/src/mapwidget/mapripper.h deleted file mode 100644 index 20259e128..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapripper.h +++ /dev/null @@ -1,64 +0,0 @@ -/** -****************************************************************************** -* -* @file mapripper.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A class that allows ripping of a selection of the map -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef MAPRIPPER_H -#define MAPRIPPER_H - -#include -#include "../internals/core.h" -#include "mapripform.h" -#include -#include -namespace mapcontrol -{ - class MapRipper:public QThread - { - Q_OBJECT - public: - MapRipper(internals::Core *,internals::RectLatLng const&); - void run(); - private: - QList points; - int zoom; - core::MapType::Types type; - int sleep; - internals::RectLatLng area; - bool cancel; - MapRipForm * progressForm; - int maxzoom; - internals::Core * core; - - signals: - void percentageChanged(int const& perc); - void numberOfTilesChanged(int const& total,int const& actual); - void providerChanged(QString const& prov,int const& zoom); - - - public slots: - void finish(); - }; -} -#endif // MAPRIPPER_H diff --git a/libs/opmapcontrol/src/mapwidget/mapwidget.pro b/libs/opmapcontrol/src/mapwidget/mapwidget.pro deleted file mode 100644 index 5402e8c2b..000000000 --- a/libs/opmapcontrol/src/mapwidget/mapwidget.pro +++ /dev/null @@ -1,50 +0,0 @@ -TEMPLATE = lib -TARGET = opmapwidget -DEFINES += OPMAPWIDGET_LIBRARY -include(../../../../openpilotgcslibrary.pri) - -# DESTDIR = ../build -SOURCES += mapgraphicitem.cpp \ - opmapwidget.cpp \ - configuration.cpp \ - waypointitem.cpp \ - uavitem.cpp \ - gpsitem.cpp \ - trailitem.cpp \ - homeitem.cpp \ - mapripform.cpp \ - mapripper.cpp \ - traillineitem.cpp - -LIBS += -L../build \ - -lcore \ - -linternals \ - -lcore - -# order of linking matters -include(../../../utils/utils.pri) - -POST_TARGETDEPS += ../build/libcore.a -POST_TARGETDEPS += ../build/libinternals.a - -HEADERS += mapgraphicitem.h \ - opmapwidget.h \ - configuration.h \ - waypointitem.h \ - uavitem.h \ - gpsitem.h \ - uavmapfollowtype.h \ - uavtrailtype.h \ - trailitem.h \ - homeitem.h \ - mapripform.h \ - mapripper.h \ - traillineitem.h -QT += opengl -QT += network -QT += sql -QT += svg -RESOURCES += mapresources.qrc - -FORMS += \ - mapripform.ui diff --git a/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp b/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp deleted file mode 100644 index 23c895be7..000000000 --- a/libs/opmapcontrol/src/mapwidget/opmapwidget.cpp +++ /dev/null @@ -1,510 +0,0 @@ -/** -****************************************************************************** -* -* @file opmapwidget.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief The Map Widget, this is the part exposed to the user -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "opmapwidget.h" -#include -#include -#include "waypointitem.h" - -namespace mapcontrol -{ - - OPMapWidget::OPMapWidget(QWidget *parent, Configuration *config) : QGraphicsView(parent), - configuration(config), - UAV(0), - GPS(0), - Home(0), - followmouse(true), - compass(0), - showuav(false), - showhome(false), - diagTimer(0), - showDiag(false), - diagGraphItem(0) - { - setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); - core=new internals::Core; - map=new MapGraphicItem(core,config); - mscene.addItem(map); - this->setScene(&mscene); - this->adjustSize(); - connect(map,SIGNAL(zoomChanged(double,double,double)),this,SIGNAL(zoomChanged(double,double,double))); - connect(map->core,SIGNAL(OnCurrentPositionChanged(internals::PointLatLng)),this,SIGNAL(OnCurrentPositionChanged(internals::PointLatLng))); - connect(map->core,SIGNAL(OnEmptyTileError(int,core::Point)),this,SIGNAL(OnEmptyTileError(int,core::Point))); - connect(map->core,SIGNAL(OnMapDrag()),this,SIGNAL(OnMapDrag())); - connect(map->core,SIGNAL(OnMapTypeChanged(MapType::Types)),this,SIGNAL(OnMapTypeChanged(MapType::Types))); - connect(map->core,SIGNAL(OnMapZoomChanged()),this,SIGNAL(OnMapZoomChanged())); - connect(map->core,SIGNAL(OnMapZoomChanged()),this,SLOT(emitMapZoomChanged())); - connect(map->core,SIGNAL(OnTileLoadComplete()),this,SIGNAL(OnTileLoadComplete())); - connect(map->core,SIGNAL(OnTileLoadStart()),this,SIGNAL(OnTileLoadStart())); - connect(map->core,SIGNAL(OnTilesStillToLoad(int)),this,SIGNAL(OnTilesStillToLoad(int))); - SetShowDiagnostics(showDiag); - this->setMouseTracking(followmouse); - SetShowCompass(true); - - } - void OPMapWidget::SetShowDiagnostics(bool const& value) - { - showDiag=value; - if(!showDiag) - { - if(diagGraphItem!=0) - { - delete diagGraphItem; - diagGraphItem=0; - } - if(diagTimer!=0) - { - delete diagTimer; - diagTimer=0; - } - } - else - { - diagTimer=new QTimer(); - connect(diagTimer,SIGNAL(timeout()),this,SLOT(diagRefresh())); - diagTimer->start(500); - } - - } - void OPMapWidget::SetUavPic(QString UAVPic) - { - if(UAV!=0) - UAV->SetUavPic(UAVPic); - if(GPS!=0) - GPS->SetUavPic(UAVPic); - - - } - - UAVItem* OPMapWidget::AddUAV(int id) - { - UAVItem* newUAV = new UAVItem(map,this); - newUAV->setParentItem(map); - UAVS.insert(id, newUAV); - QGraphicsItemGroup* waypointLine = new QGraphicsItemGroup(map); - waypointLines.insert(id, waypointLine); - return newUAV; - } - - void OPMapWidget::AddUAV(int id, UAVItem* uav) - { - uav->setParentItem(map); - QGraphicsItemGroup* waypointLine = new QGraphicsItemGroup(map); - waypointLines.insert(id, waypointLine); - UAVS.insert(id, uav); - } - - void OPMapWidget::DeleteUAV(int id) - { - UAVItem* uav = UAVS.value(id, NULL); - UAVS.remove(id); - if (uav) - { - delete uav; - uav = NULL; - } - QGraphicsItemGroup* wpLine = waypointLines.value(id, NULL); - waypointLines.remove(id); - if (wpLine) - { - delete wpLine; - wpLine = NULL; - } - } - - /** - * @return The reference to the UAVItem or NULL if no item exists yet - * @see AddUAV() for adding a not yet existing UAV to the map - */ - UAVItem* OPMapWidget::GetUAV(int id) - { - return UAVS.value(id, 0); - } - - const QList OPMapWidget::GetUAVS() - { - return UAVS.values(); - } - - QGraphicsItemGroup* OPMapWidget::waypointLine(int id) - { - return waypointLines.value(id, NULL); - } - - void OPMapWidget::SetShowUAV(const bool &value) - { - if(value && UAV==0) - { - UAV=new UAVItem(map,this); - UAV->setParentItem(map); - // FIXME XXX The map widget is here actually handling - // safety and mission logic - might be worth some refactoring - connect(this,SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng)),UAV,SIGNAL(UAVLeftSafetyBouble(internals::PointLatLng))); - connect(this,SIGNAL(UAVReachedWayPoint(int,WayPointItem*)),UAV,SIGNAL(UAVReachedWayPoint(int,WayPointItem*))); - } - else if(!value) - { - if(UAV!=0) - { - delete UAV; - UAV=0; - } - - } - if(value && GPS==0) - { - GPS=new GPSItem(map,this); - GPS->setParentItem(map); - } - else if(!value) - { - if(GPS!=0) - { - delete GPS; - GPS=0; - } - - } - } - void OPMapWidget::SetShowHome(const bool &value) - { - if(value && Home==0) - { - Home=new HomeItem(map,this); - Home->setParentItem(map); - } - else if(!value) - { - if(Home!=0) - { - delete Home; - Home=0; - } - - } - } - - void OPMapWidget::resizeEvent(QResizeEvent *event) - { - if (scene()) - scene()->setSceneRect( - QRect(QPoint(0, 0), event->size())); - QGraphicsView::resizeEvent(event); - if(compass) - compass->setScale(0.1+0.05*(qreal)(event->size().width())/1000*(qreal)(event->size().height())/600); - - } - QSize OPMapWidget::sizeHint() const - { - return map->sizeHint(); - } - void OPMapWidget::showEvent(QShowEvent *event) - { - connect(&mscene,SIGNAL(sceneRectChanged(QRectF)),map,SLOT(resize(QRectF)), Qt::UniqueConnection); - map->start(); - QGraphicsView::showEvent(event); - } - OPMapWidget::~OPMapWidget() - { - delete UAV; - - foreach(UAVItem* uav, this->UAVS) - { - delete uav; - } - - delete Home; - delete map; - delete core; - delete configuration; - foreach(QGraphicsItem* i,this->items()) - { - delete i; - } - } - void OPMapWidget::closeEvent(QCloseEvent *event) - { - core->OnMapClose(); - event->accept(); - } - void OPMapWidget::SetUseOpenGL(const bool &value) - { - useOpenGL=value; - if (useOpenGL) - setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); - else - setupViewport(new QWidget()); - update(); - } - internals::PointLatLng OPMapWidget::currentMousePosition() - { - return currentmouseposition; - } - - void OPMapWidget::mouseMoveEvent(QMouseEvent *event) - { - QGraphicsView::mouseMoveEvent(event); - QPointF p=event->localPos(); - p=map->mapFromParent(p); - currentmouseposition=map->FromLocalToLatLng(p.x(),p.y()); - } - ////////////////WAYPOINT//////////////////////// - WayPointItem* OPMapWidget::WPCreate() - { - WayPointItem* item=new WayPointItem(this->CurrentPosition(),0,map); - ConnectWP(item); - item->setParentItem(map); - return item; - } - void OPMapWidget::WPCreate(WayPointItem* item) - { - ConnectWP(item); - item->setParentItem(map); - } - void OPMapWidget::WPCreate(int id, WayPointItem* item) - { - Q_UNUSED(id); - static internals::PointLatLng lastPos; - - ConnectWP(item); - item->setParentItem(map); - -// QGraphicsItemGroup* wpLine = waypointLines.value(id, NULL); -// if (!wpLine) -// { -// wpLine = new QGraphicsItemGroup(map); -// waypointLines.insert(id, wpLine); -// } - -// if (!lastPos.IsEmpty()) -// { -// wpLine->addToGroup(new TrailLineItem(lastPos, item->Coord(), Qt::red, map)); -// lastPos = item->Coord(); -// } - - - - // Add waypoint line -// trail->addToGroup(new TrailItem(position,altitude,color,this)); -// if(!lasttrailline.IsEmpty()) -// trailLine->addToGroup((new TrailLineItem(lasttrailline,position,color,map))); -// lasttrailline=position; - } - WayPointItem* OPMapWidget::WPCreate(internals::PointLatLng const& coord,int const& altitude) - { - WayPointItem* item=new WayPointItem(coord,altitude,map); - ConnectWP(item); - item->setParentItem(map); - return item; - } - WayPointItem* OPMapWidget::WPCreate(internals::PointLatLng const& coord,int const& altitude, QString const& description) - { - WayPointItem* item=new WayPointItem(coord,altitude,description,map); - ConnectWP(item); - item->setParentItem(map); - return item; - } - WayPointItem* OPMapWidget::WPInsert(const int &position) - { - WayPointItem* item=new WayPointItem(this->CurrentPosition(),0,map); - item->SetNumber(position); - ConnectWP(item); - item->setParentItem(map); - emit WPInserted(position,item); - return item; - } - void OPMapWidget::WPInsert(WayPointItem* item,const int &position) - { - item->SetNumber(position); - ConnectWP(item); - item->setParentItem(map); - emit WPInserted(position,item); - - } - WayPointItem* OPMapWidget::WPInsert(internals::PointLatLng const& coord,int const& altitude,const int &position) - { - WayPointItem* item=new WayPointItem(coord,altitude,map); - item->SetNumber(position); - ConnectWP(item); - item->setParentItem(map); - emit WPInserted(position,item); - return item; - } - WayPointItem* OPMapWidget::WPInsert(internals::PointLatLng const& coord,int const& altitude, QString const& description,const int &position) - { - WayPointItem* item=new WayPointItem(coord,altitude,description,map); - item->SetNumber(position); - ConnectWP(item); - item->setParentItem(map); - emit WPInserted(position,item); - return item; - } - void OPMapWidget::WPDelete(WayPointItem *item) - { - emit WPDeleted(item->Number()); - delete item; - } - void OPMapWidget::WPDeleteAll() - { - foreach(QGraphicsItem* i,map->childItems()) - { - WayPointItem* w=qgraphicsitem_cast(i); - if(w) - delete w; - } - } - QList OPMapWidget::WPSelected() - { - QList list; - foreach(QGraphicsItem* i,mscene.selectedItems()) - { - WayPointItem* w=qgraphicsitem_cast(i); - if(w) - list.append(w); - } - return list; - } - void OPMapWidget::WPRenumber(WayPointItem *item, const int &newnumber) - { - item->SetNumber(newnumber); - } - - void OPMapWidget::ConnectWP(WayPointItem *item) - { - connect(item,SIGNAL(WPNumberChanged(int,int,WayPointItem*)),this,SIGNAL(WPNumberChanged(int,int,WayPointItem*))); - connect(item,SIGNAL(WPValuesChanged(WayPointItem*)),this,SIGNAL(WPValuesChanged(WayPointItem*))); - connect(this,SIGNAL(WPInserted(int,WayPointItem*)),item,SLOT(WPInserted(int,WayPointItem*))); - connect(this,SIGNAL(WPNumberChanged(int,int,WayPointItem*)),item,SLOT(WPRenumbered(int,int,WayPointItem*))); - connect(this,SIGNAL(WPDeleted(int)),item,SLOT(WPDeleted(int))); - } - void OPMapWidget::diagRefresh() - { - if(showDiag) - { - if(diagGraphItem==0) - { - diagGraphItem=new QGraphicsTextItem(); - mscene.addItem(diagGraphItem); - diagGraphItem->setPos(10,100); - diagGraphItem->setZValue(3); - diagGraphItem->setFlag(QGraphicsItem::ItemIsMovable,true); - diagGraphItem->setDefaultTextColor(Qt::yellow); - } - diagGraphItem->setPlainText(core->GetDiagnostics().toString()); - } - else - if(diagGraphItem!=0) - { - delete diagGraphItem; - diagGraphItem=0; - } - } - - ////////////////////////////////////////////// - void OPMapWidget::SetShowCompass(const bool &value) - { - if(value && !compass) - { - compass=new QGraphicsSvgItem(QString::fromUtf8(":/markers/images/compas.svg")); - compass->setScale(0.1+0.05*(qreal)(this->size().width())/1000*(qreal)(this->size().height())/600); - // compass->setTransformOriginPoint(compass->boundingRect().width(),compass->boundingRect().height()); - compass->setFlag(QGraphicsItem::ItemIsMovable,true); - mscene.addItem(compass); - compass->setTransformOriginPoint(compass->boundingRect().width()/2,compass->boundingRect().height()/2); - compass->setPos(55-compass->boundingRect().width()/2,55-compass->boundingRect().height()/2); - compass->setZValue(3); - compass->setOpacity(0.7); - - } - if(!value && compass) - { - delete compass; - compass=0; - } - } - void OPMapWidget::SetRotate(qreal const& value) - { - map->mapRotate(value); - if(compass && (compass->rotation() != value)) { - compass->setRotation(value); - } - } - void OPMapWidget::RipMap() - { - new MapRipper(core,map->SelectedArea()); - } - - -#define deg_to_rad ((double)M_PI / 180.0) -#define rad_to_deg (180.0 / (double)M_PI) -#define earth_mean_radius 6371 // kilometers - -// ************************************************************************************* -// return the bearing from one point to another .. in degrees - -double OPMapWidget::bearing(internals::PointLatLng from, internals::PointLatLng to) -{ - double lat1 = from.Lat() * deg_to_rad; - double lon1 = from.Lng() * deg_to_rad; - - double lat2 = to.Lat() * deg_to_rad; - double lon2 = to.Lng() * deg_to_rad; - -// double delta_lat = lat2 - lat1; - double delta_lon = lon2 - lon1; - - double y = sin(delta_lon) * cos(lat2); - double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon); - double bear = atan2(y, x) * rad_to_deg; - - bear += 360; - while (bear < 0) bear += 360; - while (bear >= 360) bear -= 360; - - return bear; -} - -// ************************************************************************************* -// return a destination lat/lon point given a source lat/lon point and the bearing and distance from the source point - -internals::PointLatLng OPMapWidget::destPoint(internals::PointLatLng source, double bear, double dist) -{ - double lat1 = source.Lat() * deg_to_rad; - double lon1 = source.Lng() * deg_to_rad; - - bear *= deg_to_rad; - - double ad = dist / earth_mean_radius; - - double lat2 = asin(sin(lat1) * cos(ad) + cos(lat1) * sin(ad) * cos(bear)); - double lon2 = lon1 + atan2(sin(bear) * sin(ad) * cos(lat1), cos(ad) - sin(lat1) * sin(lat2)); - - return internals::PointLatLng(lat2 * rad_to_deg, lon2 * rad_to_deg); -} - -} diff --git a/libs/opmapcontrol/src/mapwidget/opmapwidget.h b/libs/opmapcontrol/src/mapwidget/opmapwidget.h deleted file mode 100644 index 305468173..000000000 --- a/libs/opmapcontrol/src/mapwidget/opmapwidget.h +++ /dev/null @@ -1,533 +0,0 @@ -/** -****************************************************************************** -* -* @file opmapwidget.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief The Map Widget, this is the part exposed to the user -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef OPMAPWIDGET_H -#define OPMAPWIDGET_H - -#include "../mapwidget/mapgraphicitem.h" -#include "../core/geodecoderstatus.h" -#include "../core/maptype.h" -#include "../core/languagetype.h" -#include "../core/diagnostics.h" -#include "configuration.h" -#include -#include -#include -#include -#include "waypointitem.h" -#include "QtSvg/QGraphicsSvgItem" -#include "uavitem.h" -#include "gpsitem.h" -#include "homeitem.h" -#include "waypointlineitem.h" -#include "mapripper.h" -#include "uavtrailtype.h" -namespace mapcontrol -{ - class UAVItem; - class GPSItem; - class HomeItem; - /** - * @brief Collection of static functions to help dealing with various enums used - * Contains functions for enumToString conversio, StringToEnum, QStringList of enum values... - * - * @class Helper opmapwidget.h "opmapwidget.h" - */ - class Helper - { - public: - /** - * @brief Converts from String to Type - * - * @param value String to convert - * @return - */ - static MapType::Types MapTypeFromString(QString const& value){return MapType::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromMapType(MapType::Types const& value){return MapType::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList MapTypes(){return MapType::TypesList();} - - /** - * @brief Converts from String to Type - */ - static GeoCoderStatusCode::Types GeoCoderStatusCodeFromString(QString const& value){return GeoCoderStatusCode::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromGeoCoderStatusCode(GeoCoderStatusCode::Types const& value){return GeoCoderStatusCode::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList GeoCoderTypes(){return GeoCoderStatusCode::TypesList();} - - /** - * @brief Converts from String to Type - */ - static internals::MouseWheelZoomType::Types MouseWheelZoomTypeFromString(QString const& value){return internals::MouseWheelZoomType::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromMouseWheelZoomType(internals::MouseWheelZoomType::Types const& value){return internals::MouseWheelZoomType::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList MouseWheelZoomTypes(){return internals::MouseWheelZoomType::TypesList();} - /** - * @brief Converts from String to Type - */ - static core::LanguageType::Types LanguageTypeFromString(QString const& value){return core::LanguageType::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromLanguageType(core::LanguageType::Types const& value){return core::LanguageType::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList LanguageTypes(){return core::LanguageType::TypesList();} - /** - * @brief Converts from String to Type - */ - static core::AccessMode::Types AccessModeFromString(QString const& value){return core::AccessMode::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromAccessMode(core::AccessMode::Types const& value){return core::AccessMode::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList AccessModeTypes(){return core::AccessMode::TypesList();} - - /** - * @brief Converts from String to Type - */ - static UAVMapFollowType::Types UAVMapFollowFromString(QString const& value){return UAVMapFollowType::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromUAVMapFollow(UAVMapFollowType::Types const& value){return UAVMapFollowType::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList UAVMapFollowTypes(){return UAVMapFollowType::TypesList();} - /** - * @brief Converts from String to Type - */ - static UAVTrailType::Types UAVTrailTypeFromString(QString const& value){return UAVTrailType::TypeByStr(value);} - /** - * @brief Converts from Type to String - */ - static QString StrFromUAVTrailType(UAVTrailType::Types const& value){return UAVTrailType::StrByType(value);} - /** - * @brief Returns QStringList with string representing all the enum values - */ - static QStringList UAVTrailTypes(){return UAVTrailType::TypesList();} - }; - - class OPMapWidget:public QGraphicsView - { - Q_OBJECT - - // Q_PROPERTY(int MaxZoom READ MaxZoom WRITE SetMaxZoom) - Q_PROPERTY(int MinZoom READ MinZoom WRITE SetMinZoom) - Q_PROPERTY(bool ShowTileGridLines READ ShowTileGridLines WRITE SetShowTileGridLines) - Q_PROPERTY(double Zoom READ ZoomTotal WRITE SetZoom) - Q_PROPERTY(qreal Rotate READ Rotate WRITE SetRotate) - Q_ENUMS(internals::MouseWheelZoomType::Types) - Q_ENUMS(core::GeoCoderStatusCode::Types) - - public: - QSize sizeHint() const; - /** - * @brief Constructor - * - * @param parent parent widget - * @param config pointer to configuration classed to be used - * @return - */ - OPMapWidget(QWidget *parent=0,Configuration *config=new Configuration); - ~OPMapWidget(); - - /** - * @brief Returns true if map is showing gridlines - * - * @return bool - */ - bool ShowTileGridLines()const {return map->showTileGridLines;} - - /** - * @brief Defines if map is to show gridlines - * - * @param value - * @return - */ - void SetShowTileGridLines(bool const& value){map->showTileGridLines=value;map->update();} - - /** - * @brief Returns the maximum zoom for the map - * - */ - int MaxZoom()const{return map->MaxZoom();} - - // void SetMaxZoom(int const& value){map->maxZoom = value;} - - /** - * @brief - * - */ - int MinZoom()const{return map->minZoom;} - /** - * @brief - * - * @param value - */ - void SetMinZoom(int const& value){map->minZoom = value;} - - internals::MouseWheelZoomType::Types GetMouseWheelZoomType(){return map->core->GetMouseWheelZoomType();} - void SetMouseWheelZoomType(internals::MouseWheelZoomType::Types const& value){map->core->SetMouseWheelZoomType(value);} - // void SetMouseWheelZoomTypeByStr(const QString &value){map->core->SetMouseWheelZoomType(internals::MouseWheelZoomType::TypeByStr(value));} - // QString GetMouseWheelZoomTypeStr(){return map->GetMouseWheelZoomTypeStr();} - - internals::RectLatLng SelectedArea()const{return map->selectedArea;} - void SetSelectedArea(internals::RectLatLng const& value){ map->selectedArea = value;this->update();} - - bool CanDragMap()const{return map->CanDragMap();} - void SetCanDragMap(bool const& value){map->SetCanDragMap(value);} - - internals::PointLatLng CurrentPosition()const{return map->core->CurrentPosition();} - void SetCurrentPosition(internals::PointLatLng const& value){map->core->SetCurrentPosition(value);} - - double ZoomReal(){return map->Zoom();} - double ZoomDigi(){return map->ZoomDigi();} - double ZoomTotal(){return map->ZoomTotal();} - - qreal Rotate(){return map->rotation;} - void SetRotate(qreal const& value); - - void ReloadMap(){map->ReloadMap(); map->resize();} - - GeoCoderStatusCode::Types SetCurrentPositionByKeywords(QString const& keys){return map->SetCurrentPositionByKeywords(keys);} - - bool UseOpenGL(){return useOpenGL;} - void SetUseOpenGL(bool const& value); - - MapType::Types GetMapType(){return map->core->GetMapType();} - void SetMapType(MapType::Types const& value){map->lastimage=QImage(); map->core->SetMapType(value);} - - bool isStarted(){return map->core->isStarted();} - - Configuration* configuration; - - internals::PointLatLng currentMousePosition(); - - void SetFollowMouse(bool const& value){followmouse=value;this->setMouseTracking(followmouse);} - bool FollowMouse(){return followmouse;} - - internals::PointLatLng GetFromLocalToLatLng(QPointF p) {return map->FromLocalToLatLng(p.x(),p.y());} - - /** @brief Convert meters to pixels */ - float metersToPixels(double meters); - - /** @brief Return the bearing from one point to another .. in degrees */ - double bearing(internals::PointLatLng from, internals::PointLatLng to); - - /** @brief Return a destination lat/lon point given a source lat/lon point and the bearing and distance from the source point */ - internals::PointLatLng destPoint(internals::PointLatLng source, double bear, double dist); - - /** - * @brief Creates a new WayPoint on the center of the map - * - * @return WayPointItem a pointer to the WayPoint created - */ - WayPointItem* WPCreate(); - /** - * @brief Creates a new WayPoint - * - * @param item the WayPoint to create - */ - void WPCreate(WayPointItem* item); - /** - * @brief Creates a new WayPoint - * - * @param id the system (MAV) id this waypoint belongs to - * @param item the WayPoint to create - */ - void WPCreate(int id, WayPointItem* item); - /** - * @brief Creates a new WayPoint - * - * @param coord the coordinates in LatLng of the WayPoint - * @param altitude the Altitude of the WayPoint - * @return WayPointItem a pointer to the WayPoint created - */ - WayPointItem* WPCreate(internals::PointLatLng const& coord,int const& altitude); - /** - * @brief Creates a new WayPoint - * - * @param coord the coordinates in LatLng of the WayPoint - * @param altitude the Altitude of the WayPoint - * @param description the description of the WayPoint - * @return WayPointItem a pointer to the WayPoint created - */ - WayPointItem* WPCreate(internals::PointLatLng const& coord,int const& altitude, QString const& description); - /** - * @brief Inserts a new WayPoint on the specified position - * - * @param position index of the WayPoint - * @return WayPointItem a pointer to the WayPoint created - */ - WayPointItem* WPInsert(int const& position); - /** - * @brief Inserts a new WayPoint on the specified position - * - * @param item the WayPoint to Insert - * @param position index of the WayPoint - */ - void WPInsert(WayPointItem* item,int const& position); - /** - * @brief Inserts a new WayPoint on the specified position - * - * @param coord the coordinates in LatLng of the WayPoint - * @param altitude the Altitude of the WayPoint - * @param position index of the WayPoint - * @return WayPointItem a pointer to the WayPoint Inserted - */ - WayPointItem* WPInsert(internals::PointLatLng const& coord,int const& altitude,int const& position); - /** - * @brief Inserts a new WayPoint on the specified position - * - * @param coord the coordinates in LatLng of the WayPoint - * @param altitude the Altitude of the WayPoint - * @param description the description of the WayPoint - * @param position index of the WayPoint - * @return WayPointItem a pointer to the WayPoint Inserted - */ - WayPointItem* WPInsert(internals::PointLatLng const& coord,int const& altitude, QString const& description,int const& position); - - /** - * @brief Deletes the WayPoint - * - * @param item the WayPoint to delete - */ - void WPDelete(WayPointItem* item); - /** - * @brief deletes all WayPoints - * - */ - void WPDeleteAll(); - /** - * @brief Returns the currently selected WayPoints - * - * @return @return QList - */ - QList WPSelected(); - - /** - * @brief Renumbers the WayPoint and all others as needed - * - * @param item the WayPoint to renumber - * @param newnumber the WayPoint's new number - */ - void WPRenumber(WayPointItem* item,int const& newnumber); - - void SetShowCompass(bool const& value); - - // FIXME XXX Move to protected namespace - UAVItem* UAV; - QMap waypointLines; - GPSItem* GPS; - HomeItem* Home; - // END OF FIXME XXX - - UAVItem* AddUAV(int id); - void AddUAV(int id, UAVItem* uav); - /** @brief Deletes UAV and its waypoints from map */ - void DeleteUAV(int id); - UAVItem* GetUAV(int id); - const QList GetUAVS(); - QGraphicsItemGroup* waypointLine(int id); - void SetShowUAV(bool const& value); - bool ShowUAV()const{return showuav;} - void SetShowHome(bool const& value); - bool ShowHome()const{return showhome;} - void SetShowDiagnostics(bool const& value); - void SetUavPic(QString UAVPic); - QMap UAVS; - private: - internals::Core *core; - QGraphicsScene mscene; - bool useOpenGL; - GeoCoderStatusCode x; - MapType y; - core::AccessMode xx; - internals::PointLatLng currentmouseposition; - bool followmouse; - QGraphicsSvgItem *compass; - bool showuav; - bool showhome; - QTimer * diagTimer; - bool showDiag; - QGraphicsTextItem * diagGraphItem; - - private slots: - void diagRefresh(); - // WayPointItem* item;//apagar - protected: - MapGraphicItem *map; - void resizeEvent(QResizeEvent *event); - void showEvent ( QShowEvent * event ); - void closeEvent(QCloseEvent *event); - void mouseMoveEvent ( QMouseEvent * event ); - void ConnectWP(WayPointItem* item); - // private slots: - signals: - void zoomChanged(double zoomt,double zoom, double zoomd); - /** - * @brief Notify connected widgets about new map zoom - */ - void zoomChanged(int newZoom); - /** - * @brief fires when one of the WayPoints numbers changes (not fired if due to a auto-renumbering) - * - * @param oldnumber WayPoint old number - * @param newnumber WayPoint new number - * @param waypoint a pointer to the WayPoint that was renumbered - */ - void WPNumberChanged(int const& oldnumber,int const& newnumber,WayPointItem* waypoint); - /** - * @brief Fired when the description, altitude or coordinates of a WayPoint changed - * - * @param waypoint a pointer to the WayPoint - */ - void WPValuesChanged(WayPointItem* waypoint); - /** - * @brief Fires when a new WayPoint is inserted - * - * @param number new WayPoint number - * @param waypoint WayPoint inserted - */ - void WPReached(WayPointItem* waypoint); - /** - * @brief Fires when a new WayPoint is inserted - * - * @param number new WayPoint number - * @param waypoint WayPoint inserted - */ - void WPInserted(int const& number,WayPointItem* waypoint); - /** - * @brief Fires When a WayPoint is deleted - * - * @param number number of the deleted WayPoint - */ - void WPDeleted(int const& number); - /** - * @brief Fires When a WayPoint is Reached - * - * @param number number of the Reached WayPoint - */ - void UAVReachedWayPoint(int const& waypointnumber,WayPointItem* waypoint); - /** - * @brief Fires When the UAV lives the safety bouble - * - * @param position the position of the UAV - */ - void UAVLeftSafetyBouble(internals::PointLatLng const& position); - - /** - * @brief Fires when map position changes - * - * @param point the point in LatLng of the new center of the map - */ - void OnCurrentPositionChanged(internals::PointLatLng point); - /** - * @brief Fires when there are no more tiles to load - * - */ - void OnTileLoadComplete(); - /** - * @brief Fires when tiles loading begins - * - */ - void OnTileLoadStart(); - /** - * @brief Fires when the map is dragged - * - */ - void OnMapDrag(); - /** - * @brief Fires when map zoom changes - * - */ - void OnMapZoomChanged(); - /** - * @brief Fires when map type changes - * - * @param type The maps new type - */ - void OnMapTypeChanged(MapType::Types type); - /** - * @brief Fires when an error ocurred while loading a tile - * - * @param zoom tile zoom - * @param pos tile position - */ - void OnEmptyTileError(int zoom, core::Point pos); - /** - * @brief Fires when the number of tiles in the load queue changes - * - * @param number the number of tiles still in the queue - */ - void OnTilesStillToLoad(int number); - public slots: - /** - * @brief Ripps the current selection to the DB - */ - void RipMap(); - - /** - * @brief Sets the map zoom level - */ - void SetZoom(double const& value){map->SetZoom(value);} - /** - * @brief Sets the map zoom level - */ - void SetZoom(int const& value){map->SetZoom(value);} - - /** - * @brief Notify external widgets about map zoom change - */ - void emitMapZoomChanged() - { - emit zoomChanged(ZoomReal()); - } - - }; -} -#endif // OPMAPWIDGET_H diff --git a/libs/opmapcontrol/src/mapwidget/trailitem.cpp b/libs/opmapcontrol/src/mapwidget/trailitem.cpp deleted file mode 100644 index 91b04c60d..000000000 --- a/libs/opmapcontrol/src/mapwidget/trailitem.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** -****************************************************************************** -* -* @file trailitem.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a trail point -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "trailitem.h" -#include -namespace mapcontrol -{ - TrailItem::TrailItem(internals::PointLatLng const& coord,int const& altitude, QBrush color, QGraphicsItem* parent):QGraphicsItem(parent),coord(coord) - { - m_brush=color; - QDateTime time=QDateTime::currentDateTime(); - QString coord_str = " " + QString::number(coord.Lat(), 'f', 6) + " " + QString::number(coord.Lng(), 'f', 6); - setToolTip(QString(tr("Position:")+"%1\n"+tr("Altitude:")+"%2\n"+tr("Time:")+"%3").arg(coord_str).arg(QString::number(altitude)).arg(time.toString())); - } - - void TrailItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - // painter->drawRect(QRectF(-3,-3,6,6)); - painter->setBrush(m_brush); - painter->drawEllipse(-2,-2,4,4); - } - QRectF TrailItem::boundingRect()const - { - return QRectF(-2,-2,4,4); - } - - - int TrailItem::type()const - { - return Type; - } - - -} diff --git a/libs/opmapcontrol/src/mapwidget/trailitem.h b/libs/opmapcontrol/src/mapwidget/trailitem.h deleted file mode 100644 index 6711954bc..000000000 --- a/libs/opmapcontrol/src/mapwidget/trailitem.h +++ /dev/null @@ -1,63 +0,0 @@ -/** -****************************************************************************** -* -* @file trailitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef TRAILITEM_H -#define TRAILITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include - -namespace mapcontrol -{ - - class TrailItem:public QObject,public QGraphicsItem - { - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - enum { Type = UserType + 3 }; - TrailItem(internals::PointLatLng const& coord,int const& altitude, QBrush color, QGraphicsItem* parent); - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - QRectF boundingRect() const; - int type() const; - internals::PointLatLng coord; - private: - QBrush m_brush; - - - public slots: - - signals: - - }; -} -#endif // TRAILITEM_H - - diff --git a/libs/opmapcontrol/src/mapwidget/traillineitem.cpp b/libs/opmapcontrol/src/mapwidget/traillineitem.cpp deleted file mode 100644 index 513dfb223..000000000 --- a/libs/opmapcontrol/src/mapwidget/traillineitem.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/** -****************************************************************************** -* -* @file trailitem.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a trail point -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "traillineitem.h" - -namespace mapcontrol -{ - TrailLineItem::TrailLineItem(internals::PointLatLng const& coord1,internals::PointLatLng const& coord2, QBrush color, QGraphicsItem* parent):QGraphicsLineItem(parent),coord1(coord1),coord2(coord2) - { - m_brush=color; - QPen pen; - pen.setBrush(m_brush); - pen.setWidth(1); - this->setPen(pen); - } -/* - void TrailLineItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - // painter->drawRect(QRectF(-3,-3,6,6)); - painter->setBrush(m_brush); - QPen pen; - pen.setBrush(m_brush); - pen.setWidth(2); - painter->drawLine(this->line().x1(),this->line().y1(),this->line().x2(),this->line().y2()); - } -*/ - int TrailLineItem::type()const - { - return Type; - } - - -} diff --git a/libs/opmapcontrol/src/mapwidget/traillineitem.h b/libs/opmapcontrol/src/mapwidget/traillineitem.h deleted file mode 100644 index f765b521e..000000000 --- a/libs/opmapcontrol/src/mapwidget/traillineitem.h +++ /dev/null @@ -1,62 +0,0 @@ -/** -****************************************************************************** -* -* @file traillineitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef TAILLINEITEM_H -#define TAILLINEITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include - -namespace mapcontrol -{ - - class TrailLineItem:public QObject,public QGraphicsLineItem - { - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - enum { Type = UserType + 7 }; - TrailLineItem(internals::PointLatLng const& coord1,internals::PointLatLng const& coord2, QBrush color, QGraphicsItem* parent); - int type() const; - // void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - // QWidget *widget); - internals::PointLatLng coord1; - internals::PointLatLng coord2; - private: - QBrush m_brush; - - - public slots: - - signals: - - }; -} - -#endif // TAILLINEITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/uavitem.cpp b/libs/opmapcontrol/src/mapwidget/uavitem.cpp deleted file mode 100644 index 28011cbd8..000000000 --- a/libs/opmapcontrol/src/mapwidget/uavitem.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/** -****************************************************************************** -* -* @file uavitem.cpp -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a UAV -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#include "../internals/pureprojection.h" -#include "uavitem.h" -namespace mapcontrol -{ - UAVItem::UAVItem(MapGraphicItem* map,OPMapWidget* parent,QString uavPic):map(map),mapwidget(parent),showtrail(true),showtrailline(true),trailtime(5),traildistance(20),autosetreached(true) - ,autosetdistance(100) - { - //QDir dir(":/uavs/images/"); - //QStringList list=dir.entryList(); - pic.load(uavPic); - // Don't scale but trust the image we are given - // pic=pic.scaled(50,33,Qt::IgnoreAspectRatio); - localposition=map->FromLatLngToLocal(mapwidget->CurrentPosition()); - this->setPos(localposition.X(),localposition.Y()); - this->setZValue(4); - trail=new QGraphicsItemGroup(); - trail->setParentItem(map); - trailLine=new QGraphicsItemGroup(); - trailLine->setParentItem(map); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - mapfollowtype=UAVMapFollowType::None; - trailtype=UAVTrailType::ByDistance; - timer.start(); - } - UAVItem::~UAVItem() - { - delete trail; - } - - void UAVItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - // painter->rotate(-90); - QPainter::RenderHints oldhints = painter->renderHints(); - painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); - painter->drawPixmap(-pic.width()/2,-pic.height()/2,pic); - painter->setRenderHints(oldhints); - // painter->drawRect(QRectF(-pic.width()/2,-pic.height()/2,pic.width()-1,pic.height()-1)); - } - QRectF UAVItem::boundingRect()const - { - return QRectF(-pic.width()/2,-pic.height()/2,pic.width(),pic.height()); - } - void UAVItem::SetUAVPos(const internals::PointLatLng &position, const int &altitude, const QColor &color) - { - if(coord.IsEmpty()) - lastcoord=coord; - if(coord!=position) - { - - if(trailtype==UAVTrailType::ByTimeElapsed) - { - if(timer.elapsed()>trailtime*1000) - { - trail->addToGroup(new TrailItem(position,altitude,color,this)); - if(!lasttrailline.IsEmpty()) - trailLine->addToGroup((new TrailLineItem(lasttrailline,position,color,map))); - lasttrailline=position; - timer.restart(); - } - - } - else if(trailtype==UAVTrailType::ByDistance) - { - if(qAbs(internals::PureProjection::DistanceBetweenLatLng(lastcoord,position)*1000)>traildistance) - { - trail->addToGroup(new TrailItem(position,altitude,color,this)); - if(!lasttrailline.IsEmpty()) - trailLine->addToGroup((new TrailLineItem(lasttrailline,position,color,map))); - lasttrailline=position; - lastcoord=position; - } - } - coord=position; - this->altitude=altitude; - RefreshPos(); - if(mapfollowtype==UAVMapFollowType::CenterAndRotateMap||mapfollowtype==UAVMapFollowType::CenterMap) - { - mapwidget->SetCurrentPosition(coord); - } - this->update(); - if(autosetreached) - { - foreach(QGraphicsItem* i,map->childItems()) - { - WayPointItem* wp=qgraphicsitem_cast(i); - if(wp) - { - if(Distance3D(wp->Coord(),wp->Altitude())SetReached(true); - emit UAVReachedWayPoint(wp->Number(),wp); - } - } - } - } - if(mapwidget->Home!=0) - { - //verify if the UAV is inside the safety bouble - if(Distance3D(mapwidget->Home->Coord(),mapwidget->Home->Altitude())>mapwidget->Home->SafeArea()) - { - if(mapwidget->Home->safe!=false) - { - mapwidget->Home->safe=false; - mapwidget->Home->update(); - emit UAVLeftSafetyBouble(this->coord); - } - } - else - { - if(mapwidget->Home->safe!=true) - { - mapwidget->Home->safe=true; - mapwidget->Home->update(); - } - } - - } - } - } - - /** - * Rotate the UAV Icon on the map, or rotate the map - * depending on the display mode - */ - void UAVItem::SetUAVHeading(const qreal &value) - { - if(mapfollowtype==UAVMapFollowType::CenterAndRotateMap) - { - mapwidget->SetRotate(-value); - } - else { - if (this->rotation() != value) - this->setRotation(value); - } - } - - - int UAVItem::type()const - { - return Type; - } - - - void UAVItem::RefreshPos() - { - localposition=map->FromLatLngToLocal(coord); - this->setPos(localposition.X(),localposition.Y()); - foreach(QGraphicsItem* i,trail->childItems()) - { - TrailItem* w=qgraphicsitem_cast(i); - if(w) - w->setPos(map->FromLatLngToLocal(w->coord).X(),map->FromLatLngToLocal(w->coord).Y()); - } - foreach(QGraphicsItem* i,trailLine->childItems()) - { - TrailLineItem* ww=qgraphicsitem_cast(i); - if(ww) - ww->setLine(map->FromLatLngToLocal(ww->coord1).X(),map->FromLatLngToLocal(ww->coord1).Y(),map->FromLatLngToLocal(ww->coord2).X(),map->FromLatLngToLocal(ww->coord2).Y()); - } - - } - void UAVItem::SetTrailType(const UAVTrailType::Types &value) - { - trailtype=value; - if(trailtype==UAVTrailType::ByTimeElapsed) - timer.restart(); - } - void UAVItem::SetShowTrail(const bool &value) - { - showtrail=value; - trail->setVisible(value); - } - void UAVItem::SetShowTrailLine(const bool &value) - { - showtrailline=value; - trailLine->setVisible(value); - } - - void UAVItem::DeleteTrail()const - { - foreach(QGraphicsItem* i,trail->childItems()) - delete i; - foreach(QGraphicsItem* i,trailLine->childItems()) - delete i; - } - double UAVItem::Distance3D(const internals::PointLatLng &coord, const int &altitude) - { - return sqrt(pow(internals::PureProjection::DistanceBetweenLatLng(this->coord,coord)*1000,2)+ - pow(static_cast(this->altitude-altitude),2)); - } - void UAVItem::SetUavPic(QString UAVPic) - { - pic.load(":/uavs/images/"+UAVPic); - } -} diff --git a/libs/opmapcontrol/src/mapwidget/uavitem.h b/libs/opmapcontrol/src/mapwidget/uavitem.h deleted file mode 100644 index a62572752..000000000 --- a/libs/opmapcontrol/src/mapwidget/uavitem.h +++ /dev/null @@ -1,230 +0,0 @@ -/** -****************************************************************************** -* -* @file uavitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef UAVITEM_H -#define UAVITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include "mapgraphicitem.h" -#include "waypointitem.h" -#include -#include "uavmapfollowtype.h" -#include "uavtrailtype.h" -#include -#include "opmapwidget.h" -#include "trailitem.h" -#include "traillineitem.h" -namespace mapcontrol -{ - class WayPointItem; - class OPMapWidget; - /** -* @brief A QGraphicsItem representing the UAV -* -* @class UAVItem uavitem.h "mapwidget/uavitem.h" -*/ - class UAVItem:public QObject,public QGraphicsItem - { - Q_OBJECT - Q_INTERFACES(QGraphicsItem) - public: - enum { Type = UserType + 2 }; - UAVItem(MapGraphicItem* map,OPMapWidget* parent, QString uavPic=QString::fromUtf8(":/uavs/images/mapquad.png")); - ~UAVItem(); - /** - * @brief Sets the UAV position - * - * @param position LatLng point - * @param altitude altitude in meters - */ - void SetUAVPos(internals::PointLatLng const& position,int const& altitude, QColor const& color=QColor(Qt::red)); - /** - * @brief Sets the UAV heading - * - * @param value heading angle (north=0deg) - */ - void SetUAVHeading(qreal const& value); - /** - * @brief Returns the UAV position - * - * @return internals::PointLatLng - */ - internals::PointLatLng UAVPos()const{return coord;} - /** - * @brief Sets the Map follow type - * - * @param value can be "none"(map doesnt follow UAV), "CenterMap"(map moves to keep UAV centered) or "CenterAndRotateMap"(map moves and rotates to keep UAV centered and straight) - */ - void SetMapFollowType(UAVMapFollowType::Types const& value){mapfollowtype=value;} - /** - * @brief Sets the trail type - * - * @param value can be "NoTrail"(no trail is plotted), "ByTimeElapsed"(a trail point is plotted each TrailTime()) or ByDistance(a trail point is plotted if the distance between the UAV and the last trail point is bigger than TrailDistance()) - */ - void SetTrailType(UAVTrailType::Types const& value); - /** - * @brief Returns the map follow method used - * - * @return UAVMapFollowType::Types - */ - UAVMapFollowType::Types GetMapFollowType()const{return mapfollowtype;} - /** - * @brief Returns the UAV trail type. It can be plotted by time elapsed or distance - * - * @return UAVTrailType::Types - */ - UAVTrailType::Types GetTrailType()const{return trailtype;} - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - void RefreshPos(); - QRectF boundingRect() const; - /** - * @brief Sets the trail time to be used if TrailType is ByTimeElapsed - * - * @param seconds the UAV trail time elapsed value. If the trail type is time elapsed - * a trail point will be plotted each "value returned" seconds. - */ - void SetTrailTime(int const& seconds){trailtime=seconds;} - /** - * @brief Returns the UAV trail time elapsed value. If the trail type is time elapsed - * a trail point will be plotted each "value returned" seconds. - * - * @return int - */ - int TrailTime()const{return trailtime;} - /** - * @brief Sets the trail distance to be used if TrailType is ByDistance - * - * @param distance the UAV trail plot distance. - * If the trail type is ByDistance a trail dot is plotted if - * the distance between the current UAV position and the last trail point - * is bigger than the returned value - */ - void SetTrailDistance(int const& distance){traildistance=distance;} - /** - * @brief Returns the UAV trail plot distance. - * If the trail type is distance diference a trail dot is plotted if - * the distance between the current UAV position and the last trail point - * is bigger than the returned value - * - * @return int - */ - int TrailDistance()const{return traildistance;} - /** - * @brief Returns true if UAV trail is shown - * - * @return bool - */ - bool ShowTrail()const{return showtrail;} - /** - * @brief Returns true if UAV trail line is shown - * - * @return bool - */ - bool ShowTrailLine()const{return showtrailline;} - /** - * @brief Used to define if the UAV displays a trail - * - * @param value - */ - void SetShowTrail(bool const& value); - /** - * @brief Used to define if the UAV displays a trail line - * - * @param value - */ - void SetShowTrailLine(bool const& value); - /** - * @brief Deletes all the trail points - */ - void DeleteTrail()const; - /** - * @brief Returns true if the UAV automaticaly sets WP reached value (changing its color) - * - * @return bool - */ - bool AutoSetReached()const{return autosetreached;} - /** - * @brief Defines if the UAV can set the WP's "reached" value automaticaly. - * - * @param value - */ - void SetAutoSetReached(bool const& value){autosetreached=value;} - /** - * @brief Returns the 3D distance in meters necessary for the UAV to set WP's to "reached" - * - * @return double - */ - double AutoSetDistance()const{return autosetdistance;} - /** - * @brief Sets the the 3D distance in meters necessary for the UAV to set WP's to "reached" - * - * @param value - */ - void SetAutoSetDistance(double const& value){autosetdistance=value;} - - int type() const; - - void SetUavPic(QString UAVPic); - - protected: - QPixmap pic; - - private: - MapGraphicItem* map; - - int altitude; - UAVMapFollowType::Types mapfollowtype; - UAVTrailType::Types trailtype; - internals::PointLatLng coord; - internals::PointLatLng lastcoord; - core::Point localposition; - OPMapWidget* mapwidget; - QGraphicsItemGroup* trail; - QGraphicsItemGroup * trailLine; - internals::PointLatLng lasttrailline; - QTime timer; - bool showtrail; - bool showtrailline; - int trailtime; - int traildistance; - bool autosetreached; - double Distance3D(internals::PointLatLng const& coord, int const& altitude); - double autosetdistance; - // QRectF rect; - - public slots: - - signals: - void UAVReachedWayPoint(int const& waypointnumber,WayPointItem* waypoint); - void UAVLeftSafetyBouble(internals::PointLatLng const& position); - }; -} -#endif // UAVITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/uavmapfollowtype.h b/libs/opmapcontrol/src/mapwidget/uavmapfollowtype.h deleted file mode 100644 index f7a3c45f4..000000000 --- a/libs/opmapcontrol/src/mapwidget/uavmapfollowtype.h +++ /dev/null @@ -1,86 +0,0 @@ -/** -****************************************************************************** -* -* @file uavmapfollowtype.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief An enum representing the various map follow modes -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#ifndef UAVMAPFOLLOWTYPE_H -#define UAVMAPFOLLOWTYPE_H -#include -#include -#include -#include -namespace mapcontrol { - class UAVMapFollowType:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - ///

- /// only centers the map on the UAV - /// - CenterMap, - - /// - /// centers and rotates map on the UAV - /// - CenterAndRotateMap, - - /// - /// map is not connected to UAV position or heading - /// - None - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = UAVMapFollowType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = UAVMapFollowType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = UAVMapFollowType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;x -#include -#include -#include -namespace mapcontrol { - class UAVTrailType:public QObject - { - Q_OBJECT - Q_ENUMS(Types) - public: - enum Types - { - /** - * @brief UAV does not plot a trail - * - * @var NoTrail - */ - NoTrail, - /** - * @brief UAV plots a trail point every 'x' seconds - * - * @var ByTimeElapsed - */ - ByTimeElapsed, - /** - * @brief UAV plots a trail point every 'x' meters (ground distance) - * - * @var ByDistance - */ - ByDistance - }; - static QString StrByType(Types const& value) - { - QMetaObject metaObject = UAVTrailType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - QString s=metaEnum.valueToKey(value); - return s; - } - static Types TypeByStr(QString const& value) - { - QMetaObject metaObject = UAVTrailType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - Types s=(Types)metaEnum.keyToValue(value.toLatin1()); - return s; - } - static QStringList TypesList() - { - QStringList ret; - QMetaObject metaObject = UAVTrailType().staticMetaObject; - QMetaEnum metaEnum= metaObject.enumerator( metaObject.indexOfEnumerator("Types")); - for(int x=0;xsetFlag(QGraphicsItem::ItemIsMovable,true); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - this->setFlag(QGraphicsItem::ItemIsSelectable,true); - // transf.translate(picture.width()/2,picture.height()); - // this->setTransform(transf); - SetShowNumber(shownumber); - RefreshToolTip(); - RefreshPos(); - } - WayPointItem::WayPointItem(const internals::PointLatLng &coord,double const& altitude, const QString &description, MapGraphicItem *map) : - map(map), - coord(coord), - reached(false), - description(description), - shownumber(true), - isDragging(false), - altitude(altitude), - heading(0) - { - text=0; - numberI=0; - picture.load(QString::fromUtf8(":/markers/images/marker.png")); - number=WayPointItem::snumber; - ++WayPointItem::snumber; - this->setFlag(QGraphicsItem::ItemIsMovable,true); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - this->setFlag(QGraphicsItem::ItemIsSelectable,true); - //transf.translate(picture.width()/2,picture.height()); - // this->setTransform(transf); - SetShowNumber(shownumber); - RefreshToolTip(); - RefreshPos(); - } - - QRectF WayPointItem::boundingRect() const - { - return QRectF(-picture.width()/2,-picture.height(),picture.width(),picture.height()); - } - - void WayPointItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - painter->drawPixmap(-picture.width()/2,-picture.height(),picture); - if(this->isSelected()) - { - painter->drawRect(QRectF(-picture.width()/2,-picture.height(),picture.width()-1,picture.height()-1)); - } - } - void WayPointItem::mousePressEvent(QGraphicsSceneMouseEvent *event) - { - if(event->button()==Qt::LeftButton) - { - text=new QGraphicsSimpleTextItem(this); - textBG=new QGraphicsRectItem(this); - -// textBG->setBrush(Qt::white); -// textBG->setOpacity(0.5); - - textBG->setBrush(QColor(255, 255, 255, 128)); - - text->setPen(QPen(Qt::red)); - text->setPos(10,-picture.height()); - textBG->setPos(10,-picture.height()); - text->setZValue(3); - RefreshToolTip(); - isDragging=true; - } - QGraphicsItem::mousePressEvent(event); - } - void WayPointItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) - { - if(event->button()==Qt::LeftButton) - { - delete text; - delete textBG; - coord=map->FromLocalToLatLng(this->pos().x(),this->pos().y()); - QString coord_str = " " + QString::number(coord.Lat(), 'f', 6) + " " + QString::number(coord.Lng(), 'f', 6); - // qDebug() << "WP MOVE:" << coord_str << __FILE__ << __LINE__; - isDragging=false; - RefreshToolTip(); - - emit WPValuesChanged(this); - } - QGraphicsItem::mouseReleaseEvent(event); - } - void WayPointItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) - { - - if(isDragging) - { - coord=map->FromLocalToLatLng(this->pos().x(),this->pos().y()); - QString coord_str = " " + QString::number(coord.Lat(), 'f', 6) + " " + QString::number(coord.Lng(), 'f', 6); - text->setText(coord_str); - // qDebug() << "WP DRAG:" << coord_str << __FILE__ << __LINE__; - textBG->setRect(text->boundingRect()); - - emit WPValuesChanged(this); - } - QGraphicsItem::mouseMoveEvent(event); - } - void WayPointItem::SetAltitude(const double &value) - { - altitude=value; - RefreshToolTip(); - - emit WPValuesChanged(this); - this->update(); - } - void WayPointItem::SetHeading(const float &value) - { - heading=value; - RefreshToolTip(); - - emit WPValuesChanged(this); - this->update(); - } - void WayPointItem::SetCoord(const internals::PointLatLng &value) - { - coord=value; - emit WPValuesChanged(this); - RefreshPos(); - RefreshToolTip(); - this->update(); - } - void WayPointItem::SetDescription(const QString &value) - { - description=value; - RefreshToolTip(); - emit WPValuesChanged(this); - this->update(); - } - void WayPointItem::SetNumber(const int &value) - { - emit WPNumberChanged(number,value,this); - number=value; - RefreshToolTip(); - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - this->update(); - } - void WayPointItem::SetReached(const bool &value) - { - if (autoreachedEnabled) - { - reached=value; - emit WPValuesChanged(this); - if(value) - picture.load(QString::fromUtf8(":/markers/images/bigMarkerGreen.png")); - else - picture.load(QString::fromUtf8(":/markers/images/marker.png")); - this->update(); - } - } - void WayPointItem::SetShowNumber(const bool &value) - { -// shownumber=value; -// if((numberI==0) && value) -// { -// numberI=new QGraphicsSimpleTextItem(this); -// numberIBG=new QGraphicsRectItem(this); -// numberIBG->setBrush(Qt::white); -// numberIBG->setOpacity(0.5); -// numberI->setZValue(3); -// numberI->setPen(QPen(Qt::blue)); -// numberI->setPos(0,-13-picture.height()); -// numberIBG->setPos(0,-13-picture.height()); -// numberI->setText(QString::number(number)); -// numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); -// } -// else if (!value && numberI) -// { -// delete numberI; -// delete numberIBG; -// } -// this->update(); - - - - shownumber=value; - if((numberI==0) && value) - { - numberI=new QGraphicsSimpleTextItem(this); - numberIBG=new QGraphicsRectItem(this); - numberIBG->setBrush(Qt::black); - numberIBG->setOpacity(0.5); - numberI->setZValue(3); - numberI->setPen(QPen(Qt::white)); - numberI->setPos(18,-picture.height()/2-2); - numberIBG->setPos(18,-picture.height()/2-2); - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - } - else if (!value && numberI) - { - delete numberI; - delete numberIBG; - } - this->update(); - - - - } - void WayPointItem::WPDeleted(const int &onumber) - { - if(number>onumber) --number; - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - RefreshToolTip(); - this->update(); - } - void WayPointItem::WPInserted(const int &onumber, WayPointItem *waypoint) - { - if(waypoint!=this) - { - if(onumber<=number) ++number; - numberI->setText(QString::number(number)); - RefreshToolTip(); - this->update(); - } - } - void WayPointItem::WPRenumbered(const int &oldnumber, const int &newnumber, WayPointItem *waypoint) - { - if (waypoint!=this) - { - if(((oldnumber>number) && (newnumber<=number))) - { - ++number; - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - RefreshToolTip(); - } - else if (((oldnumbernumber))) - { - --number; - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - RefreshToolTip(); - } - else if (newnumber==number) - { - ++number; - numberI->setText(QString::number(number)); - RefreshToolTip(); - } - this->update(); - } - } - int WayPointItem::type() const - { - // Enable the use of qgraphicsitem_cast with this item. - return Type; - } - - WayPointItem::~WayPointItem() - { - --WayPointItem::snumber; - } - void WayPointItem::RefreshPos() - { - core::Point point=map->FromLatLngToLocal(coord); - this->setPos(point.X(),point.Y()); - } - void WayPointItem::RefreshToolTip() - { - QString coord_str = QString::number(coord.Lat(), 'f', 7) + " " + QString::number(coord.Lng(), 'f', 7); - setToolTip(QString("WayPoint Number: %1\nDescription: %2\nCoordinate: %4\nAltitude: %5 m (MSL)\nHeading: %6 deg").arg(QString::number(WayPointItem::number)).arg(description).arg(coord_str).arg(QString::number(altitude)).arg(QString::number(heading))); - } - - int WayPointItem::snumber=0; -} diff --git a/libs/opmapcontrol/src/mapwidget/waypointitem.h b/libs/opmapcontrol/src/mapwidget/waypointitem.h deleted file mode 100644 index e732211dc..000000000 --- a/libs/opmapcontrol/src/mapwidget/waypointitem.h +++ /dev/null @@ -1,220 +0,0 @@ -/** -****************************************************************************** -* -* @file waypointitem.h -* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. -* @brief A graphicsItem representing a WayPoint -* @see The GNU Public License (GPL) Version 3 -* @defgroup OPMapWidget -* @{ -* -*****************************************************************************/ -/* -* This program 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. -* -* This program 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 this program; if not, write to the Free Software Foundation, Inc., -* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ -#ifndef WAYPOINTITEM_H -#define WAYPOINTITEM_H - -#include -#include -#include -#include "../internals/pointlatlng.h" -#include "mapgraphicitem.h" -#include -namespace mapcontrol -{ -/** -* @brief A QGraphicsItem representing a WayPoint -* -* @class WayPointItem waypointitem.h "waypointitem.h" -*/ -class WayPointItem:public QObject,public QGraphicsItem -{ - Q_OBJECT - Q_INTERFACES(QGraphicsItem) -public: - enum { Type = UserType + 1 }; - /** - * @brief Constructer - * - * @param coord coordinates in LatLng of the Waypoint - * @param altitude altitude of the WayPoint - * @param map pointer to map to use - * @return - */ - WayPointItem(internals::PointLatLng const& coord,double const& altitude,MapGraphicItem* map); - /** - * @brief Constructer - * - * @param coord coordinates in LatLng of the WayPoint - * @param altitude altitude of the WayPoint - * @param description description fo the WayPoint - * @param map pointer to map to use - * @return - */ - WayPointItem(internals::PointLatLng const& coord,double const& altitude,QString const& description,MapGraphicItem* map); - /** - * @brief Returns the WayPoint description - * - * @return QString - */ - QString Description(){return description;} - /** - * @brief Sets the WayPoint description - * - * @param value - */ - void SetDescription(QString const& value); - /** - * @brief Returns true if WayPoint is Reached - * - * @return bool - */ - bool Reached(){return reached;} - /** - * @brief Sets if WayPoint is Reached - * - * @param value - */ - void SetReached(bool const& value); - /** - * @brief Returns the WayPoint number - * - */ - int Number(){return number;} - /** - * @brief Sets WayPoint number - * - * @param value - */ - void SetNumber(int const& value); - /** - * @brief Returns WayPoint LatLng coordinate - * - */ - internals::PointLatLng Coord() const {return coord;} - /** - * @brief Sets WayPoint LatLng coordinate - * - * @param value - */ - void SetCoord(internals::PointLatLng const& value); - /** - * @brief Used if WayPoint number is to be drawn on screen - * - */ - bool ShowNumber(){return shownumber;} - /** - * @brief Used to set if WayPoint number is to be drawn on screen - * - * @param value - */ - virtual void SetShowNumber(bool const& value); - /** - * @brief Returns the WayPoint altitude in meters - * - * @return int - */ - double Altitude(){return altitude;} - /** - * @brief Returns the WayPoint Heading - * - * @return Waypoint heading in degrees, 0 = north, 90 = east - */ - float Heading(){return heading;} - /** - * @brief Sets the WayPoint Altitude - * - * @param value altitude in meters above mean sea level (MSL) - */ - void SetAltitude(double const& value); - /** - * @brief Sets the WayPoint Heading - * - * @param value heading in degrees, 0 = north, 90 = east - */ - void SetHeading(float const& value); - int type() const; - virtual QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, - QWidget *widget); - void RefreshPos(); - void RefreshToolTip(); - QPixmap picture; -~WayPointItem(); - - static int snumber; -protected: - void mouseMoveEvent ( QGraphicsSceneMouseEvent * event ); - void mousePressEvent ( QGraphicsSceneMouseEvent * event ); - void mouseReleaseEvent ( QGraphicsSceneMouseEvent * event ); - - MapGraphicItem* map; - bool autoreachedEnabled; ///< If the waypoint should change appearance once it has been reached - QGraphicsSimpleTextItem* text; - QGraphicsRectItem* textBG; - QGraphicsSimpleTextItem* numberI; - QGraphicsRectItem* numberIBG; - QTransform transf; - internals::PointLatLng coord;//coordinates of this WayPoint - bool reached; - QString description; - bool shownumber; - bool isDragging; - double altitude; - float heading; - int number; - -public slots: - /** - * @brief Called when a WayPoint is deleted - * - * @param number number of the WayPoint that was deleted - */ - void WPDeleted(int const& number); - /** - * @brief Called when a WayPoint is renumbered - * - * @param oldnumber the old WayPoint number - * @param newnumber the new WayPoint number - * @param waypoint a pointer to the WayPoint renumbered - */ - void WPRenumbered(int const& oldnumber,int const& newnumber,WayPointItem* waypoint); - /** - * @brief Called when a WayPoint is inserted - * - * @param number the number of the WayPoint - * @param waypoint a pointer to the WayPoint inserted - */ - void WPInserted(int const& number,WayPointItem* waypoint); -signals: - /** - * @brief fires when this WayPoint number changes (not fired if due to a auto-renumbering) - * - * @param oldnumber this WayPoint old number - * @param newnumber this WayPoint new number - * @param waypoint a pointer to this WayPoint - */ - void WPNumberChanged(int const& oldnumber,int const& newnumber,WayPointItem* waypoint); - /** - * @brief Fired when the description, altitude or coordinates change - * - * @param waypoint a pointer to this WayPoint - */ - void WPValuesChanged(WayPointItem* waypoint); - -}; -} -#endif // WAYPOINTITEM_H diff --git a/libs/opmapcontrol/src/mapwidget/waypointlineitem.cpp b/libs/opmapcontrol/src/mapwidget/waypointlineitem.cpp deleted file mode 100644 index 7f8ca3625..000000000 --- a/libs/opmapcontrol/src/mapwidget/waypointlineitem.cpp +++ /dev/null @@ -1,91 +0,0 @@ -#include "waypointlineitem.h" - -namespace mapcontrol -{ -WaypointLineItem::WaypointLineItem(WayPointItem* wp1, WayPointItem* wp2, QColor color, mapcontrol::MapGraphicItem* map) : - QGraphicsLineItem(map), - wp1(wp1), - wp2(wp2), - map(map) -{ - // Make sure this stick to the map - //this->setFlag(QGraphicsItem::Item,true); - setParentItem(map); - - // Set up the pen for this icon with the UAV color - QPen pen(color); - pen.setWidth(2); - setPen(pen); - - point1 = wp1->Coord(); - point2 = wp2->Coord(); - - // Pixel coordinates of the local points - core::Point localPoint1 = map->FromLatLngToLocal(wp1->Coord()); - core::Point localPoint2 = map->FromLatLngToLocal(wp2->Coord()); - // Draw line - setLine(localPoint1.X(), localPoint1.Y(), localPoint2.X(), localPoint2.Y()); - - // Connect updates - // Update line from both waypoints - connect(wp1, SIGNAL(WPValuesChanged(WayPointItem*)), this, SLOT(updateWPValues(WayPointItem*))); - connect(wp2, SIGNAL(WPValuesChanged(WayPointItem*)), this, SLOT(updateWPValues(WayPointItem*))); - // Delete line if one of the waypoints get deleted - connect(wp1, SIGNAL(destroyed()), this, SLOT(deleteLater())); - connect(wp2, SIGNAL(destroyed()), this, SLOT(deleteLater())); - - // Map Zoom and move - connect(map, SIGNAL(mapChanged()), this, SLOT(updateWPValues())); -} - -void WaypointLineItem::RefreshPos() -{ - // Delete if either waypoint got deleted - if (!wp1 || !wp2) - { - this->deleteLater(); - } - else - { - // Set new pixel coordinates based on new global coordinates - //QTimer::singleShot(0, this, SLOT(updateWPValues())); - core::Point localPoint1 = map->FromLatLngToLocal(point1); - core::Point localPoint2 = map->FromLatLngToLocal(point2); - if (!localPoint1.IsEmpty() && !localPoint2.IsEmpty()) - { - setLine(localPoint1.X(), localPoint1.Y(), localPoint2.X(), localPoint2.Y()); - } - } -} - -void WaypointLineItem::updateWPValues(WayPointItem* waypoint) -{ - Q_UNUSED(waypoint); - // Delete if either waypoint got deleted - if (!wp1 || !wp2) - { - this->deleteLater(); - } - else - { - // Set new pixel coordinates based on new global coordinates - point1 = wp1->Coord(); - point2 = wp2->Coord(); - core::Point localPoint1 = map->FromLatLngToLocal(wp1->Coord()); - core::Point localPoint2 = map->FromLatLngToLocal(wp2->Coord()); - - setLine(localPoint1.X(), localPoint1.Y(), localPoint2.X(), localPoint2.Y()); - } -} - -void WaypointLineItem::updateWPValues() -{ - updateWPValues(NULL); -} - -int WaypointLineItem::type()const -{ - return Type; -} - -} diff --git a/libs/opmapcontrol/src/mapwidget/waypointlineitem.h b/libs/opmapcontrol/src/mapwidget/waypointlineitem.h deleted file mode 100644 index 023f7ca6b..000000000 --- a/libs/opmapcontrol/src/mapwidget/waypointlineitem.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef WAYPOINTLINEITEM_H -#define WAYPOINTLINEITEM_H - -#include -#include "../../opmapcontrol.h" - -namespace mapcontrol { -class WaypointLineItem : public QObject,public QGraphicsLineItem -{ - Q_OBJECT - Q_INTERFACES(QGraphicsItem) -public: - enum { Type = UserType + 7 }; - WaypointLineItem(WayPointItem* wp1, WayPointItem* wp2, QColor color=QColor(Qt::red), MapGraphicItem* parent=0); - int type() const; - -public slots: - /** - * @brief Update waypoint values - * - * @param waypoint The waypoint object that just changed - */ - void updateWPValues(WayPointItem* waypoint); - /** - * @brief Update waypoint values - */ - void updateWPValues(); - /** - * @brief Update waypoint values - * - */ - void RefreshPos(); - -protected: - internals::PointLatLng point1; - internals::PointLatLng point2; - WayPointItem* wp1; - WayPointItem* wp2; - MapGraphicItem* map; ///< The map this item is parent of -}; -} - -#endif // WAYPOINTLINEITEM_H diff --git a/libs/opmapcontrol/src/src.pro b/libs/opmapcontrol/src/src.pro deleted file mode 100644 index 28d447759..000000000 --- a/libs/opmapcontrol/src/src.pro +++ /dev/null @@ -1,6 +0,0 @@ -TEMPLATE = subdirs -CONFIG += ordered -SUBDIRS = core -SUBDIRS += internals -SUBDIRS += mapwidget -#SUBDIRS +=finaltest diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 25650be9f..b5e879ef6 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -138,7 +138,6 @@ src/ui/toolbar/MainToolBar.qml src/FlightDisplay/FlightDisplayView.qml src/FlightDisplay/FlightDisplayWidget.qml - src/ui/mapdisplay/MapDisplay.qml src/MissionEditor/MissionEditor.qml @@ -155,11 +154,9 @@ src/FlightMap/Widgets/QGCCompassHUD.qml src/FlightMap/Widgets/QGCCurrentAltitude.qml src/FlightMap/Widgets/QGCCurrentSpeed.qml - src/FlightMap/Widgets/QGCMapToolButton.qml src/FlightMap/Widgets/QGCPitchIndicator.qml src/FlightMap/Widgets/QGCSlider.qml src/FlightMap/Widgets/QGCSpeedWidget.qml - src/FlightMap/Widgets/QGCWaypointEditor.qml src/FlightMap/MapItems/MissionItemIndicator.qml diff --git a/resources/styles/style-dark.css b/resources/styles/style-dark.css index ac426b45c..463a1db48 100644 --- a/resources/styles/style-dark.css +++ b/resources/styles/style-dark.css @@ -557,21 +557,3 @@ QGCUnconnectedInfoWidget QPushButton#connectButton { margin: 15px; padding: 20px; } - -WaypointEditableView, WaypointViewOnlyView { - border: 1px solid #777; - border-radius: 5px; - margin-bottom: 3px; -} - -WaypointEditableView[RowColoring="odd"], WaypointViewOnlyView[RowColoring="odd"] { - background-color: #333; -} - -WaypointEditableView[RowColoring="even"], WaypointViewOnlyView[RowColoring="even"] { - background-color: #555; -} - -WaypointEditableView QCheckBox, WaypointEditableView .QWidget, WaypointViewOnlyView QCheckBox, WaypointViewOnlyView .QWidget { - background: none; -} diff --git a/resources/styles/style-light.css b/resources/styles/style-light.css index 9e4e1dbf9..e48d139bd 100644 --- a/resources/styles/style-light.css +++ b/resources/styles/style-light.css @@ -370,19 +370,3 @@ UASView { UASView QLabel#heartBeatLabel, UASView QLabel#typeLabel { border-color: #333; } - -WaypointEditableView, WaypointViewOnlyView { - border-color: #333; -} - -WaypointEditableView[RowColoring="odd"], WaypointViewOnlyView[RowColoring="odd"] { - background-color: #999; -} - -WaypointEditableView[RowColoring="even"], WaypointViewOnlyView[RowColoring="even"] { - background-color: #CCC; -} - -WaypointEditableView QCheckBox, WaypointEditableView .QWidget, WaypointViewOnlyView QCheckBox, WaypointViewOnlyView .QWidget { - background: none; -} diff --git a/src/FlightMap/qmldir b/src/FlightMap/qmldir index 5ab3544a9..692c7d79e 100644 --- a/src/FlightMap/qmldir +++ b/src/FlightMap/qmldir @@ -13,11 +13,9 @@ QGCCompassHUD 1.0 QGCCompassHUD.qml QGCCompassWidget 1.0 QGCCompassWidget.qml QGCCurrentAltitude 1.0 QGCCurrentAltitude.qml QGCCurrentSpeed 1.0 QGCCurrentSpeed.qml -QGCMapToolButton 1.0 QGCMapToolButton.qml QGCPitchIndicator 1.0 QGCPitchIndicator.qml QGCSlider 1.0 QGCSlider.qml QGCSpeedWidget 1.0 QGCSpeedWidget.qml -QGCWaypointEditor 1.0 QGCWaypointEditor.qml # MapQuickItems VehicleMapItem 1.0 VehicleMapItem.qml diff --git a/src/MissionItemTest.cc b/src/MissionItemTest.cc index a1ee32afa..59d590450 100644 --- a/src/MissionItemTest.cc +++ b/src/MissionItemTest.cc @@ -22,6 +22,7 @@ ======================================================================*/ #include "MissionItemTest.h" +#include "MissionItem.h" UT_REGISTER_TEST(MissionItemTest) diff --git a/src/MissionItemTest.h b/src/MissionItemTest.h index 643df0e2a..ec91ec27d 100644 --- a/src/MissionItemTest.h +++ b/src/MissionItemTest.h @@ -28,6 +28,8 @@ #include "TCPLink.h" #include "MultiSignalSpy.h" +#include + /// @file /// @brief FlightGear HIL Simulation unit tests /// diff --git a/src/MissionManager/MissionManagerTest.h b/src/MissionManager/MissionManagerTest.h index 9647159d3..432afd92c 100644 --- a/src/MissionManager/MissionManagerTest.h +++ b/src/MissionManager/MissionManagerTest.h @@ -29,6 +29,8 @@ #include "MissionManager.h" #include "MultiSignalSpy.h" +#include + class MissionManagerTest : public UnitTest { Q_OBJECT diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index e192efb9d..adf28b1b2 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -42,7 +42,6 @@ #include "VideoStreaming.h" -#include "configuration.h" #include "QGC.h" #include "QGCApplication.h" #include "MainWindow.h" @@ -829,11 +828,3 @@ void QGCApplication::showToolBarMessage(const QString& message) QGCMessageBox::information("", message); } } - -void QGCApplication::setUseNewMissionEditor(bool use) -{ - // Temp hack for new mission editor - QSettings settings; - - settings.setValue("UseNewMissionEditor", use); -} diff --git a/src/QGCApplication.h b/src/QGCApplication.h index 5e37a55cf..1e98b7e30 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -106,9 +106,6 @@ public: /// @return true: Fake ui into showing mobile interface bool fakeMobile(void) { return _fakeMobile; } - bool useNewMissionEditor(void) { return _useNewMissionEditor; } - void setUseNewMissionEditor(bool use); - #ifdef QT_DEBUG bool testHighDPI(void) { return _testHighDPI; } #endif diff --git a/src/Vehicle/MultiVehicleManager.cc b/src/Vehicle/MultiVehicleManager.cc index 4ff9a53ab..708e67b98 100644 --- a/src/Vehicle/MultiVehicleManager.cc +++ b/src/Vehicle/MultiVehicleManager.cc @@ -36,7 +36,6 @@ MultiVehicleManager::MultiVehicleManager(QObject* parent) : , _activeVehicleAvailable(false) , _parameterReadyVehicleAvailable(false) , _activeVehicle(NULL) - , _offlineWaypointManager(NULL) { QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); qmlRegisterUncreatableType("QGroundControl.MultiVehicleManager", 1, 0, "MultiVehicleManager", "Reference only"); @@ -210,18 +209,6 @@ void MultiVehicleManager::setHomePositionForAllVehicles(double lat, double lon, } } -UASWaypointManager* MultiVehicleManager::activeWaypointManager(void) -{ - if (_activeVehicle) { - return _activeVehicle->uas()->getWaypointManager(); - } - - if (!_offlineWaypointManager) { - _offlineWaypointManager = new UASWaypointManager(NULL, NULL); - } - return _offlineWaypointManager; -} - void MultiVehicleManager::saveSetting(const QString &name, const QString& value) { QSettings settings; diff --git a/src/Vehicle/MultiVehicleManager.h b/src/Vehicle/MultiVehicleManager.h index 36294e93c..36a717129 100644 --- a/src/Vehicle/MultiVehicleManager.h +++ b/src/Vehicle/MultiVehicleManager.h @@ -30,7 +30,6 @@ #include "QGCSingleton.h" #include "Vehicle.h" #include "QGCMAVLink.h" -#include "UASWaypointManager.h" #include "QmlObjectListModel.h" class MultiVehicleManager : public QGCSingleton @@ -64,8 +63,6 @@ public: UAS* activeUas(void) { return _activeVehicle ? _activeVehicle->uas() : NULL; } - UASWaypointManager* activeWaypointManager(void); - QList vehicles(void); // Property accessors @@ -111,8 +108,6 @@ private: QList _ignoreVehicleIds; ///< List of vehicle id for which we ignore further communication QmlObjectListModel _vehicles; - - UASWaypointManager* _offlineWaypointManager; }; #endif diff --git a/src/Vehicle/Vehicle.cc b/src/Vehicle/Vehicle.cc index 578dabfa1..800613de9 100644 --- a/src/Vehicle/Vehicle.cc +++ b/src/Vehicle/Vehicle.cc @@ -85,7 +85,6 @@ Vehicle::Vehicle(LinkInterface* link, int vehicleId, MAV_AUTOPILOT firmwareType, , _currentWaypoint(0) , _satelliteCount(-1) , _satelliteLock(0) - , _wpm(NULL) , _updateCount(0) , _missionManager(NULL) , _armed(false) @@ -142,14 +141,6 @@ Vehicle::Vehicle(LinkInterface* link, int vehicleId, MAV_AUTOPILOT firmwareType, connect(_mav, &UASInterface::nameChanged, this, &Vehicle::_updateName); connect(_mav, &UASInterface::systemTypeSet, this, &Vehicle::_setSystemType); connect(_mav, &UASInterface::localizationChanged, this, &Vehicle::_setSatLoc); - _wpm = _mav->getWaypointManager(); - if (_wpm) { - connect(_wpm, &UASWaypointManager::currentWaypointChanged, this, &Vehicle::_updateCurrentWaypoint); - connect(_wpm, &UASWaypointManager::waypointDistanceChanged, this, &Vehicle::_updateWaypointDistance); - connect(_wpm, SIGNAL(waypointViewOnlyListChanged(void)), this, SLOT(_waypointViewOnlyListChanged(void))); - connect(_wpm, SIGNAL(waypointViewOnlyChanged(int,MissionItem*)),this, SLOT(_updateWaypointViewOnly(int,MissionItem*))); - _wpm->readWaypoints(true); - } UAS* pUas = dynamic_cast(_mav); if(pUas) { _setSatelliteCount(pUas->getSatelliteCount(), QString("")); @@ -157,14 +148,10 @@ Vehicle::Vehicle(LinkInterface* link, int vehicleId, MAV_AUTOPILOT firmwareType, } _setSystemType(_mav, _mav->getSystemType()); - _waypointViewOnlyListChanged(); - _loadSettings(); - if (qgcApp()->useNewMissionEditor()) { _missionManager = new MissionManager(this); connect(_missionManager, &MissionManager::error, this, &Vehicle::_missionManagerError); - } _firmwarePlugin->initializeVehicle(this); @@ -196,12 +183,6 @@ Vehicle::~Vehicle() disconnect(_mav, &UASInterface::nameChanged, this, &Vehicle::_updateName); disconnect(_mav, &UASInterface::systemTypeSet, this, &Vehicle::_setSystemType); disconnect(_mav, &UASInterface::localizationChanged, this, &Vehicle::_setSatLoc); - if (_wpm) { - disconnect(_wpm, &UASWaypointManager::currentWaypointChanged, this, &Vehicle::_updateCurrentWaypoint); - disconnect(_wpm, &UASWaypointManager::waypointDistanceChanged, this, &Vehicle::_updateWaypointDistance); - disconnect(_wpm, SIGNAL(waypointViewOnlyListChanged(void)), this, SLOT(_waypointViewOnlyListChanged(void))); - disconnect(_wpm, SIGNAL(waypointViewOnlyChanged(int,MissionItem*)), this, SLOT(_updateWaypointViewOnly(int,MissionItem*))); - } UAS* pUas = dynamic_cast(_mav); if(pUas) { disconnect(pUas, &UAS::satelliteCountChanged, this, &Vehicle::_setSatelliteCount); @@ -778,21 +759,6 @@ void Vehicle::_updateWaypointViewOnly(int, MissionItem* /*wp*/) */ } -void Vehicle::_waypointViewOnlyListChanged() -{ - if(_wpm) { - const QList& newMisionItems = _wpm->getWaypointViewOnlyList(); - _missionItems.clear(); - qCDebug(VehicleLog) << QString("Loading %1 mission items").arg(newMisionItems.count()); - for(int i = 0; i < newMisionItems.count(); i++) { - MissionItem* itemToCopy = newMisionItems[i]; - MissionItem* item = new MissionItem(*itemToCopy); - item->setParent(this); - _missionItems.append(item); - } - } -} - void Vehicle::_handleTextMessage(int newCount) { // Reset? @@ -987,11 +953,7 @@ void Vehicle::setActive(bool active) QmlObjectListModel* Vehicle::missionItemsModel(void) { - if (qgcApp()->useNewMissionEditor()) { - return missionManager()->missionItems(); - } else { - return &_missionItems; - } + return missionManager()->missionItems(); } bool Vehicle::homePositionAvailable(void) diff --git a/src/Vehicle/Vehicle.h b/src/Vehicle/Vehicle.h index aef3c6c44..60abe7893 100644 --- a/src/Vehicle/Vehicle.h +++ b/src/Vehicle/Vehicle.h @@ -41,7 +41,6 @@ class UAS; class UASInterface; class FirmwarePlugin; class AutoPilotPlugin; -class UASWaypointManager; class MissionManager; Q_DECLARE_LOGGING_CATEGORY(VehicleLog) @@ -329,7 +328,6 @@ private slots: void _setSatelliteCount (double val, QString name); void _setSatLoc (UASInterface* uas, int fix); void _updateWaypointViewOnly (int uas, MissionItem* wp); - void _waypointViewOnlyListChanged (); private: bool _containsLink(LinkInterface* link); @@ -408,7 +406,6 @@ private: quint16 _currentWaypoint; int _satelliteCount; int _satelliteLock; - UASWaypointManager* _wpm; int _updateCount; MissionManager* _missionManager; diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index adf786321..e122d5778 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -22,7 +22,6 @@ #include "UASInterface.h" #include "UASInterface.h" #include "UAS.h" -#include "configuration.h" #include "LinkManager.h" #include "QGCMAVLink.h" #include "QGC.h" diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc index 4c7f84b1a..112ef3985 100644 --- a/src/comm/QGCFlightGearLink.cc +++ b/src/comm/QGCFlightGearLink.cc @@ -36,6 +36,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #include #include diff --git a/src/main.cc b/src/main.cc index 510078d27..e9428490d 100644 --- a/src/main.cc +++ b/src/main.cc @@ -37,7 +37,6 @@ This file is part of the QGROUNDCONTROL project #include #include "QGCApplication.h" #include "MainWindow.h" -#include "configuration.h" #ifdef QT_DEBUG #ifndef __mobile__ #include "UnitTest.h" diff --git a/src/uas/FileManager.h b/src/uas/FileManager.h index 3369b650a..696358961 100644 --- a/src/uas/FileManager.h +++ b/src/uas/FileManager.h @@ -26,6 +26,7 @@ #include #include +#include #include "UASInterface.h" #include "QGCLoggingCategory.h" diff --git a/src/uas/UAS.cc b/src/uas/UAS.cc index f978cb621..eada86aa1 100644 --- a/src/uas/UAS.cc +++ b/src/uas/UAS.cc @@ -179,13 +179,8 @@ UAS::UAS(MAVLinkProtocol* protocol, Vehicle* vehicle) : UASInterface(), lastSendTimeGPS(0), lastSendTimeSensors(0), lastSendTimeOpticalFlow(0), - _waypointManager(NULL), _vehicle(vehicle) { - - if (!qgcApp()->useNewMissionEditor()) { - _waypointManager = new UASWaypointManager(vehicle, this); - } for (unsigned int i = 0; i<255;++i) { @@ -948,161 +943,7 @@ void UAS::receiveMessage(mavlink_message_t message) emit valueChanged(uasId, "yaw sp", "rad", yaw, time); } break; - case MAVLINK_MSG_ID_MISSION_COUNT: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_count_t mc; - mavlink_msg_mission_count_decode(&message, &mc); - - // Special case a 0 for the target system or component, it means that anyone is the target, so we should process this. - if (mc.target_system == 0) { - mc.target_system = mavlink->getSystemId(); - } - if (mc.target_component == 0) { - mc.target_component = mavlink->getComponentId(); - } - - // Check that this message applies to the UAS. - if(mc.target_system == mavlink->getSystemId()) - { - - if (mc.target_component != mavlink->getComponentId()) { - qDebug() << "The target component ID is not set correctly. This is currently only a warning, but will be turned into an error."; - qDebug() << "Expecting" << mavlink->getComponentId() << "but got" << mc.target_component; - } - - _waypointManager->handleWaypointCount(message.sysid, message.compid, mc.count); - } - else - { - qDebug() << QString("Received mission count message, but was wrong system id. Expected %1, received %2").arg(mavlink->getSystemId()).arg(mc.target_system); - } - } - } - break; - - case MAVLINK_MSG_ID_MISSION_ITEM: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_item_t mi; - mavlink_msg_mission_item_decode(&message, &mi); - - // Special case a 0 for the target system or component, it means that anyone is the target, so we should process this. - if (mi.target_system == 0) { - mi.target_system = mavlink->getSystemId(); - } - if (mi.target_component == 0) { - mi.target_component = mavlink->getComponentId(); - } - - // Check that the item pertains to this UAS. - if(mi.target_system == mavlink->getSystemId()) - { - - if (mi.target_component != mavlink->getComponentId()) { - qDebug() << "The target component ID is not set correctly. This is currently only a warning, but will be turned into an error."; - qDebug() << "Expecting" << mavlink->getComponentId() << "but got" << mi.target_component; - } - - _waypointManager->handleWaypoint(message.sysid, message.compid, &mi); - } - else - { - qDebug() << QString("Received mission item message, but was wrong system id. Expected %1, received %2").arg(mavlink->getSystemId()).arg(mi.target_system); - } - } - } - break; - - case MAVLINK_MSG_ID_MISSION_ACK: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_ack_t ma; - mavlink_msg_mission_ack_decode(&message, &ma); - - // Special case a 0 for the target system or component, it means that anyone is the target, so we should process this. - if (ma.target_system == 0) { - ma.target_system = mavlink->getSystemId(); - } - if (ma.target_component == 0) { - ma.target_component = mavlink->getComponentId(); - } - - // Check that the ack pertains to this UAS. - if(ma.target_system == mavlink->getSystemId()) - { - - if (ma.target_component != mavlink->getComponentId()) { - qDebug() << tr("The target component ID is not set correctly. This is currently only a warning, but will be turned into an error."); - qDebug() << "Expecting" << mavlink->getComponentId() << "but got" << ma.target_component; - } - - _waypointManager->handleWaypointAck(message.sysid, message.compid, &ma); - } - else - { - qDebug() << QString("Received mission ack message, but was wrong system id. Expected %1, received %2").arg(mavlink->getSystemId()).arg(ma.target_system); - } - } - } - break; - - case MAVLINK_MSG_ID_MISSION_REQUEST: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_request_t mr; - mavlink_msg_mission_request_decode(&message, &mr); - - // Special case a 0 for the target system or component, it means that anyone is the target, so we should process this. - if (mr.target_system == 0) { - mr.target_system = mavlink->getSystemId(); - } - if (mr.target_component == 0) { - mr.target_component = mavlink->getComponentId(); - } - - // Check that the request pertains to this UAS. - if(mr.target_system == mavlink->getSystemId()) - { - - if (mr.target_component != mavlink->getComponentId()) { - qDebug() << QString("The target component ID is not set correctly. This is currently only a warning, but will be turned into an error."); - qDebug() << "Expecting" << mavlink->getComponentId() << "but got" << mr.target_component; - } - - _waypointManager->handleWaypointRequest(message.sysid, message.compid, &mr); - } - else - { - qDebug() << QString("Received mission request message, but was wrong system id. Expected %1, received %2").arg(mavlink->getSystemId()).arg(mr.target_system); - } - } - } - break; - - case MAVLINK_MSG_ID_MISSION_ITEM_REACHED: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_item_reached_t wpr; - mavlink_msg_mission_item_reached_decode(&message, &wpr); - _waypointManager->handleWaypointReached(message.sysid, message.compid, &wpr); - QString text = QString("System %1 reached waypoint %2").arg(getUASID()).arg(wpr.seq); - _say(text); - emit textMessageReceived(message.sysid, message.compid, MAV_SEVERITY_INFO, text); - } - } - break; - - case MAVLINK_MSG_ID_MISSION_CURRENT: - { - if (!qgcApp()->useNewMissionEditor()) { - mavlink_mission_current_t wpc; - mavlink_msg_mission_current_decode(&message, &wpc); - _waypointManager->handleWaypointCurrent(message.sysid, message.compid, &wpc); - } - } - break; - + case MAVLINK_MSG_ID_POSITION_TARGET_LOCAL_NED: { if (multiComponentSourceDetected && wrongComponent) diff --git a/src/uas/UAS.h b/src/uas/UAS.h index f2386a6fa..e7b2d46c3 100644 --- a/src/uas/UAS.h +++ b/src/uas/UAS.h @@ -371,7 +371,6 @@ public: bool isRotaryWing(); bool isFixedWing(); - friend class UASWaypointManager; friend class FileManager; protected: //COMMENTS FOR TEST UNIT @@ -509,11 +508,6 @@ public: /** @brief Get the human-readable status message for this code */ void getStatusForCode(int statusCode, QString& uasState, QString& stateDescription); - /** @brief Get reference to the waypoint manager **/ - UASWaypointManager* getWaypointManager() { - return _waypointManager; - } - virtual FileManager* getFileManager() { return &fileManager; } @@ -701,7 +695,6 @@ private: void _say(const QString& text, int severity = 6); private: - UASWaypointManager* _waypointManager; Vehicle* _vehicle; }; diff --git a/src/uas/UASInterface.h b/src/uas/UASInterface.h index 2bc404538..8121e819b 100644 --- a/src/uas/UASInterface.h +++ b/src/uas/UASInterface.h @@ -40,7 +40,6 @@ This file is part of the QGROUNDCONTROL project #include "LinkInterface.h" #include "ProtocolInterface.h" -#include "UASWaypointManager.h" class FileManager; @@ -92,9 +91,6 @@ public: /** @brief Set the airframe of this MAV */ virtual int getAirframe() const = 0; - /** @brief Get reference to the waypoint manager **/ - virtual UASWaypointManager* getWaypointManager(void) = 0; - virtual FileManager* getFileManager() = 0; enum Airframe { diff --git a/src/uas/UASWaypointManager.cc b/src/uas/UASWaypointManager.cc deleted file mode 100644 index 5b21e9eb2..000000000 --- a/src/uas/UASWaypointManager.cc +++ /dev/null @@ -1,1218 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009-2012 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief Implementation of the waypoint protocol handler - * - * @author Petri Tanskanen - * - */ - -#include "UASWaypointManager.h" -#include "UAS.h" -#include "mavlink_types.h" -#include "HomePositionManager.h" -#include "QGCMessageBox.h" -#include "Vehicle.h" - -#define PROTOCOL_TIMEOUT_MS 2000 ///< maximum time to wait for pending messages until timeout -#define PROTOCOL_DELAY_MS 20 ///< minimum delay between sent messages -#define PROTOCOL_MAX_RETRIES 5 ///< maximum number of send retries (after timeout) -const float UASWaypointManager::defaultAltitudeHomeOffset = 30.0f; -UASWaypointManager::UASWaypointManager(Vehicle* vehicle, UAS* uas) - : _vehicle(vehicle), - current_retries(0), - current_wp_id(0), - current_count(0), - current_state(WP_IDLE), - current_partner_systemid(0), - current_partner_compid(0), - currentWaypointEditable(), - protocol_timer(this), - _updateWPlist_timer(this) -{ - _offlineEditingModeMessage = tr("You are in offline editing mode. Make sure to save your mission to a file before connecting to a system - you will need to load the file into the system, the offline list will be cleared on connect."); - - if (_vehicle) - { - uasid = _vehicle->id(); - connect(&protocol_timer, SIGNAL(timeout()), this, SLOT(timeout())); - connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(handleLocalPositionChanged(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(handleGlobalPositionChanged(UASInterface*,double,double,double,double,quint64))); - } - else - { - uasid = 0; - } - - // We signal to ourselves here so that tiemrs are started and stopped on correct thread - connect(this, SIGNAL(_startProtocolTimer(void)), this, SLOT(_startProtocolTimerOnThisThread(void))); - connect(this, SIGNAL(_stopProtocolTimer(void)), this, SLOT(_stopProtocolTimerOnThisThread(void))); - _updateWPlist_timer.setInterval(1500); - _updateWPlist_timer.setSingleShot(true); - connect(&_updateWPlist_timer, SIGNAL(timeout()), this, SLOT(_updateWPonTimer())); -} - -UASWaypointManager::~UASWaypointManager() -{ - -} - -void UASWaypointManager::timeout() -{ - if (current_retries > 0) { - protocol_timer.start(PROTOCOL_TIMEOUT_MS); - current_retries--; - emit updateStatusString(tr("Timeout, retrying (retries left: %1)").arg(current_retries)); - - if (current_state == WP_GETLIST) { - sendWaypointRequestList(); - } else if (current_state == WP_GETLIST_GETWPS) { - sendWaypointRequest(current_wp_id); - } else if (current_state == WP_SENDLIST) { - sendWaypointCount(); - } else if (current_state == WP_SENDLIST_SENDWPS) { - sendWaypoint(current_wp_id); - } else if (current_state == WP_CLEARLIST) { - sendWaypointClearAll(); - } else if (current_state == WP_SETCURRENT) { - sendWaypointSetCurrent(current_wp_id); - } - } else { - protocol_timer.stop(); - - emit updateStatusString("Operation timed out."); - - current_state = WP_IDLE; - current_count = 0; - current_wp_id = 0; - } -} - -void UASWaypointManager::handleLocalPositionChanged(UASInterface* mav, double x, double y, double z, quint64 time) -{ - Q_UNUSED(mav); - Q_UNUSED(time); - if (waypointsEditable.count() > 0 && !currentWaypointEditable.isNull() && (currentWaypointEditable->frame() == MAV_FRAME_LOCAL_NED || currentWaypointEditable->frame() == MAV_FRAME_LOCAL_ENU)) - { - double xdiff = x-currentWaypointEditable->x(); - double ydiff = y-currentWaypointEditable->y(); - double zdiff = z-currentWaypointEditable->z(); - double dist = sqrt(xdiff*xdiff + ydiff*ydiff + zdiff*zdiff); - emit waypointDistanceChanged(dist); - } -} - -void UASWaypointManager::handleGlobalPositionChanged(UASInterface* mav, double lat, double lon, double altAMSL, double altWGS84, quint64 time) -{ - Q_UNUSED(mav); - Q_UNUSED(time); - Q_UNUSED(altAMSL); - Q_UNUSED(altWGS84); - Q_UNUSED(lon); - Q_UNUSED(lat); - if (waypointsEditable.count() > 0 && !currentWaypointEditable.isNull() && (currentWaypointEditable->frame() == MAV_FRAME_GLOBAL || currentWaypointEditable->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)) - { - // TODO FIXME Calculate distance - double dist = 0; - emit waypointDistanceChanged(dist); - } -} - -void UASWaypointManager::handleWaypointCount(quint8 systemId, quint8 compId, quint16 count) -{ - if (current_state == WP_GETLIST && systemId == current_partner_systemid) { - emit _startProtocolTimer(); // Start timer on correct thread - current_retries = PROTOCOL_MAX_RETRIES; - - //Clear the old edit-list before receiving the new one - if (read_to_edit == true){ - while(waypointsEditable.count()>0) { - MissionItem *t = waypointsEditable[0]; - waypointsEditable.removeAt(0); - delete t; - } - emit waypointEditableListChanged(); - } - - if (count > 0) { - current_count = count; - current_wp_id = 0; - current_state = WP_GETLIST_GETWPS; - sendWaypointRequest(current_wp_id); - } else { - emit _stopProtocolTimer(); // Stop the time on our thread - QTime time = QTime::currentTime(); - emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString())); - current_state = WP_IDLE; - current_count = 0; - current_wp_id = 0; - } - - - } else { - if (current_state != WP_GETLIST_GETWPS && systemId == current_partner_systemid) - { - qDebug("Requesting new waypoints. Propably changed onboard."); - if (!_updateWPlist_timer.isActive()) - { - current_state = WP_IDLE; - _updateWPlist_timer.start(); - } - } - else - { - qDebug("Rejecting waypoint count message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_GETLIST, current_partner_systemid, systemId, current_partner_compid, compId); - } - } -} - -void UASWaypointManager::handleWaypoint(quint8 systemId, quint8 compId, mavlink_mission_item_t *wp) -{ - if (systemId == current_partner_systemid && current_state == WP_GETLIST_GETWPS && wp->seq == current_wp_id) { - emit _startProtocolTimer(); // Start timer on our thread - current_retries = PROTOCOL_MAX_RETRIES; - - if(wp->seq == current_wp_id) { - - MissionItem *lwp_vo = new MissionItem(NULL, - wp->seq, - QGeoCoordinate(wp->x, wp->y, wp->z), - (MAV_CMD) wp->command, - wp->param1, - wp->param2, - wp->param3, - wp->param4, - wp->autocontinue, - wp->current, - (MAV_FRAME) wp->frame); - - addWaypointViewOnly(lwp_vo); - - if (read_to_edit == true) { - MissionItem *lwp_ed = new MissionItem(NULL, - wp->seq, - QGeoCoordinate(wp->x, wp->y, wp->z), - (MAV_CMD) wp->command, - wp->param1, - wp->param2, - wp->param3, - wp->param4, - wp->autocontinue, - wp->current, - (MAV_FRAME) wp->frame); - addWaypointEditable(lwp_ed, false); - if (wp->current == 1) currentWaypointEditable = lwp_ed; - } - - - //get next waypoint - current_wp_id++; - - if(current_wp_id < current_count) { - sendWaypointRequest(current_wp_id); - } else { - sendWaypointAck(0); - - // all waypoints retrieved, change state to idle - current_state = WP_IDLE; - current_count = 0; - current_wp_id = 0; - - emit _stopProtocolTimer(); // Stop timer on our thread - emit readGlobalWPFromUAS(false); - QTime time = QTime::currentTime(); - emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString())); - - } - } else { - emit updateStatusString(tr("MissionItem ID mismatch, rejecting waypoint")); - } - } else if (systemId == current_partner_systemid - && wp->seq < waypointsViewOnly.size() && waypointsViewOnly[wp->seq]->command()) { - // accept single sent waypoints because they can contain updates about remaining DO_JUMP repetitions - // but only update view only side - MissionItem *lwp_vo = new MissionItem(NULL, - wp->seq, - QGeoCoordinate(wp->x, wp->y, wp->z), - (MAV_CMD) wp->command, - wp->param1, - wp->param2, - wp->param3, - wp->param4, - wp->autocontinue, - wp->current, - (MAV_FRAME) wp->frame); - - waypointsViewOnly.replace(wp->seq, lwp_vo); - emit waypointViewOnlyListChanged(); - emit waypointViewOnlyListChanged(uasid); - - } else { - qDebug("Rejecting waypoint message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_GETLIST_GETWPS, current_partner_systemid, systemId, current_partner_compid, compId); - } -} - -void UASWaypointManager::handleWaypointAck(quint8 systemId, quint8 compId, mavlink_mission_ack_t *wpa) -{ - if (systemId != current_partner_systemid) { - return; - } - - // Check if the current partner component ID is generic. If it is, we might need to update - if (current_partner_compid == MAV_COMP_ID_MISSIONPLANNER) { - current_partner_compid = compId; - } - - if (compId == current_partner_compid || compId == MAV_COMP_ID_ALL) { - if((current_state == WP_SENDLIST || current_state == WP_SENDLIST_SENDWPS) && (current_wp_id == waypoint_buffer.count()-1 && wpa->type == 0)) { - //all waypoints sent and ack received - emit _stopProtocolTimer(); // Stop timer on our thread - current_state = WP_IDLE; - readWaypoints(false); //Update "Onboard Waypoints"-tab immediately after the waypoint list has been sent. - QTime time = QTime::currentTime(); - emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString())); - } else if((current_state == WP_SENDLIST || current_state == WP_SENDLIST_SENDWPS) && wpa->type != 0) { - //give up transmitting if a WP is rejected - switch (wpa->type) - { - case MAV_MISSION_UNSUPPORTED_FRAME: - emit updateStatusString(tr("ERROR: Coordinate frame unsupported.")); - break; - case MAV_MISSION_UNSUPPORTED: - emit updateStatusString(tr("ERROR: Unsupported command.")); - break; - case MAV_MISSION_NO_SPACE: - emit updateStatusString(tr("ERROR: Mission count exceeds storage.")); - break; - case MAV_MISSION_INVALID: - case MAV_MISSION_INVALID_PARAM1: - case MAV_MISSION_INVALID_PARAM2: - case MAV_MISSION_INVALID_PARAM3: - case MAV_MISSION_INVALID_PARAM4: - case MAV_MISSION_INVALID_PARAM5_X: - case MAV_MISSION_INVALID_PARAM6_Y: - case MAV_MISSION_INVALID_PARAM7: - emit updateStatusString(tr("ERROR: A specified parameter was invalid.")); - break; - case MAV_MISSION_INVALID_SEQUENCE: - emit updateStatusString(tr("ERROR: Mission received out of sequence.")); - break; - case MAV_MISSION_DENIED: - emit updateStatusString(tr("ERROR: UAS not accepting missions.")); - break; - case MAV_MISSION_ERROR: - default: - emit updateStatusString(tr("ERROR: Unspecified error")); - break; - } - emit _stopProtocolTimer(); // Stop timer on our thread - current_state = WP_IDLE; - } else if(current_state == WP_CLEARLIST) { - emit _stopProtocolTimer(); // Stop timer on our thread - current_state = WP_IDLE; - QTime time = QTime::currentTime(); - emit updateStatusString(tr("Done. (updated at %1)").arg(time.toString())); - } - } -} - -void UASWaypointManager::handleWaypointRequest(quint8 systemId, quint8 compId, mavlink_mission_request_t *wpr) -{ - if (systemId == current_partner_systemid && ((current_state == WP_SENDLIST && wpr->seq == 0) || (current_state == WP_SENDLIST_SENDWPS && (wpr->seq == current_wp_id || wpr->seq == current_wp_id + 1)))) { - emit _startProtocolTimer(); // Start timer on our thread - current_retries = PROTOCOL_MAX_RETRIES; - - if (wpr->seq < waypoint_buffer.count()) { - current_state = WP_SENDLIST_SENDWPS; - current_wp_id = wpr->seq; - sendWaypoint(current_wp_id); - } else { - //TODO: Error message or something - } - } else { - qDebug("Rejecting waypoint request message, check mismatch: current_state: %d == %d, system id %d == %d, comp id %d == %d", current_state, WP_SENDLIST_SENDWPS, current_partner_systemid, systemId, current_partner_compid, compId); - } -} - -void UASWaypointManager::handleWaypointReached(quint8 systemId, quint8 compId, mavlink_mission_item_reached_t *wpr) -{ - Q_UNUSED(compId); - if (!_vehicle) return; - if (systemId == uasid) { - emit updateStatusString(tr("Reached waypoint %1").arg(wpr->seq)); - } -} - -void UASWaypointManager::handleWaypointCurrent(quint8 systemId, quint8 compId, mavlink_mission_current_t *wpc) -{ - Q_UNUSED(compId); - if (!_vehicle) return; - if (systemId == uasid) { - // FIXME Petri - if (current_state == WP_SETCURRENT) { - emit _stopProtocolTimer(); // Stop timer on our thread - current_state = WP_IDLE; - - // update the local main storage - if (wpc->seq < waypointsViewOnly.size()) { - for(int i = 0; i < waypointsViewOnly.size(); i++) { - if (waypointsViewOnly[i]->sequenceNumber() == wpc->seq) { - waypointsViewOnly[i]->setIsCurrentItem(true); - } else { - waypointsViewOnly[i]->setIsCurrentItem(false); - } - } - } - } - emit updateStatusString(tr("New current waypoint %1").arg(wpc->seq)); - //emit update to UI widgets - emit currentWaypointChanged(wpc->seq); - } -} - -void UASWaypointManager::notifyOfChangeEditable(MissionItem* wp) -{ - // If only one waypoint was changed, emit only WP signal - if (wp != NULL) { - emit waypointEditableChanged(uasid, wp); - } else { - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); - } -} - -void UASWaypointManager::notifyOfChangeViewOnly(MissionItem* wp) -{ - if (wp != NULL) { - emit waypointViewOnlyChanged(uasid, wp); - } else { - emit waypointViewOnlyListChanged(); - emit waypointViewOnlyListChanged(uasid); - } -} - - -int UASWaypointManager::setCurrentWaypoint(quint16 seq) -{ - if (seq < waypointsViewOnly.size()) { - if(current_state == WP_IDLE) { - - //send change to UAS - important to note: if the transmission fails, we have inconsistencies - emit _startProtocolTimer(); // Start timer on our thread - current_retries = PROTOCOL_MAX_RETRIES; - - current_state = WP_SETCURRENT; - current_wp_id = seq; - current_partner_systemid = uasid; - current_partner_compid = MAV_COMP_ID_MISSIONPLANNER; - - sendWaypointSetCurrent(current_wp_id); - - return 0; - } - } - return -1; -} - -int UASWaypointManager::setCurrentEditable(quint16 seq) -{ - if (seq < waypointsEditable.count()) { - if(current_state == WP_IDLE) { - //update local main storage - for (int i = 0; i < waypointsEditable.count(); i++) { - if (waypointsEditable[i]->sequenceNumber() == seq) { - waypointsEditable[i]->setIsCurrentItem(true); - } else { - waypointsEditable[i]->setIsCurrentItem(false); - } - } - - return 0; - } - } - return -1; -} - -void UASWaypointManager::addWaypointViewOnly(MissionItem *wp) -{ - if (wp) - { - waypointsViewOnly.insert(waypointsViewOnly.size(), wp); - connect(wp, SIGNAL(changed(MissionItem*)), this, SLOT(notifyOfChangeViewOnly(MissionItem*))); - - emit waypointViewOnlyListChanged(); - emit waypointViewOnlyListChanged(uasid); - } -} - - -/** - * @warning Make sure the waypoint stays valid for the whole application lifecycle! - * @param enforceFirstActive Enforces that the first waypoint is set as active - * @see createWaypoint() is more suitable for most use cases - */ -void UASWaypointManager::addWaypointEditable(MissionItem *wp, bool enforceFirstActive) -{ - if (wp) - { - // Check if this is the first waypoint in an offline list - if (waypointsEditable.count() == 0 && _vehicle == NULL) { - QGCMessageBox::critical(tr("MissionItem Manager"), _offlineEditingModeMessage); - } - - wp->setSequenceNumber(waypointsEditable.count()); - if (enforceFirstActive && waypointsEditable.count() == 0) - { - wp->setIsCurrentItem(true); - currentWaypointEditable = wp; - } - waypointsEditable.insert(waypointsEditable.count(), wp); - connect(wp, SIGNAL(changed(MissionItem*)), this, SLOT(notifyOfChangeEditable(MissionItem*))); - - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); - } -} - -/** - * @param enforceFirstActive Enforces that the first waypoint is set as active - */ -MissionItem* UASWaypointManager::createWaypoint(bool enforceFirstActive) -{ - // Check if this is the first waypoint in an offline list - if (waypointsEditable.count() == 0 && _vehicle == NULL) { - QGCMessageBox::critical(tr("MissionItem Manager"), _offlineEditingModeMessage); - } - - MissionItem* wp = new MissionItem(); - wp->setSequenceNumber(waypointsEditable.count()); - wp->setFrame((MAV_FRAME)getFrameRecommendation()); - wp->setAltitude(getAltitudeRecommendation()); - wp->setAcceptanceRadius(getAcceptanceRadiusRecommendation()); - if (enforceFirstActive && waypointsEditable.count() == 0) - { - wp->setIsCurrentItem(true); - currentWaypointEditable = wp; - } - waypointsEditable.append(wp); - connect(wp, SIGNAL(changed(MissionItem*)), this, SLOT(notifyOfChangeEditable(MissionItem*))); - - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); - return wp; -} - -int UASWaypointManager::removeWaypoint(quint16 seq) -{ - if (seq < waypointsEditable.count()) - { - MissionItem *t = waypointsEditable[seq]; - - if (t->isCurrentItem() == true) //trying to remove the current waypoint - { - if (seq+1 < waypointsEditable.count()) // setting the next waypoint as current - { - waypointsEditable[seq+1]->setIsCurrentItem(true); - } - else if (seq-1 >= 0) // if deleting the last on the list, then setting the previous waypoint as current - { - waypointsEditable[seq-1]->setIsCurrentItem(true); - } - } - - waypointsEditable.removeAt(seq); - delete t; - t = NULL; - - for(int i = seq; i < waypointsEditable.count(); i++) - { - waypointsEditable[i]->setSequenceNumber(i); - } - - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); - return 0; - } - return -1; -} - -void UASWaypointManager::moveWaypoint(quint16 cur_seq, quint16 new_seq) -{ - if (cur_seq != new_seq && cur_seq < waypointsEditable.count() && new_seq < waypointsEditable.count()) - { - MissionItem *t = waypointsEditable[cur_seq]; - if (cur_seq < new_seq) { - for (int i = cur_seq; i < new_seq; i++) - { - waypointsEditable[i] = waypointsEditable[i+1]; - waypointsEditable[i]->setSequenceNumber(i); - } - } - else - { - for (int i = cur_seq; i > new_seq; i--) - { - waypointsEditable[i] = waypointsEditable[i-1]; - waypointsEditable[i]->setSequenceNumber(i); - } - } - waypointsEditable[new_seq] = t; - waypointsEditable[new_seq]->setSequenceNumber(new_seq); - - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); - } -} - -void UASWaypointManager::saveWaypoints(const QString &saveFile) -{ - QFile file(saveFile); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) - return; - - QTextStream out(&file); - - //write the waypoint list version to the first line for compatibility check - out << "QGC WPL 120\r\n"; - - for (int i = 0; i < waypointsEditable.count(); i++) - { - waypointsEditable[i]->setSequenceNumber(i); - waypointsEditable[i]->save(out); - } - file.close(); -} - -void UASWaypointManager::loadWaypoints(const QString &loadFile) -{ - QFile file(loadFile); - if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) - return; - - while(waypointsEditable.count()>0) { - MissionItem *t = waypointsEditable[0]; - waypointsEditable.removeAt(0); - delete t; - } - - QTextStream in(&file); - - const QStringList &version = in.readLine().split(" "); - - if (!(version.size() == 3 && version[0] == "QGC" && version[1] == "WPL" && version[2] == "120")) - { - emit updateStatusString(tr("The waypoint file is not compatible with the current version of QGroundControl.")); - } - else - { - while (!in.atEnd()) - { - MissionItem *t = new MissionItem(); - if(t->load(in)) - { - //Use the existing function to add waypoints to the map instead of doing it manually - //Indeed, we should connect our waypoints to the map in order to synchronize them - //t->setSequenceNumber(waypointsEditable.count()); - // waypointsEditable.insert(waypointsEditable.count(), t); - addWaypointEditable(t, false); - } - else - { - emit updateStatusString(tr("The waypoint file is corrupted. Load operation only partly succesful.")); - break; - } - } - } - - file.close(); - - emit loadWPFile(); - emit waypointEditableListChanged(); - emit waypointEditableListChanged(uasid); -} - -void UASWaypointManager::clearWaypointList() -{ - if (current_state == WP_IDLE) - { - emit _startProtocolTimer(); // Start timer on our thread - current_retries = PROTOCOL_MAX_RETRIES; - - current_state = WP_CLEARLIST; - current_wp_id = 0; - current_partner_systemid = uasid; - current_partner_compid = MAV_COMP_ID_MISSIONPLANNER; - - sendWaypointClearAll(); - } -} - -const QList UASWaypointManager::getGlobalFrameWaypointList() -{ - // TODO Keep this global frame list up to date - // with complete waypoint list - // instead of filtering on each request - QList wps; - foreach (MissionItem* wp, waypointsEditable) - { - if (wp->frame() == MAV_FRAME_GLOBAL || wp->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) - { - wps.append(wp); - } - } - return wps; -} - -const QList UASWaypointManager::getGlobalFrameAndNavTypeWaypointList() -{ - // TODO Keep this global frame list up to date - // with complete waypoint list - // instead of filtering on each request - QList wps; - foreach (MissionItem* wp, waypointsEditable) - { - if ((wp->frame() == MAV_FRAME_GLOBAL || wp->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && wp->isNavigationType()) - { - wps.append(wp); - } - } - return wps; -} - -const QList UASWaypointManager::getNavTypeWaypointList() -{ - // TODO Keep this global frame list up to date - // with complete waypoint list - // instead of filtering on each request - QList wps; - foreach (MissionItem* wp, waypointsEditable) - { - if (wp->isNavigationType()) - { - wps.append(wp); - } - } - return wps; -} - -int UASWaypointManager::getIndexOf(MissionItem* wp) -{ - return waypointsEditable.indexOf(wp); -} - -int UASWaypointManager::getGlobalFrameIndexOf(MissionItem* wp) -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) { - if (p->frame() == MAV_FRAME_GLOBAL || wp->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) - { - if (p == wp) - { - return i; - } - i++; - } - } - - return -1; -} - -int UASWaypointManager::getGlobalFrameAndNavTypeIndexOf(MissionItem* wp) -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) { - if ((p->frame() == MAV_FRAME_GLOBAL || wp->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && p->isNavigationType()) - { - if (p == wp) - { - return i; - } - i++; - } - } - - return -1; -} - -int UASWaypointManager::getNavTypeIndexOf(MissionItem* wp) -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) - { - if (p->isNavigationType()) - { - if (p == wp) - { - return i; - } - i++; - } - } - - return -1; -} - -int UASWaypointManager::getGlobalFrameCount() -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) - { - if (p->frame() == MAV_FRAME_GLOBAL || p->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) - { - i++; - } - } - - return i; -} - -int UASWaypointManager::getGlobalFrameAndNavTypeCount() -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) { - if ((p->frame() == MAV_FRAME_GLOBAL || p->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT) && p->isNavigationType()) - { - i++; - } - } - - return i; -} - -int UASWaypointManager::getNavTypeCount() -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) { - if (p->isNavigationType()) { - i++; - } - } - - return i; -} - -int UASWaypointManager::getLocalFrameCount() -{ - // Search through all waypointsEditable, - // counting only those in global frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) - { - if (p->frame() == MAV_FRAME_LOCAL_NED || p->frame() == MAV_FRAME_LOCAL_ENU) - { - i++; - } - } - - return i; -} - -int UASWaypointManager::getLocalFrameIndexOf(MissionItem* wp) -{ - // Search through all waypointsEditable, - // counting only those in local frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) - { - if (p->frame() == MAV_FRAME_LOCAL_NED || p->frame() == MAV_FRAME_LOCAL_ENU) - { - if (p == wp) - { - return i; - } - i++; - } - } - - return -1; -} - -int UASWaypointManager::getMissionFrameIndexOf(MissionItem* wp) -{ - // Search through all waypointsEditable, - // counting only those in mission frame - int i = 0; - foreach (MissionItem* p, waypointsEditable) - { - if (p->frame() == MAV_FRAME_MISSION) - { - if (p == wp) - { - return i; - } - i++; - } - } - - return -1; -} - - -/** - * @param readToEdit If true, incoming waypoints will be copied both to "edit"-tab and "view"-tab. Otherwise, only to "view"-tab. - */ -void UASWaypointManager::readWaypoints(bool readToEdit) -{ - read_to_edit = readToEdit; - emit readGlobalWPFromUAS(true); - if(current_state == WP_IDLE) { - - - //Clear the old view-list before receiving the new one - while(waypointsViewOnly.size()>0) { - MissionItem *t = waypointsViewOnly[0]; - waypointsViewOnly.removeAt(0); - delete t; - } - emit waypointViewOnlyListChanged(); - /* THIS PART WAS MOVED TO handleWaypointCount. THE EDIT-LIST SHOULD NOT BE CLEARED UNLESS THERE IS A RESPONSE FROM UAV. - //Clear the old edit-list before receiving the new one - if (read_to_edit == true){ - while(waypointsEditable.count()>0) { - MissionItem *t = waypointsEditable[0]; - waypointsEditable.remove(0); - delete t; - } - emit waypointEditableListChanged(); - } - */ - - // We are signalling ourselves here so that the timer gets started on the right thread - emit _startProtocolTimer(); - - current_retries = PROTOCOL_MAX_RETRIES; - - current_state = WP_GETLIST; - current_wp_id = 0; - current_partner_systemid = uasid; - current_partner_compid = MAV_COMP_ID_MISSIONPLANNER; - - sendWaypointRequestList(); - - } -} -bool UASWaypointManager::guidedModeSupported() -{ - return (_vehicle->firmwareType() == MAV_AUTOPILOT_ARDUPILOTMEGA); -} - -void UASWaypointManager::goToWaypoint(MissionItem *wp) -{ - //Don't try to send a guided mode message to an AP that does not support it. - if (_vehicle->firmwareType() == MAV_AUTOPILOT_ARDUPILOTMEGA) - { - mavlink_mission_item_t mission; - memset(&mission, 0, sizeof(mavlink_mission_item_t)); //initialize with zeros - //const MissionItem *cur_s = waypointsEditable.at(i); - - mission.autocontinue = 0; - mission.current = 2; //2 for guided mode - mission.param1 = wp->param1(); - mission.param2 = wp->param2(); - mission.param3 = wp->param3(); - mission.param4 = wp->param4(); - mission.frame = wp->frame(); - mission.command = wp->command(); - mission.seq = 0; // don't read out the sequence number of the waypoint class - mission.x = wp->x(); - mission.y = wp->y(); - mission.z = wp->z(); - mavlink_message_t message; - mission.target_system = uasid; - mission.target_component = MAV_COMP_ID_MISSIONPLANNER; - mavlink_msg_mission_item_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &mission); - _vehicle->sendMessage(message); - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); - } -} - -void UASWaypointManager::writeWaypoints() -{ - if (current_state == WP_IDLE) { - // Send clear all if count == 0 - if (waypointsEditable.count() > 0) { - emit _startProtocolTimer(); // Start timer on our thread - current_retries = PROTOCOL_MAX_RETRIES; - - current_count = waypointsEditable.count(); - current_state = WP_SENDLIST; - current_wp_id = 0; - current_partner_systemid = uasid; - current_partner_compid = MAV_COMP_ID_MISSIONPLANNER; - - //clear local buffer - // Why not replace with waypoint_buffer.clear() ? - // because this will lead to memory leaks, the waypoint-structs - // have to be deleted, clear() would only delete the pointers. - while(!waypoint_buffer.empty()) { - delete waypoint_buffer.back(); - waypoint_buffer.pop_back(); - } - - bool noCurrent = true; - - //copy waypoint data to local buffer - for (int i=0; i < current_count; i++) { - waypoint_buffer.push_back(new mavlink_mission_item_t); - mavlink_mission_item_t *cur_d = waypoint_buffer.back(); - memset(cur_d, 0, sizeof(mavlink_mission_item_t)); //initialize with zeros - const MissionItem *cur_s = waypointsEditable.at(i); - - cur_d->autocontinue = cur_s->autoContinue(); - cur_d->current = cur_s->isCurrentItem() & noCurrent; //make sure only one current waypoint is selected, the first selected will be chosen - cur_d->param1 = cur_s->param1(); - cur_d->param2 = cur_s->param2(); - cur_d->param3 = cur_s->param3(); - cur_d->param4 = cur_s->param4(); - cur_d->frame = cur_s->frame(); - cur_d->command = cur_s->command(); - cur_d->seq = i; // don't read out the sequence number of the waypoint class - cur_d->x = cur_s->x(); - cur_d->y = cur_s->y(); - cur_d->z = cur_s->z(); - - if (cur_s->isCurrentItem() && noCurrent) - noCurrent = false; - if (i == (current_count - 1) && noCurrent == true) //not a single waypoint was set as "current" - cur_d->current = true; // set the last waypoint as current. Or should it better be the first waypoint ? - } - - - - - //send the waypoint count to UAS (this starts the send transaction) - sendWaypointCount(); - } else if (waypointsEditable.count() == 0) - { - clearWaypointList(); - } - } - else - { - // We're in another transaction, ignore command - qDebug() << tr("UASWaypointManager::sendWaypoints() doing something else. Ignoring command"); - } -} - -void UASWaypointManager::sendWaypointClearAll() -{ - if (!_vehicle) return; - - // Send the message. - mavlink_message_t message; - mavlink_mission_clear_all_t wpca = {(quint8)uasid, MAV_COMP_ID_MISSIONPLANNER}; - mavlink_msg_mission_clear_all_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wpca); - _vehicle->sendMessage(message); - - // And update the UI. - emit updateStatusString(tr("Clearing waypoint list...")); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -void UASWaypointManager::sendWaypointSetCurrent(quint16 seq) -{ - if (!_vehicle) return; - - // Send the message. - mavlink_message_t message; - mavlink_mission_set_current_t wpsc = {seq, (quint8)uasid, MAV_COMP_ID_MISSIONPLANNER}; - mavlink_msg_mission_set_current_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wpsc); - _vehicle->sendMessage(message); - - // And update the UI. - emit updateStatusString(tr("Updating target waypoint...")); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -void UASWaypointManager::sendWaypointCount() -{ - if (!_vehicle) return; - - - // Tell the UAS how many missions we'll sending. - mavlink_message_t message; - mavlink_mission_count_t wpc = {current_count, (quint8)uasid, MAV_COMP_ID_MISSIONPLANNER}; - mavlink_msg_mission_count_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wpc); - _vehicle->sendMessage(message); - - // And update the UI. - emit updateStatusString(tr("Starting to transmit waypoints...")); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -void UASWaypointManager::sendWaypointRequestList() -{ - if (!_vehicle) return; - - // Send a MISSION_REQUEST message to the uas for this mission manager, using the MISSIONPLANNER component. - mavlink_message_t message; - mavlink_mission_request_list_t wprl = {(quint8)uasid, MAV_COMP_ID_MISSIONPLANNER}; - mavlink_msg_mission_request_list_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wprl); - _vehicle->sendMessage(message); - - // And update the UI. - QString statusMsg(tr("Requesting waypoint list...")); - qDebug() << __FILE__ << __LINE__ << statusMsg; - emit updateStatusString(statusMsg); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -void UASWaypointManager::sendWaypointRequest(quint16 seq) -{ - if (!_vehicle) return; - - // Send a MISSION_REQUEST message to the UAS's MISSIONPLANNER component. - mavlink_message_t message; - mavlink_mission_request_t wpr = {seq, (quint8)uasid, MAV_COMP_ID_MISSIONPLANNER}; - mavlink_msg_mission_request_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wpr); - _vehicle->sendMessage(message); - - // And update the UI. - emit updateStatusString(tr("Retrieving waypoint ID %1 of %2").arg(wpr.seq).arg(current_count)); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -void UASWaypointManager::sendWaypoint(quint16 seq) -{ - if (!_vehicle) return; - mavlink_message_t message; - - if (seq < waypoint_buffer.count()) { - - // Fetch the current mission to send, and set it to apply to the curent UAS. - mavlink_mission_item_t *wp = waypoint_buffer.at(seq); - wp->target_system = uasid; - wp->target_component = MAV_COMP_ID_MISSIONPLANNER; - - // Transmit the new mission - mavlink_msg_mission_item_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, wp); - _vehicle->sendMessage(message); - - // And update the UI. - emit updateStatusString(tr("Sending waypoint ID %1 of %2 total").arg(wp->seq).arg(current_count)); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); - } -} - -void UASWaypointManager::sendWaypointAck(quint8 type) -{ - if (!_vehicle) return; - - // Send the message. - mavlink_message_t message; - mavlink_mission_ack_t wpa = {(quint8)uasid, MAV_COMP_ID_MISSIONPLANNER, type}; - mavlink_msg_mission_ack_encode(MAVLinkProtocol::instance()->getSystemId(), MAVLinkProtocol::instance()->getComponentId(), &message, &wpa); - _vehicle->sendMessage(message); - - QGC::SLEEP::msleep(PROTOCOL_DELAY_MS); -} - -UAS* UASWaypointManager::getUAS() { - return _vehicle ? _vehicle->uas() : NULL; ///< Returns the owning UAS -} - -float UASWaypointManager::getAltitudeRecommendation() -{ - if (waypointsEditable.count() > 0) { - return waypointsEditable.last()->altitude(); - } else { - return HomePositionManager::instance()->getHomeAltitude() + getHomeAltitudeOffsetDefault(); - } -} - -int UASWaypointManager::getFrameRecommendation() -{ - if (waypointsEditable.count() > 0) { - return static_cast(waypointsEditable.last()->frame()); - } else { - return MAV_FRAME_GLOBAL; - } -} - -float UASWaypointManager::getAcceptanceRadiusRecommendation() -{ - if (waypointsEditable.count() > 0) - { - return waypointsEditable.last()->acceptanceRadius(); - } - else - { - // Default to rotary wing waypoint radius for offline editing - if (!_vehicle || _vehicle->uas()->isRotaryWing()) - { - return UASInterface::WAYPOINT_RADIUS_DEFAULT_ROTARY_WING; - } - else if (_vehicle->uas()->isFixedWing()) - { - return UASInterface::WAYPOINT_RADIUS_DEFAULT_FIXED_WING; - } - } - - return 10.0f; -} - -float UASWaypointManager::getHomeAltitudeOffsetDefault() -{ - return defaultAltitudeHomeOffset; -} - - -void UASWaypointManager::_startProtocolTimerOnThisThread(void) -{ - protocol_timer.start(PROTOCOL_TIMEOUT_MS); -} - -void UASWaypointManager::_stopProtocolTimerOnThisThread(void) -{ - protocol_timer.stop(); -} - - -void UASWaypointManager::_updateWPonTimer() -{ - while (current_state != WP_IDLE) - { - QGC::SLEEP::msleep(100); - } - readWaypoints(true); -} diff --git a/src/uas/UASWaypointManager.h b/src/uas/UASWaypointManager.h deleted file mode 100644 index 42739dc1f..000000000 --- a/src/uas/UASWaypointManager.h +++ /dev/null @@ -1,200 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief Definition of the waypoint protocol handler - * - * @author Petri Tanskanen - * - */ - -#ifndef UASWAYPOINTMANAGER_H -#define UASWAYPOINTMANAGER_H - -#include -#include -#include -#include -#include "MissionItem.h" -#include "QGCMAVLink.h" - -class UAS; -class UASInterface; -class Vehicle; - -/** - * @brief Implementation of the MAVLINK waypoint protocol - * - * This class handles the communication with a waypoint manager on the MAV. - * All waypoints are stored in the QList waypoints, modifications can be done with the WaypointList widget. - * Notice that currently the access to the internal waypoint storage is not guarded nor thread-safe. This works as long as no other widget alters the data. - * - * See http://qgroundcontrol.org/waypoint_protocol for more information about the protocol and the states. - */ -class UASWaypointManager : public QObject -{ - Q_OBJECT -private: - enum WaypointState { - WP_IDLE = 0, ///< Waiting for commands - WP_SENDLIST, ///< Initial state for sending waypoints to the MAV - WP_SENDLIST_SENDWPS,///< Sending waypoints - WP_GETLIST, ///< Initial state for retrieving waypoints from the MAV - WP_GETLIST_GETWPS, ///< Receiving waypoints - WP_CLEARLIST, ///< Clearing waypoint list on the MAV - WP_SETCURRENT ///< Setting new current waypoint on the MAV - }; ///< The possible states for the waypoint protocol - -public: - UASWaypointManager(Vehicle* vehicle, UAS* uas); ///< Standard constructor - ~UASWaypointManager(); - bool guidedModeSupported(); - - void goToWaypoint(MissionItem *wp); - /** @name Received message handlers */ - /*@{*/ - void handleWaypointCount(quint8 systemId, quint8 compId, quint16 count); ///< Handles received waypoint count messages - void handleWaypoint(quint8 systemId, quint8 compId, mavlink_mission_item_t *wp); ///< Handles received waypoint messages - void handleWaypointAck(quint8 systemId, quint8 compId, mavlink_mission_ack_t *wpa); ///< Handles received waypoint ack messages - void handleWaypointRequest(quint8 systemId, quint8 compId, mavlink_mission_request_t *wpr); ///< Handles received waypoint request messages - void handleWaypointReached(quint8 systemId, quint8 compId, mavlink_mission_item_reached_t *wpr); ///< Handles received waypoint reached messages - void handleWaypointCurrent(quint8 systemId, quint8 compId, mavlink_mission_current_t *wpc); ///< Handles received set current waypoint messages - /*@}*/ - - /** @name Remote operations */ - /*@{*/ - void clearWaypointList(); ///< Sends the waypoint clear all message to the MAV - - void readWaypoints(bool read_to_edit=false); ///< Requests the MAV's current waypoint list. - void writeWaypoints(); ///< Sends the waypoint list to the MAV - int setCurrentWaypoint(quint16 seq); ///< Sends the sequence number of the waypoint that should get the new target waypoint to the UAS - int setCurrentEditable(quint16 seq); ///< Changes the current waypoint in edit tab - /*@}*/ - - /** @name MissionItem list operations */ - /*@{*/ - const QList &getWaypointEditableList(void) { - return waypointsEditable; ///< Returns a const reference to the waypoint list. - } - const QList &getWaypointViewOnlyList(void) { - return waypointsViewOnly; ///< Returns a const reference to the waypoint list. - } - const QList getGlobalFrameWaypointList(); ///< Returns a global waypoint list - const QList getGlobalFrameAndNavTypeWaypointList(); ///< Returns a global waypoint list containing only waypoints suitable for navigation. Actions and other mission items are filtered out. - const QList getNavTypeWaypointList(); ///< Returns a waypoint list containing only waypoints suitable for navigation. Actions and other mission items are filtered out. - int getIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list - int getGlobalFrameIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list, counting only global waypoints - int getGlobalFrameAndNavTypeIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list, counting only global AND navigation mode waypoints - int getNavTypeIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list, counting only navigation mode waypoints - int getLocalFrameIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list, counting only local waypoints - int getMissionFrameIndexOf(MissionItem* wp); ///< Get the index of a waypoint in the list, counting only mission waypoints - int getGlobalFrameCount(); ///< Get the count of global waypoints in the list - int getGlobalFrameAndNavTypeCount(); ///< Get the count of global waypoints in navigation mode in the list - int getNavTypeCount(); ///< Get the count of global waypoints in navigation mode in the list - int getLocalFrameCount(); ///< Get the count of local waypoints in the list - /*@}*/ - - UAS* getUAS(); - float getAltitudeRecommendation(); - int getFrameRecommendation(); - float getAcceptanceRadiusRecommendation(); - float getHomeAltitudeOffsetDefault(); - -private: - /** @name Message send functions */ - /*@{*/ - void sendWaypointClearAll(); - void sendWaypointSetCurrent(quint16 seq); - void sendWaypointCount(); - void sendWaypointRequestList(); - void sendWaypointRequest(quint16 seq); ///< Requests a waypoint with sequence number seq - void sendWaypoint(quint16 seq); ///< Sends a waypoint with sequence number seq - void sendWaypointAck(quint8 type); ///< Sends a waypoint ack - /*@}*/ - -public slots: - void timeout(); ///< Called by the timer if a response times out. Handles send retries. - /** @name MissionItem list operations */ - /*@{*/ - void addWaypointEditable(MissionItem *wp, bool enforceFirstActive=true); ///< adds a new waypoint to the end of the editable list and changes its sequence number accordingly - void addWaypointViewOnly(MissionItem *wp); ///< adds a new waypoint to the end of the view-only list and changes its sequence number accordingly - MissionItem* createWaypoint(bool enforceFirstActive=true); ///< Creates a waypoint - int removeWaypoint(quint16 seq); ///< locally remove the specified waypoint from the storage - void moveWaypoint(quint16 cur_seq, quint16 new_seq); ///< locally move a waypoint from its current position cur_seq to a new position new_seq - void saveWaypoints(const QString &saveFile); ///< saves the local waypoint list to saveFile - void loadWaypoints(const QString &loadFile); ///< loads a waypoint list from loadFile - void notifyOfChangeEditable(MissionItem* wp); ///< Notifies manager to changes to an editable waypoint - void notifyOfChangeViewOnly(MissionItem* wp); ///< Notifies manager to changes to a viewonly waypoint, e.g. some widget wants to change "current" - /*@}*/ - void handleLocalPositionChanged(UASInterface* mav, double x, double y, double z, quint64 time); - void handleGlobalPositionChanged(UASInterface* mav, double lat, double lon, double altAMSL, double altWGS84, quint64 time); - -signals: - void waypointEditableListChanged(void); ///< emits signal that the list of editable waypoints has been changed - void waypointEditableListChanged(int uasid); ///< emits signal that the list of editable waypoints has been changed - void waypointEditableChanged(int uasid, MissionItem* wp); ///< emits signal that a single editable waypoint has been changed - void waypointViewOnlyListChanged(void); ///< emits signal that the list of editable waypoints has been changed - void waypointViewOnlyListChanged(int uasid); ///< emits signal that the list of editable waypoints has been changed - void waypointViewOnlyChanged(int uasid, MissionItem* wp); ///< emits signal that a single editable waypoint has been changed - void currentWaypointChanged(quint16); ///< emits the new current waypoint sequence number - void updateStatusString(const QString &); ///< emits the current status string - void waypointDistanceChanged(double distance); ///< Distance to next waypoint changed (in meters) - - void loadWPFile(); ///< emits signal that a file wp has been load - void readGlobalWPFromUAS(bool value); ///< emits signal when finish to read Global WP from UAS - - void _startProtocolTimer(void); ///< emits signal to start protocol timer - void _stopProtocolTimer(void); ///< emits signal to stop protocol timer - -private slots: - void _startProtocolTimerOnThisThread(void); ///< Starts the protocol timer - void _stopProtocolTimerOnThisThread(void); ///< Starts the protocol timer - void _updateWPonTimer(void); ///< Starts requesting WP on timer timeout - -private: - Vehicle* _vehicle; - quint32 current_retries; ///< The current number of retries left - quint16 current_wp_id; ///< The last used waypoint ID in the current protocol transaction - quint16 current_count; ///< The number of waypoints in the current protocol transaction - WaypointState current_state; ///< The current protocol state - quint8 current_partner_systemid; ///< The current protocol communication target system - quint8 current_partner_compid; ///< The current protocol communication target component - bool read_to_edit; ///< If true, after readWaypoints() incoming waypoints will be copied both to "edit"-tab and "view"-tab. Otherwise, only to "view"-tab. - - QList waypointsViewOnly; ///< local copy of current waypoint list on MAV - QList waypointsEditable; ///< local editable waypoint list - QPointer currentWaypointEditable; ///< The currently used waypoint - QList waypoint_buffer; ///< buffer for waypoints during communication - QTimer protocol_timer; ///< Timer to catch timeouts - QTimer _updateWPlist_timer; ///< update WP list if modified by another instance onboard - bool standalone; ///< If standalone is set, do not write to UAS - int uasid; ///< The ID of the current UAS. Retrieved via `uas->getUASID();`, stored as an `int` to match its return type. - - // XXX export to settings - static const float defaultAltitudeHomeOffset; ///< Altitude offset in meters from home for new waypoints - - QString _offlineEditingModeMessage; -}; - -#endif // UASWAYPOINTMANAGER_H diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 53b3581e2..255c9d45f 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -40,19 +40,18 @@ This file is part of the QGROUNDCONTROL project #endif #include #include +#include +#include #include "QGC.h" #ifndef __ios__ #include "SerialLink.h" #endif #include "MAVLinkProtocol.h" -#include "QGCWaypointListMulti.h" #include "MainWindow.h" #include "GAudioOutput.h" #include "QGCMAVLinkLogPlayer.h" #include "SettingsDialog.h" -#include "QGCMapTool.h" -#include "QGCMapDisplay.h" #include "MAVLinkDecoder.h" #include "QGCMAVLinkMessageSender.h" #include "UASQuickView.h" @@ -86,7 +85,6 @@ This file is part of the QGROUNDCONTROL project /// The key under which the Main Window settings are saved const char* MAIN_SETTINGS_GROUP = "QGC_MAINWINDOW"; -const char* MainWindow::_waypointsDockWidgetName = "WAYPOINT_LIST_DOCKWIDGET"; const char* MainWindow::_mavlinkDockWidgetName = "MAVLINK_INSPECTOR_DOCKWIDGET"; const char* MainWindow::_customCommandWidgetName = "CUSTOM_COMMAND_DOCKWIDGET"; const char* MainWindow::_filesDockWidgetName = "FILE_VIEW_DOCKWIDGET"; @@ -386,7 +384,6 @@ void MainWindow::_buildCommonWidgets(void) }; static const struct DockWidgetInfo rgDockWidgetInfo[] = { - { _waypointsDockWidgetName, "Mission Plan", Qt::BottomDockWidgetArea }, { _mavlinkDockWidgetName, "MAVLink Inspector", Qt::RightDockWidgetArea }, { _customCommandWidgetName, "Custom Command", Qt::RightDockWidgetArea }, { _filesDockWidgetName, "Onboard Files", Qt::RightDockWidgetArea }, @@ -403,14 +400,6 @@ void MainWindow::_buildCommonWidgets(void) } } -void MainWindow::_buildPlanView(void) -{ - if (!_planView) { - _planView = new QGCMapTool(this); - _planView->setVisible(false); - } -} - void MainWindow::_buildMissionEditorView(void) { if (!_missionEditorView) { @@ -446,7 +435,7 @@ void MainWindow::_buildAnalyzeView(void) void MainWindow::_buildSimView(void) { if (!_simView) { - _simView = new QGCMapTool(this); + _simView = new FlightDisplayView(this); _simView->setVisible(false); } } @@ -483,9 +472,7 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName) QWidget* widget = NULL; - if (widgetName == _waypointsDockWidgetName) { - widget = new QGCWaypointListMulti(this); - } else if (widgetName == _mavlinkDockWidgetName) { + if (widgetName == _mavlinkDockWidgetName) { widget = new QGCMAVLinkInspector(MAVLinkProtocol::instance(),this); } else if (widgetName == _customCommandWidgetName) { widget = new CustomCommandWidget(this); @@ -493,8 +480,6 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName) widget = new QGCUASFileViewMulti(this); } else if (widgetName == _uasStatusDetailsDockWidgetName) { widget = new UASInfoWidget(this); - } else if (widgetName == _mapViewDockWidgetName) { - widget = new QGCMapTool(this); } else if (widgetName == _pfdDockWidgetName) { widget = new FlightDisplayWidget(this); } else if (widgetName == _uasInfoViewDockWidgetName) { @@ -686,7 +671,7 @@ void MainWindow::connectCommonActions() _ui.actionSimulationView->setChecked(true); _ui.actionSimulationView->activate(QAction::Trigger); } - if (_currentView == VIEW_PLAN || _currentView == VIEW_MISSIONEDITOR) + if (_currentView == VIEW_MISSIONEDITOR) { _ui.actionPlan->setChecked(true); _ui.actionPlan->activate(QAction::Trigger); @@ -710,9 +695,6 @@ void MainWindow::connectCommonActions() connect(_ui.actionAnalyze, SIGNAL(triggered()), this, SLOT(loadAnalyzeView())); connect(_ui.actionPlan, SIGNAL(triggered()), this, SLOT(loadPlanView())); - _ui.actionUseMissionEditor->setChecked(qgcApp()->useNewMissionEditor()); - connect(_ui.actionUseMissionEditor, &QAction::triggered, this, &MainWindow::_setUseMissionEditor); - // Help Actions connect(_ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp())); connect(_ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits())); @@ -858,12 +840,6 @@ void MainWindow::_loadCurrentViewState(void) defaultWidgets = "COMMUNICATION_CONSOLE_DOCKWIDGET,UAS_INFO_INFOVIEW_DOCKWIDGET"; break; - case VIEW_PLAN: - _buildPlanView(); - centerView = _planView; - defaultWidgets = "WAYPOINT_LIST_DOCKWIDGET"; - break; - case VIEW_MISSIONEDITOR: _buildMissionEditorView(); centerView = _missionEditorView; @@ -964,22 +940,12 @@ void MainWindow::loadAnalyzeView() void MainWindow::loadPlanView() { - if (qgcApp()->useNewMissionEditor()) { - if (_currentView != VIEW_MISSIONEDITOR) - { - _storeCurrentViewState(); - _currentView = VIEW_MISSIONEDITOR; - _ui.actionPlan->setChecked(true); - _loadCurrentViewState(); - } - } else { - if (_currentView != VIEW_PLAN) - { - _storeCurrentViewState(); - _currentView = VIEW_PLAN; - _ui.actionPlan->setChecked(true); - _loadCurrentViewState(); - } + if (_currentView != VIEW_MISSIONEDITOR) + { + _storeCurrentViewState(); + _currentView = VIEW_MISSIONEDITOR; + _ui.actionPlan->setChecked(true); + _loadCurrentViewState(); } } @@ -1076,8 +1042,3 @@ void MainWindow::_showQmlTestWidget(void) new QmlTestWidget(); } #endif - -void MainWindow::_setUseMissionEditor(bool checked) -{ - qgcApp()->setUseNewMissionEditor(checked); -} diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 22e56b10f..b6151b626 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -42,12 +42,10 @@ This file is part of the QGROUNDCONTROL project #include "LinkInterface.h" #include "UASInterface.h" #include "UASInfoWidget.h" -#include "WaypointList.h" #include "CameraView.h" #if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX) #include "Mouse6dofInput.h" #endif // QGC_MOUSE_ENABLED_WIN -#include "opmapcontrol.h" #include "MainToolBar.h" #include "LogCompressor.h" @@ -58,7 +56,6 @@ This file is part of the QGROUNDCONTROL project #include "QGCUASFileViewMulti.h" #include "Vehicle.h" -class QGCMapTool; class QGCMAVLinkMessageSender; class QGCFirmwareUpdate; class QSplashScreen; @@ -170,8 +167,6 @@ protected slots: * @brief Enable/Disable Status Bar */ void showStatusBarCallback(bool checked); - - void _setUseMissionEditor(bool checked); signals: void initStatusChanged(const QString& message, int alignment, const QColor &color); @@ -196,10 +191,10 @@ protected: typedef enum _VIEW_SECTIONS { VIEW_ANALYZE, // Engineering/Analyze view mode. Used for analyzing data and modifying onboard parameters - VIEW_PLAN, // Old mission editor + VIEW_UNUSED3, // Unused (don't remove, or it will screw up saved settigns indices) VIEW_FLIGHT, // Flight/Fly/Operate view mode. Used for 1st-person observation of the vehicle. VIEW_SIMULATION, // HIL Simulation view. Useful overview of the entire system when doing hardware-in-the-loop simulations. - VIEW_SETUP, // Setup view. Used for initializing the system for operation. Includes UI for calibration, firmware updating/checking, and parameter modifcation. + VIEW_SETUP, // Setup view. Used for initializing the system for operation. VIEW_UNUSED1, // Unused (don't remove, or it will screw up saved settigns indices) VIEW_UNUSED2, // Unused (don't remove, or it will screw up saved settigns indices) VIEW_MISSIONEDITOR, // New mission editor @@ -286,7 +281,6 @@ private: // Dock widget names static const char* _uasControlDockWidgetName; static const char* _uasListDockWidgetName; - static const char* _waypointsDockWidgetName; static const char* _mavlinkDockWidgetName; static const char* _customCommandWidgetName; static const char* _filesDockWidgetName; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index 3132ca0f0..5b22ce583 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -62,7 +62,6 @@ - @@ -254,17 +253,6 @@ Mission Editor - - - true - - - Use new mission editor (reboot required) - - - Mission Editor - - diff --git a/src/ui/QGCWaypointListMulti.cc b/src/ui/QGCWaypointListMulti.cc deleted file mode 100644 index 12cd90de9..000000000 --- a/src/ui/QGCWaypointListMulti.cc +++ /dev/null @@ -1,82 +0,0 @@ -#include "QGCWaypointListMulti.h" -#include "MultiVehicleManager.h" -#include "UAS.h" - -#include "ui_QGCWaypointListMulti.h" - -void* QGCWaypointListMulti::_offlineUAS = NULL; - -QGCWaypointListMulti::QGCWaypointListMulti(QWidget *parent) : - QWidget(parent), - _ui(new Ui::QGCWaypointListMulti) -{ - _ui->setupUi(this); - setMinimumSize(600, 80); - - connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &QGCWaypointListMulti::_vehicleAdded); - connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleRemoved, this, &QGCWaypointListMulti::_vehicleRemoved); - connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &QGCWaypointListMulti::_activeVehicleChanged); - - WaypointList* list = new WaypointList(_ui->stackedWidget, MultiVehicleManager::instance()->activeWaypointManager()); - _lists.insert(_offlineUAS, list); - _ui->stackedWidget->addWidget(list); - - if (MultiVehicleManager::instance()->activeVehicle()) { - _vehicleAdded(MultiVehicleManager::instance()->activeVehicle()); - _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); - } -} - -QGCWaypointListMulti::~QGCWaypointListMulti() -{ - delete _ui; -} - -void QGCWaypointListMulti::_vehicleRemoved(Vehicle* vehicle) -{ - // Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already - // been destroyed. - - if (vehicle) { - UAS* uas = vehicle->uas(); - - WaypointList* list = _lists.value(uas, NULL); - if (list) { - delete list; - _lists.remove(uas); - } - } -} - -void QGCWaypointListMulti::_vehicleAdded(Vehicle* vehicle) -{ - UAS* uas = vehicle->uas(); - - WaypointList* list = new WaypointList(_ui->stackedWidget, uas->getWaypointManager()); - _lists.insert(uas, list); - _ui->stackedWidget->addWidget(list); -} - -void QGCWaypointListMulti::_activeVehicleChanged(Vehicle* vehicle) -{ - if (vehicle) { - UAS* uas = vehicle->uas(); - - WaypointList* list = _lists.value(uas, NULL); - if (list) { - _ui->stackedWidget->setCurrentWidget(list); - } - } -} - -void QGCWaypointListMulti::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - _ui->retranslateUi(this); - break; - default: - break; - } -} diff --git a/src/ui/QGCWaypointListMulti.h b/src/ui/QGCWaypointListMulti.h deleted file mode 100644 index aad940bff..000000000 --- a/src/ui/QGCWaypointListMulti.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef QGCWAYPOINTLISTMULTI_H -#define QGCWAYPOINTLISTMULTI_H - -#include -#include - -#include "WaypointList.h" -#include "MultiVehicleManager.h" - -namespace Ui -{ -class QGCWaypointListMulti; -} - -class QGCWaypointListMulti : public QWidget -{ - Q_OBJECT - -public: - explicit QGCWaypointListMulti(QWidget *parent = 0); - ~QGCWaypointListMulti(); - -protected: - // Override from Widget - virtual void changeEvent(QEvent *e); - -private slots: - void _vehicleRemoved(Vehicle* vehicle); - void _vehicleAdded(Vehicle* vehicle); - void _activeVehicleChanged(Vehicle* vehicle); - -private: - - static void* _offlineUAS; - QMap _lists; - Ui::QGCWaypointListMulti* _ui; -}; - -#endif // QGCWAYPOINTLISTMULTI_H diff --git a/src/ui/QGCWaypointListMulti.ui b/src/ui/QGCWaypointListMulti.ui deleted file mode 100644 index 166688410..000000000 --- a/src/ui/QGCWaypointListMulti.ui +++ /dev/null @@ -1,27 +0,0 @@ - - - QGCWaypointListMulti - - - - 0 - 0 - 400 - 300 - - - - Form - - - - 0 - - - - - - - - - diff --git a/src/ui/WaypointEditableView.cc b/src/ui/WaypointEditableView.cc deleted file mode 100644 index b2ba45fed..000000000 --- a/src/ui/WaypointEditableView.cc +++ /dev/null @@ -1,623 +0,0 @@ -/*=================================================================== -======================================================================*/ - -/** - * @file - * @brief Displays one waypoint - * - * @author Lorenz Meier - * @author Benjamin Knecht - * @author Petri Tanskanen - * - */ - -#include -#include -#include - -#include -#include - -#include "WaypointEditableView.h" -#include "ui_WaypointEditableView.h" - -#include "MainWindow.h" -#include "mission/QGCMissionNavWaypoint.h" -#include "mission/QGCMissionNavLoiterUnlim.h" -#include "mission/QGCMissionNavLoiterTurns.h" -#include "mission/QGCMissionNavLoiterTime.h" -#include "mission/QGCMissionNavReturnToLaunch.h" -#include "mission/QGCMissionNavLand.h" -#include "mission/QGCMissionNavTakeoff.h" -#include "mission/QGCMissionNavSweep.h" -#include "mission/QGCMissionConditionDelay.h" -#include "mission/QGCMissionDoJump.h" -#include "mission/QGCMissionDoStartSearch.h" -#include "mission/QGCMissionDoFinishSearch.h" -#include "mission/QGCMissionOther.h" - - -WaypointEditableView::WaypointEditableView(MissionItem* wp, QWidget* parent) : - QWidget(parent), - wp(wp), - viewMode(QGC_WAYPOINTEDITABLEVIEW_MODE_DEFAULT), - m_ui(new Ui::WaypointEditableView) -{ - m_ui->setupUi(this); - connect(wp, SIGNAL(destroyed(QObject*)), this, SLOT(deleted(QObject*))); - - // CUSTOM COMMAND WIDGET - QHBoxLayout *layout = new QHBoxLayout; - layout->setSpacing(2); - layout->setContentsMargins(4, 0 ,4 ,0); - m_ui->customActionWidget->setLayout(layout); - - MissionNavWaypointWidget = NULL; - MissionNavLoiterUnlimWidget = NULL; - MissionNavLoiterTurnsWidget = NULL; - MissionNavLoiterTimeWidget = NULL; - MissionNavReturnToLaunchWidget = NULL; - MissionNavLandWidget = NULL; - MissionNavTakeoffWidget = NULL; - MissionNavSweepWidget = NULL; - MissionConditionDelayWidget = NULL; - MissionDoJumpWidget = NULL; - MissionDoStartSearchWidget = NULL; - MissionDoFinishSearchWidget = NULL; - MissionOtherWidget = NULL; - - - // add actions - m_ui->comboBox_action->addItem(tr("NAV: MissionItem"),MAV_CMD_NAV_WAYPOINT); - m_ui->comboBox_action->addItem(tr("NAV: TakeOff"),MAV_CMD_NAV_TAKEOFF); - m_ui->comboBox_action->addItem(tr("NAV: Loiter Unlim."),MAV_CMD_NAV_LOITER_UNLIM); - m_ui->comboBox_action->addItem(tr("NAV: Loiter Time"),MAV_CMD_NAV_LOITER_TIME); - m_ui->comboBox_action->addItem(tr("NAV: Loiter Turns"),MAV_CMD_NAV_LOITER_TURNS); - m_ui->comboBox_action->addItem(tr("NAV: Ret. to Launch"),MAV_CMD_NAV_RETURN_TO_LAUNCH); - m_ui->comboBox_action->addItem(tr("NAV: Land"),MAV_CMD_NAV_LAND); - //m_ui->comboBox_action->addItem(tr("NAV: Target"),MAV_CMD_NAV_TARGET); - m_ui->comboBox_action->addItem(tr("IF: Delay over"),MAV_CMD_CONDITION_DELAY); - //m_ui->comboBox_action->addItem(tr("IF: Yaw angle is"),MAV_CMD_CONDITION_YAW); - m_ui->comboBox_action->addItem(tr("DO: Jump to Index"),MAV_CMD_DO_JUMP); - m_ui->comboBox_action->addItem(tr("Other"), MAV_CMD_ENUM_END); - - // add frames - m_ui->comboBox_frame->addItem("Global/Abs. Alt",MAV_FRAME_GLOBAL); - m_ui->comboBox_frame->addItem("Global/Rel. Alt", MAV_FRAME_GLOBAL_RELATIVE_ALT); - m_ui->comboBox_frame->addItem("Local(NED)",MAV_FRAME_LOCAL_NED); - m_ui->comboBox_frame->addItem("Local Offset(NED)",MAV_FRAME_LOCAL_OFFSET_NED); - m_ui->comboBox_frame->addItem("Mission",MAV_FRAME_MISSION); - - // We do not want users to mess with the current waypoint in missions - - // they have to use the one downloaded from the MAV to change the current WP. - m_ui->selectedBox->setVisible(false); - connect(m_ui->selectedBox, SIGNAL(stateChanged(int)), this, SLOT(changedCurrent(int))); - - // Initialize view correctly - int actionID = wp->command(); - initializeActionView(actionID); - updateValues(); - updateActionView(actionID); - - // Check for mission frame - if (wp->frame() == MAV_FRAME_MISSION) - { - m_ui->comboBox_action->setCurrentIndex(m_ui->comboBox_action->count()-1); - } - - connect(m_ui->upButton, SIGNAL(clicked()), this, SLOT(moveUp())); - connect(m_ui->downButton, SIGNAL(clicked()), this, SLOT(moveDown())); - connect(m_ui->removeButton, SIGNAL(clicked()), this, SLOT(remove())); - - connect(m_ui->autoContinue, SIGNAL(stateChanged(int)), this, SLOT(changedAutoContinue(int))); - connect(m_ui->comboBox_action, SIGNAL(activated(int)), this, SLOT(changedAction(int))); - connect(m_ui->comboBox_frame, SIGNAL(activated(int)), this, SLOT(changedFrame(int))); - -} - -void WaypointEditableView::moveUp() -{ - emit moveUpWaypoint(wp); -} - -void WaypointEditableView::moveDown() -{ - emit moveDownWaypoint(wp); -} - - -void WaypointEditableView::remove() -{ - emit removeWaypoint(wp); - deleteLater(); -} - -void WaypointEditableView::changedAutoContinue(int state) -{ - if (state == 0) - wp->setAutocontinue(false); - else - wp->setAutocontinue(true); -} - -void WaypointEditableView::updateActionView(int action) -{ - //Hide all - if(MissionNavWaypointWidget) MissionNavWaypointWidget->hide(); - if(MissionNavLoiterUnlimWidget) MissionNavLoiterUnlimWidget->hide(); - if(MissionNavLoiterTurnsWidget) MissionNavLoiterTurnsWidget->hide(); - if(MissionNavLoiterTimeWidget) MissionNavLoiterTimeWidget->hide(); - if(MissionNavReturnToLaunchWidget) MissionNavReturnToLaunchWidget->hide(); - if(MissionNavLandWidget) MissionNavLandWidget->hide(); - if(MissionNavTakeoffWidget) MissionNavTakeoffWidget->hide(); - if(MissionNavSweepWidget) MissionNavSweepWidget->hide(); - if(MissionConditionDelayWidget) MissionConditionDelayWidget->hide(); - if(MissionDoJumpWidget) MissionDoJumpWidget->hide(); - if(MissionDoStartSearchWidget) MissionDoStartSearchWidget->hide(); - if(MissionDoFinishSearchWidget) MissionDoFinishSearchWidget->hide(); - if(MissionOtherWidget) MissionOtherWidget->hide(); - - //Show only the correct one - if (viewMode != QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING) - { - switch(action) { - case MAV_CMD_NAV_WAYPOINT: - if(MissionNavWaypointWidget) MissionNavWaypointWidget->show(); - break; - case MAV_CMD_NAV_LOITER_UNLIM: - if(MissionNavLoiterUnlimWidget) MissionNavLoiterUnlimWidget->show(); - break; - case MAV_CMD_NAV_LOITER_TURNS: - if(MissionNavLoiterTurnsWidget) MissionNavLoiterTurnsWidget->show(); - break; - case MAV_CMD_NAV_LOITER_TIME: - if(MissionNavLoiterTimeWidget) MissionNavLoiterTimeWidget->show(); - break; - case MAV_CMD_NAV_RETURN_TO_LAUNCH: - if(MissionNavReturnToLaunchWidget) MissionNavReturnToLaunchWidget->show(); - break; - case MAV_CMD_NAV_LAND: - if(MissionNavLandWidget) MissionNavLandWidget->show(); - break; - case MAV_CMD_NAV_TAKEOFF: - if(MissionNavTakeoffWidget) MissionNavTakeoffWidget->show(); - break; - case MAV_CMD_CONDITION_DELAY: - if(MissionConditionDelayWidget) MissionConditionDelayWidget->show(); - break; - case MAV_CMD_DO_JUMP: - if(MissionDoJumpWidget) MissionDoJumpWidget->show(); - break; - - default: - if(MissionOtherWidget) MissionOtherWidget->show(); - viewMode = QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING; - break; - } - } - else - { - if(MissionOtherWidget) MissionOtherWidget->show(); - } -} - -/** - * @param index The index of the combo box of the action entry, NOT the action ID - */ -void WaypointEditableView::changedAction(int index) -{ - // set waypoint action - int actionID = m_ui->comboBox_action->itemData(index).toUInt(); - if (actionID == QVariant::Invalid || actionID == MAV_CMD_ENUM_END) - { - viewMode = QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING; - } - else //(actionID < MAV_CMD_ENUM_END && actionID >= 0) - { - viewMode = QGC_WAYPOINTEDITABLEVIEW_MODE_DEFAULT; - MAV_CMD action = (MAV_CMD) actionID; - wp->setAction(action); - } - // change the view - initializeActionView(actionID); - updateValues(); - updateActionView(actionID); -} - -void WaypointEditableView::initializeActionView(int actionID) -{ - //initialize a new action-widget, if needed. - switch(actionID) { - case MAV_CMD_NAV_WAYPOINT: - if (!MissionNavWaypointWidget) - { - MissionNavWaypointWidget = new QGCMissionNavWaypoint(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavWaypointWidget); - } - break; - case MAV_CMD_NAV_LOITER_UNLIM: - if (!MissionNavLoiterUnlimWidget) - { - MissionNavLoiterUnlimWidget = new QGCMissionNavLoiterUnlim(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavLoiterUnlimWidget); - } - break; - case MAV_CMD_NAV_LOITER_TURNS: - if (!MissionNavLoiterTurnsWidget) - { - MissionNavLoiterTurnsWidget = new QGCMissionNavLoiterTurns(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavLoiterTurnsWidget); - } - break; - case MAV_CMD_NAV_LOITER_TIME: - if (!MissionNavLoiterTimeWidget) - { - MissionNavLoiterTimeWidget = new QGCMissionNavLoiterTime(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavLoiterTimeWidget); - } - break; - case MAV_CMD_NAV_RETURN_TO_LAUNCH: - if (!MissionNavReturnToLaunchWidget) - { - MissionNavReturnToLaunchWidget = new QGCMissionNavReturnToLaunch(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavReturnToLaunchWidget); - } - break; - case MAV_CMD_NAV_LAND: - if (!MissionNavLandWidget) - { - MissionNavLandWidget = new QGCMissionNavLand(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavLandWidget); - } - break; - case MAV_CMD_NAV_TAKEOFF: - if (!MissionNavTakeoffWidget) - { - MissionNavTakeoffWidget = new QGCMissionNavTakeoff(this); - m_ui->customActionWidget->layout()->addWidget(MissionNavTakeoffWidget); - } - break; - case MAV_CMD_CONDITION_DELAY: - if (!MissionConditionDelayWidget) - { - MissionConditionDelayWidget = new QGCMissionConditionDelay(this); - m_ui->customActionWidget->layout()->addWidget(MissionConditionDelayWidget); - } - break; - case MAV_CMD_DO_JUMP: - if (!MissionDoJumpWidget) - { - MissionDoJumpWidget = new QGCMissionDoJump(this); - m_ui->customActionWidget->layout()->addWidget(MissionDoJumpWidget); - } - break; - case MAV_CMD_ENUM_END: - default: - if (!MissionOtherWidget) - { - MissionOtherWidget = new QGCMissionOther(this); - m_ui->customActionWidget->layout()->addWidget(MissionOtherWidget); - } - break; - } -} - -void WaypointEditableView::deleted(QObject* waypoint) -{ - // Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already - // been destroyed. - - Q_UNUSED(waypoint); -} - -void WaypointEditableView::changedFrame(int index) -{ - // set waypoint action - MAV_FRAME frame = (MAV_FRAME)m_ui->comboBox_frame->itemData(index).toUInt(); - wp->setFrame(frame); -} - -void WaypointEditableView::changedCurrent(int state) -{ - if (state == 0) - { - if (wp->isCurrentItem() == true) //User clicked on the waypoint, that is already current - { - m_ui->selectedBox->setChecked(true); - m_ui->selectedBox->setCheckState(Qt::Checked); - } - else - { - m_ui->selectedBox->setChecked(false); - m_ui->selectedBox->setCheckState(Qt::Unchecked); - } - } - else - { - wp->setIsCurrentItem(true); - // At this point we do not consider this signal - // to be valid / the edit check boxes should not change the view state - //emit changeCurrentWaypoint(wp->sequenceNumber()); - //the slot changeCurrentWaypoint() in WaypointList sets all other current flags to false - } -} - -void WaypointEditableView::updateValues() -{ - // Check if we just lost the wp, delete the widget - // accordingly - if (!wp) { - deleteLater(); - return; - } - - //wp->blockSignals(true); - - // Deactivate all QDoubleSpinBox signals due to - // unwanted rounding effects - for (int j = 0; j < children().size(); ++j) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(children().at(j)); - if (spin) - { - //qDebug() << "DEACTIVATED SPINBOX #" << j; - spin->blockSignals(true); - } - else - { - // Store only QGCToolWidgetItems - QWidget* item = dynamic_cast(children().at(j)); - if (item) - { - //qDebug() << "FOUND WIDGET BOX"; - for (int k = 0; k < item->children().size(); ++k) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(item->children().at(k)); - if (spin) - { - //qDebug() << "DEACTIVATED SPINBOX #" << k; - spin->blockSignals(true); - } - } - } - } - } - - // Block all custom action widget actions - for (int j = 0; j < m_ui->customActionWidget->children().size(); ++j) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(m_ui->customActionWidget->children().at(j)); - if (spin) - { - //qDebug() << "DEACTIVATED SPINBOX #" << j; - spin->blockSignals(true); - } - else - { - // Store only QGCToolWidgetItems - QWidget* item = dynamic_cast(m_ui->customActionWidget->children().at(j)); - if (item) - { - //qDebug() << "CUSTOM ACTIONS FOUND WIDGET BOX"; - for (int k = 0; k < item->children().size(); ++k) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(item->children().at(k)); - if (spin) - { - //qDebug() << "DEACTIVATED SPINBOX #" << k; - spin->blockSignals(true); - } - } - } - } - } - - - // update frame - MAV_FRAME frame = (MAV_FRAME)wp->frame(); - int frame_index = m_ui->comboBox_frame->findData(frame); - if (m_ui->comboBox_frame->currentIndex() != frame_index) { - m_ui->comboBox_frame->setCurrentIndex(frame_index); - } - - // Update action - MAV_CMD action = (MAV_CMD)wp->command(); - int action_index = m_ui->comboBox_action->findData(action); - if (m_ui->comboBox_action->currentIndex() != action_index) - { - if (viewMode != QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING) - { - // Set to "Other" action if it was -1 - if (action_index == -1) - { - action_index = m_ui->comboBox_action->findData(MAV_CMD_ENUM_END); - viewMode = QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING; - } - m_ui->comboBox_action->setCurrentIndex(action_index); - } - } - - emit commandBroadcast(wp->command()); - emit frameBroadcast((MAV_FRAME)wp->frame()); - emit param1Broadcast(wp->param1()); - emit param2Broadcast(wp->param2()); - emit param3Broadcast(wp->param3()); - emit param4Broadcast(wp->param4()); - emit param5Broadcast(wp->param5()); - emit param6Broadcast(wp->param6()); - emit param7Broadcast(wp->param7()); - - - if (m_ui->selectedBox->isChecked() != wp->isCurrentItem()) - { - // This is never a reason to emit a changed signal - m_ui->selectedBox->blockSignals(true); - m_ui->selectedBox->setChecked(wp->isCurrentItem()); - m_ui->selectedBox->blockSignals(false); - } - if (m_ui->autoContinue->isChecked() != wp->autoContinue()) - { - m_ui->autoContinue->setChecked(wp->autoContinue()); - } - - m_ui->idLabel->setText(QString::number(wp->sequenceNumber())); - - // Style alternating rows of Missions as lighter/darker. - static int lastId = -1; - int currId = wp->sequenceNumber() % 2; - if (currId != lastId) - { - if (currId == 1) - { - this->setProperty("RowColoring", "odd"); - } - else - { - this->setProperty("RowColoring", "even"); - } - lastId = currId; - } - - // Activate all QDoubleSpinBox signals due to - // unwanted rounding effects - for (int j = 0; j < children().size(); ++j) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(children().at(j)); - if (spin) - { - //qDebug() << "ACTIVATED SPINBOX #" << j; - spin->blockSignals(false); - } - else - { - // Store only QGCToolWidgetItems - QGroupBox* item = dynamic_cast(children().at(j)); - if (item) - { - //qDebug() << "FOUND GROUP BOX"; - for (int k = 0; k < item->children().size(); ++k) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(item->children().at(k)); - if (spin) - { - //qDebug() << "ACTIVATED SPINBOX #" << k; - spin->blockSignals(false); - } - } - } - } - } - - // Unblock all custom action widget actions - for (int j = 0; j < m_ui->customActionWidget->children().size(); ++j) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(m_ui->customActionWidget->children().at(j)); - if (spin) - { - //qDebug() << "ACTIVATED SPINBOX #" << j; - spin->blockSignals(false); - } - else - { - // Store only QGCToolWidgetItems - QWidget* item = dynamic_cast(m_ui->customActionWidget->children().at(j)); - if (item) - { - //qDebug() << "FOUND WIDGET BOX"; - for (int k = 0; k < item->children().size(); ++k) - { - // Store only QGCToolWidgetItems - QDoubleSpinBox* spin = dynamic_cast(item->children().at(k)); - if (spin) - { - //qDebug() << "ACTIVATED SPINBOX #" << k; - spin->blockSignals(false); - } - } - } - } - } - -// wp->blockSignals(false); -} - -void WaypointEditableView::setCurrent(bool state) -{ - if (m_ui->selectedBox->isChecked() != state) - { - m_ui->selectedBox->blockSignals(true); - m_ui->selectedBox->setChecked(state); - m_ui->selectedBox->blockSignals(false); - } -} - - -void WaypointEditableView::changedCommand(int mav_cmd_id) -{ - if (mav_cmd_idsetAction(mav_cmd_id); - } -} -void WaypointEditableView::changedParam1(double value) -{ - wp->setParam1(value); -} -void WaypointEditableView::changedParam2(double value) -{ - wp->setParam2(value); -} -void WaypointEditableView::changedParam3(double value) -{ - wp->setParam3(value); -} -void WaypointEditableView::changedParam4(double value) -{ - wp->setParam4(value); -} -void WaypointEditableView::changedParam5(double value) -{ - wp->setParam5(value); -} -void WaypointEditableView::changedParam6(double value) -{ - wp->setParam6(value); -} -void WaypointEditableView::changedParam7(double value) -{ - wp->setParam7(value); -} - -WaypointEditableView::~WaypointEditableView() -{ - delete m_ui; -} - -void WaypointEditableView::changeEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::LanguageChange: - m_ui->retranslateUi(this); - break; - default: - break; - } -} - -/** - * Implement paintEvent() so that stylesheets work for our custom widget. - */ -void WaypointEditableView::paintEvent(QPaintEvent *) - { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - } diff --git a/src/ui/WaypointEditableView.h b/src/ui/WaypointEditableView.h deleted file mode 100644 index efd8685e0..000000000 --- a/src/ui/WaypointEditableView.h +++ /dev/null @@ -1,141 +0,0 @@ -/*=================================================================== -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief Displays one waypoint - * - * @author Lorenz Meier - * @author Benjamin Knecht - * @author Petri Tanskanen - * @author Alex Trofimov - */ - -#ifndef WAYPOINTEDITABLEVIEW_H -#define WAYPOINTEDITABLEVIEW_H - -#include -#include "MissionItem.h" -#include - -enum QGC_WAYPOINTEDITABLEVIEW_MODE { - QGC_WAYPOINTEDITABLEVIEW_MODE_DEFAULT, - QGC_WAYPOINTEDITABLEVIEW_MODE_DIRECT_EDITING -}; - -namespace Ui -{ -class WaypointEditableView; -} -class QGCMissionNavWaypoint; -class QGCMissionNavLoiterUnlim; -class QGCMissionNavLoiterTurns; -class QGCMissionNavLoiterTime; -class QGCMissionNavReturnToLaunch; -class QGCMissionNavLand; -class QGCMissionNavTakeoff; -class QGCMissionNavSweep; -class QGCMissionDoJump; -class QGCMissionDoStartSearch; -class QGCMissionDoFinishSearch; -class QGCMissionConditionDelay; -class QGCMissionOther; - -class WaypointEditableView : public QWidget -{ - Q_OBJECT - Q_DISABLE_COPY(WaypointEditableView) -public: - explicit WaypointEditableView(MissionItem* wp, QWidget* parent); - virtual ~WaypointEditableView(); - -public: - void setCurrent(bool state); - -public slots: - void moveUp(); - void moveDown(); - void remove(); - /** @brief MissionItem matching this widget has been deleted */ - void deleted(QObject* waypoint); - void changedAutoContinue(int); - void changedFrame(int state); - void updateActionView(int action); - void initializeActionView(int action); - - void changedCurrent(int); - void updateValues(void); - void changedAction(int state); //change commandID, including the view - void changedCommand(int mav_cmd_id); //only update WP->command, but do not change the view. Should only be used for "other" waypoint-type. - void changedParam1(double value); - void changedParam2(double value); - void changedParam3(double value); - void changedParam4(double value); - void changedParam5(double value); - void changedParam6(double value); - void changedParam7(double value); - -protected slots: - -protected: - virtual void changeEvent(QEvent *e); - virtual void paintEvent(QPaintEvent *); - MissionItem* wp; - QGC_WAYPOINTEDITABLEVIEW_MODE viewMode; - // Widgets for every mission element - QGCMissionNavWaypoint* MissionNavWaypointWidget; - QGCMissionNavLoiterUnlim* MissionNavLoiterUnlimWidget; - QGCMissionNavLoiterTurns* MissionNavLoiterTurnsWidget; - QGCMissionNavLoiterTime* MissionNavLoiterTimeWidget; - QGCMissionNavReturnToLaunch* MissionNavReturnToLaunchWidget; - QGCMissionNavLand* MissionNavLandWidget; - QGCMissionNavTakeoff* MissionNavTakeoffWidget; - QGCMissionNavSweep* MissionNavSweepWidget; - QGCMissionDoJump* MissionDoJumpWidget; - QGCMissionDoStartSearch* MissionDoStartSearchWidget; - QGCMissionDoFinishSearch* MissionDoFinishSearchWidget; - QGCMissionConditionDelay* MissionConditionDelayWidget; - QGCMissionOther* MissionOtherWidget; - - -private: - Ui::WaypointEditableView *m_ui; - -signals: - void moveUpWaypoint(MissionItem*); - void moveDownWaypoint(MissionItem*); - void removeWaypoint(MissionItem*); - void changeCurrentWaypoint(quint16); - void setYaw(double); - - void commandBroadcast(int mav_cmd_id); - void frameBroadcast(MAV_FRAME frame); - void param1Broadcast(double value); - void param2Broadcast(double value); - void param3Broadcast(double value); - void param4Broadcast(double value); - void param5Broadcast(double value); - void param6Broadcast(double value); - void param7Broadcast(double value); -}; - -#endif // WAYPOINTEDITABLEVIEW_H diff --git a/src/ui/WaypointEditableView.ui b/src/ui/WaypointEditableView.ui deleted file mode 100644 index 7156a0ce1..000000000 --- a/src/ui/WaypointEditableView.ui +++ /dev/null @@ -1,290 +0,0 @@ - - - WaypointEditableView - - - - 0 - 0 - 585 - 45 - - - - - 0 - 0 - - - - - 200 - 0 - - - - Form - - - - - - - 6 - - - 6 - - - 6 - - - 6 - - - - - - 0 - 0 - - - - - 25 - 0 - - - - Waypoint Sequence Number - - - ID - - - Qt::AlignCenter - - - - - - - false - - - - 0 - 0 - - - - - 20 - 0 - - - - Qt::TabFocus - - - Mission Start - - - Mission Start - - - - - - - 16 - 16 - - - - - - - - - 0 - 0 - - - - - 100 - 16777215 - - - - Coordinate frame - - - Coordinate frame - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 120 - 16777215 - - - - Action at Waypoint - - - Action at Waypoint - - - QComboBox::AdjustToContentsOnFirstShow - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - - - - - - 0 - 0 - - - - Automatically continue after this waypoint - - - Automatically continue after this waypoint - - - - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Move Up in List - - - Move Up in List - - - - - - - :/res/UpArrow:/res/UpArrow - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Move Down in List - - - Move Down in List - - - - - - - :/res/DownArrow:/res/DownArrow - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - Qt::NoFocus - - - Delete - - - - - - - :/res/MinusSign:/res/MinusSign - - - - - - - - - - diff --git a/src/ui/WaypointList.cc b/src/ui/WaypointList.cc deleted file mode 100644 index f47cf7dcf..000000000 --- a/src/ui/WaypointList.cc +++ /dev/null @@ -1,702 +0,0 @@ -/*===================================================================== - -PIXHAWK Micro Air Vehicle Flying Robotics Toolkit - -(c) 2009, 2010 PIXHAWK PROJECT - -This file is part of the PIXHAWK project - - PIXHAWK 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. - - PIXHAWK 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 PIXHAWK. If not, see . - -======================================================================*/ - -/** - * @file - * @brief Waypoint list widget - * - * @author Lorenz Meier - * @author Benjamin Knecht - * @author Petri Tanskanen - * - */ - -#include "WaypointList.h" -#include "ui_WaypointList.h" -#include "QGCFileDialog.h" - -#include -#include -#include -#include -#include -#include - -WaypointList::WaypointList(QWidget *parent, UASWaypointManager* wpm) : - QWidget(parent), - uas(NULL), - WPM(wpm), - mavX(0.0), - mavY(0.0), - mavZ(0.0), - mavYaw(0.0), - showOfflineWarning(false), - m_ui(new Ui::WaypointList) -{ - - m_ui->setupUi(this); - - //EDIT TAB - - editableListLayout = new QVBoxLayout(m_ui->editableListWidget); - editableListLayout->setSpacing(0); - editableListLayout->setMargin(0); - editableListLayout->setAlignment(Qt::AlignTop); - m_ui->editableListWidget->setLayout(editableListLayout); - - // ADD WAYPOINT - // Connect add action, set right button icon and connect action to this class - connect(m_ui->addButton, SIGNAL(clicked()), m_ui->actionAddWaypoint, SIGNAL(triggered())); - connect(m_ui->actionAddWaypoint, SIGNAL(triggered()), this, SLOT(addEditable())); - - // ADD WAYPOINT AT CURRENT POSITION - connect(m_ui->positionAddButton, SIGNAL(clicked()), this, SLOT(addCurrentPositionWaypoint())); - - // SEND WAYPOINTS - connect(m_ui->transmitButton, SIGNAL(clicked()), this, SLOT(transmit())); - - // DELETE ALL WAYPOINTS - connect(m_ui->clearWPListButton, SIGNAL(clicked()), this, SLOT(clearWPWidget())); - - // REQUEST WAYPOINTS - connect(m_ui->readButton, SIGNAL(clicked()), this, SLOT(read())); - - // SAVE/LOAD WAYPOINTS - connect(m_ui->saveButton, SIGNAL(clicked()), this, SLOT(saveWaypoints())); - connect(m_ui->loadButton, SIGNAL(clicked()), this, SLOT(loadWaypoints())); - - //VIEW TAB - - viewOnlyListLayout = new QVBoxLayout(m_ui->viewOnlyListWidget); - viewOnlyListLayout->setSpacing(0); - viewOnlyListLayout->setMargin(0); - viewOnlyListLayout->setAlignment(Qt::AlignTop); - m_ui->viewOnlyListWidget->setLayout(viewOnlyListLayout); - - // REFRESH VIEW TAB - - connect(m_ui->refreshButton, SIGNAL(clicked()), this, SLOT(refresh())); - - if (WPM) { - // SET UAS AFTER ALL SIGNALS/SLOTS ARE CONNECTED - if (!WPM->getUAS()) - { - // Disable buttons which don't make sense without valid UAS. - m_ui->positionAddButton->setEnabled(false); - m_ui->transmitButton->setEnabled(false); - m_ui->readButton->setEnabled(false); - m_ui->refreshButton->setEnabled(false); - - //FIXME: The whole "Onboard Waypoints"-tab should be hidden, instead of "refresh" button - // Insert a "NO UAV" info into the Onboard Tab - QLabel* noUas = new QLabel(this); - noUas->setObjectName("noUas"); - noUas->setText("NO UAS"); - noUas->setEnabled(false); - noUas->setAlignment(Qt::AlignCenter); - viewOnlyListLayout->insertWidget(0, noUas); - - showOfflineWarning = true; - } else { - setUAS(static_cast(WPM->getUAS())); - } - - /* connect slots */ - connect(WPM, SIGNAL(updateStatusString(const QString &)), this, SLOT(updateStatusLabel(const QString &))); - connect(WPM, SIGNAL(waypointEditableListChanged(void)), this, SLOT(waypointEditableListChanged(void))); - connect(WPM, SIGNAL(waypointEditableChanged(int,MissionItem*)), this, SLOT(updateWaypointEditable(int,MissionItem*))); - connect(WPM, SIGNAL(waypointViewOnlyListChanged(void)), this, SLOT(waypointViewOnlyListChanged(void))); - connect(WPM, SIGNAL(waypointViewOnlyChanged(int,MissionItem*)), this, SLOT(updateWaypointViewOnly(int,MissionItem*))); - connect(WPM, SIGNAL(currentWaypointChanged(quint16)), this, SLOT(currentWaypointViewOnlyChanged(quint16))); - - //Even if there are no waypoints, since this is a new instance and there is an - //existing WPM, then we need to assume things have changed, and act appropriatly. - waypointEditableListChanged(); - waypointViewOnlyListChanged(); - } - - // STATUS LABEL - updateStatusLabel(""); - - this->setVisible(false); - loadFileGlobalWP = false; - readGlobalWP = false; - centerMapCoordinate.setX(0.0); - centerMapCoordinate.setY(0.0); - -} - -WaypointList::~WaypointList() -{ - delete m_ui; -} - -void WaypointList::updatePosition(UASInterface* uas, double x, double y, double z, quint64 usec) -{ - Q_UNUSED(uas); - Q_UNUSED(usec); - mavX = x; - mavY = y; - mavZ = z; -} - -void WaypointList::updateAttitude(UASInterface* uas, double roll, double pitch, double yaw, quint64 usec) -{ - Q_UNUSED(uas); - Q_UNUSED(usec); - Q_UNUSED(roll); - Q_UNUSED(pitch); - mavYaw = yaw; -} - -void WaypointList::setUAS(UASInterface* uas) -{ - if (!uas) - return; - - if (this->uas != NULL) - { - // Clear current list - on_clearWPListButton_clicked(); - // Disconnect everything - disconnect(WPM, SIGNAL(updateStatusString(const QString &)), this, SLOT(updateStatusLabel(const QString &))); - disconnect(WPM, SIGNAL(waypointEditableListChanged(void)), this, SLOT(waypointEditableListChanged(void))); - disconnect(WPM, SIGNAL(waypointEditableChanged(int,MissionItem*)), this, SLOT(updateWaypointEditable(int,MissionItem*))); - disconnect(WPM, SIGNAL(waypointViewOnlyListChanged(void)), this, SLOT(waypointViewOnlyListChanged(void))); - disconnect(WPM, SIGNAL(waypointViewOnlyChanged(int,MissionItem*)), this, SLOT(updateWaypointViewOnly(int,MissionItem*))); - disconnect(WPM, SIGNAL(currentWaypointChanged(quint16)), this, SLOT(currentWaypointViewOnlyChanged(quint16))); - disconnect(this->uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updatePosition(UASInterface*,double,double,double,quint64))); - disconnect(this->uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); - } - - // Now that there's a valid UAS, enable the UI. - m_ui->positionAddButton->setEnabled(true); - m_ui->transmitButton->setEnabled(true); - m_ui->readButton->setEnabled(true); - m_ui->refreshButton->setEnabled(true); - - WPM = uas->getWaypointManager(); - - this->uas = uas; - connect(WPM, SIGNAL(updateStatusString(const QString &)), this, SLOT(updateStatusLabel(const QString &))); - connect(WPM, SIGNAL(waypointEditableListChanged(void)), this, SLOT(waypointEditableListChanged(void))); - connect(WPM, SIGNAL(waypointEditableChanged(int,MissionItem*)), this, SLOT(updateWaypointEditable(int,MissionItem*))); - connect(WPM, SIGNAL(waypointViewOnlyListChanged(void)), this, SLOT(waypointViewOnlyListChanged(void))); - connect(WPM, SIGNAL(waypointViewOnlyChanged(int,MissionItem*)), this, SLOT(updateWaypointViewOnly(int,MissionItem*))); - connect(WPM, SIGNAL(currentWaypointChanged(quint16)), this, SLOT(currentWaypointViewOnlyChanged(quint16))); - connect(uas, SIGNAL(localPositionChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updatePosition(UASInterface*,double,double,double,quint64))); - connect(uas, SIGNAL(attitudeChanged(UASInterface*,double,double,double,quint64)), this, SLOT(updateAttitude(UASInterface*,double,double,double,quint64))); - //connect(WPM,SIGNAL(loadWPFile()),this,SLOT(setIsLoadFileWP())); - //connect(WPM,SIGNAL(readGlobalWPFromUAS(bool)),this,SLOT(setIsReadGlobalWP(bool))); - - // Update list - read(); -} - -void WaypointList::saveWaypoints() -{ - // TODO Need better default directory - QString fileName = QGCFileDialog::getSaveFileName(this, tr("Save Waypoint File"), "./untitled.waypoints", tr("Waypoint Files (*.waypoints)"), "waypoints", true); - WPM->saveWaypoints(fileName); -} - -void WaypointList::loadWaypoints() -{ - // TODO Need better default directory - QString fileName = QGCFileDialog::getOpenFileName(this, tr("Load Waypoint File"), ".", tr("Waypoint Files (*.waypoints);;All Files (*)")); - WPM->loadWaypoints(fileName); -} - -void WaypointList::transmit() -{ - if (uas) - { - WPM->writeWaypoints(); - } -} - -void WaypointList::read() -{ - if (uas) - { - WPM->readWaypoints(true); - } -} - -void WaypointList::refresh() -{ - if (uas) - { - WPM->readWaypoints(false); - } -} - -void WaypointList::addEditable() -{ - addEditable(false); -} - -void WaypointList::addEditable(bool onCurrentPosition) -{ - - const QList &waypoints = WPM->getWaypointEditableList(); - MissionItem *wp; - if (waypoints.count() > 0 && - !(onCurrentPosition && uas && (uas->localPositionKnown() || uas->globalPositionKnown()))) - { - // Create waypoint with last frame - MissionItem *last = waypoints.last(); - wp = WPM->createWaypoint(); -// wp->blockSignals(true); - MAV_FRAME frame = (MAV_FRAME)last->frame(); - wp->setFrame(frame); - if (frame == MAV_FRAME_GLOBAL || frame == MAV_FRAME_GLOBAL_RELATIVE_ALT) - { - wp->setLatitude(last->latitude()); - wp->setLongitude(last->longitude()); - wp->setAltitude(last->altitude()); - } else { - wp->setX(last->x()); - wp->setY(last->y()); - wp->setZ(last->z()); - } - wp->setParam1(last->param1()); - wp->setParam2(last->param2()); - wp->setParam3(last->param3()); - wp->setParam4(last->param4()); - wp->setAutocontinue(last->autoContinue()); -// wp->blockSignals(false); - wp->setAction(last->command()); -// WPM->addWaypointEditable(wp); - } - else - { - if (uas) - { - // Create first waypoint at current MAV position - if (uas->globalPositionKnown()) - { - if (onCurrentPosition) - { - - if (WPM->getFrameRecommendation() == MAV_FRAME_GLOBAL) { - updateStatusLabel(tr("Added default GLOBAL (Abs alt.) waypoint.")); - } else { - updateStatusLabel(tr("Added default GLOBAL (Relative alt.) waypoint.")); - } - wp = new MissionItem(NULL, - 0, - QGeoCoordinate(uas->getLatitude(), uas->getLongitude(), uas->getAltitudeAMSL()), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - (MAV_FRAME)WPM->getFrameRecommendation()); - WPM->addWaypointEditable(wp); - - } else { - - if (WPM->getFrameRecommendation() == MAV_FRAME_GLOBAL) { - updateStatusLabel(tr("Added default GLOBAL (Abs alt.) waypoint.")); - } else { - updateStatusLabel(tr("Added default GLOBAL (Relative alt.) waypoint.")); - } - wp = new MissionItem(NULL, - 0, - QGeoCoordinate(HomePositionManager::instance()->getHomeLatitude(), HomePositionManager::instance()->getHomeLongitude(), WPM->getAltitudeRecommendation()), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - (MAV_FRAME)WPM->getFrameRecommendation()); - WPM->addWaypointEditable(wp); - } - } - else if (uas->localPositionKnown()) - { - if (onCurrentPosition) - { - updateStatusLabel(tr("Added default LOCAL (NED) waypoint.")); - wp = new MissionItem(NULL, - 0, - QGeoCoordinate(uas->getLocalX(), uas->getLocalY(), uas->getLocalZ()), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - MAV_FRAME_LOCAL_NED); - WPM->addWaypointEditable(wp); - } else { - updateStatusLabel(tr("Added default LOCAL (NED) waypoint.")); - wp = new MissionItem(0, - 0, - QGeoCoordinate(0, 0, -0.50), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - MAV_FRAME_LOCAL_NED); - WPM->addWaypointEditable(wp); - } - } - else - { - // MAV connected, but position unknown, add default waypoint - updateStatusLabel(tr("WARNING: No position known. Adding default LOCAL (NED) waypoint")); - wp = new MissionItem(NULL, - 0, - QGeoCoordinate(HomePositionManager::instance()->getHomeLatitude(), HomePositionManager::instance()->getHomeLongitude(), WPM->getAltitudeRecommendation()), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - (MAV_FRAME)WPM->getFrameRecommendation()); - WPM->addWaypointEditable(wp); - } - } - else - { - //Since no UAV available, create first default waypoint. - updateStatusLabel(tr("No UAV connected. Adding default GLOBAL (NED) waypoint")); - wp = new MissionItem(NULL, - 0, - QGeoCoordinate(HomePositionManager::instance()->getHomeLatitude(), HomePositionManager::instance()->getHomeLongitude(), WPM->getAltitudeRecommendation()), - MAV_CMD_NAV_WAYPOINT, - 0, - WPM->getAcceptanceRadiusRecommendation(), - 0, - 0, - true, - true, - (MAV_FRAME)WPM->getFrameRecommendation()); - WPM->addWaypointEditable(wp); - } - } -} - -void WaypointList::addCurrentPositionWaypoint() { - addEditable(true); -} - -void WaypointList::updateStatusLabel(const QString &string) -{ - // Status label in write widget - m_ui->statusLabel->setText(string); - // Status label in read only widget - m_ui->viewStatusLabel->setText(string); -} - -// Request UASWaypointManager to send the SET_CURRENT message to UAV -void WaypointList::changeCurrentWaypoint(quint16 seq) -{ - if (uas) - { - WPM->setCurrentWaypoint(seq); - } -} - -// Request UASWaypointManager to set the new "current" and make sure all other waypoints are not "current" -void WaypointList::currentWaypointEditableChanged(quint16 seq) -{ - WPM->setCurrentEditable(seq); - const QList waypoints = WPM->getWaypointEditableList(); - - if (seq < waypoints.count()) - { - for(int i = 0; i < waypoints.count(); i++) - { - WaypointEditableView* widget = wpEditableViews.value(waypoints[i], NULL); - - if (widget) { - if (waypoints[i]->sequenceNumber() == seq) - { - widget->setCurrent(true); - } - else - { - widget->setCurrent(false); - } - } - } - } -} - -// Update waypointViews to correctly indicate the new current waypoint -void WaypointList::currentWaypointViewOnlyChanged(quint16 seq) -{ - // First update the edit list - currentWaypointEditableChanged(seq); - - const QList waypoints = WPM->getWaypointViewOnlyList(); - - if (seq < waypoints.count()) - { - for(int i = 0; i < waypoints.count(); i++) - { - WaypointViewOnlyView* widget = wpViewOnlyViews.value(waypoints[i], NULL); - - if (widget) { - if (waypoints[i]->sequenceNumber() == seq) - { - widget->setCurrent(true); - } - else - { - widget->setCurrent(false); - } - } - } - } -} - -void WaypointList::updateWaypointEditable(int uas, MissionItem* wp) -{ - Q_UNUSED(uas); - WaypointEditableView *wpv = wpEditableViews.value(wp, NULL); - if (wpv) { - wpv->updateValues(); - } - m_ui->tabWidget->setCurrentIndex(0); // XXX magic number -} - -void WaypointList::updateWaypointViewOnly(int uas, MissionItem* wp) -{ - Q_UNUSED(uas); - WaypointViewOnlyView *wpv = wpViewOnlyViews.value(wp, NULL); - if (wpv) { - wpv->updateValues(); - } - m_ui->tabWidget->setCurrentIndex(1); // XXX magic number -} - -void WaypointList::waypointViewOnlyListChanged() -{ - // Prevent updates to prevent visual flicker - this->setUpdatesEnabled(false); - const QList &waypoints = WPM->getWaypointViewOnlyList(); - - if (!wpViewOnlyViews.empty()) { - QMapIterator viewIt(wpViewOnlyViews); - viewIt.toFront(); - while(viewIt.hasNext()) { - viewIt.next(); - MissionItem *cur = viewIt.key(); - int i; - for (i = 0; i < waypoints.count(); i++) { - if (waypoints[i] == cur) { - break; - } - } - if (i == waypoints.count()) { - WaypointViewOnlyView* widget = wpViewOnlyViews.value(cur, NULL); - if (widget) { - widget->hide(); - viewOnlyListLayout->removeWidget(widget); - wpViewOnlyViews.remove(cur); - } - } - } - } - - // then add/update the views for each waypoint in the list - for(int i = 0; i < waypoints.count(); i++) { - MissionItem *wp = waypoints[i]; - if (!wpViewOnlyViews.contains(wp)) { - WaypointViewOnlyView* wpview = new WaypointViewOnlyView(wp, this); - wpViewOnlyViews.insert(wp, wpview); - connect(wpview, SIGNAL(changeCurrentWaypoint(quint16)), this, SLOT(changeCurrentWaypoint(quint16))); - viewOnlyListLayout->insertWidget(i, wpview); - } - WaypointViewOnlyView *wpv = wpViewOnlyViews.value(wp); - - //check if ordering has changed - if(viewOnlyListLayout->itemAt(i)->widget() != wpv) { - viewOnlyListLayout->removeWidget(wpv); - viewOnlyListLayout->insertWidget(i, wpv); - } - - wpv->updateValues(); // update the values of the ui elements in the view - } - this->setUpdatesEnabled(true); - loadFileGlobalWP = false; - - m_ui->tabWidget->setCurrentIndex(1); - -} - - -void WaypointList::waypointEditableListChanged() -{ - // Prevent updates to prevent visual flicker - this->setUpdatesEnabled(false); - const QList &waypoints = WPM->getWaypointEditableList(); - - if (!wpEditableViews.empty()) { - QMapIterator viewIt(wpEditableViews); - viewIt.toFront(); - while(viewIt.hasNext()) { - viewIt.next(); - MissionItem *cur = viewIt.key(); - int i; - for (i = 0; i < waypoints.count(); i++) { - if (waypoints[i] == cur) { - break; - } - } - if (i == waypoints.count()) { - WaypointEditableView* widget = wpEditableViews.value(cur, NULL); - - if (widget) { - widget->hide(); - editableListLayout->removeWidget(widget); - wpEditableViews.remove(cur); - } - } - } - } - - // then add/update the views for each waypoint in the list - for(int i = 0; i < waypoints.count(); i++) { - MissionItem *wp = waypoints[i]; - if (!wpEditableViews.contains(wp)) { - WaypointEditableView* wpview = new WaypointEditableView(wp, this); - wpEditableViews.insert(wp, wpview); - connect(wpview, SIGNAL(moveDownWaypoint(MissionItem*)), this, SLOT(moveDown(MissionItem*))); - connect(wpview, SIGNAL(moveUpWaypoint(MissionItem*)), this, SLOT(moveUp(MissionItem*))); - connect(wpview, SIGNAL(removeWaypoint(MissionItem*)), this, SLOT(removeWaypoint(MissionItem*))); - //connect(wpview, SIGNAL(currentWaypointChanged(quint16)), this, SLOT(currentWaypointChanged(quint16))); - connect(wpview, SIGNAL(changeCurrentWaypoint(quint16)), this, SLOT(currentWaypointEditableChanged(quint16))); - editableListLayout->insertWidget(i, wpview); - } - WaypointEditableView *wpv = wpEditableViews.value(wp); - - //check if ordering has changed - if(editableListLayout->itemAt(i)->widget() != wpv) { - editableListLayout->removeWidget(wpv); - editableListLayout->insertWidget(i, wpv); - } - - wpv->updateValues(); // update the values of the ui elements in the view - } - this->setUpdatesEnabled(true); - loadFileGlobalWP = false; - -} - -void WaypointList::moveUp(MissionItem* wp) -{ - const QList &waypoints = WPM->getWaypointEditableList(); - - //get the current position of wp in the local storage - int i; - for (i = 0; i < waypoints.count(); i++) { - if (waypoints[i] == wp) - break; - } - - // if wp was found and its not the first entry, move it - if (i < waypoints.count() && i > 0) { - WPM->moveWaypoint(i, i-1); - } -} - -void WaypointList::moveDown(MissionItem* wp) -{ - const QList &waypoints = WPM->getWaypointEditableList(); - - //get the current position of wp in the local storage - int i; - for (i = 0; i < waypoints.count(); i++) { - if (waypoints[i] == wp) - break; - } - - // if wp was found and its not the last entry, move it - if (i < waypoints.count()-1) { - WPM->moveWaypoint(i, i+1); - } -} - -void WaypointList::removeWaypoint(MissionItem* wp) -{ - WPM->removeWaypoint(wp->sequenceNumber()); -} - -void WaypointList::changeEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::LanguageChange: - m_ui->retranslateUi(this); - break; - default: - break; - } -} - - - -void WaypointList::on_clearWPListButton_clicked() -{ - if (uas) { - emit clearPathclicked(); - const QList &waypoints = WPM->getWaypointEditableList(); - while(!waypoints.isEmpty()) { - WaypointEditableView* widget = wpEditableViews.value(waypoints[0], NULL); - if (widget) { - widget->remove(); - } - } - } -} - -void WaypointList::clearWPWidget() -{ - // Get list - const QList waypoints = WPM->getWaypointEditableList(); - - - // XXX delete wps as well - - // Clear UI elements - while(!waypoints.isEmpty()) { - WaypointEditableView* widget = wpEditableViews.value(waypoints[0], NULL); - if (widget) { - widget->remove(); - } - } -} diff --git a/src/ui/WaypointList.h b/src/ui/WaypointList.h deleted file mode 100644 index e20f23403..000000000 --- a/src/ui/WaypointList.h +++ /dev/null @@ -1,155 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief Definition of list of waypoints widget - * - * @author Lorenz Meier - * @author Benjamin Knecht - * @author Petri Tanskanen - * - */ - -#ifndef WAYPOINTLIST_H -#define WAYPOINTLIST_H - -#include -#include -#include -#include -#include "MissionItem.h" -#include "UASInterface.h" -#include "WaypointEditableView.h" -#include "WaypointViewOnlyView.h" - -namespace Ui -{ -class WaypointList; -} - -class WaypointList : public QWidget -{ - Q_OBJECT - Q_DISABLE_COPY(WaypointList) -public: - WaypointList(QWidget* parent = NULL, UASWaypointManager* wpm = NULL); - virtual ~WaypointList(); - -public slots: - void updatePosition(UASInterface*, double x, double y, double z, quint64 usec); - void updateAttitude(UASInterface*, double roll, double pitch, double yaw, quint64 usec); - - void setUAS(UASInterface* uas); - - //MissionItem list operations - /** @brief Save the local waypoint list to a file */ - void saveWaypoints(); - /** @brief Load a waypoint list from a file */ - void loadWaypoints(); - /** @brief Transmit the local waypoint list to the UAS */ - void transmit(); - /** @brief Read the remote waypoint list to both tabs */ - void read(); - /** @brief Read the remote waypoint list to "view"-tab only*/ - void refresh(); - /** @brief Add a waypoint to "edit"-tab */ - void addEditable(); - /** @brief Add a waypoint to "edit"-tab on current MAV position or on generic position (home) */ - void addEditable(bool onCurrentPosition); - /** @brief Add a waypoint at the current MAV position */ - void addCurrentPositionWaypoint(); - /** @brief Add a waypoint by mouse click over the map */ - - //Update events - /** @brief sets statusLabel string */ - void updateStatusLabel(const QString &string); - /** @brief The user wants to change the current waypoint */ - void changeCurrentWaypoint(quint16 seq); - /** @brief Current waypoint in edit-tab was changed, so the list must be updated (to contain only one waypoint checked as "current") */ - void currentWaypointEditableChanged(quint16 seq); - /** @brief Current waypoint on UAV was changed, update view-tab */ - void currentWaypointViewOnlyChanged(quint16 seq); - /** @brief The waypoint manager informs that one editable waypoint was changed */ - void updateWaypointEditable(int uas, MissionItem* wp); - /** @brief The waypoint manager informs that one viewonly waypoint was changed */ - void updateWaypointViewOnly(int uas, MissionItem* wp); - /** @brief The waypoint manager informs that the editable waypoint list was changed */ - void waypointEditableListChanged(void); - /** @brief The waypoint manager informs that the waypoint list on the MAV was changed */ - void waypointViewOnlyListChanged(void); - -// /** @brief The MapWidget informs that a waypoint global was changed on the map */ -// void waypointGlobalChanged(const QPointF coordinate, const int indexWP); - - void clearWPWidget(); - - //void changeWPPositionBySpinBox(MissionItem* wp); - - // MissionItem operations - void moveUp(MissionItem* wp); - void moveDown(MissionItem* wp); - void removeWaypoint(MissionItem* wp); - -// void setIsLoadFileWP(); -// void setIsReadGlobalWP(bool value); - - - - -signals: - void clearPathclicked(); - void createWaypointAtMap(const QPointF coordinate); - -protected: - virtual void changeEvent(QEvent *e); - -protected: - QMap wpEditableViews; - QMap wpViewOnlyViews; - QVBoxLayout* viewOnlyListLayout; - QVBoxLayout* editableListLayout; - UASInterface* uas; - UASWaypointManager* WPM; - double mavX; - double mavY; - double mavZ; - double mavYaw; - QPointF centerMapCoordinate; - bool loadFileGlobalWP; - bool readGlobalWP; - bool showOfflineWarning; - -private: - Ui::WaypointList *m_ui; - - - - - -private slots: - void on_clearWPListButton_clicked(); - -}; - -#endif // WAYPOINTLIST_H diff --git a/src/ui/WaypointList.ui b/src/ui/WaypointList.ui deleted file mode 100644 index 218f5ed4e..000000000 --- a/src/ui/WaypointList.ui +++ /dev/null @@ -1,388 +0,0 @@ - - - WaypointList - - - - 0 - 0 - 854 - 398 - - - - - 100 - 120 - - - - Form - - - - 0 - - - 8 - - - 0 - - - 0 - - - 0 - - - - - true - - - 0 - - - - Edit Waypoints - - - - 6 - - - 0 - - - 6 - - - 6 - - - 6 - - - - - Add a new waypoint to this list. Transmit via write to the MAV. - - - Add a new waypoint to this list. Transmit via write to the MAV. - - - Add a new waypoint to this list. Transmit via write to the MAV. - - - ... - - - - :/res/PlusSign:/res/PlusSign - - - - - - - Load waypoints from a file on the local harddisk. Does not load the waypoints on the MAV. - - - Load waypoints from a file on the local harddisk. Does not load the waypoints on the MAV. - - - Load waypoints from a file on the local harddisk. Does not load the waypoints on the MAV. - - - Load WPs - - - - - - - Qt::Horizontal - - - - 127 - 20 - - - - - - - - Save waypoints to a file on the local harddisk. Does not save them on the MAV. - - - Save waypoints to a file on the local harddisk. Does not save them on the MAV. - - - Save waypoints to a file on the local harddisk. Does not save them on the MAV. - - - Save WPs - - - - - - - The current waypoint transmission status - - - The current waypoint transmission status - - - The current waypoint transmission status - - - Please add first waypoint. - - - - - - - true - - - - - 0 - 0 - 834 - 325 - - - - - - - Waypoint list. The list is empty until you issue a read command or add waypoints. - - - Waypoint list. The list is empty until you issue a read command or add waypoints. - - - Waypoint list. The list is empty until you issue a read command or add waypoints. - - - - - - - - - - - false - - - Read all waypoints from the MAV. Clears the list on this computer. - - - Read all waypoints from the MAV. Clears the list on this computer. - - - Read all waypoints from the MAV. Clears the list on this computer. - - - Get - - - - - - - false - - - Transmit all waypoints on this list to the MAV. - - - Transmit all waypoints on this list to the MAV. - - - Transmit all waypoints on this list to the MAV. - - - Set - - - - - - - Delete all waypoints from this list. You have to click write to clear the list on the MAV as well. - - - Delete all waypoints from this list. You have to click write to clear the list on the MAV as well. - - - Delete all waypoints from this list. You have to click write to clear the list on the MAV as well. - - - ... - - - - :/res/Kill:/res/Kill - - - - - - - false - - - Set the current vehicle position as new waypoint - - - Set the current vehicle position as new waypoint - - - Set the current vehicle position as new waypoint - - - ... - - - - :/res/BottomArrow:/res/BottomArrow - - - - - - - - Onboard Waypoints - - - - 6 - - - 0 - - - 6 - - - 6 - - - - - true - - - - - 0 - 0 - 834 - 323 - - - - true - - - - - - true - - - - 16777215 - 16777215 - - - - - - - - - - - - - - - - - - - Qt::Horizontal - - - - 714 - 20 - - - - - - - - false - - - Read all waypoints from the MAV and display in View tab.. - - - Read all waypoints from the MAV and display in View tab.. - - - Read all waypoints from the MAV and display in View tab. - - - Refresh - - - - :/res/JumpArrow:/res/JumpArrow - - - - - - - - - - - Add Waypoint - - - Add a new waypoint to the end of the list - - - - - Transmit - - - Transmit waypoints to unmanned system - - - - - Read - - - - - - - - diff --git a/src/ui/WaypointViewOnlyView.cc b/src/ui/WaypointViewOnlyView.cc deleted file mode 100644 index 5f7d6e871..000000000 --- a/src/ui/WaypointViewOnlyView.cc +++ /dev/null @@ -1,386 +0,0 @@ -#include - -#include "MainWindow.h" -#include "WaypointViewOnlyView.h" -#include "ui_WaypointViewOnlyView.h" - -WaypointViewOnlyView::WaypointViewOnlyView(MissionItem* wp, QWidget *parent) : - QWidget(parent), - wp(wp), - m_ui(new Ui::WaypointViewOnlyView) -{ - m_ui->setupUi(this); - updateValues(); - - connect(m_ui->current, SIGNAL(stateChanged(int)), this, SLOT(changedCurrent(int))); - connect(m_ui->autoContinue, SIGNAL(stateChanged(int)),this, SLOT(changedAutoContinue(int))); -} - -void WaypointViewOnlyView::changedAutoContinue(int state) -{ - bool new_value = false; - if (state != 0) - { - new_value = true; - } - wp->setAutocontinue(new_value); - emit changeAutoContinue(wp->sequenceNumber(),new_value); -} - -void WaypointViewOnlyView::changedCurrent(int state) -//This is a slot receiving signals from QCheckBox m_ui->current. The state given here is whatever the user has clicked and not the true "current" value onboard. -{ - Q_UNUSED(state); - //qDebug() << "Trof: WaypointViewOnlyView::changedCurrent(" << state << ") ID:" << wp->sequenceNumber(); - m_ui->current->blockSignals(true); - - if (m_ui->current->isChecked() == false) - { - if (wp->isCurrentItem() == true) //User clicked on the waypoint, that is already current. Box stays checked - { - m_ui->current->setCheckState(Qt::Checked); - //qDebug() << "Trof: WaypointViewOnlyView::changedCurrent. Rechecked true. stay true " << m_ui->current->isChecked(); - } - else // Strange case, unchecking the box which was not checked to start with - { - m_ui->current->setCheckState(Qt::Unchecked); - //qDebug() << "Trof: WaypointViewOnlyView::changedCurrent. Unchecked false. set false " << m_ui->current->isChecked(); - } - } - else - { - m_ui->current->setCheckState(Qt::Unchecked); - //qDebug() << "Trof: WaypointViewOnlyView::changedCurrent. Checked new. Sending set_current request to Manager " << m_ui->current->isChecked(); - emit changeCurrentWaypoint(wp->sequenceNumber()); //the slot changeCurrentWaypoint() in WaypointList sets all other current flags to false - - } - m_ui->current->blockSignals(false); -} - -void WaypointViewOnlyView::setCurrent(bool state) -//This is a slot receiving signals from UASWaypointManager. The state given here is the true representation of what the "current" waypoint on UAV is. -{ - if (!wp) { - return; - } - - m_ui->current->blockSignals(true); - if (state == true) - { - wp->setIsCurrentItem(true); - m_ui->current->setCheckState(Qt::Checked); - } - else - { - wp->setIsCurrentItem(false); - m_ui->current->setCheckState(Qt::Unchecked); - } - m_ui->current->blockSignals(false); -} - -void WaypointViewOnlyView::updateValues() -{ - // Check if we just lost the wp, delete the widget - // accordingly - if (!wp) - { - deleteLater(); - return; - } - - // Style alternating rows of Missions as lighter/darker. - static int lastId = -1; - int currId = wp->sequenceNumber() % 2; - if (currId != lastId) - { - if (currId == 1) - { - this->setProperty("RowColoring", "odd"); - } - else - { - this->setProperty("RowColoring", "even"); - } - - lastId = currId; - } - - // update frame - - m_ui->idLabel->setText(QString("%1").arg(wp->sequenceNumber())); - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL: - { - m_ui->frameLabel->setText(QString("GAA")); - break; - } - case MAV_FRAME_LOCAL_NED: - { - m_ui->frameLabel->setText(QString("NED")); - break; - } - case MAV_FRAME_MISSION: - { - m_ui->frameLabel->setText(QString("MIS")); - break; - } - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - { - m_ui->frameLabel->setText(QString("GRA")); - break; - } - case MAV_FRAME_LOCAL_ENU: - { - m_ui->frameLabel->setText(QString("ENU")); - break; - } - default: - { - m_ui->frameLabel->setText(QString("")); - break; - } - } - - if (m_ui->current->isChecked() != wp->isCurrentItem()) - { - m_ui->current->blockSignals(true); - m_ui->current->setChecked(wp->isCurrentItem()); - m_ui->current->blockSignals(false); - } - if (m_ui->autoContinue->isChecked() != wp->autoContinue()) - { - m_ui->autoContinue->blockSignals(true); - m_ui->autoContinue->setChecked(wp->autoContinue()); - m_ui->autoContinue->blockSignals(false); - } - - switch (wp->command()) - { - case MAV_CMD_NAV_WAYPOINT: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - if (wp->param1()>0) - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and wait there for %4 sec; yaw: %5; rad: %6").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param1()).arg(wp->param4()).arg(wp->param2())); - } - else - { - m_ui->displayBar->setText(QString("Go to (lat %1o,lon %2o,alt %3); yaw: %4; rad: %5").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param4()).arg(wp->param2())); - } - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - if (wp->param1()>0) - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and wait there for %4 sec; yaw: %5; rad: %6").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f',2).arg(wp->param1()).arg(wp->param4()).arg(wp->param2())); - } - else - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3); yaw: %4; rad: %5").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(wp->param4()).arg(wp->param2())); - } - break; - } - } //end Frame switch - break; - } - case MAV_CMD_NAV_LOITER_UNLIM: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there indefinitely (clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param3())); - } - else - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there indefinitely (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(-wp->param3())); - } - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there indefinitely (clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f',2).arg(wp->param3())); - } - else - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there indefinitely (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(-wp->param3())); - } - break; - } - } //end Frame switch - break; - } - case MAV_CMD_NAV_LOITER_TURNS: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there for %5 turns (clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param3()).arg(wp->param1())); - } - else - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there for %5 turns (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(-wp->param3()).arg(wp->param1())); - } - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there for %5 turns (clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f',2).arg(wp->param3()).arg(wp->param1())); - } - else - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there for %5 turns (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(-wp->param3()).arg(wp->param1())); - } - break; - } - } //end Frame switch - break; - } - case MAV_CMD_NAV_LOITER_TIME: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there for %5s (clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param3()).arg(wp->param1())); - } - else - { - m_ui->displayBar->setText(QString("Go to (lat %1o, lon %2o, alt %3) and loiter there for %5s (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(-wp->param3()).arg(wp->param1())); - } - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - if (wp->param3()>=0) - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there for %5s (clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f',2).arg(wp->param3()).arg(wp->param1())); - } - else - { - m_ui->displayBar->setText(QString("Go to (%1, %2, %3) and loiter there for %5s (counter-clockwise); rad: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(-wp->param3()).arg(wp->param1())); - } - break; - } - } //end Frame switch - break; - } - case MAV_CMD_NAV_RETURN_TO_LAUNCH: - { - m_ui->displayBar->setText(QString("Return to launch location")); - break; - } - case MAV_CMD_NAV_LAND: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - m_ui->displayBar->setText(QString("LAND. Go to (lat %1o, lon %2o, alt %3) and descent; yaw: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param4())); - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - m_ui->displayBar->setText(QString("LAND. Go to (%1, %2, %3) and descent; yaw: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(wp->param4())); - break; - } - } //end Frame switch - break; - } - case MAV_CMD_NAV_TAKEOFF: - { - switch (wp->frame()) - { - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - case MAV_FRAME_GLOBAL: - { - m_ui->displayBar->setText(QString("TAKEOFF. Go to (lat %1o, lon %2o, alt %3); yaw: %4").arg(wp->x(),0, 'f', 7).arg(wp->y(),0, 'f', 7).arg(wp->z(),0, 'f', 2).arg(wp->param4())); - break; - } - case MAV_FRAME_LOCAL_NED: - default: - { - m_ui->displayBar->setText(QString("TAKEOFF. Go to (%1, %2, %3); yaw: %4").arg(wp->x(),0, 'f', 2).arg(wp->y(),0, 'f', 2).arg(wp->z(),0, 'f', 2).arg(wp->param4())); - break; - } - } //end Frame switch - break; - break; - } - case MAV_CMD_DO_JUMP: - { - if (wp->param2()>0) - { - m_ui->displayBar->setText(QString("Jump to waypoint %1. Jumps left: %2").arg(wp->param1()).arg(wp->param2())); - } - else - { - m_ui->displayBar->setText(QString("No jumps left. Proceed to next waypoint.")); - } - break; - } - case MAV_CMD_CONDITION_DELAY: - { - m_ui->displayBar->setText(QString("Delay: %1 sec").arg(wp->param1())); - break; - } - default: - { - m_ui->displayBar->setText(QString("Unknown Command ID (%1) : %2, %3, %4, %5, %6, %7, %8").arg(wp->command()).arg(wp->param1()).arg(wp->param2()).arg(wp->param3()).arg(wp->param4()).arg(wp->param5()).arg(wp->param6()).arg(wp->param7())); - break; - } - } -} - -WaypointViewOnlyView::~WaypointViewOnlyView() -{ - delete m_ui; -} - -void WaypointViewOnlyView::changeEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::LanguageChange: - m_ui->retranslateUi(this); - break; - default: - break; - } -} - -/** - * Implement paintEvent() so that stylesheets work for our custom widget. - */ -void WaypointViewOnlyView::paintEvent(QPaintEvent *) - { - QStyleOption opt; - opt.init(this); - QPainter p(this); - style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); - } diff --git a/src/ui/WaypointViewOnlyView.h b/src/ui/WaypointViewOnlyView.h deleted file mode 100644 index 902bd4fe5..000000000 --- a/src/ui/WaypointViewOnlyView.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef WAYPOINTVIEWONLYVIEW_H -#define WAYPOINTVIEWONLYVIEW_H - -#include -#include "MissionItem.h" -#include - -namespace Ui { - class WaypointViewOnlyView; -} - -class WaypointViewOnlyView : public QWidget -{ - Q_OBJECT - -public: - explicit WaypointViewOnlyView(MissionItem* wp, QWidget *parent = 0); - ~WaypointViewOnlyView(); - -public slots: - void changedCurrent(int state); - void changedAutoContinue(int state); - void updateValues(void); - void setCurrent(bool state); - -signals: - void changeCurrentWaypoint(quint16); - void changeAutoContinue(quint16, bool); - -protected: - MissionItem* wp; - virtual void changeEvent(QEvent *e); - virtual void paintEvent(QPaintEvent *); - -private: - Ui::WaypointViewOnlyView *m_ui; -}; - -#endif // WAYPOINTVIEWONLYVIEW_H diff --git a/src/ui/WaypointViewOnlyView.ui b/src/ui/WaypointViewOnlyView.ui deleted file mode 100644 index 99b5c70e1..000000000 --- a/src/ui/WaypointViewOnlyView.ui +++ /dev/null @@ -1,570 +0,0 @@ - - - WaypointViewOnlyView - - - - 0 - 0 - 704 - 31 - - - - - 0 - 0 - - - - - 200 - 30 - - - - Form - - - - - - - 6 - - - - - - 0 - 0 - - - - - 25 - 0 - - - - 1 - - - ID - - - Qt::AlignCenter - - - - - - - - 0 - 0 - - - - - 25 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 255 - 0 - - - - - - - 0 - 212 - 0 - - - - - - - 0 - 85 - 0 - - - - - - - 0 - 113 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 127 - 212 - 127 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 255 - 0 - - - - - - - 0 - 212 - 0 - - - - - - - 0 - 85 - 0 - - - - - - - 0 - 113 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 0 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 127 - 212 - 127 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - - 0 - 85 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 255 - 0 - - - - - - - 0 - 212 - 0 - - - - - - - 0 - 85 - 0 - - - - - - - 0 - 113 - 0 - - - - - - - 0 - 85 - 0 - - - - - - - 255 - 255 - 255 - - - - - - - 0 - 85 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 0 - 0 - 0 - - - - - - - 0 - 170 - 0 - - - - - - - 255 - 255 - 220 - - - - - - - 0 - 0 - 0 - - - - - - - - Currently executed waypoint - - - Currently executed waypoint - - - - - - - - - - - 0 - 0 - - - - Mission element description - - - Mission element description - - - - - - Mission element description - - - - - - - Coordinate Frame - - - Coordinate Frame - - - - - - Frame - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - false - - - - 0 - 0 - - - - Automatically continue after this waypoint - - - Automatically continue after this waypoint - - - - - - true - - - - - - - - diff --git a/src/ui/map/MAV2DIcon.cc b/src/ui/map/MAV2DIcon.cc deleted file mode 100644 index 9446eb350..000000000 --- a/src/ui/map/MAV2DIcon.cc +++ /dev/null @@ -1,275 +0,0 @@ -#include "MAV2DIcon.h" -#include - -#include - -#include "QGC.h" -#include "MultiVehicleManager.h" -#include "UAS.h" - -MAV2DIcon::MAV2DIcon(mapcontrol::MapGraphicItem* map,mapcontrol::OPMapWidget* parent, UASInterface* uas, int radius, int type) - : UAVItem(map,parent), - yaw(0.0f), - radius(radius), - type(type), - airframe(uas->getAirframe()), - iconColor(uas->getColor()), - selected(MultiVehicleManager::instance()->activeUas() == uas), - uasid(uas->getUASID()) -{ - size = QSize(radius, radius); - pic = QPixmap(size); - drawIcon(); -} - -MAV2DIcon::MAV2DIcon(mapcontrol::MapGraphicItem* map, mapcontrol::OPMapWidget* parent, qreal lat, qreal lon, qreal alt, QColor color) - : UAVItem(map,parent), - radius(20), - type(0), - airframe(0), - iconColor(color), - selected(false), - uasid(0) -{ - size = QSize(radius, radius); - pic = QPixmap(size); - drawIcon(); - SetUAVPos(internals::PointLatLng(lat, lon), alt, color); -} - -MAV2DIcon::~MAV2DIcon() -{ -} - -void MAV2DIcon::setSelectedUAS(bool selected) -{ - this->selected = selected; - drawIcon(); -} - -/** - * Yaw changes of less than ±15 degrees are ignored. - * - * @param yaw in radians, 0 = north, positive = clockwise - */ -void MAV2DIcon::setYaw(float yaw) -{ - float diff = fabs(yaw - this->yaw); - while (diff > (float)M_PI) { - diff -= (float)M_PI; - } - - if (diff > 0.1f) { - this->yaw = yaw; - drawIcon(); - // FIXME - } -} - -void MAV2DIcon::drawIcon() -{ - pic.fill(Qt::transparent); - QPainter painter(&pic); - painter.setRenderHint(QPainter::TextAntialiasing); - painter.setRenderHint(QPainter::Antialiasing); - painter.setRenderHint(QPainter::HighQualityAntialiasing); - - radius = qMin(pic.width(), pic.height()); - - // Rotate by yaw - painter.translate(radius/2, radius/2); - - // Draw selected indicator - painter.setBrush(Qt::NoBrush); - if (selected) { - QPen pen(Qt::yellow); - pen.setWidth(2); - painter.setPen(pen); - } - else - { - QPen pen(Qt::white); - pen.setWidth(1); - painter.setPen(pen); - } - painter.drawEllipse(QPoint(0, 0), radius/2-1, radius/2-1); - drawAirframePolygon(airframe, painter, radius, iconColor, yaw); -} - -void MAV2DIcon::drawAirframePolygon(int airframe, QPainter& painter, int radius, QColor& iconColor, float yaw) -{ - switch (airframe) { - case UASInterface::QGC_AIRFRAME_PREDATOR: - case UASInterface::QGC_AIRFRAME_REAPER: { - // DRAW AIRPLANE - - // Rotate 180 degs more since the icon is oriented downwards - //float yawRotate = (yaw/(float)M_PI)*180.0f + 180.0f+180.0f; - - const float yawDeg = ((yaw/M_PI)*180.0f)+180.0f+180.0f; - int yawRotate = static_cast(yawDeg) % 360; - - painter.rotate(yawRotate); - - //// qDebug() << "ICON SIZE:" << radius; - - float iconSize = radius*0.9f; - QPolygonF poly(24); - poly.replace(0, QPointF(0.000000f*iconSize, -0.312500f*iconSize)); - poly.replace(1, QPointF(0.025000f*iconSize, -0.287500f*iconSize)); - poly.replace(2, QPointF(0.037500f*iconSize, -0.237500f*iconSize)); - poly.replace(3, QPointF(0.031250f*iconSize, -0.187500f*iconSize)); - poly.replace(4, QPointF(0.025000f*iconSize, -0.043750f*iconSize)); - poly.replace(5, QPointF(0.500000f*iconSize, -0.025000f*iconSize)); - poly.replace(6, QPointF(0.500000f*iconSize, 0.025000f*iconSize)); - poly.replace(7, QPointF(0.025000f*iconSize, 0.043750f*iconSize)); - poly.replace(8, QPointF(0.025000f*iconSize, 0.162500f*iconSize)); - poly.replace(9, QPointF(0.137500f*iconSize, 0.181250f*iconSize)); - poly.replace(10, QPointF(0.137500f*iconSize, 0.218750f*iconSize)); - poly.replace(11, QPointF(0.025000f*iconSize, 0.206250f*iconSize)); - poly.replace(12, QPointF(-0.025000f*iconSize, 0.206250f*iconSize)); - poly.replace(13, QPointF(-0.137500f*iconSize, 0.218750f*iconSize)); - poly.replace(14, QPointF(-0.137500f*iconSize, 0.181250f*iconSize)); - poly.replace(15, QPointF(-0.025000f*iconSize, 0.162500f*iconSize)); - poly.replace(16, QPointF(-0.025000f*iconSize, 0.043750f*iconSize)); - poly.replace(17, QPointF(-0.500000f*iconSize, 0.025000f*iconSize)); - poly.replace(18, QPointF(-0.500000f*iconSize, -0.025000f*iconSize)); - poly.replace(19, QPointF(-0.025000f*iconSize, -0.043750f*iconSize)); - poly.replace(20, QPointF(-0.031250f*iconSize, -0.187500f*iconSize)); - poly.replace(21, QPointF(-0.037500f*iconSize, -0.237500f*iconSize)); - poly.replace(22, QPointF(-0.031250f*iconSize, -0.262500f*iconSize)); - poly.replace(23, QPointF(0.000000f*iconSize, -0.312500f*iconSize)); - - painter.setBrush(QBrush(iconColor)); - QPen iconPen(Qt::black); - iconPen.setWidthF(1.0f); - painter.setPen(iconPen); - - painter.drawPolygon(poly); - painter.rotate(-yawRotate); - } - break; - case UASInterface::QGC_AIRFRAME_MIKROKOPTER: - case UASInterface::QGC_AIRFRAME_CHEETAH: { - // QUADROTOR - float iconSize = radius*0.9f; - const float yawDeg = ((yaw/M_PI)*180.0f)+180.0f; - int yawRotate = static_cast(yawDeg) % 360; - - painter.rotate(yawRotate); - - //// qDebug() << "ICON SIZE:" << radius; - - QPointF front(0, 0.2); - front = front *iconSize; - QPointF left(-0.2, 0); - left = left * iconSize; - QPointF right(0.2, 0.0); - right *= iconSize; - QPointF back(0, -0.2); - back *= iconSize; - - QPolygonF poly(0); - - - - painter.setBrush(QBrush(iconColor)); - QPen iconPen(Qt::black); - iconPen.setWidthF(1.0f); - painter.setPen(iconPen); - - painter.drawPolygon(poly); - - painter.drawEllipse(left, radius/4/2, radius/4/2); - painter.drawEllipse(right, radius/4/2, radius/4/2); - painter.drawEllipse(back, radius/4/2, radius/4/2); - - painter.setBrush(Qt::red); - painter.drawEllipse(front, radius/4/2, radius/4/2); - painter.rotate(-yawRotate); - } - break; - case UASInterface::QGC_AIRFRAME_EASYSTAR: - case UASInterface::QGC_AIRFRAME_MERLIN: - case UASInterface::QGC_AIRFRAME_TWINSTAR: - case UASInterface::QGC_AIRFRAME_PTERYX: { - // DRAW AIRPLANE - - const float yawDeg = ((yaw/M_PI)*180.0f)+180.0f; - int yawRotate = static_cast(yawDeg) % 360; - painter.rotate(yawRotate); - - //// qDebug() << "ICON SIZE:" << radius; - - float iconSize = radius*0.7f; - - QPolygonF poly(32); - poly.replace(0, QPointF(0.000000f*iconSize, 0.362319f*iconSize)); - poly.replace(1, QPointF(0.018116f*iconSize, 0.340580f*iconSize)); - poly.replace(2, QPointF(0.028986f*iconSize, 0.318841f*iconSize)); - poly.replace(3, QPointF(0.036232f*iconSize, 0.166667f*iconSize)); - poly.replace(4, QPointF(0.326087f*iconSize, 0.170290f*iconSize)); - poly.replace(5, QPointF(0.420290f*iconSize, 0.130435f*iconSize)); - poly.replace(6, QPointF(0.456522f*iconSize, 0.108696f*iconSize)); - poly.replace(7, QPointF(0.500000f*iconSize, 0.000000f*iconSize)); - poly.replace(8, QPointF(0.456522f*iconSize, 0.021739f*iconSize)); - poly.replace(9, QPointF(0.391304f*iconSize, 0.021739f*iconSize)); - poly.replace(10, QPointF(0.028986f*iconSize, 0.021739f*iconSize)); - poly.replace(11, QPointF(0.021739f*iconSize, -0.239130f*iconSize)); - poly.replace(12, QPointF(0.094203f*iconSize, -0.246377f*iconSize)); - poly.replace(13, QPointF(0.123188f*iconSize, -0.268116f*iconSize)); - poly.replace(14, QPointF(0.144928f*iconSize, -0.304348f*iconSize)); - poly.replace(15, QPointF(0.000000f*iconSize, -0.307971f*iconSize)); - poly.replace(16, QPointF(0.000000f*iconSize, -0.307971f*iconSize)); - poly.replace(17, QPointF(-0.144928f*iconSize, -0.304348f*iconSize)); - poly.replace(18, QPointF(-0.123188f*iconSize, -0.268116f*iconSize)); - poly.replace(19, QPointF(-0.094203f*iconSize, -0.246377f*iconSize)); - poly.replace(20, QPointF(-0.021739f*iconSize, -0.239130f*iconSize)); - poly.replace(21, QPointF(-0.028986f*iconSize, 0.021739f*iconSize)); - poly.replace(22, QPointF(-0.391304f*iconSize, 0.021739f*iconSize)); - poly.replace(23, QPointF(-0.456522f*iconSize, 0.021739f*iconSize)); - poly.replace(24, QPointF(-0.500000f*iconSize, 0.000000f*iconSize)); - poly.replace(25, QPointF(-0.456522f*iconSize, 0.108696f*iconSize)); - poly.replace(26, QPointF(-0.420290f*iconSize, 0.130435f*iconSize)); - poly.replace(27, QPointF(-0.326087f*iconSize, 0.170290f*iconSize)); - poly.replace(28, QPointF(-0.036232f*iconSize, 0.166667f*iconSize)); - poly.replace(29, QPointF(-0.028986f*iconSize, 0.318841f*iconSize)); - poly.replace(30, QPointF(-0.018116f*iconSize, 0.340580f*iconSize)); - poly.replace(31, QPointF(-0.000000f*iconSize, 0.362319f*iconSize)); - - painter.setBrush(QBrush(iconColor)); - QPen iconPen(Qt::black); - iconPen.setWidthF(1.0f); - painter.setPen(iconPen); - - painter.drawPolygon(poly); - painter.rotate(-yawRotate); - } - break; - case UASInterface::QGC_AIRFRAME_GENERIC: - default: { - // GENERIC - - float yawRotate = (yaw/(float)M_PI)*180.0f + 180.0f; - - painter.rotate(yawRotate); - - //// qDebug() << "ICON SIZE:" << radius; - - float iconSize = radius*0.9f; - QPolygonF poly(3); - poly.replace(0, QPointF(0.0f*iconSize, 0.3f*iconSize)); - poly.replace(1, QPointF(-0.2f*iconSize, -0.2f*iconSize)); - poly.replace(2, QPointF(0.2f*iconSize, -0.2f*iconSize)); - - painter.setBrush(QBrush(iconColor)); - QPen iconPen(Qt::black); - iconPen.setWidthF(1.0f); - painter.setPen(iconPen); - - painter.drawPolygon(poly); - painter.rotate(-yawRotate); - } - break; - } -} diff --git a/src/ui/map/MAV2DIcon.h b/src/ui/map/MAV2DIcon.h deleted file mode 100644 index be83312c3..000000000 --- a/src/ui/map/MAV2DIcon.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef MAV2DICON_H -#define MAV2DICON_H - -#include - -#include "UASInterface.h" -#include "opmapcontrol.h" - -class MAV2DIcon : public mapcontrol::UAVItem -{ -public: - enum { - MAV_ICON_GENERIC = 0, - MAV_ICON_AIRPLANE, - MAV_ICON_QUADROTOR, - MAV_ICON_COAXIAL, - MAV_ICON_HELICOPTER, - } MAV_ICON_TYPE; - - //! - /*! - * - * @param x longitude - * @param y latitude - * @param radius the radius of the circle - * @param name name of the circle point - * @param alignment alignment (Middle or TopLeft) - * @param pen QPen for drawing - */ - MAV2DIcon(mapcontrol::MapGraphicItem* map,mapcontrol::OPMapWidget* parent, UASInterface* uas, int radius = 40, int type=0); - - /*! - * - * @param x longitude - * @param y latitude - * @param name name of the circle point - * @param alignment alignment (Middle or TopLeft) - * @param pen QPen for drawing - */ - MAV2DIcon(mapcontrol::MapGraphicItem* map,mapcontrol::OPMapWidget* parent, qreal lat=0, qreal lon=0, qreal alt=0, QColor color=QColor()); - - virtual ~MAV2DIcon(); - - /** @brief Mark this system as selected */ - void setSelectedUAS(bool selected); - void setYaw(float yaw); - /** @brief Set the airframe this MAV uses */ - void setAirframe(int airframe) { - this->airframe = airframe; - } - - /** @brief Get system id */ - int getUASId() const { - return uasid; - } - - void drawIcon(); - static void drawAirframePolygon(int airframe, QPainter& painter, int radius, QColor& iconColor, float yaw); - -protected: - float yaw; ///< Yaw angle of the MAV - int radius; ///< Radius / width of the icon - int type; ///< Type of aircraft: 0: generic, 1: airplane, 2: quadrotor, 3-n: rotary wing - int airframe; ///< The specific type of airframe used - QColor iconColor; ///< Color to be used for the icon - bool selected; ///< Wether this is the system currently in focus - int uasid; ///< ID of tracked system - QSize size; - -}; - -#endif // MAV2DICON_H diff --git a/src/ui/map/QGCMapTool.cc b/src/ui/map/QGCMapTool.cc deleted file mode 100644 index ef159c69d..000000000 --- a/src/ui/map/QGCMapTool.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "QGCMapTool.h" -#include "ui_QGCMapTool.h" -#include -#include - -QGCMapTool::QGCMapTool(QWidget *parent) : - QWidget(parent), - ui(new Ui::QGCMapTool) -{ - ui->setupUi(this); - - // Connect map and toolbar - ui->toolBar->setMap(ui->map); - // Connect zoom slider and map - ui->zoomSlider->setMinimum(ui->map->MinZoom()); - ui->zoomSlider->setMaximum(ui->map->MaxZoom()); - ui->zoomSlider->setValue(ui->map->ZoomReal()); - connect(ui->zoomSlider, SIGNAL(valueChanged(int)), ui->map, SLOT(SetZoom(int))); - connect(ui->map, SIGNAL(zoomChanged(int)), this, SLOT(setZoom(int))); -} - -void QGCMapTool::setZoom(int zoom) -{ - if (ui->zoomSlider->value() != zoom) - { - ui->zoomSlider->setValue(zoom); - } -} - -QGCMapTool::~QGCMapTool() -{ - delete ui; -} diff --git a/src/ui/map/QGCMapTool.h b/src/ui/map/QGCMapTool.h deleted file mode 100644 index ca0e33ad9..000000000 --- a/src/ui/map/QGCMapTool.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef QGCMAPTOOL_H -#define QGCMAPTOOL_H - -#include -#include - -namespace Ui { - class QGCMapTool; -} - -class QGCMapTool : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMapTool(QWidget *parent = 0); - ~QGCMapTool(); - -public slots: - /** @brief Update slider zoom from map change */ - void setZoom(int zoom); - -signals: - void visibilityChanged(bool visible); - -protected: - void showEvent(QShowEvent* event) - { - QWidget::showEvent(event); - emit visibilityChanged(true); - } - - void hideEvent(QHideEvent* event) - { - QWidget::hideEvent(event); - emit visibilityChanged(false); - } - -private: - Ui::QGCMapTool *ui; -}; - -#endif // QGCMAPTOOL_H diff --git a/src/ui/map/QGCMapTool.ui b/src/ui/map/QGCMapTool.ui deleted file mode 100644 index b8efd016a..000000000 --- a/src/ui/map/QGCMapTool.ui +++ /dev/null @@ -1,60 +0,0 @@ - - - QGCMapTool - - - - 0 - 0 - 261 - 206 - - - - Form - - - - 3 - - - 0 - - - 0 - - - - - - - - 60 - - - Qt::Vertical - - - - - - - - - - - QGCMapToolBar - QWidget -
QGCMapToolBar.h
- 1 -
- - QGCMapWidget - QWidget -
QGCMapWidget.h
- 1 -
-
- - -
diff --git a/src/ui/map/QGCMapToolBar.cc b/src/ui/map/QGCMapToolBar.cc deleted file mode 100644 index b1dad3edb..000000000 --- a/src/ui/map/QGCMapToolBar.cc +++ /dev/null @@ -1,258 +0,0 @@ -#include "QGCMapToolBar.h" -#include "QGCMapWidget.h" -#include "ui_QGCMapToolBar.h" - -QGCMapToolBar::QGCMapToolBar(QWidget *parent) : - QWidget(parent), - _ui(new Ui::QGCMapToolBar), - _map(NULL), - _optionsMenu(new QMenu(this)), - _trailPlotMenu(new QMenu(this)), - _updateTimesMenu(new QMenu(this)), - _mapTypesMenu(new QMenu(this)), - _trailSettingsGroup(new QActionGroup(this)), - _updateTimesGroup(new QActionGroup(this)), - _mapTypesGroup(new QActionGroup(this)), - _statusMaxLen(15) -{ - _ui->setupUi(this); -} - -void QGCMapToolBar::setMap(QGCMapWidget* map) -{ - _map = map; - - if (_map) - { - connect(_ui->goToButton, SIGNAL(clicked()), _map, SLOT(showGoToDialog())); - connect(_ui->goHomeButton, SIGNAL(clicked()), _map, SLOT(goHome())); - connect(_ui->lastPosButton, SIGNAL(clicked()), _map, SLOT(loadSettings())); - connect(_ui->clearTrailsButton, SIGNAL(clicked()), _map, SLOT(deleteTrails())); - connect(_ui->lockCheckBox, SIGNAL(clicked(bool)), _map, SLOT(setZoomBlocked(bool))); - connect(_map, SIGNAL(OnTileLoadStart()), this, SLOT(tileLoadStart())); - connect(_map, SIGNAL(OnTileLoadComplete()), this, SLOT(tileLoadEnd())); - connect(_map, SIGNAL(OnTilesStillToLoad(int)), this, SLOT(tileLoadProgress(int))); - connect(_ui->ripMapButton, SIGNAL(clicked()), _map, SLOT(cacheVisibleRegion())); - - _ui->followCheckBox->setChecked(_map->getFollowUAVEnabled()); - connect(_ui->followCheckBox, SIGNAL(clicked(bool)), _map, SLOT(setFollowUAVEnabled(bool))); - - // Edit mode handling - _ui->editButton->hide(); - - const int uavTrailTimeList[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // seconds - const int uavTrailTimeCount = 10; - - const int uavTrailDistanceList[] = {1, 2, 5, 10, 20, 50, 100, 200, 500}; // meters - const int uavTrailDistanceCount = 9; - - // Set exclusive items - _trailSettingsGroup->setExclusive(true); - _updateTimesGroup->setExclusive(true); - _mapTypesGroup->setExclusive(true); - - // Build up menu - _trailPlotMenu->setTitle(tr("&Add trail dot every..")); - _updateTimesMenu->setTitle(tr("&Limit map view update rate to..")); - _mapTypesMenu->setTitle(tr("&Map type")); - - - //setup the mapTypesMenu - QAction* action; - action = _mapTypesMenu->addAction(tr("Bing Hybrid"),this,SLOT(setMapType())); - action->setData(MapType::BingHybrid); - action->setCheckable(true); -#ifdef MAP_DEFAULT_TYPE_BING - action->setChecked(true); -#endif - _mapTypesGroup->addAction(action); - - action = _mapTypesMenu->addAction(tr("Google Hybrid"),this,SLOT(setMapType())); - action->setData(MapType::GoogleHybrid); - action->setCheckable(true); -#ifdef MAP_DEFAULT_TYPE_GOOGLE - action->setChecked(true); -#endif - _mapTypesGroup->addAction(action); - - action = _mapTypesMenu->addAction(tr("OpenStreetMap"),this,SLOT(setMapType())); - action->setData(MapType::OpenStreetMap); - action->setCheckable(true); -#ifdef MAP_DEFAULT_TYPE_OSM - action->setChecked(true); -#endif - _mapTypesGroup->addAction(action); - - _optionsMenu->addMenu(_mapTypesMenu); - - - // FIXME MARK CURRENT VALUES IN MENU - QAction *defaultTrailAction = _trailPlotMenu->addAction(tr("No trail"), this, SLOT(setUAVTrailTime())); - defaultTrailAction->setData(-1); - defaultTrailAction->setCheckable(true); - _trailSettingsGroup->addAction(defaultTrailAction); - - for (int i = 0; i < uavTrailTimeCount; ++i) - { - action = _trailPlotMenu->addAction(tr("%1 second%2").arg(uavTrailTimeList[i]).arg((uavTrailTimeList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailTime())); - action->setData(uavTrailTimeList[i]); - action->setCheckable(true); - _trailSettingsGroup->addAction(action); - if (static_cast(map->getTrailType()) == mapcontrol::UAVTrailType::ByTimeElapsed && _map->getTrailInterval() == uavTrailTimeList[i]) - { - // This is the current active time, set the action checked - action->setChecked(true); - } - } - for (int i = 0; i < uavTrailDistanceCount; ++i) - { - action = _trailPlotMenu->addAction(tr("%1 meter%2").arg(uavTrailDistanceList[i]).arg((uavTrailDistanceList[i] > 1) ? "s" : ""), this, SLOT(setUAVTrailDistance())); - action->setData(uavTrailDistanceList[i]); - action->setCheckable(true); - _trailSettingsGroup->addAction(action); - if (static_cast(_map->getTrailType()) == mapcontrol::UAVTrailType::ByDistance && _map->getTrailInterval() == uavTrailDistanceList[i]) - { - // This is the current active time, set the action checked - action->setChecked(true); - } - } - - // Set no trail checked if no action is checked yet - if (!_trailSettingsGroup->checkedAction()) - { - defaultTrailAction->setChecked(true); - } - - _optionsMenu->addMenu(_trailPlotMenu); - - // Add update times menu - for (int i = 100; i < 5000; i+=400) - { - float time = i/1000.0f; // Convert from ms to seconds - QAction* action = _updateTimesMenu->addAction(tr("%1 seconds").arg(time), this, SLOT(setUpdateInterval())); - action->setData(time); - action->setCheckable(true); - if (time == _map->getUpdateRateLimit()) - { - action->blockSignals(true); - action->setChecked(true); - action->blockSignals(false); - } - _updateTimesGroup->addAction(action); - } - - // If the current time is not part of the menu defaults - // still add it as new option - if (!_updateTimesGroup->checkedAction()) - { - float time = _map->getUpdateRateLimit(); - QAction* action = _updateTimesMenu->addAction(tr("uptate every %1 seconds").arg(time), this, SLOT(setUpdateInterval())); - action->setData(time); - action->setCheckable(true); - action->setChecked(true); - _updateTimesGroup->addAction(action); - } - _optionsMenu->addMenu(_updateTimesMenu); - - _ui->optionsButton->setMenu(_optionsMenu); - } -} - -void QGCMapToolBar::setUAVTrailTime() -{ - QObject* sender = QObject::sender(); - QAction* action = qobject_cast(sender); - - if (action) - { - bool ok; - int trailTime = action->data().toInt(&ok); - if (ok) - { - (_map->setTrailModeTimed(trailTime)); - setStatusLabelText(tr("Trail mode: Every %1 second%2").arg(trailTime).arg((trailTime > 1) ? "s" : "")); - } - } -} - -void QGCMapToolBar::setStatusLabelText(const QString &text) -{ - _ui->posLabel->setText(text.leftJustified(_statusMaxLen, QChar('.'), true)); -} - -void QGCMapToolBar::setUAVTrailDistance() -{ - QObject* sender = QObject::sender(); - QAction* action = qobject_cast(sender); - - if (action) - { - bool ok; - int trailDistance = action->data().toInt(&ok); - if (ok) - { - _map->setTrailModeDistance(trailDistance); - setStatusLabelText(tr("Trail mode: Every %1 meter%2").arg(trailDistance).arg((trailDistance == 1) ? "s" : "")); - } - } -} - -void QGCMapToolBar::setUpdateInterval() -{ - QObject* sender = QObject::sender(); - QAction* action = qobject_cast(sender); - - if (action) - { - bool ok; - float time = action->data().toFloat(&ok); - if (ok) - { - _map->setUpdateRateLimit(time); - setStatusLabelText(tr("Limit: %1 second%2").arg(time).arg((time != 1.0f) ? "s" : "")); - } - } -} - -void QGCMapToolBar::setMapType() -{ - QObject* sender = QObject::sender(); - QAction* action = qobject_cast(sender); - - if (action) - { - bool ok; - int mapType = action->data().toInt(&ok); - if (ok) - { - _map->SetMapType((MapType::Types)mapType); - setStatusLabelText(tr("Map: %1").arg(mapType)); - } - } -} - -void QGCMapToolBar::tileLoadStart() -{ - setStatusLabelText(tr("Loading")); -} - -void QGCMapToolBar::tileLoadEnd() -{ - setStatusLabelText(tr("Finished")); -} - -void QGCMapToolBar::tileLoadProgress(int progress) -{ - if (progress == 1) - { - setStatusLabelText(tr("1 tile")); - } - else if (progress > 0) - { - setStatusLabelText(tr("%1 tile").arg(progress)); - } - else - { - tileLoadEnd(); - } -} diff --git a/src/ui/map/QGCMapToolBar.h b/src/ui/map/QGCMapToolBar.h deleted file mode 100644 index e837761d1..000000000 --- a/src/ui/map/QGCMapToolBar.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef QGCMAPTOOLBAR_H -#define QGCMAPTOOLBAR_H - -#include -#include -#include - -class QGCMapWidget; - -namespace Ui { - class QGCMapToolBar; -} - -class QGCMapToolBar : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMapToolBar(QWidget *parent = 0); - - void setMap(QGCMapWidget* map); - -public slots: - void tileLoadStart(); - void tileLoadEnd(); - void tileLoadProgress(int progress); - void setUAVTrailTime(); - void setUAVTrailDistance(); - void setUpdateInterval(); - void setMapType(); - void setStatusLabelText(const QString &text); - -private: - Ui::QGCMapToolBar* _ui; - - QGCMapWidget* _map; - QMenu* _optionsMenu; - QMenu* _trailPlotMenu; - QMenu* _updateTimesMenu; - QMenu* _mapTypesMenu; - - QActionGroup* _trailSettingsGroup; - QActionGroup* _updateTimesGroup; - QActionGroup* _mapTypesGroup; - - unsigned _statusMaxLen; -}; - -#endif // QGCMAPTOOLBAR_H diff --git a/src/ui/map/QGCMapToolBar.ui b/src/ui/map/QGCMapToolBar.ui deleted file mode 100644 index 6ad334a82..000000000 --- a/src/ui/map/QGCMapToolBar.ui +++ /dev/null @@ -1,132 +0,0 @@ - - - QGCMapToolBar - - - - 0 - 0 - 809 - 35 - - - - Form - - - - 2 - - - 4 - - - 4 - - - 4 - - - 4 - - - - - Lat/Lon - - - - - - - Edit - - - - - - - Go Home - - - - - - - Last Pos - - - - - - - Cache - - - - - - - Clear Map - - - - - - - Lock - - - - - - - Follow - - - - - - - Qt::Horizontal - - - - 20 - 20 - - - - - - - - 00.00 00.00 - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Options - - - - - - - - diff --git a/src/ui/map/QGCMapWidget.cc b/src/ui/map/QGCMapWidget.cc deleted file mode 100644 index fae9bca13..000000000 --- a/src/ui/map/QGCMapWidget.cc +++ /dev/null @@ -1,902 +0,0 @@ -#include -#include "QGCMapWidget.h" -#include "QGCMapToolBar.h" -#include "UASInterface.h" -#include "HomePositionManager.h" -#include "MAV2DIcon.h" -#include "Waypoint2DIcon.h" -#include "UASWaypointManager.h" -#include "QGCMessageBox.h" -#include "MultiVehicleManager.h" - -QGCMapWidget::QGCMapWidget(QWidget *parent) : - mapcontrol::OPMapWidget(parent), - firingWaypointChange(NULL), - maxUpdateInterval(2.1f), // 2 seconds - followUAVEnabled(false), - trailType(mapcontrol::UAVTrailType::ByTimeElapsed), - trailInterval(2.0f), - followUAVID(0), - mapInitialized(false), - mapPositionInitialized(false), - homeAltitude(0), - zoomBlocked(false), - _uas(NULL) -{ - currWPManager = MultiVehicleManager::instance()->activeWaypointManager(); - - waypointLines.insert(0, new QGraphicsItemGroup(map)); - - connect(currWPManager, SIGNAL(waypointEditableListChanged(int)), this, SLOT(updateWaypointList(int))); - connect(currWPManager, SIGNAL(waypointEditableChanged(int, MissionItem*)), this, SLOT(updateWaypoint(int,MissionItem*))); - - connect(this, SIGNAL(waypointCreated(MissionItem*)), currWPManager, SLOT(addWaypointEditable(MissionItem*))); - connect(this, SIGNAL(waypointChanged(MissionItem*)), currWPManager, SLOT(notifyOfChangeEditable(MissionItem*))); - - offlineMode = true; - // Widget is inactive until shown - defaultGuidedAlt = -1; - loadSettings(false); - - //handy for debugging: - //this->SetShowTileGridLines(true); - - //default appears to be Google Hybrid, and is broken currently -#if defined MAP_DEFAULT_TYPE_BING - this->SetMapType(MapType::BingHybrid); -#elif defined MAP_DEFAULT_TYPE_GOOGLE - this->SetMapType(MapType::GoogleHybrid); -#else - this->SetMapType(MapType::OpenStreetMap); -#endif - - this->setContextMenuPolicy(Qt::ActionsContextMenu); - - // Go to options - QAction *guidedaction = new QAction(this); - guidedaction->setText("Go To Here (Guided Mode)"); - connect(guidedaction,SIGNAL(triggered()),this,SLOT(guidedActionTriggered())); - this->addAction(guidedaction); - guidedaction = new QAction(this); - guidedaction->setText("Go To Here Alt (Guided Mode)"); - connect(guidedaction,SIGNAL(triggered()),this,SLOT(guidedAltActionTriggered())); - this->addAction(guidedaction); - - // Set home location option - QAction *sethomeaction = new QAction(this); - sethomeaction->setText("Set Home Location Here"); - connect(sethomeaction,SIGNAL(triggered()),this,SLOT(setHomeActionTriggered())); - this->addAction(sethomeaction); -} -void QGCMapWidget::guidedActionTriggered() -{ - if (!_uas) - { - QGCMessageBox::information(tr("Error"), tr("Please connect first")); - return; - } - if (currWPManager) - { - if (defaultGuidedAlt == -1) - { - if (!guidedAltActionTriggered()) - { - return; - } - } - // Create new waypoint and send it to the WPManager to send out. - internals::PointLatLng pos = map->FromLocalToLatLng(contextMousePressPos.x(), contextMousePressPos.y()); - qDebug() << "Guided action requested. Lat:" << pos.Lat() << "Lon:" << pos.Lng(); - MissionItem wp; - wp.setLatitude(pos.Lat()); - wp.setLongitude(pos.Lng()); - wp.setAltitude(defaultGuidedAlt); - currWPManager->goToWaypoint(&wp); - } -} -bool QGCMapWidget::guidedAltActionTriggered() -{ - if (!_uas) - { - QGCMessageBox::information(tr("Error"), tr("Please connect first")); - return false; - } - bool ok = false; - int tmpalt = QInputDialog::getInt(this,"Altitude","Enter default altitude (in meters) of destination point for guided mode",100,0,30000,1,&ok); - if (!ok) - { - //Use has chosen cancel. Do not send the waypoint - return false; - } - defaultGuidedAlt = tmpalt; - guidedActionTriggered(); - return true; -} - -/** - * @brief QGCMapWidget::setHomeActionTriggered - */ -bool QGCMapWidget::setHomeActionTriggered() -{ - if (!_uas) - { - QGCMessageBox::information(tr("Error"), tr("Please connect first")); - return false; - } - HomePositionManager *uasManager = HomePositionManager::instance(); - if (!uasManager) { return false; } - - // Enter an altitude - bool ok = false; - double alt = QInputDialog::getDouble(this,"Home Altitude","Enter altitude (in meters) of new home location",0.0,0.0,30000.0,2,&ok); - if (!ok) return false; //Use has chosen cancel. Do not send the waypoint - - // Create new waypoint and send it to the WPManager to send out. - internals::PointLatLng pos = map->FromLocalToLatLng(contextMousePressPos.x(), contextMousePressPos.y()); - qDebug("Set home location sent. Lat: %f, Lon: %f, Alt: %f.", pos.Lat(), pos.Lng(), alt); - - bool success = uasManager->setHomePositionAndNotify(pos.Lat(),pos.Lng(), alt); - - qDebug() << ((success)? "Set new home location." : "Failed to set new home location."); - - return success; -} - -void QGCMapWidget::mousePressEvent(QMouseEvent *event) -{ - - // Store right-click event presses separate for context menu - // TODO add check if click was on map, or popup box. - if (event->button() == Qt::RightButton) { - contextMousePressPos = event->pos(); - } - - mapcontrol::OPMapWidget::mousePressEvent(event); -} - -void QGCMapWidget::mouseReleaseEvent(QMouseEvent *event) -{ - mousePressPos = event->pos(); - mapcontrol::OPMapWidget::mouseReleaseEvent(event); - - // If the mouse is released, we can't be dragging - if (firingWaypointChange) { - firingWaypointChange->setChanged(); - firingWaypointChange = NULL; - } -} - -QGCMapWidget::~QGCMapWidget() -{ - SetShowHome(false); // doing this appears to stop the map lib crashing on exit - SetShowUAV(false); // " " - storeSettings(); -} - -void QGCMapWidget::showEvent(QShowEvent* event) -{ - // Disable OP's standard UAV, we have more than one - SetShowUAV(false); - - // Pass on to parent widget - OPMapWidget::showEvent(event); - - // Connect map updates to the adapter slots - connect(this, SIGNAL(WPValuesChanged(WayPointItem*)), this, SLOT(handleMapWaypointEdit(WayPointItem*)), Qt::UniqueConnection); - - connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &QGCMapWidget::_vehicleAdded); - connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &QGCMapWidget::_activeVehicleChanged); - - connect(HomePositionManager::instance(), SIGNAL(homePositionChanged(double,double,double)), this, SLOT(updateHomePosition(double,double,double)), Qt::UniqueConnection); - - foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles()) { - _vehicleAdded(vehicle); - } - - if (!mapInitialized) - { - internals::PointLatLng pos_lat_lon = internals::PointLatLng(0, 0); - - SetMouseWheelZoomType(internals::MouseWheelZoomType::MousePositionWithoutCenter); // set how the mouse wheel zoom functions - SetFollowMouse(true); // we want a contiuous mouse position reading - - SetShowHome(true); // display the HOME position on the map - Home->SetSafeArea(0); // set radius (meters) - Home->SetShowSafeArea(false); // show the safe area - Home->SetCoord(pos_lat_lon); // set the HOME position - - setFrameStyle(QFrame::NoFrame); // no border frame - setBackgroundBrush(QBrush(Qt::black)); // tile background - - if (!MultiVehicleManager::instance()->activeVehicle()) { - SetCurrentPosition(pos_lat_lon); // set the map position to default - } - - // Set home - updateHomePosition(HomePositionManager::instance()->getHomeLatitude(), HomePositionManager::instance()->getHomeLongitude(), HomePositionManager::instance()->getHomeAltitude()); - - // Set currently selected system - _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); - setFocus(); - - // Start timer - connect(&updateTimer, SIGNAL(timeout()), this, SLOT(updateGlobalPosition())); - mapInitialized = true; - //QTimer::singleShot(800, this, SLOT(loadSettings())); - } - updateTimer.start(maxUpdateInterval*1000); - // Update all UAV positions - updateGlobalPosition(); -} - -void QGCMapWidget::hideEvent(QHideEvent* event) -{ - updateTimer.stop(); - storeSettings(); - OPMapWidget::hideEvent(event); -} - -void QGCMapWidget::wheelEvent ( QWheelEvent * event ) -{ - if (!zoomBlocked) { - OPMapWidget::wheelEvent(event); - } -} - -/** - * @param changePosition Load also the last position from settings and update the map position. - */ -void QGCMapWidget::loadSettings(bool changePosition) -{ - // Atlantic Ocean near Africa, coordinate origin - double lastZoom = 1; - double lastLat = 0; - double lastLon = 0; - - QSettings settings; - settings.beginGroup("QGC_MAPWIDGET"); - if (changePosition) - { - lastLat = settings.value("LAST_LATITUDE", lastLat).toDouble(); - lastLon = settings.value("LAST_LONGITUDE", lastLon).toDouble(); - lastZoom = settings.value("LAST_ZOOM", lastZoom).toDouble(); - } - trailType = static_cast(settings.value("TRAIL_TYPE", trailType).toInt()); - trailInterval = settings.value("TRAIL_INTERVAL", trailInterval).toFloat(); - settings.endGroup(); - -#if 0 - // FIXME: NYI - // SET CORRECT MENU CHECKBOXES - // Set the correct trail interval - if (trailType == mapcontrol::UAVTrailType::ByDistance) - { - // XXX - qDebug() << "WARNING: Settings loading for trail type (ByDistance) not implemented"; - } - else if (trailType == mapcontrol::UAVTrailType::ByTimeElapsed) - { - // XXX - qDebug() << "WARNING: Settings loading for trail type (ByTimeElapsed) not implemented"; - } -#endif - - // SET TRAIL TYPE - foreach (mapcontrol::UAVItem* uav, GetUAVS()) - { - // Set the correct trail type - uav->SetTrailType(trailType); - // Set the correct trail interval - if (trailType == mapcontrol::UAVTrailType::ByDistance) - { - uav->SetTrailDistance(trailInterval); - } - else if (trailType == mapcontrol::UAVTrailType::ByTimeElapsed) - { - uav->SetTrailTime(trailInterval); - } - } - - // SET INITIAL POSITION AND ZOOM - internals::PointLatLng pos_lat_lon = internals::PointLatLng(lastLat, lastLon); - SetCurrentPosition(pos_lat_lon); // set the map position - SetZoom(lastZoom); // set map zoom level -} - -void QGCMapWidget::storeSettings() -{ - QSettings settings; - settings.beginGroup("QGC_MAPWIDGET"); - internals::PointLatLng pos = CurrentPosition(); - settings.setValue("LAST_LATITUDE", pos.Lat()); - settings.setValue("LAST_LONGITUDE", pos.Lng()); - settings.setValue("LAST_ZOOM", ZoomReal()); - settings.setValue("TRAIL_TYPE", static_cast(trailType)); - settings.setValue("TRAIL_INTERVAL", trailInterval); - settings.endGroup(); -} - -void QGCMapWidget::mouseDoubleClickEvent(QMouseEvent* event) -{ - // If a waypoint manager is available - if (currWPManager) - { - // Create new waypoint - internals::PointLatLng pos = map->FromLocalToLatLng(event->pos().x(), event->pos().y()); - MissionItem* wp = currWPManager->createWaypoint(); - wp->setLatitude(pos.Lat()); - wp->setLongitude(pos.Lng()); - wp->setFrame((MAV_FRAME)currWPManager->getFrameRecommendation()); - wp->setAltitude(currWPManager->getAltitudeRecommendation()); - } - - OPMapWidget::mouseDoubleClickEvent(event); -} - - -/** - * - * @param uas the UAS/MAV to monitor/display with the map widget - */ -void QGCMapWidget::_vehicleAdded(Vehicle* vehicle) -{ - UAS* uas = vehicle->uas(); - - connect(uas, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,double,quint64)), - this, SLOT(updateGlobalPosition(UASInterface*,double,double,double,double,quint64)), Qt::UniqueConnection); - connect(uas, SIGNAL(systemSpecsChanged(int)), this, SLOT(updateSystemSpecs(int)), Qt::UniqueConnection); - if (!waypointLines.value(uas->getUASID(), NULL)) { - waypointLines.insert(uas->getUASID(), new QGraphicsItemGroup(map)); - } else { - foreach (QGraphicsItem* item, waypointLines.value(uas->getUASID())->childItems()) - { - delete item; - } - } -} - -void QGCMapWidget::_activeVehicleChanged(Vehicle* vehicle) -{ - _uas = NULL; - - // Disconnect old MAV manager - if (currWPManager) - { - // Disconnect the waypoint manager / data storage from the UI - disconnect(currWPManager, SIGNAL(waypointEditableListChanged(int)), this, SLOT(updateWaypointList(int))); - disconnect(currWPManager, SIGNAL(waypointEditableChanged(int, MissionItem*)), this, SLOT(updateWaypoint(int,MissionItem*))); - disconnect(this, SIGNAL(waypointCreated(MissionItem*)), currWPManager, SLOT(addWaypointEditable(MissionItem*))); - disconnect(this, SIGNAL(waypointChanged(MissionItem*)), currWPManager, SLOT(notifyOfChangeEditable(MissionItem*))); - } - - // Attach the new waypoint manager if a new UAS was selected. Otherwise, indicate - // that no such manager exists. - if (vehicle) - { - _uas = vehicle->uas(); - - currWPManager = _uas->getWaypointManager(); - - updateSelectedSystem(vehicle->id()); - followUAVID = vehicle->id(); - updateWaypointList(vehicle->id()); - - // Connect the waypoint manager / data storage to the UI - connect(currWPManager, SIGNAL(waypointEditableListChanged(int)), this, SLOT(updateWaypointList(int)), Qt::UniqueConnection); - connect(currWPManager, SIGNAL(waypointEditableChanged(int, MissionItem*)), this, SLOT(updateWaypoint(int,MissionItem*)), Qt::UniqueConnection); - connect(this, SIGNAL(waypointCreated(MissionItem*)), currWPManager, SLOT(addWaypointEditable(MissionItem*)), Qt::UniqueConnection); - connect(this, SIGNAL(waypointChanged(MissionItem*)), currWPManager, SLOT(notifyOfChangeEditable(MissionItem*)), Qt::UniqueConnection); - - if (!mapPositionInitialized) { - internals::PointLatLng pos_lat_lon = internals::PointLatLng(_uas->getLatitude(), _uas->getLongitude()); - SetCurrentPosition(pos_lat_lon); - - // Zoom in - SetZoom(13); - - mapPositionInitialized = true; - } - } - else - { - currWPManager = NULL; - } -} - -/** - * Updates the global position of one MAV and append the last movement to the trail - * - * @param uas The unmanned air system - * @param lat Latitude in WGS84 ellipsoid - * @param lon Longitutde in WGS84 ellipsoid - * @param alt Altitude over mean sea level - * @param usec Timestamp of the position message in milliseconds FIXME will move to microseconds - */ -void QGCMapWidget::updateGlobalPosition(UASInterface* uas, double lat, double lon, double altAMSL, double altWGS84, quint64 usec) -{ - Q_UNUSED(usec); - Q_UNUSED(altAMSL); - - // Immediate update - if (maxUpdateInterval == 0) - { - // Get reference to graphic UAV item - mapcontrol::UAVItem* uav = GetUAV(uas->getUASID()); - // Check if reference is valid, else create a new one - if (uav == NULL) - { - MAV2DIcon* newUAV = new MAV2DIcon(map, this, uas); - newUAV->setParentItem(map); - UAVS.insert(uas->getUASID(), newUAV); - uav = GetUAV(uas->getUASID()); - // Set the correct trail type - uav->SetTrailType(trailType); - // Set the correct trail interval - if (trailType == mapcontrol::UAVTrailType::ByDistance) - { - uav->SetTrailDistance(trailInterval); - } - else if (trailType == mapcontrol::UAVTrailType::ByTimeElapsed) - { - uav->SetTrailTime(trailInterval); - } - } - - // Set new lat/lon position of UAV icon - internals::PointLatLng pos_lat_lon = internals::PointLatLng(lat, lon); - uav->SetUAVPos(pos_lat_lon, altWGS84); - // Follow status - if (followUAVEnabled && uas->getUASID() == followUAVID) SetCurrentPosition(pos_lat_lon); - // Convert from radians to degrees and apply - uav->SetUAVHeading((uas->getYaw()/M_PI)*180.0f); - } -} - -/** - * Pulls in the positions of all UAVs from the UAS manager - */ -void QGCMapWidget::updateGlobalPosition() -{ - foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles()) - { - UAS* system = vehicle->uas(); - - // Get reference to graphic UAV item - mapcontrol::UAVItem* uav = GetUAV(system->getUASID()); - // Check if reference is valid, else create a new one - if (uav == NULL) - { - MAV2DIcon* newUAV = new MAV2DIcon(map, this, system); - AddUAV(system->getUASID(), newUAV); - uav = newUAV; - uav->SetTrailTime(1); - uav->SetTrailDistance(5); - uav->SetTrailType(mapcontrol::UAVTrailType::ByTimeElapsed); - } - - // Set new lat/lon position of UAV icon - internals::PointLatLng pos_lat_lon = internals::PointLatLng(system->getLatitude(), system->getLongitude()); - uav->SetUAVPos(pos_lat_lon, system->getAltitudeAMSL()); - // Follow status - if (followUAVEnabled && system->getUASID() == followUAVID) SetCurrentPosition(pos_lat_lon); - // Convert from radians to degrees and apply - uav->SetUAVHeading((system->getYaw()/M_PI)*180.0f); - } -} - -void QGCMapWidget::updateLocalPosition() -{ - foreach (Vehicle* vehicle, MultiVehicleManager::instance()->vehicles()) - { - UAS* system = vehicle->uas(); - - // Get reference to graphic UAV item - mapcontrol::UAVItem* uav = GetUAV(system->getUASID()); - // Check if reference is valid, else create a new one - if (uav == NULL) - { - MAV2DIcon* newUAV = new MAV2DIcon(map, this, system); - AddUAV(system->getUASID(), newUAV); - uav = newUAV; - uav->SetTrailTime(1); - uav->SetTrailDistance(5); - uav->SetTrailType(mapcontrol::UAVTrailType::ByTimeElapsed); - } - - // Set new lat/lon position of UAV icon - internals::PointLatLng pos_lat_lon = internals::PointLatLng(system->getLatitude(), system->getLongitude()); - uav->SetUAVPos(pos_lat_lon, system->getAltitudeAMSL()); - // Follow status - if (followUAVEnabled && system->getUASID() == followUAVID) SetCurrentPosition(pos_lat_lon); - // Convert from radians to degrees and apply - uav->SetUAVHeading((system->getYaw()/M_PI)*180.0f); - } -} - -void QGCMapWidget::updateLocalPositionEstimates() -{ - updateLocalPosition(); -} - - -void QGCMapWidget::updateSystemSpecs(int uas) -{ - foreach (mapcontrol::UAVItem* p, UAVS.values()) - { - MAV2DIcon* icon = dynamic_cast(p); - if (icon && icon->getUASId() == uas) - { - // Set new airframe - icon->setAirframe(MultiVehicleManager::instance()->getVehicleById(uas)->uas()->getAirframe()); - icon->drawIcon(); - } - } -} - -/** - * Does not update the system type or configuration, only the selected status - */ -void QGCMapWidget::updateSelectedSystem(int uas) -{ - foreach (mapcontrol::UAVItem* p, UAVS.values()) - { - MAV2DIcon* icon = dynamic_cast(p); - if (icon) - { - // Set as selected if ids match - icon->setSelectedUAS((icon->getUASId() == uas)); - } - } -} - - -// MAP NAVIGATION -void QGCMapWidget::showGoToDialog() -{ - bool ok; - QString text = QInputDialog::getText(this, tr("Please enter coordinates"), - tr("Coordinates (Lat,Lon):"), QLineEdit::Normal, - QString("%1,%2").arg(CurrentPosition().Lat(), 0, 'g', 6).arg(CurrentPosition().Lng(), 0, 'g', 6), &ok); - if (ok && !text.isEmpty()) - { - QStringList split = text.split(","); - if (split.length() == 2) - { - bool convert; - double latitude = split.first().toDouble(&convert); - ok &= convert; - double longitude = split.last().toDouble(&convert); - ok &= convert; - - if (ok) - { - internals::PointLatLng pos_lat_lon = internals::PointLatLng(latitude, longitude); - SetCurrentPosition(pos_lat_lon); // set the map position - } - } - } -} - - -void QGCMapWidget::updateHomePosition(double latitude, double longitude, double altitude) -{ - qDebug() << "HOME SET TO: " << latitude << longitude << altitude; - Home->SetCoord(internals::PointLatLng(latitude, longitude)); - Home->SetAltitude(altitude); - homeAltitude = altitude; - SetShowHome(true); // display the HOME position on the map - Home->RefreshPos(); -} - -void QGCMapWidget::goHome() -{ - SetCurrentPosition(Home->Coord()); - SetZoom(17); -} - -/** - * Limits the update rate on the specified interval. Set to zero (0) to run at maximum - * telemetry speed. Recommended rate is 2 s. - */ -void QGCMapWidget::setUpdateRateLimit(float seconds) -{ - maxUpdateInterval = seconds; - updateTimer.start(maxUpdateInterval*1000); -} - -void QGCMapWidget::cacheVisibleRegion() -{ - internals::RectLatLng rect = map->SelectedArea(); - - if (rect.IsEmpty()) - { - QGCMessageBox::information(tr("Cannot cache tiles for offline use"), - tr("Please select an area first by holding down SHIFT or ALT and selecting the area with the left mouse button.")); - } - else - { - RipMap(); - // Set empty area = unselect area - map->SetSelectedArea(internals::RectLatLng()); - } -} - - -// WAYPOINT MAP INTERACTION FUNCTIONS - -void QGCMapWidget::handleMapWaypointEdit(mapcontrol::WayPointItem* waypoint) -{ - // Block circle updates - MissionItem* wp = iconsToWaypoints.value(waypoint, NULL); - - // Delete UI element if wp doesn't exist - if (!wp) - WPDelete(waypoint); - - // Update WP values - internals::PointLatLng pos = waypoint->Coord(); - - // Block waypoint signals - wp->blockSignals(true); - wp->setLatitude(pos.Lat()); - wp->setLongitude(pos.Lng()); - wp->blockSignals(false); - - -// internals::PointLatLng coord = waypoint->Coord(); -// QString coord_str = " " + QString::number(coord.Lat(), 'f', 6) + " " + QString::number(coord.Lng(), 'f', 6); -// qDebug() << "MAP WP COORD (MAP):" << coord_str << __FILE__ << __LINE__; -// QString wp_str = QString::number(wp->getLatitude(), 'f', 6) + " " + QString::number(wp->longitude(), 'f', 6); -// qDebug() << "MAP WP COORD (WP):" << wp_str << __FILE__ << __LINE__; - - // Protect from vicious double update cycle - if (firingWaypointChange == wp) { - return; - } - // Not in cycle, block now from entering it - firingWaypointChange = wp; - - emit waypointChanged(wp); -} - -// WAYPOINT UPDATE FUNCTIONS - -/** - * This function is called if a a single waypoint is updated and - * also if the whole list changes. - */ -void QGCMapWidget::updateWaypoint(int uas, MissionItem* wp) -{ - //qDebug() << __FILE__ << __LINE__ << "UPDATING WP FUNCTION CALLED"; - // Source of the event was in this widget, do nothing - if (firingWaypointChange == wp) { - return; - } - // Currently only accept waypoint updates from the UAS in focus - // this has to be changed to accept read-only updates from other systems as well. - UASInterface* uasInstance = MultiVehicleManager::instance()->getVehicleById(uas)->uas(); - if (currWPManager) - { - // Only accept waypoints in global coordinate frame - if (((wp->frame() == MAV_FRAME_GLOBAL) || (wp->frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT)) && wp->isNavigationType()) - { - // We're good, this is a global waypoint - - // Get the index of this waypoint - // note the call to getGlobalFrameAndNavTypeIndexOf() - // as we're only handling global waypoints - int wpindex = currWPManager->getGlobalFrameAndNavTypeIndexOf(wp); - // If not found, return (this should never happen, but helps safety) - if (wpindex < 0) return; - // Mark this wp as currently edited - firingWaypointChange = wp; - - qDebug() << "UPDATING WAYPOINT" << wpindex << "IN 2D MAP"; - - // Check if wp exists yet in map - if (!waypointsToIcons.contains(wp)) - { - // Create icon for new WP - QColor wpColor(Qt::red); - if (uasInstance) wpColor = uasInstance->getColor(); - Waypoint2DIcon* icon = new Waypoint2DIcon(map, this, wp, wpColor, wpindex); - ConnectWP(icon); - icon->setParentItem(map); - // Update maps to allow inverse data association - waypointsToIcons.insert(wp, icon); - iconsToWaypoints.insert(icon, wp); - - // Add line element if this is NOT the first waypoint - if (wpindex > 0) - { - // Get predecessor of this WP - QList wps = currWPManager->getGlobalFrameAndNavTypeWaypointList(); - MissionItem* wp1 = wps.at(wpindex-1); - mapcontrol::WayPointItem* prevIcon = waypointsToIcons.value(wp1, NULL); - // If we got a valid graphics item, continue - if (prevIcon) - { - mapcontrol::WaypointLineItem* line = new mapcontrol::WaypointLineItem(prevIcon, icon, wpColor, map); - line->setParentItem(map); - QGraphicsItemGroup* group = waypointLines.value(uas, NULL); - if (group) - { - group->addToGroup(line); - group->setParentItem(map); - } - } - } - } - else - { - // MissionItem exists, block it's signals and update it - mapcontrol::WayPointItem* icon = waypointsToIcons.value(wp); - // Make sure we don't die on a null pointer - // this should never happen, just a precaution - if (!icon) return; - // Block outgoing signals to prevent an infinite signal loop - // should not happen, just a precaution - this->blockSignals(true); - // Update the WP - Waypoint2DIcon* wpicon = dynamic_cast(icon); - if (wpicon) - { - // Let icon read out values directly from waypoint - icon->SetNumber(wpindex); - wpicon->updateWaypoint(); - } - else - { - // Use safe standard interfaces for non MissionItem-class based wps - icon->SetCoord(internals::PointLatLng(wp->latitude(), wp->longitude())); - icon->SetAltitude(wp->altitude()); - icon->SetHeading(wp->yawRadians()); - icon->SetNumber(wpindex); - } - // Re-enable signals again - this->blockSignals(false); - } - - firingWaypointChange = NULL; - - } - else - { - // Check if the index of this waypoint is larger than the global - // waypoint list. This implies that the coordinate frame of this - // waypoint was changed and the list containing only global - // waypoints was shortened. Thus update the whole list - if (waypointsToIcons.count() > currWPManager->getGlobalFrameAndNavTypeCount()) - { - updateWaypointList(uas); - } - } - } -} - -/** - * Update the whole list of waypoints. This is e.g. necessary if the list order changed. - * The UAS manager will emit the appropriate signal whenever updating the list - * is necessary. - */ -void QGCMapWidget::updateWaypointList(int uas) -{ - qDebug() << "UPDATE WP LIST IN 2D MAP CALLED FOR UAS" << uas; - // Currently only accept waypoint updates from the UAS in focus - // this has to be changed to accept read-only updates from other systems as well. - UASInterface* uasInstance = MultiVehicleManager::instance()->getVehicleById(uas)->uas(); - if (currWPManager) - { - // ORDER MATTERS HERE! - // TWO LOOPS ARE NEEDED - INFINITY LOOP ELSE - - qDebug() << "DELETING NOW OLD WPS"; - - // Delete connecting waypoint lines - QGraphicsItemGroup* group = waypointLines.value(uas, NULL); - if (group) - { - foreach (QGraphicsItem* item, group->childItems()) - { - delete item; - } - } - - // Delete first all old waypoints - // this is suboptimal (quadratic, but wps should stay in the sub-100 range anyway) - QList wps = currWPManager->getGlobalFrameAndNavTypeWaypointList(); - foreach (MissionItem* wp, waypointsToIcons.keys()) - { - if (!wps.contains(wp)) - { - // Get icon to work on - mapcontrol::WayPointItem* icon = waypointsToIcons.value(wp); - waypointsToIcons.remove(wp); - iconsToWaypoints.remove(icon); - WPDelete(icon); - } - } - - // Update all existing waypoints - foreach (MissionItem* wp, waypointsToIcons.keys()) - { - // Update remaining waypoints - updateWaypoint(uas, wp); - } - - // Update all potentially new waypoints - foreach (MissionItem* wp, wps) - { - qDebug() << "UPDATING NEW WP" << wp->sequenceNumber(); - // Update / add only if new - if (!waypointsToIcons.contains(wp)) updateWaypoint(uas, wp); - } - - // Add line element if this is NOT the first waypoint - mapcontrol::WayPointItem* prevIcon = NULL; - foreach (MissionItem* wp, wps) - { - mapcontrol::WayPointItem* currIcon = waypointsToIcons.value(wp, NULL); - // Do not work on first waypoint, but only increment counter - // do not continue if icon is invalid - if (prevIcon && currIcon) - { - // If we got a valid graphics item, continue - QColor wpColor(Qt::red); - if (uasInstance) wpColor = uasInstance->getColor(); - mapcontrol::WaypointLineItem* line = new mapcontrol::WaypointLineItem(prevIcon, currIcon, wpColor, map); - line->setParentItem(map); - QGraphicsItemGroup* group = waypointLines.value(uas, NULL); - if (group) - { - group->addToGroup(line); - group->setParentItem(map); - } - } - prevIcon = currIcon; - } - } -} - - -//// ADAPTER / HELPER FUNCTIONS -//float QGCMapWidget::metersToPixels(double meters) -//{ -// return meters/map->Projection()->GetGroundResolution(map->ZoomTotal(),coord.Lat()); -//} - -//double QGCMapWidget::headingP1P2(internals::PointLatLng p1, internals::PointLatLng p2) -//{ -// double lat1 = p1.Lat() * deg_to_rad; -// double lon1 = p2.Lng() * deg_to_rad; - -// double lat2 = p2.Lat() * deg_to_rad; -// double lon2 = p2.Lng() * deg_to_rad; - -// double delta_lon = lon2 - lon1; - -// double y = sin(delta_lon) * cos(lat2); -// double x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(delta_lon); -// double heading = atan2(y, x) * rad_to_deg; - -// heading += 360; -// while (heading < 0) bear += 360; -// while (heading >= 360) bear -= 360; - -// return heading; -//} - -//internals::PointLatLng QGCMapWidget::targetLatLon(internals::PointLatLng source, double heading, double dist) -//{ -// double lat1 = source.Lat() * deg_to_rad; -// double lon1 = source.Lng() * deg_to_rad; - -// heading *= deg_to_rad; - -// double ad = dist / earth_mean_radius; - -// double lat2 = asin(sin(lat1) * cos(ad) + cos(lat1) * sin(ad) * cos(heading)); -// double lon2 = lon1 + atan2(sin(bear) * sin(ad) * cos(lat1), cos(ad) - sin(lat1) * sin(lat2)); - -// return internals::PointLatLng(lat2 * rad_to_deg, lon2 * rad_to_deg); -//} diff --git a/src/ui/map/QGCMapWidget.h b/src/ui/map/QGCMapWidget.h deleted file mode 100644 index d2eb547ad..000000000 --- a/src/ui/map/QGCMapWidget.h +++ /dev/null @@ -1,185 +0,0 @@ -#ifndef QGCMAPWIDGET_H -#define QGCMAPWIDGET_H - -#include -#include - -#include "opmapcontrol.h" -#include "Vehicle.h" - -// Choose one default map type -//#define MAP_DEFAULT_TYPE_BING -#define MAP_DEFAULT_TYPE_GOOGLE -//#define MAP_DEFAULT_TYPE_OSM - -class UASInterface; -class UASWaypointManager; -class MissionItem; -typedef mapcontrol::WayPointItem WayPointItem; - -/** - * @brief Class representing a 2D map using aerial imagery - */ -class QGCMapWidget : public mapcontrol::OPMapWidget -{ - Q_OBJECT -public: - explicit QGCMapWidget(QWidget *parent = 0); - ~QGCMapWidget(); -// /** @brief Convert meters to pixels */ -// float metersToPixels(double meters); -// double headingP1P2(internals::PointLatLng p1, internals::PointLatLng p2); -// internals::PointLatLng targetLatLon(internals::PointLatLng source, double heading, double dist); - - /** @brief Map centered on current active system */ - bool getFollowUAVEnabled() { return followUAVEnabled; } - /** @brief The maximum map update rate */ - float getUpdateRateLimit() { return maxUpdateInterval; } - /** @brief Get the trail type */ - int getTrailType() { return static_cast(trailType); } - /** @brief Get the trail interval */ - float getTrailInterval() { return trailInterval; } - -signals: - void homePositionChanged(double latitude, double longitude, double altitude); - /** @brief Signal for newly created map waypoints */ - void waypointCreated(MissionItem* wp); - void waypointChanged(MissionItem* wp); - -public slots: - /** @brief Action triggered when guided action is selected from the context menu */ - void guidedActionTriggered(); - /** @brief Action triggered when guided action is selected from the context menu, allows for altitude selection */ - bool guidedAltActionTriggered(); - /** @brief Action triggered when set home action is selected from the context menu. */ - bool setHomeActionTriggered(); - /** @brief Update the global position of a system */ - void updateGlobalPosition(UASInterface* uas, double lat, double lon, double altAMSL, double altWGS84, quint64 usec); - /** @brief Update the global position of all systems */ - void updateGlobalPosition(); - /** @brief Update the local position and draw it converted to GPS reference */ - void updateLocalPosition(); - /** @brief Update the local position estimates (individual sensors) and draw it converted to GPS reference */ - void updateLocalPositionEstimates(); - /** @brief Update the type, size, etc. of this system */ - void updateSystemSpecs(int uas); - /** @brief Show a dialog to jump to given GPS coordinates */ - void showGoToDialog(); - /** @brief Jump to the home position on the map */ - void goHome(); - /** @brief Update this waypoint for this UAS */ - void updateWaypoint(int uas, MissionItem* wp); - /** @brief Update the whole waypoint */ - void updateWaypointList(int uas); - /** @brief Update the home position on the map */ - void updateHomePosition(double latitude, double longitude, double altitude); - /** @brief Set update rate limit */ - void setUpdateRateLimit(float seconds); - /** @brief Cache visible region to harddisk */ - void cacheVisibleRegion(); - /** @brief Set follow mode */ - void setFollowUAVEnabled(bool enabled) { followUAVEnabled = enabled; } - /** @brief Set trail to time mode and set time @param seconds The minimum time between trail dots in seconds. If set to a value < 0, trails will be disabled*/ - void setTrailModeTimed(int seconds) - { - foreach(mapcontrol::UAVItem* uav, GetUAVS()) - { - if (seconds >= 0) - { - uav->SetTrailTime(seconds); - uav->SetTrailType(mapcontrol::UAVTrailType::ByTimeElapsed); - } - else - { - uav->SetTrailType(mapcontrol::UAVTrailType::NoTrail); - } - } - } - /** @brief Set trail to distance mode and set time @param meters The minimum distance between trail dots in meters. The actual distance depends on the MAV's update rate as well. If set to a value < 0, trails will be disabled*/ - void setTrailModeDistance(int meters) - { - foreach(mapcontrol::UAVItem* uav, GetUAVS()) - { - if (meters >= 0) - { - uav->SetTrailDistance(meters); - uav->SetTrailType(mapcontrol::UAVTrailType::ByDistance); - } - else - { - uav->SetTrailType(mapcontrol::UAVTrailType::NoTrail); - } - } - } - /** @brief Delete all trails */ - void deleteTrails() - { - foreach(mapcontrol::UAVItem* uav, GetUAVS()) - { - uav->DeleteTrail(); - } - } - - void setZoomBlocked(bool blocked) - { - zoomBlocked = blocked; - } - - /** @brief Load the settings for this widget from disk */ - void loadSettings(bool changePosition=true); - /** @brief Store the settings for this widget to disk */ - void storeSettings(); - -protected slots: - /** @brief Convert a map edit into a QGC waypoint event */ - void handleMapWaypointEdit(WayPointItem* waypoint); - -protected: - /** @brief Update the highlighting of the currently controlled system */ - void updateSelectedSystem(int uas); - /** @brief Initialize */ - void showEvent(QShowEvent* event); - void hideEvent(QHideEvent* event); - void wheelEvent(QWheelEvent* event); - void mousePressEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void mouseDoubleClickEvent(QMouseEvent* event); - - //void contextMenuEvent(QContextMenuEvent *); - - UASWaypointManager* currWPManager; ///< The current waypoint manager - bool offlineMode; - QMap waypointsToIcons; - QMap iconsToWaypoints; - MissionItem* firingWaypointChange; - QTimer updateTimer; - float maxUpdateInterval; - enum editMode { - EDIT_MODE_NONE, - EDIT_MODE_WAYPOINTS, - EDIT_MODE_SWEEP, - EDIT_MODE_UAVS, - EDIT_MODE_HOME, - EDIT_MODE_SAFE_AREA, - EDIT_MODE_CACHING - }; - editMode currEditMode; ///< The current edit mode on the map - bool followUAVEnabled; ///< Does the map follow the UAV? - mapcontrol::UAVTrailType::Types trailType; ///< Time or distance based trail dots - float trailInterval; ///< Time or distance between trail items - int followUAVID; ///< Which UAV should be tracked? - bool mapInitialized; ///< Map initialized? - bool mapPositionInitialized; ///< The position on the map has a reasonable value? - float homeAltitude; ///< Home altitude - QPoint mousePressPos; ///< Mouse position when the button is released. - QPoint contextMousePressPos; ///< Mouse position when context menu activated. - int defaultGuidedAlt; ///< Default altitude for guided mode - bool zoomBlocked; ///< Wether zooming is blocked - UASInterface* _uas; ///< Currently selected UAS. - -private slots: - void _vehicleAdded(Vehicle* vehicle); - void _activeVehicleChanged(Vehicle* vehicle); -}; - -#endif // QGCMAPWIDGET_H diff --git a/src/ui/map/Waypoint2DIcon.cc b/src/ui/map/Waypoint2DIcon.cc deleted file mode 100644 index 1681d7f36..000000000 --- a/src/ui/map/Waypoint2DIcon.cc +++ /dev/null @@ -1,318 +0,0 @@ -#include "Waypoint2DIcon.h" -#include -#include "opmapcontrol.h" -#include "QGC.h" - -Waypoint2DIcon::Waypoint2DIcon(mapcontrol::MapGraphicItem* map, mapcontrol::OPMapWidget* parent, qreal latitude, qreal longitude, qreal altitude, int listindex, QString name, int radius) - : mapcontrol::WayPointItem(internals::PointLatLng(latitude, longitude), altitude, QString(), map), - parent(parent), - waypoint(), - radius(radius), - showAcceptanceRadius(true), - showOrbit(false), - color(Qt::red) -{ - Q_UNUSED(name); - - SetHeading(0); - SetNumber(listindex); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - picture = QPixmap(radius+1, radius+1); - autoreachedEnabled = false; // In contrast to the use in OpenPilot, we don't - // want to let the map interfere with the actual mission logic - // wether a WP is reached depends solely on the UAV's state machine - drawIcon(); -} - -Waypoint2DIcon::Waypoint2DIcon(mapcontrol::MapGraphicItem* map, mapcontrol::OPMapWidget* parent, MissionItem* wp, const QColor& color, int listindex, int radius) - : mapcontrol::WayPointItem(internals::PointLatLng(wp->latitude(), wp->longitude()), wp->altitude(), QString(), map), - parent(parent), - waypoint(wp), - radius(radius), - showAcceptanceRadius(true), - showOrbit(false), - color(color) -{ - SetHeading(wp->yawRadians()); - SetNumber(listindex); - this->setFlag(QGraphicsItem::ItemIgnoresTransformations,true); - picture = QPixmap(radius+1, radius+1); - autoreachedEnabled = false; // In contrast to the use in OpenPilot, we don't - // want to let the map interfere with the actual mission logic - // wether a WP is reached depends solely on the UAV's state machine - updateWaypoint(); -} - -Waypoint2DIcon::~Waypoint2DIcon() -{ -} - -void Waypoint2DIcon::SetHeading(float heading) -{ - mapcontrol::WayPointItem::SetHeading(heading); - drawIcon(); -} - -void Waypoint2DIcon::updateWaypoint() -{ - if (!waypoint.isNull()) { - // Store old size - static QRectF oldSize; - - SetHeading(waypoint->yawRadians()); - SetCoord(internals::PointLatLng(waypoint->latitude(), waypoint->longitude())); - - // qDebug() << "UPDATING WP:" << waypoint->sequenceNumber() << "LAT:" << waypoint->latitude() << "LON:" << waypoint->longitude(); - - SetAltitude(waypoint->altitude()); - // FIXME Add SetNumber (currently needs a separate call) - drawIcon(); - QRectF newSize = boundingRect(); - - // qDebug() << "WIDTH" << newSize.width() << "<" << oldSize.width(); - - // If new size is smaller than old size, update surrounding - if ((newSize.width() <= oldSize.width()) || (newSize.height() <= oldSize.height())) - { - // If the symbol size was reduced, enforce an update of the environment -// update(oldSize); - int oldWidth = oldSize.width() + 20; - int oldHeight = oldSize.height() + 20; - map->update(this->x()-10, this->y()-10, oldWidth, oldHeight); - //// qDebug() << "UPDATING DUE TO SMALLER SIZE"; - //// qDebug() << "X:" << this->x()-1 << "Y:" << this->y()-1 << "WIDTH:" << oldWidth << "HEIGHT:" << oldHeight; - } - else - { - // Symbol size stayed constant or increased, use new size for update - this->update(); - } - oldSize = boundingRect(); - } -} - -QRectF Waypoint2DIcon::boundingRect() const -{ - int loiter = 0; - int acceptance = 0; - internals::PointLatLng coord = (internals::PointLatLng)Coord(); - - if (!waypoint.isNull()) { - if (showAcceptanceRadius && (waypoint->command() == (int)MAV_CMD_NAV_WAYPOINT)) - { - acceptance = map->metersToPixels(waypoint->acceptanceRadius(), coord); - } - if (((waypoint->command() == (int)MAV_CMD_NAV_LOITER_UNLIM) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TIME) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TURNS))) - { - loiter = map->metersToPixels(waypoint->loiterOrbitRadius(), coord); - } - } - - int width = qMax(picture.width()/2, qMax(loiter, acceptance)); - int height = qMax(picture.height()/2, qMax(loiter, acceptance)); - - return QRectF(-width,-height,2*width,2*height); -} - -void Waypoint2DIcon::drawIcon() -{ - picture.fill(Qt::transparent); - QPainter painter(&picture); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::HighQualityAntialiasing, true); - - QFont font("Bitstream Vera Sans"); - int fontSize = picture.height()*0.8f; - font.setPixelSize(fontSize); - - QFontMetrics metrics = QFontMetrics(font); - int border = qMax(4, metrics.leading()); - painter.setFont(font); - painter.setRenderHint(QPainter::TextAntialiasing); - - - - QPen pen1(Qt::black); - pen1.setWidth(4); - QPen pen2(color); - pen2.setWidth(2); - painter.setBrush(Qt::NoBrush); - - int penWidth = pen1.width(); - - // DRAW WAYPOINT - QPointF p(picture.width()/2, picture.height()/2); - - QPolygonF poly(4); - // Top point - poly.replace(0, QPointF(p.x(), p.y()-picture.height()/2.0f+penWidth/2)); - // Right point - poly.replace(1, QPointF(p.x()+picture.width()/2.0f-penWidth/2, p.y())); - // Bottom point - poly.replace(2, QPointF(p.x(), p.y() + picture.height()/2.0f-penWidth/2)); - poly.replace(3, QPointF(p.x() - picture.width()/2.0f+penWidth/2, p.y())); - - int waypointSize = qMin(picture.width(), picture.height()); - float rad = (waypointSize/2.0f) * 0.7f * (1/sqrt(2.0f)); - - // If this is not a waypoint (only the default representation) - // or it is a waypoint, but not one where direction has no meaning - // then draw the heading indicator - if (waypoint.isNull() || (waypoint && ( - (waypoint->command() != (int)MAV_CMD_NAV_TAKEOFF) && - (waypoint->command() != (int)MAV_CMD_NAV_LAND) && - (waypoint->command() != (int)MAV_CMD_NAV_LOITER_UNLIM) && - (waypoint->command() != (int)MAV_CMD_NAV_LOITER_TIME) && - (waypoint->command() != (int)MAV_CMD_NAV_LOITER_TURNS) && - (waypoint->command() != (int)MAV_CMD_NAV_RETURN_TO_LAUNCH) - ))) - { - painter.setPen(pen1); - painter.drawLine(p.x(), p.y(), p.x()+sin(Heading()/180.0f*M_PI) * rad, p.y()-cos(Heading()/180.0f*M_PI) * rad); - painter.setPen(pen2); - painter.drawLine(p.x(), p.y(), p.x()+sin(Heading()/180.0f*M_PI) * rad, p.y()-cos(Heading()/180.0f*M_PI) * rad); - } - - if (((!waypoint.isNull())) && (waypoint->command() == (int)MAV_CMD_NAV_TAKEOFF)) - { - // Takeoff waypoint - int width = picture.width()-penWidth; - int height = picture.height()-penWidth; - - painter.setPen(pen1); - painter.drawRect(penWidth/2, penWidth/2, width, height); - painter.setPen(pen2); - painter.drawRect(penWidth/2, penWidth/2, width, height); - - painter.setPen(pen1); - painter.drawRect(width*0.3, height*0.3f, width*0.6f, height*0.6f); - painter.setPen(pen2); - painter.drawRect(width*0.3, height*0.3f, width*0.6f, height*0.6f); - } - else if (((!waypoint.isNull())) && (waypoint->command() == (int)MAV_CMD_NAV_LAND)) - { - // Landing waypoint - int width = (picture.width())/2-penWidth; - int height = (picture.height())/2-penWidth; - painter.setPen(pen1); - painter.drawEllipse(p, width, height); - painter.drawLine(p.x()-width/2, p.y()-height/2, 2*width, 2*height); - painter.setPen(pen2); - painter.drawEllipse(p, width, height); - painter.drawLine(p.x()-width/2, p.y()-height/2, 2*width, 2*height); - } - else if (((!waypoint.isNull())) && ((waypoint->command() == (int)MAV_CMD_NAV_LOITER_UNLIM) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TIME) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TURNS))) - { - // Loiter waypoint - int width = (picture.width()-penWidth)/2; - int height = (picture.height()-penWidth)/2; - painter.setPen(pen1); - painter.drawEllipse(p, width, height); - painter.drawPoint(p); - painter.setPen(pen2); - painter.drawEllipse(p, width, height); - painter.drawPoint(p); - } - else if (((!waypoint.isNull())) && (waypoint->command() == (int)MAV_CMD_NAV_RETURN_TO_LAUNCH)) - { - // Return to launch waypoint - int width = picture.width()-penWidth; - int height = picture.height()-penWidth; - painter.setPen(pen1); - painter.drawRect(penWidth/2, penWidth/2, width, height); - painter.setPen(pen2); - painter.drawRect(penWidth/2, penWidth/2, width, height); - - QString text("R"); - - painter.setPen(pen1); - QRect rect = metrics.boundingRect(0, 0, width - 2*border, height, Qt::AlignLeft | Qt::TextWordWrap, text); - painter.drawText(width/4, height/6, rect.width(), rect.height(), - Qt::AlignCenter | Qt::TextWordWrap, text); - painter.setPen(pen2); - - font.setPixelSize(fontSize*0.85f); - painter.setFont(font); - painter.drawText(width/4, height/6, rect.width(), rect.height(), Qt::AlignCenter | Qt::TextWordWrap, text); - } - else - { - // Navigation waypoint - painter.setPen(pen1); - painter.drawPolygon(poly); - painter.setPen(pen2); - painter.drawPolygon(poly); - } -} - -void Waypoint2DIcon::SetShowNumber(const bool &value) -{ - shownumber=value; - if((numberI==0) && value) - { - numberI=new QGraphicsSimpleTextItem(this); - numberIBG=new QGraphicsRectItem(this); - numberIBG->setBrush(Qt::black); - numberIBG->setOpacity(0.5); - numberI->setZValue(3); - numberI->setPen(QPen(QGC::colorCyan)); - numberI->setPos(5,-picture.height()); - numberIBG->setPos(5,-picture.height()); - numberI->setText(QString::number(number)); - numberIBG->setRect(numberI->boundingRect().adjusted(-2,0,1,0)); - } - else if (!value && numberI) - { - delete numberI; - delete numberIBG; - } - this->update(); -} - -void Waypoint2DIcon::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) -{ - Q_UNUSED(option); - Q_UNUSED(widget); - QPen pen = painter->pen(); - pen.setWidth(2); - painter->drawPixmap(-picture.width()/2,-picture.height()/2,picture); - if (this->isSelected()) - { - pen.setColor(Qt::yellow); - painter->drawRect(QRectF(-picture.width()/2,-picture.height()/2,picture.width()-1,picture.height()-1)); - } - - QPen penBlack(Qt::black); - penBlack.setWidth(4); - pen.setColor(color); - - if ((!waypoint.isNull()) && (waypoint->command() == (int)MAV_CMD_NAV_WAYPOINT) && showAcceptanceRadius) - { - QPen redPen = QPen(pen); - redPen.setColor(Qt::yellow); - redPen.setWidth(1); - painter->setPen(redPen); - const int acceptance = map->metersToPixels(waypoint->acceptanceRadius(), Coord()); - if (acceptance > 0) { - painter->setPen(penBlack); - painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); - painter->setPen(redPen); - painter->drawEllipse(QPointF(0, 0), acceptance, acceptance); - } - } - if ((!waypoint.isNull()) && ((waypoint->command() == (int)MAV_CMD_NAV_LOITER_UNLIM) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TIME) || (waypoint->command() == (int)MAV_CMD_NAV_LOITER_TURNS))) - { - QPen penDash(color); - penDash.setWidth(1); - //penDash.setStyle(Qt::DotLine); - // A negative radius indicates counter-clockwise rotation, but we still want to draw it positive - const int loiter = map->metersToPixels(fabs(waypoint->loiterOrbitRadius()), Coord()); - if (loiter > picture.width()/2) - { - painter->setPen(penBlack); - painter->drawEllipse(QPointF(0, 0), loiter, loiter); - painter->setPen(penDash); - painter->drawEllipse(QPointF(0, 0), loiter, loiter); - } - } -} diff --git a/src/ui/map/Waypoint2DIcon.h b/src/ui/map/Waypoint2DIcon.h deleted file mode 100644 index 8d23fc3b8..000000000 --- a/src/ui/map/Waypoint2DIcon.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef WAYPOINT2DICON_H -#define WAYPOINT2DICON_H - -#include - -#include "MissionItem.h" -#include "opmapcontrol.h" - -class Waypoint2DIcon : public mapcontrol::WayPointItem -{ -public: - /** - * - * @param latitude - * @param longitude - * @param name name of the circle point - */ - Waypoint2DIcon(mapcontrol::MapGraphicItem* map, mapcontrol::OPMapWidget* parent, qreal latitude, qreal longitude, qreal altitude, int listindex, QString name = QString(), int radius=30); - - /** - * - * @param wp MissionItem - * @param radius the radius of the circle - */ - Waypoint2DIcon(mapcontrol::MapGraphicItem* map, mapcontrol::OPMapWidget* parent, MissionItem* wp, const QColor& color, int listindex, int radius = 31); - - virtual ~Waypoint2DIcon(); - - void SetHeading(float heading); - - /** @brief Rectangle to be updated on changes */ - QRectF boundingRect() const; - /** @brief Draw the icon in a double buffer */ - void drawIcon(); - /** @brief Draw the icon on a QPainter device (map) */ - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - /** @brief Enable and format the waypoint number display */ - void SetShowNumber(const bool &value); - -public: - void updateWaypoint(); - -protected: - mapcontrol::OPMapWidget* parent; ///< Parent widget - QPointer waypoint; ///< MissionItem data container this icon represents - int radius; ///< Radius / diameter of the icon in pixels - bool showAcceptanceRadius; - bool showOrbit; - QColor color; -// QSize size; - -}; - -#endif // WAYPOINT2DICON_H diff --git a/src/ui/mapdisplay/MapDisplay.qml b/src/ui/mapdisplay/MapDisplay.qml deleted file mode 100644 index 20526821f..000000000 --- a/src/ui/mapdisplay/MapDisplay.qml +++ /dev/null @@ -1,170 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2015 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief QGC Main Map Display - * @author Gus Grubba - */ - -import QtQuick 2.3 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.2 -import QtQuick.Layouts 1.1 - -import QGroundControl.Palette 1.0 -import QGroundControl.Controls 1.0 -import QGroundControl.FlightMap 1.0 - -Rectangle { - QGCPalette { id: __palette; colorGroupEnabled: true } - id: root - color: Qt.rgba(0,0,0,0); - - property real roll: isNaN(mapEngine.roll) ? 0 : mapEngine.roll - property real pitch: isNaN(mapEngine.pitch) ? 0 : mapEngine.pitch - property bool showWaypointEditor: true - - SplitView { - id: splitView - anchors.fill: parent - orientation: Qt.Horizontal - z: 10 - - // This sets the color of the splitter line - handleDelegate: Rectangle { - width: 1 - height: 1 - color: __palette.window - } - - //---------------------------------------------------------------------------------------- - // Map View - FlightMap { - id: mapBackground - Layout.fillWidth: true - Layout.minimumWidth: 300 - heading: isNaN(mapEngine.heading) ? 0 : mapEngine.heading - latitude: 37.803784 // mapEngine.latitude - longitude: -122.462276 // mapEngine.longitude - showWaypoints: true - mapName: 'MainMapDisplay' - - // Chevron button at upper right corner of Map Display - Item { - id: openWaypoints - anchors.top: mapBackground.top - anchors.right: mapBackground.right - width: 30 - height: 30 - opacity: 0.85 - z: splitView.z + 10 - Image { - id: buttomImg - anchors.fill: parent - source: showWaypointEditor ? "/qmlimages/buttonRight.svg" : "/qmlimages/buttonLeft.svg" - mipmap: true - smooth: true - antialiasing: true - fillMode: Image.PreserveAspectFit - } - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.LeftButton - onClicked: { - if (mouse.button == Qt.LeftButton) - { - showWaypointEditor = !showWaypointEditor - } - } - } - } - } - //---------------------------------------------------------------------------------------- - // MissionItem Editor - QGCWaypointEditor { - id: waypointEditor - Layout.minimumWidth: 200 - visible: showWaypointEditor - } - } - - //-------------------------------------------------------------------------------------------- - // Right click anywhere on the map for a context menu - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.RightButton - onClicked: { - if (mouse.button == Qt.RightButton) - { - mapBackground.mapMenu.popup() - } - } - z: splitView.z + 5 - } - - //-------------------------------------------------------------------------------------------- - // Tool Bar - Rectangle { - id: toolBar - color: Qt.rgba(0,0,0,0) - height: buttonColumn.height - visible: showWaypointEditor - anchors.top: parent.top - anchors.left: parent.left - anchors.topMargin: 40 - anchors.leftMargin: 4 - z: splitView.z + 10 - - ExclusiveGroup { id: mainActionGroup } - - Column { - id: buttonColumn - spacing: 4 - QGCMapToolButton { - width: 50 - height: 50 - imageSource: "/qmlimages/buttonHome.svg" - exclusiveGroup: mainActionGroup - } - QGCMapToolButton { - width: 50 - height: 50 - imageSource: "/qmlimages/buttonHome.svg" - exclusiveGroup: mainActionGroup - } - QGCMapToolButton { - width: 50 - height: 50 - imageSource: "/qmlimages/buttonHome.svg" - exclusiveGroup: mainActionGroup - } - QGCMapToolButton { - width: 50 - height: 50 - imageSource: "/qmlimages/buttonHome.svg" - exclusiveGroup: mainActionGroup - } - } - } -} diff --git a/src/ui/mapdisplay/QGCMapDisplay.cc b/src/ui/mapdisplay/QGCMapDisplay.cc deleted file mode 100644 index 2c4ce9f04..000000000 --- a/src/ui/mapdisplay/QGCMapDisplay.cc +++ /dev/null @@ -1,93 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2015 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief QGC Main Map Display - * @author Gus Grubba - */ - -#include -#include -#include - -#include "ScreenToolsController.h" -#include "QGCMapDisplay.h" - -const char* kMainMapDisplayGroup = "MainMapDisplay"; - -QGCMapDisplay::QGCMapDisplay(QWidget *parent) - : QGCQmlWidgetHolder(parent) -{ - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - setObjectName("MainMapDisplay"); - // Get rid of layout default margins - QLayout* pl = layout(); - if(pl) { - pl->setContentsMargins(0,0,0,0); - } -#ifndef __android__ - setMinimumWidth( 32 * ScreenToolsController::defaultFontPixelSize_s()); - setMinimumHeight(33 * ScreenToolsController::defaultFontPixelSize_s()); -#endif - setContextPropertyObject("mapEngine", this); - setSource(QUrl::fromUserInput("qrc:/qml/MapDisplay.qml")); - setVisible(true); -} - -QGCMapDisplay::~QGCMapDisplay() -{ - -} - -void QGCMapDisplay::saveSetting(const QString &name, const QString& value) -{ - QSettings settings; - QString key(kMainMapDisplayGroup); - key += "/" + name; - settings.setValue(key, value); -} - -QString QGCMapDisplay::loadSetting(const QString &name, const QString& defaultValue) -{ - QSettings settings; - QString key(kMainMapDisplayGroup); - key += "/" + name; - return settings.value(key, defaultValue).toString(); -} - -/* - * Internal - */ - -void QGCMapDisplay::showEvent(QShowEvent* event) -{ - // React only to internal (pre-display) events - QWidget::showEvent(event); -} - -void QGCMapDisplay::hideEvent(QHideEvent* event) -{ - // React only to internal (pre-display) events - QWidget::hideEvent(event); -} diff --git a/src/ui/mapdisplay/QGCMapDisplay.h b/src/ui/mapdisplay/QGCMapDisplay.h deleted file mode 100644 index 86aca81b7..000000000 --- a/src/ui/mapdisplay/QGCMapDisplay.h +++ /dev/null @@ -1,65 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2015 QGROUNDCONTROL PROJECT - -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 . - -======================================================================*/ - -/** - * @file - * @brief QGC Main Map Display - * @author Gus Grubba - */ - -#ifndef QGCMAPDISPLAY_H -#define QGCMAPDISPLAY_H - -#include "QGCQmlWidgetHolder.h" - -class UASInterface; -class UASWaypointManager; - -class QGCMapDisplay : public QGCQmlWidgetHolder -{ - Q_OBJECT -public: - QGCMapDisplay(QWidget* parent = NULL); - ~QGCMapDisplay(); - - Q_INVOKABLE void saveSetting (const QString &key, const QString& value); - Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue); - - /** @brief Start updating widget */ - void showEvent(QShowEvent* event); - /** @brief Stop updating widget */ - void hideEvent(QHideEvent* event); - -signals: - -private slots: - -private: - -private: - UASWaypointManager* WPM; - -}; - - -#endif // QGCFLIGHTDISPLAY_H diff --git a/src/ui/mission/QGCMissionConditionDelay.cc b/src/ui/mission/QGCMissionConditionDelay.cc deleted file mode 100644 index 2e1908ac2..000000000 --- a/src/ui/mission/QGCMissionConditionDelay.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "QGCMissionConditionDelay.h" -#include "ui_QGCMissionConditionDelay.h" -#include "WaypointEditableView.h" - -QGCMissionConditionDelay::QGCMissionConditionDelay(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionConditionDelay) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->param1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->param1SpinBox,SLOT(setValue(double))); -} - -QGCMissionConditionDelay::~QGCMissionConditionDelay() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionConditionDelay.h b/src/ui/mission/QGCMissionConditionDelay.h deleted file mode 100644 index b9d2af900..000000000 --- a/src/ui/mission/QGCMissionConditionDelay.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QGCMISSIONCONDITIONDELAY_H -#define QGCMISSIONCONDITIONDELAY_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionConditionDelay; -} - -class QGCMissionConditionDelay : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionConditionDelay(WaypointEditableView* WEV); - ~QGCMissionConditionDelay(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionConditionDelay *ui; -}; - -#endif // QGCMISSIONCONDITIONDELAY_H diff --git a/src/ui/mission/QGCMissionConditionDelay.ui b/src/ui/mission/QGCMissionConditionDelay.ui deleted file mode 100644 index 2fc8980db..000000000 --- a/src/ui/mission/QGCMissionConditionDelay.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - QGCMissionConditionDelay - - - - 0 - 0 - 448 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Delay duration - - - Delay duration - - - false - - - true - - - true - - - false - - - Duration: - - - s - - - 2 - - - 0.000000000000000 - - - 100000.000000000000000 - - - 1.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionDoFinishSearch.cc b/src/ui/mission/QGCMissionDoFinishSearch.cc deleted file mode 100644 index d13374e79..000000000 --- a/src/ui/mission/QGCMissionDoFinishSearch.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "QGCMissionDoFinishSearch.h" -#include "ui_QGCMissionDoFinishSearch.h" -#include "WaypointEditableView.h" - -QGCMissionDoFinishSearch::QGCMissionDoFinishSearch(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionDoFinishSearch) -{ - ui->setupUi(this); - this->WEV = WEV; - //Using UI to change WP: - connect(this->ui->param1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - connect(this->ui->param2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - //connect(this->ui->param4SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - //connect(this->ui->param5SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double))); - //connect(this->ui->param6SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - //connect(this->ui->param7SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - - //Reading WP to update UI: - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->param1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->param2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->param4SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->param5SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->param6SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->param7SpinBox,SLOT(setValue(double))); -} - -QGCMissionDoFinishSearch::~QGCMissionDoFinishSearch() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionDoFinishSearch.h b/src/ui/mission/QGCMissionDoFinishSearch.h deleted file mode 100644 index 2ad076204..000000000 --- a/src/ui/mission/QGCMissionDoFinishSearch.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef QGCMISSIONDOFINISHSEARCH_H -#define QGCMISSIONDOFINISHSEARCH_H - -#include -#include "WaypointEditableView.h" -namespace Ui { - class QGCMissionDoFinishSearch; -} - -class QGCMissionDoFinishSearch : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionDoFinishSearch(WaypointEditableView* WEV); - ~QGCMissionDoFinishSearch(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionDoFinishSearch *ui; -}; - -#endif // QGCMISSIONDOFINISHSEARCH_H diff --git a/src/ui/mission/QGCMissionDoFinishSearch.ui b/src/ui/mission/QGCMissionDoFinishSearch.ui deleted file mode 100644 index e2099b98e..000000000 --- a/src/ui/mission/QGCMissionDoFinishSearch.ui +++ /dev/null @@ -1,129 +0,0 @@ - - - QGCMissionDoFinishSearch - - - - 0 - 0 - 499 - 27 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - 5 - - - 0 - - - - - Jump to this index, if search successful - - - Jump to this index, if search successful - - - - - - false - - - Jump to index: - - - - - - 0 - - - 0.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Jump to this index, if search unsuccessful - - - Jump to this index, if search unsuccessful - - - - - - false - - - Jump to index: - - - 0 - - - 0.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Remaining number of jumps. Terminate search if jumps == 0. - - - Remaining number of jumps. Terminate search if jumps == 0. - - - - - - false - - - - - - time(s) - - - 0 - - - 0.000000000000000 - - - 2147483647.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionDoJump.cc b/src/ui/mission/QGCMissionDoJump.cc deleted file mode 100644 index e6080938d..000000000 --- a/src/ui/mission/QGCMissionDoJump.cc +++ /dev/null @@ -1,24 +0,0 @@ -#include "QGCMissionDoJump.h" -#include "ui_QGCMissionDoJump.h" -#include "WaypointEditableView.h" - -QGCMissionDoJump::QGCMissionDoJump(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionDoJump) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->param1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - connect(this->ui->param2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->param1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->param2SpinBox,SLOT(setValue(double))); -} - -QGCMissionDoJump::~QGCMissionDoJump() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionDoJump.h b/src/ui/mission/QGCMissionDoJump.h deleted file mode 100644 index d5d602946..000000000 --- a/src/ui/mission/QGCMissionDoJump.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QGCMISSIONDOJUMP_H -#define QGCMISSIONDOJUMP_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionDoJump; -} - -class QGCMissionDoJump : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionDoJump(WaypointEditableView* WEV); - ~QGCMissionDoJump(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionDoJump *ui; -}; - -#endif // QGCMISSIONDOJUMP_H diff --git a/src/ui/mission/QGCMissionDoJump.ui b/src/ui/mission/QGCMissionDoJump.ui deleted file mode 100644 index 1fe1e4dd2..000000000 --- a/src/ui/mission/QGCMissionDoJump.ui +++ /dev/null @@ -1,134 +0,0 @@ - - - QGCMissionDoJump - - - - 0 - 0 - 448 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Mission element ID to jump to - - - Mission element ID to jump to - - - false - - - true - - - true - - - false - - - Jump to index - - - - - - 0 - - - 0.000000000000000 - - - 10000.000000000000000 - - - 1.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Maximal number of jumps - - - Maximal number of jumps - - - false - - - - - - time(s) - - - 0 - - - 0.000000000000000 - - - 10000.000000000000000 - - - 1.000000000000000 - - - 1.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionDoStartSearch.cc b/src/ui/mission/QGCMissionDoStartSearch.cc deleted file mode 100644 index 61d552a30..000000000 --- a/src/ui/mission/QGCMissionDoStartSearch.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "QGCMissionDoStartSearch.h" -#include "ui_QGCMissionDoStartSearch.h" -#include "WaypointEditableView.h" - -QGCMissionDoStartSearch::QGCMissionDoStartSearch(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionDoStartSearch) -{ - ui->setupUi(this); - this->WEV = WEV; - //Using UI to change WP: - connect(this->ui->param1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - connect(this->ui->param2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - //connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - //connect(this->ui->param4SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - //connect(this->ui->param5SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double))); - //connect(this->ui->param6SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - //connect(this->ui->param7SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - - //Reading WP to update UI: - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->param1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->param2SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->param4SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->param5SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->param6SpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->param7SpinBox,SLOT(setValue(double))); -} - -QGCMissionDoStartSearch::~QGCMissionDoStartSearch() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionDoStartSearch.h b/src/ui/mission/QGCMissionDoStartSearch.h deleted file mode 100644 index e4c137640..000000000 --- a/src/ui/mission/QGCMissionDoStartSearch.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QGCMISSIONDOSTARTSEARCH_H -#define QGCMISSIONDOSTARTSEARCH_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionDoStartSearch; -} - -class QGCMissionDoStartSearch : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionDoStartSearch(WaypointEditableView* WEV); - ~QGCMissionDoStartSearch(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionDoStartSearch *ui; -}; - -#endif // QGCMISSIONDOSTARTSEARCH_H diff --git a/src/ui/mission/QGCMissionDoStartSearch.ui b/src/ui/mission/QGCMissionDoStartSearch.ui deleted file mode 100644 index 51887f6ed..000000000 --- a/src/ui/mission/QGCMissionDoStartSearch.ui +++ /dev/null @@ -1,92 +0,0 @@ - - - QGCMissionDoStartSearch - - - - 0 - 0 - 482 - 27 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - 5 - - - 0 - - - - - Minimal required detection confidence - - - Minimal required detection confidence - - - false - - - Conf: - - - 3 - - - 0.000000000000000 - - - 100.000000000000000 - - - 0.100000000000000 - - - - - - - Required number of detections - - - Required number of detections - - - false - - - #det: - - - 0 - - - 0.000000000000000 - - - 2147483647.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavLand.cc b/src/ui/mission/QGCMissionNavLand.cc deleted file mode 100644 index 3f6bca227..000000000 --- a/src/ui/mission/QGCMissionNavLand.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "QGCMissionNavLand.h" -#include "ui_QGCMissionNavLand.h" -#include "WaypointEditableView.h" - -QGCMissionNavLand::QGCMissionNavLand(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavLand) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - //connect(this->ui->holdTimeSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - //connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - //connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->holdTimeSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); -} - -void QGCMissionNavLand::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavLand::~QGCMissionNavLand() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavLand.h b/src/ui/mission/QGCMissionNavLand.h deleted file mode 100644 index 5dfc0f323..000000000 --- a/src/ui/mission/QGCMissionNavLand.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVLAND_H -#define QGCMISSIONNAVLAND_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavLand; -} - -class QGCMissionNavLand : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavLand(WaypointEditableView* WEV); - ~QGCMissionNavLand(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavLand *ui; -}; - -#endif // QGCMISSIONNAVLAND_H diff --git a/src/ui/mission/QGCMissionNavLand.ui b/src/ui/mission/QGCMissionNavLand.ui deleted file mode 100644 index 264283fb3..000000000 --- a/src/ui/mission/QGCMissionNavLand.ui +++ /dev/null @@ -1,319 +0,0 @@ - - - QGCMissionNavLand - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavLoiterTime.cc b/src/ui/mission/QGCMissionNavLoiterTime.cc deleted file mode 100644 index e7c7db01b..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTime.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "QGCMissionNavLoiterTime.h" -#include "ui_QGCMissionNavLoiterTime.h" -#include "WaypointEditableView.h" - -QGCMissionNavLoiterTime::QGCMissionNavLoiterTime(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavLoiterTime) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->timeSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->radSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->timeSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->radSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); -} - -void QGCMissionNavLoiterTime::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavLoiterTime::~QGCMissionNavLoiterTime() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavLoiterTime.h b/src/ui/mission/QGCMissionNavLoiterTime.h deleted file mode 100644 index 9f8619698..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTime.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVLOITERTIME_H -#define QGCMISSIONNAVLOITERTIME_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavLoiterTime; -} - -class QGCMissionNavLoiterTime : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavLoiterTime(WaypointEditableView* WEV); - ~QGCMissionNavLoiterTime(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavLoiterTime *ui; -}; - -#endif // QGCMISSIONNAVLOITERTIME_H diff --git a/src/ui/mission/QGCMissionNavLoiterTime.ui b/src/ui/mission/QGCMissionNavLoiterTime.ui deleted file mode 100644 index 3fb94202e..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTime.ui +++ /dev/null @@ -1,384 +0,0 @@ - - - QGCMissionNavLoiterTime - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - 0 - 0 - - - - Loiter Radius. If negative loiter counter-clockwise - - - Loiter Radius. If negative loiter counter-clockwise - - - false - - - m - - - -1000000.000000000000000 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Time to loiter around the mission point - - - Time to loiter around the mission point - - - false - - - s - - - 2 - - - 0.000000000000000 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavLoiterTurns.cc b/src/ui/mission/QGCMissionNavLoiterTurns.cc deleted file mode 100644 index 755ae784c..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTurns.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "QGCMissionNavLoiterTurns.h" -#include "ui_QGCMissionNavLoiterTurns.h" -#include "WaypointEditableView.h" - -QGCMissionNavLoiterTurns::QGCMissionNavLoiterTurns(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavLoiterTurns) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->turnsSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->radSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->turnsSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->radSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); -} - -void QGCMissionNavLoiterTurns::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavLoiterTurns::~QGCMissionNavLoiterTurns() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavLoiterTurns.h b/src/ui/mission/QGCMissionNavLoiterTurns.h deleted file mode 100644 index 038ebad6a..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTurns.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVLOITERTURNS_H -#define QGCMISSIONNAVLOITERTURNS_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavLoiterTurns; -} - -class QGCMissionNavLoiterTurns : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavLoiterTurns(WaypointEditableView* WEV); - ~QGCMissionNavLoiterTurns(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavLoiterTurns *ui; -}; - -#endif // QGCMISSIONNAVLOITERTURNS_H diff --git a/src/ui/mission/QGCMissionNavLoiterTurns.ui b/src/ui/mission/QGCMissionNavLoiterTurns.ui deleted file mode 100644 index b3c1dd90a..000000000 --- a/src/ui/mission/QGCMissionNavLoiterTurns.ui +++ /dev/null @@ -1,384 +0,0 @@ - - - QGCMissionNavLoiterTurns - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - 0 - 0 - - - - Loiter Radius. If negative loiter counter-clockwise - - - Loiter Radius. If negative loiter counter-clockwise - - - false - - - m - - - -1000000.000000000000000 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Number of turns around the loiter point - - - Number of turns around the loiter point - - - false - - - turns - - - 0 - - - 0.000000000000000 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavLoiterUnlim.cc b/src/ui/mission/QGCMissionNavLoiterUnlim.cc deleted file mode 100644 index 8e33e27d0..000000000 --- a/src/ui/mission/QGCMissionNavLoiterUnlim.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "QGCMissionNavLoiterUnlim.h" -#include "ui_QGCMissionNavLoiterUnlim.h" -#include "WaypointEditableView.h" - -QGCMissionNavLoiterUnlim::QGCMissionNavLoiterUnlim(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavLoiterUnlim) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - //connect(this->ui->holdTimeSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->radSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - //connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->holdTimeSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->radSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); -} - -void QGCMissionNavLoiterUnlim::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavLoiterUnlim::~QGCMissionNavLoiterUnlim() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavLoiterUnlim.h b/src/ui/mission/QGCMissionNavLoiterUnlim.h deleted file mode 100644 index 954a75292..000000000 --- a/src/ui/mission/QGCMissionNavLoiterUnlim.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVLOITERUNLIM_H -#define QGCMISSIONNAVLOITERUNLIM_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavLoiterUnlim; -} - -class QGCMissionNavLoiterUnlim : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavLoiterUnlim(WaypointEditableView* WEV); - ~QGCMissionNavLoiterUnlim(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavLoiterUnlim *ui; -}; - -#endif // QGCMISSIONNAVLOITERUNLIM_H diff --git a/src/ui/mission/QGCMissionNavLoiterUnlim.ui b/src/ui/mission/QGCMissionNavLoiterUnlim.ui deleted file mode 100644 index c9fde6709..000000000 --- a/src/ui/mission/QGCMissionNavLoiterUnlim.ui +++ /dev/null @@ -1,350 +0,0 @@ - - - QGCMissionNavLoiterUnlim - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - 0 - 0 - - - - Loiter Radius. If negative loiter counter-clockwise - - - Loiter Radius. If negative loiter counter-clockwise - - - false - - - m - - - -1000000.000000000000000 - - - 1000000.000000000000000 - - - 0.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavReturnToLaunch.cc b/src/ui/mission/QGCMissionNavReturnToLaunch.cc deleted file mode 100644 index 5e698c4d5..000000000 --- a/src/ui/mission/QGCMissionNavReturnToLaunch.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "QGCMissionNavReturnToLaunch.h" -#include "ui_QGCMissionNavReturnToLaunch.h" -#include "WaypointEditableView.h" - -QGCMissionNavReturnToLaunch::QGCMissionNavReturnToLaunch(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavReturnToLaunch) -{ - ui->setupUi(this); - this->WEV = WEV; -} - -QGCMissionNavReturnToLaunch::~QGCMissionNavReturnToLaunch() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavReturnToLaunch.h b/src/ui/mission/QGCMissionNavReturnToLaunch.h deleted file mode 100644 index 7e061454e..000000000 --- a/src/ui/mission/QGCMissionNavReturnToLaunch.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QGCMISSIONNAVRETURNTOLAUNCH_H -#define QGCMISSIONNAVRETURNTOLAUNCH_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavReturnToLaunch; -} - -class QGCMissionNavReturnToLaunch : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavReturnToLaunch(WaypointEditableView* WEV); - ~QGCMissionNavReturnToLaunch(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavReturnToLaunch *ui; -}; - -#endif // QGCMISSIONNAVRETURNTOLAUNCH_H diff --git a/src/ui/mission/QGCMissionNavReturnToLaunch.ui b/src/ui/mission/QGCMissionNavReturnToLaunch.ui deleted file mode 100644 index 87bc7186d..000000000 --- a/src/ui/mission/QGCMissionNavReturnToLaunch.ui +++ /dev/null @@ -1,52 +0,0 @@ - - - QGCMissionNavReturnToLaunch - - - - 0 - 0 - 258 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - No Parameters - - - Qt::AlignCenter - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavSweep.cc b/src/ui/mission/QGCMissionNavSweep.cc deleted file mode 100644 index 3d68f6069..000000000 --- a/src/ui/mission/QGCMissionNavSweep.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "QGCMissionNavSweep.h" -#include "ui_QGCMissionNavSweep.h" -#include "WaypointEditableView.h" - -QGCMissionNavSweep::QGCMissionNavSweep(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavSweep) -{ - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->radSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->posN1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double)));//NED - connect(this->ui->posE1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posN2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double))); - connect(this->ui->posE2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->lat1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double)));//Global - connect(this->ui->lon1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->lat2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double))); - connect(this->ui->lon2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->radSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->posN1SpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->posE1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posN2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posE2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->lat1SpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->lon1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->lat2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lon2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); -} - -void QGCMissionNavSweep::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posN1SpinBox->show(); - this->ui->posE1SpinBox->show(); - this->ui->posN2SpinBox->show(); - this->ui->posE2SpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->lat1SpinBox->hide(); - this->ui->lon1SpinBox->hide(); - this->ui->lat2SpinBox->hide(); - this->ui->lon2SpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posN1SpinBox->hide(); - this->ui->posE1SpinBox->hide(); - this->ui->posN2SpinBox->hide(); - this->ui->posE2SpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->lat1SpinBox->show(); - this->ui->lon1SpinBox->show(); - this->ui->lat2SpinBox->show(); - this->ui->lon2SpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavSweep::~QGCMissionNavSweep() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavSweep.h b/src/ui/mission/QGCMissionNavSweep.h deleted file mode 100644 index dd578acd9..000000000 --- a/src/ui/mission/QGCMissionNavSweep.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVSWEEP_H -#define QGCMISSIONNAVSWEEP_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavSweep; -} - -class QGCMissionNavSweep : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavSweep(WaypointEditableView* WEV); - ~QGCMissionNavSweep(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavSweep *ui; -}; - -#endif // QGCMISSIONNAVSWEEP_H diff --git a/src/ui/mission/QGCMissionNavSweep.ui b/src/ui/mission/QGCMissionNavSweep.ui deleted file mode 100644 index c186e7b27..000000000 --- a/src/ui/mission/QGCMissionNavSweep.ui +++ /dev/null @@ -1,470 +0,0 @@ - - - QGCMissionNavSweep - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - X coordinate of the first sweep area corner - - - X coordinate of the first sweep area corner - - - false - - - true - - - true - - - false - - - (1)N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Y coordinate of the first sweep area corner - - - Y coordinate of the first sweep area corner - - - false - - - (1)E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - X coordinate of the second sweep area corner - - - X coordinate of the second sweep area corner - - - false - - - true - - - true - - - false - - - (2)N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Y coordinate of the second sweep area corner - - - Y coordinate of the second sweep area corner - - - false - - - (2)E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude of the first sweep area corner - - - Latitude of the first sweep area corner - - - false - - - (1)lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude of the first sweep area corner - - - Longitude of the first sweep area corner - - - false - - - (1)lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude of the second sweep area corner - - - Latitude of the second sweep area corner - - - false - - - (2)lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude of the second sweep area corner - - - Longitude of the second sweep area corner - - - false - - - (2)lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude - - - Altitude - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Radius of the circle under the MAV covered by the camera - - - Radius of the circle under the MAV covered by the camera - - - false - - - m - - - 0.200000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavTakeoff.cc b/src/ui/mission/QGCMissionNavTakeoff.cc deleted file mode 100644 index 386cb65d7..000000000 --- a/src/ui/mission/QGCMissionNavTakeoff.cc +++ /dev/null @@ -1,68 +0,0 @@ -#include "QGCMissionNavTakeoff.h" -#include "ui_QGCMissionNavTakeoff.h" -#include "WaypointEditableView.h" - -QGCMissionNavTakeoff::QGCMissionNavTakeoff(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavTakeoff) - { - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->minPitchSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - //connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - //connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->minPitchSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); - } - -void QGCMissionNavTakeoff::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavTakeoff::~QGCMissionNavTakeoff() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavTakeoff.h b/src/ui/mission/QGCMissionNavTakeoff.h deleted file mode 100644 index 198ccfc49..000000000 --- a/src/ui/mission/QGCMissionNavTakeoff.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVTAKEOFF_H -#define QGCMISSIONNAVTAKEOFF_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavTakeoff; -} - -class QGCMissionNavTakeoff : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavTakeoff(WaypointEditableView* WEV); - ~QGCMissionNavTakeoff(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavTakeoff *ui; -}; - -#endif // QGCMISSIONNAVTAKEOFF_H diff --git a/src/ui/mission/QGCMissionNavTakeoff.ui b/src/ui/mission/QGCMissionNavTakeoff.ui deleted file mode 100644 index bf0aab426..000000000 --- a/src/ui/mission/QGCMissionNavTakeoff.ui +++ /dev/null @@ -1,365 +0,0 @@ - - - QGCMissionNavTakeoff - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - heading - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - 0 - 0 - - - - Minimum Pitch - - - Minimum Pitch - - - false - - - min. pitch - - - ° - - - 0 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000000000000000 - - - - - - - - diff --git a/src/ui/mission/QGCMissionNavWaypoint.cc b/src/ui/mission/QGCMissionNavWaypoint.cc deleted file mode 100644 index 79e3a9bfd..000000000 --- a/src/ui/mission/QGCMissionNavWaypoint.cc +++ /dev/null @@ -1,69 +0,0 @@ -#include "QGCMissionNavWaypoint.h" -#include "ui_QGCMissionNavWaypoint.h" -#include "WaypointEditableView.h" - -QGCMissionNavWaypoint::QGCMissionNavWaypoint(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionNavWaypoint) - { - ui->setupUi(this); - this->WEV = WEV; - - //Using UI to change WP: - connect(this->ui->holdTimeSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - connect(this->ui->acceptanceSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - //connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->yawSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->posNSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//NED - connect(this->ui->posESpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->posDSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - connect(this->ui->latSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double)));//Global - connect(this->ui->lonSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->altSpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - //Reading WP to update UI: - connect(WEV,SIGNAL(frameBroadcast(MAV_FRAME)),this,SLOT(updateFrame(MAV_FRAME))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->holdTimeSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->acceptanceSpinBox,SLOT(setValue(double))); - //connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->yawSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->posNSpinBox,SLOT(setValue(double)));//NED - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->posESpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->posDSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->latSpinBox,SLOT(setValue(double)));//Global - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->lonSpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->altSpinBox,SLOT(setValue(double))); - } - -void QGCMissionNavWaypoint::updateFrame(MAV_FRAME frame) -{ - switch(frame) - { - case MAV_FRAME_LOCAL_ENU: - case MAV_FRAME_LOCAL_NED: - case MAV_FRAME_LOCAL_OFFSET_NED: - this->ui->posNSpinBox->show(); - this->ui->posESpinBox->show(); - this->ui->posDSpinBox->show(); - this->ui->latSpinBox->hide(); - this->ui->lonSpinBox->hide(); - this->ui->altSpinBox->hide(); - break; - case MAV_FRAME_GLOBAL: - case MAV_FRAME_GLOBAL_RELATIVE_ALT: - this->ui->posNSpinBox->hide(); - this->ui->posESpinBox->hide(); - this->ui->posDSpinBox->hide(); - this->ui->latSpinBox->show(); - this->ui->lonSpinBox->show(); - this->ui->altSpinBox->show(); - break; - default: - break; - } -} - -QGCMissionNavWaypoint::~QGCMissionNavWaypoint() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionNavWaypoint.h b/src/ui/mission/QGCMissionNavWaypoint.h deleted file mode 100644 index c4c9d1531..000000000 --- a/src/ui/mission/QGCMissionNavWaypoint.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef QGCMISSIONNAVWAYPOINT_H -#define QGCMISSIONNAVWAYPOINT_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionNavWaypoint; -} - -class QGCMissionNavWaypoint : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionNavWaypoint(WaypointEditableView* WEV); - ~QGCMissionNavWaypoint(); - -public slots: - void updateFrame(MAV_FRAME); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionNavWaypoint *ui; -}; - -#endif // QGCMISSIONNAVWAYPOINT_H diff --git a/src/ui/mission/QGCMissionNavWaypoint.ui b/src/ui/mission/QGCMissionNavWaypoint.ui deleted file mode 100644 index b10a08542..000000000 --- a/src/ui/mission/QGCMissionNavWaypoint.ui +++ /dev/null @@ -1,370 +0,0 @@ - - - QGCMissionNavWaypoint - - - - 0 - 0 - 2208 - 37 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - 5 - - - 0 - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position X coordinate - - - Position X corrdinate - - - false - - - true - - - true - - - false - - - N - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Y/Longitude coordinate - - - Position Y/Longitude coordinate - - - false - - - E - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - 0.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Position Z coordinate (local frame, negative) - - - - - - false - - - D - - - m - - - -10000.000000000000000 - - - 10000.000000000000000 - - - 0.050000000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Latitude in degrees - - - Latitude in degrees - - - false - - - lat - - - ° - - - 7 - - - -90.000000000000000 - - - 90.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Qt::WheelFocus - - - Longitude in degrees - - - Longitude in degrees - - - false - - - lon - - - ° - - - 7 - - - -180.000000000000000 - - - 180.000000000000000 - - - 0.000010000000000 - - - - - - - - 0 - 0 - - - - Altitude in meters - - - Altitude in meters - - - false - - - alt - - - m - - - 2 - - - -100000.000000000000000 - - - 100000.000000000000000 - - - - - - - - 0 - 0 - - - - Qt::StrongFocus - - - Rotary wing only: Desired yaw angle at waypoint - - - Rotary wing only: Desired yaw angle at waypoint - - - true - - - false - - - - - - ° - - - 0 - - - -180.000000000000000 - - - 180.000000000000000 - - - - - - - - 0 - 0 - - - - Uncertainty radius in meters -where to accept this waypoint as reached - - - Uncertainty radius in meters where to accept this waypoint as reached - - - false - - - m - - - 0.200000000000000 - - - - - - - - 0 - 0 - - - - Time to stay/loiter at this position before advancing - - - Time to stay/loiter at this position before advancing - - - false - - - s - - - 9999.989999999999782 - - - - - - - - diff --git a/src/ui/mission/QGCMissionOther.cc b/src/ui/mission/QGCMissionOther.cc deleted file mode 100644 index cd0807454..000000000 --- a/src/ui/mission/QGCMissionOther.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "QGCMissionOther.h" -#include "ui_QGCMissionOther.h" -#include "WaypointEditableView.h" - -QGCMissionOther::QGCMissionOther(WaypointEditableView* WEV) : - QWidget(WEV), - ui(new Ui::QGCMissionOther) -{ - ui->setupUi(this); - this->WEV = WEV; - //Using UI to change WP: - connect(this->ui->commandSpinBox,SIGNAL(valueChanged(int)),WEV,SLOT(changedCommand(int))); - connect(this->ui->param1SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam1(double))); - connect(this->ui->param2SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam2(double))); - connect(this->ui->param3SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam3(double))); - connect(this->ui->param4SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam4(double))); - connect(this->ui->param5SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam5(double))); - connect(this->ui->param6SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam6(double))); - connect(this->ui->param7SpinBox, SIGNAL(valueChanged(double)),WEV,SLOT(changedParam7(double))); - - - //Reading WP to update UI: - connect(WEV,SIGNAL(commandBroadcast(int)),this->ui->commandSpinBox,SLOT(setValue(int))); - connect(WEV,SIGNAL(param1Broadcast(double)),this->ui->param1SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param2Broadcast(double)),this->ui->param2SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param3Broadcast(double)),this->ui->param3SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param4Broadcast(double)),this->ui->param4SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param5Broadcast(double)),this->ui->param5SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param6Broadcast(double)),this->ui->param6SpinBox,SLOT(setValue(double))); - connect(WEV,SIGNAL(param7Broadcast(double)),this->ui->param7SpinBox,SLOT(setValue(double))); -} - -QGCMissionOther::~QGCMissionOther() -{ - delete ui; -} diff --git a/src/ui/mission/QGCMissionOther.h b/src/ui/mission/QGCMissionOther.h deleted file mode 100644 index 29da3ac18..000000000 --- a/src/ui/mission/QGCMissionOther.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifndef QGCMISSIONOTHER_H -#define QGCMISSIONOTHER_H - -#include -#include "WaypointEditableView.h" - -namespace Ui { - class QGCMissionOther; -} - -class QGCMissionOther : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMissionOther(WaypointEditableView* WEV); - ~QGCMissionOther(); - -protected: - WaypointEditableView* WEV; - -private: - Ui::QGCMissionOther *ui; -}; - -#endif // QGCMISSIONOTHER_H diff --git a/src/ui/mission/QGCMissionOther.ui b/src/ui/mission/QGCMissionOther.ui deleted file mode 100644 index 719a8b260..000000000 --- a/src/ui/mission/QGCMissionOther.ui +++ /dev/null @@ -1,239 +0,0 @@ - - - QGCMissionOther - - - - 0 - 0 - 1266 - 27 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - 5 - - - 0 - - - - - MAV_CMD id - - - MAV_CMD id - - - false - - - CMD - - - 0 - - - 255 - - - 0 - - - - - - - Mission parameter #1 - - - Mission parameter #1 - - - false - - - P1 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #2 - - - Mission parameter #2 - - - false - - - P2 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #3 - - - Mission parameter #3 - - - false - - - P3 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #4 - - - Mission parameter #4 - - - false - - - P4 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #5 - - - Mission parameter #5 - - - false - - - P5 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #6 - - - Mission parameter #6 - - - false - - - P6 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - Mission parameter #7 - - - Mission parameter #7 - - - false - - - P7 - - - 7 - - - -2147483647.000000000000000 - - - 2147483647.000000000000000 - - - - - - - - diff --git a/src/ui/toolbar/MainToolBar.cc b/src/ui/toolbar/MainToolBar.cc index 97f869a4a..6d8dea3d6 100644 --- a/src/ui/toolbar/MainToolBar.cc +++ b/src/ui/toolbar/MainToolBar.cc @@ -142,7 +142,7 @@ void MainToolBar::onSetupView() void MainToolBar::onPlanView() { - setCurrentView(MainWindow::VIEW_PLAN); + setCurrentView(MainWindow::VIEW_MISSIONEDITOR); MainWindow::instance()->loadPlanView(); } @@ -250,10 +250,10 @@ void MainToolBar::setCurrentView(int currentView) case MainWindow::VIEW_ANALYZE: view = ViewAnalyze; break; - case MainWindow::VIEW_PLAN: + case MainWindow::VIEW_MISSIONEDITOR: view = ViewPlan; break; - case MainWindow::VIEW_FLIGHT: + case MainWindow::VIEW_FLIGHT: view = ViewFly; break; case MainWindow::VIEW_SETUP: diff --git a/src/ui/toolbar/MainToolBar.h b/src/ui/toolbar/MainToolBar.h index deb2ea490..44e0dbfe2 100644 --- a/src/ui/toolbar/MainToolBar.h +++ b/src/ui/toolbar/MainToolBar.h @@ -52,7 +52,7 @@ public: typedef enum { ViewNone = -1, ViewAnalyze, // MainWindow::VIEW_ENGINEER - ViewPlan , // MainWindow::VIEW_MISSION + ViewPlan , // MainWindow::VIEW_MISSION_EDITOR ViewFly , // MainWindow::VIEW_FLIGHT ViewSetup , // MainWindow::VIEW_SETUP } ViewType_t; -- 2.22.0