36 #include <netinet/in.h>
41 #define DEFAULT_QUADRANT_SEGMENTS 8
43 #define CATCH_GEOS(r) \
44 catch (GEOSException &e) \
46 QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr("GEOS") ); \
55 if ( theMsg ==
"Unknown exception thrown" &&
lastMsg.isNull() )
96 vsnprintf( buffer,
sizeof buffer, fmt, ap );
99 QgsDebugMsg( QString(
"GEOS exception: %1" ).arg( buffer ) );
106 #if defined(QGISDEBUG)
111 vsnprintf( buffer,
sizeof buffer, fmt, ap );
114 QgsDebugMsg( QString(
"GEOS notice: %1" ).arg( QString::fromUtf8( buffer ) ) );
137 #if defined(GEOS_VERSION_MAJOR) && (GEOS_VERSION_MAJOR<3)
138 #define GEOSGeom_getCoordSeq(g) GEOSGeom_getCoordSeq( (GEOSGeometry *) g )
139 #define GEOSGetExteriorRing(g) GEOSGetExteriorRing( (GEOSGeometry *)g )
140 #define GEOSGetNumInteriorRings(g) GEOSGetNumInteriorRings( (GEOSGeometry *)g )
141 #define GEOSGetInteriorRingN(g,i) GEOSGetInteriorRingN( (GEOSGeometry *)g, i )
142 #define GEOSDisjoint(g0,g1) GEOSDisjoint( (GEOSGeometry *)g0, (GEOSGeometry*)g1 )
143 #define GEOSIntersection(g0,g1) GEOSIntersection( (GEOSGeometry*) g0, (GEOSGeometry*)g1 )
144 #define GEOSBuffer(g, d, s) GEOSBuffer( (GEOSGeometry*) g, d, s )
145 #define GEOSArea(g, a) GEOSArea( (GEOSGeometry*) g, a )
146 #define GEOSTopologyPreserveSimplify(g, t) GEOSTopologyPreserveSimplify( (GEOSGeometry*) g, t )
147 #define GEOSGetCentroid(g) GEOSGetCentroid( (GEOSGeometry*) g )
149 #define GEOSCoordSeq_getSize(cs,n) GEOSCoordSeq_getSize( (GEOSCoordSequence *) cs, n )
150 #define GEOSCoordSeq_getX(cs,i,x) GEOSCoordSeq_getX( (GEOSCoordSequence *)cs, i, x )
151 #define GEOSCoordSeq_getY(cs,i,y) GEOSCoordSeq_getY( (GEOSCoordSequence *)cs, i, y )
155 static GEOSGeometry *cloneGeosGeom(
const GEOSGeometry *geom )
159 int type = GEOSGeomTypeId(( GEOSGeometry * ) geom );
161 if ( type == GEOS_MULTIPOINT || type == GEOS_MULTILINESTRING || type == GEOS_MULTIPOLYGON )
163 QVector<GEOSGeometry *> geoms;
167 for (
int i = 0; i < GEOSGetNumGeometries(( GEOSGeometry * )geom ); ++i )
168 geoms << GEOSGeom_clone(( GEOSGeometry * ) GEOSGetGeometryN(( GEOSGeometry * ) geom, i ) );
175 for (
int i = 0; i < geoms.count(); i++ )
176 GEOSGeom_destroy( geoms[i] );
183 return GEOSGeom_clone(( GEOSGeometry * ) geom );
187 #define GEOSGeom_clone(g) cloneGeosGeom(g)
195 , mDirtyGeos( false )
201 , mGeometrySize( rhs.mGeometrySize )
202 , mDirtyWkb( rhs.mDirtyWkb )
203 , mDirtyGeos( rhs.mDirtyGeos )
226 GEOSGeom_destroy(
mGeos );
233 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( geom );
234 GEOSCoordSeq_getSize( cs, &n );
240 GEOSCoordSequence *coord = GEOSCoordSeq_create( 1, 2 );
241 GEOSCoordSeq_setX( coord, 0, point.
x() );
242 GEOSCoordSeq_setY( coord, 0, point.
y() );
243 return GEOSGeom_createPoint( coord );
248 GEOSCoordSequence *coord = 0;
252 coord = GEOSCoordSeq_create( points.count(), 2 );
254 for ( i = 0; i < points.count(); i++ )
256 GEOSCoordSeq_setX( coord, i, points[i].x() );
257 GEOSCoordSeq_setY( coord, i, points[i].y() );
272 GEOSGeometry **geomarr =
new GEOSGeometry*[ geoms.size()];
276 for (
int i = 0; i < geoms.size(); i++ )
277 geomarr[i] = geoms[i];
279 GEOSGeometry *geom = 0;
283 geom = GEOSGeom_createCollection( typeId, geomarr, geoms.size() );
297 GEOSCoordSequence *coord = 0;
302 return GEOSGeom_createLineString( coord );
316 GEOSCoordSequence *coord = 0;
318 if ( polyline.count() == 0 )
323 if ( polyline[0] != polyline[polyline.size()-1] )
335 return GEOSGeom_createLinearRing( coord );
351 if ( rings.size() == 0 )
353 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
354 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
355 return GEOSGeom_createEmptyPolygon();
357 shell = GEOSGeom_createLinearRing( GEOSCoordSeq_create( 0, 2 ) );
365 GEOSGeometry **holes = NULL;
368 if ( rings.size() > 1 )
370 nHoles = rings.size() - 1;
371 holes =
new GEOSGeometry*[ nHoles ];
375 for (
int i = 0; i < nHoles; i++ )
376 holes[i] = rings[i+1];
379 GEOSGeometry *geom = GEOSGeom_createPolygon( shell, holes, nHoles );
394 if ( polygon.count() == 0 )
397 QVector<GEOSGeometry *> geoms;
401 for (
int i = 0; i < polygon.count(); i++ )
409 for (
int i = 0; i < geoms.count(); i++ )
410 GEOSGeom_destroy( geoms[i] );
429 #if defined(GEOS_VERSION_MAJOR) && (GEOS_VERSION_MAJOR>=3)
430 GEOSWKTReader *reader = GEOSWKTReader_create();
432 GEOSWKTReader_destroy( reader );
435 return fromGeosGeom( GEOSGeomFromWKT( wkt.toLocal8Bit().data() ) );
462 QVector<GEOSGeometry *> geoms;
466 for (
int i = 0; i < multipoint.size(); ++i )
475 for (
int i = 0; i < geoms.size(); ++i )
476 GEOSGeom_destroy( geoms[i] );
484 QVector<GEOSGeometry *> geoms;
488 for (
int i = 0; i < multiline.count(); i++ )
497 for (
int i = 0; i < geoms.count(); i++ )
498 GEOSGeom_destroy( geoms[i] );
506 if ( multipoly.count() == 0 )
509 QVector<GEOSGeometry *> geoms;
513 for (
int i = 0; i < multipoly.count(); i++ )
522 for (
int i = 0; i < geoms.count(); i++ )
523 GEOSGeom_destroy( geoms[i] );
539 polygon.append( ring );
560 GEOSGeom_destroy(
mGeos );
587 GEOSGeom_destroy(
mGeos );
689 GEOSGeom_destroy(
mGeos );
727 bool hasZValue =
false;
738 actdist = point.
sqrDist( x, y );
754 wkbPtr +=
sizeof( double );
756 double dist = point.
sqrDist( x, y );
757 if ( dist < actdist )
763 beforeVertex =
index - 1;
764 afterVertex =
index == nPoints - 1 ? -1 :
index + 1;
780 for (
int index2 = 0; index2 < nPoints; ++index2 )
785 wkbPtr +=
sizeof( double );
787 double dist = point.
sqrDist( x, y );
788 if ( dist < actdist )
792 vertexnr = pointIndex;
797 beforeVertex = pointIndex + ( nPoints - 2 );
798 afterVertex = pointIndex + 1;
800 else if ( index2 == nPoints - 1 )
802 beforeVertex = pointIndex - 1;
803 afterVertex = pointIndex - ( nPoints - 2 );
807 beforeVertex = pointIndex - 1;
808 afterVertex = pointIndex + 1;
825 wkbPtr += 1 +
sizeof( int );
830 wkbPtr +=
sizeof( double );
832 double dist = point.
sqrDist( x, y );
833 if ( dist < actdist )
851 wkbPtr += 1 +
sizeof( int );
855 for (
int index2 = 0; index2 < nPoints; ++index2 )
860 wkbPtr +=
sizeof( double );
862 double dist = point.
sqrDist( x, y );
863 if ( dist < actdist )
867 vertexnr = pointIndex;
872 beforeVertex = vertexnr - 1;
874 if ( index2 == nPoints - 1 )
877 afterVertex = vertexnr + 1;
894 wkbPtr += 1 +
sizeof( int );
897 for (
int index2 = 0; index2 < nRings; ++index2 )
901 for (
int index3 = 0; index3 < nPoints; ++index3 )
906 wkbPtr +=
sizeof( double );
908 double dist = point.
sqrDist( x, y );
909 if ( dist < actdist )
913 vertexnr = pointIndex;
918 beforeVertex = pointIndex + ( nPoints - 2 );
919 afterVertex = pointIndex + 1;
921 else if ( index3 == nPoints - 1 )
923 beforeVertex = pointIndex - 1;
924 afterVertex = pointIndex - ( nPoints - 2 );
928 beforeVertex = pointIndex - 1;
929 afterVertex = pointIndex + 1;
967 bool hasZValue =
false;
985 if ( atVertex >= nPoints )
988 const int index = atVertex;
992 beforeVertex = index - 1;
994 if ( index == nPoints - 1 )
997 afterVertex = index + 1;
1009 for (
int index0 = 0, pointIndex = 0; index0 < nRings; ++index0 )
1013 for (
int index1 = 0; index1 < nPoints; ++index1 )
1015 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1017 if ( pointIndex == atVertex )
1021 beforeVertex = pointIndex + ( nPoints - 2 );
1022 afterVertex = pointIndex + 1;
1024 else if ( index1 == nPoints - 1 )
1026 beforeVertex = pointIndex - 1;
1027 afterVertex = pointIndex - ( nPoints - 2 );
1031 beforeVertex = pointIndex - 1;
1032 afterVertex = pointIndex + 1;
1055 for (
int index0 = 0, pointIndex = 0; index0 < nLines; ++index0 )
1057 wkbPtr += 1 +
sizeof( int );
1062 for (
int index1 = 0; index1 < nPoints; ++index1 )
1064 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1066 if ( pointIndex == atVertex )
1072 beforeVertex = pointIndex - 1;
1074 if ( index1 == nPoints - 1 )
1077 afterVertex = pointIndex + 1;
1093 for (
int index0 = 0, pointIndex = 0; index0 < nPolys; ++index0 )
1095 wkbPtr += 1 +
sizeof( int );
1099 for (
int index1 = 0; index1 < nRings; ++index1 )
1103 for (
int index2 = 0; index2 < nPoints; ++index2 )
1105 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1107 if ( pointIndex == atVertex )
1114 beforeVertex = pointIndex + ( nPoints - 2 );
1115 afterVertex = pointIndex + 1;
1117 else if ( index2 == nPoints - 1 )
1119 beforeVertex = pointIndex - 1;
1120 afterVertex = pointIndex - ( nPoints - 2 );
1124 beforeVertex = pointIndex - 1;
1125 afterVertex = pointIndex + 1;
1143 const GEOSCoordSequence *old_sequence,
1144 GEOSCoordSequence **new_sequence )
1147 if ( beforeVertex < 0 )
1153 unsigned int numPoints;
1154 GEOSCoordSeq_getSize( old_sequence, &numPoints );
1156 *new_sequence = GEOSCoordSeq_create( numPoints + 1, 2 );
1157 if ( !*new_sequence )
1160 bool inserted =
false;
1161 for (
unsigned int i = 0, j = 0; i < numPoints; i++, j++ )
1164 if ( beforeVertex == static_cast<int>( i ) )
1166 GEOSCoordSeq_setX( *new_sequence, j, x );
1167 GEOSCoordSeq_setY( *new_sequence, j, y );
1173 GEOSCoordSeq_getX( old_sequence, i, &aX );
1174 GEOSCoordSeq_getY( old_sequence, i, &aY );
1176 GEOSCoordSeq_setX( *new_sequence, j, aX );
1177 GEOSCoordSeq_setY( *new_sequence, j, aY );
1184 GEOSCoordSeq_setX( *new_sequence, numPoints, x );
1185 GEOSCoordSeq_setY( *new_sequence, numPoints, y );
1198 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1201 if ( atVertex >= pointIndex + nPoints )
1203 wkbPtr += ps * nPoints;
1204 pointIndex += nPoints;
1208 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1209 atVertex = pointIndex;
1212 wkbPtr += ps * ( atVertex - pointIndex );
1217 if ( isRing && atVertex == pointIndex )
1219 wkbPtr += ps * ( nPoints - 2 );
1243 bool hasZValue =
false;
1253 if ( atVertex != 0 )
1266 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1282 if ( atVertex < nPoints )
1284 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1304 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1306 wkbPtr += 1 +
sizeof( int );
1307 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1324 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1326 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1340 wkbPtr >> nPolygons;
1341 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
1343 wkbPtr += 1 +
sizeof( int );
1348 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1350 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1367 QgsDebugMsg( QString(
"atVertex:%1 hasZValue:%2 pointIndex:%3 isRing:%4" ).arg( atVertex ).arg( hasZValue ).arg( pointIndex ).arg( isRing ) );
1368 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1372 if ( atVertex < pointIndex || atVertex >= pointIndex + nPoints )
1375 if ( lastItem && atVertex >= pointIndex + nPoints )
1380 int len = nPoints * ps;
1381 memcpy( dstPtr, srcPtr, len );
1384 pointIndex += nPoints;
1388 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1389 atVertex = pointIndex;
1391 dstPtr << nPoints - 1;
1393 int len = ( atVertex - pointIndex ) * ps;
1396 memcpy( dstPtr, srcPtr, len );
1403 len = ( pointIndex + nPoints - atVertex - 1 ) * ps;
1404 const unsigned char *first = 0;
1405 if ( isRing && atVertex == pointIndex )
1413 memcpy( dstPtr, srcPtr, len );
1420 memcpy( dstPtr, first, ps );
1425 pointIndex += nPoints - 1;
1447 srcPtr >> endianess >>
wkbType;
1451 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1453 ps += 1 +
sizeof(
int );
1455 unsigned char *dstBuffer =
new unsigned char[
mGeometrySize - ps];
1457 dstPtr << endianess <<
wkbType;
1459 bool deleted =
false;
1470 deleted =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false,
true );
1481 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1482 deleted |=
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, ringnr == nRings - 1 );
1493 if ( atVertex < nPoints )
1495 dstPtr << nPoints - 1;
1497 int len = ps * atVertex;
1500 memcpy( dstPtr, srcPtr, len );
1507 len = ps * ( nPoints - atVertex - 1 );
1510 memcpy( dstPtr, srcPtr, len );
1528 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1530 srcPtr >> endianess >>
wkbType;
1531 dstPtr << endianess <<
wkbType;
1532 deleted |=
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false, linenr == nLines - 1 );
1545 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1548 srcPtr >> endianess >> wkbType >> nRings;
1549 dstPtr << endianess << wkbType << nRings;
1551 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1552 deleted |=
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, polynr == nPolys - 1 && ringnr == nRings - 1 );
1572 delete [] dstBuffer;
1582 bool insertHere = beforeVertex >= pointIndex && beforeVertex < pointIndex + nPoints;
1587 dstPtr << nPoints + 1;
1588 len = ( hasZValue ? 3 : 2 ) * ( beforeVertex - pointIndex ) *
sizeof( double );
1591 memcpy( dstPtr, srcPtr, len );
1600 len = ( hasZValue ? 3 : 2 ) * ( pointIndex + nPoints - beforeVertex ) *
sizeof( double );
1601 if ( isRing && beforeVertex == pointIndex )
1602 len -= ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1607 len = ( hasZValue ? 3 : 2 ) * nPoints *
sizeof(
double );
1610 memcpy( dstPtr, srcPtr, len );
1614 if ( isRing && beforeVertex == pointIndex )
1621 pointIndex += nPoints;
1637 if ( beforeVertex < 0 )
1643 srcPtr >> endianess >>
wkbType;
1647 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1649 ps += 1 +
sizeof(
int );
1651 unsigned char *dstBuffer =
new unsigned char[
mGeometrySize + ps];
1653 dstPtr << endianess <<
wkbType;
1655 bool inserted =
false;
1666 inserted =
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1677 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1678 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1689 if ( beforeVertex <= nPoints )
1691 dstPtr << nPoints + 1;
1693 int len = ps * beforeVertex;
1696 memcpy( dstPtr, srcPtr, len );
1705 len = ps * ( nPoints - beforeVertex );
1707 memcpy( dstPtr, srcPtr, len );
1722 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1724 srcPtr >> endianess >>
wkbType;
1725 dstPtr << endianess <<
wkbType;
1726 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1738 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1741 srcPtr >> endianess >> wkbType >> nRings;
1742 dstPtr << endianess << wkbType << nRings;
1744 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1745 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1765 delete [] dstBuffer;
1788 bool hasZValue =
false;
1794 if ( atVertex != 0 )
1811 if ( atVertex >= nPoints )
1815 wkbPtr += atVertex * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1830 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1835 if ( atVertex >= pointIndex + nPoints )
1837 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1838 pointIndex += nPoints;
1842 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1860 if ( atVertex >= nPoints )
1863 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1877 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1879 wkbPtr += 1 +
sizeof( int );
1883 if ( atVertex >= pointIndex + nPoints )
1885 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1886 pointIndex += nPoints;
1890 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1906 wkbPtr >> nPolygons;
1908 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
1910 wkbPtr += 1 +
sizeof( int );
1914 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1919 if ( atVertex >= pointIndex + nPoints )
1921 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1922 pointIndex += nPoints;
1926 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1938 QgsDebugMsg(
"error: mGeometry type not recognized" );
1953 QgsDebugMsg(
"Exiting with std::numeric_limits<double>::max()." );
1966 int closestVertexIndex = 0;
1975 const GEOSGeometry *g = GEOSGetExteriorRing(
mGeos );
1979 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq( g );
1982 GEOSCoordSeq_getSize( sequence, &n );
1984 for (
unsigned int i = 0; i < n; i++ )
1987 GEOSCoordSeq_getX( sequence, i, &x );
1988 GEOSCoordSeq_getY( sequence, i, &y );
1990 double testDist = point.
sqrDist( x, y );
1991 if ( testDist < sqrDist )
1993 closestVertexIndex = i;
1998 atVertex = closestVertexIndex;
2036 int closestSegmentIndex = 0;
2037 bool hasZValue =
false;
2056 double prevx = 0.0, prevy = 0.0;
2059 double thisx, thisy;
2060 wkbPtr >> thisx >> thisy;
2062 wkbPtr +=
sizeof( double );
2066 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2067 if ( testdist < sqrDist )
2069 closestSegmentIndex =
index;
2071 minDistPoint = distPoint;
2082 afterVertex = closestSegmentIndex;
2092 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
2094 wkbPtr += 1 +
sizeof( int );
2098 double prevx = 0.0, prevy = 0.0;
2099 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2101 double thisx, thisy;
2102 wkbPtr >> thisx >> thisy;
2104 wkbPtr +=
sizeof( double );
2108 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2109 if ( testdist < sqrDist )
2111 closestSegmentIndex = pointIndex;
2113 minDistPoint = distPoint;
2126 afterVertex = closestSegmentIndex;
2137 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
2142 double prevx = 0.0, prevy = 0.0;
2143 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2145 double thisx, thisy;
2146 wkbPtr >> thisx >> thisy;
2148 wkbPtr +=
sizeof( double );
2152 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2153 if ( testdist < sqrDist )
2155 closestSegmentIndex = pointIndex;
2157 minDistPoint = distPoint;
2170 afterVertex = closestSegmentIndex;
2179 wkbPtr >> nPolygons;
2180 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
2182 wkbPtr += 1 +
sizeof( int );
2185 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
2190 double prevx = 0.0, prevy = 0.0;
2191 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2193 double thisx, thisy;
2194 wkbPtr >> thisx >> thisy;
2196 wkbPtr +=
sizeof( double );
2200 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2201 if ( testdist < sqrDist )
2203 closestSegmentIndex = pointIndex;
2205 minDistPoint = distPoint;
2219 afterVertex = closestSegmentIndex;
2229 QgsDebugMsg( QString(
"Exiting with nearest point %1, dist %2." )
2230 .arg( point.
toString() ).arg( sqrDist ) );
2242 if ( ring.size() < 4 )
2246 if ( ring.first() != ring.last() )
2260 int type = GEOSGeomTypeId(
mGeos );
2263 QVector<const GEOSGeometry*> polygonList;
2267 if ( type != GEOS_POLYGON )
2270 polygonList <<
mGeos;
2274 if ( type != GEOS_MULTIPOLYGON )
2277 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); ++i )
2278 polygonList << GEOSGetGeometryN(
mGeos, i );
2282 GEOSGeometry *newRing = 0;
2283 GEOSGeometry *newRingPolygon = 0;
2288 if ( !GEOSisValid( newRing ) )
2294 if ( !GEOSisValid( newRingPolygon ) )
2303 if ( newRingPolygon )
2304 GEOSGeom_destroy( newRingPolygon );
2306 GEOSGeom_destroy( newRing );
2311 QVector<GEOSGeometry*> rings;
2314 for ( i = 0; i < polygonList.size(); i++ )
2316 for (
int j = 0; j < rings.size(); j++ )
2317 GEOSGeom_destroy( rings[j] );
2320 GEOSGeometry *shellRing = 0;
2321 GEOSGeometry *shell = 0;
2324 shellRing = GEOSGeom_clone( GEOSGetExteriorRing( polygonList[i] ) );
2327 if ( !GEOSWithin( newRingPolygon, shell ) )
2329 GEOSGeom_destroy( shell );
2338 GEOSGeom_destroy( shell );
2339 else if ( shellRing )
2340 GEOSGeom_destroy( shellRing );
2342 GEOSGeom_destroy( newRingPolygon );
2348 rings << GEOSGeom_clone( shellRing );
2350 GEOSGeom_destroy( shell );
2353 int n = GEOSGetNumInteriorRings( polygonList[i] );
2356 for ( j = 0; j < n; j++ )
2358 GEOSGeometry *holeRing = 0;
2359 GEOSGeometry *hole = 0;
2362 holeRing = GEOSGeom_clone( GEOSGetInteriorRingN( polygonList[i], j ) );
2365 if ( !GEOSDisjoint( hole, newRingPolygon ) )
2367 GEOSGeom_destroy( hole );
2376 GEOSGeom_destroy( hole );
2377 else if ( holeRing )
2378 GEOSGeom_destroy( holeRing );
2383 rings << GEOSGeom_clone( holeRing );
2384 GEOSGeom_destroy( hole );
2392 if ( i == polygonList.size() )
2395 for (
int j = 0; j < rings.size(); j++ )
2396 GEOSGeom_destroy( rings[j] );
2399 GEOSGeom_destroy( newRingPolygon );
2405 rings << GEOSGeom_clone( newRing );
2406 GEOSGeom_destroy( newRingPolygon );
2412 GEOSGeom_destroy(
mGeos );
2417 QVector<GEOSGeometry*> newPolygons;
2419 for (
int j = 0; j < polygonList.size(); j++ )
2421 newPolygons << ( i == j ? newPolygon : GEOSGeom_clone( polygonList[j] ) );
2424 GEOSGeom_destroy(
mGeos );
2444 if ( points.size() != 1 )
2446 QgsDebugMsg(
"expected 1 point: " + QString::number( points.size() ) );
2453 if ( points.size() < 2 )
2455 QgsDebugMsg(
"line must at least have two points: " + QString::number( points.size() ) );
2462 if ( points.size() < 4 )
2464 QgsDebugMsg(
"polygon must at least have three distinct points and must be closed: " + QString::number( points.size() ) );
2469 if ( points.first() != points.last() )
2477 QgsDebugMsg(
"unsupported geometry type: " + QString::number( geomType ) );
2481 GEOSGeometry *newPart = 0;
2496 GEOSGeometry *newRing = 0;
2501 if ( !GEOSisValid( newRing ) )
2511 GEOSGeom_destroy( newRing );
2536 const GEOSGeometry * geosPart = newPart->
asGeos();
2537 return addPart( GEOSGeom_clone( geosPart ) );
2562 int geosType = GEOSGeomTypeId(
mGeos );
2564 Q_ASSERT( newPart );
2568 if ( !GEOSisValid( newPart ) )
2576 GEOSGeom_destroy( newPart );
2582 QVector<GEOSGeometry*> parts;
2585 int n = GEOSGetNumGeometries(
mGeos );
2587 for ( i = 0; i < n; ++i )
2589 const GEOSGeometry *partN = GEOSGetGeometryN(
mGeos, i );
2591 if ( geomType ==
QGis::Polygon && GEOSOverlaps( partN, newPart ) )
2595 parts << GEOSGeom_clone( partN );
2601 for (
int i = 0; i < parts.size(); i++ )
2602 GEOSGeom_destroy( parts[i] );
2608 int nPartGeoms = GEOSGetNumGeometries( newPart );
2609 for (
int i = 0; i < nPartGeoms; ++i )
2611 parts << GEOSGeom_clone( GEOSGetGeometryN( newPart, i ) );
2613 GEOSGeom_destroy( newPart );
2615 GEOSGeom_destroy(
mGeos );
2640 bool hasZValue =
false;
2672 for (
int index2 = 0; index2 < nPoints; ++index2 )
2688 wkbPtr += 1 +
sizeof( int );
2702 wkbPtr += 1 +
sizeof( int );
2705 for (
int index2 = 0; index2 < nPoints; ++index2 )
2719 wkbPtr += 1 +
sizeof( int );
2724 for (
int index2 = 0; index2 < nRings; ++index2 )
2728 for (
int index3 = 0; index3 < nPoints; ++index3 )
2753 bool hasZValue =
false;
2789 for (
int index2 = 0; index2 < nPoints; ++index2 )
2804 wkbPtr += 1 +
sizeof( int );
2818 wkbPtr += 1 +
sizeof( int );
2821 for (
int index2 = 0; index2 < nPoints; ++index2 )
2836 wkbPtr += 1 +
sizeof( int );
2839 for (
int index2 = 0; index2 < nRings; ++index2 )
2843 for (
int index3 = 0; index3 < nPoints; ++index3 )
2857 int QgsGeometry::splitGeometry(
const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries,
bool topological, QList<QgsPoint> &topologyTestPoints )
2877 if ( !GEOSisValid(
mGeos ) )
2881 if ( splitLine.size() < 2 )
2884 newGeometries.clear();
2889 if ( !GEOSisValid( splitLineGeos ) || !GEOSisSimple( splitLineGeos ) )
2891 GEOSGeom_destroy( splitLineGeos );
2906 GEOSGeom_destroy( splitLineGeos );
2911 GEOSGeom_destroy( splitLineGeos );
2926 if ( reshapeWithLine.size() < 2 )
2942 int numGeoms = GEOSGetNumGeometries(
mGeos );
2943 if ( numGeoms == -1 )
2946 bool isMultiGeom =
false;
2947 int geosTypeId = GEOSGeomTypeId(
mGeos );
2948 if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
2956 GEOSGeometry* reshapedGeometry;
2962 GEOSGeom_destroy( reshapeLineGeos );
2963 if ( reshapedGeometry )
2965 GEOSGeom_destroy(
mGeos );
2966 mGeos = reshapedGeometry;
2978 bool reshapeTookPlace =
false;
2980 GEOSGeometry* currentReshapeGeometry = 0;
2981 GEOSGeometry** newGeoms =
new GEOSGeometry*[numGeoms];
2983 for (
int i = 0; i < numGeoms; ++i )
2986 currentReshapeGeometry =
reshapeLine( GEOSGetGeometryN(
mGeos, i ), reshapeLineGeos );
2990 if ( currentReshapeGeometry )
2992 newGeoms[i] = currentReshapeGeometry;
2993 reshapeTookPlace =
true;
2997 newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN(
mGeos, i ) );
3000 GEOSGeom_destroy( reshapeLineGeos );
3002 GEOSGeometry* newMultiGeom = 0;
3005 newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
3009 newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
3013 if ( !newMultiGeom )
3016 if ( reshapeTookPlace )
3018 GEOSGeom_destroy(
mGeos );
3019 mGeos = newMultiGeom;
3025 GEOSGeom_destroy( newMultiGeom );
3043 if ( !GEOSisValid(
mGeos ) )
3046 if ( !GEOSisSimple(
mGeos ) )
3053 if ( !other->
mGeos )
3109 bool hasZValue =
false;
3144 for (
int idx = 0; idx < nPoints; idx++ )
3146 wkbPtr += 1 +
sizeof( int );
3151 wkbPtr +=
sizeof( double );
3175 for (
int idx = 0; idx < nPoints; idx++ )
3180 wkbPtr +=
sizeof( double );
3203 for (
int jdx = 0; jdx < nLines; jdx++ )
3206 wkbPtr += 1 +
sizeof( int );
3209 for (
int idx = 0; idx < nPoints; idx++ )
3214 wkbPtr +=
sizeof( double );
3239 for (
int idx = 0; idx < nRings; idx++ )
3244 for (
int jdx = 0; jdx < nPoints; jdx++ )
3250 wkbPtr +=
sizeof( double );
3274 wkbPtr >> nPolygons;
3275 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3279 wkbPtr += 1 +
sizeof( int );
3282 for (
int idx = 0; idx < nRings; idx++ )
3287 for (
int jdx = 0; jdx < nPoints; jdx++ )
3293 wkbPtr +=
sizeof( double );
3314 QgsDebugMsg( QString(
"Unknown WkbType %1 ENCOUNTERED" ).arg( wkbType ) );
3347 return GEOSIntersects(
mGeos, geometry->
mGeos );
3368 GEOSGeometry *geosPoint = 0;
3370 bool returnval =
false;
3375 returnval = GEOSContains(
mGeos, geosPoint );
3384 GEOSGeom_destroy( geosPoint );
3390 char( *op )(
const GEOSGeometry*,
const GEOSGeometry * ),
3415 return geosRelOp( GEOSContains,
this, geometry );
3420 return geosRelOp( GEOSDisjoint,
this, geometry );
3425 return geosRelOp( GEOSEquals,
this, geometry );
3430 return geosRelOp( GEOSTouches,
this, geometry );
3435 return geosRelOp( GEOSOverlaps,
this, geometry );
3440 return geosRelOp( GEOSWithin,
this, geometry );
3445 return geosRelOp( GEOSCrosses,
this, geometry );
3460 QgsDebugMsg(
"WKB geometry not available or too short!" );
3461 return QString::null;
3464 bool hasZValue =
false;
3489 wkt +=
"LINESTRING(";
3491 for (
int idx = 0; idx < nPoints; ++idx )
3496 wkbPtr +=
sizeof( double );
3518 for (
int idx = 0; idx < nRings; idx++ )
3528 for (
int jdx = 0; jdx < nPoints; jdx++ )
3536 wkbPtr +=
sizeof( double );
3553 wkt +=
"MULTIPOINT(";
3554 for (
int idx = 0; idx < nPoints; ++idx )
3556 wkbPtr += 1 +
sizeof( int );
3563 wkbPtr +=
sizeof( double );
3578 wkt +=
"MULTILINESTRING(";
3579 for (
int jdx = 0; jdx < nLines; jdx++ )
3585 wkbPtr += 1 +
sizeof( int );
3588 for (
int idx = 0; idx < nPoints; idx++ )
3596 wkbPtr +=
sizeof( double );
3611 wkbPtr >> nPolygons;
3613 wkt +=
"MULTIPOLYGON(";
3614 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3620 wkbPtr += 1 +
sizeof( int );
3623 for (
int idx = 0; idx < nRings; idx++ )
3631 for (
int jdx = 0; jdx < nPoints; jdx++ )
3639 wkbPtr +=
sizeof( double );
3652 QgsDebugMsg(
"error: mGeometry type not recognized" );
3653 return QString::null;
3668 return QString::null;
3674 bool hasZValue =
false;
3687 wkt +=
"{ \"type\": \"Point\", \"coordinates\": ["
3699 wkt +=
"{ \"type\": \"LineString\", \"coordinates\": [ ";
3703 for (
int idx = 0; idx < nPoints; ++idx )
3711 wkbPtr +=
sizeof( double );
3724 wkt +=
"{ \"type\": \"Polygon\", \"coordinates\": [ ";
3731 for (
int idx = 0; idx < nRings; idx++ )
3741 for (
int jdx = 0; jdx < nPoints; jdx++ )
3749 wkbPtr +=
sizeof( double );
3763 wkt +=
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ";
3766 for (
int idx = 0; idx < nPoints; ++idx )
3768 wkbPtr += 1 +
sizeof( int );
3775 wkbPtr +=
sizeof( double );
3787 wkt +=
"{ \"type\": \"MultiLineString\", \"coordinates\": [ ";
3791 for (
int jdx = 0; jdx < nLines; jdx++ )
3797 wkbPtr += 1 +
sizeof( int );
3801 for (
int idx = 0; idx < nPoints; idx++ )
3809 wkbPtr +=
sizeof( double );
3824 wkt +=
"{ \"type\": \"MultiPolygon\", \"coordinates\": [ ";
3827 wkbPtr >> nPolygons;
3828 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3835 wkbPtr += 1 +
sizeof( int );
3839 for (
int idx = 0; idx < nRings; idx++ )
3848 for (
int jdx = 0; jdx < nPoints; jdx++ )
3856 wkbPtr +=
sizeof( double );
3869 QgsDebugMsg(
"error: mGeometry type not recognized" );
3870 return QString::null;
3886 GEOSGeom_destroy(
mGeos );
3898 bool hasZValue =
false;
3922 QVector<GEOSGeometry *> points;
3926 for (
int idx = 0; idx < nPoints; idx++ )
3929 wkbPtr += 1 +
sizeof( int );
3932 wkbPtr +=
sizeof( double );
3949 for (
int idx = 0; idx < nPoints; idx++ )
3954 wkbPtr +=
sizeof( double );
3967 QVector<GEOSGeometry*> lines;
3970 for (
int jdx = 0; jdx < nLines; jdx++ )
3975 wkbPtr += 1 +
sizeof( int );
3978 for (
int idx = 0; idx < nPoints; idx++ )
3983 wkbPtr +=
sizeof( double );
3989 if ( sequence.count() > 1 )
4005 QVector<GEOSGeometry*> rings;
4007 for (
int idx = 0; idx < nRings; idx++ )
4016 for (
int jdx = 0; jdx < nPoints; jdx++ )
4022 wkbPtr +=
sizeof( double );
4038 QVector<GEOSGeometry*> polygons;
4042 wkbPtr >> nPolygons;
4044 for (
int kdx = 0; kdx < nPolygons; kdx++ )
4047 QVector<GEOSGeometry*> rings;
4051 wkbPtr += 1 +
sizeof( int );
4054 for (
int idx = 0; idx < numRings; idx++ )
4063 for (
int jdx = 0; jdx < nPoints; jdx++ )
4069 wkbPtr +=
sizeof( double );
4119 switch ( GEOSGeomTypeId(
mGeos ) )
4125 2 *
sizeof(
double );
4129 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(
mGeos );
4132 GEOSCoordSeq_getX( cs, 0, &x );
4133 GEOSCoordSeq_getY( cs, 0, &y );
4142 case GEOS_LINESTRING:
4146 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(
mGeos );
4147 unsigned int nPoints;
4148 GEOSCoordSeq_getSize( cs, &nPoints );
4154 ((
sizeof( double ) +
4155 sizeof(
double ) ) * nPoints );
4162 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq(
mGeos );
4165 for (
unsigned int n = 0; n < nPoints; n++ )
4168 GEOSCoordSeq_getX( sequence, n, &x );
4169 GEOSCoordSeq_getY( sequence, n, &y );
4179 case GEOS_LINEARRING:
4187 int nPointsInRing = 0;
4190 int geometrySize = 1 + 2 *
sizeof( int );
4191 const GEOSGeometry *theRing = GEOSGetExteriorRing(
mGeos );
4194 geometrySize +=
sizeof( int );
4197 for (
int i = 0; i < GEOSGetNumInteriorRings(
mGeos ); ++i )
4199 geometrySize +=
sizeof( int );
4200 theRing = GEOSGetInteriorRingN(
mGeos, i );
4207 mGeometry =
new unsigned char[geometrySize];
4213 int nRings = GEOSGetNumInteriorRings(
mGeos ) + 1;
4217 theRing = GEOSGetExteriorRing(
mGeos );
4222 wkbPtr << nPointsInRing;
4224 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4226 GEOSCoordSeq_getSize( cs, &n );
4228 for (
unsigned int j = 0; j < n; ++j )
4231 GEOSCoordSeq_getX( cs, j, &x );
4232 GEOSCoordSeq_getY( cs, j, &y );
4238 for (
int i = 0; i < GEOSGetNumInteriorRings(
mGeos ); i++ )
4240 theRing = GEOSGetInteriorRingN(
mGeos, i );
4242 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4244 unsigned int nPointsInRing;
4245 GEOSCoordSeq_getSize( cs, &nPointsInRing );
4246 wkbPtr << nPointsInRing;
4248 for (
unsigned int j = 0; j < nPointsInRing; j++ )
4251 GEOSCoordSeq_getX( cs, j, &x );
4252 GEOSCoordSeq_getY( cs, j, &y );
4261 case GEOS_MULTIPOINT:
4264 int geometrySize = 1 + 2 *
sizeof( int );
4265 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4267 geometrySize += 1 +
sizeof( int ) + 2 *
sizeof(
double );
4270 mGeometry =
new unsigned char[geometrySize];
4274 int numPoints = GEOSGetNumGeometries(
mGeos );
4278 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4283 const GEOSGeometry *currentPoint = GEOSGetGeometryN(
mGeos, i );
4285 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( currentPoint );
4288 GEOSCoordSeq_getX( cs, 0, &x );
4289 GEOSCoordSeq_getY( cs, 0, &y );
4296 case GEOS_MULTILINESTRING:
4299 int geometrySize = 1 + 2 *
sizeof( int );
4300 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4302 geometrySize += 1 + 2 *
sizeof( int );
4306 mGeometry =
new unsigned char[geometrySize];
4311 int numLines = GEOSGetNumGeometries(
mGeos );
4315 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4320 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( GEOSGetGeometryN(
mGeos, i ) );
4323 unsigned int lineSize;
4324 GEOSCoordSeq_getSize( cs, &lineSize );
4328 for (
unsigned int j = 0; j < lineSize; ++j )
4331 GEOSCoordSeq_getX( cs, j, &x );
4332 GEOSCoordSeq_getY( cs, j, &y );
4340 case GEOS_MULTIPOLYGON:
4343 int geometrySize = 1 + 2 *
sizeof( int );
4344 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4346 const GEOSGeometry *thePoly = GEOSGetGeometryN(
mGeos, i );
4347 geometrySize += 1 + 2 *
sizeof( int );
4349 geometrySize +=
sizeof( int );
4350 const GEOSGeometry *exRing = GEOSGetExteriorRing( thePoly );
4353 const GEOSGeometry *intRing = 0;
4354 for (
int j = 0; j < GEOSGetNumInteriorRings( thePoly ); j++ )
4356 geometrySize +=
sizeof( int );
4357 intRing = GEOSGetInteriorRingN( thePoly, j );
4362 mGeometry =
new unsigned char[geometrySize];
4366 int numPolygons = GEOSGetNumGeometries(
mGeos );
4370 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4372 const GEOSGeometry *thePoly = GEOSGetGeometryN(
mGeos, i );
4373 int numRings = GEOSGetNumInteriorRings( thePoly ) + 1;
4376 const GEOSGeometry *theRing = GEOSGetExteriorRing( thePoly );
4381 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4383 for (
int k = 0; k < nPointsInRing; ++k )
4386 GEOSCoordSeq_getX( cs, k, &x );
4387 GEOSCoordSeq_getY( cs, k, &y );
4392 for (
int j = 0; j < GEOSGetNumInteriorRings( thePoly ); j++ )
4394 theRing = GEOSGetInteriorRingN( thePoly, j );
4397 wkbPtr << nPointsInRing;
4399 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4401 for (
int k = 0; k < nPointsInRing; ++k )
4404 GEOSCoordSeq_getX( cs, k, &x );
4405 GEOSCoordSeq_getY( cs, k, &y );
4414 case GEOS_GEOMETRYCOLLECTION:
4417 QgsDebugMsg(
"geometry collection - not supported" );
4449 unsigned char* newGeometry =
new unsigned char[newGeomSize];
4455 wkbPtr << byteOrder;
4481 delete [] newGeometry;
4485 wkbPtr << newMultiType << 1;
4499 double x, y, translated_x, translated_y;
4502 memcpy( &x, wkbPtr,
sizeof(
double ) );
4503 translated_x = x + dx;
4504 memcpy( wkbPtr, &translated_x,
sizeof(
double ) );
4505 wkbPtr +=
sizeof( double );
4508 memcpy( &y, wkbPtr,
sizeof(
double ) );
4509 translated_y = y + dy;
4510 memcpy( wkbPtr, &translated_y,
sizeof(
double ) );
4511 wkbPtr +=
sizeof( double );
4514 wkbPtr +=
sizeof( double );
4521 memcpy( &x, wkbPtr,
sizeof(
double ) );
4522 memcpy( &y, wkbPtr +
sizeof(
double ),
sizeof(
double ) );
4530 wkbPtr +=
sizeof( double );
4546 if ( !GEOSIntersects( splitLine,
mGeos ) )
4550 int linearIntersect = GEOSRelatePattern(
mGeos, splitLine,
"1********" );
4551 if ( linearIntersect > 0 )
4554 GEOSGeometry* splitGeom = GEOSDifference(
mGeos, splitLine );
4555 QVector<GEOSGeometry*> lineGeoms;
4557 int splitType = GEOSGeomTypeId( splitGeom );
4558 if ( splitType == GEOS_MULTILINESTRING )
4560 int nGeoms = GEOSGetNumGeometries( splitGeom );
4561 for (
int i = 0; i < nGeoms; ++i )
4562 lineGeoms << GEOSGeom_clone( GEOSGetGeometryN( splitGeom, i ) );
4567 lineGeoms << GEOSGeom_clone( splitGeom );
4572 if ( lineGeoms.size() > 0 )
4574 GEOSGeom_destroy(
mGeos );
4575 mGeos = lineGeoms[0];
4579 for (
int i = 1; i < lineGeoms.size(); ++i )
4584 GEOSGeom_destroy( splitGeom );
4600 if ( !GEOSIntersects( splitLine,
mGeos ) )
4605 if ( !nodedGeometry )
4608 GEOSGeometry *polygons = GEOSPolygonize( &nodedGeometry, 1 );
4612 GEOSGeom_destroy( polygons );
4614 GEOSGeom_destroy( nodedGeometry );
4619 GEOSGeom_destroy( nodedGeometry );
4623 QVector<GEOSGeometry*> testedGeometries;
4624 GEOSGeometry *intersectGeometry = 0;
4631 const GEOSGeometry *polygon = GEOSGetGeometryN( polygons, i );
4632 intersectGeometry = GEOSIntersection(
mGeos, polygon );
4633 if ( !intersectGeometry )
4639 double intersectionArea;
4640 GEOSArea( intersectGeometry, &intersectionArea );
4643 GEOSArea( polygon, &polygonArea );
4645 const double areaRatio = intersectionArea / polygonArea;
4646 if ( areaRatio > 0.99 && areaRatio < 1.01 )
4647 testedGeometries << GEOSGeom_clone( polygon );
4649 GEOSGeom_destroy( intersectGeometry );
4652 bool splitDone =
true;
4654 if ( testedGeometries.size() == nGeometriesThis )
4664 for (
int i = 0; i < testedGeometries.size(); ++i )
4666 GEOSGeom_destroy( testedGeometries[i] );
4670 else if ( testedGeometries.size() > 0 )
4672 GEOSGeom_destroy(
mGeos );
4673 mGeos = testedGeometries[0];
4678 for ( i = 1; i < testedGeometries.size() && GEOSisValid( testedGeometries[i] ); ++i )
4681 if ( i < testedGeometries.size() )
4683 for ( i = 0; i < testedGeometries.size(); ++i )
4684 GEOSGeom_destroy( testedGeometries[i] );
4689 for ( i = 1; i < testedGeometries.size(); ++i )
4692 GEOSGeom_destroy( polygons );
4699 int nIntersections = 0;
4700 int lastIntersectingRing = -2;
4701 const GEOSGeometry* lastIntersectingGeom = 0;
4703 int nRings = GEOSGetNumInteriorRings( polygon );
4708 const GEOSGeometry* outerRing = GEOSGetExteriorRing( polygon );
4709 if ( GEOSIntersects( outerRing, reshapeLineGeos ) == 1 )
4712 lastIntersectingRing = -1;
4713 lastIntersectingGeom = outerRing;
4717 const GEOSGeometry **innerRings =
new const GEOSGeometry*[nRings];
4721 for (
int i = 0; i < nRings; ++i )
4723 innerRings[i] = GEOSGetInteriorRingN( polygon, i );
4724 if ( GEOSIntersects( innerRings[i], reshapeLineGeos ) == 1 )
4727 lastIntersectingRing = i;
4728 lastIntersectingGeom = innerRings[i];
4738 if ( nIntersections != 1 )
4740 delete [] innerRings;
4745 GEOSGeometry* reshapeResult =
reshapeLine( lastIntersectingGeom, reshapeLineGeos );
4746 if ( !reshapeResult )
4748 delete [] innerRings;
4753 GEOSGeometry* newRing = 0;
4754 const GEOSCoordSequence* reshapeSequence = GEOSGeom_getCoordSeq( reshapeResult );
4755 GEOSCoordSequence* newCoordSequence = GEOSCoordSeq_clone( reshapeSequence );
4757 GEOSGeom_destroy( reshapeResult );
4759 newRing = GEOSGeom_createLinearRing( newCoordSequence );
4762 delete [] innerRings;
4766 GEOSGeometry* newOuterRing = 0;
4767 if ( lastIntersectingRing == -1 )
4768 newOuterRing = newRing;
4770 newOuterRing = GEOSGeom_clone( outerRing );
4773 QList<GEOSGeometry*> ringList;
4776 GEOSGeometry* outerRingPoly = GEOSGeom_createPolygon( GEOSGeom_clone( newOuterRing ), 0, 0 );
4777 if ( outerRingPoly )
4779 GEOSGeometry* currentRing = 0;
4780 for (
int i = 0; i < nRings; ++i )
4782 if ( lastIntersectingRing == i )
4783 currentRing = newRing;
4785 currentRing = GEOSGeom_clone( innerRings[i] );
4788 if ( GEOSContains( outerRingPoly, currentRing ) == 1 )
4789 ringList.push_back( currentRing );
4791 GEOSGeom_destroy( currentRing );
4794 GEOSGeom_destroy( outerRingPoly );
4797 GEOSGeometry** newInnerRings =
new GEOSGeometry*[ringList.size()];
4798 for (
int i = 0; i < ringList.size(); ++i )
4799 newInnerRings[i] = ringList.at( i );
4801 delete [] innerRings;
4803 GEOSGeometry* reshapedPolygon = GEOSGeom_createPolygon( newOuterRing, newInnerRings, ringList.size() );
4804 delete[] newInnerRings;
4806 return reshapedPolygon;
4811 if ( !line || !reshapeLineGeos )
4814 bool atLeastTwoIntersections =
false;
4819 GEOSGeometry* intersectGeom = GEOSIntersection( line, reshapeLineGeos );
4820 if ( intersectGeom )
4822 atLeastTwoIntersections = ( GEOSGeomTypeId( intersectGeom ) == GEOS_MULTIPOINT && GEOSGetNumGeometries( intersectGeom ) > 1 );
4823 GEOSGeom_destroy( intersectGeom );
4829 atLeastTwoIntersections =
false;
4832 if ( !atLeastTwoIntersections )
4836 const GEOSCoordSequence* lineCoordSeq = GEOSGeom_getCoordSeq( line );
4837 if ( !lineCoordSeq )
4840 unsigned int lineCoordSeqSize;
4841 if ( GEOSCoordSeq_getSize( lineCoordSeq, &lineCoordSeqSize ) == 0 )
4844 if ( lineCoordSeqSize < 2 )
4848 double x1, y1, x2, y2;
4849 GEOSCoordSeq_getX( lineCoordSeq, 0, &x1 );
4850 GEOSCoordSeq_getY( lineCoordSeq, 0, &y1 );
4851 GEOSCoordSeq_getX( lineCoordSeq, lineCoordSeqSize - 1, &x2 );
4852 GEOSCoordSeq_getY( lineCoordSeq, lineCoordSeqSize - 1, &y2 );
4856 bool isRing =
false;
4857 if ( GEOSGeomTypeId( line ) == GEOS_LINEARRING || GEOSEquals( beginLineVertex, endLineVertex ) == 1 )
4861 GEOSGeometry* nodedGeometry =
nodeGeometries( reshapeLineGeos, line );
4862 if ( !nodedGeometry )
4864 GEOSGeom_destroy( beginLineVertex );
4865 GEOSGeom_destroy( endLineVertex );
4870 GEOSGeometry *mergedLines = GEOSLineMerge( nodedGeometry );
4871 GEOSGeom_destroy( nodedGeometry );
4874 GEOSGeom_destroy( beginLineVertex );
4875 GEOSGeom_destroy( endLineVertex );
4879 int numMergedLines = GEOSGetNumGeometries( mergedLines );
4880 if ( numMergedLines < 2 )
4882 GEOSGeom_destroy( beginLineVertex );
4883 GEOSGeom_destroy( endLineVertex );
4884 if ( numMergedLines == 1 )
4885 return GEOSGeom_clone( reshapeLineGeos );
4890 QList<GEOSGeometry*> resultLineParts;
4891 QList<GEOSGeometry*> probableParts;
4893 for (
int i = 0; i < numMergedLines; ++i )
4895 const GEOSGeometry* currentGeom;
4897 currentGeom = GEOSGetGeometryN( mergedLines, i );
4898 const GEOSCoordSequence* currentCoordSeq = GEOSGeom_getCoordSeq( currentGeom );
4899 unsigned int currentCoordSeqSize;
4900 GEOSCoordSeq_getSize( currentCoordSeq, ¤tCoordSeqSize );
4901 if ( currentCoordSeqSize < 2 )
4905 double xBegin, xEnd, yBegin, yEnd;
4906 GEOSCoordSeq_getX( currentCoordSeq, 0, &xBegin );
4907 GEOSCoordSeq_getY( currentCoordSeq, 0, &yBegin );
4908 GEOSCoordSeq_getX( currentCoordSeq, currentCoordSeqSize - 1, &xEnd );
4909 GEOSCoordSeq_getY( currentCoordSeq, currentCoordSeqSize - 1, &yEnd );
4914 int nEndpointsOnOriginalLine = 0;
4916 nEndpointsOnOriginalLine += 1;
4919 nEndpointsOnOriginalLine += 1;
4922 int nEndpointsSameAsOriginalLine = 0;
4923 if ( GEOSEquals( beginCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals( beginCurrentGeomVertex, endLineVertex ) == 1 )
4924 nEndpointsSameAsOriginalLine += 1;
4926 if ( GEOSEquals( endCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals( endCurrentGeomVertex, endLineVertex ) == 1 )
4927 nEndpointsSameAsOriginalLine += 1;
4930 bool currentGeomOverlapsOriginalGeom =
false;
4931 bool currentGeomOverlapsReshapeLine =
false;
4933 currentGeomOverlapsOriginalGeom =
true;
4936 currentGeomOverlapsReshapeLine =
true;
4939 if ( nEndpointsSameAsOriginalLine == 1 && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
4941 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
4944 else if ( isRing && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
4946 probableParts.push_back( GEOSGeom_clone( currentGeom ) );
4948 else if ( nEndpointsOnOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
4950 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
4952 else if ( nEndpointsSameAsOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
4954 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
4956 else if ( currentGeomOverlapsOriginalGeom && currentGeomOverlapsReshapeLine )
4958 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
4961 GEOSGeom_destroy( beginCurrentGeomVertex );
4962 GEOSGeom_destroy( endCurrentGeomVertex );
4966 if ( isRing && probableParts.size() > 0 )
4968 GEOSGeometry* maxGeom = 0;
4969 GEOSGeometry* currentGeom = 0;
4970 double maxLength = -DBL_MAX;
4971 double currentLength = 0;
4972 for (
int i = 0; i < probableParts.size(); ++i )
4974 currentGeom = probableParts.at( i );
4975 GEOSLength( currentGeom, ¤tLength );
4976 if ( currentLength > maxLength )
4978 maxLength = currentLength;
4979 GEOSGeom_destroy( maxGeom );
4980 maxGeom = currentGeom;
4984 GEOSGeom_destroy( currentGeom );
4987 resultLineParts.push_back( maxGeom );
4990 GEOSGeom_destroy( beginLineVertex );
4991 GEOSGeom_destroy( endLineVertex );
4992 GEOSGeom_destroy( mergedLines );
4994 GEOSGeometry* result = 0;
4995 if ( resultLineParts.size() < 1 )
4998 if ( resultLineParts.size() == 1 )
5000 result = resultLineParts[0];
5004 GEOSGeometry **lineArray =
new GEOSGeometry*[resultLineParts.size()];
5005 for (
int i = 0; i < resultLineParts.size(); ++i )
5007 lineArray[i] = resultLineParts[i];
5011 GEOSGeometry* multiLineGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, lineArray, resultLineParts.size() );
5012 delete [] lineArray;
5015 result = GEOSLineMerge( multiLineGeom );
5016 GEOSGeom_destroy( multiLineGeom );
5020 if ( GEOSGeomTypeId( result ) != GEOS_LINESTRING )
5022 GEOSGeom_destroy( result );
5036 GEOSGeometry* intersectionGeom = GEOSIntersection(
mGeos, splitLine );
5037 if ( !intersectionGeom )
5040 bool simple =
false;
5041 int nIntersectGeoms = 1;
5042 if ( GEOSGeomTypeId( intersectionGeom ) == GEOS_LINESTRING || GEOSGeomTypeId( intersectionGeom ) == GEOS_POINT )
5046 nIntersectGeoms = GEOSGetNumGeometries( intersectionGeom );
5048 for (
int i = 0; i < nIntersectGeoms; ++i )
5050 const GEOSGeometry* currentIntersectGeom;
5052 currentIntersectGeom = intersectionGeom;
5054 currentIntersectGeom = GEOSGetGeometryN( intersectionGeom, i );
5056 const GEOSCoordSequence* lineSequence = GEOSGeom_getCoordSeq( currentIntersectGeom );
5057 unsigned int sequenceSize = 0;
5059 if ( GEOSCoordSeq_getSize( lineSequence, &sequenceSize ) != 0 )
5061 for (
unsigned int i = 0; i < sequenceSize; ++i )
5063 if ( GEOSCoordSeq_getX( lineSequence, i, &x ) != 0 )
5065 if ( GEOSCoordSeq_getY( lineSequence, i, &y ) != 0 )
5067 testPoints.push_back(
QgsPoint( x, y ) );
5073 GEOSGeom_destroy( intersectionGeom );
5079 if ( !splitLine || !geom )
5082 GEOSGeometry *geometryBoundary = 0;
5083 if ( GEOSGeomTypeId( geom ) == GEOS_POLYGON || GEOSGeomTypeId( geom ) == GEOS_MULTIPOLYGON )
5084 geometryBoundary = GEOSBoundary( geom );
5086 geometryBoundary = GEOSGeom_clone( geom );
5088 GEOSGeometry *splitLineClone = GEOSGeom_clone( splitLine );
5089 GEOSGeometry *unionGeometry = GEOSUnion( splitLineClone, geometryBoundary );
5090 GEOSGeom_destroy( splitLineClone );
5092 GEOSGeom_destroy( geometryBoundary );
5093 return unionGeometry;
5098 if ( !line1 || !line2 )
5103 double bufferDistance = 0.00001;
5105 bufferDistance = 0.00000001;
5111 GEOSGeometry* intersectionGeom = GEOSIntersection( bufferGeom, line1 );
5114 double intersectGeomLength;
5117 GEOSLength( intersectionGeom, &intersectGeomLength );
5118 GEOSLength( line1, &line1Length );
5120 GEOSGeom_destroy( bufferGeom );
5121 GEOSGeom_destroy( intersectionGeom );
5123 double intersectRatio = line1Length / intersectGeomLength;
5124 if ( intersectRatio > 0.9 && intersectRatio < 1.1 )
5132 if ( !point || !line )
5135 double bufferDistance = 0.000001;
5137 bufferDistance = 0.00000001;
5139 GEOSGeometry* lineBuffer = GEOSBuffer( line, bufferDistance, 8 );
5143 bool contained =
false;
5144 if ( GEOSContains( lineBuffer, point ) == 1 )
5147 GEOSGeom_destroy( lineBuffer );
5153 GEOSGeometry* bbox = GEOSEnvelope( geom );
5157 const GEOSGeometry* bBoxRing = GEOSGetExteriorRing( bbox );
5161 const GEOSCoordSequence* bBoxCoordSeq = GEOSGeom_getCoordSeq( bBoxRing );
5163 if ( !bBoxCoordSeq )
5166 unsigned int nCoords = 0;
5167 if ( !GEOSCoordSeq_getSize( bBoxCoordSeq, &nCoords ) )
5171 for (
unsigned int i = 0; i < ( nCoords - 1 ); ++i )
5173 GEOSCoordSeq_getX( bBoxCoordSeq, i, &x );
5174 if ( x > 180 || x < -180 )
5177 GEOSCoordSeq_getY( bBoxCoordSeq, i, &y );
5178 if ( y > 90 || y < -90 )
5191 int geometryType = GEOSGeomTypeId( g );
5192 if ( geometryType == GEOS_POINT || geometryType == GEOS_LINESTRING || geometryType == GEOS_LINEARRING
5193 || geometryType == GEOS_POLYGON )
5197 return GEOSGetNumGeometries( g );
5209 int type = GEOSGeomTypeId(
mGeos );
5210 if ( type != GEOS_GEOMETRYCOLLECTION &&
5211 type != GEOS_MULTILINESTRING &&
5212 type != GEOS_MULTIPOLYGON &&
5213 type != GEOS_MULTIPOINT )
5216 QVector<GEOSGeometry*> copyList = splitResult;
5217 splitResult.clear();
5220 QVector<GEOSGeometry*> unionGeom;
5222 for (
int i = 0; i < copyList.size(); ++i )
5225 bool isPart =
false;
5226 for (
int j = 0; j < GEOSGetNumGeometries(
mGeos ); j++ )
5228 if ( GEOSEquals( copyList[i], GEOSGetGeometryN(
mGeos, j ) ) )
5237 unionGeom << copyList[i];
5241 QVector<GEOSGeometry*> geomVector;
5242 geomVector << copyList[i];
5244 if ( type == GEOS_MULTILINESTRING )
5246 else if ( type == GEOS_MULTIPOLYGON )
5249 GEOSGeom_destroy( copyList[i] );
5254 if ( unionGeom.size() > 0 )
5256 if ( type == GEOS_MULTILINESTRING )
5258 else if ( type == GEOS_MULTIPOLYGON )
5271 wkbPtr += 1 +
sizeof( int );
5276 wkbPtr +=
sizeof( double );
5283 wkbPtr += 1 +
sizeof( int );
5285 unsigned int nPoints;
5291 for ( uint i = 0; i < nPoints; ++i )
5296 wkbPtr +=
sizeof( double );
5306 wkbPtr += 1 +
sizeof( int );
5309 unsigned int numRings;
5312 if ( numRings == 0 )
5317 for ( uint idx = 0; idx < numRings; idx++ )
5324 for (
int jdx = 0; jdx < nPoints; jdx++ )
5329 wkbPtr +=
sizeof( double );
5384 for (
int i = 0; i < nPoints; i++ )
5386 points[i] =
asPoint( wkbPtr, hasZValue );
5403 wkbPtr >> numLineStrings;
5407 for (
int i = 0; i < numLineStrings; i++ )
5424 wkbPtr >> numPolygons;
5428 for (
int i = 0; i < numPolygons; i++ )
5429 polygons[i] =
asPolygon( wkbPtr, hasZValue );
5446 if ( GEOSArea(
mGeos, &area ) == 0 )
5466 if ( GEOSLength(
mGeos, &length ) == 0 )
5557 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
5558 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2)))
5612 GEOSGeometry* unionGeom = GEOSUnion(
mGeos, geometry->
mGeos );
5618 GEOSGeometry* mergedGeom = GEOSLineMerge( unionGeom );
5621 GEOSGeom_destroy( unionGeom );
5622 unionGeom = mergedGeom;
5678 return QList<QgsGeometry*>();
5680 int type = GEOSGeomTypeId(
mGeos );
5681 QgsDebugMsg(
"geom type: " + QString::number( type ) );
5683 QList<QgsGeometry*> geomCollection;
5685 if ( type != GEOS_MULTIPOINT &&
5686 type != GEOS_MULTILINESTRING &&
5687 type != GEOS_MULTIPOLYGON &&
5688 type != GEOS_GEOMETRYCOLLECTION )
5691 geomCollection.append(
new QgsGeometry( *
this ) );
5692 return geomCollection;
5695 int count = GEOSGetNumGeometries(
mGeos );
5696 QgsDebugMsg(
"geom count: " + QString::number( count ) );
5698 for (
int i = 0; i < count; ++i )
5700 const GEOSGeometry * geometry = GEOSGetGeometryN(
mGeos, i );
5701 geomCollection.append(
fromGeosGeom( GEOSGeom_clone( geometry ) ) );
5704 return geomCollection;
5709 if ( ringNum <= 0 || partNum < 0 )
5721 if ( ringNum >= polygon.count() )
5724 polygon.remove( ringNum );
5737 if ( partNum >= mpolygon.count() )
5740 if ( ringNum >= mpolygon[partNum].count() )
5743 mpolygon[partNum].remove( ringNum );
5768 if ( partNum >= mpoint.size() || mpoint.size() == 1 )
5771 mpoint.remove( partNum );
5784 if ( partNum >= mline.size() || mline.size() == 1 )
5787 mline.remove( partNum );
5800 if ( partNum >= mpolygon.size() || mpolygon.size() == 1 )
5803 mpolygon.remove( partNum );
5823 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && (((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)) || (GEOS_VERSION_MAJOR>3))
5824 GEOSGeometry* geomCollection = 0;
5826 GEOSGeometry* geomUnion = GEOSUnaryUnion( geomCollection );
5827 GEOSGeom_destroy( geomCollection );
5830 GEOSGeometry* geomCollection = geoms.takeFirst();
5832 while ( !geoms.isEmpty() )
5834 GEOSGeometry* g = geoms.takeFirst();
5835 GEOSGeometry* geomCollectionNew = GEOSUnion( geomCollection, g );
5836 GEOSGeom_destroy( geomCollection );
5837 GEOSGeom_destroy( g );
5838 geomCollection = geomCollectionNew;
5841 return geomCollection;
5847 int returnValue = 0;
5861 QList<GEOSGeometry*> nearGeometries;
5865 QStringList::const_iterator aIt = avoidIntersectionsList.constBegin();
5866 for ( ; aIt != avoidIntersectionsList.constEnd(); ++aIt )
5872 QMap<QgsVectorLayer*, QSet<qint64> >::const_iterator ignoreIt = ignoreFeatures.find( currentLayer );
5873 if ( ignoreIt != ignoreFeatures.constEnd() )
5874 ignoreIds = ignoreIt.value();
5882 if ( ignoreIds.contains( f.
id() ) )
5893 if ( nearGeometries.isEmpty() )
5896 GEOSGeometry* nearGeometriesUnion = 0;
5897 GEOSGeometry* geomWithoutIntersections = 0;
5900 nearGeometriesUnion =
_makeUnion( nearGeometries );
5901 geomWithoutIntersections = GEOSDifference(
asGeos(), nearGeometriesUnion );
5903 fromGeos( geomWithoutIntersections );
5905 GEOSGeom_destroy( nearGeometriesUnion );
5909 if ( nearGeometriesUnion )
5910 GEOSGeom_destroy( nearGeometriesUnion );
5911 if ( geomWithoutIntersections )
5912 GEOSGeom_destroy( geomWithoutIntersections );
5919 if (
wkbType() != geomTypeBeforeModification )
5934 const GEOSGeometry *g =
asGeos();
5939 return GEOSisValid( g );
5950 return geosRelOp( GEOSEquals,
this, &g );
5957 const GEOSGeometry *g =
asGeos();
5962 return GEOSisEmpty( g );
5974 double f2 = y2 - y1;
5976 double f4 = x2 - x1;
5977 return f1*f2 - f3*f4;
QgsFeatureId id() const
Get the feature id for this feature.
Wrapper for iterator of features from vector data provider or vector layer.
GEOSException(QString theMsg)
A rectangle specified with double values.
static void validateGeometry(QgsGeometry *g, QList< QgsGeometry::Error > &errors)
Validate geometry and produce a list of geometry errors.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
void adjacentVertices(int atVertex, int &beforeVertex, int &afterVertex)
Returns the indexes of the vertices before and after the given vertex index.
int makeDifference(QgsGeometry *other)
Changes this geometry such that it does not intersect the other geometry.
void translateVertex(QgsWkbPtr &wkbPtr, double dx, double dy, bool hasZValue)
Translates a single vertex by dx and dy.
bool mDirtyWkb
If the geometry has been set since the last conversion to WKB.
double length()
get length of geometry using GEOS
static GEOSGeometry * nodeGeometries(const GEOSGeometry *splitLine, const GEOSGeometry *poly)
Nodes together a split line and a (multi-) polygon geometry in a multilinestring. ...
int reshapeGeometry(const QList< QgsPoint > &reshapeWithLine)
Replaces a part of this geometry with another line.
Use exact geometry intersection (slower) instead of bounding boxes.
QgsGeometry * combine(QgsGeometry *geometry)
Returns a geometry representing all the points in this geometry and other (a union geometry operation...
size_t wkbSize() const
Returns the size of the WKB in asWkb().
double yMaximum() const
Get the y maximum value (top side of rectangle)
QSet< QgsFeatureId > QgsFeatureIds
bool isMultipart()
Returns true if wkb of the geometry is of WKBMulti* type.
QgsMultiPolyline asMultiPolyline() const
return contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QVector< QgsPoint > QgsPolyline
polyline is represented as a vector of points
QString qgsDoubleToString(const double &a)
QgsGeometry * geometry() const
Get the geometry object associated with this feature.
QgsPolygon asPolygon() const
return contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list ...
QList< QgsGeometry * > asGeometryCollection() const
return contents of the geometry as a list of geometries
static GEOSGeometry * createGeosCollection(int typeId, QVector< GEOSGeometry * > geoms)
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=0, double epsilon=DEFAULT_SEGMENT_EPSILON)
Searches for the closest segment of geometry to the given point.
bool moveVertex(double x, double y, int atVertex)
Moves the vertex at the given position number and item (first number is index 0) to the given coordin...
double closestVertexWithContext(const QgsPoint &point, int &atVertex)
Searches for the closest vertex in this geometry to the given point.
static int lineContainedInLine(const GEOSGeometry *line1, const GEOSGeometry *line2)
Tests if line1 is completely contained in line2.
QGis::GeometryType type()
Returns type of the vector.
bool crosses(const QgsGeometry *geometry) const
Test for if geometry crosses another (uses GEOS)
int addPart(const QList< QgsPoint > &points, QGis::GeometryType geomType=QGis::UnknownGeometry)
Adds a new island polygon to a multipolygon feature.
WkbType
Used for symbology operations.
QgsGeometry()
Constructor.
static GEOSGeometry * createGeosPolygon(const QVector< GEOSGeometry * > &rings)
int mergeGeometriesMultiTypeSplit(QVector< GEOSGeometry * > &splitResult)
int topologicalTestPointsSplit(const GEOSGeometry *splitLine, QList< QgsPoint > &testPoints) const
Finds out the points that need to be tested for topological correctnes if this geometry will be split...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
double area()
get area of geometry using GEOS
bool insertVertex(double x, double y, int beforeVertex)
Insert a new vertex before the given vertex index, ring and item (first number is index 0) If the req...
int splitLinearGeometry(GEOSGeometry *splitLine, QList< QgsGeometry * > &newGeometries)
Splits line/multiline geometries.
QgsPoint closestVertex(const QgsPoint &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist)
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
QgsPoint vertexAt(int atVertex)
Returns coordinates of a vertex.
static endian_t endian()
Returns whether this machine uses big or little endian.
QgsGeometry & operator=(QgsGeometry const &rhs)
assignments will prompt a deep copy of the object
double sqrDist(double x, double y) const
Returns the squared distance between this point and x,y.
GEOSException(const GEOSException &rhs)
QgsGeometry * difference(QgsGeometry *geometry)
Returns a geometry representing the points making up this geometry that do not make up other...
bool deleteRing(int ringNum, int partNum=0)
delete a ring in polygon or multipolygon.
size_t mGeometrySize
size of geometry
const GEOSGeometry * asGeos() const
Returns a geos geomtry.
static void throwGEOSException(const char *fmt,...)
QgsGeometry * centroid()
Returns the center of mass of a geometry.
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
QgsMultiPolygon asMultiPolygon() const
return contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty ...
bool deletePart(int partNum)
delete part identified by the part number
bool isGeosValid()
check validity using GEOS
double ANALYSIS_EXPORT max(double x, double y)
returns the maximum of two doubles or the first argument if both are equal
static WkbType flatType(WkbType type)
int splitGeometry(const QList< QgsPoint > &splitLine, QList< QgsGeometry * > &newGeometries, bool topological, QList< QgsPoint > &topologyTestPoints)
Splits this geometry according to a given line.
bool contains(const QgsPoint *p) const
Test for containment of a point (uses GEOS)
QStringList readListEntry(const QString &scope, const QString &key, QStringList def=QStringList(), bool *ok=0) const
key value accessors
QString exportToWkt() const
Exports the geometry to mWkt.
QgsGeometry * buffer(double distance, int segments)
Returns a buffer region around this geometry having the given width and with a specified number of se...
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
static GEOSCoordSequence * createGeosCoordSequence(const QgsPolyline &points)
bool isGeosEmpty()
check if geometry is empty using GEOS
double xMaximum() const
Get the x maximum value (right side of rectangle)
#define QgsDebugMsgLevel(str, level)
QgsGeometry * convexHull()
Returns the smallest convex polygon that contains all the points in the geometry. ...
bool overlaps(const QgsGeometry *geometry) const
Test for if geometry overlaps another (uses GEOS)
QgsGeometry * simplify(double tolerance)
Returns a simplified version of this geometry using a specified tolerance value.
bool deleteVertex(int atVertex)
Deletes the vertex at the given position number and item (first number is index 0) Returns false if a...
double sqrDistToSegment(double x1, double y1, double x2, double y2, QgsPoint &minDistPoint, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Returns the minimum distance between this point and a segment.
int avoidIntersections(QMap< QgsVectorLayer *, QSet< QgsFeatureId > > ignoreFeatures=(QMap< QgsVectorLayer *, QSet< QgsFeatureId > >()))
Modifies geometry to avoid intersections with the layers specified in project properties.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QVector< QgsPolygon > QgsMultiPolygon
a collection of QgsPolygons that share a common collection of attributes
static GEOSGeometry * createGeosLinearRing(const QgsPolyline &polyline)
QList< int > QgsAttributeList
static GEOSGeometry * createGeosLineString(const QgsPolyline &polyline)
QVector< QgsPoint > QgsMultiPoint
a collection of QgsPoints that share a common collection of attributes
void fromGeos(GEOSGeometry *geos)
Set the geometry, feeding in a geometry in GEOS format.
static GEOSGeometry * createGeosPoint(const QgsPoint &point)
QString toString() const
String representation of the point (x,y)
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
int splitPolygonGeometry(GEOSGeometry *splitLine, QList< QgsGeometry * > &newGeometries)
Splits polygon/multipolygon geometries.
QVector< QgsPolyline > QgsPolygon
polygon: first item of the list is outer ring, inner rings (if any) start from second item ...
void validateGeometry(QList< Error > &errors)
Validate geometry and produce a list of geometry errors.
void set(double x, double y)
QgsGeometry * intersection(QgsGeometry *geometry)
Returns a geometry representing the points shared by this geometry and other.
A class to represent a point geometry.
static QgsGeometry * fromPoint(const QgsPoint &point)
construct geometry from a point
int translate(double dx, double dy)
Translate this geometry by dx, dy.
static bool geomInDegrees(const GEOSGeometry *geom)
Tests if geom bounding rect is within -180 <= x <= 180, -90 <= y <= 90.
static GEOSGeometry * reshapeLine(const GEOSGeometry *origLine, const GEOSGeometry *reshapeLineGeos)
Creates a new line from an original line and a reshape line.
bool isGeosEqual(QgsGeometry &)
compare geometries using GEOS
bool mDirtyGeos
If the geometry has been set since the last conversion to GEOS.
QVector< QgsPolyline > QgsMultiPolyline
a collection of QgsPolylines that share a common collection of attributes
static bool isMultiType(WkbType type)
static QgsGeometry * fromMultiPolyline(const QgsMultiPolyline &multiline)
construct geometry from a multipolyline
QgsGeometry * symDifference(QgsGeometry *geometry)
Returns a Geometry representing the points making up this Geometry that do not make up other...
QgsPolyline asPolyline() const
return contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list ...
QgsRectangle boundingBox()
Returns the bounding box of this feature.
int numberOfGeometries(GEOSGeometry *g) const
Returns number of single geometry in a geos geometry.
static int wkbDimensions(WkbType type)
bool exportWkbToGeos() const
Converts from the WKB geometry to the GEOS geometry.
static void printGEOSNotice(const char *fmt,...)
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
bool exportGeosToWkb() const
Converts from the GEOS geometry to the WKB geometry.
void fromWkb(unsigned char *wkb, size_t length)
Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length...
unsigned char * mGeometry
pointer to geometry in binary WKB format This is the class' native implementation ...
QgsMultiPoint asMultiPoint() const
return contents of the geometry as a multi point if wkbType is WKBMultiPoint, otherwise an empty list...
bool equals(const QgsGeometry *geometry) const
Test for if geometry equals another (uses GEOS)
static QgsProject * instance()
access to canonical QgsProject instance
bool within(const QgsGeometry *geometry) const
Test for if geometry is within another (uses GEOS)
double sqrDistToVertexAt(QgsPoint &point, int atVertex)
Returns the squared cartesian distance between the given point to the given vertex index (vertex at t...
static QgsGeometry * fromRect(const QgsRectangle &rect)
construct geometry from a rectangle
int transform(const QgsCoordinateTransform &ct)
Transform this geometry as described by CoordinateTranasform ct.
static QgsGeometry * fromMultiPoint(const QgsMultiPoint &multipoint)
construct geometry from a multipoint
static QgsGeometry * fromPolyline(const QgsPolyline &polyline)
construct geometry from a polyline
static QgsGeometry * fromWkt(QString wkt)
static method that creates geometry from Wkt
#define DEFAULT_QUADRANT_SEGMENTS
static unsigned int getNumGeosPoints(const GEOSGeometry *geom)
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
bool disjoint(const QgsGeometry *geometry) const
Test for if geometry is disjoint of another (uses GEOS)
static QgsGeometry * fromMultiPolygon(const QgsMultiPolygon &multipoly)
construct geometry from a multipolygon
static QgsGeometry * fromPolygon(const QgsPolygon &polygon)
construct geometry from a polygon
~QgsGeometry()
Destructor.
bool touches(const QgsGeometry *geometry) const
Test for if geometry touch another (uses GEOS)
double leftOf(double x, double y, double &x1, double &y1, double &x2, double &y2)
Returns < 0 if point(x/y) is left of the line x1,y1 -> x1,y2.
double ANALYSIS_EXPORT leftOf(Point3D *thepoint, Point3D *p1, Point3D *p2)
Returns whether 'thepoint' is left or right of the line from 'p1' to 'p2'.
int addRing(const QList< QgsPoint > &ring)
Adds a new ring to this geometry.
QgsGeometry * interpolate(double distance)
static int pointContainedInLine(const GEOSGeometry *point, const GEOSGeometry *line)
Tests if a point is on a line.
QString exportToGeoJSON() const
Exports the geometry to mGeoJSON.
bool nextFeature(QgsFeature &f)
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
static bool geosRelOp(char(*op)(const GEOSGeometry *, const GEOSGeometry *), const QgsGeometry *a, const QgsGeometry *b)
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
Represents a vector layer which manages a vector based data sets.
static GEOSGeometry * _makeUnion(QList< GEOSGeometry * > geoms)
Return union of several geometries - try to use unary union if available (GEOS >= 3...
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
double xMinimum() const
Get the x minimum value (left side of rectangle)
void transformVertex(QgsWkbPtr &wkbPtr, const QgsCoordinateTransform &ct, bool hasZValue)
Transforms a single vertex by ct.
static QgsGeometry * fromGeosGeom(GEOSGeometry *geom)
double distance(QgsGeometry &geom)
static GEOSGeometry * reshapePolygon(const GEOSGeometry *polygon, const GEOSGeometry *reshapeLineGeos)
Creates a new polygon replacing the part from the first to the second intersection with the reshape l...
GEOSGeometry * mGeos
cached GEOS version of this geometry