void QgsVectorLayerJoinBuffer::cacheJoinLayer( QgsVectorJoinInfo& joinInfo ) { //memory cache not required or already done if ( !joinInfo.memoryCache || joinInfo.cachedAttributes.size() > 0 ) { return; } QgsVectorLayer* cacheLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) ); if ( cacheLayer ) { int joinFieldIndex; if ( joinInfo.joinFieldName.isEmpty() ) joinFieldIndex = joinInfo.joinFieldIndex; //for compatibility with 1.x else joinFieldIndex = cacheLayer->pendingFields().indexFromName( joinInfo.joinFieldName ); if ( joinFieldIndex < 0 || joinFieldIndex >= cacheLayer->pendingFields().count() ) return; joinInfo.cachedAttributes.clear(); QgsFeatureIterator fit = cacheLayer->getFeatures( QgsFeatureRequest().setFlags( QgsFeatureRequest::NoGeometry ) ); QgsFeature f; while ( fit.nextFeature( f ) ) { const QgsAttributes& attrs = f.attributes(); joinInfo.cachedAttributes.insert( attrs[joinFieldIndex].toString(), attrs ); } } }
void QgsMapCanvasAnnotationItem::setFeatureForMapPosition() { if ( !mAnnotation || !mAnnotation->hasFixedMapPosition() ) return; QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mAnnotation->mapLayer() ); if ( !vectorLayer ) return; double halfIdentifyWidth = QgsMapTool::searchRadiusMU( mMapCanvas ); QgsPointXY mapPosition = mAnnotation->mapPosition(); try { QgsCoordinateTransform ct( mAnnotation->mapPositionCrs(), mMapCanvas->mapSettings().destinationCrs(), QgsProject::instance() ); if ( ct.isValid() ) mapPosition = ct.transform( mapPosition ); } catch ( QgsCsException & ) { } QgsRectangle searchRect( mapPosition.x() - halfIdentifyWidth, mapPosition.y() - halfIdentifyWidth, mapPosition.x() + halfIdentifyWidth, mapPosition.y() + halfIdentifyWidth ); searchRect = mMapCanvas->mapSettings().mapToLayerCoordinates( vectorLayer, searchRect ); QgsFeatureIterator fit = vectorLayer->getFeatures( QgsFeatureRequest().setFilterRect( searchRect ).setFlags( QgsFeatureRequest::ExactIntersect ).setLimit( 1 ) ); QgsFeature currentFeature; ( void )fit.nextFeature( currentFeature ); mAnnotation->setAssociatedFeature( currentFeature ); }
QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsMapCanvas *mpMapCanvas ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ); if ( !vlayer ) return ""; // Get the setting for the search radius from user preferences, if it exists QSettings settings; double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble(); // create the search rectangle double searchRadius = mpMapCanvas->extent().width() * ( identifyValue / 100.0 ); QgsRectangle r; r.setXMinimum( mapPosition.x() - searchRadius ); r.setYMinimum( mapPosition.y() - searchRadius ); r.setXMaximum( mapPosition.x() + searchRadius ); r.setYMaximum( mapPosition.y() + searchRadius ); r = mpMapCanvas->mapSettings().mapToLayerCoordinates( layer, r ); QgsFeature feature; if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ).nextFeature( feature ) ) return ""; int idx = vlayer->fieldNameIndex( vlayer->displayField() ); if ( idx < 0 ) return QgsExpression::replaceExpressionText( vlayer->displayField(), &feature, vlayer ); else return feature.attribute( idx ).toString(); }
void QgsAttributeTableDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const { QgsVectorLayer *vl = layer( model ); if ( !vl ) return; int fieldIdx = model->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt(); QgsFeatureId fid = model->data( index, QgsAttributeTableModel::FeatureIdRole ).toLongLong(); QVariant oldValue = model->data( index, Qt::EditRole ); QVariant newValue; QgsEditorWidgetWrapper *eww = QgsEditorWidgetWrapper::fromWidget( editor ); if ( !eww ) return; newValue = eww->value(); if ( ( oldValue != newValue && newValue.isValid() ) || oldValue.isNull() != newValue.isNull() ) { // This fixes https://issues.qgis.org/issues/16492 QgsFeatureRequest request( fid ); request.setFlags( QgsFeatureRequest::NoGeometry ); request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeature feature; vl->getFeatures( request ).nextFeature( feature ); if ( feature.isValid() ) { vl->beginEditCommand( tr( "Attribute changed" ) ); vl->changeAttributeValue( fid, fieldIdx, newValue, oldValue ); vl->endEditCommand(); } } }
QString QgsRelationReferenceFieldFormatter::representValue( QgsVectorLayer* layer, int fieldIndex, const QVariantMap& config, const QVariant& cache, const QVariant& value ) const { Q_UNUSED( cache ); // Some sanity checks if ( !config.contains( QStringLiteral( "Relation" ) ) ) { QgsMessageLog::logMessage( "Missing Relation in configuration" ); return value.toString(); } QgsRelation relation = QgsProject::instance()->relationManager()->relation( config[QStringLiteral( "Relation" )].toString() ); if ( !relation.isValid() ) { QgsMessageLog::logMessage( "Invalid relation" ); return value.toString(); } QgsVectorLayer* referencingLayer = relation.referencingLayer(); if ( layer != referencingLayer ) { QgsMessageLog::logMessage( "representValue() with inconsistent layer parameter w.r.t relation referencingLayer" ); return value.toString(); } int referencingFieldIdx = referencingLayer->fields().lookupField( relation.fieldPairs().at( 0 ).first ); if ( referencingFieldIdx != fieldIndex ) { QgsMessageLog::logMessage( "representValue() with inconsistent fieldIndex parameter w.r.t relation referencingFieldIdx" ); return value.toString(); } QgsVectorLayer* referencedLayer = relation.referencedLayer(); if ( !referencedLayer ) { QgsMessageLog::logMessage( "Cannot find referenced layer" ); return value.toString(); } // Attributes from the referencing layer QgsAttributes attrs = QgsAttributes( layer->fields().count() ); // Set the value on the foreign key field of the referencing record attrs[ referencingFieldIdx ] = value; QgsFeatureRequest request = relation.getReferencedFeatureRequest( attrs ); QgsFeature feature; referencedLayer->getFeatures( request ).nextFeature( feature ); if ( !feature.isValid() ) return value.toString(); QgsExpression expr( referencedLayer->displayExpression() ); QgsExpressionContext context; context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::layerScope( referencedLayer ); context.setFeature( feature ); QString title = expr.evaluate( &context ).toString(); if ( expr.hasEvalError() ) { int referencedFieldIdx = referencedLayer->fields().lookupField( relation.fieldPairs().at( 0 ).second ); title = feature.attribute( referencedFieldIdx ).toString(); } return title; }
void QgsMapToolRotateFeature::canvasReleaseEvent( QMouseEvent * e ) { Q_UNUSED( e ); if ( !mRubberBand ) { return; } QgsVectorLayer* vlayer = currentVectorLayer(); if ( !vlayer ) { return; } //calculations for affine transformation double angle = -1 * mRotation * ( PI / 180 ); QgsPoint anchorPoint = toLayerCoordinates( vlayer, mStartPointMapCoords ); double a = cos( angle ); double b = -1 * sin( angle ); double c = anchorPoint.x() - cos( angle ) * anchorPoint.x() + sin( angle ) * anchorPoint.y(); double d = sin( angle ); double ee = cos( angle ); double f = anchorPoint.y() - sin( angle ) * anchorPoint.x() - cos( angle ) * anchorPoint.y(); vlayer->beginEditCommand( tr( "Features Rotated" ) ); int start; if ( vlayer->geometryType() == 2 ) { start = 1; } else { start = 0; } int i = 0; foreach ( QgsFeatureId id, mRotatedFeatures ) { QgsFeature feat; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( feat ); QgsGeometry* geom = feat.geometry(); i = start; QgsPoint vertex = geom->vertexAt( i ); while ( vertex != QgsPoint( 0, 0 ) ) { double newX = a * vertex.x() + b * vertex.y() + c; double newY = d * vertex.x() + ee * vertex.y() + f; vlayer->moveVertex( newX, newY, id, i ); i = i + 1; vertex = geom->vertexAt( i ); } }
void QgsMapToolRotateFeature::applyRotation( double rotation ) { mRotation = rotation; mRotationActive = false; QgsVectorLayer *vlayer = currentVectorLayer(); if ( !vlayer ) { deleteRubberband(); notifyNotVectorLayer(); return; } //calculations for affine transformation double angle = -1 * mRotation * ( M_PI / 180 ); QgsPointXY anchorPoint = toLayerCoordinates( vlayer, mStartPointMapCoords ); double a = std::cos( angle ); double b = -1 * std::sin( angle ); double c = anchorPoint.x() - std::cos( angle ) * anchorPoint.x() + std::sin( angle ) * anchorPoint.y(); double d = std::sin( angle ); double ee = std::cos( angle ); double f = anchorPoint.y() - std::sin( angle ) * anchorPoint.x() - std::cos( angle ) * anchorPoint.y(); vlayer->beginEditCommand( tr( "Features Rotated" ) ); int start; if ( vlayer->geometryType() == 2 ) { start = 1; } else { start = 0; } int i = 0; Q_FOREACH ( QgsFeatureId id, mRotatedFeatures ) { QgsFeature feat; vlayer->getFeatures( QgsFeatureRequest().setFilterFid( id ) ).nextFeature( feat ); QgsGeometry geom = feat.geometry(); i = start; QgsPointXY vertex = geom.vertexAt( i ); while ( vertex != QgsPointXY( 0, 0 ) ) { double newX = a * vertex.x() + b * vertex.y() + c; double newY = d * vertex.x() + ee * vertex.y() + f; vlayer->moveVertex( newX, newY, id, i ); i = i + 1; vertex = geom.vertexAt( i ); } }
void QgsMapToolNodeTool::createTopologyRubberBands() { QgsVectorLayer* vlayer = mSelectedFeature->vlayer(); Q_FOREACH ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() ) { if ( !vertexEntry->isSelected() ) { continue; } // Snap vertex QMultiMap<double, QgsSnappingResult> snapResults; vlayer->snapWithContext( vertexEntry->pointV1(), ZERO_TOLERANCE, snapResults, QgsSnapper::SnapToVertex ); Q_FOREACH ( const QgsSnappingResult& snapResult, snapResults ) { // Get geometry of snapped feature QgsFeatureId snapFeatureId = snapResult.snappedAtGeometry; QgsFeature feature; if ( !vlayer->getFeatures( QgsFeatureRequest( snapFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( feature ) ) { continue; } // Get VertexId of snapped vertex QgsVertexId vid; if ( !feature.geometry().vertexIdFromVertexNr( snapResult.snappedVertexNr, vid ) ) { continue; } // Add rubberband if not already added if ( !mMoveRubberBands.contains( snapFeatureId ) ) { QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, feature.geometry().type() ); QSettings settings; QColor color( settings.value( QStringLiteral( "/qgis/digitizing/line_color_red" ), 255 ).toInt(), settings.value( QStringLiteral( "/qgis/digitizing/line_color_green" ), 0 ).toInt(), settings.value( QStringLiteral( "/qgis/digitizing/line_color_blue" ), 0 ).toInt() ); double myAlpha = settings.value( QStringLiteral( "/qgis/digitizing/line_color_alpha" ), 30 ).toInt() / 255.0 ; color.setAlphaF( myAlpha ); rb->setOutlineColor( color ); rb->setBrushStyle( Qt::NoBrush ); rb->setOutlineWidth( settings.value( QStringLiteral( "/qgis/digitizing/line_width" ), 1 ).toInt() ); QgsAbstractGeometry* rbGeom = feature.geometry().geometry()->clone(); if ( mCanvas->mapSettings().layerTransform( vlayer ).isValid() ) rbGeom->transform( mCanvas->mapSettings().layerTransform( vlayer ) ); rb->setGeometry( rbGeom ); mMoveRubberBands.insert( snapFeatureId, rb ); } // Add to list of vertices to be moved mMoveVertices[snapFeatureId].append( qMakePair( vid, toMapCoordinates( vlayer, feature.geometry().geometry()->vertexAt( vid ) ) ) ); } }
bool QgsMapToolLabel::currentFeature( QgsFeature& f, bool fetchGeom ) { QgsVectorLayer* vlayer = currentLayer(); if ( !vlayer ) { return false; } return vlayer->getFeatures( QgsFeatureRequest() .setFilterFid( mCurrentLabelPos.featureId ) .setFlags( fetchGeom ? QgsFeatureRequest::NoFlags : QgsFeatureRequest::NoGeometry ) ).nextFeature( f ); }
void QgsMapToolOffsetCurve::canvasPressEvent( QMouseEvent* e ) { deleteRubberBandAndGeometry(); mGeometryModified = false; mForceCopy = false; if ( !mCanvas ) { return; } //get selected features or snap to nearest feature if no selection QgsVectorLayer* layer = currentVectorLayer(); if ( !layer ) { notifyNotVectorLayer(); return; } QgsMapRenderer* renderer = mCanvas->mapRenderer(); QgsSnapper snapper( renderer ); configureSnapper( snapper ); QList<QgsSnappingResult> snapResults; snapper.snapPoint( e->pos(), snapResults ); if ( snapResults.size() > 0 ) { QgsFeature fet; const QgsSnappingResult& snapResult = snapResults.at( 0 ); if ( snapResult.layer ) { mSourceLayerId = snapResult.layer->id(); QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( mSourceLayerId ) ); if ( vl && vl->getFeatures( QgsFeatureRequest().setFilterFid( snapResult.snappedAtGeometry ) ).nextFeature( fet ) ) { mForceCopy = ( e->modifiers() & Qt::ControlModifier ); //no geometry modification if ctrl is pressed mOriginalGeometry = createOriginGeometry( vl, snapResult, fet ); mRubberBand = createRubberBand(); if ( mRubberBand ) { mRubberBand->setToGeometry( mOriginalGeometry, layer ); } mModifiedFeature = fet.id(); createDistanceItem(); } } } }
void QgsMapToolNodeTool::createTopologyRubberBands() { QgsVectorLayer* vlayer = mSelectedFeature->vlayer(); foreach ( const QgsVertexEntry* vertexEntry, mSelectedFeature->vertexMap() ) { if ( !vertexEntry->isSelected() ) { continue; } // Snap vertex QMultiMap<double, QgsSnappingResult> snapResults; vlayer->snapWithContext( vertexEntry->pointV1(), ZERO_TOLERANCE, snapResults, QgsSnapper::SnapToVertex ); foreach ( const QgsSnappingResult& snapResult, snapResults.values() ) { // Get geometry of snapped feature QgsFeatureId snapFeatureId = snapResult.snappedAtGeometry; QgsFeature feature; if ( !vlayer->getFeatures( QgsFeatureRequest( snapFeatureId ).setSubsetOfAttributes( QgsAttributeList() ) ).nextFeature( feature ) ) { continue; } // Get VertexId of snapped vertex QgsVertexId vid; if ( !feature.geometry()->vertexIdFromVertexNr( snapResult.snappedVertexNr, vid ) ) { continue; } // Add rubberband if not already added if ( !mMoveRubberBands.contains( snapFeatureId ) ) { QgsGeometryRubberBand* rb = new QgsGeometryRubberBand( mCanvas, feature.geometry()->type() ); rb->setOutlineColor( Qt::blue ); rb->setBrushStyle( Qt::NoBrush ); rb->setOutlineWidth( 2 ); QgsAbstractGeometryV2* rbGeom = feature.geometry()->geometry()->clone(); if ( mCanvas->mapSettings().layerTransform( vlayer ) ) rbGeom->transform( *mCanvas->mapSettings().layerTransform( vlayer ) ); rb->setGeometry( rbGeom ); mMoveRubberBands.insert( snapFeatureId, rb ); } // Add to list of vertices to be moved mMoveVertices[snapFeatureId].append( qMakePair( vid, toMapCoordinates( vlayer, feature.geometry()->geometry()->vertexAt( vid ) ) ) ); } } }
QString QgsMapToolLabel::currentLabelText( int trunc ) { bool settingsOk; QgsPalLayerSettings& labelSettings = currentLabelSettings( &settingsOk ); if ( !settingsOk ) { return ""; } if ( labelSettings.isExpression ) { QString labelText = mCurrentLabelPos.labelText; if ( trunc > 0 && labelText.length() > trunc ) { labelText.truncate( trunc ); labelText += "..."; } return labelText; } else { QgsVectorLayer* vlayer = currentLayer(); if ( !vlayer ) { return ""; } QString labelField = vlayer->customProperty( "labeling/fieldName" ).toString(); if ( !labelField.isEmpty() ) { int labelFieldId = vlayer->fieldNameIndex( labelField ); QgsFeature f; if ( vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mCurrentLabelPos.featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { QString labelText = f.attribute( labelFieldId ).toString(); if ( trunc > 0 && labelText.length() > trunc ) { labelText.truncate( trunc ); labelText += "..."; } return labelText; } } } return ""; }
QString QgsMapToolLabel::currentLabelText( int trunc ) { if ( !mCurrentLabel.valid ) { return QString(); } QgsPalLayerSettings &labelSettings = mCurrentLabel.settings; if ( labelSettings.isExpression ) { QString labelText = mCurrentLabel.pos.labelText; if ( trunc > 0 && labelText.length() > trunc ) { labelText.truncate( trunc ); labelText += QChar( 0x2026 ); } return labelText; } else { QgsVectorLayer *vlayer = mCurrentLabel.layer; if ( !vlayer ) { return QString(); } QString labelField = labelSettings.fieldName; if ( !labelField.isEmpty() ) { int labelFieldId = vlayer->fields().lookupField( labelField ); QgsFeature f; if ( vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mCurrentLabel.pos.featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { QString labelText = f.attribute( labelFieldId ).toString(); if ( trunc > 0 && labelText.length() > trunc ) { labelText.truncate( trunc ); labelText += QChar( 0x2026 ); } return labelText; } } } return QString(); }
Qt3DCore::QEntity *QgsRuleBased3DRenderer::createEntity( const Qgs3DMapSettings &map ) const { QgsVectorLayer *vl = layer(); if ( !vl ) return nullptr; Qgs3DRenderContext context( map ); QgsExpressionContext exprContext( Qgs3DUtils::globalProjectLayerExpressionContext( vl ) ); exprContext.setFields( vl->fields() ); context.setExpressionContext( exprContext ); RuleToHandlerMap handlers; mRootRule->createHandlers( vl, handlers ); QSet<QString> attributeNames; mRootRule->prepare( context, attributeNames, handlers ); QgsFeatureRequest req; req.setDestinationCrs( map.crs(), map.transformContext() ); req.setSubsetOfAttributes( attributeNames, vl->fields() ); QgsFeature f; QgsFeatureIterator fi = vl->getFeatures( req ); while ( fi.nextFeature( f ) ) { context.expressionContext().setFeature( f ); mRootRule->registerFeature( f, context, handlers ); } Qt3DCore::QEntity *entity = new Qt3DCore::QEntity; for ( QgsFeature3DHandler *handler : handlers.values() ) handler->finalize( entity, context ); qDeleteAll( handlers.values() ); return entity; }
bool QgsMapToolLabel::currentLabelDataDefinedPosition( double &x, bool &xSuccess, double &y, bool &ySuccess, int &xCol, int &yCol ) const { QgsVectorLayer *vlayer = mCurrentLabel.layer; QgsFeatureId featureId = mCurrentLabel.pos.featureId; xSuccess = false; ySuccess = false; if ( !vlayer ) { return false; } if ( mCurrentLabel.pos.isDiagram ) { if ( !diagramMoveable( vlayer, xCol, yCol ) ) { return false; } } else if ( !labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) ) { return false; } QgsFeature f; if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { return false; } QgsAttributes attributes = f.attributes(); if ( !attributes.at( xCol ).isNull() ) x = attributes.at( xCol ).toDouble( &xSuccess ); if ( !attributes.at( yCol ).isNull() ) y = attributes.at( yCol ).toDouble( &ySuccess ); return true; }
/** * Selection routine called by the mouse release event * @param thePoint = QgsPoint representing the x, y coordinates of the mouse release event */ void eVisEventIdTool::select( QgsPoint thePoint ) { if ( 0 == mCanvas ) return; QgsVectorLayer* myLayer = ( QgsVectorLayer* )mCanvas->currentLayer( ); // create the search rectangle. this was modeled after the QgsMapIdentifyTool in core QGIS application double searchWidth = mCanvas->extent( ).width( ) * (( double )QGis::DEFAULT_IDENTIFY_RADIUS / 100.0 ); QgsRectangle myRectangle; myRectangle.setXMinimum( thePoint.x( ) - searchWidth ); myRectangle.setXMaximum( thePoint.x( ) + searchWidth ); myRectangle.setYMinimum( thePoint.y( ) - searchWidth ); myRectangle.setYMaximum( thePoint.y( ) + searchWidth ); //Transform rectange to map coordinates myRectangle = toLayerCoordinates( myLayer, myRectangle ); //Rather than add to the current selection, clear all selected features myLayer->removeSelection( false ); //select features QgsFeatureIterator fit = myLayer->getFeatures( QgsFeatureRequest().setFilterRect( myRectangle ).setFlags( QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; QgsFeatureIds newSelectedFeatures; while ( fit.nextFeature( f ) ) { newSelectedFeatures.insert( f.id() ); } myLayer->setSelectedFeatures( newSelectedFeatures ); //Launch a new event browser to view selected features mBrowser = new eVisGenericEventBrowserGui( mCanvas, mCanvas, NULL ); mBrowser->setAttribute( Qt::WA_DeleteOnClose ); }
QString QgsMapTip::fetchFeature( QgsMapLayer *layer, QgsPoint &mapPosition, QgsMapCanvas *mapCanvas ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ); if ( !vlayer ) return QString(); double searchRadius = QgsMapTool::searchRadiusMU( mapCanvas ); QgsRectangle r; r.setXMinimum( mapPosition.x() - searchRadius ); r.setYMinimum( mapPosition.y() - searchRadius ); r.setXMaximum( mapPosition.x() + searchRadius ); r.setYMaximum( mapPosition.y() + searchRadius ); r = mapCanvas->mapSettings().mapToLayerCoordinates( layer, r ); QgsFeature feature; if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ).nextFeature( feature ) ) return QString(); QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( vlayer ) ); if ( mapCanvas ) context.appendScope( QgsExpressionContextUtils::mapSettingsScope( mapCanvas->mapSettings() ) ); context.setFeature( feature ); QString mapTip = vlayer->mapTipTemplate(); if ( !mapTip.isEmpty() ) { return QgsExpression::replaceExpressionText( mapTip, &context ); } else { QgsExpression exp( vlayer->displayExpression() ); return exp.evaluate( &context ).toString(); } }
bool QgsMapToolLabel::currentLabelDataDefinedRotation( double &rotation, bool &rotationSuccess, int &rCol, bool ignoreXY ) const { QgsVectorLayer *vlayer = mCurrentLabel.layer; QgsFeatureId featureId = mCurrentLabel.pos.featureId; rotationSuccess = false; if ( !vlayer ) { return false; } if ( !labelIsRotatable( vlayer, mCurrentLabel.settings, rCol ) ) { return false; } QgsFeature f; if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { return false; } //test, if data defined x- and y- values are not null. Otherwise, the position is determined by PAL and the rotation cannot be fixed if ( !ignoreXY ) { int xCol, yCol; double x, y; bool xSuccess, ySuccess; if ( !currentLabelDataDefinedPosition( x, xSuccess, y, ySuccess, xCol, yCol ) || !xSuccess || !ySuccess ) { return false; } } rotation = f.attribute( rCol ).toDouble( &rotationSuccess ); return true; }
/** * Selection routine called by the mouse release event * @param point = QgsPointXY representing the x, y coordinates of the mouse release event */ void eVisEventIdTool::select( const QgsPointXY &point ) { if ( !mCanvas ) return; QgsVectorLayer *myLayer = ( QgsVectorLayer * )mCanvas->currentLayer(); // create the search rectangle. this was modeled after the QgsMapIdentifyTool in core QGIS application double searchWidth = QgsMapTool::searchRadiusMU( mCanvas ); QgsRectangle myRectangle; myRectangle.setXMinimum( point.x() - searchWidth ); myRectangle.setXMaximum( point.x() + searchWidth ); myRectangle.setYMinimum( point.y() - searchWidth ); myRectangle.setYMaximum( point.y() + searchWidth ); //Transform rectangle to map coordinates myRectangle = toLayerCoordinates( myLayer, myRectangle ); //select features QgsFeatureIterator fit = myLayer->getFeatures( QgsFeatureRequest().setFilterRect( myRectangle ).setFlags( QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; QgsFeatureIds newSelectedFeatures; while ( fit.nextFeature( f ) ) { newSelectedFeatures.insert( f.id() ); } myLayer->selectByIds( newSelectedFeatures ); //Launch a new event browser to view selected features mBrowser = new eVisGenericEventBrowserGui( mCanvas, mCanvas, nullptr ); mBrowser->setAttribute( Qt::WA_DeleteOnClose ); }
void CDTMapToolSelectTrainingSamples::canvasReleaseEvent(QgsMapMouseEvent *e) { if ( e->button() == Qt::LeftButton ) { if ( mDragging ) { mCanvas->panActionEnd( e->pos() ); mDragging = false; } else // add pan to mouse cursor { // transform the mouse pos to map coordinates QgsPoint center = mCanvas->getCoordinateTransform()->toMapPoint( e->x(), e->y() ); mCanvas->setExtent( QgsRectangle( center, center ) ); mCanvas->refresh(); } } else if (e->button()==Qt::RightButton) { QgsVectorLayer* vlayer = NULL; if ( !mapCanvas->currentLayer() || ( vlayer = qobject_cast<QgsVectorLayer *>( mapCanvas->currentLayer() ) ) == NULL ) return; QRect selectRect( 0, 0, 0, 0 ); int boxSize = 1; selectRect.setLeft ( e->pos().x() - boxSize ); selectRect.setRight ( e->pos().x() + boxSize ); selectRect.setTop ( e->pos().y() - boxSize ); selectRect.setBottom( e->pos().y() + boxSize ); const QgsMapToPixel* transform = mapCanvas->getCoordinateTransform(); QgsPoint ll = transform->toMapCoordinates( selectRect.left(), selectRect.bottom() ); QgsPoint ur = transform->toMapCoordinates( selectRect.right(), selectRect.top() ); QgsPolyline points; points.push_back(ll); points.push_back(QgsPoint( ur.x(), ll.y() )); points.push_back(ur); points.push_back(QgsPoint( ll.x(), ur.y() )); QgsPolygon polygon; polygon.push_back(points); QgsGeometry selectGeom = *(QgsGeometry::fromPolygon(polygon) ); if ( mapCanvas->mapSettings().hasCrsTransformEnabled() ) { QgsCoordinateTransform ct( mapCanvas->mapSettings().destinationCrs(), vlayer->crs() ); selectGeom.transform( ct ); } QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectGeom.boundingBox() ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; qint64 closestFeatureId = 0; bool foundSingleFeature = false; double closestFeatureDist = std::numeric_limits<double>::max(); while ( fit.nextFeature( f ) ) { QgsGeometry* g = f.geometry(); if ( !selectGeom.intersects( g ) ) continue; foundSingleFeature = true; double distance = g->distance( selectGeom ); if ( distance <= closestFeatureDist ) { closestFeatureDist = distance; closestFeatureId = f.attribute("GridCode").toInt(); } } if ( foundSingleFeature ) addSingleSample( closestFeatureId ); } }
QFont QgsMapToolLabel::labelFontCurrentFeature() { QFont font; QgsVectorLayer* vlayer = currentLayer(); bool labelSettingsOk; QgsPalLayerSettings& labelSettings = currentLabelSettings( &labelSettingsOk ); if ( labelSettingsOk && vlayer ) { font = labelSettings.textFont; QgsFeature f; if ( vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mCurrentLabelPos.featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { //size int sizeIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Size, vlayer ); if ( sizeIndx != -1 ) { if ( labelSettings.fontSizeInMapUnits ) { font.setPixelSize( labelSettings.sizeToPixel( f.attribute( sizeIndx ).toDouble(), QgsRenderContext(), QgsPalLayerSettings::MapUnits, true ) ); } else { font.setPointSizeF( f.attribute( sizeIndx ).toDouble() ); } } //family int fmIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Family, vlayer ); if ( fmIndx != -1 ) { font.setFamily( f.attribute( fmIndx ).toString() ); } //underline int ulIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Underline, vlayer ); if ( ulIndx != -1 ) { font.setUnderline( f.attribute( ulIndx ).toBool() ); } //strikeout int soIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Strikeout, vlayer ); if ( soIndx != -1 ) { font.setStrikeOut( f.attribute( soIndx ).toBool() ); } //bold int boIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Bold, vlayer ); if ( boIndx != -1 ) { font.setBold( f.attribute( boIndx ).toBool() ); } //italic int itIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Italic, vlayer ); if ( itIndx != -1 ) { font.setItalic( f.attribute( itIndx ).toBool() ); } // TODO: Add other font data defined values (word spacing, etc.) } } return font; }
QDomDocument createTransactionDocument( QgsServerInterface* serverIface, const QString& version, const QgsServerRequest& request ) { Q_UNUSED( version ); QDomDocument doc; QgsWfsProjectParser* configParser = getConfigParser( serverIface ); #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsAccessControl* accessControl = serverIface->accessControls(); #endif const QString requestBody = request.getParameter( QStringLiteral( "REQUEST_BODY" ) ); QString errorMsg; if ( !doc.setContent( requestBody, true, &errorMsg ) ) { throw QgsRequestNotWellFormedException( errorMsg ); } QDomElement docElem = doc.documentElement(); QDomNodeList docChildNodes = docElem.childNodes(); // Re-organize the transaction document QDomDocument mDoc; QDomElement mDocElem = mDoc.createElement( QStringLiteral( "myTransactionDocument" ) ); mDocElem.setAttribute( QStringLiteral( "xmlns" ), QGS_NAMESPACE ); mDocElem.setAttribute( QStringLiteral( "xmlns:wfs" ), WFS_NAMESPACE ); mDocElem.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE ); mDocElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE ); mDocElem.setAttribute( QStringLiteral( "xmlns:qgs" ), QGS_NAMESPACE ); mDocElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) ); mDoc.appendChild( mDocElem ); QDomElement actionElem; QString actionName; QDomElement typeNameElem; QString typeName; for ( int i = docChildNodes.count(); 0 < i; --i ) { actionElem = docChildNodes.at( i - 1 ).toElement(); actionName = actionElem.localName(); if ( actionName == QLatin1String( "Insert" ) ) { QDomElement featureElem = actionElem.firstChild().toElement(); typeName = featureElem.localName(); } else if ( actionName == QLatin1String( "Update" ) ) { typeName = actionElem.attribute( QStringLiteral( "typeName" ) ); } else if ( actionName == QLatin1String( "Delete" ) ) { typeName = actionElem.attribute( QStringLiteral( "typeName" ) ); } if ( typeName.contains( QLatin1String( ":" ) ) ) typeName = typeName.section( QStringLiteral( ":" ), 1, 1 ); QDomNodeList typeNameList = mDocElem.elementsByTagName( typeName ); if ( typeNameList.count() == 0 ) { typeNameElem = mDoc.createElement( typeName ); mDocElem.appendChild( typeNameElem ); } else typeNameElem = typeNameList.at( 0 ).toElement(); typeNameElem.appendChild( actionElem ); } // It's time to make the transaction // Create the response document QDomDocument resp; //wfs:WFS_TransactionRespone element QDomElement respElem = resp.createElement( QStringLiteral( "WFS_TransactionResponse" )/*wfs:WFS_TransactionResponse*/ ); respElem.setAttribute( QStringLiteral( "xmlns" ), WFS_NAMESPACE ); respElem.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) ); respElem.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WFS_NAMESPACE + " http://schemas.opengis.net/wfs/1.0.0/wfs.xsd" ); respElem.setAttribute( QStringLiteral( "xmlns:ogc" ), OGC_NAMESPACE ); respElem.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) ); resp.appendChild( respElem ); // Store the created feature id for WFS QStringList insertResults; // Get the WFS layers id QStringList wfsLayersId = configParser->wfsLayers();; QList<QgsMapLayer*> layerList; QgsMapLayer* currentLayer = nullptr; // Loop through the layer transaction elements docChildNodes = mDocElem.childNodes(); for ( int i = 0; i < docChildNodes.count(); ++i ) { // Get the vector layer typeNameElem = docChildNodes.at( i ).toElement(); typeName = typeNameElem.tagName(); layerList = configParser->mapLayerFromTypeName( typeName ); // Could be empty! if ( layerList.count() > 0 ) { currentLayer = layerList.at( 0 ); } else { throw QgsRequestNotWellFormedException( QStringLiteral( "Wrong TypeName: %1" ).arg( typeName ) ); } QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( currentLayer ); // it's a vectorlayer and defined by the administrator as a WFS layer if ( layer && wfsLayersId.contains( layer->id() ) ) { #ifdef HAVE_SERVER_PYTHON_PLUGINS if ( actionName == QLatin1String( "Insert" ) ) { if ( !accessControl->layerInsertPermission( layer ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature insert permission denied" ) ); } } else if ( actionName == QLatin1String( "Update" ) ) { if ( !accessControl->layerUpdatePermission( layer ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature update permission denied" ) ); } } else if ( actionName == QLatin1String( "Delete" ) ) { if ( !accessControl->layerDeletePermission( layer ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature delete permission denied" ) ); } } #endif // Get the provider and it's capabilities QgsVectorDataProvider* provider = layer->dataProvider(); if ( !provider ) { continue; } int cap = provider->capabilities(); // Start the update transaction layer->startEditing(); if (( cap & QgsVectorDataProvider::ChangeAttributeValues ) && ( cap & QgsVectorDataProvider::ChangeGeometries ) ) { // Loop through the update elements for this layer QDomNodeList upNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Update" ) ); for ( int j = 0; j < upNodeList.count(); ++j ) { if ( !configParser->wfstUpdateLayers().contains( layer->id() ) ) { //no wfs permissions to do updates QString errorMsg = "No permissions to do WFS updates on layer '" + layer->name() + "'"; QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL ); addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Update" ), errorMsg ); return resp; } actionElem = upNodeList.at( j ).toElement(); // Get the Feature Ids for this filter on the layer QDomElement filterElem = actionElem.elementsByTagName( QStringLiteral( "Filter" ) ).at( 0 ).toElement(); QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer ); // Loop through the property elements // Store properties and the geometry element QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral( "Property" ) ); QMap<QString, QString> propertyMap; QDomElement propertyElem; QDomElement nameElem; QDomElement valueElem; QDomElement geometryElem; for ( int l = 0; l < propertyNodeList.count(); ++l ) { propertyElem = propertyNodeList.at( l ).toElement(); nameElem = propertyElem.elementsByTagName( QStringLiteral( "Name" ) ).at( 0 ).toElement(); valueElem = propertyElem.elementsByTagName( QStringLiteral( "Value" ) ).at( 0 ).toElement(); if ( nameElem.text() != QLatin1String( "geometry" ) ) { propertyMap.insert( nameElem.text(), valueElem.text() ); } else { geometryElem = valueElem; } } // Update the features QgsFields fields = provider->fields(); QMap<QString, int> fieldMap = provider->fieldNameMap(); QMap<QString, int>::const_iterator fieldMapIt; QString fieldName; bool conversionSuccess; QgsFeatureIds::const_iterator fidIt = fids.constBegin(); for ( ; fidIt != fids.constEnd(); ++fidIt ) { #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) ); QgsFeature feature; while ( fit.nextFeature( feature ) ) { if ( !accessControl->allowToEdit( layer, feature ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) ); } } #endif QMap< QString, QString >::const_iterator it = propertyMap.constBegin(); for ( ; it != propertyMap.constEnd(); ++it ) { fieldName = it.key(); fieldMapIt = fieldMap.find( fieldName ); if ( fieldMapIt == fieldMap.constEnd() ) { continue; } QgsField field = fields.at( fieldMapIt.value() ); if ( field.type() == 2 ) layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toInt( &conversionSuccess ) ); else if ( field.type() == 6 ) layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value().toDouble( &conversionSuccess ) ); else layer->changeAttributeValue( *fidIt, fieldMapIt.value(), it.value() ); } if ( !geometryElem.isNull() ) { QgsGeometry g = QgsOgcUtils::geometryFromGML( geometryElem ); if ( !layer->changeGeometry( *fidIt, g ) ) { throw QgsRequestNotWellFormedException( QStringLiteral( "Error in change geometry" ) ); } } #ifdef HAVE_SERVER_PYTHON_PLUGINS fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) ); while ( fit.nextFeature( feature ) ) { if ( !accessControl->allowToEdit( layer, feature ) ) { layer->rollBack(); throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) ); } } #endif } } } // Commit the changes of the update elements if ( !layer->commitChanges() ) { addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Update" ), layer->commitErrors().join( QStringLiteral( "\n " ) ) ); return resp; } // Start the delete transaction layer->startEditing(); if (( cap & QgsVectorDataProvider::DeleteFeatures ) ) { // Loop through the delete elements QDomNodeList delNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Delete" ) ); for ( int j = 0; j < delNodeList.count(); ++j ) { if ( !configParser->wfstDeleteLayers().contains( layer->id() ) ) { //no wfs permissions to do updates QString errorMsg = "No permissions to do WFS deletes on layer '" + layer->name() + "'"; QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL ); addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Delete" ), errorMsg ); return resp; } actionElem = delNodeList.at( j ).toElement(); QDomElement filterElem = actionElem.firstChild().toElement(); // Get Feature Ids for the Filter element QgsFeatureIds fids = getFeatureIdsFromFilter( filterElem, layer ); #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsFeatureIds::const_iterator fidIt = fids.constBegin(); for ( ; fidIt != fids.constEnd(); ++fidIt ) { QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest( *fidIt ) ); QgsFeature feature; while ( fit.nextFeature( feature ) ) { if ( !accessControl->allowToEdit( layer, feature ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) ); } } } #endif layer->selectByIds( fids ); layer->deleteSelectedFeatures(); } } // Commit the changes of the delete elements if ( !layer->commitChanges() ) { addTransactionResult( resp, respElem, QStringLiteral( "PARTIAL" ), QStringLiteral( "Delete" ), layer->commitErrors().join( QStringLiteral( "\n " ) ) ); return resp; } // Store the inserted features QgsFeatureList inFeatList; if ( cap & QgsVectorDataProvider::AddFeatures ) { // Get Layer Field Information QgsFields fields = provider->fields(); QMap<QString, int> fieldMap = provider->fieldNameMap(); QMap<QString, int>::const_iterator fieldMapIt; // Loop through the insert elements QDomNodeList inNodeList = typeNameElem.elementsByTagNameNS( WFS_NAMESPACE, QStringLiteral( "Insert" ) ); for ( int j = 0; j < inNodeList.count(); ++j ) { if ( !configParser->wfstInsertLayers().contains( layer->id() ) ) { //no wfs permissions to do updates QString errorMsg = "No permissions to do WFS inserts on layer '" + layer->name() + "'"; QgsMessageLog::logMessage( errorMsg, QStringLiteral( "Server" ), QgsMessageLog::CRITICAL ); addTransactionResult( resp, respElem, QStringLiteral( "FAILED" ), QStringLiteral( "Insert" ), errorMsg ); return resp; } actionElem = inNodeList.at( j ).toElement(); // Loop through the feature element QDomNodeList featNodes = actionElem.childNodes(); for ( int l = 0; l < featNodes.count(); l++ ) { // Add the feature to the layer // and store it to put it's Feature Id in the response inFeatList << QgsFeature( fields ); // Create feature for this layer QDomElement featureElem = featNodes.at( l ).toElement(); QDomNode currentAttributeChild = featureElem.firstChild(); while ( !currentAttributeChild.isNull() ) { QDomElement currentAttributeElement = currentAttributeChild.toElement(); QString attrName = currentAttributeElement.localName(); if ( attrName != QLatin1String( "boundedBy" ) ) { if ( attrName != QLatin1String( "geometry" ) ) //a normal attribute { fieldMapIt = fieldMap.find( attrName ); if ( fieldMapIt == fieldMap.constEnd() ) { continue; } QgsField field = fields.at( fieldMapIt.value() ); QString attrValue = currentAttributeElement.text(); int attrType = field.type(); QgsMessageLog::logMessage( QStringLiteral( "attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) ); if ( attrType == QVariant::Int ) inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toInt() ); else if ( attrType == QVariant::Double ) inFeatList.last().setAttribute( fieldMapIt.value(), attrValue.toDouble() ); else inFeatList.last().setAttribute( fieldMapIt.value(), attrValue ); } else //a geometry attribute { QgsGeometry g = QgsOgcUtils::geometryFromGML( currentAttributeElement ); inFeatList.last().setGeometry( g ); } } currentAttributeChild = currentAttributeChild.nextSibling(); } } } } #ifdef HAVE_SERVER_PYTHON_PLUGINS QgsFeatureList::iterator featureIt = inFeatList.begin(); while ( featureIt != inFeatList.end() ) { if ( !accessControl->allowToEdit( layer, *featureIt ) ) { throw QgsSecurityAccessException( QStringLiteral( "Feature modify permission denied" ) ); } featureIt++; } #endif // add the features if ( !provider->addFeatures( inFeatList ) ) { addTransactionResult( resp, respElem, QStringLiteral( "Partial" ), QStringLiteral( "Insert" ), layer->commitErrors().join( QStringLiteral( "\n " ) ) ); if ( provider->hasErrors() ) { provider->clearErrors(); } return resp; } // Get the Feature Ids of the inserted feature for ( int j = 0; j < inFeatList.size(); j++ ) { insertResults << typeName + "." + QString::number( inFeatList[j].id() ); } } } // Put the Feature Ids of the inserted feature if ( !insertResults.isEmpty() ) { Q_FOREACH ( const QString &fidStr, insertResults ) { QDomElement irElem = doc.createElement( QStringLiteral( "InsertResult" ) ); QDomElement fiElem = doc.createElement( QStringLiteral( "ogc:FeatureId" ) ); fiElem.setAttribute( QStringLiteral( "fid" ), fidStr ); irElem.appendChild( fiElem ); respElem.appendChild( irElem ); }
void QgsAttributeTableModel::loadAttributes() { if ( !layer() ) { return; } bool ins = false, rm = false; QgsAttributeList attributes; const QgsFields& fields = layer()->pendingFields(); for ( int idx = 0; idx < fields.count(); ++idx ) { switch ( layer()->editType( idx ) ) { case QgsVectorLayer::Hidden: continue; case QgsVectorLayer::ValueMap: mValueMaps.insert( idx, new QMap< QString, QVariant >( layer()->valueMap( idx ) ) ); break; case QgsVectorLayer::ValueRelation: { const QgsVectorLayer::ValueRelationData &data = layer()->valueRelation( idx ); QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( data.mLayer ) ); if ( !layer ) continue; int ki = layer->fieldNameIndex( data.mKey ); int vi = layer->fieldNameIndex( data.mValue ); QgsExpression *e = 0; if ( !data.mFilterExpression.isEmpty() ) { e = new QgsExpression( data.mFilterExpression ); if ( e->hasParserError() || !e->prepare( layer->pendingFields() ) ) continue; } if ( ki >= 0 && vi >= 0 ) { QSet<int> attributes; attributes << ki << vi; QgsFeatureRequest::Flag flags = QgsFeatureRequest::NoGeometry; if ( e ) { if ( e->needsGeometry() ) flags = QgsFeatureRequest::NoFlags; foreach ( const QString &field, e->referencedColumns() ) { int idx = layer->fieldNameIndex( field ); if ( idx < 0 ) continue; attributes << idx; } } QMap< QString, QVariant > *map = new QMap< QString, QVariant >(); QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFlags( flags ).setSubsetOfAttributes( attributes.toList() ) ); QgsFeature f; while ( fit.nextFeature( f ) ) { if ( e && !e->evaluate( &f ).toBool() ) continue; map->insert( f.attribute( vi ).toString(), f.attribute( ki ) ); } mValueMaps.insert( idx, map ); } } break; default: break; } attributes << idx; }
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect ) { if ( selectGeometry->type() != QGis::Polygon ) { return; } QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas ); if ( vlayer == nullptr ) { return; } // toLayerCoordinates will throw an exception for any 'invalid' points in // the rubber band. // For example, if you project a world map onto a globe using EPSG 2163 // and then click somewhere off the globe, an exception will be thrown. //QgsGeometry selectGeomTrans( *selectGeometry ); //if ( canvas->mapSettings().hasCrsTransformEnabled() ) //{ // try // { // QgsCoordinateTransform ct( canvas->mapSettings().destinationCrs(), vlayer->crs() ); // selectGeomTrans.transform( ct ); // } // catch ( QgsCsException &cse ) // { // Q_UNUSED( cse ); // // catch exception for 'invalid' point and leave existing selection unchanged // QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); // LOG_INFO( "CRS Exception\nSelection extends beyond layer's coordinate system" ); // return; // } //} QgsGeometry selectGeomTrans; try{ selectGeomTrans = toLayerCoordinates( canvas, selectGeometry, vlayer ); } catch ( QgsCsException & ) { return; } QApplication::setOverrideCursor( Qt::WaitCursor ); QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); QgsRenderContext context = QgsRenderContext::fromMapSettings( canvas->mapSettings() ); QgsFeatureRendererV2* r = vlayer->rendererV2(); if ( r ) r->startRender( context, vlayer->pendingFields() ); QgsFeatureRequest request; request.setFilterRect( selectGeomTrans.boundingBox() ); request.setFlags( QgsFeatureRequest::ExactIntersect ); if ( r ) request.setSubsetOfAttributes( r->usedAttributes(), vlayer->pendingFields() ); else request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fit = vlayer->getFeatures( request ); QgsFeatureIds newSelectedFeatures; QgsFeature f; QgsFeatureId closestFeatureId = 0; bool foundSingleFeature = false; double closestFeatureDist = std::numeric_limits<double>::max(); while ( fit.nextFeature( f ) ) { #if (VERSION_INT >= 21601) context.expressionContext().setFeature( f ); //taken from QGIS 2.16.1 // make sure to only use features that are visible if ( r && !r->willRenderFeature( f, context ) ) #else if ( r && !r->willRenderFeature( f ) ) #endif continue; QgsGeometry* g = f.geometry(); if ( doContains ) { if ( !selectGeomTrans.contains( g ) ) continue; } else { if ( !selectGeomTrans.intersects( g ) ) continue; } if ( singleSelect ) { foundSingleFeature = true; double distance = g->distance( selectGeomTrans ); if ( distance <= closestFeatureDist ) { closestFeatureDist = distance; closestFeatureId = f.id(); } } else { newSelectedFeatures.insert( f.id() ); } } if ( singleSelect && foundSingleFeature ) { newSelectedFeatures.insert( closestFeatureId ); } if ( r ) r->stopRender( context ); QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) ); if ( doDifference ) { QgsFeatureIds layerSelectedFeatures = vlayer->selectedFeaturesIds(); QgsFeatureIds selectedFeatures; QgsFeatureIds deselectedFeatures; QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); while ( i != newSelectedFeatures.constBegin() ) { --i; if ( layerSelectedFeatures.contains( *i ) ) { deselectedFeatures.insert( *i ); } else { selectedFeatures.insert( *i ); } } vlayer->modifySelection( selectedFeatures, deselectedFeatures ); } else { SelectFeatures( vlayer, newSelectedFeatures ); // vlayer->setSelectedFeatures( newSelectedFeatures ); } QApplication::restoreOverrideCursor(); }
bool QgsComposerAttributeTableV2::getTableContents( QgsComposerTableContents &contents ) { contents.clear(); if (( mSource == QgsComposerAttributeTableV2::AtlasFeature || mSource == QgsComposerAttributeTableV2::RelationChildren ) && !mComposition->atlasComposition().enabled() ) { //source mode requires atlas, but atlas disabled return false; } QgsVectorLayer* layer = sourceLayer(); if ( !layer ) { //no source layer return false; } //prepare filter expression std::auto_ptr<QgsExpression> filterExpression; bool activeFilter = false; if ( mFilterFeatures && !mFeatureFilter.isEmpty() ) { filterExpression = std::auto_ptr<QgsExpression>( new QgsExpression( mFeatureFilter ) ); if ( !filterExpression->hasParserError() ) { activeFilter = true; } } QgsRectangle selectionRect; if ( mComposerMap && mShowOnlyVisibleFeatures ) { selectionRect = *mComposerMap->currentMapExtent(); if ( layer && mComposition->mapSettings().hasCrsTransformEnabled() ) { //transform back to layer CRS QgsCoordinateTransform coordTransform( layer->crs(), mComposition->mapSettings().destinationCrs() ); try { selectionRect = coordTransform.transformBoundingBox( selectionRect, QgsCoordinateTransform::ReverseTransform ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); return false; } } } QgsFeatureRequest req; if ( mSource == QgsComposerAttributeTableV2::RelationChildren ) { QgsRelation relation = QgsProject::instance()->relationManager()->relation( mRelationId ); QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( atlasFeature ) { req = relation.getRelatedFeaturesRequest( *atlasFeature ); } else { //no atlas feature, so empty table return true; } } if ( !selectionRect.isEmpty() ) req.setFilterRect( selectionRect ); req.setFlags( mShowOnlyVisibleFeatures ? QgsFeatureRequest::ExactIntersect : QgsFeatureRequest::NoFlags ); if ( mSource == QgsComposerAttributeTableV2::AtlasFeature && mComposition->atlasComposition().enabled() ) { //source mode is current atlas feature QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( atlasFeature ) { req.setFilterFid( atlasFeature->id() ); } else { //no atlas feature, so empty table return true; } } QgsFeature f; int counter = 0; QgsFeatureIterator fit = layer->getFeatures( req ); while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures ) { //check feature against filter if ( activeFilter ) { QVariant result = filterExpression->evaluate( &f, layer->pendingFields() ); // skip this feature if the filter evaluation is false if ( !result.toBool() ) { continue; } } //check against atlas feature intersection if ( mFilterToAtlasIntersection ) { if ( !f.geometry() || ! mComposition->atlasComposition().enabled() ) { continue; } QgsFeature* atlasFeature = mComposition->atlasComposition().currentFeature(); if ( !atlasFeature || !atlasFeature->geometry() || !f.geometry()->intersects( atlasFeature->geometry() ) ) { //feature falls outside current atlas feature continue; } } QgsComposerTableRow currentRow; QList<QgsComposerTableColumn*>::const_iterator columnIt = mColumns.constBegin(); for ( ; columnIt != mColumns.constEnd(); ++columnIt ) { int idx = layer->fieldNameIndex(( *columnIt )->attribute() ); if ( idx != -1 ) { currentRow << f.attributes()[idx]; } else { // Lets assume it's an expression QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() ); expression->setCurrentRowNumber( counter + 1 ); expression->prepare( layer->pendingFields() ); QVariant value = expression->evaluate( f ) ; currentRow << value; } } if ( !mShowUniqueRowsOnly || !contentsContainsRow( contents, currentRow ) ) { contents << currentRow; ++counter; } } //sort the list, starting with the last attribute QgsComposerAttributeTableCompareV2 c; QList< QPair<int, bool> > sortColumns = sortAttributes(); for ( int i = sortColumns.size() - 1; i >= 0; --i ) { c.setSortColumn( sortColumns.at( i ).first ); c.setAscending( sortColumns.at( i ).second ); qStableSort( contents.begin(), contents.end(), c ); } recalculateTableSize(); return true; }
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect ) { if ( selectGeometry->type() != QGis::Polygon ) { return; } QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas ); if ( vlayer == NULL ) { return; } // toLayerCoordinates will throw an exception for any 'invalid' points in // the rubber band. // For example, if you project a world map onto a globe using EPSG 2163 // and then click somewhere off the globe, an exception will be thrown. QgsGeometry selectGeomTrans( *selectGeometry ); if ( canvas->mapSettings().hasCrsTransformEnabled() ) { try { QgsCoordinateTransform ct( canvas->mapSettings().destinationCrs(), vlayer->crs() ); selectGeomTrans.transform( ct ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and leave existing selection unchanged QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) ); QgisApp::instance()->messageBar()->pushMessage( QObject::tr( "CRS Exception" ), QObject::tr( "Selection extends beyond layer's coordinate system" ), QgsMessageBar::WARNING, QgisApp::instance()->messageTimeout() ); return; } } QApplication::setOverrideCursor( Qt::WaitCursor ); QgsDebugMsg( "Selection layer: " + vlayer->name() ); QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() ); QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) ); QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) ); QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectGeomTrans.boundingBox() ).setFlags( QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeatureIds newSelectedFeatures; QgsFeature f; QgsFeatureId closestFeatureId = 0; bool foundSingleFeature = false; double closestFeatureDist = std::numeric_limits<double>::max(); while ( fit.nextFeature( f ) ) { QgsGeometry* g = f.geometry(); if ( doContains ) { if ( !selectGeomTrans.contains( g ) ) continue; } else { if ( !selectGeomTrans.intersects( g ) ) continue; } if ( singleSelect ) { foundSingleFeature = true; double distance = g->distance( selectGeomTrans ); if ( distance <= closestFeatureDist ) { closestFeatureDist = distance; closestFeatureId = f.id(); } } else { newSelectedFeatures.insert( f.id() ); } } if ( singleSelect && foundSingleFeature ) { newSelectedFeatures.insert( closestFeatureId ); } QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) ); if ( doDifference ) { QgsFeatureIds layerSelectedFeatures = vlayer->selectedFeaturesIds(); QgsFeatureIds selectedFeatures; QgsFeatureIds deselectedFeatures; QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); while ( i != newSelectedFeatures.constBegin() ) { --i; if ( layerSelectedFeatures.contains( *i ) ) { deselectedFeatures.insert( *i ); } else { selectedFeatures.insert( *i ); } } vlayer->modifySelection( selectedFeatures, deselectedFeatures ); } else { vlayer->setSelectedFeatures( newSelectedFeatures ); } QApplication::restoreOverrideCursor(); }
void QgsMapToolFillRing::cadCanvasReleaseEvent( QgsMapMouseEvent * e ) { //check if we operate on a vector layer QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCanvas->currentLayer() ); if ( !vlayer ) { notifyNotVectorLayer(); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint() ); if ( error == 1 ) { //current layer is not a vector layer return; } else if ( error == 2 ) { //problem with coordinate transformation emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { if ( !isCapturing() ) return; deleteTempRubberBand(); closePolygon(); vlayer->beginEditCommand( tr( "Ring added and filled" ) ); QList< QgsPoint > pointList = points(); QgsFeatureId modifiedFid; int addRingReturnCode = vlayer->addRing( pointList, &modifiedFid ); if ( addRingReturnCode != 0 ) { QString errorMessage; //todo: open message box to communicate errors if ( addRingReturnCode == 1 ) { errorMessage = tr( "a problem with geometry type occured" ); } else if ( addRingReturnCode == 2 ) { errorMessage = tr( "the inserted Ring is not closed" ); } else if ( addRingReturnCode == 3 ) { errorMessage = tr( "the inserted Ring is not a valid geometry" ); } else if ( addRingReturnCode == 4 ) { errorMessage = tr( "the inserted Ring crosses existing rings" ); } else if ( addRingReturnCode == 5 ) { errorMessage = tr( "the inserted Ring is not contained in a feature" ); } else { errorMessage = tr( "an unknown error occured" ); } emit messageEmitted( tr( "could not add ring since %1." ).arg( errorMessage ), QgsMessageBar::CRITICAL ); vlayer->destroyEditCommand(); } else { // find parent feature and get it attributes double xMin, xMax, yMin, yMax; QgsRectangle bBox; xMin = std::numeric_limits<double>::max(); xMax = -std::numeric_limits<double>::max(); yMin = std::numeric_limits<double>::max(); yMax = -std::numeric_limits<double>::max(); Q_FOREACH ( const QgsPoint& point, pointList ) { xMin = qMin( xMin, point.x() ); xMax = qMax( xMax, point.x() ); yMin = qMin( yMin, point.y() ); yMax = qMax( yMax, point.y() ); } bBox.setXMinimum( xMin ); bBox.setYMinimum( yMin ); bBox.setXMaximum( xMax ); bBox.setYMaximum( yMax ); QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterFid( modifiedFid ) ); QgsFeature f; bool res = false; if ( fit.nextFeature( f ) ) { //create QgsFeature with wkb representation QgsFeature* ft = new QgsFeature( vlayer->fields(), 0 ); ft->setGeometry( QgsGeometry::fromPolygon( QgsPolygon() << pointList.toVector() ) ); ft->setAttributes( f.attributes() ); if ( QApplication::keyboardModifiers() == Qt::ControlModifier ) { res = vlayer->addFeature( *ft ); } else { QgsAttributeDialog *dialog = new QgsAttributeDialog( vlayer, ft, false, NULL, true ); dialog->setIsAddDialog( true ); res = dialog->exec(); // will also add the feature } if ( res ) { vlayer->endEditCommand(); } else { delete ft; vlayer->destroyEditCommand(); } res = false; } } stopCapturing(); }
void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints, QVector< QgsPoint >& tiedPoint ) const { QgsVectorLayer *vl = mVectorLayer; if ( vl == NULL ) return; int featureCount = ( int ) vl->featureCount() * 2; int step = 0; QgsCoordinateTransform ct; ct.setSourceCrs( vl->crs() ); if ( builder->coordinateTransformationEnabled() ) { ct.setDestCRS( builder->destinationCrs() ); } else { ct.setDestCRS( vl->crs() ); } tiedPoint = QVector< QgsPoint >( additionalPoints.size(), QgsPoint( 0.0, 0.0 ) ); TiePointInfo tmpInfo; tmpInfo.mLength = std::numeric_limits<double>::infinity(); QVector< TiePointInfo > pointLengthMap( additionalPoints.size(), tmpInfo ); QVector< TiePointInfo >::iterator pointLengthIt; //Graph's points; QVector< QgsPoint > points; QgsFeatureIterator fit = vl->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( QgsAttributeList() ) ); // begin: tie points to the graph QgsAttributeList la; QgsFeature feature; while ( fit.nextFeature( feature ) ) { QgsMultiPolyline mpl; if ( feature.constGeometry()->wkbType() == QGis::WKBMultiLineString ) mpl = feature.constGeometry()->asMultiPolyline(); else if ( feature.constGeometry()->wkbType() == QGis::WKBLineString ) mpl.push_back( feature.constGeometry()->asPolyline() ); QgsMultiPolyline::iterator mplIt; for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt ) { QgsPoint pt1, pt2; bool isFirstPoint = true; QgsPolyline::iterator pointIt; for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt ) { pt2 = ct.transform( *pointIt ); points.push_back( pt2 ); if ( !isFirstPoint ) { int i = 0; for ( i = 0; i != additionalPoints.size(); ++i ) { TiePointInfo info; if ( pt1 == pt2 ) { info.mLength = additionalPoints[ i ].sqrDist( pt1 ); info.mTiedPoint = pt1; } else { info.mLength = additionalPoints[ i ].sqrDistToSegment( pt1.x(), pt1.y(), pt2.x(), pt2.y(), info.mTiedPoint ); } if ( pointLengthMap[ i ].mLength > info.mLength ) { Q_UNUSED( info.mTiedPoint ); info.mFirstPoint = pt1; info.mLastPoint = pt2; pointLengthMap[ i ] = info; tiedPoint[ i ] = info.mTiedPoint; } } } pt1 = pt2; isFirstPoint = false; } } emit buildProgress( ++step, featureCount ); } // end: tie points to graph // add tied point to graph int i = 0; for ( i = 0; i < tiedPoint.size(); ++i ) { if ( tiedPoint[ i ] != QgsPoint( 0.0, 0.0 ) ) { points.push_back( tiedPoint [ i ] ); } } QgsPointCompare pointCompare( builder->topologyTolerance() ); qSort( points.begin(), points.end(), pointCompare ); QVector< QgsPoint >::iterator tmp = std::unique( points.begin(), points.end() ); points.resize( tmp - points.begin() ); for ( i = 0;i < points.size();++i ) builder->addVertex( i, points[ i ] ); for ( i = 0; i < tiedPoint.size() ; ++i ) tiedPoint[ i ] = *( my_binary_search( points.begin(), points.end(), tiedPoint[ i ], pointCompare ) ); qSort( pointLengthMap.begin(), pointLengthMap.end(), TiePointInfoCompare ); { // fill attribute list 'la' QgsAttributeList tmpAttr; if ( mDirectionFieldId != -1 ) { tmpAttr.push_back( mDirectionFieldId ); } QList< QgsArcProperter* >::const_iterator it; QgsAttributeList::const_iterator it2; for ( it = mProperterList.begin(); it != mProperterList.end(); ++it ) { QgsAttributeList tmp = ( *it )->requiredAttributes(); for ( it2 = tmp.begin(); it2 != tmp.end(); ++it2 ) { tmpAttr.push_back( *it2 ); } } qSort( tmpAttr.begin(), tmpAttr.end() ); int lastAttrId = -1; for ( it2 = tmpAttr.begin(); it2 != tmpAttr.end(); ++it2 ) { if ( *it2 == lastAttrId ) { continue; } la.push_back( *it2 ); lastAttrId = *it2; } } // end fill attribute list 'la' // begin graph construction fit = vl->getFeatures( QgsFeatureRequest().setSubsetOfAttributes( la ) ); while ( fit.nextFeature( feature ) ) { int directionType = mDefaultDirection; // What direction have feature? QString str = feature.attribute( mDirectionFieldId ).toString(); if ( str == mBothDirectionValue ) { directionType = 3; } else if ( str == mDirectDirectionValue ) { directionType = 1; } else if ( str == mReverseDirectionValue ) { directionType = 2; } // begin features segments and add arc to the Graph; QgsMultiPolyline mpl; if ( feature.constGeometry()->wkbType() == QGis::WKBMultiLineString ) mpl = feature.constGeometry()->asMultiPolyline(); else if ( feature.constGeometry()->wkbType() == QGis::WKBLineString ) mpl.push_back( feature.constGeometry()->asPolyline() ); QgsMultiPolyline::iterator mplIt; for ( mplIt = mpl.begin(); mplIt != mpl.end(); ++mplIt ) { QgsPoint pt1, pt2; bool isFirstPoint = true; QgsPolyline::iterator pointIt; for ( pointIt = mplIt->begin(); pointIt != mplIt->end(); ++pointIt ) { pt2 = ct.transform( *pointIt ); if ( !isFirstPoint ) { std::map< double, QgsPoint > pointsOnArc; pointsOnArc[ 0.0 ] = pt1; pointsOnArc[ pt1.sqrDist( pt2 )] = pt2; TiePointInfo t; t.mFirstPoint = pt1; t.mLastPoint = pt2; pointLengthIt = my_binary_search( pointLengthMap.begin(), pointLengthMap.end(), t, TiePointInfoCompare ); if ( pointLengthIt != pointLengthMap.end() ) { QVector< TiePointInfo >::iterator it; for ( it = pointLengthIt; it - pointLengthMap.begin() >= 0; --it ) { if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 ) { pointsOnArc[ pt1.sqrDist( it->mTiedPoint )] = it->mTiedPoint; } } for ( it = pointLengthIt + 1; it != pointLengthMap.end(); ++it ) { if ( it->mFirstPoint == pt1 && it->mLastPoint == pt2 ) { pointsOnArc[ pt1.sqrDist( it->mTiedPoint )] = it->mTiedPoint; } } } std::map< double, QgsPoint >::iterator pointsIt; QgsPoint pt1; QgsPoint pt2; int pt1idx = -1, pt2idx = -1; bool isFirstPoint = true; for ( pointsIt = pointsOnArc.begin(); pointsIt != pointsOnArc.end(); ++pointsIt ) { pt2 = pointsIt->second; tmp = my_binary_search( points.begin(), points.end(), pt2, pointCompare ); pt2 = *tmp; pt2idx = tmp - points.begin(); if ( !isFirstPoint && pt1 != pt2 ) { double distance = builder->distanceArea()->measureLine( pt1, pt2 ); QVector< QVariant > prop; QList< QgsArcProperter* >::const_iterator it; for ( it = mProperterList.begin(); it != mProperterList.end(); ++it ) { prop.push_back(( *it )->property( distance, feature ) ); } if ( directionType == 1 || directionType == 3 ) { builder->addArc( pt1idx, pt1, pt2idx, pt2, prop ); } if ( directionType == 2 || directionType == 3 ) { builder->addArc( pt2idx, pt2, pt1idx, pt1, prop ); } } pt1idx = pt2idx; pt1 = pt2; isFirstPoint = false; } } // if ( !isFirstPoint ) pt1 = pt2; isFirstPoint = false; } // for (it = pl.begin(); it != pl.end(); ++it) } emit buildProgress( ++step, featureCount ); } // while( vl->nextFeature(feature) ) } // makeGraph( QgsGraphBuilderInterface *builder, const QVector< QgsPoint >& additionalPoints, QVector< QgsPoint >& tiedPoint )
QgsAbstractGeometryV2* QgsGeometryEditUtils::avoidIntersections( const QgsAbstractGeometryV2& geom, QMap<QgsVectorLayer*, QSet<QgsFeatureId> > ignoreFeatures ) { QScopedPointer<QgsGeometryEngine> geomEngine( QgsGeometry::createGeometryEngine( &geom ) ); if ( geomEngine.isNull() ) { return nullptr; } QgsWKBTypes::Type geomTypeBeforeModification = geom.wkbType(); //check if g has polygon type if ( QgsWKBTypes::geometryType( geomTypeBeforeModification ) != QgsWKBTypes::PolygonGeometry ) { return nullptr; } //read avoid intersections list from project properties bool listReadOk; QStringList avoidIntersectionsList = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList", QStringList(), &listReadOk ); if ( !listReadOk ) return nullptr; //no intersections stored in project does not mean error QList< QgsAbstractGeometryV2* > nearGeometries; //go through list, convert each layer to vector layer and call QgsVectorLayer::removePolygonIntersections for each QgsVectorLayer* currentLayer = nullptr; QStringList::const_iterator aIt = avoidIntersectionsList.constBegin(); for ( ; aIt != avoidIntersectionsList.constEnd(); ++aIt ) { currentLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( *aIt ) ); if ( currentLayer ) { QgsFeatureIds ignoreIds; QMap<QgsVectorLayer*, QSet<qint64> >::const_iterator ignoreIt = ignoreFeatures.find( currentLayer ); if ( ignoreIt != ignoreFeatures.constEnd() ) ignoreIds = ignoreIt.value(); QgsFeatureIterator fi = currentLayer->getFeatures( QgsFeatureRequest( geom.boundingBox() ) .setFlags( QgsFeatureRequest::ExactIntersect ) .setSubsetOfAttributes( QgsAttributeList() ) ); QgsFeature f; while ( fi.nextFeature( f ) ) { if ( ignoreIds.contains( f.id() ) ) continue; if ( !f.hasGeometry() ) continue; nearGeometries << f.geometry().geometry()->clone(); } } } if ( nearGeometries.isEmpty() ) { return nullptr; } QgsAbstractGeometryV2* combinedGeometries = geomEngine.data()->combine( nearGeometries ); qDeleteAll( nearGeometries ); if ( !combinedGeometries ) { return nullptr; } QgsAbstractGeometryV2* diffGeom = geomEngine.data()->difference( *combinedGeometries ); delete combinedGeometries; return diffGeom; }
QFont QgsMapToolLabel::currentLabelFont() { QFont font; QgsPalLayerSettings &labelSettings = mCurrentLabel.settings; QgsVectorLayer *vlayer = mCurrentLabel.layer; QgsRenderContext context = QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ); if ( mCurrentLabel.valid && vlayer ) { font = labelSettings.format().font(); QgsFeature f; if ( vlayer->getFeatures( QgsFeatureRequest().setFilterFid( mCurrentLabel.pos.featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( f ) ) { //size int sizeIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Size, mCurrentLabel.settings, vlayer ); if ( sizeIndx != -1 ) { font.setPixelSize( QgsTextRenderer::sizeToPixel( f.attribute( sizeIndx ).toDouble(), context, labelSettings.format().sizeUnit(), labelSettings.format().sizeMapUnitScale() ) ); } //family int fmIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Family, labelSettings, vlayer ); if ( fmIndx != -1 ) { font.setFamily( f.attribute( fmIndx ).toString() ); } //underline int ulIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Underline, labelSettings, vlayer ); if ( ulIndx != -1 ) { font.setUnderline( f.attribute( ulIndx ).toBool() ); } //strikeout int soIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Strikeout, labelSettings, vlayer ); if ( soIndx != -1 ) { font.setStrikeOut( f.attribute( soIndx ).toBool() ); } //bold int boIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Bold, labelSettings, vlayer ); if ( boIndx != -1 ) { font.setBold( f.attribute( boIndx ).toBool() ); } //italic int itIndx = dataDefinedColumnIndex( QgsPalLayerSettings::Italic, labelSettings, vlayer ); if ( itIndx != -1 ) { font.setItalic( f.attribute( itIndx ).toBool() ); } // TODO: Add other font data defined values (word spacing, etc.) } } return font; }