int QgsMapToolDeletePart::partNumberOfVertex( QgsGeometry* g, int beforeVertexNr ) { int part; switch ( g->wkbType() ) { case QGis::WKBMultiPoint25D: case QGis::WKBMultiPoint: if ( beforeVertexNr < g->asMultiPoint().count() ) return beforeVertexNr; else return -1; case QGis::WKBMultiLineString25D: case QGis::WKBMultiLineString: { QgsMultiPolyline mline = g->asMultiPolyline(); for ( part = 0; part < mline.count(); part++ ) { if ( beforeVertexNr < mline[part].count() ) return part; beforeVertexNr -= mline[part].count(); } return -1; // not found } case QGis::WKBMultiPolygon25D: case QGis::WKBMultiPolygon: { QgsMultiPolygon mpolygon = g->asMultiPolygon(); for ( part = 0; part < mpolygon.count(); part++ ) // go through the polygons { const QgsPolygon& polygon = mpolygon[part]; for ( int ring = 0; ring < polygon.count(); ring++ ) // go through the rings { if ( beforeVertexNr < polygon[ring].count() ) return part; beforeVertexNr -= polygon[ring].count(); } } return -1; // not found } default: return -1; } }
int QgsMapToolDeleteRing::ringNumInMultiPolygon( const QgsGeometry &g, int vertexNr, int &partNum ) { QgsMultiPolygon mpolygon = g.asMultiPolygon(); for ( int part = 0; part < mpolygon.count(); part++ ) { const QgsPolygon &polygon = mpolygon[part]; for ( int ring = 0; ring < polygon.count(); ring++ ) { if ( vertexNr < polygon[ring].count() ) { partNum = part; return ring; } vertexNr -= polygon[ring].count(); } } return -1; }
QgsGeometry* QgsMapToolDeletePart::partUnderPoint( QPoint point, QgsFeatureId& fid, int& partNum ) { QgsFeature f; QgsGeometry* geomPart = new QgsGeometry(); switch ( vlayer->geometryType() ) { case QGis::Point: case QGis::Line: { QgsPointLocator::Match match = mCanvas->snappingUtils()->snapToCurrentLayer( point, QgsPointLocator::Vertex | QgsPointLocator::Edge ); if ( !match.isValid() ) return geomPart; int snapVertex = match.vertexIndex(); vlayer->getFeatures( QgsFeatureRequest().setFilterFid( match.featureId() ) ).nextFeature( f ); const QgsGeometry* g = f.constGeometry(); if ( !g->isMultipart() ) { fid = match.featureId(); delete geomPart; return QgsGeometry::fromPoint( match.point() ); } if ( g->wkbType() == QGis::WKBMultiPoint || g->wkbType() == QGis::WKBMultiPoint25D ) { fid = match.featureId(); partNum = snapVertex; delete geomPart; return QgsGeometry::fromPoint( match.point() ); } if ( g->wkbType() == QGis::WKBMultiLineString || g->wkbType() == QGis::WKBMultiLineString25D ) { QgsMultiPolyline mline = g->asMultiPolyline(); for ( int part = 0; part < mline.count(); part++ ) { if ( snapVertex < mline[part].count() ) { fid = match.featureId(); partNum = part; delete geomPart; return QgsGeometry::fromPolyline( mline[part] ); } snapVertex -= mline[part].count(); } } break; } case QGis::Polygon: { QgsPoint layerCoords = toLayerCoordinates( vlayer, point ); double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->currentLayer(), mCanvas->mapSettings() ); QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius, layerCoords.x() + searchRadius, layerCoords.y() + searchRadius ); QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectRect ) ); fit.nextFeature( f ); const QgsGeometry* g = f.constGeometry(); if ( !g ) return geomPart; if ( !g->isMultipart() ) { fid = f.id(); return geomPart; } QgsMultiPolygon mpolygon = g->asMultiPolygon(); for ( int part = 0; part < mpolygon.count(); part++ ) // go through the polygons { const QgsPolygon& polygon = mpolygon[part]; QgsGeometry* partGeo = QgsGeometry::fromPolygon( polygon ); if ( partGeo->contains( &layerCoords ) ) { fid = f.id(); partNum = part; delete geomPart; return partGeo; } delete partGeo; } break; } default: { break; } } return geomPart; }
QgsGeometry* QgsMapToolDeletePart::partUnderPoint( QPoint point, int& fid, int& partNum ) { QgsFeature f; QgsGeometry* geomPart = new QgsGeometry(); switch ( vlayer->geometryType() ) { case QGis::Point: case QGis::Line: { if ( mSnapper.snapToCurrentLayer( point, mRecentSnappingResults, QgsSnapper::SnapToVertexAndSegment ) == 0 ) { if ( mRecentSnappingResults.length() > 0 ) { QgsSnappingResult sr = mRecentSnappingResults.first(); int snapVertex = sr.snappedVertexNr; if ( snapVertex == -1 ) snapVertex = sr.beforeVertexNr; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( sr.snappedAtGeometry ) ).nextFeature( f ); QgsGeometry* g = f.geometry(); if ( !g->isMultipart() ) return geomPart; if ( g->wkbType() == QGis::WKBMultiPoint || g->wkbType() == QGis::WKBMultiPoint25D ) { fid = sr.snappedAtGeometry; partNum = snapVertex; return QgsGeometry::fromPoint( sr.snappedVertex ); } if ( g->wkbType() == QGis::WKBMultiLineString || g->wkbType() == QGis::WKBMultiLineString25D ) { QgsMultiPolyline mline = g->asMultiPolyline(); for ( int part = 0; part < mline.count(); part++ ) { if ( snapVertex < mline[part].count() ) { fid = sr.snappedAtGeometry; partNum = part; return QgsGeometry::fromPolyline( mline[part] ); } snapVertex -= mline[part].count(); } } } } break; } case QGis::Polygon: { QgsPoint layerCoords = toLayerCoordinates( vlayer, point ); double searchRadius = QgsTolerance::vertexSearchRadius( mCanvas->currentLayer(), mCanvas->mapSettings() ); QgsRectangle selectRect( layerCoords.x() - searchRadius, layerCoords.y() - searchRadius, layerCoords.x() + searchRadius, layerCoords.y() + searchRadius ); QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectRect ) ); fit.nextFeature( f ); QgsGeometry* g = f.geometry(); if ( !g ) return geomPart; if ( !g->isMultipart() ) return geomPart; QgsMultiPolygon mpolygon = g->asMultiPolygon(); for ( int part = 0; part < mpolygon.count(); part++ ) // go through the polygons { const QgsPolygon& polygon = mpolygon[part]; QgsGeometry* partGeo = QgsGeometry::fromPolygon( polygon ); if ( partGeo->contains( &layerCoords ) ) { fid = f.id(); partNum = part; return partGeo; } } break; } default: { break; } } return geomPart; }
ErrorList topolTest::checkGaps( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent ) { Q_UNUSED( tolerance ); Q_UNUSED( layer2 ); int i = 0; ErrorList errorList; GEOSContextHandle_t geosctxt = QgsGeometry::getGEOSHandler(); // could be enabled for lines and points too // so duplicate rule may be removed? if ( layer1->geometryType() != QGis::Polygon ) { return errorList; } QList<FeatureLayer>::Iterator it; QgsGeometry* g1; QList<GEOSGeometry*> geomList; qDebug() << mFeatureList1.count() << " features in list!"; QList<FeatureLayer>::ConstIterator FeatureListEnd = mFeatureList1.end(); for ( it = mFeatureList1.begin(); it != FeatureListEnd; ++it ) { qDebug() << "reading features-" << i; if ( !( ++i % 100 ) ) { emit progress( i ); } if ( testCancelled() ) { break; } g1 = it->feature.geometry(); if ( !g1 ) { continue; } if ( !g1->asGeos() ) { continue; } if ( !g1->isGeosValid() ) { qDebug() << "invalid geometry found..skipping.." << it->feature.id(); continue; } if ( g1->isMultipart() ) { QgsMultiPolygon polys = g1->asMultiPolygon(); for ( int m = 0; m < polys.count(); m++ ) { QgsPolygon polygon = polys[m]; QgsGeometry* polyGeom = QgsGeometry::fromPolygon( polygon ); geomList.push_back( GEOSGeom_clone_r( geosctxt, polyGeom->asGeos() ) ); delete polyGeom; } } else { geomList.push_back( GEOSGeom_clone_r( geosctxt, g1->asGeos() ) ); } } GEOSGeometry** geomArray = new GEOSGeometry*[geomList.size()]; for ( int i = 0; i < geomList.size(); ++i ) { //qDebug() << "filling geometry array-" << i; geomArray[i] = geomList.at( i ); } qDebug() << "creating geometry collection-"; if ( geomList.size() == 0 ) { //qDebug() << "geometry list is empty!"; delete [] geomArray; return errorList; } GEOSGeometry* collection = 0; collection = GEOSGeom_createCollection_r( geosctxt, GEOS_MULTIPOLYGON, geomArray, geomList.size() ); qDebug() << "performing cascaded union..might take time..-"; GEOSGeometry* unionGeom = GEOSUnionCascaded_r( geosctxt, collection ); //delete[] geomArray; QgsGeometry test; test.fromGeos( unionGeom ); //qDebug() << "wktmerged - " << test.exportToWkt(); QString extentWkt = test.boundingBox().asWktPolygon(); QgsGeometry* extentGeom = QgsGeometry::fromWkt( extentWkt ); QgsGeometry* bufferExtent = extentGeom->buffer( 2, 3 ); delete extentGeom; //qDebug() << "extent wkt - " << bufferExtent->exportToWkt(); QgsGeometry* diffGeoms = bufferExtent->difference( &test ); delete bufferExtent; if ( !diffGeoms ) { qDebug() << "difference result 0-"; return errorList; } //qDebug() << "difference gometry - " << diffGeoms->exportToWkt(); QList<QgsGeometry*> geomColl = diffGeoms->asGeometryCollection(); QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() ); for ( int i = 1; i < geomColl.count() ; ++i ) { QgsGeometry* conflictGeom = geomColl[i]; if ( isExtent ) { if ( canvasExtentPoly->disjoint( conflictGeom ) ) { continue; } if ( canvasExtentPoly->crosses( conflictGeom ) ) { conflictGeom = conflictGeom->intersection( canvasExtentPoly ); } } QgsRectangle bBox = conflictGeom->boundingBox(); QgsFeature feat; FeatureLayer ftrLayer1; ftrLayer1.layer = layer1; QList<FeatureLayer> errorFtrLayers; errorFtrLayers << ftrLayer1 << ftrLayer1; TopolErrorGaps* err = new TopolErrorGaps( bBox, conflictGeom, errorFtrLayers ); errorList << err; } delete canvasExtentPoly; return errorList; }