예제 #1
0
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;
  }
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}