QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgswfsdescribefeaturetypejson.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgswfsdescribefeaturetypegeojson.cpp
3 ------------------------------------
4 begin : December 09 , 2022
5 copyright : (C) 2022 by David Marteau
6 email : david dot marteau at 3liz dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17#include "qgswfsutils.h"
21#include "qgswfsparameters.h"
22#include "qgsjsonutils.h"
23#include "qgsproject.h"
24#include "qgsvectorlayer.h"
26
27#include <QJsonObject>
28#include <QJsonArray>
29#include <QJsonDocument>
30
31using namespace QgsWfs;
32
34 : wfsParameters( wfsParams )
35{}
36
37void QgsWfsDescribeFeatureTypeJson::writeDescribeFeatureType( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
38 const QgsServerRequest &request, QgsServerResponse &response ) const
39{
40 const QJsonDocument doc( createDescribeFeatureTypeDocument( serverIface, project, version, request ) );
41
42 response.setHeader( "Content-Type", "application/vnd.geo+json; charset=utf-8" );
43 response.write( doc.toJson( QJsonDocument::Compact ) );
44}
45
46
47QJsonObject QgsWfsDescribeFeatureTypeJson::createDescribeFeatureTypeDocument( QgsServerInterface *serverIface, const QgsProject *project, const QString &version,
48 const QgsServerRequest &request ) const
49{
50 Q_UNUSED( version )
51
52
53#ifdef HAVE_SERVER_PYTHON_PLUGINS
54 QgsAccessControl *accessControl = serverIface->accessControls();
55#else
56 ( void )serverIface;
57#endif
58
59 QJsonObject json;
60 json[QStringLiteral( "elementFormDefault" )] = QStringLiteral( "qualified" );
61 json[QStringLiteral( "targetNamespace" )] = QGS_NAMESPACE;
62 json[QStringLiteral( "targetPrefix" )] = QStringLiteral( "qgs" );
63
64 QJsonArray featureTypes;
65
66 QStringList typeNameList = getRequestTypeNames( request, wfsParameters );
67
68 const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
69 for ( int i = 0; i < wfsLayerIds.size(); ++i )
70 {
71 QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) );
72 if ( !layer )
73 {
74 continue;
75 }
76
77 const QString name = layerTypeName( layer );
78
79 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
80 {
81 continue;
82 }
83#ifdef HAVE_SERVER_PYTHON_PLUGINS
84 if ( accessControl && !accessControl->layerReadPermission( layer ) )
85 {
86 if ( !typeNameList.isEmpty() )
87 {
88 throw QgsSecurityAccessException( QStringLiteral( "Feature access permission denied" ) );
89 }
90 else
91 {
92 continue;
93 }
94 }
95#endif
96 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer );
97 QgsVectorDataProvider *provider = vLayer->dataProvider();
98 if ( !provider )
99 {
100 continue;
101 }
102
103 featureTypes.append( schemaLayerToJson( const_cast<QgsVectorLayer *>( vLayer ) ) );
104 }
105
106 json[QStringLiteral( "featureTypes" )] = featureTypes;
107 return json;
108}
109
110QJsonObject QgsWfsDescribeFeatureTypeJson::schemaLayerToJson( const QgsVectorLayer *layer ) const
111{
112 const QString typeName = layerTypeName( layer );
113
114 QJsonObject json;
115 QJsonArray properties;
116
117 json[QStringLiteral( "typeName" )] = typeName;
118
119 if ( layer->isSpatial() )
120 {
121 QString geomType, geomLocalType;
122 getGeometryType( layer, geomType, geomLocalType );
123
124 QJsonObject property;
125 property[QStringLiteral( "name" )] = QStringLiteral( "geometry" );
126 property[QStringLiteral( "minOccurs" )] = QStringLiteral( "0" );
127 property[QStringLiteral( "maxOccurs" )] = QStringLiteral( "1" );
128 property[QStringLiteral( "type" )] = geomType;
129
130
131 if ( !geomLocalType.isEmpty() )
132 {
133 property[QStringLiteral( "localType" )] = geomLocalType;
134 }
135 properties.append( property );
136 }
137
138 //Attributes
139 const QgsFields fields = layer->fields();
140 //hidden attributes for this layer
141 for ( int idx = 0; idx < fields.count(); ++idx )
142 {
143 const QgsField field = fields.at( idx );
144 //skip attribute if excluded from WFS publication
146 {
147 continue;
148 }
149
150 QString attributeName, attributeType;
151
152 // Defined in qgswfsdescribefeaturetype.h
153 getFieldAttributes( field, attributeName, attributeType );
154
155 QJsonObject property;
156 property[QStringLiteral( "name" )] = attributeName;
157 property[QStringLiteral( "type" )] = attributeType;
158 property[QStringLiteral( "localType" )] = attributeType;
159
160 if ( !( field.constraints().constraints() & QgsFieldConstraints::Constraint::ConstraintNotNull ) )
161 {
162 property[QStringLiteral( "nillable" )] = "true";
163 }
164
165 const QString alias = field.alias();
166 if ( !alias.isEmpty() )
167 {
168 property[QStringLiteral( "alias" )] = alias;
169 }
170
171 properties.append( property );
172 }
173
174 json[QStringLiteral( "properties" )] = properties;
175 return json;
176}
177
178void QgsWfsDescribeFeatureTypeJson::getGeometryType( const QgsVectorLayer *layer, QString &geomType, QString &geomLocalType ) const
179{
180 const Qgis::WkbType wkbType = layer->wkbType();
181 switch ( wkbType )
182 {
185 geomType = QStringLiteral( "gml:PointPropertyType" );
186 geomLocalType = QStringLiteral( "Point" );
187 break;
188
191 geomType = QStringLiteral( "gml:LineStringPropertyType" );
192 geomLocalType = QStringLiteral( "LineString" );
193 break;
194
197 geomType = QStringLiteral( "gml:PolygonPropertyType" );
198 geomLocalType = QStringLiteral( "Polygon" );
199 break;
200
203 geomType = QStringLiteral( "gml:MultiPointPropertyType" );
204 geomLocalType = QStringLiteral( "MultiPoint" );
205 break;
206
210 geomType = QStringLiteral( "gml:MultiCurvePropertyType" );
211 geomLocalType = QStringLiteral( "MultiCurve" );
212 break;
213
217 geomType = QStringLiteral( "gml:MultiSurfacePropertyType" );
218 geomLocalType = QStringLiteral( "MultiSurface" );
219 break;
220
221 default:
222 geomType = QStringLiteral( "gml:GeometryPropertyType" );
223 }
224}
225
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition: qgis.h:182
@ LineString25D
LineString25D.
@ LineString
LineString.
@ MultiPolygon25D
MultiPolygon25D.
@ MultiPoint
MultiPoint.
@ Polygon
Polygon.
@ MultiLineString25D
MultiLineString25D.
@ MultiPolygon
MultiPolygon.
@ MultiLineString
MultiLineString.
@ MultiPoint25D
MultiPoint25D.
@ MultiCurve
MultiCurve.
@ Point25D
Point25D.
@ MultiSurface
MultiSurface.
@ Polygon25D
Polygon25D.
@ HideFromWfs
Field is not available if layer is served as WFS from QGIS server.
A helper class that centralizes restrictions given by all the access control filter plugins.
Q_GADGET Constraints constraints
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:53
Qgis::FieldConfigurationFlags configurationFlags
Definition: qgsfield.h:66
QString alias
Definition: qgsfield.h:63
QgsFieldConstraints constraints
Definition: qgsfield.h:65
Container of fields for a vector layer.
Definition: qgsfields.h:45
int count() const
Returns number of items.
Definition: qgsfields.cpp:133
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
Definition: qgsfields.cpp:163
Base class for all map layer types.
Definition: qgsmaplayer.h:75
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:107
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
QgsServerResponse Class defining response interface passed to services QgsService::executeRequest() m...
virtual void write(const QString &data)
Write string This is a convenient method that will write directly to the underlying I/O device.
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...
This is the base class for vector data providers.
Represents a vector layer which manages a vector based data sets.
bool isSpatial() const FINAL
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Q_INVOKABLE Qgis::WkbType wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
QgsWfsDescribeFeatureTypeJson(const QgsWfs::QgsWfsParameters wfsParams)
Constructor.
void writeDescribeFeatureType(QgsServerInterface *serverIface, const QgsProject *project, const QString &version, const QgsServerRequest &request, QgsServerResponse &response) const
Output GeoJson response.
Exception thrown when data access violates access controls.
Provides an interface to retrieve and manipulate WFS parameters received from the client.
SERVER_EXPORT QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
WMS implementation.
Definition: qgswfs.cpp:36
QString layerTypeName(const QgsMapLayer *layer)
Returns typename from vector layer.
Definition: qgswfsutils.cpp:68
void getFieldAttributes(const QgsField &field, QString &fieldName, QString &fieldType)
Helper for returning the field type and type name.
const QString QGS_NAMESPACE
Definition: qgswfsutils.h:77
QStringList getRequestTypeNames(const QgsServerRequest &request, const QgsWfsParameters &wfsParams)
Helper for returning typename list from the request.
const QString & typeName