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;