示例#1
0
void QgsSpatialQuery::populateIndexResultDisjoint(
  QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry * geomTarget,
  bool ( QgsGeometry::* op )( QgsGeometry * ) )
{
  QList<QgsFeatureId> listIdReference;
  listIdReference = mIndexReference.intersects( geomTarget->boundingBox() );
  if ( listIdReference.count() == 0 )
  {
    qsetIndexResult.insert( idTarget );
    return;
  }
  QgsFeature featureReference;
  QgsGeometry * geomReference;
  QList<QgsFeatureId>::iterator iterIdReference = listIdReference.begin();
  bool addIndex = true;
  for ( ; iterIdReference != listIdReference.end(); iterIdReference++ )
  {
    mLayerReference->featureAtId( *iterIdReference, featureReference );
    geomReference = featureReference.geometry();

    if ( !( geomTarget->*op )( geomReference ) )
    {
      addIndex = false;
      break;
    }
  }
  if ( addIndex )
  {
    qsetIndexResult.insert( idTarget );
  }

} // void QgsSpatialQuery::populateIndexResultDisjoint( ...
示例#2
0
void QgsOfflineEditing::committedFeaturesRemoved( const QString& qgisLayerId, const QgsFeatureIds& deletedFeatureIds )
{
  sqlite3* db = openLoggingDb();
  if ( db == NULL )
  {
    return;
  }

  // insert log
  int layerId = getOrCreateLayerId( db, qgisLayerId );

  for ( QgsFeatureIds::const_iterator it = deletedFeatureIds.begin(); it != deletedFeatureIds.end(); ++it )
  {
    if ( isAddedFeature( db, layerId, *it ) )
    {
      // remove from added features log
      QString sql = QString( "DELETE FROM 'log_added_features' WHERE \"layer_id\" = %1 AND \"fid\" = %2" ).arg( layerId ).arg( *it );
      sqlExec( db, sql );
    }
    else
    {
      QString sql = QString( "INSERT INTO 'log_removed_features' VALUES ( %1, %2)" )
                    .arg( layerId )
                    .arg( *it );
      sqlExec( db, sql );
    }
  }

  sqlite3_close( db );
}
示例#3
0
void QgsSpatialQuery::populateIndexResultDisjoint(
  QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry * geomTarget,
  bool ( QgsGeometryEngine::* op )( const QgsAbstractGeometryV2&, QString* ) const )
{
  QgsFeatureIds listIdReference = mIndexReference.intersects( geomTarget->boundingBox() ).toSet();
  if ( listIdReference.isEmpty() )
  {
    qsetIndexResult.insert( idTarget );
    return;
  }

  //prepare geometry
  QgsGeometryEngine* geomEngine = geomTarget->createGeometryEngine( geomTarget->geometry() );
  geomEngine->prepareGeometry();

  QgsFeature featureReference;
  const QgsGeometry * geomReference;
  QgsFeatureIterator listIt = mLayerReference->getFeatures( QgsFeatureRequest().setFilterFids( listIdReference ) );

  bool addIndex = true;
  while ( listIt.nextFeature( featureReference ) )
  {
    geomReference = featureReference.constGeometry();
    if (( geomEngine->*op )( *( geomReference->geometry() ), 0 ) )
    {
      addIndex = false;
      break;
    }
  }
  if ( addIndex )
  {
    qsetIndexResult.insert( idTarget );
  }
  delete geomEngine;
} // void QgsSpatialQuery::populateIndexResultDisjoint( ...
示例#4
0
bool QgsWFSProvider::deleteFeatures( const QgsFeatureIds &id )
{
  if ( id.size() < 1 )
  {
    return true;
  }

  //find out typename from uri and strip namespace prefix
  QString tname = mShared->mURI.typeName();
  if ( tname.isNull() )
  {
    return false;
  }

  //create <Transaction> xml
  QDomDocument transactionDoc;
  QDomElement transactionElem = createTransactionElement( transactionDoc );
  transactionDoc.appendChild( transactionElem );
  //delete element
  QDomElement deleteElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Delete" );
  deleteElem.setAttribute( "typeName", tname );
  QDomElement filterElem = transactionDoc.createElementNS( QgsWFSConstants::OGC_NAMESPACE, "Filter" );


  QgsFeatureIds::const_iterator idIt = id.constBegin();
  for ( ; idIt != id.constEnd(); ++idIt )
  {
    //find out feature id
    QString gmlid = mShared->findGmlId( *idIt );
    if ( gmlid.isEmpty() )
    {
      QgsDebugMsg( QString( "Cannot identify feature of id %1" ).arg( *idIt ) );
      continue;
    }
    QDomElement featureIdElem = transactionDoc.createElementNS( QgsWFSConstants::OGC_NAMESPACE, "FeatureId" );
    featureIdElem.setAttribute( "fid", gmlid );
    filterElem.appendChild( featureIdElem );
  }

  deleteElem.appendChild( filterElem );
  transactionElem.appendChild( deleteElem );

  QDomDocument serverResponse;
  bool success = sendTransactionDocument( transactionDoc, serverResponse );
  if ( !success )
  {
    return false;
  }

  if ( transactionSuccess( serverResponse ) )
  {
    mShared->deleteFeatures( id );
    return true;
  }
  else
  {
    handleException( serverResponse );
    return false;
  }
}
示例#5
0
void QgsSpatialQuery::populateIndexResultDisjoint(
    QgsFeatureIds &qsetIndexResult, QgsFeatureId idTarget, QgsGeometry * geomTarget,
    bool ( QgsGeometry::* op )( const QgsGeometry * ) const )
{
    QList<QgsFeatureId> listIdReference;
    listIdReference = mIndexReference.intersects( geomTarget->boundingBox() );
    if ( listIdReference.isEmpty() )
    {
        qsetIndexResult.insert( idTarget );
        return;
    }
    QgsFeature featureReference;
    const QgsGeometry * geomReference;
    QList<QgsFeatureId>::iterator iterIdReference = listIdReference.begin();
    bool addIndex = true;
    for ( ; iterIdReference != listIdReference.end(); ++iterIdReference )
    {
        mLayerReference->getFeatures( QgsFeatureRequest().setFilterFid( *iterIdReference ) ).nextFeature( featureReference );
        geomReference = featureReference.constGeometry();

        if ( !( geomTarget->*op )( geomReference ) )
        {
            addIndex = false;
            break;
        }
    }
    if ( addIndex )
    {
        qsetIndexResult.insert( idTarget );
    }

} // void QgsSpatialQuery::populateIndexResultDisjoint( ...
void QgsMapToolShowHideLabels::showHideLabels( QMouseEvent * e )
{
  QgsMapLayer* layer = mCanvas->currentLayer();

  QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( layer );
  if ( !vlayer )
  {
    QgsDebugMsg( "Failed to cast label layer to vector layer" );
    return;
  }
  if ( !vlayer->isEditable() )
  {
    QgsDebugMsg( "Vector layer not editable, skipping label" );
    return;
  }

  bool doHide = e->modifiers() & Qt::ShiftModifier;
  bool labelChanged = false;
  QString editTxt = doHide ? tr( "Hid labels" ) : tr( "Showed labels" );
  vlayer->beginEditCommand( editTxt );

  if ( !doHide )
  {
    QgsDebugMsg( "Showing labels operation" );

    QgsFeatureIds selectedFeatIds;
    if ( !selectedFeatures( vlayer, selectedFeatIds ) )
    {
      vlayer->destroyEditCommand();
      return;
    }

    QgsDebugMsg( "Number of selected labels or features: " + QString::number( selectedFeatIds.size() ) );

    if ( selectedFeatIds.isEmpty() )
    {
      vlayer->destroyEditCommand();
      return;
    }

    Q_FOREACH ( QgsFeatureId fid, selectedFeatIds )
    {
      mCurrentLabel.pos.featureId = fid;

      mCurrentLabel.pos.isDiagram = false;
      bool labChanged = showHide( vlayer, true );

      mCurrentLabel.pos.isDiagram = true;
      bool diagChanged = showHide( vlayer, true );

      if ( labChanged || diagChanged )
      {
        // TODO: highlight features (maybe with QTimer?)
        labelChanged = labelChanged || true;
      }
    }
示例#7
0
void QgsSpatialQueryDialog::on_cbTypeItems_currentIndexChanged( int index )
{
  // Get Value type Item
  QVariant qtypItem = cbTypeItems->itemData( index );
  TypeItems typeItem = ( TypeItems ) qtypItem.toInt();

  QgsFeatureIds *setItems = 0;
  int totalFeat = mLayerTarget->featureCount();
  switch ( typeItem )
  {
    case itemsResult:
      setItems = &mFeatureResult;
      break;
    case itemsInvalidTarget:
      setItems = &mFeatureInvalidTarget;
      break;
    case itemsInvalidReference:
      setItems = &mFeatureInvalidReference;
      totalFeat = mLayerReference->featureCount();
      break;
    default:
      return;
  }

  lwFeatures->blockSignals( true );
  lwFeatures->clear();
  int totalItens = setItems->size();
  if ( totalItens > 0 )
  {
    // Populate lwFeatures
    QSetIterator <QgsFeatureId> item( *setItems );
    QListWidgetItem *lwItem = NULL;
    while ( item.hasNext() )
    {
      lwItem = new QListWidgetItem( lwFeatures );
      QVariant fid  = QVariant( item.next() );
      lwItem->setData( Qt::UserRole, fid ); // Data
      lwItem->setData( Qt::DisplayRole, fid ); // Label
      lwFeatures->addItem( lwItem );
    }
    lwFeatures->sortItems();
    lwFeatures->blockSignals( false );
    lwFeatures->setCurrentRow( 0 ); // Has signal/slot for change current item in ListWidget
  }
  else
  {
    mRubberSelectId->reset();
    lwFeatures->blockSignals( false );
  }
  // Set lbStatusItems and pbCreateLayer
  QString formatLabel( tr( "%1 of %2 identified" ) );
  lbStatusItems->setText( formatLabel.arg( totalItens ).arg( totalFeat ) );
  pbCreateLayerItems->setEnabled( totalItens > 0 );
  ckbZoomItem->setEnabled( totalItens > 0 );
}
QgsFeatureIds QgsAttributeTableFilterModel::filteredFeatures()
{
  QgsFeatureIds ids;
  ids.reserve( rowCount() );
  for ( int i = 0; i < rowCount(); ++i )
  {
    QModelIndex row = index( i, 0 );
    ids << rowToId( row );
  }
  return ids;
}
void QgsAttributeTableView::onVerticalHeaderSectionClicked( int logicalIndex )
{
  Q_UNUSED( logicalIndex )

  QgsFeatureIds selectedFeatures;

  QModelIndexList selectedRows = selectionModel()->selectedRows();

  foreach ( QModelIndex row, selectedRows )
  {
    selectedFeatures.insert( mFilterModel->rowToId( row ) );
  }
void QgsGeometryFollowBoundariesCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &/*messages*/, QAtomicInt *progressCounter, const QMap<QString, QgsFeatureIds> &ids ) const
{
  if ( !mIndex || !mCheckLayer )
  {
    return;
  }

  QMap<QString, QgsFeatureIds> featureIds = ids.isEmpty() ? allLayerFeatureIds() : ids;
  featureIds.remove( mCheckLayer->id() ); // Don't check layer against itself
  QgsGeometryCheckerUtils::LayerFeatures layerFeatures( mContext->featurePools, featureIds, mCompatibleGeometryTypes, progressCounter );
  for ( const QgsGeometryCheckerUtils::LayerFeature &layerFeature : layerFeatures )
  {
    const QgsAbstractGeometry *geom = layerFeature.geometry();

    // The geometry to crs of the check layer
    QgsCoordinateTransform crst = QgsCoordinateTransformCache::instance()->transform( layerFeature.layer().crs().authid(), mCheckLayer->crs().authid() );
    QScopedPointer<QgsAbstractGeometry> geomt( geom->clone() );
    geomt->transform( crst );

    QSharedPointer<QgsGeometryEngine> geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geomt.data(), mContext->tolerance );

    // Get potential reference features
    QgsRectangle searchBounds = geomt->boundingBox();
    searchBounds.grow( mContext->tolerance );
    QgsFeatureIds refFeatureIds = mIndex->intersects( searchBounds ).toSet();

    QgsFeatureRequest refFeatureRequest = QgsFeatureRequest().setFilterFids( refFeatureIds ).setSubsetOfAttributes( QgsAttributeList() );
    QgsFeatureIterator refFeatureIt = mCheckLayer->getFeatures( refFeatureRequest );

    if ( refFeatureIds.isEmpty() )
    {
      // If no potential reference features are found, the geometry is definitely not following boundaries of reference layer features
      errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
    }
    else
    {
      // All reference features must be either contained or disjoint from tested geometry
      QgsFeature refFeature;
      while ( refFeatureIt.nextFeature( refFeature ) )
      {
        QgsAbstractGeometry *refGeom = refFeature.geometry().geometry();
        QSharedPointer<QgsGeometryEngine> refgeomEngine = QgsGeometryCheckerUtils::createGeomEngine( refGeom, mContext->tolerance );
        QScopedPointer<QgsAbstractGeometry> reducedRefGeom( refgeomEngine->buffer( -mContext->tolerance, 0 ) );
        if ( !( geomEngine->contains( reducedRefGeom.data() ) || geomEngine->disjoint( reducedRefGeom.data() ) ) )
        {
          errors.append( new QgsGeometryCheckError( this, layerFeature, QgsPointXY( geom->centroid() ) ) );
          break;
        }
      }
    }
  }
}
示例#11
0
bool QgsVectorLayerTools::copyMoveFeatures( QgsVectorLayer* layer, QgsFeatureRequest& request, double dx, double dy, QString* errorMsg ) const
{
    bool res = false;
    if ( !layer || !layer->isEditable() )
    {
        return false;
    }

    QgsFeatureIterator fi = layer->getFeatures( request );
    QgsFeature f;
    QgsAttributeList pkAttrList = layer->pkAttributeList();

    int browsedFeatureCount = 0;
    int couldNotWriteCount = 0;
    int noGeometryCount = 0;

    QgsFeatureIds fidList;

    while ( fi.nextFeature( f ) )
    {
        browsedFeatureCount++;
        // remove pkey values
        Q_FOREACH ( auto idx, pkAttrList )
        {
            f.setAttribute( idx, QVariant() );
        }
        // translate
        if ( f.hasGeometry() )
        {
            QgsGeometry geom = f.geometry();
            geom.translate( dx, dy );
            f.setGeometry( geom );
#ifdef QGISDEBUG
            const QgsFeatureId fid = f.id();
#endif
            // paste feature
            if ( !layer->addFeature( f, false ) )
            {
                couldNotWriteCount++;
                QgsDebugMsg( QString( "Could not add new feature. Original copied feature id: %1" ).arg( fid ) );
            }
            else
            {
                fidList.insert( f.id() );
            }
        }
        else
        {
            noGeometryCount++;
        }
    }
示例#12
0
void QgsOfflineEditing::applyFeaturesRemoved( QgsVectorLayer* remoteLayer, sqlite3* db, int layerId )
{
  QString sql = QString( "SELECT \"fid\" FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).arg( layerId );
  QgsFeatureIds values = sqlQueryFeaturesRemoved( db, sql );

  emit progressModeSet( QgsOfflineEditing::RemoveFeatures, values.size() );

  int i = 1;
  for ( QgsFeatureIds::const_iterator it = values.begin(); it != values.end(); ++it )
  {
    QgsFeatureId fid = remoteFid( db, layerId, *it );
    remoteLayer->deleteFeature( fid );

    emit progressUpdated( i++ );
  }
}
void QgsOfflineEditing::applyFeaturesRemoved( QgsVectorLayer* remoteLayer, sqlite3* db, int layerId )
{
  QString sql = QString( "SELECT \"fid\" FROM 'log_removed_features' WHERE \"layer_id\" = %1" ).arg( layerId );
  QgsFeatureIds values = sqlQueryFeaturesRemoved( db, sql );

  mProgressDialog->setupProgressBar( tr( "%v / %m features removed" ), values.size() );

  int i = 1;
  for ( QgsFeatureIds::const_iterator it = values.begin(); it != values.end(); ++it )
  {
    int fid = remoteFid( db, layerId, *it );
    remoteLayer->deleteFeature( fid );

    mProgressDialog->setProgressValue( i++ );
  }
}
void QgsGeometryAreaCheck::collectErrors( QList<QgsGeometryCheckError*>& errors, QStringList &/*messages*/, QAtomicInt* progressCounter , const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds& featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  foreach ( const QgsFeatureId& featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }

    QgsAbstractGeometryV2* geom = feature.geometry()->geometry();
    if ( dynamic_cast<QgsGeometryCollectionV2*>( geom ) )
    {
      QgsGeometryCollectionV2* multiGeom = static_cast<QgsGeometryCollectionV2*>( geom );
      for ( int i = 0, n = multiGeom->numGeometries(); i < n; ++i )
      {
        double value;
        if ( checkThreshold( multiGeom->geometryN( i ), value ) )
        {
          errors.append( new QgsGeometryCheckError( this, featureid, multiGeom->geometryN( i )->centroid(), QgsVertexId( i ), value, QgsGeometryCheckError::ValueArea ) );
        }
      }
    }
    else
    {
      double value;
      if ( checkThreshold( geom, value ) )
      {
        errors.append( new QgsGeometryCheckError( this, featureid, geom->centroid(), QgsVertexId( 0 ), value, QgsGeometryCheckError::ValueArea ) );
      }
    }
  }
}
QgsCachedFeatureIterator::QgsCachedFeatureIterator( QgsVectorLayerCache *vlCache, QgsFeatureRequest featureRequest, QgsFeatureIds featureIds )
    : QgsAbstractFeatureIterator( featureRequest )
    , mFeatureIds( featureIds )
    , mVectorLayerCache( vlCache )
{
  mFeatureIdIterator = featureIds.begin();
}
示例#16
0
void QgsDualView::flashCurrentFeature()
{
  QModelIndex currentIndex = mTableView->currentIndex();
  if ( !currentIndex.isValid() )
  {
    return;
  }

  QgsFeatureIds ids;
  ids.insert( mFilterModel->rowToId( currentIndex ) );
  QgsMapCanvas *canvas = mFilterModel->mapCanvas();
  if ( canvas )
  {
    canvas->flashFeatureIds( mLayer, ids );
  }
}
void QgsGeometrySelfIntersectionCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &/*messages*/, QAtomicInt *progressCounter, const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds &featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  Q_FOREACH ( QgsFeatureId featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }
    QgsGeometry featureGeom = feature.geometry();
    QgsAbstractGeometry *geom = featureGeom.geometry();

    for ( int iPart = 0, nParts = geom->partCount(); iPart < nParts; ++iPart )
    {
      for ( int iRing = 0, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
      {
        Q_FOREACH ( const QgsGeometryUtils::SelfIntersection &inter, QgsGeometryUtils::getSelfIntersections( geom, iPart, iRing, QgsGeometryCheckPrecision::tolerance() ) )
        {
          errors.append( new QgsGeometrySelfIntersectionCheckError( this, featureid, inter.point, QgsVertexId( iPart, iRing ), inter ) );
        }
      }
    }
  }
void QgsGeometryDuplicateNodesCheck::collectErrors( QList<QgsGeometryCheckError*>& errors, QStringList &/*messages*/, QAtomicInt* progressCounter , const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds& featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  Q_FOREACH ( QgsFeatureId featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }

    QgsGeometry featureGeom = feature.geometry();
    QgsAbstractGeometry* geom = featureGeom.geometry();
    for ( int iPart = 0, nParts = geom->partCount(); iPart < nParts; ++iPart )
    {
      for ( int iRing = 0, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
      {
        int nVerts = QgsGeometryCheckerUtils::polyLineSize( geom, iPart, iRing );
        if ( nVerts < 2 )
          continue;
        for ( int iVert = nVerts - 1, jVert = 0; jVert < nVerts; iVert = jVert++ )
        {
          QgsPointV2 pi = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
          QgsPointV2 pj = geom->vertexAt( QgsVertexId( iPart, iRing, jVert ) );
          if ( QgsGeometryUtils::sqrDistance2D( pi, pj ) < QgsGeometryCheckPrecision::tolerance() * QgsGeometryCheckPrecision::tolerance() )
          {
            errors.append( new QgsGeometryCheckError( this, featureid, pj, QgsVertexId( iPart, iRing, jVert ) ) );
          }
        }
      }
    }
  }
}
示例#19
0
void QgsLine3DSymbolEntity::addEntityForNotSelectedLines( const Qgs3DMapSettings &map, QgsVectorLayer *layer, const QgsLine3DSymbol &symbol )
{
  // build the default material
  Qt3DExtras::QPhongMaterial *mat = material( symbol );

  // build the feature request to select features
  QgsFeatureRequest req;
  req.setDestinationCrs( map.crs(), map.transformContext() );

  QgsFeatureIds notSelected = layer->allFeatureIds();
  notSelected.subtract( layer->selectedFeatureIds() );
  req.setFilterFids( notSelected );

  // build the entity
  QgsLine3DSymbolEntityNode *entity = new QgsLine3DSymbolEntityNode( map, layer, symbol, req );
  entity->addComponent( mat );
  entity->setParent( this );
}
示例#20
0
void QgsFeaturePool::addFeature( QgsFeature &feature )
{
  QgsFeatureList features;
  features.append( feature );
  mLayerMutex.lock();
  mLayer->dataProvider()->addFeatures( features );
  feature.setId( features.front().id() );
  if ( mSelectedOnly )
  {
    QgsFeatureIds selectedFeatureIds = mLayer->selectedFeatureIds();
    selectedFeatureIds.insert( feature.id() );
    mLayer->selectByIds( selectedFeatureIds );
  }
  mLayerMutex.unlock();
  mIndexMutex.lock();
  mIndex.insertFeature( feature );
  mIndexMutex.unlock();
}
示例#21
0
void QgsGeometryOverlapCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &messages, QAtomicInt *progressCounter, const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds &featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  Q_FOREACH ( QgsFeatureId featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }
    QgsGeometry featureGeom = feature.geometry();
    QgsAbstractGeometry *geom = featureGeom.geometry();
    QgsGeometryEngine *geomEngine = QgsGeometryCheckerUtils::createGeomEngine( geom, QgsGeometryCheckPrecision::tolerance() );

    QgsFeatureIds ids = mFeaturePool->getIntersects( feature.geometry().boundingBox() );
    Q_FOREACH ( QgsFeatureId otherid, ids )
    {
      // >= : only report overlaps once
      if ( otherid >= featureid )
      {
        continue;
      }

      QgsFeature otherFeature;
      if ( !mFeaturePool->get( otherid, otherFeature ) )
      {
        continue;
      }

      QString errMsg;
      if ( geomEngine->overlaps( *otherFeature.geometry().geometry(), &errMsg ) )
      {
        QgsAbstractGeometry *interGeom = geomEngine->intersection( *otherFeature.geometry().geometry() );
        if ( interGeom && !interGeom->isEmpty() )
        {
          QgsGeometryCheckerUtils::filter1DTypes( interGeom );
          for ( int iPart = 0, nParts = interGeom->partCount(); iPart < nParts; ++iPart )
          {
            double area = QgsGeometryCheckerUtils::getGeomPart( interGeom, iPart )->area();
            if ( area > QgsGeometryCheckPrecision::reducedTolerance() && area < mThreshold )
            {
              errors.append( new QgsGeometryOverlapCheckError( this, featureid, QgsGeometryCheckerUtils::getGeomPart( interGeom, iPart )->centroid(), area, otherid ) );
            }
          }
        }
        else if ( !errMsg.isEmpty() )
        {
          messages.append( tr( "Overlap check between features %1 and %2: %3" ).arg( feature.id() ).arg( otherFeature.id() ).arg( errMsg ) );
        }
        delete interGeom;
      }
    }
    delete geomEngine;
  }
}
QVariantMap QgsSelectByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
  QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral( "INPUT" ), context );
  QgsVectorLayer::SelectBehavior method = static_cast< QgsVectorLayer::SelectBehavior >( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
  std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
  const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );

  QgsFeatureIds selectedIds;
  auto addToSelection = [&]( const QgsFeature & feature )
  {
    selectedIds.insert( feature.id() );
  };
  process( selectLayer, intersectSource.get(), selectedPredicates, addToSelection, true, feedback );

  selectLayer->selectByIds( selectedIds, method );
  QVariantMap results;
  results.insert( QStringLiteral( "OUTPUT" ), parameters.value( QStringLiteral( "INPUT" ) ) );
  return results;
}
示例#23
0
QgsFeatureIds QgsAfsSharedData::getFeatureIdsInExtent( const QgsRectangle &extent, QgsFeedback *feedback )
{
  QString errorTitle;
  QString errorText;

  const QString authcfg = mDataSource.authConfigId();
  const QList<quint32> featuresInRect = QgsArcGisRestUtils::getObjectIdsByExtent( mDataSource.param( QStringLiteral( "url" ) ),
                                        mObjectIdFieldName,
                                        extent, errorTitle, errorText, authcfg, feedback );

  QgsFeatureIds ids;
  for ( quint32 id : featuresInRect )
  {
    int featureId = mObjectIds.indexOf( id );
    if ( featureId >= 0 )
      ids.insert( featureId );
  }
  return ids;
}
bool QgsMemoryProvider::deleteFeatures( const QgsFeatureIds & id )
{
  for ( QgsFeatureIds::const_iterator it = id.begin(); it != id.end(); ++it )
  {
    QgsFeatureMap::iterator fit = mFeatures.find( *it );

    // check whether such feature exists
    if ( fit == mFeatures.end() )
      continue;

    // update spatial index
    if ( mSpatialIndex )
      mSpatialIndex->deleteFeature( *fit );

    mFeatures.erase( fit );
  }

  updateExtent();

  return TRUE;
}
bool QgsMapToolShowHideLabels::selectedFeatures( QgsVectorLayer* vlayer,
    QgsFeatureIds& selectedFeatIds )
{
  // culled from QgsMapToolSelectUtils::setSelectFeatures()

  QgsGeometry* selectGeometry = mRubberBand->asGeometry();

  // toLayerCoordinates will throw an exception for any 'invalid' points in
  // the rubber band.
  // For example, if you project a world map onto a globe using EPSG 2163
  // and then click somewhere off the globe, an exception will be thrown.
  QgsGeometry selectGeomTrans( *selectGeometry );

  if ( mRender->hasCrsTransformEnabled() )
  {
    try
    {
      QgsCoordinateTransform ct( mRender->destinationCrs(), vlayer->crs() );
      selectGeomTrans.transform( ct );
    }
    catch ( QgsCsException &cse )
    {
      Q_UNUSED( cse );
      // catch exception for 'invalid' point and leave existing selection unchanged
      QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
      QMessageBox::warning( mCanvas, QObject::tr( "CRS Exception" ),
                            QObject::tr( "Selection extends beyond layer's coordinate system." ) );
      return false;
    }
  }

  QApplication::setOverrideCursor( Qt::WaitCursor );

  QgsDebugMsg( "Selection layer: " + vlayer->name() );
  QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() );

  QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectGeomTrans.boundingBox() ).setFlags( QgsFeatureRequest::NoGeometry | QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) );

  QgsFeature f;
  while ( fit.nextFeature( f ) )
  {
    QgsGeometry* g = f.geometry();

    if ( !selectGeomTrans.intersects( g ) )
      continue;

    selectedFeatIds.insert( f.id() );
  }

  QApplication::restoreOverrideCursor();

  return true;
}
void QgsMapToolSelectUtils::selectSingleFeature( QgsMapCanvas *canvas, const QgsGeometry &selectGeometry, Qt::KeyboardModifiers modifiers )
{
  QgsVectorLayer *vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas );
  if ( !vlayer )
    return;

  QApplication::setOverrideCursor( Qt::WaitCursor );

  QgsFeatureIds selectedFeatures = getMatchingFeatures( canvas, selectGeometry, false, true );
  if ( selectedFeatures.isEmpty() )
  {
    if ( !( modifiers & Qt::ShiftModifier || modifiers & Qt::ControlModifier ) )
    {
      // if no modifiers then clicking outside features clears the selection
      // but if there's a shift or ctrl modifier, then it's likely the user was trying
      // to modify an existing selection by adding or subtracting features and just
      // missed the feature
      vlayer->removeSelection();
    }
    QApplication::restoreOverrideCursor();
    return;
  }

  QgsVectorLayer::SelectBehavior behavior = QgsVectorLayer::SetSelection;

  //either shift or control modifier switches to "toggle" selection mode
  if ( modifiers & Qt::ShiftModifier || modifiers & Qt::ControlModifier )
  {
    QgsFeatureId selectId = *selectedFeatures.constBegin();
    QgsFeatureIds layerSelectedFeatures = vlayer->selectedFeatureIds();
    if ( layerSelectedFeatures.contains( selectId ) )
      behavior = QgsVectorLayer::RemoveFromSelection;
    else
      behavior = QgsVectorLayer::AddToSelection;
  }

  vlayer->selectByIds( selectedFeatures, behavior );

  QApplication::restoreOverrideCursor();
}
示例#27
0
/**
* Selection routine called by the mouse release event
* @param thePoint = QgsPoint representing the x, y coordinates of the mouse release event
*/
void eVisEventIdTool::select( QgsPoint thePoint )
{

  if ( 0 == mCanvas )
    return;

  QgsVectorLayer* myLayer = ( QgsVectorLayer* )mCanvas->currentLayer( );

  // create the search rectangle. this was modeled after the QgsMapIdentifyTool in core QGIS application
  double searchWidth = mCanvas->extent( ).width( ) * (( double )QGis::DEFAULT_IDENTIFY_RADIUS / 100.0 );

  QgsRectangle myRectangle;
  myRectangle.setXMinimum( thePoint.x( ) - searchWidth );
  myRectangle.setXMaximum( thePoint.x( ) + searchWidth );
  myRectangle.setYMinimum( thePoint.y( ) - searchWidth );
  myRectangle.setYMaximum( thePoint.y( ) + searchWidth );

  //Transform rectange to map coordinates
  myRectangle = toLayerCoordinates( myLayer, myRectangle );

  //Rather than add to the current selection, clear all selected features
  myLayer->removeSelection( false );
  //select features
  QgsFeatureIterator fit = myLayer->getFeatures( QgsFeatureRequest().setFilterRect( myRectangle ).setFlags( QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) );

  QgsFeature f;
  QgsFeatureIds newSelectedFeatures;
  while ( fit.nextFeature( f ) )
  {
    newSelectedFeatures.insert( f.id() );
  }

  myLayer->setSelectedFeatures( newSelectedFeatures );

  //Launch a new event browser to view selected features
  mBrowser = new eVisGenericEventBrowserGui( mCanvas, mCanvas, NULL );
  mBrowser->setAttribute( Qt::WA_DeleteOnClose );
}
示例#28
0
void QgsGeometryAngleCheck::collectErrors( QList<QgsGeometryCheckError *> &errors, QStringList &/*messages*/, QAtomicInt *progressCounter, const QgsFeatureIds &ids ) const
{
  const QgsFeatureIds &featureIds = ids.isEmpty() ? mFeaturePool->getFeatureIds() : ids;
  Q_FOREACH ( QgsFeatureId featureid, featureIds )
  {
    if ( progressCounter ) progressCounter->fetchAndAddRelaxed( 1 );
    QgsFeature feature;
    if ( !mFeaturePool->get( featureid, feature ) )
    {
      continue;
    }
    QgsGeometry g = feature.geometry();
    const QgsAbstractGeometry *geom = g.geometry();
    for ( int iPart = 0, nParts = geom->partCount(); iPart < nParts; ++iPart )
    {
      for ( int iRing = 0, nRings = geom->ringCount( iPart ); iRing < nRings; ++iRing )
      {
        int nVerts = QgsGeometryCheckerUtils::polyLineSize( geom, iPart, iRing );
        // Less than three points, no angles to check
        if ( nVerts < 3 )
        {
          continue;
        }
        for ( int iVert = 0; iVert < nVerts; ++iVert )
        {
          const QgsPoint &p1 = geom->vertexAt( QgsVertexId( iPart, iRing, ( iVert - 1 + nVerts ) % nVerts ) );
          const QgsPoint &p2 = geom->vertexAt( QgsVertexId( iPart, iRing, iVert ) );
          const QgsPoint &p3 = geom->vertexAt( QgsVertexId( iPart, iRing, ( iVert + 1 ) % nVerts ) );
          QgsVector v21, v23;
          try
          {
            v21 = QgsVector( p1.x() - p2.x(), p1.y() - p2.y() ).normalized();
            v23 = QgsVector( p3.x() - p2.x(), p3.y() - p2.y() ).normalized();
          }
          catch ( const QgsException & )
          {
            // Zero length vectors
            continue;
          }

          double angle = std::acos( v21 * v23 ) / M_PI * 180.0;
          if ( angle < mMinAngle )
          {
            errors.append( new QgsGeometryCheckError( this, featureid, p2, QgsVertexId( iPart, iRing, iVert ), angle ) );
          }
        }
      }
    }
  }
}
示例#29
0
bool QgsDb2Provider::deleteFeatures( const QgsFeatureIds & id )
{
  if ( mFidColName.isEmpty() )
    return false;

  QString featureIds;
  for ( QgsFeatureIds::const_iterator it = id.begin(); it != id.end(); ++it )
  {
    if ( featureIds.isEmpty() )
      featureIds = FID_TO_STRING( *it );
    else
      featureIds += ',' + FID_TO_STRING( *it );
  }

  if ( !mDatabase.isOpen() )
  {
    QString errMsg;
    mDatabase = getDatabase( mConnInfo, errMsg );
    if ( !errMsg.isEmpty() )
    {
      return false;
    }
  }
  QSqlQuery query = QSqlQuery( mDatabase );
  query.setForwardOnly( true );
  QString statement;
  statement = QString( "DELETE FROM %1.%2 WHERE %3 IN (%4)" ).arg( mSchemaName,
              mTableName, mFidColName, featureIds );
  QgsDebugMsg( statement );
  if ( !query.exec( statement ) )
  {
    QgsDebugMsg( query.lastError().text() );
    return false;
  }

  return true;
}
示例#30
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;
}