Coverage for gws-app/gws/plugin/qgis/__init__.py: 100%
1 statements
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-23 20:06 +0200
« prev ^ index » next coverage.py v7.17.0, created at 2026-10-23 20:06 +0200
1"""QGIS support.
3This plugin uses QGIS projects as data sources for layers, search, models,
4legends and print templates. Projects are stored in files (``.qgs`` or
5zipped ``.qgz``) or in a Postgres table (``qgis_projects``, the QGIS
6"store project in PostgreSQL" format). Projects are parsed by reading the
7project XML directly; no QGIS APIs are used. Rendering, feature info,
8legends and printing are done by sending requests to a QGIS Server instance,
9whose address comes from the ``server.qgis`` application settings.
11Submodules
12----------
14- ``project`` - loading and storing QGIS projects (`project.Object`,
15 `project.Store`), in files or in a Postgres database.
16- ``caps`` - the project XML parser. It produces a `caps.Caps` object with
17 the project metadata, CRS, extents, source layers, print layouts,
18 visibility presets and custom properties, and also parses layer data
19 source strings (``parse_datasource``).
20- ``provider`` - the service provider (`provider.Object`). It loads the
21 project, computes the project bounds, talks to QGIS Server (GetMap,
22 GetFeatureInfo and other requests) and creates the configuration of leaf
23 layers for the ``qgis`` tree layer.
24- ``layer`` - the ``qgis`` layer, a group that shows the project as a tree
25 of layers.
26- ``flatlayer`` - the ``qgisflat`` layer, which renders selected project
27 layers as a single image. By default, it gets a ``qgis`` model and a
28 ``qgis`` finder for its queryable source layers and a ``qgis`` legend,
29 whose options are merged with the provider's ``defaultLegendOptions``.
30- ``grabber`` - the raster grabber for ``qgisflat`` layers and composite
31 ``qgis`` layers; it requests boxes from QGIS Server with GetMap. Boxes are
32 requested in the target CRS, QGIS Server reprojects as needed.
33- ``finder`` - the ``qgis`` finder, which searches project layers by point
34 with GetFeatureInfo.
35- ``model`` - the ``qgis`` model for features found with the finder.
36- ``legend`` - the ``qgis`` legend, rendered with GetLegendGraphic. Rendered
37 images are cached for ``cacheMaxAge``.
38- ``template`` - the ``qgis`` print template, based on a print layout of
39 the project.
40- ``cli`` - the ``gws qgis caps`` and ``gws qgis copy`` commands.
42Design
43------
45Layers, finders, models, legends and templates refer to a project through
46their ``provider`` configuration. A provider created from the same
47configuration is shared between objects. When the provider has
48``withWatch`` enabled, it checks the project periodically and reloads the
49application when the project changes.
51The ``qgis`` layer creates a child layer for each source layer of the
52project, keeping the group structure. By default, a child is a
53``qgisflat`` layer that renders through QGIS Server. With the provider
54options ``directRender`` and ``directSearch``, children based on WMS, WMTS
55or XYZ sources are rendered by WebSuite directly (``wmsflat``, ``wmts`` or
56``tile`` layers), and WMS, WFS and Postgres sources get their own finders
57(and, for Postgres, models) instead of going through QGIS Server. With
58``withCompositeRender``, the ``qgis`` layer renders all visible ``qgisflat``
59children as one image with one GetMap request. It then creates grabbers like
60an image layer, and the client gets a ``compositeBox`` or ``compositeTile``
61layer whose children are ``compositeLeaf`` layers; the client sends the
62visible children in ``compositeLayerUids``.
64QGIS projects are usually dynamic, so ``qgis`` and ``qgisflat`` layers have
65``withCache`` off by default. A ``qgis`` layer with ``withCache`` passes it on
66to all its leaf layers, before ``autoLayers`` configs are applied; direct
67render leaves of a ``qgis`` layer without ``withCache`` keep their own default.
68The ``cache`` settings of a ``qgis`` layer are passed on the same way, except
69``name``, so that each leaf keeps its own cache directory.
71Print templates work as follows. The project is reloaded on each render.
72The map is rendered by WebSuite as a PDF.
73Label and HTML items of the QGIS layout are treated as WebSuite ``html``
74templates, so they can use placeholders such as ``@legend``; if any of them
75changes, a temporary copy of the project with the rendered HTML is created.
76The layout is then printed by QGIS Server with GetPrint, and the QGIS PDF is
77placed over the map PDF, so that grids and other decorations are drawn
78above the map. For this to work, the page and the map item of the layout
79must be transparent, and since the project is copied, it must use absolute
80paths to its assets. Integer map positions and sizes in the layout give the
81best alignment.
83Project and layer extents
84-------------------------
86QGIS does not provide complete project and layer extents with respect to
87symbology. Only data-based extents are known at parse time. Extents are
88computed with the following logic:
90- if a project provides an explicit WMS extent (Project Properties ->
91 QGIS Server -> WMS), this extent is used as the project render extent
92 (``bounds``)
93- otherwise, if ``useCanvasExtent`` is true, the canvas extent is used
94- otherwise, the project render extent is the union of the layers' data
95 extents plus the configured ``extentBuffer``
96- if the render extent is empty, the CRS extent is taken
97- for layers, the data extent is either an explicit extent (Layer
98 Properties -> Metadata -> Extent) or an implicit data extent
99- the layer data extent is used as a "zoom" extent, but when rendering a
100 layer, the project extent is used
102Example::
104 map.layers+ {
105 title "City"
106 type "qgis"
107 provider.path "/data/city.qgs"
108 provider.directSearch [ "wms" "wfs" "postgres" ]
109 }
111 map.layers+ {
112 title "Districts"
113 type "qgisflat"
114 provider.path "/data/city.qgs"
115 sourceLayers.names [ "districts" ]
116 }
118 printers+ {
119 template {
120 type "qgis"
121 provider.path "/data/print.qgs"
122 index 0
123 }
124 }
125"""
127from . import provider, project, caps