Warning, /libraries/kosmindoormap/src/app/indoormap.qml is written in an unsupported language. File is not indexed.
0001 /*
0002 SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
0003
0004 SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006
0007 import QtCore
0008 import QtQuick
0009 import QtQuick.Layouts
0010 import QtQuick.Controls as QQC2
0011 import QtQuick.Dialogs as Dialogs
0012 import org.kde.kirigami as Kirigami
0013 import org.kde.kpublictransport as PublicTransport
0014 import org.kde.kosmindoormap
0015 import org.kde.kosmindoormap.kpublictransport
0016 import org.kde.osm.editorcontroller
0017 import org.kde.kirigamiaddons.formcard as FormCard
0018
0019 Kirigami.ApplicationWindow {
0020 globalDrawer: Kirigami.GlobalDrawer {
0021 title: "Indoor Map"
0022 titleIcon: "map-symbolic"
0023 isMenu: true
0024 actions: [
0025 Kirigami.Action {
0026 text: "Open O5M File"
0027 icon.name: "document-open-symbolic"
0028 onTriggered: fileDialog.open()
0029 },
0030 Kirigami.Action {
0031 text: "Open MapCSS Stylesheet"
0032 icon.name: "document-open-symbolic"
0033 onTriggered: mapcssDialog.open()
0034 },
0035 Kirigami.Action {
0036 text: "Reload Stylesheet"
0037 icon.name: "view-refresh-symbolic"
0038 shortcut: "F5"
0039 onTriggered: {
0040 var s = page.map.styleSheet;
0041 page.map.styleSheet = "";
0042 page.map.styleSheet = s;
0043 }
0044 },
0045 Kirigami.Action { separator: true },
0046 Kirigami.Action {
0047 text: "Data Sources"
0048 icon.name: "help-about-symbolic"
0049 onTriggered: function() { applicationWindow().pageStack.push(attributionPage); }
0050 },
0051 Kirigami.Action {
0052 id: aboutAction
0053 text: "About"
0054 icon.name: "help-about-symbolic"
0055 onTriggered: function() { applicationWindow().pageStack.push(aboutPage); }
0056 }
0057 ]
0058 }
0059 contextDrawer: Kirigami.ContextDrawer {
0060 id: contextDrawer
0061 }
0062
0063 Dialogs.FileDialog {
0064 id: fileDialog
0065 title: "Open OSM File"
0066 fileMode: Dialogs.FileDialog.OpenFile
0067 nameFilters: ["o5m file (*.o5m)", "OSM XML file (*.osm *.xml)", "PBF file (*.osm.pbf)"]
0068 onAccepted: page.map.mapLoader.loadFromFile(fileDialog.selectedFile);
0069 }
0070 Dialogs.FileDialog {
0071 id: mapcssDialog
0072 title: "Open MapCSS Stylesheet"
0073 fileMode: Dialogs.FileDialog.OpenFile
0074 nameFilters: ["MapCSS stylesheet (*.mapcss)"]
0075 onAccepted: page.map.styleSheet = mapcssDialog.selectedFile
0076 }
0077 PublicTransport.Manager { id: ptMgr }
0078 Settings {
0079 id: settings
0080 property alias debugMode: debugAction.checked
0081 property alias stylesheet: page.map.styleSheet
0082 property alias hoverMode: page.mapHoverEnabled
0083 }
0084
0085 pageStack.initialPage: IndoorMapPage {
0086 id: page
0087 debug: debugAction.checked
0088
0089 actions: [
0090 Kirigami.Action {
0091 text: "Select Location"
0092 icon.name: "search"
0093 onTriggered: locationSheet.open()
0094 },
0095 Kirigami.Action {
0096 text: "Light Style"
0097 onTriggered: page.map.styleSheet = "breeze-light"
0098 },
0099 Kirigami.Action {
0100 text: "Dark Style"
0101 onTriggered: page.map.styleSheet = "breeze-dark"
0102 },
0103 Kirigami.Action {
0104 text: "Diagnostic View"
0105 onTriggered: page.map.styleSheet = "diagnostic"
0106 },
0107 Kirigami.Action {
0108 id: debugAction
0109 text: "Debug Info Model"
0110 checkable: true
0111 checked: false
0112 },
0113 Kirigami.Action {
0114 id: platformAction
0115 text: "Find Platform"
0116 onTriggered: platformSheet.open()
0117 visible: !platformModel.isEmpty
0118 },
0119 Kirigami.Action {
0120 id: gateAction
0121 text: "Find Gate"
0122 onTriggered: gateSheet.open()
0123 visible: !gateModel.isEmpty
0124 },
0125 Kirigami.Action {
0126 id: amenityAction
0127 text: "Find Amenity"
0128 onTriggered: amenitySheet.open()
0129 },
0130 Kirigami.Action {
0131 id: equipmentAction
0132 text: "Show Elevator Status"
0133 checkable: true
0134 enabled: !page.map.mapLoader.isLoading
0135 onTriggered: page.queryLiveLocationData();
0136 },
0137 Kirigami.Action {
0138 id: rentalVehicleAction
0139 text: i18n("Show Rental Vehicles")
0140 checkable: true
0141 enabled: !page.map.mapLoader.isLoading
0142 onTriggered: page.queryLiveLocationData();
0143 },
0144 Kirigami.Action {
0145 text: i18n("Edit with iD")
0146 icon.name: "document-edit"
0147 onTriggered: EditorController.editBoundingBox(page.map.view.mapSceneToGeo(page.map.view.viewport), Editor.ID)
0148 },
0149 Kirigami.Action {
0150 text: i18n("Edit with JOSM")
0151 icon.name: "org.openstreetmap.josm"
0152 visible: EditorController.hasEditor(Editor.JOSM)
0153 onTriggered: EditorController.editBoundingBox(page.map.view.mapSceneToGeo(page.map.view.viewport), Editor.JOSM)
0154 },
0155 Kirigami.Action {
0156 text: i18n("Edit with Vespucci")
0157 icon.name: "document-edit"
0158 visible: EditorController.hasEditor(Editor.Vespucci)
0159 onTriggered: EditorController.editBoundingBox(page.map.view.mapSceneToGeo(page.map.view.viewport), Editor.Vespucci)
0160 },
0161 Kirigami.Action {
0162 text: i18n("Enable hover selection")
0163 icon.name: "followmouse"
0164 checkable: true
0165 checked: page.mapHoverEnabled
0166 onToggled: page.mapHoverEnabled = !page.mapHoverEnabled
0167 }
0168 ]
0169
0170 function queryLiveLocationData() {
0171 if (rentalVehicleAction.checked || equipmentAction.checked) {
0172 locationQuery.request.latitude = map.mapData.center.y;
0173 locationQuery.request.longitude = map.mapData.center.x;
0174 locationQuery.request.maximumDistance = map.mapData.radius;
0175 locationQuery.request.types =
0176 (rentalVehicleAction.checked ? (PublicTransport.Location.RentedVehicleStation | PublicTransport.Location.RentedVehicle) : 0)
0177 | (equipmentAction.checked ? PublicTransport.Location.Equipment : 0);
0178 } else {
0179 locationQuery.clear();
0180 }
0181 }
0182
0183 PlatformModel {
0184 id: platformModel
0185 mapData: page.map.mapData
0186 }
0187
0188 Component {
0189 id: platformDelegate
0190 QQC2.ItemDelegate {
0191 property var platform: model
0192 width: ListView.view.width
0193 contentItem: Row {
0194 QQC2.Label { text: platform.lines.length == 0 ? platform.display : (platform.display + " - "); }
0195 Repeater {
0196 model: platform.lines
0197 delegate: Row {
0198 Kirigami.Icon {
0199 id: icon
0200 height: Kirigami.Units.iconSizes.small
0201 width: implicitWidth
0202 visible: source != ""
0203 source: {
0204 switch (platform.mode) {
0205 case Platform.Rail:
0206 return PublicTransport.LineMetaData.lookup(modelData, platform.coordinate.y, platform.coordinate.x, PublicTransport.Line.Train, true).logo;
0207 case Platform.Tram:
0208 return PublicTransport.LineMetaData.lookup(modelData, platform.coordinate.y, platform.coordinate.x, PublicTransport.Line.Tramway, true).logo;
0209 case Platform.Subway:
0210 return PublicTransport.LineMetaData.lookup(modelData, platform.coordinate.y, platform.coordinate.x, PublicTransport.Line.Metro, true).logo;
0211 }
0212 return "";
0213 }
0214 }
0215 QQC2.Label {
0216 text: modelData + " "
0217 visible: icon.source == ""
0218 }
0219 }
0220 }
0221 }
0222 highlighted: false
0223 onClicked: {
0224 page.map.view.floorLevel = model.level
0225 page.map.view.centerOnGeoCoordinate(model.coordinate);
0226 page.map.view.setZoomLevel(19, Qt.point(page.map.width / 2.0, page.map.height/ 2.0));
0227 platformSheet.close()
0228 }
0229 }
0230 }
0231
0232 Kirigami.OverlaySheet {
0233 id: platformSheet
0234
0235 header: Kirigami.Heading {
0236 text: "Find Platform"
0237 }
0238
0239 ListView {
0240 model: platformModel
0241 clip: true
0242 Layout.preferredWidth: Kirigami.Units.gridUnit * 25
0243
0244 section.property: "mode"
0245 section.delegate: Kirigami.ListSectionHeader {
0246 label: switch(parseInt(section)) {
0247 case Platform.Rail: return "Railway";
0248 case Platform.Subway: return "Subway";
0249 case Platform.Tram: return "Tramway";
0250 case Platform.Bus: return "Bus";
0251 default: console.log(section, Platform.Rail); return section;
0252 }
0253 width: ListView.view.width
0254 }
0255 section.criteria: ViewSection.FullString
0256
0257 delegate: platformDelegate
0258 }
0259 }
0260
0261 GateModel {
0262 id: gateModel
0263 mapData: page.map.mapData
0264 }
0265
0266 Kirigami.OverlaySheet {
0267 id: gateSheet
0268
0269 header: Kirigami.Heading {
0270 text: "Find Gate"
0271 }
0272
0273 ListView {
0274 model: gateModel
0275 Layout.preferredWidth: Kirigami.Units.gridUnit * 10
0276 delegate: QQC2.ItemDelegate {
0277 highlighted: false
0278 width: ListView.view.width
0279 contentItem: Kirigami.TitleSubtitle {
0280 title: model.display
0281 }
0282 onClicked: {
0283 page.map.view.floorLevel = model.level
0284 page.map.view.centerOnGeoCoordinate(model.coordinate);
0285 page.map.view.setZoomLevel(18, Qt.point(page.map.width / 2.0, page.map.height/ 2.0));
0286 gateSheet.close();
0287 }
0288 }
0289 }
0290 }
0291
0292 AmenityModel {
0293 id: amenityModel
0294 mapData: page.map.mapData
0295 }
0296
0297 Kirigami.OverlaySheet {
0298 id: amenitySheet
0299 header: Kirigami.Heading {
0300 text: "Find Amenity"
0301 }
0302
0303 ListView {
0304 clip: true
0305 Layout.preferredWidth: Kirigami.Units.gridUnit * 25
0306 model: AmenitySortFilterProxyModel {
0307 sourceModel: amenitySheet.visible ? amenityModel : null
0308 filterCaseSensitivity: Qt.CaseInsensitive
0309 filterString: amenitySearchField.text
0310 }
0311
0312 delegate: IndoorMapAmenityDelegate {
0313 id: item
0314 mapData: page.map.mapData
0315 required property QtObject model
0316 onClicked: {
0317 page.map.view.floorLevel = item.model.level
0318 page.map.view.centerOnGeoCoordinate(item.model.coordinate);
0319 page.map.view.setZoomLevel(21, Qt.point(page.map.width / 2.0, page.map.height/ 2.0));
0320 console.log(item.model.element.url);
0321 amenitySheet.close();
0322 }
0323 }
0324
0325 section.property: "groupName"
0326 section.delegate: Kirigami.ListSectionHeader {
0327 label: section
0328 width: ListView.view.width
0329 }
0330 }
0331
0332 footer: Kirigami.SearchField {
0333 id: amenitySearchField
0334 focus: true
0335 }
0336 onOpened: amenitySearchField.clear()
0337 }
0338
0339 LocationQueryOverlayProxyModel {
0340 id: locationModel
0341 sourceModel: PublicTransport.LocationQueryModel {
0342 id: locationQuery
0343 manager: ptMgr
0344 }
0345 mapData: page.map.mapData
0346 }
0347
0348 RealtimeEquipmentModel {
0349 id: equipmentModel
0350 mapData: page.map.mapData
0351 realtimeModel: locationModel.sourceModel
0352 }
0353
0354 SelectLocationSheet {
0355 id: locationSheet
0356 publicTransportManager: ptMgr
0357 onCoordinateSelected: function() {
0358 page.map.mapLoader.loadForCoordinate(locationSheet.coordinate.y, locationSheet.coordinate.x);
0359 page.map.view.beginTime = new Date();
0360 page.map.view.endTime = new Date(page.map.view.beginTime.getTime() + 3600000);
0361 // TODO timezone
0362
0363 settings.setValue("latitude", locationSheet.coordinate.y);
0364 settings.setValue("longitude", locationSheet.coordinate.x);
0365 }
0366 }
0367
0368 map.overlaySources: [ gateModel, platformModel, locationModel, equipmentModel ]
0369 map.timeZone: "Europe/Berlin"
0370
0371 header: RowLayout {
0372 QQC2.Label { text: "Floor Level:" }
0373 QQC2.ComboBox {
0374 id: floorLevelCombo
0375 model: page.map.floorLevels
0376 textRole: "display"
0377 currentIndex: page.map.floorLevels.rowForLevel(page.map.view.floorLevel);
0378 onCurrentIndexChanged: if (currentIndex >= 0) { page.map.view.floorLevel = page.map.floorLevels.levelForRow(currentIndex); }
0379 Layout.fillWidth: true
0380 }
0381 Connections {
0382 target: page.map.view
0383 function onFloorLevelChanged() { floorLevelCombo.currentIndex = page.map.floorLevels.rowForLevel(page.map.view.floorLevel); }
0384 }
0385
0386 QQC2.Slider {
0387 id: zoomSlider
0388 from: 14.0
0389 to: 21.0
0390 live: true
0391 Layout.fillWidth: true
0392
0393 onValueChanged: {
0394 page.map.view.setZoomLevel(value, Qt.point(page.map.width / 2.0, page.map.height/ 2.0));
0395 }
0396 }
0397 Connections {
0398 target: page.map.view
0399 function onZoomLevelChanged() { zoomSlider.value = page.map.view.zoomLevel; }
0400 }
0401 }
0402
0403 coordinate: Qt.point(settings.value("longitude", 11.08196), settings.value("latitude", 49.44572))
0404 }
0405
0406 Connections {
0407 target: page.map
0408 function onMapDataChanged() {
0409 page.queryLiveLocationData();
0410 }
0411 }
0412
0413 Component {
0414 id: attributionPage
0415 AttributionPage {
0416 publicTransportManager: ptMgr
0417 }
0418 }
0419
0420 Component {
0421 id: aboutPage
0422 FormCard.AboutPage {
0423 aboutData: {
0424 "displayName": "KDE OSM Indoor Map",
0425 "productName": "org.kde.kosmindoormap",
0426 "componentName": "org.kde.kosmindoormap",
0427 "shortDescription": "OSM Indoor Map Demo",
0428 "homepage": "https://kde.org/",
0429 "bugAddress": "submit@bugs.kde.org",
0430 "version": "23.08",
0431 "licenses": [
0432 {
0433 "name": "LGPL 2.0 or later",
0434 "spdx": "LGPL-2.0-or-later"
0435 }
0436 ],
0437 "copyrightStatement": "© 2020-2023 The KDE Team",
0438 "desktopFileName": "kosmindoormap"
0439 }
0440 }
0441 }
0442 }