aboutsummaryrefslogtreecommitdiffstats
path: root/examples/demos/osmbuildings/manager.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/demos/osmbuildings/manager.py')
-rw-r--r--examples/demos/osmbuildings/manager.py104
1 files changed, 104 insertions, 0 deletions
diff --git a/examples/demos/osmbuildings/manager.py b/examples/demos/osmbuildings/manager.py
new file mode 100644
index 000000000..6ff2d204b
--- /dev/null
+++ b/examples/demos/osmbuildings/manager.py
@@ -0,0 +1,104 @@
+# Copyright (C) 2024 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtQuick3D import QQuick3DTextureData
+from PySide6.QtQml import QmlElement
+from PySide6.QtGui import QImage, QVector3D
+from PySide6.QtCore import QByteArray, QObject, Property, Slot, Signal
+
+from request import OSMTileData, OSMRequest
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "OSMBuildings"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class OSMManager(QObject):
+
+ mapsDataReady = Signal(QByteArray, int, int, int)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self.m_request = OSMRequest(self)
+ self.m_startBuildingTileX = 17605
+ self.m_startBuildingTileY = 10746
+ self.m_tileSizeX = 37
+ self.m_tileSizeY = 37
+ self.m_request.mapsDataReady.connect(self._slotMapsDataReady)
+
+ def tileSizeX(self):
+ return self.m_tileSizeX
+
+ def tileSizeY(self):
+ return self.m_tileSizeY
+
+ @Slot(QByteArray, int, int, int)
+ def _slotMapsDataReady(self, mapData, tileX, tileY, zoomLevel):
+ self.mapsDataReady.emit(mapData, tileX - self.m_startBuildingTileX,
+ tileY - self.m_startBuildingTileY, zoomLevel)
+
+ @Slot(QVector3D, QVector3D, float, float, float, float, float, float)
+ def setCameraProperties(self, position, right,
+ cameraZoom, minimumZoom, maximumZoom,
+ cameraTilt, minimumTilt, maximumTilt):
+
+ tiltFactor = (cameraTilt - minimumTilt) / max(maximumTilt - minimumTilt, 1.0)
+ zoomFactor = (cameraZoom - minimumZoom) / max(maximumZoom - minimumZoom, 1.0)
+
+ # Forward vector align to the XY plane
+ forwardVector = QVector3D.crossProduct(right, QVector3D(0.0, 0.0, -1.0)).normalized()
+ projectionOfForwardOnXY = position + forwardVector * tiltFactor * zoomFactor * 50.0
+
+ queue = []
+ for forwardIndex in range(-20, 21):
+ for sidewardIndex in range(-20, 21):
+ vx = float(self.m_tileSizeX * sidewardIndex)
+ vy = float(self.m_tileSizeY * forwardIndex)
+ transferredPosition = projectionOfForwardOnXY + QVector3D(vx, vy, 0)
+ tile_x = self.m_startBuildingTileX + int(transferredPosition.x() / self.m_tileSizeX)
+ tile_y = self.m_startBuildingTileY - int(transferredPosition.y() / self.m_tileSizeY)
+ self.addBuildingRequestToQueue(queue, tile_x, tile_y)
+
+ projectedTileX = (self.m_startBuildingTileX + int(projectionOfForwardOnXY.x()
+ / self.m_tileSizeX))
+ projectedTileY = (self.m_startBuildingTileY - int(projectionOfForwardOnXY.y()
+ / self.m_tileSizeY))
+
+ def tile_sort_key(tile_data):
+ return tile_data.distanceTo(projectedTileX, projectedTileY)
+
+ queue.sort(key=tile_sort_key)
+
+ self.m_request.getMapsData(queue.copy())
+
+ def addBuildingRequestToQueue(self, queue, tileX, tileY, zoomLevel=15):
+ queue.append(OSMTileData(tileX, tileY, zoomLevel))
+
+ @Slot(result=bool)
+ def isDemoToken(self):
+ return self.m_request.isDemoToken()
+
+ @Slot(str)
+ def setToken(self, token):
+ self.m_request.setToken(token)
+
+ @Slot(result=str)
+ def token(self):
+ return self.m_request.token()
+
+ tileSizeX = Property(int, tileSizeX, constant=True)
+ tileSizeY = Property(int, tileSizeY, constant=True)
+
+
+@QmlElement
+class CustomTextureData(QQuick3DTextureData):
+
+ @Slot(QByteArray)
+ def setImageData(self, data):
+ image = QImage.fromData(data).convertToFormat(QImage.Format.Format_RGBA8888)
+ self.setTextureData(QByteArray(bytearray(image.constBits())))
+ self.setSize(image.size())
+ self.setHasTransparency(False)
+ self.setFormat(QQuick3DTextureData.Format.RGBA8)