QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
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 ***************************************************************************/
18
20#include "qgsjsonutils.h"
21#include "qgsproject.h"
23#include "qgsvectorlayer.h"
25#include "qgswfsparameters.h"
26#include "qgswfsutils.h"
27
28#include <QJsonArray>
29#include <QJsonDocument>
30#include <QJsonObject>
31
32using namespace QgsWfs;
33
35 : wfsParameters( wfsParams )
36{}
37
38void QgsWfsDescribeFeatureTypeJson::writeDescribeFeatureType( QgsServerInterface *serverIface, const QgsProject *project, const QString &version, 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, const QgsServerRequest &request ) const
48{
49 Q_UNUSED( version )
50
51
52#ifdef HAVE_SERVER_PYTHON_PLUGINS
53 QgsAccessControl *accessControl = serverIface->accessControls();
54#else
55 ( void ) serverIface;
56#endif
57
58 QJsonObject json;
59 json[QStringLiteral( "elementFormDefault" )] = QStringLiteral( "qualified" );
60 json[QStringLiteral( "targetNamespace" )] = QGS_NAMESPACE;
61 json[QStringLiteral( "targetPrefix" )] = QStringLiteral( "qgs" );
62
63 QJsonArray featureTypes;
64
65 QStringList typeNameList = getRequestTypeNames( request, wfsParameters );
66
67 const QStringList wfsLayerIds = QgsServerProjectUtils::wfsLayerIds( *project );
68 for ( int i = 0; i < wfsLayerIds.size(); ++i )
69 {
70 QgsMapLayer *layer = project->mapLayer( wfsLayerIds.at( i ) );
71 if ( !layer )
72 {
73 continue;
74 }
75
76 const QString name = layer->serverProperties()->wfsTypeName();
77
78 if ( !typeNameList.isEmpty() && !typeNameList.contains( name ) )
79 {
80 continue;
81 }
82#ifdef HAVE_SERVER_PYTHON_PLUGINS
83 if ( accessControl && !accessControl->layerReadPermission( layer ) )
84 {
85 if ( !typeNameList.isEmpty() )
86 {
87 throw QgsSecurityAccessException( QStringLiteral( "Feature access permission denied" ) );
88 }
89 else
90 {
91 continue;
92 }
93 }
94#endif
95 QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer *>( layer );
96 QgsVectorDataProvider *provider = vLayer->dataProvider();
97 if ( !provider )
98 {
99 continue;
100 }
101
102 featureTypes.append( schemaLayerToJson( const_cast<QgsVectorLayer *>( vLayer ) ) );
103 }
104
105 json[QStringLiteral( "featureTypes" )] = featureTypes;
106 return json;
107}
108
109QJsonObject QgsWfsDescribeFeatureTypeJson::schemaLayerToJson( const QgsVectorLayer *layer ) const
110{
111 const QString typeName = layer->serverProperties()->wfsTypeName();
112
113 QJsonObject json;
114 QJsonArray properties;
115
116 json[QStringLiteral( "typeName" )] = typeName;
117
118 if ( layer->isSpatial() )
119 {
120 QString geomType, geomLocalType;
121 getGeometryType( layer, geomType, geomLocalType );
122
123 QJsonObject property;
124 property[QStringLiteral( "name" )] = QStringLiteral( "geometry" );
125 property[QStringLiteral( "minOccurs" )] = QStringLiteral( "0" );
126 property[QStringLiteral( "maxOccurs" )] = QStringLiteral( "1" );
127 property[QStringLiteral( "type" )] = geomType;
128
129
130 if ( !geomLocalType.isEmpty() )
131 {
132 property[QStringLiteral( "localType" )] = geomLocalType;
133 }
134 properties.append( property );
135 }
136
137 //Attributes
138 const QgsFields fields = layer->fields();
139 //hidden attributes for this layer
140 for ( int idx = 0; idx < fields.count(); ++idx )
141 {
142 const QgsField field = fields.at( idx );
143 //skip attribute if excluded from WFS publication
145 {
146 continue;
147 }
148
149 QString attributeName, attributeType;
150
151 // Defined in qgswfsdescribefeaturetype.h
152 getFieldAttributes( field, attributeName, attributeType );
153
154 QJsonObject property;
155 property[QStringLiteral( "name" )] = attributeName;
156 property[QStringLiteral( "type" )] = attributeType;
157 property[QStringLiteral( "localType" )] = attributeType;
158
160 {
161 property[QStringLiteral( "nillable" )] = "true";
162 }
163
164 const QString alias = field.alias();
165 if ( !alias.isEmpty() )
166 {
167 property[QStringLiteral( "alias" )] = alias;
168 }
169
170 properties.append( property );
171 }
172
173 json[QStringLiteral( "properties" )] = properties;
174 return json;
175}
176
177void QgsWfsDescribeFeatureTypeJson::getGeometryType( const QgsVectorLayer *layer, QString &geomType, QString &geomLocalType ) const
178{
179 const Qgis::WkbType wkbType = layer->wkbType();
180 switch ( wkbType )
181 {
184 geomType = QStringLiteral( "gml:PointPropertyType" );
185 geomLocalType = QStringLiteral( "Point" );
186 break;
187
190 geomType = QStringLiteral( "gml:LineStringPropertyType" );
191 geomLocalType = QStringLiteral( "LineString" );
192 break;
193
196 geomType = QStringLiteral( "gml:PolygonPropertyType" );
197 geomLocalType = QStringLiteral( "Polygon" );
198 break;
199
202 geomType = QStringLiteral( "gml:MultiPointPropertyType" );
203 geomLocalType = QStringLiteral( "MultiPoint" );
204 break;
205
209 geomType = QStringLiteral( "gml:MultiCurvePropertyType" );
210 geomLocalType = QStringLiteral( "MultiCurve" );
211 break;
212
216 geomType = QStringLiteral( "gml:MultiSurfacePropertyType" );
217 geomLocalType = QStringLiteral( "MultiSurface" );
218 break;
219
220 default:
221 geomType = QStringLiteral( "gml:GeometryPropertyType" );
222 }
223}
WkbType
The WKB type describes the number of dimensions a geometry has.
Definition qgis.h:277
@ LineString25D
LineString25D.
Definition qgis.h:341
@ Point
Point.
Definition qgis.h:279
@ LineString
LineString.
Definition qgis.h:280
@ MultiPolygon25D
MultiPolygon25D.
Definition qgis.h:345
@ MultiPoint
MultiPoint.
Definition qgis.h:283
@ Polygon
Polygon.
Definition qgis.h:281
@ MultiLineString25D
MultiLineString25D.
Definition qgis.h:344
@ MultiPolygon
MultiPolygon.
Definition qgis.h:285
@ MultiLineString
MultiLineString.
Definition qgis.h:284
@ MultiPoint25D
MultiPoint25D.
Definition qgis.h:343
@ MultiCurve
MultiCurve.
Definition qgis.h:290
@ Point25D
Point25D.
Definition qgis.h:340
@ MultiSurface
MultiSurface.
Definition qgis.h:291
@ Polygon25D
Polygon25D.
Definition qgis.h:342
@ HideFromWfs
Field is not available if layer is served as WFS from QGIS server.
Definition qgis.h:1725
A helper class that centralizes restrictions given by all the access control filter plugins.
@ ConstraintNotNull
Field may not be null.
Qgis::FieldConfigurationFlags configurationFlags
Definition qgsfield.h:67
QString alias
Definition qgsfield.h:64
QgsFieldConstraints constraints
Definition qgsfield.h:66
int count
Definition qgsfields.h:50
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
QString wfsTypeName() const
Returns WFS typename for the layer.
Base class for all map layer types.
Definition qgsmaplayer.h:80
QgsMapLayerServerProperties * serverProperties()
Returns QGIS Server Properties for the map layer.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:109
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Defines interfaces exposed by QGIS Server and made available to plugins.
virtual QgsAccessControl * accessControls() const =0
Gets the registered access control filters.
static QStringList wfsLayerIds(const QgsProject &project)
Returns the Layer ids list defined in a QGIS project as published in WFS.
Defines requests passed to QgsService classes.
Defines the response interface passed to QgsService.
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...
Represents a vector layer which manages a vector based dataset.
bool isSpatial() const final
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
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.
Provides an interface to retrieve and manipulate WFS parameters received from the client.
WMS implementation.
Definition qgswfs.cpp:36
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:72
QStringList getRequestTypeNames(const QgsServerRequest &request, const QgsWfsParameters &wfsParams)
Helper for returning typename list from the request.