Beispiel #1
0
void checkDock::validate( ValidateType type )
{
  mErrorList.clear();

  QList<QgsRubberBand*>::const_iterator it;
  for ( it = mRbErrorMarkers.begin(); it != mRbErrorMarkers.end(); ++it )
  {
    QgsRubberBand* rb = *it;
    rb->reset();
    delete rb;
  }

  mRbErrorMarkers.clear();

  runTests( type );
  mComment->setText( tr( "%1 errors were found" ).arg( mErrorList.count() ) );

  mRBFeature1->reset();
  mRBFeature2->reset();
  mRBConflict->reset();
  clearVertexMarkers();

  mErrorTableView->resizeColumnsToContents();
  mToggleRubberband->setChecked( true );
}
Beispiel #2
0
void checkDock::runTests( ValidateType type )
{
  for ( int i = 0; i < mTestTable->rowCount(); ++i )
  {
    QString testName = mTestTable->item( i, 0 )->text();
    QString layer1Str = mTestTable->item( i, 3 )->text();
    QString layer2Str = mTestTable->item( i, 4 )->text();

    // test if layer1 is in the registry
    if ( !( ( QgsVectorLayer * )QgsProject::instance()->mapLayers().contains( layer1Str ) ) )
    {
      QgsMessageLog::logMessage( tr( "Layer %1 not found in registry." ).arg( layer1Str ), tr( "Topology plugin" ) );
      return;
    }

    QgsVectorLayer *layer1 = ( QgsVectorLayer * )QgsProject::instance()->mapLayer( layer1Str );
    QgsVectorLayer *layer2 = nullptr;

    if ( ( QgsVectorLayer * )QgsProject::instance()->mapLayers().contains( layer2Str ) )
      layer2 = ( QgsVectorLayer * )QgsProject::instance()->mapLayer( layer2Str );

    QProgressDialog progress( testName, tr( "Abort" ), 0, layer1->featureCount(), this );
    progress.setWindowModality( Qt::WindowModal );

    connect( &progress, &QProgressDialog::canceled, mTest, &topolTest::setTestCanceled );
    connect( mTest, &topolTest::progress, &progress, &QProgressDialog::setValue );
    // run the test

    ErrorList errors = mTest->runTest( testName, layer1, layer2, type );

    QList<TopolError *>::Iterator it;

    QgsRubberBand *rb = nullptr;
    for ( it = errors.begin(); it != errors.end(); ++it )
    {
      TopolError *te = *it;
      te->conflict();

      QgsSettings settings;
      if ( te->conflict().type() == QgsWkbTypes::PolygonGeometry )
      {
        rb = new QgsRubberBand( qgsInterface->mapCanvas(), QgsWkbTypes::PolygonGeometry );
      }
      else
      {
        rb = new QgsRubberBand( qgsInterface->mapCanvas(), te->conflict().type() );
      }
      rb->setColor( "red" );
      rb->setWidth( 4 );
      rb->setToGeometry( te->conflict(), layer1 );
      rb->show();
      mRbErrorMarkers << rb;
    }
    disconnect( &progress, &QProgressDialog::canceled, mTest, &topolTest::setTestCanceled );
    disconnect( mTest, &topolTest::progress, &progress, &QProgressDialog::setValue );
    mErrorList << errors;
  }
  mToggleRubberband->setChecked( true );
  mErrorListModel->resetModel();
}
Beispiel #3
0
QgsRubberBand* QgsMapToolEdit::createRubberBand( QGis::GeometryType geometryType )
{
  QSettings settings;
  QgsRubberBand* rb = new QgsRubberBand( mCanvas, geometryType );
  QColor color( settings.value( "/qgis/digitizing/line_color_red", 255 ).toInt(),
                settings.value( "/qgis/digitizing/line_color_green", 0 ).toInt(),
                settings.value( "/qgis/digitizing/line_color_blue", 0 ).toInt() );
  rb->setColor( color );
  rb->setWidth( settings.value( "/qgis/digitizing/line_width", 1 ).toInt() );
  rb->show();
  return rb;
}
Beispiel #4
0
void checkDock::toggleErrorMarker()
{
  QList<QgsRubberBand*>::const_iterator it;
  for ( it = mRbErrorMarkers.begin(); it != mRbErrorMarkers.end(); ++it )
  {
    QgsRubberBand* rb = *it;
    if ( mToggleRubberband->isChecked() )
    {
      rb->show();
    }
    else
    {
      rb->hide();
    }
  }
}
Beispiel #5
0
void checkDock::toggleErrorMarkers()
{
  QList<QgsRubberBand*>::const_iterator it;
  for ( it = mRbErrorMarkers.begin(); it != mRbErrorMarkers.end(); ++it )
  {
    QgsRubberBand* rb = *it;
    if ( mMarkersVisible == true )
    {
      rb->hide();
    }
    else
    {
      rb->show();
    }
  }
  mMarkersVisible = !mMarkersVisible;

}
Beispiel #6
0
checkDock::~checkDock()
{
  delete mConfigureDialog;
  delete mErrorListModel;

  QList<QgsRubberBand*>::const_iterator it;
  for ( it = mRbErrorMarkers.begin(); it != mRbErrorMarkers.end(); ++it )
  {
    QgsRubberBand* rb = *it;
    rb->reset();
    delete rb;
  }

  clearVertexMarkers();

  // delete errors in list
  deleteErrors();
}
Beispiel #7
0
void checkDock::deleteErrors()
{
  QList<TopolError*>::Iterator it = mErrorList.begin();
  for ( ; it != mErrorList.end(); ++it )
    delete *it;

  mErrorList.clear();
  mErrorListModel->resetModel();

  QList<QgsRubberBand*>::const_iterator rit;

  for ( rit = mRbErrorMarkers.begin(); rit != mRbErrorMarkers.end(); ++rit )
  {
    QgsRubberBand* rb = *rit;
    rb->reset();
    delete rb;
  }
}
Beispiel #8
0
QgsRubberBand* QgsMapToolEdit::createRubberBand( QGis::GeometryType geometryType, bool alternativeBand )
{
  QSettings settings;
  QgsRubberBand* rb = new QgsRubberBand( mCanvas, geometryType );
  rb->setWidth( settings.value( "/qgis/digitizing/line_width", 1 ).toInt() );
  QColor color(
    settings.value( "/qgis/digitizing/line_color_red", 255 ).toInt(),
    settings.value( "/qgis/digitizing/line_color_green", 0 ).toInt(),
    settings.value( "/qgis/digitizing/line_color_blue", 0 ).toInt() );
  double myAlpha = settings.value( "/qgis/digitizing/line_color_alpha", 200 ).toInt() / 255.0;
  if ( alternativeBand )
  {
    myAlpha = myAlpha * settings.value( "/qgis/digitizing/line_color_alpha_scale", 0.75 ).toDouble();
    rb->setLineStyle( Qt::DotLine );
  }
  if ( geometryType == QGis::Polygon )
  {
    color.setAlphaF( myAlpha );
  }
  color.setAlphaF( myAlpha );
  rb->setColor( color );

  QColor fillColor(
    settings.value( "/qgis/digitizing/fill_color_red", 255 ).toInt(),
    settings.value( "/qgis/digitizing/fill_color_green", 0 ).toInt(),
    settings.value( "/qgis/digitizing/fill_color_blue", 0 ).toInt() );
  myAlpha = settings.value( "/qgis/digitizing/fill_color_alpha", 30 ).toInt() / 255.0 ;
  fillColor.setAlphaF( myAlpha );
  rb->setFillColor( fillColor );

  rb->show();
  return rb;
}
void QgsMapToolPinLabels::highlightLabel( const QgsLabelPosition &labelpos,
    const QString &id,
    const QColor &color )
{
  QgsRectangle rect = labelpos.labelRect;
  QgsRubberBand *rb = new QgsRubberBand( mCanvas, QgsWkbTypes::PolygonGeometry );
  rb->addPoint( QgsPointXY( rect.xMinimum(), rect.yMinimum() ) );
  rb->addPoint( QgsPointXY( rect.xMinimum(), rect.yMaximum() ) );
  rb->addPoint( QgsPointXY( rect.xMaximum(), rect.yMaximum() ) );
  rb->addPoint( QgsPointXY( rect.xMaximum(), rect.yMinimum() ) );
  rb->addPoint( QgsPointXY( rect.xMinimum(), rect.yMinimum() ) );
  rb->setColor( color );
  rb->setWidth( 0 );
  rb->show();

  mHighlights.insert( id, rb );
}
QgsRubberBand* QgsMapToolNodeTool::createRubberBandMarker( QgsPoint center, QgsVectorLayer* vlayer )
{
  //create rubber band marker for moving points
  QgsRubberBand* marker = new QgsRubberBand( mCanvas, true );
  marker->setColor( Qt::red );
  marker->setWidth( 2 );
  double movement = 4;
  double s = QgsTolerance::toleranceInMapUnits( movement, vlayer, mCanvas->mapRenderer(), QgsTolerance::Pixels );
  QgsPoint pom = toMapCoordinates( vlayer, center );
  pom.setX( pom.x() - s );
  pom.setY( pom.y() - s );
  marker->addPoint( pom );
  pom.setX( pom.x() + 2*s );
  marker->addPoint( pom );
  pom.setY( pom.y() + 2*s );
  marker->addPoint( pom );
  pom.setX( pom.x() - 2*s );
  marker->addPoint( pom );
  pom.setY( pom.y() - 2*s );
  marker->addPoint( pom );
  return marker;
}
void QgsGeometryCheckerResultTab::highlightErrors( bool current )
{
  qDeleteAll( mCurrentRubberBands );
  mCurrentRubberBands.clear();

  QList<QTableWidgetItem*> items;
  QList<QgsPoint> errorPositions;
  QgsRectangle totextent;

  if ( current )
  {
    items.append( ui.tableWidgetErrors->currentItem() );
  }
  else
  {
    items.append( ui.tableWidgetErrors->selectedItems() );
  }
  foreach ( QTableWidgetItem* item, items )
  {
    QgsGeometryCheckError* error = ui.tableWidgetErrors->item( item->row(), 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError*>();

    QgsAbstractGeometryV2* geometry = error->geometry();
    if ( ui.checkBoxHighlight->isChecked() && geometry )
    {
      QgsRubberBand* featureRubberBand = new QgsRubberBand( mIface->mapCanvas() );
      QgsGeometry geom( geometry );
      featureRubberBand->addGeometry( &geom, mFeaturePool->getLayer() );
      featureRubberBand->setWidth( 5 );
      featureRubberBand->setColor( Qt::yellow );
      mCurrentRubberBands.append( featureRubberBand );
    }
    else
    {
      // QgsGeometry above takes ownership of geometry and deletes it when it goes out of scope
      delete geometry;
      geometry = 0;
    }

    if ( ui.radioButtonError->isChecked() || current || error->status() == QgsGeometryCheckError::StatusFixed )
    {
      QgsRubberBand* pointRubberBand = new QgsRubberBand( mIface->mapCanvas(), QGis::Point );
      QgsPoint pos = mIface->mapCanvas()->mapSettings().layerToMapCoordinates( mFeaturePool->getLayer(), QgsPoint( error->location().x(), error->location().y() ) );
      pointRubberBand->addPoint( pos );
      pointRubberBand->setWidth( 20 );
      pointRubberBand->setColor( Qt::red );
      mCurrentRubberBands.append( pointRubberBand );
      errorPositions.append( pos );
    }
    else if ( ui.radioButtonFeature->isChecked() && geometry )
    {
      QgsRectangle geomextent = mIface->mapCanvas()->mapSettings().layerExtentToOutputExtent( mFeaturePool->getLayer(), geometry->boundingBox() );
      if ( totextent.isEmpty() )
      {
        totextent = geomextent;
      }
      else
      {
        totextent.unionRect( geomextent );
      }
    }
  }
Beispiel #12
0
void QgsMapToolNodeTool::createMovingRubberBands()
{
  int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 );

  Q_ASSERT( mSelectedFeature );

  QgsVectorLayer *vlayer = mSelectedFeature->vlayer();
  Q_ASSERT( vlayer );

  QList<QgsVertexEntry*> &vertexMap = mSelectedFeature->vertexMap();
  QgsGeometry* geometry = mSelectedFeature->geometry();
  int beforeVertex, afterVertex;
  int lastRubberBand = 0;
  int vertex;
  for ( int i = 0; i < vertexMap.size(); i++ )
  {
    // create rubberband
    if ( vertexMap[i]->isSelected() && !vertexMap[i]->isInRubberBand() )
    {
      geometry->adjacentVertices( i, beforeVertex, afterVertex );
      vertex = i;
      while ( beforeVertex !=  -1 )
      {
        // move forward NOTE: end if whole cycle is selected
        if ( vertexMap[beforeVertex]->isSelected() && beforeVertex != i ) // and take care of cycles
        {
          vertex = beforeVertex;
          geometry->adjacentVertices( vertex, beforeVertex, afterVertex );
        }
        else
        {
          // break if cycle is found
          break;
        }
      }
      // we have first vertex of moving part
      // create rubberband and set default paramaters
      QgsRubberBand* rb = new QgsRubberBand( mCanvas, QGis::Line );
      rb->setWidth( 2 );
      rb->setColor( Qt::blue );
      int index = 0;
      if ( beforeVertex != -1 ) // adding first point which is not moving
      {
        rb->addPoint( toMapCoordinates( vlayer, vertexMap[beforeVertex]->point() ), false );
        vertexMap[beforeVertex]->setRubberBandValues( true, lastRubberBand, index );
        index++;
      }
      while ( vertex != -1 && vertexMap[vertex]->isSelected() && !vertexMap[vertex]->isInRubberBand() )
      {
        // topology rubberband creation if needed
        if ( topologicalEditing )
        {
          createTopologyRubberBands( vlayer, vertexMap, vertex );
        }
        // adding point which will be moved
        rb->addPoint( toMapCoordinates( vlayer, vertexMap[vertex]->point() ), false );
        // setting values about added vertex
        vertexMap[vertex]->setRubberBandValues( true, lastRubberBand, index );
        index++;
        geometry->adjacentVertices( vertex, beforeVertex, vertex );
      }
      if ( vertex != -1 && !vertexMap[vertex]->isSelected() ) // add last point not moving if exists
      {
        rb->addPoint( toMapCoordinates( vlayer, vertexMap[vertex]->point() ), true );
        vertexMap[vertex]->setRubberBandValues( true, lastRubberBand, index );
        index++;
      }
      mRubberBands.append( rb );
      lastRubberBand++;
    }
  }
}
Beispiel #13
0
void QgsMapToolNodeTool::createTopologyRubberBands( QgsVectorLayer* vlayer, const QList<QgsVertexEntry*> &vertexMap, int vertex )
{
  QMultiMap<double, QgsSnappingResult> currentResultList;
  QgsGeometry *geometry = mSelectedFeature->geometry();

  // snap from current vertex
  currentResultList.clear();
  vlayer->snapWithContext( vertexMap[vertex]->point(), ZERO_TOLERANCE, currentResultList, QgsSnapper::SnapToVertex );
  QMultiMap<double, QgsSnappingResult>::iterator resultIt =  currentResultList.begin();

  for ( ; resultIt != currentResultList.end(); ++resultIt )
  {
    // move all other
    if ( mSelectedFeature->featureId() != resultIt.value().snappedAtGeometry )
    {
      if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry ) )
      {
        if ( mTopologyMovingVertexes[resultIt.value().snappedAtGeometry]->contains( resultIt.value().snappedVertexNr ) )
        {
          // skip vertex already exists in some rubberband
          continue;
        }
      }
      QgsRubberBand* trb = new QgsRubberBand( mCanvas, QGis::Line );
      mTopologyRubberBand.append( trb );
      int rbId = mTopologyRubberBand.size() - 1;
      trb->setWidth( 1 );
      trb->setColor( Qt::red );

      int tVertex = resultIt.value().snappedVertexNr;
      int tVertexBackup = -1, tVertexAfter = -1;
      int tVertexFirst = tVertex; // vertex number to check for cycling
      QgsFeature topolFeature;

      vlayer->getFeatures( QgsFeatureRequest().setFilterFid( resultIt.value().snappedAtGeometry ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( topolFeature );
      QgsGeometry* topolGeometry = topolFeature.geometry();

      while ( tVertex != -1 ) // looking for first vertex to rubberband
      {
        tVertexBackup = tVertex;
        topolGeometry->adjacentVertices( tVertex, tVertex, tVertexAfter );
        if ( tVertex == -1 || tVertex == tVertexFirst )
          break; // check if this is not first vertex of the feature or cycling error
        // if closest vertex is not from selected feature or is not selected end
        double dist;
        QgsPoint point = topolGeometry->vertexAt( tVertex );
        int at, before, after;
        geometry->closestVertex( point, at, before, after, dist );
        if ( dist > ZERO_TOLERANCE || !vertexMap[at]->isSelected() ) // problem with double precision
        {
          break; // found first vertex
        }
      }

      int movingPointIndex = 0;
      Vertexes* movingPoints = new Vertexes();
      Vertexes* addedPoints = new Vertexes();
      if ( mTopologyMovingVertexes.contains( resultIt.value().snappedAtGeometry ) )
      {
        addedPoints = mTopologyMovingVertexes[ resultIt.value().snappedAtGeometry ];
      }
      if ( tVertex == -1 ) // adding first point if needed
      {
        tVertex = tVertexBackup;
      }
      else
      {
        trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) );
        if ( tVertex == tVertexFirst ) // cycle first vertex need to be added also
        {
          movingPoints->insert( movingPointIndex );
        }
        movingPointIndex = 1;
        topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex );
      }

      while ( tVertex != -1 )
      {
        // if closest vertex is not from selected feature or is not selected end
        double dist;
        QgsPoint point = topolGeometry->vertexAt( tVertex );
        int at, before, after;
        geometry->closestVertex( point, at, before, after, dist );
        // find first no matching vertex
        if ( dist > ZERO_TOLERANCE || !vertexMap[at]->isSelected() ) // problem with double precision
        {
          trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) );
          break; // found first vertex
        }
        else // add moving point to rubberband
        {
          if ( addedPoints->contains( tVertex ) )
            break; // just preventing to circle
          trb->addPoint( toMapCoordinates( vlayer, topolGeometry->vertexAt( tVertex ) ) );
          movingPoints->insert( movingPointIndex );
          movingPointIndex++;
          addedPoints->insert( tVertex );
        }
        topolGeometry->adjacentVertices( tVertex, tVertexAfter, tVertex );
      }
      mTopologyMovingVertexes.insert( resultIt.value().snappedAtGeometry, addedPoints );
      mTopologyRubberBandVertexes.insert( rbId, movingPoints );
    }
  }
}
Beispiel #14
0
void checkDock::runTests( ValidateType type )
{
  for ( int i = 0; i < mTestTable->rowCount(); ++i )
  {
    QString testName = mTestTable->item( i, 0 )->text();
    QString toleranceStr = mTestTable->item( i, 3 )->text();
    QString layer1Str = mTestTable->item( i, 4 )->text();
    QString layer2Str = mTestTable->item( i, 5 )->text();

    // test if layer1 is in the registry
    if ( !(( QgsVectorLayer* )mLayerRegistry->mapLayers().contains( layer1Str ) ) )
    {
      QgsMessageLog::logMessage( tr( "Layer %1 not found in registry." ).arg( layer1Str ), tr( "Topology plugin" ) );
      return;
    }

    QgsVectorLayer* layer1 = ( QgsVectorLayer* )mLayerRegistry->mapLayers()[layer1Str];
    QgsVectorLayer* layer2 = 0;

    if (( QgsVectorLayer* )mLayerRegistry->mapLayers().contains( layer2Str ) )
      layer2 = ( QgsVectorLayer* )mLayerRegistry->mapLayers()[layer2Str];

    QProgressDialog progress( testName, tr( "Abort" ), 0, layer1->featureCount(), this );
    progress.setWindowModality( Qt::WindowModal );

    connect( &progress, SIGNAL( canceled() ), mTest, SLOT( setTestCancelled() ) );
    connect( mTest, SIGNAL( progress( int ) ), &progress, SLOT( setValue( int ) ) );
    // run the test

    ErrorList errors = mTest->runTest( testName, layer1, layer2, type, toleranceStr.toDouble() );

    QList<TopolError*>::Iterator it;

    QgsRubberBand* rb = 0;
    for ( it = errors.begin(); it != errors.end(); ++it )
    {
      TopolError* te = *it;
      te->conflict();

      QSettings settings;
      if ( te->conflict()->type() == QGis::Polygon )
      {
        rb = new QgsRubberBand( qgsInterface->mapCanvas(), true );
      }
      else
      {
        rb = new QgsRubberBand( qgsInterface->mapCanvas(), te->conflict()->type() );
      }
      rb->setColor( "red" );
      rb->setWidth( 4 );
      rb->setToGeometry( te->conflict(), layer1 );
      rb->show();
      mRbErrorMarkers << rb;
    }
    disconnect( &progress, SIGNAL( canceled() ), mTest, SLOT( setTestCancelled() ) );
    disconnect( mTest, SIGNAL( progress( int ) ), &progress, SLOT( setValue( int ) ) );
    mErrorList << errors;
  }
  mMarkersVisible = true;
  mErrorListModel->resetModel();
}
void QgsGeometryCheckerResultTab::highlightErrors( bool current )
{
  qDeleteAll( mCurrentRubberBands );
  mCurrentRubberBands.clear();

  QList<QTableWidgetItem *> items;
  QVector<QgsPointXY> errorPositions;
  QgsRectangle totextent;

  if ( current )
  {
    items.append( ui.tableWidgetErrors->currentItem() );
  }
  else
  {
    items.append( ui.tableWidgetErrors->selectedItems() );
  }
  for ( QTableWidgetItem *item : qgis::as_const( items ) )
  {
    QgsGeometryCheckError *error = ui.tableWidgetErrors->item( item->row(), 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError *>();

    const QgsGeometry geom = error->geometry();
    if ( ui.checkBoxHighlight->isChecked() && !geom.isNull() )
    {
      QgsRubberBand *featureRubberBand = new QgsRubberBand( mIface->mapCanvas() );
      featureRubberBand->addGeometry( geom, nullptr );
      featureRubberBand->setWidth( 5 );
      featureRubberBand->setColor( Qt::yellow );
      mCurrentRubberBands.append( featureRubberBand );
    }

    if ( ui.radioButtonError->isChecked() || current || error->status() == QgsGeometryCheckError::StatusFixed )
    {
      QgsRubberBand *pointRubberBand = new QgsRubberBand( mIface->mapCanvas(), QgsWkbTypes::PointGeometry );
      pointRubberBand->addPoint( error->location() );
      pointRubberBand->setWidth( 20 );
      pointRubberBand->setColor( Qt::red );
      mCurrentRubberBands.append( pointRubberBand );
      errorPositions.append( error->location() );
    }
    else if ( ui.radioButtonFeature->isChecked() )
    {
      QgsRectangle geomextent = error->affectedAreaBBox();
      if ( totextent.isEmpty() )
      {
        totextent = geomextent;
      }
      else
      {
        totextent.combineExtentWith( geomextent );
      }
    }
  }

  // If error positions positions are marked, pan to the center of all positions,
  // and zoom out if necessary to make all points fit.
  if ( !errorPositions.isEmpty() )
  {
    double cx = 0., cy = 0.;
    QgsRectangle pointExtent( errorPositions.first(), errorPositions.first() );
    Q_FOREACH ( const QgsPointXY &p, errorPositions )
    {
      cx += p.x();
      cy += p.y();
      pointExtent.include( p );
    }