void QgsRelationEditorWidget::addFeature() { QgsAttributeMap keyAttrs; const QgsVectorLayerTools* vlTools = mEditorContext.vectorLayerTools(); if ( mNmRelation.isValid() ) { // n:m Relation: first let the user create a new feature on the other table // and autocreate a new linking feature. QgsFeature f; if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) ) { QgsFeature flink( mRelation.referencingLayer()->fields() ); // Linking feature flink.setAttribute( mRelation.fieldPairs().at( 0 ).first, mFeature.attribute( mRelation.fieldPairs().at( 0 ).second ) ); flink.setAttribute( mNmRelation.referencingFields().at( 0 ), f.attribute( mNmRelation.referencedFields().at( 0 ) ) ); mRelation.referencingLayer()->addFeature( flink ); updateUi(); } } else { QgsFields fields = mRelation.referencingLayer()->fields(); Q_FOREACH ( const QgsRelation::FieldPair& fieldPair, mRelation.fieldPairs() ) { keyAttrs.insert( fields.indexFromName( fieldPair.referencingField() ), mFeature.attribute( fieldPair.referencedField() ) ); } vlTools->addFeature( mDualView->masterModel()->layer(), keyAttrs ); } }
QString QgsWFSServer::createFeatureGeoJSON( QgsFeature* feat, QgsCoordinateReferenceSystem &, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/ { QString fStr = "{\"type\": \"Feature\",\n"; fStr += " \"id\": "; fStr += QString::number( feat->id() ); fStr += ",\n"; QgsGeometry* geom = feat->geometry(); if ( geom && mWithGeom ) { QgsRectangle box = geom->boundingBox(); fStr += " \"bbox\": [ " + QString::number( box.xMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.yMinimum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.xMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + ", " + QString::number( box.yMaximum(), 'f', 6 ).remove( QRegExp( "[0]{1,5}$" ) ) + "],\n"; fStr += " \"geometry\": "; fStr += geom->exportToGeoJSON(); fStr += ",\n"; } //read all attribute values from the feature fStr += " \"properties\": {\n"; QgsAttributeMap featureAttributes = feat->attributeMap(); int attributeCounter = 0; for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it ) { QString attributeName = fields[it.key()].name(); //skip attribute if it has edit type 'hidden' if ( hiddenAttributes.contains( attributeName ) ) { continue; } if ( attributeCounter == 0 ) fStr += " \""; else fStr += " ,\""; fStr += attributeName; fStr += "\": "; if ( it->type() == 6 || it->type() == 2 ) { fStr += it->toString(); } else { fStr += "\""; fStr += it->toString().replace( QString( "\"" ), QString( "\\\"" ) ); fStr += "\""; } fStr += "\n"; ++attributeCounter; } fStr += " }\n"; fStr += " }"; return fStr; }
void QgsGrassEdit::addAttributes( int field, int cat ) { QString *key = mProvider->key( field ); QString lab; lab.sprintf( "%d:%d", field, cat ); int tab = mAttributes->addTab( lab ); mAttributes->setField( tab, field ); QString catLabel; if ( key->isEmpty() ) { catLabel = "Category"; } else { catLabel = *key; } mAttributes->setCat( tab, catLabel, cat ); if ( !key->isEmpty() ) // Database link defined { QVector<QgsField> *cols = mProvider->columns( field ); if ( cols->size() == 0 ) { QString str; str.setNum( field ); QMessageBox::warning( 0, tr( "Warning" ), tr( "Cannot describe table for field %1" ).arg( str ) ); } else { QgsAttributeMap *atts = mProvider->attributes( field, cat ); if ( atts->size() == 0 ) // cannot select attributes { mAttributes->addTextRow( tab, "WARNING: ATTRIBUTES MISSING" ); } else { for ( int j = 0; j < cols->size(); j++ ) { QgsField col = ( *cols )[j]; QVariant att = ( *atts )[j]; QgsDebugMsg( QString( " name = %1" ).arg( col.name() ) ); if ( col.name() != *key ) { QgsDebugMsg( QString( " value = %1" ).arg( att.toString() ) ); mAttributes->addAttribute( tab, col.name(), att.toString(), col.typeName() ); } } } delete atts; } delete cols; } }
QString QgsActionManager::expandAction( QString action, const QgsAttributeMap &attributes, uint clickedOnValue ) { // This function currently replaces all %% characters in the action // with the value from values[clickedOnValue].second, and then // searches for all strings that go %attribute_name, where // attribute_name is found in values[x].first, and replaces any that // it finds by values[s].second. // Additional substitutions could include symbols for $CWD, $HOME, // etc (and their OSX and Windows equivalents) // This function will potentially fall apart if any of the // substitutions produce text that could match another // substitution. May be better to adopt a two pass approach - identify // all matches and their substitutions and then do a second pass // for the actual substitutions. QString expanded_action; if ( attributes.contains( clickedOnValue ) ) expanded_action = action.replace( "%%", attributes[clickedOnValue].toString() ); else expanded_action = action; const QgsFields &fields = mLayer->fields(); for ( int i = 0; i < 4; i++ ) { for ( QgsAttributeMap::const_iterator it = attributes.begin(); it != attributes.end(); ++it ) { int attrIdx = it.key(); if ( attrIdx < 0 || attrIdx >= fields.count() ) continue; QString to_replace; switch ( i ) { case 0: to_replace = "[%" + fields[attrIdx].name() + ']'; break; case 1: to_replace = "[%" + mLayer->attributeDisplayName( attrIdx ) + ']'; break; case 2: to_replace = '%' + fields[attrIdx].name(); break; case 3: to_replace = '%' + mLayer->attributeDisplayName( attrIdx ); break; } expanded_action = expanded_action.replace( to_replace, it.value().toString() ); } } return expanded_action; }
QDomElement QgsWFSServer::createFeatureElem( QgsFeature* feat, QDomDocument& doc, QgsCoordinateReferenceSystem& crs, QMap< int, QgsField > fields, QSet<QString> hiddenAttributes ) /*const*/ { //gml:FeatureMember QDomElement featureElement = doc.createElement( "gml:featureMember"/*wfs:FeatureMember*/ ); //qgs:%TYPENAME% QDomElement typeNameElement = doc.createElement( "qgs:" + mTypeName.replace( QString( " " ), QString( "_" ) )/*qgs:%TYPENAME%*/ ); typeNameElement.setAttribute( "fid", QString::number( feat->id() ) ); featureElement.appendChild( typeNameElement ); if ( mWithGeom ) { //add geometry column (as gml) QgsGeometry* geom = feat->geometry(); QDomElement geomElem = doc.createElement( "qgs:geometry" ); QDomElement gmlElem = createGeometryElem( geom, doc ); if ( !gmlElem.isNull() ) { QgsRectangle box = geom->boundingBox(); QDomElement bbElem = doc.createElement( "gml:boundedBy" ); QDomElement boxElem = createBoxElem( &box, doc ); if ( crs.isValid() ) { boxElem.setAttribute( "srsName", crs.authid() ); gmlElem.setAttribute( "srsName", crs.authid() ); } bbElem.appendChild( boxElem ); typeNameElement.appendChild( bbElem ); geomElem.appendChild( gmlElem ); typeNameElement.appendChild( geomElem ); } } //read all attribute values from the feature QgsAttributeMap featureAttributes = feat->attributeMap(); for ( QgsAttributeMap::const_iterator it = featureAttributes.begin(); it != featureAttributes.end(); ++it ) { QString attributeName = fields[it.key()].name(); //skip attribute if it has edit type 'hidden' if ( hiddenAttributes.contains( attributeName ) ) { continue; } QDomElement fieldElem = doc.createElement( "qgs:" + attributeName.replace( QString( " " ), QString( "_" ) ) ); QDomText fieldText = doc.createTextNode( it->toString() ); fieldElem.appendChild( fieldText ); typeNameElement.appendChild( fieldElem ); } return featureElement; }
QVariant QgsFilter::propertyIndexValue( const QgsFeature& f ) const { QgsAttributeMap featureAttributes = f.attributeMap(); QgsAttributeMap::const_iterator f_it = featureAttributes.find( mPropertyIndex ); if ( f_it == featureAttributes.constEnd() ) { return QVariant(); } return f_it.value(); }
void QgsVectorLayerEditBuffer::updateAttributeMapIndex( QgsAttributeMap& map, int index, int offset ) const { QgsAttributeMap updatedMap; for ( QgsAttributeMap::const_iterator it = map.begin(); it != map.end(); ++it ) { int attrIndex = it.key(); updatedMap.insert( attrIndex < index ? attrIndex : attrIndex + offset, it.value() ); } map = updatedMap; }
QgsAttributeMap QgsAttributes::toMap() const { QgsAttributeMap map; for ( int idx = 0; idx < count(); ++idx ) { QVariant v = at( idx ); if ( v.isValid() ) map.insert( idx, v ); } return map; }
void QgsGPXProvider::changeAttributeValues( QgsGPSObject& obj, const QgsAttributeMap& attrs ) { QgsWaypoint* wpt = dynamic_cast<QgsWaypoint*>( &obj ); QgsGPSExtended* ext = dynamic_cast<QgsGPSExtended*>( &obj ); QgsAttributeMap::const_iterator aIter = attrs.begin(); for ( ; aIter != attrs.end(); ++aIter ) { int i = aIter.key(); QVariant v = aIter.value(); // common attributes switch ( indexToAttr[i] ) { case NameAttr: obj.name = v.toString(); break; case CmtAttr: obj.cmt = v.toString(); break; case DscAttr: obj.desc = v.toString(); break; case SrcAttr: obj.src = v.toString(); break; case URLAttr: obj.url = v.toString(); break; case URLNameAttr: obj.urlname = v.toString(); break; } // waypoint-specific attributes if ( wpt != NULL ) { if ( indexToAttr[i] == SymAttr ) wpt->sym = v.toString(); else if ( indexToAttr[i] == EleAttr ) { bool eleIsOK; double ele = v.toDouble( &eleIsOK ); if ( eleIsOK ) wpt->ele = ele; } } // route- and track-specific attributes if ( ext != NULL ) { if ( indexToAttr[i] == NumAttr ) { bool numIsOK; int num = v.toInt( &numIsOK ); if ( numIsOK ) ext->number = num; } } } }
void QgsOverlayAnalyzer::combineAttributeMaps( QgsAttributeMap& attributeMapA, QgsAttributeMap attributeMapB ) { QMap<int, QVariant>::const_iterator i = attributeMapB.constBegin(); QVariant attribute; int fcount = attributeMapA.size(); while ( i != attributeMapB.constEnd() ) { attribute = i.value(); attributeMapA.insert( fcount, attribute ); ++i; ++fcount; } }
QString QgsPointDisplacementRenderer::getLabel( const QgsFeature& f ) { QString attribute; QgsAttributeMap attMap = f.attributeMap(); if ( attMap.size() > 0 ) { QgsAttributeMap::const_iterator valIt = attMap.find( mLabelIndex ); if ( valIt != attMap.constEnd() ) { attribute = valIt->toString(); } } return attribute; }
QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c ) { Q_UNUSED( c ); QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute ); if ( attIt == attributes.constEnd() ) { return QSizeF(); //zero size if attribute is missing } double value = attIt.value().toDouble(); //interpolate size double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue ); return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ), mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) ); }
bool QgsVectorLayerEditBuffer::changeAttributeValues( QgsFeatureId fid, const QgsAttributeMap &newValues, const QgsAttributeMap &oldValues ) { bool success = true; for ( auto it = newValues.constBegin() ; it != newValues.constEnd(); ++it ) { const int field = it.key(); const QVariant newValue = it.value(); QVariant oldValue; if ( oldValues.contains( field ) ) oldValue = oldValues[field]; success &= changeAttributeValue( fid, field, newValue, oldValue ); } return success; }
bool QgsComposerTextTable::getFeatureAttributes( QList<QgsAttributeMap>& attributes ) { attributes.clear(); QList< QStringList >::const_iterator rowIt = mRowText.constBegin(); QStringList currentStringList; for ( ; rowIt != mRowText.constEnd(); ++rowIt ) { currentStringList = *rowIt; QgsAttributeMap map; for ( int i = 0; i < currentStringList.size(); ++i ) { map.insert( i, QVariant( currentStringList.at( i ) ) ); } attributes.append( map ); } return true; }
QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is ) { Q_UNUSED( c ); QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute ); if ( attIt == attributes.constEnd() ) { return QSizeF(); //zero size if attribute is missing } double scaledValue = attIt.value().toDouble(); double scaledLowerValue = is.lowerValue; double scaledUpperValue = is.upperValue; double scaledLowerSizeWidth = is.lowerSize.width(); double scaledLowerSizeHeight = is.lowerSize.height(); double scaledUpperSizeWidth = is.upperSize.width(); double scaledUpperSizeHeight = is.upperSize.height(); // interpolate the squared value if scale by area if ( s.scaleByArea ) { scaledValue = sqrt( scaledValue ); scaledLowerValue = sqrt( scaledLowerValue ); scaledUpperValue = sqrt( scaledUpperValue ); scaledLowerSizeWidth = sqrt( scaledLowerSizeWidth ); scaledLowerSizeHeight = sqrt( scaledLowerSizeHeight ); scaledUpperSizeWidth = sqrt( scaledUpperSizeWidth ); scaledUpperSizeHeight = sqrt( scaledUpperSizeHeight ); } //interpolate size double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue ); QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ), is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) ); // Scale, if extension is smaller than the specified minimum if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize ) { size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio ); } return size; }
bool QgsFeatureAction::editFeature() { bool res = false; if ( !mLayer ) return res; QgsAttributeDialog *dialog = newDialog( false ); if ( !mLayer->isEditable() ) { res = dialog->exec(); } else { QgsAttributeMap src = mFeature.attributeMap(); if ( dialog->exec() ) { mLayer->beginEditCommand( text() ); const QgsAttributeMap &dst = mFeature.attributeMap(); for ( QgsAttributeMap::const_iterator it = dst.begin(); it != dst.end(); it++ ) { if ( !src.contains( it.key() ) || it.value() != src[it.key()] ) { mLayer->changeAttributeValue( mFeature.id(), it.key(), it.value() ); } } mLayer->endEditCommand(); res = true; } else { res = false; } } delete dialog; return res; }
void QgsGrassEdit::addCat( int line ) { int mode = mCatModeBox->currentIndex(); int field = mFieldBox->currentText().toInt(); int cat = mCatEntry->text().toInt(); int type = mProvider->readLine( mPoints, mCats, line ); if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL ) { Vect_cat_set( mCats, field, cat ); } line = mProvider->rewriteLine( line, type, mPoints, mCats ); mSelectedLine = line; if ( mAttributes ) mAttributes->setLine( line ); updateSymb(); increaseMaxCat(); // Insert new DB record if link is defined and the record for this cat does not exist QString *key = mProvider->key( field ); if ( !key->isEmpty() ) // Database link defined { QgsAttributeMap *atts = mProvider->attributes( field, cat ); if ( atts->size() == 0 ) // Nothing selected { QString *error = mProvider->insertAttributes( field, cat ); if ( !error->isEmpty() ) { QMessageBox::warning( 0, tr( "Warning" ), *error ); } delete error; } delete atts; } addAttributes( field, cat ); }
int QgsDiagramRenderer::classificationValue( const QgsFeature& f, QVariant& value ) const { //find out attribute value of the feature QgsAttributeMap featureAttributes = f.attributeMap(); QgsAttributeMap::const_iterator iter; if ( value.type() == QVariant::String ) //string type { //we can only handle one classification field for strings if ( mClassificationAttributes.size() > 1 ) { return 1; } iter = featureAttributes.find( mClassificationAttributes.first() ); if ( iter == featureAttributes.constEnd() ) { return 2; } value = iter.value(); } else //numeric type { double currentValue; double totalValue = 0; QList<int>::const_iterator list_it = mClassificationAttributes.constBegin(); for ( ; list_it != mClassificationAttributes.constEnd(); ++list_it ) { QgsAttributeMap::const_iterator iter = featureAttributes.find( *list_it ); if ( iter == featureAttributes.constEnd() ) { continue; } currentValue = iter.value().toDouble(); totalValue += currentValue; } value = QVariant( totalValue ); } return 0; }
void QgsMapToolChangeLabelProperties::applyChanges( const QgsAttributeMap& changes ) { QgsVectorLayer* vlayer = mCurrentLabel.layer; if ( !vlayer ) return; if ( !changes.isEmpty() ) { vlayer->beginEditCommand( tr( "Changed properties for label" ) + QStringLiteral( " '%1'" ).arg( currentLabelText( 24 ) ) ); QgsAttributeMap::const_iterator changeIt = changes.constBegin(); for ( ; changeIt != changes.constEnd(); ++changeIt ) { vlayer->changeAttributeValue( mCurrentLabel.pos.featureId, changeIt.key(), changeIt.value() ); } vlayer->endEditCommand(); vlayer->triggerRepaint(); } }
void QgsGPXProvider::changeAttributeValues( QgsGPSObject& obj, const QgsAttributeMap& attrs ) { QgsAttributeMap::const_iterator aIter; // TODO: if ( attrs.contains( NameAttr ) ) obj.name = attrs[NameAttr].toString(); if ( attrs.contains( CmtAttr ) ) obj.cmt = attrs[CmtAttr].toString(); if ( attrs.contains( DscAttr ) ) obj.desc = attrs[DscAttr].toString(); if ( attrs.contains( SrcAttr ) ) obj.src = attrs[SrcAttr].toString(); if ( attrs.contains( URLAttr ) ) obj.url = attrs[URLAttr].toString(); if ( attrs.contains( URLNameAttr ) ) obj.urlname = attrs[URLNameAttr].toString(); // waypoint-specific attributes QgsWaypoint* wpt = dynamic_cast<QgsWaypoint*>( &obj ); if ( wpt != NULL ) { if ( attrs.contains( SymAttr ) ) wpt->sym = attrs[SymAttr].toString(); if ( attrs.contains( EleAttr ) ) { bool eleIsOK; double ele = attrs[EleAttr].toDouble( &eleIsOK ); if ( eleIsOK ) wpt->ele = ele; } } // route- and track-specific attributes QgsGPSExtended* ext = dynamic_cast<QgsGPSExtended*>( &obj ); if ( ext != NULL ) { if ( attrs.contains( NumAttr ) ) { bool eleIsOK; double ele = attrs[NumAttr].toDouble( &eleIsOK ); if ( eleIsOK ) wpt->ele = ele; } } }
QgsAttributeMap QgsMergeAttributesDialog::mergedAttributesMap() const { if ( mFeatureList.size() < 1 ) { return QgsAttributeMap(); } QgsAttributeMap resultMap; for ( int i = 0; i < mTableWidget->columnCount(); i++ ) { int idx = mTableWidget->horizontalHeaderItem( i )->data( Qt::UserRole ).toInt(); QTableWidgetItem* currentItem = mTableWidget->item( mFeatureList.size() + 1, i ); if ( !currentItem ) continue; resultMap.insert( idx, currentItem->text() ); } return resultMap; }
void QgsFeaturePool::updateFeature( QgsFeature& feature ) { QgsGeometryMap geometryMap; geometryMap.insert( feature.id(), QgsGeometry( feature.geometry()->geometry()->clone() ) ); QgsChangedAttributesMap changedAttributesMap; QgsAttributeMap attribMap; for ( int i = 0, n = feature.attributes().size(); i < n; ++i ) { attribMap.insert( i, feature.attributes().at( i ) ); } changedAttributesMap.insert( feature.id(), attribMap ); mLayerMutex.lock(); mFeatureCache.remove( feature.id() ); // Remove to force reload on next get() mLayer->dataProvider()->changeGeometryValues( geometryMap ); mLayer->dataProvider()->changeAttributeValues( changedAttributesMap ); mLayerMutex.unlock(); mIndexMutex.lock(); mIndex.deleteFeature( feature ); mIndex.insertFeature( feature ); mIndexMutex.unlock(); }
void QgsOfflineEditing::applyFeaturesAdded( QgsVectorLayer* offlineLayer, QgsVectorLayer* remoteLayer, sqlite3* db, int layerId ) { QString sql = QString( "SELECT \"fid\" FROM 'log_added_features' WHERE \"layer_id\" = %1" ).arg( layerId ); QList<int> newFeatureIds = sqlQueryInts( db, sql ); // get new features from offline layer QgsFeatureList features; for ( int i = 0; i < newFeatureIds.size(); i++ ) { QgsFeature feature; if ( offlineLayer->featureAtId( newFeatureIds.at( i ), feature, true, true ) ) { features << feature; } } // copy features to remote layer mProgressDialog->setupProgressBar( tr( "%v / %m features added" ), features.size() ); int i = 1; for ( QgsFeatureList::iterator it = features.begin(); it != features.end(); ++it ) { QgsFeature f = *it; // NOTE: Spatialite provider ignores position of geometry column // restore gap in QgsAttributeMap if geometry column is not last (WORKAROUND) QMap<int, int> attrLookup = attributeLookup( offlineLayer, remoteLayer ); QgsAttributeMap newAttrMap; QgsAttributeMap attrMap = f.attributeMap(); for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it ) { newAttrMap.insert( attrLookup[ it.key()], it.value() ); } f.setAttributeMap( newAttrMap ); remoteLayer->addFeature( f, false ); mProgressDialog->setProgressValue( i++ ); } }
void QgsRelationReferenceWidget::addEntry() { QgsFeature f( mReferencedLayer->fields() ); QgsAttributeMap attributes; // if custom text is in the combobox and the displayExpression is simply a field, use the current text for the new feature if ( mComboBox->itemText( mComboBox->currentIndex() ) != mComboBox->currentText() ) { int fieldIdx = mReferencedLayer->fields().lookupField( mReferencedLayer->displayExpression() ); if ( fieldIdx != -1 ) { attributes.insert( fieldIdx, mComboBox->currentText() ); } } if ( mEditorContext.vectorLayerTools()->addFeature( mReferencedLayer, attributes, QgsGeometry(), &f ) ) { mComboBox->setIdentifierValue( f.attribute( mReferencingFieldIdx ) ); mAddEntryButton->setEnabled( false ); } }
int QgsGrassEdit::writeLine( int type, struct line_pnts *Points ) { int mode = mCatModeBox->currentIndex(); int field = mFieldBox->currentText().toInt(); int cat = mCatEntry->text().toInt(); Vect_reset_cats( mCats ); if ( mode == CAT_MODE_NEXT || mode == CAT_MODE_MANUAL ) { Vect_cat_set( mCats, field, cat ); // Insert new DB record if link is defined and the record for this cat does not exist QString *key = mProvider->key( field ); if ( !key->isEmpty() ) // Database link defined { QgsAttributeMap *atts = mProvider->attributes( field, cat ); if ( atts->count() == 0 ) // Nothing selected { QString *error = mProvider->insertAttributes( field, cat ); if ( !error->isEmpty() ) { QMessageBox::warning( 0, tr( "Warning" ), *error ); } delete error; } delete atts; } } Vect_line_prune( Points ); int line = mProvider->writeLine( type, Points, mCats ); increaseMaxCat(); return line; }
void QgsRelationEditorWidget::addFeature() { QgsAttributeMap keyAttrs; const QgsVectorLayerTools *vlTools = mEditorContext.vectorLayerTools(); if ( mNmRelation.isValid() ) { // n:m Relation: first let the user create a new feature on the other table // and autocreate a new linking feature. QgsFeature f; if ( vlTools->addFeature( mNmRelation.referencedLayer(), QgsAttributeMap(), QgsGeometry(), &f ) ) { // Fields of the linking table const QgsFields fields = mRelation.referencingLayer()->fields(); // Expression context for the linking table QgsExpressionContext context = mRelation.referencingLayer()->createExpressionContext(); QgsAttributeMap linkAttributes; Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mRelation.fieldPairs() ) { int index = fields.indexOf( fieldPair.first ); linkAttributes.insert( index, mFeature.attribute( fieldPair.second ) ); } Q_FOREACH ( const QgsRelation::FieldPair &fieldPair, mNmRelation.fieldPairs() ) { int index = fields.indexOf( fieldPair.first ); linkAttributes.insert( index, f.attribute( fieldPair.second ) ); } QgsFeature linkFeature = QgsVectorLayerUtils::createFeature( mRelation.referencingLayer(), QgsGeometry(), linkAttributes, &context ); mRelation.referencingLayer()->addFeature( linkFeature ); updateUi(); } }
/*! \fn OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr) */ bool OptVectorLayer:: changeAttribute(QgsFeature& feature, int field, QVariant attr) { if ( !isEditable() ) { startEditing(); } if ( isModified() ) { commitChanges(); } QgsChangedAttributesMap attributeChanges; QgsAttributeMap newAttMap; newAttMap.insert(field, attr ); attributeChanges.insert(feature.id(), newAttMap); //{zhangliye2715} ;api changed // commitAttributeChanges(QgsAttributeIds(), // QgsNewAttributesMap(), // attributeChanges); dataProvider()->changeAttributeValues(attributeChanges); //commit or rollBack the change if ( isModified() ) { commitChanges(); } else { rollBack(); return false; } //make the layer still editable for the next adding operation startEditing(); return true; }
void QgsOfflineEditing::committedAttributeValuesChanges( const QString& qgisLayerId, const QgsChangedAttributesMap& changedAttrsMap ) { sqlite3* db = openLoggingDb(); if ( db == NULL ) { return; } // insert log int layerId = getOrCreateLayerId( db, qgisLayerId ); int commitNo = getCommitNo( db ); for ( QgsChangedAttributesMap::const_iterator cit = changedAttrsMap.begin(); cit != changedAttrsMap.end(); ++cit ) { QgsFeatureId fid = cit.key(); if ( isAddedFeature( db, layerId, fid ) ) { // skip added features continue; } QgsAttributeMap attrMap = cit.value(); for ( QgsAttributeMap::const_iterator it = attrMap.begin(); it != attrMap.end(); ++it ) { QString sql = QString( "INSERT INTO 'log_feature_updates' VALUES ( %1, %2, %3, %4, '%5' )" ) .arg( layerId ) .arg( commitNo ) .arg( fid ) .arg( it.key() ) // attr .arg( it.value().toString() ); // value sqlExec( db, sql ); } } increaseCommitNo( db ); sqlite3_close( db ); }
int QgsZonalStatistics::calculateStatistics( QgsFeedback *feedback ) { if ( !mPolygonLayer || mPolygonLayer->geometryType() != QgsWkbTypes::PolygonGeometry ) { return 1; } QgsVectorDataProvider *vectorProvider = mPolygonLayer->dataProvider(); if ( !vectorProvider ) { return 2; } if ( !mRasterLayer ) { return 3; } if ( mRasterLayer->bandCount() < mRasterBand ) { return 4; } mRasterProvider = mRasterLayer->dataProvider(); mInputNodataValue = mRasterProvider->sourceNoDataValue( mRasterBand ); //get geometry info about raster layer int nCellsXProvider = mRasterProvider->xSize(); int nCellsYProvider = mRasterProvider->ySize(); double cellsizeX = mRasterLayer->rasterUnitsPerPixelX(); if ( cellsizeX < 0 ) { cellsizeX = -cellsizeX; } double cellsizeY = mRasterLayer->rasterUnitsPerPixelY(); if ( cellsizeY < 0 ) { cellsizeY = -cellsizeY; } QgsRectangle rasterBBox = mRasterProvider->extent(); //add the new fields to the provider QList<QgsField> newFieldList; QString countFieldName; if ( mStatistics & QgsZonalStatistics::Count ) { countFieldName = getUniqueFieldName( mAttributePrefix + "count", newFieldList ); QgsField countField( countFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( countField ); } QString sumFieldName; if ( mStatistics & QgsZonalStatistics::Sum ) { sumFieldName = getUniqueFieldName( mAttributePrefix + "sum", newFieldList ); QgsField sumField( sumFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( sumField ); } QString meanFieldName; if ( mStatistics & QgsZonalStatistics::Mean ) { meanFieldName = getUniqueFieldName( mAttributePrefix + "mean", newFieldList ); QgsField meanField( meanFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( meanField ); } QString medianFieldName; if ( mStatistics & QgsZonalStatistics::Median ) { medianFieldName = getUniqueFieldName( mAttributePrefix + "median", newFieldList ); QgsField medianField( medianFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( medianField ); } QString stdevFieldName; if ( mStatistics & QgsZonalStatistics::StDev ) { stdevFieldName = getUniqueFieldName( mAttributePrefix + "stdev", newFieldList ); QgsField stdField( stdevFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( stdField ); } QString minFieldName; if ( mStatistics & QgsZonalStatistics::Min ) { minFieldName = getUniqueFieldName( mAttributePrefix + "min", newFieldList ); QgsField minField( minFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minField ); } QString maxFieldName; if ( mStatistics & QgsZonalStatistics::Max ) { maxFieldName = getUniqueFieldName( mAttributePrefix + "max", newFieldList ); QgsField maxField( maxFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( maxField ); } QString rangeFieldName; if ( mStatistics & QgsZonalStatistics::Range ) { rangeFieldName = getUniqueFieldName( mAttributePrefix + "range", newFieldList ); QgsField rangeField( rangeFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( rangeField ); } QString minorityFieldName; if ( mStatistics & QgsZonalStatistics::Minority ) { minorityFieldName = getUniqueFieldName( mAttributePrefix + "minority", newFieldList ); QgsField minorityField( minorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( minorityField ); } QString majorityFieldName; if ( mStatistics & QgsZonalStatistics::Majority ) { majorityFieldName = getUniqueFieldName( mAttributePrefix + "majority", newFieldList ); QgsField majField( majorityFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( majField ); } QString varietyFieldName; if ( mStatistics & QgsZonalStatistics::Variety ) { varietyFieldName = getUniqueFieldName( mAttributePrefix + "variety", newFieldList ); QgsField varietyField( varietyFieldName, QVariant::Int, QStringLiteral( "int" ) ); newFieldList.push_back( varietyField ); } QString varianceFieldName; if ( mStatistics & QgsZonalStatistics::Variance ) { varianceFieldName = getUniqueFieldName( mAttributePrefix + "variance", newFieldList ); QgsField varianceField( varianceFieldName, QVariant::Double, QStringLiteral( "double precision" ) ); newFieldList.push_back( varianceField ); } vectorProvider->addAttributes( newFieldList ); //index of the new fields int countIndex = mStatistics & QgsZonalStatistics::Count ? vectorProvider->fieldNameIndex( countFieldName ) : -1; int sumIndex = mStatistics & QgsZonalStatistics::Sum ? vectorProvider->fieldNameIndex( sumFieldName ) : -1; int meanIndex = mStatistics & QgsZonalStatistics::Mean ? vectorProvider->fieldNameIndex( meanFieldName ) : -1; int medianIndex = mStatistics & QgsZonalStatistics::Median ? vectorProvider->fieldNameIndex( medianFieldName ) : -1; int stdevIndex = mStatistics & QgsZonalStatistics::StDev ? vectorProvider->fieldNameIndex( stdevFieldName ) : -1; int minIndex = mStatistics & QgsZonalStatistics::Min ? vectorProvider->fieldNameIndex( minFieldName ) : -1; int maxIndex = mStatistics & QgsZonalStatistics::Max ? vectorProvider->fieldNameIndex( maxFieldName ) : -1; int rangeIndex = mStatistics & QgsZonalStatistics::Range ? vectorProvider->fieldNameIndex( rangeFieldName ) : -1; int minorityIndex = mStatistics & QgsZonalStatistics::Minority ? vectorProvider->fieldNameIndex( minorityFieldName ) : -1; int majorityIndex = mStatistics & QgsZonalStatistics::Majority ? vectorProvider->fieldNameIndex( majorityFieldName ) : -1; int varietyIndex = mStatistics & QgsZonalStatistics::Variety ? vectorProvider->fieldNameIndex( varietyFieldName ) : -1; int varianceIndex = mStatistics & QgsZonalStatistics::Variance ? vectorProvider->fieldNameIndex( varianceFieldName ) : -1; if ( ( mStatistics & QgsZonalStatistics::Count && countIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Sum && sumIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Mean && meanIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Median && medianIndex == -1 ) || ( mStatistics & QgsZonalStatistics::StDev && stdevIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Min && minIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Max && maxIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Range && rangeIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Minority && minorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Majority && majorityIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variety && varietyIndex == -1 ) || ( mStatistics & QgsZonalStatistics::Variance && varianceIndex == -1 ) ) { //failed to create a required field return 8; } //progress dialog long featureCount = vectorProvider->featureCount(); //iterate over each polygon QgsFeatureRequest request; request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fi = vectorProvider->getFeatures( request ); QgsFeature f; bool statsStoreValues = ( mStatistics & QgsZonalStatistics::Median ) || ( mStatistics & QgsZonalStatistics::StDev ) || ( mStatistics & QgsZonalStatistics::Variance ); bool statsStoreValueCount = ( mStatistics & QgsZonalStatistics::Minority ) || ( mStatistics & QgsZonalStatistics::Majority ); FeatureStats featureStats( statsStoreValues, statsStoreValueCount ); int featureCounter = 0; QgsChangedAttributesMap changeMap; while ( fi.nextFeature( f ) ) { if ( feedback && feedback->isCanceled() ) { break; } if ( feedback ) { feedback->setProgress( 100.0 * static_cast< double >( featureCounter ) / featureCount ); } if ( !f.hasGeometry() ) { ++featureCounter; continue; } QgsGeometry featureGeometry = f.geometry(); QgsRectangle featureRect = featureGeometry.boundingBox().intersect( &rasterBBox ); if ( featureRect.isEmpty() ) { ++featureCounter; continue; } int offsetX, offsetY, nCellsX, nCellsY; if ( cellInfoForBBox( rasterBBox, featureRect, cellsizeX, cellsizeY, offsetX, offsetY, nCellsX, nCellsY ) != 0 ) { ++featureCounter; continue; } //avoid access to cells outside of the raster (may occur because of rounding) if ( ( offsetX + nCellsX ) > nCellsXProvider ) { nCellsX = nCellsXProvider - offsetX; } if ( ( offsetY + nCellsY ) > nCellsYProvider ) { nCellsY = nCellsYProvider - offsetY; } statisticsFromMiddlePointTest( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); if ( featureStats.count <= 1 ) { //the cell resolution is probably larger than the polygon area. We switch to precise pixel - polygon intersection in this case statisticsFromPreciseIntersection( featureGeometry, offsetX, offsetY, nCellsX, nCellsY, cellsizeX, cellsizeY, rasterBBox, featureStats ); } //write the statistics value to the vector data provider QgsAttributeMap changeAttributeMap; if ( mStatistics & QgsZonalStatistics::Count ) changeAttributeMap.insert( countIndex, QVariant( featureStats.count ) ); if ( mStatistics & QgsZonalStatistics::Sum ) changeAttributeMap.insert( sumIndex, QVariant( featureStats.sum ) ); if ( featureStats.count > 0 ) { double mean = featureStats.sum / featureStats.count; if ( mStatistics & QgsZonalStatistics::Mean ) changeAttributeMap.insert( meanIndex, QVariant( mean ) ); if ( mStatistics & QgsZonalStatistics::Median ) { std::sort( featureStats.values.begin(), featureStats.values.end() ); int size = featureStats.values.count(); bool even = ( size % 2 ) < 1; double medianValue; if ( even ) { medianValue = ( featureStats.values.at( size / 2 - 1 ) + featureStats.values.at( size / 2 ) ) / 2; } else //odd { medianValue = featureStats.values.at( ( size + 1 ) / 2 - 1 ); } changeAttributeMap.insert( medianIndex, QVariant( medianValue ) ); } if ( mStatistics & QgsZonalStatistics::StDev || mStatistics & QgsZonalStatistics::Variance ) { double sumSquared = 0; for ( int i = 0; i < featureStats.values.count(); ++i ) { double diff = featureStats.values.at( i ) - mean; sumSquared += diff * diff; } double variance = sumSquared / featureStats.values.count(); if ( mStatistics & QgsZonalStatistics::StDev ) { double stdev = std::pow( variance, 0.5 ); changeAttributeMap.insert( stdevIndex, QVariant( stdev ) ); } if ( mStatistics & QgsZonalStatistics::Variance ) changeAttributeMap.insert( varianceIndex, QVariant( variance ) ); } if ( mStatistics & QgsZonalStatistics::Min ) changeAttributeMap.insert( minIndex, QVariant( featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Max ) changeAttributeMap.insert( maxIndex, QVariant( featureStats.max ) ); if ( mStatistics & QgsZonalStatistics::Range ) changeAttributeMap.insert( rangeIndex, QVariant( featureStats.max - featureStats.min ) ); if ( mStatistics & QgsZonalStatistics::Minority || mStatistics & QgsZonalStatistics::Majority ) { QList<int> vals = featureStats.valueCount.values(); std::sort( vals.begin(), vals.end() ); if ( mStatistics & QgsZonalStatistics::Minority ) { float minorityKey = featureStats.valueCount.key( vals.first() ); changeAttributeMap.insert( minorityIndex, QVariant( minorityKey ) ); } if ( mStatistics & QgsZonalStatistics::Majority ) { float majKey = featureStats.valueCount.key( vals.last() ); changeAttributeMap.insert( majorityIndex, QVariant( majKey ) ); } } if ( mStatistics & QgsZonalStatistics::Variety ) changeAttributeMap.insert( varietyIndex, QVariant( featureStats.valueCount.count() ) ); } changeMap.insert( f.id(), changeAttributeMap ); ++featureCounter; } vectorProvider->changeAttributeValues( changeMap ); if ( feedback ) { feedback->setProgress( 100 ); } mPolygonLayer->updateFields(); if ( feedback && feedback->isCanceled() ) { return 9; } return 0; }
bool QgsFeatureAction::addFeature( const QgsAttributeMap& defaultAttributes ) { if ( !mLayer || !mLayer->isEditable() ) return false; QgsVectorDataProvider *provider = mLayer->dataProvider(); QSettings settings; bool reuseLastValues = settings.value( "/qgis/digitizing/reuseLastValues", false ).toBool(); QgsDebugMsg( QString( "reuseLastValues: %1" ).arg( reuseLastValues ) ); // add the fields to the QgsFeature const QgsFields& fields = mLayer->pendingFields(); mFeature.initAttributes( fields.count() ); for ( int idx = 0; idx < fields.count(); ++idx ) { if ( defaultAttributes.contains( idx ) ) { QgsDebugMsg( QString( "Using specified default %1 for %2" ).arg( defaultAttributes.value( idx ).toString() ).arg( idx ) ); mFeature.setAttribute( idx, defaultAttributes.value( idx ) ); } else if ( reuseLastValues && mLastUsedValues.contains( mLayer ) && mLastUsedValues[ mLayer ].contains( idx ) ) { QgsDebugMsg( QString( "reusing %1 for %2" ).arg( mLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) ); mFeature.setAttribute( idx, mLastUsedValues[ mLayer ][idx] ); } else { mFeature.setAttribute( idx, provider->defaultValue( idx ) ); } } bool res = false; mLayer->beginEditCommand( text() ); // show the dialog to enter attribute values bool isDisabledAttributeValuesDlg = settings.value( "/qgis/digitizing/disable_enter_attribute_values_dialog", false ).toBool(); // override application-wide setting with any layer setting switch ( mLayer->featureFormSuppress() ) { case QgsVectorLayer::SuppressOn: isDisabledAttributeValuesDlg = true; break; case QgsVectorLayer::SuppressOff: isDisabledAttributeValuesDlg = false; break; case QgsVectorLayer::SuppressDefault: break; } if ( isDisabledAttributeValuesDlg ) { res = mLayer->addFeature( mFeature ); } else { QgsAttributes origValues; if ( reuseLastValues ) origValues = mFeature.attributes(); QgsAttributeDialog *dialog = newDialog( false ); if ( dialog->exec() ) { if ( reuseLastValues ) { for ( int idx = 0; idx < fields.count(); ++idx ) { const QgsAttributes &newValues = mFeature.attributes(); if ( origValues[idx] != newValues[idx] ) { QgsDebugMsg( QString( "saving %1 for %2" ).arg( mLastUsedValues[ mLayer ][idx].toString() ).arg( idx ) ); mLastUsedValues[ mLayer ][idx] = newValues[idx]; } } } res = mLayer->addFeature( mFeature ); } else { QgsDebugMsg( "Adding feature to layer failed" ); res = false; } } if ( res ) mLayer->endEditCommand(); else mLayer->destroyEditCommand(); return res; }