38 #include <netinet/in.h> 43 #define DEFAULT_QUADRANT_SEGMENTS 8 45 #define CATCH_GEOS(r) \ 46 catch (GEOSException &e) \ 48 QgsMessageLog::logMessage( QObject::tr( "Exception: %1" ).arg( e.what() ), QObject::tr("GEOS") ); \ 57 if ( theMsg ==
"Unknown exception thrown" && lastMsg.isNull() )
77 lastMsg = QString::null;
87 static QString lastMsg;
90 QString GEOSException::lastMsg;
98 vsnprintf( buffer,
sizeof buffer, fmt, ap );
101 qWarning() << QString(
"GEOS exception: %1" ).arg( buffer );
108 #if defined(QGISDEBUG) 113 vsnprintf( buffer,
sizeof buffer, fmt, ap );
116 QgsDebugMsg( QString(
"GEOS notice: %1" ).arg( QString::fromUtf8( buffer ) ) );
134 finishGEOS_r( ctxt );
142 return geosinit.
ctxt;
150 , mDirtyGeos( false )
156 , mGeometrySize( rhs.mGeometrySize )
157 , mDirtyWkb( rhs.mDirtyWkb )
158 , mDirtyGeos( rhs.mDirtyGeos )
160 if ( mGeometrySize && rhs.mGeometry )
162 mGeometry =
new unsigned char[mGeometrySize];
163 memcpy( mGeometry, rhs.mGeometry, mGeometrySize );
168 mGeos = GEOSGeom_clone_r( geosinit.
ctxt, rhs.mGeos );
181 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
188 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, geom );
189 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &n );
195 GEOSCoordSequence *coord = GEOSCoordSeq_create_r( geosinit.
ctxt, 1, 2 );
196 GEOSCoordSeq_setX_r( geosinit.
ctxt, coord, 0, x );
197 GEOSCoordSeq_setY_r( geosinit.
ctxt, coord, 0, y );
198 return GEOSGeom_createPoint_r( geosinit.
ctxt, coord );
208 GEOSCoordSequence *coord = 0;
212 coord = GEOSCoordSeq_create_r( geosinit.
ctxt, points.count(), 2 );
214 for ( i = 0; i < points.count(); i++ )
216 GEOSCoordSeq_setX_r( geosinit.
ctxt, coord, i, points[i].x() );
217 GEOSCoordSeq_setY_r( geosinit.
ctxt, coord, i, points[i].y() );
232 GEOSGeometry **geomarr =
new GEOSGeometry*[ geoms.size()];
236 for (
int i = 0; i < geoms.size(); i++ )
237 geomarr[i] = geoms[i];
239 GEOSGeometry *geom = 0;
243 geom = GEOSGeom_createCollection_r( geosinit.
ctxt, typeId, geomarr, geoms.size() );
257 GEOSCoordSequence *coord = 0;
262 return GEOSGeom_createLineString_r( geosinit.
ctxt, coord );
276 GEOSCoordSequence *coord = 0;
278 if ( polyline.count() <= 2 )
283 if ( polyline[0] != polyline[polyline.size()-1] )
294 if ( polyline.count() == 3 )
300 return GEOSGeom_createLinearRing_r( geosinit.
ctxt, coord );
316 if ( rings.size() == 0 )
318 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ 319 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) 320 return GEOSGeom_createEmptyPolygon_r( geosinit.
ctxt );
322 shell = GEOSGeom_createLinearRing_r( geosinit.
ctxt, GEOSCoordSeq_create_r( geosinit.
ctxt, 0, 2 ) );
330 GEOSGeometry **holes = NULL;
333 if ( rings.size() > 1 )
335 nHoles = rings.size() - 1;
336 holes =
new GEOSGeometry*[ nHoles ];
340 for (
int i = 0; i < nHoles; i++ )
341 holes[i] = rings[i+1];
344 GEOSGeometry *geom = GEOSGeom_createPolygon_r( geosinit.
ctxt, shell, holes, nHoles );
359 if ( polygon.count() == 0 )
362 QVector<GEOSGeometry *> geoms;
366 for (
int i = 0; i < polygon.count(); i++ )
372 for (
int j = 0; j < geoms.count(); j++ )
373 GEOSGeom_destroy_r( geosinit.
ctxt, geoms[j] );
386 for (
int i = 0; i < geoms.count(); i++ )
387 GEOSGeom_destroy_r( geosinit.
ctxt, geoms[i] );
406 GEOSWKTReader *reader = GEOSWKTReader_create_r( geosinit.
ctxt );
408 GEOSWKTReader_destroy_r( geosinit.
ctxt, reader );
435 QVector<GEOSGeometry *> geoms;
439 for (
int i = 0; i < multipoint.size(); ++i )
448 for (
int i = 0; i < geoms.size(); ++i )
449 GEOSGeom_destroy_r( geosinit.
ctxt, geoms[i] );
457 QVector<GEOSGeometry *> geoms;
461 for (
int i = 0; i < multiline.count(); i++ )
470 for (
int i = 0; i < geoms.count(); i++ )
471 GEOSGeom_destroy_r( geosinit.
ctxt, geoms[i] );
479 if ( multipoly.count() == 0 )
482 QVector<GEOSGeometry *> geoms;
486 for (
int i = 0; i < multipoly.count(); i++ )
495 for (
int i = 0; i < geoms.count(); i++ )
496 GEOSGeom_destroy_r( geosinit.
ctxt, geoms[i] );
512 polygon.append( ring );
524 if ( polygon.isClosed() )
534 QgsPolygon QgsGeometry::createPolygonFromQPolygonF(
const QPolygonF &polygon )
537 result << createPolylineFromQPolygonF( polygon );
541 QgsPolyline QgsGeometry::createPolylineFromQPolygonF(
const QPolygonF &polygon )
544 QPolygonF::const_iterator it = polygon.constBegin();
545 for ( ; it != polygon.constEnd(); ++it )
564 mGeometrySize = rhs.mGeometrySize;
567 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
568 mGeos = rhs.mGeos ? GEOSGeom_clone_r( geosinit.
ctxt, rhs.mGeos ) : 0;
570 mDirtyGeos = rhs.mDirtyGeos;
571 mDirtyWkb = rhs.mDirtyWkb;
573 if ( mGeometrySize && rhs.mGeometry )
575 mGeometry =
new unsigned char[mGeometrySize];
576 memcpy( mGeometry, rhs.mGeometry, mGeometrySize );
594 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
618 return mGeometrySize;
625 if ( !exportWkbToGeos() )
639 if ( mGeometry &&
wkbSize() >= 5 )
696 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
734 bool hasZValue =
false;
746 actdist = point.
sqrDist( x, y );
763 wkbPtr +=
sizeof( double );
765 double dist = point.
sqrDist( x, y );
766 if ( dist < actdist )
772 beforeVertex =
index - 1;
773 afterVertex =
index == nPoints - 1 ? -1 :
index + 1;
790 for (
int index2 = 0; index2 < nPoints; ++index2 )
795 wkbPtr +=
sizeof( double );
797 double dist = point.
sqrDist( x, y );
798 if ( dist < actdist )
802 vertexnr = pointIndex;
807 beforeVertex = pointIndex + ( nPoints - 2 );
808 afterVertex = pointIndex + 1;
810 else if ( index2 == nPoints - 1 )
812 beforeVertex = pointIndex - 1;
813 afterVertex = pointIndex - ( nPoints - 2 );
817 beforeVertex = pointIndex - 1;
818 afterVertex = pointIndex + 1;
836 wkbPtr += 1 +
sizeof( int );
841 wkbPtr +=
sizeof( double );
843 double dist = point.
sqrDist( x, y );
844 if ( dist < actdist )
863 wkbPtr += 1 +
sizeof( int );
867 for (
int index2 = 0; index2 < nPoints; ++index2 )
872 wkbPtr +=
sizeof( double );
874 double dist = point.
sqrDist( x, y );
875 if ( dist < actdist )
879 vertexnr = pointIndex;
884 beforeVertex = vertexnr - 1;
886 if ( index2 == nPoints - 1 )
889 afterVertex = vertexnr + 1;
907 wkbPtr += 1 +
sizeof( int );
910 for (
int index2 = 0; index2 < nRings; ++index2 )
914 for (
int index3 = 0; index3 < nPoints; ++index3 )
919 wkbPtr +=
sizeof( double );
921 double dist = point.
sqrDist( x, y );
922 if ( dist < actdist )
926 vertexnr = pointIndex;
931 beforeVertex = pointIndex + ( nPoints - 2 );
932 afterVertex = pointIndex + 1;
934 else if ( index3 == nPoints - 1 )
936 beforeVertex = pointIndex - 1;
937 afterVertex = pointIndex - ( nPoints - 2 );
941 beforeVertex = pointIndex - 1;
942 afterVertex = pointIndex + 1;
980 bool hasZValue =
false;
998 if ( atVertex >= nPoints )
1001 const int index = atVertex;
1005 beforeVertex = index - 1;
1007 if ( index == nPoints - 1 )
1010 afterVertex = index + 1;
1023 for (
int index0 = 0, pointIndex = 0; index0 < nRings; ++index0 )
1027 for (
int index1 = 0; index1 < nPoints; ++index1 )
1029 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1031 if ( pointIndex == atVertex )
1035 beforeVertex = pointIndex + ( nPoints - 2 );
1036 afterVertex = pointIndex + 1;
1038 else if ( index1 == nPoints - 1 )
1040 beforeVertex = pointIndex - 1;
1041 afterVertex = pointIndex - ( nPoints - 2 );
1045 beforeVertex = pointIndex - 1;
1046 afterVertex = pointIndex + 1;
1070 for (
int index0 = 0, pointIndex = 0; index0 < nLines; ++index0 )
1072 wkbPtr += 1 +
sizeof( int );
1077 for (
int index1 = 0; index1 < nPoints; ++index1 )
1079 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1081 if ( pointIndex == atVertex )
1087 beforeVertex = pointIndex - 1;
1089 if ( index1 == nPoints - 1 )
1092 afterVertex = pointIndex + 1;
1109 for (
int index0 = 0, pointIndex = 0; index0 < nPolys; ++index0 )
1111 wkbPtr += 1 +
sizeof( int );
1115 for (
int index1 = 0; index1 < nRings; ++index1 )
1119 for (
int index2 = 0; index2 < nPoints; ++index2 )
1121 wkbPtr += ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1123 if ( pointIndex == atVertex )
1130 beforeVertex = pointIndex + ( nPoints - 2 );
1131 afterVertex = pointIndex + 1;
1133 else if ( index2 == nPoints - 1 )
1135 beforeVertex = pointIndex - 1;
1136 afterVertex = pointIndex - ( nPoints - 2 );
1140 beforeVertex = pointIndex - 1;
1141 afterVertex = pointIndex + 1;
1159 const GEOSCoordSequence *old_sequence,
1160 GEOSCoordSequence **new_sequence )
1163 if ( beforeVertex < 0 )
1169 unsigned int numPoints;
1170 GEOSCoordSeq_getSize_r( geosinit.
ctxt, old_sequence, &numPoints );
1172 *new_sequence = GEOSCoordSeq_create_r( geosinit.
ctxt, numPoints + 1, 2 );
1173 if ( !*new_sequence )
1176 bool inserted =
false;
1177 for (
unsigned int i = 0, j = 0; i < numPoints; i++, j++ )
1180 if ( beforeVertex == static_cast<int>( i ) )
1182 GEOSCoordSeq_setX_r( geosinit.
ctxt, *new_sequence, j, x );
1183 GEOSCoordSeq_setY_r( geosinit.
ctxt, *new_sequence, j, y );
1189 GEOSCoordSeq_getX_r( geosinit.
ctxt, old_sequence, i, &aX );
1190 GEOSCoordSeq_getY_r( geosinit.
ctxt, old_sequence, i, &aY );
1192 GEOSCoordSeq_setX_r( geosinit.
ctxt, *new_sequence, j, aX );
1193 GEOSCoordSeq_setY_r( geosinit.
ctxt, *new_sequence, j, aY );
1200 GEOSCoordSeq_setX_r( geosinit.
ctxt, *new_sequence, numPoints, x );
1201 GEOSCoordSeq_setY_r( geosinit.
ctxt, *new_sequence, numPoints, y );
1214 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1217 if ( atVertex >= pointIndex + nPoints )
1219 wkbPtr += ps * nPoints;
1220 pointIndex += nPoints;
1224 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1225 atVertex = pointIndex;
1228 wkbPtr += ps * ( atVertex - pointIndex );
1233 if ( isRing && atVertex == pointIndex )
1235 wkbPtr += ps * ( nPoints - 2 );
1259 bool hasZValue =
false;
1270 if ( atVertex != 0 )
1284 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1301 if ( atVertex < nPoints )
1303 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1324 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1326 wkbPtr += 1 +
sizeof( int );
1327 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
false ) )
1345 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1347 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1362 wkbPtr >> nPolygons;
1363 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
1365 wkbPtr += 1 +
sizeof( int );
1370 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1372 if (
moveVertex( wkbPtr, x, y, atVertex, hasZValue, pointIndex,
true ) )
1401 QgsDebugMsg( QString(
"atVertex:%1 hasZValue:%2 pointIndex:%3 isRing:%4" ).arg( atVertex ).arg( hasZValue ).arg( pointIndex ).arg( isRing ) );
1402 const int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1407 if ( atVertex < pointIndex || atVertex >= pointIndex + nPoints )
1410 if ( lastItem && atVertex >= pointIndex + nPoints )
1415 int len = nPoints * ps;
1416 memcpy( dstPtr, srcPtr, len );
1419 pointIndex += nPoints;
1424 if ( isRing && atVertex == pointIndex + nPoints - 1 )
1425 atVertex = pointIndex;
1427 if ( nPoints == ( isRing ? 2 : 1 ) )
1431 srcPtr += nPoints * ps;
1432 pointIndex += nPoints;
1436 dstPtr << nPoints - 1;
1439 int len = ( atVertex - pointIndex ) * ps;
1442 memcpy( dstPtr, srcPtr, len );
1451 len = ( pointIndex + nPoints - atVertex - 1 ) * ps;
1454 const unsigned char *first = 0;
1455 if ( isRing && atVertex == pointIndex )
1463 memcpy( dstPtr, srcPtr, len );
1471 memcpy( dstPtr, first, ps );
1476 pointIndex += nPoints;
1483 QgsDebugMsg( QString(
"atVertex:%1" ).arg( atVertex ) );
1499 srcPtr >> endianness >>
wkbType;
1503 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1505 ps += 1 +
sizeof(
int );
1507 unsigned char *dstBuffer =
new unsigned char[mGeometrySize - ps];
1509 dstPtr << endianness <<
wkbType;
1511 bool deleted =
false;
1522 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false,
true );
1541 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1543 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, ringnr == nRings - 1 );
1547 deleted |= res != 0;
1559 if ( atVertex < nPoints )
1561 dstPtr << nPoints - 1;
1563 int len = ps * atVertex;
1566 memcpy( dstPtr, srcPtr, len );
1573 len = ps * ( nPoints - atVertex - 1 );
1576 memcpy( dstPtr, srcPtr, len );
1595 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1598 srcPtr >> endianness >>
wkbType;
1599 dstPtr << endianness <<
wkbType;
1601 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
false, linenr == nLines - 1 );
1606 dstPtr = saveDstPtr;
1609 deleted |= res != 0;
1623 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1626 srcPtr >> endianness >> wkbType >> nRings;
1628 dstPtr << endianness <<
wkbType;
1632 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1634 int res =
deleteVertex( srcPtr, dstPtr, atVertex, hasZValue, pointIndex,
true, polynr == nPolys - 1 && ringnr == nRings - 1 );
1641 ptrNPolys << nPolys - 1;
1642 dstPtr = saveDstPolyPtr;
1646 ptrNRings << nRings - 1;
1650 deleted |= res != 0;
1663 delete [] mGeometry;
1664 mGeometry = dstBuffer;
1665 mGeometrySize -= ps;
1671 delete [] dstBuffer;
1681 bool insertHere = beforeVertex >= pointIndex && beforeVertex < pointIndex + nPoints;
1686 dstPtr << nPoints + 1;
1687 len = ( hasZValue ? 3 : 2 ) * ( beforeVertex - pointIndex ) *
sizeof( double );
1690 memcpy( dstPtr, srcPtr, len );
1699 len = ( hasZValue ? 3 : 2 ) * ( pointIndex + nPoints - beforeVertex ) *
sizeof( double );
1700 if ( isRing && beforeVertex == pointIndex )
1701 len -= ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1706 len = ( hasZValue ? 3 : 2 ) * nPoints *
sizeof(
double );
1709 memcpy( dstPtr, srcPtr, len );
1713 if ( isRing && beforeVertex == pointIndex )
1720 pointIndex += nPoints;
1736 if ( beforeVertex < 0 )
1742 srcPtr >> endianness >>
wkbType;
1746 int ps = ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1748 ps += 1 +
sizeof(
int );
1750 unsigned char *dstBuffer =
new unsigned char[mGeometrySize + ps];
1752 dstPtr << endianness <<
wkbType;
1754 bool inserted =
false;
1765 inserted =
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1776 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1777 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1788 if ( beforeVertex <= nPoints )
1790 dstPtr << nPoints + 1;
1792 int len = ps * beforeVertex;
1795 memcpy( dstPtr, srcPtr, len );
1804 len = ps * ( nPoints - beforeVertex );
1806 memcpy( dstPtr, srcPtr, len );
1821 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1823 srcPtr >> endianness >>
wkbType;
1824 dstPtr << endianness <<
wkbType;
1825 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
false );
1837 for (
int polynr = 0, pointIndex = 0; polynr < nPolys; ++polynr )
1840 srcPtr >> endianness >> wkbType >> nRings;
1841 dstPtr << endianness << wkbType << nRings;
1843 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
1844 inserted |=
insertVertex( srcPtr, dstPtr, beforeVertex, x, y, hasZValue, pointIndex,
true );
1856 delete [] mGeometry;
1857 mGeometry = dstBuffer;
1858 mGeometrySize += ps;
1864 delete [] dstBuffer;
1887 bool hasZValue =
false;
1893 if ( atVertex != 0 )
1911 if ( atVertex >= nPoints )
1915 wkbPtr += atVertex * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1931 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
1936 if ( atVertex >= pointIndex + nPoints )
1938 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1939 pointIndex += nPoints;
1943 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
1962 if ( atVertex >= nPoints )
1965 wkbPtr += atVertex * ( 1 +
sizeof( int ) + ( hasZValue ? 3 : 2 ) *
sizeof( double ) ) + 1 +
sizeof( int );
1980 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
1982 wkbPtr += 1 +
sizeof( int );
1986 if ( atVertex >= pointIndex + nPoints )
1988 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
1989 pointIndex += nPoints;
1993 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
2010 wkbPtr >> nPolygons;
2012 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
2014 wkbPtr += 1 +
sizeof( int );
2018 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
2023 if ( atVertex >= pointIndex + nPoints )
2025 wkbPtr += nPoints * ( hasZValue ? 3 : 2 ) *
sizeof(
double );
2026 pointIndex += nPoints;
2030 wkbPtr += ( atVertex - pointIndex ) * ( hasZValue ? 3 : 2 ) *
sizeof( double );
2042 QgsDebugMsg(
"error: mGeometry type not recognized" );
2057 QgsDebugMsg(
"Exiting with std::numeric_limits<double>::max()." );
2070 int closestVertexIndex = 0;
2079 const GEOSGeometry *g = GEOSGetExteriorRing_r( geosinit.
ctxt, mGeos );
2083 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, g );
2086 GEOSCoordSeq_getSize_r( geosinit.
ctxt, sequence, &n );
2088 for (
unsigned int i = 0; i < n; i++ )
2091 GEOSCoordSeq_getX_r( geosinit.
ctxt, sequence, i, &x );
2092 GEOSCoordSeq_getY_r( geosinit.
ctxt, sequence, i, &y );
2094 double testDist = point.
sqrDist( x, y );
2095 if ( testDist < sqrDist )
2097 closestVertexIndex = i;
2102 atVertex = closestVertexIndex;
2140 int closestSegmentIndex = 0;
2141 bool hasZValue =
false;
2161 double prevx = 0.0, prevy = 0.0;
2164 double thisx, thisy;
2165 wkbPtr >> thisx >> thisy;
2167 wkbPtr +=
sizeof( double );
2171 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2172 if ( testdist < sqrDist )
2174 closestSegmentIndex =
index;
2176 minDistPoint = distPoint;
2179 *leftOf = QgsGeometry::leftOf( point.
x(), point.
y(), prevx, prevy, thisx, thisy );
2187 afterVertex = closestSegmentIndex;
2198 for (
int linenr = 0, pointIndex = 0; linenr < nLines; ++linenr )
2200 wkbPtr += 1 +
sizeof( int );
2204 double prevx = 0.0, prevy = 0.0;
2205 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2207 double thisx, thisy;
2208 wkbPtr >> thisx >> thisy;
2210 wkbPtr +=
sizeof( double );
2214 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2215 if ( testdist < sqrDist )
2217 closestSegmentIndex = pointIndex;
2219 minDistPoint = distPoint;
2222 *leftOf = QgsGeometry::leftOf( point.
x(), point.
y(), prevx, prevy, thisx, thisy );
2232 afterVertex = closestSegmentIndex;
2244 for (
int ringnr = 0, pointIndex = 0; ringnr < nRings; ++ringnr )
2249 double prevx = 0.0, prevy = 0.0;
2250 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2252 double thisx, thisy;
2253 wkbPtr >> thisx >> thisy;
2255 wkbPtr +=
sizeof( double );
2259 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2260 if ( testdist < sqrDist )
2262 closestSegmentIndex = pointIndex;
2264 minDistPoint = distPoint;
2267 *leftOf = QgsGeometry::leftOf( point.
x(), point.
y(), prevx, prevy, thisx, thisy );
2277 afterVertex = closestSegmentIndex;
2287 wkbPtr >> nPolygons;
2288 for (
int polynr = 0, pointIndex = 0; polynr < nPolygons; ++polynr )
2290 wkbPtr += 1 +
sizeof( int );
2293 for (
int ringnr = 0; ringnr < nRings; ++ringnr )
2298 double prevx = 0.0, prevy = 0.0;
2299 for (
int pointnr = 0; pointnr < nPoints; ++pointnr )
2301 double thisx, thisy;
2302 wkbPtr >> thisx >> thisy;
2304 wkbPtr +=
sizeof( double );
2308 double testdist = point.
sqrDistToSegment( prevx, prevy, thisx, thisy, distPoint, epsilon );
2309 if ( testdist < sqrDist )
2311 closestSegmentIndex = pointIndex;
2313 minDistPoint = distPoint;
2316 *leftOf = QgsGeometry::leftOf( point.
x(), point.
y(), prevx, prevy, thisx, thisy );
2327 afterVertex = closestSegmentIndex;
2338 .arg( point.
toString() ).arg( sqrDist ), 3 );
2350 if ( ring.size() < 4 )
2354 if ( ring.first() != ring.last() )
2368 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
2371 QVector<const GEOSGeometry*> polygonList;
2375 if ( type != GEOS_POLYGON )
2378 polygonList << mGeos;
2382 if ( type != GEOS_MULTIPOLYGON )
2385 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); ++i )
2386 polygonList << GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
2390 GEOSGeometry *newRing = 0;
2391 GEOSGeometry *newRingPolygon = 0;
2396 if ( !GEOSisValid_r( geosinit.
ctxt, newRing ) )
2402 if ( !GEOSisValid_r( geosinit.
ctxt, newRingPolygon ) )
2411 if ( newRingPolygon )
2412 GEOSGeom_destroy_r( geosinit.
ctxt, newRingPolygon );
2414 GEOSGeom_destroy_r( geosinit.
ctxt, newRing );
2419 QVector<GEOSGeometry*> rings;
2422 for ( i = 0; i < polygonList.size(); i++ )
2424 for (
int j = 0; j < rings.size(); j++ )
2425 GEOSGeom_destroy_r( geosinit.
ctxt, rings[j] );
2428 GEOSGeometry *shellRing = 0;
2429 GEOSGeometry *shell = 0;
2432 shellRing = GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetExteriorRing_r( geosinit.
ctxt, polygonList[i] ) );
2435 if ( !GEOSWithin_r( geosinit.
ctxt, newRingPolygon, shell ) )
2437 GEOSGeom_destroy_r( geosinit.
ctxt, shell );
2446 GEOSGeom_destroy_r( geosinit.
ctxt, shell );
2447 else if ( shellRing )
2448 GEOSGeom_destroy_r( geosinit.
ctxt, shellRing );
2450 GEOSGeom_destroy_r( geosinit.
ctxt, newRingPolygon );
2456 rings << GEOSGeom_clone_r( geosinit.
ctxt, shellRing );
2458 GEOSGeom_destroy_r( geosinit.
ctxt, shell );
2461 int n = GEOSGetNumInteriorRings_r( geosinit.
ctxt, polygonList[i] );
2464 for ( j = 0; j < n; j++ )
2466 GEOSGeometry *holeRing = 0;
2467 GEOSGeometry *hole = 0;
2470 holeRing = GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetInteriorRingN_r( geosinit.
ctxt, polygonList[i], j ) );
2473 if ( !GEOSDisjoint_r( geosinit.
ctxt, hole, newRingPolygon ) )
2475 GEOSGeom_destroy_r( geosinit.
ctxt, hole );
2484 GEOSGeom_destroy_r( geosinit.
ctxt, hole );
2485 else if ( holeRing )
2486 GEOSGeom_destroy_r( geosinit.
ctxt, holeRing );
2491 rings << GEOSGeom_clone_r( geosinit.
ctxt, holeRing );
2492 GEOSGeom_destroy_r( geosinit.
ctxt, hole );
2500 if ( i == polygonList.size() )
2503 for (
int j = 0; j < rings.size(); j++ )
2504 GEOSGeom_destroy_r( geosinit.
ctxt, rings[j] );
2507 GEOSGeom_destroy_r( geosinit.
ctxt, newRingPolygon );
2513 rings << GEOSGeom_clone_r( geosinit.
ctxt, newRing );
2514 GEOSGeom_destroy_r( geosinit.
ctxt, newRingPolygon );
2520 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
2525 QVector<GEOSGeometry*> newPolygons;
2527 for (
int j = 0; j < polygonList.size(); j++ )
2529 newPolygons << ( i == j ? newPolygon : GEOSGeom_clone_r( geosinit.
ctxt, polygonList[j] ) );
2532 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
2552 if ( points.size() != 1 )
2554 QgsDebugMsg(
"expected 1 point: " + QString::number( points.size() ) );
2561 if ( points.size() < 2 )
2563 QgsDebugMsg(
"line must at least have two points: " + QString::number( points.size() ) );
2570 if ( points.size() < 4 )
2572 QgsDebugMsg(
"polygon must at least have three distinct points and must be closed: " + QString::number( points.size() ) );
2577 if ( points.first() != points.last() )
2585 QgsDebugMsg(
"unsupported geometry type: " + QString::number( geomType ) );
2589 GEOSGeometry *newPart = 0;
2604 GEOSGeometry *newRing = 0;
2609 if ( !GEOSisValid_r( geosinit.
ctxt, newRing ) )
2619 GEOSGeom_destroy_r( geosinit.
ctxt, newRing );
2644 const GEOSGeometry * geosPart = newPart->
asGeos();
2645 return addPart( GEOSGeom_clone_r( geosinit.
ctxt, geosPart ) );
2670 int geosType = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
2672 Q_ASSERT( newPart );
2676 if ( !GEOSisValid_r( geosinit.
ctxt, newPart ) )
2684 GEOSGeom_destroy_r( geosinit.
ctxt, newPart );
2690 QVector<GEOSGeometry*> parts;
2693 int n = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
2695 for ( i = 0; i < n; ++i )
2697 const GEOSGeometry *partN = GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
2699 if ( geomType ==
QGis::Polygon && GEOSOverlaps_r( geosinit.
ctxt, partN, newPart ) )
2703 parts << GEOSGeom_clone_r( geosinit.
ctxt, partN );
2709 for (
int i = 0; i < parts.size(); i++ )
2710 GEOSGeom_destroy_r( geosinit.
ctxt, parts[i] );
2716 int nPartGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, newPart );
2717 for (
int i = 0; i < nPartGeoms; ++i )
2719 parts << GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, newPart, i ) );
2721 GEOSGeom_destroy_r( geosinit.
ctxt, newPart );
2723 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
2744 bool hasZValue =
false;
2754 transformVertex( wkbPtr, t, hasZValue );
2766 transformVertex( wkbPtr, t, hasZValue );
2782 for (
int index2 = 0; index2 < nPoints; ++index2 )
2783 transformVertex( wkbPtr, t, hasZValue );
2798 wkbPtr += 1 +
sizeof( int );
2799 transformVertex( wkbPtr, t, hasZValue );
2813 wkbPtr += 1 +
sizeof( int );
2816 for (
int index2 = 0; index2 < nPoints; ++index2 )
2817 transformVertex( wkbPtr, t, hasZValue );
2832 wkbPtr += 1 +
sizeof( int );
2835 for (
int index2 = 0; index2 < nRings; ++index2 )
2839 for (
int index3 = 0; index3 < nPoints; ++index3 )
2840 transformVertex( wkbPtr, t, hasZValue );
2855 return transform( QTransform::fromTranslate( dx, dy ) );
2860 QTransform t = QTransform::fromTranslate( center.
x(), center.
y() );
2861 t.rotate( -rotation );
2862 t.translate( -center.
x(), -center.
y() );
2877 bool hasZValue =
false;
2887 transformVertex( wkbPtr, ct, hasZValue );
2899 transformVertex( wkbPtr, ct, hasZValue );
2915 for (
int index2 = 0; index2 < nPoints; ++index2 )
2916 transformVertex( wkbPtr, ct, hasZValue );
2931 wkbPtr += 1 +
sizeof( int );
2932 transformVertex( wkbPtr, ct, hasZValue );
2946 wkbPtr += 1 +
sizeof( int );
2949 for (
int index2 = 0; index2 < nPoints; ++index2 )
2950 transformVertex( wkbPtr, ct, hasZValue );
2965 wkbPtr += 1 +
sizeof( int );
2968 for (
int index2 = 0; index2 < nRings; ++index2 )
2972 for (
int index3 = 0; index3 < nPoints; ++index3 )
2973 transformVertex( wkbPtr, ct, hasZValue );
2986 int QgsGeometry::splitGeometry(
const QList<QgsPoint>& splitLine, QList<QgsGeometry*>& newGeometries,
bool topological, QList<QgsPoint> &topologyTestPoints )
3006 if ( !GEOSisValid_r( geosinit.
ctxt, mGeos ) )
3014 newGeometries.clear();
3018 GEOSGeometry* splitLineGeos;
3019 if ( splitLine.size() > 1 )
3023 else if ( splitLine.size() == 1 )
3031 if ( !GEOSisValid_r( geosinit.
ctxt, splitLineGeos ) || !GEOSisSimple_r( geosinit.
ctxt, splitLineGeos ) )
3033 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
3040 if ( topologicalTestPointsSplit( splitLineGeos, topologyTestPoints ) != 0 )
3047 returnCode = splitLinearGeometry( splitLineGeos, newGeometries );
3048 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
3052 returnCode = splitPolygonGeometry( splitLineGeos, newGeometries );
3053 GEOSGeom_destroy_r( geosinit.
ctxt, splitLineGeos );
3068 if ( reshapeWithLine.size() < 2 )
3084 int numGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
3085 if ( numGeoms == -1 )
3088 bool isMultiGeom =
false;
3089 int geosTypeId = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
3090 if ( geosTypeId == GEOS_MULTILINESTRING || geosTypeId == GEOS_MULTIPOLYGON )
3098 GEOSGeometry* reshapedGeometry;
3100 reshapedGeometry = reshapeLine( mGeos, reshapeLineGeos );
3102 reshapedGeometry = reshapePolygon( mGeos, reshapeLineGeos );
3104 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeLineGeos );
3105 if ( reshapedGeometry )
3107 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
3108 mGeos = reshapedGeometry;
3120 bool reshapeTookPlace =
false;
3122 GEOSGeometry* currentReshapeGeometry = 0;
3123 GEOSGeometry** newGeoms =
new GEOSGeometry*[numGeoms];
3125 for (
int i = 0; i < numGeoms; ++i )
3128 currentReshapeGeometry = reshapeLine( GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ), reshapeLineGeos );
3130 currentReshapeGeometry = reshapePolygon( GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ), reshapeLineGeos );
3132 if ( currentReshapeGeometry )
3134 newGeoms[i] = currentReshapeGeometry;
3135 reshapeTookPlace =
true;
3139 newGeoms[i] = GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ) );
3142 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeLineGeos );
3144 GEOSGeometry* newMultiGeom = 0;
3147 newMultiGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTILINESTRING, newGeoms, numGeoms );
3151 newMultiGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTIPOLYGON, newGeoms, numGeoms );
3155 if ( !newMultiGeom )
3158 if ( reshapeTookPlace )
3160 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
3161 mGeos = newMultiGeom;
3167 GEOSGeom_destroy_r( geosinit.
ctxt, newMultiGeom );
3185 if ( !GEOSisValid_r( geosinit.
ctxt, mGeos ) )
3188 if ( !GEOSisSimple_r( geosinit.
ctxt, mGeos ) )
3192 if ( other->mDirtyGeos )
3193 other->exportWkbToGeos();
3195 if ( !other->mGeos )
3201 if ( GEOSIntersects_r( geosinit.
ctxt, mGeos, other->mGeos ) )
3206 mGeos = GEOSDifference_r( geosinit.
ctxt, mGeos, other->mGeos );
3251 bool hasZValue =
false;
3287 for (
int idx = 0; idx < nPoints; idx++ )
3289 wkbPtr += 1 +
sizeof( int );
3294 wkbPtr +=
sizeof( double );
3319 for (
int idx = 0; idx < nPoints; idx++ )
3324 wkbPtr +=
sizeof( double );
3348 for (
int jdx = 0; jdx < nLines; jdx++ )
3351 wkbPtr += 1 +
sizeof( int );
3354 for (
int idx = 0; idx < nPoints; idx++ )
3359 wkbPtr +=
sizeof( double );
3385 for (
int idx = 0; idx < nRings; idx++ )
3390 for (
int jdx = 0; jdx < nPoints; jdx++ )
3396 wkbPtr +=
sizeof( double );
3421 wkbPtr >> nPolygons;
3422 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3426 wkbPtr += 1 +
sizeof( int );
3429 for (
int idx = 0; idx < nRings; idx++ )
3434 for (
int jdx = 0; jdx < nPoints; jdx++ )
3440 wkbPtr +=
sizeof( double );
3461 QgsDebugMsg( QString(
"Unknown WkbType %1 ENCOUNTERED" ).arg( wkbType ) );
3486 geometry->exportWkbToGeos();
3488 if ( !mGeos || !geometry->mGeos )
3494 return GEOSIntersects_r( geosinit.
ctxt, mGeos, geometry->mGeos );
3515 GEOSGeometry *geosPoint = 0;
3517 bool returnval =
false;
3522 returnval = GEOSContains_r( geosinit.
ctxt, mGeos, geosPoint );
3531 GEOSGeom_destroy_r( geosinit.
ctxt, geosPoint );
3536 bool QgsGeometry::geosRelOp(
3537 char( *op )( GEOSContextHandle_t handle,
const GEOSGeometry*,
const GEOSGeometry * ),
3547 a->exportWkbToGeos();
3548 b->exportWkbToGeos();
3550 if ( !a->mGeos || !b->mGeos )
3555 return op( geosinit.
ctxt, a->mGeos, b->mGeos );
3562 return geosRelOp( GEOSContains_r,
this, geometry );
3567 return geosRelOp( GEOSDisjoint_r,
this, geometry );
3572 return geosRelOp( GEOSEquals_r,
this, geometry );
3577 return geosRelOp( GEOSTouches_r,
this, geometry );
3582 return geosRelOp( GEOSOverlaps_r,
this, geometry );
3587 return geosRelOp( GEOSWithin_r,
this, geometry );
3592 return geosRelOp( GEOSCrosses_r,
this, geometry );
3605 if ( !mGeometry ||
wkbSize() < 5 )
3607 QgsDebugMsg(
"WKB geometry not available or too short!" );
3608 return QString::null;
3611 bool hasZValue =
false;
3637 wkt +=
"LINESTRING(";
3639 for (
int idx = 0; idx < nPoints; ++idx )
3644 wkbPtr +=
sizeof( double );
3667 for (
int idx = 0; idx < nRings; idx++ )
3677 for (
int jdx = 0; jdx < nPoints; jdx++ )
3685 wkbPtr +=
sizeof( double );
3703 wkt +=
"MULTIPOINT(";
3704 for (
int idx = 0; idx < nPoints; ++idx )
3706 wkbPtr += 1 +
sizeof( int );
3713 wkbPtr +=
sizeof( double );
3729 wkt +=
"MULTILINESTRING(";
3730 for (
int jdx = 0; jdx < nLines; jdx++ )
3736 wkbPtr += 1 +
sizeof( int );
3739 for (
int idx = 0; idx < nPoints; idx++ )
3747 wkbPtr +=
sizeof( double );
3763 wkbPtr >> nPolygons;
3765 wkt +=
"MULTIPOLYGON(";
3766 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3772 wkbPtr += 1 +
sizeof( int );
3775 for (
int idx = 0; idx < nRings; idx++ )
3783 for (
int jdx = 0; jdx < nPoints; jdx++ )
3791 wkbPtr +=
sizeof( double );
3804 QgsDebugMsg(
"error: mGeometry type not recognized" );
3805 return QString::null;
3820 return QString::null;
3826 bool hasZValue =
false;
3839 wkt +=
"{ \"type\": \"Point\", \"coordinates\": [" 3852 wkt +=
"{ \"type\": \"LineString\", \"coordinates\": [ ";
3856 for (
int idx = 0; idx < nPoints; ++idx )
3864 wkbPtr +=
sizeof( double );
3878 wkt +=
"{ \"type\": \"Polygon\", \"coordinates\": [ ";
3885 for (
int idx = 0; idx < nRings; idx++ )
3895 for (
int jdx = 0; jdx < nPoints; jdx++ )
3903 wkbPtr +=
sizeof( double );
3918 wkt +=
"{ \"type\": \"MultiPoint\", \"coordinates\": [ ";
3921 for (
int idx = 0; idx < nPoints; ++idx )
3923 wkbPtr += 1 +
sizeof( int );
3930 wkbPtr +=
sizeof( double );
3943 wkt +=
"{ \"type\": \"MultiLineString\", \"coordinates\": [ ";
3947 for (
int jdx = 0; jdx < nLines; jdx++ )
3953 wkbPtr += 1 +
sizeof( int );
3957 for (
int idx = 0; idx < nPoints; idx++ )
3965 wkbPtr +=
sizeof( double );
3981 wkt +=
"{ \"type\": \"MultiPolygon\", \"coordinates\": [ ";
3984 wkbPtr >> nPolygons;
3985 for (
int kdx = 0; kdx < nPolygons; kdx++ )
3992 wkbPtr += 1 +
sizeof( int );
3996 for (
int idx = 0; idx < nRings; idx++ )
4005 for (
int jdx = 0; jdx < nPoints; jdx++ )
4013 wkbPtr +=
sizeof( double );
4026 QgsDebugMsg(
"error: mGeometry type not recognized" );
4027 return QString::null;
4031 bool QgsGeometry::exportWkbToGeos()
const 4043 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
4055 bool hasZValue =
false;
4080 QVector<GEOSGeometry *> points;
4084 for (
int idx = 0; idx < nPoints; idx++ )
4087 wkbPtr += 1 +
sizeof( int );
4090 wkbPtr +=
sizeof( double );
4108 for (
int idx = 0; idx < nPoints; idx++ )
4113 wkbPtr +=
sizeof( double );
4127 QVector<GEOSGeometry*> lines;
4130 for (
int jdx = 0; jdx < nLines; jdx++ )
4135 wkbPtr += 1 +
sizeof( int );
4138 for (
int idx = 0; idx < nPoints; idx++ )
4143 wkbPtr +=
sizeof( double );
4149 if ( sequence.count() > 1 )
4166 QVector<GEOSGeometry*> rings;
4168 for (
int idx = 0; idx < nRings; idx++ )
4177 for (
int jdx = 0; jdx < nPoints; jdx++ )
4183 wkbPtr +=
sizeof( double );
4189 if ( ring ) rings << ring;
4201 QVector<GEOSGeometry*> polygons;
4205 wkbPtr >> nPolygons;
4207 for (
int kdx = 0; kdx < nPolygons; kdx++ )
4210 QVector<GEOSGeometry*> rings;
4214 wkbPtr += 1 +
sizeof( int );
4217 for (
int idx = 0; idx < numRings; idx++ )
4226 for (
int jdx = 0; jdx < nPoints; jdx++ )
4232 wkbPtr +=
sizeof( double );
4238 if ( ring ) rings << ring;
4242 if ( polygon ) polygons << polygon;
4258 bool QgsGeometry::exportGeosToWkb()
const 4270 delete [] mGeometry;
4284 switch ( GEOSGeomTypeId_r( geosinit.
ctxt, mGeos ) )
4290 2 *
sizeof(
double );
4291 mGeometry =
new unsigned char[mGeometrySize];
4294 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, mGeos );
4297 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, 0, &x );
4298 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, 0, &y );
4307 case GEOS_LINESTRING:
4311 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, mGeos );
4312 unsigned int nPoints;
4313 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &nPoints );
4319 ((
sizeof( double ) +
4320 sizeof(
double ) ) * nPoints );
4322 mGeometry =
new unsigned char[mGeometrySize];
4327 const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, mGeos );
4330 for (
unsigned int n = 0; n < nPoints; n++ )
4333 GEOSCoordSeq_getX_r( geosinit.
ctxt, sequence, n, &x );
4334 GEOSCoordSeq_getY_r( geosinit.
ctxt, sequence, n, &y );
4344 case GEOS_LINEARRING:
4352 int nPointsInRing = 0;
4355 int geometrySize = 1 + 2 *
sizeof( int );
4356 const GEOSGeometry *theRing = GEOSGetExteriorRing_r( geosinit.
ctxt, mGeos );
4359 geometrySize +=
sizeof( int );
4362 for (
int i = 0; i < GEOSGetNumInteriorRings_r( geosinit.
ctxt, mGeos ); ++i )
4364 geometrySize +=
sizeof( int );
4365 theRing = GEOSGetInteriorRingN_r( geosinit.
ctxt, mGeos, i );
4372 mGeometry =
new unsigned char[geometrySize];
4373 mGeometrySize = geometrySize;
4378 int nRings = GEOSGetNumInteriorRings_r( geosinit.
ctxt, mGeos ) + 1;
4382 theRing = GEOSGetExteriorRing_r( geosinit.
ctxt, mGeos );
4387 wkbPtr << nPointsInRing;
4389 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, theRing );
4391 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &n );
4393 for (
unsigned int j = 0; j < n; ++j )
4396 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, j, &x );
4397 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, j, &y );
4403 for (
int i = 0; i < GEOSGetNumInteriorRings_r( geosinit.
ctxt, mGeos ); i++ )
4405 theRing = GEOSGetInteriorRingN_r( geosinit.
ctxt, mGeos, i );
4407 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, theRing );
4409 unsigned int nPointsInRing;
4410 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &nPointsInRing );
4411 wkbPtr << nPointsInRing;
4413 for (
unsigned int j = 0; j < nPointsInRing; j++ )
4416 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, j, &x );
4417 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, j, &y );
4426 case GEOS_MULTIPOINT:
4429 int geometrySize = 1 + 2 *
sizeof( int );
4430 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4432 geometrySize += 1 +
sizeof( int ) + 2 *
sizeof(
double );
4435 mGeometry =
new unsigned char[geometrySize];
4436 mGeometrySize = geometrySize;
4439 int numPoints = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
4443 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4448 const GEOSGeometry *currentPoint = GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
4450 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, currentPoint );
4453 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, 0, &x );
4454 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, 0, &y );
4461 case GEOS_MULTILINESTRING:
4464 int geometrySize = 1 + 2 *
sizeof( int );
4465 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4467 geometrySize += 1 + 2 *
sizeof( int );
4468 geometrySize +=
getNumGeosPoints( GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ) ) * 2 *
sizeof( double );
4471 mGeometry =
new unsigned char[geometrySize];
4472 mGeometrySize = geometrySize;
4476 int numLines = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
4480 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4485 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i ) );
4488 unsigned int lineSize;
4489 GEOSCoordSeq_getSize_r( geosinit.
ctxt, cs, &lineSize );
4493 for (
unsigned int j = 0; j < lineSize; ++j )
4496 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, j, &x );
4497 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, j, &y );
4505 case GEOS_MULTIPOLYGON:
4508 int geometrySize = 1 + 2 *
sizeof( int );
4509 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4511 const GEOSGeometry *thePoly = GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
4512 geometrySize += 1 + 2 *
sizeof( int );
4514 geometrySize +=
sizeof( int );
4515 const GEOSGeometry *exRing = GEOSGetExteriorRing_r( geosinit.
ctxt, thePoly );
4518 const GEOSGeometry *intRing = 0;
4519 for (
int j = 0; j < GEOSGetNumInteriorRings_r( geosinit.
ctxt, thePoly ); j++ )
4521 geometrySize +=
sizeof( int );
4522 intRing = GEOSGetInteriorRingN_r( geosinit.
ctxt, thePoly, j );
4527 mGeometry =
new unsigned char[geometrySize];
4528 mGeometrySize = geometrySize;
4531 int numPolygons = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
4535 for (
int i = 0; i < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); i++ )
4537 const GEOSGeometry *thePoly = GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
4538 int numRings = GEOSGetNumInteriorRings_r( geosinit.
ctxt, thePoly ) + 1;
4541 const GEOSGeometry *theRing = GEOSGetExteriorRing_r( geosinit.
ctxt, thePoly );
4546 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, theRing );
4548 for (
int k = 0; k < nPointsInRing; ++k )
4551 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, k, &x );
4552 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, k, &y );
4557 for (
int j = 0; j < GEOSGetNumInteriorRings_r( geosinit.
ctxt, thePoly ); j++ )
4559 theRing = GEOSGetInteriorRingN_r( geosinit.
ctxt, thePoly, j );
4562 wkbPtr << nPointsInRing;
4564 const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, theRing );
4566 for (
int k = 0; k < nPointsInRing; ++k )
4569 GEOSCoordSeq_getX_r( geosinit.
ctxt, cs, k, &x );
4570 GEOSCoordSeq_getY_r( geosinit.
ctxt, cs, k, &y );
4579 case GEOS_GEOMETRYCOLLECTION:
4582 QgsDebugMsg(
"geometry collection - not supported" );
4596 return convertToPoint( destMultipart );
4599 return convertToLine( destMultipart );
4602 return convertToPolygon( destMultipart );
4631 size_t newGeomSize = mGeometrySize + 1 + 2 *
sizeof( int );
4632 unsigned char* newGeometry =
new unsigned char[newGeomSize];
4638 wkbPtr << byteOrder;
4664 delete [] newGeometry;
4668 wkbPtr << newMultiType << 1;
4671 memcpy( wkbPtr, mGeometry, mGeometrySize );
4673 delete [] mGeometry;
4674 mGeometry = newGeometry;
4675 mGeometrySize = newGeomSize;
4680 void QgsGeometry::transformVertex(
QgsWkbPtr &wkbPtr,
const QTransform& trans,
bool hasZValue )
4682 qreal x, y, rotated_x, rotated_y;
4686 trans.map( x, y, &rotated_x, &rotated_y );
4687 wkbPtr << rotated_x << rotated_y;
4690 wkbPtr +=
sizeof( double );
4695 double x, y, z = 0.0;
4703 wkbPtr +=
sizeof( double );
4706 GEOSGeometry* QgsGeometry::linePointDifference( GEOSGeometry* GEOSsplitPoint )
4708 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
4711 if ( type == GEOS_MULTILINESTRING )
4713 else if ( type == GEOS_LINESTRING )
4728 for (
int i = 0; i < multiLine.size() ; ++i )
4730 line = multiLine[i];
4732 newline.append( line[0] );
4734 for (
int j = 1; j < line.size() - 1 ; ++j )
4736 newline.append( line[j] );
4737 if ( line[j] == splitPoint )
4739 lines.append( newline );
4741 newline.append( line[j] );
4744 newline.append( line.last() );
4745 lines.append( newline );
4748 GEOSGeometry* splitGeom = GEOSGeom_clone_r( geosinit.
ctxt, splitLines->
asGeos() );
4754 int QgsGeometry::splitLinearGeometry( GEOSGeometry *splitLine, QList<QgsGeometry*>& newGeometries )
4766 if ( !GEOSIntersects_r( geosinit.
ctxt, splitLine, mGeos ) )
4770 int linearIntersect = GEOSRelatePattern_r( geosinit.
ctxt, mGeos, splitLine,
"1********" );
4771 if ( linearIntersect > 0 )
4774 int splitGeomType = GEOSGeomTypeId_r( geosinit.
ctxt, splitLine );
4776 GEOSGeometry* splitGeom;
4777 if ( splitGeomType == GEOS_POINT )
4779 splitGeom = linePointDifference( splitLine );
4783 splitGeom = GEOSDifference_r( geosinit.
ctxt, mGeos, splitLine );
4785 QVector<GEOSGeometry*> lineGeoms;
4787 int splitType = GEOSGeomTypeId_r( geosinit.
ctxt, splitGeom );
4788 if ( splitType == GEOS_MULTILINESTRING )
4790 int nGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, splitGeom );
4791 for (
int i = 0; i < nGeoms; ++i )
4792 lineGeoms << GEOSGeom_clone_r( geosinit.
ctxt, GEOSGetGeometryN_r( geosinit.
ctxt, splitGeom, i ) );
4797 lineGeoms << GEOSGeom_clone_r( geosinit.
ctxt, splitGeom );
4800 mergeGeometriesMultiTypeSplit( lineGeoms );
4802 if ( lineGeoms.size() > 0 )
4807 for (
int i = 1; i < lineGeoms.size(); ++i )
4812 GEOSGeom_destroy_r( geosinit.
ctxt, splitGeom );
4816 int QgsGeometry::splitPolygonGeometry( GEOSGeometry* splitLine, QList<QgsGeometry*>& newGeometries )
4828 if ( !GEOSIntersects_r( geosinit.
ctxt, splitLine, mGeos ) )
4832 GEOSGeometry *nodedGeometry = nodeGeometries( splitLine, mGeos );
4833 if ( !nodedGeometry )
4836 GEOSGeometry *polygons = GEOSPolygonize_r( geosinit.
ctxt, &nodedGeometry, 1 );
4837 if ( !polygons || numberOfGeometries( polygons ) == 0 )
4840 GEOSGeom_destroy_r( geosinit.
ctxt, polygons );
4842 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
4847 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
4851 QVector<GEOSGeometry*> testedGeometries;
4852 GEOSGeometry *intersectGeometry = 0;
4857 for (
int i = 0; i < numberOfGeometries( polygons ); i++ )
4859 const GEOSGeometry *polygon = GEOSGetGeometryN_r( geosinit.
ctxt, polygons, i );
4860 intersectGeometry = GEOSIntersection_r( geosinit.
ctxt, mGeos, polygon );
4861 if ( !intersectGeometry )
4867 double intersectionArea;
4868 GEOSArea_r( geosinit.
ctxt, intersectGeometry, &intersectionArea );
4871 GEOSArea_r( geosinit.
ctxt, polygon, &polygonArea );
4873 const double areaRatio = intersectionArea / polygonArea;
4874 if ( areaRatio > 0.99 && areaRatio < 1.01 )
4875 testedGeometries << GEOSGeom_clone_r( geosinit.
ctxt, polygon );
4877 GEOSGeom_destroy_r( geosinit.
ctxt, intersectGeometry );
4880 bool splitDone =
true;
4881 int nGeometriesThis = numberOfGeometries( mGeos );
4882 if ( testedGeometries.size() == nGeometriesThis )
4887 mergeGeometriesMultiTypeSplit( testedGeometries );
4892 for (
int i = 0; i < testedGeometries.size(); ++i )
4894 GEOSGeom_destroy_r( geosinit.
ctxt, testedGeometries[i] );
4898 else if ( testedGeometries.size() > 0 )
4900 GEOSGeom_destroy_r( geosinit.
ctxt, mGeos );
4901 mGeos = testedGeometries[0];
4906 for ( i = 1; i < testedGeometries.size() && GEOSisValid_r( geosinit.
ctxt, testedGeometries[i] ); ++i )
4909 if ( i < testedGeometries.size() )
4911 for ( i = 0; i < testedGeometries.size(); ++i )
4912 GEOSGeom_destroy_r( geosinit.
ctxt, testedGeometries[i] );
4917 for ( i = 1; i < testedGeometries.size(); ++i )
4920 GEOSGeom_destroy_r( geosinit.
ctxt, polygons );
4924 GEOSGeometry* QgsGeometry::reshapePolygon(
const GEOSGeometry* polygon,
const GEOSGeometry* reshapeLineGeos )
4927 int nIntersections = 0;
4928 int lastIntersectingRing = -2;
4929 const GEOSGeometry* lastIntersectingGeom = 0;
4931 int nRings = GEOSGetNumInteriorRings_r( geosinit.
ctxt, polygon );
4936 const GEOSGeometry* outerRing = GEOSGetExteriorRing_r( geosinit.
ctxt, polygon );
4937 if ( GEOSIntersects_r( geosinit.
ctxt, outerRing, reshapeLineGeos ) == 1 )
4940 lastIntersectingRing = -1;
4941 lastIntersectingGeom = outerRing;
4945 const GEOSGeometry **innerRings =
new const GEOSGeometry*[nRings];
4949 for (
int i = 0; i < nRings; ++i )
4951 innerRings[i] = GEOSGetInteriorRingN_r( geosinit.
ctxt, polygon, i );
4952 if ( GEOSIntersects_r( geosinit.
ctxt, innerRings[i], reshapeLineGeos ) == 1 )
4955 lastIntersectingRing = i;
4956 lastIntersectingGeom = innerRings[i];
4966 if ( nIntersections != 1 )
4968 delete [] innerRings;
4973 GEOSGeometry* reshapeResult = reshapeLine( lastIntersectingGeom, reshapeLineGeos );
4974 if ( !reshapeResult )
4976 delete [] innerRings;
4981 GEOSGeometry* newRing = 0;
4982 const GEOSCoordSequence* reshapeSequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, reshapeResult );
4983 GEOSCoordSequence* newCoordSequence = GEOSCoordSeq_clone_r( geosinit.
ctxt, reshapeSequence );
4985 GEOSGeom_destroy_r( geosinit.
ctxt, reshapeResult );
4989 newRing = GEOSGeom_createLinearRing_r( geosinit.
ctxt, newCoordSequence );
4998 delete [] innerRings;
5002 GEOSGeometry* newOuterRing = 0;
5003 if ( lastIntersectingRing == -1 )
5004 newOuterRing = newRing;
5006 newOuterRing = GEOSGeom_clone_r( geosinit.
ctxt, outerRing );
5009 QList<GEOSGeometry*> ringList;
5012 GEOSGeometry* outerRingPoly = GEOSGeom_createPolygon_r( geosinit.
ctxt, GEOSGeom_clone_r( geosinit.
ctxt, newOuterRing ), 0, 0 );
5013 if ( outerRingPoly )
5015 GEOSGeometry* currentRing = 0;
5016 for (
int i = 0; i < nRings; ++i )
5018 if ( lastIntersectingRing == i )
5019 currentRing = newRing;
5021 currentRing = GEOSGeom_clone_r( geosinit.
ctxt, innerRings[i] );
5024 if ( GEOSContains_r( geosinit.
ctxt, outerRingPoly, currentRing ) == 1 )
5025 ringList.push_back( currentRing );
5027 GEOSGeom_destroy_r( geosinit.
ctxt, currentRing );
5030 GEOSGeom_destroy_r( geosinit.
ctxt, outerRingPoly );
5033 GEOSGeometry** newInnerRings =
new GEOSGeometry*[ringList.size()];
5034 for (
int i = 0; i < ringList.size(); ++i )
5035 newInnerRings[i] = ringList.at( i );
5037 delete [] innerRings;
5039 GEOSGeometry* reshapedPolygon = GEOSGeom_createPolygon_r( geosinit.
ctxt, newOuterRing, newInnerRings, ringList.size() );
5040 delete[] newInnerRings;
5042 return reshapedPolygon;
5045 GEOSGeometry* QgsGeometry::reshapeLine(
const GEOSGeometry* line,
const GEOSGeometry* reshapeLineGeos )
5047 if ( !line || !reshapeLineGeos )
5050 bool atLeastTwoIntersections =
false;
5055 GEOSGeometry* intersectGeom = GEOSIntersection_r( geosinit.
ctxt, line, reshapeLineGeos );
5056 if ( intersectGeom )
5058 atLeastTwoIntersections = ( GEOSGeomTypeId_r( geosinit.
ctxt, intersectGeom ) == GEOS_MULTIPOINT && GEOSGetNumGeometries_r( geosinit.
ctxt, intersectGeom ) > 1 );
5059 GEOSGeom_destroy_r( geosinit.
ctxt, intersectGeom );
5065 atLeastTwoIntersections =
false;
5068 if ( !atLeastTwoIntersections )
5072 const GEOSCoordSequence* lineCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, line );
5073 if ( !lineCoordSeq )
5076 unsigned int lineCoordSeqSize;
5077 if ( GEOSCoordSeq_getSize_r( geosinit.
ctxt, lineCoordSeq, &lineCoordSeqSize ) == 0 )
5080 if ( lineCoordSeqSize < 2 )
5084 double x1, y1, x2, y2;
5085 GEOSCoordSeq_getX_r( geosinit.
ctxt, lineCoordSeq, 0, &x1 );
5086 GEOSCoordSeq_getY_r( geosinit.
ctxt, lineCoordSeq, 0, &y1 );
5087 GEOSCoordSeq_getX_r( geosinit.
ctxt, lineCoordSeq, lineCoordSeqSize - 1, &x2 );
5088 GEOSCoordSeq_getY_r( geosinit.
ctxt, lineCoordSeq, lineCoordSeqSize - 1, &y2 );
5092 bool isRing =
false;
5093 if ( GEOSGeomTypeId_r( geosinit.
ctxt, line ) == GEOS_LINEARRING || GEOSEquals_r( geosinit.
ctxt, beginLineVertex, endLineVertex ) == 1 )
5097 GEOSGeometry* nodedGeometry = nodeGeometries( reshapeLineGeos, line );
5098 if ( !nodedGeometry )
5100 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
5101 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
5106 GEOSGeometry *mergedLines = GEOSLineMerge_r( geosinit.
ctxt, nodedGeometry );
5107 GEOSGeom_destroy_r( geosinit.
ctxt, nodedGeometry );
5110 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
5111 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
5115 int numMergedLines = GEOSGetNumGeometries_r( geosinit.
ctxt, mergedLines );
5116 if ( numMergedLines < 2 )
5118 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
5119 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
5120 if ( numMergedLines == 1 )
5121 return GEOSGeom_clone_r( geosinit.
ctxt, reshapeLineGeos );
5126 QList<GEOSGeometry*> resultLineParts;
5127 QList<GEOSGeometry*> probableParts;
5129 for (
int i = 0; i < numMergedLines; ++i )
5131 const GEOSGeometry* currentGeom;
5133 currentGeom = GEOSGetGeometryN_r( geosinit.
ctxt, mergedLines, i );
5134 const GEOSCoordSequence* currentCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, currentGeom );
5135 unsigned int currentCoordSeqSize;
5136 GEOSCoordSeq_getSize_r( geosinit.
ctxt, currentCoordSeq, ¤tCoordSeqSize );
5137 if ( currentCoordSeqSize < 2 )
5141 double xBegin, xEnd, yBegin, yEnd;
5142 GEOSCoordSeq_getX_r( geosinit.
ctxt, currentCoordSeq, 0, &xBegin );
5143 GEOSCoordSeq_getY_r( geosinit.
ctxt, currentCoordSeq, 0, &yBegin );
5144 GEOSCoordSeq_getX_r( geosinit.
ctxt, currentCoordSeq, currentCoordSeqSize - 1, &xEnd );
5145 GEOSCoordSeq_getY_r( geosinit.
ctxt, currentCoordSeq, currentCoordSeqSize - 1, &yEnd );
5150 int nEndpointsOnOriginalLine = 0;
5151 if ( pointContainedInLine( beginCurrentGeomVertex, line ) == 1 )
5152 nEndpointsOnOriginalLine += 1;
5154 if ( pointContainedInLine( endCurrentGeomVertex, line ) == 1 )
5155 nEndpointsOnOriginalLine += 1;
5158 int nEndpointsSameAsOriginalLine = 0;
5159 if ( GEOSEquals_r( geosinit.
ctxt, beginCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals_r( geosinit.
ctxt, beginCurrentGeomVertex, endLineVertex ) == 1 )
5160 nEndpointsSameAsOriginalLine += 1;
5162 if ( GEOSEquals_r( geosinit.
ctxt, endCurrentGeomVertex, beginLineVertex ) == 1 || GEOSEquals_r( geosinit.
ctxt, endCurrentGeomVertex, endLineVertex ) == 1 )
5163 nEndpointsSameAsOriginalLine += 1;
5166 bool currentGeomOverlapsOriginalGeom =
false;
5167 bool currentGeomOverlapsReshapeLine =
false;
5168 if ( QgsGeometry::lineContainedInLine( currentGeom, line ) == 1 )
5169 currentGeomOverlapsOriginalGeom =
true;
5171 if ( QgsGeometry::lineContainedInLine( currentGeom, reshapeLineGeos ) == 1 )
5172 currentGeomOverlapsReshapeLine =
true;
5175 if ( nEndpointsSameAsOriginalLine == 1 && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
5177 resultLineParts.push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
5180 else if ( isRing && nEndpointsOnOriginalLine == 2 && currentGeomOverlapsOriginalGeom )
5182 probableParts.push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
5184 else if ( nEndpointsOnOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
5186 resultLineParts.push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
5188 else if ( nEndpointsSameAsOriginalLine == 2 && !currentGeomOverlapsOriginalGeom )
5190 resultLineParts.push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
5192 else if ( currentGeomOverlapsOriginalGeom && currentGeomOverlapsReshapeLine )
5194 resultLineParts.push_back( GEOSGeom_clone_r( geosinit.
ctxt, currentGeom ) );
5197 GEOSGeom_destroy_r( geosinit.
ctxt, beginCurrentGeomVertex );
5198 GEOSGeom_destroy_r( geosinit.
ctxt, endCurrentGeomVertex );
5202 if ( isRing && probableParts.size() > 0 )
5204 GEOSGeometry* maxGeom = 0;
5205 GEOSGeometry* currentGeom = 0;
5206 double maxLength = -DBL_MAX;
5207 double currentLength = 0;
5208 for (
int i = 0; i < probableParts.size(); ++i )
5210 currentGeom = probableParts.at( i );
5211 GEOSLength_r( geosinit.
ctxt, currentGeom, ¤tLength );
5212 if ( currentLength > maxLength )
5214 maxLength = currentLength;
5215 GEOSGeom_destroy_r( geosinit.
ctxt, maxGeom );
5216 maxGeom = currentGeom;
5220 GEOSGeom_destroy_r( geosinit.
ctxt, currentGeom );
5223 resultLineParts.push_back( maxGeom );
5226 GEOSGeom_destroy_r( geosinit.
ctxt, beginLineVertex );
5227 GEOSGeom_destroy_r( geosinit.
ctxt, endLineVertex );
5228 GEOSGeom_destroy_r( geosinit.
ctxt, mergedLines );
5230 GEOSGeometry* result = 0;
5231 if ( resultLineParts.size() < 1 )
5234 if ( resultLineParts.size() == 1 )
5236 result = resultLineParts[0];
5240 GEOSGeometry **lineArray =
new GEOSGeometry*[resultLineParts.size()];
5241 for (
int i = 0; i < resultLineParts.size(); ++i )
5243 lineArray[i] = resultLineParts[i];
5247 GEOSGeometry* multiLineGeom = GEOSGeom_createCollection_r( geosinit.
ctxt, GEOS_MULTILINESTRING, lineArray, resultLineParts.size() );
5248 delete [] lineArray;
5251 result = GEOSLineMerge_r( geosinit.
ctxt, multiLineGeom );
5252 GEOSGeom_destroy_r( geosinit.
ctxt, multiLineGeom );
5256 if ( GEOSGeomTypeId_r( geosinit.
ctxt, result ) != GEOS_LINESTRING )
5258 GEOSGeom_destroy_r( geosinit.
ctxt, result );
5265 int QgsGeometry::topologicalTestPointsSplit(
const GEOSGeometry* splitLine, QList<QgsPoint>& testPoints )
const 5272 GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosinit.
ctxt, mGeos, splitLine );
5273 if ( !intersectionGeom )
5276 bool simple =
false;
5277 int nIntersectGeoms = 1;
5278 if ( GEOSGeomTypeId_r( geosinit.
ctxt, intersectionGeom ) == GEOS_LINESTRING || GEOSGeomTypeId_r( geosinit.
ctxt, intersectionGeom ) == GEOS_POINT )
5282 nIntersectGeoms = GEOSGetNumGeometries_r( geosinit.
ctxt, intersectionGeom );
5284 for (
int i = 0; i < nIntersectGeoms; ++i )
5286 const GEOSGeometry* currentIntersectGeom;
5288 currentIntersectGeom = intersectionGeom;
5290 currentIntersectGeom = GEOSGetGeometryN_r( geosinit.
ctxt, intersectionGeom, i );
5292 const GEOSCoordSequence* lineSequence = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, currentIntersectGeom );
5293 unsigned int sequenceSize = 0;
5295 if ( GEOSCoordSeq_getSize_r( geosinit.
ctxt, lineSequence, &sequenceSize ) != 0 )
5297 for (
unsigned int i = 0; i < sequenceSize; ++i )
5299 if ( GEOSCoordSeq_getX_r( geosinit.
ctxt, lineSequence, i, &x ) != 0 )
5301 if ( GEOSCoordSeq_getY_r( geosinit.
ctxt, lineSequence, i, &y ) != 0 )
5303 testPoints.push_back(
QgsPoint( x, y ) );
5309 GEOSGeom_destroy_r( geosinit.
ctxt, intersectionGeom );
5313 GEOSGeometry *QgsGeometry::nodeGeometries(
const GEOSGeometry *splitLine,
const GEOSGeometry *geom )
5315 if ( !splitLine || !geom )
5318 if ( GEOSGeomTypeId_r( geosinit.
ctxt, geom ) == GEOS_POLYGON || GEOSGeomTypeId_r( geosinit.
ctxt, geom ) == GEOS_MULTIPOLYGON )
5320 GEOSGeometry *geometryBoundary = GEOSBoundary_r( geosinit.
ctxt, geom );
5321 GEOSGeometry *unionGeometry = GEOSUnion_r( geosinit.
ctxt, splitLine, geometryBoundary );
5322 GEOSGeom_destroy_r( geosinit.
ctxt, geometryBoundary );
5323 return unionGeometry;
5327 return GEOSUnion_r( geosinit.
ctxt, splitLine, geom );
5331 int QgsGeometry::lineContainedInLine(
const GEOSGeometry* line1,
const GEOSGeometry* line2 )
5333 if ( !line1 || !line2 )
5338 double bufferDistance = pow( 10.0L, geomDigits( line2 ) - 11 );
5344 GEOSGeometry* intersectionGeom = GEOSIntersection_r( geosinit.
ctxt, bufferGeom, line1 );
5347 double intersectGeomLength;
5350 GEOSLength_r( geosinit.
ctxt, intersectionGeom, &intersectGeomLength );
5351 GEOSLength_r( geosinit.
ctxt, line1, &line1Length );
5353 GEOSGeom_destroy_r( geosinit.
ctxt, bufferGeom );
5354 GEOSGeom_destroy_r( geosinit.
ctxt, intersectionGeom );
5356 double intersectRatio = line1Length / intersectGeomLength;
5357 if ( intersectRatio > 0.9 && intersectRatio < 1.1 )
5363 int QgsGeometry::pointContainedInLine(
const GEOSGeometry* point,
const GEOSGeometry* line )
5365 if ( !point || !line )
5368 double bufferDistance = pow( 10.0L, geomDigits( line ) - 11 );
5370 GEOSGeometry* lineBuffer = GEOSBuffer_r( geosinit.
ctxt, line, bufferDistance, 8 );
5374 bool contained =
false;
5375 if ( GEOSContains_r( geosinit.
ctxt, lineBuffer, point ) == 1 )
5378 GEOSGeom_destroy_r( geosinit.
ctxt, lineBuffer );
5382 int QgsGeometry::geomDigits(
const GEOSGeometry* geom )
5384 GEOSGeometry* bbox = GEOSEnvelope_r( geosinit.
ctxt, geom );
5388 const GEOSGeometry* bBoxRing = GEOSGetExteriorRing_r( geosinit.
ctxt, bbox );
5392 const GEOSCoordSequence* bBoxCoordSeq = GEOSGeom_getCoordSeq_r( geosinit.
ctxt, bBoxRing );
5394 if ( !bBoxCoordSeq )
5397 unsigned int nCoords = 0;
5398 if ( !GEOSCoordSeq_getSize_r( geosinit.
ctxt, bBoxCoordSeq, &nCoords ) )
5402 for (
unsigned int i = 0; i < nCoords - 1; ++i )
5405 GEOSCoordSeq_getX_r( geosinit.
ctxt, bBoxCoordSeq, i, &t );
5408 digits = ceil( log10( fabs( t ) ) );
5409 if ( digits > maxDigits )
5412 GEOSCoordSeq_getY_r( geosinit.
ctxt, bBoxCoordSeq, i, &t );
5413 digits = ceil( log10( fabs( t ) ) );
5414 if ( digits > maxDigits )
5421 int QgsGeometry::numberOfGeometries( GEOSGeometry* g )
const 5426 int geometryType = GEOSGeomTypeId_r( geosinit.
ctxt, g );
5427 if ( geometryType == GEOS_POINT || geometryType == GEOS_LINESTRING || geometryType == GEOS_LINEARRING
5428 || geometryType == GEOS_POLYGON )
5432 return GEOSGetNumGeometries_r( geosinit.
ctxt, g );
5435 int QgsGeometry::mergeGeometriesMultiTypeSplit( QVector<GEOSGeometry*>& splitResult )
5444 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
5445 if ( type != GEOS_GEOMETRYCOLLECTION &&
5446 type != GEOS_MULTILINESTRING &&
5447 type != GEOS_MULTIPOLYGON &&
5448 type != GEOS_MULTIPOINT )
5451 QVector<GEOSGeometry*> copyList = splitResult;
5452 splitResult.clear();
5455 QVector<GEOSGeometry*> unionGeom;
5457 for (
int i = 0; i < copyList.size(); ++i )
5460 bool isPart =
false;
5461 for (
int j = 0; j < GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos ); j++ )
5463 if ( GEOSEquals_r( geosinit.
ctxt, copyList[i], GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, j ) ) )
5472 unionGeom << copyList[i];
5476 QVector<GEOSGeometry*> geomVector;
5477 geomVector << copyList[i];
5479 if ( type == GEOS_MULTILINESTRING )
5481 else if ( type == GEOS_MULTIPOLYGON )
5484 GEOSGeom_destroy_r( geosinit.
ctxt, copyList[i] );
5489 if ( unionGeom.size() > 0 )
5491 if ( type == GEOS_MULTILINESTRING )
5493 else if ( type == GEOS_MULTIPOLYGON )
5506 wkbPtr += 1 +
sizeof( int );
5511 wkbPtr +=
sizeof( double );
5518 wkbPtr += 1 +
sizeof( int );
5520 unsigned int nPoints;
5526 for ( uint i = 0; i < nPoints; ++i )
5531 wkbPtr +=
sizeof( double );
5541 wkbPtr += 1 +
sizeof( int );
5544 unsigned int numRings;
5547 if ( numRings == 0 )
5552 for ( uint idx = 0; idx < numRings; idx++ )
5559 for (
int jdx = 0; jdx < nPoints; jdx++ )
5564 wkbPtr +=
sizeof( double );
5619 for (
int i = 0; i < nPoints; i++ )
5621 points[i] =
asPoint( wkbPtr, hasZValue );
5638 wkbPtr >> numLineStrings;
5642 for (
int i = 0; i < numLineStrings; i++ )
5659 wkbPtr >> numPolygons;
5663 for (
int i = 0; i < numPolygons; i++ )
5664 polygons[i] =
asPolygon( wkbPtr, hasZValue );
5681 if ( GEOSArea_r( geosinit.
ctxt, mGeos, &area ) == 0 )
5701 if ( GEOSLength_r( geosinit.
ctxt, mGeos, &length ) == 0 )
5713 if ( geom.mDirtyGeos )
5714 geom.exportWkbToGeos();
5716 if ( !mGeos || !geom.mGeos )
5723 GEOSDistance_r( geosinit.
ctxt, mGeos, geom.mGeos, &dist );
5740 return fromGeosGeom( GEOSBuffer_r( geosinit.
ctxt, mGeos, distance, segments ) );
5747 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ 5748 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) 5757 return fromGeosGeom( GEOSBufferWithStyle_r( geosinit.
ctxt, mGeos, distance, segments, endCapStyle, joinStyle, mitreLimit ) );
5767 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ 5768 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3))) 5777 return fromGeosGeom( GEOSOffsetCurve_r( geosinit.
ctxt, mGeos, distance, segments, joinStyle, mitreLimit ) );
5795 return fromGeosGeom( GEOSTopologyPreserveSimplify_r( geosinit.
ctxt, mGeos, tolerance ) );
5847 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && \ 5848 ((GEOS_VERSION_MAJOR>3) || ((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=2))) 5857 return fromGeosGeom( GEOSInterpolate_r( geosinit.
ctxt, mGeos, distance ) );
5874 if ( geometry->mDirtyGeos )
5875 geometry->exportWkbToGeos();
5877 if ( !mGeos || !geometry->mGeos )
5882 return fromGeosGeom( GEOSIntersection_r( geosinit.
ctxt, mGeos, geometry->mGeos ) );
5895 if ( geometry->mDirtyGeos )
5896 geometry->exportWkbToGeos();
5898 if ( !mGeos || !geometry->mGeos )
5903 GEOSGeometry* unionGeom = GEOSUnion_r( geosinit.
ctxt, mGeos, geometry->mGeos );
5909 GEOSGeometry* mergedGeom = GEOSLineMerge_r( geosinit.
ctxt, unionGeom );
5912 GEOSGeom_destroy_r( geosinit.
ctxt, unionGeom );
5913 unionGeom = mergedGeom;
5929 if ( geometry->mDirtyGeos )
5930 geometry->exportWkbToGeos();
5932 if ( !mGeos || !geometry->mGeos )
5937 return fromGeosGeom( GEOSDifference_r( geosinit.
ctxt, mGeos, geometry->mGeos ) );
5950 if ( geometry->mDirtyGeos )
5951 geometry->exportWkbToGeos();
5953 if ( !mGeos || !geometry->mGeos )
5958 return fromGeosGeom( GEOSSymDifference_r( geosinit.
ctxt, mGeos, geometry->mGeos ) );
5969 return QList<QgsGeometry*>();
5971 int type = GEOSGeomTypeId_r( geosinit.
ctxt, mGeos );
5972 QgsDebugMsg(
"geom type: " + QString::number( type ) );
5974 QList<QgsGeometry*> geomCollection;
5976 if ( type != GEOS_MULTIPOINT &&
5977 type != GEOS_MULTILINESTRING &&
5978 type != GEOS_MULTIPOLYGON &&
5979 type != GEOS_GEOMETRYCOLLECTION )
5982 geomCollection.append(
new QgsGeometry( *
this ) );
5983 return geomCollection;
5986 int count = GEOSGetNumGeometries_r( geosinit.
ctxt, mGeos );
5987 QgsDebugMsg(
"geom count: " + QString::number( count ) );
5989 for (
int i = 0; i < count; ++i )
5991 const GEOSGeometry * geometry = GEOSGetGeometryN_r( geosinit.
ctxt, mGeos, i );
5992 geomCollection.append(
fromGeosGeom( GEOSGeom_clone_r( geosinit.
ctxt, geometry ) ) );
5995 return geomCollection;
6016 if ( polygon.size() < 1 )
6018 polyline = polygon.at( 0 );
6025 QgsPolyline::const_iterator lineIt = polyline.constBegin();
6026 for ( ; lineIt != polyline.constEnd(); ++lineIt )
6028 result << lineIt->toQPointF();
6035 if ( ringNum <= 0 || partNum < 0 )
6047 if ( ringNum >= polygon.count() )
6050 polygon.remove( ringNum );
6063 if ( partNum >= mpolygon.count() )
6066 if ( ringNum >= mpolygon[partNum].count() )
6069 mpolygon[partNum].remove( ringNum );
6094 if ( partNum >= mpoint.size() || mpoint.size() == 1 )
6097 mpoint.remove( partNum );
6110 if ( partNum >= mline.size() || mline.size() == 1 )
6113 mline.remove( partNum );
6126 if ( partNum >= mpolygon.size() || mpolygon.size() == 1 )
6129 mpolygon.remove( partNum );
6149 #if defined(GEOS_VERSION_MAJOR) && defined(GEOS_VERSION_MINOR) && (((GEOS_VERSION_MAJOR==3) && (GEOS_VERSION_MINOR>=3)) || (GEOS_VERSION_MAJOR>3)) 6150 GEOSGeometry* geomCollection = 0;
6152 GEOSGeometry* geomUnion = GEOSUnaryUnion_r( geosinit.
ctxt, geomCollection );
6153 GEOSGeom_destroy_r( geosinit.
ctxt, geomCollection );
6156 GEOSGeometry* geomCollection = geoms.takeFirst();
6158 while ( !geoms.isEmpty() )
6160 GEOSGeometry* g = geoms.takeFirst();
6161 GEOSGeometry* geomCollectionNew = GEOSUnion_r( geosinit.
ctxt, geomCollection, g );
6162 GEOSGeom_destroy_r( geosinit.
ctxt, geomCollection );
6163 GEOSGeom_destroy_r( geosinit.
ctxt, g );
6164 geomCollection = geomCollectionNew;
6167 return geomCollection;
6173 int returnValue = 0;
6187 QList<GEOSGeometry*> nearGeometries;
6191 QStringList::const_iterator aIt = avoidIntersectionsList.constBegin();
6192 for ( ; aIt != avoidIntersectionsList.constEnd(); ++aIt )
6198 QMap<QgsVectorLayer*, QSet<qint64> >::const_iterator ignoreIt = ignoreFeatures.find( currentLayer );
6199 if ( ignoreIt != ignoreFeatures.constEnd() )
6200 ignoreIds = ignoreIt.value();
6208 if ( ignoreIds.contains( f.
id() ) )
6219 if ( nearGeometries.isEmpty() )
6222 GEOSGeometry* nearGeometriesUnion = 0;
6223 GEOSGeometry* geomWithoutIntersections = 0;
6226 nearGeometriesUnion =
_makeUnion( nearGeometries );
6227 geomWithoutIntersections = GEOSDifference_r( geosinit.
ctxt,
asGeos(), nearGeometriesUnion );
6229 fromGeos( geomWithoutIntersections );
6231 GEOSGeom_destroy_r( geosinit.
ctxt, nearGeometriesUnion );
6235 if ( nearGeometriesUnion )
6236 GEOSGeom_destroy_r( geosinit.
ctxt, nearGeometriesUnion );
6237 if ( geomWithoutIntersections )
6238 GEOSGeom_destroy_r( geosinit.
ctxt, geomWithoutIntersections );
6245 if (
wkbType() != geomTypeBeforeModification )
6260 const GEOSGeometry *g =
asGeos();
6265 return GEOSisValid_r( geosinit.
ctxt, g );
6276 return geosRelOp( GEOSEquals_r,
this, &g );
6283 const GEOSGeometry *g =
asGeos();
6288 return GEOSisEmpty_r( geosinit.
ctxt, g );
6297 double QgsGeometry::leftOf(
double x,
double y,
double& x1,
double& y1,
double& x2,
double& y2 )
6300 double f2 = y2 - y1;
6302 double f4 = x2 - x1;
6303 return f1*f2 - f3*f4;
6306 QgsGeometry* QgsGeometry::convertToPoint(
bool destMultipart )
6314 if (( destMultipart && srcIsMultipart ) ||
6315 ( !destMultipart && !srcIsMultipart ) )
6320 if ( destMultipart )
6329 if ( multiPoint.count() == 1 )
6340 if ( !destMultipart )
6348 for ( QgsMultiPolyline::const_iterator multiLineIt = multiLine.constBegin(); multiLineIt != multiLine.constEnd(); ++multiLineIt )
6349 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6350 multiPoint << *lineIt;
6357 if ( !line.isEmpty() )
6366 if ( !destMultipart )
6374 for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
6375 for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
6376 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6377 multiPoint << *lineIt;
6385 for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
6386 for ( QgsPolyline::const_iterator lineIt = ( *multiLineIt ).constBegin(); lineIt != ( *multiLineIt ).constEnd(); ++lineIt )
6387 multiPoint << *lineIt;
6397 QgsGeometry* QgsGeometry::convertToLine(
bool destMultipart )
6407 if ( multiPoint.count() < 2 )
6410 if ( destMultipart )
6420 if (( destMultipart && srcIsMultipart ) ||
6421 ( !destMultipart && ! srcIsMultipart ) )
6426 if ( destMultipart )
6430 if ( !line.isEmpty() )
6437 if ( multiLine.count() == 1 )
6450 for ( QgsMultiPolygon::const_iterator polygonIt = multiPolygon.constBegin(); polygonIt != multiPolygon.constEnd(); ++polygonIt )
6451 for ( QgsMultiPolyline::const_iterator multiLineIt = ( *polygonIt ).constBegin(); multiLineIt != ( *polygonIt ).constEnd(); ++multiLineIt )
6452 multiLine << *multiLineIt;
6454 if ( destMultipart )
6459 else if ( multiLine.count() == 1 )
6470 if ( polygon.count() > 1 )
6474 if ( destMultipart )
6478 for ( QgsMultiPolyline::const_iterator multiLineIt = polygon.constBegin(); multiLineIt != polygon.constEnd(); ++multiLineIt )
6479 multiLine << *multiLineIt;
6484 else if ( polygon.count() == 1 )
6486 if ( destMultipart )
6504 QgsGeometry* QgsGeometry::convertToPolygon(
bool destMultipart )
6514 if ( multiPoint.count() < 3 )
6517 if ( multiPoint.last() != multiPoint.first() )
6518 multiPoint << multiPoint.first();
6521 if ( destMultipart )
6534 for ( QgsMultiPolyline::iterator multiLineIt = multiLine.begin(); multiLineIt != multiLine.end(); ++multiLineIt )
6537 if (( *multiLineIt ).count() < 3 )
6539 if (( *multiLineIt ).count() == 3 && ( *multiLineIt ).first() == ( *multiLineIt ).last() )
6543 if (( *multiLineIt ).first() != ( *multiLineIt ).last() )
6544 *multiLineIt << ( *multiLineIt ).first();
6545 multiPolygon << (
QgsPolygon() << *multiLineIt );
6548 if ( !multiPolygon.isEmpty() )
6550 if ( destMultipart )
6554 else if ( multiPolygon.count() == 1 )
6567 if ( line.count() < 3 )
6569 if ( line.count() == 3 && line.first() == line.last() )
6573 if ( line.first() != line.last() )
6574 line << line.first();
6577 if ( destMultipart )
6593 if (( destMultipart && srcIsMultipart ) ||
6594 ( !destMultipart && ! srcIsMultipart ) )
6599 if ( destMultipart )
6603 if ( !polygon.isEmpty() )
6609 if ( multiPolygon.count() == 1 )
6625 QList<GEOSGeometry*> geoms;
6628 geoms.append( GEOSGeom_clone_r( geosinit.
ctxt, g->
asGeos() ) );
6630 GEOSGeometry *geomUnion =
_makeUnion( geoms );
QgsFeatureId id() const
Get the feature id for this feature.
static QgsGeometry * fromQPolygonF(const QPolygonF &polygon)
Construct geometry from a QPolygonF.
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.
double length()
get length of geometry using GEOS
int reshapeGeometry(const QList< QgsPoint > &reshapeWithLine)
Replaces a part of this geometry with another line.
Use exact geometry intersection (slower) instead of bounding boxes.
QPolygonF asQPolygonF() const
Return contents of the geometry as a QPolygonF.
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
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
QPointF asQPointF() const
Return contents of the geometry as a QPointF if wkbType is WKBPoint, otherwise returns a null QPointF...
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 QgsMapLayerRegistry * instance()
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...
QGis::GeometryType type() const
Returns type of the vector.
double closestVertexWithContext(const QgsPoint &point, int &atVertex)
Searches for the closest vertex in this geometry to the given point.
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)
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...
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.
const GEOSGeometry * asGeos() const
Returns a geos geometry.
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
static WkbType flatType(WkbType type)
int splitGeometry(const QList< QgsPoint > &splitLine, QList< QgsGeometry * > &newGeometries, bool topological, QList< QgsPoint > &topologyTestPoints)
Splits this geometry according to a given line.
bool contains(const QgsPoint *p) const
Test for containment of a point (uses GEOS)
QStringList readListEntry(const QString &scope, const QString &key, QStringList def=QStringList(), bool *ok=0) const
key value accessors
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.
QString toString() const
String representation of the point (x,y)
static GEOSGeometry * createGeosPoint(const double x, const double y)
QGis::WkbType wkbType() const
Returns type of wkb (point / linestring / polygon etc.)
QVector< QgsPolyline > QgsPolygon
polygon: first item of the list is outer ring, inner rings (if any) start from second item ...
void validateGeometry(QList< Error > &errors)
Validate geometry and produce a list of geometry errors.
void set(double x, double y)
QgsGeometry * intersection(QgsGeometry *geometry)
Returns a geometry representing the points shared by this geometry and other.
A class to represent a point.
static QgsGeometry * fromPoint(const QgsPoint &point)
construct geometry from a point
int translate(double dx, double dy)
Translate this geometry by dx, dy.
QgsGeometry * pointOnSurface()
Returns a point within a geometry.
bool isGeosEqual(QgsGeometry &)
compare geometries using GEOS
QString qgsDoubleToString(const double &a, const int &precision=17)
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
static QgsGeometry * fromQPointF(const QPointF &point)
Construct geometry from a QPointF.
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.
static int wkbDimensions(WkbType type)
static void printGEOSNotice(const char *fmt,...)
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
static GEOSContextHandle_t getGEOSHandler()
return GEOS context handle
QString exportToGeoJSON(const int &precision=17) const
Exports the geometry to GeoJSON.
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...
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)
int rotate(double rotation, const QgsPoint ¢er)
Rotate this geometry around the Z axis.
static QgsProject * instance()
access to canonical QgsProject instance
bool isMultipart() const
Returns true if wkb of the geometry is of WKBMulti* type.
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 CoordinateTransform 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)
int addRing(const QList< QgsPoint > &ring)
Adds a new ring to this geometry.
QgsGeometry * interpolate(double distance)
bool nextFeature(QgsFeature &f)
QgsPoint asPoint() const
return contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
bool intersects(const QgsRectangle &r) const
Test for intersection with a rectangle (uses GEOS)
Represents a vector layer which manages a vector based data sets.
static GEOSGeometry * _makeUnion(QList< GEOSGeometry * > geoms)
Return union of several geometries - try to use unary union if available (GEOS >= 3...
const unsigned char * asWkb() const
Returns the buffer containing this geometry in WKB format.
double xMinimum() const
Get the x minimum value (left side of rectangle)
QString exportToWkt(const int &precision=17) const
Exports the geometry to WKT.
static QgsGeometry * fromGeosGeom(GEOSGeometry *geom)
double distance(QgsGeometry &geom)
QPointF toQPointF() const
Converts a point to a QPointF.