[Marble-commits] KDE/kdeedu/marble/src/lib/geodata/data
Dennis Nienhüser
earthwings at gentoo.org
Sun Oct 10 12:05:46 CEST 2010
SVN commit 1184451 by nienhueser:
Implement bool GeoDataLinearRing::contains( GeoDataCoordinates ) using the ray casting algorithm (runs in O(n), n number of vertices). Implement bool GeoDataPolygon::contains( GeoDataCoordinates ) using the GeoDataLinearRing implementation.
M +27 -0 GeoDataLinearRing.cpp
M +7 -0 GeoDataLinearRing.h
M +17 -0 GeoDataPolygon.cpp
M +7 -0 GeoDataPolygon.h
--- trunk/KDE/kdeedu/marble/src/lib/geodata/data/GeoDataLinearRing.cpp #1184450:1184451
@@ -73,5 +73,32 @@
return p()->m_rangeCorrected;
}
+bool GeoDataLinearRing::contains( const GeoDataCoordinates &coordinates ) const
+{
+ // Quick bounding box check
+ if ( !latLonAltBox().contains( coordinates ) ) {
+ return false;
}
+ int const points = size();
+ bool inside = false; // also true for points = 0
+ int j = points - 1;
+
+ for ( int i=0; i<points; ++i ) {
+ GeoDataCoordinates one = at( i );
+ GeoDataCoordinates two = at( j );
+
+ if ( ( one.longitude() < coordinates.longitude() && two.longitude() >= coordinates.longitude() ) ||
+ ( two.longitude() < coordinates.longitude() && one.longitude() >= coordinates.longitude() ) ) {
+ if ( one.latitude() + ( coordinates.longitude() - one.longitude()) / ( two.longitude() - one.longitude()) * ( two.latitude()-one.latitude() ) < coordinates.latitude() ) {
+ inside = !inside;
+ }
+ }
+
+ j = i;
+ }
+
+ return inside;
+}
+
+}
--- trunk/KDE/kdeedu/marble/src/lib/geodata/data/GeoDataLinearRing.h #1184450:1184451
@@ -120,6 +120,13 @@
Deprecation Warning: This method will likely be removed from the public API.
*/
virtual QVector<GeoDataLineString*> toRangeCorrected() const;
+
+/*!
+ \brief Returns whether the given coordinates lie within the polygon.
+
+ \return <code>true</code> if the coordinates lie within the polygon, false otherwise.
+*/
+ virtual bool contains( const GeoDataCoordinates &coordinates ) const;
};
}
--- trunk/KDE/kdeedu/marble/src/lib/geodata/data/GeoDataPolygon.cpp #1184450:1184451
@@ -150,4 +150,21 @@
}
}
+bool GeoDataPolygon::contains( const GeoDataCoordinates &coordinates ) const
+{
+ if ( !outerBoundary().contains( coordinates ) ) {
+ // Not inside the polygon at all
+ return false;
}
+
+ foreach( const GeoDataLinearRing &ring, innerBoundaries() ) {
+ if ( ring.contains( coordinates ) ) {
+ // Inside the polygon, but in one of its holes
+ return false;
+ }
+ }
+
+ return true;
+}
+
+}
--- trunk/KDE/kdeedu/marble/src/lib/geodata/data/GeoDataPolygon.h #1184450:1184451
@@ -179,7 +179,14 @@
*/
void appendInnerBoundary( const GeoDataLinearRing& boundary );
+/*!
+ \brief Returns whether the given coordinates lie within the polygon.
+ \return <code>true</code> if the coordinates lie within the polygon
+ (and not in its holes), false otherwise.
+*/
+ virtual bool contains( const GeoDataCoordinates &coordinates ) const;
+
// Serialization
/*!
\brief Serialize the Polygon to a stream.
More information about the Marble-commits
mailing list