diff --git a/.env.example b/.env.example
index da0add223..a9dd79254 100644
--- a/.env.example
+++ b/.env.example
@@ -1,25 +1,25 @@
-# Public hostmane
+# Public hostname, for docker internal network aliases
WEBGIS_PUBLIC_HOSTNAME=dev.g3wsuite.it
-# Shared volume mount (docker internal: shared-volume)
-# I suggest not to use the /tmp/ folder, /tmp/ folder is cleaned at each reboot
+# Persistent data folder (projects, database, uploads), mounted into "g3w-suite" container at: `/shared-volume`
WEBGIS_DOCKER_SHARED_VOLUME=./shared-volume
-# Docker internal DB
+##
+# 🚨 PostGIS DB
+##
G3WSUITE_POSTGRES_USER_LOCAL=g3wsuite
G3WSUITE_POSTGRES_PASS='89#kL8y3D'
G3WSUITE_POSTGRES_DBNAME=g3wsuite
G3WSUITE_POSTGRES_HOST=postgis
G3WSUITE_POSTGRES_PORT=5432
-# Set this to true to activate the frontend module
+# OPTIONAL: whether activate frontend module
FRONTEND=False
# QGIS Server env variables
# ----------------------------------------------------
-# Put your pg service into ./secrets/pg_service.conf file, the conf file will be mounted into
-# docker container at runtime a the PGSERVICEFILE
+# To use PostgreSql Service, mounted into postgis container at: `./secrets/pg_service.conf`,
PGSERVICEFILE=/pg_service/pg_service.conf
QGIS_SERVER_LOG_FILE=/shared_volume/QGIS/error.log
diff --git a/.gitignore b/.gitignore
index 9cfd7ebbc..c1b3047b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,15 @@ projects
.idea
code
-shared-volume
\ No newline at end of file
+shared-volume/**
+
+# DEMO DATA
+!shared-volume/backup/
+!shared-volume/backup/demo/
+!shared-volume/backup/demo/**
+!shared-volume/media/
+!shared-volume/media/project_data/
+!shared-volume/media/project_data/spatialite/
+!shared-volume/media/project_data/spatialite/**
+!shared-volume/media/projects/
+!shared-volume/media/projects/3857_public-building-management-demo.qgs
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000..06ba7ba2e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,84 @@
+ifeq ($(ENV),)
+ $(error ENV is not set)
+endif
+
+##
+# Ensure: "Docker Desktop > Resources > WSL Integration"
+##
+ifeq ($(OS), Windows_NT)
+ $(error make.exe not supported, please try again within a WSL shell: https://docs.docker.com/desktop/wsl/#enabling-docker-support-in-wsl-2-distros)
+endif
+
+##
+# ENV = { dev | prod | consumer }
+##
+ifeq ($(ENV), prod)
+ DOCKER_COMPOSE:= docker compose -f docker-compose.yml
+else
+ DOCKER_COMPOSE:= docker compose -f docker-compose-$(ENV).yml
+endif
+
+G3W_SUITE:= docker compose exec g3w-suite
+
+
+##
+# SSH login
+#
+# make run-g3wsuite ENV=DEV
+# make run-postgis ENV=DEV
+##
+run-%:
+ $(DOCKER_COMPOSE) start $*
+ docker exec -it $$(docker ps | grep $* | head -1 | awk '{print $$1}') bash
+
+##
+# Recreate g3w-suite containers
+#
+# make db-reset ENV=dev
+##
+db-reset:
+ $(DOCKER_COMPOSE) up -d
+ $(G3W_SUITE) bash -c 'rm -rf /shared-volume/cache'
+ $(G3W_SUITE) bash -c 'rm -rf /shared-volume/__pycache__'
+ $(G3W_SUITE) bash -c 'rm -f /shared-volume/build_done'
+ $(G3W_SUITE) bash -c 'rm -f /shared-volume/setup_done'
+ $(G3W_SUITE) bash -c 'rm -f /shared-volume/.secret_key'
+ $(DOCKER_COMPOSE) up -d --force-recreate
+ ID=demo ./scripts/makefile/db-restore.sh
+
+##
+# Backup databases
+#
+# make db-backup ID=name ENV=dev
+##
+db-backup:
+ ./scripts/makefile/db-backup.sh
+
+##
+# Restore databases
+#
+# make db-restore ID=name ENV=dev
+##
+db-restore:
+ $(DOCKER_COMPOSE) up -d --force-recreate
+ ./scripts/makefile/db-restore.sh
+
+##
+# Run certbot
+#
+# make renew-ssl ENV=dev
+##
+renew-ssl:
+ ./scripts/makefile/renew-ssl.sh
+ $(DOCKER_COMPOSE) up -d --force-recreate
+
+##
+# Rebuild docker image
+#
+# make docker-image v=v3.8.x
+##
+docker-image:
+ ifeq ($(v),)
+ $(error v is not set)
+ endif
+ docker build -f Dockerfile.g3wsuite.dockerfile -t g3wsuite/g3w-suite:$(v) --no-cache .
\ No newline at end of file
diff --git a/README.md b/README.md
index 6bda15459..b79d44db2 100644
--- a/README.md
+++ b/README.md
@@ -1,157 +1,159 @@
-# G3W-SUITE WebGIS
+# G3W-SUITE-DOCKER
[](https://github.com/g3w-suite/g3w-suite-docker/actions/workflows/build_and_push_main_image.yml)
[](https://github.com/g3w-suite/g3w-suite-docker/actions/workflows/build_and_push_deps_ltr.yml)
-This repository contains scripts and recipes for deploy of the G3W-SUITE web-gis application with Docker and Docker compose .
+Run a self hosted web-gis application with Docker Compose
-
+
-## Deploy
+ ⬆️ How to upgrade from v3.7 to v3.8
-Follow steps to deploy G3W-SUITE on a Ubuntu Server (20.04)
+Since **v3.8** PostgreSQL/PostGIS changed from **v11/2.5** to **v16/3.4**, to upgrade follow below steps:
-### Configuration
+```sh
+# NB:
+# • (ENV = dev) → docker-compose-dev.yml
+# • (ENV = prod) → docker-compose.yml
+# • (ENV = consumer) → docker-compose-consumer.yml
-Create a file `.env` (or copy `.env.example` and rename it in `.env`) and place it in the main directory, the file
-will contain the database credentials (change ``) and other settings:
+### BACKUP (v3.7.x) ###
-```bash
-# External hostname, for docker internal network aliases
-WEBGIS_PUBLIC_HOSTNAME=demo.g3wsuite.it/
+docker compose up -f docker-compose-dev.yml up -d
+
+git fetch
+git checkout v3.8.x
-# This volume is persistent and mounted by all
-# containers as /shared-volume
-WEBGIS_DOCKER_SHARED_VOLUME=/tmp/shared-volume-g3w-suite
+make db-backup ID=11 ENV=prod
+### RESTORE (v3.8.x) ###
-# DB setup
-G3WSUITE_POSTGRES_USER_LOCAL=g3wsuite
-G3WSUITE_POSTGRES_PASS=
-G3WSUITE_POSTGRES_DBNAME=g3wsuite
-G3WSUITE_POSTGRES_HOST=postgis
-G3WSUITE_POSTGRES_PORT=5432
+make db-restore ID=11 ENV=prod
+### OPTIONAL (delete old DB) ###
-# QGIS Server env variables
-# ----------------------------------------------------
-PGSERVICEFILE=/pg_service/pg_service.conf
+docker compose exec g3w-suite bash -c 'rm -r /shared-volume/11'
+docker compose exec g3w-suite bash -c 'rm -r /shared-volume/backup/11'
```
+
+
-### Run
+---
-```bash
-docker-compose up -d
-```
+
-If all went well, G3W-SUITE run on http://localhost:8080
-
+## 🌍 Deploying your webgis app
-## G3W-SUITE with consumer image
-G3W-SUITE use `huey` for bach processing (https://github.com/coleifer/huey), so if you want to use it,
-use `docker-compose-consumer.yml` file on deploy:
-```bash
-docker-compose -f docker-compose-consumer.yml up -d
+Install [docker compose](https://docs.docker.com/compose/install/).
+
+Clone this repository:
+
+```
+git clone https://github.com/g3w-suite/g3w-suite-docker/
+cd g3w-suite-docker
```
-## Builds
+Create a `.env` file starting from [`.env.example`](./.env.example) and tailor it to your needs:
-Docker compose will download images from docker hub (https://hub.docker.com/u/g3wsuite),
-but is also possible build main image of G3W-SUITE and other docker-compose images.
+```diff
+# CHANGE ME: PostGIS DB password
-#### G3W-SUITE
+- G3WSUITE_POSTGRES_PASS='89#kL8y3D'
++ G3WSUITE_POSTGRES_PASS=
+```
-The main suite docker image can be built with:
+Start containers:
-```bash
-docker build -f Dockerfile.g3wsuite.dockerfile -t g3wsuite/g3w-suite:dev --no-cache .
+```sh
+docker-compose up -d
```
-The image is build from `https://github.com/g3w-suite/g3w-admin.git --branch dev` and from a dependencies base image `Dockerfile.g3wsuite-deps.ltr.dockerfile`, the dependencies image can be built with:
+or, if you intend to use [huey](https://github.com/coleifer/huey) (batch processing)
-```bash
-docker build -f Dockerfile.g3wsuite-deps.ltr.dockerfile -t g3wsuite/g3w-suite-deps-ltr:dev --no-cache .
+```sh
+docker-compose -f docker-compose-consumer.yml up -d
```
-Usually is sufficient make build of main docker image g3wsuite/g3w-suite:dev,
-the build of dependence image g3wsuite/g3w-suite-deps-ltr:dev is done to update last QGIS LTR version.
+**NB:** at the very first start, have a lot of patience 😴 → the system must finalize the installation. \*
-#### Postgis
+After some time the suite will be available at:
-Postgis image can be built with:
+- http://localhost:8080 (user: `admin`, pass: `admin`)
-```bash
-docker build -f Dockerfile.postgis.dockerfile -t g3wsuite/postgis:11.0-2.5 .
-```
-The Docker hub name for this image is `g3wsuite/postgis:11.0-2.5`
+
-## Setups
+\* in case of faulty container (eg. the first time you didn't wait long enough before trying to access):
-### PG_SERVICE
+```sh
+# 🚨 deletes all data
+make db-reset ENV=prod
-To use of PostgreSql Service, put your service setups into `./secrets/pg_service.conf file`,
-the conf file will be mounted into docker container at runtime to PGSERVICEFILE path position.
+# or
+# make db-reset ENV=consumer
+```
-### HTTPS additional setup
+## 💻 How to access into a container
-To active https with LetsEncrypt just follow the following instructions:
+1. login into a service
-- uncomment ssl section within `config/nginx/nginx.conf`
-- update `WEBGIS_PUBLIC_HOSTNAME` environment variable within the `.env` and `config/nginx/nginx.conf` files
-- launch `sudo ./run_certbot.sh`
-- restart compose: `docker compose down && docker compose up -d`
-- make sure the certs are renewed by adding a cron job with `sudo crontab -e` and add the following line:
- `0 3 * * * //run_certbot.sh`
+```sh
+$ make run-postgis ENV=prod
-### Volumes
+# make run-g3w-suite ENV=prod
+# make run-nginx ENV=prod
+# make run-redis ENV=prod
+```
-Data, projects, uploads and the database are stored in a shared mounted volume `shared-volume`, the volume should be on a persistent storage device and a backup
-policy must be enforced.
+2. perform your administrative tasks (eg. connect to postgis as "postgres" user):
-Currently, the volume is mounted in `/tmp/shared-volume-g3wsuite-dev`. In production
-environments it is encouraged to change this to a permanent location.
-This can be done by modifying the `.env` file.
+```sh
+root@84ef6a8d23e6:/# su - postgres
-### First time setup
+postgres@84ef6a8d23e6:~$ psql
+psql (11.2 (Debian 11.2-1.pgdg90+1))
+Type "help" for help.
-- log into the application web administration panel using default credentials (_admin/admin_)
-- change the password for the admin user and for any other example user that may be present
+postgres=#
+```
-### Caching
+## 🔒 HTTPS
-Tile cache can be configured and cleared per-layer through the webgis admin panel and lasts forever until it is disabled or cleared.
+To enable https with LetsEncrypt::
-> Tip: enable cache on linestring and polygon layers.
+- uncomment ssl section within `config/nginx/nginx.conf`
+- update `WEBGIS_PUBLIC_HOSTNAME` environment variable within the `.env` and `config/nginx/nginx.conf` files
+- launch `sudo make renew-ssl`
+- make sure the certs are renewed by adding a cron job with `sudo crontab -e` and add the following line:
+ `0 3 * * * //run_certbot.sh`
-### Editing
+## 📦 Docker image
-Editing module is active by default, to avoid simultaneous feature editing by two or more users, the editing module works with a feature lock system.
-This locking system can remain active if users do not exit the editing state correctly, to avoid this it is advisable to activate a cron job on host machine that checks the features that have been locked for more than 4 hours and frees them:
+Docker compose will usually download images from: https://hub.docker.com/u/g3wsuite
-```
-0 */1 * * * docker exec g3w-suite-docker_g3w-suite_1 python3 /code/g3w-admin/manage.py check_features_locked
-```
+A custom (local) docker image for the suite can be created with:
-## Front-end App
+```bash
+docker build -f Dockerfile.g3wsuite.dockerfile -t g3wsuite/g3w-suite:dev --no-cache .
-Set the environment variable
+# OPTIONAL:
+# docker build -f Dockerfile.g3wsuite-deps.ltr.dockerfile -t g3wsuite/g3w-suite-deps-ltr:dev --no-cache .
```
-FRONTEND=True
-```
-This will set the front end app as the default app
-
-## Style customization
-Templates can now be overridden by placing the overrides in the `config/g3w-suite/overrides/templates`, a Docker service restart is required to make the changes effective.
+The image is build on latest Ubuntu and QGIS LTR, following this execution order:
-The logo is also overridden (through `config/g3w-suite/settings_docker.py` which is mounted as a volume), changes to the settings file require the Docker service to be restarted.
+1. [Dockerfile.g3wsuite-deps.ltr.dockerfile](./Dockerfile.g3wsuite-deps.ltr.dockerfile) ← installs Ubuntu and QGIS LTR
+2. [Dockerfile.g3wsuite.dockerfile](./Dockerfile.g3wsuite.dockerfile) ← run "setup.sh" and "docker-entrypoint.sh"
+3. [scripts/setup.sh](./scripts/setup.sh) ← install g3w-admin and some other python plugins
+4. [scripts/docker-entrypoint.sh](./scripts/docker-entrypoint.sh) ← start gunicorn
-A custom CSS is added to the pages, the file is located in `config/g3w-suite/overrides/static/style.css` and can be modified directly, changes are effective immediately.
+## 🎨 Style customization
-## Performances optimization
+- custom templates folder: `config/g3w-suite/overrides/templates` → a Docker service restart is required to make the changes effective.
+- custom logo (see: [docs](https://g3w-suite.readthedocs.io/en/latest/settings.html#general-layout-settings)): `config/g3w-suite/settings_docker.py` → a Docker service restart is required to make the changes effective.
+- custom CSS: `config/g3w-suite/overrides/static/style.css` → changes are effective immediately
-General rules (in no particular order: they are all mandatory):
+## 🚀 Performance optimizations
1. set scale-dependent visibility for the entire layer or for some filtered features (example: show only major roads until at scale 1:1E+6)
2. when using rule-based/categorized classification or scale-dependent visibility create indexes on the column(s) involved in the rule expression (example: "create index idx_elec_penwell_ious on elec_penwell_ious (owner);" )
@@ -159,49 +161,36 @@ General rules (in no particular order: they are all mandatory):
4. do not turn on by default base-layers XYZ such as (Google base maps)
5. do not use rule-based/categorized rendering on layers with too many categories (example: elec_penwell_public_power), they are unreadable anyway
6. enable redering simplification for not-point layers, set it to `Distance` `1.2` and check `Enable provider simplification if available`
-
-## PostgreSQL administration
-
-Postgres is running into a Docker container, in order to access the container, you can follow the instruction below:
-
-### Check the container name
-
-```bash
-$ docker ps | grep postgis
-84ef6a8d23e6 g3wsuite/postgis:11.0-2.5 "/bin/sh -c /docker-…" 2 days ago Up 2 days 0.0.0.0:5438->5432/tcp g3wsuitedocker_postgis_1
+7. enable cache on linestring and polygon layers (tile cache can be configured and cleared per-layer through the webgis admin panel and lasts forever until it is disabled or cleared)
+8. set a cron job on host machine that checks edited features that have been locked for more than 4 hours and frees them:
```
-
-In the above example the container name is `g3wsuitedocker_postgis_1`
-
-### Log into the container
-
-```bash
-$ docker exec -it g3wsuitedocker_postgis_1 bash
+0 */1 * * * docker exec g3w-suite-docker_g3w-suite_1 python3 /code/g3w-admin/manage.py check_features_locked
```
-### Become postgres user
+## 🐋 Portainer usage
-```bash
-root@84ef6a8d23e6:/# su - postgres
-```
+Portainer (https://www.portainer.io) is a docker-based web application used to edit and manage Docker applications in a simple and intuitive way.
-### Connect to postgis
+Plese refer to the [Add new stack](https://docs.portainer.io/user/docker/stacks/add) section to learn how to deploy the `docker-compose-consumer.yml` stack with Portainer (>= v2.1.1).
-```bash
-postgres@84ef6a8d23e6:~$ psql
-psql (11.2 (Debian 11.2-1.pgdg90+1))
-Type "help" for help.
-postgres=#
-```
+## ♻️ Database backup / restore
-## Portainer usage
+```sh
+# NB:
+# • (ENV = dev) → docker-compose-dev.yml
+# • (ENV = prod) → docker-compose.yml
+# • (ENV = consumer) → docker-compose-consumer.yml
-Portainer (https://www.portainer.io) is a docker-based web application used to edit and manage Docker applications in a simple and intuitive way.
+docker compose up -f docker-compose.yml up -d
-Plese refer to the [Add new stack](https://docs.portainer.io/v/ce-2.9/user/docker/stacks/add) section to learn how to deploy the `docker-compose-consumer.yml` stack with Portainer (>= v2.1.1).
+make backup-db ID=foo-backup ENV=prod
+make restore-db ID=foo-backup ENV=prod
+```
### Contributors
-* Walter Lorenzetti - Gis3W ([@wlorenzetti](https://github.com/wlorenzetti))
-* Alessandro Pasotti - ItOpen ([@elpaso](https://github.com/elpaso))
-* Mazano - Kartoza ([@NyakudyaA](https://github.com/NyakudyaA))
+
+* GIS3W: [wlorenzetti](https://github.com/wlorenzetti), [raruto](https://github.com/Raruto)
+* ItOpen: [elpaso](https://github.com/elpaso)
+* Kartoza: [NyakudyaA](https://github.com/NyakudyaA)
+* QTIBIA: [tudorbarascu](https://github.com/tudorbarascu)
diff --git a/README_DEV.md b/README_DEV.md
index b68522321..7f46cd981 100644
--- a/README_DEV.md
+++ b/README_DEV.md
@@ -6,114 +6,116 @@ Follow instructions are for development environment.
* set `G3WSUITE_DEBUG` to `True`;
* set `G3WSUITE_LOCAL_CODE_PATH` with path to your local G3W-SUITE code location.
-2. Since the frontend modeul is not available in dev mode, it needs to be disabled in the settings
- file of the docker project: config/g3w-suite/settings_docker.py
+2. Run `docker compose -f docker-compose-dev.yml up -d`. \*
+ 1. If all went well G3W-SUITE is running in development mode on http://127.0.0.1:8000
-```python
- G3WADMIN_LOCAL_MORE_APPS = [
- 'caching',
- 'editing',
- 'filemanager',
- 'qplotly',
- # Uncomment if you wont activate the following module
- #'openrouteservice',
- 'qtimeseries',
- # 'frontend' <-- this needs to be commented
- ]
-```
+---
+ \* if necessary, comment out any missing installed modules from [G3WADMIN_LOCAL_MORE_APPS](./config/g3w-suite/settings_docker.py) list and then try again
-3. Run `docker compose -f docker-compose-dev.yml up -d`.
- 1. If all went well G3W-SUITE is running in development mode on http://127.0.0.1:8000
+ \* if you customize [docker-compose-dev.yml](./docker-compose-dev.yml) (eg. by choosing a specific image: g3wsuite/g3w-suite:dev g3wsuite/g3w-suite:v3.7.x
) you then apply them via: `docker compose -f docker-compose-dev.yml up -d --force-recreate`
-## An example workflow to develop a suite plugin against a given g3w-suite version
+## Loading default demo
-Let's assume you need to develop a plugin for the v3.7.8 version of the suite.
-The plugin will be developed in a separate repository, let's call it `my-fantastic-plugin`.
+```
+# 🚨 deletes all data
+make db-restore ID=demo ENV=dev
-### Step 1: Fork the docker project and set its version to the one you need
+# or (a custom backup):
-```bash
-git clone https://github.com/moovida/g3w-suite-docker
-cd g3w-suite-docker/
-git remote add gis3w https://github.com/g3w-suite/g3w-suite-docker
-git checkout v3.7.8
-git checkout -b v3.7.8_my-fantastic-plugin
-git push origin v3.7.8_my-fantastic-plugin
+# make backup-db ID=foo-backup ENV=dev
+# make restore-db ID=demo ENV=dev
+# ...
+# make restore-db ID=foo-backup ENV=dev
```
-in the docker-compose-dev.yml choose the right image to address (in this case the v3.7.x train):
+## Developing a python plugin (pip install)
+
+Below you can find some sample plugins from which to take inspiration:
+
+- https://github.com/g3w-suite/g3w-admin-ps-timeseries
+- https://github.com/g3w-suite/g3w-admin-processing
+- https://github.com/g3w-suite/g3w-admin-authjwt
-```diff
- - image: g3wsuite/g3w-suite:dev
- + image: g3wsuite/g3w-suite:v3.7.x
+For example, installing a plugin within the docker container (editable mode):
+
+```
+docker compose -f docker-compose-dev.yml exec g3w-suite mkdir -p /shared-volume/plugins
+docker compose -f docker-compose-dev.yml exec g3w-suite git clone https://github.com/g3w-suite/g3w-admin-ps-timeseries
+docker compose -f docker-compose-dev.yml exec g3w-suite pip3 install -v -e /shared-volume/plugins/qps_timeseries
```
-### Step 2: Fork the admin project and set its version to the one you need
+**NB:** If the above seems wordy to you, you can also inject a custom script within: [scripts/docker-entrypoint-dev.sh](./scripts/docker-entrypoint-dev.sh)
+
+## Developing a python plugin (git only)
+
+Below are the steps to develop a new Django app into g3w-admin (as git submodule).
```bash
-git clone https://github.com/moovida/g3w-admin
-cd g3w-admin/
-git remote add gis3w https://github.com/g3w-suite/g3w-admin
+
+## Fork g3w-suite (docker + admin) ##
+
+git clone https://github.com/YOUR-USERNAME/g3w-suite-docker
+git clone https://github.com/YOUR-USERNAME/g3w-admin
+
+## Create dev branches (v3.7.8_my-fantastic-plugin) ##
+
+cd g3w-suite-docker
+git remote add gis3w https://github.com/g3w-suite/g3w-suite-docker
git checkout v3.7.8
git checkout -b v3.7.8_my-fantastic-plugin
git push origin v3.7.8_my-fantastic-plugin
-```
-### Step 3: Configure the docker project
+cd g3w-admin
+git remote add gis3w https://github.com/g3w-suite/g3w-admin
+git checkout v3.7.8
+git checkout -b v3.7.8_my-fantastic-plugin
+git push origin v3.7.8_my-fantastic-plugin
-Copy the .env.example file and make sure you set the following vars:
+## Add your plugin into g3w-admin (as git submodule) ##
-```bash
- WEBGIS_DOCKER_SHARED_VOLUME=/SHARED_VOLUME/
- G3WSUITE_DEBUG=True
- G3WSUITE_LOCAL_CODE_PATH=/home/gis3w/g3w-admin/
+cd g3w-admin
+git submodule add https://github.com/YOUR-USERNAME/my-plugin my-plugin
```
-### Step 4: Run the containers
-
-start the docker containers:
+Now customize [.env](./.env) and [settings_docker.py](./config/g3w-suite/settings_docker.py) files to fit your needs, eg:
```bash
- docker compose -f docker-compose-dev.yml up -d
+# .env
+WEBGIS_DOCKER_SHARED_VOLUME=/SHARED_VOLUME/
+G3WSUITE_DEBUG=True
+G3WSUITE_LOCAL_CODE_PATH=/home/gis3w/g3w-admin/
```
-if everythign works, stop it with
-```bash
- docker compose -f docker-compose-dev.yml down`
-```
-
-### Step 5: Add your plugin
-Plugins are developed as django apps. First get the code in the right place as a git submodule:
-
-If the repo is:
-
-```
- https://github.com/g3w-suite/my-fantastic-plugin
+```python
+# settings_docker.py
+G3WADMIN_LOCAL_MORE_APPS = [
+ 'caching',
+ 'editing',
+ 'filemanager',
+ 'qplotly',
+ 'openrouteservice',
+ 'qtimeseries',
+ 'my-plugin', # ← YOUR CUSTOM PLUGIN
+]
```
-adding the app as submodule is done as follows from within the g3w-admin project (not the docker one):
+Start the containers:
```bash
- cd g3w-admin/
- git submodule add https://github.com/g3w-suite/my-fantastic-plugin my-fantastic-plugin
+ docker compose -f docker-compose-dev.yml up -d
```
-Make sure you add your plugin to the `G3WADMIN_LOCAL_MORE_APPS` list in the `config/g3w-suite/settings_docker.py` file.
+Stop the containers:
-```python
- G3WADMIN_LOCAL_MORE_APPS = [
- 'caching',
- 'editing',
- 'filemanager',
- 'qplotly',
- 'openrouteservice',
- 'qtimeseries',
- 'my-fantastic-plugin',
- ]
+```bash
+ docker compose -f docker-compose-dev.yml down
```
+
-### Extra step: develop in debugging mode using vscode
+## Additional notes
+
+ Debugging using vscode
To develop inside the container with Visual Studio Code, you need to avoid starting up the server when you start the container. To do so, change the last line of the docker-entrypoint-dev.sh from:
```bash
@@ -155,11 +157,10 @@ Once inside the container run the suite using a newly created launch.json file t
```
You should now be able to debug the suite with the common vscode tools.
+
-
-
-
-## Additional notes
+
+ Connecting to a local DB (PostGIS)
If you are working in a mixed setup (ie. a local [postgis](https://postgis.net/) instance + a [g3w-suite-docker](https://github.com/g3w-suite/g3w-suite-docker) container), you should add an `extra_hosts` directive within your `docker-compose-dev.yml` to make your local postgres databases accessible from both sides:
@@ -186,3 +187,7 @@ taking care to edit your `hosts` file accordingly:
**For more info:**
- https://docs.docker.com/compose/compose-file/compose-file-v3/#extra_hosts
+
+
+
+
diff --git a/config/nginx/django b/config/nginx/django
index 17bb8a099..638e5ba8c 100644
--- a/config/nginx/django
+++ b/config/nginx/django
@@ -12,7 +12,7 @@ server {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
- proxy_set_header X-Forwarded-Host $host;
+ proxy_set_header X-Forwarded-Host $host:8080;
proxy_pass http://g3w_suite/;
}
diff --git a/docker-compose-consumer.yml b/docker-compose-consumer.yml
index 4fe7b744a..35c69985c 100644
--- a/docker-compose-consumer.yml
+++ b/docker-compose-consumer.yml
@@ -1,6 +1,6 @@
services:
postgis:
- image: kartoza/postgis:15-3.3
+ image: kartoza/postgis:16-3.4
ports:
- "5439:5432"
environment:
diff --git a/docker-compose-dev.yml b/docker-compose-dev.yml
index 443e430b0..2ed14eb44 100644
--- a/docker-compose-dev.yml
+++ b/docker-compose-dev.yml
@@ -1,6 +1,6 @@
services:
postgis:
- image: kartoza/postgis:15-3.3
+ image: kartoza/postgis:16-3.4
ports:
- "5439:5432"
environment:
diff --git a/docker-compose.yml b/docker-compose.yml
index b45343ac7..8c6eb9835 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,6 @@
services:
postgis:
- image: kartoza/postgis:15-3.3
+ image: kartoza/postgis:16-3.4
ports:
- "5439:5432"
environment:
diff --git a/run_certbot.sh b/run_certbot.sh
index 683123f6c..8be520c91 100755
--- a/run_certbot.sh
+++ b/run_certbot.sh
@@ -1,31 +1,5 @@
#!/bin/bash
-# Run certbot docker container to renew the HTTPS certificate.
-# Requires .env file with container configuration variables
CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
-source ${CURRENT_DIR}/.env
-
-if [ "${WEBGIS_PUBLIC_HOSTNAME}" = "" ]; then
- echo "WEBGIS_PUBLIC_HOSTNAME not defined: exiting"
- exit 1
-fi
-
-if [ "${WEBGIS_DOCKER_SHARED_VOLUME}" = "" ]; then
- echo "WEBGIS_DOCKER_SHARED_VOLUME not defined: exiting"
- exit 1
-fi
-
-mkdir -p "${WEBGIS_DOCKER_SHARED_VOLUME}/certs/letsencrypt/"
-
-curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf > "${WEBGIS_DOCKER_SHARED_VOLUME}/certs/letsencrypt/options-ssl-nginx.conf"
-curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem > "${WEBGIS_DOCKER_SHARED_VOLUME}/certs/letsencrypt/ssl-dhparams.pem"
-
-docker run -it --rm --name certbot \
- -v ${WEBGIS_DOCKER_SHARED_VOLUME}/certs/letsencrypt:/etc/letsencrypt \
- -v ${WEBGIS_DOCKER_SHARED_VOLUME}/var/www/.well-known:/var/www/.well-known \
- certbot/certbot -t certonly \
- --agree-tos --renew-by-default \
- --no-eff-email \
- --webroot -w /var/www \
- -d ${WEBGIS_PUBLIC_HOSTNAME}
+make -C $CURRENT_DIR renew-ssl ENV=DEV
diff --git a/scripts/docker-entrypoint-dev.sh b/scripts/docker-entrypoint-dev.sh
index ec9f3c6b1..101984ae6 100755
--- a/scripts/docker-entrypoint-dev.sh
+++ b/scripts/docker-entrypoint-dev.sh
@@ -2,6 +2,8 @@
# Entrypoint script for Development purposes.
# -------------------------------------------
+figlet -t "G3W-SUITE" && echo -e "v`git tag --sort=v:refname | tail -1 | sed 's/^v//'`\n"
+
# Start XVfb
if [[ -f /tmp/.X99-lock ]]; then
rm /tmp/.X99-lock
@@ -21,4 +23,4 @@ cd /code/g3w-admin
git config --global --add safe.directory /code
# Start Django server
-python3 manage.py runserver 0.0.0.0:8000
\ No newline at end of file
+gunicorn base.wsgi:application -c /shared-volume/gunicorn.conf.py
diff --git a/scripts/docker-entrypoint.sh b/scripts/docker-entrypoint.sh
index 7ebd118ce..96c2a0af0 100755
--- a/scripts/docker-entrypoint.sh
+++ b/scripts/docker-entrypoint.sh
@@ -34,11 +34,19 @@ wait-for-it -h ${G3WSUITE_REDIS_HOST:-redis} -p ${G3WSUITE_REDIS_PORT:-6379} -t
# Setup once
/code/ci_scripts/setup_suite.sh
-gunicorn base.wsgi:application \
- --limit-request-fields 0 \
- --error-logfile - \
- --log-level=debug \
- --timeout ${G3WSUITE_GUNICORN_TIMEOUT:-120} \
- --workers=${G3WSUITE_GUNICORN_NUM_WORKERS:-8} \
- --max-requests=${G3WSUITE_GUNICORN_MAX_REQUESTS:-200} \
- -b 0.0.0.0:8000
+if [ ! -f /shared-volume/gunicorn.conf.py ]; then
+ cat > /shared-volume/gunicorn.conf.py << EOF
+import os
+limit_request_fields = 0
+error_logfile = '-'
+log_level = 'info'
+timeout = os.getenv('G3WSUITE_GUNICORN_TIMEOUT', 120)
+workers = os.getenv('G3WSUITE_GUNICORN_NUM_WORKERS', 8)
+max_requests = os.getenv('G3WSUITE_GUNICORN_MAX_REQUESTS', 200)
+bind = '0.0.0.0:8000'
+reload = False # os.path.ismount('/code')
+EOF
+fi
+
+# Start Django server
+gunicorn base.wsgi:application -c /shared-volume/gunicorn.conf.py
diff --git a/scripts/makefile/db-backup.sh b/scripts/makefile/db-backup.sh
new file mode 100755
index 000000000..dc1cf2d92
--- /dev/null
+++ b/scripts/makefile/db-backup.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+##
+# ENV = { dev | prod | consumer }
+##
+if [ -z $ENV ]; then
+ echo "ENV is not set"
+ exit 1
+fi
+
+if [ "$ENV" = "prod" ]; then
+ DOCKER_COMPOSE="docker compose -f docker-compose.yml"
+else
+ DOCKER_COMPOSE="docker compose -f docker-compose-${ENV}.yml"
+fi
+
+source .env
+
+DB_LOGIN="--host ${G3WSUITE_POSTGRES_HOST} --port ${G3WSUITE_POSTGRES_PORT} --username ${G3WSUITE_POSTGRES_USER_LOCAL}"
+DB_NAMES="${G3WSUITE_POSTGRES_DBNAME} data_production data_testing"
+PG_VERSION=`${DOCKER_COMPOSE} exec postgis bash -c pg_config --version | awk '{print $2}' | cut -d'.' -f1`
+ID=${ID:-$PG_VERSION}
+
+##
+# Create a .pgpass in root home
+##
+echo "${G3WSUITE_POSTGRES_HOST}:${G3WSUITE_POSTGRES_PORT}:*:${G3WSUITE_POSTGRES_USER_LOCAL}:${G3WSUITE_POSTGRES_PASS}" > .pgpass
+bash -c "$DOCKER_COMPOSE cp .pgpass postgis:/root/"
+bash -c "$DOCKER_COMPOSE exec postgis chmod 600 /root/.pgpass"
+rm .pgpass
+
+##
+# Backup databases
+##
+echo "#!/bin/bash" > pg_backup.sh
+echo "mkdir -p /var/lib/postgresql/backup/${ID}" >> pg_backup.sh
+
+for DB in $DB_NAMES; do
+ cat >> pg_backup.sh << EOF
+pg_dump ${DB_LOGIN} -d ${DB} --file /var/lib/postgresql/backup/${ID}/${DB}.bck --verbose --format=c --create --clean
+EOF
+done
+
+bash -c "$DOCKER_COMPOSE cp pg_backup.sh postgis:/root/"
+rm pg_backup.sh
+
+bash -c "$DOCKER_COMPOSE exec postgis chmod +x /root/pg_backup.sh"
+bash -c "$DOCKER_COMPOSE exec postgis bash /root/pg_backup.sh"
+bash -c "$DOCKER_COMPOSE exec postgis rm /root/pg_backup.sh"
\ No newline at end of file
diff --git a/scripts/makefile/db-restore.sh b/scripts/makefile/db-restore.sh
new file mode 100755
index 000000000..11c054740
--- /dev/null
+++ b/scripts/makefile/db-restore.sh
@@ -0,0 +1,78 @@
+#!/bin/bash
+
+##
+# ENV = { dev | prod | consumer }
+##
+if [ -z $ENV ]; then
+ echo "ENV is not set"
+ exit 1
+fi
+
+if [ -z $ID ]; then
+ echo "ID is not set"
+ exit 1
+fi
+
+if [ "$ENV" = "prod" ]; then
+ DOCKER_COMPOSE="docker compose -f docker-compose.yml"
+else
+ DOCKER_COMPOSE="docker compose -f docker-compose-${ENV}.yml"
+fi
+
+source .env
+
+PG_VERSION=`${DOCKER_COMPOSE} exec postgis bash -c pg_config --version | awk '{print $2}' | cut -d'.' -f1`
+DB_LOGIN="--host ${G3WSUITE_POSTGRES_HOST} --port ${G3WSUITE_POSTGRES_PORT} --username ${G3WSUITE_POSTGRES_USER_LOCAL}"
+DB_NAMES="${G3WSUITE_POSTGRES_DBNAME} data_production data_testing"
+ID=${ID:-$PG_VERSION}
+
+##
+# Check ID
+##
+if [ -z `${DOCKER_COMPOSE} exec postgis bash -c "test -d /var/lib/postgresql/backup/${ID} && echo '1'"` ]; then
+ echo "invalid ID: $ID"
+ exit 1
+fi
+
+##
+# Create a .pgpass in root home
+##
+echo "${G3WSUITE_POSTGRES_HOST}:${G3WSUITE_POSTGRES_PORT}:*:${G3WSUITE_POSTGRES_USER_LOCAL}:${G3WSUITE_POSTGRES_PASS}" > .pgpass
+bash -c "$DOCKER_COMPOSE cp .pgpass postgis:/root/"
+bash -c "$DOCKER_COMPOSE exec postgis chmod 600 /root/.pgpass"
+rm .pgpass
+
+##
+# Restore databases
+##
+echo "#!/bin/bash" > pg_restore.sh
+
+# Waiting che creation of new cluster.
+
+for DB in $DB_NAMES; do
+ cat >> pg_restore.sh << EOF
+until pg_isready; do
+ echo "wait 30s until is ready"
+ sleep 30;
+done
+psql ${DB_LOGIN} -d template1 -c "DROP DATABASE IF EXISTS ${DB}_1634;"
+psql ${DB_LOGIN} -d template1 -c "create database ${DB}_1634;"
+pg_restore ${DB_LOGIN} -d ${DB}_1634 /var/lib/postgresql/backup/${ID}/${DB}.bck
+psql ${DB_LOGIN} -d ${DB}_1634 -c "select postgis_extensions_upgrade();"
+psql ${DB_LOGIN} -d template1 -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname='${DB}';"
+psql ${DB_LOGIN} -d template1 -c "drop database ${DB};"
+psql ${DB_LOGIN} -d template1 -c "alter database ${DB}_1634 rename to ${DB};"
+EOF
+done
+
+bash -c "$DOCKER_COMPOSE cp pg_restore.sh postgis:/root/"
+rm pg_restore.sh
+
+bash -c "$DOCKER_COMPOSE exec postgis chmod +x /root/pg_restore.sh"
+bash -c "$DOCKER_COMPOSE exec postgis bash /root/pg_restore.sh"
+bash -c "$DOCKER_COMPOSE exec postgis rm /root/pg_restore.sh"
+
+##
+# Restart g3w-suite container
+##
+bash -c "$DOCKER_COMPOSE restart g3w-suite"
diff --git a/scripts/makefile/renew-ssl.sh b/scripts/makefile/renew-ssl.sh
new file mode 100755
index 000000000..a9acb5a5f
--- /dev/null
+++ b/scripts/makefile/renew-ssl.sh
@@ -0,0 +1,38 @@
+#!/bin/bash
+# Run certbot docker container to renew the HTTPS certificate.
+# Requires .env file with container configuration variables
+
+source .env
+
+if [ "${WEBGIS_PUBLIC_HOSTNAME}" = "" ]; then
+ echo "WEBGIS_PUBLIC_HOSTNAME not defined: exiting"
+ exit 1
+fi
+
+if [ "${WEBGIS_DOCKER_SHARED_VOLUME}" = "" ]; then
+ echo "WEBGIS_DOCKER_SHARED_VOLUME not defined: exiting"
+ exit 1
+fi
+
+certs_folder="${WEBGIS_DOCKER_SHARED_VOLUME}/certs/letsencrypt"
+acme_folder="${WEBGIS_DOCKER_SHARED_VOLUME}/var/www/.well-known"
+default_ssl_conf="https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/_internal/tls_configs/options-ssl-nginx.conf"
+default_ssl_pem="https://raw.githubusercontent.com/certbot/certbot/master/certbot/certbot/ssl-dhparams.pem"
+domain="$WEBGIS_PUBLIC_HOSTNAME"
+
+# STEP 1
+echo "### Downloading recommended TLS parameters ..."
+mkdir -p "$certs_folder"
+curl -s "$default_ssl_conf" > "${certs_folder}/options-ssl-nginx.conf"
+curl -s "$default_ssl_pem" > "${certs_folder}/ssl-dhparams.pem"
+
+# STEP 2
+echo "### Requesting Let's Encrypt certificate for $domain ..."
+docker run -it --rm --name certbot --pull=missing \
+ -v ${certs_folder}:/etc/letsencrypt \
+ -v ${acme_folder}:/var/www/.well-known \
+ certbot/certbot -t certonly \
+ --agree-tos --renew-by-default \
+ --no-eff-email \
+ --webroot -w /var/www \
+ -d ${domain}
diff --git a/shared-volume/backup/demo/data_production.bck b/shared-volume/backup/demo/data_production.bck
new file mode 100644
index 000000000..abbe76875
Binary files /dev/null and b/shared-volume/backup/demo/data_production.bck differ
diff --git a/shared-volume/backup/demo/data_testing.bck b/shared-volume/backup/demo/data_testing.bck
new file mode 100644
index 000000000..29f7cf361
Binary files /dev/null and b/shared-volume/backup/demo/data_testing.bck differ
diff --git a/shared-volume/backup/demo/g3wsuite.bck b/shared-volume/backup/demo/g3wsuite.bck
new file mode 100644
index 000000000..dfb013620
Binary files /dev/null and b/shared-volume/backup/demo/g3wsuite.bck differ
diff --git a/shared-volume/gunicorn.conf.py b/shared-volume/gunicorn.conf.py
new file mode 100644
index 000000000..c4ebfe972
--- /dev/null
+++ b/shared-volume/gunicorn.conf.py
@@ -0,0 +1,12 @@
+import os
+limit_request_fields = 0
+error_logfile = '-'
+accesslog = '-'
+access_log_format = '[REQUEST] %(p)s "%(s)s %(m)s %(U)s %(H)s"'
+# access_log_format = '[REQUEST] %(s)s\n\t"%(m)s %(U)s %(H)s"\n\t"FROM %(f)s"\n\t"AGENT %(a)s"\n\t%(p)s'
+log_level = 'info'
+timeout = os.getenv('G3WSUITE_GUNICORN_TIMEOUT', 120)
+workers = os.getenv('G3WSUITE_GUNICORN_NUM_WORKERS', 8)
+max_requests = os.getenv('G3WSUITE_GUNICORN_MAX_REQUESTS', 200)
+bind = '0.0.0.0:8000'
+reload = os.path.ismount('/code')
diff --git a/shared-volume/media/project_data/spatialite/building_management_demo.sqlite b/shared-volume/media/project_data/spatialite/building_management_demo.sqlite
new file mode 100644
index 000000000..dba97db51
Binary files /dev/null and b/shared-volume/media/project_data/spatialite/building_management_demo.sqlite differ
diff --git a/shared-volume/media/project_data/spatialite/plots/qplotly_cost-analysis-for-intervention.xml b/shared-volume/media/project_data/spatialite/plots/qplotly_cost-analysis-for-intervention.xml
new file mode 100644
index 000000000..578072602
--- /dev/null
+++ b/shared-volume/media/project_data/spatialite/plots/qplotly_cost-analysis-for-intervention.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shared-volume/media/project_data/spatialite/plots/qplotly_high-year-by-type.xml b/shared-volume/media/project_data/spatialite/plots/qplotly_high-year-by-type.xml
new file mode 100644
index 000000000..16ea25611
--- /dev/null
+++ b/shared-volume/media/project_data/spatialite/plots/qplotly_high-year-by-type.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shared-volume/media/project_data/spatialite/plots/qplotly_rating-trend.xml b/shared-volume/media/project_data/spatialite/plots/qplotly_rating-trend.xml
new file mode 100644
index 000000000..03341dd3c
--- /dev/null
+++ b/shared-volume/media/project_data/spatialite/plots/qplotly_rating-trend.xml
@@ -0,0 +1,98 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shared-volume/media/project_data/spatialite/plots/qplotly_type-distribution.xml b/shared-volume/media/project_data/spatialite/plots/qplotly_type-distribution.xml
new file mode 100644
index 000000000..a10063dcd
--- /dev/null
+++ b/shared-volume/media/project_data/spatialite/plots/qplotly_type-distribution.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shared-volume/media/project_data/spatialite/plots/qplotly_year-volume.xml b/shared-volume/media/project_data/spatialite/plots/qplotly_year-volume.xml
new file mode 100644
index 000000000..4f3fe0973
--- /dev/null
+++ b/shared-volume/media/project_data/spatialite/plots/qplotly_year-volume.xml
@@ -0,0 +1,93 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/shared-volume/media/projects/3857_public-building-management-demo.qgs b/shared-volume/media/projects/3857_public-building-management-demo.qgs
new file mode 100644
index 000000000..b5b566276
--- /dev/null
+++ b/shared-volume/media/projects/3857_public-building-management-demo.qgs
@@ -0,0 +1,17377 @@
+
+
+
+ Public building management Demo
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ - buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ - roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ - work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ meters
+
+ 1251405.68882991839200258
+ 5432891.28804122190922499
+ 1252856.58116712141782045
+ 5433668.86507420893758535
+
+ 0
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Annotations_31c5549c_b70d_4625_8793_9e879106475f
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+ 1
+ 0
+
+
+
+
+
+ 1251576.10492830001749098
+ 5433028.20238997042179108
+ 1252676.39167100004851818
+ 5433501.81321199983358383
+
+
+ 11.24309944295869812
+ 43.79017313177826054
+ 11.2529834869375609
+ 43.79324430005035396
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="buildings" (geom)
+ Main layer connected through 1: N relation with maintenance interventions list and trend rating
+
+
+
+ buildings
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 2
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+
+
+ buildings_rating_3d535fae_fd04_4df6_b6ff_8cbd13df078f
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="buildings_rating"
+
+
+
+ Buildings rating
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ COALESCE( "year", '<NULL>' )
+
+
+
+ maintenance_works_f8cbe34a_eebe_4cd1_9c78_5d420ab0af63
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="maintenance_works"
+
+
+
+ Maintenance works
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ COALESCE( "date", '<NULL>' )
+
+
+
+
+ 1251946.88214470399543643
+ 5433043.78593171760439873
+ 1252625.35694216866977513
+ 5433426.97840871382504702
+
+
+ 11.24643019136368771
+ 43.7902741870455543
+ 11.25252503416824013
+ 43.7927590381207068
+
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="roads" (geom)
+
+
+
+ roads
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+
+
+ type_subtype_caec4a0b_e7c4_4542_b59c_769f2033d6b1
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="type_subtype"
+
+
+
+ Type - Subtype
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+
+ 1
+ 1
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+ generatedlayout
+
+
+
+
+
+ "type"
+
+
+
+
+ 1251440.23388556623831391
+ 5432909.80178010184317827
+ 1252822.03611147403717041
+ 5433650.35133532714098692
+
+
+ 11.24187889261512829
+ 43.78940532864077539
+ 11.2542918332067412
+ 43.79420747519977652
+
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+ dbname='/shared-volume/media/project_data/spatialite/building_management_demo.sqlite' table="work_areas" (geom)
+
+
+
+ Work areas
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+ spatialite
+
+
+
+
+
+
+
+
+
+ 0
+ 1
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-"""I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.Usa questa funzione per aggiungere logica extra ai tuoi forms..Inserisci il nome della funzione nel campo "Funzione Python di avvio".Segue un esempio:"""from qgis.PyQt.QtWidgets import QWidgetdef my_form_open(dialog, layer, feature): geom = feature.geometry() control = dialog.findChild(QWidget, "MyLineEdit")
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+ 2
+
+
+
+
+
+
+ 1
+ 1
+ 0
+ 0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.
+
+Usa questa funzione per aggiungere logica extra ai tuoi forms..
+
+Inserisci il nome della funzione nel campo "Funzione Python di avvio".
+
+Segue un esempio:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+
+
+
+
+
+
+
+
+
+ 1
+ © OpenStreetMap contributors, CC-BY-SA
+ 1
+ 1
+
+
+
+ 0
+
+
+ 255
+ 255
+ 255
+ 255
+ 0
+ 255
+ 255
+
+
+ true
+
+
+
+
+
+ EPSG:7030
+
+
+ m2
+ meters
+
+
+ 50
+ 5
+ 16
+ 30
+ 2.5
+ false
+ false
+ 1
+ 0
+ false
+ false
+ true
+ 0
+ 255,0,0,255
+
+
+ false
+
+
+ true
+ 2
+ MU
+
+ false
+
+
+ [['Yes', 0, 0, [], [], 'band number', [[], []], 'Band set 0', '', '']]
+ 0
+
+
+ 1
+
+
+
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+ 8
+ 8
+ 8
+
+
+
+
+
+
+
+ None
+ true
+ info@gis3w.it
+ Gis3W SNC
+ Leonardo Lami
+
+ author
+
+ EPSG:3857
+
+
+ 1
+
+ 1251272.6927000000141561
+ 5432681.18240000028163195
+ 1252946.79920000000856817
+ 5433857.58160000015050173
+
+ false
+ no conditions apply
+ 90
+
+ qgis
+ g3wsuite
+ webgis
+
+ 1
+
+ 8
+ G3W-SUITE
+ false
+ <b><h4>Example of cartographic management product with <a href="https://www.qgis.org">QGIS</a> and <a href="https://g3wsuite.it/">G3W-SUITE</a>.</h4></b>
+
+<b><h5>Management of buildings, their value over the years and related maintenance interventions.
+Manage public builds and registering individual maintenance interventions.</h5></b>
+
+<p>The suite allows you to automatically inherit from QGIS project:</p>
+
+<ul>
+ <li>project and layers properties and capabilities</li>
+ <li>join and 1:N relation</li>
+ <li>plots create with <a href="https://github.com/ghtmtt/DataPlotly">DataPlotly</a> QGIS plugin</li>
+ <li>print layouts (simple and atlas)</li>
+ <li>query and editing form</li>
+ <li>editing constraints and widget</li>
+</ul>
+
+
+
+ true
+ Public building management Spatialite
+ 0
+
+ true
+
+
+
+
+
+
+
+ false
+
+
+
+
+ false
+
+ 5000
+
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Public building management Demo
+
+
+
+
+
+
+
+
+
+
+
+ Gis3W
+ 2021-04-02T12:58:19
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ None
+ WholeRaster
+ Estimated
+ 0.02
+ 0.98
+ 2
+
+
+
+
+
+ resamplingFilter
+
+ 0
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 2
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 1
+
+
+
+
+
+ 0
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.
+
+Usa questa funzione per aggiungere logica extra ai tuoi forms..
+
+Inserisci il nome della funzione nel campo "Funzione Python di avvio".
+
+Segue un esempio:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ None
+ WholeRaster
+ Estimated
+ 0.02
+ 0.98
+ 2
+
+
+
+
+
+ resamplingFilter
+
+ 0
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 2
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 1
+
+
+
+
+
+ 0
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.
+
+Usa questa funzione per aggiungere logica extra ai tuoi forms..
+
+Inserisci il nome della funzione nel campo "Funzione Python di avvio".
+
+Segue un esempio:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ None
+ WholeRaster
+ Estimated
+ 0.02
+ 0.98
+ 2
+
+
+
+
+
+ resamplingFilter
+
+ 0
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 2
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 1
+
+
+
+
+
+ 0
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.
+
+Usa questa funzione per aggiungere logica extra ai tuoi forms..
+
+Inserisci il nome della funzione nel campo "Funzione Python di avvio".
+
+Segue un esempio:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ buildings_2f43dc1d_6725_42d2_a09b_dd446220104a
+ roads_ea006d6f_bd87_4635_aae0_4e9e7842b3f4
+ work_areas_f0ecbe28_cbd1_4a38_8a57_ab6da91473fe
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ None
+ WholeRaster
+ Estimated
+ 0.02
+ 0.98
+ 2
+
+
+
+
+
+ resamplingFilter
+
+ 0
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 2
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ tablayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "fid"
+
+ 4
+
+
+
+
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+QGIS forms can have a Python function that is called when the form is
+opened.
+
+Use this function to add extra logic to your forms.
+
+Enter the name of the function in the "Python Init function"
+field.
+An example follows:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ "name"
+
+ 1
+
+
+
+
+
+ 0
+ 1
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+ 0
+ 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0
+
+ # -*- coding: utf-8 -*-
+"""
+I form QGIS possono avere una funzione Python che può essere chiamata quando un form viene aperto.
+
+Usa questa funzione per aggiungere logica extra ai tuoi forms..
+
+Inserisci il nome della funzione nel campo "Funzione Python di avvio".
+
+Segue un esempio:
+"""
+from qgis.PyQt.QtWidgets import QWidget
+
+def my_form_open(dialog, layer, feature):
+ geom = feature.geometry()
+ control = dialog.findChild(QWidget, "MyLineEdit")
+
+ 0
+ generatedlayout
+
+
+
+
+
+
+
+
+
+
+
+
+ "id"
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+ PROJCRS["WGS 84 / Pseudo-Mercator",BASEGEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],ID["EPSG",4326]],CONVERSION["Popular Visualisation Pseudo-Mercator",METHOD["Popular Visualisation Pseudo Mercator",ID["EPSG",1024]],PARAMETER["Latitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8801]],PARAMETER["Longitude of natural origin",0,ANGLEUNIT["degree",0.0174532925199433],ID["EPSG",8802]],PARAMETER["False easting",0,LENGTHUNIT["metre",1],ID["EPSG",8806]],PARAMETER["False northing",0,LENGTHUNIT["metre",1],ID["EPSG",8807]]],CS[Cartesian,2],AXIS["easting (X)",east,ORDER[1],LENGTHUNIT["metre",1]],AXIS["northing (Y)",north,ORDER[2],LENGTHUNIT["metre",1]],USAGE[SCOPE["Web mapping and visualisation."],AREA["World between 85.06°S and 85.06°N."],BBOX[-85.06,-180,85.06,180]],ID["EPSG",3857]]
+ +proj=merc +a=6378137 +b=6378137 +lat_ts=0 +lon_0=0 +x_0=0 +y_0=0 +k=1 +units=m +nadgrids=@null +wktext +no_defs
+ 3857
+ 3857
+ EPSG:3857
+ WGS 84 / Pseudo-Mercator
+ merc
+ EPSG:7030
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GEOGCRS["WGS 84",ENSEMBLE["World Geodetic System 1984 ensemble",MEMBER["World Geodetic System 1984 (Transit)"],MEMBER["World Geodetic System 1984 (G730)"],MEMBER["World Geodetic System 1984 (G873)"],MEMBER["World Geodetic System 1984 (G1150)"],MEMBER["World Geodetic System 1984 (G1674)"],MEMBER["World Geodetic System 1984 (G1762)"],MEMBER["World Geodetic System 1984 (G2139)"],ELLIPSOID["WGS 84",6378137,298.257223563,LENGTHUNIT["metre",1]],ENSEMBLEACCURACY[2.0]],PRIMEM["Greenwich",0,ANGLEUNIT["degree",0.0174532925199433]],CS[ellipsoidal,2],AXIS["geodetic latitude (Lat)",north,ORDER[1],ANGLEUNIT["degree",0.0174532925199433]],AXIS["geodetic longitude (Lon)",east,ORDER[2],ANGLEUNIT["degree",0.0174532925199433]],USAGE[SCOPE["Horizontal component of 3D system."],AREA["World."],BBOX[-90,-180,90,180]],ID["EPSG",4326]]
+ +proj=longlat +datum=WGS84 +no_defs
+ 3452
+ 4326
+ EPSG:4326
+ WGS 84
+ longlat
+ EPSG:7030
+ true
+
+
+
+
\ No newline at end of file