Update the docker-osm from the OSGS osm-mirror service (#120)

* update the mapping.yml file

* update post-pbf-import.sql.example

* update qgis_style.sql

* update production import nd backup schemas

* add the materialized_views schema

* update osm-mirror project

* add elevation data and the materialized view layers for the default qgis-project

* update the readme

* update qgis_style.sql
pull/123/head
Victoria Neema 2022-06-07 16:55:23 +03:00 zatwierdzone przez GitHub
rodzic 79680727de
commit f3452495f9
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
11 zmienionych plików z 39877 dodań i 4688 usunięć

Wyświetl plik

@ -32,11 +32,11 @@ SRID=4326
# see http://imposm.org/docs/imposm3/latest/tutorial.html#optimize
OPTIMIZE=false
# see http://imposm.org/docs/imposm3/latest/tutorial.html#deploy-production-tables
DBSCHEMA_PRODUCTION=public
DBSCHEMA_PRODUCTION=osm
# http://imposm.org/docs/imposm3/latest/tutorial.html#deploy-production-tables
DBSCHEMA_IMPORT=import
DBSCHEMA_IMPORT=osm_import
# http://imposm.org/docs/imposm3/latest/tutorial.html#deploy-production-tables
DBSCHEMA_BACKUP=backup
DBSCHEMA_BACKUP=osm_backup
# Install some styles if you are using the default mapping. It can be 'yes' or 'no'
QGIS_STYLE=yes
# Use clip in the database - To use this you should have run make import_clip to add your clip to the DB

Wyświetl plik

@ -122,3 +122,40 @@ backup_styles:
@echo "------------------------------------------------------------------"
@echo "SET XML OPTION DOCUMENT;" > BACKUP-STYLES.sql
@docker-compose exec -T db su - postgres -c "/usr/bin/pg_dump --format plain --inserts --table public.layer_styles gis" >> BACKUP-STYLES.sql
###
# QGIS Project
###
materialized_views:
@echo
@echo "------------------------------------------------------------------"
@echo "Generate materialized views for the OSM layers"
@echo "------------------------------------------------------------------"
@docker cp settings/materialized_views.sql dockerosm_db_1:/tmp/
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec -u postgres db psql -f /tmp/materialized_views.sql -d gis
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec db rm /tmp/materialized_views.sql
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec -u postgres db psql -c "select schemaname as schema_name, matviewname as view_name, matviewowner as owner, ispopulated as is_populated from pg_matviews order by schema_name, view_name;" gis
elevation:
@echo "-------------------------------------------------------------------"
@echo "Adding the SRTM 30m DEM and contours for the OSM clip area to the db"
@echo "-------------------------------------------------------------------"
@python3 settings/getDEM.py
@echo -n "Are you sure you want to delete the elevation schema? [y/N] " && read ans && [ $${ans:-N} = y ]
# - at start of next line means error will be ignored (in case the elevation schema isn't already there)
-@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec -u postgres db psql -c "DROP SCHEMA IF EXISTS elevation CASCADE; CREATE SCHEMA elevation AUTHORIZATION docker;" gis
# Load the dem into the database.
@raster2pgsql -s 4326 -C -P -F -I settings/SRTM_DEM/SRTM_30m_DEM.tif elevation.dem > settings/SRTM_DEM/srtm30m_dem.sql
@docker cp settings/SRTM_DEM/srtm30m_dem.sql dockerosm_db_1:/tmp/
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec -u postgres db psql -f /tmp/srtm30m_dem.sql -d gis
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec db rm /tmp/srtm30m_dem.sql
# Load the contours into the database.
@shp2pgsql -s 4326 settings/SRTM_DEM/countours.shp elevation.contours > settings/SRTM_DEM/contours.sql
@docker cp settings/SRTM_DEM/contours.sql dockerosm_db_1:/tmp/
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec -u postgres db psql -f /tmp/contours.sql -d gis
@COMPOSE_PROFILES=$(shell paste -sd, enabled-profiles) docker-compose exec db rm /tmp/contours.sql
# File clean up
@rm -r settings/SRTM_DEM/

Wyświetl plik

@ -146,6 +146,20 @@ smaller extent. The CRS of the geojson should always be EPSG:4326.
a simplified geometry is easier to process during the import.
Rather use the minimum bounding box for the area you intend to clip your dataset with.
### QGIS project
There is a default QGIS project provided in the `web/` folder, named `osm_mirror_qgis_project.qgz`. To be able to load the layers in this project correctly in QGIS, first run `make materialized_views` and `make elevation` then set up your connection service file with the following parameters. The host parameter is where you have set up `docker-osm`:
```
[docker-osm]
dbname=gis
port=35432
user=docker
password=docker
host=<host>
sslmode=disable
```
### QGIS Styles
The database is provided with some default styles. These styles will be loaded

122
settings/getDEM.py 100644
Wyświetl plik

@ -0,0 +1,122 @@
# This code is adapted from https://dwtkns.com/srtm30m/
# Load the necessary packages.
import os
import geopandas as gpd
import glob
from zipfile import ZipFile
from osgeo import gdal
import getpass
## Set up a .wgetrc file to store your NASA Earthdata login username and password,
# https://lpdaac.usgs.gov/documents/195/HowtoAccessLPDAACDatafromtheCommandLine_FINAL_CK.docx
print("Please enter your NASA Earthdata credentials!")
earthdata_username = input("Enter NASA Earthdata username: ")
earthdata_password = getpass.getpass("Enter your NASA Earthdata password: ")
# Check if the login credentials already exist and add the login credentials
# if they don't.
wgetrc_fp = '~/.wgetrc'
full_wgetrc_fp = os.path.expanduser(wgetrc_fp)
try:
file = open(full_wgetrc_fp)
except FileNotFoundError:
os.system("touch ~/.wgetrc | chmod og-rw ~/.wgetrc")
with open(full_wgetrc_fp) as myfile:
if f'http-user={earthdata_username}' and f'http-password={earthdata_password}' in myfile.read():
print("The NASA Earthdata credentials provided already exist.")
else:
os.system(
f"echo http-user={earthdata_username} >> ~/.wgetrc | echo http-password={earthdata_password} >> ~/.wgetrc")
## Get the SRTM_30m DEM for the osm clip area.
# Load the clip.geojson file.
clip_fp = 'settings/clip.geojson'
clip_gdf = gpd.read_file(clip_fp)
# Create the output directory to store the elevation data if it does not exist.
output_dir = "settings/SRTM_DEM"
os.system(f"mkdir -p {output_dir}")
# Download and load the GeoJSON indexing DEM file names.
strm30m_tile_index_fp = os.path.join(output_dir, "srtm30m_bounding_boxes.geojson")
os.system(
f"wget -nc -O {strm30m_tile_index_fp} https://dwtkns.com/srtm30m/srtm30m_bounding_boxes.json")
srtm30m_tile_index = gpd.read_file(strm30m_tile_index_fp)
# Get the SRTM tiles that intersect with the clip.geojson.
# For each SRTM tile, check if it intersects with the clip.geojson.
srtm30m_tile_index['intersect'] = srtm30m_tile_index.geometry.map(
lambda x: x.intersects(clip_gdf.geometry.any()))
# Get the indices for the tiles intersect with the clip.geojson.
index = srtm30m_tile_index.index
condition = srtm30m_tile_index['intersect'] == True
intersection_indices = index[condition]
intersection_indices_list = intersection_indices.tolist()
# Get a list of the file names for the tiles that intersect with the clip.geojson.
tile_names = srtm30m_tile_index.iloc[intersection_indices_list]['dataFile'].to_list(
)
# Download the tiles into the output directory.
# Tiles come as zipped SRTMHGT files at # 1-arcsecond resolution (3601x3601 pixels)
# in a latitude/longitude projection (EPSG:4326), downloaded from NASA servers.
for tile in tile_names:
base_url = "http://e4ftl01.cr.usgs.gov/MEASURES/SRTMGL1.003/2000.02.11/"
download_url = base_url + tile
download_command = f"wget -nc -P {output_dir} " + download_url
os.system(download_command)
# Get the list of downloaded zipfiles in the output directory.
zip_search_criteria = "*.zip"
zip_query = os.path.join(output_dir, zip_search_criteria)
srtm30m_zipfiles = glob.glob(zip_query)
# Extract the SRTMHGT files from the downloaded zipfiles.
for srtm30m_zipfile in srtm30m_zipfiles:
# Create a ZipFile Object and load the zipfile into it.
with ZipFile(f'{srtm30m_zipfile}', 'r') as zipObj:
# Extract all the contents of the zip file in the output directory.
zipObj.extractall(output_dir)
# Get the list of extracted SRTMHGT files.
hgt_search_criteria = "*.hgt"
hgt_query = os.path.join(output_dir, hgt_search_criteria)
hgt_files = glob.glob(hgt_query)
# Merge the SRTMHGT files into a single TIF file.
merged_tif = 'merged_SRTM_30m_DEM.tif'
merged_tif_fp = os.path.join(output_dir, merged_tif)
files_string = " ".join(hgt_files)
command = f"gdal_merge.py -o {merged_tif_fp} -of GTiff -co COMPRESS=DEFLATE -co TILED=YES -co PREDICTOR=2 -co ZLEVEL=9 -ot Int16 " + files_string
os.system(command)
# Clip the merged TIF file using the clip.geojson vector.
srtm30m_tif = 'SRTM_30m_DEM.tif'
srtm30m_tif_fp = os.path.join(output_dir, srtm30m_tif)
clip_command = f"gdalwarp -overwrite -t_srs EPSG:4326 -of GTiff -tr 0.0002777777777777777 -0.0002777777777777778 -tap -cutline {clip_fp} -crop_to_cutline -dstnodata -9999.0 -co COMPRESS=DEFLATE -co PREDICTOR=2 -co ZLEVEL=9 {merged_tif_fp} {srtm30m_tif_fp}"
os.system(clip_command)
# Generate contours from the clipped TIF file.
contours_fn = 'countours.shp'
contours_fp = os.path.join(output_dir, contours_fn)
generate_contours_command = f'gdal_contour -b 1 -a ELEV -i 20.0 -f "ESRI Shapefile" {srtm30m_tif_fp} {contours_fp}'
os.system(generate_contours_command)
## File clean up.
# Remove the GeoJSON indexing DEM file names.
os.remove(strm30m_tile_index_fp)
# Delete the downloaded zipfiles.
for srtm30m_zipfile in srtm30m_zipfiles:
os.remove(srtm30m_zipfile)
# Delete the SRTMHGT files.
for hgt_file in hgt_files:
os.remove(hgt_file)
# Remove the merged TIF file.
os.remove(merged_tif_fp)

Plik diff jest za duży Load Diff

Wyświetl plik

@ -0,0 +1,84 @@
-- Drop the materialized_views schema if it exists.
DROP SCHEMA IF EXISTS materialized_views CASCADE;
-- Create the materialized_views schema.
CREATE SCHEMA materialized_views;
ALTER SCHEMA materialized_views OWNER TO docker;
-- Create materialized views for the osm_admin layer.
CREATE MATERIALIZED VIEW materialized_views.osm_admin_500m_8m AS
SELECT *
FROM osm.osm_admin
WHERE admin_level = 2;
CREATE MATERIALIZED VIEW materialized_views.osm_admin_8m_2m AS
SELECT *
FROM osm.osm_admin
WHERE admin_level = 3;
CREATE MATERIALIZED VIEW materialized_views.osm_admin_2m_500k AS
SELECT *
FROM osm.osm_admin
WHERE admin_level = 4;
CREATE MATERIALIZED VIEW materialized_views.osm_admin_500k_0 AS
SELECT *
FROM osm.osm_admin
WHERE admin_level > 4;
-- Create materialized views for the osm_roads layer.
CREATE MATERIALIZED VIEW materialized_views.osm_roads_15m AS
SELECT *
FROM osm.osm_roads
WHERE type SIMILAR TO '%(trunk|primary)%';
CREATE MATERIALIZED VIEW materialized_views.osm_roads_1m AS
SELECT *
FROM osm.osm_roads
WHERE type SIMILAR TO '%(secondary)%';
CREATE MATERIALIZED VIEW materialized_views.osm_roads_500k AS
SELECT *
FROM osm.osm_roads
WHERE type SIMILAR TO '%(tertiary)%';
CREATE MATERIALIZED VIEW materialized_views.osm_roads_15k AS
SELECT *
FROM osm.osm_roads
WHERE type NOT LIKE ALL(ARRAY['trunk', 'trunk_link', 'primary', 'primary_link', 'secondary', 'secondary_link', 'tertiary', 'tertiary_link']);
-- Create materialized views for the osm_places layer.
CREATE MATERIALIZED VIEW materialized_views.osm_places_8m_2m AS
SELECT *
FROM osm.osm_places
WHERE place IN ('state', 'region');
CREATE MATERIALIZED VIEW materialized_views.osm_places_2m_500k AS
SELECT *
FROM osm.osm_places
WHERE place = 'county';
CREATE MATERIALIZED VIEW materialized_views.osm_places_2m_150k AS
SELECT *
FROM osm.osm_places
WHERE place = 'city';
CREATE MATERIALIZED VIEW materialized_views.osm_places_150k AS
SELECT *
FROM osm.osm_places
WHERE place = 'town';
CREATE MATERIALIZED VIEW materialized_views.osm_places_70k AS
SELECT *
FROM osm.osm_places
WHERE place IN ('suburb', 'village', 'hamlet') ;
CREATE MATERIALIZED VIEW materialized_views.osm_places_35k AS
SELECT *
FROM osm.osm_places
WHERE place = 'locality';

Wyświetl plik

@ -0,0 +1,20 @@
CREATE OR REPLACE FUNCTION clean_tables() RETURNS void AS
$BODY$
DECLARE osm_tables CURSOR FOR
SELECT table_name
FROM information_schema.tables
WHERE table_schema='public'
AND table_type='BASE TABLE'
AND table_name LIKE 'osm_%';
BEGIN
FOR osm_table IN osm_tables LOOP
EXECUTE 'DELETE FROM ' || quote_ident(osm_table.table_name) || ' WHERE osm_id IN (
SELECT DISTINCT osm_id
FROM ' || quote_ident(osm_table.table_name) || '
LEFT JOIN clip ON ST_Intersects(geometry, geom)
WHERE clip.ogc_fid IS NULL)
;';
END LOOP;
END;
$BODY$
LANGUAGE plpgsql;

41557
settings/qgis_style.sql 100755 → 100644

File diff suppressed because one or more lines are too long

Wyświetl plik

@ -1,57 +0,0 @@
<!DOCTYPE html><html><head>
<title>Docker OSM</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<style>
body {
padding: 0;
margin: 0;
}
html, body, #map {
height: 100%;
width: 100%;
background-color: #2b6adb;
}
#overlay{
position:absolute;
top:10px;
left:50px;
background-color:rgba(255, 255, 255, 0.7);
padding: 5px;
border: 1px solid;
border-radius: 2px;
z-index: 100;
}
</style>
</head>
<body>
<div id="map"></div>
<div id="overlay">timestamp</div>
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
<script>
var timestamp;
xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200) {
timestamp = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "settings/timestamp.txt", false );
xmlhttp.send();
document.getElementById('overlay').innerHTML = timestamp;
var map = L.map('map').setView([0, 0], 3);
var osm = L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png?').addTo(map);
var wms = L.tileLayer.wms("http://localhost:8198/", {
layers: 'osm_buildings20160720014515980',
format: 'image/png',
transparent: true,
attribution: "OpenStreetMap"
}).addTo(map);
var overlays = {
"OSM-Docker": wms,
"OSM-Tiles": osm
};
L.control.layers({}, overlays).addTo(map);
</script></body></html>

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -1,805 +0,0 @@
<!DOCTYPE qgis PUBLIC 'http://mrcc.com/qgis.dtd' 'SYSTEM'>
<qgis projectname="" version="3.4.12-Madeira">
<homePath path=""/>
<title></title>
<autotransaction active="0"/>
<evaluateDefaultValues active="0"/>
<trust active="0"/>
<projectCrs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</projectCrs>
<layer-tree-group>
<customproperties/>
<layer-tree-layer name="osm_roads" expanded="1" id="osm_roads20180302190105366" source="dbname='gis' host=db port=5432 user='docker' sslmode=disable key='id,osm_id' srid=4326 type=LineString checkPrimaryKeyUnicity='1' table=&quot;public&quot;.&quot;osm_roads&quot; (geometry) sql=" providerKey="postgres" checked="Qt::Checked">
<customproperties/>
</layer-tree-layer>
<layer-tree-layer name="osm_buildings" expanded="1" id="osm_buildings20160720014515980" source="dbname='gis' host=db port=5432 user='docker' sslmode=disable key='id,osm_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table=&quot;public&quot;.&quot;osm_buildings&quot; (geometry) sql=" providerKey="postgres" checked="Qt::Checked">
<customproperties/>
</layer-tree-layer>
<custom-order enabled="0">
<item>osm_buildings20160720014515980</item>
<item>osm_roads20180302190105366</item>
</custom-order>
</layer-tree-group>
<snapping-settings intersection-snapping="0" mode="1" tolerance="0" enabled="0" unit="2" type="1">
<individual-layer-settings>
<layer-setting tolerance="0" id="osm_buildings20160720014515980" units="1" enabled="0" type="2"/>
<layer-setting tolerance="12" id="osm_roads20180302190105366" units="1" enabled="0" type="1"/>
</individual-layer-settings>
</snapping-settings>
<relations/>
<mapcanvas name="theMapCanvas" annotationsVisible="1">
<units>degrees</units>
<extent>
<xmin>47.52122050961614264</xmin>
<ymin>-18.91370031309673294</ymin>
<xmax>47.52770232007358686</xmax>
<ymax>-18.90150075927243023</ymax>
</extent>
<rotation>0</rotation>
<destinationsrs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</destinationsrs>
<rendermaptile>0</rendermaptile>
</mapcanvas>
<projectModels/>
<legend updateDrawingOrder="true">
<legendlayer name="osm_roads" open="true" drawingOrder="-1" checked="Qt::Checked" showFeatureCount="0">
<filegroup open="true" hidden="false">
<legendlayerfile visible="1" isInOverview="0" layerid="osm_roads20180302190105366"/>
</filegroup>
</legendlayer>
<legendlayer name="osm_buildings" open="true" drawingOrder="-1" checked="Qt::Checked" showFeatureCount="0">
<filegroup open="true" hidden="false">
<legendlayerfile visible="1" isInOverview="0" layerid="osm_buildings20160720014515980"/>
</filegroup>
</legendlayer>
</legend>
<mapViewDocks/>
<projectlayers>
<maplayer minScale="3.25069e+06" readOnly="0" simplifyAlgorithm="0" simplifyLocal="1" maxScale="1" refreshOnNotifyEnabled="0" refreshOnNotifyMessage="" hasScaleBasedVisibilityFlag="1" styleCategories="AllStyleCategories" autoRefreshTime="0" simplifyDrawingTol="1" geometry="Polygon" simplifyDrawingHints="1" simplifyMaxScale="1" autoRefreshEnabled="0" type="vector" labelsEnabled="1">
<extent>
<xmin>-171.99783107077300315</xmin>
<ymin>-46.96690365331490113</ymin>
<xmax>178.47205985402101192</xmax>
<ymax>71.23581296164789478</ymax>
</extent>
<id>osm_buildings20160720014515980</id>
<datasource>dbname='gis' host=db port=5432 user='docker' password='docker' sslmode=disable key='id,osm_id' srid=4326 type=MultiPolygon checkPrimaryKeyUnicity='1' table="public"."osm_buildings" (geometry) sql=</datasource>
<keywordList>
<value></value>
</keywordList>
<layername>osm_buildings</layername>
<srs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</srs>
<resourceMetadata>
<identifier></identifier>
<parentidentifier></parentidentifier>
<language></language>
<type></type>
<title></title>
<abstract></abstract>
<links/>
<fees></fees>
<encoding></encoding>
<crs>
<spatialrefsys>
<proj4></proj4>
<srsid>0</srsid>
<srid>0</srid>
<authid></authid>
<description></description>
<projectionacronym></projectionacronym>
<ellipsoidacronym></ellipsoidacronym>
<geographicflag>false</geographicflag>
</spatialrefsys>
</crs>
<extent/>
</resourceMetadata>
<provider encoding="UTF-8">postgres</provider>
<vectorjoins/>
<layerDependencies/>
<dataDependencies/>
<legend type="default-vector"/>
<expressionfields/>
<map-layer-style-manager current="défaut">
<map-layer-style name="défaut"/>
</map-layer-style-manager>
<auxiliaryLayer/>
<flags>
<Identifiable>1</Identifiable>
<Removable>1</Removable>
<Searchable>1</Searchable>
</flags>
<renderer-v2 enableorderby="0" symbollevels="0" type="singleSymbol" forceraster="0">
<symbols>
<symbol name="0" alpha="1" force_rhr="0" clip_to_extent="1" type="fill">
<layer class="SimpleFill" pass="0" enabled="1" locked="0">
<prop k="border_width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<prop k="color" v="255,255,255,255"/>
<prop k="joinstyle" v="bevel"/>
<prop k="offset" v="0,0"/>
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<prop k="offset_unit" v="MM"/>
<prop k="outline_color" v="255,255,255,255"/>
<prop k="outline_style" v="solid"/>
<prop k="outline_width" v="0.26"/>
<prop k="outline_width_unit" v="MM"/>
<prop k="style" v="solid"/>
<data_defined_properties>
<Option type="Map">
<Option name="name" type="QString" value=""/>
<Option name="properties"/>
<Option name="type" type="QString" value="collection"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</symbols>
<rotation/>
<sizescale/>
</renderer-v2>
<customproperties>
<property key="embeddedWidgets/count" value="0"/>
<property key="variableNames"/>
<property key="variableValues"/>
</customproperties>
<blendMode>0</blendMode>
<featureBlendMode>0</featureBlendMode>
<layerOpacity>1</layerOpacity>
<LinearlyInterpolatedDiagramRenderer attributeLegend="1" diagramType="Histogram" classificationAttributeExpression="" lowerHeight="0" upperWidth="50" lowerWidth="0" upperValue="0" upperHeight="50" lowerValue="0">
<DiagramCategory enabled="0" lineSizeType="MM" penAlpha="255" scaleBasedVisibility="0" rotationOffset="270" height="15" diagramOrientation="Up" backgroundAlpha="255" penColor="#000000" sizeType="MM" barWidth="5" opacity="1" lineSizeScale="3x:0,0,0,0,0,0" minScaleDenominator="100000" labelPlacementMethod="XHeight" width="15" minimumSize="0" sizeScale="3x:0,0,0,0,0,0" backgroundColor="#ffffff" scaleDependency="Area" maxScaleDenominator="1e+08" penWidth="0">
<fontProperties style="" description=".SF NS Text,13,-1,5,50,0,0,0,0,0"/>
<attribute color="#000000" label="" field=""/>
</DiagramCategory>
</LinearlyInterpolatedDiagramRenderer>
<DiagramLayerSettings priority="0" dist="0" placement="0" zIndex="0" showAll="1" obstacle="0" linePlacementFlags="10">
<properties>
<Option type="Map">
<Option name="name" type="QString" value=""/>
<Option name="properties" type="Map">
<Option name="show" type="Map">
<Option name="active" type="bool" value="true"/>
<Option name="field" type="QString" value="id"/>
<Option name="type" type="int" value="2"/>
</Option>
</Option>
<Option name="type" type="QString" value="collection"/>
</Option>
</properties>
</DiagramLayerSettings>
<geometryOptions removeDuplicateNodes="0" geometryPrecision="0">
<activeChecks/>
<checkConfiguration/>
</geometryOptions>
<fieldConfiguration>
<field name="id">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="osm_id">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="name">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="type">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
</fieldConfiguration>
<aliases>
<alias name="" field="id" index="0"/>
<alias name="" field="osm_id" index="1"/>
<alias name="" field="name" index="2"/>
<alias name="" field="type" index="3"/>
</aliases>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<defaults>
<default expression="" applyOnUpdate="0" field="id"/>
<default expression="" applyOnUpdate="0" field="osm_id"/>
<default expression="" applyOnUpdate="0" field="name"/>
<default expression="" applyOnUpdate="0" field="type"/>
</defaults>
<constraints>
<constraint constraints="1" notnull_strength="1" unique_strength="0" exp_strength="0" field="id"/>
<constraint constraints="1" notnull_strength="1" unique_strength="0" exp_strength="0" field="osm_id"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="name"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="type"/>
</constraints>
<constraintExpressions>
<constraint desc="" exp="" field="id"/>
<constraint desc="" exp="" field="osm_id"/>
<constraint desc="" exp="" field="name"/>
<constraint desc="" exp="" field="type"/>
</constraintExpressions>
<expressionfields/>
<attributeactions/>
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
<columns>
<column name="id" width="-1" hidden="0" type="field"/>
<column name="osm_id" width="-1" hidden="0" type="field"/>
<column name="name" width="-1" hidden="0" type="field"/>
<column name="type" width="-1" hidden="0" type="field"/>
<column width="-1" hidden="1" type="actions"/>
</columns>
</attributetableconfig>
<conditionalstyles>
<rowstyles/>
<fieldstyles/>
</conditionalstyles>
<editform tolerant="1">.</editform>
<editforminit/>
<editforminitcodesource>0</editforminitcodesource>
<editforminitfilepath>.</editforminitfilepath>
<editforminitcode><![CDATA[# -*- 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")
]]></editforminitcode>
<featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout>
<editable/>
<labelOnTop/>
<widgets/>
<previewExpression>"name"</previewExpression>
<mapTip></mapTip>
</maplayer>
<maplayer minScale="100000" readOnly="0" simplifyAlgorithm="0" simplifyLocal="1" maxScale="1" refreshOnNotifyEnabled="0" refreshOnNotifyMessage="" hasScaleBasedVisibilityFlag="1" styleCategories="AllStyleCategories" autoRefreshTime="0" simplifyDrawingTol="1" geometry="Line" simplifyDrawingHints="1" simplifyMaxScale="1" autoRefreshEnabled="0" type="vector" labelsEnabled="1">
<extent>
<xmin>-172.03645261748201278</xmin>
<ymin>-46.88596606843370296</ymin>
<xmax>178.46728317503999506</xmax>
<ymax>69.04282369931030416</ymax>
</extent>
<id>osm_roads20180302190105366</id>
<datasource>dbname='gis' host=db port=5432 user='docker' password='docker' sslmode=disable key='id,osm_id' srid=4326 type=LineString checkPrimaryKeyUnicity='1' table="public"."osm_roads" (geometry) sql=</datasource>
<keywordList>
<value></value>
</keywordList>
<layername>osm_roads</layername>
<srs>
<spatialrefsys>
<proj4>+proj=longlat +datum=WGS84 +no_defs</proj4>
<srsid>3452</srsid>
<srid>4326</srid>
<authid>EPSG:4326</authid>
<description>WGS 84</description>
<projectionacronym>longlat</projectionacronym>
<ellipsoidacronym>WGS84</ellipsoidacronym>
<geographicflag>true</geographicflag>
</spatialrefsys>
</srs>
<resourceMetadata>
<identifier></identifier>
<parentidentifier></parentidentifier>
<language></language>
<type></type>
<title></title>
<abstract></abstract>
<links/>
<fees></fees>
<encoding></encoding>
<crs>
<spatialrefsys>
<proj4></proj4>
<srsid>0</srsid>
<srid>0</srid>
<authid></authid>
<description></description>
<projectionacronym></projectionacronym>
<ellipsoidacronym></ellipsoidacronym>
<geographicflag>false</geographicflag>
</spatialrefsys>
</crs>
<extent/>
</resourceMetadata>
<provider encoding="UTF-8">postgres</provider>
<vectorjoins/>
<layerDependencies/>
<dataDependencies/>
<legend type="default-vector"/>
<expressionfields/>
<map-layer-style-manager current="défaut">
<map-layer-style name="défaut"/>
</map-layer-style-manager>
<auxiliaryLayer/>
<flags>
<Identifiable>1</Identifiable>
<Removable>1</Removable>
<Searchable>1</Searchable>
</flags>
<renderer-v2 enableorderby="0" symbollevels="0" type="singleSymbol" forceraster="0">
<symbols>
<symbol name="0" alpha="1" force_rhr="0" clip_to_extent="1" type="line">
<layer class="SimpleLine" pass="0" enabled="1" locked="0">
<prop k="capstyle" v="square"/>
<prop k="customdash" v="5;2"/>
<prop k="customdash_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<prop k="customdash_unit" v="MM"/>
<prop k="draw_inside_polygon" v="0"/>
<prop k="joinstyle" v="bevel"/>
<prop k="line_color" v="255,255,255,255"/>
<prop k="line_style" v="solid"/>
<prop k="line_width" v="0.26"/>
<prop k="line_width_unit" v="MM"/>
<prop k="offset" v="0"/>
<prop k="offset_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<prop k="offset_unit" v="MM"/>
<prop k="ring_filter" v="0"/>
<prop k="use_custom_dash" v="0"/>
<prop k="width_map_unit_scale" v="3x:0,0,0,0,0,0"/>
<data_defined_properties>
<Option type="Map">
<Option name="name" type="QString" value=""/>
<Option name="properties"/>
<Option name="type" type="QString" value="collection"/>
</Option>
</data_defined_properties>
</layer>
</symbol>
</symbols>
<rotation/>
<sizescale/>
</renderer-v2>
<customproperties>
<property key="variableNames" value="_fields_"/>
<property key="variableValues" value=""/>
</customproperties>
<blendMode>0</blendMode>
<featureBlendMode>0</featureBlendMode>
<layerOpacity>1</layerOpacity>
<SingleCategoryDiagramRenderer attributeLegend="1" diagramType="Pie">
<DiagramCategory enabled="0" lineSizeType="MM" penAlpha="255" scaleBasedVisibility="0" rotationOffset="270" height="15" diagramOrientation="Up" backgroundAlpha="255" penColor="#000000" sizeType="MM" barWidth="5" opacity="1" lineSizeScale="3x:0,0,0,0,0,0" minScaleDenominator="1" labelPlacementMethod="XHeight" width="15" minimumSize="0" sizeScale="3x:0,0,0,0,0,0" backgroundColor="#ffffff" scaleDependency="Area" maxScaleDenominator="1e+08" penWidth="0">
<fontProperties style="" description=".SF NS Text,13,-1,5,50,0,0,0,0,0"/>
<attribute color="#000000" label="" field=""/>
</DiagramCategory>
</SingleCategoryDiagramRenderer>
<DiagramLayerSettings priority="0" dist="0" placement="2" zIndex="0" showAll="1" obstacle="0" linePlacementFlags="10">
<properties>
<Option type="Map">
<Option name="name" type="QString" value=""/>
<Option name="properties" type="Map">
<Option name="show" type="Map">
<Option name="active" type="bool" value="true"/>
<Option name="field" type="QString" value="id"/>
<Option name="type" type="int" value="2"/>
</Option>
</Option>
<Option name="type" type="QString" value="collection"/>
</Option>
</properties>
</DiagramLayerSettings>
<geometryOptions removeDuplicateNodes="0" geometryPrecision="0">
<activeChecks/>
<checkConfiguration/>
</geometryOptions>
<fieldConfiguration>
<field name="id">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="osm_id">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="type">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="name">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="tunnel">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="bridge">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="oneway">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="ref">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="z_order">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="access">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="service">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
<field name="class">
<editWidget type="TextEdit">
<config>
<Option type="Map">
<Option name="IsMultiline" type="QString" value="0"/>
<Option name="UseHtml" type="QString" value="0"/>
</Option>
</config>
</editWidget>
</field>
</fieldConfiguration>
<aliases>
<alias name="" field="id" index="0"/>
<alias name="" field="osm_id" index="1"/>
<alias name="" field="type" index="2"/>
<alias name="" field="name" index="3"/>
<alias name="" field="tunnel" index="4"/>
<alias name="" field="bridge" index="5"/>
<alias name="" field="oneway" index="6"/>
<alias name="" field="ref" index="7"/>
<alias name="" field="z_order" index="8"/>
<alias name="" field="access" index="9"/>
<alias name="" field="service" index="10"/>
<alias name="" field="class" index="11"/>
</aliases>
<excludeAttributesWMS/>
<excludeAttributesWFS/>
<defaults>
<default expression="" applyOnUpdate="0" field="id"/>
<default expression="" applyOnUpdate="0" field="osm_id"/>
<default expression="" applyOnUpdate="0" field="type"/>
<default expression="" applyOnUpdate="0" field="name"/>
<default expression="" applyOnUpdate="0" field="tunnel"/>
<default expression="" applyOnUpdate="0" field="bridge"/>
<default expression="" applyOnUpdate="0" field="oneway"/>
<default expression="" applyOnUpdate="0" field="ref"/>
<default expression="" applyOnUpdate="0" field="z_order"/>
<default expression="" applyOnUpdate="0" field="access"/>
<default expression="" applyOnUpdate="0" field="service"/>
<default expression="" applyOnUpdate="0" field="class"/>
</defaults>
<constraints>
<constraint constraints="1" notnull_strength="1" unique_strength="0" exp_strength="0" field="id"/>
<constraint constraints="1" notnull_strength="1" unique_strength="0" exp_strength="0" field="osm_id"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="type"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="name"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="tunnel"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="bridge"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="oneway"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="ref"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="z_order"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="access"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="service"/>
<constraint constraints="0" notnull_strength="0" unique_strength="0" exp_strength="0" field="class"/>
</constraints>
<constraintExpressions>
<constraint desc="" exp="" field="id"/>
<constraint desc="" exp="" field="osm_id"/>
<constraint desc="" exp="" field="type"/>
<constraint desc="" exp="" field="name"/>
<constraint desc="" exp="" field="tunnel"/>
<constraint desc="" exp="" field="bridge"/>
<constraint desc="" exp="" field="oneway"/>
<constraint desc="" exp="" field="ref"/>
<constraint desc="" exp="" field="z_order"/>
<constraint desc="" exp="" field="access"/>
<constraint desc="" exp="" field="service"/>
<constraint desc="" exp="" field="class"/>
</constraintExpressions>
<expressionfields/>
<attributeactions>
<defaultAction key="Canvas" value="{00000000-0000-0000-0000-000000000000}"/>
</attributeactions>
<attributetableconfig actionWidgetStyle="dropDown" sortExpression="" sortOrder="0">
<columns/>
</attributetableconfig>
<conditionalstyles>
<rowstyles/>
<fieldstyles/>
</conditionalstyles>
<editform tolerant="1">.</editform>
<editforminit/>
<editforminitcodesource>0</editforminitcodesource>
<editforminitfilepath>.</editforminitfilepath>
<editforminitcode><![CDATA[# -*- 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 PyQt4.QtGui import QWidget
def my_form_open(dialog, layer, feature):
geom = feature.geometry()
control = dialog.findChild(QWidget, "MyLineEdit")
]]></editforminitcode>
<featformsuppress>0</featformsuppress>
<editorlayout>generatedlayout</editorlayout>
<editable/>
<labelOnTop/>
<widgets/>
<previewExpression>"name"</previewExpression>
<mapTip></mapTip>
</maplayer>
</projectlayers>
<layerorder>
<layer id="osm_buildings20160720014515980"/>
<layer id="osm_roads20180302190105366"/>
</layerorder>
<properties>
<SpatialRefSys>
<ProjectCrs type="QString">EPSG:4326</ProjectCrs>
<ProjectCRSProj4String type="QString">+proj=longlat +datum=WGS84 +no_defs</ProjectCRSProj4String>
<ProjectionsEnabled type="int">1</ProjectionsEnabled>
<ProjectCRSID type="int">3452</ProjectCRSID>
</SpatialRefSys>
<WCSLayers type="QStringList"/>
<Measure>
<Ellipsoid type="QString">WGS84</Ellipsoid>
</Measure>
<WFSUrl type="QString"></WFSUrl>
<WMSContactPosition type="QString"></WMSContactPosition>
<WMSServiceTitle type="QString"></WMSServiceTitle>
<WMSRestrictedLayers type="QStringList"/>
<WMSFees type="QString">conditions unknown</WMSFees>
<Gui>
<SelectionColorBluePart type="int">0</SelectionColorBluePart>
<CanvasColorBluePart type="int">219</CanvasColorBluePart>
<SelectionColorGreenPart type="int">255</SelectionColorGreenPart>
<CanvasColorGreenPart type="int">106</CanvasColorGreenPart>
<CanvasColorRedPart type="int">43</CanvasColorRedPart>
<SelectionColorAlphaPart type="int">255</SelectionColorAlphaPart>
<SelectionColorRedPart type="int">255</SelectionColorRedPart>
</Gui>
<DefaultStyles>
<Line type="QString"></Line>
<RandomColors type="bool">true</RandomColors>
<ColorRamp type="QString"></ColorRamp>
<AlphaInt type="int">255</AlphaInt>
<Fill type="QString"></Fill>
<Marker type="QString"></Marker>
</DefaultStyles>
<PositionPrecision>
<DegreeFormat type="QString">MU</DegreeFormat>
<DecimalPlaces type="int">2</DecimalPlaces>
<Automatic type="bool">true</Automatic>
</PositionPrecision>
<WCSUrl type="QString"></WCSUrl>
<Legend>
<filterByMap type="bool">false</filterByMap>
</Legend>
<WMSServiceCapabilities type="bool">true</WMSServiceCapabilities>
<WMSUseLayerIDs type="bool">true</WMSUseLayerIDs>
<Variables>
<variableNames type="QStringList"/>
<variableValues type="QStringList"/>
</Variables>
<WFSTLayers>
<Update type="QStringList"/>
<Delete type="QStringList"/>
<Insert type="QStringList"/>
</WFSTLayers>
<WMSImageQuality type="int">90</WMSImageQuality>
<Macros>
<pythonCode type="QString"></pythonCode>
</Macros>
<WMSServiceAbstract type="QString"></WMSServiceAbstract>
<Paths>
<Absolute type="bool">false</Absolute>
</Paths>
<WMSRestrictedComposers type="QStringList"/>
<WFSLayers type="QStringList"/>
<WMSKeywordList type="QStringList">
<value></value>
</WMSKeywordList>
<WMSCrsList type="QStringList">
<value>EPSG:4326</value>
<value>EPSG:3857</value>
</WMSCrsList>
<PAL>
<CandidatesPoint type="int">16</CandidatesPoint>
<ShowingPartialsLabels type="bool">true</ShowingPartialsLabels>
<TextFormat type="int">0</TextFormat>
<SearchMethod type="int">0</SearchMethod>
<ShowingCandidates type="bool">false</ShowingCandidates>
<CandidatesPolygon type="int">30</CandidatesPolygon>
<DrawRectOnly type="bool">false</DrawRectOnly>
<ShowingAllLabels type="bool">false</ShowingAllLabels>
<CandidatesLine type="int">50</CandidatesLine>
</PAL>
<WMSPrecision type="QString">1</WMSPrecision>
<WMSUrl type="QString"></WMSUrl>
<WMSContactOrganization type="QString"></WMSContactOrganization>
<WMSSegmentizeFeatureInfoGeometry type="bool">false</WMSSegmentizeFeatureInfoGeometry>
<WMSContactMail type="QString"></WMSContactMail>
<Digitizing>
<LayerSnappingList type="QStringList">
<value>osm_buildings20160720014515980</value>
</LayerSnappingList>
<LayerSnapToList type="QStringList">
<value>to_vertex_and_segment</value>
</LayerSnapToList>
<LayerSnappingEnabledList type="QStringList">
<value>disabled</value>
</LayerSnappingEnabledList>
<AvoidIntersectionsList type="QStringList"/>
<DefaultSnapType type="QString">off</DefaultSnapType>
<DefaultSnapToleranceUnit type="int">2</DefaultSnapToleranceUnit>
<LayerSnappingToleranceUnitList type="QStringList">
<value>1</value>
</LayerSnappingToleranceUnitList>
<SnappingMode type="QString">current_layer</SnappingMode>
<DefaultSnapTolerance type="double">0</DefaultSnapTolerance>
<LayerSnappingToleranceList type="QStringList">
<value>0.000000</value>
</LayerSnappingToleranceList>
</Digitizing>
<WMSContactPhone type="QString"></WMSContactPhone>
<Measurement>
<DistanceUnits type="QString">meters</DistanceUnits>
<AreaUnits type="QString">m2</AreaUnits>
</Measurement>
<WMSContactPerson type="QString"></WMSContactPerson>
<WMSAccessConstraints type="QString">None</WMSAccessConstraints>
<Identify>
<disabledLayers type="QStringList"/>
</Identify>
<WMSAddWktGeometry type="bool">false</WMSAddWktGeometry>
<WMSOnlineResource type="QString"></WMSOnlineResource>
</properties>
<visibility-presets/>
<transformContext/>
<projectMetadata>
<identifier></identifier>
<parentidentifier></parentidentifier>
<language></language>
<type></type>
<title></title>
<abstract></abstract>
<links/>
<author></author>
<creation></creation>
</projectMetadata>
<Annotations/>
<Layouts/>
</qgis>