30 #include <QtCore/qmath.h>
32 #define DEFAULT_QUADRANT_SEGMENTS 8
34 #define CATCH_GEOS(r) \
35 catch (GEOSException &e) \
37 QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr("GEOS") ); \
41 #define CATCH_GEOS_WITH_ERRMSG(r) \
42 catch (GEOSException &e) \
44 QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr("GEOS") ); \
47 *errorMsg = e.what(); \
59 vsnprintf( buffer,
sizeof buffer, fmt, ap );
69 #if defined(QGISDEBUG)
74 vsnprintf( buffer,
sizeof buffer, fmt, ap );
106 GEOSGeometry*
get()
const {
return mGeom; }
107 operator bool()
const {
return mGeom != 0; }
110 GEOSGeom_destroy_r( geosinit.
ctxt, mGeom );
119 :
QgsGeometryEngine( geometry ), mGeos( 0 ), mGeosPrepared( 0 ), mPrecision( precision )
126 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
128 GEOSPreparedGeom_destroy_r( geosinit.
ctxt, mGeosPrepared );
134 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
136 GEOSPreparedGeom_destroy_r( geosinit.
ctxt, mGeosPrepared );
143 GEOSPreparedGeom_destroy_r( geosinit.
ctxt, mGeosPrepared );
147 mGeosPrepared = GEOSPrepare_r( geosinit.
ctxt, mGeos );
151 void QgsGeos::cacheGeos()
const
163 return overlay( geom, INTERSECTION, errorMsg );
168 return overlay( geom, DIFFERENCE, errorMsg );
173 return overlay( geom, UNION, errorMsg );
181 for (
int i = 0; i < geomList.
size(); ++i )
183 geosGeometries[i] =
asGeos( geomList.
at( i ), mPrecision );
186 GEOSGeometry* geomUnion = 0;
189 GEOSGeometry* geomCollection = createGeosCollection( GEOS_GEOMETRYCOLLECTION, geosGeometries );
190 geomUnion = GEOSUnaryUnion_r( geosinit.
ctxt, geomCollection );
191 GEOSGeom_destroy_r( geosinit.
ctxt, geomCollection );
196 GEOSGeom_destroy_r( geosinit.
ctxt, geomUnion );
202 return overlay( geom, SYMDIFFERENCE, errorMsg );
213 GEOSGeometry* otherGeosGeom =
asGeos( &geom, mPrecision );
214 if ( !otherGeosGeom )
221 GEOSDistance_r( geosinit.
ctxt, mGeos, otherGeosGeom, &distance );
225 GEOSGeom_destroy_r( geosinit.
ctxt, otherGeosGeom );
232 return relation( geom, INTERSECTS, errorMsg );
237 return relation( geom, TOUCHES, errorMsg );
242 return relation( geom, CROSSES, errorMsg );
247 return relation( geom, WITHIN, errorMsg );
252 return relation( geom, OVERLAPS, errorMsg );
257 return relation( geom, CONTAINS, errorMsg );
262 return relation( geom, DISJOINT, errorMsg );
281 char* r = GEOSRelate_r( geosinit.
ctxt, mGeos, geosGeom.
get() );
285 GEOSFree_r( geosinit.
ctxt, r );
288 catch ( GEOSException &e )
292 *errorMsg = e.what();
309 if ( GEOSArea_r( geosinit.
ctxt, mGeos, &area ) != 1 )
325 if ( GEOSLength_r( geosinit.
ctxt, mGeos, &length ) != 1 )
351 if ( !GEOSisValid_r( geosinit.
ctxt, mGeos ) )
359 newGeometries.
clear();
360 GEOSGeometry* splitLineGeos = 0;
366 splitLineGeos = createGeosLinestring( &splitLine, mPrecision );
371 splitLineGeos = createGeosPoint( &pt, 2, mPrecision );
378 if ( !GEOSisValid_r( geosinit.
ctxt, splitLineGeos ) || !GEOSisSimple_r( geosinit.
ctxt, splitLineGeos ) )
380 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
387 if ( topologicalTestPointsSplit( splitLineGeos, topologyTestPoints ) != 0 )
394 returnCode = splitLinearGeometry( splitLineGeos, newGeometries );
395 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
399 returnCode = splitPolygonGeometry( splitLineGeos, newGeometries );
400 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
414 int QgsGeos::topologicalTestPointsSplit(
const GEOSGeometry* splitLine,
QList<QgsPointV2>& testPoints,
QString* errorMsg )
const
428 GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosinit.
ctxt, mGeos, splitLine );
429 if ( !intersectionGeom )
433 int nIntersectGeoms = 1;
434 if ( GEOSGeomTypeId_r( geosinit.
ctxt, intersectionGeom ) == GEOS_LINESTRING
435 || GEOSGeomTypeId_r( geosinit.
ctxt, intersectionGeom ) == GEOS_POINT )
439 nIntersectGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, intersectionGeom );
441 for (
int i = 0; i < nIntersectGeoms; ++i )
443 const GEOSGeometry* currentIntersectGeom;
445 currentIntersectGeom = intersectionGeom;
447 currentIntersectGeom = GEOSGetGeometryN_r( geosinit.
ctxt, intersectionGeom, i );
449 const GEOSCoordSequence* lineSequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, currentIntersectGeom );
450 unsigned int sequenceSize = 0;
452 if ( GEOSCoordSeq_getSize_r( geosinit.
ctxt, lineSequence, &sequenceSize ) != 0 )
454 for (
unsigned int i = 0; i < sequenceSize; ++i )
456 if ( GEOSCoordSeq_getX_r( geosinit.
ctxt, lineSequence, i, &x ) != 0 )
458 if ( GEOSCoordSeq_getY_r( geosinit.
ctxt, lineSequence, i, &y ) != 0 )
466 GEOSGeom_destroy_r( geosinit.
ctxt, intersectionGeom );
473 GEOSGeometry*
QgsGeos::linePointDifference( GEOSGeometry* GEOSsplitPoint )
const
475 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
478 if ( type == GEOS_MULTILINESTRING )
482 else if ( type == GEOS_LINESTRING )
502 delete splitGeom;
return 0;
517 for (
int j = 1; j < ( nVertices - 1 ); ++j )
521 if ( currentPoint == *splitPoint )
535 return asGeos( &lines, mPrecision );
547 if ( !GEOSIntersects_r( geosinit.
ctxt, splitLine, mGeos ) )
551 int linearIntersect = GEOSRelatePattern_r( geosinit.
ctxt, mGeos, splitLine,
"1********" );
552 if ( linearIntersect > 0 )
555 int splitGeomType = GEOSGeomTypeId_r( geosinit.
ctxt, splitLine );
557 GEOSGeometry* splitGeom;
558 if ( splitGeomType == GEOS_POINT )
560 splitGeom = linePointDifference( splitLine );
564 splitGeom = GEOSDifference_r( geosinit.
ctxt, mGeos, splitLine );
568 int splitType = GEOSGeomTypeId_r( geosinit.
ctxt, splitGeom );
569 if ( splitType == GEOS_MULTILINESTRING )
571 int nGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, splitGeom );
573 for (
int i = 0; i < nGeoms; ++i )
574 lineGeoms << GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, splitGeom, i ) );
579 lineGeoms << GEOSGeom_clone_r( geosinit.
ctxt, splitGeom );
582 mergeGeometriesMultiTypeSplit( lineGeoms );
584 for (
int i = 0; i < lineGeoms.
size(); ++i )
586 newGeometries <<
fromGeos( lineGeoms[i] );
587 GEOSGeom_destroy_r( geosinit.
ctxt, lineGeoms[i] );
590 GEOSGeom_destroy_r( geosinit.
ctxt, splitGeom );
603 if ( !GEOSIntersects_r( geosinit.
ctxt, splitLine, mGeos ) )
607 GEOSGeometry *nodedGeometry = nodeGeometries( splitLine, mGeos );
608 if ( !nodedGeometry )
611 GEOSGeometry *polygons = GEOSPolygonize_r( geosinit.
ctxt, &nodedGeometry, 1 );
612 if ( !polygons || numberOfGeometries( polygons ) == 0 )
615 GEOSGeom_destroy_r( geosinit.
ctxt, polygons );
617 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
622 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
627 GEOSGeometry *intersectGeometry = 0;
632 for (
int i = 0; i < numberOfGeometries( polygons ); i++ )
634 const GEOSGeometry *polygon = GEOSGetGeometryN_r( geosinit.
ctxt, polygons, i );
635 intersectGeometry = GEOSIntersection_r( geosinit.
ctxt, mGeos, polygon );
636 if ( !intersectGeometry )
642 double intersectionArea;
643 GEOSArea_r( geosinit.
ctxt, intersectGeometry, &intersectionArea );
646 GEOSArea_r( geosinit.
ctxt, polygon, &polygonArea );
648 const double areaRatio = intersectionArea / polygonArea;
649 if ( areaRatio > 0.99 && areaRatio < 1.01 )
650 testedGeometries << GEOSGeom_clone_r( geosinit.
ctxt, polygon );
652 GEOSGeom_destroy_r( geosinit.
ctxt, intersectGeometry );
654 GEOSGeom_destroy_r( geosinit.
ctxt, polygons );
656 bool splitDone =
true;
657 int nGeometriesThis = numberOfGeometries( mGeos );
658 if ( testedGeometries.
size() == nGeometriesThis )
663 mergeGeometriesMultiTypeSplit( testedGeometries );
668 for (
int i = 0; i < testedGeometries.
size(); ++i )
670 GEOSGeom_destroy_r( geosinit.
ctxt, testedGeometries[i] );
676 for ( i = 0; i < testedGeometries.
size() && GEOSisValid_r( geosinit.
ctxt, testedGeometries[i] ); ++i )
679 if ( i < testedGeometries.
size() )
681 for ( i = 0; i < testedGeometries.
size(); ++i )
682 GEOSGeom_destroy_r( geosinit.
ctxt, testedGeometries[i] );
687 for ( i = 0; i < testedGeometries.
size(); ++i )
688 newGeometries <<
fromGeos( testedGeometries[i] );
693 GEOSGeometry* QgsGeos::nodeGeometries(
const GEOSGeometry *splitLine,
const GEOSGeometry *geom )
695 if ( !splitLine || !geom )
698 GEOSGeometry *geometryBoundary = 0;
699 if ( GEOSGeomTypeId_r( geosinit.
ctxt, geom ) == GEOS_POLYGON || GEOSGeomTypeId_r( geosinit.
ctxt, geom ) == GEOS_MULTIPOLYGON )
700 geometryBoundary = GEOSBoundary_r( geosinit.
ctxt, geom );
702 geometryBoundary = GEOSGeom_clone_r( geosinit.
ctxt, geom );
704 GEOSGeometry *splitLineClone = GEOSGeom_clone_r( geosinit.
ctxt, splitLine );
705 GEOSGeometry *unionGeometry = GEOSUnion_r( geosinit.
ctxt, splitLineClone, geometryBoundary );
706 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineClone );
708 GEOSGeom_destroy_r( geosinit.
ctxt, geometryBoundary );
709 return unionGeometry;
718 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
719 if ( type != GEOS_GEOMETRYCOLLECTION &&
720 type != GEOS_MULTILINESTRING &&
721 type != GEOS_MULTIPOLYGON &&
722 type != GEOS_MULTIPOINT )
731 for (
int i = 0; i < copyList.
size(); ++i )
735 for (
int j = 0; j < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); j++ )
737 if ( GEOSEquals_r( geosinit.
ctxt, copyList[i], GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, j ) ) )
746 unionGeom << copyList[i];
751 geomVector << copyList[i];
753 if ( type == GEOS_MULTILINESTRING )
754 splitResult << createGeosCollection( GEOS_MULTILINESTRING, geomVector );
755 else if ( type == GEOS_MULTIPOLYGON )
756 splitResult << createGeosCollection( GEOS_MULTIPOLYGON, geomVector );
758 GEOSGeom_destroy_r( geosinit.
ctxt, copyList[i] );
763 if ( unionGeom.
size() > 0 )
765 if ( type == GEOS_MULTILINESTRING )
766 splitResult << createGeosCollection( GEOS_MULTILINESTRING, unionGeom );
767 else if ( type == GEOS_MULTIPOLYGON )
768 splitResult << createGeosCollection( GEOS_MULTIPOLYGON, unionGeom );
780 int nNullGeoms = geoms.
count( 0 );
781 int nNotNullGeoms = geoms.
size() - nNullGeoms;
783 GEOSGeometry **geomarr =
new GEOSGeometry*[ nNotNullGeoms ];
791 for ( ; geomIt != geoms.
constEnd(); ++geomIt )
795 geomarr[i] = *geomIt;
799 GEOSGeometry *geom = 0;
803 geom = GEOSGeom_createCollection_r( geosinit.
ctxt, typeId, geomarr, nNotNullGeoms );
805 catch ( GEOSException &e )
822 int nCoordDims = GEOSGeom_getCoordinateDimension_r( geosinit.
ctxt, geos );
823 int nDims = GEOSGeom_getDimensions_r( geosinit.
ctxt, geos );
824 bool hasZ = ( nCoordDims == 3 );
825 bool hasM = (( nDims - nCoordDims ) == 1 );
827 switch ( GEOSGeomTypeId_r( geosinit.
ctxt, geos ) )
831 const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, geos );
834 case GEOS_LINESTRING:
836 return sequenceToLinestring( geos, hasZ, hasM );
842 case GEOS_MULTIPOINT:
845 int nParts = GEOSGetNumGeometries_r( geosinit.
ctxt, geos );
846 for (
int i = 0; i < nParts; ++i )
848 const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, geos, i ) );
856 case GEOS_MULTILINESTRING:
859 int nParts = GEOSGetNumGeometries_r( geosinit.
ctxt, geos );
860 for (
int i = 0; i < nParts; ++i )
862 QgsLineStringV2* line = sequenceToLinestring( GEOSGetGeometryN_r( geosinit.
ctxt, geos, i ), hasZ, hasM );
868 return multiLineString;
870 case GEOS_MULTIPOLYGON:
874 int nParts = GEOSGetNumGeometries_r( geosinit.
ctxt, geos );
875 for (
int i = 0; i < nParts; ++i )
885 case GEOS_GEOMETRYCOLLECTION:
888 int nParts = GEOSGetNumGeometries_r( geosinit.
ctxt, geos );
889 for (
int i = 0; i < nParts; ++i )
897 return geomCollection;
905 if ( GEOSGeomTypeId_r( geosinit.
ctxt, geos ) != GEOS_POLYGON )
910 int nCoordDims = GEOSGeom_getCoordinateDimension_r( geosinit.
ctxt, geos );
911 int nDims = GEOSGeom_getDimensions_r( geosinit.
ctxt, geos );
912 bool hasZ = ( nCoordDims == 3 );
913 bool hasM = (( nDims - nCoordDims ) == 1 );
917 const GEOSGeometry* ring = GEOSGetExteriorRing_r( geosinit.
ctxt, geos );
924 for (
int i = 0; i < GEOSGetNumInteriorRings_r( geosinit.
ctxt, geos ); ++i )
926 ring = GEOSGetInteriorRingN_r( geosinit.
ctxt, geos, i );
929 interiorRings.
push_back( sequenceToLinestring( ring, hasZ, hasM ) );
937 QgsLineStringV2* QgsGeos::sequenceToLinestring(
const GEOSGeometry* geos,
bool hasZ,
bool hasM )
940 const GEOSCoordSequence* cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, geos );
941 unsigned int nPoints;
942 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &nPoints );
944 for (
unsigned int i = 0; i < nPoints; ++i )
953 int QgsGeos::numberOfGeometries( GEOSGeometry* g )
958 int geometryType = GEOSGeomTypeId_r( geosinit.
ctxt, g );
959 if ( geometryType == GEOS_POINT || geometryType == GEOS_LINESTRING || geometryType == GEOS_LINEARRING
960 || geometryType == GEOS_POLYGON )
964 return GEOSGetNumGeometries_r( geosinit.
ctxt, g );
977 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, i, &x );
978 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, i, &y );
981 GEOSCoordSeq_getZ_r( geosinit.
ctxt, cs, i, &z );
985 GEOSCoordSeq_getOrdinate_r( geosinit.
ctxt, cs, i, 3, &m );
1022 return createGeosLinestring( lineString.data(), precision );
1024 else if ( curvePolygon )
1027 return createGeosPolygon( polygon.data(), precision );
1031 return createGeosPoint( geom, coordDims, precision );
1035 int geosType = GEOS_MULTIPOINT;
1038 geosType = GEOS_MULTIPOINT;
1042 geosType = GEOS_MULTILINESTRING;
1046 geosType = GEOS_MULTIPOLYGON;
1048 else if ( geom->
geometryType() ==
"GeometryCollection" )
1050 geosType = GEOS_GEOMETRYCOLLECTION;
1064 return createGeosCollection( geosType, geomVector );
1089 opGeom.
reset( GEOSIntersection_r( geosinit.
ctxt, mGeos, geosGeom.get() ) );
1092 opGeom.
reset( GEOSDifference_r( geosinit.
ctxt, mGeos, geosGeom.get() ) );
1096 GEOSGeometry *unionGeometry = GEOSUnion_r( geosinit.
ctxt, mGeos, geosGeom.get() );
1098 if ( unionGeometry && GEOSGeomTypeId_r( geosinit.
ctxt, unionGeometry ) == GEOS_MULTILINESTRING )
1100 GEOSGeometry *mergedLines = GEOSLineMerge_r( geosinit.
ctxt, unionGeometry );
1103 GEOSGeom_destroy_r( geosinit.
ctxt, unionGeometry );
1104 unionGeometry = mergedLines;
1108 opGeom.
reset( unionGeometry );
1112 opGeom.
reset( GEOSSymDifference_r( geosinit.
ctxt, mGeos, geosGeom.get() ) );
1120 catch ( GEOSException &e )
1124 *errorMsg = e.what();
1143 bool result =
false;
1146 if ( mGeosPrepared )
1151 result = ( GEOSPreparedIntersects_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1154 result = ( GEOSPreparedTouches_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1157 result = ( GEOSPreparedCrosses_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1160 result = ( GEOSPreparedWithin_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1163 result = ( GEOSPreparedContains_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1166 result = ( GEOSPreparedDisjoint_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1169 result = ( GEOSPreparedOverlaps_r( geosinit.
ctxt, mGeosPrepared, geosGeom.get() ) == 1 );
1180 result = ( GEOSIntersects_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1183 result = ( GEOSTouches_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1186 result = ( GEOSCrosses_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1189 result = ( GEOSWithin_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1192 result = ( GEOSContains_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1195 result = ( GEOSDisjoint_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1198 result = ( GEOSOverlaps_r( geosinit.
ctxt, mGeos, geosGeom.get() ) == 1 );
1204 catch ( GEOSException &e )
1208 *errorMsg = e.what();
1226 geos.
reset( GEOSBuffer_r( geosinit.
ctxt, mGeos, distance, segments ) );
1239 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
1240 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
1245 geos.
reset( GEOSBufferWithStyle_r( geosinit.
ctxt, mGeos, distance, segments, endCapStyle, joinStyle, mitreLimit ) );
1263 geos.
reset( GEOSTopologyPreserveSimplify_r( geosinit.
ctxt, mGeos, tolerance ) );
1278 geos.
reset( GEOSInterpolate_r( geosinit.
ctxt, mGeos, distance ) );
1294 geos.
reset( GEOSGetCentroid_r( geosinit.
ctxt, mGeos ) );
1304 GEOSGeomGetX_r( geosinit.
ctxt, geos.
get(), &x );
1305 GEOSGeomGetY_r( geosinit.
ctxt, geos.
get(), &y );
1319 geos.
reset( GEOSEnvelope_r( geosinit.
ctxt, mGeos ) );
1335 geos.
reset( GEOSPointOnSurface_r( geosinit.
ctxt, mGeos ) );
1345 GEOSGeomGetX_r( geosinit.
ctxt, geos.
get(), &x );
1346 GEOSGeomGetY_r( geosinit.
ctxt, geos.
get(), &y );
1363 GEOSGeometry* cHull = GEOSConvexHull_r( geosinit.
ctxt, mGeos );
1365 GEOSGeom_destroy_r( geosinit.
ctxt, cHull );
1380 return GEOSisValid_r( geosinit.
ctxt, mGeos );
1399 bool equal = GEOSEquals_r( geosinit.
ctxt, mGeos, geosGeom.
get() );
1414 return GEOSisEmpty_r( geosinit.
ctxt, mGeos );
1419 GEOSCoordSequence* QgsGeos::createCoordinateSequence(
const QgsCurveV2* curve,
double precision )
1421 bool segmentize =
false;
1435 bool hasZ = line->
is3D();
1448 GEOSCoordSequence* coordSeq = 0;
1451 coordSeq = GEOSCoordSeq_create_r( geosinit.
ctxt, numPoints, coordDims );
1452 if ( precision > 0. )
1454 for (
int i = 0; i < numPoints; ++i )
1457 GEOSCoordSeq_setX_r( geosinit.
ctxt, coordSeq, i,
qgsRound( pt.
x() / precision ) * precision );
1458 GEOSCoordSeq_setY_r( geosinit.
ctxt, coordSeq, i,
qgsRound( pt.
y() / precision ) * precision );
1461 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, i, 2,
qgsRound( pt.
z() / precision ) * precision );
1465 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, i, 3, pt.
m() );
1471 for (
int i = 0; i < numPoints; ++i )
1474 GEOSCoordSeq_setX_r( geosinit.
ctxt, coordSeq, i, pt.
x() );
1475 GEOSCoordSeq_setY_r( geosinit.
ctxt, coordSeq, i, pt.
y() );
1478 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, i, 2, pt.
z() );
1482 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, i, 3, pt.
m() );
1496 GEOSGeometry* QgsGeos::createGeosPoint(
const QgsAbstractGeometryV2* point,
int coordDims,
double precision )
1502 GEOSGeometry* geosPoint = 0;
1506 GEOSCoordSequence* coordSeq = GEOSCoordSeq_create_r( geosinit.
ctxt, 1, coordDims );
1507 if ( precision > 0. )
1509 GEOSCoordSeq_setX_r( geosinit.
ctxt, coordSeq, 0,
qgsRound( pt->
x() / precision ) * precision );
1510 GEOSCoordSeq_setY_r( geosinit.
ctxt, coordSeq, 0,
qgsRound( pt->
y() / precision ) * precision );
1513 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, 0, 2,
qgsRound( pt->
z() / precision ) * precision );
1518 GEOSCoordSeq_setX_r( geosinit.
ctxt, coordSeq, 0, pt->
x() );
1519 GEOSCoordSeq_setY_r( geosinit.
ctxt, coordSeq, 0, pt->
y() );
1522 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, 0, 2, pt->
z() );
1527 GEOSCoordSeq_setOrdinate_r( geosinit.
ctxt, coordSeq, 0, 3, pt->
m() );
1529 geosPoint = GEOSGeom_createPoint_r( geosinit.
ctxt, coordSeq );
1541 GEOSCoordSequence* coordSeq = createCoordinateSequence( c, precision );
1545 GEOSGeometry* geosGeom = 0;
1548 geosGeom = GEOSGeom_createLineString_r( geosinit.
ctxt, coordSeq );
1561 if ( !exteriorRing )
1566 GEOSGeometry* geosPolygon = 0;
1569 GEOSGeometry* exteriorRingGeos = GEOSGeom_createLinearRing_r( geosinit.
ctxt, createCoordinateSequence( exteriorRing, precision ) );
1573 GEOSGeometry** holes = 0;
1576 holes =
new GEOSGeometry*[ nHoles ];
1579 for (
int i = 0; i < nHoles; ++i )
1582 holes[i] = GEOSGeom_createLinearRing_r( geosinit.
ctxt, createCoordinateSequence( interiorRing, precision ) );
1584 geosPolygon = GEOSGeom_createPolygon_r( geosinit.
ctxt, exteriorRingGeos, holes, nHoles );
1597 GEOSGeometry* offset = 0;
1600 offset = GEOSOffsetCurve_r( geosinit.
ctxt, mGeos, distance, segments, joinStyle, mitreLimit );
1604 GEOSGeom_destroy_r( geosinit.
ctxt, offset );
1612 if ( errorCode ) { *errorCode = 1; }
1616 GEOSGeometry* reshapeLineGeos = createGeosLinestring( &reshapeWithLine, mPrecision );
1619 int numGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
1620 if ( numGeoms == -1 )
1622 if ( errorCode ) { *errorCode = 1; }
1623 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeLineGeos );
1627 bool isMultiGeom =
false;
1628 int geosTypeId = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
1629 if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
1636 GEOSGeometry* reshapedGeometry;
1639 reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos, mPrecision );
1643 reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos, mPrecision );
1646 if ( errorCode ) { *errorCode = 0; }
1648 GEOSGeom_destroy_r( geosinit.
ctxt, reshapedGeometry );
1649 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeLineGeos );
1650 return reshapeResult;
1657 bool reshapeTookPlace =
false;
1659 GEOSGeometry* currentReshapeGeometry = 0;
1660 GEOSGeometry** newGeoms =
new GEOSGeometry*[numGeoms];
1662 for (
int i = 0; i < numGeoms; ++i )
1665 currentReshapeGeometry = reshapeLine( GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ), reshapeLineGeos, mPrecision );
1667 currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ), reshapeLineGeos, mPrecision );
1669 if ( currentReshapeGeometry )
1671 newGeoms[i] = currentReshapeGeometry;
1672 reshapeTookPlace =
true;
1676 newGeoms[i] = GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ) );
1679 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeLineGeos );
1681 GEOSGeometry* newMultiGeom = 0;
1684 newMultiGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTILINESTRING, newGeoms, numGeoms );
1688 newMultiGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTIPOLYGON, newGeoms, numGeoms );
1692 if ( !newMultiGeom )
1694 if ( errorCode ) { *errorCode = 3; }
1698 if ( reshapeTookPlace )
1700 if ( errorCode ) { *errorCode = 0; }
1702 GEOSGeom_destroy_r( geosinit.
ctxt, newMultiGeom );
1703 return reshapedMultiGeom;
1707 GEOSGeom_destroy_r( geosinit.
ctxt, newMultiGeom );
1708 if ( errorCode ) { *errorCode = 1; }
1716 GEOSGeometry* QgsGeos::reshapeLine(
const GEOSGeometry* line,
const GEOSGeometry* reshapeLineGeos ,
double precision )
1718 if ( !line || !reshapeLineGeos )
1721 bool atLeastTwoIntersections =
false;
1726 GEOSGeometry* intersectGeom = GEOSIntersection_r( geosinit.
ctxt, line, reshapeLineGeos );
1727 if ( intersectGeom )
1729 atLeastTwoIntersections = ( GEOSGeomTypeId_r( geosinit.
ctxt, intersectGeom ) == GEOS_MULTIPOINT
1730 && GEOSGetNumGeometries_r( geosinit.
ctxt, intersectGeom ) > 1 );
1731 GEOSGeom_destroy_r( geosinit.
ctxt, intersectGeom );
1734 catch ( GEOSException &e )
1737 atLeastTwoIntersections =
false;
1740 if ( !atLeastTwoIntersections )
1744 const GEOSCoordSequence* lineCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, line );
1745 if ( !lineCoordSeq )
1748 unsigned int lineCoordSeqSize;
1749 if ( GEOSCoordSeq_getSize_r( geosinit.
ctxt, lineCoordSeq, &lineCoordSeqSize ) == 0 )
1752 if ( lineCoordSeqSize < 2 )
1756 double x1, y1, x2, y2;
1757 GEOSCoordSeq_getX_r( geosinit.
ctxt, lineCoordSeq, 0, &x1 );
1758 GEOSCoordSeq_getY_r( geosinit.
ctxt, lineCoordSeq, 0, &y1 );
1759 GEOSCoordSeq_getX_r( geosinit.
ctxt, lineCoordSeq, lineCoordSeqSize - 1, &x2 );
1760 GEOSCoordSeq_getY_r( geosinit.
ctxt, lineCoordSeq, lineCoordSeqSize - 1, &y2 );
1762 GEOSGeometry* beginLineVertex = createGeosPoint( &beginPoint, 2, precision );
1764 GEOSGeometry* endLineVertex = createGeosPoint( &endPoint, 2, precision );
1766 bool isRing =
false;
1767 if ( GEOSGeomTypeId_r( geosinit.
ctxt, line ) == GEOS_LINEARRING
1768 || GEOSEquals_r( geosinit.
ctxt, beginLineVertex, endLineVertex ) == 1 )
1772 GEOSGeometry* nodedGeometry = nodeGeometries( reshapeLineGeos, line );
1773 if ( !nodedGeometry )
1775 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
1776 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
1781 GEOSGeometry *mergedLines = GEOSLineMerge_r( geosinit.
ctxt, nodedGeometry );
1782 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
1785 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
1786 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
1790 int numMergedLines = GEOSGetNumGeometries_r( geosinit.
ctxt, mergedLines );
1791 if ( numMergedLines < 2 )
1793 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
1794 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
1795 if ( numMergedLines == 1 )
1796 return GEOSGeom_clone_r( geosinit.
ctxt, reshapeLineGeos );
1804 for (
int i = 0; i < numMergedLines; ++i )
1806 const GEOSGeometry* currentGeom;
1808 currentGeom = GEOSGetGeometryN_r( geosinit.
ctxt, mergedLines, i );
1809 const GEOSCoordSequence* currentCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, currentGeom );
1810 unsigned int currentCoordSeqSize;
1811 GEOSCoordSeq_getSize_r( geosinit.
ctxt, currentCoordSeq, ¤tCoordSeqSize );
1812 if ( currentCoordSeqSize < 2 )
1816 double xBegin, xEnd, yBegin, yEnd;
1817 GEOSCoordSeq_getX_r( geosinit.
ctxt, currentCoordSeq, 0, &xBegin );
1818 GEOSCoordSeq_getY_r( geosinit.
ctxt, currentCoordSeq, 0, &yBegin );
1819 GEOSCoordSeq_getX_r( geosinit.
ctxt, currentCoordSeq, currentCoordSeqSize - 1, &xEnd );
1820 GEOSCoordSeq_getY_r( geosinit.
ctxt, currentCoordSeq, currentCoordSeqSize - 1, &yEnd );
1822 GEOSGeometry* beginCurrentGeomVertex = createGeosPoint( &beginPoint, 2, precision );
1824 GEOSGeometry* endCurrentGeomVertex = createGeosPoint( &endPoint, 2, precision );
1827 int nEndpointsOnOriginalLine = 0;
1828 if ( pointContainedInLine( beginCurrentGeomVertex, line ) == 1 )
1829 nEndpointsOnOriginalLine += 1;
1831 if ( pointContainedInLine( endCurrentGeomVertex, line ) == 1 )
1832 nEndpointsOnOriginalLine += 1;
1835 int nEndpointsSameAsOriginalLine = 0;
1836 if ( GEOSEquals_r( geosinit.
ctxt, beginCurrentGeomVertex, beginLineVertex ) == 1
1837 || GEOSEquals_r( geosinit.
ctxt, beginCurrentGeomVertex, endLineVertex ) == 1 )
1838 nEndpointsSameAsOriginalLine += 1;
1840 if ( GEOSEquals_r( geosinit.
ctxt, endCurrentGeomVertex, beginLineVertex ) == 1
1841 || GEOSEquals_r( geosinit.
ctxt, endCurrentGeomVertex, endLineVertex ) == 1 )
1842 nEndpointsSameAsOriginalLine += 1;
1845 bool currentGeomOverlapsOriginalGeom =
false;
1846 bool currentGeomOverlapsReshapeLine =
false;
1847 if ( lineContainedInLine( currentGeom, line ) == 1 )
1848 currentGeomOverlapsOriginalGeom =
true;
1850 if ( lineContainedInLine( currentGeom, reshapeLineGeos ) == 1 )
1851 currentGeomOverlapsReshapeLine =
true;
1854 if ( nEndpointsSameAsOriginalLine == 1 && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
1856 resultLineParts.
push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
1859 else if ( isRing && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
1861 probableParts.
push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
1863 else if ( nEndpointsOnOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
1865 resultLineParts.
push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
1867 else if ( nEndpointsSameAsOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
1869 resultLineParts.
push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
1871 else if ( currentGeomOverlapsOriginalGeom && currentGeomOverlapsReshapeLine )
1873 resultLineParts.
push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
1876 GEOSGeom_destroy_r( geosinit.
ctxt, beginCurrentGeomVertex );
1877 GEOSGeom_destroy_r( geosinit.
ctxt, endCurrentGeomVertex );
1881 if ( isRing && probableParts.
size() > 0 )
1883 GEOSGeometry* maxGeom = 0;
1884 GEOSGeometry* currentGeom = 0;
1886 double currentLength = 0;
1887 for (
int i = 0; i < probableParts.
size(); ++i )
1889 currentGeom = probableParts.
at( i );
1890 GEOSLength_r( geosinit.
ctxt, currentGeom, ¤tLength );
1891 if ( currentLength > maxLength )
1893 maxLength = currentLength;
1894 GEOSGeom_destroy_r( geosinit.
ctxt, maxGeom );
1895 maxGeom = currentGeom;
1899 GEOSGeom_destroy_r( geosinit.
ctxt, currentGeom );
1905 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
1906 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
1907 GEOSGeom_destroy_r( geosinit.
ctxt, mergedLines );
1909 GEOSGeometry* result = 0;
1910 if ( resultLineParts.
size() < 1 )
1913 if ( resultLineParts.
size() == 1 )
1915 result = resultLineParts[0];
1919 GEOSGeometry **lineArray =
new GEOSGeometry*[resultLineParts.
size()];
1920 for (
int i = 0; i < resultLineParts.
size(); ++i )
1922 lineArray[i] = resultLineParts[i];
1926 GEOSGeometry* multiLineGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTILINESTRING, lineArray, resultLineParts.
size() );
1927 delete [] lineArray;
1930 result = GEOSLineMerge_r( geosinit.
ctxt, multiLineGeom );
1931 GEOSGeom_destroy_r( geosinit.
ctxt, multiLineGeom );
1935 if ( GEOSGeomTypeId_r( geosinit.
ctxt, result ) != GEOS_LINESTRING )
1937 GEOSGeom_destroy_r( geosinit.
ctxt, result );
1944 GEOSGeometry* QgsGeos::reshapePolygon(
const GEOSGeometry* polygon,
const GEOSGeometry* reshapeLineGeos,
double precision )
1947 int nIntersections = 0;
1948 int lastIntersectingRing = -2;
1949 const GEOSGeometry* lastIntersectingGeom = 0;
1951 int nRings = GEOSGetNumInteriorRings_r( geosinit.
ctxt, polygon );
1956 const GEOSGeometry* outerRing = GEOSGetExteriorRing_r( geosinit.
ctxt, polygon );
1957 if ( GEOSIntersects_r( geosinit.
ctxt, outerRing, reshapeLineGeos ) == 1 )
1960 lastIntersectingRing = -1;
1961 lastIntersectingGeom = outerRing;
1965 const GEOSGeometry **innerRings =
new const GEOSGeometry*[nRings];
1969 for (
int i = 0; i < nRings; ++i )
1971 innerRings[i] = GEOSGetInteriorRingN_r( geosinit.
ctxt, polygon, i );
1972 if ( GEOSIntersects_r( geosinit.
ctxt, innerRings[i], reshapeLineGeos ) == 1 )
1975 lastIntersectingRing = i;
1976 lastIntersectingGeom = innerRings[i];
1980 catch ( GEOSException &e )
1986 if ( nIntersections != 1 )
1988 delete [] innerRings;
1993 GEOSGeometry* reshapeResult = reshapeLine( lastIntersectingGeom, reshapeLineGeos, precision );
1994 if ( !reshapeResult )
1996 delete [] innerRings;
2001 GEOSGeometry* newRing = 0;
2002 const GEOSCoordSequence* reshapeSequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, reshapeResult );
2003 GEOSCoordSequence* newCoordSequence = GEOSCoordSeq_clone_r( geosinit.
ctxt, reshapeSequence );
2005 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeResult );
2007 newRing = GEOSGeom_createLinearRing_r( geosinit.
ctxt, newCoordSequence );
2010 delete [] innerRings;
2014 GEOSGeometry* newOuterRing = 0;
2015 if ( lastIntersectingRing == -1 )
2016 newOuterRing = newRing;
2018 newOuterRing = GEOSGeom_clone_r( geosinit.
ctxt, outerRing );
2024 GEOSGeometry* outerRingPoly = GEOSGeom_createPolygon_r( geosinit.
ctxt, GEOSGeom_clone_r( geosinit.
ctxt, newOuterRing ), 0, 0 );
2025 if ( outerRingPoly )
2027 GEOSGeometry* currentRing = 0;
2028 for (
int i = 0; i < nRings; ++i )
2030 if ( lastIntersectingRing == i )
2031 currentRing = newRing;
2033 currentRing = GEOSGeom_clone_r( geosinit.
ctxt, innerRings[i] );
2036 if ( GEOSContains_r( geosinit.
ctxt, outerRingPoly, currentRing ) == 1 )
2039 GEOSGeom_destroy_r( geosinit.
ctxt, currentRing );
2042 GEOSGeom_destroy_r( geosinit.
ctxt, outerRingPoly );
2045 GEOSGeometry** newInnerRings =
new GEOSGeometry*[ringList.
size()];
2046 for (
int i = 0; i < ringList.
size(); ++i )
2047 newInnerRings[i] = ringList.
at( i );
2049 delete [] innerRings;
2051 GEOSGeometry* reshapedPolygon = GEOSGeom_createPolygon_r( geosinit.
ctxt, newOuterRing, newInnerRings, ringList.
size() );
2052 delete[] newInnerRings;
2054 return reshapedPolygon;
2057 int QgsGeos::lineContainedInLine(
const GEOSGeometry* line1,
const GEOSGeometry* line2 )
2059 if ( !line1 || !line2 )
2064 double bufferDistance = pow( 10.0L, geomDigits( line2 ) - 11 );
2070 GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosinit.
ctxt, bufferGeom, line1 );
2073 double intersectGeomLength;
2076 GEOSLength_r( geosinit.
ctxt, intersectionGeom, &intersectGeomLength );
2077 GEOSLength_r( geosinit.
ctxt, line1, &line1Length );
2079 GEOSGeom_destroy_r( geosinit.
ctxt, bufferGeom );
2080 GEOSGeom_destroy_r( geosinit.
ctxt, intersectionGeom );
2082 double intersectRatio = line1Length / intersectGeomLength;
2083 if ( intersectRatio > 0.9 && intersectRatio < 1.1 )
2089 int QgsGeos::pointContainedInLine(
const GEOSGeometry* point,
const GEOSGeometry* line )
2091 if ( !point || !line )
2094 double bufferDistance = pow( 10.0L, geomDigits( line ) - 11 );
2096 GEOSGeometry* lineBuffer = GEOSBuffer_r( geosinit.
ctxt, line, bufferDistance, 8 );
2100 bool contained =
false;
2101 if ( GEOSContains_r( geosinit.
ctxt, lineBuffer, point ) == 1 )
2104 GEOSGeom_destroy_r( geosinit.
ctxt, lineBuffer );
2108 int QgsGeos::geomDigits(
const GEOSGeometry* geom )
2114 const GEOSGeometry* bBoxRing = GEOSGetExteriorRing_r( geosinit.
ctxt, bbox.get() );
2118 const GEOSCoordSequence* bBoxCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, bBoxRing );
2120 if ( !bBoxCoordSeq )
2123 unsigned int nCoords = 0;
2124 if ( !GEOSCoordSeq_getSize_r( geosinit.
ctxt, bBoxCoordSeq, &nCoords ) )
2128 for (
unsigned int i = 0; i < nCoords - 1; ++i )
2131 GEOSCoordSeq_getX_r( geosinit.
ctxt, bBoxCoordSeq, i, &t );
2134 digits = ceil( log10( fabs( t ) ) );
2135 if ( digits > maxDigits )
2138 GEOSCoordSeq_getY_r( geosinit.
ctxt, bBoxCoordSeq, i, &t );
2139 digits = ceil( log10( fabs( t ) ) );
2140 if ( digits > maxDigits )
2149 return geosinit.
ctxt;
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
void reset(GEOSGeometry *geom)
QgsWKBTypes::Type wkbType() const
Returns the WKB type of the geometry.
double length(QString *errorMsg=0) const override
static bool isMultiType(Type type)
QgsPointV2 pointN(int i) const
bool intersects(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
QgsAbstractGeometryV2 * interpolate(double distance, QString *errorMsg=0) const override
bool crosses(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
static QgsPointV2 coordSeqPoint(const GEOSCoordSequence *cs, int i, bool hasZ, bool hasM)
void push_back(const T &value)
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
Multi curve geometry collection.
const_iterator constEnd() const
bool centroid(QgsPointV2 &pt, QString *errorMsg=0) const override
const T & at(int i) const
QgsCurveV2 * exteriorRing() const
Abstract base class for all geometries.
static QgsAbstractGeometryV2 * fromGeos(const GEOSGeometry *geos)
Create a geometry from a GEOSGeometry.
bool pointOnSurface(QgsPointV2 &pt, QString *errorMsg=0) const override
QgsGeos(const QgsAbstractGeometryV2 *geometry, double precision=0)
GEOS geometry engine constructor.
Multi point geometry collection.
bool disjoint(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
bool contains(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
QgsAbstractGeometryV2 * symDifference(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
double area(QString *errorMsg=0) const override
Multi line string geometry collection.
QString tr(const char *sourceText, const char *disambiguation, int n)
static GEOSContextHandle_t getGEOSHandler()
GEOSGeometry * get() const
double ANALYSIS_EXPORT max(double x, double y)
Returns the maximum of two doubles or the first argument if both are equal.
#define CATCH_GEOS_WITH_ERRMSG(r)
double qgsRound(double x)
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
void setInteriorRings(const QList< QgsCurveV2 * > &rings)
Sets all interior rings (takes ownership)
GEOSGeomScopedPtr(GEOSGeometry *geom=0)
QString fromUtf8(const char *str, int size)
bool overlaps(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
static QgsPolygonV2 * fromGeosPolygon(const GEOSGeometry *geos)
bool isMeasure() const
Returns true if the geometry contains m values.
Line string geometry type.
QgsAbstractGeometryV2 * combine(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
void prepareGeometry() override
int splitGeometry(const QgsLineStringV2 &splitLine, QList< QgsAbstractGeometryV2 * > &newGeometries, bool topological, QList< QgsPointV2 > &topologyTestPoints, QString *errorMsg=0) const override
Splits this geometry according to a given line.
static void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
virtual bool addGeometry(QgsAbstractGeometryV2 *g) override
Adds a geometry and takes ownership.
virtual QgsLineStringV2 * clone() const override
Clones the geometry by performing a deep copy.
virtual QgsPolygonV2 * toPolygon() const
const QgsAbstractGeometryV2 * mGeometry
Does vector analysis using the geos library and handles import, export, exception handling*...
QgsAbstractGeometryV2 * reshapeGeometry(const QgsLineStringV2 &reshapeWithLine, int *errorCode, QString *errorMsg=0) const
static GEOSGeometry * asGeos(const QgsAbstractGeometryV2 *geom, double precision=0)
virtual QString geometryType() const =0
Returns a unique string representing the geometry type.
void geometryChanged() override
Removes caches.
QgsAbstractGeometryV2 * difference(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
static void printGEOSNotice(const char *fmt,...)
QgsAbstractGeometryV2 * convexHull(QString *errorMsg=0) const override
QgsAbstractGeometryV2 * simplify(double tolerance, QString *errorMsg=0) const override
int numGeometries() const
Returns the number of geometries within the collection.
void addVertex(const QgsPointV2 &pt)
QgsAbstractGeometryV2 * buffer(double distance, int segments, QString *errorMsg=0) const override
virtual QgsLineStringV2 * curveToLine() const =0
Returns a new line string geometry corresponding to a segmentized approximation of the curve...
const_iterator constBegin() const
QgsAbstractGeometryV2 * intersection(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
void setPoints(const QList< QgsPointV2 > &points)
void setExteriorRing(QgsCurveV2 *ring)
Sets exterior ring (takes ownership)
bool within(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
virtual bool addGeometry(QgsAbstractGeometryV2 *g)
Adds a geometry and takes ownership.
virtual int dimension() const =0
Returns the inherent dimension of the geometry.
static void throwGEOSException(const char *fmt,...)
int count(const T &value) const
bool isEqual(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
const QgsAbstractGeometryV2 * geometryN(int n) const
Returns a const reference to a geometry from within the collection.
bool isEmpty(QString *errorMsg=0) const override
QgsAbstractGeometryV2 * envelope(QString *errorMsg=0) const override
QgsAbstractGeometryV2 * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit, QString *errorMsg=0) const override
bool touches(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
double distance(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Multi polygon geometry collection.
Contains geometry relation and modification algorithms.
QString relate(const QgsAbstractGeometryV2 &geom, QString *errorMsg=0) const override
Returns the Dimensional Extended 9 Intersection Model (DE-9IM) representation of the relationship bet...
Curve polygon geometry type.
int numInteriorRings() const
virtual QgsAbstractGeometryV2 * clone() const =0
Clones the geometry by performing a deep copy.
Abstract base class for curved geometry type.
bool isValid(QString *errorMsg=0) const override
#define DEFAULT_QUADRANT_SEGMENTS
QgsCurveV2 * interiorRing(int i) const
int numPoints() const override
Returns the number of points in the curve.