6 #include "MarbleQuickItem.h"
7 #include "GeoPolyline.h"
8 #include "Coordinate.h"
10 #include <QSGGeometryNode>
11 #include <QSGFlatColorMaterial>
12 #include <QSGSimpleTextureNode>
17 #include "MarbleGlobal.h"
20 using Marble::EARTH_RADIUS;
21 using Marble::DEG2RAD;
25 GeoPolyline::GeoPolyline(
QQuickItem *parent ) :
32 m_clipScreenCoordinates(true)
34 setFlag(ItemHasContents,
true);
37 MarbleQuickItem * GeoPolyline::map()
const
42 void GeoPolyline::setMap(MarbleQuickItem *map)
49 connect(m_map, &MarbleQuickItem::visibleLatLonAltBoxChanged,
this, &GeoPolyline::updateScreenPositions);
50 emit mapChanged(m_map);
53 void GeoPolyline::updateScreenPositions() {
54 GeoDataLineString lineString(m_lineString);
58 displayPolygon <<
QPointF(-10,-10) <<
QPointF(m_map->mapWidth() + 10, -10)
59 <<
QPointF(m_map->mapWidth() + 10, m_map->mapHeight() + 10) <<
QPointF(-10, m_map->mapHeight() + 10);
60 m_screenPolygons.clear();
62 bool success = m_map->screenCoordinatesFromGeoDataLineString(lineString, fullScreenPolygons);
63 if (m_clipScreenCoordinates) {
64 for (
auto reducedPolygon : qAsConst(fullScreenPolygons)) {
65 m_screenPolygons << reducedPolygon->intersected(displayPolygon);
69 for (
auto eachPolygon : qAsConst(fullScreenPolygons)) {
70 m_screenPolygons << *eachPolygon;
74 qDeleteAll(fullScreenPolygons);
76 QVariantList previousScreenCoordinates;
77 previousScreenCoordinates = m_screenCoordinates;
78 m_screenCoordinates.clear();
81 for (
auto screenPolygon : qAsConst(m_screenPolygons)) {
82 QVariantList polyline;
83 for (
auto node : screenPolygon) {
87 polyline.append(vmap);
89 m_screenCoordinates.insert(i, polyline);
94 QRectF polygonBoundingRect;
95 if (m_screenPolygons.length() == 1) {
96 polygonBoundingRect = m_screenPolygons[0].boundingRect();
100 for (
auto polygon : qAsConst(m_screenPolygons)) {
105 setX(polygonBoundingRect.
x());
106 setY(polygonBoundingRect.
y());
107 setWidth(polygonBoundingRect.
width());
108 setHeight(polygonBoundingRect.
height());
110 if (m_screenCoordinates != previousScreenCoordinates) {
111 emit screenCoordinatesChanged();
113 emit readonlyXChanged();
114 emit readonlyYChanged();
115 emit readonlyWidthChanged();
116 emit readonlyHeightChanged();
121 bool GeoPolyline::observable()
const
126 QVariantList GeoPolyline::geoCoordinates()
const
128 return m_geoCoordinates;
131 void GeoPolyline::setGeoCoordinates(
const QVariantList & coordinates)
133 m_lineString.clear();
134 m_lineString.setTessellate(m_tessellate);
135 for(
auto & item : coordinates) {
136 QVariantMap
map = item.toMap();
141 GeoDataCoordinates::Degree
145 m_geoCoordinates = coordinates;
146 emit geoCoordinatesChanged();
147 updateScreenPositions();
150 QVariantList GeoPolyline::screenCoordinates()
const
152 return m_screenCoordinates;
155 QColor GeoPolyline::lineColor()
const
160 qreal GeoPolyline::lineWidth()
const
165 void GeoPolyline::setLineColor(
const QColor& lineColor)
167 if (m_lineColor == lineColor)
170 m_lineColor = lineColor;
171 emit lineColorChanged(m_lineColor);
174 void GeoPolyline::setLineWidth(
const qreal lineWidth)
176 if (m_lineWidth == lineWidth)
179 m_lineWidth = lineWidth;
180 emit lineWidthChanged(m_lineWidth);
183 bool GeoPolyline::tessellate()
const
188 bool GeoPolyline::clipScreenCoordinates()
const
190 return m_clipScreenCoordinates;
193 void GeoPolyline::setTessellate(
bool tessellate)
195 if (m_tessellate == tessellate)
198 m_tessellate = tessellate;
199 emit tessellateChanged(m_tessellate);
202 void GeoPolyline::setClipScreenCoordinates(
bool clipped)
204 if (m_clipScreenCoordinates == clipped)
207 m_clipScreenCoordinates = clipped;
208 emit clipScreenCoordinatesChanged(m_clipScreenCoordinates);
211 qreal GeoPolyline::readonlyX()
const
216 qreal GeoPolyline::readonlyY()
const
221 qreal GeoPolyline::readonlyWidth()
const
226 qreal GeoPolyline::readonlyHeight()
const
231 QSGNode *GeoPolyline::updatePaintNode(
QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
233 qreal
const halfWidth = m_lineWidth;
238 if (m_screenPolygons.isEmpty())
return oldNode;
240 for(
int i = 0; i < m_screenPolygons.length(); ++i) {
243 int segmentCount = polygon.
size() - 1;
245 for(
int i = 0; i < segmentCount; ++i) {
252 lineNodeGeo->
allocate((segmentCount + 1)*2);
265 for(
int i = 0; i < segmentCount + 1; ++i) {
266 auto const & a = mapFromItem(m_map, polygon.
at(i));
267 auto const & n = normals[qMin(i, segmentCount - 1)].toPointF();
268 points[++k].set(a.x() - halfWidth * n.y(), a.y() + halfWidth * n.x());
269 points[++k].set(a.x() + halfWidth * n.y(), a.y() - halfWidth * n.x());
278 #include "moc_GeoPolyline.cpp"