diff --git a/CHANGELOG.md b/CHANGELOG.md index 99ca80a49..4a3872a6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -211,7 +211,7 @@ - If you are using environment variable [`OAUTH2_CALLBACK_URL`](doc/env-settings.md#oauth2_callback_url), change only its URL path from `/client/authn/oauth2-liferay/callback` to `/client/authn/oauth2-provider/callback`. Keep protocol, domain, and port unchanged. - Stop using environment variable `LAYMAN_AUTHN_OAUTH2_PROVIDERS`, it has no effect to Layman anymore. There is exactly one OAuth2 provider Python module now, no need to set it. - Stop using environment variable `FLASK_ENV`, it has no effect to Layman anymore. - - If you used environment variable `FLASK_ENV` with value `development`, add new environment variable [`FLASK_DEBUG`](https://flask.palletsprojects.com/en/2.3.x/config/?highlight=flask_debug#DEBUG): + - If you used environment variable `FLASK_ENV` with value `development`, add new environment variable [`FLASK_DEBUG`](https://flask.palletsprojects.com/en/stable/config/?highlight=flask_debug#DEBUG): ``` FLASK_DEBUG=1 ``` @@ -580,10 +580,10 @@ make timgen-build ### Changes - [#167](https://github.com/LayerManager/layman/issues/167) Allow publishing also raster geospatial data using [POST Workspace Layers](doc/rest.md#post-workspace-layers) and [PATCH Workspace Layer](doc/rest.md#patch-workspace-layer). - Following formats are supported: - - [GeoTIFF](https://gdal.org/drivers/raster/gtiff.html) - - [JPEG2000](https://gdal.org/drivers/raster/jp2openjpeg.html) - - [PNG](https://gdal.org/drivers/raster/png.html) - - [JPEG](https://gdal.org/drivers/raster/jpeg.html) + - [GeoTIFF](https://gdal.org/en/stable/drivers/raster/gtiff.html) + - [JPEG2000](https://gdal.org/en/stable/drivers/raster/jp2openjpeg.html) + - [PNG](https://gdal.org/en/stable/drivers/raster/png.html) + - [JPEG](https://gdal.org/en/stable/drivers/raster/jpeg.html) - Following input combinations of bands and color interpretations are supported: - 1 band: Gray - 1 band: Palette @@ -743,7 +743,7 @@ make timgen-build - Parameter *style* accepts also QGIS layer style (QML). Layman Test Client enables to select also `*.qml` files. - Endpoint [GET Workspace Layer](doc/rest.md#get-workspace-layer) returns in `style` attribute also `type`, either `"sld"` or `"qml"`. - Endpoint [GET Workspace Layer Style](doc/rest.md#get-workspace-layer-style) returns SLD style or QML style. - - Treat attribute names in QML (also known as '[launder](https://gdal.org/drivers/vector/pg.html#layer-creation-options)'). + - Treat attribute names in QML (also known as '[launder](https://gdal.org/en/stable/drivers/vector/pg.html#layer-creation-options)'). - New docker container with QGIS server called `qgis` in demo configuration. - New directory [LAYMAN_QGIS_DATA_DIR](doc/env-settings.md#LAYMAN_QGIS_DATA_DIR) is used to store [layer QGS files](doc/data-storage.md#filesystem). - [WMS](doc/endpoints.md#web-map-service) is moved to dedicated [GeoServer workspace](doc/data-storage.md#geoserver) whose name is composed from Layman's [workspace](doc/models.md#workspace) name and suffix `_wms`. [WFS](doc/endpoints.md#web-feature-service) remains in GeoServer workspace whose name is equal to Layman's workspace name. diff --git a/README.md b/README.md index 421a370b7..9bc88df4d 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,8 @@ Publishing geospatial data online through [REST API](doc/rest.md). - [**layer**](doc/models.md#layer): visual representation of single vector or raster dataset, including raster [timeseries](doc/models.md#timeseries) - [**map**](doc/models.md#map): collection of layers - Accepts **vector** layer data in [GeoJSON](https://en.wikipedia.org/wiki/GeoJSON), [ShapeFile](https://en.wikipedia.org/wiki/Shapefile), or [PostGIS table](https://postgis.net/) identified by [PostgreSQL connection URI](https://www.postgresql.org/docs/15/libpq-connect.html#id-1.7.3.8.3.6) -- Accepts **raster** layer data in [GeoTIFF](https://gdal.org/drivers/raster/gtiff.html), [JPEG2000](https://gdal.org/drivers/raster/jp2openjpeg.html), [PNG](https://gdal.org/drivers/raster/png.html), and [JPEG](https://gdal.org/drivers/raster/jpeg.html) formats -- Accepts layer **style** in [Styled Layer Descriptor](https://ogc.org/standard/sld), [Symbology Encoding](https://ogc.org/standard/se), and [QGIS Style File Format](https://docs.qgis.org/3.16/en/docs/user_manual/appendices/qgis_file_formats.html#qml-the-qgis-style-file-format) (for vector data only) formats +- Accepts **raster** layer data in [GeoTIFF](https://gdal.org/en/stable/drivers/raster/gtiff.html), [JPEG2000](https://gdal.org/en/stable/drivers/raster/jp2openjpeg.html), [PNG](https://gdal.org/en/stable/drivers/raster/png.html), and [JPEG](https://gdal.org/en/stable/drivers/raster/jpeg.html) formats +- Accepts layer **style** in [Styled Layer Descriptor](https://www.ogc.org/publications/standard/sld/), [Symbology Encoding](https://www.ogc.org/publications/standard/se/), and [QGIS Style File Format](https://docs.qgis.org/3.16/en/docs/user_manual/appendices/qgis_file_formats.html#qml-the-qgis-style-file-format) (for vector data only) formats - Accepts **map** definition in [HSLayers Map Composition](https://github.com/hslayers/map-compositions) format - Even large files can be easily uploaded from browser thanks to asynchronous chunk upload - [OAuth2 authentication](doc/security.md#authentication) @@ -35,7 +35,7 @@ Publishing geospatial data online through [REST API](doc/rest.md). You can check your kernel version with `uname -r`. - Docker Engine v20.10.13+ including Docker Compose v2+ - - installation instructions for [centos 7](https://docs.docker.com/install/linux/docker-ce/centos/), including docker-compose-plugin installation + - installation instructions for [centos 7](https://docs.docker.com/engine/install/centos/), including docker-compose-plugin installation **Optionally** - linux or any tool to run tasks defined in Makefile using `make` command @@ -106,7 +106,7 @@ Then you can log in with automatically provided Wagtail user `layman` and passwo Layman's source code provides settings suitable for development, testing and demo purposes. Furthermore, there exists [`Makefile`](Makefile) with predefined commands for each purpose including starting all necessary services (both in background and foreground) and stoping it. Layman's configuration is split into three levels: -- `docker-compose.*.yml` files used as [docker-compose configuration files](https://docs.docker.com/compose/compose-file/) with most general settings of docker containers including volume mappings, port mappings, container names and startup commands +- `docker-compose.*.yml` files used as [docker-compose configuration files](https://docs.docker.com/reference/compose-file/) with most general settings of docker containers including volume mappings, port mappings, container names and startup commands - `.env*` files with environment settings of both build stage and runtime of docker containers - `src/layman_settings.py` Python module with settings of Layman's Python modules for runtime @@ -170,7 +170,7 @@ When providing **external dependencies**, check their production-related documen - [PostgreSQL 13.3](https://www.postgresql.org/docs/13/admin.html) & [PostGIS 3.1](http://postgis.net/docs/manual-3.1/performance_tips.html) - [QGIS Server 3.16.1](https://docs.qgis.org/3.10/en/docs/user_manual/working_with_ogc/server/index.html) - [GeoServer 2.21.2](https://geoserver.org/release/2.21.2/) -- [Redis 4.0](https://redis.io/topics/admin) +- [Redis 4.0](https://redis.io/docs/latest/operate/oss_and_stack/management/admin/) - [Micka v2020.014](https://github.com/hsrs-cz/Micka/releases/tag/v2020.014), see also [configuration](deps/micka/sample/confs/config.local.neon) of [dockerized Micka](https://github.com/LayerManager/docker-micka). Within PostgreSQL, you need to provide one database for Layman and one database for Micka. For Layman, you also need to provide one user [LAYMAN_PG_USER](doc/env-settings.md#LAYMAN_PG_USER) who needs enough privileges to create new schemas in [LAYMAN_PG_DBNAME](doc/env-settings.md#LAYMAN_PG_DBNAME) database. The user also needs access to `public` schema where PostGIS must be installed. @@ -190,8 +190,8 @@ After providing external dependencies there is time to provide **internal depend **System-level** dependencies includes - python 3.8+ - [python3-lxml](https://lxml.de/installation.html) -- [ogr2ogr](https://gdal.org/programs/ogr2ogr.html) utility of [gdal](https://gdal.org/) 3.3+ -- [chromium-browser](https://chromium.org/) 90+ and corresponding version of [chromedriver](https://chromedriver.chromium.org/) +- [ogr2ogr](https://gdal.org/en/stable/programs/ogr2ogr.html) utility of [gdal](https://gdal.org/) 3.3+ +- [chromium-browser](https://www.chromium.org/) 90+ and corresponding version of [chromedriver](https://developer.chrome.com/docs/chromedriver/) - [pipenv](https://pypi.org/project/pipenv/) - [node.js](https://nodejs.org/) 18 & npm 8 for running Layman Test Client - [node.js](https://nodejs.org/) 16 & npm 8 for running Timgen diff --git a/doc/dependencies.md b/doc/dependencies.md index 56b204dcb..af70d5e9f 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -35,12 +35,12 @@ | --- | --- | --- | --- | --- | --- | | [flask](http://flask.pocoo.org/) | BSD License | Pipfile | prod | bin | to build REST API | | [celery](https://github.com/celery/celery) | BSD 3-Clause | Pipfile | prod | bin | asynchronous task runner | -| [redis-py](https://github.com/andymccurdy/redis-py) | MIT | Pipfile | prod | bin | | +| [redis-py](https://github.com/redis/redis-py) | MIT | Pipfile | prod | bin | | | [unidecode](https://github.com/avian2/unidecode) | GNU GPL v2 | Pipfile | prod | bin | | | [psycopg2-binary](https://github.com/psycopg/psycopg2) | GNU LGPL | Pipfile | prod | bin | | | [requests](https://requests.readthedocs.io/) | Apache License 2.0 | Pipfile | prod | bin | | | [owslib](https://github.com/geopython/OWSLib) | BSD 3-Clause | Pipfile | prod | bin | | -| [jsonschema](https://github.com/Julian/jsonschema) | MIT | Pipfile | prod | bin | | +| [jsonschema](https://github.com/python-jsonschema/jsonschema) | MIT | Pipfile | prod | bin | | | [flower](https://github.com/mher/flower) | BSD 3-Clause | Pipfile | prod | bin | to monitor celery tasks | | [selenium](https://www.chromium.org/) | Apache License 2.0 | Dockerfile | prod | bin | for client-side map rendering and integration testing | | [cacheout](https://github.com/dgilland/cacheout) | MIT | Pipfile | prod | bin | | @@ -51,7 +51,7 @@ | [pytest](https://pytest.org/) | MIT License | Pipfile | test | bin | | | [flake8](https://flake8.pycqa.org/) | MIT | Pipfile | test | bin | code style checker | | [pycodestyle](https://pycodestyle.pycqa.org/) | MIT | Pipfile | test | bin | code style checker | -| [pylint](https://github.com/PyCQA/pylint) | GNU GPL v2 | Pipfile | test | bin | code style checker | +| [pylint](https://github.com/pylint-dev/pylint) | GNU GPL v2 | Pipfile | test | bin | code style checker | | [autopep8](https://github.com/hhatto/autopep8) | MIT | Pipfile | test | bin | to automatically fix code style | | [pytest-rerunfailures](https://github.com/pytest-dev/pytest-rerunfailures) | MPL | Pipfile | test | bin | to automatically rerun flaky tests | | [pytest-timeout](https://pypi.org/project/pytest-timeout/) | MIT | Pipfile | test | bin | to automatically stop tests after given timeout | @@ -89,5 +89,5 @@ | [layermanager/docker-postgis](https://github.com/layermanager/docker-postgis) | MIT | docker-compose.yml | dev | bin | | | [jirikcz/micka](https://github.com/LayerManager/docker-micka) | GNU GPL v3 | docker-compose.yml | prod-external | bin | | | [samtux/micka](https://github.com/samtux/docker-micka) | GNU GPL v3 | jirikcz/micka | prod-external | src | | -| [docker-library/redis](https://github.com/docker-library/redis) | BSD 3-Clause | docker-compose.yml | prod | bin | | +| [docker-library/redis](https://github.com/redis/docker-library-redis) | BSD 3-Clause | docker-compose.yml | prod | bin | | | [plantuml/plantuml](https://hub.docker.com/r/plantuml/plantuml) | GNU GPL v3 | Makefile | dev | bin | render PlantUML images | diff --git a/doc/endpoints.md b/doc/endpoints.md index 125267cd8..2cbe15056 100644 --- a/doc/endpoints.md +++ b/doc/endpoints.md @@ -2,7 +2,7 @@ To use [headers for GeoServer's Proxy URL](https://docs.geoserver.org/2.21.x/en/user/configuration/globalsettings.html#use-headers-for-proxy-url) see [client proxy documentation](client-proxy.md). ## Web Map Service -[Web Map Service (WMS)](https://ogc.org/standard/wms) endpoint is implemented using combination of Layman's authentication proxy, Layman's WMS proxy, and [GeoServer](https://docs.geoserver.org/2.21.x/en/user/services/wms/reference.html). +[Web Map Service (WMS)](https://www.ogc.org/publications/standard/wms/) endpoint is implemented using combination of Layman's authentication proxy, Layman's WMS proxy, and [GeoServer](https://docs.geoserver.org/2.21.x/en/user/services/wms/reference.html). The authentication proxy understands same [authentication credentials](security.md#authentication) as Layman REST API (e.g. OAuth2 credentials) and passes the request to GeoServer with credentials understandable by GeoServer. @@ -15,7 +15,7 @@ WMS respects [publication access rights](security.md#publication-access-rights). GetLegendGraphic query is answered directly by GeoServer for layers with SLD style and can be parametrized according to [GeoServer documentation](https://docs.geoserver.org/latest/en/user/services/wms/get_legend_graphic/index.html). For layers with QML style is such query redirected by GeoServer to QGIS server and can be parametrized according to [QGIS documentation](https://docs.qgis.org/3.16/en/docs/server_manual/services.html?highlight=getlegendgraphic#getlegendgraphics). ## Web Feature Service -[Web Feature Service (WFS)](https://ogc.org/standard/wfs) endpoint is implemented using combination of Layman's authentication proxy, Layman's WFS proxy, and [GeoServer](https://docs.geoserver.org/2.21.x/en/user/services/wfs/reference.html). +[Web Feature Service (WFS)](https://www.ogc.org/publications/standard/wfs/) endpoint is implemented using combination of Layman's authentication proxy, Layman's WFS proxy, and [GeoServer](https://docs.geoserver.org/2.21.x/en/user/services/wfs/reference.html). The authentication proxy behaves in the same way as in case of [WMS](#web-map-service). @@ -31,4 +31,4 @@ WFS respects [publication access rights](security.md#publication-access-rights). For layers in `EPSG:5514` and WFS requests in `CRS:84`, the features may have wrong coordinates by hundreds of meters. For requests in `EPSG:4326`, coordinates are correct. ## Catalogue Service -[Catalogue Service (CSW)](https://ogc.org/standard/cat) is implemented using [Micka](https://github.com/hsrs-cz/Micka). +[Catalogue Service (CSW)](https://www.ogc.org/publications/standard/cat/) is implemented using [Micka](https://github.com/hsrs-cz/Micka). diff --git a/doc/env-settings.md b/doc/env-settings.md index b313ad429..b3a058204 100644 --- a/doc/env-settings.md +++ b/doc/env-settings.md @@ -109,7 +109,7 @@ Internal URL of REST API [Current User](rest.md#current-user) endpoint. Internal URL (only protocol & host & port, without path) of Layman's REST API. ### LTC_REDIS_URL -URL of [Redis logical database](https://redis.io/commands/select) including database number where Layman Test Client stores user sessions including authentication credentials. +URL of [Redis logical database](https://redis.io/docs/latest/commands/select/) including database number where Layman Test Client stores user sessions including authentication credentials. ### LTC_SESSION_SECRET See [`secret` at express-session documentation](https://www.npmjs.com/package/express-session#secret). @@ -126,7 +126,7 @@ To enable not-so-secure SSL communication (UnsafeLegacyRenegotiation), set `NODE ## Connection to Redis ### LAYMAN_REDIS_URL -URL of [Redis logical database](https://redis.io/commands/select) including database number. Layman stores internal data about publications and users in this database. By default, Layman flushes the whole logical database on every startup! See also [LAYMAN_SKIP_REDIS_LOADING](#LAYMAN_SKIP_REDIS_LOADING). +URL of [Redis logical database](https://redis.io/docs/latest/commands/select/) including database number. Layman stores internal data about publications and users in this database. By default, Layman flushes the whole logical database on every startup! See also [LAYMAN_SKIP_REDIS_LOADING](#LAYMAN_SKIP_REDIS_LOADING). ## Connection to PostgreSQL @@ -197,10 +197,10 @@ Filesystem directory where data published on QGIS are stored, including styles. HTTP Basic Authentication credentials for communication with [CSW](#CSW_URL) encoded as `user:password`. ### CSW_URL -Internal URL of [OGC Catalogue Service v2.0.2](https://ogc.org/standard/cat) endpoint. Tested with [Micka](http://micka.bnhelp.cz/). +Internal URL of [OGC Catalogue Service v2.0.2](https://www.ogc.org/publications/standard/cat/) endpoint. Tested with [Micka](https://www.bnhelp.cz/produkty/metadata/). ### CSW_PROXY_URL -Public URL of [OGC Catalogue Service v2.0.2](https://ogc.org/standard/cat) endpoint. Tested with [Micka](http://micka.bnhelp.cz/). +Public URL of [OGC Catalogue Service v2.0.2](https://www.ogc.org/publications/standard/cat/) endpoint. Tested with [Micka](https://www.bnhelp.cz/produkty/metadata/). ### MICKA_ACCEPTED_VERSION Version of Micka that Layman will accept on startup encoded as `version:revision`, e.g. `2020.014:2020-04-15.01`. Also, on one of '>=' or '==' prefixes can be used with obvious meaning, `e.g. >=2020.014:2020-04-15.01`. For prefix '>=', version and revision are compared independently as strings. If the variable is not set, a version defined in [`src/layman_settings.py`](../src/layman_settings.py) will be accepted. If none prefix is used, value is compared as with '=='. @@ -214,10 +214,10 @@ String with public domain and optionally port, e.g. `` or `:"`. +**Authorization** header contains access token according to [RFC6750 Bearer Token Usage](https://datatracker.ietf.org/doc/html/rfc6750#section-2.1). Structure of its value is `"Bearer "`. Because access token is known only on server side of LTC and not to client side, every request from client side to Layman REST API goes through **proxy** on LTC server side. The proxy adds `Authorization` header to the request and forward it to the Layman. To authenticate end-user, Layman then validates access token on *authorization server* using [Token Introspection](https://oauth.net/2/token-introspection/) mechanism. @@ -87,7 +87,7 @@ Username is reserved by [PATCH Current User](../rest.md#patch-current-user). Use ![patch-current-user.puml](patch-current-user.png) ### Refresh Access Token -During end-user's session, *client* keeps both access tokens and refresh token. When access token expires or it's lifetime is close, *client* should use refresh token to generate new access token at [Token Endpoint](https://tools.ietf.org/html/rfc6749#section-3.2). +During end-user's session, *client* keeps both access tokens and refresh token. When access token expires or it's lifetime is close, *client* should use refresh token to generate new access token at [Token Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.2). In case of LTC, refreshing happens automatically on any request to Layman REST API if access token expired, or it's lifetime is closer than 10 seconds. @@ -112,7 +112,7 @@ Sample values for OAuth2 authentication can be found in [`layman_settings.py`](. ### Django OAuth Toolkit Settings Every *client* must be registered in Django OAuth Toolkit (Wagtail) as *application*, as described in [documentation](https://django-oauth-toolkit.readthedocs.io/en/latest/getting_started.html#oauth2-authorization-grants). For LTC, fill in following settings: -- **Redirect URIs** must contain URL of OAuth2 [Redirection Endpoint](https://tools.ietf.org/html/rfc6749#section-3.1.2). In case of LTC, the value is the same as LTC setting OAUTH2_CALLBACK_URL. +- **Redirect URIs** must contain URL of OAuth2 [Redirection Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2). In case of LTC, the value is the same as LTC setting OAUTH2_CALLBACK_URL. - **Client Type**: Confidential - **Authorization Grant Type**: Authorization Code - **Name**: layman-test-client @@ -125,7 +125,7 @@ Furthermore, you need to provide endpoint `/profile` with user-related metadata. Check following environment variables of LTC: - OAUTH2_CLIENT_ID: **Client ID** from authorization server - OAUTH2_CLIENT_SECRET: **Client Secret** from authorization server -- OAUTH2_AUTH_URL: URL of [Authorization Endpoint](https://tools.ietf.org/html/rfc6749#section-3.1), usually the same as the first URL from Layman's OAUTH2_AUTH_URLS -- OAUTH2_TOKEN_URL: URL of [Token Endpoint](https://tools.ietf.org/html/rfc6749#section-3.2). In case of Django OAuth Toolkit (Wagtail), it's something like `:///o/token` -- OAUTH2_CALLBACK_URL: URL of [Redirection Endpoint](https://tools.ietf.org/html/rfc6749#section-3.1.2), the value is `:///auth/oauth2-provider/callback`. +- OAUTH2_AUTH_URL: URL of [Authorization Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.1), usually the same as the first URL from Layman's OAUTH2_AUTH_URLS +- OAUTH2_TOKEN_URL: URL of [Token Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.2). In case of Django OAuth Toolkit (Wagtail), it's something like `:///o/token` +- OAUTH2_CALLBACK_URL: URL of [Redirection Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.1.2), the value is `:///auth/oauth2-provider/callback`. - OAUTH2_USER_PROFILE_URL: URL of Layman's [GET Current User](../rest.md#get-current-user) diff --git a/doc/publish-map.md b/doc/publish-map.md index dfb21a832..a85d5ed23 100644 --- a/doc/publish-map.md +++ b/doc/publish-map.md @@ -13,9 +13,9 @@ In QGIS, you need to implement following steps. First, compose JSON valid against [map-composition schema](https://github.com/hslayers/map-compositions). For Layman, especially `describedBy`, `name`, `title`, `abstract`, `layers`, `projection`, and `extent attributes are important. Each layer must have `className` attribute equal to `HSLayers.Layer.WMS` or `WMS`. Then save the file to Layman using [POST Workspace Maps](rest.md#post-workspace-maps) endpoint. Well-known [requests](https://requests.readthedocs.io/en/latest/) module can be used for sending HTTP requests. See especially -- [More complicated POST requests](https://requests.readthedocs.io/en/latest/user/quickstart.html#more-complicated-post-requests) -- [POST a Multipart-Encoded File](https://requests.readthedocs.io/en/latest/user/quickstart.html#post-a-multipart-encoded-file) -- [POST Multiple Multipart-Encoded Files](https://requests.readthedocs.io/en/latest/user/advanced.html#post-multiple-multipart-encoded-files) +- [More complicated POST requests](https://requests.readthedocs.io/en/latest/user/quickstart/#more-complicated-post-requests) +- [POST a Multipart-Encoded File](https://requests.readthedocs.io/en/latest/user/quickstart/#post-a-multipart-encoded-file) +- [POST Multiple Multipart-Encoded Files](https://requests.readthedocs.io/en/latest/user/advanced/#post-multiple-multipart-encoded-files) In response of [POST Workspace Maps](rest.md#post-workspace-maps) you will obtain - `name` of the map unique within all maps in used [workspace](models.md#workspace) diff --git a/doc/rest.md b/doc/rest.md index 8c1692471..e20b75500 100644 --- a/doc/rest.md +++ b/doc/rest.md @@ -156,7 +156,7 @@ Body parameters: - 3 bands: Red, Green, Blue - 4 bands: Red, Green, Blue, Alpha - if published file has empty bounding box (i.e. no features), its bounding box on WMS/WFS endpoint is set to the whole World - - attribute names are [laundered](https://gdal.org/drivers/vector/pg.html#layer-creation-options) to be safely stored in DB + - attribute names are [laundered](https://gdal.org/en/stable/drivers/vector/pg.html#layer-creation-options) to be safely stored in DB - if QML style is used in this request, it must list all attributes contained in given data file - *external_table_uri*, string - exactly one of `file` or `external_table_uri` must be set @@ -199,7 +199,7 @@ Body parameters: - QML style for raster data file is not supported - It's possible to encode also external images in QML styles and use them in the style. To do so, each image needs to be encoded in Base64 encoding inside QML file. You can achieve it by selecting "Embed File" option in QGIS Layer Symbology window, see e.g. QGIS issues [2815](https://github.com/qgis/QGIS-Documentation/issues/2815) or [4563](https://github.com/qgis/QGIS-Documentation/pull/4563). - uploading of additional style files, e.g. point-symbol images or fonts is not supported - - attribute names are [laundered](https://gdal.org/drivers/vector/pg.html#layer-creation-options) to be in line with DB attribute names + - attribute names are [laundered](https://gdal.org/en/stable/drivers/vector/pg.html#layer-creation-options) to be in line with DB attribute names - *access_rights.read*, string - comma-separated names of [users](./models.md#user) and [roles](./models.md#role) who will get [read access](./security.md#publication-access-rights) to this publication - default value is current authenticated user, or EVERYONE if published by anonymous @@ -211,7 +211,7 @@ Body parameters: - alias for *style* parameter - *overview_resampling*, string - supported only for raster layers - - method used by [`gdaladdo`](https://gdal.org/programs/gdaladdo.html#cmdoption-gdaladdo-r) for overview resampling when normalizing raster layer + - method used by [`gdaladdo`](https://gdal.org/en/stable/programs/gdaladdo.html#cmdoption-gdaladdo-r) for overview resampling when normalizing raster layer - by default Layman will guess overview resampling method from input file metadata - supported values are: `nearest`, `average`, `rms`, `bilinear`, `gauss`, `cubic`, `cubicspline`, `lanczos`, `average_magphase` and `mode` - *time_regex*, string, e.g. `[0-9]{8}T[0-9]{6}Z` @@ -404,7 +404,7 @@ Body parameters: - SLD or QML style file (recognized by the root element of XML: `StyledLayerDescriptor` or `qgis`) - QML style for raster data file is not supported - It's possible to encode also external images in QML styles and use them in the style. See [POST Workspace Layers](#post-workspace-layers) body parameter *style* for details. - - attribute names are [laundered](https://gdal.org/drivers/vector/pg.html#layer-creation-options) to be in line with DB attribute names + - attribute names are [laundered](https://gdal.org/en/stable/drivers/vector/pg.html#layer-creation-options) to be in line with DB attribute names - If provided, current layer thumbnail will be temporarily deleted and created again using the new style. - *access_rights.read*, string - comma-separated names of [users](./models.md#user) and [roles](./models.md#role) who will get [read access](./security.md#publication-access-rights) to this publication @@ -415,7 +415,7 @@ Body parameters: - alias for *style* parameter - *overview_resampling*, string - supported only for raster layers - - method used by [`gdaladdo`](https://gdal.org/programs/gdaladdo.html#cmdoption-gdaladdo-r) for overview resampling when normalizing raster layer + - method used by [`gdaladdo`](https://gdal.org/en/stable/programs/gdaladdo.html#cmdoption-gdaladdo-r) for overview resampling when normalizing raster layer - by default Layman will guess overview resampling method from input file metadata - supported values are: `nearest`, `average`, `rms`, `bilinear`, `gauss`, `cubic`, `cubicspline`, `lanczos`, `average_magphase` and `mode` - can be used only together with `file` parameter, otherwise error is raised diff --git a/src/layman/layer/rest_workspace_layer.py b/src/layman/layer/rest_workspace_layer.py index 2a535bc6b..0b24d666c 100644 --- a/src/layman/layer/rest_workspace_layer.py +++ b/src/layman/layer/rest_workspace_layer.py @@ -132,7 +132,7 @@ def patch(workspace, layername): # Overview resampling overview_resampling = request.form.get('overview_resampling', '') if overview_resampling and overview_resampling not in settings.OVERVIEW_RESAMPLING_METHOD_LIST: - raise LaymanError(2, {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/programs/gdaladdo.html', + raise LaymanError(2, {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/en/stable/programs/gdaladdo.html', 'parameter': 'overview_resampling', 'detail': {'found': 'no_overview_resampling', 'supported_values': settings.OVERVIEW_RESAMPLING_METHOD_LIST}, }) diff --git a/src/layman/layer/rest_workspace_layers.py b/src/layman/layer/rest_workspace_layers.py index 19a0d3a7b..eac646104 100644 --- a/src/layman/layer/rest_workspace_layers.py +++ b/src/layman/layer/rest_workspace_layers.py @@ -161,7 +161,7 @@ def post(workspace): # Overview resampling overview_resampling = request.form.get('overview_resampling', '') if overview_resampling and overview_resampling not in settings.OVERVIEW_RESAMPLING_METHOD_LIST: - raise LaymanError(2, {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/programs/gdaladdo.html', + raise LaymanError(2, {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/en/stable/programs/gdaladdo.html', 'parameter': 'overview_resampling', 'detail': {'found': 'no_overview_resampling', 'supported_values': settings.OVERVIEW_RESAMPLING_METHOD_LIST}, }) diff --git a/tests/dynamic_data/publications/wrong_input/wrong_input_test.py b/tests/dynamic_data/publications/wrong_input/wrong_input_test.py index ed7e46ec9..63db8950e 100644 --- a/tests/dynamic_data/publications/wrong_input/wrong_input_test.py +++ b/tests/dynamic_data/publications/wrong_input/wrong_input_test.py @@ -540,7 +540,7 @@ class Key(Enum): 'http_code': 400, 'sync': True, 'code': 2, - 'data': {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/programs/gdaladdo.html', + 'data': {'expected': 'Resampling method for gdaladdo utility, https://gdal.org/en/stable/programs/gdaladdo.html', 'parameter': 'overview_resampling', 'detail': {'found': 'no_overview_resampling', 'supported_values': settings.OVERVIEW_RESAMPLING_METHOD_LIST}, }, diff --git a/tests/static_data/single_publication/layers_files_test.py b/tests/static_data/single_publication/layers_files_test.py index f209e9345..ee0d63bdb 100644 --- a/tests/static_data/single_publication/layers_files_test.py +++ b/tests/static_data/single_publication/layers_files_test.py @@ -29,7 +29,7 @@ def test_raster_files(workspace, publ_type, publication): # check number of overviews raster_size = max(gdal.get_raster_size(norm_file_path)) overview_counts = gdal.get_overview_counts(norm_file_path) - # https://gdal.org/programs/gdaladdo.html#cmdoption-gdaladdo-minsize + # https://gdal.org/en/stable/programs/gdaladdo.html#cmdoption-gdaladdo-minsize exp_overview_count = max(math.ceil(math.log(raster_size / 256, 2)), 0) assert overview_counts == [exp_overview_count] * len(overview_counts) exp_def_overview_count = publ_test_data.get('normalized_overviews')