diff options
Diffstat (limited to 'examples/demos/osmbuildings/manager.py')
| -rw-r--r-- | examples/demos/osmbuildings/manager.py | 104 |
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) |
