コード例 #1
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkMultipart( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( layer2 );
  Q_UNUSED( layer1 );
  Q_UNUSED( isExtent );

  int i = 0;
  ErrorList errorList;
  QList<FeatureLayer>::Iterator it;
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( ++i );
    if ( testCanceled() )
      break;
    QgsGeometry g = it->feature.geometry();
    if ( g.isNull() )
    {
      QgsMessageLog::logMessage( tr( "Missing geometry in multipart check." ), tr( "Topology plugin" ) );
      continue;
    }
    if ( !_canExportToGeos( g ) )
      continue;
    if ( g.isMultipart() )
    {
      QgsRectangle r = g.boundingBox();
      QList<FeatureLayer> fls;
      fls << *it << *it;
      TopolErroMultiPart *err = new TopolErroMultiPart( r, g, fls );
      errorList << err;
    }
  }
  return errorList;
}
コード例 #2
0
ファイル: topolTest.cpp プロジェクト: cz172638/QGIS
ErrorList topolTest::checkPolygonContainsPoint( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );
  Q_UNUSED( isExtent );

  int i = 0;
  ErrorList errorList;

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

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

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

  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.constEnd();
    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 ( g1.contains( g2 ) )
      {
        touched = true;
        break;
      }
    }
    if ( !touched )
    {
      QList<FeatureLayer> fls;
      fls << *it << *it;
      //bb.scale(10);
      TopolErrorPolygonContainsPoint *err = new TopolErrorPolygonContainsPoint( bb, g1, fls );
      errorList << err;
    }
  }
  return errorList;
}
コード例 #3
0
ファイル: topolTest.cpp プロジェクト: cz172638/QGIS
ErrorList topolTest::checkValid( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( tolerance );
  Q_UNUSED( layer1 );
  Q_UNUSED( layer2 );
  Q_UNUSED( isExtent );

  int i = 0;
  ErrorList errorList;
  QgsFeature f;

  QList<FeatureLayer>::Iterator it;

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

    QgsGeometry g = it->feature.geometry();
    if ( g.isNull() )
    {
      QgsMessageLog::logMessage( tr( "Invalid geometry in validity test." ), tr( "Topology plugin" ) );
      continue;
    }

    GEOSGeometry *gGeos = g.exportToGeos();
    if ( !gGeos )
      continue;

    if ( !GEOSisValid_r( QgsGeometry::getGEOSHandler(), gGeos ) )
    {
      QgsRectangle r = g.boundingBox();
      QList<FeatureLayer> fls;
      fls << *it << *it;

      TopolErrorValid *err = new TopolErrorValid( r, g, fls );
      errorList << err;
    }
    GEOSGeom_destroy_r( QgsGeometry::getGEOSHandler(), gGeos );
  }

  return errorList;
}
コード例 #4
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
QgsSpatialIndex *topolTest::createIndex( QgsVectorLayer *layer, const QgsRectangle &extent )
{
  QgsSpatialIndex *index = new QgsSpatialIndex();

  QgsFeatureIterator fit;
  if ( extent.isEmpty() )
  {
    fit = layer->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) );
  }
  else
  {
    fit = layer->getFeatures( QgsFeatureRequest()
                              .setFilterRect( extent )
                              .setFlags( QgsFeatureRequest::ExactIntersect )
                              .setSubsetOfAttributes( QgsAttributeList() ) );
  }


  int i = 0;
  QgsFeature f;
  while ( fit.nextFeature( f ) )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

    if ( testCanceled() )
    {
      delete index;
      return nullptr;
    }

    if ( f.hasGeometry() )
    {
      index->addFeature( f );
      mFeatureMap2[f.id()] = FeatureLayer( layer, f );
    }
  }

  return index;
}
コード例 #5
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkPointCoveredByLineEnds( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  int i = 0;
  ErrorList errorList;


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

  if ( layer2->geometryType() != QgsWkbTypes::LineGeometry )
  {
    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.constBegin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.constEnd();
    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;
      }
      QgsPolylineXY g2Line = g2.asPolyline();
      QgsGeometry startPoint = QgsGeometry::fromPointXY( g2Line.at( 0 ) );
      QgsGeometry endPoint = QgsGeometry::fromPointXY( g2Line.last() );
      touched = g1.intersects( startPoint ) || g1.intersects( endPoint );

      if ( touched )
      {
        break;
      }
    }
    if ( !touched )
    {
      QgsGeometry conflictGeom = g1;
      if ( isExtent )
      {
        if ( canvasExtentPoly.disjoint( conflictGeom ) )
        {
          continue;
        }
      }

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

      TopolErrorPointNotCoveredByLineEnds *err = new TopolErrorPointNotCoveredByLineEnds( bb, conflictGeom, fls );
      errorList << err;
    }
  }
  return errorList;
}
コード例 #6
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkOverlapWithLayer( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  int i = 0;
  ErrorList errorList;

  bool skipItself = layer1 == layer2;
  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();
    for ( ; cit != crossingIdsEnd; ++cit )
    {
      QgsFeature &f = mFeatureMap2[*cit].feature;
      QgsGeometry g2 = f.geometry();

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

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

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

        QgsGeometry conflictGeom = g1.intersection( g2 );
        // could this for some reason return NULL?
        if ( conflictGeom.isNull() )
        {
          continue;
        }

        if ( isExtent )
        {
          if ( canvasExtentPoly.disjoint( conflictGeom ) )
          {
            continue;
          }
          if ( canvasExtentPoly.crosses( conflictGeom ) )
          {
            conflictGeom = 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, fls );

        errorList << err;
      }
    }
  }
  return errorList;
}
コード例 #7
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkPointCoveredBySegment( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  int i = 0;

  ErrorList errorList;

  if ( layer1->geometryType() != QgsWkbTypes::PointGeometry )
  {
    return errorList;
  }
  if ( layer2->geometryType() == QgsWkbTypes::PointGeometry )
  {
    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() )
      {
        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 = QgsGeometry( g1 );

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

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

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

      errorList << err;
    }
  }
  return errorList;
}
コード例 #8
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkPseudos( 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( "Skipping invalid first geometry in pseudo line test." ), tr( "Topology plugin" ) );
      continue;
    }

    if ( !_canExportToGeos( g1 ) )
    {
      QgsMessageLog::logMessage( tr( "Failed to import first geometry into GEOS in pseudo 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 );

    if ( repetitions == 2 )
    {
      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;

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

    }
  }
  return errorList;
}
コード例 #9
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkGaps( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( layer2 );

  int i = 0;
  ErrorList errorList;
  GEOSContextHandle_t geosctxt = QgsGeos::getGEOSHandler();

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

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

  QList<FeatureLayer>::iterator it;
  QgsGeometry g1;

  QList<GEOSGeometry *> geomList;

  qDebug() << mFeatureList1.count() << " features in list!";
  for ( it = mFeatureList1.begin(); it != mFeatureList1.end(); ++it )
  {
    qDebug() << "reading features-" << i;

    if ( !( ++i % 100 ) )
    {
      emit progress( i );
    }

    if ( testCanceled() )
    {
      break;
    }

    g1 = it->feature.geometry();

    if ( g1.isNull() )
    {
      continue;
    }

    if ( !_canExportToGeos( g1 ) )
    {
      continue;
    }

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

    if ( g1.isMultipart() )
    {
      QgsMultiPolygonXY polys = g1.asMultiPolygon();
      for ( int m = 0; m < polys.count(); m++ )
      {
        QgsPolygonXY polygon = polys[m];

        QgsGeometry polyGeom = QgsGeometry::fromPolygonXY( polygon );

        geomList.push_back( QgsGeos::asGeos( polyGeom ).release() );
      }

    }
    else
    {
      geomList.push_back( QgsGeos::asGeos( g1 ).release() );
    }
  }

  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.isEmpty() )
  {
    //qDebug() << "geometry list is empty!";
    delete [] geomArray;
    return errorList;
  }

  GEOSGeometry *collection = nullptr;
  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 = QgsGeos::geometryFromGeos( unionGeom );

  //qDebug() << "wktmerged - " << test.exportToWkt();

  QString extentWkt = test.boundingBox().asWktPolygon();
  QgsGeometry extentGeom = QgsGeometry::fromWkt( extentWkt );
  QgsGeometry bufferExtent = extentGeom.buffer( 2, 3 );

  //qDebug() << "extent wkt - " << bufferExtent->exportToWkt();

  QgsGeometry diffGeoms = bufferExtent.difference( test );
  if ( !diffGeoms )
  {
    qDebug() << "difference result 0-";
    return errorList;
  }

  //qDebug() << "difference gometry - " << diffGeoms->exportToWkt();

  QVector<QgsGeometry> geomColl = diffGeoms.asGeometryCollection();

  QgsGeometry canvasExtentPoly = QgsGeometry::fromWkt( qgsInterface->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();
    FeatureLayer ftrLayer1;
    ftrLayer1.layer = layer1;
    QList<FeatureLayer> errorFtrLayers;
    errorFtrLayers << ftrLayer1 << ftrLayer1;
    TopolErrorGaps *err = new TopolErrorGaps( bBox, conflictGeom, errorFtrLayers );
    errorList << err;
  }

  return errorList;
}
コード例 #10
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkOverlaps( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  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() != QgsWkbTypes::PolygonGeometry )
  {
    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>::const_iterator it;
  for ( it = mFeatureMap2.constBegin(); it != mFeatureMap2.constEnd(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

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

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

    if ( testCanceled() )
      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>::ConstIterator cit = crossingIds.begin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.end();

    bool duplicate = false;

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

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

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

      if ( !_canExportToGeos( g2 ) )
      {
        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;
        QgsGeometry conflictGeom = g1.intersection( g2 );

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

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

        errorList << err;
      }

    }
  }

  delete duplicateIds;

  return errorList;
}
コード例 #11
0
ファイル: topolTest.cpp プロジェクト: phborba/QGIS
ErrorList topolTest::checkDuplicates( QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  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( qgsInterface->mapCanvas()->extent().asWktPolygon() );

  QMap<QgsFeatureId, FeatureLayer>::const_iterator it;
  for ( it = mFeatureMap2.constBegin(); it != mFeatureMap2.constEnd(); ++it )
  {
    if ( !( ++i % 100 ) )
      emit progress( i );

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

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

    if ( testCanceled() )
      break;

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

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

    QList<QgsFeatureId>::ConstIterator cit = crossingIds.constBegin();
    QList<QgsFeatureId>::ConstIterator crossingIdsEnd = crossingIds.constEnd();

    bool duplicate = false;

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

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

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

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

      if ( duplicate )
      {


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

        if ( isExtent )
        {
          if ( canvasExtentPoly.disjoint( conflict ) )
          {
            continue;
          }
          if ( canvasExtentPoly.crosses( conflict ) )
          {
            conflict = conflict.intersection( canvasExtentPoly );
          }
        }

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

        errorList << err;
      }

    }

  }
  return errorList;
}
コード例 #12
0
void Downloader::onReadyRead()
{
    if (testCanceled()) {
        m_futureInterface->reportFinished();
        emit finished(); return;    // error
    }

    QNetworkReply *const reply = qobject_cast<QNetworkReply *>(sender());
    if (!reply)
        return;

    Data &data = *m_downloads[reply];
    if (!data.file) {
        std::unique_ptr<QFile> file = Q_NULLPTR;
        const QString target = data.taskItem.target();
        if (target.isEmpty()) {
            std::unique_ptr<QTemporaryFile> tmp(new QTemporaryFile);
            tmp->setAutoRemove(false);
            file = std::move(tmp);
        } else {
            std::unique_ptr<QFile> tmp(new QFile(target));
            file = std::move(tmp);
        }

        if (file->exists() && (!QFileInfo(file->fileName()).isFile())) {
            m_futureInterface->reportException(TaskException(tr("Target file \"%1\" already exists "
                "but is not a file.").arg(file->fileName())));
            return;
        }

        if (!file->open(QIODevice::WriteOnly | QIODevice::Truncate)) {
            //: %2 is a sentence describing the error
            m_futureInterface->reportException(
                        TaskException(tr("Cannot open file \"%1\" for writing: %2").arg(
                                          QDir::toNativeSeparators(file->fileName()),
                                          file->errorString())));
            return;
        }
        data.file = std::move(file);
    }

    if (!data.file->isOpen()) {
        //: %2 is a sentence describing the error.
        m_futureInterface->reportException(
                    TaskException(tr("File \"%1\" not open for writing: %2").arg(
                                      QDir::toNativeSeparators(data.file->fileName()),
                                      data.file->errorString())));
        return;
    }

    QByteArray buffer(32768, Qt::Uninitialized);
    while (reply->bytesAvailable()) {
        if (testCanceled()) {
            m_futureInterface->reportFinished();
            emit finished(); return;    // error
        }

        const qint64 read = reply->read(buffer.data(), buffer.size());
        qint64 written = 0;
        while (written < read) {
            const qint64 toWrite = data.file->write(buffer.constData() + written, read - written);
            if (toWrite < 0) {
                //: %2 is a sentence describing the error.
                m_futureInterface->reportException(
                            TaskException(tr("Writing to file \"%1\" failed: %2").arg(
                                                  QDir::toNativeSeparators(data.file->fileName()),
                                              data.file->errorString())));
                return;
            }
            written += toWrite;
        }

        data.observer->addSample(read);
        data.observer->addBytesTransfered(read);
        data.observer->addCheckSumData(buffer.data(), read);

        int progress = m_finished * 100;
        for (const auto &pair : m_downloads)
            progress += pair.second->observer->progressValue();
        if (!reply->attribute(QNetworkRequest::RedirectionTargetAttribute).isValid()) {
            m_futureInterface->setProgressValueAndText(progress / m_items.count(),
                data.observer->progressText());
        }
    }
}
コード例 #13
0
ファイル: topolTest.cpp プロジェクト: cz172638/QGIS
ErrorList topolTest::checkSegmentLength( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( layer1 );
  Q_UNUSED( layer2 );
  Q_UNUSED( isExtent );

  int i = 0;
  ErrorList errorList;
  QgsFeature f;


  QList<FeatureLayer>::iterator it;

  QgsPolygonXY pol;

  QgsMultiPolygonXY mpol;
  QgsPolylineXY segm;
  QgsPolylineXY ls;
  QgsMultiPolylineXY mls;
  QList<FeatureLayer> fls;
  TopolErrorShort *err = nullptr;
  double distance;

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

    if ( testCanceled() )
    {
      break;
    }

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


    // switching by type here, because layer can contain both single and multi version geometries
    switch ( g1.wkbType() )
    {
      case QgsWkbTypes::LineString:
      case QgsWkbTypes::LineString25D:
        ls = g1.asPolyline();


        for ( int i = 1; i < ls.size(); ++i )
        {
          distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
          if ( distance < tolerance )
          {
            fls.clear();
            fls << *it << *it;
            segm.clear();
            segm << ls[i - 1] << ls[i];
            QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
            err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
            //err = new TopolErrorShort(g1->boundingBox(), QgsGeometry::fromPolyline(segm), fls);
            errorList << err;
            //break on getting the first error
            break;
          }
        }
        break;

      case QgsWkbTypes::Polygon:
      case QgsWkbTypes::Polygon25D:
        pol = g1.asPolygon();

        for ( int i = 0; i < pol.size(); ++i )
        {
          for ( int j = 1; j < pol[i].size(); ++j )
          {
            distance = std::sqrt( pol[i][j - 1].sqrDist( pol[i][j] ) );
            if ( distance < tolerance )
            {
              fls.clear();
              fls << *it << *it;
              segm.clear();
              segm << pol[i][j - 1] << pol[i][j];
              QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
              err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
              errorList << err;
              //break on getting the first error
              break;
            }
          }
        }

        break;

      case QgsWkbTypes::MultiLineString:
      case QgsWkbTypes::MultiLineString25D:
        mls = g1.asMultiPolyline();

        for ( int k = 0; k < mls.size(); ++k )
        {
          QgsPolylineXY &ls = mls[k];
          for ( int i = 1; i < ls.size(); ++i )
          {
            distance = std::sqrt( ls[i - 1].sqrDist( ls[i] ) );
            if ( distance < tolerance )
            {
              fls.clear();
              fls << *it << *it;
              segm.clear();
              segm << ls[i - 1] << ls[i];
              QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
              err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
              errorList << err;
              //break on getting the first error
              break;
            }
          }
        }
        break;

      case QgsWkbTypes::MultiPolygon:
      case QgsWkbTypes::MultiPolygon25D:
        mpol = g1.asMultiPolygon();

        for ( int k = 0; k < mpol.size(); ++k )
        {
          QgsPolygonXY &pol = mpol[k];
          for ( int i = 0; i < pol.size(); ++i )
          {
            for ( int j = 1; j < pol[i].size(); ++j )
            {
              distance = pol[i][j - 1].sqrDist( pol[i][j] );
              if ( distance < tolerance )
              {
                fls.clear();
                fls << *it << *it;
                segm.clear();
                segm << pol[i][j - 1] << pol[i][j];
                QgsGeometry conflict = QgsGeometry::fromPolylineXY( segm );
                err = new TopolErrorShort( g1.boundingBox(), conflict, fls );
                errorList << err;
                //break on getting the first error
                break;
              }
            }
          }
        }
        break;

      default:
        continue;
    }
  }

  return errorList;
}
コード例 #14
0
ファイル: topolTest.cpp プロジェクト: cz172638/QGIS
ErrorList topolTest::checkCloseFeature( double tolerance, QgsVectorLayer *layer1, QgsVectorLayer *layer2, bool isExtent )
{
  Q_UNUSED( isExtent );
  ErrorList errorList;
  QgsSpatialIndex *index = 0;

  bool badG1 = false, badG2 = false;
  bool skipItself = layer1 == layer2;

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

    if ( testCanceled() )
      break;

    QgsGeometry *g1 = it->feature.geometry();
    if ( !g1 || !g1->asGeos() )
    {
      badG1 = true;
      continue;
    }

    QgsRectangle bb = g1->boundingBox();

    // increase bounding box by tolerance
    QgsRectangle frame( bb.xMinimum() - tolerance, bb.yMinimum() - tolerance, bb.xMaximum() + tolerance, bb.yMaximum() + tolerance );

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

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

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

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

      if ( !g2 || !g2->asGeos() )
      {
        badG2 = true;
        continue;
      }

      if ( g1->distance( *g2 ) < tolerance )
      {
        QgsRectangle r = g2->boundingBox();
        r.combineExtentWith( &bb );

        QList<FeatureLayer> fls;
        FeatureLayer fl;
        fl.feature = f;
        fl.layer = layer2;
        fls << *it << fl;
        QgsGeometry *conflict = new QgsGeometry( *g2 );
        TopolErrorClose *err = new TopolErrorClose( r, conflict, fls );
        //TopolErrorClose* err = new TopolErrorClose(r, g2, fls);

        errorList << err;
      }
    }
  }

  if ( badG2 )
    QgsMessageLog::logMessage( tr( "Invalid second geometry." ), tr( "Topology plugin" ) );

  if ( badG1 )
    QgsMessageLog::logMessage( tr( "Invalid first geometry." ), tr( "Topology plugin" ) );

  return errorList;
}