地面站终端 App
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1208 lines
59 KiB

/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
import QtLocation 5.3
import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.QGCMapEngineManager 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FactControls 1.0
QGCView {
id: offlineMapView
viewPanel: panel
anchors.fill: parent
9 years ago
property var _currentSelection: null
9 years ago
property string mapKey: "lastMapType"
property Fact _mapboxFact: QGroundControl.settingsManager.appSettings.mapboxToken
property Fact _esriFact: QGroundControl.settingsManager.appSettings.esriToken
property string mapType: _settings.mapProvider.enumStringValue + " " + _settings.mapType.enumStringValue
property bool isMapInteractive: false
property var savedCenter: undefined
property real savedZoom: 3
property string savedMapType: ""
property bool _showPreview: true
property bool _defaultSet: offlineMapView && offlineMapView._currentSelection && offlineMapView._currentSelection.defaultSet
property real _margins: ScreenTools.defaultFontPixelWidth * 0.5
property real _buttonSize: ScreenTools.defaultFontPixelWidth * 12
property real _bigButtonSize: ScreenTools.defaultFontPixelWidth * 16
property bool _saveRealEstate: ScreenTools.isTinyScreen || ScreenTools.isShortScreen
property real _adjustableFontPointSize: _saveRealEstate ? ScreenTools.smallFontPointSize : ScreenTools.defaultFontPointSize
property var _mapAdjustedColor: _map.isSatelliteMap ? "white" : "black"
property bool _tooManyTiles: QGroundControl.mapEngineManager.tileCount > _maxTilesForDownload
property var _settings: QGroundControl.settingsManager.flightMapSettings
readonly property real minZoomLevel: 1
readonly property real maxZoomLevel: 20
readonly property real sliderTouchArea: ScreenTools.defaultFontPixelWidth * (ScreenTools.isTinyScreen ? 5 : (ScreenTools.isMobile ? 6 : 3))
readonly property int _maxTilesForDownload: 100000
QGCPalette { id: qgcPal }
Component.onCompleted: {
QGroundControl.mapEngineManager.loadTileSets()
updateMap()
savedCenter = _map.toCoordinate(Qt.point(_map.width / 2, _map.height / 2), false /* clipToViewPort */)
}
Connections {
target: QGroundControl.mapEngineManager
onTileSetsChanged: {
setName.text = QGroundControl.mapEngineManager.getUniqueName()
}
onErrorMessageChanged: {
errorDialog.visible = true
}
}
ExclusiveGroup { id: setGroup }
function handleChanges() {
if(isMapInteractive) {
var xl = 0
var yl = 0
var xr = _map.width.toFixed(0) - 1 // Must be within boundaries of visible map
var yr = _map.height.toFixed(0) - 1 // Must be within boundaries of visible map
var c0 = _map.toCoordinate(Qt.point(xl, yl), false /* clipToViewPort */)
var c1 = _map.toCoordinate(Qt.point(xr, yr), false /* clipToViewPort */)
QGroundControl.mapEngineManager.updateForCurrentView(c0.longitude, c0.latitude, c1.longitude, c1.latitude, sliderMinZoom.value, sliderMaxZoom.value, mapType)
}
}
function updateMap() {
for (var i = 0; i < _map.supportedMapTypes.length; i++) {
//console.log(_map.supportedMapTypes[i].name)
if (mapType === _map.supportedMapTypes[i].name) {
_map.activeMapType = _map.supportedMapTypes[i]
//console.log("Update Map:" + " " + _map.activeMapType)
handleChanges()
return
}
}
}
function addNewSet() {
isMapInteractive = true
mapType = _settings.mapProvider.enumStringValue + " " + _settings.mapType.enumStringValue
resetMapToDefaults()
handleChanges()
_map.visible = true
_tileSetList.visible = false
infoView.visible = false
_exporTiles.visible = false
addNewSetView.visible = true
}
function showList() {
_exporTiles.visible = false
isMapInteractive = false
_map.visible = false
_tileSetList.visible = true
infoView.visible = false
addNewSetView.visible = false
QGroundControl.mapEngineManager.resetAction();
}
function showExport() {
isMapInteractive = false
_map.visible = false
_tileSetList.visible = false
infoView.visible = false
addNewSetView.visible = false
_exporTiles.visible = true
}
function showInfo() {
isMapInteractive = false
if(_currentSelection && !offlineMapView._currentSelection.deleting) {
enterInfoView()
} else
showList()
}
function toRadian(deg) {
return deg * Math.PI / 180
}
function toDegree(rad) {
return rad * 180 / Math.PI
}
function midPoint(lat1, lat2, lon1, lon2) {
var dLon = toRadian(lon2 - lon1);
lat1 = toRadian(lat1);
lat2 = toRadian(lat2);
lon1 = toRadian(lon1);
var Bx = Math.cos(lat2) * Math.cos(dLon);
var By = Math.cos(lat2) * Math.sin(dLon);
var lat3 = Math.atan2(Math.sin(lat1) + Math.sin(lat2), Math.sqrt((Math.cos(lat1) + Bx) * (Math.cos(lat1) + Bx) + By * By));
var lon3 = lon1 + Math.atan2(By, Math.cos(lat1) + Bx);
return QtPositioning.coordinate(toDegree(lat3), toDegree(lon3))
}
function enterInfoView() {
_map.visible = true
isMapInteractive = false
savedCenter = _map.toCoordinate(Qt.point(_map.width / 2, _map.height / 2), false /* clipToViewPort */)
savedZoom = _map.zoomLevel
savedMapType = mapType
if(!offlineMapView._currentSelection.defaultSet) {
mapType = offlineMapView._currentSelection.mapTypeStr
_map.center = midPoint(offlineMapView._currentSelection.topleftLat, offlineMapView._currentSelection.bottomRightLat, offlineMapView._currentSelection.topleftLon, offlineMapView._currentSelection.bottomRightLon)
//-- Delineate Set Region
var x0 = offlineMapView._currentSelection.topleftLon
var x1 = offlineMapView._currentSelection.bottomRightLon
var y0 = offlineMapView._currentSelection.topleftLat
var y1 = offlineMapView._currentSelection.bottomRightLat
mapBoundary.topLeft = QtPositioning.coordinate(y0, x0)
mapBoundary.bottomRight = QtPositioning.coordinate(y1, x1)
mapBoundary.visible = true
// Some times, for whatever reason, the bounding box is correct (around ETH for instance), but the rectangle is drawn across the planet.
// When that happens, the "_map.fitViewportToMapItems()" below makes the map to zoom to the entire earth.
//console.log("Map boundary: " + mapBoundary.topLeft + " " + mapBoundary.bottomRight)
_map.fitViewportToMapItems()
}
_tileSetList.visible = false
addNewSetView.visible = false
infoView.visible = true
}
function leaveInfoView() {
mapBoundary.visible = false
_map.center = savedCenter
_map.zoomLevel = savedZoom
mapType = savedMapType
}
function resetMapToDefaults() {
_map.center = QGroundControl.flightMapPosition
_map.zoomLevel = QGroundControl.flightMapZoom
}
ExclusiveGroup {
id: _dropButtonsExclusiveGroup
}
onMapTypeChanged: {
updateMap()
if(isMapInteractive) {
QGroundControl.mapEngineManager.saveSetting(mapKey, mapType)
}
}
MessageDialog {
id: errorDialog
visible: false
text: QGroundControl.mapEngineManager.errorMessage
icon: StandardIcon.Critical
standardButtons: StandardButton.Ok
title: qsTr("Error Message")
onYes: {
errorDialog.visible = false
}
}
Component {
id: optionsDialogComponent
QGCViewDialog {
id: optionDialog
function accept() {
QGroundControl.mapEngineManager.maxDiskCache = parseInt(maxCacheSize.text)
QGroundControl.mapEngineManager.maxMemCache = parseInt(maxCacheMemSize.text)
optionDialog.hideDialog()
}
QGCFlickable {
anchors.fill: parent
contentHeight: optionsColumn.height
Column {
id: optionsColumn
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
spacing: ScreenTools.defaultFontPixelHeight / 2
QGCLabel { text: qsTr("Max Cache Disk Size (MB):") }
QGCTextField {
id: maxCacheSize
maximumLength: 6
inputMethodHints: Qt.ImhDigitsOnly
validator: IntValidator {bottom: 1; top: 262144;}
text: QGroundControl.mapEngineManager.maxDiskCache
}
Item { width: 1; height: 1 }
QGCLabel { text: qsTr("Max Cache Memory Size (MB):") }
QGCTextField {
id: maxCacheMemSize
maximumLength: 4
inputMethodHints: Qt.ImhDigitsOnly
validator: IntValidator {bottom: 1; top: 1024;}
text: QGroundControl.mapEngineManager.maxMemCache
}
QGCLabel {
font.pointSize: _adjustableFontPointSize
text: qsTr("Memory cache changes require a restart to take effect.")
}
Item { width: 1; height: 1; visible: _mapboxFact ? _mapboxFact.visible : false }
QGCLabel { text: qsTr("Mapbox Access Token"); visible: _mapboxFact ? _mapboxFact.visible : false }
FactTextField {
fact: _mapboxFact
visible: _mapboxFact ? _mapboxFact.visible : false
maximumLength: 256
width: ScreenTools.defaultFontPixelWidth * 30
}
QGCLabel {
text: qsTr("To enable Mapbox maps, enter your access token.")
visible: _mapboxFact ? _mapboxFact.visible : false
font.pointSize: _adjustableFontPointSize
}
Item { width: 1; height: 1; visible: _esriFact ? _esriFact.visible : false }
QGCLabel { text: qsTr("Esri Access Token"); visible: _esriFact ? _esriFact.visible : false }
FactTextField {
fact: _esriFact
visible: _esriFact ? _esriFact.visible : false
maximumLength: 256
width: ScreenTools.defaultFontPixelWidth * 30
}
QGCLabel {
text: qsTr("To enable Esri maps, enter your access token.")
visible: _esriFact ? _esriFact.visible : false
font.pointSize: _adjustableFontPointSize
}
} // GridLayout
} // QGCFlickable
} // QGCViewDialog - optionsDialog
} // Component - optionsDialogComponent
Component {
id: deleteConfirmationDialogComponent
QGCViewMessage {
id: deleteConfirmationDialog
message: {
if(offlineMapView._currentSelection.defaultSet)
return qsTr("This will delete all tiles INCLUDING the tile sets you have created yourself.\n\nIs this really what you want?");
else
return qsTr("Delete %1 and all its tiles.\n\nIs this really what you want?").arg(offlineMapView._currentSelection.name);
}
function accept() {
QGroundControl.mapEngineManager.deleteTileSet(offlineMapView._currentSelection)
deleteConfirmationDialog.hideDialog()
leaveInfoView()
showList()
}
}
}
QGCViewPanel {
id: panel
anchors.fill: parent
Map {
id: _map
anchors.fill: parent
center: QGroundControl.flightMapPosition
visible: false
gesture.flickDeceleration: 3000
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1
plugin: Plugin { name: "QGroundControl" }
MapRectangle {
id: mapBoundary
border.width: 2
border.color: "red"
color: Qt.rgba(1,0,0,0.05)
smooth: true
antialiasing: true
}
Component.onCompleted: resetMapToDefaults()
onCenterChanged: handleChanges()
onZoomLevelChanged: handleChanges()
onWidthChanged: handleChanges()
onHeightChanged: handleChanges()
// Used to make pinch zoom work
MouseArea {
anchors.fill: parent
}
MapScale {
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2
anchors.bottomMargin: anchors.leftMargin
anchors.left: parent.left
anchors.bottom: parent.bottom
mapControl: _map
}
//-----------------------------------------------------------------
//-- Show Set Info
Rectangle {
id: infoView
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
width: tileInfoColumn.width + (ScreenTools.defaultFontPixelWidth * 2)
height: tileInfoColumn.height + (ScreenTools.defaultFontPixelHeight * 2)
color: Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.85)
radius: ScreenTools.defaultFontPixelWidth * 0.5
visible: false
property bool _extraButton: {
if(!offlineMapView._currentSelection)
return false;
var curSel = offlineMapView._currentSelection;
return !_defaultSet && ((!curSel.complete && !curSel.downloading) || (!curSel.complete && curSel.downloading));
}
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 10
property real _valueWidth: ScreenTools.defaultFontPixelWidth * 14
Column {
id: tileInfoColumn
anchors.margins: ScreenTools.defaultFontPixelHeight * 0.5
spacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.centerIn: parent
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: offlineMapView._currentSelection ? offlineMapView._currentSelection.name : ""
font.pointSize: _saveRealEstate ? ScreenTools.defaultFontPointSize : ScreenTools.mediumFontPointSize
horizontalAlignment: Text.AlignHCenter
visible: _defaultSet
}
QGCTextField {
id: editSetName
anchors.left: parent.left
anchors.right: parent.right
visible: !_defaultSet
text: offlineMapView._currentSelection ? offlineMapView._currentSelection.name : ""
}
QGCLabel {
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: {
if(offlineMapView._currentSelection) {
if(offlineMapView._currentSelection.defaultSet)
return qsTr("System Wide Tile Cache");
else
return "(" + offlineMapView._currentSelection.mapTypeStr + ")"
} else
return "";
}
horizontalAlignment: Text.AlignHCenter
}
//-- Tile Sets
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: !_defaultSet
QGCLabel { text: qsTr("Zoom Levels:"); width: infoView._labelWidth; }
QGCLabel { text: offlineMapView._currentSelection ? (offlineMapView._currentSelection.minZoom + " - " + offlineMapView._currentSelection.maxZoom) : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: !_defaultSet
QGCLabel { text: qsTr("Total:"); width: infoView._labelWidth; }
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.totalTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.totalTilesSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && offlineMapView._currentSelection.uniqueTileCount > 0
QGCLabel { text: qsTr("Unique:"); width: infoView._labelWidth; }
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.uniqueTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.uniqueTileSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && !offlineMapView._currentSelection.complete
QGCLabel { text: qsTr("Downloaded:"); width: infoView._labelWidth; }
QGCLabel { text: (offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileCountStr : "") + " (" + (offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileSizeStr : "") + ")"; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: offlineMapView && offlineMapView._currentSelection && !_defaultSet && !offlineMapView._currentSelection.complete && offlineMapView._currentSelection.errorCount > 0
QGCLabel { text: qsTr("Error Count:"); width: infoView._labelWidth; }
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.errorCountStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
//-- Default Tile Set
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: _defaultSet
QGCLabel { text: qsTr("Size:"); width: infoView._labelWidth; }
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileSizeStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: _defaultSet
QGCLabel { text: qsTr("Tile Count:"); width: infoView._labelWidth; }
QGCLabel { text: offlineMapView._currentSelection ? offlineMapView._currentSelection.savedTileCountStr : ""; horizontalAlignment: Text.AlignRight; width: infoView._valueWidth; }
}
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Resume Download")
visible: offlineMapView._currentSelection && offlineMapView._currentSelection && !_defaultSet && (!offlineMapView._currentSelection.complete && !offlineMapView._currentSelection.downloading)
width: ScreenTools.defaultFontPixelWidth * 16
onClicked: {
if(offlineMapView._currentSelection)
offlineMapView._currentSelection.resumeDownloadTask()
}
}
QGCButton {
text: qsTr("Cancel Download")
visible: offlineMapView._currentSelection && offlineMapView._currentSelection && !_defaultSet && (!offlineMapView._currentSelection.complete && offlineMapView._currentSelection.downloading)
width: ScreenTools.defaultFontPixelWidth * 16
onClicked: {
if(offlineMapView._currentSelection)
offlineMapView._currentSelection.cancelDownloadTask()
}
}
QGCButton {
text: qsTr("Delete")
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10)
onClicked: showDialog(deleteConfirmationDialogComponent, qsTr("Confirm Delete"), qgcView.showDialogDefaultWidth, StandardButton.Yes | StandardButton.No)
}
QGCButton {
text: qsTr("Ok")
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10)
visible: !_defaultSet
enabled: editSetName.text !== ""
onClicked: {
if(editSetName.text !== _currentSelection.name) {
QGroundControl.mapEngineManager.renameTileSet(_currentSelection, editSetName.text)
}
leaveInfoView()
showList()
}
}
QGCButton {
text: _defaultSet ? qsTr("Close") : qsTr("Cancel")
width: ScreenTools.defaultFontPixelWidth * (infoView._extraButton ? 6 : 10)
onClicked: {
leaveInfoView()
showList()
}
}
}
}
} // Rectangle - infoView
//-----------------------------------------------------------------
//-- Add new set
Item {
id: addNewSetView
anchors.fill: parent
visible: false
Column {
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: _margins
anchors.left: parent.left
spacing: _margins
QGCButton {
text: "Show zoom previews"
visible: !_showPreview
onClicked: _showPreview = !_showPreview
}
Map {
id: minZoomPreview
width: addNewSetView.width / 4
height: addNewSetView.height / 4
center: _map.center
activeMapType: _map.activeMapType
zoomLevel: sliderMinZoom.value
gesture.enabled: false
visible: _showPreview
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1
plugin: Plugin { name: "QGroundControl" }
MapScale {
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2
anchors.bottomMargin: anchors.leftMargin
anchors.left: parent.left
anchors.bottom: parent.bottom
mapControl: parent
}
Rectangle {
anchors.fill: parent
border.color: _mapAdjustedColor
color: "transparent"
QGCMapLabel {
anchors.centerIn: parent
map: minZoomPreview
text: qsTr("Min Zoom: %1").arg(sliderMinZoom.value)
}
MouseArea {
anchors.fill: parent
onClicked: _showPreview = false
}
}
} // Map
Map {
id: maxZoomPreview
width: minZoomPreview.width
height: minZoomPreview.height
center: _map.center
activeMapType: _map.activeMapType
zoomLevel: sliderMaxZoom.value
gesture.enabled: false
visible: _showPreview
property bool isSatelliteMap: activeMapType.name.indexOf("Satellite") > -1 || activeMapType.name.indexOf("Hybrid") > -1
plugin: Plugin { name: "QGroundControl" }
MapScale {
anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 2
anchors.bottomMargin: anchors.leftMargin
anchors.left: parent.left
anchors.bottom: parent.bottom
mapControl: parent
}
Rectangle {
anchors.fill: parent
border.color: _mapAdjustedColor
color: "transparent"
QGCMapLabel {
anchors.centerIn: parent
map: maxZoomPreview
text: qsTr("Max Zoom: %1").arg(sliderMaxZoom.value)
}
MouseArea {
anchors.fill: parent
onClicked: _showPreview = false
}
}
} // Map
}
} // Item - Add new set view
CenterMapDropButton {
topMargin: 0
anchors.margins: _margins
anchors.left: map.left
anchors.top: map.top
map: _map
showMission: false
showAllItems: false
visible: addNewSetView.visible
}
} // Map
//-- Add new set dialog
Rectangle {
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
visible: addNewSetView.visible
width: ScreenTools.defaultFontPixelWidth * (ScreenTools.isTinyScreen ? 24 : 28)
height: Math.min(parent.height - (anchors.margins * 2), addNewSetFlickable.y + addNewSetColumn.height + addNewSetLabel.anchors.margins)
color: Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.85)
radius: ScreenTools.defaultFontPixelWidth * 0.5
MouseArea {
anchors.fill: parent
onWheel: { wheel.accepted = true; }
onPressed: { mouse.accepted = true; }
onReleased: { mouse.accepted = true; }
}
QGCLabel {
id: addNewSetLabel
anchors.margins: ScreenTools.defaultFontPixelHeight / 2
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
text: qsTr("Add New Set")
font.pointSize: _saveRealEstate ? ScreenTools.defaultFontPointSize : ScreenTools.mediumFontPointSize
horizontalAlignment: Text.AlignHCenter
}
QGCFlickable {
id: addNewSetFlickable
anchors.leftMargin: ScreenTools.defaultFontPixelWidth
anchors.rightMargin: anchors.leftMargin
anchors.topMargin: ScreenTools.defaultFontPixelWidth / 3
anchors.bottomMargin: anchors.topMargin
anchors.top: addNewSetLabel.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
clip: true
contentHeight: addNewSetColumn.height
Column {
id: addNewSetColumn
anchors.left: parent.left
anchors.right: parent.right
spacing: ScreenTools.defaultFontPixelHeight * (ScreenTools.isTinyScreen ? 0.25 : 0.5)
Column {
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.25
anchors.left: parent.left
anchors.right: parent.right
QGCLabel { text: qsTr("Name:") }
QGCTextField {
id: setName
anchors.left: parent.left
anchors.right: parent.right
}
}
Column {
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.25
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
text: qsTr("Map type:")
visible: !_saveRealEstate
}
QGCComboBox {
id: mapCombo
anchors.left: parent.left
anchors.right: parent.right
model: QGroundControl.mapEngineManager.mapList
onActivated: {
mapType = textAt(index)
if(_dropButtonsExclusiveGroup.current)
_dropButtonsExclusiveGroup.current.checked = false
_dropButtonsExclusiveGroup.current = null
}
Component.onCompleted: {
var index = mapCombo.find(mapType)
if (index === -1) {
console.warn("Active map name not in combo", mapType)
} else {
mapCombo.currentIndex = index
}
}
}
}
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: zoomColumn.height + ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
border.color: qgcPal.text
radius: ScreenTools.defaultFontPixelWidth * 0.5
Column {
id: zoomColumn
spacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.5
anchors.margins: ScreenTools.defaultFontPixelHeight * 0.25
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
text: qsTr("Min/Max Zoom Levels")
font.pointSize: _adjustableFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
Slider {
id: sliderMinZoom
anchors.left: parent.left
anchors.right: parent.right
height: sliderTouchArea * 1.25
minimumValue: minZoomLevel
maximumValue: maxZoomLevel
stepSize: 1
updateValueWhileDragging: true
property real _savedZoom
Component.onCompleted: Math.max(sliderMinZoom.value = _map.zoomLevel - 4, 2)
onValueChanged: {
if(sliderMinZoom.value > sliderMaxZoom.value) {
sliderMaxZoom.value = sliderMinZoom.value
}
handleChanges()
}
style: SliderStyle {
groove: Rectangle {
implicitWidth: sliderMinZoom.width
implicitHeight: 4
color: qgcPal.colorBlue
radius: 4
}
handle: Rectangle {
anchors.centerIn: parent
color: qgcPal.button
border.color: qgcPal.buttonText
border.width: 1
implicitWidth: sliderTouchArea
implicitHeight: sliderTouchArea
radius: sliderTouchArea * 0.5
Label {
text: sliderMinZoom.value
anchors.centerIn: parent
font.family: ScreenTools.normalFontFamily
font.pointSize: ScreenTools.smallFontPointSize
color: qgcPal.buttonText
}
}
}
} // Slider - min zoom
Slider {
id: sliderMaxZoom
anchors.left: parent.left
anchors.right: parent.right
height: sliderTouchArea * 1.25
minimumValue: minZoomLevel
maximumValue: maxZoomLevel
stepSize: 1
updateValueWhileDragging: true
property real _savedZoom
Component.onCompleted: Math.min(sliderMaxZoom.value = _map.zoomLevel + 2, 20)
onValueChanged: {
if(sliderMaxZoom.value < sliderMinZoom.value) {
sliderMinZoom.value = sliderMaxZoom.value
}
handleChanges()
}
style: SliderStyle {
groove: Rectangle {
implicitWidth: sliderMaxZoom.width
implicitHeight: 4
color: qgcPal.colorBlue
radius: 4
}
handle: Rectangle {
anchors.centerIn: parent
color: qgcPal.button
border.color: qgcPal.buttonText
border.width: 1
implicitWidth: sliderTouchArea
implicitHeight: sliderTouchArea
radius: sliderTouchArea * 0.5
Label {
text: sliderMaxZoom.value
anchors.centerIn: parent
font.family: ScreenTools.normalFontFamily
font.pointSize: ScreenTools.smallFontPointSize
color: qgcPal.buttonText
}
}
}
} // Slider - max zoom
GridLayout {
columns: 2
rowSpacing: ScreenTools.isTinyScreen ? 0 : ScreenTools.defaultFontPixelHeight * 0.5
QGCLabel {
text: qsTr("Tile Count:")
font.pointSize: _adjustableFontPointSize
}
QGCLabel {
text: QGroundControl.mapEngineManager.tileCountStr
font.pointSize: _adjustableFontPointSize
}
QGCLabel {
text: qsTr("Est Size:")
font.pointSize: _adjustableFontPointSize
}
QGCLabel {
text: QGroundControl.mapEngineManager.tileSizeStr
font.pointSize: _adjustableFontPointSize
}
}
} // Column - Zoom info
} // Rectangle - Zoom info
QGCLabel {
text: qsTr("Too many tiles")
visible: _tooManyTiles
color: qgcPal.warningText
anchors.horizontalCenter: parent.horizontalCenter
}
Row {
id: addButtonRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Download")
width: (addNewSetColumn.width * 0.5) - (addButtonRow.spacing * 0.5)
enabled: !_tooManyTiles && setName.text.length > 0
onClicked: {
if(QGroundControl.mapEngineManager.findName(setName.text)) {
duplicateName.visible = true
} else {
QGroundControl.mapEngineManager.startDownload(setName.text, mapType);
showList()
}
}
}
QGCButton {
text: qsTr("Cancel")
width: (addNewSetColumn.width * 0.5) - (addButtonRow.spacing * 0.5)
onClicked: {
showList()
}
}
}
} // Column
} // QGCFlickable
} // Rectangle - Add new set dialog
QGCFlickable {
id: _tileSetList
clip: true
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.bottom: _listButtonRow.top
anchors.left: parent.left
anchors.right: parent.right
contentHeight: _cacheList.height
Column {
id: _cacheList
width: Math.min(_tileSetList.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0))
spacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.horizontalCenter: parent.horizontalCenter
OfflineMapButton {
id: firstButton
text: qsTr("Add New Set")
width: _cacheList.width
height: ScreenTools.defaultFontPixelHeight * 2
onClicked: {
offlineMapView._currentSelection = null
addNewSet()
}
}
Repeater {
model: QGroundControl.mapEngineManager.tileSets
delegate: OfflineMapButton {
text: object.name
size: object.downloadStatus
tiles: object.totalTileCount
complete: object.complete
width: firstButton.width
height: ScreenTools.defaultFontPixelHeight * 2
onClicked: {
offlineMapView._currentSelection = object
showInfo()
}
}
}
}
}
Row {
id: _listButtonRow
visible: _tileSetList.visible
spacing: _margins
anchors.bottom: parent.bottom
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Import")
width: _buttonSize
visible: !ScreenTools.isMobile
onClicked: {
QGroundControl.mapEngineManager.importAction = QGCMapEngineManager.ActionNone
rootLoader.sourceComponent = importDialog
}
}
QGCButton {
text: qsTr("Export")
width: _buttonSize
visible: !ScreenTools.isMobile
enabled: QGroundControl.mapEngineManager.tileSets.count > 1
onClicked: showExport()
}
QGCButton {
text: qsTr("Options")
width: _buttonSize
onClicked: showDialog(optionsDialogComponent, qsTr("Offline Maps Options"), qgcView.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel)
}
}
//-- Export Tile Sets
QGCFlickable {
id: _exporTiles
clip: true
visible: false
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.bottom: _exportButtonRow.top
anchors.left: parent.left
anchors.right: parent.right
contentHeight: _exportList.height
Column {
id: _exportList
width: Math.min(_exporTiles.width, (ScreenTools.defaultFontPixelWidth * 50).toFixed(0))
spacing: ScreenTools.defaultFontPixelHeight * 0.5
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Select Tile Sets to Export")
font.pointSize: ScreenTools.mediumFontPointSize
}
Item { width: 1; height: ScreenTools.defaultFontPixelHeight; }
Repeater {
model: QGroundControl.mapEngineManager.tileSets
delegate: QGCCheckBox {
text: object.name
checked: object.selected
onClicked: {
object.selected = checked
}
}
}
}
}
Row {
id: _exportButtonRow
visible: _exporTiles.visible
spacing: _margins
anchors.bottom: parent.bottom
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Select All")
width: _bigButtonSize
onClicked: QGroundControl.mapEngineManager.selectAll()
}
QGCButton {
text: qsTr("Select None")
width: _bigButtonSize
onClicked: QGroundControl.mapEngineManager.selectNone()
}
QGCButton {
text: qsTr("Export")
width: _bigButtonSize
enabled: QGroundControl.mapEngineManager.selectedCount > 0
onClicked: {
showList();
if(QGroundControl.mapEngineManager.exportSets()) {
rootLoader.sourceComponent = exportToDiskProgress
}
}
}
QGCButton {
text: qsTr("Cancel")
width: _bigButtonSize
onClicked: showList()
}
}
} // QGCViewPanel
Component {
id: exportToDiskProgress
Rectangle {
width: mainWindow.width
height: mainWindow.height
color: "black"
anchors.centerIn: parent
Rectangle {
width: parent.width * 0.5
height: exportCol.height * 1.25
radius: ScreenTools.defaultFontPixelWidth
color: qgcPal.windowShadeDark
border.color: qgcPal.text
anchors.centerIn: parent
Column {
id: exportCol
spacing: ScreenTools.defaultFontPixelHeight
width: parent.width
anchors.centerIn: parent
QGCLabel {
text: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting ? qsTr("Tile Set Export Progress") : qsTr("Tile Set Export Completed")
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
ProgressBar {
id: progressBar
width: parent.width * 0.45
maximumValue: 100
value: QGroundControl.mapEngineManager.actionProgress
anchors.horizontalCenter: parent.horizontalCenter
}
BusyIndicator {
visible: QGroundControl.mapEngineManager ? QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting : false
running: QGroundControl.mapEngineManager ? QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionExporting : false
width: exportCloseButton.height
height: exportCloseButton.height
anchors.horizontalCenter: parent.horizontalCenter
}
QGCButton {
id: exportCloseButton
text: qsTr("Close")
width: _buttonSize
visible: !QGroundControl.mapEngineManager.exporting
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
rootLoader.sourceComponent = null
}
}
}
}
}
}
Component {
id: importDialog
Rectangle {
width: mainWindow.width
height: mainWindow.height
color: "black"
anchors.centerIn: parent
Rectangle {
width: parent.width * 0.5
height: importCol.height * 1.5
radius: ScreenTools.defaultFontPixelWidth
color: qgcPal.windowShadeDark
border.color: qgcPal.text
anchors.centerIn: parent
Column {
id: importCol
spacing: ScreenTools.defaultFontPixelHeight
width: parent.width
anchors.centerIn: parent
QGCLabel {
text: {
if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone) {
return qsTr("Map Tile Set Import");
} else if(QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting) {
return qsTr("Map Tile Set Import Progress");
} else {
return qsTr("Map Tile Set Import Completed");
}
}
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
ProgressBar {
id: progressBar
width: parent.width * 0.45
maximumValue: 100
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting
value: QGroundControl.mapEngineManager.actionProgress
anchors.horizontalCenter: parent.horizontalCenter
}
BusyIndicator {
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting
running: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionImporting
width: ScreenTools.defaultFontPixelWidth * 2
height: width
anchors.horizontalCenter: parent.horizontalCenter
}
ExclusiveGroup { id: radioGroup }
Column {
spacing: ScreenTools.defaultFontPixelHeight
width: ScreenTools.defaultFontPixelWidth * 24
anchors.horizontalCenter: parent.horizontalCenter
QGCRadioButton {
exclusiveGroup: radioGroup
text: qsTr("Append to existing set")
checked: !QGroundControl.mapEngineManager.importReplace
onClicked: QGroundControl.mapEngineManager.importReplace = !checked
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone
}
QGCRadioButton {
exclusiveGroup: radioGroup
text: qsTr("Replace existing set")
checked: QGroundControl.mapEngineManager.importReplace
onClicked: QGroundControl.mapEngineManager.importReplace = checked
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone
}
}
QGCButton {
text: qsTr("Close")
width: _bigButtonSize * 1.25
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionDone
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
showList();
rootLoader.sourceComponent = null
}
}
Row {
spacing: _margins
visible: QGroundControl.mapEngineManager.importAction === QGCMapEngineManager.ActionNone
anchors.horizontalCenter: parent.horizontalCenter
QGCButton {
text: qsTr("Import")
width: _bigButtonSize * 1.25
onClicked: {
if(!QGroundControl.mapEngineManager.importSets()) {
showList();
rootLoader.sourceComponent = null
}
}
}
QGCButton {
text: qsTr("Cancel")
width: _bigButtonSize * 1.25
onClicked: {
showList();
rootLoader.sourceComponent = null
}
}
}
}
}
}
}
} // QGCView