[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