void QgsGeometryCheck::replaceFeatureGeometryPart( QgsFeature& feature, int partIdx, QgsAbstractGeometryV2* newPartGeom, Changes& changes ) const { QgsAbstractGeometryV2* geom = feature.geometry()->geometry(); if ( dynamic_cast<QgsGeometryCollectionV2*>( geom ) ) { QgsGeometryCollectionV2* GeomCollection = static_cast<QgsGeometryCollectionV2*>( geom ); GeomCollection->removeGeometry( partIdx ); GeomCollection->addGeometry( newPartGeom ); changes[feature.id()].append( Change( ChangeFeature, ChangeRemoved, QgsVertexId( partIdx ) ) ); changes[feature.id()].append( Change( ChangeFeature, ChangeAdded, QgsVertexId( GeomCollection->partCount() - 1 ) ) ); } else { feature.setGeometry( new QgsGeometry( newPartGeom ) ); changes[feature.id()].append( Change( ChangeFeature, ChangeChanged ) ); } mFeaturePool->updateFeature( feature ); }
int QgsGeometryEditUtils::addPart( QgsAbstractGeometryV2* geom, QgsAbstractGeometryV2* part ) { if ( !geom ) { return 1; } if ( !part ) { return 2; } //multitype? QgsGeometryCollectionV2* geomCollection = dynamic_cast<QgsGeometryCollectionV2*>( geom ); if ( !geomCollection ) { return 1; } bool added = false; if ( QgsWKBTypes::flatType( geom->wkbType() ) == QgsWKBTypes::MultiSurface || QgsWKBTypes::flatType( geom->wkbType() ) == QgsWKBTypes::MultiPolygon ) { QgsCurveV2* curve = dynamic_cast<QgsCurveV2*>( part ); if ( curve && curve->isClosed() && curve->numPoints() >= 4 ) { QgsCurvePolygonV2 *poly = nullptr; if ( QgsWKBTypes::flatType( curve->wkbType() ) == QgsWKBTypes::LineString ) { poly = new QgsPolygonV2(); } else { poly = new QgsCurvePolygonV2(); } poly->setExteriorRing( curve ); added = geomCollection->addGeometry( poly ); } else if ( QgsWKBTypes::flatType( part->wkbType() ) == QgsWKBTypes::Polygon ) { added = geomCollection->addGeometry( part ); } else if ( QgsWKBTypes::flatType( part->wkbType() ) == QgsWKBTypes::MultiPolygon ) { QgsGeometryCollectionV2 *parts = static_cast<QgsGeometryCollectionV2*>( part ); int i; int n = geomCollection->numGeometries(); for ( i = 0; i < parts->numGeometries() && geomCollection->addGeometry( parts->geometryN( i )->clone() ); i++ ) ; added = i == parts->numGeometries(); if ( !added ) { while ( geomCollection->numGeometries() > n ) geomCollection->removeGeometry( n ); delete part; return 2; } delete part; } else { delete part; return 2; } } else { added = geomCollection->addGeometry( part ); } return added ? 0 : 2; }
void QgsGeometryTypeCheck::fixError( QgsGeometryCheckError* error, int method, int /*mergeAttributeIndex*/, Changes &changes ) const { QgsFeature feature; if ( !mFeaturePool->get( error->featureId(), feature ) ) { error->setObsolete(); return; } QgsAbstractGeometryV2* geom = feature.geometry()->geometry(); // Check if error still applies QgsWKBTypes::Type type = QgsWKBTypes::flatType( geom->wkbType() ); if (( mAllowedTypes & ( 1 << type ) ) != 0 ) { error->setObsolete(); return; } // Fix with selected method if ( method == NoChange ) { error->setFixed( method ); } else if ( method == Convert ) { // Check if corresponding single type is allowed if ( QgsWKBTypes::isMultiType( type ) && (( 1 << QgsWKBTypes::singleType( type ) ) & mAllowedTypes ) != 0 ) { // Explode multi-type feature into single-type features for ( int iPart = 1, nParts = geom->partCount(); iPart < nParts; ++iPart ) { QgsFeature newFeature; newFeature.setAttributes( feature.attributes() ); newFeature.setGeometry( new QgsGeometry( QgsGeomUtils::getGeomPart( geom, iPart )->clone() ) ); mFeaturePool->addFeature( newFeature ); changes[newFeature.id()].append( Change( ChangeFeature, ChangeAdded ) ); } // Recycle feature for part 0 feature.setGeometry( new QgsGeometry( QgsGeomUtils::getGeomPart( geom, 0 ) ) ); changes[feature.id()].append( Change( ChangeFeature, ChangeChanged ) ); } // Check if corresponding multi type is allowed else if ( QgsWKBTypes::isSingleType( type ) && (( 1 << QgsWKBTypes::multiType( type ) ) & mAllowedTypes ) != 0 ) { QgsGeometryCollectionV2* geomCollection = nullptr; switch ( QgsWKBTypes::multiType( type ) ) { case QgsWKBTypes::MultiPoint: { geomCollection = new QgsMultiPointV2(); break; } case QgsWKBTypes::MultiLineString: { geomCollection = new QgsMultiLineStringV2(); break; } case QgsWKBTypes::MultiPolygon: { geomCollection = new QgsMultiPolygonV2(); break; } case QgsWKBTypes::MultiCurve: { geomCollection = new QgsMultiCurveV2(); break; } case QgsWKBTypes::MultiSurface: { geomCollection = new QgsMultiSurfaceV2(); break; } default: break; } if ( !geomCollection ) { error->setFixFailed( tr( "Unknown geometry type" ) ); } else { geomCollection->addGeometry( geom->clone() ); feature.setGeometry( new QgsGeometry( geomCollection ) ); mFeaturePool->updateFeature( feature ); changes[feature.id()].append( Change( ChangeFeature, ChangeChanged ) ); } } // Delete feature else { mFeaturePool->deleteFeature( feature ); changes[error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) ); } error->setFixed( method ); } else if ( method == Delete ) { mFeaturePool->deleteFeature( feature ); error->setFixed( method ); changes[error->featureId()].append( Change( ChangeFeature, ChangeRemoved ) ); } else { error->setFixFailed( tr( "Unknown method" ) ); } }