12#include <QtQml/QQmlComponent>
13#include <QtQuick3D/QQuick3DObject>
31 connect(
this, &QQuickItem::visibleChanged,
this, &GeoMapItem::_updateNode3DVisibility);
46 _updateNode3DVisibility();
62 if (
scene == _scene) {
65 qCDebug(GeoMapItemLog) <<
"scene" << (
scene ?
"set" :
"cleared");
67 disconnect(_scene,
nullptr,
this,
nullptr);
76 connect(_scene, &QObject::destroyed,
this, [
this] {
94 disconnect(_surfaceModel,
nullptr,
this,
nullptr);
99 connect(_surfaceModel, &QObject::destroyed,
this, [
this] {
100 _surfaceModel =
nullptr;
111 if (mode == _altitudeMode) {
114 _altitudeMode = mode;
124 qCDebug(GeoMapItemLog) <<
"delegate3D" << (
delegate3D ?
"set" :
"cleared");
126 disconnect(_delegate3D,
nullptr,
this,
nullptr);
130 connect(_delegate3D, &QObject::destroyed,
this, [
this] {
131 _delegate3D =
nullptr;
150void GeoMapItem::_connectCamera()
153 if (camera == _connectedCamera) {
157 if (_connectedCamera) {
158 disconnect(_connectedCamera,
nullptr,
this,
nullptr);
160 _connectedCamera = camera;
161 if (_connectedCamera) {
165 connect(_connectedCamera, &QObject::destroyed,
this, [
this] {
166 _connectedCamera =
nullptr;
173void GeoMapItem::_terrainHeightsChanged()
180void GeoMapItem::_setProjected(
bool projected)
194void GeoMapItem::_setScenePosition(
const QVector3D& scenePosition)
201 _node3D->setProperty(
"position", _scenePosition);
206void GeoMapItem::_rebuildNode3D()
208 const bool hadNode = _node3D !=
nullptr;
212 if (
auto*
const object3D = qobject_cast<QQuick3DObject*>(_node3D)) {
213 object3D->setParentItem(
nullptr);
215 _node3D->deleteLater();
219 QQuick3DObject*
const container = _scene ? qobject_cast<QQuick3DObject*>(_scene->
content3D()) : nullptr;
220 if (_delegate3D && container) {
221 QObject*
const node = _delegate3D->create(_delegate3D->creationContext());
223 qCWarning(GeoMapItemLog) <<
"delegate3D failed to create:" << _delegate3D->errorString();
224 }
else if (
auto*
const object3D = qobject_cast<QQuick3DObject*>(node)) {
225 node->setParent(container);
226 object3D->setParentItem(container);
227 node->setProperty(
"position", _scenePosition);
229 _updateNode3DVisibility();
232 qCWarning(GeoMapItemLog) <<
"delegate3D did not produce a QQuick3DObject";
238 if (hadNode || _node3D) {
243void GeoMapItem::_updateNode3DVisibility()
246 _node3D->setProperty(
"visible", isVisible() && _coordinate.isValid());
250void GeoMapItem::_updateCrossfade()
254 _node3D->setProperty(
"opacity", 1.0);
256 if (_contentOpacity2D != 1.0) {
257 _contentOpacity2D = 1.0;
262 const qreal terrainScale = _scene ? std::clamp(_scene->
terrainScale(), 0.0, 1.0) : 0.0;
264 _node3D->setProperty(
"opacity", terrainScale);
273void GeoMapItem::_updatePosition()
275 if (!_scene || !_coordinate.isValid()) {
276 _setScenePosition(QVector3D());
277 _setProjected(
false);
281 double altitude = 0.0;
283 altitude = std::isfinite(_coordinate.altitude()) ? _coordinate.altitude() : 0.0;
284 }
else if (_surfaceModel) {
291 _setScenePosition(QVector3D(
static_cast<float>(world.x() - origin.x()),
static_cast<float>(world.y() - origin.y()),
292 static_cast<float>(sceneZ)));
296 _setProjected(
false);
301 _setProjected(
false);
304 setPosition(*screen - _anchorPoint);
static constexpr QPointF kParkedPosition
#define QGC_LOGGING_CATEGORY(name, categoryStr)
std::optional< QPointF > worldToScreen(const QPointF &worldGround, double worldZ=0.0) const
void fieldOfViewChanged()
void viewportSizeChanged()
SurfacePatchModel * surfaceModel() const
void crossfade3DChanged()
void setAnchorPoint(const QPointF &anchorPoint)
void setCrossfade3D(bool crossfade3D)
void surfaceModelChanged()
qreal contentOpacity2D() const
AltitudeMode
How the coordinate's vertical position is resolved.
@ ClampToGround
sit on the rendered terrain surface (default)
@ Absolute
use coordinate.altitude (NaN treated as 0)
void setAltitudeMode(AltitudeMode mode)
void setDelegate3D(QQmlComponent *delegate3D)
QVector3D scenePosition() const
void scenePositionChanged()
GeoMapItem(QQuickItem *parent=nullptr)
void setScene(GeoScene *scene)
QPointF anchorPoint() const
void anchorPointChanged()
void setSurfaceModel(SurfacePatchModel *surfaceModel)
QGeoCoordinate coordinate() const
void altitudeModeChanged()
QQmlComponent * delegate3D() const
void setCoordinate(const QGeoCoordinate &coordinate)
void contentOpacity2DChanged()
qreal verticalScale() const
void sceneOriginChanged()
qreal terrainScale() const
void terrainScaleChanged()
QObject * content3D() const
GeoMapCamera * camera() const
QPointF sceneOrigin() const
void terrainHeightsChanged()
terrainHeightAt answers changed somewhere: consumers re-query
Q_INVOKABLE double terrainHeightAt(const QGeoCoordinate &coordinate) const
QPointF geoToWorld(const QGeoCoordinate &coord)
Geo -> world meters. Latitude is clamped to +/-kMaxLatitude.