Пример #1
0
ErrorList topolTest::checkDanglingLines( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( layer2 );

  int i = 0;
  ErrorList errorList;
  QgsFeature f;

  if ( layer1->geometryType() != QgsWkbTypes::LineGeometry )
  {
    return errorList;
  }

  QList<FeatureLayer>::iterator it;

  qDebug() << mFeatureList1.count();

  QgsPointXY startPoint;
  QgsPointXY endPoint;

  std::multimap<QgsPointXY, QgsFeatureId, PointComparer> endVerticesMap;

  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    if ( testCanceled() )
      break;

    QgsGeometry g1 = it->feature.geometry();

    if ( g1.isNull() )
    {
      QgsMessageLog::logMessage( tr( "First geometry invalid in dangling line test." ), tr( "Topology plugin" ) );
      continue;
    }

    if ( !_canExportToGeos( g1 ) )
    {
      QgsMessageLog::logMessage( tr( "Failed to import first geometry into GEOS in dangling line test." ), tr( "Topology plugin" ) );
      continue;
    }

    if ( g1.isMultipart() )
    {
      QgsMultiPolylineXY lines = g1.asMultiPolyline();
      for ( int m = 0; m < lines.count(); m++ )
      {
        QgsPolylineXY line = lines[m];
        startPoint = line[0];
        endPoint = line[line.size() - 1];

        endVerticesMap.insert( std::pair<QgsPointXY, QgsFeatureId>( startPoint, it->feature.id() ) );
        endVerticesMap.insert( std::pair<QgsPointXY, QgsFeatureId>( endPoint, it->feature.id() ) );

      }
    }
    else
    {
      QgsPolylineXY polyline = g1.asPolyline();
      startPoint = polyline[0];
      endPoint = polyline[polyline.size() - 1];
      endVerticesMap.insert( std::pair<QgsPointXY, QgsFeatureId>( startPoint, it->feature.id() ) );
      endVerticesMap.insert( std::pair<QgsPointXY, QgsFeatureId>( endPoint, it->feature.id() ) );
    }
  }

  QgsGeometry canvasExtentPoly = QgsGeometry::fromWkt( qgsInterface->mapCanvas()->extent().asWktPolygon() );


  for ( std::multimap<QgsPointXY, QgsFeatureId, PointComparer>::iterator pointIt = endVerticesMap.begin(), end = endVerticesMap.end(); pointIt != end; pointIt = endVerticesMap.upper_bound( pointIt->first ) )
  {
    QgsPointXY p = pointIt->first;
    QgsFeatureId k = pointIt->second;

    size_t repetitions = endVerticesMap.count( p );

    //QgsGeometry* extentPoly =
    if ( repetitions == 1 )
    {

      QgsGeometry conflictGeom = QgsGeometry::fromPointXY( p );
      if ( isExtent )
      {
        if ( canvasExtentPoly.disjoint( 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;

      TopolErrorDangle *err = new TopolErrorDangle( bBox, conflictGeom, errorFtrLayers );
      errorList << err;

    }
  }
  return errorList;
}
Пример #2
0
ErrorList topolTest::checkPointCoveredBySegment( double tolerance, QgsVectorLayer* layer1, QgsVectorLayer* layer2, bool isExtent )
{
  Q_UNUSED( tolerance );

  int i = 0;

  ErrorList errorList;

  if ( layer1->geometryType() != QGis::Point )
  {
    return errorList;
  }
  if ( layer2->geometryType() == QGis::Point )
  {
    return errorList;
  }

  QgsSpatialIndex* index = mLayerIndexes[layer2->id()];
  QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );


  QList<FeatureLayer>::Iterator it;
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    if ( testCancelled() )
      break;

    QgsGeometry* g1 = it->feature.geometry();
    QgsRectangle bb = g1->boundingBox();

    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );

    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();

    bool touched = false;

    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature& f = mFeatureMap2[*cit].feature;
      const QgsGeometry* g2 = f.constGeometry();

      if ( !g2 )
      {
        QgsMessageLog::logMessage( tr( "Invalid geometry in covering test." ), tr( "Topology plugin" ) );
        continue;
      }

      // test if point touches other geometry
      if ( g1->touches( g2 ) )
      {
        touched = true;
        break;
      }
    }

    if ( !touched )
    {
      QgsGeometry* conflictGeom = new QgsGeometry( *g1 );

      if ( isExtent )
      {
        if ( canvasExtentPoly->disjoint( conflictGeom ) )
        {
          delete conflictGeom;
          continue;
        }
      }

      QList<FeatureLayer> fls;
      fls << *it << *it;
      //bb.scale(10);

      TopolErrorCovered* err = new TopolErrorCovered( bb, conflictGeom, fls );

      errorList << err;
    }
  }
  delete canvasExtentPoly;
  return errorList;
}
Пример #3
0
ErrorList topolTest::checkPointInPolygon( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  int i = 0;
  ErrorList errorList;

  if ( layer1->geometryType() != QgsWkbTypes::PointGeometry )
  {
    return errorList;
  }

  if ( layer2->geometryType() != QgsWkbTypes::PolygonGeometry )
  {
    return errorList;
  }

  QgsSpatialIndex *index = mLayerIndexes[layer2->id()];

  QgsGeometry canvasExtentPoly = QgsGeometry::fromWkt( qgsInterface->mapCanvas()->extent().asWktPolygon() );

  QList<FeatureLayer>::Iterator it;
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );
    if ( testCanceled() )
      break;
    QgsGeometry g1 = it->feature.geometry();
    QgsRectangle bb = g1.boundingBox();
    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );
    QList<QgsFeatureId>::ConstIterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();
    bool touched = false;
    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature &f = mFeatureMap2[*cit].feature;
      QgsGeometry g2 = f.geometry();
      if ( g2.isNull() || !_canExportToGeos( g2 ) )
      {
        QgsMessageLog::logMessage( tr( "Second geometry missing or GEOS import failed." ), tr( "Topology plugin" ) );
        continue;
      }
      if ( g2.contains( g1 ) )
      {
        touched = true;
        break;
      }
    }
    if ( !touched )
    {
      QgsGeometry conflictGeom = g1;

      if ( isExtent )
      {
        if ( canvasExtentPoly.disjoint( conflictGeom ) )
        {
          continue;
        }
      }

      QList<FeatureLayer> fls;
      fls << *it << *it;
      //bb.scale(10);

      TopolErrorPointNotInPolygon *err = new TopolErrorPointNotInPolygon( bb, conflictGeom, fls );
      errorList << err;
    }
  }

  return errorList;
}
Пример #4
0
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;
}
Пример #5
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;
}
Пример #6
0
ErrorList topolTest::checkOverlaps( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );
  Q_UNUSED( layer2 );
  int i = 0;
  ErrorList errorList;

  // could be enabled for lines and points too
  // so duplicate rule may be removed?

  if ( layer1->geometryType() != QGis::Polygon )
  {
    return errorList;
  }

  QList<QgsFeatureId> *duplicateIds = new QList<QgsFeatureId>();

  QgsSpatialIndex* index = mLayerIndexes[layer1->id()];
  if ( !index )
  {
    qDebug() << "no index present";
    delete duplicateIds;
    return errorList;
  }

  QMap<QgsFeatureId, FeatureLayer>::Iterator it;
  QMap<QgsFeatureId, FeatureLayer>::ConstIterator FeatureListEnd = mFeatureMap2.end();
  for ( it = mFeatureMap2.begin(); it != FeatureListEnd; ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    QgsFeatureId currentId = it->feature.id();

    if ( duplicateIds->contains( currentId ) )
    {
      //is already a duplicate geometry..skip..
      continue;
    }

    if ( testCancelled() )
      break;

    QgsGeometry* g1 = it->feature.geometry();

    if ( !g1->isGeosValid() )
    {
      qDebug() << "invalid geometry(g1) found..skipping.." << it->feature.id();
      continue;
    }

    QgsRectangle bb = g1->boundingBox();

    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );

    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();

    bool duplicate = false;

    QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );

    for ( ; cit != crossingIdsEnd; ++cit )
    {
      duplicate = false;
      // skip itself
      if ( mFeatureMap2[*cit].feature.id() == it->feature.id() )
        continue;

      const QgsGeometry* g2 = mFeatureMap2[*cit].feature.constGeometry();
      if ( !g2 )
      {
        QgsMessageLog::logMessage( tr( "Invalid second geometry in overlaps test." ), tr( "Topology plugin" ) );
        continue;
      }

      if ( !g2->asGeos() )
      {
        QgsMessageLog::logMessage( tr( "Failed to import second geometry into GEOS in overlaps test." ), tr( "Topology plugin" ) );
        continue;
      }

      if ( !g2->isGeosValid() )
      {
        QgsMessageLog::logMessage( tr( "Skipping invalid second geometry of feature %1 in overlaps test." ).arg( it->feature.id() ), tr( "Topology plugin" ) );
        continue;
      }


      qDebug() << "checking overlap for" << it->feature.id();
      if ( g1->overlaps( g2 ) )
      {
        duplicate = true;
        duplicateIds->append( mFeatureMap2[*cit].feature.id() );
      }

      if ( duplicate )
      {
        QList<FeatureLayer> fls;
        fls << *it << *it;
        QScopedPointer< QgsGeometry > conflictGeom( g1->intersection( g2 ) );

        if ( isExtent )
        {
          if ( canvasExtentPoly->disjoint( conflictGeom.data() ) )
          {
            continue;
          }
          if ( canvasExtentPoly->crosses( conflictGeom.data() ) )
          {
            conflictGeom.reset( conflictGeom->intersection( canvasExtentPoly ) );
          }
        }

        TopolErrorOverlaps* err = new TopolErrorOverlaps( bb, conflictGeom.take(), fls );

        errorList << err;
      }

    }
    delete canvasExtentPoly;
  }

  delete duplicateIds;

  return errorList;
}
Пример #7
0
ErrorList topolTest::checkDuplicates( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );
  Q_UNUSED( layer2 );
  //TODO: multilines - check all separate pieces
  int i = 0;
  ErrorList errorList;

  QList<QgsFeatureId> duplicateIds;

  QgsSpatialIndex* index = mLayerIndexes[layer1->id()];

  QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );

  QMap<QgsFeatureId, FeatureLayer>::Iterator it;
  QMap<QgsFeatureId, FeatureLayer>::ConstIterator FeatureListEnd = mFeatureMap2.end();
  for ( it = mFeatureMap2.begin(); it != FeatureListEnd; ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    QgsFeatureId currentId = it->feature.id();

    if ( duplicateIds.contains( currentId ) )
    {
      //is already a duplicate geometry..skip..
      continue;
    }

    if ( testCancelled() )
      break;

    QgsGeometry* g1 = it->feature.geometry();
    QgsRectangle bb = g1->boundingBox();

    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );

    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();

    bool duplicate = false;

    for ( ; cit != crossingIdsEnd; ++cit )
    {
      duplicate = false;
      // skip itself
      if ( mFeatureMap2[*cit].feature.id() == it->feature.id() )
        continue;

      const QgsGeometry* g2 = mFeatureMap2[*cit].feature.constGeometry();
      if ( !g2 )
      {
        QgsMessageLog::logMessage( tr( "Invalid second geometry in duplicate geometry test." ), tr( "Topology plugin" ) );
        continue;
      }

      if ( !g2->asGeos() )
      {
        QgsMessageLog::logMessage( tr( "Failed to import second geometry into GEOS in duplicate geometry test." ), tr( "Topology plugin" ) );
        continue;
      }

      if ( g1->equals( g2 ) )
      {
        duplicate = true;
        duplicateIds.append( mFeatureMap2[*cit].feature.id() );
      }

      if ( duplicate )
      {


        QList<FeatureLayer> fls;
        fls << *it << *it;
        QScopedPointer<QgsGeometry> conflict( new QgsGeometry( *g1 ) );

        if ( isExtent )
        {
          if ( canvasExtentPoly->disjoint( conflict.data() ) )
          {
            continue;
          }
          if ( canvasExtentPoly->crosses( conflict.data() ) )
          {
            conflict.reset( conflict->intersection( canvasExtentPoly ) );
          }
        }

        TopolErrorDuplicates* err = new TopolErrorDuplicates( bb, conflict.take(), fls );

        errorList << err;
      }

    }

  }
  delete canvasExtentPoly;
  return errorList;
}
Пример #8
0
ErrorList topolTest::checkyLineEndsCoveredByPoints( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );

  int i = 0;
  ErrorList errorList;


  if ( layer1->geometryType() != QGis::Line )
  {
    return errorList;
  }

  if ( layer2->geometryType() != QGis::Point )
  {
    return errorList;
  }

  QgsSpatialIndex* index = mLayerIndexes[layer2->id()];

  QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );

  QList<FeatureLayer>::Iterator it;
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );
    if ( testCancelled() )
      break;
    QgsGeometry* g1 = it->feature.geometry();

    QgsGeometry* startPoint = QgsGeometry::fromPoint( g1->asPolyline().first() );
    QgsGeometry* endPoint = QgsGeometry::fromPoint( g1->asPolyline().last() );

    QgsRectangle bb = g1->boundingBox();
    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );
    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();
    bool touched = false;

    bool touchStartPoint = false;
    bool touchEndPoint = false;

    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature& f = mFeatureMap2[*cit].feature;
      const QgsGeometry* g2 = f.constGeometry();
      if ( !g2 || !g2->asGeos() )
      {
        QgsMessageLog::logMessage( tr( "Second geometry missing or GEOS import failed." ), tr( "Topology plugin" ) );
        continue;
      }


      if ( g2->intersects( startPoint ) )
      {
        touchStartPoint = true;
      }

      if ( g2->intersects( endPoint ) )
      {
        touchEndPoint = true;
      }

      if ( touchStartPoint && touchEndPoint )
      {
        touched = true;
        break;
      }

    }
    delete startPoint;
    delete endPoint;

    if ( !touched )
    {
      QScopedPointer<QgsGeometry> conflictGeom( new QgsGeometry( *g1 ) );

      if ( isExtent )
      {
        if ( canvasExtentPoly->disjoint( conflictGeom.data() ) )
        {
          continue;
        }
        if ( canvasExtentPoly->crosses( conflictGeom.data() ) )
        {
          conflictGeom.reset( conflictGeom->intersection( canvasExtentPoly ) );
        }
      }
      QList<FeatureLayer> fls;
      fls << *it << *it;
      //bb.scale(10);

      TopolErrorLineEndsNotCoveredByPoints* err = new TopolErrorLineEndsNotCoveredByPoints( bb, conflictGeom.take(), fls );
      errorList << err;
    }
  }
  delete canvasExtentPoly;
  return errorList;
}
Пример #9
0
ErrorList topolTest::checkOverlapWithLayer( double tolerance, QgsVectorLayer* layer1, QgsVectorLayer* layer2, bool isExtent )
{
  Q_UNUSED( tolerance );

  int i = 0;
  ErrorList errorList;

  bool skipItself = layer1 == layer2;
  QgsSpatialIndex* index = mLayerIndexes[layer2->id()];

  QgsGeometry* canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );


  QList<FeatureLayer>::Iterator it;
  QList<FeatureLayer>::ConstIterator FeatureListEnd = mFeatureList1.end();
  for ( it = mFeatureList1.begin(); it != FeatureListEnd; ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    if ( testCancelled() )
      break;

    QgsGeometry* g1 = it->feature.geometry();
    QgsRectangle bb = g1->boundingBox();

    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );

    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();
    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature& f = mFeatureMap2[*cit].feature;
      const QgsGeometry* g2 = f.constGeometry();

      // skip itself, when invoked with the same layer
      if ( skipItself && f.id() == it->feature.id() )
        continue;

      if ( !g2 )
      {
        QgsMessageLog::logMessage( tr( "Second geometry missing." ), tr( "Topology plugin" ) );
        continue;
      }

      if ( g1->overlaps( g2 ) )
      {
        QgsRectangle r = bb;
        QgsRectangle r2 = g2->boundingBox();
        r.combineExtentWith( &r2 );

        QScopedPointer<QgsGeometry> conflictGeom( g1->intersection( g2 ) );
        // could this for some reason return NULL?
        if ( !conflictGeom )
        {
          continue;
        }

        if ( isExtent )
        {
          if ( canvasExtentPoly->disjoint( conflictGeom.data() ) )
          {
            continue;
          }
          if ( canvasExtentPoly->crosses( conflictGeom.data() ) )
          {
            conflictGeom.reset( conflictGeom->intersection( canvasExtentPoly ) );
          }
        }

        //c = new QgsGeometry;

        QList<FeatureLayer> fls;
        FeatureLayer fl;
        fl.feature = f;
        fl.layer = layer2;
        fls << *it << fl;
        TopolErrorIntersection* err = new TopolErrorIntersection( r, conflictGeom.take(), fls );

        errorList << err;
      }
    }
  }
  delete canvasExtentPoly;
  return errorList;
}
Пример #10
0
ErrorList topolTest::checkyLineEndsCoveredByPoints( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );

  int i = 0;
  ErrorList errorList;


  if ( layer1->geometryType() != QgsWkbTypes::LineGeometry )
  {
    return errorList;
  }

  if ( layer2->geometryType() != QgsWkbTypes::PointGeometry )
  {
    return errorList;
  }

  QgsSpatialIndex* index = mLayerIndexes[layer2->id()];

  QgsGeometry canvasExtentPoly = QgsGeometry::fromWkt( theQgsInterface->mapCanvas()->extent().asWktPolygon() );

  QList<FeatureLayer>::Iterator it;
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );
    if ( testCancelled() )
      break;
    QgsGeometry g1 = it->feature.geometry();

    QgsPolyline g1Polyline = g1.asPolyline();
    QgsGeometry startPoint = QgsGeometry::fromPoint( g1Polyline.at( 0 ) );
    QgsGeometry endPoint = QgsGeometry::fromPoint( g1Polyline.last() );

    QgsRectangle bb = g1.boundingBox();
    QList<QgsFeatureId> crossingIds;
    crossingIds = index->intersects( bb );
    QList<QgsFeatureId>::Iterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();
    bool touched = false;

    bool touchStartPoint = false;
    bool touchEndPoint = false;

    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature& f = mFeatureMap2[*cit].feature;
      QgsGeometry g2 = f.geometry();
      if ( g2.isEmpty() || !_canExportToGeos( g2 ) )
      {
        QgsMessageLog::logMessage( tr( "Second geometry missing or GEOS import failed." ), tr( "Topology plugin" ) );
        continue;
      }


      if ( g2.intersects( startPoint ) )
      {
        touchStartPoint = true;
      }

      if ( g2.intersects( endPoint ) )
      {
        touchEndPoint = true;
      }

      if ( touchStartPoint && touchEndPoint )
      {
        touched = true;
        break;
      }

    }

    if ( !touched )
    {
      QgsGeometry conflictGeom = g1;

      if ( isExtent )
      {
        if ( canvasExtentPoly.disjoint( conflictGeom ) )
        {
          continue;
        }
        if ( canvasExtentPoly.crosses( conflictGeom ) )
        {
          conflictGeom = conflictGeom.intersection( canvasExtentPoly );
        }
      }
      QList<FeatureLayer> fls;
      fls << *it << *it;
      //bb.scale(10);

      TopolErrorLineEndsNotCoveredByPoints* err = new TopolErrorLineEndsNotCoveredByPoints( bb, conflictGeom, fls );
      errorList << err;
    }
  }
  return errorList;
}