void TestQgsGeometrySnapper::snapPointToLine()
{
  QgsVectorLayer* rl = new QgsVectorLayer( QStringLiteral( "Linestring" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) );

  // closed linestring
  QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(0 0, 10 0, 10 10, 0 10, 0 0)" ) );
  QgsFeature ff( 0 );
  ff.setGeometry( refGeom );
  QgsFeatureList flist;
  flist << ff;
  rl->dataProvider()->addFeatures( flist );

  QgsGeometry pointGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0.1 -0.1)" ) );
  QgsGeometrySnapper snapper( rl );
  QgsGeometry result = snapper.snapGeometry( pointGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Point (0 0)" ) );

  pointGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(10.6 -0.1)" ) );
  result = snapper.snapGeometry( pointGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Point (10 0)" ) );

  pointGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0.5 0.5)" ) );
  result = snapper.snapGeometry( pointGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Point (0 0)" ) );
}
void TestQgsGeometrySnapper::snapPolygonToPolygon()
{
  QgsVectorLayer* rl = new QgsVectorLayer( QStringLiteral( "Polygon" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) );
  QgsFeature ff( 0 );
  QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0 0, 10 0, 10 10, 0 10, 0 0))" ) );
  ff.setGeometry( refGeom );
  QgsFeatureList flist;
  flist << ff;
  rl->dataProvider()->addFeatures( flist );

  QgsGeometry polygonGeom = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 9.9 10.1, 0 10, 0.1 -0.1))" ) );
  QgsGeometrySnapper snapper( rl );
  QgsGeometry result = snapper.snapGeometry( polygonGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" ) );

  QgsGeometry polygonGeom2 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 0 10, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom2, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 0 10, 0 0))" ) );

  // insert new vertex
  QgsGeometry polygonGeom3 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 20.5 0.5, 20 10, 0 9.9, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom3, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 20.5 0.5, 20 10, 10 10, 0 10, 0 0))" ) );

  // remove vertex
  QgsGeometry polygonGeom4 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 9.9 10.1, 5 10, 0 10, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom4, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" ) );
}
void TestQgsGeometrySnapper::snapLineToPoint()
{
  QgsVectorLayer* rl = new QgsVectorLayer( QStringLiteral( "Point" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) );

  QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0 0)" ) );
  QgsFeature ff( 0 );
  ff.setGeometry( refGeom );
  QgsGeometry refGeom2 = QgsGeometry::fromWkt( QStringLiteral( "Point(10 0)" ) );
  QgsFeature ff2( 2 );
  ff2.setGeometry( refGeom2 );
  QgsFeatureList flist;
  flist << ff << ff2;
  rl->dataProvider()->addFeatures( flist );

  QgsGeometry lineGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(0.1 -0.1, 10.1 0, 10 10, 0 10)" ) );
  QgsGeometrySnapper snapper( rl );
  QgsGeometry result = snapper.snapGeometry( lineGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "LineString (0 0, 10 0, 10 10, 0 10)" ) );

  QgsGeometry lineGeom2 = QgsGeometry::fromWkt( QStringLiteral( "LineString(0.1 -0.1, 10.1 0, 0 10)" ) );
  result = snapper.snapGeometry( lineGeom2, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "LineString (0 0, 10 0, 0 10)" ) );

  // insert new vertex
  QgsGeometry lineGeom3 = QgsGeometry::fromWkt( QStringLiteral( "LineString(0.1 -0.1, 20.0 0.0, 20 10, 0 10)" ) );
  result = snapper.snapGeometry( lineGeom3, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "LineString (0 0, 10 0, 20 0, 20 10, 0 10)" ) );
}
Example #4
0
void QgsOfflineEditing::committedGeometriesChanges( const QString& qgisLayerId, const QgsGeometryMap& changedGeometries )
{
  sqlite3* db = openLoggingDb();
  if ( db == NULL )
  {
    return;
  }

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

  for ( QgsGeometryMap::const_iterator it = changedGeometries.begin(); it != changedGeometries.end(); ++it )
  {
    QgsFeatureId fid = it.key();
    if ( isAddedFeature( db, layerId, fid ) )
    {
      // skip added features
      continue;
    }
    QgsGeometry geom = it.value();
    QString sql = QString( "INSERT INTO 'log_geometry_updates' VALUES ( %1, %2, %3, '%4' )" )
                  .arg( layerId )
                  .arg( commitNo )
                  .arg( fid )
                  .arg( geom.exportToWkt() );
    sqlExec( db, sql );

    // TODO: use WKB instead of WKT?
  }

  increaseCommitNo( db );
  sqlite3_close( db );
}
void TestQgsGeometrySnapper::snapPolygonToLine()
{
  QgsVectorLayer* rl = new QgsVectorLayer( QStringLiteral( "Linestring" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) );

  // closed linestring
  QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "LineString(0 0, 10 0, 10 10, 0 10, 0 0)" ) );
  QgsFeature ff( 0 );
  ff.setGeometry( refGeom );
  // unclosed linestring
  QgsGeometry refGeom2 = QgsGeometry::fromWkt( QStringLiteral( "LineString(100 0, 110 0, 110 10, 100 10)" ) );
  QgsFeature ff2( 2 );
  ff2.setGeometry( refGeom2 );
  QgsFeatureList flist;
  flist << ff << ff2;
  rl->dataProvider()->addFeatures( flist );


  // snapping to closed linestring
  QgsGeometry polygonGeom = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 9.9 10.1, 0 10, 0.1 -0.1))" ) );
  QgsGeometrySnapper snapper( rl );
  QgsGeometry result = snapper.snapGeometry( polygonGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" ) );

  QgsGeometry polygonGeom2 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 0 10, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom2, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 0 10, 0 0))" ) );

  // insert new vertex
  QgsGeometry polygonGeom3 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 20.5 0.5, 20 10, 0 9.9, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom3, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 20.5 0.5, 20 10, 10 10, 0 10, 0 0))" ) );

  // remove vertex
  QgsGeometry polygonGeom4 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((0.1 -0.1, 10.1 0, 9.9 10.1, 5 10, 0 10, 0.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom4, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((0 0, 10 0, 10 10, 0 10, 0 0))" ) );


  // snapping to unclosed linestring
  QgsGeometry polygonGeom5 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((100.1 -0.1, 110.1 0, 109.9 10.1, 100 10, 100.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom5, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((100 0, 110 0, 110 10, 100 10, 100 0))" ) );

  QgsGeometry polygonGeom6 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((100.1 -0.1, 110.1 0, 100 10, 100.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom6, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((100 0, 110 0, 100 10, 100 0))" ) );

  // insert new vertex
  QgsGeometry polygonGeom7 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((100.1 -0.1, 120.5 0.5, 120 10, 100 9.9, 100.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom7, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((100 0, 110 0, 120.5 0.5, 120 10, 110 10, 100 10, 100 0))" ) );

  // remove vertex
  QgsGeometry polygonGeom8 = QgsGeometry::fromWkt( QStringLiteral( "Polygon((100.1 -0.1, 110.1 0, 109.9 10.1, 105 10, 100 10, 100.1 -0.1))" ) );
  result = snapper.snapGeometry( polygonGeom8, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Polygon ((100 0, 110 0, 110 10, 100 10, 100 0))" ) );
}
Example #6
0
QString TestQgsGrassCommand::toString() const
{
  QString string;
  if ( command == StartEditing )
  {
    string += "StartEditing grassLayerCode: " + values["grassLayerCode"].toString();
    string += " expectedLayerType: " + values["expectedLayerType"].toString();
  }
  else if ( command == CommitChanges )
  {
    string += "CommitChanges";
  }
  else if ( command == RollBack )
  {
    string += "RollBack";
  }
  else if ( command == AddFeature )
  {
    string += "AddFeature ";
    string += expectedFeature.constGeometry()->exportToWkt( 1 );
  }
  else if ( command == DeleteFeature )
  {
    string += "DeleteFeature ";
    string += QString( "fid: %1" ).arg( fid );
  }
  else if ( command == ChangeGeometry )
  {
    string += "ChangeGeometry ";
    string += QString( "fid: %1 geometry: %2" ).arg( fid ).arg( geometry->exportToWkt( 1 ) );
  }
  else if ( command == AddAttribute )
  {
    string += "AddAttribute ";
    string += "name: " + field.name() + " type: " + QVariant::typeToName( field.type() );
  }
  else if ( command == DeleteAttribute )
  {
    string += "DeleteAttribute ";
    string += "name: " + field.name();
  }
  else if ( command == ChangeAttributeValue )
  {
    string += "ChangeAttributeValue ";
    string += "name: " + field.name() + " value: " + value.toString();
  }
  else if ( command == UndoAll )
  {
    string += "UndoAll";
  }
  else if ( command == RedoAll )
  {
    string += "RedoAll";
  }
  return string;
}
void TestQgsGeometrySnapper::snapPointToPoint()
{
  QgsVectorLayer* rl = new QgsVectorLayer( QStringLiteral( "Point" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) );

  QgsGeometry refGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0 0)" ) );
  QgsFeature ff( 0 );
  ff.setGeometry( refGeom );
  QgsGeometry refGeom2 = QgsGeometry::fromWkt( QStringLiteral( "Point(1 0)" ) );
  QgsFeature ff2( 2 );
  ff2.setGeometry( refGeom2 );
  QgsFeatureList flist;
  flist << ff << ff2;
  rl->dataProvider()->addFeatures( flist );

  QgsGeometry pointGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0.1 -0.1)" ) );
  QgsGeometrySnapper snapper( rl );
  QgsGeometry result = snapper.snapGeometry( pointGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Point (0 0)" ) );

  pointGeom = QgsGeometry::fromWkt( QStringLiteral( "Point(0.6 -0.1)" ) );
  result = snapper.snapGeometry( pointGeom, 1 );
  QCOMPARE( result.exportToWkt(), QStringLiteral( "Point (1 0)" ) );
}
Example #8
0
    void eval_geometry_method()
    {
      QFETCH( QString, string );
      QFETCH( void*, geomptr );
      QFETCH( bool, evalError );
      QFETCH( bool, needGeom );
      QFETCH( void*, resultptr );

      QgsGeometry* geom = ( QgsGeometry* ) geomptr;
      QgsGeometry* result = ( QgsGeometry* ) resultptr;

      QgsFeature f;
      f.setGeometry( geom );

      QgsExpression exp( string );
      QCOMPARE( exp.hasParserError(), false );
      QCOMPARE( exp.needsGeometry(), needGeom );
      QVariant out = exp.evaluate( &f );
      QCOMPARE( exp.hasEvalError(), evalError );

      QCOMPARE( out.canConvert<QgsGeometry>(), true );
      QgsGeometry outGeom = out.value<QgsGeometry>();
      QCOMPARE( outGeom.exportToWkt(), result->exportToWkt() );
    }
Example #9
0
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas,
	QgsGeometry* selectGeometry,
	bool doContains,
	bool doDifference,
	bool singleSelect )
{
	if ( selectGeometry->type() != QGis::Polygon )
	{
		return;
	}
	QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas );
	if ( vlayer == nullptr )
	{
		return;
	}

	// 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 ( canvas->mapSettings().hasCrsTransformEnabled() )
	//{
	//	try
	//	{
	//		QgsCoordinateTransform ct( canvas->mapSettings().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__ ) );
	//		LOG_INFO( "CRS Exception\nSelection extends beyond layer's coordinate system" );
	//		return;
	//	}
	//}
	QgsGeometry selectGeomTrans;
	try{
		selectGeomTrans = toLayerCoordinates( canvas, selectGeometry, vlayer );
	}
	catch ( QgsCsException & )
	{
		return;
	}

	QApplication::setOverrideCursor( Qt::WaitCursor );

	QgsDebugMsg( "Selection layer: " + vlayer->name() );
	QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() );
	QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) );
	QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) );

	QgsRenderContext context = QgsRenderContext::fromMapSettings( canvas->mapSettings() );
	QgsFeatureRendererV2* r = vlayer->rendererV2();
	if ( r )
		r->startRender( context, vlayer->pendingFields() );

	QgsFeatureRequest request;
	request.setFilterRect( selectGeomTrans.boundingBox() );
	request.setFlags( QgsFeatureRequest::ExactIntersect );
	if ( r )
		request.setSubsetOfAttributes( r->usedAttributes(), vlayer->pendingFields() );
	else
		request.setSubsetOfAttributes( QgsAttributeList() );

	QgsFeatureIterator fit = vlayer->getFeatures( request );

	QgsFeatureIds newSelectedFeatures;
	QgsFeature f;
	QgsFeatureId closestFeatureId = 0;
	bool foundSingleFeature = false;
	double closestFeatureDist = std::numeric_limits<double>::max();
	while ( fit.nextFeature( f ) )
	{
#if (VERSION_INT >= 21601)
		context.expressionContext().setFeature( f );		//taken from QGIS 2.16.1
		// make sure to only use features that are visible
		if ( r && !r->willRenderFeature( f, context ) )
#else
		if ( r && !r->willRenderFeature( f ) )
#endif
			continue;

		QgsGeometry* g = f.geometry();
		if ( doContains )
		{
			if ( !selectGeomTrans.contains( g ) )
				continue;
		}
		else
		{
			if ( !selectGeomTrans.intersects( g ) )
				continue;
		}
		if ( singleSelect )
		{
			foundSingleFeature = true;
			double distance = g->distance( selectGeomTrans );
			if ( distance <= closestFeatureDist )
			{
				closestFeatureDist = distance;
				closestFeatureId = f.id();
			}
		}
		else
		{
			newSelectedFeatures.insert( f.id() );
		}
	}
	if ( singleSelect && foundSingleFeature )
	{
		newSelectedFeatures.insert( closestFeatureId );
	}

	if ( r )
		r->stopRender( context );

	QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) );

	if ( doDifference )
	{
		QgsFeatureIds layerSelectedFeatures = vlayer->selectedFeaturesIds();

		QgsFeatureIds selectedFeatures;
		QgsFeatureIds deselectedFeatures;

		QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd();
		while ( i != newSelectedFeatures.constBegin() )
		{
			--i;
			if ( layerSelectedFeatures.contains( *i ) )
			{
				deselectedFeatures.insert( *i );
			}
			else
			{
				selectedFeatures.insert( *i );
			}
		}

		vlayer->modifySelection( selectedFeatures, deselectedFeatures );
	}
	else
	{
		SelectFeatures( vlayer, newSelectedFeatures );		//		vlayer->setSelectedFeatures( newSelectedFeatures );
	}

	QApplication::restoreOverrideCursor();
}