summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Sherollari <jdotsh@gmail.com>2018-07-27 16:04:42 +0200
committerPaolo Angelelli <paolo.angelelli@qt.io>2018-08-20 10:53:02 +0000
commit282d146923533eea6105758b9f09f29ee896975a (patch)
treeb7223c5ca5cc0b896dd4cd2e003360eca6356f00
parent367c49e91366aa9b13bc7d64209321168680841e (diff)
downloadqtlocation-282d146923533eea6105758b9f09f29ee896975a.tar.gz
Add hole support in QGeoPolygon
[ChangeLog][QtPositioning] Added holes in QGeoPolygons Change-Id: I490bcf8c4a6d9f35fa364072d8ea70b914bfc640 Reviewed-by: Alex Blasche <alexander.blasche@qt.io> Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io>
-rw-r--r--src/positioning/qgeopath.cpp66
-rw-r--r--src/positioning/qgeopath_p.h6
-rw-r--r--src/positioning/qgeopolygon.cpp78
-rw-r--r--src/positioning/qgeopolygon.h6
4 files changed, 156 insertions, 0 deletions
diff --git a/src/positioning/qgeopath.cpp b/src/positioning/qgeopath.cpp
index 6fc79c07..3747474e 100644
--- a/src/positioning/qgeopath.cpp
+++ b/src/positioning/qgeopath.cpp
@@ -38,6 +38,7 @@
****************************************************************************/
#include "qgeopath.h"
+#include "qgeopolygon.h"
#include "qgeopath_p.h"
#include "qgeocoordinate.h"
@@ -580,11 +581,26 @@ bool QGeoPathPrivate::lineContains(const QGeoCoordinate &coordinate) const
return (m_path[0].distanceTo(coordinate) <= lineRadius);
}
+/*!
+ modified version of polygonContains with holes support.
+*/
bool QGeoPathPrivate::polygonContains(const QGeoCoordinate &coordinate) const
{
if (m_clipperDirty)
const_cast<QGeoPathPrivate *>(this)->updateClipperPath();
+ // iterates the holes List checking whether the point is contained inside the holes
+ for (const QList<QGeoCoordinate> &holePath : qAsConst(m_holesList)) {
+
+ QGeoPolygon holePolygon;
+ holePolygon.setPath(holePath);
+ QGeoPath holeBoundary;
+ holeBoundary.setPath(holePath);
+
+ if (holePolygon.contains(coordinate) && !(holeBoundary.contains(coordinate)))
+ return false;
+ }
+
QDoubleVector2D coord = QWebMercator::coordToMercator(coordinate);
double tlx = QWebMercator::coordToMercator(m_bbox.topLeft()).x();
if (coord.x() < tlx)
@@ -621,6 +637,14 @@ void QGeoPathPrivate::translate(double degreesLatitude, double degreesLongitude)
p.setLatitude(p.latitude() + degreesLatitude);
p.setLongitude(QLocationUtils::wrapLong(p.longitude() + degreesLongitude));
}
+ if (!m_holesList.isEmpty()){
+ for (QList<QGeoCoordinate> &hole: m_holesList){
+ for (QGeoCoordinate &holeVertex: hole){
+ holeVertex.setLatitude(holeVertex.latitude() + degreesLatitude);
+ holeVertex.setLongitude(QLocationUtils::wrapLong(holeVertex.longitude() + degreesLongitude));
+ }
+ }
+ }
m_bbox.translate(degreesLatitude, degreesLongitude);
m_minLati += degreesLatitude;
m_maxLati += degreesLatitude;
@@ -800,4 +824,46 @@ void QGeoPathPrivate::updateClipperPath()
m_clipperPath = QClipperUtils::qListToPath(preservedPath);
}
+
+/*!
+ Sets the \a path for an Hole inside the polygon.The hole has QList<QGeoCoordinate> type
+*/
+void QGeoPathPrivate::addHole(const QList<QGeoCoordinate> &holePath)
+{
+ for (const QGeoCoordinate &holeVertex: holePath)
+ if (!holeVertex.isValid())
+ return;
+
+ m_holesList << holePath;
+}
+
+/*!
+ Returns a QVariant containing a QList<QGeoCoordinate> representing the hole at index
+*/
+const QList<QGeoCoordinate> QGeoPathPrivate::holePath(int index) const
+{
+ return m_holesList.at(index);
+}
+
+
+/*!
+ Removes element at position \a index from the holes QList.
+*/
+void QGeoPathPrivate::removeHole(int index)
+{
+ if (index < 0 || index >= m_holesList.size())
+ return;
+
+ m_holesList.removeAt(index);
+}
+
+/*!
+ Returns the number of holes.
+*/
+int QGeoPathPrivate::holesCount() const
+{
+ return m_holesList.size();
+}
+
QT_END_NAMESPACE
+
diff --git a/src/positioning/qgeopath_p.h b/src/positioning/qgeopath_p.h
index 6548ce84..d39f0ab2 100644
--- a/src/positioning/qgeopath_p.h
+++ b/src/positioning/qgeopath_p.h
@@ -101,8 +101,14 @@ public:
void computeBoundingBox();
void updateBoundingBox();
void updateClipperPath();
+ void addHole(const QList<QGeoCoordinate> &holePath);
+ const QList<QGeoCoordinate> holePath(int index) const;
+ void removeHole(int index);
+ int holesCount() const;
+
QList<QGeoCoordinate> m_path;
+ QList<QList<QGeoCoordinate>> m_holesList;
QVector<double> m_deltaXs; // longitude deltas from m_path[0]
double m_minX; // minimum value inside deltaXs
double m_maxX; // maximum value inside deltaXs
diff --git a/src/positioning/qgeopolygon.cpp b/src/positioning/qgeopolygon.cpp
index 1cbbc06e..66659d4b 100644
--- a/src/positioning/qgeopolygon.cpp
+++ b/src/positioning/qgeopolygon.cpp
@@ -354,4 +354,82 @@ QString QGeoPolygon::toString() const
return QStringLiteral("QGeoPolygon([ %1 ])").arg(pathString);
}
+/*!
+ Sets the \a path for a hole inside the polygon. The hole is a QVariant containing a QList<QGeoCoordinate>.
+
+ \since 5.12
+*/
+void QGeoPolygon::addHole(const QVariant &holePath)
+{
+ Q_D(QGeoPolygon);
+ QList<QGeoCoordinate> qgcHolePath;
+ if (holePath.canConvert<QVariantList>()) {
+ const QVariantList qvlHolePath = holePath.toList();
+ for (const QVariant &vertex : qvlHolePath) {
+ if (vertex.canConvert<QGeoCoordinate>())
+ qgcHolePath << vertex.value<QGeoCoordinate>();
+ }
+ }
+ //ToDo: add QGeoShape support
+ return d->addHole(qgcHolePath);
+}
+
+/*!
+ Overloaded method. Sets the \a path for a hole inside the polygon. The hole is a QList<QGeoCoordinate>.
+
+ \since 5.12
+*/
+void QGeoPolygon::addHole(const QList<QGeoCoordinate> &holePath)
+{
+ Q_D(QGeoPolygon);
+ return d->addHole(holePath);
+}
+
+/*!
+ Returns a QVariant containing a QVariant containing a QList<QGeoCoordinate> which represents the hole at index.
+
+ \since 5.12
+*/
+const QVariantList QGeoPolygon::hole(int index) const
+{
+ Q_D(const QGeoPolygon);
+ QVariantList holeCoordinates;
+ for (const QGeoCoordinate &coords: d->holePath(index))
+ holeCoordinates << QVariant::fromValue(coords);
+ return holeCoordinates;
+}
+
+/*!
+ Returns a QList<QGeoCoordinate> which represents the hole at \a index.
+
+ \since 5.12
+*/
+const QList<QGeoCoordinate> QGeoPolygon::holePath(int index) const
+{
+ Q_D(const QGeoPolygon);
+ return d->holePath(index);
+}
+
+/*!
+ Removes element at position \a index from the holes QList.
+
+ \since 5.12
+*/
+void QGeoPolygon::removeHole(int index)
+{
+ Q_D(QGeoPolygon);
+ return d->removeHole(index);
+}
+
+/*!
+ Returns the number of holes.
+
+ \since 5.12
+*/
+int QGeoPolygon::holesCount() const
+{
+ Q_D(const QGeoPolygon);
+ return d->holesCount();
+}
+
QT_END_NAMESPACE
diff --git a/src/positioning/qgeopolygon.h b/src/positioning/qgeopolygon.h
index 85b09e34..ccc4b98b 100644
--- a/src/positioning/qgeopolygon.h
+++ b/src/positioning/qgeopolygon.h
@@ -73,6 +73,12 @@ public:
void setPath(const QList<QGeoCoordinate> &path); // ### Qt6: rename into setPerimeter
const QList<QGeoCoordinate> &path() const;
+ Q_INVOKABLE void addHole(const QVariant &holePath);
+ void addHole(const QList<QGeoCoordinate> &holePath);
+ Q_INVOKABLE const QVariantList hole(int index) const;
+ const QList<QGeoCoordinate> holePath(int index) const;
+ Q_INVOKABLE void removeHole(int index);
+ Q_INVOKABLE int holesCount() const;
Q_INVOKABLE void translate(double degreesLatitude, double degreesLongitude);
Q_INVOKABLE QGeoPolygon translated(double degreesLatitude, double degreesLongitude) const;
Q_INVOKABLE double length(int indexFrom = 0, int indexTo = -1) const;