bool QgsGeometryEditUtils::deleteRing( QgsAbstractGeometry *geom, int ringNum, int partNum ) { if ( !geom || partNum < 0 ) { return false; } if ( ringNum < 1 ) //cannot remove exterior ring { return false; } QgsAbstractGeometry *g = geom; QgsGeometryCollection *c = qgsgeometry_cast<QgsGeometryCollection *>( geom ); if ( c ) { g = c->geometryN( partNum ); } else if ( partNum > 0 ) { //part num specified, but not a multi part geometry type return false; } QgsCurvePolygon *cpoly = qgsgeometry_cast<QgsCurvePolygon *>( g ); if ( !cpoly ) { return false; } return cpoly->removeInteriorRing( ringNum - 1 ); }
static bool lwcollection_make_geos_friendly( QgsGeometryCollection &g ) { for ( int i = 0; i < g.numGeometries(); i++ ) { if ( !lwgeom_make_geos_friendly( *g.geometryN( i ) ) ) return false; } return true; }
QgsGeometry::OperationResult QgsGeometryEditUtils::addRing( QgsAbstractGeometry *geom, std::unique_ptr<QgsCurve> ring ) { if ( !ring ) { return QgsGeometry::InvalidInput; } QList< QgsCurvePolygon * > polygonList; QgsCurvePolygon *curvePoly = qgsgeometry_cast< QgsCurvePolygon * >( geom ); QgsGeometryCollection *multiGeom = qgsgeometry_cast< QgsGeometryCollection * >( geom ); if ( curvePoly ) { polygonList.append( curvePoly ); } else if ( multiGeom ) { polygonList.reserve( multiGeom->numGeometries() ); for ( int i = 0; i < multiGeom->numGeometries(); ++i ) { polygonList.append( qgsgeometry_cast< QgsCurvePolygon * >( multiGeom->geometryN( i ) ) ); } } else { return QgsGeometry::InvalidInput; //not polygon / multipolygon; } //ring must be closed if ( !ring->isClosed() ) { return QgsGeometry::AddRingNotClosed; } else if ( !ring->isRing() ) { return QgsGeometry::AddRingNotValid; } std::unique_ptr<QgsGeometryEngine> ringGeom( QgsGeometry::createGeometryEngine( ring.get() ) ); ringGeom->prepareGeometry(); //for each polygon, test if inside outer ring and no intersection with other interior ring QList< QgsCurvePolygon * >::const_iterator polyIter = polygonList.constBegin(); for ( ; polyIter != polygonList.constEnd(); ++polyIter ) { if ( ringGeom->within( *polyIter ) ) { //check if disjoint with other interior rings int nInnerRings = ( *polyIter )->numInteriorRings(); for ( int i = 0; i < nInnerRings; ++i ) { if ( !ringGeom->disjoint( ( *polyIter )->interiorRing( i ) ) ) { return QgsGeometry::AddRingCrossesExistingRings; } } //make sure dimensionality of ring matches geometry if ( QgsWkbTypes::hasZ( geom->wkbType() ) ) ring->addZValue( 0 ); if ( QgsWkbTypes::hasM( geom->wkbType() ) ) ring->addMValue( 0 ); ( *polyIter )->addInteriorRing( ring.release() ); return QgsGeometry::Success; //success } } return QgsGeometry::AddRingNotInExistingFeature; //not contained in any outer ring }