Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions python/PyQt6/server/auto_additions/qgsserverogcapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,30 @@
QgsServerOgcApi.items = QgsServerOgcApi.Rel.items
QgsServerOgcApi.conformance = QgsServerOgcApi.Rel.conformance
QgsServerOgcApi.data = QgsServerOgcApi.Rel.data
QgsServerOgcApi.schema = QgsServerOgcApi.Rel.schema
QgsServerOgcApi.profile = QgsServerOgcApi.Rel.profile
QgsServerOgcApi.Rel.baseClass = QgsServerOgcApi
QgsServerOgcApi.GEOJSON = QgsServerOgcApi.ContentType.GEOJSON
QgsServerOgcApi.OPENAPI3 = QgsServerOgcApi.ContentType.OPENAPI3
QgsServerOgcApi.JSON = QgsServerOgcApi.ContentType.JSON
QgsServerOgcApi.SCHEMA_JSON = QgsServerOgcApi.ContentType.SCHEMA_JSON
QgsServerOgcApi.HTML = QgsServerOgcApi.ContentType.HTML
QgsServerOgcApi.XML = QgsServerOgcApi.ContentType.XML
QgsServerOgcApi.FLATGEOBUF = QgsServerOgcApi.ContentType.FLATGEOBUF
QgsServerOgcApi.ContentType.baseClass = QgsServerOgcApi
# monkey patching scoped based enum
QgsServerOgcApi.Profile.NONE.__doc__ = "No profile"
QgsServerOgcApi.Profile.RFC7946.__doc__ = "GeoJSON profile according to RFC7946"
QgsServerOgcApi.Profile.REL_AS_LINK.__doc__ = "JSON responses that include links for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-link"
QgsServerOgcApi.Profile.REL_AS_KEY.__doc__ = "JSON responses that include key for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-key"
QgsServerOgcApi.Profile.REL_AS_URI.__doc__ = "JSON responses that include URI for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-uri"
QgsServerOgcApi.Profile.__doc__ = """JSON profile

* ``NONE``: No profile
* ``RFC7946``: GeoJSON profile according to RFC7946
* ``REL_AS_LINK``: JSON responses that include links for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-link
* ``REL_AS_KEY``: JSON responses that include key for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-key
* ``REL_AS_URI``: JSON responses that include URI for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-uri

"""
# --
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# The following has been generated automatically from src/server/qgsserverogcapihandler.h
try:
QgsServerOgcApiHandler.profileFromString = staticmethod(QgsServerOgcApiHandler.profileFromString)
QgsServerOgcApiHandler.parentLink = staticmethod(QgsServerOgcApiHandler.parentLink)
QgsServerOgcApiHandler.layerFromCollectionId = staticmethod(QgsServerOgcApiHandler.layerFromCollectionId)
QgsServerOgcApiHandler.__virtual_methods__ = ['parameters', 'tags', 'defaultContentType', 'handleRequest', 'values']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ union of the intervals describes the temporal extent.
.. versionadded:: 3.12
%End


static QgsCoordinateReferenceSystem parseCrs( const QString &bboxCrs );
%Docstring
Parses the CRS URI ``bboxCrs`` (example:
Expand Down
11 changes: 9 additions & 2 deletions python/PyQt6/server/auto_generated/qgsserverogcapi.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,17 @@ as instances of :py:class:`QgsServerOgcApiHandler`.
// In addition the following link relation types are used for which no applicable registered link relation type could be identified:
items,
conformance,
data
data,
schema,
profile
};

enum ContentType /BaseType=IntEnum/
{
GEOJSON,
OPENAPI3,
JSON,
SCHEMA_JSON,
HTML,
XML,
FLATGEOBUF
Expand All @@ -76,6 +79,9 @@ as instances of :py:class:`QgsServerOgcApiHandler`.
// I am very optimistic that it will be supported soon!
// JSONFG, //!< JSON Feature Geometry profile according to OGC API - Features 1.0
// JSONFG_PLUS //!< JSON Feature Geometry profile with GeoJSON compatibility extensions
REL_AS_LINK,
REL_AS_KEY,
REL_AS_URI
};

QgsServerOgcApi( QgsServerInterface *serverIface, const QString &rootPath, const QString &name, const QString &description = QString(), const QString &version = QString() );
Expand Down Expand Up @@ -122,7 +128,8 @@ component that always starts with a slash.

static std::string relToString( const QgsServerOgcApi::Rel &rel );
%Docstring
Returns the string representation of ``rel`` attribute.
Returns the string representation of ``rel`` attribute, to be used or
"rel" link attribute in an OGC API response.
%End

static QString contentTypeToString( const QgsServerOgcApi::ContentType &ct );
Expand Down
22 changes: 22 additions & 0 deletions python/PyQt6/server/auto_generated/qgsserverogcapihandler.sip.in
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,28 @@ default content type of the handler if none of the above matches.
(:py:func:`contentTypes` member)
%End

static QgsServerOgcApi::Profile profileFromString( const QString &profile, bool &ok /Out/ );
%Docstring
Returns the Profile from the string representation in ``profile``, or
Profile.NONE if the string was not recognized.

:param profile: the string representation of the profile, for example
"rel-as-key" or "RFC7946"

:return: - ok: output parameter set to true if the profile string was
recognized, false otherwise

.. versionadded:: 4.2
%End

QList<QgsServerOgcApi::Profile> profilesFromRequest( const QgsServerRequest *request ) const;
%Docstring
Return a list of the profiles in the request, extracted from the
"profile" query parameter.

.. versionadded:: 4.2
%End

static QString parentLink( const QUrl &url, int levels = 1 );
%Docstring
Returns a link to the parent page up to ``levels`` in the HTML hierarchy
Expand Down
6 changes: 5 additions & 1 deletion resources/server/api/ogc/schema.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{ "components" : {
"schemas" : {
"anyObject" : {
"type" : "object",
"description" : "any JSON object"
},
"exception" : {
"required" : [ "code" ],
"type" : "object",
Expand Down Expand Up @@ -294,7 +298,7 @@
}
}
},
"parameters" : {
"parameters" : {
"limit" : {
"name" : "limit",
"in" : "query",
Expand Down
58 changes: 58 additions & 0 deletions resources/server/api/ogc/templates/wfs3/getCollectionSchema.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<!-- template for the WFS3 API collection schema page -->
{% include "header.html" %}

<div class="row">
<div class="col-md-12">
<h1><a title="View items of: {{ title }}" href="{% for link in links %}
{% if link.type == "text/html" and link.rel == "items" %}
{{ link.href }}
{% endif %}
{% endfor %}">{{ title }}</a></h1>
<h3>Schema</h3>

<div>The schema of the feature type describes the "returnables" and "receivables". "Returnables" are feature properties that are returned in responses to a query. "Receivables" are feature properties are feature properties that have to or can be provided by the client in mutation operations (create, replace, or update). Unless otherwise specified, a property is both a returnable and a receivable.</div>
<div>
<dl>
{% for name, property in properties %}
<dt>{{ name }}</dt>
<dd>
<ul class="list-unstyled">
{% if existsIn(property, "role") %}
<li>Special role: {{ property.role }}</li>
{% endif %}
{% if existsIn(property, "type") %}
<li>Data type: {{ property.type }}.</li>
{% endif %}
{% if existsIn(property, "description") %}
<li>{{ property.description }}</li>
{% endif %}
{% if existsIn(property, "format") %}
<li>Format: {{ property.format }}</li>
{% endif %}
{% if existsIn(property, "readOnly") %}
<li>This property is returnable but not receivable.</li>
{% endif %}
</ul>
</dd>
{% endfor %}
</dl>
</div>

<h3>Links</h3>
<ul>
{% for link in links %}
{% if link.rel != "self" %}
<li><a rel="{{ link.rel }}" href="{{ link.href }}">{{ link.title }}</a></li>
{% endif %}
{% endfor %}
</ul>

</div>

<div class="col-md-6">

</div>

</div>

{% include "footer.html" %}
2 changes: 1 addition & 1 deletion src/core/project/qgsproject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2003,7 +2003,7 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList<QDomNode> &broken
}

// It should be safe to delete the layer now if layer was stored, because all the store
// had to to was to reset the data source in case the validity changed.
// had to do was to reset the data source in case the validity changed.
if ( !layerWasStored )
{
mapLayer.release();
Expand Down
2 changes: 2 additions & 0 deletions src/server/qgsbufferserverresponse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ QMap<QString, QString> QgsBufferServerResponse::headers() const
QMap<QString, QString> singleHeaders;
for ( auto it = mHeaders.keyBegin(); it != mHeaders.keyEnd(); ++it )
{
Q_NOWARN_DEPRECATED_PUSH
singleHeaders.insert( *it, header( *it ) );
Q_NOWARN_DEPRECATED_POP
}
return singleHeaders;
}
Expand Down
1 change: 1 addition & 0 deletions src/server/qgsserverapiutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ class SERVER_EXPORT QgsServerApiUtils
*/
static QVariantList temporalExtentList( const QgsVectorLayer *layer ) SIP_PYNAME( temporalExtent );


/**
* Parses the CRS URI \a bboxCrs (example: "http://www.opengis.net/def/crs/OGC/1.3/CRS84") into a QGIS CRS object
*/
Expand Down
37 changes: 30 additions & 7 deletions src/server/qgsserverogcapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ using namespace Qt::StringLiterals;
QMap<QgsServerOgcApi::ContentType, QStringList> QgsServerOgcApi::sContentTypeMime = []() -> QMap<QgsServerOgcApi::ContentType, QStringList> {
QMap<QgsServerOgcApi::ContentType, QStringList> map;
map[QgsServerOgcApi::ContentType::JSON] = QStringList { u"application/json"_s };
map[QgsServerOgcApi::ContentType::SCHEMA_JSON] = QStringList { u"application/schema+json"_s };
map[QgsServerOgcApi::ContentType::GEOJSON] = QStringList { u"application/geo+json"_s, u"application/vnd.geo+json"_s, u"application/geojson"_s };
map[QgsServerOgcApi::ContentType::HTML] = QStringList { u"text/html"_s };
map[QgsServerOgcApi::ContentType::OPENAPI3] = QStringList { u"application/vnd.oai.openapi+json;version=3.0"_s };
Expand All @@ -42,7 +43,7 @@ QMap<QgsServerOgcApi::ContentType, QStringList> QgsServerOgcApi::sContentTypeMim

QHash<QgsServerOgcApi::ContentType, QList<QgsServerOgcApi::ContentType>> QgsServerOgcApi::sContentTypeAliases = []() -> QHash<ContentType, QList<ContentType>> {
QHash<QgsServerOgcApi::ContentType, QList<QgsServerOgcApi::ContentType>> map;
map[ContentType::JSON] = { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::OPENAPI3 };
map[ContentType::JSON] = { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::OPENAPI3, QgsServerOgcApi::ContentType::SCHEMA_JSON };
return map;
}();

Expand Down Expand Up @@ -141,6 +142,12 @@ QString QgsServerOgcApi::profileToString( const Profile &profile )
#endif
case Profile::NONE:
return QString();
case Profile::REL_AS_KEY:
return u"rel-as-key"_s;
case Profile::REL_AS_URI:
return u"rel-as-uri"_s;
case Profile::REL_AS_LINK:
return u"rel-as-link"_s;
}
Q_UNREACHABLE();
return QString();
Expand All @@ -160,6 +167,12 @@ QString QgsServerOgcApi::profileToUri( const Profile &profile )
case Profile::JSONFG_PLUS:
return u"http://www.opengis.net/def/profile/OGC/0/jsonfg-plus"_s;
#endif
case Profile::REL_AS_KEY:
return u"http://www.opengis.net/def/profile/ogc/0/rel-as-key"_s;
case Profile::REL_AS_URI:
return u"http://www.opengis.net/def/profile/ogc/0/rel-as-uri"_s;
case Profile::REL_AS_LINK:
return u"http://www.opengis.net/def/profile/ogc/0/rel-as-link"_s;
case Profile::NONE:
return QString();
}
Expand All @@ -169,6 +182,10 @@ QString QgsServerOgcApi::profileToUri( const Profile &profile )

std::string QgsServerOgcApi::relToString( const Rel &rel )
{
if ( rel == Rel::schema )
{
return "http://www.opengis.net/def/rel/ogc/1.0/schema";
}
static const QMetaEnum metaEnum = QMetaEnum::fromType<QgsServerOgcApi::Rel>();
std::string val { metaEnum.valueToKey( rel ) };
std::replace( val.begin(), val.end(), '_', '-' );
Expand All @@ -190,14 +207,20 @@ std::string QgsServerOgcApi::contentTypeToStdString( const ContentType &ct )

QString QgsServerOgcApi::contentTypeToExtension( const ContentType &ct )
{
const QString extension { contentTypeToString( ct ).toLower() };
// Special case for flatgeobuf, which is a bit too long for
// an extension and has a widely used alternative (fgb)
if ( extension.compare( u"flatgeobuf"_s, Qt::CaseSensitivity::CaseInsensitive ) == 0 )
switch ( ct )
{
return u"fgb"_s;
case ContentType::SCHEMA_JSON:
{
return u"json"_s;
}
case ContentType::FLATGEOBUF:
{
return u"fgb"_s;
}
default:
return contentTypeToString( ct ).toLower();
}
return extension;
// UNREACHABLE CODE
}

QgsServerOgcApi::ContentType QgsServerOgcApi::contentTypeFromExtension( const std::string &extension )
Expand Down
10 changes: 8 additions & 2 deletions src/server/qgsserverogcapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
// In addition the following link relation types are used for which no applicable registered link relation type could be identified:
items, //!< Refers to a resource that is comprised of members of the collection represented by the link’s context.
conformance, //!< The target IRI points to a resource which represents the collection resource for the context IRI.
data //!< The target IRI points to resource data
data, //!< The target IRI points to resource data
schema, //!< "http://www.opengis.net/def/rel/ogc/0.0/schema"
profile //!< "http://www.opengis.net/spec/ogcapi-features-5/0.0/conf/feature-references"
};
Q_ENUM( Rel )

Expand All @@ -78,6 +80,7 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
GEOJSON,
OPENAPI3, //!< "application/openapi+json;version=3.0"
JSON,
SCHEMA_JSON, //! "application/schema+json"
HTML,
XML,
FLATGEOBUF //!< "application/flatgeobuf"
Expand All @@ -93,6 +96,9 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
// I am very optimistic that it will be supported soon!
// JSONFG, //!< JSON Feature Geometry profile according to OGC API - Features 1.0
// JSONFG_PLUS //!< JSON Feature Geometry profile with GeoJSON compatibility extensions
REL_AS_LINK, //!< JSON responses that include links for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-link
REL_AS_KEY, //!< JSON responses that include key for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-key
REL_AS_URI //!< JSON responses that include URI for referenced resources http://www.opengis.net/def/profile/ogc/0/rel-as-uri
};
Q_ENUM( Profile )

Expand Down Expand Up @@ -165,7 +171,7 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
static QUrl sanitizeUrl( const QUrl &url );

/**
* Returns the string representation of \a rel attribute.
* Returns the string representation of \a rel attribute, to be used or "rel" link attribute in an OGC API response.
*/
static std::string relToString( const QgsServerOgcApi::Rel &rel );

Expand Down
Loading
Loading