From 2d9115fa565a44cd4fa91a21775b6e461734aaa2 Mon Sep 17 00:00:00 2001 From: "Juergen E. Fischer" Date: Wed, 1 Aug 2012 08:47:11 +0200 Subject: [PATCH] - GEOSInterpolate only available in GEOS>=3.2 - sync QgsGeometry sip bindings with C++ --- python/core/qgsgeometry.sip | 214 +++++++++++++++++++----------------- src/core/qgsgeometry.cpp | 31 +++--- src/core/qgsgeometry.h | 21 ++-- 3 files changed, 142 insertions(+), 124 deletions(-) diff --git a/python/core/qgsgeometry.sip b/python/core/qgsgeometry.sip index 745708c1e34..edd89cba6cf 100644 --- a/python/core/qgsgeometry.sip +++ b/python/core/qgsgeometry.sip @@ -1,10 +1,10 @@ -/** polyline is just a list of points */ +/** polyline is represented as a vector of points */ typedef QVector QgsPolyline; /** polygon: first item of the list is outer ring, inner rings (if any) start from second item */ typedef QVector< QVector > QgsPolygon; - + /** a collection of QgsPoints that share a common collection of attributes */ typedef QVector QgsMultiPoint; @@ -23,36 +23,34 @@ class QgsGeometry %End public: - //! Constructor QgsGeometry(); - + /** copy constructor will prompt a deep copy of the object */ QgsGeometry( const QgsGeometry & ); - + //! Destructor ~QgsGeometry(); - /** static method that creates geometry from Wkt */ - static QgsGeometry* fromWkt(QString wkt) /Factory/; - + static QgsGeometry* fromWkt( QString wkt ) /Factory/; + /** construct geometry from a point */ - static QgsGeometry* fromPoint(const QgsPoint& point) /Factory/; + static QgsGeometry* fromPoint( const QgsPoint& point ) /Factory/; /** construct geometry from a multipoint */ - static QgsGeometry* fromMultiPoint(const QgsMultiPoint& multipoint) /Factory/; + static QgsGeometry* fromMultiPoint( const QgsMultiPoint& multipoint ) /Factory/; /** construct geometry from a polyline */ - static QgsGeometry* fromPolyline(const QgsPolyline& polyline) /Factory/; + static QgsGeometry* fromPolyline( const QgsPolyline& polyline ) /Factory/; /** construct geometry from a multipolyline*/ - static QgsGeometry* fromMultiPolyline(const QgsMultiPolyline& multiline) /Factory/; + static QgsGeometry* fromMultiPolyline( const QgsMultiPolyline& multiline ) /Factory/; /** construct geometry from a polygon */ - static QgsGeometry* fromPolygon(const QgsPolygon& polygon) /Factory/; + static QgsGeometry* fromPolygon( const QgsPolygon& polygon ) /Factory/; /** construct geometry from a multipolygon */ - static QgsGeometry* fromMultiPolygon(const QgsMultiPolygon& multipoly) /Factory/; + static QgsGeometry* fromMultiPolygon( const QgsMultiPolygon& multipoly ) /Factory/; /** construct geometry from a rectangle */ - static QgsGeometry* fromRect(const QgsRectangle& rect) /Factory/; - + static QgsGeometry* fromRect( const QgsRectangle& rect ) /Factory/; + /** @@ -77,10 +75,10 @@ class QgsGeometry %End /** - Returns the size of the WKB in asWkb(). - */ + * Returns the size of the WKB in asWkb(). + */ size_t wkbSize(); - + /** Returns type of wkb (point / linestring / polygon etc.) */ QGis::WkbType wkbType(); @@ -105,29 +103,24 @@ class QgsGeometry */ bool isGeosEmpty(); - /** - Set the geometry, feeding in a geometry in GEOS format. - */ - // TODO: unsupported class... would be possible to use PyGEOS? - //void fromGeos(geos::Geometry* geos); - - /** get area using GEOS + /** get area of geometry using GEOS @note added in 1.5 */ double area(); - /** get length using GEOS + /** get length of geometry using GEOS @note added in 1.5 */ double length(); - double distance(QgsGeometry& geom); + double distance( QgsGeometry& geom ); /** - Returns the vertex closest to the given point - (and also vertex index, squared distance and indexes of the vertices before/after) + Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap point / target point + and the indices of the vertices before/after. The vertices before/after are -1 if not present */ - QgsPoint closestVertex(const QgsPoint& point, int& atVertex /Out/, int& beforeVertex /Out/, int& afterVertex /Out/, double& sqrDist /Out/); + QgsPoint closestVertex( const QgsPoint& point, int& atVertex /Out/, int& beforeVertex /Out/, int& afterVertex /Out/, double& sqrDist /Out/); + /** Returns the indexes of the vertices before and after the given vertex index. @@ -141,32 +134,33 @@ class QgsGeometry account the first vertex is equal to the last vertex (and will skip equal vertex positions). */ - void adjacentVertices(int atVertex, int& beforeVertex /Out/, int& afterVertex /Out/); + void adjacentVertices( int atVertex, int& beforeVertex /Out/, int& afterVertex /Out/ ); + /** Insert a new vertex before the given vertex index, * ring and item (first number is index 0) * If the requested vertex number (beforeVertex.back()) is greater * than the last actual vertex on the requested ring and item, * it is assumed that the vertex is to be appended instead of inserted. - * Returns FALSE if atVertex does not correspond to a valid vertex + * Returns false if atVertex does not correspond to a valid vertex * on this geometry (including if this geometry is a Point). * It is up to the caller to distinguish between * these error conditions. (Or maybe we add another method to this * object to help make the distinction?) */ - bool insertVertex(double x, double y, int beforeVertex); + bool insertVertex( double x, double y, int beforeVertex ); - /** Moves the vertex at the given position number, - * ring and item (first number is index 0) + /** Moves the vertex at the given position number + * and item (first number is index 0) * to the given coordinates. - * Returns FALSE if atVertex does not correspond to a valid vertex - * on this geometry + * Returns false if atVertex does not correspond to a valid vertex + * on this geometry */ - bool moveVertex(double x, double y, int atVertex); - - /** Deletes the vertex at the given position number, - * ring and item (first number is index 0) - * Returns FALSE if atVertex does not correspond to a valid vertex + bool moveVertex( double x, double y, int atVertex ); + + /** Deletes the vertex at the given position number and item + * (first number is index 0) + * Returns false if atVertex does not correspond to a valid vertex * on this geometry (including if this geometry is a Point), * or if the number of remaining verticies in the linestring * would be less than two. @@ -174,87 +168,95 @@ class QgsGeometry * these error conditions. (Or maybe we add another method to this * object to help make the distinction?) */ - bool deleteVertex(int atVertex); + bool deleteVertex( int atVertex ); /** * Returns coordinates of a vertex. * @param atVertex index of the vertex * @return Coordinates of the vertex or QgsPoint(0,0) on error */ - QgsPoint vertexAt(int atVertex); + QgsPoint vertexAt( int atVertex ); /** - Returns the squared cartesian distance between the given point - to the given vertex index*/ - double sqrDistToVertexAt(QgsPoint& point /In/, int atVertex); + * Returns the squared cartesian distance between the given point + * to the given vertex index (vertex at the given position number, + * ring and item (first number is index 0)) + */ + double sqrDistToVertexAt( QgsPoint& point /In/, int atVertex ); - - /** + /** * Searches for the the closest vertex in this geometry to the given point. * @param point Specifiest the point for search * @param atVertex Receives index of the closest vertex * @return The squared cartesian distance is also returned in sqrDist, negative number on error */ - double closestVertexWithContext(const QgsPoint& point, int& atVertex /Out/); + double closestVertexWithContext( const QgsPoint& point, int& atVertex /Out/ ); /** * Searches for the closest segment of geometry to the given point * @param point Specifies the point for search * @param minDistPoint Receives the nearest point on the segment - * @param beforeVertex Receives index of the vertex before the closest segment + * @param afterVertex Receives index of the vertex after the closest segment. The vertex + * before the closest segment is always afterVertex - 1 + * @param leftOf Out: Returns if the point lies on the left of right side of the segment ( < 0 means left, > 0 means right ) + * @param epsilon epsilon for segment snapping (added in 1.8) * @return The squared cartesian distance is also returned in sqrDist, negative number on error */ - double closestSegmentWithContext(const QgsPoint& point, QgsPoint& minDistPoint /Out/, int& beforeVertex /Out/); + double closestSegmentWithContext( const QgsPoint& point, QgsPoint& minDistPoint /Out/, int& beforeVertex /Out/ ); - /**Adds a new ring to this geometry. This makes only sense for polygon and multipolygons. - @return 0 in case of success (ring added), 1 problem with geometry type, 2 ring not closed, \ + /**Adds a new ring to this geometry. This makes only sense for polygon and multipolygons. + @return 0 in case of success (ring added), 1 problem with geometry type, 2 ring not closed, 3 ring is not valid geometry, 4 ring not disjoint with existing rings, 5 no polygon found which contained the ring*/ - int addRing(const QList& ring); + int addRing( const QList& ring ); - /**Adds a new island polygon to a multipolygon feature - @return 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring \ -not disjoint with existing polygons of the feature*/ - int addPart(const QList& ring); + /**Adds a new island polygon to a multipolygon feature + @return 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring + not disjoint with existing polygons of the feature*/ + int addPart( const QList& ring ); int addIsland( const QList &ring ) /Deprecated/; - /**Translate this geometry by dx, dy + /**Translate this geometry by dx, dy @return 0 in case of success*/ - int translate(double dx, double dy); + int translate( double dx, double dy ); - /**Transform this geometry as described by CoordinateTranasform ct + /**Transform this geometry as described by CoordinateTranasform ct @return 0 in case of success*/ int transform( const QgsCoordinateTransform& ct ); - /**Splits this geometry according to a given line. Note that the geometry is only split once. If there are several intersections - between geometry and splitLine, only the first one is considered. + /**Splits this geometry according to a given line. Note that the geometry is only split once. If there are several intersections + between geometry and splitLine, only the first one is considered. @param splitLine the line that splits the geometry - @param newGeometrys OUT: list of new geometries that have been created with the split + @param[out] newGeometries list of new geometries that have been created with the split @param topological true if topological editing is enabled - @topologyTestPoints OUT: points that need to be tested for topological completeness in the dataset + @param[out] topologyTestPoints points that need to be tested for topological completeness in the dataset @return 0 in case of success, 1 if geometry has not been split, error else*/ - int splitGeometry(const QList& splitLine, QList& newGeometries /Out/, bool topological, QList& topologyTestPoints /Out/); + int splitGeometry( const QList& splitLine, + QList&newGeometries /Out/, + bool topological, + QList &topologyTestPoints /Out/); -/**Replaces a part of this geometry with another line + /**Replaces a part of this geometry with another line @return 0 in case of success @note: this function was added in version 1.3*/ int reshapeGeometry( const QList& reshapeWithLine ); - /**Changes this geometry such that it does not intersect the other geometry + /**Changes this geometry such that it does not intersect the other geometry @param other geometry that should not be intersect @return 0 in case of success*/ - int makeDifference(QgsGeometry* other); + int makeDifference( QgsGeometry* other ); /**Returns the bounding box of this feature*/ QgsRectangle boundingBox(); /** Test for intersection with a rectangle (uses GEOS) */ - bool intersects(const QgsRectangle& r); - /** Test for intersection with a geoemetry (uses GEOS) */ - bool intersects(QgsGeometry* geometry); + bool intersects( const QgsRectangle& r ); + + /** Test for intersection with a geometry (uses GEOS) */ + bool intersects( QgsGeometry* geometry ); /** Test for containment of a point (uses GEOS) */ - bool contains(QgsPoint* p); - + bool contains( QgsPoint* p ); + /** Test for if geometry is contained in an other (uses GEOS) * @note added in 1.5 */ bool contains( QgsGeometry* geometry ); @@ -285,11 +287,11 @@ not disjoint with existing polygons of the feature*/ /** Returns a buffer region around this geometry having the given width and with a specified number of segments used to approximate curves */ - QgsGeometry* buffer(double distance, int segments) /Factory/; + QgsGeometry* buffer( double distance, int segments ) /Factory/; /** Returns a simplified version of this geometry using a specified tolerance value */ - QgsGeometry* simplify(double tolerance) /Factory/; - + QgsGeometry* simplify( double tolerance ) /Factory/; + /** Returns the center of mass of a geometry * @note for line based geometries, the center point of the line is returned, * and for point based geometries, the point itself is returned */ @@ -298,53 +300,59 @@ not disjoint with existing polygons of the feature*/ /** Returns the smallest convex polygon that contains all the points in the geometry. */ QgsGeometry* convexHull() /Factory/; + /* Return interpolated point on line at distance + * @note added in 1.9 + */ QgsGeometry* interpolate( double distance ) /Factory/; - + /** Returns a geometry representing the points shared by this geometry and other. */ - QgsGeometry* intersection(QgsGeometry* geometry) /Factory/; - + QgsGeometry* intersection( QgsGeometry* geometry ) /Factory/; + /** Returns a geometry representing all the points in this geometry and other (a - * union geometry operation). + * union geometry operation). * @note this operation is not called union since its a reserved word in C++.*/ QgsGeometry* combine( QgsGeometry* geometry ) /Factory/; - + /** Returns a geometry representing the points making up this geometry that do not make up other. */ - QgsGeometry* difference(QgsGeometry* geometry) /Factory/; - + QgsGeometry* difference( QgsGeometry* geometry ) /Factory/; + /** Returns a Geometry representing the points making up this Geometry that do not make up other. */ - QgsGeometry* symDifference(QgsGeometry* geometry) /Factory/; - - /**Creates a geos geometry from this features geometry. Note, that the returned object needs to be deleted*/ - // TODO: unsupported class... would be possible to use PyGEOS? - //geos::Geometry* geosGeometry() const; + QgsGeometry* symDifference( QgsGeometry* geometry ) /Factory/; /** Exports the geometry to mWkt - @return true in case of success and false else + * @return true in case of success and false else */ QString exportToWkt(); - + + /** Exports the geometry to mGeoJSON + * @return true in case of success and false else + * @note added in 1.8 + * @note python binding added in 1.9 + */ + QString exportToGeoJSON(); + /* Accessor functions for getting geometry data */ - + /** return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0,0] */ QgsPoint asPoint(); - + /** return contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list */ QgsPolyline asPolyline(); - + /** return contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list */ QgsPolygon asPolygon(); - + /** return contents of the geometry as a multi point - if wkbType is WKBMultiPint, otherwise an empty list */ + if wkbType is WKBMultiPoint, otherwise an empty list */ QgsMultiPoint asMultiPoint(); - + /** return contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list */ QgsMultiPolyline asMultiPolyline(); - + /** return contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list */ QgsMultiPolygon asMultiPolygon(); @@ -356,12 +364,12 @@ not disjoint with existing polygons of the feature*/ /** delete a ring in polygon or multipolygon. Ring 0 is outer ring and can't be deleted. - @return TRUE on success + @return true on success @note added in version 1.2 */ bool deleteRing( int ringNum, int partNum = 0 ); /** delete part identified by the part number - @return TRUE on success + @return true on success @note added in version 1.2 */ bool deletePart( int partNum ); @@ -388,7 +396,7 @@ not disjoint with existing polygons of the feature*/ QgsPoint where(); bool hasWhere(); }; - + /** Validate geometry and produce a list of geometry errors * @note python binding added in 1.6 **/ diff --git a/src/core/qgsgeometry.cpp b/src/core/qgsgeometry.cpp index 3d6fed1b2bc..d9fb18b015d 100644 --- a/src/core/qgsgeometry.cpp +++ b/src/core/qgsgeometry.cpp @@ -6411,20 +6411,25 @@ QgsGeometry* QgsGeometry::convexHull() QgsGeometry* QgsGeometry::interpolate( double distance ) { - if ( !mGeos ) - { - exportWkbToGeos(); - } - if ( !mGeos ) - { - return 0; - } +#if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ + ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2))) + if ( !mGeos ) + { + exportWkbToGeos(); + } + if ( !mGeos ) + { + return 0; + } - try - { - return fromGeosGeom( GEOSInterpolate( mGeos, distance ) ); - } - CATCH_GEOS( 0 ) + try + { + return fromGeosGeom( GEOSInterpolate( mGeos, distance ) ); + } + CATCH_GEOS( 0 ) +#else + QgsMessageLog::logMessage( QObject::tr( "GEOS prior to 3.2 doesn't support GEOSInterpolate" ), QObject::tr( "GEOS" ) ); +#endif } QgsGeometry* QgsGeometry::intersection( QgsGeometry* geometry ) diff --git a/src/core/qgsgeometry.h b/src/core/qgsgeometry.h index d8de4ac47cd..61fa6f1607f 100644 --- a/src/core/qgsgeometry.h +++ b/src/core/qgsgeometry.h @@ -113,8 +113,8 @@ class CORE_EXPORT QgsGeometry unsigned char * asWkb(); /** - Returns the size of the WKB in asWkb(). - */ + * Returns the size of the WKB in asWkb(). + */ size_t wkbSize(); /**Returns a geos geomtry. QgsGeometry keeps ownership, don't delete the returned object! @@ -220,10 +220,9 @@ class CORE_EXPORT QgsGeometry QgsPoint vertexAt( int atVertex ); /** - Returns the squared cartesian distance between the given point - to the given vertex index (vertex at the given position number, - ring and item (first number is index 0)) - + * Returns the squared cartesian distance between the given point + * to the given vertex index (vertex at the given position number, + * ring and item (first number is index 0)) */ double sqrDistToVertexAt( QgsPoint& point, int atVertex ); @@ -343,6 +342,9 @@ class CORE_EXPORT QgsGeometry /** Returns the smallest convex polygon that contains all the points in the geometry. */ QgsGeometry* convexHull(); + /* Return interpolated point on line at distance + * @note added in 1.9 + */ QgsGeometry* interpolate( double distance ); /** Returns a geometry representing the points shared by this geometry and other. */ @@ -360,12 +362,14 @@ class CORE_EXPORT QgsGeometry QgsGeometry* symDifference( QgsGeometry* geometry ); /** Exports the geometry to mWkt - @return true in case of success and false else + * @return true in case of success and false else */ QString exportToWkt(); /** Exports the geometry to mGeoJSON - @return true in case of success and false else + * @return true in case of success and false else + * @note added in 1.8 + * @note python binding added in 1.9 */ QString exportToGeoJSON(); @@ -441,6 +445,7 @@ class CORE_EXPORT QgsGeometry /** Validate geometry and produce a list of geometry errors * @note added in 1.5 + * @note python binding added in 1.6 **/ void validateGeometry( QList &errors );