Exemplo n.º 1
0
void OptMapToolDeleteLink::deleteSelected( QgsVectorLayer *layer )
{
	if ( !( layer->dataProvider()->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
	{
		QMessageBox::information( 0, tr( "Provider does not support deletion" ),
			tr( "Data provider does not support deleting features" ) );
		return;
	}

	if ( !layer->isEditable() )
	{
		QMessageBox::information( 0, tr( "Layer not editable" ),
			tr( "The current layer is not editable. Choose 'Start editing' in the digitizing toolbar." ) );
		return;
	}

	//display a warning
	int numberOfDeletedFeatures = layer->selectedFeaturesIds().size();
	if ( QMessageBox::warning( 0, tr( "Delete features" ), tr( "Delete %n feature(s)?", "number of features to delete", numberOfDeletedFeatures ), QMessageBox::Ok, QMessageBox::Cancel ) == QMessageBox::Cancel )
	{
		return;
	}

	//change the endpoint connected information and deleted endpoints if necessary
	QgsFeatureList features = layer->selectedFeatures();
	OptFeature selectedFeature;
	if ( features.count() > 0)
		selectedFeature = features[0];
	if ( !selectedFeature.isValid() )
		return;

	//selectedFeature.

	//OptFeature feature;
	//lineLayer->getFeatureAtId_(lineID, feature);

	//lineLayer->changeAttribute(feature, OPT::LineFields_LENGTH, QVariant(lineLength));
	//

	//delete the selected line
	layer->beginEditCommand( tr( "Features deleted" ) );
	if ( !layer->deleteSelectedFeatures() )
	{
		QMessageBox::information( 0, tr( "Problem deleting features" ),
			tr( "A problem occured during deletion of features" ) );
	}

	layer->endEditCommand();
}
bool QgsVectorLayerEditBuffer::commitChanges( QStringList& commitErrors )
{
  QgsVectorDataProvider* provider = L->dataProvider();
  commitErrors.clear();

  int cap = provider->capabilities();
  bool success = true;

  QgsFields oldFields = L->pendingFields();

  //
  // delete attributes
  //
  bool attributesChanged = false;
  if ( !mDeletedAttributeIds.isEmpty() )
  {
    if (( cap & QgsVectorDataProvider::DeleteAttributes ) && provider->deleteAttributes( mDeletedAttributeIds.toSet() ) )
    {
      commitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );

      emit committedAttributesDeleted( L->id(), mDeletedAttributeIds );

      mDeletedAttributeIds.clear();
      attributesChanged = true;
    }
    else
    {
      commitErrors << tr( "ERROR: %n attribute(s) not deleted.", "not deleted attributes count", mDeletedAttributeIds.size() );
      success = false;
    }
  }

  //
  // add attributes
  //
  if ( !mAddedAttributes.isEmpty() )
  {
    if (( cap & QgsVectorDataProvider::AddAttributes ) && provider->addAttributes( mAddedAttributes ) )
    {
      commitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributes.size() );

      emit committedAttributesAdded( L->id(), mAddedAttributes );

      mAddedAttributes.clear();
      attributesChanged = true;
    }
    else
    {
      commitErrors << tr( "ERROR: %n new attribute(s) not added", "not added attributes count", mAddedAttributes.size() );
      success = false;
    }
  }

  //
  // check that addition/removal went as expected
  //
  bool attributeChangesOk = true;
  if ( attributesChanged )
  {
    L->updateFields();
    QgsFields newFields = L->pendingFields();

    if ( oldFields.count() != newFields.count() )
    {
      commitErrors << tr( "ERROR: the count of fields is incorrect after addition/removal of fields!" );
      attributeChangesOk = false;   // don't try attribute updates - they'll fail.
    }

    for ( int i = 0; i < oldFields.count(); ++i )
    {
      const QgsField& oldField = oldFields[i];
      const QgsField& newField = newFields[i];
      if ( attributeChangesOk && oldField != newField )
      {
        commitErrors << tr( "ERROR: field with index %1 is not the same!" ).arg( i );
        attributeChangesOk = false;   // don't try attribute updates - they'll fail.
      }
    }
  }

  if ( attributeChangesOk )
  {
    //
    // change attributes
    //
    if ( !mChangedAttributeValues.isEmpty() )
    {
      if (( cap & QgsVectorDataProvider::ChangeAttributeValues ) && provider->changeAttributeValues( mChangedAttributeValues ) )
      {
        commitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );

        emit committedAttributeValuesChanges( L->id(), mChangedAttributeValues );

        mChangedAttributeValues.clear();
      }
      else
      {
        commitErrors << tr( "ERROR: %n attribute value change(s) not applied.", "not changed attribute values count", mChangedAttributeValues.size() );
        success = false;
      }
    }

    //
    // delete features
    //
    if ( !mDeletedFeatureIds.isEmpty() )
    {
      if (( cap & QgsVectorDataProvider::DeleteFeatures ) && provider->deleteFeatures( mDeletedFeatureIds ) )
      {
        commitErrors << tr( "SUCCESS: %n feature(s) deleted.", "deleted features count", mDeletedFeatureIds.size() );
        // TODO[MD]: we should not need this here
        for ( QgsFeatureIds::const_iterator it = mDeletedFeatureIds.begin(); it != mDeletedFeatureIds.end(); it++ )
        {
          mChangedAttributeValues.remove( *it );
          mChangedGeometries.remove( *it );
        }

        emit committedFeaturesRemoved( L->id(), mDeletedFeatureIds );

        mDeletedFeatureIds.clear();
      }
      else
      {
        commitErrors << tr( "ERROR: %n feature(s) not deleted.", "not deleted features count", mDeletedFeatureIds.size() );
        success = false;
      }
    }

    //
    //  add features
    //
    if ( !mAddedFeatures.isEmpty() )
    {
      if ( cap & QgsVectorDataProvider::AddFeatures )
      {
        QList<QgsFeatureId> ids = mAddedFeatures.keys();
        QgsFeatureList featuresToAdd = mAddedFeatures.values();

        if ( provider->addFeatures( featuresToAdd ) )
        {
          commitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", featuresToAdd.size() );

          emit committedFeaturesAdded( L->id(), featuresToAdd );

          // notify everyone that the features with temporary ids were updated with permanent ids
          for ( int i = 0; i < featuresToAdd.count(); ++i )
          {
            if ( featuresToAdd[i].id() != ids[i] )
            {
              emit featureDeleted( ids[i] );
              emit featureAdded( featuresToAdd[i].id() );
            }
          }

          mAddedFeatures.clear();
        }
        else
        {
          commitErrors << tr( "ERROR: %n feature(s) not added.", "not added features count", mAddedFeatures.size() );
          success = false;
        }
      }
      else
      {
        commitErrors << tr( "ERROR: %n feature(s) not added - provider doesn't support adding features.", "not added features count", mAddedFeatures.size() );
        success = false;
      }
    }
  }

  //
  // update geometries
  //
  if ( !mChangedGeometries.isEmpty() )
  {
    if (( cap & QgsVectorDataProvider::ChangeGeometries ) && provider->changeGeometryValues( mChangedGeometries ) )
    {
      commitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );

      emit committedGeometriesChanges( L->id(), mChangedGeometries );

      mChangedGeometries.clear();
    }
    else
    {
      commitErrors << tr( "ERROR: %n geometries not changed.", "not changed geometries count", mChangedGeometries.size() );
      success = false;
    }
  }

  if ( !success )
  {
    if ( provider->hasErrors() )
    {
      commitErrors << tr( "\n  Provider errors:" ) << provider->errors();
      provider->clearErrors();
    }
  }

  return success;
}
Exemplo n.º 3
0
bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int y )
{
  if ( !layer )
    return false;

  QMap< QString, QString > attributes, derivedAttributes;

  QgsPoint point = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y );

  derivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() );

  // load identify radius from settings
  QSettings settings;
  double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble();
  QString ellipsoid = settings.value( "/qgis/measure/ellipsoid", "WGS84" ).toString();

  if ( identifyValue <= 0.0 )
    identifyValue = QGis::DEFAULT_IDENTIFY_RADIUS;

  int featureCount = 0;

  QgsFeatureList featureList;

  // toLayerCoordinates will throw an exception for an 'invalid' point.
  // 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.
  try
  {
    // create the search rectangle
    double searchRadius = mCanvas->extent().width() * ( identifyValue / 100.0 );

    QgsRectangle r;
    r.setXMinimum( point.x() - searchRadius );
    r.setXMaximum( point.x() + searchRadius );
    r.setYMinimum( point.y() - searchRadius );
    r.setYMaximum( point.y() + searchRadius );

    r = toLayerCoordinates( layer, r );

    layer->select( layer->pendingAllAttributesList(), r, true, true );
    QgsFeature f;
    while ( layer->nextFeature( f ) )
      featureList << QgsFeature( f );
  }
  catch ( QgsCsException & cse )
  {
    Q_UNUSED( cse );
    // catch exception for 'invalid' point and proceed with no features found
    QgsDebugMsg( QString( "Caught CRS exception %1" ).arg( cse.what() ) );
  }

  // init distance/area calculator
  QgsDistanceArea calc;
  if ( !featureList.count() == 0 )
  {
    calc.setProjectionsEnabled( mCanvas->hasCrsTransformEnabled() ); // project?
    calc.setEllipsoid( ellipsoid );
    calc.setSourceCrs( layer->crs().srsid() );
  }
  QgsFeatureList::iterator f_it = featureList.begin();

  for ( ; f_it != featureList.end(); ++f_it )
  {
    featureCount++;

    QgsFeatureId fid = f_it->id();
    QMap<QString, QString> derivedAttributes;

    // Calculate derived attributes and insert:
    // measure distance or area depending on geometry type
    if ( layer->geometryType() == QGis::Line )
    {
      double dist = calc.measure( f_it->geometry() );
      QGis::UnitType myDisplayUnits;
      convertMeasurement( calc, dist, myDisplayUnits, false );
      QString str = calc.textUnit( dist, 3, myDisplayUnits, false );  // dist and myDisplayUnits are out params
      derivedAttributes.insert( tr( "Length" ), str );
      if ( f_it->geometry()->wkbType() == QGis::WKBLineString ||
           f_it->geometry()->wkbType() == QGis::WKBLineString25D )
      {
        // Add the start and end points in as derived attributes
        str = QLocale::system().toString( f_it->geometry()->asPolyline().first().x(), 'g', 10 );
        derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str );
        str = QLocale::system().toString( f_it->geometry()->asPolyline().first().y(), 'g', 10 );
        derivedAttributes.insert( tr( "firstY" ), str );
        str = QLocale::system().toString( f_it->geometry()->asPolyline().last().x(), 'g', 10 );
        derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str );
        str = QLocale::system().toString( f_it->geometry()->asPolyline().last().y(), 'g', 10 );
        derivedAttributes.insert( tr( "lastY" ), str );
      }
    }
    else if ( layer->geometryType() == QGis::Polygon )
    {
      double area = calc.measure( f_it->geometry() );
      QGis::UnitType myDisplayUnits;
      convertMeasurement( calc, area, myDisplayUnits, true );  // area and myDisplayUnits are out params
      QString str = calc.textUnit( area, 3, myDisplayUnits, true );
      derivedAttributes.insert( tr( "Area" ), str );
    }
    else if ( layer->geometryType() == QGis::Point &&
              ( f_it->geometry()->wkbType() == QGis::WKBPoint ||
                f_it->geometry()->wkbType() == QGis::WKBPoint25D ) )
    {
      // Include the x and y coordinates of the point as a derived attribute
      QString str;
      str = QLocale::system().toString( f_it->geometry()->asPoint().x(), 'g', 10 );
      derivedAttributes.insert( "X", str );
      str = QLocale::system().toString( f_it->geometry()->asPoint().y(), 'g', 10 );
      derivedAttributes.insert( "Y", str );
    }

    derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) );

    results()->addFeature( layer, *f_it, derivedAttributes );
  }

  QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) );

  return featureCount > 0;
}