37 #ifdef HAVE_SERVER_PYTHON_PLUGINS
41 const QDomDocument *describeDocument =
nullptr;
43 #ifdef HAVE_SERVER_PYTHON_PLUGINS
45 if ( cacheManager && cacheManager->
getCachedDocument( &doc, project, request, accessControl ) )
47 describeDocument = &doc;
57 describeDocument = &doc;
61 describeDocument = &doc;
63 response.
setHeader(
"Content-Type",
"text/xml; charset=utf-8" );
64 response.
write( describeDocument->toByteArray() );
76 QgsWfsParameters wfsParameters( QUrlQuery( request.
url() ) );
80 if ( oFormat == QgsWfsParameters::Format::NONE )
82 QStringLiteral(
"OUTPUTFORMAT %1 is not supported" ).arg( wfsParameters.outputFormatAsString() ) );
84 #ifdef HAVE_SERVER_PYTHON_PLUGINS
91 QDomElement schemaElement = doc.createElement( QStringLiteral(
"schema" ) );
92 schemaElement.setAttribute( QStringLiteral(
"xmlns" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
93 schemaElement.setAttribute( QStringLiteral(
"xmlns:xsd" ), QStringLiteral(
"http://www.w3.org/2001/XMLSchema" ) );
94 schemaElement.setAttribute( QStringLiteral(
"xmlns:ogc" ),
OGC_NAMESPACE );
95 schemaElement.setAttribute( QStringLiteral(
"xmlns:gml" ),
GML_NAMESPACE );
96 schemaElement.setAttribute( QStringLiteral(
"xmlns:qgs" ),
QGS_NAMESPACE );
97 schemaElement.setAttribute( QStringLiteral(
"targetNamespace" ),
QGS_NAMESPACE );
98 schemaElement.setAttribute( QStringLiteral(
"elementFormDefault" ), QStringLiteral(
"qualified" ) );
99 schemaElement.setAttribute( QStringLiteral(
"version" ), QStringLiteral(
"1.0" ) );
100 doc.appendChild( schemaElement );
103 QDomElement importElement = doc.createElement( QStringLiteral(
"import" ) );
104 importElement.setAttribute( QStringLiteral(
"namespace" ),
GML_NAMESPACE );
105 if ( oFormat == QgsWfsParameters::Format::GML2 )
106 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/2.1.2/feature.xsd" ) );
107 else if ( oFormat == QgsWfsParameters::Format::GML3 )
108 importElement.setAttribute( QStringLiteral(
"schemaLocation" ), QStringLiteral(
"http://schemas.opengis.net/gml/3.1.1/base/gml.xsd" ) );
109 schemaElement.appendChild( importElement );
111 QStringList typeNameList;
112 QDomDocument queryDoc;
114 if ( queryDoc.setContent( request.
data(),
true, &errorMsg ) )
117 QDomElement queryDocElem = queryDoc.documentElement();
118 QDomNodeList docChildNodes = queryDocElem.childNodes();
119 if ( docChildNodes.size() )
121 for (
int i = 0; i < docChildNodes.size(); i++ )
123 QDomElement docChildElem = docChildNodes.at( i ).toElement();
124 if ( docChildElem.tagName() == QLatin1String(
"TypeName" ) )
126 QString
typeName = docChildElem.text().trimmed();
128 typeNameList <<
typeName.section(
':', 1, 1 );
137 typeNameList = wfsParameters.typeNames();
151 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
155 #ifdef HAVE_SERVER_PYTHON_PLUGINS
158 if ( !typeNameList.isEmpty() )
160 throw QgsSecurityAccessException( QStringLiteral(
"Feature access permission denied" ) );
190 QDomElement elementElem = doc.createElement( QStringLiteral(
"element" ) );
191 elementElem.setAttribute( QStringLiteral(
"name" ),
typeName );
192 elementElem.setAttribute( QStringLiteral(
"type" ),
"qgs:" +
typeName +
"Type" );
193 elementElem.setAttribute( QStringLiteral(
"substitutionGroup" ), QStringLiteral(
"gml:_Feature" ) );
194 parentElement.appendChild( elementElem );
197 QDomElement complexTypeElem = doc.createElement( QStringLiteral(
"complexType" ) );
198 complexTypeElem.setAttribute( QStringLiteral(
"name" ),
typeName +
"Type" );
199 parentElement.appendChild( complexTypeElem );
202 QDomElement complexContentElem = doc.createElement( QStringLiteral(
"complexContent" ) );
203 complexTypeElem.appendChild( complexContentElem );
206 QDomElement extensionElem = doc.createElement( QStringLiteral(
"extension" ) );
207 extensionElem.setAttribute( QStringLiteral(
"base" ), QStringLiteral(
"gml:AbstractFeatureType" ) );
208 complexContentElem.appendChild( extensionElem );
211 QDomElement sequenceElem = doc.createElement( QStringLiteral(
"sequence" ) );
212 extensionElem.appendChild( sequenceElem );
217 QDomElement geomElem = doc.createElement( QStringLiteral(
"element" ) );
218 geomElem.setAttribute( QStringLiteral(
"name" ), QStringLiteral(
"geometry" ) );
225 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PointPropertyType" ) );
229 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:LineStringPropertyType" ) );
233 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:PolygonPropertyType" ) );
237 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPointPropertyType" ) );
240 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiCurveType" ) );
244 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiLineStringPropertyType" ) );
247 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiSurfaceType" ) );
251 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:MultiPolygonPropertyType" ) );
254 geomElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"gml:GeometryPropertyType" ) );
257 geomElem.setAttribute( QStringLiteral(
"minOccurs" ), QStringLiteral(
"0" ) );
258 geomElem.setAttribute( QStringLiteral(
"maxOccurs" ), QStringLiteral(
"1" ) );
259 sequenceElem.appendChild( geomElem );
266 for (
int idx = 0; idx < fields.
count(); ++idx )
269 QString attributeName = field.
name();
271 if ( layerExcludedAttributes.contains( attributeName ) )
277 QDomElement attElem = doc.createElement( QStringLiteral(
"element" ) );
278 attElem.setAttribute( QStringLiteral(
"name" ), attributeName.replace(
' ',
'_' ).replace(
cleanTagNameRegExp, QString() ) );
279 QVariant::Type attributeType = field.
type();
280 if ( attributeType == QVariant::Int )
282 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
284 else if ( attributeType == QVariant::UInt )
286 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedInt" ) );
288 else if ( attributeType == QVariant::LongLong )
290 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"long" ) );
292 else if ( attributeType == QVariant::ULongLong )
294 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"unsignedLong" ) );
296 else if ( attributeType == QVariant::Double )
299 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
301 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
303 else if ( attributeType == QVariant::Bool )
305 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"boolean" ) );
307 else if ( attributeType == QVariant::Date )
309 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
311 else if ( attributeType == QVariant::Time )
313 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
315 else if ( attributeType == QVariant::DateTime )
317 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
321 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"string" ) );
325 if ( setup.
type() == QStringLiteral(
"DateTime" ) )
328 const QVariantMap config = setup.
config();
329 const QString fieldFormat = config.value( QStringLiteral(
"field_format" ), fieldFormatter.
defaultFormat( field.
type() ) ).toString();
330 if ( fieldFormat == QStringLiteral(
"yyyy-MM-dd" ) )
331 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"date" ) );
332 else if ( fieldFormat == QStringLiteral(
"HH:mm:ss" ) )
333 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"time" ) );
335 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"dateTime" ) );
337 else if ( setup.
type() == QStringLiteral(
"Range" ) )
339 const QVariantMap config = setup.
config();
340 if ( config.contains( QStringLiteral(
"Precision" ) ) )
345 int configPrec( config[ QStringLiteral(
"Precision" ) ].toInt( &ok ) );
346 if ( ok && configPrec != field.
precision() )
348 if ( configPrec == 0 )
349 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"integer" ) );
351 attElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"decimal" ) );
358 attElem.setAttribute( QStringLiteral(
"nillable" ), QStringLiteral(
"true" ) );
361 sequenceElem.appendChild( attElem );
363 QString alias = field.
alias();
364 if ( !alias.isEmpty() )
366 attElem.setAttribute( QStringLiteral(
"alias" ), alias );