QgsAbstractGeometry *densifyGeometry( const QgsAbstractGeometry *geom, int extraNodesPerSegment = 1, double distance = 1 ) { std::unique_ptr< QgsAbstractGeometry > segmentizedCopy; if ( QgsWkbTypes::isCurvedType( geom->wkbType() ) ) { segmentizedCopy.reset( geom->segmentize() ); geom = segmentizedCopy.get(); } if ( QgsWkbTypes::geometryType( geom->wkbType() ) == QgsWkbTypes::LineGeometry ) { return doDensify( static_cast< const QgsLineString * >( geom ), extraNodesPerSegment, distance ); } else { // polygon const QgsPolygon *polygon = static_cast< const QgsPolygon * >( geom ); QgsPolygon *result = new QgsPolygon(); result->setExteriorRing( doDensify( static_cast< const QgsLineString * >( polygon->exteriorRing() ), extraNodesPerSegment, distance ) ); for ( int i = 0; i < polygon->numInteriorRings(); ++i ) { result->addInteriorRing( doDensify( static_cast< const QgsLineString * >( polygon->interiorRing( i ) ), extraNodesPerSegment, distance ) ); } return result; } }
QgsAbstractGeometry *orthogonalizeGeom( const QgsAbstractGeometry *geom, int maxIterations, double tolerance, double lowerThreshold, double upperThreshold ) { std::unique_ptr< QgsAbstractGeometry > segmentizedCopy; if ( QgsWkbTypes::isCurvedType( geom->wkbType() ) ) { segmentizedCopy.reset( geom->segmentize() ); geom = segmentizedCopy.get(); } if ( QgsWkbTypes::geometryType( geom->wkbType() ) == QgsWkbTypes::LineGeometry ) { return doOrthogonalize( static_cast< QgsLineString * >( geom->clone() ), maxIterations, tolerance, lowerThreshold, upperThreshold ); } else { // polygon const QgsPolygon *polygon = static_cast< const QgsPolygon * >( geom ); QgsPolygon *result = new QgsPolygon(); result->setExteriorRing( doOrthogonalize( static_cast< QgsLineString * >( polygon->exteriorRing()->clone() ), maxIterations, tolerance, lowerThreshold, upperThreshold ) ); for ( int i = 0; i < polygon->numInteriorRings(); ++i ) { result->addInteriorRing( doOrthogonalize( static_cast< QgsLineString * >( polygon->interiorRing( i )->clone() ), maxIterations, tolerance, lowerThreshold, upperThreshold ) ); } return result; } }
static QgsPolygon *_transform_polygon_to_new_base( const QgsPolygon &polygon, const QgsPoint &pt0, const QMatrix4x4 *toNewBase ) { QgsPolygon *p = new QgsPolygon; p->setExteriorRing( _transform_ring_to_new_base( *polygon.exteriorRing(), pt0, toNewBase ) ); for ( int i = 0; i < polygon.numInteriorRings(); ++i ) p->addInteriorRing( _transform_ring_to_new_base( *polygon.interiorRing( i ), pt0, toNewBase ) ); return p; }
void QgsMapToolCapture::validateGeometry() { QgsSettings settings; if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 0 ) return; if ( mValidator ) { mValidator->deleteLater(); mValidator = nullptr; } mGeomErrors.clear(); while ( !mGeomErrorMarkers.isEmpty() ) { delete mGeomErrorMarkers.takeFirst(); } QgsGeometry geom; switch ( mCaptureMode ) { case CaptureNone: case CapturePoint: return; case CaptureLine: if ( size() < 2 ) return; geom = QgsGeometry( mCaptureCurve.curveToLine() ); break; case CapturePolygon: if ( size() < 3 ) return; QgsLineString *exteriorRing = mCaptureCurve.curveToLine(); exteriorRing->close(); QgsPolygon *polygon = new QgsPolygon(); polygon->setExteriorRing( exteriorRing ); geom = QgsGeometry( polygon ); break; } if ( geom.isNull() ) return; QgsGeometry::ValidationMethod method = QgsGeometry::ValidatorQgisInternal; if ( settings.value( QStringLiteral( "qgis/digitizing/validate_geometries" ), 1 ).toInt() == 2 ) method = QgsGeometry::ValidatorGeos; mValidator = new QgsGeometryValidator( geom, nullptr, method ); connect( mValidator, &QgsGeometryValidator::errorFound, this, &QgsMapToolCapture::addError ); mValidator->start(); QgsDebugMsgLevel( QStringLiteral( "Validation started" ), 4 ); }
QgsGeometry QgsInternalGeometryEngine::extrude( double x, double y ) const { QVector<QgsLineString *> linesToProcess; const QgsMultiCurve *multiCurve = qgsgeometry_cast< const QgsMultiCurve * >( mGeometry ); if ( multiCurve ) { for ( int i = 0; i < multiCurve->partCount(); ++i ) { linesToProcess << static_cast<QgsLineString *>( multiCurve->geometryN( i )->clone() ); } } const QgsCurve *curve = qgsgeometry_cast< const QgsCurve * >( mGeometry ); if ( curve ) { linesToProcess << static_cast<QgsLineString *>( curve->segmentize() ); } std::unique_ptr<QgsMultiPolygon> multipolygon( linesToProcess.size() > 1 ? new QgsMultiPolygon() : nullptr ); QgsPolygon *polygon = nullptr; if ( !linesToProcess.empty() ) { std::unique_ptr< QgsLineString > secondline; for ( QgsLineString *line : qgis::as_const( linesToProcess ) ) { QTransform transform = QTransform::fromTranslate( x, y ); secondline.reset( line->reversed() ); secondline->transform( transform ); line->append( secondline.get() ); line->addVertex( line->pointN( 0 ) ); polygon = new QgsPolygon(); polygon->setExteriorRing( line ); if ( multipolygon ) multipolygon->addGeometry( polygon ); } if ( multipolygon ) return QgsGeometry( multipolygon.release() ); else return QgsGeometry( polygon ); } return QgsGeometry(); }