47 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
48 const QString &locator,
const QString &message );
59 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
60 response.
write( doc.toByteArray() );
74 if ( doc.setContent( parameters.value( QStringLiteral(
"REQUEST_BODY" ) ),
true, &errorMsg ) )
76 QDomElement docElem = doc.documentElement();
85 if ( actionCount == 0 )
96 QDomElement respElem = resp.createElement( QStringLiteral(
"TransactionResponse" ) );
97 respElem.setAttribute( QStringLiteral(
"xmlns" ),
WFS_NAMESPACE );
98 respElem.setAttribute( QStringLiteral(
"xmlns:xsi" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema-instance" ) );
99 respElem.setAttribute( QStringLiteral(
"xsi:schemaLocation" ),
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" );
100 respElem.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
101 respElem.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.1.0" ) );
102 resp.appendChild( respElem );
104 int totalInserted = 0;
105 int totalUpdated = 0;
106 int totalDeleted = 0;
110 QDomElement trsElem = doc.createElement( QStringLiteral(
"TransactionResults" ) );
113 QDomElement irsElem = doc.createElement( QStringLiteral(
"InsertResults" ) );
114 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
115 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
121 QString locator = action.
handle;
122 if ( locator.isEmpty() )
124 locator = QStringLiteral(
"Insert:%1" ).arg( action.
typeName );
126 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
133 QString fidStr = *fidIt;
134 QDomElement irElem = doc.createElement( QStringLiteral(
"Feature" ) );
135 if ( !action.
handle.isEmpty() )
137 irElem.setAttribute( QStringLiteral(
"handle" ), action.
handle );
139 QDomElement fiElem = doc.createElement( QStringLiteral(
"ogc:FeatureId" ) );
140 fiElem.setAttribute( QStringLiteral(
"fid" ), fidStr );
141 irElem.appendChild( fiElem );
142 irsElem.appendChild( irElem );
148 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
149 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
155 QString locator = action.
handle;
156 if ( locator.isEmpty() )
158 locator = QStringLiteral(
"Update:%1" ).arg( action.
typeName );
160 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
165 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
166 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
172 QString locator = action.
handle;
173 if ( locator.isEmpty() )
175 locator = QStringLiteral(
"Delete:%1" ).arg( action.
typeName );
177 addTransactionResult( resp, trsElem, locator, action.
errorMsg );
183 QDomElement summaryElem = doc.createElement( QStringLiteral(
"TransactionSummary" ) );
184 if ( aRequest.
inserts.size() > 0 )
186 QDomElement totalInsertedElem = doc.createElement( QStringLiteral(
"TotalInserted" ) );
187 totalInsertedElem.appendChild( doc.createTextNode( QString::number( totalInserted ) ) );
188 summaryElem.appendChild( totalInsertedElem );
190 if ( aRequest.
updates.size() > 0 )
192 QDomElement totalUpdatedElem = doc.createElement( QStringLiteral(
"TotalUpdated" ) );
193 totalUpdatedElem.appendChild( doc.createTextNode( QString::number( totalUpdated ) ) );
194 summaryElem.appendChild( totalUpdatedElem );
196 if ( aRequest.
deletes.size() > 0 )
198 QDomElement totalDeletedElem = doc.createElement( QStringLiteral(
"TotalDeleted" ) );
199 totalDeletedElem.appendChild( doc.createTextNode( QString::number( totalDeleted ) ) );
200 summaryElem.appendChild( totalDeletedElem );
202 respElem.appendChild( summaryElem );
205 if ( errorCount > 0 && trsElem.hasChildNodes() )
207 respElem.appendChild( trsElem );
211 if ( aRequest.
inserts.size() > 0 && irsElem.hasChildNodes() )
213 respElem.appendChild( irsElem );
220 #ifndef HAVE_SERVER_PYTHON_PLUGINS 224 QStringList typeNameList;
226 QList<transactionInsert>::iterator tiIt = aRequest.
inserts.begin();
227 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
229 QString name = ( *tiIt ).typeName;
230 if ( !typeNameList.contains( name ) )
231 typeNameList << name;
233 QList<transactionUpdate>::iterator tuIt = aRequest.
updates.begin();
234 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
236 QString name = ( *tuIt ).typeName;
237 if ( !typeNameList.contains( name ) )
238 typeNameList << name;
240 QList<transactionDelete>::iterator tdIt = aRequest.
deletes.begin();
241 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
243 QString name = ( *tdIt ).typeName;
244 if ( !typeNameList.contains( name ) )
245 typeNameList << name;
248 #ifdef HAVE_SERVER_PYTHON_PLUGINS 262 QMap<QString, QgsVectorLayer *> mapLayerMap;
263 for (
int i = 0; i < wfsLayerIds.size(); ++i )
270 if ( layer->
type() != QgsMapLayer::LayerType::VectorLayer )
277 if ( !typeNameList.contains( name ) )
304 if ( !wfstUpdateLayerIds.contains( vlayer->
id() )
305 && !wfstDeleteLayerIds.contains( vlayer->
id() )
306 && !wfstInsertLayerIds.contains( vlayer->
id() ) )
322 mapLayerMap[name] = vlayer;
326 tuIt = aRequest.
updates.begin();
327 for ( ; tuIt != aRequest.
updates.end(); ++tuIt )
332 if ( !mapLayerMap.keys().contains( typeName ) )
335 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg( typeName );
343 if ( !wfstUpdateLayerIds.contains( vlayer->
id() ) )
346 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg( typeName );
352 action.
errorMsg = QStringLiteral(
"No permissions to do WFS updates on layer '%1'" ).arg( typeName );
364 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS updates on layer '%1'" ).arg( typeName );
387 #ifdef HAVE_SERVER_PYTHON_PLUGINS 397 int totalUpdated = 0;
399 QMap<QString, QString> propertyMap = action.
propertyMap;
404 QMap<QString, int>::const_iterator fieldMapIt;
406 bool conversionSuccess;
410 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
413 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg( typeName );
417 QMap< QString, QString >::const_iterator it = propertyMap.constBegin();
418 for ( ; it != propertyMap.constEnd(); ++it )
420 fieldName = it.key();
421 fieldMapIt = fieldMap.find( fieldName );
422 if ( fieldMapIt == fieldMap.constEnd() )
426 QgsField field = fields.
at( fieldMapIt.value() );
427 QVariant value = it.value();
428 if ( value.isNull() )
433 action.
errorMsg = QStringLiteral(
"NOT NULL constraint error on layer '%1', field '%2'" ).arg( typeName, field.
name() );
440 if ( field.
type() == QVariant::Type::Int )
442 value = it.value().toInt( &conversionSuccess );
443 if ( !conversionSuccess )
446 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg( typeName );
451 else if ( field.
type() == QVariant::Type::Double )
453 value = it.value().toDouble( &conversionSuccess );
454 if ( !conversionSuccess )
457 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg( typeName );
462 else if ( field.
type() == QVariant::Type::LongLong )
464 value = it.value().toLongLong( &conversionSuccess );
465 if ( !conversionSuccess )
468 action.
errorMsg = QStringLiteral(
"Property conversion error on layer '%1'" ).arg( typeName );
481 if ( !geometryElem.isNull() )
487 action.
errorMsg = QStringLiteral(
"Geometry from GML error on layer '%1'" ).arg( typeName );
494 action.
errorMsg = QStringLiteral(
"Error in change geometry on layer '%1'" ).arg( typeName );
511 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
514 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg( typeName );
529 action.
errorMsg = QStringLiteral(
"Error committing updates: %1" ).arg( vlayer->
commitErrors().join( QStringLiteral(
"; " ) ) );
535 action.
error =
false;
540 tdIt = aRequest.
deletes.begin();
541 for ( ; tdIt != aRequest.
deletes.end(); ++tdIt )
546 if ( !mapLayerMap.keys().contains( typeName ) )
549 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg( typeName );
557 if ( !wfstDeleteLayerIds.contains( vlayer->
id() ) )
560 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg( typeName );
566 action.
errorMsg = QStringLiteral(
"No permissions to do WFS deletes on layer '%1'" ).arg( typeName );
578 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS deletes on layer '%1'" ).arg( typeName );
598 action.
errorMsg = QStringLiteral(
"No feature ids to do WFS deletes on layer '%1'" ).arg( typeName );
605 #ifdef HAVE_SERVER_PYTHON_PLUGINS 619 if ( accessControl && !accessControl->
allowToEdit( vlayer, feature ) )
622 action.
errorMsg = QStringLiteral(
"Feature modify permission denied" );
626 fids << feature.
id();
636 action.
errorMsg = QStringLiteral(
"Delete features failed on layer '%1'" ).arg( typeName );
645 action.
errorMsg = QStringLiteral(
"Error committing deletes: %1" ).arg( vlayer->
commitErrors().join( QStringLiteral(
"; " ) ) );
651 action.
error =
false;
655 tiIt = aRequest.
inserts.begin();
656 for ( ; tiIt != aRequest.
inserts.end(); ++tiIt )
661 if ( !mapLayerMap.keys().contains( typeName ) )
664 action.
errorMsg = QStringLiteral(
"TypeName '%1' unknown" ).arg( typeName );
672 if ( !wfstInsertLayerIds.contains( vlayer->
id() ) )
675 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg( typeName );
678 #ifdef HAVE_SERVER_PYTHON_PLUGINS 682 action.
errorMsg = QStringLiteral(
"No permissions to do WFS inserts on layer '%1'" ).arg( typeName );
695 action.
errorMsg = QStringLiteral(
"No capabilities to do WFS inserts on layer '%1'" ).arg( typeName );
711 action.
errorMsg = QStringLiteral(
"%1 '%2'" ).arg( ex.
message() ).arg( typeName );
715 if ( featureList.empty() )
718 action.
errorMsg = QStringLiteral(
"No features to insert in layer '%1'" ).arg( typeName );
722 #ifdef HAVE_SERVER_PYTHON_PLUGINS 726 QgsFeatureList::iterator featureIt = featureList.begin();
727 while ( featureIt != featureList.end() )
729 if ( !accessControl->
allowToEdit( vlayer, *featureIt ) )
732 action.
errorMsg = QStringLiteral(
"Feature modify permission denied on layer '%1'" ).arg( typeName );
749 action.
errorMsg = QStringLiteral(
"Insert features failed on layer '%1'" ).arg( typeName );
750 if ( provider ->hasErrors() )
762 action.
errorMsg = QStringLiteral(
"Error committing inserts: %1" ).arg( vlayer->
commitErrors().join( QStringLiteral(
"; " ) ) );
767 action.
error =
false;
771 for (
const QgsFeature &feat : qgis::as_const( featureList ) )
778 filterRestorer.reset();
789 QMap<QString, int>::const_iterator fieldMapIt;
791 for (
int i = 0; i < featureNodeList.count(); i++ )
795 QDomElement featureElem = featureNodeList.at( i ).toElement();
796 QDomNode currentAttributeChild = featureElem.firstChild();
797 bool conversionSuccess =
true;
799 while ( !currentAttributeChild.isNull() )
801 QDomElement currentAttributeElement = currentAttributeChild.toElement();
802 QString attrName = currentAttributeElement.localName();
804 if ( attrName != QLatin1String(
"boundedBy" ) )
806 if ( attrName != QLatin1String(
"geometry" ) )
808 fieldMapIt = fieldMap.find( attrName );
809 if ( fieldMapIt == fieldMap.constEnd() )
814 QgsField field = fields.
at( fieldMapIt.value() );
815 QString attrValue = currentAttributeElement.text();
816 int attrType = field.
type();
818 QgsMessageLog::logMessage( QStringLiteral(
"attr: name=%1 idx=%2 value=%3" ).arg( attrName ).arg( fieldMapIt.value() ).arg( attrValue ) );
820 if ( attrType == QVariant::Int )
821 feat.
setAttribute( fieldMapIt.value(), attrValue.toInt( &conversionSuccess ) );
822 else if ( attrType == QVariant::Double )
823 feat.
setAttribute( fieldMapIt.value(), attrValue.toDouble( &conversionSuccess ) );
827 if ( !conversionSuccess )
842 currentAttributeChild = currentAttributeChild.nextSibling();
852 if ( !parameters.contains( QStringLiteral(
"OPERATION" ) ) )
856 if ( parameters.value( QStringLiteral(
"OPERATION" ) ).toUpper() != QStringLiteral(
"DELETE" ) )
862 if ( ( parameters.contains( QStringLiteral(
"FEATUREID" ) )
863 && ( parameters.contains( QStringLiteral(
"FILTER" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
864 || ( parameters.contains( QStringLiteral(
"FILTER" ) )
865 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"BBOX" ) ) ) )
866 || ( parameters.contains( QStringLiteral(
"BBOX" ) )
867 && ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) || parameters.contains( QStringLiteral(
"FILTER" ) ) ) )
875 QStringList typeNameList;
877 if ( parameters.contains( QStringLiteral(
"FEATUREID" ) ) )
879 QStringList fidList = parameters.value( QStringLiteral(
"FEATUREID" ) ).split(
',' );
881 QMap<QString, QStringList> fidsMap;
883 QStringList::const_iterator fidIt = fidList.constBegin();
884 for ( ; fidIt != fidList.constEnd(); ++fidIt )
887 QString fid = *fidIt;
890 if ( !fid.contains(
'.' ) )
895 QString
typeName = fid.section(
'.', 0, 0 );
896 fid = fid.section(
'.', 1, 1 );
897 if ( !typeNameList.contains( typeName ) )
903 if ( fidsMap.contains( typeName ) )
905 fids = fidsMap.value( typeName );
908 fidsMap.insert( typeName, fids );
911 QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
912 while ( fidsMapIt != fidsMap.constEnd() )
920 request.
deletes.append( action );
925 if ( !parameters.contains( QStringLiteral(
"TYPENAME" ) ) )
930 typeNameList = parameters.value( QStringLiteral(
"TYPENAME" ) ).split(
',' );
933 QStringList::const_iterator typeNameIt = typeNameList.constBegin();
934 for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
937 typeName = typeName.trimmed();
942 request.
deletes.append( action );
946 if ( parameters.contains( QStringLiteral(
"EXP_FILTER" ) ) )
948 QString expFilterName = parameters.value( QStringLiteral(
"EXP_FILTER" ) );
949 QStringList expFilterList;
950 QRegExp rx(
"\\(([^()]+)\\)" );
951 if ( rx.indexIn( expFilterName, 0 ) == -1 )
953 expFilterList << expFilterName;
958 while ( ( pos = rx.indexIn( expFilterName, pos ) ) != -1 )
960 expFilterList << rx.cap( 1 );
961 pos += rx.matchedLength();
966 if ( request.
deletes.size() == expFilterList.size() )
969 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
970 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
971 for ( ; dIt != request.
deletes.end(); ++dIt )
976 if ( expFilterIt != expFilterList.constEnd() )
978 expFilter = *expFilterIt;
980 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
983 if ( filter->hasParserError() )
989 if ( filter->needsGeometry() )
1000 QgsMessageLog::logMessage(
"There has to be a 1:1 mapping between each element in a TYPENAME and the EXP_FILTER list" );
1004 if ( parameters.contains( QStringLiteral(
"BBOX" ) ) )
1007 QString bbox = parameters.value( QStringLiteral(
"BBOX" ) );
1008 if ( bbox.isEmpty() )
1014 QStringList corners = bbox.split(
',' );
1015 if ( corners.size() != 4 )
1023 for (
int i = 0; i < 4; i++ )
1025 corners[i].replace(
' ',
'+' );
1026 d[i] = corners[i].toDouble( &ok );
1036 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1037 for ( ; dIt != request.
deletes.end(); ++dIt )
1044 else if ( parameters.contains( QStringLiteral(
"FILTER" ) ) )
1046 QString filterName = parameters.value( QStringLiteral(
"FILTER" ) );
1047 QStringList filterList;
1048 QRegExp rx(
"\\(([^()]+)\\)" );
1049 if ( rx.indexIn( filterName, 0 ) == -1 )
1051 filterList << filterName;
1056 while ( ( pos = rx.indexIn( filterName, pos ) ) != -1 )
1058 filterList << rx.cap( 1 );
1059 pos += rx.matchedLength();
1064 if ( request.
deletes.size() != filterList.size() )
1070 QList<transactionDelete>::iterator dIt = request.
deletes.begin();
1071 QStringList::const_iterator filterIt = filterList.constBegin();
1072 for ( ; dIt != request.
deletes.end(); ++dIt )
1077 QDomDocument filter;
1078 if ( filterIt != filterList.constEnd() )
1081 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
1087 QDomElement filterElem = filter.firstChildElement();
1088 QStringList serverFids;
1092 if ( filterIt != filterList.constEnd() )
1107 QDomNodeList docChildNodes = docElem.childNodes();
1109 QDomElement actionElem;
1112 for (
int i = docChildNodes.count(); 0 < i; --i )
1114 actionElem = docChildNodes.at( i - 1 ).toElement();
1115 actionName = actionElem.localName();
1117 if ( actionName == QLatin1String(
"Insert" ) )
1120 request.
inserts.append( action );
1122 else if ( actionName == QLatin1String(
"Update" ) )
1125 request.
updates.append( action );
1127 else if ( actionName == QLatin1String(
"Delete" ) )
1130 request.
deletes.append( action );
1139 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1140 if ( typeName.contains(
':' ) )
1141 typeName = typeName.section(
':', 1, 1 );
1143 QDomElement filterElem = actionElem.firstChild().toElement();
1144 if ( filterElem.tagName() != QLatin1String(
"Filter" ) )
1149 QStringList serverFids;
1156 action.
error =
false;
1158 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1160 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1169 QString
typeName = actionElem.attribute( QStringLiteral(
"typeName" ) );
1170 if ( typeName.contains(
':' ) )
1171 typeName = typeName.section(
':', 1, 1 );
1173 QDomNodeList propertyNodeList = actionElem.elementsByTagName( QStringLiteral(
"Property" ) );
1174 if ( propertyNodeList.isEmpty() )
1179 QMap<QString, QString> propertyMap;
1180 QDomElement propertyElem;
1181 QDomElement nameElem;
1182 QDomElement valueElem;
1183 QDomElement geometryElem;
1185 for (
int l = 0; l < propertyNodeList.count(); ++l )
1187 propertyElem = propertyNodeList.at( l ).toElement();
1188 nameElem = propertyElem.elementsByTagName( QStringLiteral(
"Name" ) ).at( 0 ).toElement();
1189 valueElem = propertyElem.elementsByTagName( QStringLiteral(
"Value" ) ).at( 0 ).toElement();
1190 if ( nameElem.text() != QLatin1String(
"geometry" ) )
1192 propertyMap.insert( nameElem.text(), valueElem.text() );
1196 geometryElem = valueElem;
1200 QDomNodeList filterNodeList = actionElem.elementsByTagName( QStringLiteral(
"Filter" ) );
1202 QStringList serverFids;
1203 if ( filterNodeList.size() != 0 )
1205 QDomElement filterElem = filterNodeList.at( 0 ).toElement();
1212 action.propertyMap = propertyMap;
1213 action.geometryElement = geometryElem;
1214 action.featureRequest = featureRequest;
1215 action.serverFids = serverFids;
1216 action.error =
false;
1218 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1220 action.handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1228 QDomNodeList featureNodeList = actionElem.childNodes();
1229 if ( featureNodeList.size() != 1 )
1235 for (
int i = 0; i < featureNodeList.count(); ++i )
1237 QString tempTypeName = featureNodeList.at( i ).toElement().localName();
1238 if ( tempTypeName.contains(
':' ) )
1239 tempTypeName = tempTypeName.section(
':', 1, 1 );
1241 if ( typeName.isEmpty() )
1243 typeName = tempTypeName;
1245 else if ( tempTypeName != typeName )
1254 action.
error =
false;
1256 if ( actionElem.hasAttribute( QStringLiteral(
"handle" ) ) )
1258 action.
handle = actionElem.attribute( QStringLiteral(
"handle" ) );
1267 void addTransactionResult( QDomDocument &responseDoc, QDomElement &resultsElem,
1268 const QString &locator,
const QString &message )
1270 QDomElement trElem = responseDoc.createElement( QStringLiteral(
"Action" ) );
1271 resultsElem.appendChild( trElem );
1273 if ( !locator.isEmpty() )
1275 trElem.setAttribute( QStringLiteral(
"locator" ), locator );
1278 if ( !message.isEmpty() )
1280 QDomElement mesElem = responseDoc.createElement( QStringLiteral(
"Message" ) );
1281 mesElem.appendChild( responseDoc.createTextNode( message ) );
1282 trElem.appendChild( mesElem );
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
virtual void setHeader(const QString &key, const QString &value)=0
Set Header entry Add Header entry to the response Note that it is usually an error to set Header afte...
bool layerInsertPermission(const QgsVectorLayer *layer) const
Returns the layer insert right.
A rectangle specified with double values.
Base class for all map layer types.
transactionUpdate parseUpdateActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Update element to transactionUpdate.
SERVER_EXPORT QStringList wfstUpdateLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with update capabilities...
QSet< QgsFeatureId > QgsFeatureIds
QgsMapLayer::LayerType type() const
Returns the type of the layer.
QgsFeatureRequest featureRequest
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
virtual QgsAttributeList pkAttributeIndexes() const
Returns list of indexes of fields that make up the primary key.
bool layerUpdatePermission(const QgsVectorLayer *layer) const
Returns the layer update right.
SERVER_EXPORT QString getServerFid(const QgsFeature &feature, const QgsAttributeList &pkAttributes)
Returns the feature id based on primary keys.
QStringList commitErrors() const
Returns a list containing any error messages generated when attempting to commit changes to the layer...
transactionRequest parseTransactionRequestBody(QDomElement &docElem, const QgsProject *project)
Transform RequestBody root element to getFeatureRequest.
bool addFeatures(QgsFeatureList &flist, QgsFeatureSink::Flags flags=nullptr) override
Adds a list of features to the sink.
QList< QgsFeature > QgsFeatureList
bool commitChanges()
Attempts to commit to the underlying data provider any buffered changes made since the last to call t...
bool startEditing()
Makes the layer editable.
Exception base class for service exceptions.
bool deleteFeatures(const QgsFeatureIds &fids)
Deletes a set of features from the layer (but does not commit it)
Container of fields for a vector layer.
A geometry is the spatial representation of a feature.
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device...
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
QList< transactionUpdate > updates
static void applyAccessControlLayerFilters(const QgsAccessControl *accessControl, QgsMapLayer *mapLayer, QHash< QgsMapLayer *, QString > &originalLayerFilters)
Apply filter from AccessControl.
QMap< QString, QString > propertyMap
QgsFeatureRequest & setExpressionContext(const QgsExpressionContext &context)
Sets the expression context used to evaluate filter expressions.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
transactionRequest parseTransactionParameters(QgsServerRequest::Parameters parameters, const QgsProject *project)
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
bool changeGeometry(QgsFeatureId fid, QgsGeometry &geometry, bool skipDefaultValue=false)
Changes a feature's geometry within the layer's edit buffer (but does not immediately commit the chan...
bool rollBack(bool deleteBuffer=true)
Stops a current editing operation and discards any uncommitted edits.
QList< transactionInsert > inserts
SERVER_EXPORT QStringList wfstDeleteLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with delete capabilities...
QgsFields fields() const override=0
Returns the fields associated with this data provider.
QDomNodeList featureNodeList
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
This class wraps a request for features to a vector layer (or directly its vector data provider)...
void writeTransaction(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response)
Output WFS transaction response.
const QString WFS_NAMESPACE
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
QgsFeatureRequest parseFilterElement(const QString &typeName, QDomElement &filterElem, const QgsProject *project)
Transform a Filter element to a feature request.
Allows modifications of geometries.
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Reads and writes project states.
void clearErrors()
Clear recorded errors.
QgsFeatureList featuresFromGML(QDomNodeList featureNodeList, QgsVectorDataProvider *provider)
Transform GML feature nodes to features.
Encapsulate a field in an attribute table or data source.
QMap< QString, int > fieldNameMap() const
Returns a map where the key is the name of the field and the value is its index.
bool allowToEdit(const QgsVectorLayer *layer, const QgsFeature &feature) const
Are we authorized to modify the following geometry.
SERVER_EXPORT QgsFeatureRequest updateFeatureRequestFromServerFids(QgsFeatureRequest &featureRequest, const QStringList &serverFids, const QgsVectorDataProvider *provider)
Returns the feature request based on feature ids build with primary keys.
transactionDelete parseDeleteActionElement(QDomElement &actionElem, const QgsProject *project)
Transform Delete element to transactionDelete.
const QString OGC_NAMESPACE
QDomDocument createTransactionDocument(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request)
Create a wfs transaction document.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QStringList insertFeatureIds
static QgsGeometry geometryFromGML(const QString &xmlString)
Static method that creates geometry from GML.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins...
QgsFieldConstraints constraints
virtual QgsVectorDataProvider::Capabilities capabilities() const
Returns flags containing the supported capabilities.
QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
QList< transactionDelete > deletes
RAII class to restore layer filters on destruction.
void performTransaction(transactionRequest &aRequest, QgsServerInterface *serverIface, const QgsProject *project)
Perform the transaction.
A helper class that centralizes restrictions given by all the access control filter plugins...
void filterFeatures(const QgsVectorLayer *layer, QgsFeatureRequest &filterFeatures) const override
Filter the features of the layer.
SERVER_EXPORT QStringList wfstInsertLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published as WFS-T with insert capabilities...
Exception thrown when data access violates access controls.
Allows deletion of features.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant(), bool skipDefaultValues=false)
Changes an attribute value for a feature (but does not immediately commit the changes).
QDomElement geometryElement
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider.
QList< int > QgsAttributeList
QString message() const
Returns the exception message.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
bool nextFeature(QgsFeature &f)
This is the base class for vector data providers.
bool layerDeletePermission(const QgsVectorLayer *layer) const
Returns the layer delete right.
Represents a vector layer which manages a vector based data sets.
QgsServerRequest::Parameters parameters() const
Returns a map of query parameters with keys converted to uppercase.
Allows modification of attribute values.
transactionInsert parseInsertActionElement(QDomElement &actionElem)
Transform Insert element to transactionInsert.
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
QMap< QString, QString > Parameters
QgsFeatureRequest featureRequest