blob: 9963cac9dcd2fb295ff9250e8289d5bbc7f14a64 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2018 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtLocation module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qmappolygonobjectqsg_p_p.h"
#include <QtQuick/qsgnode.h>
#include <QtQuick/qsgsimplerectnode.h>
#include <QtPositioning/private/qgeopolygon_p.h>
QT_BEGIN_NAMESPACE
QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(QGeoMapObject *q)
: QMapPolygonObjectPrivateDefault(q)
{
}
QMapPolygonObjectPrivateQSG::QMapPolygonObjectPrivateQSG(const QMapPolygonObjectPrivate &other)
: QMapPolygonObjectPrivateDefault(other)
{
// Data already cloned by the *Default copy constructor, but necessary
// update operations triggered only by setters overrides
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
}
QMapPolygonObjectPrivateQSG::~QMapPolygonObjectPrivateQSG()
{
if (m_map)
m_map->removeMapObject(q);
}
QList<QDoubleVector2D> QMapPolygonObjectPrivateQSG::projectPath()
{
QList<QDoubleVector2D> geopathProjected_;
if (!m_map || m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return geopathProjected_;
const QGeoProjectionWebMercator &p =
static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
geopathProjected_.reserve(m_path.path().size());
for (const QGeoCoordinate &c : m_path.path())
geopathProjected_ << p.geoToMapProjection(c);
return geopathProjected_;
}
QSGNode *QMapPolygonObjectPrivateQSG::updateMapObjectNode(QSGNode *oldNode,
VisibleNode **visibleNode,
QSGNode *root,
QQuickWindow * /*window*/)
{
Q_UNUSED(visibleNode);
MapPolygonNode *node = static_cast<MapPolygonNode *>(oldNode);
bool created = false;
if (!node) {
if (!m_geometry.size() && !m_borderGeometry.size())
return nullptr;
node = new MapPolygonNode();
*visibleNode = static_cast<VisibleNode *>(node);
created = true;
}
//TODO: update only material
if (m_geometry.isScreenDirty() || !m_borderGeometry.isScreenDirty() || !oldNode || created) {
node->update(fillColor(), borderColor(), &m_geometry, &m_borderGeometry);
m_geometry.setPreserveGeometry(false);
m_borderGeometry.setPreserveGeometry(false);
m_geometry.markClean();
m_borderGeometry.markClean();
}
if (created)
root->appendChildNode(node);
return node;
}
void QMapPolygonObjectPrivateQSG::setPath(const QList<QGeoCoordinate> &path)
{
QMapPolygonObjectPrivateDefault::setPath(path);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
}
void QMapPolygonObjectPrivateQSG::setFillColor(const QColor &color)
{
QMapPolygonObjectPrivateDefault::setFillColor(color);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
}
void QMapPolygonObjectPrivateQSG::setBorderColor(const QColor &color)
{
QMapPolygonObjectPrivateDefault::setBorderColor(color);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
}
void QMapPolygonObjectPrivateQSG::setBorderWidth(qreal width)
{
QMapPolygonObjectPrivateDefault::setBorderWidth(width);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
}
QGeoMapObjectPrivate *QMapPolygonObjectPrivateQSG::clone()
{
return new QMapPolygonObjectPrivateQSG(static_cast<QMapPolygonObjectPrivate &>(*this));
}
void QMapPolygonObjectPrivateQSG::setGeoShape(const QGeoShape &shape)
{
if (shape == m_path)
return;
m_path = QGeoPathEager(shape);
updateGeometry();
if (m_map)
emit m_map->sgNodeChanged();
emit static_cast<QMapPolygonObject *>(q)->pathChanged();
}
void QMapPolygonObjectPrivateQSG::updateGeometry()
{
if (!m_map || m_path.path().length() == 0
|| m_map->geoProjection().projectionType() != QGeoProjection::ProjectionWebMercator)
return;
QScopedValueRollback<bool> rollback(m_updatingGeometry);
m_updatingGeometry = true;
const QList<QDoubleVector2D> &geopathProjected = projectPath();
m_geometry.markSourceDirty();
m_geometry.setPreserveGeometry(true, m_path.boundingGeoRectangle().topLeft());
m_geometry.updateSourcePoints(*m_map, geopathProjected);
m_geometry.updateScreenPoints(*m_map);
m_borderGeometry.clear();
//if (border_.color() != Qt::transparent && border_.width() > 0)
{
const QGeoProjectionWebMercator &p = static_cast<const QGeoProjectionWebMercator&>(m_map->geoProjection());
QList<QDoubleVector2D> closedPath = geopathProjected;
closedPath << closedPath.first();
m_borderGeometry.markSourceDirty();
m_borderGeometry.setPreserveGeometry(true, m_path.boundingGeoRectangle().topLeft());
const QGeoCoordinate &geometryOrigin = m_geometry.origin();
m_borderGeometry.clearSource();
QDoubleVector2D borderLeftBoundWrapped;
QList<QList<QDoubleVector2D > > clippedPaths =
m_borderGeometry.clipPath(*m_map.data(), closedPath, borderLeftBoundWrapped);
if (clippedPaths.size()) {
borderLeftBoundWrapped = p.geoToWrappedMapProjection(geometryOrigin);
m_borderGeometry.pathToScreen(*m_map.data(), clippedPaths, borderLeftBoundWrapped);
m_borderGeometry.updateScreenPoints(*m_map.data(), borderWidth(), false);
} else {
m_borderGeometry.clear();
}
}
QPointF origin = m_map->geoProjection().coordinateToItemPosition(m_geometry.origin(), false).toPointF();
m_geometry.translate(origin - m_geometry.firstPointOffset());
m_borderGeometry.translate(origin - m_borderGeometry.firstPointOffset());
}
QT_END_NAMESPACE