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 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(); }
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; }
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 ); } } }
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++; } } }
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 ); } } }
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 ); }