1
0
mirror of https://github.com/f4exb/sdrangel.git synced 2024-11-26 17:58:43 -05:00
sdrangel/plugins/channelrx/demodadsb/map/map.qml
Jon Beniston 97f55be6e9 ADS-B Demod Updates
Add support for animated 3D models.
Downloaded zipped airplane database as 1/4 of the size.
Add table context menu.
Add airline and country images to text bubbles on maps.
Fix calculation of ground speed when on surface.
Fix position calculation when aircraft transistions from surface to air.
Fix altitude calculation when Q-bit is set.
Speed up processing of large log files.
Add new airline logos.
2022-02-04 16:57:45 +00:00

390 lines
13 KiB
QML

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtLocation 5.12
import QtPositioning 5.12
import QtGraphicalEffects 1.12
Item {
id: qmlMap
property int aircraftZoomLevel: 11
property int airportZoomLevel: 11
property string mapProvider: "osm"
property variant mapPtr
property string requestedMapType
property bool lightIcons
property variant guiPtr
function createMap(pluginParameters, requestedMap, gui) {
requestedMapType = requestedMap
guiPtr = gui
var paramString = ""
for (var prop in pluginParameters) {
var parameter = 'PluginParameter { name: "' + prop + '"; value: "' + pluginParameters[prop] + '"}'
paramString = paramString + parameter
}
var pluginString = 'import QtLocation 5.12; Plugin{ name:"' + mapProvider + '"; ' + paramString + '}'
var plugin = Qt.createQmlObject (pluginString, qmlMap)
if (mapPtr) {
// Objects aren't destroyed immediately, so don't call findChild("map")
mapPtr.destroy()
mapPtr = null
}
mapPtr = actualMapComponent.createObject(page)
mapPtr.plugin = plugin
mapPtr.forceActiveFocus()
return mapPtr
}
Item {
id: page
anchors.fill: parent
}
Component {
id: actualMapComponent
Map {
id: map
objectName: "map"
anchors.fill: parent
center: QtPositioning.coordinate(51.5, 0.125) // London
zoomLevel: 10
// Needs to come first, otherwise MouseAreas in the MapItemViews don't get clicked event first
// Setting z doesn't seem to work
MouseArea {
anchors.fill: parent
onClicked: {
// Unhighlight current aircraft
guiPtr.clearHighlighted()
}
}
MapStation {
id: station
objectName: "station"
stationName: "Home"
}
MapItemView {
model: airspaceModel
delegate: airspaceComponent
}
MapItemView {
model: navAidModel
delegate: navAidComponent
}
MapItemView {
model: airspaceModel
delegate: airspaceNameComponent
}
MapItemView {
model: airportModel
delegate: airportComponent
}
// This needs to be before aircraftComponent MapItemView, so it's drawn underneath
MapItemView {
model: aircraftModel
delegate: aircraftPathComponent
}
MapItemView {
model: aircraftModel
delegate: aircraftComponent
}
onZoomLevelChanged: {
if (zoomLevel > 11) {
station.zoomLevel = zoomLevel
aircraftZoomLevel = zoomLevel
airportZoomLevel = zoomLevel
} else {
station.zoomLevel = 11
aircraftZoomLevel = 11
airportZoomLevel = 11
}
}
onSupportedMapTypesChanged : {
for (var i = 0; i < supportedMapTypes.length; i++) {
if (requestedMapType == supportedMapTypes[i].name) {
activeMapType = supportedMapTypes[i]
}
}
lightIcons = requestedMapType == "Night Transit Map"
}
}
}
Component {
id: navAidComponent
MapQuickItem {
id: navAid
anchorPoint.x: image.width/2
anchorPoint.y: image.height/2
coordinate: position
zoomLevel: airportZoomLevel
sourceItem: Grid {
columns: 1
Grid {
horizontalItemAlignment: Grid.AlignHCenter
columnSpacing: 5
layer.enabled: true
layer.smooth: true
Image {
id: image
source: navAidImage
visible: !lightIcons
MouseArea {
anchors.fill: parent
onClicked: (mouse) => {
selected = !selected
}
}
}
ColorOverlay {
cached: true
width: image.width
height: image.height
source: image
color: "#c0ffffff"
visible: lightIcons
}
Rectangle {
id: bubble
color: bubbleColour
border.width: 1
width: text.width + 5
height: text.height + 5
radius: 5
Text {
id: text
anchors.centerIn: parent
text: navAidData
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: (mouse) => {
selected = !selected
}
}
}
}
}
}
}
Component {
id: airspaceComponent
MapPolygon {
border.width: 1
border.color: airspaceBorderColor
color: airspaceFillColor
path: airspacePolygon
}
}
Component {
id: airspaceNameComponent
MapQuickItem {
coordinate: position
anchorPoint.x: airspaceText.width/2
anchorPoint.y: airspaceText.height/2
zoomLevel: airportZoomLevel
sourceItem: Grid {
columns: 1
Grid {
layer.enabled: true
layer.smooth: true
horizontalItemAlignment: Grid.AlignHCenter
Text {
id: airspaceText
text: details
}
}
}
}
}
Component {
id: aircraftPathComponent
MapPolyline {
line.width: 2
line.color: 'gray'
path: aircraftPath
}
}
Component {
id: aircraftComponent
MapQuickItem {
id: aircraft
anchorPoint.x: image.width/2
anchorPoint.y: image.height/2
coordinate: position
zoomLevel: aircraftZoomLevel
sourceItem: Grid {
columns: 1
Grid {
layer.enabled: true
layer.smooth: true
horizontalItemAlignment: Grid.AlignHCenter
Image {
id: image
rotation: heading
source: aircraftImage
visible: !lightIcons
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.LeftButton) {
highlighted = true
} else if (mouse.button === Qt.RightButton) {
contextMenu.popup()
}
}
onDoubleClicked: {
target = true
}
}
}
ColorOverlay {
cached: true
width: image.width
height: image.height
rotation: heading
source: image
color: "#c0ffffff"
visible: lightIcons
MouseArea {
anchors.fill: parent
onClicked: {
highlighted = true
}
onDoubleClicked: {
target = true
}
}
}
Rectangle {
id: bubble
color: bubbleColour
border.width: 1
width: text.width * 1.1
height: text.height * 1.1
radius: 5
Text {
id: text
anchors.centerIn: parent
text: adsbData
textFormat: TextEdit.RichText
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button === Qt.LeftButton) {
showAll = !showAll
} else if (mouse.button === Qt.RightButton) {
contextMenu.popup()
}
}
Menu {
id: contextMenu
MenuItem {
text: "Set as target"
onTriggered: target = true
}
MenuItem {
text: "Find on feature map"
onTriggered: aircraftModel.findOnMap(index)
}
}
}
}
}
}
}
}
Component {
id: airportComponent
MapQuickItem {
id: aircraft
anchorPoint.x: image.width/2
anchorPoint.y: image.height/2
coordinate: position
zoomLevel: airportZoomLevel
sourceItem: Grid {
columns: 1
Grid {
horizontalItemAlignment: Grid.AlignHCenter
layer.enabled: true
layer.smooth: true
Image {
id: image
source: airportImage
visible: !lightIcons
}
ColorOverlay {
cached: true
width: image.width
height: image.height
source: image
color: "#c0ffffff"
visible: lightIcons
}
Rectangle {
id: bubble
color: bubbleColour
border.width: 1
width: text.width + 5
height: text.height + 5
radius: 5
Text {
id: text
anchors.centerIn: parent
text: airportData
}
MouseArea {
anchors.fill: parent
onClicked: (mouse) => {
if (showFreq) {
var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows))
if (freqIdx == 0) {
showFreq = false
}
} else {
showFreq = true
}
}
onDoubleClicked: (mouse) => {
if (showFreq) {
var freqIdx = Math.floor((mouse.y-5)/((height-10)/airportDataRows))
if (freqIdx != 0) {
selectedFreq = freqIdx - 1
}
}
}
}
}
}
}
}
}
}