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)" ) ); }
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))" ) ); }
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)" ) ); }
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() ); }
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(); }