void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent canvasExtent ) { if ( !mCanvas ) return; if ( !f.isValid() ) { f = referencedFeature(); if ( !f.isValid() ) return; } if ( !f.hasGeometry() ) { return; } QgsGeometry geom = f.geometry(); // scale or pan if ( canvasExtent == Scale ) { QgsRectangle featBBox = geom.boundingBox(); featBBox = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, featBBox ); QgsRectangle extent = mCanvas->extent(); if ( !extent.contains( featBBox ) ) { extent.combineExtentWith( featBBox ); extent.scale( 1.1 ); mCanvas->setExtent( extent ); mCanvas->refresh(); } } else if ( canvasExtent == Pan ) { QgsGeometry centroid = geom.centroid(); QgsPointXY center = centroid.asPoint(); center = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, center ); mCanvas->zoomByFactor( 1.0, ¢er ); // refresh is done in this method } // highlight deleteHighlight(); mHighlight = new QgsHighlight( mCanvas, f, mReferencedLayer ); QgsIdentifyMenu::styleHighlight( mHighlight ); mHighlight->show(); QTimer *timer = new QTimer( this ); timer->setSingleShot( true ); connect( timer, &QTimer::timeout, this, &QgsRelationReferenceWidget::deleteHighlight ); timer->start( 3000 ); }
QgsVectorLayer *QgsAuxiliaryLayer::toSpatialLayer() const { QgsVectorLayer *layer = QgsMemoryProviderUtils::createMemoryLayer( QStringLiteral( "auxiliary_layer" ), fields(), mLayer->wkbType(), mLayer->crs() ); QString pkField = mJoinInfo.targetFieldName(); QgsFeature joinFeature; QgsFeature targetFeature; QgsFeatureIterator it = getFeatures(); layer->startEditing(); while ( it.nextFeature( joinFeature ) ) { QString filter = QgsExpression::createFieldEqualityExpression( pkField, joinFeature.attribute( AS_JOINFIELD ) ); QgsFeatureRequest request; request.setFilterExpression( filter ); mLayer->getFeatures( request ).nextFeature( targetFeature ); if ( targetFeature.isValid() ) { QgsFeature newFeature( joinFeature ); newFeature.setGeometry( targetFeature.geometry() ); layer->addFeature( newFeature ); } } layer->commitChanges(); return layer; }
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 QgsRelationReferenceWidget::setForeignKey( const QVariant& value ) { if ( !value.isValid() || value.isNull() ) { deleteForeignKey(); return; } QgsFeature f; if ( !mReferencedLayer ) return; // TODO: Rewrite using expression QgsFeatureIterator fit = mReferencedLayer->getFeatures( QgsFeatureRequest() ); while ( fit.nextFeature( f ) ) { if ( f.attribute( mFkeyFieldIdx ) == value ) { break; } } if ( !f.isValid() ) { deleteForeignKey(); return; } mForeignKey = f.attribute( mFkeyFieldIdx ); if ( mReadOnlySelector ) { QgsExpression expr( mReferencedLayer->displayExpression() ); QString title = expr.evaluate( &f ).toString(); if ( expr.hasEvalError() ) { title = f.attribute( mFkeyFieldIdx ).toString(); } mLineEdit->setText( title ); mFeatureId = f.id(); } else { int i = mComboBox->findData( value ); if ( i == -1 && mAllowNull ) { mComboBox->setCurrentIndex( 0 ); } else { mComboBox->setCurrentIndex( i ); } } mRemoveFKButton->setEnabled( mIsEditable ); highlightFeature( f ); updateAttributeEditorFrame( f ); emit foreignKeyChanged( foreignKey() ); }
void QgsRelationReferenceWidget::updateAttributeEditorFrame( const QgsFeature &feature ) { mOpenFormButton->setEnabled( feature.isValid() ); // Check if we're running with an embedded frame we need to update if ( mAttributeEditorFrame && mReferencedAttributeForm ) { mReferencedAttributeForm->setFeature( feature ); } }
void QgsRelationReferenceWidget::openForm() { QgsFeature feat = referencedFeature(); if ( !feat.isValid() ) return; QgsAttributeEditorContext context( mEditorContext, mRelation, QgsAttributeEditorContext::Single, QgsAttributeEditorContext::StandaloneDialog ); QgsAttributeDialog attributeDialog( mReferencedLayer, new QgsFeature( feat ), true, this, true, context ); attributeDialog.exec(); }
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature ) { if ( !feature.isValid() ) return false; const QgsGeometry *geom = feature.constGeometry(); if ( !geom || geom->isGeosEmpty() ) return false; return true; } // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature ) { if ( !feature.isValid() ) return false; QgsGeometry geom = feature.geometry(); if ( geom.isNull() || geom.isEmpty() ) return false; return true; } // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
void QgsHtmlAnnotation::setAssociatedFeature( const QgsFeature &feature ) { QgsAnnotation::setAssociatedFeature( feature ); QString newText; QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( mapLayer() ); if ( feature.isValid() && vectorLayer ) { QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( vectorLayer ) ); context.setFeature( feature ); newText = QgsExpression::replaceExpressionText( mHtmlSource, &context ); } else { newText = mHtmlSource; } mWebPage->mainFrame()->setHtml( newText ); emit appearanceChanged(); }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString& string, const QgsFields& fields, QTextCodec* encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QString( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( TO8( randomFileName ), reinterpret_cast< GByte* >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); OGRDataSourceH hDS = OGROpen( TO8( randomFileName ), false, nullptr ); if ( !hDS ) { VSIUnlink( TO8( randomFileName ) ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS, 0 ); if ( !ogrLayer ) { OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; } OGRFeatureH oFeat; while (( oFeat = OGR_L_GetNextFeature( ogrLayer ) ) ) { QgsFeature feat = readOgrFeature( oFeat, fields, encoding ); if ( feat.isValid() ) features << feat; OGR_F_Destroy( oFeat ); } OGR_DS_Destroy( hDS ); VSIUnlink( TO8( randomFileName ) ); return features; }
QgsFeatureList QgsOgrUtils::stringToFeatureList( const QString &string, const QgsFields &fields, QTextCodec *encoding ) { QgsFeatureList features; if ( string.isEmpty() ) return features; QString randomFileName = QStringLiteral( "/vsimem/%1" ).arg( QUuid::createUuid().toString() ); // create memory file system object from string buffer QByteArray ba = string.toUtf8(); VSIFCloseL( VSIFileFromMemBuffer( randomFileName.toUtf8().constData(), reinterpret_cast< GByte * >( ba.data() ), static_cast< vsi_l_offset >( ba.size() ), FALSE ) ); gdal::ogr_datasource_unique_ptr hDS( OGROpen( randomFileName.toUtf8().constData(), false, nullptr ) ); if ( !hDS ) { VSIUnlink( randomFileName.toUtf8().constData() ); return features; } OGRLayerH ogrLayer = OGR_DS_GetLayer( hDS.get(), 0 ); if ( !ogrLayer ) { hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; } gdal::ogr_feature_unique_ptr oFeat; while ( oFeat.reset( OGR_L_GetNextFeature( ogrLayer ) ), oFeat ) { QgsFeature feat = readOgrFeature( oFeat.get(), fields, encoding ); if ( feat.isValid() ) features << feat; } hDS.reset(); VSIUnlink( randomFileName.toUtf8().constData() ); return features; }
bool QgsSpatialQuery::hasValidGeometry( QgsFeature &feature ) { if ( ! feature.isValid() ) { return false; } const QgsGeometry *geom = feature.constGeometry(); if ( NULL == geom ) { return false; } if ( geom->isGeosEmpty() ) { return false; } return true; } // bool QgsSpatialQuery::hasValidGeometry(QgsFeature &feature)
void QgsEditorWidgetWrapper::updateConstraint( const QgsVectorLayer *layer, int index, const QgsFeature &ft, QgsFieldConstraints::ConstraintOrigin constraintOrigin ) { QStringList errors; QStringList softErrors; QStringList expressions; QStringList descriptions; bool toEmit( false ); bool hardConstraintsOk( true ); bool softConstraintsOk( true ); QgsField field = layer->fields().at( index ); QString expression = field.constraints().constraintExpression(); if ( ft.isValid() ) { if ( ! expression.isEmpty() ) { expressions << expression; descriptions << field.constraints().constraintDescription(); toEmit = true; } if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintNotNull ) { descriptions << tr( "Not NULL" ); if ( !expression.isEmpty() ) { expressions << field.name() + QStringLiteral( " IS NOT NULL" ); } else { expressions << QStringLiteral( "IS NOT NULL" ); } toEmit = true; } if ( field.constraints().constraints() & QgsFieldConstraints::ConstraintUnique ) { descriptions << tr( "Unique" ); if ( !expression.isEmpty() ) { expressions << field.name() + QStringLiteral( " IS UNIQUE" ); } else { expressions << QStringLiteral( "IS UNIQUE" ); } toEmit = true; } hardConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, errors, QgsFieldConstraints::ConstraintStrengthHard, constraintOrigin ); softConstraintsOk = QgsVectorLayerUtils::validateAttribute( layer, ft, index, softErrors, QgsFieldConstraints::ConstraintStrengthSoft, constraintOrigin ); errors << softErrors; } else // invalid feature { if ( ! expression.isEmpty() ) { hardConstraintsOk = true; softConstraintsOk = false; errors << QStringLiteral( "Invalid feature" ); toEmit = true; } } mValidConstraint = hardConstraintsOk && softConstraintsOk; mIsBlockingCommit = !hardConstraintsOk; mConstraintFailureReason = errors.join( QStringLiteral( ", " ) ); if ( toEmit ) { QString errStr = errors.isEmpty() ? tr( "Constraint checks passed" ) : mConstraintFailureReason; QString description = descriptions.join( QStringLiteral( ", " ) ); QString expressionDesc; if ( expressions.size() > 1 ) expressionDesc = "( " + expressions.join( QStringLiteral( " ) AND ( " ) ) + " )"; else if ( !expressions.isEmpty() ) expressionDesc = expressions.at( 0 ); ConstraintResult result = !hardConstraintsOk ? ConstraintResultFailHard : ( !softConstraintsOk ? ConstraintResultFailSoft : ConstraintResultPass ); //set the constraint result mConstraintResult = result; updateConstraintWidgetStatus(); emit constraintStatusChanged( expressionDesc, description, errStr, result ); } }
QVariant QgsProperty::propertyValue( const QgsExpressionContext &context, const QVariant &defaultValue, bool *ok ) const { if ( ok ) *ok = false; if ( !d->active ) return defaultValue; switch ( d->type ) { case StaticProperty: { if ( ok ) *ok = true; return d->staticValue; } case FieldBasedProperty: { QgsFeature f = context.feature(); if ( !f.isValid() ) return defaultValue; //shortcut the field lookup if ( d->cachedFieldIdx >= 0 ) { if ( ok ) *ok = true; return f.attribute( d->cachedFieldIdx ); } int fieldIdx = f.fieldNameIndex( d->fieldName ); if ( fieldIdx < 0 ) return defaultValue; if ( ok ) *ok = true; return f.attribute( fieldIdx ); } case ExpressionBasedProperty: { d.detach(); if ( !d->expressionPrepared && !prepare( context ) ) return defaultValue; QVariant result = d->expression.evaluate( &context ); if ( result.isValid() ) { if ( ok ) *ok = true; return result; } else { return defaultValue; } } case InvalidProperty: return defaultValue; }; return QVariant(); }