47 struct createFeatureParams
66 QString createFeatureGeoJSON(
const QgsFeature &feature,
const createFeatureParams ¶ms,
const QgsAttributeList &pkAttributes );
70 QDomElement createFeatureGML2(
const QgsFeature &feature, QDomDocument &doc,
const createFeatureParams ¶ms,
const QgsProject *project,
const QgsAttributeList &pkAttributes );
72 QDomElement createFeatureGML3(
const QgsFeature &feature, QDomDocument &doc,
const createFeatureParams ¶ms,
const QgsProject *project,
const QgsAttributeList &pkAttributes );
87 QgsWfsParameters mWfsParameters;
100 mWfsParameters.dump();
106 if ( doc.setContent( request.
data(),
true, &errorMsg ) )
108 QDomElement docElem = doc.documentElement();
117 QStringList typeNameList;
120 bool onlyOneLayer = ( aRequest.
queries.size() == 1 );
123 int requestPrecision = 6;
127 QList<getFeatureQuery>::iterator qIt = aRequest.
queries.begin();
128 for ( ; qIt != aRequest.
queries.end(); ++qIt )
130 typeNameList << ( *qIt ).typeName;
136 QMap<QString, QgsMapLayer *> mapLayerMap;
151 if ( typeNameList.contains( name ) )
154 mapLayerMap[name] = layer;
158 requestRect = layer->
extent();
159 requestCrs = layer->
crs();
178 requestRect =
QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
184 #ifdef HAVE_SERVER_PYTHON_PLUGINS
194 long sentFeatures = 0;
195 long iteratedFeatures = 0;
198 qIt = aRequest.
queries.begin();
199 for ( ; qIt != aRequest.
queries.end(); ++qIt )
204 if ( !mapLayerMap.keys().contains(
typeName ) )
210 #ifdef HAVE_SERVER_PYTHON_PLUGINS
228 #ifdef HAVE_SERVER_PYTHON_PLUGINS
235 QMap< int, QString > layerAliasInfo;
237 QgsStringMap::const_iterator aliasIt = aliasMap.constBegin();
238 for ( ; aliasIt != aliasMap.constEnd(); ++aliasIt )
241 if ( attrIndex != -1 )
243 layerAliasInfo.insert( attrIndex, aliasIt.value() );
254 if ( !propertyList.isEmpty() && propertyList.first() != QLatin1String(
"*" ) )
257 QStringList::const_iterator plstIt;
260 QList<QString> propertynames;
261 QList<QString> fieldnames;
268 for ( plstIt = propertyList.constBegin(); plstIt != propertyList.constEnd(); ++plstIt )
271 int fieldNameIdx = propertynames.indexOf( fieldName );
272 if ( fieldNameIdx == -1 )
274 fieldNameIdx = fieldnames.indexOf( fieldName );
276 if ( fieldNameIdx > -1 )
278 idxList.append( fieldNameIdx );
280 else if ( fieldName == QLatin1String(
"geometry" ) )
285 if ( !idxList.isEmpty() )
287 attrIndexes = idxList;
292 if ( !attrIndexes.isEmpty() )
298 int fieldNameIdx = fields.indexOf(
field.
name() );
299 if ( fieldNameIdx > -1 && attrIndexes.contains( fieldNameIdx ) )
301 attrIndexes.removeOne( fieldNameIdx );
330 #ifdef HAVE_SERVER_PYTHON_PLUGINS
335 QStringList attributes = QStringList();
336 for (
int idx : attrIndexes )
349 if ( !pkAttributes.isEmpty() )
352 for (
int idx : pkAttributes )
354 if ( !subsetOfAttrs.contains( idx ) )
356 subsetOfAttrs.prepend( idx );
387 if ( !query.
srsName.isEmpty() )
414 if ( mWfsParameters.resultType() == QgsWfsParameters::ResultType::HITS )
418 if ( iteratedFeatures >= aRequest.
startIndex )
427 const createFeatureParams cfp = { layerPrecision,
438 if ( iteratedFeatures == aRequest.
startIndex )
439 startGetFeature( request, response, project, aRequest.
outputFormat, requestPrecision, requestCrs, &requestRect, typeNameList );
441 if ( iteratedFeatures >= aRequest.
startIndex )
451 #ifdef HAVE_SERVER_PYTHON_PLUGINS
453 filterRestorer.reset();
456 if ( mWfsParameters.resultType() == QgsWfsParameters::ResultType::HITS )
458 hitGetFeature( request, response, project, aRequest.
outputFormat, sentFeatures, typeNameList );
463 if ( iteratedFeatures <= aRequest.
startIndex )
464 startGetFeature( request, response, project, aRequest.
outputFormat, requestPrecision, requestCrs, &requestRect, typeNameList );
473 request.
maxFeatures = mWfsParameters.maxFeaturesAsInt();
474 request.
startIndex = mWfsParameters.startIndexAsInt();
478 QStringList fidList = mWfsParameters.featureIds();
479 bool paramContainsFeatureIds = !fidList.isEmpty();
480 QStringList filterList = mWfsParameters.filters();
481 bool paramContainsFilters = !filterList.isEmpty();
482 QString bbox = mWfsParameters.bbox();
483 bool paramContainsBbox = !bbox.isEmpty();
484 if ( ( paramContainsFeatureIds
485 && ( paramContainsFilters || paramContainsBbox ) )
486 || ( paramContainsFilters
487 && ( paramContainsFeatureIds || paramContainsBbox ) )
488 || ( paramContainsBbox
489 && ( paramContainsFeatureIds || paramContainsFilters ) )
496 QStringList propertyNameList = mWfsParameters.propertyNames();
499 request.
geometryName = mWfsParameters.geometryNameAsString().toUpper();
501 QStringList typeNameList;
503 if ( paramContainsFeatureIds )
506 if ( !propertyNameList.isEmpty() && propertyNameList.size() != fidList.size() )
510 if ( propertyNameList.isEmpty() )
512 for (
int i = 0; i < fidList.size(); ++i )
514 propertyNameList << QStringLiteral(
"*" );
518 QMap<QString, QStringList> fidsMap;
520 QStringList::const_iterator fidIt = fidList.constBegin();
521 QStringList::const_iterator propertyNameIt = propertyNameList.constBegin();
522 for ( ; fidIt != fidList.constEnd(); ++fidIt )
525 QString fid = *fidIt;
528 QString propertyName;
529 if ( propertyNameIt != propertyNameList.constEnd() )
531 propertyName = *propertyNameIt;
534 if ( !fid.contains(
'.' ) )
539 QString
typeName = fid.section(
'.', 0, 0 );
540 fid = fid.section(
'.', 1, 1 );
541 if ( !typeNameList.contains(
typeName ) )
547 QString key = QStringLiteral(
"%1(%2)" ).arg(
typeName ).arg( propertyName );
549 if ( fidsMap.contains( key ) )
551 fids = fidsMap.value( key );
554 fidsMap.insert( key, fids );
556 if ( propertyNameIt != propertyNameList.constEnd() )
562 QMap<QString, QStringList>::const_iterator fidsMapIt = fidsMap.constBegin();
563 while ( fidsMapIt != fidsMap.constEnd() )
565 QString key = fidsMapIt.key();
568 QRegExp rx(
"([^()]+)\\(([^()]+)\\)" );
569 if ( rx.indexIn( key, 0 ) == -1 )
574 QString propertyName = rx.cap( 2 );
578 query.
srsName = mWfsParameters.srsName();
581 if ( propertyName != QLatin1String(
"*" ) )
583 QStringList propertyList;
585 const QStringList attrList = propertyName.split(
',' );
586 QStringList::const_iterator alstIt;
587 for ( alstIt = attrList.constBegin(); alstIt != attrList.constEnd(); ++alstIt )
589 QString fieldName = *alstIt;
590 fieldName = fieldName.trimmed();
591 if ( fieldName.contains(
':' ) )
593 fieldName = fieldName.section(
':', 1, 1 );
595 if ( fieldName.contains(
'/' ) )
597 if ( fieldName.section(
'/', 0, 0 ) !=
typeName )
601 fieldName = fieldName.section(
'/', 1, 1 );
603 propertyList.append( fieldName );
612 request.
queries.append( query );
618 if ( !mRequestParameters.contains( QStringLiteral(
"TYPENAME" ) ) )
623 typeNameList = mWfsParameters.typeNames();
625 if ( !propertyNameList.isEmpty() && typeNameList.size() != propertyNameList.size() )
629 if ( propertyNameList.isEmpty() )
631 for (
int i = 0; i < typeNameList.size(); ++i )
633 propertyNameList << QStringLiteral(
"*" );
638 QStringList::const_iterator typeNameIt = typeNameList.constBegin();
639 QStringList::const_iterator propertyNameIt = propertyNameList.constBegin();
640 for ( ; typeNameIt != typeNameList.constEnd(); ++typeNameIt )
645 QString propertyName;
646 if ( propertyNameIt != propertyNameList.constEnd() )
648 propertyName = *propertyNameIt;
653 query.
srsName = mWfsParameters.srsName();
656 if ( propertyName != QLatin1String(
"*" ) )
658 QStringList propertyList;
660 const QStringList attrList = propertyName.split(
',' );
661 QStringList::const_iterator alstIt;
662 for ( alstIt = attrList.constBegin(); alstIt != attrList.constEnd(); ++alstIt )
664 QString fieldName = *alstIt;
665 fieldName = fieldName.trimmed();
666 if ( fieldName.contains(
':' ) )
668 fieldName = fieldName.section(
':', 1, 1 );
670 if ( fieldName.contains(
'/' ) )
672 if ( fieldName.section(
'/', 0, 0 ) !=
typeName )
676 fieldName = fieldName.section(
'/', 1, 1 );
678 propertyList.append( fieldName );
683 request.
queries.append( query );
685 if ( propertyNameIt != propertyNameList.constEnd() )
692 QStringList expFilterList = mWfsParameters.expFilters();
693 if ( !expFilterList.isEmpty() )
696 if ( request.
queries.size() == expFilterList.size() )
699 QList<getFeatureQuery>::iterator qIt = request.
queries.begin();
700 QStringList::const_iterator expFilterIt = expFilterList.constBegin();
701 for ( ; qIt != request.
queries.end(); ++qIt )
706 if ( expFilterIt != expFilterList.constEnd() )
708 expFilter = *expFilterIt;
710 std::shared_ptr<QgsExpression> filter(
new QgsExpression( expFilter ) );
713 if ( filter->hasParserError() )
717 if ( filter->needsGeometry() )
731 if ( paramContainsBbox )
738 if ( mWfsParameters.bbox().split(
',' ).size() == 5 && ! mWfsParameters.srsName().isEmpty() )
740 QString
crs( mWfsParameters.bbox().split(
',' )[4] );
741 if (
crs != mWfsParameters.srsName() )
753 if ( extentGeom.
transform( transform ) == 0 )
767 QList<getFeatureQuery>::iterator qIt = request.
queries.begin();
768 for ( ; qIt != request.
queries.end(); ++qIt )
775 else if ( paramContainsFilters )
778 if ( request.
queries.size() != filterList.size() )
784 QList<getFeatureQuery>::iterator qIt = request.
queries.begin();
785 QStringList::const_iterator filterIt = filterList.constBegin();
786 for ( ; qIt != request.
queries.end(); ++qIt )
791 if ( filterIt != filterList.constEnd() )
794 if ( !filter.setContent( *filterIt,
true, &errorMsg ) )
800 QDomElement filterElem = filter.firstChildElement();
801 QStringList serverFids;
805 if ( filterIt != filterList.constEnd() )
813 QStringList sortByList = mWfsParameters.sortBy();
814 if ( !sortByList.isEmpty() && request.
queries.size() == sortByList.size() )
817 QList<getFeatureQuery>::iterator qIt = request.
queries.begin();
818 QStringList::const_iterator sortByIt = sortByList.constBegin();
819 for ( ; qIt != request.
queries.end(); ++qIt )
824 if ( sortByIt != sortByList.constEnd() )
828 for (
const QString &attribute : sortBy.split(
',' ) )
830 if ( attribute.endsWith( QLatin1String(
" D" ) ) || attribute.endsWith( QLatin1String(
"+D" ) ) )
834 else if ( attribute.endsWith( QLatin1String(
" DESC" ) ) || attribute.endsWith( QLatin1String(
"+DESC" ) ) )
838 else if ( attribute.endsWith( QLatin1String(
" A" ) ) || attribute.endsWith( QLatin1String(
"+A" ) ) )
842 else if ( attribute.endsWith( QLatin1String(
" ASC" ) ) || attribute.endsWith( QLatin1String(
"+ASC" ) ) )
860 request.
maxFeatures = mWfsParameters.maxFeaturesAsInt();
861 request.
startIndex = mWfsParameters.startIndexAsInt();
864 QDomNodeList queryNodes = docElem.elementsByTagName( QStringLiteral(
"Query" ) );
865 QDomElement queryElem;
866 for (
int i = 0; i < queryNodes.size(); i++ )
868 queryElem = queryNodes.at( i ).toElement();
870 request.
queries.append( query );
877 QDomNodeList sortByNodes = sortByElem.childNodes();
878 if ( sortByNodes.size() )
880 for (
int i = 0; i < sortByNodes.size(); i++ )
882 QDomElement sortPropElem = sortByNodes.at( i ).toElement();
883 QDomNodeList sortPropChildNodes = sortPropElem.childNodes();
884 if ( sortPropChildNodes.size() )
887 bool ascending =
true;
888 for (
int j = 0; j < sortPropChildNodes.size(); j++ )
890 QDomElement sortPropChildElem = sortPropChildNodes.at( j ).toElement();
891 if ( sortPropChildElem.tagName() == QLatin1String(
"PropertyName" ) )
893 fieldName = sortPropChildElem.text().trimmed();
895 else if ( sortPropChildElem.tagName() == QLatin1String(
"SortOrder" ) )
897 QString sortOrder = sortPropChildElem.text().trimmed().toUpper();
898 if ( sortOrder == QLatin1String(
"DESC" ) || sortOrder == QLatin1String(
"D" ) )
903 if ( fieldName.contains(
':' ) )
905 fieldName = fieldName.section(
':', 1, 1 );
907 if ( fieldName.contains(
'/' ) )
909 if ( fieldName.section(
'/', 0, 0 ) !=
typeName )
913 fieldName = fieldName.section(
'/', 1, 1 );
916 if ( !fieldName.isEmpty() )
917 featureRequest.
addOrderBy( fieldName, ascending );
925 QString
typeName = queryElem.attribute( QStringLiteral(
"typeName" ), QString() );
932 QStringList serverFids;
933 QStringList propertyList;
934 QDomNodeList queryChildNodes = queryElem.childNodes();
935 if ( queryChildNodes.size() )
937 QDomElement sortByElem;
938 for (
int q = 0; q < queryChildNodes.size(); q++ )
940 QDomElement queryChildElem = queryChildNodes.at( q ).toElement();
941 if ( queryChildElem.tagName() == QLatin1String(
"PropertyName" ) )
943 QString fieldName = queryChildElem.text().trimmed();
944 if ( fieldName.contains(
':' ) )
946 fieldName = fieldName.section(
':', 1, 1 );
948 if ( fieldName.contains(
'/' ) )
950 if ( fieldName.section(
'/', 0, 0 ) !=
typeName )
954 fieldName = fieldName.section(
'/', 1, 1 );
956 propertyList.append( fieldName );
958 else if ( queryChildElem.tagName() == QLatin1String(
"Filter" ) )
962 else if ( queryChildElem.tagName() == QLatin1String(
"SortBy" ) )
964 sortByElem = queryChildElem;
971 QString srsName = queryElem.attribute( QStringLiteral(
"srsName" ), QString() );
984 static QSet< QString > sParamFilter
986 QStringLiteral(
"REQUEST" ),
987 QStringLiteral(
"FORMAT" ),
988 QStringLiteral(
"OUTPUTFORMAT" ),
989 QStringLiteral(
"BBOX" ),
990 QStringLiteral(
"FEATUREID" ),
991 QStringLiteral(
"TYPENAME" ),
992 QStringLiteral(
"FILTER" ),
993 QStringLiteral(
"EXP_FILTER" ),
994 QStringLiteral(
"MAXFEATURES" ),
995 QStringLiteral(
"STARTINDEX" ),
996 QStringLiteral(
"PROPERTYNAME" ),
997 QStringLiteral(
"_DC" )
1002 int numberOfFeatures,
const QStringList &typeNames )
1004 QDateTime now = QDateTime::currentDateTime();
1007 if ( format == QgsWfsParameters::Format::GeoJSON )
1009 response.
setHeader(
"Content-Type",
"application/vnd.geo+json; charset=utf-8" );
1010 fcString = QStringLiteral(
"{\"type\": \"FeatureCollection\",\n" );
1011 fcString += QStringLiteral(
" \"timeStamp\": \"%1\"\n" ).arg( now.toString( Qt::ISODate ) );
1012 fcString += QStringLiteral(
" \"numberOfFeatures\": %1\n" ).arg( QString::number( numberOfFeatures ) );
1013 fcString += QLatin1Char(
'}' );
1017 if ( format == QgsWfsParameters::Format::GML2 )
1018 response.
setHeader(
"Content-Type",
"text/xml; subtype=gml/2.1.2; charset=utf-8" );
1020 response.
setHeader(
"Content-Type",
"text/xml; subtype=gml/3.1.1; charset=utf-8" );
1023 QString hrefString =
serviceUrl( request, project );
1025 QUrl mapUrl( hrefString );
1027 QUrlQuery query( mapUrl );
1028 query.addQueryItem( QStringLiteral(
"SERVICE" ), QStringLiteral(
"WFS" ) );
1030 if ( mWfsParameters.version().isEmpty() )
1033 query.addQueryItem( QStringLiteral(
"VERSION" ), QStringLiteral(
"1.1.0" ) );
1035 query.addQueryItem( QStringLiteral(
"VERSION" ), QStringLiteral(
"1.0.0" ) );
1037 for (
auto param : query.queryItems() )
1039 if ( sParamFilter.contains( param.first.toUpper() ) )
1040 query.removeAllQueryItems( param.first );
1043 query.addQueryItem( QStringLiteral(
"REQUEST" ), QStringLiteral(
"DescribeFeatureType" ) );
1044 query.addQueryItem( QStringLiteral(
"TYPENAME" ), typeNames.join(
',' ) );
1047 if ( format == QgsWfsParameters::Format::GML2 )
1048 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"text/xml; subtype=gml/2.1.2" ) );
1050 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"text/xml; subtype=gml/3.1.1" ) );
1053 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"XMLSCHEMA" ) );
1055 mapUrl.setQuery( query );
1057 hrefString = mapUrl.toString();
1060 fcString = QStringLiteral(
"<wfs:FeatureCollection" );
1064 fcString += QLatin1String(
" xmlns:ows=\"http://www.opengis.net/ows\"" );
1065 fcString += QLatin1String(
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" );
1067 fcString += QLatin1String(
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" );
1068 fcString +=
" xsi:schemaLocation=\"" +
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.0.0/wfs.xsd " +
QGS_NAMESPACE +
" " + hrefString.replace( QLatin1String(
"&" ), QLatin1String(
"&" ) ) +
"\"";
1069 fcString +=
"\n timeStamp=\"" + now.toString( Qt::ISODate ) +
"\"";
1070 fcString +=
"\n numberOfFeatures=\"" + QString::number( numberOfFeatures ) +
"\"";
1071 fcString += QLatin1String(
">\n" );
1072 fcString += QLatin1String(
"</wfs:FeatureCollection>" );
1075 response.
write( fcString.toUtf8() );
1084 std::unique_ptr< QgsRectangle > transformedRect;
1086 if ( format == QgsWfsParameters::Format::GeoJSON )
1088 response.
setHeader(
"Content-Type",
"application/vnd.geo+json; charset=utf-8" );
1098 if ( exportGeom.
transform( transform ) == 0 )
1101 rect = transformedRect.get();
1112 fcString = QStringLiteral(
"{\"type\": \"FeatureCollection\",\n" );
1114 fcString += QLatin1String(
" \"features\": [\n" );
1115 response.
write( fcString.toUtf8() );
1119 if ( format == QgsWfsParameters::Format::GML2 )
1120 response.
setHeader(
"Content-Type",
"text/xml; subtype=gml/2.1.2; charset=utf-8" );
1122 response.
setHeader(
"Content-Type",
"text/xml; subtype=gml/3.1.1; charset=utf-8" );
1125 QString hrefString =
serviceUrl( request, project );
1127 QUrl mapUrl( hrefString );
1129 QUrlQuery query( mapUrl );
1130 query.addQueryItem( QStringLiteral(
"SERVICE" ), QStringLiteral(
"WFS" ) );
1132 if ( mWfsParameters.version().isEmpty() )
1135 query.addQueryItem( QStringLiteral(
"VERSION" ), QStringLiteral(
"1.1.0" ) );
1137 query.addQueryItem( QStringLiteral(
"VERSION" ), QStringLiteral(
"1.0.0" ) );
1139 for (
auto param : query.queryItems() )
1141 if ( sParamFilter.contains( param.first.toUpper() ) )
1142 query.removeAllQueryItems( param.first );
1145 query.addQueryItem( QStringLiteral(
"REQUEST" ), QStringLiteral(
"DescribeFeatureType" ) );
1146 query.addQueryItem( QStringLiteral(
"TYPENAME" ), typeNames.join(
',' ) );
1149 if ( format == QgsWfsParameters::Format::GML2 )
1150 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"text/xml; subtype=gml/2.1.2" ) );
1152 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"text/xml; subtype=gml/3.1.1" ) );
1155 query.addQueryItem( QStringLiteral(
"OUTPUTFORMAT" ), QStringLiteral(
"XMLSCHEMA" ) );
1157 mapUrl.setQuery( query );
1159 hrefString = mapUrl.toString();
1162 fcString = QStringLiteral(
"<wfs:FeatureCollection" );
1166 fcString += QLatin1String(
" xmlns:ows=\"http://www.opengis.net/ows\"" );
1167 fcString += QLatin1String(
" xmlns:xlink=\"http://www.w3.org/1999/xlink\"" );
1169 fcString += QLatin1String(
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" );
1170 fcString +=
" xsi:schemaLocation=\"" +
WFS_NAMESPACE +
" http://schemas.opengis.net/wfs/1.0.0/wfs.xsd " +
QGS_NAMESPACE +
" " + hrefString.replace( QLatin1String(
"&" ), QLatin1String(
"&" ) ) +
"\"";
1171 fcString += QLatin1String(
">\n" );
1173 response.
write( fcString.toUtf8() );
1177 QDomElement bbElem = doc.createElement( QStringLiteral(
"gml:boundedBy" ) );
1178 if ( format == QgsWfsParameters::Format::GML3 )
1181 if ( !envElem.isNull() )
1185 envElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1187 bbElem.appendChild( envElem );
1188 doc.appendChild( bbElem );
1194 if ( !boxElem.isNull() )
1198 boxElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1200 bbElem.appendChild( boxElem );
1201 doc.appendChild( bbElem );
1204 response.
write( doc.toByteArray() );
1215 if ( format == QgsWfsParameters::Format::GeoJSON )
1219 fcString += QLatin1String(
" " );
1221 fcString += QLatin1String(
" ," );
1222 mJsonExporter.setSourceCrs( params.crs );
1223 mJsonExporter.setIncludeGeometry(
false );
1224 mJsonExporter.setIncludeAttributes( !params.attributeIndexes.isEmpty() );
1225 mJsonExporter.setAttributes( params.attributeIndexes );
1226 fcString += createFeatureGeoJSON( feature, params, pkAttributes );
1227 fcString += QLatin1String(
"\n" );
1229 response.
write( fcString.toUtf8() );
1233 QDomDocument gmlDoc;
1234 QDomElement featureElement;
1235 if ( format == QgsWfsParameters::Format::GML3 )
1237 featureElement = createFeatureGML3( feature, gmlDoc, params, project, pkAttributes );
1238 gmlDoc.appendChild( featureElement );
1242 featureElement = createFeatureGML2( feature, gmlDoc, params, project, pkAttributes );
1243 gmlDoc.appendChild( featureElement );
1245 response.
write( gmlDoc.toByteArray() );
1255 if ( format == QgsWfsParameters::Format::GeoJSON )
1257 fcString += QLatin1String(
" ]\n" );
1258 fcString += QLatin1Char(
'}' );
1262 fcString = QStringLiteral(
"</wfs:FeatureCollection>\n" );
1264 response.
write( fcString.toUtf8() );
1268 QString createFeatureGeoJSON(
const QgsFeature &feature,
const createFeatureParams ¶ms,
const QgsAttributeList &pkAttributes )
1278 if ( !geom.
isNull() && params.withGeom && params.geometryName != QLatin1String(
"NONE" ) )
1280 mJsonExporter.setIncludeGeometry(
true );
1281 if ( params.geometryName == QLatin1String(
"EXTENT" ) )
1286 else if ( params.geometryName == QLatin1String(
"CENTROID" ) )
1292 return mJsonExporter.exportFeature( f, QVariantMap(),
id );
1296 QDomElement createFeatureGML2(
const QgsFeature &feature, QDomDocument &doc,
const createFeatureParams ¶ms,
const QgsProject *project,
const QgsAttributeList &pkAttributes )
1299 QDomElement featureElement = doc.createElement( QStringLiteral(
"gml:featureMember" ) );
1302 QDomElement typeNameElement = doc.createElement(
"qgs:" + params.typeName );
1304 typeNameElement.setAttribute( QStringLiteral(
"fid" ),
id );
1305 featureElement.appendChild( typeNameElement );
1309 if ( !geom.
isNull() && params.withGeom && params.geometryName != QLatin1String(
"NONE" ) )
1311 int prec = params.precision;
1317 if ( transformed.
transform( mTransform ) == 0 )
1320 crs = params.outputCrs;
1322 prec = std::min( params.precision + 3, 6 );
1330 QDomElement geomElem = doc.createElement( QStringLiteral(
"qgs:geometry" ) );
1331 QDomElement gmlElem;
1333 if ( params.geometryName == QLatin1String(
"EXTENT" ) )
1337 else if ( params.geometryName == QLatin1String(
"CENTROID" ) )
1348 gmlElem = abstractGeom->
asGml2( doc, prec,
"http://www.opengis.net/gml" );
1351 if ( !gmlElem.isNull() )
1354 QDomElement bbElem = doc.createElement( QStringLiteral(
"gml:boundedBy" ) );
1359 boxElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1360 gmlElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1363 bbElem.appendChild( boxElem );
1364 typeNameElement.appendChild( bbElem );
1366 geomElem.appendChild( gmlElem );
1367 typeNameElement.appendChild( geomElem );
1374 for (
int i = 0; i < params.attributeIndexes.count(); ++i )
1376 int idx = params.attributeIndexes[i];
1377 if ( idx >= fields.
count() )
1385 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
1386 QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx], setup ) );
1387 if ( featureAttributes[idx].isNull() )
1389 fieldElem.setAttribute( QStringLiteral(
"xsi:nil" ), QStringLiteral(
"true" ) );
1391 fieldElem.appendChild( fieldText );
1392 typeNameElement.appendChild( fieldElem );
1395 return featureElement;
1398 QDomElement createFeatureGML3(
const QgsFeature &feature, QDomDocument &doc,
const createFeatureParams ¶ms,
const QgsProject *project,
const QgsAttributeList &pkAttributes )
1401 QDomElement featureElement = doc.createElement( QStringLiteral(
"gml:featureMember" ) );
1404 QDomElement typeNameElement = doc.createElement(
"qgs:" + params.typeName );
1406 typeNameElement.setAttribute( QStringLiteral(
"gml:id" ),
id );
1407 featureElement.appendChild( typeNameElement );
1411 if ( !geom.
isNull() && params.withGeom && params.geometryName != QLatin1String(
"NONE" ) )
1413 int prec = params.precision;
1419 if ( transformed.
transform( mTransform ) == 0 )
1422 crs = params.outputCrs;
1424 prec = std::min( params.precision + 3, 6 );
1432 QDomElement geomElem = doc.createElement( QStringLiteral(
"qgs:geometry" ) );
1433 QDomElement gmlElem;
1435 if ( params.geometryName == QLatin1String(
"EXTENT" ) )
1439 else if ( params.geometryName == QLatin1String(
"CENTROID" ) )
1450 gmlElem = abstractGeom->
asGml3( doc, prec,
"http://www.opengis.net/gml" );
1453 if ( !gmlElem.isNull() )
1456 QDomElement bbElem = doc.createElement( QStringLiteral(
"gml:boundedBy" ) );
1461 boxElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1462 gmlElem.setAttribute( QStringLiteral(
"srsName" ),
crs.
authid() );
1465 bbElem.appendChild( boxElem );
1466 typeNameElement.appendChild( bbElem );
1468 geomElem.appendChild( gmlElem );
1469 typeNameElement.appendChild( geomElem );
1476 for (
int i = 0; i < params.attributeIndexes.count(); ++i )
1478 int idx = params.attributeIndexes[i];
1479 if ( idx >= fields.
count() )
1489 QDomElement fieldElem = doc.createElement(
"qgs:" + attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
1490 QDomText fieldText = doc.createTextNode( encodeValueToText( featureAttributes[idx], setup ) );
1491 if ( featureAttributes[idx].isNull() )
1493 fieldElem.setAttribute( QStringLiteral(
"xsi:nil" ), QStringLiteral(
"true" ) );
1495 fieldElem.appendChild( fieldText );
1496 typeNameElement.appendChild( fieldElem );
1499 return featureElement;
1504 if ( value.isNull() )
1507 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
1510 const QVariantMap config = setup.
config();
1511 const QString fieldFormat = config.value( QStringLiteral(
"field_format" ), fieldFormatter.
defaultFormat( value.type() ) ).toString();
1512 QDateTime date = value.toDateTime();
1514 if ( date.isValid() )
1516 return date.toString( fieldFormat );
1519 else if ( setup.
type() == QStringLiteral(
"Range" ) )
1521 const QVariantMap config = setup.
config();
1522 if ( config.contains( QStringLiteral(
"Precision" ) ) )
1526 int precision( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
1528 return QString::number( value.toDouble(),
'f',
precision );
1532 switch ( value.type() )
1535 case QVariant::UInt:
1536 case QVariant::LongLong:
1537 case QVariant::ULongLong:
1538 case QVariant::Double:
1539 return value.toString();
1541 case QVariant::Bool:
1542 return value.toBool() ? QStringLiteral(
"true" ) : QStringLiteral(
"false" );
1544 case QVariant::StringList:
1545 case QVariant::List:
1551 if ( v.indexOf(
'<' ) != -1 || v.indexOf(
'&' ) != -1 )
1552 v.prepend( QStringLiteral(
"<![CDATA[" ) ).append( QStringLiteral(
"]]>" ) );
1558 case QVariant::String:
1560 QString v = value.toString();
1563 if ( v.indexOf(
'<' ) != -1 || v.indexOf(
'&' ) != -1 )
1564 v.prepend( QStringLiteral(
"<![CDATA[" ) ).append( QStringLiteral(
"]]>" ) );