bool QgsWFSProvider::addFeatures( QgsFeatureList &flist ) { //create <Transaction> xml QDomDocument transactionDoc; QDomElement transactionElem = createTransactionElement( transactionDoc ); transactionDoc.appendChild( transactionElem ); //find out typename from uri and strip namespace prefix QString tname = mShared->mURI.typeName(); if ( tname.isNull() ) { return false; } removeNamespacePrefix( tname ); //Add the features QgsFeatureList::iterator featureIt = flist.begin(); for ( ; featureIt != flist.end(); ++featureIt ) { //Insert element QDomElement insertElem = transactionDoc.createElementNS( QgsWFSConstants::WFS_NAMESPACE, "Insert" ); transactionElem.appendChild( insertElem ); QDomElement featureElem = transactionDoc.createElementNS( mApplicationNamespace, tname ); QgsAttributes featureAttributes = featureIt->attributes(); int nAttrs = featureAttributes.size(); for ( int i = 0; i < nAttrs; ++i ) { const QVariant& value = featureAttributes.at( i ); if ( value.isValid() && !value.isNull() ) { QDomElement fieldElem = transactionDoc.createElementNS( mApplicationNamespace, mShared->mFields.at( i ).name() ); QDomText fieldText = transactionDoc.createTextNode( value.toString() ); fieldElem.appendChild( fieldText ); featureElem.appendChild( fieldElem ); } } //add geometry column (as gml) const QgsGeometry* geometry = featureIt->constGeometry(); if ( geometry != nullptr ) { QDomElement geomElem = transactionDoc.createElementNS( mApplicationNamespace, mShared->mGeometryAttribute ); QgsGeometry the_geom( *geometry ); // convert to multi if the layer geom type is multi and the geom is not if ( QGis::isMultiType( this->geometryType( ) ) && ! the_geom.isMultipart( ) ) { the_geom.convertToMultiType(); } QDomElement gmlElem = QgsOgcUtils::geometryToGML( &the_geom, transactionDoc ); if ( !gmlElem.isNull() ) { gmlElem.setAttribute( "srsName", crs().authid() ); geomElem.appendChild( gmlElem ); featureElem.appendChild( geomElem ); } } insertElem.appendChild( featureElem ); } QDomDocument serverResponse; bool success = sendTransactionDocument( transactionDoc, serverResponse ); if ( !success ) { return false; } if ( transactionSuccess( serverResponse ) ) { //transaction successful. Add the features to the cache QStringList idList = insertedFeatureIds( serverResponse ); QStringList::const_iterator idIt = idList.constBegin(); featureIt = flist.begin(); QVector<QgsWFSFeatureGmlIdPair> serializedFeatureList; for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt ) { serializedFeatureList.push_back( QgsWFSFeatureGmlIdPair( *featureIt, *idIt ) ); } mShared->serializeFeatures( serializedFeatureList ); // And now set the feature id from the one got from the database QMap< QString, QgsFeatureId > map; for ( int idx = 0; idx < serializedFeatureList.size(); idx++ ) map[ serializedFeatureList[idx].second ] = serializedFeatureList[idx].first.id(); idIt = idList.constBegin(); featureIt = flist.begin(); for ( ; idIt != idList.constEnd() && featureIt != flist.end(); ++idIt, ++featureIt ) { if ( map.find( *idIt ) != map.end() ) featureIt->setFeatureId( map[*idIt] ); } return true; } else { handleException( serverResponse ); return false; } }