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 }