예제 #1
0
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;
}
예제 #2
0
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 );
    }
  }

}
예제 #3
0
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;
}
예제 #4
0
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 );
}
예제 #5
0
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;
}
예제 #6
0
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 );
      }
    }
  }
}
예제 #7
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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 );
    }
  }
}
예제 #15
0
QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap &parameters, 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;
}
예제 #16
0
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;
}
예제 #18
0
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 );
  }
}
예제 #19
0
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 );
    }
}
예제 #20
0
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;
  }
}
예제 #21
0
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 );
}
예제 #22
0
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 );
  }
}
예제 #25
0
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 );
  }
}
예제 #27
0
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" ) );
  }
}