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; } }
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::checkPseudos( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent ) { Q_UNUSED( tolerance ); Q_UNUSED( layer2 ); int i = 0; ErrorList errorList; QgsFeature f; if ( layer1->geometryType() != QGis::Line ) { return errorList; } QList<FeatureLayer>::Iterator it; QList<FeatureLayer>::ConstIterator FeatureListEnd = mFeatureList1.end(); qDebug() << mFeatureList1.count(); QgsPoint startPoint; QgsPoint endPoint; std::multimap<QgsPoint, QgsFeatureId, PointComparer> endVerticesMap; for ( it = mFeatureList1.begin(); it != FeatureListEnd; ++it ) { if ( !( ++i % 100 ) ) emit progress( i ); if ( testCancelled() ) break; QgsGeometry* g1 = it->feature.geometry(); if ( !g1 ) { QgsMessageLog::logMessage( tr( "Skipping invalid first geometry in pseudo line test." ), tr( "Topology plugin" ) ); continue; } if ( !g1->asGeos() ) { QgsMessageLog::logMessage( tr( "Failed to import first geometry into GEOS in pseudo line test." ), tr( "Topology plugin" ) ); continue; } if ( g1->isMultipart() ) { QgsMultiPolyline lines = g1->asMultiPolyline(); for ( int m = 0; m < lines.count(); m++ ) { QgsPolyline line = lines[m]; startPoint = line[0]; endPoint = line[line.size() - 1]; endVerticesMap.insert( std::pair<QgsPoint, QgsFeatureId>( startPoint, it->feature.id() ) ); endVerticesMap.insert( std::pair<QgsPoint, QgsFeatureId>( endPoint, it->feature.id() ) ); } } else { QgsPolyline polyline = g1->asPolyline(); startPoint = polyline[0]; endPoint = polyline[polyline.size()-1]; endVerticesMap.insert( std::pair<QgsPoint, QgsFeatureId>( startPoint, it->feature.id() ) ); endVerticesMap.insert( std::pair<QgsPoint, QgsFeatureId>( endPoint, it->feature.id() ) ); } } QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() ); for ( std::multimap<QgsPoint, QgsFeatureId, PointComparer>::iterator pointIt = endVerticesMap.begin(), end = endVerticesMap.end(); pointIt != end; pointIt = endVerticesMap.upper_bound( pointIt->first ) ) { QgsPoint p = pointIt->first; QgsFeatureId k = pointIt->second; size_t repetitions = endVerticesMap.count( p ); if ( repetitions == 2 ) { QgsGeometry* conflictGeom = QgsGeometry::fromPoint( p ); if ( isExtent ) { if ( canvasExtentPoly->disjoint( conflictGeom ) ) { delete conflictGeom; continue; } } QgsRectangle bBox = conflictGeom->boundingBox(); QgsFeature feat; FeatureLayer ftrLayer1; //need to fetch attributes?? being safe side by fetching.. layer1->getFeatures( QgsFeatureRequest().setFilterFid( k ) ).nextFeature( feat ); ftrLayer1.feature = feat; ftrLayer1.layer = layer1; QList<FeatureLayer> errorFtrLayers; errorFtrLayers << ftrLayer1 << ftrLayer1; TopolErrorPseudos* err = new TopolErrorPseudos( bBox, conflictGeom, errorFtrLayers ); errorList << err; } } delete canvasExtentPoly; return errorList; }