QgsGeometry::OperationResult QgsVectorLayerEditUtils::addRing( QgsCurve *ring, const QgsFeatureIds &targetFeatureIds, QgsFeatureId *modifiedFeatureId ) { if ( !mLayer->isSpatial() ) { delete ring; return QgsGeometry::AddRingNotInExistingFeature; } QgsGeometry::OperationResult addRingReturnCode = QgsGeometry::AddRingNotInExistingFeature; //default: return code for 'ring not inserted' QgsFeature f; QgsFeatureIterator fit; if ( !targetFeatureIds.isEmpty() ) { //check only specified features fit = mLayer->getFeatures( QgsFeatureRequest().setFilterFids( targetFeatureIds ) ); } else { //check all intersecting features QgsRectangle bBox = ring->boundingBox(); fit = mLayer->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); } //find first valid feature we can add the ring to while ( fit.nextFeature( f ) ) { if ( !f.hasGeometry() ) continue; //add ring takes ownership of ring, and deletes it if there's an error QgsGeometry g = f.geometry(); addRingReturnCode = g.addRing( static_cast< QgsCurve * >( ring->clone() ) ); if ( addRingReturnCode == 0 ) if ( addRingReturnCode == QgsGeometry::Success ) { mLayer->editBuffer()->changeGeometry( f.id(), g ); if ( modifiedFeatureId ) *modifiedFeatureId = f.id(); //setModified( true, true ); break; } } delete ring; return addRingReturnCode; }
void QgsVectorLayerUndoCommandChangeGeometry::undo() { if ( FID_IS_NEW( mFid ) ) { // modify added features QgsFeatureMap::iterator it = mBuffer->mAddedFeatures.find( mFid ); Q_ASSERT( it != mBuffer->mAddedFeatures.end() ); it.value().setGeometry( mOldGeom ); cache()->cacheGeometry( mFid, mOldGeom ); emit mBuffer->geometryChanged( mFid, mOldGeom ); } else { // existing feature if ( mOldGeom.isEmpty() ) { mBuffer->mChangedGeometries.remove( mFid ); QgsFeature f; if ( layer()->getFeatures( QgsFeatureRequest().setFilterFid( mFid ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) && f.hasGeometry() ) { cache()->cacheGeometry( mFid, f.geometry() ); emit mBuffer->geometryChanged( mFid, f.geometry() ); } } else { mBuffer->mChangedGeometries[mFid] = mOldGeom; cache()->cacheGeometry( mFid, mOldGeom ); emit mBuffer->geometryChanged( mFid, mOldGeom ); } } }
QgsFeature QgsFixGeometriesAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingFeedback *feedback ) { if ( !feature.hasGeometry() ) return feature; QgsFeature outputFeature = feature; QgsGeometry outputGeometry = outputFeature.geometry().makeValid(); if ( !outputGeometry ) { feedback->pushInfo( QObject::tr( "makeValid failed for feature %1 " ).arg( feature.id() ) ); outputFeature.clearGeometry(); return outputFeature; } if ( outputGeometry.wkbType() == QgsWkbTypes::Unknown || QgsWkbTypes::flatType( outputGeometry.wkbType() ) == QgsWkbTypes::GeometryCollection ) { // keep only the parts of the geometry collection with correct type const QVector< QgsGeometry > tmpGeometries = outputGeometry.asGeometryCollection(); QVector< QgsGeometry > matchingParts; for ( const QgsGeometry &g : tmpGeometries ) { if ( g.type() == feature.geometry().type() ) matchingParts << g; } if ( !matchingParts.empty() ) outputGeometry = QgsGeometry::collectGeometry( matchingParts ); else outputGeometry = QgsGeometry(); } outputGeometry.convertToMultiType(); outputFeature.setGeometry( outputGeometry ); return outputFeature; }
void QgsAtlasComposition::setCoverageLayer( QgsVectorLayer* layer ) { mCoverageLayer = layer; // update the number of features QgsExpression::setSpecialColumn( "$numfeatures", QVariant(( int )mFeatureIds.size() ) ); // Grab the first feature so that user can use it to test the style in rules. QgsFeature fet; layer->getFeatures().nextFeature( fet ); QgsExpression::setSpecialColumn( "$atlasfeatureid", fet.id() ); QgsExpression::setSpecialColumn( "$atlasgeometry", QVariant::fromValue( *fet.geometry() ) ); emit coverageLayerChanged( layer ); }
bool QgsSimplifyFeature::simplifyPolygon( QgsFeature& polygonFeature, double tolerance ) { QgsGeometry* polygon = polygonFeature.geometry(); if ( polygon->type() != QGis::Polygon ) { return false; } QVector<QgsPoint> resultPoints = simplifyPoints( polygon->asPolygon()[0], tolerance ); //resultPoints.push_back(resultPoints[0]); QVector<QgsPolyline> poly; poly.append( resultPoints ); polygonFeature.setGeometry( QgsGeometry::fromPolygon( poly ) ); return true; }
void QgsOverlayAnalyzer::intersectFeature( QgsFeature &f, QgsVectorFileWriter *vfw, QgsVectorLayer *vl, QgsSpatialIndex *index ) { if ( !f.hasGeometry() ) { return; } QgsGeometry featureGeometry = f.geometry(); QgsGeometry intersectGeometry; QgsFeature overlayFeature; QList<QgsFeatureId> intersects = index->intersects( featureGeometry.boundingBox() ); QgsFeatureRequest req = QgsFeatureRequest().setFilterFids( intersects.toSet() ); QgsFeatureIterator intersectIt = vl->getFeatures( req ); QgsFeature outFeature; while ( intersectIt.nextFeature( overlayFeature ) ) { if ( featureGeometry.intersects( overlayFeature.geometry() ) ) { intersectGeometry = featureGeometry.intersection( overlayFeature.geometry() ); outFeature.setGeometry( intersectGeometry ); QgsAttributes attributesA = f.attributes(); QgsAttributes attributesB = overlayFeature.attributes(); combineAttributeMaps( attributesA, attributesB ); outFeature.setAttributes( attributesA ); //add it to vector file writer if ( vfw ) { vfw->addFeature( outFeature ); } } } }
bool QgsNullSymbolRenderer::renderFeature( QgsFeature &feature, QgsRenderContext &context, int layer, bool selected, bool drawVertexMarker ) { //render selected features or features being edited only if ( !selected && !drawVertexMarker ) { return true; } if ( !feature.hasGeometry() || feature.geometry().type() == QgsWkbTypes::NullGeometry || feature.geometry().type() == QgsWkbTypes::UnknownGeometry ) return true; if ( !mSymbol ) { //create default symbol mSymbol.reset( QgsSymbol::defaultSymbol( feature.geometry().type() ) ); mSymbol->startRender( context ); } mSymbol->renderFeature( feature, context, layer, selected, drawVertexMarker, mCurrentVertexMarkerType, mCurrentVertexMarkerSize ); return true; }
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring ) { if ( !L->hasGeometryType() ) return 5; int addRingReturnCode = 5; //default: return code for 'ring not inserted' double xMin, yMin, xMax, yMax; QgsRectangle bBox; if ( boundingBoxFromPointList( ring, xMin, yMin, xMax, yMax ) == 0 ) { bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin ); bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax ); } else { return 3; //ring not valid } QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; while ( fit.nextFeature( f ) ) { addRingReturnCode = f.geometry()->addRing( ring ); if ( addRingReturnCode == 0 ) { L->editBuffer()->changeGeometry( f.id(), f.geometry() ); //setModified( true, true ); break; } } return addRingReturnCode; }
QgsRectangle QgsFeatureSource::sourceExtent() const { QgsRectangle r; QgsFeatureRequest req; req.setNoAttributes(); QgsFeatureIterator it = getFeatures( req ); QgsFeature f; while ( it.nextFeature( f ) ) { if ( f.hasGeometry() ) r.combineExtentWith( f.geometry().boundingBox() ); } return r; }
void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError*>& errors, QStringList &messages, QAtomicInt* progressCounter , const QgsFeatureIds &ids ) const { Q_ASSERT( mFeaturePool->getLayer()->geometryType() == QgsWkbTypes::PolygonGeometry ); if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 ); // Collect geometries, build spatial index QList<QgsAbstractGeometryV2*> geomList; const QgsFeatureIds& featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids; Q_FOREACH ( QgsFeatureId id, featureIds ) { QgsFeature feature; if ( mFeaturePool->get( id, feature ) ) { geomList.append( feature.geometry().geometry()->clone() ); } }
QgsFeature QgsMinimumEnclosingCircleAlgorithm::processFeature( const QgsFeature &feature, QgsProcessingContext &, QgsProcessingFeedback * ) { QgsFeature f = feature; if ( f.hasGeometry() ) { double radius = 0; QgsPointXY center; QgsGeometry outputGeometry = f.geometry().minimalEnclosingCircle( center, radius, mSegments ); f.setGeometry( outputGeometry ); QgsAttributes attrs = f.attributes(); attrs << radius << M_PI *radius *radius; f.setAttributes( attrs ); } return f; }
bool QgsVectorLayerEditUtils::moveVertex( const QgsPoint &p, QgsFeatureId atFeatureId, int atVertex ) { if ( !mLayer->isSpatial() ) return false; QgsFeature f; if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.hasGeometry() ) return false; // geometry not found QgsGeometry geometry = f.geometry(); geometry.moveVertex( p, atVertex ); mLayer->editBuffer()->changeGeometry( atFeatureId, geometry ); return true; }
bool QgsVectorLayerEditUtils::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex ) { if ( !mLayer->isSpatial() ) return false; QgsFeature f; if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( atFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.hasGeometry() ) return false; // geometry not found QgsGeometry geometry = f.geometry(); geometry.insertVertex( x, y, beforeVertex ); mLayer->editBuffer()->changeGeometry( atFeatureId, geometry ); return true; }
void QgsGeometryAnalyzer::bufferFeature( QgsFeature& f, int nProcessedFeatures, QgsVectorFileWriter* vfw, bool dissolve, QgsGeometry& dissolveGeometry, double bufferDistance, int bufferDistanceField ) { if ( !f.hasGeometry() ) { return; } double currentBufferDistance; QgsGeometry featureGeometry = f.geometry(); QgsGeometry bufferGeometry; //create buffer if ( bufferDistanceField == -1 ) { currentBufferDistance = bufferDistance; } else { currentBufferDistance = f.attribute( bufferDistanceField ).toDouble(); } bufferGeometry = featureGeometry.buffer( currentBufferDistance, 5 ); if ( dissolve ) { if ( nProcessedFeatures == 0 ) { dissolveGeometry = bufferGeometry; } else { dissolveGeometry = dissolveGeometry.combine( bufferGeometry ); } } else //dissolve { QgsFeature newFeature; newFeature.setGeometry( bufferGeometry ); newFeature.setAttributes( f.attributes() ); //add it to vector file writer if ( vfw ) { vfw->addFeature( newFeature ); } } }
QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap ¶meters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) { std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) ); if ( !featureSource ) return QVariantMap(); QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() ); bool clip = parameterAsBool( parameters, QStringLiteral( "CLIP" ), context ); // if clipping, we force multi output QgsWkbTypes::Type outType = clip ? QgsWkbTypes::multiType( featureSource->wkbType() ) : featureSource->wkbType(); QString dest; std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, featureSource->fields(), outType, featureSource->sourceCrs() ) ); if ( !sink ) return QVariantMap(); QgsGeometry clipGeom = parameterAsExtentGeometry( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() ); double step = featureSource->featureCount() > 0 ? 100.0 / featureSource->featureCount() : 1; QgsFeatureIterator inputIt = featureSource->getFeatures( QgsFeatureRequest().setFilterRect( extent ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; int i = -1; while ( inputIt.nextFeature( f ) ) { i++; if ( feedback->isCanceled() ) { break; } if ( clip ) { QgsGeometry g = f.geometry().intersection( clipGeom ); g.convertToMultiType(); f.setGeometry( g ); } sink->addFeature( f, QgsFeatureSink::FastInsert ); feedback->setProgress( i * step ); } QVariantMap outputs; outputs.insert( QStringLiteral( "OUTPUT" ), dest ); return outputs; }
void QgsLabel::labelPoint( std::vector<labelpoint>& points, QgsFeature & feature ) { QgsGeometry *geometry = feature.geometry(); const unsigned char *geom = geometry->asWkb(); size_t geomlen = geometry->wkbSize(); QGis::WkbType wkbType = geometry->wkbType(); labelpoint point; switch ( wkbType ) { case QGis::WKBPoint25D: case QGis::WKBPoint: case QGis::WKBLineString25D: case QGis::WKBLineString: case QGis::WKBPolygon25D: case QGis::WKBPolygon: { labelPoint( point, geom, geomlen ); points.push_back( point ); } break; case QGis::WKBMultiPoint25D: case QGis::WKBMultiPoint: case QGis::WKBMultiLineString25D: case QGis::WKBMultiLineString: case QGis::WKBMultiPolygon25D: case QGis::WKBMultiPolygon: // Return a position for each individual in the multi-feature { Q_ASSERT( 1 + sizeof( wkbType ) + sizeof( int ) <= geomlen ); geom += 1 + sizeof( wkbType ); int nFeatures = *( unsigned int * )geom; geom += sizeof( int ); const unsigned char *feature = geom; for ( int i = 0; i < nFeatures && feature; ++i ) { feature = labelPoint( point, feature, geom + geomlen - feature ); points.push_back( point ); } } break; default: QgsDebugMsg( "Unknown geometry type of " + QString::number( wkbType ) ); } }
QSGNode* FeatureListModelHighlight::updatePaintNode( QSGNode* n, QQuickItem::UpdatePaintNodeData* ) { if ( mDirty && mMapSettings ) { delete n; n = new QSGNode; int count = mModel->rowCount( QModelIndex() ); QgsSGGeometry* sn = 0; QModelIndex firstIndex = mModel->index( 0, 0, QModelIndex() ); QgsVectorLayer* layer = mModel->data( firstIndex, MultiFeatureListModel::LayerRole ).value<QgsVectorLayer*>(); if ( layer ) { QgsCoordinateTransform transf( layer->crs(), mMapSettings->destinationCrs() ); for ( int i = 0; i < count; ++i ) { QgsSGGeometry* gn; QModelIndex index = mModel->index( i, 0, QModelIndex() ); QgsFeature feature = mModel->data( index, MultiFeatureListModel::FeatureRole ).value<QgsFeature>(); QgsGeometry geom( feature.geometry() ); geom.transform( transf ); if ( mSelection && mSelection->selection() == i ) { sn = new QgsSGGeometry( geom, mSelectionColor, mWidth ); sn->setFlag( QSGNode::OwnedByParent ); } else { gn = new QgsSGGeometry( geom, mColor, mWidth ); gn->setFlag( QSGNode::OwnedByParent ); n->appendChildNode( gn ); } } if ( sn ) n->appendChildNode( sn ); } mDirty = false; } return n; }
void QgsSelectedFeature::updateGeometry( QgsGeometry *geom ) { QgsDebugMsg( "Entering." ); delete mGeometry; if ( !geom ) { QgsFeature f; mVlayer->featureAtId( mFeatureId, f ); mGeometry = new QgsGeometry( *f.geometry() ); } else { mGeometry = new QgsGeometry( *geom ); } }
void QgsSelectedFeature::updateGeometry( QgsGeometry *geom ) { QgsDebugCall; delete mGeometry; if ( !geom ) { QgsFeature f; mVlayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureId ) ).nextFeature( f ); mGeometry = new QgsGeometry( *f.geometry() ); } else { mGeometry = new QgsGeometry( *geom ); } }
void QgsPointSample::addSamplePoints( QgsFeature& inputFeature, QgsVectorFileWriter& writer, int nPoints, double minDistance ) { if ( !inputFeature.hasGeometry() ) return; QgsGeometry geom = inputFeature.geometry(); QgsRectangle geomRect = geom.boundingBox(); if ( geomRect.isEmpty() ) { return; } QgsSpatialIndex sIndex; //to check minimum distance QMap< QgsFeatureId, QgsPoint > pointMapForFeature; int nIterations = 0; int maxIterations = nPoints * 200; int points = 0; double randX = 0; double randY = 0; while ( nIterations < maxIterations && points < nPoints ) { randX = (( double )mt_rand() / MD_RAND_MAX ) * geomRect.width() + geomRect.xMinimum(); randY = (( double )mt_rand() / MD_RAND_MAX ) * geomRect.height() + geomRect.yMinimum(); QgsPoint randPoint( randX, randY ); QgsGeometry ptGeom = QgsGeometry::fromPoint( randPoint ); if ( ptGeom.within( geom ) && checkMinDistance( randPoint, sIndex, minDistance, pointMapForFeature ) ) { //add feature to writer QgsFeature f( mNCreatedPoints ); f.setAttribute( QStringLiteral( "id" ), mNCreatedPoints + 1 ); f.setAttribute( QStringLiteral( "station_id" ), points + 1 ); f.setAttribute( QStringLiteral( "stratum_id" ), inputFeature.id() ); f.setGeometry( ptGeom ); writer.addFeature( f ); sIndex.insertFeature( f ); pointMapForFeature.insert( mNCreatedPoints, randPoint ); ++points; ++mNCreatedPoints; } ++nIterations; } }
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 ); }
void QgsLockedFeature::updateGeometry( const QgsGeometry *geom ) { delete mGeometry; if ( !geom ) { QgsFeature f; mLayer->getFeatures( QgsFeatureRequest().setFilterFid( mFeatureId ) ).nextFeature( f ); if ( f.hasGeometry() ) mGeometry = new QgsGeometry( f.geometry() ); else mGeometry = new QgsGeometry(); } else { mGeometry = new QgsGeometry( *geom ); } }
QgsGeometry QgsGeometryAnalyzer::dissolveFeature( const QgsFeature& f, const QgsGeometry& dissolveInto ) { if ( !f.hasGeometry() ) { return dissolveInto; } QgsGeometry featureGeometry = f.geometry(); if ( dissolveInto.isEmpty() ) { return featureGeometry; } else { return dissolveInto.combine( featureGeometry ); } }
void QgsGeometryAnalyzer::centroidFeature( QgsFeature& f, QgsVectorFileWriter* vfw ) { if ( !f.hasGeometry() ) { return; } QgsGeometry featureGeometry = f.geometry(); QgsFeature newFeature; newFeature.setGeometry( featureGeometry.centroid() ); newFeature.setAttributes( f.attributes() ); //add it to vector file writer if ( vfw ) { vfw->addFeature( newFeature ); } }
int QgsVectorLayerEditUtils::translateFeature( QgsFeatureId featureId, double dx, double dy ) { if ( !mLayer->isSpatial() ) return 1; QgsFeature f; if ( !mLayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( f ) || !f.hasGeometry() ) return 1; //geometry not found QgsGeometry geometry = f.geometry(); int errorCode = geometry.translate( dx, dy ); if ( errorCode == 0 ) { mLayer->editBuffer()->changeGeometry( featureId, geometry ); } return errorCode; }
void QgsGeometryAnalyzer::convexFeature( QgsFeature& f, int nProcessedFeatures, QgsGeometry& dissolveGeometry ) { if ( !f.hasGeometry() ) { return; } QgsGeometry featureGeometry = f.geometry(); QgsGeometry convexGeometry = featureGeometry.convexHull(); if ( nProcessedFeatures == 0 ) { dissolveGeometry = convexGeometry; } else { dissolveGeometry = dissolveGeometry.combine( convexGeometry ); } }
QgsGeometry QgsTransectSample::findBaselineGeometry( const QVariant& strataId ) { if ( !mBaselineLayer ) { return QgsGeometry(); } QgsFeatureIterator baseLineIt = mBaselineLayer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QStringList( mBaselineStrataId ), mBaselineLayer->fields() ) ); QgsFeature fet; while ( baseLineIt.nextFeature( fet ) ) //todo: cache this in case there are many baslines { if ( strataId == fet.attribute( mBaselineStrataId ) || mShareBaseline ) { return fet.geometry(); } } return QgsGeometry(); }
QgsFeatureList QgsFilterVerticesAlgorithmBase::processFeature( const QgsFeature &feature, QgsProcessingContext &context, QgsProcessingFeedback * ) { QgsFeature f = feature; if ( f.hasGeometry() ) { QgsGeometry geometry = f.geometry(); double min = mMin; if ( mDynamicMin ) min = mMinProperty.valueAsDouble( context.expressionContext(), std::numeric_limits<double>::quiet_NaN() ); double max = mMax; if ( mDynamicMax ) max = mMaxProperty.valueAsDouble( context.expressionContext(), std::numeric_limits<double>::quiet_NaN() ); filter( geometry, min, max ); f.setGeometry( geometry ); } return QgsFeatureList() << f; }
void QgsVectorLayerFeatureIterator::useChangedAttributeFeature( QgsFeatureId fid, const QgsGeometry& geom, QgsFeature& f ) { f.setFeatureId( fid ); f.setValid( true ); f.setFields( &L->mUpdatedFields ); if ( !( mRequest.flags() & QgsFeatureRequest::NoGeometry ) ) { f.setGeometry( geom ); // simplify the edited geometry using its simplifier configured if ( mEditGeometrySimplifier ) { QgsGeometry* geometry = f.geometry(); QGis::GeometryType geometryType = geometry->type(); if ( geometryType == QGis::Line || geometryType == QGis::Polygon ) mEditGeometrySimplifier->simplifyGeometry( geometry ); } } bool subsetAttrs = ( mRequest.flags() & QgsFeatureRequest::SubsetOfAttributes ); if ( !subsetAttrs || ( subsetAttrs && mRequest.subsetOfAttributes().count() > 0 ) ) { // retrieve attributes from provider QgsFeature tmp; //mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes ); QgsFeatureRequest request; request.setFilterFid( fid ).setFlags( QgsFeatureRequest::NoGeometry ); if ( subsetAttrs ) { request.setSubsetOfAttributes( mProviderRequest.subsetOfAttributes() ); } QgsFeatureIterator fi = L->dataProvider()->getFeatures( request ); if ( fi.nextFeature( tmp ) ) { updateChangedAttributes( tmp ); f.setAttributes( tmp.attributes() ); } } if ( !mFetchJoinInfo.isEmpty() ) addJoinedAttributes( f ); }
void QgsGeometryMultipartCheck::fixError( const QMap<QString, QgsFeaturePool *> &featurePools, QgsGeometryCheckError *error, int method, const QMap<QString, int> & /*mergeAttributeIndices*/, Changes &changes ) const { QgsFeaturePool *featurePool = featurePools[ error->layerId() ]; QgsFeature feature; if ( !featurePool->getFeature( error->featureId(), feature ) ) { error->setObsolete(); return; } QgsGeometry featureGeom = feature.geometry(); const QgsAbstractGeometry *geom = featureGeom.constGet(); // Check if error still applies if ( geom->partCount() > 1 || !QgsWkbTypes::isMultiType( geom->wkbType() ) ) { error->setObsolete(); return; } // Fix error if ( method == NoChange ) { error->setFixed( method ); } else if ( method == ConvertToSingle ) { feature.setGeometry( QgsGeometry( QgsGeometryCheckerUtils::getGeomPart( geom, 0 )->clone() ) ); featurePool->updateFeature( feature ); error->setFixed( method ); changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeChanged ) ); } else if ( method == RemoveObject ) { featurePool->deleteFeature( feature.id() ); error->setFixed( method ); changes[error->layerId()][feature.id()].append( Change( ChangeFeature, ChangeRemoved ) ); } else { error->setFixFailed( tr( "Unknown method" ) ); } }