const QgsGraphDirector* RoadGraphPlugin::director() const { QList< QgsMapLayer* > mapLayers = QgsMapLayerRegistry::instance()->mapLayersByName( mSettings->mLayerName ); if ( mapLayers.isEmpty() ) return nullptr; QgsVectorLayer *layer = dynamic_cast< QgsVectorLayer* >( mapLayers.at( 0 ) ); if ( !layer ) return nullptr; if ( layer->wkbType() == QgsWkbTypes::LineString || layer->wkbType() == QgsWkbTypes::MultiLineString ) { SpeedUnit speedUnit = SpeedUnit::byName( mSettings->mSpeedUnitName ); QgsLineVectorLayerDirector * director = new QgsLineVectorLayerDirector( layer, layer->fields().lookupField( mSettings->mDirection ), mSettings->mFirstPointToLastPointDirectionVal, mSettings->mLastPointToFirstPointDirectionVal, mSettings->mBothDirectionVal, mSettings->mDefaultDirection ); director->addProperter( new QgsDistanceArcProperter() ); director->addProperter( new RgSpeedProperter( layer->fields().lookupField( mSettings->mSpeed ), mSettings->mDefaultSpeed, speedUnit.multipler() ) ); return director; } return nullptr; }
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; }
QgsField QgsEditorWidgetWrapper::field() const { QgsVectorLayer *vl = layer(); if ( vl && mFieldIdx < vl->fields().count() ) return vl->fields().at( mFieldIdx ); else return QgsField(); }
void test_willRenderFeature_symbolsForFeature() { // prepare features QgsVectorLayer* layer = new QgsVectorLayer( "point?field=fld:int", "x", "memory" ); int idx = layer->fieldNameIndex( "fld" ); QVERIFY( idx != -1 ); QgsFeature f1; f1.initAttributes( 1 ); f1.setAttribute( idx, QVariant( 2 ) ); QgsFeature f2; f2.initAttributes( 1 ); f2.setAttribute( idx, QVariant( 8 ) ); QgsFeature f3; f3.initAttributes( 1 ); f3.setAttribute( idx, QVariant( 100 ) ); // prepare renderer QgsSymbol* s1 = QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ); QgsSymbol* s2 = QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ); RRule* rootRule = new RRule( nullptr ); rootRule->appendChild( new RRule( s1, 0, 0, "fld >= 5 and fld <= 20" ) ); rootRule->appendChild( new RRule( s2, 0, 0, "fld <= 10" ) ); QgsRuleBasedRenderer r( rootRule ); QVERIFY( r.capabilities() & QgsFeatureRenderer::MoreSymbolsPerFeature ); QgsRenderContext ctx; // dummy render context ctx.expressionContext().setFields( layer->fields() ); r.startRender( ctx, layer->fields() ); // test willRenderFeature ctx.expressionContext().setFeature( f1 ); QVERIFY( r.willRenderFeature( f1, ctx ) ); ctx.expressionContext().setFeature( f2 ); QVERIFY( r.willRenderFeature( f2, ctx ) ); ctx.expressionContext().setFeature( f3 ); QVERIFY( !r.willRenderFeature( f3, ctx ) ); // test symbolsForFeature ctx.expressionContext().setFeature( f1 ); QgsSymbolList lst1 = r.symbolsForFeature( f1, ctx ); QVERIFY( lst1.count() == 1 ); ctx.expressionContext().setFeature( f2 ); QgsSymbolList lst2 = r.symbolsForFeature( f2, ctx ); QVERIFY( lst2.count() == 2 ); ctx.expressionContext().setFeature( f3 ); QgsSymbolList lst3 = r.symbolsForFeature( f3, ctx ); QVERIFY( lst3.isEmpty() ); r.stopRender( ctx ); delete layer; }
void QgsComposerAttributeTableV2::setDisplayedFields( const QStringList& fields, bool refresh ) { QgsVectorLayer* source = sourceLayer(); if ( !source ) { return; } //rebuild columns list, taking only fields contained in supplied list qDeleteAll( mColumns ); mColumns.clear(); QgsFields layerFields = source->fields(); if ( !fields.isEmpty() ) { Q_FOREACH ( const QString& field, fields ) { int attrIdx = layerFields.lookupField( field ); if ( attrIdx < 0 ) continue; QString currentAlias = source->attributeDisplayName( attrIdx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( layerFields.at( attrIdx ).name() ); col->setHeading( currentAlias ); mColumns.append( col ); }
void RgLineVectorLayerSettingsWidget::on_mcbLayers_selectItem() { mcbDirection->clear(); mcbSpeed->clear(); mcbDirection->insertItem( 0, tr( "Always use default" ) ); mcbSpeed->insertItem( 0, tr( "Always use default" ) ); QgsVectorLayer* vl = selectedLayer(); if ( !vl ) return; Q_FOREACH ( const QgsField& currentField, vl->fields() ) { QVariant currentType = currentField.type(); if ( currentType == QVariant::Int || currentType == QVariant::LongLong || currentType == QVariant::String ) { mcbDirection->insertItem( 1, currentField.name() ); } if ( currentType == QVariant::Int || currentType == QVariant::LongLong || currentType == QVariant::Double ) { mcbSpeed->insertItem( 1, currentField.name() ); } } }
void QgsComposerAttributeTableV2::resetColumns() { QgsVectorLayer *source = sourceLayer(); if ( !source ) { return; } //remove existing columns qDeleteAll( mColumns ); mColumns.clear(); //rebuild columns list from vector layer fields int idx = 0; const QgsFields sourceFields = source->fields(); for ( const auto &field : sourceFields ) { QString currentAlias = source->attributeDisplayName( idx ); QgsComposerTableColumn *col = new QgsComposerTableColumn; col->setAttribute( field.name() ); col->setHeading( currentAlias ); mColumns.append( col ); idx++; } }
QWidget *QgsAttributeTableDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index ) const { Q_UNUSED( option ); QgsVectorLayer *vl = layer( index.model() ); if ( !vl ) return nullptr; int fieldIdx = index.model()->data( index, QgsAttributeTableModel::FieldIndexRole ).toInt(); QgsAttributeEditorContext context( masterModel( index.model() )->editorContext(), QgsAttributeEditorContext::Popup ); QgsEditorWidgetWrapper *eww = QgsGui::editorWidgetRegistry()->create( vl, fieldIdx, nullptr, parent, context ); QWidget *w = eww->widget(); w->setAutoFillBackground( true ); w->setFocusPolicy( Qt::StrongFocus ); // to make sure QMouseEvents are propagated to the editor widget const int fieldOrigin = vl->fields().fieldOrigin( fieldIdx ); bool readOnly = true; if ( fieldOrigin == QgsFields::OriginJoin ) { int srcFieldIndex; const QgsVectorLayerJoinInfo *info = vl->joinBuffer()->joinForFieldIndex( fieldIdx, vl->fields(), srcFieldIndex ); if ( info && info->isEditable() ) readOnly = info->joinLayer()->editFormConfig().readOnly( srcFieldIndex ); } else readOnly = vl->editFormConfig().readOnly( fieldIdx ); eww->setEnabled( !readOnly ); return w; }
bool QgsGeometryCheckerResultTab::exportErrorsDo( const QString& file ) { QList< QPair<QString, QString> > attributes; attributes.append( qMakePair( QString( "FeatureID" ), QString( "String;10;" ) ) ); attributes.append( qMakePair( QString( "ErrorDesc" ), QString( "String;80;" ) ) ); QLibrary ogrLib( QgsProviderRegistry::instance()->library( "ogr" ) ); if ( !ogrLib.load() ) { return false; } typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, Qgis::WkbType, const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem& ); createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( ogrLib.resolve( "createEmptyDataSource" ) ); if ( !createEmptyDataSource ) { return false; } if ( !createEmptyDataSource( file, "ESRI Shapefile", mFeaturePool->getLayer()->dataProvider()->encoding(), Qgis::WKBPoint, attributes, mFeaturePool->getLayer()->crs() ) ) { return false; } QgsVectorLayer* layer = new QgsVectorLayer( file, QFileInfo( file ).baseName(), "ogr" ); if ( !layer->isValid() ) { delete layer; return false; } int fieldFeatureId = layer->fieldNameIndex( "FeatureID" ); int fieldErrDesc = layer->fieldNameIndex( "ErrorDesc" ); for ( int row = 0, nRows = ui.tableWidgetErrors->rowCount(); row < nRows; ++row ) { QgsGeometryCheckError* error = ui.tableWidgetErrors->item( row, 0 )->data( Qt::UserRole ).value<QgsGeometryCheckError*>(); QgsFeature f( layer->fields() ); f.setAttribute( fieldFeatureId, error->featureId() ); f.setAttribute( fieldErrDesc, error->description() ); f.setGeometry( QgsGeometry( error->location().clone() ) ); layer->dataProvider()->addFeatures( QgsFeatureList() << f ); } // Remove existing layer with same uri QStringList toRemove; Q_FOREACH ( QgsMapLayer* maplayer, QgsMapLayerRegistry::instance()->mapLayers() ) { if ( dynamic_cast<QgsVectorLayer*>( maplayer ) && static_cast<QgsVectorLayer*>( maplayer )->dataProvider()->dataSourceUri() == layer->dataProvider()->dataSourceUri() ) { toRemove.append( maplayer->id() ); } } if ( !toRemove.isEmpty() ) { QgsMapLayerRegistry::instance()->removeMapLayers( toRemove ); } QgsMapLayerRegistry::instance()->addMapLayers( QList<QgsMapLayer*>() << layer ); return true; }
void RgShortestPathWidget::exportPath() { RgExportDlg dlg( this ); if ( !dlg.exec() ) return; QgsVectorLayer *vl = dlg.mapLayer(); if ( vl == NULL ) return; QgsPoint p1, p2; QgsGraph *path = getPath( p1, p2 ); if ( path == NULL ) return; QgsCoordinateTransform ct( mPlugin->iface()->mapCanvas()->mapSettings().destinationCrs(), vl->crs() ); int startVertexIdx = path->findVertex( p1 ); int stopVertexIdx = path->findVertex( p2 ); double time = 0.0; double cost = 0.0; Unit timeUnit = Unit::byName( mPlugin->timeUnitName() ); Unit distanceUnit = Unit::byName( mPlugin->distanceUnitName() ); QgsPolyline p; while ( startVertexIdx != stopVertexIdx ) { if ( stopVertexIdx < 0 ) break; QgsGraphArcIdList l = path->vertex( stopVertexIdx ).inArc(); if ( l.empty() ) break; const QgsGraphArc& e = path->arc( l.front() ); cost += e.property( 0 ).toDouble(); time += e.property( 1 ).toDouble(); p.push_front( ct.transform( path->vertex( e.inVertex() ).point() ) ); stopVertexIdx = e.outVertex(); } p.push_front( ct.transform( p1 ) ); QgsFeature f; f.initAttributes( vl->fields().count() ); f.setGeometry( QgsGeometry::fromPolyline( p ) ); f.setAttribute( 0, cost / distanceUnit.multipler() ); f.setAttribute( 1, time / timeUnit.multipler() ); QgsFeatureList features; features << f; vl->dataProvider()->addFeatures( features ); vl->updateExtents(); mPlugin->iface()->mapCanvas()->update(); delete path; }
int HeatmapGui::weightField() const { QgsVectorLayer *inputLayer = inputVectorLayer(); if ( !inputLayer ) return 0; return inputLayer->fields().indexFromName( mWeightFieldCombo->currentField() ); }
void FieldSelectorDelegate::setEditorData( QWidget *editor, const QModelIndex &index ) const { const QgsVectorLayerAndAttributeModel *m = dynamic_cast< const QgsVectorLayerAndAttributeModel *>( index.model() ); if ( !m ) return; QgsVectorLayer *vl = m->vectorLayer( index ); if ( !vl ) return; QgsFieldComboBox *fcb = qobject_cast<QgsFieldComboBox *>( editor ); if ( !fcb ) return; int idx = m->attributeIndex( vl ); if ( vl->fields().exists( idx ) ) fcb->setField( vl->fields().at( idx ).name() ); }
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; }
void QgsEditorWidgetRegistry::writeMapLayer( QgsMapLayer* mapLayer, QDomElement& layerElem, QDomDocument& doc ) const { if ( mapLayer->type() != QgsMapLayer::VectorLayer ) { return; } QgsVectorLayer* vectorLayer = qobject_cast<QgsVectorLayer*>( mapLayer ); if ( !vectorLayer ) { return; } QDomNode editTypesNode = doc.createElement( "edittypes" ); QgsFields fields = vectorLayer->fields(); for ( int idx = 0; idx < fields.count(); ++idx ) { QgsField field = fields.at( idx ); const QString& widgetType = vectorLayer->editFormConfig()->widgetType( idx ); if ( !mWidgetFactories.contains( widgetType ) ) { QgsMessageLog::logMessage( tr( "Could not save unknown editor widget type '%1'." ).arg( widgetType ) ); continue; } QDomElement editTypeElement = doc.createElement( "edittype" ); editTypeElement.setAttribute( "name", field.name() ); editTypeElement.setAttribute( "widgetv2type", widgetType ); if ( mWidgetFactories.contains( widgetType ) ) { QDomElement ewv2CfgElem = doc.createElement( "widgetv2config" ); ewv2CfgElem.setAttribute( "fieldEditable", !vectorLayer->editFormConfig()->readOnly( idx ) ); ewv2CfgElem.setAttribute( "labelOnTop", vectorLayer->editFormConfig()->labelOnTop( idx ) ); ewv2CfgElem.setAttribute( "notNull", vectorLayer->editFormConfig()->notNull( idx ) ); ewv2CfgElem.setAttribute( "constraint", vectorLayer->editFormConfig()->expression( idx ) ); ewv2CfgElem.setAttribute( "constraintDescription", vectorLayer->editFormConfig()->expressionDescription( idx ) ); mWidgetFactories[widgetType]->writeConfig( vectorLayer->editFormConfig()->widgetConfig( idx ), ewv2CfgElem, doc, vectorLayer, idx ); editTypeElement.appendChild( ewv2CfgElem ); } editTypesNode.appendChild( editTypeElement ); } layerElem.appendChild( editTypesNode ); }
void HeatmapGui::updateBBox() { // Set the row/cols and cell sizes here QgsVectorLayer *inputLayer = inputVectorLayer(); if ( !inputLayer ) return; mBBox = inputLayer->extent(); QgsCoordinateReferenceSystem layerCrs = inputLayer->crs(); double radiusInMapUnits = 0.0; if ( mRadiusFieldCheckBox->isChecked() ) { int idx = inputLayer->fields().indexFromName( mRadiusFieldCombo->currentField() ); double maxInField = inputLayer->maximumValue( idx ).toDouble(); if ( mRadiusFieldUnitCombo->currentIndex() == HeatmapGui::LayerUnits ) { radiusInMapUnits = mapUnitsOf( maxInField, layerCrs ); } else if ( mRadiusFieldUnitCombo->currentIndex() == HeatmapGui::MapUnits ) { radiusInMapUnits = maxInField; } } else { double radiusValue = mBufferSizeLineEdit->text().toDouble(); if ( mBufferUnitCombo->currentIndex() == HeatmapGui::LayerUnits ) { radiusInMapUnits = mapUnitsOf( radiusValue, layerCrs ); } else if ( mBufferUnitCombo->currentIndex() == HeatmapGui::MapUnits ) { radiusInMapUnits = radiusValue; } } // get the distance converted into map units mBBox.setXMinimum( mBBox.xMinimum() - radiusInMapUnits ); mBBox.setYMinimum( mBBox.yMinimum() - radiusInMapUnits ); mBBox.setXMaximum( mBBox.xMaximum() + radiusInMapUnits ); mBBox.setYMaximum( mBBox.yMaximum() + radiusInMapUnits ); // Leave number of rows the same, and calculate new corresponding cell size and number of columns mYcellsize = mBBox.height() / ( mRows - 1 ); mXcellsize = mYcellsize; mColumns = max( mBBox.width() / mXcellsize + 1, 1 ); updateSize(); }
void QgsComposerAttributeTableV2::setDisplayAttributes( const QSet<int>& attr, bool refresh ) { QgsVectorLayer* source = sourceLayer(); if ( !source ) { return; } //rebuild columns list, taking only attributes with index in supplied QSet qDeleteAll( mColumns ); mColumns.clear(); const QgsFields& fields = source->fields(); if ( !attr.empty() ) { QSet<int>::const_iterator attIt = attr.constBegin(); for ( ; attIt != attr.constEnd(); ++attIt ) { int attrIdx = ( *attIt ); if ( !fields.exists( attrIdx ) ) { continue; } QString currentAlias = source->attributeDisplayName( attrIdx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( fields[attrIdx].name() ); col->setHeading( currentAlias ); mColumns.append( col ); } } else { //resetting, so add all attributes to columns for ( int idx = 0; idx < fields.count(); ++idx ) { QString currentAlias = source->attributeDisplayName( idx ); QgsComposerTableColumn* col = new QgsComposerTableColumn; col->setAttribute( fields[idx].name() ); col->setHeading( currentAlias ); mColumns.append( col ); } } if ( refresh ) { refreshAttributes(); } }
void FieldSelectorDelegate::setModelData( QWidget *editor, QAbstractItemModel *model, const QModelIndex &index ) const { QgsVectorLayerAndAttributeModel *m = dynamic_cast< QgsVectorLayerAndAttributeModel *>( model ); if ( !m ) return; QgsVectorLayer *vl = m->vectorLayer( index ); if ( !vl ) return; QgsFieldComboBox *fcb = qobject_cast<QgsFieldComboBox *>( editor ); if ( !fcb ) return; model->setData( index, vl->fields().lookupField( fcb->currentField() ) ); }
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(); }
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsPalIndexes &indexes ) const { bool newAuxiliaryLayer = false; QgsVectorLayer *vlayer = details.layer; QString providerId = details.pos.providerID; if ( !vlayer || !vlayer->labelsEnabled() ) return false; if ( !vlayer->auxiliaryLayer() ) { QgsNewAuxiliaryLayerDialog dlg( vlayer ); dlg.exec(); newAuxiliaryLayer = true; } if ( !vlayer->auxiliaryLayer() ) return false; for ( const QgsPalLayerSettings::Property &p : qgis::as_const( mPalProperties ) ) { int index = -1; // always use the default activated property QgsProperty prop = details.settings.dataDefinedProperties().property( p ); if ( prop.propertyType() == QgsProperty::FieldBasedProperty && prop.isActive() ) { index = vlayer->fields().lookupField( prop.field() ); } else { index = QgsAuxiliaryLayer::createProperty( p, vlayer ); } indexes[p] = index; } details.settings = vlayer->labeling()->settings( providerId ); return newAuxiliaryLayer; }
QWidget *QgsFormAnnotation::createDesignerWidget( const QString &filePath ) { QFile file( filePath ); if ( !file.open( QFile::ReadOnly ) ) { return nullptr; } QUiLoader loader; QFileInfo fi( file ); loader.setWorkingDirectory( fi.dir() ); QWidget *widget = loader.load( &file, nullptr ); file.close(); //get feature and set attribute information QgsAttributeEditorContext context; QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() ); if ( vectorLayer && associatedFeature().isValid() ) { QgsFields fields = vectorLayer->fields(); QgsAttributes attrs = associatedFeature().attributes(); for ( int i = 0; i < attrs.count(); ++i ) { if ( i < fields.count() ) { QWidget *attWidget = widget->findChild<QWidget *>( fields.at( i ).name() ); if ( attWidget ) { QgsEditorWidgetWrapper *eww = QgsGui::editorWidgetRegistry()->create( vectorLayer, i, attWidget, widget, context ); if ( eww ) { eww->setValue( attrs.at( i ) ); } } } } } return widget; }
void QgsJoinDialog::joinedLayerChanged( QgsMapLayer* layer ) { mJoinFieldComboBox->clear(); QgsVectorLayer* vLayer = dynamic_cast<QgsVectorLayer*>( layer ); if ( !vLayer ) { return; } mUseJoinFieldsSubset->setChecked( false ); QStandardItemModel* subsetModel = new QStandardItemModel( this ); const QgsFields& layerFields = vLayer->fields(); for ( int idx = 0; idx < layerFields.count(); ++idx ) { QStandardItem* subsetItem = new QStandardItem( layerFields[idx].name() ); subsetItem->setCheckable( true ); //subsetItem->setFlags( subsetItem->flags() | Qt::ItemIsUserCheckable ); subsetModel->appendRow( subsetItem ); } mJoinFieldsSubsetView->setModel( subsetModel ); QgsVectorDataProvider* dp = vLayer->dataProvider(); bool canCreateAttrIndex = dp && ( dp->capabilities() & QgsVectorDataProvider::CreateAttributeIndex ); if ( canCreateAttrIndex ) { mCreateIndexCheckBox->setEnabled( true ); } else { mCreateIndexCheckBox->setEnabled( false ); mCreateIndexCheckBox->setChecked( false ); } if ( !mUseCustomPrefix->isChecked() ) { mCustomPrefix->setText( layer->name() + "_" ); } }
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsDiagramIndexes &indexes ) { bool newAuxiliaryLayer = false; QgsVectorLayer *vlayer = details.layer; if ( !vlayer ) return newAuxiliaryLayer; if ( !vlayer->auxiliaryLayer() ) { QgsNewAuxiliaryLayerDialog dlg( vlayer ); dlg.exec(); newAuxiliaryLayer = true; } if ( !vlayer->auxiliaryLayer() ) return false; for ( const QgsDiagramLayerSettings::Property &p : qgis::as_const( mDiagramProperties ) ) { int index = -1; // always use the default activated property QgsProperty prop = vlayer->diagramLayerSettings()->dataDefinedProperties().property( p ); if ( prop.propertyType() == QgsProperty::FieldBasedProperty && prop.isActive() ) { index = vlayer->fields().lookupField( prop.field() ); } else { index = QgsAuxiliaryLayer::createProperty( p, vlayer ); } indexes[p] = index; } return newAuxiliaryLayer; }
QVariant QgsVectorLayerAndAttributeModel::data( const QModelIndex& idx, int role ) const { if ( idx.column() == 0 ) { if ( role == Qt::CheckStateRole ) { if ( !idx.isValid() ) return QVariant(); if ( mCheckedLeafs.contains( idx ) ) return Qt::Checked; bool hasChecked = false, hasUnchecked = false; int n; for ( n = 0; !hasChecked || !hasUnchecked; n++ ) { QVariant v = data( idx.child( n, 0 ), role ); if ( !v.isValid() ) break; switch ( v.toInt() ) { case Qt::PartiallyChecked: // parent of partially checked child shared state return Qt::PartiallyChecked; case Qt::Checked: hasChecked = true; break; case Qt::Unchecked: hasUnchecked = true; break; } } // unchecked leaf if ( n == 0 ) return Qt::Unchecked; // both if ( hasChecked && hasUnchecked ) return Qt::PartiallyChecked; if ( hasChecked ) return Qt::Checked; Q_ASSERT( hasUnchecked ); return Qt::Unchecked; } else return QgsLayerTreeModel::data( idx, role ); } QgsVectorLayer *vl = vectorLayer( idx ); if ( vl ) { int idx = mAttributeIdx.value( vl, -1 ); if ( role == Qt::EditRole ) return idx; if ( role == Qt::DisplayRole ) { if ( vl->fields().exists( idx ) ) return vl->fields().at( idx ).name(); else return vl->name(); } if ( role == Qt::ToolTipRole ) { return tr( "Attribute containing the name of the destination layer in the DXF output." ); } } return QVariant(); }
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 QgsMapToolAddFeature::cadCanvasReleaseEvent( QgsMapMouseEvent* e ) { QgsVectorLayer* vlayer = currentVectorLayer(); if ( !vlayer ) { notifyNotVectorLayer(); return; } QGis::WkbType layerWKBType = vlayer->wkbType(); QgsVectorDataProvider* provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), QgsMessageBar::WARNING ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QGis::Point && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } QgsPoint savePoint; //point in layer coordinates try { savePoint = toLayerCoordinates( vlayer, e->mapPoint() ); QgsDebugMsg( "savePoint = " + savePoint.toString() ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), QgsMessageBar::WARNING ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->fields(), 0 ); QgsGeometry *g = 0; if ( layerWKBType == QGis::WKBPoint || layerWKBType == QGis::WKBPoint25D ) { g = QgsGeometry::fromPoint( savePoint ); } else if ( layerWKBType == QGis::WKBMultiPoint || layerWKBType == QGis::WKBMultiPoint25D ) { g = QgsGeometry::fromMultiPoint( QgsMultiPoint() << savePoint ); } else { // if layer supports more types (mCheckGeometryType is false) g = QgsGeometry::fromPoint( savePoint ); } f.setGeometry( g ); f.setValid( true ); addFeature( vlayer, &f, false ); mCanvas->refresh(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QGis::Line && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), QgsMessageBar::WARNING ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QGis::Polygon && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), QgsMessageBar::WARNING ); 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 ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } if ( mode() == CapturePolygon ) { closePolygon(); } //create QgsFeature with wkb representation QScopedPointer< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); //does compoundcurve contain circular strings? //does provider support circular strings? bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries; QgsCurveV2* curveToAdd = 0; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { curveToAdd = captureCurve()->clone(); } else { curveToAdd = captureCurve()->curveToLine(); } if ( mode() == CaptureLine ) { f->setGeometry( new QgsGeometry( curveToAdd ) ); } else { QgsCurvePolygonV2* poly = 0; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { poly = new QgsCurvePolygonV2(); } else { poly = new QgsPolygonV2(); } poly->setExteriorRing( curveToAdd ); f->setGeometry( new QgsGeometry( poly ) ); int avoidIntersectionsReturn = f->geometry()->avoidIntersections(); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } #if 0 else if ( avoidIntersectionsReturn == 2 ) //MH120131: disable this error message until there is a better way to cope with the single type / multi type problem { //bail out... emit messageEmitted( tr( "The feature could not be added because removing the polygon intersections would change the geometry type" ), QgsMessageBar::CRITICAL ); stopCapturing(); return; } #endif else if ( avoidIntersectionsReturn == 3 ) { emit messageEmitted( tr( "An error was reported during intersection removal" ), QgsMessageBar::CRITICAL ); } if ( !f->constGeometry()->asWkb() ) //avoid intersection might have removed the whole geometry { QString reason; if ( avoidIntersectionsReturn != 2 ) { reason = tr( "The feature cannot be added because it's geometry is empty" ); } else { reason = tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ); } emit messageEmitted( reason, QgsMessageBar::CRITICAL ); stopCapturing(); return; } } if ( addFeature( vlayer, f.data(), false ) ) { //add points to other features to keep topology up-to-date int topologicalEditing = QgsProject::instance()->readNumEntry( "Digitizing", "/TopologicalEditing", 0 ); //use always topological editing for avoidIntersection. //Otherwise, no way to guarantee the geometries don't have a small gap in between. QStringList intersectionLayers = QgsProject::instance()->readListEntry( "Digitizing", "/AvoidIntersectionsList" ); bool avoidIntersection = !intersectionLayers.isEmpty(); if ( avoidIntersection ) //try to add topological points also to background layers { QStringList::const_iterator lIt = intersectionLayers.constBegin(); for ( ; lIt != intersectionLayers.constEnd(); ++lIt ) { QgsMapLayer* ml = QgsMapLayerRegistry::instance()->mapLayer( *lIt ); QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( ml ); //can only add topological points if background layer is editable... if ( vl && vl->geometryType() == QGis::Polygon && vl->isEditable() ) { vl->addTopologicalPoints( f->constGeometry() ); } } } else if ( topologicalEditing ) { vlayer->addTopologicalPoints( f->constGeometry() ); } } stopCapturing(); } } }
void QgsLabelPropertyDialog::init( const QString& layerId, const QString& providerId, int featureId, const QString& labelText ) { //get feature attributes QgsVectorLayer* vlayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( layerId ) ); if ( !vlayer ) { return; } if ( !vlayer->labeling() ) { return; } if ( !vlayer->getFeatures( QgsFeatureRequest().setFilterFid( featureId ).setFlags( QgsFeatureRequest::NoGeometry ) ).nextFeature( mCurLabelFeat ) ) { return; } QgsAttributes attributeValues = mCurLabelFeat.attributes(); //get layerproperties. Problem: only for pallabeling... blockElementSignals( true ); QgsPalLayerSettings layerSettings = vlayer->labeling()->settings( vlayer, providerId ); //get label field and fill line edit if ( layerSettings.isExpression && !labelText.isNull() ) { mLabelTextLineEdit->setText( labelText ); mLabelTextLineEdit->setEnabled( false ); mLabelTextLabel->setText( tr( "Expression result" ) ); } else { QString labelFieldName = vlayer->customProperty( "labeling/fieldName" ).toString(); if ( !labelFieldName.isEmpty() ) { mCurLabelField = vlayer->fieldNameIndex( labelFieldName ); if ( mCurLabelField >= 0 ) { mLabelTextLineEdit->setText( attributeValues.at( mCurLabelField ).toString() ); const QgsFields& layerFields = vlayer->fields(); switch ( layerFields.at( mCurLabelField ).type() ) { case QVariant::Double: mLabelTextLineEdit->setValidator( new QDoubleValidator( this ) ); break; case QVariant::Int: case QVariant::UInt: case QVariant::LongLong: mLabelTextLineEdit->setValidator( new QIntValidator( this ) ); break; default: break; } } else { mLabelTextLineEdit->setEnabled( false ); } } } //get attributes of the feature and fill data defined values // font is set directly from QgsLabelPosition updateFont( mLabelFont, false ); //set all the gui elements to the default layer-level values mLabelDistanceSpinBox->clear(); mLabelDistanceSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( layerSettings.dist, 'f', mLabelDistanceSpinBox->decimals() ) ) ); mBufferSizeSpinBox->clear(); mBufferSizeSpinBox->setSpecialValueText( tr( "Layer default (%1)" ).arg( QString::number( layerSettings.bufferSize, 'f', mBufferSizeSpinBox->decimals() ) ) ); mRotationSpinBox->clear(); mXCoordSpinBox->clear(); mYCoordSpinBox->clear(); mShowLabelChkbx->setChecked( true ); mFontColorButton->setColor( layerSettings.textColor ); mBufferColorButton->setColor( layerSettings.bufferColor ); mMinScaleSpinBox->setValue( layerSettings.scaleMin ); mMaxScaleSpinBox->setValue( layerSettings.scaleMax ); mHaliComboBox->setCurrentIndex( mHaliComboBox->findData( "Left" ) ); mValiComboBox->setCurrentIndex( mValiComboBox->findData( "Bottom" ) ); mFontColorButton->setColorDialogTitle( tr( "Font color" ) ); mBufferColorButton->setColorDialogTitle( tr( "Buffer color" ) ); disableGuiElements(); QMap< QgsPalLayerSettings::DataDefinedProperties, QgsDataDefined* >::const_iterator it = layerSettings.dataDefinedProperties.constBegin(); for ( ; it != layerSettings.dataDefinedProperties.constEnd(); ++it ) { mDataDefinedProperties.insert( it.key(), it.value() ? new QgsDataDefined( *it.value() ) : nullptr ); } //set widget values from data defined results setDataDefinedValues( layerSettings, vlayer ); //enable widgets connected to data defined fields enableDataDefinedWidgets( vlayer ); blockElementSignals( false ); }
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 ) 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" ) ); QgsRenderContext context = QgsRenderContext::fromMapSettings( canvas->mapSettings() ); context.expressionContext() << QgsExpressionContextUtils::layerScope( vlayer ); QgsFeatureRendererV2* r = vlayer->rendererV2(); if ( r ) r->startRender( context, vlayer->fields() ); QgsFeatureRequest request; request.setFilterRect( selectGeomTrans.boundingBox() ); request.setFlags( QgsFeatureRequest::ExactIntersect ); if ( r ) request.setSubsetOfAttributes( r->usedAttributes(), vlayer->fields() ); 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 ) ) { context.expressionContext().setFeature( f ); // make sure to only use features that are visible if ( r && !r->willRenderFeature( f, context ) ) continue; const QgsGeometry* g = f.constGeometry(); 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 { vlayer->setSelectedFeatures( newSelectedFeatures ); } QApplication::restoreOverrideCursor(); }
QgsGeometryCheckerResultTab::QgsGeometryCheckerResultTab( QgisInterface *iface, QgsGeometryChecker *checker, QTabWidget *tabWidget, QWidget *parent ) : QWidget( parent ) , mTabWidget( tabWidget ) , mIface( iface ) , mChecker( checker ) { ui.setupUi( this ); mErrorCount = 0; mFixedCount = 0; mCloseable = true; const QStringList layers = mChecker->featurePools().keys(); for ( const QString &layerId : layers ) { QgsVectorLayer *layer = mChecker->featurePools()[layerId]->layer(); QTreeWidgetItem *item = new QTreeWidgetItem( ui.treeWidgetMergeAttribute, QStringList() << layer->name() << QString() ); QComboBox *attribCombo = new QComboBox(); const QgsFields fields = layer->fields(); for ( const QgsField &field : fields ) { attribCombo->addItem( field.name() ); } attribCombo->setCurrentIndex( 0 ); connect( attribCombo, SIGNAL( currentIndexChanged( int ) ), this, SLOT( updateMergeAttributeIndices() ) ); ui.treeWidgetMergeAttribute->setItemWidget( item, 1, attribCombo ); } updateMergeAttributeIndices(); connect( checker, &QgsGeometryChecker::errorAdded, this, &QgsGeometryCheckerResultTab::addError ); connect( checker, &QgsGeometryChecker::errorUpdated, this, &QgsGeometryCheckerResultTab::updateError ); connect( ui.tableWidgetErrors->selectionModel(), &QItemSelectionModel::selectionChanged, this, &QgsGeometryCheckerResultTab::onSelectionChanged ); connect( ui.buttonGroupSelectAction, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, [this]( int ) { QgsGeometryCheckerResultTab::highlightErrors(); } ); connect( ui.pushButtonOpenAttributeTable, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::openAttributeTable ); connect( ui.pushButtonFixWithDefault, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::fixErrorsWithDefault ); connect( ui.pushButtonFixWithPrompt, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::fixErrorsWithPrompt ); connect( ui.pushButtonErrorResolutionSettings, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::setDefaultResolutionMethods ); connect( ui.checkBoxHighlight, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::highlightErrors ); connect( QgsProject::instance(), static_cast<void ( QgsProject::* )( const QStringList & )>( &QgsProject::layersWillBeRemoved ), this, &QgsGeometryCheckerResultTab::checkRemovedLayer ); connect( ui.pushButtonExport, &QAbstractButton::clicked, this, &QgsGeometryCheckerResultTab::exportErrors ); bool allLayersEditable = true; for ( const QgsFeaturePool *featurePool : mChecker->featurePools().values() ) { if ( ( featurePool->layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeGeometries ) == 0 ) { allLayersEditable = false; break; } } if ( !allLayersEditable ) { ui.pushButtonFixWithDefault->setEnabled( false ); ui.pushButtonFixWithPrompt->setEnabled( false ); } ui.progressBarFixErrors->setVisible( false ); ui.tableWidgetErrors->horizontalHeader()->setSortIndicator( 0, Qt::AscendingOrder ); ui.tableWidgetErrors->resizeColumnToContents( 0 ); ui.tableWidgetErrors->resizeColumnToContents( 1 ); ui.tableWidgetErrors->horizontalHeader()->setResizeMode( 2, QHeaderView::Stretch ); ui.tableWidgetErrors->horizontalHeader()->setResizeMode( 3, QHeaderView::Stretch ); ui.tableWidgetErrors->horizontalHeader()->setResizeMode( 4, QHeaderView::Stretch ); ui.tableWidgetErrors->horizontalHeader()->setResizeMode( 5, QHeaderView::Stretch ); // Not sure why, but this is needed... ui.tableWidgetErrors->setSortingEnabled( true ); ui.tableWidgetErrors->setSortingEnabled( false ); }
void QgsMapToolDigitizeFeature::cadCanvasReleaseEvent( QgsMapMouseEvent *e ) { QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mLayer ); if ( !vlayer ) //if no given layer take the current from canvas vlayer = currentVectorLayer(); if ( !vlayer ) { notifyNotVectorLayer(); return; } QgsWkbTypes::Type layerWKBType = vlayer->wkbType(); QgsVectorDataProvider *provider = vlayer->dataProvider(); if ( !( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) ) { emit messageEmitted( tr( "The data provider for this layer does not support the addition of features." ), Qgis::Warning ); return; } if ( !vlayer->isEditable() ) { notifyNotEditableLayer(); return; } // POINT CAPTURING if ( mode() == CapturePoint ) { if ( e->button() != Qt::LeftButton ) return; //check we only use this tool for point/multipoint layers if ( vlayer->geometryType() != QgsWkbTypes::PointGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture point' tool on this vector layer" ), Qgis::Warning ); return; } QgsPointXY savePoint; //point in layer coordinates try { QgsPoint fetchPoint; int res; res = fetchLayerPoint( e->mapPointMatch(), fetchPoint ); if ( res == 0 ) { savePoint = QgsPointXY( fetchPoint.x(), fetchPoint.y() ); } else { savePoint = toLayerCoordinates( vlayer, e->mapPoint() ); } QgsDebugMsg( "savePoint = " + savePoint.toString() ); } catch ( QgsCsException &cse ) { Q_UNUSED( cse ); emit messageEmitted( tr( "Cannot transform the point to the layers coordinate system" ), Qgis::Warning ); return; } //only do the rest for provider with feature addition support //note that for the grass provider, this will return false since //grass provider has its own mechanism of feature addition if ( provider->capabilities() & QgsVectorDataProvider::AddFeatures ) { QgsFeature f( vlayer->fields(), 0 ); QgsGeometry g; if ( layerWKBType == QgsWkbTypes::Point ) { g = QgsGeometry::fromPointXY( savePoint ); } else if ( !QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), defaultZValue() ) ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && !QgsWkbTypes::hasZ( layerWKBType ) ) { g = QgsGeometry::fromMultiPointXY( QgsMultiPointXY() << savePoint ); } else if ( QgsWkbTypes::isMultiType( layerWKBType ) && QgsWkbTypes::hasZ( layerWKBType ) ) { QgsMultiPoint *mp = new QgsMultiPoint(); mp->addGeometry( new QgsPoint( QgsWkbTypes::PointZ, savePoint.x(), savePoint.y(), defaultZValue() ) ); g = QgsGeometry( mp ); } else { // if layer supports more types (mCheckGeometryType is false) g = QgsGeometry::fromPointXY( savePoint ); } if ( QgsWkbTypes::hasM( layerWKBType ) ) { g.get()->addMValue(); } f.setGeometry( g ); f.setValid( true ); digitized( f ); // we are done with digitizing for now so instruct advanced digitizing dock to reset its CAD points cadDockWidget()->clearPoints(); } } // LINE AND POLYGON CAPTURING else if ( mode() == CaptureLine || mode() == CapturePolygon ) { //check we only use the line tool for line/multiline layers if ( mode() == CaptureLine && vlayer->geometryType() != QgsWkbTypes::LineGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture line' tool on this vector layer" ), Qgis::Warning ); return; } //check we only use the polygon tool for polygon/multipolygon layers if ( mode() == CapturePolygon && vlayer->geometryType() != QgsWkbTypes::PolygonGeometry && mCheckGeometryType ) { emit messageEmitted( tr( "Wrong editing tool, cannot apply the 'capture polygon' tool on this vector layer" ), Qgis::Warning ); return; } //add point to list and to rubber band if ( e->button() == Qt::LeftButton ) { int error = addVertex( e->mapPoint(), e->mapPointMatch() ); 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" ), Qgis::Warning ); return; } startCapturing(); } else if ( e->button() == Qt::RightButton ) { // End of string deleteTempRubberBand(); //lines: bail out if there are not at least two vertices if ( mode() == CaptureLine && size() < 2 ) { stopCapturing(); return; } //polygons: bail out if there are not at least two vertices if ( mode() == CapturePolygon && size() < 3 ) { stopCapturing(); return; } if ( mode() == CapturePolygon ) { closePolygon(); } //create QgsFeature with wkb representation std::unique_ptr< QgsFeature > f( new QgsFeature( vlayer->fields(), 0 ) ); //does compoundcurve contain circular strings? //does provider support circular strings? bool hasCurvedSegments = captureCurve()->hasCurvedSegments(); bool providerSupportsCurvedSegments = vlayer->dataProvider()->capabilities() & QgsVectorDataProvider::CircularGeometries; QList<QgsPointLocator::Match> snappingMatchesList; QgsCurve *curveToAdd = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { curveToAdd = captureCurve()->clone(); } else { curveToAdd = captureCurve()->curveToLine(); snappingMatchesList = snappingMatches(); } if ( mode() == CaptureLine ) { QgsGeometry g( curveToAdd ); f->setGeometry( g ); } else { QgsCurvePolygon *poly = nullptr; if ( hasCurvedSegments && providerSupportsCurvedSegments ) { poly = new QgsCurvePolygon(); } else { poly = new QgsPolygon(); } poly->setExteriorRing( curveToAdd ); QgsGeometry g( poly ); f->setGeometry( g ); QgsGeometry featGeom = f->geometry(); int avoidIntersectionsReturn = featGeom.avoidIntersections( QgsProject::instance()->avoidIntersectionsLayers() ); f->setGeometry( featGeom ); if ( avoidIntersectionsReturn == 1 ) { //not a polygon type. Impossible to get there } if ( f->geometry().isEmpty() ) //avoid intersection might have removed the whole geometry { emit messageEmitted( tr( "The feature cannot be added because it's geometry collapsed due to intersection avoidance" ), Qgis::Critical ); stopCapturing(); return; } } f->setValid( true ); digitized( *f ); stopCapturing(); } } }
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; } QScopedPointer< QgsExpressionContext > context( createExpressionContext() ); context->setFields( layer->fields() ); //prepare filter expression QScopedPointer<QgsExpression> filterExpression; bool activeFilter = false; if ( mFilterFeatures && !mFeatureFilter.isEmpty() ) { filterExpression.reset( 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().feature(); req = relation.getRelatedFeaturesRequest( atlasFeature ); } 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().feature(); req.setFilterFid( atlasFeature.id() ); } QgsFeature f; int counter = 0; QgsFeatureIterator fit = layer->getFeatures( req ); while ( fit.nextFeature( f ) && counter < mMaximumNumberOfFeatures ) { context->setFeature( f ); //check feature against filter if ( activeFilter && !filterExpression.isNull() ) { QVariant result = filterExpression->evaluate( context.data() ); // skip this feature if the filter evaluation is false if ( !result.toBool() ) { continue; } } //check against atlas feature intersection if ( mFilterToAtlasIntersection ) { if ( !f.constGeometry() || ! mComposition->atlasComposition().enabled() ) { continue; } QgsFeature atlasFeature = mComposition->atlasComposition().feature(); if ( !atlasFeature.constGeometry() || !f.constGeometry()->intersects( atlasFeature.constGeometry() ) ) { //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 << replaceWrapChar( f.attributes()[idx] ); } else { // Lets assume it's an expression QgsExpression* expression = new QgsExpression(( *columnIt )->attribute() ); context->lastScope()->setVariable( QString( "_rownum_" ), counter + 1 ); expression->prepare( context.data() ); QVariant value = expression->evaluate( context.data() ); 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; }