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 )
148 #define GEOSPointOnSurface(g) GEOSPointOnSurface( (GEOSGeometry*) g )
150 #define GEOSCoordSeq_getSize(cs,n) GEOSCoordSeq_getSize( (GEOSCoordSequence *) cs, n )
151 #define GEOSCoordSeq_getX(cs,i,x) GEOSCoordSeq_getX( (GEOSCoordSequence *)cs, i, x )
152 #define GEOSCoordSeq_getY(cs,i,y) GEOSCoordSeq_getY( (GEOSCoordSequence *)cs, i, y )
156 static GEOSGeometry *cloneGeosGeom(
const GEOSGeometry *geom )
160 int type = GEOSGeomTypeId(( GEOSGeometry * ) geom );
162 if ( type == GEOS_MULTIPOINT || type == GEOS_MULTILINESTRING || type == GEOS_MULTIPOLYGON )
164 QVector<GEOSGeometry *> geoms;
168 for (
int i = 0; i < GEOSGetNumGeometries(( GEOSGeometry * )geom ); ++i )
169 geoms << GEOSGeom_clone(( GEOSGeometry * ) GEOSGetGeometryN(( GEOSGeometry * ) geom, i ) );
176 for (
int i = 0; i < geoms.count(); i++ )
177 GEOSGeom_destroy( geoms[i] );
184 return GEOSGeom_clone(( GEOSGeometry * ) geom );
188 #define GEOSGeom_clone(g) cloneGeosGeom(g)
196 , mDirtyGeos( false )
202 , mGeometrySize( rhs.mGeometrySize )
203 , mDirtyWkb( rhs.mDirtyWkb )
204 , mDirtyGeos( rhs.mDirtyGeos )
227 GEOSGeom_destroy(
mGeos );
234 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( geom );
235 GEOSCoordSeq_getSize( cs, &n );
241 GEOSCoordSequence *coord = GEOSCoordSeq_create( 1, 2 );
242 GEOSCoordSeq_setX( coord, 0, point.
x() );
243 GEOSCoordSeq_setY( coord, 0, point.
y() );
244 return GEOSGeom_createPoint( coord );
249 GEOSCoordSequence *coord = 0;
253 coord = GEOSCoordSeq_create( points.count(), 2 );
255 for ( i = 0; i < points.count(); i++ )
257 GEOSCoordSeq_setX( coord, i, points[i].x() );
258 GEOSCoordSeq_setY( coord, i, points[i].y() );
273 GEOSGeometry **geomarr =
new GEOSGeometry*[ geoms.size()];
277 for (
int i = 0; i < geoms.size(); i++ )
278 geomarr[i] = geoms[i];
280 GEOSGeometry *geom = 0;
284 geom = GEOSGeom_createCollection( typeId, geomarr, geoms.size() );
298 GEOSCoordSequence *coord = 0;
303 return GEOSGeom_createLineString( coord );
317 GEOSCoordSequence *coord = 0;
319 if ( polyline.count() == 0 )
324 if ( polyline[0] != polyline[polyline.size()-1] )
336 return GEOSGeom_createLinearRing( coord );
352 if ( rings.size() == 0 )
354 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
355 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
356 return GEOSGeom_createEmptyPolygon();
358 shell = GEOSGeom_createLinearRing( GEOSCoordSeq_create( 0, 2 ) );
366 GEOSGeometry **holes = NULL;
369 if ( rings.size() > 1 )
371 nHoles = rings.size() - 1;
372 holes =
new GEOSGeometry*[ nHoles ];
376 for (
int i = 0; i < nHoles; i++ )
377 holes[i] = rings[i+1];
380 GEOSGeometry *geom = GEOSGeom_createPolygon( shell, holes, nHoles );
395 if ( polygon.count() == 0 )
398 QVector<GEOSGeometry *> geoms;
402 for (
int i = 0; i < polygon.count(); i++ )
410 for (
int i = 0; i < geoms.count(); i++ )
411 GEOSGeom_destroy( geoms[i] );
430 #if defined(GEOS_VERSION_MAJOR) && (GEOS_VERSION_MAJOR>=3)
431 GEOSWKTReader *reader = GEOSWKTReader_create();
433 GEOSWKTReader_destroy( reader );
436 return fromGeosGeom( GEOSGeomFromWKT( wkt.toLocal8Bit().data() ) );
463 QVector<GEOSGeometry *> geoms;
467 for (
int i = 0; i < multipoint.size(); ++i )
476 for (
int i = 0; i < geoms.size(); ++i )
477 GEOSGeom_destroy( geoms[i] );
485 QVector<GEOSGeometry *> geoms;
489 for (
int i = 0; i < multiline.count(); i++ )
498 for (
int i = 0; i < geoms.count(); i++ )
499 GEOSGeom_destroy( geoms[i] );
507 if ( multipoly.count() == 0 )
510 QVector<GEOSGeometry *> geoms;
514 for (
int i = 0; i < multipoly.count(); i++ )
523 for (
int i = 0; i < geoms.count(); i++ )
524 GEOSGeom_destroy( geoms[i] );
540 polygon.append( ring );
561 GEOSGeom_destroy(
mGeos );
588 GEOSGeom_destroy(
mGeos );
690 GEOSGeom_destroy(
mGeos );
728 bool hasZValue =
false;
739 actdist = point.
sqrDist( x, y );
755 wkbPtr +=
sizeof( double );
757 double dist = point.
sqrDist( x, y );
758 if ( dist < actdist )
764 beforeVertex =
index - 1;
765 afterVertex =
index == nPoints - 1 ? -1 :
index + 1;
781 for (
int index2 = 0; index2 < nPoints; ++index2 )
786 wkbPtr +=
sizeof( double );
788 double dist = point.
sqrDist( x, y );
789 if ( dist < actdist )
793 vertexnr = pointIndex;
798 beforeVertex = pointIndex + ( nPoints - 2 );
799 afterVertex = pointIndex + 1;
801 else if ( index2 == nPoints - 1 )
803 beforeVertex = pointIndex - 1;
804 afterVertex = pointIndex - ( nPoints - 2 );
808 beforeVertex = pointIndex - 1;
809 afterVertex = pointIndex + 1;
826 wkbPtr += 1 +
sizeof( int );
831 wkbPtr +=
sizeof( double );
833 double dist = point.
sqrDist( x, y );
834 if ( dist < actdist )
852 wkbPtr += 1 +
sizeof( int );
856 for (
int index2 = 0; index2 < nPoints; ++index2 )
861 wkbPtr +=
sizeof( double );
863 double dist = point.
sqrDist( x, y );
864 if ( dist < actdist )
868 vertexnr = pointIndex;
873 beforeVertex = vertexnr - 1;
875 if ( index2 == nPoints - 1 )
878 afterVertex = vertexnr + 1;
895 wkbPtr += 1 +
sizeof( int );
898 for (
int index2 = 0; index2 < nRings; ++index2 )
902 for (
int index3 = 0; index3 < nPoints; ++index3 )
907 wkbPtr +=
sizeof( double );
909 double dist = point.
sqrDist( x, y );
910 if ( dist < actdist )
914 vertexnr = pointIndex;
919 beforeVertex = pointIndex + ( nPoints - 2 );
920 afterVertex = pointIndex + 1;
922 else if ( index3 == nPoints - 1 )
924 beforeVertex = pointIndex - 1;
925 afterVertex = pointIndex - ( nPoints - 2 );
929 beforeVertex = pointIndex - 1;
930 afterVertex = pointIndex + 1;
968 bool hasZValue =
false;
986 if ( atVertex >= nPoints )
989 const int index = atVertex;
993 beforeVertex = index - 1;
995 if ( index == nPoints - 1 )
998 afterVertex = index + 1;
1010 for (
int index0 = 0, pointIndex = 0; index0 < nRings; ++index0 )
1014 for (
int index1 = 0; index1 < nPoints; ++index1 )
1016 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1018 if ( pointIndex == atVertex )
1022 beforeVertex = pointIndex + ( nPoints - 2 );
1023 afterVertex = pointIndex + 1;
1025 else if ( index1 == nPoints - 1 )
1027 beforeVertex = pointIndex - 1;
1028 afterVertex = pointIndex - ( nPoints - 2 );
1032 beforeVertex = pointIndex - 1;
1033 afterVertex = pointIndex + 1;
1056 for (
int index0 = 0, pointIndex = 0; index0 < nLines; ++index0 )
1058 wkbPtr += 1 +
sizeof( int );
1063 for (
int index1 = 0; index1 < nPoints; ++index1 )
1065 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1067 if ( pointIndex == atVertex )
1073 beforeVertex = pointIndex - 1;
1075 if ( index1 == nPoints - 1 )
1078 afterVertex = pointIndex + 1;
1094 for (
int index0 = 0, pointIndex = 0; index0 < nPolys; ++index0 )
1096 wkbPtr += 1 +
sizeof( int );
1100 for (
int index1 = 0; index1 < nRings; ++index1 )
1104 for (
int index2 = 0; index2 < nPoints; ++index2 )
1106 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1108 if ( pointIndex == atVertex )
1115 beforeVertex = pointIndex + ( nPoints - 2 );
1116 afterVertex = pointIndex + 1;
1118 else if ( index2 == nPoints - 1 )
1120 beforeVertex = pointIndex - 1;
1121 afterVertex = pointIndex - ( nPoints - 2 );
1125 beforeVertex = pointIndex - 1;
1126 afterVertex = pointIndex + 1;
1144 const GEOSCoordSequence *old_sequence,
1145 GEOSCoordSequence **new_sequence )
1148 if ( beforeVertex < 0 )
1154 unsigned int numPoints;
1155 GEOSCoordSeq_getSize( old_sequence, &numPoints );
1157 *new_sequence = GEOSCoordSeq_create( numPoints + 1, 2 );
1158 if ( !*new_sequence )
1161 bool inserted =
false;
1162 for (
unsigned int i = 0, j = 0; i < numPoints; i++, j++ )
1165 if ( beforeVertex == static_cast<int>( i ) )
1167 GEOSCoordSeq_setX( *new_sequence, j, x );
1168 GEOSCoordSeq_setY( *new_sequence, j, y );
1174 GEOSCoordSeq_getX( old_sequence, i, &aX );
1175 GEOSCoordSeq_getY( old_sequence, i, &aY );
1177 GEOSCoordSeq_setX( *new_sequence, j, aX );
1178 GEOSCoordSeq_setY( *new_sequence, j, aY );
1185 GEOSCoordSeq_setX( *new_sequence, numPoints, x );
1186 GEOSCoordSeq_setY( *new_sequence, numPoints, y );
1199 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1202 if ( atVertex >= pointIndex + nPoints )
1204 wkbPtr += ps * nPoints;
1205 pointIndex += nPoints;
1209 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1210 atVertex = pointIndex;
1213 wkbPtr += ps * ( atVertex - pointIndex );
1218 if ( isRing && atVertex == pointIndex )
1220 wkbPtr += ps * ( nPoints - 2 );
1244 bool hasZValue =
false;
1254 if ( atVertex != 0 )
1267 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1283 if ( atVertex < nPoints )
1285 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1305 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1307 wkbPtr += 1 +
sizeof( int );
1308 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1325 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1327 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1341 wkbPtr >> nPolygons;
1342 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
1344 wkbPtr += 1 +
sizeof( int );
1349 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1351 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1380 QgsDebugMsg( QString(
"atVertex:%1 hasZValue:%2 pointIndex:%3 isRing:%4" ).arg( atVertex ).arg( hasZValue ).arg( pointIndex ).arg( isRing ) );
1381 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1386 if ( atVertex < pointIndex || atVertex >= pointIndex + nPoints )
1389 if ( lastItem && atVertex >= pointIndex + nPoints )
1394 int len = nPoints * ps;
1395 memcpy( dstPtr, srcPtr, len );
1398 pointIndex += nPoints;
1403 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1404 atVertex = pointIndex;
1406 if ( nPoints == ( isRing ? 2 : 1 ) )
1410 srcPtr += nPoints * ps;
1411 pointIndex += nPoints;
1415 dstPtr << nPoints - 1;
1418 int len = ( atVertex - pointIndex ) * ps;
1421 memcpy( dstPtr, srcPtr, len );
1430 len = ( pointIndex + nPoints - atVertex - 1 ) * ps;
1433 const unsigned char *first = 0;
1434 if ( isRing && atVertex == pointIndex )
1442 memcpy( dstPtr, srcPtr, len );
1450 memcpy( dstPtr, first, ps );
1455 pointIndex += nPoints;
1462 QgsDebugMsg( QString(
"atVertex:%1" ).arg( atVertex ) );
1478 srcPtr >> endianness >>
wkbType;
1482 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1484 ps += 1 +
sizeof(
int );
1486 unsigned char *dstBuffer =
new unsigned char[
mGeometrySize - ps];
1488 dstPtr << endianness <<
wkbType;
1490 bool deleted =
false;
1501 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false,
true );
1520 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1522 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, ringnr == nRings - 1 );
1526 deleted |= res != 0;
1538 if ( atVertex < nPoints )
1540 dstPtr << nPoints - 1;
1542 int len = ps * atVertex;
1545 memcpy( dstPtr, srcPtr, len );
1552 len = ps * ( nPoints - atVertex - 1 );
1555 memcpy( dstPtr, srcPtr, len );
1574 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1577 srcPtr >> endianness >>
wkbType;
1578 dstPtr << endianness <<
wkbType;
1580 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false, linenr == nLines - 1 );
1585 dstPtr = saveDstPtr;
1588 deleted |= res != 0;
1602 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1605 srcPtr >> endianness >> wkbType >> nRings;
1607 dstPtr << endianness <<
wkbType;
1611 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1613 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, polynr == nPolys - 1 && ringnr == nRings - 1 );
1620 ptrNPolys << nPolys - 1;
1621 dstPtr = saveDstPolyPtr;
1625 ptrNRings << nRings - 1;
1629 deleted |= res != 0;
1650 delete [] dstBuffer;
1660 bool insertHere = beforeVertex >= pointIndex && beforeVertex < pointIndex + nPoints;
1665 dstPtr << nPoints + 1;
1666 len = ( hasZValue ? 3 : 2 ) * ( beforeVertex - pointIndex ) *
sizeof( double );
1669 memcpy( dstPtr, srcPtr, len );
1678 len = ( hasZValue ? 3 : 2 ) * ( pointIndex + nPoints - beforeVertex ) *
sizeof( double );
1679 if ( isRing && beforeVertex == pointIndex )
1680 len -= ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1685 len = ( hasZValue ? 3 : 2 ) * nPoints *
sizeof(
double );
1688 memcpy( dstPtr, srcPtr, len );
1692 if ( isRing && beforeVertex == pointIndex )
1699 pointIndex += nPoints;
1715 if ( beforeVertex < 0 )
1721 srcPtr >> endianness >>
wkbType;
1725 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1727 ps += 1 +
sizeof(
int );
1729 unsigned char *dstBuffer =
new unsigned char[
mGeometrySize + ps];
1731 dstPtr << endianness <<
wkbType;
1733 bool inserted =
false;
1744 inserted =
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1755 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1756 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1767 if ( beforeVertex <= nPoints )
1769 dstPtr << nPoints + 1;
1771 int len = ps * beforeVertex;
1774 memcpy( dstPtr, srcPtr, len );
1783 len = ps * ( nPoints - beforeVertex );
1785 memcpy( dstPtr, srcPtr, len );
1800 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1802 srcPtr >> endianness >>
wkbType;
1803 dstPtr << endianness <<
wkbType;
1804 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1816 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1819 srcPtr >> endianness >> wkbType >> nRings;
1820 dstPtr << endianness << wkbType << nRings;
1822 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1823 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1843 delete [] dstBuffer;
1866 bool hasZValue =
false;
1872 if ( atVertex != 0 )
1889 if ( atVertex >= nPoints )
1893 wkbPtr += atVertex * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1908 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1913 if ( atVertex >= pointIndex + nPoints )
1915 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1916 pointIndex += nPoints;
1920 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1938 if ( atVertex >= nPoints )
1941 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1955 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1957 wkbPtr += 1 +
sizeof( int );
1961 if ( atVertex >= pointIndex + nPoints )
1963 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1964 pointIndex += nPoints;
1968 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1984 wkbPtr >> nPolygons;
1986 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
1988 wkbPtr += 1 +
sizeof( int );
1992 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1997 if ( atVertex >= pointIndex + nPoints )
1999 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
2000 pointIndex += nPoints;
2004 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
2016 QgsDebugMsg(
"error: mGeometry type not recognized" );
2031 QgsDebugMsg(
"Exiting with std::numeric_limits<double>::max()." );
2044 int closestVertexIndex = 0;
2053 const GEOSGeometry *g = GEOSGetExteriorRing(
mGeos );
2057 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq( g );
2060 GEOSCoordSeq_getSize( sequence, &n );
2062 for (
unsigned int i = 0; i < n; i++ )
2065 GEOSCoordSeq_getX( sequence, i, &x );
2066 GEOSCoordSeq_getY( sequence, i, &y );
2068 double testDist = point.
sqrDist( x, y );
2069 if ( testDist < sqrDist )
2071 closestVertexIndex = i;
2076 atVertex = closestVertexIndex;
2114 int closestSegmentIndex = 0;
2115 bool hasZValue =
false;
2134 double prevx = 0.0, prevy = 0.0;
2137 double thisx, thisy;
2138 wkbPtr >> thisx >> thisy;
2140 wkbPtr +=
sizeof( double );
2144 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2145 if ( testdist < sqrDist )
2147 closestSegmentIndex =
index;
2149 minDistPoint = distPoint;
2160 afterVertex = closestSegmentIndex;
2170 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
2172 wkbPtr += 1 +
sizeof( int );
2176 double prevx = 0.0, prevy = 0.0;
2177 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2179 double thisx, thisy;
2180 wkbPtr >> thisx >> thisy;
2182 wkbPtr +=
sizeof( double );
2186 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2187 if ( testdist < sqrDist )
2189 closestSegmentIndex = pointIndex;
2191 minDistPoint = distPoint;
2204 afterVertex = closestSegmentIndex;
2215 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
2220 double prevx = 0.0, prevy = 0.0;
2221 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2223 double thisx, thisy;
2224 wkbPtr >> thisx >> thisy;
2226 wkbPtr +=
sizeof( double );
2230 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2231 if ( testdist < sqrDist )
2233 closestSegmentIndex = pointIndex;
2235 minDistPoint = distPoint;
2248 afterVertex = closestSegmentIndex;
2257 wkbPtr >> nPolygons;
2258 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
2260 wkbPtr += 1 +
sizeof( int );
2263 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
2268 double prevx = 0.0, prevy = 0.0;
2269 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2271 double thisx, thisy;
2272 wkbPtr >> thisx >> thisy;
2274 wkbPtr +=
sizeof( double );
2278 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2279 if ( testdist < sqrDist )
2281 closestSegmentIndex = pointIndex;
2283 minDistPoint = distPoint;
2297 afterVertex = closestSegmentIndex;
2307 QgsDebugMsg( QString(
"Exiting with nearest point %1, dist %2." )
2308 .arg( point.
toString() ).arg( sqrDist ) );
2320 if ( ring.size() < 4 )
2324 if ( ring.first() != ring.last() )
2338 int type = GEOSGeomTypeId(
mGeos );
2341 QVector<const GEOSGeometry*> polygonList;
2345 if ( type != GEOS_POLYGON )
2348 polygonList <<
mGeos;
2352 if ( type != GEOS_MULTIPOLYGON )
2355 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); ++i )
2356 polygonList << GEOSGetGeometryN(
mGeos, i );
2360 GEOSGeometry *newRing = 0;
2361 GEOSGeometry *newRingPolygon = 0;
2366 if ( !GEOSisValid( newRing ) )
2372 if ( !GEOSisValid( newRingPolygon ) )
2381 if ( newRingPolygon )
2382 GEOSGeom_destroy( newRingPolygon );
2384 GEOSGeom_destroy( newRing );
2389 QVector<GEOSGeometry*> rings;
2392 for ( i = 0; i < polygonList.size(); i++ )
2394 for (
int j = 0; j < rings.size(); j++ )
2395 GEOSGeom_destroy( rings[j] );
2398 GEOSGeometry *shellRing = 0;
2399 GEOSGeometry *shell = 0;
2402 shellRing = GEOSGeom_clone( GEOSGetExteriorRing( polygonList[i] ) );
2405 if ( !GEOSWithin( newRingPolygon, shell ) )
2407 GEOSGeom_destroy( shell );
2416 GEOSGeom_destroy( shell );
2417 else if ( shellRing )
2418 GEOSGeom_destroy( shellRing );
2420 GEOSGeom_destroy( newRingPolygon );
2426 rings << GEOSGeom_clone( shellRing );
2428 GEOSGeom_destroy( shell );
2431 int n = GEOSGetNumInteriorRings( polygonList[i] );
2434 for ( j = 0; j < n; j++ )
2436 GEOSGeometry *holeRing = 0;
2437 GEOSGeometry *hole = 0;
2440 holeRing = GEOSGeom_clone( GEOSGetInteriorRingN( polygonList[i], j ) );
2443 if ( !GEOSDisjoint( hole, newRingPolygon ) )
2445 GEOSGeom_destroy( hole );
2454 GEOSGeom_destroy( hole );
2455 else if ( holeRing )
2456 GEOSGeom_destroy( holeRing );
2461 rings << GEOSGeom_clone( holeRing );
2462 GEOSGeom_destroy( hole );
2470 if ( i == polygonList.size() )
2473 for (
int j = 0; j < rings.size(); j++ )
2474 GEOSGeom_destroy( rings[j] );
2477 GEOSGeom_destroy( newRingPolygon );
2483 rings << GEOSGeom_clone( newRing );
2484 GEOSGeom_destroy( newRingPolygon );
2490 GEOSGeom_destroy(
mGeos );
2495 QVector<GEOSGeometry*> newPolygons;
2497 for (
int j = 0; j < polygonList.size(); j++ )
2499 newPolygons << ( i == j ? newPolygon : GEOSGeom_clone( polygonList[j] ) );
2502 GEOSGeom_destroy(
mGeos );
2522 if ( points.size() != 1 )
2524 QgsDebugMsg(
"expected 1 point: " + QString::number( points.size() ) );
2531 if ( points.size() < 2 )
2533 QgsDebugMsg(
"line must at least have two points: " + QString::number( points.size() ) );
2540 if ( points.size() < 4 )
2542 QgsDebugMsg(
"polygon must at least have three distinct points and must be closed: " + QString::number( points.size() ) );
2547 if ( points.first() != points.last() )
2555 QgsDebugMsg(
"unsupported geometry type: " + QString::number( geomType ) );
2559 GEOSGeometry *newPart = 0;
2574 GEOSGeometry *newRing = 0;
2579 if ( !GEOSisValid( newRing ) )
2589 GEOSGeom_destroy( newRing );
2614 const GEOSGeometry * geosPart = newPart->
asGeos();
2615 return addPart( GEOSGeom_clone( geosPart ) );
2640 int geosType = GEOSGeomTypeId(
mGeos );
2642 Q_ASSERT( newPart );
2646 if ( !GEOSisValid( newPart ) )
2654 GEOSGeom_destroy( newPart );
2660 QVector<GEOSGeometry*> parts;
2663 int n = GEOSGetNumGeometries(
mGeos );
2665 for ( i = 0; i < n; ++i )
2667 const GEOSGeometry *partN = GEOSGetGeometryN(
mGeos, i );
2669 if ( geomType ==
QGis::Polygon && GEOSOverlaps( partN, newPart ) )
2673 parts << GEOSGeom_clone( partN );
2679 for (
int i = 0; i < parts.size(); i++ )
2680 GEOSGeom_destroy( parts[i] );
2686 int nPartGeoms = GEOSGetNumGeometries( newPart );
2687 for (
int i = 0; i < nPartGeoms; ++i )
2689 parts << GEOSGeom_clone( GEOSGetGeometryN( newPart, i ) );
2691 GEOSGeom_destroy( newPart );
2693 GEOSGeom_destroy(
mGeos );
2718 bool hasZValue =
false;
2750 for (
int index2 = 0; index2 < nPoints; ++index2 )
2766 wkbPtr += 1 +
sizeof( int );
2780 wkbPtr += 1 +
sizeof( int );
2783 for (
int index2 = 0; index2 < nPoints; ++index2 )
2797 wkbPtr += 1 +
sizeof( int );
2802 for (
int index2 = 0; index2 < nRings; ++index2 )
2806 for (
int index3 = 0; index3 < nPoints; ++index3 )
2831 bool hasZValue =
false;
2867 for (
int index2 = 0; index2 < nPoints; ++index2 )
2882 wkbPtr += 1 +
sizeof( int );
2896 wkbPtr += 1 +
sizeof( int );
2899 for (
int index2 = 0; index2 < nPoints; ++index2 )
2914 wkbPtr += 1 +
sizeof( int );
2917 for (
int index2 = 0; index2 < nRings; ++index2 )
2921 for (
int index3 = 0; index3 < nPoints; ++index3 )
2935 int QgsGeometry::splitGeometry(
const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries,
bool topological, QList<QgsPoint> &topologyTestPoints )
2955 if ( !GEOSisValid(
mGeos ) )
2963 newGeometries.clear();
2967 GEOSGeometry* splitLineGeos;
2968 if ( splitLine.size() > 1 )
2972 else if ( splitLine.size() == 1 )
2980 if ( !GEOSisValid( splitLineGeos ) || !GEOSisSimple( splitLineGeos ) )
2982 GEOSGeom_destroy( splitLineGeos );
2997 GEOSGeom_destroy( splitLineGeos );
3002 GEOSGeom_destroy( splitLineGeos );
3017 if ( reshapeWithLine.size() < 2 )
3033 int numGeoms = GEOSGetNumGeometries(
mGeos );
3034 if ( numGeoms == -1 )
3037 bool isMultiGeom =
false;
3038 int geosTypeId = GEOSGeomTypeId(
mGeos );
3039 if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
3047 GEOSGeometry* reshapedGeometry;
3053 GEOSGeom_destroy( reshapeLineGeos );
3054 if ( reshapedGeometry )
3056 GEOSGeom_destroy(
mGeos );
3057 mGeos = reshapedGeometry;
3069 bool reshapeTookPlace =
false;
3071 GEOSGeometry* currentReshapeGeometry = 0;
3072 GEOSGeometry** newGeoms =
new GEOSGeometry*[numGeoms];
3074 for (
int i = 0; i < numGeoms; ++i )
3077 currentReshapeGeometry =
reshapeLine( GEOSGetGeometryN(
mGeos, i ), reshapeLineGeos );
3081 if ( currentReshapeGeometry )
3083 newGeoms[i] = currentReshapeGeometry;
3084 reshapeTookPlace =
true;
3088 newGeoms[i] = GEOSGeom_clone( GEOSGetGeometryN(
mGeos, i ) );
3091 GEOSGeom_destroy( reshapeLineGeos );
3093 GEOSGeometry* newMultiGeom = 0;
3096 newMultiGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, newGeoms, numGeoms );
3100 newMultiGeom = GEOSGeom_createCollection( GEOS_MULTIPOLYGON, newGeoms, numGeoms );
3104 if ( !newMultiGeom )
3107 if ( reshapeTookPlace )
3109 GEOSGeom_destroy(
mGeos );
3110 mGeos = newMultiGeom;
3116 GEOSGeom_destroy( newMultiGeom );
3134 if ( !GEOSisValid(
mGeos ) )
3137 if ( !GEOSisSimple(
mGeos ) )
3144 if ( !other->
mGeos )
3200 bool hasZValue =
false;
3235 for (
int idx = 0; idx < nPoints; idx++ )
3237 wkbPtr += 1 +
sizeof( int );
3242 wkbPtr +=
sizeof( double );
3266 for (
int idx = 0; idx < nPoints; idx++ )
3271 wkbPtr +=
sizeof( double );
3294 for (
int jdx = 0; jdx < nLines; jdx++ )
3297 wkbPtr += 1 +
sizeof( int );
3300 for (
int idx = 0; idx < nPoints; idx++ )
3305 wkbPtr +=
sizeof( double );
3330 for (
int idx = 0; idx < nRings; idx++ )
3335 for (
int jdx = 0; jdx < nPoints; jdx++ )
3341 wkbPtr +=
sizeof( double );
3365 wkbPtr >> nPolygons;
3366 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3370 wkbPtr += 1 +
sizeof( int );
3373 for (
int idx = 0; idx < nRings; idx++ )
3378 for (
int jdx = 0; jdx < nPoints; jdx++ )
3384 wkbPtr +=
sizeof( double );
3405 QgsDebugMsg( QString(
"Unknown WkbType %1 ENCOUNTERED" ).arg( wkbType ) );
3438 return GEOSIntersects(
mGeos, geometry->
mGeos );
3459 GEOSGeometry *geosPoint = 0;
3461 bool returnval =
false;
3466 returnval = GEOSContains(
mGeos, geosPoint );
3475 GEOSGeom_destroy( geosPoint );
3481 char( *op )(
const GEOSGeometry*,
const GEOSGeometry * ),
3506 return geosRelOp( GEOSContains,
this, geometry );
3511 return geosRelOp( GEOSDisjoint,
this, geometry );
3516 return geosRelOp( GEOSEquals,
this, geometry );
3521 return geosRelOp( GEOSTouches,
this, geometry );
3526 return geosRelOp( GEOSOverlaps,
this, geometry );
3531 return geosRelOp( GEOSWithin,
this, geometry );
3536 return geosRelOp( GEOSCrosses,
this, geometry );
3551 QgsDebugMsg(
"WKB geometry not available or too short!" );
3552 return QString::null;
3555 bool hasZValue =
false;
3580 wkt +=
"LINESTRING(";
3582 for (
int idx = 0; idx < nPoints; ++idx )
3587 wkbPtr +=
sizeof( double );
3609 for (
int idx = 0; idx < nRings; idx++ )
3619 for (
int jdx = 0; jdx < nPoints; jdx++ )
3627 wkbPtr +=
sizeof( double );
3644 wkt +=
"MULTIPOINT(";
3645 for (
int idx = 0; idx < nPoints; ++idx )
3647 wkbPtr += 1 +
sizeof( int );
3654 wkbPtr +=
sizeof( double );
3669 wkt +=
"MULTILINESTRING(";
3670 for (
int jdx = 0; jdx < nLines; jdx++ )
3676 wkbPtr += 1 +
sizeof( int );
3679 for (
int idx = 0; idx < nPoints; idx++ )
3687 wkbPtr +=
sizeof( double );
3702 wkbPtr >> nPolygons;
3704 wkt +=
"MULTIPOLYGON(";
3705 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3711 wkbPtr += 1 +
sizeof( int );
3714 for (
int idx = 0; idx < nRings; idx++ )
3722 for (
int jdx = 0; jdx < nPoints; jdx++ )
3730 wkbPtr +=
sizeof( double );
3743 QgsDebugMsg(
"error: mGeometry type not recognized" );
3744 return QString::null;
3759 return QString::null;
3765 bool hasZValue =
false;
3778 wkt +=
"{ \"type\": \"Point\", \"coordinates\": ["
3790 wkt +=
"{ \"type\": \"LineString\", \"coordinates\": [ ";
3794 for (
int idx = 0; idx < nPoints; ++idx )
3802 wkbPtr +=
sizeof( double );
3815 wkt +=
"{ \"type\": \"Polygon\", \"coordinates\": [ ";
3822 for (
int idx = 0; idx < nRings; idx++ )
3832 for (
int jdx = 0; jdx < nPoints; jdx++ )
3840 wkbPtr +=
sizeof( double );
3854 wkt +=
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ";
3857 for (
int idx = 0; idx < nPoints; ++idx )
3859 wkbPtr += 1 +
sizeof( int );
3866 wkbPtr +=
sizeof( double );
3878 wkt +=
"{ \"type\": \"MultiLineString\", \"coordinates\": [ ";
3882 for (
int jdx = 0; jdx < nLines; jdx++ )
3888 wkbPtr += 1 +
sizeof( int );
3892 for (
int idx = 0; idx < nPoints; idx++ )
3900 wkbPtr +=
sizeof( double );
3915 wkt +=
"{ \"type\": \"MultiPolygon\", \"coordinates\": [ ";
3918 wkbPtr >> nPolygons;
3919 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3926 wkbPtr += 1 +
sizeof( int );
3930 for (
int idx = 0; idx < nRings; idx++ )
3939 for (
int jdx = 0; jdx < nPoints; jdx++ )
3947 wkbPtr +=
sizeof( double );
3960 QgsDebugMsg(
"error: mGeometry type not recognized" );
3961 return QString::null;
3977 GEOSGeom_destroy(
mGeos );
3989 bool hasZValue =
false;
4013 QVector<GEOSGeometry *> points;
4017 for (
int idx = 0; idx < nPoints; idx++ )
4020 wkbPtr += 1 +
sizeof( int );
4023 wkbPtr +=
sizeof( double );
4040 for (
int idx = 0; idx < nPoints; idx++ )
4045 wkbPtr +=
sizeof( double );
4058 QVector<GEOSGeometry*> lines;
4061 for (
int jdx = 0; jdx < nLines; jdx++ )
4066 wkbPtr += 1 +
sizeof( int );
4069 for (
int idx = 0; idx < nPoints; idx++ )
4074 wkbPtr +=
sizeof( double );
4080 if ( sequence.count() > 1 )
4096 QVector<GEOSGeometry*> rings;
4098 for (
int idx = 0; idx < nRings; idx++ )
4107 for (
int jdx = 0; jdx < nPoints; jdx++ )
4113 wkbPtr +=
sizeof( double );
4129 QVector<GEOSGeometry*> polygons;
4133 wkbPtr >> nPolygons;
4135 for (
int kdx = 0; kdx < nPolygons; kdx++ )
4138 QVector<GEOSGeometry*> rings;
4142 wkbPtr += 1 +
sizeof( int );
4145 for (
int idx = 0; idx < numRings; idx++ )
4154 for (
int jdx = 0; jdx < nPoints; jdx++ )
4160 wkbPtr +=
sizeof( double );
4210 switch ( GEOSGeomTypeId(
mGeos ) )
4216 2 *
sizeof(
double );
4220 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(
mGeos );
4223 GEOSCoordSeq_getX( cs, 0, &x );
4224 GEOSCoordSeq_getY( cs, 0, &y );
4233 case GEOS_LINESTRING:
4237 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(
mGeos );
4238 unsigned int nPoints;
4239 GEOSCoordSeq_getSize( cs, &nPoints );
4245 ((
sizeof( double ) +
4246 sizeof(
double ) ) * nPoints );
4253 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq(
mGeos );
4256 for (
unsigned int n = 0; n < nPoints; n++ )
4259 GEOSCoordSeq_getX( sequence, n, &x );
4260 GEOSCoordSeq_getY( sequence, n, &y );
4270 case GEOS_LINEARRING:
4278 int nPointsInRing = 0;
4281 int geometrySize = 1 + 2 *
sizeof( int );
4282 const GEOSGeometry *theRing = GEOSGetExteriorRing(
mGeos );
4285 geometrySize +=
sizeof( int );
4288 for (
int i = 0; i < GEOSGetNumInteriorRings(
mGeos ); ++i )
4290 geometrySize +=
sizeof( int );
4291 theRing = GEOSGetInteriorRingN(
mGeos, i );
4298 mGeometry =
new unsigned char[geometrySize];
4304 int nRings = GEOSGetNumInteriorRings(
mGeos ) + 1;
4308 theRing = GEOSGetExteriorRing(
mGeos );
4313 wkbPtr << nPointsInRing;
4315 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4317 GEOSCoordSeq_getSize( cs, &n );
4319 for (
unsigned int j = 0; j < n; ++j )
4322 GEOSCoordSeq_getX( cs, j, &x );
4323 GEOSCoordSeq_getY( cs, j, &y );
4329 for (
int i = 0; i < GEOSGetNumInteriorRings(
mGeos ); i++ )
4331 theRing = GEOSGetInteriorRingN(
mGeos, i );
4333 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4335 unsigned int nPointsInRing;
4336 GEOSCoordSeq_getSize( cs, &nPointsInRing );
4337 wkbPtr << nPointsInRing;
4339 for (
unsigned int j = 0; j < nPointsInRing; j++ )
4342 GEOSCoordSeq_getX( cs, j, &x );
4343 GEOSCoordSeq_getY( cs, j, &y );
4352 case GEOS_MULTIPOINT:
4355 int geometrySize = 1 + 2 *
sizeof( int );
4356 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4358 geometrySize += 1 +
sizeof( int ) + 2 *
sizeof(
double );
4361 mGeometry =
new unsigned char[geometrySize];
4365 int numPoints = GEOSGetNumGeometries(
mGeos );
4369 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4374 const GEOSGeometry *currentPoint = GEOSGetGeometryN(
mGeos, i );
4376 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( currentPoint );
4379 GEOSCoordSeq_getX( cs, 0, &x );
4380 GEOSCoordSeq_getY( cs, 0, &y );
4387 case GEOS_MULTILINESTRING:
4390 int geometrySize = 1 + 2 *
sizeof( int );
4391 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4393 geometrySize += 1 + 2 *
sizeof( int );
4397 mGeometry =
new unsigned char[geometrySize];
4402 int numLines = GEOSGetNumGeometries(
mGeos );
4406 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4411 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( GEOSGetGeometryN(
mGeos, i ) );
4414 unsigned int lineSize;
4415 GEOSCoordSeq_getSize( cs, &lineSize );
4419 for (
unsigned int j = 0; j < lineSize; ++j )
4422 GEOSCoordSeq_getX( cs, j, &x );
4423 GEOSCoordSeq_getY( cs, j, &y );
4431 case GEOS_MULTIPOLYGON:
4434 int geometrySize = 1 + 2 *
sizeof( int );
4435 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4437 const GEOSGeometry *thePoly = GEOSGetGeometryN(
mGeos, i );
4438 geometrySize += 1 + 2 *
sizeof( int );
4440 geometrySize +=
sizeof( int );
4441 const GEOSGeometry *exRing = GEOSGetExteriorRing( thePoly );
4444 const GEOSGeometry *intRing = 0;
4445 for (
int j = 0; j < GEOSGetNumInteriorRings( thePoly ); j++ )
4447 geometrySize +=
sizeof( int );
4448 intRing = GEOSGetInteriorRingN( thePoly, j );
4453 mGeometry =
new unsigned char[geometrySize];
4457 int numPolygons = GEOSGetNumGeometries(
mGeos );
4461 for (
int i = 0; i < GEOSGetNumGeometries(
mGeos ); i++ )
4463 const GEOSGeometry *thePoly = GEOSGetGeometryN(
mGeos, i );
4464 int numRings = GEOSGetNumInteriorRings( thePoly ) + 1;
4467 const GEOSGeometry *theRing = GEOSGetExteriorRing( thePoly );
4472 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4474 for (
int k = 0; k < nPointsInRing; ++k )
4477 GEOSCoordSeq_getX( cs, k, &x );
4478 GEOSCoordSeq_getY( cs, k, &y );
4483 for (
int j = 0; j < GEOSGetNumInteriorRings( thePoly ); j++ )
4485 theRing = GEOSGetInteriorRingN( thePoly, j );
4488 wkbPtr << nPointsInRing;
4490 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( theRing );
4492 for (
int k = 0; k < nPointsInRing; ++k )
4495 GEOSCoordSeq_getX( cs, k, &x );
4496 GEOSCoordSeq_getY( cs, k, &y );
4505 case GEOS_GEOMETRYCOLLECTION:
4508 QgsDebugMsg(
"geometry collection - not supported" );
4558 unsigned char* newGeometry =
new unsigned char[newGeomSize];
4564 wkbPtr << byteOrder;
4590 delete [] newGeometry;
4594 wkbPtr << newMultiType << 1;
4608 double x, y, translated_x, translated_y;
4611 memcpy( &x, wkbPtr,
sizeof(
double ) );
4612 translated_x = x + dx;
4613 memcpy( wkbPtr, &translated_x,
sizeof(
double ) );
4614 wkbPtr +=
sizeof( double );
4617 memcpy( &y, wkbPtr,
sizeof(
double ) );
4618 translated_y = y + dy;
4619 memcpy( wkbPtr, &translated_y,
sizeof(
double ) );
4620 wkbPtr +=
sizeof( double );
4623 wkbPtr +=
sizeof( double );
4630 memcpy( &x, wkbPtr,
sizeof(
double ) );
4631 memcpy( &y, wkbPtr +
sizeof(
double ),
sizeof(
double ) );
4639 wkbPtr +=
sizeof( double );
4645 int type = GEOSGeomTypeId(
mGeos );
4648 if ( type == GEOS_MULTILINESTRING )
4650 else if ( type == GEOS_LINESTRING )
4662 for (
int i = 0; i < multiLine.size() ; ++i )
4664 line = multiLine[i];
4666 newline.append( line[0] );
4668 for (
int j = 1; j < line.size() - 1 ; ++j )
4670 newline.append( line[j] );
4671 if ( line[j] == splitPoint )
4673 lines.append( newline );
4675 newline.append( line[j] );
4678 newline.append( line.last() );
4679 lines.append( newline );
4682 GEOSGeometry* splitGeom = GEOSGeom_clone( splitLines->
asGeos() );
4700 if ( !GEOSIntersects( splitLine,
mGeos ) )
4704 int linearIntersect = GEOSRelatePattern(
mGeos, splitLine,
"1********" );
4705 if ( linearIntersect > 0 )
4708 int splitGeomType = GEOSGeomTypeId( splitLine );
4710 GEOSGeometry* splitGeom;
4711 if ( splitGeomType == GEOS_POINT )
4717 splitGeom = GEOSDifference(
mGeos, splitLine );
4719 QVector<GEOSGeometry*> lineGeoms;
4721 int splitType = GEOSGeomTypeId( splitGeom );
4722 if ( splitType == GEOS_MULTILINESTRING )
4724 int nGeoms = GEOSGetNumGeometries( splitGeom );
4725 for (
int i = 0; i < nGeoms; ++i )
4726 lineGeoms << GEOSGeom_clone( GEOSGetGeometryN( splitGeom, i ) );
4731 lineGeoms << GEOSGeom_clone( splitGeom );
4736 if ( lineGeoms.size() > 0 )
4738 GEOSGeom_destroy(
mGeos );
4739 mGeos = lineGeoms[0];
4743 for (
int i = 1; i < lineGeoms.size(); ++i )
4748 GEOSGeom_destroy( splitGeom );
4764 if ( !GEOSIntersects( splitLine,
mGeos ) )
4769 if ( !nodedGeometry )
4772 GEOSGeometry *polygons = GEOSPolygonize( &nodedGeometry, 1 );
4776 GEOSGeom_destroy( polygons );
4778 GEOSGeom_destroy( nodedGeometry );
4783 GEOSGeom_destroy( nodedGeometry );
4787 QVector<GEOSGeometry*> testedGeometries;
4788 GEOSGeometry *intersectGeometry = 0;
4795 const GEOSGeometry *polygon = GEOSGetGeometryN( polygons, i );
4796 intersectGeometry = GEOSIntersection(
mGeos, polygon );
4797 if ( !intersectGeometry )
4803 double intersectionArea;
4804 GEOSArea( intersectGeometry, &intersectionArea );
4807 GEOSArea( polygon, &polygonArea );
4809 const double areaRatio = intersectionArea / polygonArea;
4810 if ( areaRatio > 0.99 && areaRatio < 1.01 )
4811 testedGeometries << GEOSGeom_clone( polygon );
4813 GEOSGeom_destroy( intersectGeometry );
4816 bool splitDone =
true;
4818 if ( testedGeometries.size() == nGeometriesThis )
4828 for (
int i = 0; i < testedGeometries.size(); ++i )
4830 GEOSGeom_destroy( testedGeometries[i] );
4834 else if ( testedGeometries.size() > 0 )
4836 GEOSGeom_destroy(
mGeos );
4837 mGeos = testedGeometries[0];
4842 for ( i = 1; i < testedGeometries.size() && GEOSisValid( testedGeometries[i] ); ++i )
4845 if ( i < testedGeometries.size() )
4847 for ( i = 0; i < testedGeometries.size(); ++i )
4848 GEOSGeom_destroy( testedGeometries[i] );
4853 for ( i = 1; i < testedGeometries.size(); ++i )
4856 GEOSGeom_destroy( polygons );
4863 int nIntersections = 0;
4864 int lastIntersectingRing = -2;
4865 const GEOSGeometry* lastIntersectingGeom = 0;
4867 int nRings = GEOSGetNumInteriorRings( polygon );
4872 const GEOSGeometry* outerRing = GEOSGetExteriorRing( polygon );
4873 if ( GEOSIntersects( outerRing, reshapeLineGeos ) == 1 )
4876 lastIntersectingRing = -1;
4877 lastIntersectingGeom = outerRing;
4881 const GEOSGeometry **innerRings =
new const GEOSGeometry*[nRings];
4885 for (
int i = 0; i < nRings; ++i )
4887 innerRings[i] = GEOSGetInteriorRingN( polygon, i );
4888 if ( GEOSIntersects( innerRings[i], reshapeLineGeos ) == 1 )
4891 lastIntersectingRing = i;
4892 lastIntersectingGeom = innerRings[i];
4902 if ( nIntersections != 1 )
4904 delete [] innerRings;
4909 GEOSGeometry* reshapeResult =
reshapeLine( lastIntersectingGeom, reshapeLineGeos );
4910 if ( !reshapeResult )
4912 delete [] innerRings;
4917 GEOSGeometry* newRing = 0;
4918 const GEOSCoordSequence* reshapeSequence = GEOSGeom_getCoordSeq( reshapeResult );
4919 GEOSCoordSequence* newCoordSequence = GEOSCoordSeq_clone( reshapeSequence );
4921 GEOSGeom_destroy( reshapeResult );
4923 newRing = GEOSGeom_createLinearRing( newCoordSequence );
4926 delete [] innerRings;
4930 GEOSGeometry* newOuterRing = 0;
4931 if ( lastIntersectingRing == -1 )
4932 newOuterRing = newRing;
4934 newOuterRing = GEOSGeom_clone( outerRing );
4937 QList<GEOSGeometry*> ringList;
4940 GEOSGeometry* outerRingPoly = GEOSGeom_createPolygon( GEOSGeom_clone( newOuterRing ), 0, 0 );
4941 if ( outerRingPoly )
4943 GEOSGeometry* currentRing = 0;
4944 for (
int i = 0; i < nRings; ++i )
4946 if ( lastIntersectingRing == i )
4947 currentRing = newRing;
4949 currentRing = GEOSGeom_clone( innerRings[i] );
4952 if ( GEOSContains( outerRingPoly, currentRing ) == 1 )
4953 ringList.push_back( currentRing );
4955 GEOSGeom_destroy( currentRing );
4958 GEOSGeom_destroy( outerRingPoly );
4961 GEOSGeometry** newInnerRings =
new GEOSGeometry*[ringList.size()];
4962 for (
int i = 0; i < ringList.size(); ++i )
4963 newInnerRings[i] = ringList.at( i );
4965 delete [] innerRings;
4967 GEOSGeometry* reshapedPolygon = GEOSGeom_createPolygon( newOuterRing, newInnerRings, ringList.size() );
4968 delete[] newInnerRings;
4970 return reshapedPolygon;
4975 if ( !line || !reshapeLineGeos )
4978 bool atLeastTwoIntersections =
false;
4983 GEOSGeometry* intersectGeom = GEOSIntersection( line, reshapeLineGeos );
4984 if ( intersectGeom )
4986 atLeastTwoIntersections = ( GEOSGeomTypeId( intersectGeom ) == GEOS_MULTIPOINT && GEOSGetNumGeometries( intersectGeom ) > 1 );
4987 GEOSGeom_destroy( intersectGeom );
4993 atLeastTwoIntersections =
false;
4996 if ( !atLeastTwoIntersections )
5000 const GEOSCoordSequence* lineCoordSeq = GEOSGeom_getCoordSeq( line );
5001 if ( !lineCoordSeq )
5004 unsigned int lineCoordSeqSize;
5005 if ( GEOSCoordSeq_getSize( lineCoordSeq, &lineCoordSeqSize ) == 0 )
5008 if ( lineCoordSeqSize < 2 )
5012 double x1, y1, x2, y2;
5013 GEOSCoordSeq_getX( lineCoordSeq, 0, &x1 );
5014 GEOSCoordSeq_getY( lineCoordSeq, 0, &y1 );
5015 GEOSCoordSeq_getX( lineCoordSeq, lineCoordSeqSize - 1, &x2 );
5016 GEOSCoordSeq_getY( lineCoordSeq, lineCoordSeqSize - 1, &y2 );
5020 bool isRing =
false;
5021 if ( GEOSGeomTypeId( line ) == GEOS_LINEARRING || GEOSEquals( beginLineVertex, endLineVertex ) == 1 )
5025 GEOSGeometry* nodedGeometry =
nodeGeometries( reshapeLineGeos, line );
5026 if ( !nodedGeometry )
5028 GEOSGeom_destroy( beginLineVertex );
5029 GEOSGeom_destroy( endLineVertex );
5034 GEOSGeometry *mergedLines = GEOSLineMerge( nodedGeometry );
5035 GEOSGeom_destroy( nodedGeometry );
5038 GEOSGeom_destroy( beginLineVertex );
5039 GEOSGeom_destroy( endLineVertex );
5043 int numMergedLines = GEOSGetNumGeometries( mergedLines );
5044 if ( numMergedLines < 2 )
5046 GEOSGeom_destroy( beginLineVertex );
5047 GEOSGeom_destroy( endLineVertex );
5048 if ( numMergedLines == 1 )
5049 return GEOSGeom_clone( reshapeLineGeos );
5054 QList<GEOSGeometry*> resultLineParts;
5055 QList<GEOSGeometry*> probableParts;
5057 for (
int i = 0; i < numMergedLines; ++i )
5059 const GEOSGeometry* currentGeom;
5061 currentGeom = GEOSGetGeometryN( mergedLines, i );
5062 const GEOSCoordSequence* currentCoordSeq = GEOSGeom_getCoordSeq( currentGeom );
5063 unsigned int currentCoordSeqSize;
5064 GEOSCoordSeq_getSize( currentCoordSeq, ¤tCoordSeqSize );
5065 if ( currentCoordSeqSize < 2 )
5069 double xBegin, xEnd, yBegin, yEnd;
5070 GEOSCoordSeq_getX( currentCoordSeq, 0, &xBegin );
5071 GEOSCoordSeq_getY( currentCoordSeq, 0, &yBegin );
5072 GEOSCoordSeq_getX( currentCoordSeq, currentCoordSeqSize - 1, &xEnd );
5073 GEOSCoordSeq_getY( currentCoordSeq, currentCoordSeqSize - 1, &yEnd );
5078 int nEndpointsOnOriginalLine = 0;
5080 nEndpointsOnOriginalLine += 1;
5083 nEndpointsOnOriginalLine += 1;
5086 int nEndpointsSameAsOriginalLine = 0;
5087 if ( GEOSEquals( beginCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals( beginCurrentGeomVertex, endLineVertex ) == 1 )
5088 nEndpointsSameAsOriginalLine += 1;
5090 if ( GEOSEquals( endCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals( endCurrentGeomVertex, endLineVertex ) == 1 )
5091 nEndpointsSameAsOriginalLine += 1;
5094 bool currentGeomOverlapsOriginalGeom =
false;
5095 bool currentGeomOverlapsReshapeLine =
false;
5097 currentGeomOverlapsOriginalGeom =
true;
5100 currentGeomOverlapsReshapeLine =
true;
5103 if ( nEndpointsSameAsOriginalLine == 1 && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
5105 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
5108 else if ( isRing && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
5110 probableParts.push_back( GEOSGeom_clone( currentGeom ) );
5112 else if ( nEndpointsOnOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
5114 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
5116 else if ( nEndpointsSameAsOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
5118 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
5120 else if ( currentGeomOverlapsOriginalGeom && currentGeomOverlapsReshapeLine )
5122 resultLineParts.push_back( GEOSGeom_clone( currentGeom ) );
5125 GEOSGeom_destroy( beginCurrentGeomVertex );
5126 GEOSGeom_destroy( endCurrentGeomVertex );
5130 if ( isRing && probableParts.size() > 0 )
5132 GEOSGeometry* maxGeom = 0;
5133 GEOSGeometry* currentGeom = 0;
5134 double maxLength = -DBL_MAX;
5135 double currentLength = 0;
5136 for (
int i = 0; i < probableParts.size(); ++i )
5138 currentGeom = probableParts.at( i );
5139 GEOSLength( currentGeom, ¤tLength );
5140 if ( currentLength > maxLength )
5142 maxLength = currentLength;
5143 GEOSGeom_destroy( maxGeom );
5144 maxGeom = currentGeom;
5148 GEOSGeom_destroy( currentGeom );
5151 resultLineParts.push_back( maxGeom );
5154 GEOSGeom_destroy( beginLineVertex );
5155 GEOSGeom_destroy( endLineVertex );
5156 GEOSGeom_destroy( mergedLines );
5158 GEOSGeometry* result = 0;
5159 if ( resultLineParts.size() < 1 )
5162 if ( resultLineParts.size() == 1 )
5164 result = resultLineParts[0];
5168 GEOSGeometry **lineArray =
new GEOSGeometry*[resultLineParts.size()];
5169 for (
int i = 0; i < resultLineParts.size(); ++i )
5171 lineArray[i] = resultLineParts[i];
5175 GEOSGeometry* multiLineGeom = GEOSGeom_createCollection( GEOS_MULTILINESTRING, lineArray, resultLineParts.size() );
5176 delete [] lineArray;
5179 result = GEOSLineMerge( multiLineGeom );
5180 GEOSGeom_destroy( multiLineGeom );
5184 if ( GEOSGeomTypeId( result ) != GEOS_LINESTRING )
5186 GEOSGeom_destroy( result );
5200 GEOSGeometry* intersectionGeom = GEOSIntersection(
mGeos, splitLine );
5201 if ( !intersectionGeom )
5204 bool simple =
false;
5205 int nIntersectGeoms = 1;
5206 if ( GEOSGeomTypeId( intersectionGeom ) == GEOS_LINESTRING || GEOSGeomTypeId( intersectionGeom ) == GEOS_POINT )
5210 nIntersectGeoms = GEOSGetNumGeometries( intersectionGeom );
5212 for (
int i = 0; i < nIntersectGeoms; ++i )
5214 const GEOSGeometry* currentIntersectGeom;
5216 currentIntersectGeom = intersectionGeom;
5218 currentIntersectGeom = GEOSGetGeometryN( intersectionGeom, i );
5220 const GEOSCoordSequence* lineSequence = GEOSGeom_getCoordSeq( currentIntersectGeom );
5221 unsigned int sequenceSize = 0;
5223 if ( GEOSCoordSeq_getSize( lineSequence, &sequenceSize ) != 0 )
5225 for (
unsigned int i = 0; i < sequenceSize; ++i )
5227 if ( GEOSCoordSeq_getX( lineSequence, i, &x ) != 0 )
5229 if ( GEOSCoordSeq_getY( lineSequence, i, &y ) != 0 )
5231 testPoints.push_back(
QgsPoint( x, y ) );
5237 GEOSGeom_destroy( intersectionGeom );
5243 if ( !splitLine || !geom )
5246 GEOSGeometry *geometryBoundary = 0;
5247 if ( GEOSGeomTypeId( geom ) == GEOS_POLYGON || GEOSGeomTypeId( geom ) == GEOS_MULTIPOLYGON )
5248 geometryBoundary = GEOSBoundary( geom );
5250 geometryBoundary = GEOSGeom_clone( geom );
5252 GEOSGeometry *splitLineClone = GEOSGeom_clone( splitLine );
5253 GEOSGeometry *unionGeometry = GEOSUnion( splitLineClone, geometryBoundary );
5254 GEOSGeom_destroy( splitLineClone );
5256 GEOSGeom_destroy( geometryBoundary );
5257 return unionGeometry;
5262 if ( !line1 || !line2 )
5267 double bufferDistance = pow( 1.0L,
geomDigits( line2 ) - 11 );
5273 GEOSGeometry* intersectionGeom = GEOSIntersection( bufferGeom, line1 );
5276 double intersectGeomLength;
5279 GEOSLength( intersectionGeom, &intersectGeomLength );
5280 GEOSLength( line1, &line1Length );
5282 GEOSGeom_destroy( bufferGeom );
5283 GEOSGeom_destroy( intersectionGeom );
5285 double intersectRatio = line1Length / intersectGeomLength;
5286 if ( intersectRatio > 0.9 && intersectRatio < 1.1 )
5294 if ( !point || !line )
5297 double bufferDistance = pow( 1.0L,
geomDigits( line ) - 11 );
5299 GEOSGeometry* lineBuffer = GEOSBuffer( line, bufferDistance, 8 );
5303 bool contained =
false;
5304 if ( GEOSContains( lineBuffer, point ) == 1 )
5307 GEOSGeom_destroy( lineBuffer );
5313 GEOSGeometry* bbox = GEOSEnvelope( geom );
5317 const GEOSGeometry* bBoxRing = GEOSGetExteriorRing( bbox );
5321 const GEOSCoordSequence* bBoxCoordSeq = GEOSGeom_getCoordSeq( bBoxRing );
5323 if ( !bBoxCoordSeq )
5326 unsigned int nCoords = 0;
5327 if ( !GEOSCoordSeq_getSize( bBoxCoordSeq, &nCoords ) )
5331 for (
unsigned int i = 0; i < nCoords - 1; ++i )
5334 GEOSCoordSeq_getX( bBoxCoordSeq, i, &t );
5337 digits = ceil( log10( fabs( t ) ) );
5338 if ( digits > maxDigits )
5341 GEOSCoordSeq_getY( bBoxCoordSeq, i, &t );
5342 digits = ceil( log10( fabs( t ) ) );
5343 if ( digits > maxDigits )
5355 int geometryType = GEOSGeomTypeId( g );
5356 if ( geometryType == GEOS_POINT || geometryType == GEOS_LINESTRING || geometryType == GEOS_LINEARRING
5357 || geometryType == GEOS_POLYGON )
5361 return GEOSGetNumGeometries( g );
5373 int type = GEOSGeomTypeId(
mGeos );
5374 if ( type != GEOS_GEOMETRYCOLLECTION &&
5375 type != GEOS_MULTILINESTRING &&
5376 type != GEOS_MULTIPOLYGON &&
5377 type != GEOS_MULTIPOINT )
5380 QVector<GEOSGeometry*> copyList = splitResult;
5381 splitResult.clear();
5384 QVector<GEOSGeometry*> unionGeom;
5386 for (
int i = 0; i < copyList.size(); ++i )
5389 bool isPart =
false;
5390 for (
int j = 0; j < GEOSGetNumGeometries(
mGeos ); j++ )
5392 if ( GEOSEquals( copyList[i], GEOSGetGeometryN(
mGeos, j ) ) )
5401 unionGeom << copyList[i];
5405 QVector<GEOSGeometry*> geomVector;
5406 geomVector << copyList[i];
5408 if ( type == GEOS_MULTILINESTRING )
5410 else if ( type == GEOS_MULTIPOLYGON )
5413 GEOSGeom_destroy( copyList[i] );
5418 if ( unionGeom.size() > 0 )
5420 if ( type == GEOS_MULTILINESTRING )
5422 else if ( type == GEOS_MULTIPOLYGON )
5435 wkbPtr += 1 +
sizeof( int );
5440 wkbPtr +=
sizeof( double );
5447 wkbPtr += 1 +
sizeof( int );
5449 unsigned int nPoints;
5455 for ( uint i = 0; i < nPoints; ++i )
5460 wkbPtr +=
sizeof( double );
5470 wkbPtr += 1 +
sizeof( int );
5473 unsigned int numRings;
5476 if ( numRings == 0 )
5481 for ( uint idx = 0; idx < numRings; idx++ )
5488 for (
int jdx = 0; jdx < nPoints; jdx++ )
5493 wkbPtr +=
sizeof( double );
5548 for (
int i = 0; i < nPoints; i++ )
5550 points[i] =
asPoint( wkbPtr, hasZValue );
5567 wkbPtr >> numLineStrings;
5571 for (
int i = 0; i < numLineStrings; i++ )
5588 wkbPtr >> numPolygons;
5592 for (
int i = 0; i < numPolygons; i++ )
5593 polygons[i] =
asPolygon( wkbPtr, hasZValue );
5610 if ( GEOSArea(
mGeos, &area ) == 0 )
5630 if ( GEOSLength(
mGeos, &length ) == 0 )
5676 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
5677 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
5686 return fromGeosGeom( GEOSBufferWithStyle(
mGeos, distance, segments, endCapStyle, joinStyle, mitreLimit ) );
5696 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
5697 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)))
5706 return fromGeosGeom( GEOSOffsetCurve(
mGeos, distance, segments, joinStyle, mitreLimit ) );
5776 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \
5777 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2)))
5831 GEOSGeometry* unionGeom = GEOSUnion(
mGeos, geometry->
mGeos );
5837 GEOSGeometry* mergedGeom = GEOSLineMerge( unionGeom );
5840 GEOSGeom_destroy( unionGeom );
5841 unionGeom = mergedGeom;
5897 return QList<QgsGeometry*>();
5899 int type = GEOSGeomTypeId(
mGeos );
5900 QgsDebugMsg(
"geom type: " + QString::number( type ) );
5902 QList<QgsGeometry*> geomCollection;
5904 if ( type != GEOS_MULTIPOINT &&
5905 type != GEOS_MULTILINESTRING &&
5906 type != GEOS_MULTIPOLYGON &&
5907 type != GEOS_GEOMETRYCOLLECTION )
5910 geomCollection.append(
new QgsGeometry( *
this ) );
5911 return geomCollection;
5914 int count = GEOSGetNumGeometries(
mGeos );
5915 QgsDebugMsg(
"geom count: " + QString::number( count ) );
5917 for (
int i = 0; i < count; ++i )
5919 const GEOSGeometry * geometry = GEOSGetGeometryN(
mGeos, i );
5920 geomCollection.append(
fromGeosGeom( GEOSGeom_clone( geometry ) ) );
5923 return geomCollection;
5928 if ( ringNum <= 0 || partNum < 0 )
5940 if ( ringNum >= polygon.count() )
5943 polygon.remove( ringNum );
5956 if ( partNum >= mpolygon.count() )
5959 if ( ringNum >= mpolygon[partNum].count() )
5962 mpolygon[partNum].remove( ringNum );
5987 if ( partNum >= mpoint.size() || mpoint.size() == 1 )
5990 mpoint.remove( partNum );
6003 if ( partNum >= mline.size() || mline.size() == 1 )
6006 mline.remove( partNum );
6019 if ( partNum >= mpolygon.size() || mpolygon.size() == 1 )
6022 mpolygon.remove( partNum );
6042 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && (((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)) || (GEOS_VERSION_MAJOR>3))
6043 GEOSGeometry* geomCollection = 0;
6045 GEOSGeometry* geomUnion = GEOSUnaryUnion( geomCollection );
6046 GEOSGeom_destroy( geomCollection );
6049 GEOSGeometry* geomCollection = geoms.takeFirst();
6051 while ( !geoms.isEmpty() )
6053 GEOSGeometry* g = geoms.takeFirst();
6054 GEOSGeometry* geomCollectionNew = GEOSUnion( geomCollection, g );
6055 GEOSGeom_destroy( geomCollection );
6056 GEOSGeom_destroy( g );
6057 geomCollection = geomCollectionNew;
6060 return geomCollection;
6066 int returnValue = 0;
6080 QList<GEOSGeometry*> nearGeometries;
6084 QStringList::const_iterator aIt = avoidIntersectionsList.constBegin();
6085 for ( ; aIt != avoidIntersectionsList.constEnd(); ++aIt )
6091 QMap<QgsVectorLayer*, QSet<qint64> >::const_iterator ignoreIt = ignoreFeatures.find( currentLayer );
6092 if ( ignoreIt != ignoreFeatures.constEnd() )
6093 ignoreIds = ignoreIt.value();
6101 if ( ignoreIds.contains( f.
id() ) )
6112 if ( nearGeometries.isEmpty() )
6115 GEOSGeometry* nearGeometriesUnion = 0;
6116 GEOSGeometry* geomWithoutIntersections = 0;
6119 nearGeometriesUnion =
_makeUnion( nearGeometries );
6120 geomWithoutIntersections = GEOSDifference(
asGeos(), nearGeometriesUnion );
6122 fromGeos( geomWithoutIntersections );
6124 GEOSGeom_destroy( nearGeometriesUnion );
6128 if ( nearGeometriesUnion )
6129 GEOSGeom_destroy( nearGeometriesUnion );
6130 if ( geomWithoutIntersections )
6131 GEOSGeom_destroy( geomWithoutIntersections );
6138 if (
wkbType() != geomTypeBeforeModification )
6153 const GEOSGeometry *g =
asGeos();
6158 return GEOSisValid( g );
6169 return geosRelOp( GEOSEquals,
this, &g );
6176 const GEOSGeometry *g =
asGeos();
6181 return GEOSisEmpty( g );
6193 double f2 = y2 - y1;
6195 double f4 = x2 - x1;
6196 return f1*f2 - f3*f4;
6207 if (( destMultipart && srcIsMultipart ) ||
6208 ( !destMultipart && !srcIsMultipart ) )
6213 if ( destMultipart )
6222 if ( multiPoint.count() == 1 )
6233 if ( !destMultipart )
6241 for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt )
6242 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6243 multiPoint << *lineIt;
6250 if ( !line.isEmpty() )
6259 if ( !destMultipart )
6267 for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
6268 for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
6269 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6270 multiPoint << *lineIt;
6278 for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
6279 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6280 multiPoint << *lineIt;
6301 if ( multiPoint.count() < 2 )
6304 if ( destMultipart )
6314 if (( destMultipart && srcIsMultipart ) ||
6315 ( !destMultipart && ! srcIsMultipart ) )
6320 if ( destMultipart )
6324 if ( !line.isEmpty() )
6331 if ( multiLine.count() == 1 )
6344 for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
6345 for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
6346 multiLine << *multiLineIt;
6348 if ( destMultipart )
6353 else if ( multiLine.count() == 1 )
6364 if ( polygon.count() > 1 )
6368 if ( destMultipart )
6372 for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
6373 multiLine << *multiLineIt;
6378 else if ( polygon.count() == 1 )
6380 if ( destMultipart )
6408 if ( multiPoint.count() < 3 )
6411 if ( multiPoint.last() != multiPoint.first() )
6412 multiPoint << multiPoint.first();
6415 if ( destMultipart )
6428 for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt )
6431 if (( *multiLineIt ).count() < 3 )
6433 if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() )
6437 if (( *multiLineIt ).first() != ( *multiLineIt ).last() )
6438 *multiLineIt << ( *multiLineIt ).first();
6439 multiPolygon << (
QgsPolygon() << *multiLineIt );
6442 if ( !multiPolygon.isEmpty() )
6444 if ( destMultipart )
6448 else if ( multiPolygon.count() == 1 )
6461 if ( line.count() < 3 )
6463 if ( line.count() == 3 && line.first() == line.last() )
6467 if ( line.first() != line.last() )
6468 line << line.first();
6471 if ( destMultipart )
6487 if (( destMultipart && srcIsMultipart ) ||
6488 ( !destMultipart && ! srcIsMultipart ) )
6493 if ( destMultipart )
6497 if ( !polygon.isEmpty() )
6503 if ( multiPolygon.count() == 1 )
6519 QList<GEOSGeometry*> geoms;
6522 geoms.append( GEOSGeom_clone( g->
asGeos() ) );
6524 GEOSGeometry *geomUnion =
_makeUnion( geoms );
QgsFeatureId id() const
Get the feature id for this feature.
QgsGeometry * convertToLine(bool destMultipart)
try to convert the geometry to a line
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.
QgsGeometry * convertToType(QGis::GeometryType destType, bool destMultipart=false)
try to convert the geometry to the requested 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 ...
QgsGeometry * offsetCurve(double distance, int segments, int joinStyle, double mitreLimit)
Returns an offset line at a given distance and side from an input line.
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)
QgsGeometry * convertToPolygon(bool destMultipart)
try to convert the geometry to a polygon
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)
QgsGeometry * convertToPoint(bool destMultipart)
try to convert the geometry to a 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 ...
static int geomDigits(const GEOSGeometry *geom)
Determines the maximum number of digits before the dot.
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 GEOSGeometry * reshapeLine(const GEOSGeometry *origLine, const GEOSGeometry *reshapeLineGeos)
Creates a new line from an original line and a reshape line.
QgsGeometry * pointOnSurface()
Returns a point within a geometry.
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)
static QgsGeometry * unaryUnion(const QList< QgsGeometry * > &geometryList)
compute the unary union on a list of geometries.
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.
GEOSGeometry * linePointDifference(GEOSGeometry *GEOSsplitPoint)
Splits line/multiline geometries following a single point.
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