6#include "GeoPolyline.h"
7#include "MarbleQuickItem.h"
10#include <QSGFlatColorMaterial>
11#include <QSGGeometryNode>
12#include <QSGSimpleTextureNode>
27 , m_clipScreenCoordinates(true)
29 setFlag(ItemHasContents,
true);
32MarbleQuickItem *GeoPolyline::map()
const
37void GeoPolyline::setMap(MarbleQuickItem *map)
44 connect(m_map, &MarbleQuickItem::visibleLatLonAltBoxChanged,
this, &GeoPolyline::updateScreenPositions);
45 Q_EMIT mapChanged(m_map);
48void GeoPolyline::updateScreenPositions()
50 GeoDataLineString lineString(m_lineString);
54 displayPolygon <<
QPointF(-10, -10) <<
QPointF(m_map->mapWidth() + 10, -10) <<
QPointF(m_map->mapWidth() + 10, m_map->mapHeight() + 10)
55 <<
QPointF(-10, m_map->mapHeight() + 10);
56 m_screenPolygons.clear();
58 bool success = m_map->screenCoordinatesFromGeoDataLineString(lineString, fullScreenPolygons);
59 if (m_clipScreenCoordinates) {
60 for (
auto reducedPolygon : std::as_const(fullScreenPolygons)) {
61 m_screenPolygons << reducedPolygon->intersected(displayPolygon);
64 for (
auto eachPolygon : std::as_const(fullScreenPolygons)) {
65 m_screenPolygons << *eachPolygon;
69 qDeleteAll(fullScreenPolygons);
71 QVariantList previousScreenCoordinates;
72 previousScreenCoordinates = m_screenCoordinates;
73 m_screenCoordinates.clear();
76 for (
const auto &screenPolygon : std::as_const(m_screenPolygons)) {
77 QVariantList polyline;
78 for (
auto node : screenPolygon) {
80 vmap[QStringLiteral(
"x")] = node.x();
81 vmap[QStringLiteral(
"y")] = node.y();
82 polyline.append(vmap);
84 m_screenCoordinates.insert(i, polyline);
89 QRectF polygonBoundingRect;
90 if (m_screenPolygons.length() == 1) {
91 polygonBoundingRect = m_screenPolygons[0].boundingRect();
94 for (
const auto &polygon : std::as_const(m_screenPolygons)) {
99 setX(polygonBoundingRect.
x());
100 setY(polygonBoundingRect.
y());
101 setWidth(polygonBoundingRect.
width());
102 setHeight(polygonBoundingRect.
height());
104 if (m_screenCoordinates != previousScreenCoordinates) {
105 Q_EMIT screenCoordinatesChanged();
107 Q_EMIT readonlyXChanged();
108 Q_EMIT readonlyYChanged();
109 Q_EMIT readonlyWidthChanged();
110 Q_EMIT readonlyHeightChanged();
115bool GeoPolyline::observable()
const
120QVariantList GeoPolyline::geoCoordinates()
const
122 return m_geoCoordinates;
125void GeoPolyline::setGeoCoordinates(
const QVariantList &coordinates)
127 m_lineString.clear();
128 m_lineString.setTessellate(m_tessellate);
129 for (
auto &item : coordinates) {
130 QVariantMap
map = item.toMap();
132 map[QStringLiteral(
"lat")].toReal(),
133 map[QStringLiteral(
"alt")].toReal(),
134 GeoDataCoordinates::Degree);
137 m_geoCoordinates = coordinates;
138 Q_EMIT geoCoordinatesChanged();
139 updateScreenPositions();
142QVariantList GeoPolyline::screenCoordinates()
const
144 return m_screenCoordinates;
147QColor GeoPolyline::lineColor()
const
152qreal GeoPolyline::lineWidth()
const
157void GeoPolyline::setLineColor(
const QColor &lineColor)
159 if (m_lineColor == lineColor)
162 m_lineColor = lineColor;
163 Q_EMIT lineColorChanged(m_lineColor);
166void GeoPolyline::setLineWidth(
const qreal lineWidth)
168 if (m_lineWidth == lineWidth)
171 m_lineWidth = lineWidth;
172 Q_EMIT lineWidthChanged(m_lineWidth);
175bool GeoPolyline::tessellate()
const
180bool GeoPolyline::clipScreenCoordinates()
const
182 return m_clipScreenCoordinates;
185void GeoPolyline::setTessellate(
bool tessellate)
187 if (m_tessellate == tessellate)
190 m_tessellate = tessellate;
191 Q_EMIT tessellateChanged(m_tessellate);
194void GeoPolyline::setClipScreenCoordinates(
bool clipped)
196 if (m_clipScreenCoordinates == clipped)
199 m_clipScreenCoordinates = clipped;
200 Q_EMIT clipScreenCoordinatesChanged(m_clipScreenCoordinates);
203qreal GeoPolyline::readonlyX()
const
208qreal GeoPolyline::readonlyY()
const
213qreal GeoPolyline::readonlyWidth()
const
218qreal GeoPolyline::readonlyHeight()
const
223QSGNode *GeoPolyline::updatePaintNode(
QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
225 qreal
const halfWidth = m_lineWidth;
230 if (m_screenPolygons.isEmpty())
233 for (
int i = 0; i < m_screenPolygons.length(); ++i) {
236 int segmentCount = polygon.
size() - 1;
238 for (
int i = 0; i < segmentCount; ++i) {
244 lineNodeGeo->setDrawingMode(0x0005);
245 lineNodeGeo->allocate((segmentCount + 1) * 2);
250 lineNode->setGeometry(lineNodeGeo);
252 lineNode->setMaterial(material);
255 auto points = lineNodeGeo->vertexDataAsPoint2D();
257 for (
int i = 0; i < segmentCount + 1; ++i) {
258 auto const &a = mapFromItem(m_map, polygon.
at(i));
259 auto const &n = normals[qMin(i, segmentCount - 1)].toPointF();
260 points[++k].set(a.x() - halfWidth * n.y(), a.y() + halfWidth * n.x());
261 points[++k].set(a.x() + halfWidth * n.y(), a.y() - halfWidth * n.x());
270#include "moc_GeoPolyline.cpp"
A 3d point representation.
void update(Part *part, const QByteArray &data, qint64 dataSize)
Binds a QML item to a specific geodetic location in screen coordinates.
const_reference at(qsizetype i) const const
void reserve(qsizetype size)
qsizetype size() const const
QRectF boundingRect() const const
qreal height() const const
qreal width() const const
void setColor(const QColor &color)
const AttributeSet & defaultAttributes_Point2D()
void appendChildNode(QSGNode *node)
QFuture< void > map(Iterator begin, Iterator end, MapFunctor &&function)
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
QVector2D normalized() const const