rebase to full OMT

This commit is contained in:
Vojtěch Fošnár 2025-01-16 20:45:43 +01:00
parent 9e57cd55f1
commit d4ba4006e1
499 changed files with 34964 additions and 121 deletions

8
.env
View file

@ -1,15 +1,15 @@
# This file defines default environment variables for all images
# Layers definition and meta data
TILESET_FILE=vfosnarmaptiles.yaml
TILESET_FILE=openmaptiles.yaml
# Use 3-part patch version to ignore patch updates, e.g. 7.0.0
TOOLS_VERSION=7.1
# Make sure these values are in sync with the ones in .env-postgres file
PGDATABASE=vfosnarmaptiles
PGUSER=vfosnarmaptiles
PGPASSWORD=vfosnarmaptiles
PGDATABASE=openmaptiles
PGUSER=openmaptiles
PGPASSWORD=openmaptiles
PGHOST=postgres
PGPORT=5432

17
BENCHMARKING.md Normal file
View file

@ -0,0 +1,17 @@
## To determine whether any changes are a notable loss in performance:
1. Start with the old approach
2. Use a fresh database
3. Use a large extract, such as France, Germany, Britain, etc. Too small of PBFs may be entirely cached in RAM and not representative of planet performance
4. Time the extract, ensuring you have the desired zoom level as set in .env
5. Switch to the new approach and use a fresh database once again
6. Quickstart.log will have all the time logs.
7. If necessary, run an update as well to see if your approach can keep up with live updates on the chosen interval. Currently, weekly updates are the target.
## To determine whether your changes in SQL are lossless:
It is recommended to use the "sqldiff" tool to compare mbtiles.
`sqldiff --table tiles new.mbtiles old.mbtiles`
This will compare on just the tiles table, ensuring for each zoom, x, y that the tile data is the same between both mbtiles. If sqldiff returns nothing, it means the results are identical.

88
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,88 @@
# Introduction
Thank you for considering contributing to OpenMapTiles. It's people like you that make OpenMapTiles such a great project. Talk to us at the OSM Slack **#openmaptiles** channel ([join](https://slack.openstreetmap.us/)).
Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue, assessing changes, and helping you finalize your pull requests.
OpenMapTiles is an open source project and we love to receive contributions from our community — you! There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into OpenMapTiles itself.
# Ground Rules
* Create issues for any major changes and enhancements that you wish to make. Discuss things transparently and get community feedback.
* Keep feature versions as small as possible, preferably one new feature per version.
* Be welcoming to newcomers and encourage diverse new contributors from all backgrounds. See the [Python Community Code of Conduct](https://www.python.org/psf/codeofconduct/).
# Getting started
1. Create your own fork of the code
1. Do the changes in your fork
1. Create a pull request
# Code review process
We all make mistakes and bad coding decisions. So apart from the obvious fixes, all changes must be reviewed by another 2 members of the project. This also helps with the [bus factor](https://en.wikipedia.org/wiki/Bus_factor) -- there should always be other people in the team who know why a change was made.
For any non-trivial changes, all pull requests must be approved by at least three members of the OpenMapTiles team. Afterwards you can merge the PR if you have rights, or another person must do it for you.
Your pull request must:
* Address a single issue or add a single item of functionality.
* Contain a clean history of small, incremental, logically separate commits,
with no merge commits.
* Use clear commit messages.
* Be possible to merge automatically.
When you modify import data rules in `mapping.yaml` or `*.sql`, please update:
1. field description in `[layer].yaml`
2. comments starting with `#etldoc`
3. regenerate documentation graphs with `make generate-devdoc`
4. update layer description on https://openmaptiles.org/schema/ (https://github.com/openmaptiles/www.openmaptiles.org/tree/master/layers)
5. check if OMT styles are affected by the PR and if there is a need for style updates
When you are making PR that adds new spatial features to OpenMapTiles schema, please make also PR for at least one of our GL styles to show it on the map. Visual check is crucial.
# SQL unit testing
It is recommended that you create a [unit test](TESTING.md) when modifying the behavior of the SQL layer. This will ensure that your changes are working as expected when importing or updating OSM data into an OpenMapTiles database.
# Verifying that updates still work
When testing a PR, you should also verify that the update process completes without an error. Please modify, if necessary, and run the script below.
**Note:**
The verification requires the script to append temporary changes to the `.env` file. Please restore the original version from git using `git checkout .env` or remove these changes before submitting a PR.
```
(
set -e
cat >> .env << EOM
# temporary changes for verifying that updates still work
# Ensure DIFF_MODE is active
DIFF_MODE=true
# Ensure all zoom levels are tested
MAX_ZOOM=14
EOM
# Set the test area to the appropriate geofabrik extract
export area=north-america/us/indiana
# Build 1-month-old tiles
rm -fr data build cache
make destroy-db
make download-geofabrik area=$area
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "wget -nv -O data/$area.osm.pbf http://download.geofabrik.de/$area-$(date --date="$(date +%Y-%m-15) -1 month" +'%y%m01').osm.pbf"
./quickstart.sh $area
cat << EOM
# Update with the changes since a month+ ago
EOM
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "osmupdate --base-url=$(sed -n 's/ *\"replication_url\": //p' data/$area.repl.json) data/$area.osm.pbf data/changes.osc.gz"
make import-diff
make generate-tiles-pg
) < /dev/null
```

View file

@ -243,7 +243,7 @@ export HELP_MESSAGE
#
.PHONY: all
all: init-dirs build/openmaptiles.tm2source/data.yml build/mapping.yaml build-sql
all: init-dirs build/openmaptiles.tm2source/data.yml build/mapping.yaml build-sql build-style
.PHONY: help
help:
@ -596,7 +596,7 @@ psql-list-tables: init-dirs
.PHONY: vacuum-db
vacuum-db: init-dirs
@echo "Start - postgresql: VACUUM ANALYZE VERBOSE;"
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -P pager=off -c 'VACUUM ANALYZE VERBOSE;'
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -P pager=off -c 'VACUUM (ANALYZE, VERBOSE);'
.PHONY: analyze-db
analyze-db: init-dirs

477
QUICKSTART.md Normal file
View file

@ -0,0 +1,477 @@
## Quickstart - for small extracts
### Req:
* CPU: AMD64 ( = Intel 64 bit)
* The base docker debian images are x86_64 based, so the ARM, MIPS currently not supported!
* Operating system
* Linux is suggested
* The development and the testing platform is Linux.
* If you are using FreeBSD, Solaris, Windows, ...
* Please give a feedback, share your experience, write a tutorial
* bash
* git
* make
* bc
* md5sum
* docker >=1.12.3
* https://www.docker.com/products/overview
* docker-compose >=1.7.1
* https://docs.docker.com/compose/install/
* disk space ( >= ~15Gb )
* for small extracts >= ~15Gb
* for big extracts ( continents, planet) 250 Gb
* And depends on
* OpenStreetMap data size
* Zoom level
* Best on SSD for postserve but completely usable on HDD
* Takes 24hrs to import on a reasonable machine, and is immediately available with postserve
* memory ( >= 3Gb )
* for small extracts 3Gb-8Gb RAM
* for big extracts ( Europe, Planet) > 8-32 Gb
* internet connections
* for downloading docker images
* for downloading OpenStreetMap data from Geofabrik
Important: The ./quickstart.sh is for small extracts - not optimal for a Planet rendering !!
### First experiment - with `albania` ( small extracts! )
```bash
git clone https://github.com/openmaptiles/openmaptiles.git
cd openmaptiles
./quickstart.sh
```
If you have problems with the quickstart
* check the ./quickstart.log!
* doublecheck the system requirements!
* check the current issues: https://github.com/openmaptiles/openmaptiles/issues
* create new issues:
* create a new gist: https://gist.github.com/ from your ./quickstart.log
* doublecheck: don't reveal any sensitive information about your system
* create a new issue: https://github.com/openmaptiles/openmaptiles/issues
* describe the problems
* add any pertinent information about your environment
* link your (quickstart.log) gist!
### Check other extracts
IF the previous step is working,
THEN you can test other available quickstart extracts ( based on [Geofabrik extracts](http://download.geofabrik.de/index.html) ) !
* We are using https://github.com/julien-noblet/download-geofabrik tool
* The current extract list, and more information -> `make list-geofabrik` or `make list-bbbike`
This is generating `.mbtiles` for your area : [ MIN_ZOOM: "0" - MAX_ZOOM: "7" ]
```bash
./quickstart.sh africa # Africa
./quickstart.sh alabama # Alabama, US
./quickstart.sh alaska # Alaska, US
./quickstart.sh albania # Albania, Europe
./quickstart.sh alberta # Alberta, Canada
./quickstart.sh alps # Alps, Europe
./quickstart.sh alsace # Alsace, France
./quickstart.sh andorra # Andorra, Europe
./quickstart.sh antarctica # Antarctica
./quickstart.sh aquitaine # Aquitaine, France
./quickstart.sh argentina # Argentina, South-America
./quickstart.sh arizona # Arizona, US
./quickstart.sh arkansas # Arkansas, US
./quickstart.sh arnsberg-regbez # Regierungsbezirk Arnsberg, Nordrhein-Westfalen
./quickstart.sh asia # Asia
./quickstart.sh australia # Australia, Australia-Oceania
./quickstart.sh australia-oceania # Australia and Oceania
./quickstart.sh austria # Austria, Europe
./quickstart.sh auvergne # Auvergne, France
./quickstart.sh azerbaijan # Azerbaijan, Asia
./quickstart.sh azores # Azores, Europe
./quickstart.sh baden-wuerttemberg # Baden-Württemberg, Germany
./quickstart.sh bangladesh # Bangladesh, Asia
./quickstart.sh basse-normandie # Basse-Normandie, France
./quickstart.sh bayern # Bayern, Germany
./quickstart.sh belarus # Belarus, Europe
./quickstart.sh belgium # Belgium, Europe
./quickstart.sh belize # Belize, Central-America
./quickstart.sh berlin # Berlin, Germany
./quickstart.sh bolivia # Bolivia, South-America
./quickstart.sh bosnia-herzegovina # Bosnia-Herzegovina, Europe
./quickstart.sh botswana # Botswana, Africa
./quickstart.sh bourgogne # Bourgogne, France
./quickstart.sh brandenburg # Brandenburg, Germany
./quickstart.sh brazil # Brazil, South-America
./quickstart.sh bremen # Bremen, Germany
./quickstart.sh bretagne # Bretagne, France
./quickstart.sh british-columbia # British Columbia, Canada
./quickstart.sh british-isles # British Isles, Europe
./quickstart.sh buckinghamshire # Buckinghamshire, England
./quickstart.sh bulgaria # Bulgaria, Europe
./quickstart.sh burkina-faso # Burkina Faso, Africa
./quickstart.sh california # California, US
./quickstart.sh cambridgeshire # Cambridgeshire, England
./quickstart.sh cameroon # Cameroon
./quickstart.sh canada # Canada, North-America
./quickstart.sh canary-islands # Canary Islands, Africa
./quickstart.sh central-america # Central America
./quickstart.sh centre # Centre, France
./quickstart.sh champagne-ardenne # Champagne Ardenne, France
./quickstart.sh cheshire # Cheshire, England
./quickstart.sh chile # Chile, South-America
./quickstart.sh china # China, Asia
./quickstart.sh colombia # Colombia, South-America
./quickstart.sh colorado # Colorado, US
./quickstart.sh congo-democratic-republic # Congo (Democratic Republic), Africa
./quickstart.sh connecticut # Connecticut, US
./quickstart.sh cornwall # Cornwall, England
./quickstart.sh corse # Corse, France
./quickstart.sh croatia # Croatia, Europe
./quickstart.sh cuba # Cuba, Central-America
./quickstart.sh cumbria # Cumbria, England
./quickstart.sh cyprus # Cyprus, Europe
./quickstart.sh czech-republic # Czech Republic, Europe
./quickstart.sh dach # Germany, Austria, Switzerland, Europe
./quickstart.sh delaware # Delaware, US
./quickstart.sh denmark # Denmark, Europe
./quickstart.sh derbyshire # Derbyshire, England
./quickstart.sh detmold-regbez # Regierungsbezirk Detmold, Nordrhein-Westfalen
./quickstart.sh devon # Devon, England
./quickstart.sh district-of-columbia # District of Columbia, US
./quickstart.sh dorset # Dorset, England
./quickstart.sh duesseldorf-regbez # Regierungsbezirk Düsseldorf, Nordrhein-Westfalen
./quickstart.sh east-sussex # East Sussex, England
./quickstart.sh east-yorkshire-with-hull # East Yorkshire with Hull, England
./quickstart.sh ecuador # Ecuador, South-America
./quickstart.sh egypt # Egypt, Africa
./quickstart.sh england # England, Great-Britain
./quickstart.sh essex # Essex, England
./quickstart.sh estonia # Estonia, Europe
./quickstart.sh ethiopia # Ethiopia, Africa
./quickstart.sh europe # Europe
./quickstart.sh faroe-islands # Faroe Islands, Europe
./quickstart.sh fiji # Fiji, Australia-Oceania
./quickstart.sh finland # Finland, Europe
./quickstart.sh florida # Florida, US
./quickstart.sh france # France, Europe
./quickstart.sh franche-comte # Franche Comte, France
./quickstart.sh freiburg-regbez # Regierungsbezirk Freiburg, Baden-Wuerttemberg
./quickstart.sh gcc-states # GCC States, Asia
./quickstart.sh georgia-eu # Georgia (Eastern Europe), Europe
./quickstart.sh georgia-us # Georgia (US State), US
./quickstart.sh germany # Germany, Europe
./quickstart.sh gloucestershire # Gloucestershire, England
./quickstart.sh great-britain # Great Britain, Europe
./quickstart.sh greater-london # Greater London, England
./quickstart.sh greater-manchester # Greater Manchester, England
./quickstart.sh greece # Greece, Europe
./quickstart.sh greenland # Greenland, North-America
./quickstart.sh guadeloupe # Guadeloupe, France
./quickstart.sh guatemala # Guatemala, Central-America
./quickstart.sh guinea # Guinea, Africa
./quickstart.sh guinea-bissau # Guinea-Bissau, Africa
./quickstart.sh guyane # Guyane, France
./quickstart.sh haiti-and-domrep # Haiti and Dominican Republic, Central-America
./quickstart.sh hamburg # Hamburg, Germany
./quickstart.sh hampshire # Hampshire, England
./quickstart.sh haute-normandie # Haute-Normandie, France
./quickstart.sh hawaii # Hawaii, US
./quickstart.sh herefordshire # Herefordshire, England
./quickstart.sh hertfordshire # Hertfordshire, England
./quickstart.sh hessen # Hessen, Germany
./quickstart.sh hungary # Hungary, Europe
./quickstart.sh iceland # Iceland, Europe
./quickstart.sh idaho # Idaho, US
./quickstart.sh ile-de-france # Ile-de-France, France
./quickstart.sh illinois # Illinois, US
./quickstart.sh india # India, Asia
./quickstart.sh indiana # Indiana, US
./quickstart.sh indonesia # Indonesia, Asia
./quickstart.sh iowa # Iowa, US
./quickstart.sh irak # Irak, Asia
./quickstart.sh iran # Iran, Asia
./quickstart.sh ireland-and-northern-ireland # Ireland and Northern Ireland, Europe
./quickstart.sh isle-of-man # Isle of Man, Europe
./quickstart.sh isle-of-wight # Isle of Wight, England
./quickstart.sh israel-and-palestine # Israel and Palestine, Asia
./quickstart.sh italy # Italy, Europe
./quickstart.sh ivory-coast # Ivory Coast, Africa
./quickstart.sh japan # Japan, Asia
./quickstart.sh jordan # Jordan, Asia
./quickstart.sh kansas # Kansas, US
./quickstart.sh karlsruhe-regbez # Regierungsbezirk Karlsruhe, Baden-Wuerttemberg
./quickstart.sh kazakhstan # Kazakhstan, Asia
./quickstart.sh kent # Kent, England
./quickstart.sh kentucky # Kentucky, US
./quickstart.sh kenya # Kenya, Africa
./quickstart.sh koeln-regbez # Regierungsbezirk Köln, Nordrhein-Westfalen
./quickstart.sh kosovo # Kosovo, Europe
./quickstart.sh kyrgyzstan # Kyrgyzstan, Asia
./quickstart.sh lancashire # Lancashire, England
./quickstart.sh languedoc-roussillon # Languedoc-Roussillon, France
./quickstart.sh latvia # Latvia, Europe
./quickstart.sh lebanon # Lebanon, Asia
./quickstart.sh leicestershire # Leicestershire, England
./quickstart.sh lesotho # Lesotho, Africa
./quickstart.sh liberia # Liberia, Africa
./quickstart.sh libya # Libya, Africa
./quickstart.sh liechtenstein # Liechtenstein, Europe
./quickstart.sh limousin # Limousin, France
./quickstart.sh lithuania # Lithuania, Europe
./quickstart.sh lorraine # Lorraine, France
./quickstart.sh louisiana # Louisiana, US
./quickstart.sh luxembourg # Luxembourg, Europe
./quickstart.sh macedonia # Macedonia, Europe
./quickstart.sh madagascar # Madagascar, Africa
./quickstart.sh maine # Maine, US
./quickstart.sh malaysia-singapore-brunei # Malaysia, Singapore, and Brunei, Asia
./quickstart.sh malta # Malta, Europe
./quickstart.sh manitoba # Manitoba, Canada
./quickstart.sh martinique # Martinique, France
./quickstart.sh maryland # Maryland, US
./quickstart.sh massachusetts # Massachusetts, US
./quickstart.sh mayotte # Mayotte, France
./quickstart.sh mecklenburg-vorpommern # Mecklenburg-Vorpommern, Germany
./quickstart.sh mexico # Mexico, North-America
./quickstart.sh michigan # Michigan, US
./quickstart.sh midi-pyrenees # Midi-Pyrenees, France
./quickstart.sh minnesota # Minnesota, US
./quickstart.sh mississippi # Mississippi, US
./quickstart.sh missouri # Missouri, US
./quickstart.sh mittelfranken # Mittelfranken, Bayern
./quickstart.sh moldova # Moldova, Europe
./quickstart.sh monaco # Monaco, Europe
./quickstart.sh mongolia # Mongolia, Asia
./quickstart.sh montana # Montana, US
./quickstart.sh montenegro # Montenegro, Europe
./quickstart.sh morocco # Morocco, Africa
./quickstart.sh muenster-regbez # Regierungsbezirk Münster, Nordrhein-Westfalen
./quickstart.sh nebraska # Nebraska, US
./quickstart.sh nepal # Nepal, Asia
./quickstart.sh netherlands # Netherlands, Europe
./quickstart.sh nevada # Nevada, US
./quickstart.sh new-brunswick # New Brunswick, Canada
./quickstart.sh new-caledonia # New Caledonia, Australia-Oceania
./quickstart.sh new-hampshire # New Hampshire, US
./quickstart.sh new-jersey # New Jersey, US
./quickstart.sh new-mexico # New Mexico, US
./quickstart.sh new-york # New York, US
./quickstart.sh new-zealand # New Zealand, Australia-Oceania
./quickstart.sh newfoundland-and-labrador # Newfoundland and Labrador, Canada
./quickstart.sh niederbayern # Niederbayern, Bayern
./quickstart.sh niedersachsen # Niedersachsen, Germany
./quickstart.sh nigeria # Nigeria, Africa
./quickstart.sh nord-pas-de-calais # Nord-Pas-de-Calais, France
./quickstart.sh nordrhein-westfalen # Nordrhein-Westfalen, Germany
./quickstart.sh norfolk # Norfolk, England
./quickstart.sh north-america # North America
./quickstart.sh north-carolina # North Carolina, US
./quickstart.sh north-dakota # North Dakota, US
./quickstart.sh north-korea # North Korea, Asia
./quickstart.sh north-yorkshire # North Yorkshire, England
./quickstart.sh northwest-territories # Northwest Territories, Canada
./quickstart.sh norway # Norway, Europe
./quickstart.sh nottinghamshire # Nottinghamshire, England
./quickstart.sh nova-scotia # Nova Scotia, Canada
./quickstart.sh nunavut # Nunavut, Canada
./quickstart.sh oberbayern # Oberbayern, Bayern
./quickstart.sh oberfranken # Oberfranken, Bayern
./quickstart.sh oberpfalz # Oberpfalz, Bayern
./quickstart.sh ohio # Ohio, US
./quickstart.sh oklahoma # Oklahoma, US
./quickstart.sh ontario # Ontario, Canada
./quickstart.sh oregon # Oregon, US
./quickstart.sh oxfordshire # Oxfordshire, England
./quickstart.sh pakistan # Pakistan, Asia
./quickstart.sh paraguay # Paraguay, South-America
./quickstart.sh pays-de-la-loire # Pays de la Loire, France
./quickstart.sh pennsylvania # Pennsylvania, US
./quickstart.sh peru # Peru, South-America
./quickstart.sh philippines # Philippines, Asia
./quickstart.sh picardie # Picardie, France
./quickstart.sh poitou-charentes # Poitou-Charentes, France
./quickstart.sh poland # Poland, Europe
./quickstart.sh portugal # Portugal, Europe
./quickstart.sh prince-edward-island # Prince Edward Island, Canada
./quickstart.sh provence-alpes-cote-d-azur # Provence Alpes-Cote-d'Azur, France
./quickstart.sh quebec # Quebec, Canada
./quickstart.sh reunion # Reunion, France
./quickstart.sh rheinland-pfalz # Rheinland-Pfalz, Germany
./quickstart.sh rhode-island # Rhode Island, US
./quickstart.sh rhone-alpes # Rhone-Alpes, France
./quickstart.sh romania # Romania, Europe
./quickstart.sh russia-asian-part # Russia (Asian part), Asia
./quickstart.sh russia-european-part # Russia (European part), Europe
./quickstart.sh saarland # Saarland, Germany
./quickstart.sh sachsen # Sachsen, Germany
./quickstart.sh sachsen-anhalt # Sachsen-Anhalt, Germany
./quickstart.sh saskatchewan # Saskatchewan, Canada
./quickstart.sh schleswig-holstein # Schleswig-Holstein, Germany
./quickstart.sh schwaben # Schwaben, Bayern
./quickstart.sh scotland # Scotland, Great-Britain
./quickstart.sh serbia # Serbia, Europe
./quickstart.sh shropshire # Shropshire, England
./quickstart.sh sierra-leone # Sierra Leone, Africa
./quickstart.sh slovakia # Slovakia, Europe
./quickstart.sh slovenia # Slovenia, Europe
./quickstart.sh somalia # Somalia, Africa
./quickstart.sh somerset # Somerset, England
./quickstart.sh south-africa-and-lesotho # South Africa (includes Lesotho), Africa
./quickstart.sh south-america # South America
./quickstart.sh south-carolina # South Carolina, US
./quickstart.sh south-dakota # South Dakota, US
./quickstart.sh south-korea # South Korea, Asia
./quickstart.sh south-yorkshire # South Yorkshire, England
./quickstart.sh spain # Spain, Europe
./quickstart.sh sri-lanka # Sri Lanka, Asia
./quickstart.sh staffordshire # Staffordshire, England
./quickstart.sh stuttgart-regbez # Regierungsbezirk Stuttgart, Baden-Wuerttemberg
./quickstart.sh suffolk # Suffolk, England
./quickstart.sh surrey # Surrey, England
./quickstart.sh sweden # Sweden, Europe
./quickstart.sh switzerland # Switzerland, Europe
./quickstart.sh syria # Syria, Asia
./quickstart.sh taiwan # Taiwan, Asia
./quickstart.sh tajikistan # Tajikistan, Asia
./quickstart.sh tanzania # Tanzania, Africa
./quickstart.sh tennessee # Tennessee, US
./quickstart.sh texas # Texas, US
./quickstart.sh thailand # Thailand, Asia
./quickstart.sh thueringen # Thüringen, Germany
./quickstart.sh tuebingen-regbez # Regierungsbezirk Tübingen, Baden-Wuerttemberg
./quickstart.sh turkey # Turkey, Europe
./quickstart.sh turkmenistan # Turkmenistan, Asia
./quickstart.sh ukraine # Ukraine, Europe
./quickstart.sh unterfranken # Unterfranken, Bayern
./quickstart.sh uruguay # Uruguay, South-America
./quickstart.sh us-midwest # US Midwest, North-America
./quickstart.sh us-northeast # US Northeast, North-America
./quickstart.sh us-pacific # US Pacific, North-America
./quickstart.sh us-south # US South, North-America
./quickstart.sh us-west # US West, North-America
./quickstart.sh utah # Utah, US
./quickstart.sh uzbekistan # Uzbekistan, Asia
./quickstart.sh vermont # Vermont, US
./quickstart.sh vietnam # Vietnam, Asia
./quickstart.sh virginia # Virginia, US
./quickstart.sh wales # Wales, Great-Britain
./quickstart.sh washington # Washington, US
./quickstart.sh west-midlands # West Midlands, England
./quickstart.sh west-sussex # West Sussex, England
./quickstart.sh west-virginia # West Virginia, US
./quickstart.sh west-yorkshire # West Yorkshire, England
./quickstart.sh wiltshire # Wiltshire, England
./quickstart.sh wisconsin # Wisconsin, US
./quickstart.sh wyoming # Wyoming, US
./quickstart.sh yukon # Yukon, Canada
```
### Using your own OSM data
Mbtiles can be generated from an arbitrary osm.pbf (e.g. for a region that is not covered by an existing extract) by making the `data/` directory and placing an *.osm.pbf (e.g. `mydata.osm.pbf`) inside.
```
mkdir -p data
mv mydata.osm.pbf data/
make generate-bbox-file area=mydata
./quickstart.sh mydata
```
### Check postserve
* ` docker-compose up -d postserve`
and the generated maps are going to be available in browser on [localhost:8090/tiles/0/0/0.pbf](http://localhost:8090/tiles/0/0/0.pbf).
### Check tileserver
start:
* ` make start-tileserver`
and the generated maps are going to be available in webbrowser on [localhost:8080](http://localhost:8080/).
This is only a quick preview, because your mbtiles only generated to zoom level 7 !
### Set which zooms to generate
modify the settings in the `.env` file, the defaults:
* `MIN_ZOOM=0`
* `MAX_ZOOM=7`
Hints:
* Small increments! Never starts with the `MAX_ZOOM = 14`
* The suggested `MAX_ZOOM = 14` - use only with small extracts
### Set the bounding box to generate
By default, tile generation is done for the full extent of the area.
If you want to generate a tiles for a smaller extent, modify the settings in the `.env` file, the default:
* `BBOX=-180.0,-85.0511,180.0,85.0511`
Delete the `./data/<area>.bbox` file, and re-start `./quickstart.sh <area>`
Hint:
* The [boundingbox.klokantech.com](https://boundingbox.klokantech.com/) site can be used to find a bounding box (CSV format) using a map.
### Check other commands
`make help`
the current output:
```
==============================================================================
OpenMapTiles https://github.com/openmaptiles/openmaptiles
Hints for testing areas
make list-geofabrik # list actual geofabrik OSM extracts for download -> <<your-area>>
./quickstart.sh <<your-area>> # example: ./quickstart.sh madagascar
Hints for designers:
make start-maputnik # start Maputnik Editor + dynamic tile server [ see http://localhost:8088 ]
make stop-maputnik # stop Maputnik Editor + dynamic tile server
make start-postserve # start dynamic tile server [ see http://localhost:8090 ]
make stop-postserve # stop dynamic tile server
make start-tileserver # start maptiler/tileserver-gl [ see http://localhost:8080 ]
make stop-tileserver # stop maptiler/tileserver-gl
Hints for developers:
make # build source code
make bash # start openmaptiles-tools /bin/bash terminal
make generate-bbox-file # compute bounding box of a data file and store it in a file
make generate-devdoc # generate devdoc including graphs for all layers [./layers/...]
make generate-qa # statistics for a given layer's field
make generate-tiles-pg # generate vector tiles based on .env settings using PostGIS ST_MVT()
make generate-tiles # generate vector tiles based on .env settings using Mapnik (obsolete)
make generate-changed-tiles # Generate tiles changed by import-diff
make test-sql # run unit tests on the OpenMapTiles SQL schema
cat .env # list PG database and MIN_ZOOM and MAX_ZOOM information
cat quickstart.log # transcript of the last ./quickstart.sh run
make help # help about available commands
Hints for downloading & importing data:
make list-geofabrik # list actual geofabrik OSM extracts for download
make list-bbbike # list actual BBBike OSM extracts for download
make download area=albania # download OSM data from any source and create config file
make download-geofabrik area=albania # download OSM data from geofabrik.de and create config file
make download-osmfr area=asia/qatar # download OSM data from openstreetmap.fr and create config file
make download-bbbike area=Amsterdam # download OSM data from bbbike.org and create config file
make import-data # Import data from OpenStreetMapData, Natural Earth and OSM Lake Labels.
make import-osm # Import OSM data with the mapping rules from build/mapping.yaml
make import-diff # Import OSM updates from data/changes.osc.gz
make import-wikidata # Import labels from Wikidata
make import-sql # Import layers (run this after modifying layer SQL)
Hints for database management:
make psql # start PostgreSQL console
make psql-list-tables # list all PostgreSQL tables
make list-views # list PostgreSQL public schema views
make list-tables # list PostgreSQL public schema tables
make vacuum-db # PostgreSQL: VACUUM ANALYZE
make analyze-db # PostgreSQL: ANALYZE
make destroy-db # remove docker containers and PostgreSQL data volume
make start-db # start PostgreSQL, creating it if it doesn't exist
make start-db-preloaded # start PostgreSQL, creating data-prepopulated one if it doesn't exist
make stop-db # stop PostgreSQL database without destroying the data
Hints for Docker management:
make clean-unnecessary-docker # clean unnecessary docker image(s) and container(s)
make refresh-docker-images # refresh openmaptiles docker images from Docker HUB
make remove-docker-images # remove openmaptiles docker images
make list-docker-images # show a list of available docker images
==============================================================================
```

199
README.md
View file

@ -1,3 +1,198 @@
# vfosnar map tiles
## OpenMapTiles [![Build Status](https://github.com/openmaptiles/openmaptiles/workflows/OpenMapTiles%20Integrity%20CI/badge.svg?branch=master)](https://github.com/openmaptiles/openmaptiles/actions)
Fork of OpenMapTiles to generate data missing from standard OMT
OpenMapTiles is an extensible and open tile schema based on the OpenStreetMap. This project is used to generate vector tiles for online zoomable maps. OpenMapTiles is about creating a beautiful basemaps with general layers containing topographic information. More information [openmaptiles.org](https://openmaptiles.org/) and [maptiler.com/data/](https://www.maptiler.com/data/).
We encourage you to collaborate, reuse and adapt existing layers, or add your own layers. You may use our approach for your own vector tile project. Feel free to fork the repo and experiment. The repository is built on top of the [openmaptiles/openmaptiles-tools](https://github.com/openmaptiles/openmaptiles-tools) to simplify vector tile creation.
Please keep in mind that OpenMapTiles schema should display general topographic content. If creating a new layer or expanding an existing layer with a specific theme, please create a fork and invite other community members to cooperate on your topic. OpenMapTiles schema is used in many projects all over the world and the size of the final vector tiles needs to be considered in any update.
- :link: Schema https://openmaptiles.org/schema
- :link: Docs https://openmaptiles.org/docs
- :link: Data for download: https://www.maptiler.com/data/
- :link: Hosting https://www.maptiler.com/cloud/
- :link: Create own layer https://github.com/openmaptiles/openmaptiles-skiing
- :link: Practical usage of OpenMapTiles https://github.com/maptiler/foss4g-workshop
- :link: Discuss at the #openmaptiles channel at [OSM Slack](https://slack.openstreetmap.us/)
## Styles
You can start from several GL styles supporting the OpenMapTiles vector schema.
:link: [Learn how to create Mapbox GL styles with Maputnik and OpenMapTiles](http://openmaptiles.org/docs/style/maputnik/).
- [OSM OpenMapTiles](./style/README.md)
- [OSM Bright](https://github.com/openmaptiles/osm-bright-gl-style)
- [MapTiler Basic](https://github.com/openmaptiles/maptiler-basic-gl-style)
- [MapTiler 3D](https://github.com/openmaptiles/maptiler-3d-gl-style)
- [Fiord Color](https://github.com/openmaptiles/fiord-color-gl-style)
- [MapTiler Toner](https://github.com/openmaptiles/maptiler-toner-gl-style)
- [OSM Liberty](https://github.com/maputnik/osm-liberty)
- [Positron](https://github.com/openmaptiles/positron-gl-style)
- [Dark Matter](https://github.com/openmaptiles/dark-matter-gl-style)
We also ported over our favorite old raster styles (TM2).
:link: [Learn how to create TM2 styles with Mapbox Studio Classic and OpenMapTiles](http://openmaptiles.org/docs/style/mapbox-studio-classic/).
- [Light](https://github.com/openmaptiles/mapbox-studio-light.tm2/)
- [Dark](https://github.com/openmaptiles/mapbox-studio-dark.tm2/)
- [OSM Bright](https://github.com/openmaptiles/mapbox-studio-osm-bright.tm2/)
- [Pencil](https://github.com/openmaptiles/mapbox-studio-pencil.tm2/)
- [Woodcut](https://github.com/openmaptiles/mapbox-studio-woodcut.tm2/)
- [Pirates](https://github.com/openmaptiles/mapbox-studio-pirates.tm2/)
- [Wheatpaste](https://github.com/openmaptiles/mapbox-studio-wheatpaste.tm2/)
## Schema
OpenMapTiles consists out of a collection of documented and self contained layers you can modify and adapt.
Together the layers make up the OpenMapTiles tileset.
:link: [Study the vector tile schema](http://openmaptiles.org/schema)
- [aeroway](https://openmaptiles.org/schema/#aeroway)
- [boundary](https://openmaptiles.org/schema/#boundary)
- [building](https://openmaptiles.org/schema/#building)
- [housenumber](https://openmaptiles.org/schema/#housenumber)
- [landcover](https://openmaptiles.org/schema/#landcover)
- [landuse](https://openmaptiles.org/schema/#landuse)
- [mountain_peak](https://openmaptiles.org/schema/#mountain_peak)
- [park](https://openmaptiles.org/schema/#park)
- [place](https://openmaptiles.org/schema/#place)
- [poi](https://openmaptiles.org/schema/#poi)
- [transportation](https://openmaptiles.org/schema/#transportation)
- [transportation_name](https://openmaptiles.org/schema/#transportation_name)
- [water](https://openmaptiles.org/schema/#water)
- [water_name](https://openmaptiles.org/schema/#water_name)
- [waterway](https://openmaptiles.org/schema/#waterway)
## Develop
To work on OpenMapTiles you need Docker.
- Install [Docker](https://docs.docker.com/engine/installation/). Minimum version is 1.12.3+.
- Install [Docker Compose](https://docs.docker.com/compose/install/). Minimum version is 1.7.1+.
### Microsoft Windows Subsystem for Linux (WSL)
Please use Linux `/home/user/` directory, not Windows e.g. `/mnt/c` directory.
### Build
Build the tileset.
```bash
git clone https://github.com/openmaptiles/openmaptiles.git
cd openmaptiles
# Build the imposm mapping, the tm2source project and collect all SQL scripts
make
```
You can execute the following manual steps (for better understanding)
or use the provided `quickstart.sh` script to automatically download and import given area. If area is not given, Albania will be imported. List of available areas `make list-geofabrik`.
```
./quickstart.sh <area>
```
### Prepare the Database
Now start up the database container.
```bash
make start-db
```
Import external data from [OpenStreetMapData](http://osmdata.openstreetmap.de/), [Natural Earth](http://www.naturalearthdata.com/) and [OpenStreetMap Lake Labels](https://github.com/openmaptiles/osm-lakelines). Natural Earth country boundaries are used in the few lowest zoom levels.
```bash
make import-data
```
Download OpenStreetMap data extracts from any source like [Geofabrik](http://download.geofabrik.de/), and store the PBF file in the `./data` directory. To use a specific download source, use `download-geofabrik`, `download-bbbike`, or `download-osmfr`, or use `download` to make it auto-pick the area. You can use `area=planet` for the entire OSM dataset (very large). Note that if you have more than one `data/*.osm.pbf` file, every `make` command will always require `area=...` parameter (or you can just `export area=...` first).
```bash
make download area=albania
```
[Import OpenStreetMap data](https://github.com/openmaptiles/openmaptiles-tools/blob/master/bin/import-osm) with the mapping rules from
`build/mapping.yaml` (which has been created by `make`). Run after any change in layers definition (any change in `mapping.yaml`).
```bash
make import-osm
```
Import labels from Wikidata. If an OSM feature has [Key:wikidata](https://wiki.openstreetmap.org/wiki/Key:wikidata), OpenMapTiles check corresponding item in Wikidata and use its [labels](https://www.wikidata.org/wiki/Help:Label) for languages listed in [openmaptiles.yaml](openmaptiles.yaml). So the generated vector tiles includes multi-languages in name field.
This step uses [Wikidata Query Service](https://query.wikidata.org) to download just the Wikidata IDs that already exist in the database.
```bash
make import-wikidata
```
### Work on Layers
Each time you modify a layer's `mapping.yaml` file or add new OSM tags, run `make` and `make import-osm` to recreate tables (potentially with additional data) in PostgreSQL. With the new data, there can be new Wikidata records also.
```
make clean
make
make import-osm
make import-wikidata
```
Each time you modify layer SQL code run `make` and `make import-sql`.
```
make clean
make
make import-sql
```
Each time you make a modification that adds a new feature to vector tiles e.g. adding new OSM tags, modify the layer
style snippet by adding new style layer so the changes are propagated visually into the style.
All new style layers must have the `order` value which determines the order or rendering in the map style.
After the layer style snippet is modified run:
```bash
make build-style
```
Now you are ready to **generate the vector tiles**. By default, `./.env` specifies the entire planet BBOX for zooms 0-7, but running `generate-bbox-file` will analyze the data file and set the `BBOX` param to limit tile generation.
```
make generate-bbox-file # compute data bbox -- not needed for the whole planet or for downloaded area by `make download`
make generate-tiles-pg # generate tiles
```
### Workflow to generate tiles
If you go from top to bottom you can be sure that it will generate a .mbtiles file out of a .osm.pbf file
```
make clean # clean / remove existing build files
make # generate build files
make start-db # start up the database container.
make import-data # Import external data from OpenStreetMapData, Natural Earth and OpenStreetMap Lake Labels.
make download area=albania # download albania .osm.pbf file -- can be skipped if a .osm.pbf file already existing
make import-osm # import data into postgres
make import-wikidata # import Wikidata
make import-sql # create / import sql functions
make generate-bbox-file # compute data bbox -- not needed for the whole planet or for downloaded area by `make download`
make generate-tiles-pg # generate tiles
```
Instead of calling `make download area=albania` you can add a .osm.pbf file in the `data` folder `openmaptiles/data/your_area_file.osm.pbf`
To change the name of the output filename, you can modify the variable `MBTILES_FILE` in the `.env` file or set up the environment variable `MBTILES_FILE` before running `./quickstart.sh` or `make generate-tiles-pg` (e.g., `MBTILES_FILENAME=monaco.mbtiles ./quickstart.sh monaco`).
## License
All code in this repository is under the [BSD license](./LICENSE.md). Design and the cartography decisions encoded in the schema and SQL are licensed under [CC-BY](./LICENSE.md).
Products or services using maps derived from OpenMapTiles schema need to **visibly credit "OpenMapTiles.org"** or **reference "OpenMapTiles"** with a link to https://openmaptiles.org/. Exceptions to attribution requirement can be granted on request.
For a browsable electronic map based on OpenMapTiles and OpenStreetMap data, the
credit should appear in the corner of the map. For example:
[© OpenMapTiles](https://openmaptiles.org/) [© OpenStreetMap contributors](https://www.openstreetmap.org/copyright)
For printed and static maps a similar attribution should be made in a textual
description near the image, in the same fashion as if you cite a photograph.

18
TESTING.md Normal file
View file

@ -0,0 +1,18 @@
# OpenMapTiles SQL Testing
The OpenMapTiles SQL tests ensure that OSM data is properly imported and updated in the OpenMapTiles data schema. The tests work by injecting test OSM data into the database and checking to ensure that the data is properly reflected in the SQL output.
Usage:
`make clean && make test-sql`
## How it works
The SQL tests consist of the following parts:
1. **Test import data**, located in `tests/import`. This test data is in the [OSM XML](https://wiki.openstreetmap.org/wiki/OSM_XML) format and contains the data that should be initially injected into the database. The files are numbered in order to ensure that each test data file OSM id numbers that are unique from the other files. For example, the file starting with `100` will use node ids from 100000-199999, way ids from 1000-1999, and relation ids from 100-199.
2. **Test update data**, located in `tests/update`. This test data is in the [osmChange XML](https://wiki.openstreetmap.org/wiki/OsmChange) format, and contains the data that will be used to update the test import data (in order to verify that the update process is working correctly. These files are also numbered using the same scheme as the test import data.
3. **Import SQL test script**, located at `tests/test-post-import.sql`. This script is executed after the test import data has been injected, and runs SQL-based checks to ensure that the import data was properly imported. If there are failures in the tests, an entry will be added to the table `omt_test_failures`, with one record per error that occurs during the import process. A test failure will also fail the build. To inspect the test failure messages, run `make psql` and issue the comment `SELECT * FROM omt_test_failures`.
4. **Update SQL test script**, located at `tests/test-post-update.sql`. This script performs the same function as the import test script, except that it occurs after the test update data has been applied to the database. Note that script will only run if the import script passes all tests.

116
UPDATE.md Normal file
View file

@ -0,0 +1,116 @@
# Keeping the Vector Tiles Updated
Once you have imported OpenMapTiles you can also keep it up to date by importing the latest OSM changes and
regenerating the tables.
## Import
You can either keep the database up to date based on the daily (or minutely) OSM change feed
or import specific change files.
### Choosing the Download Source
While GeoFabrik currently provides extracts of basically all countries, they provide only daily updates.
If you need minutely updates you might want to try openstreetmap.fr, for example like this: `make download-osmfr area=africa/eritrea`, which configures minutely updates.
### Preparations
If you plan to keep data updated automatically, before importing any data, make sure to set
```
DIFF_MODE=true
```
in the `.env`
Now download fresh data:
```
make download area=your-area-of-choice
```
### Keep Database Updated
You can use imposm3 to keep the database updated (thanks to the [work by @stirringhalo](https://github.com/openmaptiles/openmaptiles/pull/131)).
This will repeatedly download the OSM change feed and import it into the database.
In order to be able to update the database, the initial download and import of the OSM data must be done when `DIFF_MODE=true` is set in the `.env` file.
In this mode the initial download also sets the update source and the update intervals.
To start the update process please use
```
make start-update-osm
```
To stop the update process please use
```
make stop-update-osm
```
After each update activation, **imposm3** will store lists of updated tiles in text format in subfolders of the `diffdir`,
named for the date(s) on which the import took place (`YYYYMMDD`).
See [Generate Changed Tiles](#generate-changed-tiles) below on how this file can be used.
#### Note
When the update process is actively updating the DB it is impossible to successfully generate tiles,
as there will be conflicts and deadlocks related to the DB access.
Unfortunately, there is no known way to execute an external command in-between rounds of the `update-osm` process.
#### Troubleshooting
The log file for osm update can be viewed using
```
docker-compose logs --tail 100 --follow update-osm
```
Use `Ctrl-C` to stop following the log.
The output will be similar to this:
```
[info] Importing #4889572 including changes till ....... +0000 UTC (2h10m10s behind)
```
It might take some time to catch up with the latest changes, but the "time behind" should decrease until it is a few minutes.
If it doesn't, you need to download a new extract or check that there are enough system resources to keep-up with the changes.
Finally you will get an output like this - this indicates, that some 6 objects were changed:
```
[progress] 3s C: 0/s (0) N: 0/s (0) W: 0/s (6) R: 0/s (0)
```
The process will keep running foreverprint something like this - which just means that no changes were in the latest changeset:
```
[progress] 0s C: 0/s (0) N: 0/s (0) W: 0/s (0) R: 0/s (0)
```
### Import Change File
You may perform a one-time import of OSM changes from the `changes.osc.gz` file in your import folder using
```
make import-diff
```
Similar to[Keep Database Updated](#keep_database_updated) above, **imposm3** will store the list of updated tiles in text file in subfolders of the `diffdir`,
named for the date on which the import took place (`YYYYMMDD`).
See [Generate Changed Tiles](#generate-changed-tiles) below.
#### Note
There is no `make` command for downloading OSM changes into `changes.osc.gz`.
You may perform this task using [`osmupdate`](https://wiki.openstreetmap.org/wiki/Osmupdate),
[pyosmium-get-changes](https://docs.osmcode.org/pyosmium/latest/tools_get_changes.html),
or downloading the changefile directly from the replication server.
## Generate Changed Tiles
To generate all changed tiles, based on the lists of all updated tiles, and update the existing MBtiles file, please use
```
make generate-changed-tiles
```

View file

@ -1,5 +1,5 @@
# This version must match the MAKE_DC_VERSION value below
version: "3"
# version: "3"
volumes:
pgdata:
@ -9,7 +9,6 @@ networks:
driver: bridge
services:
postgres:
image: "${POSTGIS_IMAGE:-openmaptiles/postgis}:${TOOLS_VERSION}"
# Use "command: postgres -c jit=off" for PostgreSQL 11+ because of slow large MVT query processing

View file

@ -0,0 +1,7 @@
## Aerodrome Labels
### Mapping Diagram
![Mapping diagram for aerodrome labels](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for aerodrome labels](etl_diagram.png?raw=true)

View file

@ -0,0 +1,62 @@
-- etldoc: layer_aerodrome_label[shape=record fillcolor=lightpink, style="rounded,filled", label="layer_aerodrome_label | <z8> z8 | <z9> z9 | <z10_> z10+" ] ;
CREATE OR REPLACE FUNCTION layer_aerodrome_label(bbox geometry,
zoom_level integer)
RETURNS TABLE
(
id bigint,
geometry geometry,
name text,
name_en text,
name_de text,
tags hstore,
class text,
iata text,
icao text,
ele int,
ele_ft int
)
AS
$$
SELECT
-- etldoc: osm_aerodrome_label_point -> layer_aerodrome_label:z8
-- etldoc: osm_aerodrome_label_point -> layer_aerodrome_label:z9
ABS(osm_id) AS id, -- mvt feature IDs can't be negative
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
aerodrome_type AS class,
NULLIF(iata, '') AS iata,
NULLIF(icao, '') AS icao,
substring(ele FROM E'^(-?\\d+)(\\D|$)')::int AS ele,
round(substring(ele FROM E'^(-?\\d+)(\\D|$)')::int * 3.2808399)::int AS ele_ft
FROM osm_aerodrome_label_point
WHERE geometry && bbox
AND aerodrome_type = 'international'
AND iata <> ''
AND zoom_level BETWEEN 8 AND 9
UNION ALL
SELECT
-- etldoc: osm_aerodrome_label_point -> layer_aerodrome_label:z10_
ABS(osm_id) AS id, -- mvt feature IDs can't be negative
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
aerodrome_type AS class,
NULLIF(iata, '') AS iata,
NULLIF(icao, '') AS icao,
substring(ele FROM E'^(-?\\d+)(\\D|$)')::int AS ele,
round(substring(ele FROM E'^(-?\\d+)(\\D|$)')::int * 3.2808399)::int AS ele_ft
FROM osm_aerodrome_label_point
WHERE geometry && bbox
AND zoom_level >= 10;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,50 @@
layer:
id: aerodrome_label
description: |
[Aerodrome labels](http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome)
buffer_size: 64
srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
fields:
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the aerodrome. Language-specific values are in `name:xx`.
name_en: English name `name:en` if available, otherwise `name`. This is deprecated and will be removed in a future release in favor of `name:en`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`. This is deprecated and will be removed in a future release in favor of `name:de`.
class:
description: |
Distinguish between more and less important aerodromes.
Class is derived from the value of
[`aerodrome`](http://wiki.openstreetmap.org/wiki/Proposed_features/Aerodrome)
and `aerodrome:type` tags.
values:
international:
aerodrome: 'international'
aerodrome_type: 'international'
public:
aerodrome: 'public'
aerodrome_type: ['%public%', 'civil']
regional:
aerodrome: 'regional'
aerodrome_type: 'regional'
military:
aerodrome: 'military'
aerodrome_type: '%military%'
military: 'airfield'
private:
aerodrome: 'private'
aerodrome_type: 'private'
other:
iata: 3-character code issued by the IATA.
icao: 4-letter code issued by the ICAO.
ele: Elevation (`ele`) in meters.
ele_ft: Elevation (`ele`) in feets.
datasource:
geometry_field: geometry
key_field: id
key_field_as_attribute: no
srid: 900913
query: (SELECT id, geometry, name, name_en, name_de, {name_languages}, class, iata, icao, ele, ele_ft FROM layer_aerodrome_label(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./update_aerodrome_label_point.sql
- ./aerodrome_label.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View file

@ -0,0 +1,46 @@
tables:
# etldoc: imposm3 -> osm_aerodrome_label_point
aerodrome_label_point:
type: geometry
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: name
key: name
type: string
- name: name_en
key: name:en
type: string
- name: name_de
key: name:de
type: string
- name: tags
type: hstore_tags
- name: aerodrome_type
key: aerodrome:type
type: string
- name: aerodrome
key: aerodrome
type: string
- name: military
key: military
type: string
- name: iata
key: iata
type: string
- name: icao
key: icao
type: string
- name: ele
key: ele
type: string
type_mappings:
points:
aeroway:
- aerodrome
polygons:
aeroway:
- aerodrome

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,69 @@
{
"layers": [
{
"id": "airport-label-major",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "aerodrome_label",
"minzoom": 8,
"maxzoom": 17,
"layout": {
"icon-size": 1,
"text-font": [
"Noto Sans Italic"
],
"text-size": {
"stops": [
[
8,
10
],
[
14,
12
]
]
},
"icon-image": "aerodrome.12",
"text-field": {
"stops": [
[
8,
" "
],
[
11,
"{name:latin}\n{name:nonlatin}"
]
]
},
"visibility": "visible",
"text-anchor": "top",
"text-offset": [
0,
0.6
],
"text-padding": 2,
"text-optional": true,
"symbol-z-order": "auto",
"text-max-width": 9,
"icon-allow-overlap": false,
"text-allow-overlap": false
},
"paint": {
"text-color": "#5e3b9e",
"text-halo-blur": 0.5,
"text-halo-color": "rgba(255, 255, 255, 0.8)",
"text-halo-width": 1
},
"filter": [
"all",
[
"has",
"iata"
]
],
"order": 190
}
]
}

View file

@ -0,0 +1,109 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_aerodrome_label_point;
DROP TRIGGER IF EXISTS trigger_store ON osm_aerodrome_label_point;
DROP TRIGGER IF EXISTS trigger_refresh ON aerodrome_label.updates;
-- Partial index for zoom 8/9 queries
CREATE INDEX IF NOT EXISTS osm_aerodrome_label_point_type_partial_idx
ON osm_aerodrome_label_point USING gist (geometry)
WHERE aerodrome_type = 'international'
AND iata <> '';
CREATE SCHEMA IF NOT EXISTS aerodrome_label;
CREATE TABLE IF NOT EXISTS aerodrome_label.osm_ids
(
osm_id bigint PRIMARY KEY
);
-- etldoc: osm_aerodrome_label_point -> osm_aerodrome_label_point
CREATE OR REPLACE FUNCTION update_aerodrome_label_point(full_update boolean) RETURNS void AS
$$
UPDATE osm_aerodrome_label_point
SET geometry = ST_Centroid(geometry)
WHERE (full_update OR osm_id IN (SELECT osm_id FROM aerodrome_label.osm_ids))
AND ST_GeometryType(geometry) <> 'ST_Point';
UPDATE osm_aerodrome_label_point
SET tags = update_tags(tags, geometry)
WHERE (full_update OR osm_id IN (SELECT osm_id FROM aerodrome_label.osm_ids))
AND COALESCE(tags->'name:latin', tags->'name:nonlatin', tags->'name_int') IS NULL
AND tags != update_tags(tags, geometry);
UPDATE osm_aerodrome_label_point
SET aerodrome_type=
CASE
%%FIELD_MAPPING: class %%
ELSE 'other' END
WHERE (full_update OR osm_id IN (SELECT osm_id FROM aerodrome_label.osm_ids))
AND aerodrome_type !=
CASE
%%FIELD_MAPPING: class %%
ELSE 'other' END;
$$ LANGUAGE SQL;
SELECT update_aerodrome_label_point(true);
-- Handle updates
CREATE OR REPLACE FUNCTION aerodrome_label.store() RETURNS trigger AS
$$
BEGIN
INSERT INTO aerodrome_label.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE IF NOT EXISTS aerodrome_label.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION aerodrome_label.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO aerodrome_label.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION aerodrome_label.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh aerodrome_label';
-- Analyze tracking and source tables before performing update
ANALYZE aerodrome_label.osm_ids;
ANALYZE osm_aerodrome_label_point;
PERFORM update_aerodrome_label_point(false);
-- noinspection SqlWithoutWhere
DELETE FROM aerodrome_label.osm_ids;
-- noinspection SqlWithoutWhere
DELETE FROM aerodrome_label.updates;
RAISE LOG 'Refresh aerodrome_label done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_store
AFTER INSERT OR UPDATE
ON osm_aerodrome_label_point
FOR EACH ROW
EXECUTE PROCEDURE aerodrome_label.store();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE
ON osm_aerodrome_label_point
FOR EACH STATEMENT
EXECUTE PROCEDURE aerodrome_label.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON aerodrome_label.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE aerodrome_label.refresh();

10
layers/aeroway/README.md Normal file
View file

@ -0,0 +1,10 @@
## aeroway
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#aeroway**
### Mapping Diagram
![Mapping diagram for aeroway](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for aeroway](etl_diagram.png?raw=true)

View file

@ -0,0 +1,70 @@
-- etldoc: layer_aeroway[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_aeroway |<z10> z10|<z11> z11|<z12> z12|<z13> z13|<z14_> z14+" ];
CREATE OR REPLACE FUNCTION layer_aeroway(bbox geometry, zoom_level int)
RETURNS TABLE
(
geometry geometry,
class text,
ref text
)
AS
$$
SELECT geometry, aeroway AS class, ref
FROM (
-- etldoc: osm_aeroway_linestring_gen_z10 -> layer_aeroway:z10
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen_z10
WHERE zoom_level = 10
UNION ALL
-- etldoc: osm_aeroway_linestring_gen_z11 -> layer_aeroway:z11
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen_z11
WHERE zoom_level = 11
UNION ALL
-- etldoc: osm_aeroway_linestring_gen_z12 -> layer_aeroway:z12
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen_z12
WHERE zoom_level = 12
UNION ALL
-- etldoc: osm_aeroway_linestring -> layer_aeroway:z13
-- etldoc: osm_aeroway_linestring -> layer_aeroway:z14_
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring
WHERE zoom_level >= 13
UNION ALL
-- etldoc: osm_aeroway_polygon_gen_z10 -> layer_aeroway:z10
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen_z10
WHERE zoom_level = 10
UNION ALL
-- etldoc: osm_aeroway_polygon_gen_z11 -> layer_aeroway:z11
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen_z11
WHERE zoom_level = 11
UNION ALL
-- etldoc: osm_aeroway_polygon_gen_z12 -> layer_aeroway:z12
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen_z12
WHERE zoom_level = 12
UNION ALL
-- etldoc: osm_aeroway_polygon_gen_z13 -> layer_aeroway:z13
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen_z13
WHERE zoom_level = 13
UNION ALL
-- etldoc: osm_aeroway_polygon -> layer_aeroway:z14_
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon
WHERE zoom_level >= 14
UNION ALL
-- etldoc: osm_aeroway_point -> layer_aeroway:z14_
SELECT geometry, aeroway, ref
FROM osm_aeroway_point
WHERE zoom_level >= 14
) AS zoom_levels
WHERE geometry && bbox;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,30 @@
layer:
id: "aeroway"
description: |
Aeroway polygons based of OpenStreetMap [aeroways](http://wiki.openstreetmap.org/wiki/Aeroways).
Airport buildings are contained in the **building** layer but all
other airport related polygons can be found in the **aeroway** layer.
buffer_size: 4
fields:
ref: The OSM [`ref`](http://wiki.openstreetmap.org/wiki/Key:ref) tag of the runway/taxiway.
class:
description: |
The original value of
[`aeroway`](http://wiki.openstreetmap.org/wiki/Key:aeroway) or
`area:aeroway` tag.
values:
- aerodrome
- heliport
- runway
- helipad
- taxiway
- apron
- gate
datasource:
geometry_field: geometry
query: (SELECT geometry, ref, class FROM layer_aeroway(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./aeroway.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Binary file not shown.

After

Width:  |  Height:  |  Size: 165 KiB

104
layers/aeroway/mapping.yaml Normal file
View file

@ -0,0 +1,104 @@
generalized_tables:
# etldoc: osm_aeroway_linestring_gen_z11 -> osm_aeroway_linestring_gen_z10
aeroway_linestring_gen_z10:
source: aeroway_linestring_gen_z11
tolerance: ZRES11
# etldoc: osm_aeroway_linestring_gen_z12 -> osm_aeroway_linestring_gen_z11
aeroway_linestring_gen_z11:
source: aeroway_linestring_gen_z12
tolerance: ZRES12
# etldoc: osm_aeroway_linestring -> osm_aeroway_linestring_gen_z12
aeroway_linestring_gen_z12:
source: aeroway_linestring
sql_filter: ST_IsValid(geometry)
tolerance: ZRES13
# etldoc: osm_aeroway_polygon_gen_z11 -> osm_aeroway_polygon_gen_z10
aeroway_polygon_gen_z10:
source: aeroway_polygon_gen_z11
sql_filter: area>power(ZRES9,2)
tolerance: ZRES10
# etldoc: osm_aeroway_polygon_gen_z12 -> osm_aeroway_polygon_gen_z11
aeroway_polygon_gen_z11:
source: aeroway_polygon_gen_z12
sql_filter: area>power(ZRES10,2)
tolerance: ZRES11
# etldoc: osm_aeroway_polygon_gen_z13 -> osm_aeroway_polygon_gen_z12
aeroway_polygon_gen_z12:
source: aeroway_polygon_gen_z13
sql_filter: area>power(ZRES11,2)
tolerance: ZRES12
# etldoc: osm_aeroway_polygon -> osm_aeroway_polygon_gen_z13
aeroway_polygon_gen_z13:
source: aeroway_polygon
sql_filter: area>power(ZRES12,2) AND ST_IsValid(geometry)
tolerance: ZRES13
ref_field: &ref
key: ref
name: ref
type: string
def_aeroway_polygon_mapping: &aeroway_polygon_mapping
- aerodrome
- heliport
- runway
- helipad
- taxiway
- apron
tables:
# etldoc: imposm3 -> osm_aeroway_polygon
aeroway_polygon:
type: polygon
columns:
- *ref
- name: osm_id
type: id
- name: geometry
type: geometry
- name: aeroway
type: mapping_value
- name: area
type: area
mapping:
aeroway: *aeroway_polygon_mapping
"area:aeroway": *aeroway_polygon_mapping
# etldoc: imposm3 -> osm_aeroway_linestring
aeroway_linestring:
type: linestring
columns:
- *ref
- name: osm_id
type: id
- name: geometry
type: geometry
- name: aeroway
key: aeroway
type: string
mapping:
aeroway:
- runway
- taxiway
# etldoc: imposm3 -> osm_aeroway_point
aeroway_point:
type: point
columns:
- *ref
- name: osm_id
type: id
- name: geometry
type: geometry
- name: aeroway
key: aeroway
type: string
mapping:
aeroway:
- gate

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

203
layers/aeroway/style.json Normal file
View file

@ -0,0 +1,203 @@
{
"layers": [
{
"id": "aeroway_fill",
"type": "fill",
"source": "openmaptiles",
"source-layer": "aeroway",
"minzoom": 11,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": {
"stops": [
[
6,
"rgba(223, 223, 228, 1)"
],
[
12,
"rgba(232, 231, 223, 1)"
]
]
},
"fill-opacity": 1
},
"metadata": {},
"filter": [
"==",
"$type",
"Polygon"
],
"order": 3
},
{
"id": "aeroway_runway",
"type": "line",
"source": "openmaptiles",
"source-layer": "aeroway",
"minzoom": 11,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": "rgba(178, 181, 209, 1)",
"line-width": {
"base": 1.2,
"stops": [
[
11,
3
],
[
20,
48
]
]
},
"line-opacity": 1
},
"metadata": {},
"filter": [
"all",
[
"==",
"$type",
"LineString"
],
[
"==",
"class",
"runway"
]
],
"order": 22
},
{
"id": "aeroway_taxiway",
"type": "line",
"source": "openmaptiles",
"source-layer": "aeroway",
"minzoom": 11,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": "rgba(178, 181, 209, 1)",
"line-width": {
"base": 1.2,
"stops": [
[
11,
1
],
[
20,
24
]
]
},
"line-opacity": 1
},
"metadata": {},
"filter": [
"all",
[
"==",
"$type",
"LineString"
],
[
"==",
"class",
"taxiway"
]
],
"order": 23
},
{
"id": "airport_label",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "aeroway",
"minzoom": 14,
"layout": {
"text-font": [
"Noto Sans Italic",
"Noto Sans Regular"
],
"text-size": {
"stops": [
[
15,
9
],
[
19,
15
]
]
},
"text-field": "{ref}",
"visibility": "visible",
"symbol-placement": "line"
},
"paint": {
"text-color": "#333333",
"text-halo-color": "rgba(255, 255, 255, 0.8)",
"text-halo-width": 1
},
"filter": [
"all",
[
"in",
"class",
"runway",
"taxiway"
]
],
"order": 191
},
{
"id": "airport_gate",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "aeroway",
"minzoom": 16.5,
"layout": {
"text-font": [
"Noto Sans Regular"
],
"text-size": {
"stops": [
[
17,
9
],
[
19,
15
]
]
},
"text-field": "{ref}",
"visibility": "visible"
},
"paint": {
"text-color": "rgba(135, 135, 135, 1)",
"text-halo-color": "rgba(255, 255, 255, 1)",
"text-halo-width": 1
},
"filter": [
"all",
[
"==",
"class",
"gate"
]
],
"order": 192
}
]
}

View file

@ -0,0 +1,6 @@
CREATE OR REPLACE FUNCTION layer_barrier(bbox geometry, zoom_level int)
RETURNS TABLE(geometry geometry, subclass text) AS $$
SELECT geometry, subclass
FROM osm_barrier_linestring
WHERE zoom_level >= 14 AND geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;

View file

@ -1,17 +1,17 @@
layer:
id: "kct"
description: kct
id: "barrier"
description: |
Barriers
buffer_size: 4
srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
fields:
name:
waycolor:
subclass:
datasource:
geometry_field: geometry
srid: 900913
query: (SELECT geometry, name, waycolor FROM layer_kct(!bbox!, z(!scale_denominator!))) AS t
query: (SELECT geometry, subclass FROM layer_barrier(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./layer.sql
- ./barrier.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

View file

@ -0,0 +1,13 @@
tables:
# etldoc: imposm3 -> osm_barrier_linestring
barrier_linestring:
type: linestring
columns:
- name: geometry
type: geometry
- name: subclass
type: mapping_value
mapping:
barrier:
- fence
- hedge

View file

@ -0,0 +1,3 @@
{
"layers": []
}

View file

@ -0,0 +1,7 @@
## boundary
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#boundary**
### ETL diagram
![ETL diagram for boundary](etl_diagram.png?raw=true)

View file

@ -0,0 +1,858 @@
-- etldoc: osm_border_linestring -> osm_border_linestring_gen_z13
-- etldoc: osm_border_linestring_adm -> osm_border_linestring_gen_z13
-- etldoc: osm_border_disp_linestring -> osm_border_linestring_gen_z13
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z13 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z13 AS
(
SELECT ST_Simplify(ST_Collect(geometry), ZRes(14)) AS geometry,
MAX(adm0_l) AS adm0_l,
MAX(adm0_r) AS adm0_r,
MIN(admin_level) AS admin_level,
BOOL_OR(disputed) AS disputed,
MAX(name) AS name,
MAX(claimed_by) AS claimed_by,
BOOL_OR(maritime) AS maritime
FROM (
-- All admin 3-10 boundaries
SELECT osm_id,
geometry,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
MIN(admin_level) AS admin_level,
BOOL_OR(disputed)
OR BOOL_OR(dispute)
OR BOOL_OR(border_status = 'disputed')
OR BOOL_OR(disputed_by <> '') AS disputed,
NULLIF(name, '') AS name,
NULLIF(claimed_by, '') AS claimed_by,
BOOL_OR(maritime) AS maritime
FROM osm_border_linestring
WHERE admin_level BETWEEN 3 AND 10
AND type = 1 -- ways only
GROUP BY osm_id, geometry, name, claimed_by
UNION ALL
-- All non-disputed admin 2 boundaries
SELECT osm_id,
geometry,
adm0_l,
adm0_r,
admin_level,
FALSE AS disputed,
NULL::text AS name,
NULL::text AS claimed_by,
maritime
FROM osm_border_linestring_adm
UNION ALL
-- All disputed admin 2 boundaries
SELECT osm_id,
geometry,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
2::int AS admin_level,
TRUE AS disputed,
NULLIF(name, '') AS name,
NULLIF(claimed_by, '') AS claimed_by,
maritime
FROM osm_border_disp_linestring
GROUP BY osm_id, geometry, name, claimed_by, maritime
) AS merged_boundary
GROUP by osm_id
)/* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z13_idx ON osm_border_linestring_gen_z13 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z13 -> osm_border_linestring_gen_z12
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z12 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z12 AS
(
SELECT ST_Simplify(geometry, ZRes(13)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z13
WHERE admin_level BETWEEN 2 AND 10
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z12_idx ON osm_border_linestring_gen_z12 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z12 -> osm_border_linestring_gen_z11
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z11 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z11 AS
(
SELECT ST_Simplify(geometry, ZRes(12)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z12
WHERE admin_level BETWEEN 2 AND 8
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z11_idx ON osm_border_linestring_gen_z11 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z11 -> osm_border_linestring_gen_z10
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z10 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z10 AS
(
SELECT ST_Simplify(geometry, ZRes(11)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z11
WHERE admin_level BETWEEN 2 AND 6
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z10_idx ON osm_border_linestring_gen_z10 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z10 -> osm_border_linestring_gen_z9
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z9 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z9 AS
(
SELECT ST_Simplify(geometry, ZRes(10)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z10
-- WHERE admin_level BETWEEN 2 AND 6
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z9_idx ON osm_border_linestring_gen_z9 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z9 -> osm_border_linestring_gen_z8
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z8 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z8 AS
(
SELECT ST_Simplify(geometry, ZRes(9)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z9
WHERE admin_level BETWEEN 2 AND 4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z8_idx ON osm_border_linestring_gen_z8 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z8 -> osm_border_linestring_gen_z7
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z7 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z7 AS
(
SELECT ST_Simplify(geometry, ZRes(8)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z8
-- WHERE admin_level BETWEEN 2 AND 4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z7_idx ON osm_border_linestring_gen_z7 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z7 -> osm_border_linestring_gen_z6
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z6 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z6 AS
(
SELECT ST_Simplify(geometry, ZRes(7)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z7
-- WHERE admin_level BETWEEN 2 AND 4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z6_idx ON osm_border_linestring_gen_z6 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z6 -> osm_border_linestring_gen_z5
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z5 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z5 AS
(
SELECT ST_Simplify(geometry, ZRes(6)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z6
-- WHERE admin_level BETWEEN 2 AND 4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z5_idx ON osm_border_linestring_gen_z5 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z5 -> osm_border_linestring_gen_z4
DROP MATERIALIZED VIEW IF EXISTS osm_border_linestring_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW osm_border_linestring_gen_z4 AS
(
SELECT ST_Simplify(geometry, ZRes(5)) AS geometry, adm0_l, adm0_r, admin_level, disputed, name, claimed_by, maritime
FROM osm_border_linestring_gen_z5
WHERE admin_level = 2 AND maritime
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS osm_border_linestring_gen_z4_idx ON osm_border_linestring_gen_z4 USING gist (geometry);
-- ne_10m_admin_0_boundary_lines_land
-- etldoc: ne_10m_admin_0_boundary_lines_land -> ne_10m_admin_0_boundary_lines_land_gen_z4
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_0_boundary_lines_land_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_0_boundary_lines_land_gen_z4 AS
(
SELECT ST_Simplify(geometry, ZRes(6)) as geometry,
2 AS admin_level,
(CASE WHEN featurecla LIKE 'Disputed%' THEN TRUE ELSE FALSE END) AS disputed,
NULL::text AS disputed_name,
NULL::text AS claimed_by,
FALSE AS maritime
FROM ne_10m_admin_0_boundary_lines_land
WHERE featurecla <> 'Lease limit'
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_0_boundary_lines_land_gen_z4_idx ON ne_10m_admin_0_boundary_lines_land_gen_z4 USING gist (geometry);
-- etldoc: ne_10m_admin_0_boundary_lines_land -> ne_10m_admin_0_boundary_lines_land_disputed
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_0_boundary_lines_land_disputed CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_0_boundary_lines_land_disputed AS
(
SELECT geometry,
2 AS admin_level,
(CASE WHEN featurecla LIKE 'Disputed%' THEN TRUE ELSE FALSE END) AS disputed,
NULL::text AS disputed_name,
NULL::text AS claimed_by,
FALSE AS maritime
FROM ne_10m_admin_0_boundary_lines_land
WHERE featurecla LIKE 'Disputed%' AND adm0_left = 'South Sudan' AND adm0_right = 'Kenya'
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_0_boundary_lines_land_disputed_idx ON ne_10m_admin_0_boundary_lines_land_disputed USING gist (geometry);
-- ne_10m_admin_1_states_provinces_lines
-- etldoc: ne_10m_admin_1_states_provinces_lines -> ne_10m_admin_1_states_provinces_lines_gen_z4
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_1_states_provinces_lines_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_1_states_provinces_lines_gen_z4 AS
(
SELECT ST_Simplify(geometry, ZRes(6)) as geometry,
4 AS admin_level,
FALSE AS disputed,
NULL::text AS disputed_name,
NULL::text AS claimed_by,
FALSE AS maritime,
min_zoom
FROM ne_10m_admin_1_states_provinces_lines
WHERE min_zoom <= 7.7
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_1_states_provinces_lines_gen_z4_idx ON ne_10m_admin_1_states_provinces_lines_gen_z4 USING gist (geometry);
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z4 -> ne_10m_admin_1_states_provinces_lines_gen_z3
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_1_states_provinces_lines_gen_z3 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_1_states_provinces_lines_gen_z3 AS
(
SELECT ST_Simplify(geometry, ZRes(5)) as geometry,
admin_level,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z4
WHERE min_zoom <= 7
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_1_states_provinces_lines_gen_z3_idx ON ne_10m_admin_1_states_provinces_lines_gen_z3 USING gist (geometry);
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z3 -> ne_10m_admin_1_states_provinces_lines_gen_z2
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_1_states_provinces_lines_gen_z2 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_1_states_provinces_lines_gen_z2 AS
(
SELECT ST_Simplify(geometry, ZRes(4)) as geometry,
admin_level,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z3
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_1_states_provinces_lines_gen_z2_idx ON ne_10m_admin_1_states_provinces_lines_gen_z2 USING gist (geometry);
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z2 -> ne_10m_admin_1_states_provinces_lines_gen_z1
DROP MATERIALIZED VIEW IF EXISTS ne_10m_admin_1_states_provinces_lines_gen_z1 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_admin_1_states_provinces_lines_gen_z1 AS
(
SELECT ST_Simplify(geometry, ZRes(3)) as geometry,
admin_level,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z2
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_admin_1_states_provinces_lines_gen_z1_idx ON ne_10m_admin_1_states_provinces_lines_gen_z1 USING gist (geometry);
-- ne_50m_admin_0_boundary_lines_land
-- etldoc: ne_50m_admin_0_boundary_lines_land -> ne_50m_admin_0_boundary_lines_land_gen_z3
DROP MATERIALIZED VIEW IF EXISTS ne_50m_admin_0_boundary_lines_land_gen_z3 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_admin_0_boundary_lines_land_gen_z3 AS
(
SELECT ST_Simplify(geometry, ZRes(5)) as geometry,
2 AS admin_level,
(CASE WHEN featurecla LIKE 'Disputed%' THEN TRUE ELSE FALSE END) AS disputed,
NULL::text AS disputed_name,
NULL::text AS claimed_by,
FALSE AS maritime
FROM ne_50m_admin_0_boundary_lines_land
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_admin_0_boundary_lines_land_gen_z3_idx ON ne_50m_admin_0_boundary_lines_land_gen_z3 USING gist (geometry);
-- etldoc: ne_50m_admin_0_boundary_lines_land_gen_z3 -> ne_50m_admin_0_boundary_lines_land_gen_z2
DROP MATERIALIZED VIEW IF EXISTS ne_50m_admin_0_boundary_lines_land_gen_z2 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_admin_0_boundary_lines_land_gen_z2 AS
(
SELECT ST_Simplify(geometry, ZRes(4)) as geometry,
admin_level,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_50m_admin_0_boundary_lines_land_gen_z3
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_admin_0_boundary_lines_land_gen_z2_idx ON ne_50m_admin_0_boundary_lines_land_gen_z2 USING gist (geometry);
-- etldoc: ne_50m_admin_0_boundary_lines_land_gen_z2 -> ne_50m_admin_0_boundary_lines_land_gen_z1
DROP MATERIALIZED VIEW IF EXISTS ne_50m_admin_0_boundary_lines_land_gen_z1 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_admin_0_boundary_lines_land_gen_z1 AS
(
SELECT ST_Simplify(geometry, ZRes(3)) as geometry,
admin_level,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_50m_admin_0_boundary_lines_land_gen_z2
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_admin_0_boundary_lines_land_gen_z1_idx ON ne_50m_admin_0_boundary_lines_land_gen_z1 USING gist (geometry);
-- ne_110m_admin_0_boundary_lines_land
-- etldoc: ne_110m_admin_0_boundary_lines_land -> ne_110m_admin_0_boundary_lines_land_gen_z0
DROP MATERIALIZED VIEW IF EXISTS ne_110m_admin_0_boundary_lines_land_gen_z0 CASCADE;
CREATE MATERIALIZED VIEW ne_110m_admin_0_boundary_lines_land_gen_z0 AS
(
SELECT ST_Simplify(geometry, ZRes(2)) as geometry,
2 AS admin_level,
(CASE WHEN featurecla LIKE 'Disputed%' THEN TRUE ELSE FALSE END) AS disputed,
NULL::text AS disputed_name,
NULL::text AS claimed_by,
FALSE AS maritime
FROM ne_110m_admin_0_boundary_lines_land
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_110m_admin_0_boundary_lines_land_gen_z0_idx ON ne_110m_admin_0_boundary_lines_land_gen_z0 USING gist (geometry);
CREATE OR REPLACE FUNCTION edit_name(name varchar) RETURNS text AS
$$
SELECT CASE
WHEN POSITION(' at ' IN name) > 0
THEN replace(SUBSTRING(name, POSITION(' at ' IN name) + 4), ' ', '')
ELSE replace(replace(name, ' ', ''), 'Extentof', '')
END;
$$ LANGUAGE SQL IMMUTABLE
-- STRICT
PARALLEL SAFE
;
-- etldoc: ne_110m_admin_0_boundary_lines_land_gen_z0 -> boundary_z0
CREATE OR REPLACE VIEW boundary_z0 AS
(
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_110m_admin_0_boundary_lines_land_gen_z0
);
-- etldoc: ne_50m_admin_0_boundary_lines_land_gen_z1 -> boundary_z1
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z1 -> boundary_z1
-- etldoc: ne_10m_admin_0_boundary_lines_land_disputed -> boundary_z1
-- etldoc: osm_border_disp_linestring_gen_z1 -> boundary_z1
DROP MATERIALIZED VIEW IF EXISTS boundary_z1 CASCADE;
CREATE MATERIALIZED VIEW boundary_z1 AS
(
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_50m_admin_0_boundary_lines_land_gen_z1
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z1
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_0_boundary_lines_land_disputed
);
CREATE INDEX IF NOT EXISTS boundary_z1_idx ON boundary_z1 USING gist (geometry);
-- etldoc: ne_50m_admin_0_boundary_lines_land_gen_z2 -> boundary_z2
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z2 -> boundary_z2
-- etldoc: ne_10m_admin_0_boundary_lines_land_disputed -> boundary_z2
-- etldoc: osm_border_disp_linestring_gen_z2 -> boundary_z2
DROP MATERIALIZED VIEW IF EXISTS boundary_z2 CASCADE;
CREATE MATERIALIZED VIEW boundary_z2 AS
(
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_50m_admin_0_boundary_lines_land_gen_z2
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z2
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_0_boundary_lines_land_disputed
);
CREATE INDEX IF NOT EXISTS boundary_z2_idx ON boundary_z2 USING gist (geometry);
-- etldoc: ne_50m_admin_0_boundary_lines_land_gen_z3 -> boundary_z3
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z3 -> boundary_z3
-- etldoc: ne_10m_admin_0_boundary_lines_land_disputed -> boundary_z3
-- etldoc: osm_border_disp_linestring_gen_z3 -> boundary_z3
DROP MATERIALIZED VIEW IF EXISTS boundary_z3 CASCADE;
CREATE MATERIALIZED VIEW boundary_z3 AS
(
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_50m_admin_0_boundary_lines_land_gen_z3
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z3
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_0_boundary_lines_land_disputed
);
CREATE INDEX IF NOT EXISTS boundary_z3_idx ON boundary_z3 USING gist (geometry);
-- etldoc: ne_10m_admin_0_boundary_lines_land_gen_z4 -> boundary_z4
-- etldoc: ne_10m_admin_1_states_provinces_lines_gen_z4 -> boundary_z4
-- etldoc: osm_border_linestring_gen_z4 -> boundary_z4
DROP MATERIALIZED VIEW IF EXISTS boundary_z4 CASCADE;
CREATE MATERIALIZED VIEW boundary_z4 AS
(
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_0_boundary_lines_land_gen_z4
UNION ALL
SELECT geometry,
admin_level,
NULL::text AS adm0_l,
NULL::text AS adm0_r,
disputed,
disputed_name,
claimed_by,
maritime
FROM ne_10m_admin_1_states_provinces_lines_gen_z4
UNION ALL
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z4
);
CREATE INDEX IF NOT EXISTS boundary_z4_idx ON boundary_z4 USING gist (geometry);
-- etldoc: osm_border_linestring_gen_z5 -> boundary_z5
CREATE OR REPLACE VIEW boundary_z5 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z5
WHERE admin_level <= 4
);
-- etldoc: osm_border_linestring_gen_z6 -> boundary_z6
CREATE OR REPLACE VIEW boundary_z6 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z6
WHERE admin_level <= 4
);
-- etldoc: osm_border_linestring_gen_z7 -> boundary_z7
CREATE OR REPLACE VIEW boundary_z7 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z7
WHERE admin_level <= 6
);
-- etldoc: osm_border_linestring_gen_z8 -> boundary_z8
CREATE OR REPLACE VIEW boundary_z8 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z8
WHERE admin_level <= 6
);
-- etldoc: osm_border_linestring_gen_z9 -> boundary_z9
CREATE OR REPLACE VIEW boundary_z9 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z9
WHERE admin_level <= 6
);
-- etldoc: osm_border_linestring_gen_z10 -> boundary_z10
CREATE OR REPLACE VIEW boundary_z10 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z10
WHERE admin_level <= 6
);
-- etldoc: osm_border_linestring_gen_z11 -> boundary_z11
CREATE OR REPLACE VIEW boundary_z11 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z11
WHERE admin_level <= 8
);
-- etldoc: osm_border_linestring_gen_z12 -> boundary_z12
CREATE OR REPLACE VIEW boundary_z12 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z12
);
-- etldoc: osm_border_linestring_gen_z13 -> boundary_z13
CREATE OR REPLACE VIEW boundary_z13 AS
(
SELECT geometry,
admin_level,
adm0_l,
adm0_r,
disputed,
CASE WHEN disputed THEN edit_name(name) END AS disputed_name,
claimed_by,
maritime
FROM osm_border_linestring_gen_z13
);
-- etldoc: layer_boundary[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="<sql> layer_boundary |<z0> z0 |<z1> z1 |<z2> z2 | <z3> z3 | <z4> z4 | <z5> z5 | <z6> z6 | <z7> z7 | <z8> z8 | <z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13|<z14> z14+"]
CREATE OR REPLACE FUNCTION layer_boundary(bbox geometry, zoom_level int)
RETURNS TABLE
(
geometry geometry,
admin_level int,
adm0_l text,
adm0_r text,
disputed int,
disputed_name text,
claimed_by text,
maritime int,
class text,
name text,
tags hstore
)
AS
$$
SELECT geometry, admin_level, adm0_l, adm0_r, disputed::int, disputed_name, claimed_by, maritime::int, NULL::text, NULL::text, NULL::hstore
FROM (
-- etldoc: boundary_z0 -> layer_boundary:z0
SELECT *
FROM boundary_z0
WHERE geometry && bbox
AND zoom_level = 0
UNION ALL
-- etldoc: boundary_z1 -> layer_boundary:z1
SELECT *
FROM boundary_z1
WHERE geometry && bbox
AND zoom_level = 1
UNION ALL
-- etldoc: boundary_z2 -> layer_boundary:z2
SELECT *
FROM boundary_z2
WHERE geometry && bbox
AND zoom_level = 2
UNION ALL
-- etldoc: boundary_z3 -> layer_boundary:z3
SELECT *
FROM boundary_z3
WHERE geometry && bbox
AND zoom_level = 3
UNION ALL
-- etldoc: boundary_z4 -> layer_boundary:z4
SELECT *
FROM boundary_z4
WHERE geometry && bbox
AND zoom_level = 4
UNION ALL
-- etldoc: boundary_z5 -> layer_boundary:z5
SELECT *
FROM boundary_z5
WHERE geometry && bbox
AND zoom_level = 5
UNION ALL
-- etldoc: boundary_z6 -> layer_boundary:z6
SELECT *
FROM boundary_z6
WHERE geometry && bbox
AND zoom_level = 6
UNION ALL
-- etldoc: boundary_z7 -> layer_boundary:z7
SELECT *
FROM boundary_z7
WHERE geometry && bbox
AND zoom_level = 7
UNION ALL
-- etldoc: boundary_z8 -> layer_boundary:z8
SELECT *
FROM boundary_z8
WHERE geometry && bbox
AND zoom_level = 8
UNION ALL
-- etldoc: boundary_z9 -> layer_boundary:z9
SELECT *
FROM boundary_z9
WHERE geometry && bbox
AND zoom_level = 9
UNION ALL
-- etldoc: boundary_z10 -> layer_boundary:z10
SELECT *
FROM boundary_z10
WHERE geometry && bbox
AND zoom_level = 10
UNION ALL
-- etldoc: boundary_z11 -> layer_boundary:z11
SELECT *
FROM boundary_z11
WHERE geometry && bbox
AND zoom_level = 11
UNION ALL
-- etldoc: boundary_z12 -> layer_boundary:z12
SELECT *
FROM boundary_z12
WHERE geometry && bbox
AND zoom_level = 12
UNION ALL
-- etldoc: boundary_z13 -> layer_boundary:z13
SELECT *
FROM boundary_z13
WHERE geometry && bbox
AND zoom_level >= 13
) AS segment_zoom_levels
UNION ALL
SELECT geometry, NULL::int, NULL::text, NULL::text, NULL::int, NULL::text, NULL::text, NULL::int, class, name, tags
FROM (
-- etldoc: osm_boundary_polygon_gen_z4 -> layer_boundary:z4
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z4
WHERE zoom_level = 4
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z5 -> layer_boundary:z5
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z5
WHERE zoom_level = 5
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z6 -> layer_boundary:z6
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z6
WHERE zoom_level = 6
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z7 -> layer_boundary:z7
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z7
WHERE zoom_level = 7
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z8 -> layer_boundary:z8
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z8
WHERE zoom_level = 8
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z9 -> layer_boundary:z9
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z9
WHERE zoom_level = 9
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z10 -> layer_boundary:z10
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z10
WHERE zoom_level = 10
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z11 -> layer_boundary:z11
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z11
WHERE zoom_level = 11
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z12 -> layer_boundary:z12
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z12
WHERE zoom_level = 12
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon_gen_z13 -> layer_boundary:z13
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon_gen_z13
WHERE zoom_level = 13
AND geometry && bbox
UNION ALL
-- etldoc: osm_boundary_polygon -> layer_boundary:z14
SELECT geometry,
boundary AS class,
name,
tags
FROM osm_boundary_polygon
WHERE zoom_level = 14
AND geometry && bbox
) AS area_zoom_levels
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,72 @@
layer:
id: "boundary"
requires:
tables:
- osm_border_linestring
- ne_10m_admin_0_countries
- ne_10m_admin_0_boundary_lines_land
- ne_10m_admin_1_states_provinces_lines
- ne_50m_admin_0_boundary_lines_land
- ne_110m_admin_0_boundary_lines_land
description: |
Contains administrative boundaries as linestrings and aboriginal lands as polygons.
Until z4 [Natural Earth data](http://www.naturalearthdata.com/downloads/) is used after which
OSM boundaries ([`boundary=administrative`](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative))
are present from z5 to z14 (also for maritime boundaries with `admin_level <= 2` at z4).
OSM data contains several [`admin_level`](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative#admin_level)
but for most styles it makes sense to just style `admin_level=2` and `admin_level=4`.
fields:
class:
description: |
Use the **class** to differentiate between different kinds of boundaries. The class for `boundary=aboriginal_lands` is `aboriginal_lands`.
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value (area features only).
admin_level: |
OSM [admin_level](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative#admin_level)
indicating the level of importance of this boundary.
The `admin_level` corresponds to the lowest `admin_level`
the line participates in.
At low zoom levels the Natural Earth boundaries are mapped to the equivalent admin levels.
adm0_l: |
State name on the left of the border. For country boundaries only (`admin_level = 2`).
adm0_r: |
State name on the right of the border. For country boundaries only (`admin_level = 2`).
disputed:
description: |
Mark with `1` if the border is disputed.
values: [0, 1]
disputed_name:
description: |
Field containing name of the disputed area (extracted from border relation in OSM, without spaces).
For country boundaries only (`admin_level = 2`).
Value examples from Asian OSM pbf extract
values:
- AbuMusaIsland
- BaraHotiiValleys
- ChineseClaim
- Crimea
- Demchok
- Dokdo
- IndianClaim-North
- IndianClaimwesternKashmir
- PakistaniClaim
- SamduValleys
- TirpaniValleys
claimed_by:
description: |
ISO2 code of country, which wants to see the boundary line.
For country boundaries only (`admin_level = 2`).
maritime:
description: |
Mark with `1` if it is a maritime border.
values: [0, 1]
buffer_size: 4
datasource:
geometry_field: geometry
query: (SELECT geometry, admin_level, adm0_l, adm0_r, disputed, disputed_name, claimed_by, maritime, class, name, {name_languages} FROM layer_boundary(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./update_boundary_polygon.sql
- ./boundary_name.sql
- ./boundary.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

View file

@ -0,0 +1,105 @@
DROP TABLE IF EXISTS osm_border_linestring_adm CASCADE;
-- etldoc: osm_border_linestring -> osm_border_linestring_adm
-- etldoc: osm_border_disp_linestring -> osm_border_linestring_adm
-- etldoc: ne_10m_admin_0_countries -> osm_border_linestring_adm
CREATE TABLE IF NOT EXISTS osm_border_linestring_adm AS (
WITH
-- Prepare lines from osm to be merged
multiline AS (
SELECT osm_id,
ST_Node(ST_Collect(geometry)) AS geometry,
BOOL_OR(maritime) AS maritime,
FALSE AS disputed
FROM osm_border_linestring
WHERE admin_level = 2 AND ST_Dimension(geometry) = 1
AND osm_id NOT IN (SELECT DISTINCT osm_id FROM osm_border_disp_linestring)
GROUP BY osm_id
),
mergedline AS (
SELECT osm_id,
(ST_Dump(ST_LineMerge(geometry))).geom AS geometry,
maritime,
disputed
FROM multiline
),
-- Create polygons from all boundaries to preserve real shape of country
polyg AS (
SELECT (ST_Dump(
ST_Polygonize(geometry))).geom AS geometry
FROM (
SELECT (ST_Dump(
ST_LineMerge(geometry))).geom AS geometry
FROM (SELECT ST_Node(
ST_Collect(geometry)) AS geometry
FROM osm_border_linestring
WHERE admin_level = 2 AND ST_Dimension(geometry) = 1
) nodes
) linemerge
),
centroids AS (
SELECT polyg.geometry,
ne.adm0_a3
FROM polyg,
ne_10m_admin_0_countries AS ne
WHERE ST_Within(
ST_PointOnSurface(polyg.geometry), ne.geometry)
),
country_osm_polyg AS (
SELECT country.adm0_a3,
border.geometry
FROM polyg border,
centroids country
WHERE ST_Within(country.geometry, border.geometry)
),
rights AS (
SELECT osm_id,
adm0_r,
geometry,
maritime,
disputed
FROM (
SELECT a.osm_id AS osm_id,
b.adm0_a3 AS adm0_r,
a.geometry,
a.maritime,
a.disputed
FROM mergedline AS a
LEFT JOIN country_osm_polyg AS b
-- Create short line on the right of the boundary (mergedline) and find state where line lies.
ON ST_Within(
ST_OffsetCurve(
(ST_LineSubString(a.geometry, 0.3,0.3004)), 70, 'quad_segs=4 join=mitre'), b.geometry)
) line_rights
)
SELECT osm_id,
adm0_l,
adm0_r,
geometry,
maritime,
2::integer AS admin_level,
disputed
FROM (
SELECT r.osm_id AS osm_id,
b.adm0_a3 AS adm0_l,
r.adm0_r AS adm0_r,
r.geometry,
r.maritime,
r.disputed
FROM rights AS r
LEFT JOIN country_osm_polyg AS b
-- Create short line on the left of the boundary (mergedline) and find state where line lies.
ON ST_Within(
ST_OffsetCurve(
(ST_LineSubString(r.geometry, 0.4,0.4004)), -70, 'quad_segs=4 join=mitre'), b.geometry)
) both_lines
);
CREATE INDEX IF NOT EXISTS osm_border_linestring_adm_geom_idx
ON osm_border_linestring_adm
USING GIST (geometry);

Binary file not shown.

After

Width:  |  Height:  |  Size: 750 KiB

View file

@ -0,0 +1,160 @@
generalized_tables:
# etldoc: osm_border_linestring -> osm_border_disp_linestring
border_disp_linestring:
source: border_linestring
sql_filter: ST_GeometryType(geometry) = 'ST_LineString' AND (disputed OR dispute OR border_status = 'disputed' OR disputed_by <> '') AND admin_level = 2
# etldoc: osm_boundary_polygon_gen_z5 -> osm_boundary_polygon_gen_z4
boundary_polygon_gen_z4:
source: boundary_polygon_gen_z5
sql_filter: area>power(ZRES3,2)
tolerance: ZRES4
# etldoc: osm_boundary_polygon_gen_z6 -> osm_boundary_polygon_gen_z5
boundary_polygon_gen_z5:
source: boundary_polygon_gen_z6
sql_filter: area>power(ZRES4,2)
tolerance: ZRES5
# etldoc: osm_boundary_polygon_gen_z7 -> osm_boundary_polygon_gen_z6
boundary_polygon_gen_z6:
source: boundary_polygon_gen_z7
sql_filter: area>power(ZRES5,2)
tolerance: ZRES6
# etldoc: osm_boundary_polygon_gen_z8 -> osm_boundary_polygon_gen_z7
boundary_polygon_gen_z7:
source: boundary_polygon_gen_z8
sql_filter: area>power(ZRES6,2)
tolerance: ZRES7
# etldoc: osm_boundary_polygon_gen_z9 -> osm_boundary_polygon_gen_z8
boundary_polygon_gen_z8:
source: boundary_polygon_gen_z9
sql_filter: area>power(ZRES7,2)
tolerance: ZRES8
# etldoc: osm_boundary_polygon_gen_z10 -> osm_boundary_polygon_gen_z9
boundary_polygon_gen_z9:
source: boundary_polygon_gen_z10
sql_filter: area>power(ZRES8,2)
tolerance: ZRES9
# etldoc: osm_boundary_polygon_gen_z11 -> osm_boundary_polygon_gen_z10
boundary_polygon_gen_z10:
source: boundary_polygon_gen_z11
sql_filter: area>power(ZRES9,2)
tolerance: ZRES10
# etldoc: osm_boundary_polygon_gen_z12 -> osm_boundary_polygon_gen_z11
boundary_polygon_gen_z11:
source: boundary_polygon_gen_z12
sql_filter: area>power(ZRES10,2)
tolerance: ZRES11
# etldoc: osm_boundary_polygon_gen_z13 -> osm_boundary_polygon_gen_z12
boundary_polygon_gen_z12:
source: boundary_polygon_gen_z13
sql_filter: area>power(ZRES11,2)
tolerance: ZRES12
# etldoc: osm_boundary_polygon -> osm_boundary_polygon_gen_z13
boundary_polygon_gen_z13:
source: boundary_polygon
sql_filter: area>power(ZRES12,2) AND ST_IsValid(geometry)
tolerance: ZRES13
tables:
# etldoc: imposm3 -> osm_border_linestring
border_linestring:
type: relation_member
filters:
require:
admin_level: [__any__]
boundary: [administrative]
columns:
- name: relation_id
type: id
- name: osm_id
type: id
from_member: true
- name: member
type: member_id
- name: type
type: member_type
- name: geometry
type: geometry
- key: name
name: name
type: string
# Used for disputed boundary, e.g. "Line of actual control"
from_member: true
- key: admin_level
name: admin_level
type: integer
- key: claimed_by
name: claimed_by
type: string
- key: disputed_by
name: disputed_by
type: string
from_member: true
- key: dispute
name: dispute
type: bool
from_member: true
- key: disputed
name: disputed
type: bool
from_member: true
- key: border_status
name: border_status
type: string
from_member: true
- key: maritime
name: maritime
type: bool
from_member: true
- key: boundary_type
name: boundary_type
type: string
from_member: true
- key: natural
name: natural
type: string
from_member: true
relation_types: [boundary]
mapping:
boundary:
- administrative
border_status:
- dispute
boundary_type:
- maritime
# etldoc: imposm3 -> osm_boundary_polygon
boundary_polygon:
type: polygon
filters:
require:
type: [boundary]
boundary: [aboriginal_lands]
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: name
key: name
type: string
- name: tags
type: hstore_tags
- name: boundary
key: boundary
type: string
- name: area
type: area
mapping:
boundary:
- aboriginal_lands

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

287
layers/boundary/style.json Normal file
View file

@ -0,0 +1,287 @@
{
"layers": [
{
"id": "boundary_3",
"type": "line",
"source": "openmaptiles",
"source-layer": "boundary",
"minzoom": 3,
"layout": {
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "#845283",
"line-width": {
"base": 1,
"stops": [
[
4,
0.4
],
[
5,
0.7
],
[
12,
1.6
]
]
},
"line-opacity": {
"stops": [
[
3,
0.5
],
[
10,
1
]
]
},
"line-dasharray": [
5,
3
]
},
"metadata": {},
"filter": [
"all",
[
"in",
"admin_level",
3,
4
],
[
"==",
"maritime",
0
]
],
"order": 146
},
{
"id": "boundary_2",
"type": "line",
"source": "openmaptiles",
"source-layer": "boundary",
"minzoom": 0,
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "#a37da1",
"line-width": {
"base": 1,
"stops": [
[
3,
0.5
],
[
5,
1.2
],
[
12,
3
]
]
},
"line-opacity": 1
},
"metadata": {},
"filter": [
"all",
[
"==",
"admin_level",
2
],
[
"==",
"maritime",
0
],
[
"==",
"disputed",
0
]
],
"order": 147
},
{
"id": "boundary_2_disputed",
"type": "line",
"source": "openmaptiles",
"source-layer": "boundary",
"minzoom": 0,
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "#a37da1",
"line-width": {
"base": 1,
"stops": [
[
3,
0.3
],
[
5,
1.2
],
[
12,
3
]
]
},
"line-opacity": 1,
"line-dasharray": [
4,
3
]
},
"metadata": {},
"filter": [
"all",
[
"==",
"admin_level",
2
],
[
"==",
"disputed",
1
],
[
"==",
"maritime",
0
]
],
"order": 148
},
{
"id": "boundary_2_disputed_maritime",
"type": "line",
"source": "openmaptiles",
"source-layer": "boundary",
"minzoom": 0,
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "rgba(129, 125, 163, 1)",
"line-width": {
"base": 1,
"stops": [
[
3,
0.5
],
[
5,
1.2
],
[
12,
3
]
]
},
"line-opacity": 1,
"line-dasharray": [
4,
3
]
},
"metadata": {},
"filter": [
"all",
[
"==",
"admin_level",
2
],
[
"==",
"disputed",
1
],
[
"==",
"maritime",
1
]
],
"order": 149
},
{
"id": "boundary_2_maritime",
"type": "line",
"source": "openmaptiles",
"source-layer": "boundary",
"minzoom": 4,
"layout": {
"line-cap": "round",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "#a37da1",
"line-width": {
"base": 1,
"stops": [
[
3,
0.5
],
[
5,
1.2
],
[
12,
3
]
]
},
"line-opacity": 1
},
"metadata": {},
"filter": [
"all",
[
"==",
"admin_level",
2
],
[
"==",
"disputed",
0
],
[
"==",
"maritime",
1
]
],
"order": 150
}
]
}

View file

@ -0,0 +1,170 @@
ALTER TABLE osm_boundary_polygon
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z13
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z12
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z11
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z10
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z9
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z8
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z7
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z6
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_boundary_polygon_gen_z5
ADD COLUMN IF NOT EXISTS geometry_point geometry;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z13;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z12;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z11;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z10;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z9;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z8;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z7;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z6;
DROP TRIGGER IF EXISTS update_row ON osm_boundary_polygon_gen_z5;
-- etldoc: osm_boundary_polygon -> osm_boundary_polygon
-- etldoc: osm_boundary_polygon_gen_z13 -> osm_boundary_polygon_gen_z13
-- etldoc: osm_boundary_polygon_gen_z12 -> osm_boundary_polygon_gen_z12
-- etldoc: osm_boundary_polygon_gen_z11 -> osm_boundary_polygon_gen_z11
-- etldoc: osm_boundary_polygon_gen_z10 -> osm_boundary_polygon_gen_z10
-- etldoc: osm_boundary_polygon_gen_z9 -> osm_boundary_polygon_gen_z9
-- etldoc: osm_boundary_polygon_gen_z8 -> osm_boundary_polygon_gen_z8
-- etldoc: osm_boundary_polygon_gen_z7 -> osm_boundary_polygon_gen_z7
-- etldoc: osm_boundary_polygon_gen_z6 -> osm_boundary_polygon_gen_z6
-- etldoc: osm_boundary_polygon_gen_z5 -> osm_boundary_polygon_gen_z5
CREATE OR REPLACE FUNCTION update_osm_boundary_polygon() RETURNS void AS
$$
BEGIN
UPDATE osm_boundary_polygon
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z13
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z12
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z11
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z10
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z9
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z8
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z7
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z6
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_boundary_polygon_gen_z5
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_boundary_polygon();
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_point_geom_idx ON osm_boundary_polygon USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z13_point_geom_idx ON osm_boundary_polygon_gen_z13 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z12_point_geom_idx ON osm_boundary_polygon_gen_z12 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z11_point_geom_idx ON osm_boundary_polygon_gen_z11 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z10_point_geom_idx ON osm_boundary_polygon_gen_z10 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z9_point_geom_idx ON osm_boundary_polygon_gen_z9 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z8_point_geom_idx ON osm_boundary_polygon_gen_z8 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z7_point_geom_idx ON osm_boundary_polygon_gen_z7 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z6_point_geom_idx ON osm_boundary_polygon_gen_z6 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_boundary_polygon_gen_z5_point_geom_idx ON osm_boundary_polygon_gen_z5 USING gist (geometry_point);
CREATE OR REPLACE FUNCTION update_osm_boundary_polygon_row()
RETURNS trigger
AS
$$
BEGIN
NEW.tags = update_tags(NEW.tags, NEW.geometry);
NEW.geometry_point = ST_PointOnSurface(NEW.geometry);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z13
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z12
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z11
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z10
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z9
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z8
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z7
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z6
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_boundary_polygon_gen_z5
FOR EACH ROW
EXECUTE PROCEDURE update_osm_boundary_polygon_row();

10
layers/building/README.md Normal file
View file

@ -0,0 +1,10 @@
## building
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#building**
### Mapping Diagram
![Mapping diagram for building](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for building](etl_diagram.png?raw=true)

View file

@ -0,0 +1,126 @@
-- etldoc: layer_building[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_building | <z13> z13 | <z14_> z14+ " ] ;
CREATE INDEX IF NOT EXISTS osm_building_relation_building_idx ON osm_building_relation (building) WHERE building = '' AND ST_GeometryType(geometry) = 'ST_Polygon';
CREATE INDEX IF NOT EXISTS osm_building_relation_member_idx ON osm_building_relation (member) WHERE role = 'outline';
CREATE OR REPLACE VIEW osm_all_buildings AS
(
SELECT
-- etldoc: osm_building_relation -> layer_building:z14_
-- Buildings built from relations
member AS osm_id,
geometry,
COALESCE(CleanNumeric(height), CleanNumeric(buildingheight)) AS height,
COALESCE(CleanNumeric(min_height), CleanNumeric(buildingmin_height)) AS min_height,
COALESCE(CleanNumeric(levels), CleanNumeric(buildinglevels)) AS levels,
COALESCE(CleanNumeric(min_level), CleanNumeric(buildingmin_level)) AS min_level,
nullif(material, '') AS material,
nullif(colour, '') AS colour,
FALSE AS hide_3d,
building
FROM osm_building_relation
WHERE building = ''
AND ST_GeometryType(geometry) = 'ST_Polygon'
UNION ALL
SELECT
-- etldoc: osm_building_polygon -> layer_building:z14_
-- Standalone buildings
obp.osm_id,
obp.geometry,
COALESCE(CleanNumeric(obp.height), CleanNumeric(obp.buildingheight)) AS height,
COALESCE(CleanNumeric(obp.min_height), CleanNumeric(obp.buildingmin_height)) AS min_height,
COALESCE(CleanNumeric(obp.levels), CleanNumeric(obp.buildinglevels)) AS levels,
COALESCE(CleanNumeric(obp.min_level), CleanNumeric(obp.buildingmin_level)) AS min_level,
nullif(obp.material, '') AS material,
nullif(obp.colour, '') AS colour,
obr.role IS NOT NULL AS hide_3d,
obp.building AS building
FROM osm_building_polygon obp
LEFT JOIN osm_building_relation obr ON
obp.osm_id >= 0 AND
obr.member = obp.osm_id AND
obr.role = 'outline'
WHERE ST_GeometryType(obp.geometry) IN ('ST_Polygon', 'ST_MultiPolygon')
);
CREATE OR REPLACE FUNCTION layer_building(bbox geometry, zoom_level int)
RETURNS TABLE
(
geometry geometry,
osm_id bigint,
render_height int,
render_min_height int,
colour text,
hide_3d boolean,
building text
)
AS
$$
SELECT geometry,
osm_id,
render_height,
render_min_height,
COALESCE(colour, CASE material
-- Ordered by count from taginfo
WHEN 'cement_block' THEN '#6a7880'
WHEN 'brick' THEN '#bd8161'
WHEN 'plaster' THEN '#dadbdb'
WHEN 'wood' THEN '#d48741'
WHEN 'concrete' THEN '#d3c2b0'
WHEN 'metal' THEN '#b7b1a6'
WHEN 'stone' THEN '#b4a995'
WHEN 'mud' THEN '#9d8b75'
WHEN 'steel' THEN '#b7b1a6' -- same as metal
WHEN 'glass' THEN '#5a81a0'
WHEN 'traditional' THEN '#bd8161' -- same as brick
WHEN 'masonry' THEN '#bd8161' -- same as brick
WHEN 'Brick' THEN '#bd8161' -- same as brick
WHEN 'tin' THEN '#b7b1a6' -- same as metal
WHEN 'timber_framing' THEN '#b3b0a9'
WHEN 'sandstone' THEN '#b4a995' -- same as stone
WHEN 'clay' THEN '#9d8b75' -- same as mud
END) AS colour,
CASE WHEN hide_3d THEN TRUE END AS hide_3d,
building
FROM (
SELECT
-- etldoc: osm_building_block_gen_z13 -> layer_building:z13
osm_id,
geometry,
NULL::int AS render_height,
NULL::int AS render_min_height,
NULL::text AS material,
NULL::text AS colour,
FALSE AS hide_3d,
NULL::text AS building
FROM osm_building_block_gen_z13
WHERE zoom_level = 13
AND geometry && bbox
UNION ALL
SELECT
-- etldoc: osm_building_polygon -> layer_building:z14_
DISTINCT ON (osm_id) osm_id,
geometry,
ceil(COALESCE(height, levels * 3.66, 5))::int AS render_height,
floor(COALESCE(min_height, min_level * 3.66, 0))::int AS render_min_height,
material,
colour,
hide_3d,
building
FROM osm_all_buildings
WHERE (levels IS NULL OR levels < 1000)
AND (min_level IS NULL OR min_level < 1000)
AND (height IS NULL OR height < 3000)
AND (min_height IS NULL OR min_height < 3000)
AND zoom_level >= 14
AND geometry && bbox
) AS zoom_levels
ORDER BY render_height ASC, ST_YMin(geometry) DESC;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE
;
-- not handled: where a building outline covers building parts

View file

@ -0,0 +1,28 @@
layer:
id: "building"
description: |
All [OSM Buildings](http://wiki.openstreetmap.org/wiki/Buildings). All building tags are imported ([`building=*`](http://wiki.openstreetmap.org/wiki/Key:building)).
Only buildings with tag location:underground are excluded.
buffer_size: 4
datasource:
geometry_field: geometry
key_field: osm_id
key_field_as_attribute: no
srid: 900913
query: (SELECT osm_id, geometry, render_height, render_min_height, colour, hide_3d, building FROM layer_building(!bbox!, z(!scale_denominator!))) AS t
fields:
render_height: |
An approximated height from levels and height of the building or building:part.
render_min_height: |
An approximated height from minimum levels or minimum height of the bottom of the building or building:part.
colour: |
Colour
hide_3d: |
If True, building (part) should not be rendered in 3D. Currently, [building outlines](https://wiki.openstreetmap.org/wiki/Simple_3D_buildings) are marked as hide_3d.
building:
schema:
- ./update_building.sql
- ./building.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View file

@ -0,0 +1,163 @@
#generalized_tables:
# # etldoc: imposm3 -> osm_building_polygon_gen1
# building_polygon_gen1:
# source: building_polygon
# sql_filter: area>power(ZRES12,2) AND ST_IsValid(geometry)
# tolerance: ZRES14
tables:
# etldoc: imposm3 -> osm_building_polygon
building_polygon:
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: area
type: area
- name: material
key: building:material
type: string
- name: colour
key: building:colour
type: string
- name: building
key: building
type: string
- name: buildingpart
key: building:part
type: string
- name: buildingheight
key: building:height
type: string
- name: buildingmin_height
key: building:min_height
type: string
- name: buildinglevels
key: building:levels
type: string
- name: buildingmin_level
key: building:min_level
type: string
- name: height
key: height
type: string
- name: min_height
key: min_height
type: string
- name: levels
key: levels
type: string
- name: min_level
key: min_level
type: string
mapping:
building:part:
- __any__
building:
- __any__
# these aeroway polygons all imply building=yes
aeroway:
- terminal
- hangar
location:
- underground
filters:
reject:
building: ["no","none","No"]
building:part: ["no","none","No"]
man_made: ["bridge"]
location: ["underground"]
type: polygon
# etldoc: imposm3 -> osm_building_relation
building_relation:
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: area
type: area
- name: building
key: building
type: string
from_member: true
- name: material
key: building:material
type: string
- name: colour
key: building:colour
type: string
- name: buildingpart
key: building:part
type: string
from_member: true
- name: buildingheight
key: building:height
type: string
from_member: true
- name: height
key: height
type: string
from_member: true
- name: buildingmin_height
key: building:min_height
type: string
from_member: true
- name: min_height
key: min_height
type: string
from_member: true
- name: buildinglevels
key: building:levels
type: string
from_member: true
- name: levels
key: levels
type: string
from_member: true
- name: buildingmin_level
key: building:min_level
type: string
from_member: true
- name: min_level
key: min_level
type: string
from_member: true
- name: relbuildingheight
key: building:height
type: string
- name: relheight
key: height
type: string
- name: relbuildingmin_height
key: building:min_height
type: string
- name: relmin_height
key: min_height
type: string
- name: relbuildinglevels
key: building:levels
type: string
- name: rellevels
key: levels
type: string
- name: relbuildingmin_level
key: building:min_level
type: string
- name: relmin_level
key: min_level
type: string
- name: member
type: member_id
- name: index
type: member_index
- name: role
type: member_role
from_member: true
- name: type
type: member_type
mapping:
type: [building]
type: relation_member

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -0,0 +1,44 @@
{
"layers": [
{
"id": "building",
"type": "fill",
"source": "openmaptiles",
"source-layer": "building",
"minzoom": 12,
"maxzoom": 24,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": {
"stops": [
[
13,
"rgba(222, 213, 207, 1)"
],
[
16,
"#d9d0c9"
]
]
},
"fill-outline-color": {
"base": 1,
"stops": [
[
13,
"#9A918A"
],
[
16,
"rgba(166, 157, 150, 1)"
]
]
}
},
"metadata": {},
"order": 19
}
]
}

View file

@ -0,0 +1,185 @@
DROP TRIGGER IF EXISTS trigger_refresh ON buildings.updates;
DROP TRIGGER IF EXISTS trigger_flag ON osm_building_polygon;
-- Creating aggregated building blocks with removed small polygons and small
-- holes. Aggregated polygons are simplified by Visvalingam-Whyatt algorithm.
-- Aggregating is made block by block using country_osm_grid polygon table.
-- Function returning recordset for matview.
-- Returning recordset of buildings aggregates by zres 14, with removed small
-- holes and with removed small buildings/blocks.
CREATE OR REPLACE FUNCTION osm_building_block_gen1()
RETURNS table
(
osm_id bigint,
geometry geometry
)
AS
$$
DECLARE
zres14 float := Zres(14);
zres12 float := Zres(12);
zres14vw float := Zres(14) * Zres(14);
polyg_world record;
BEGIN
FOR polyg_world IN
SELECT ST_Transform(country.geometry, 3857) AS geometry
FROM country_osm_grid country
LOOP
FOR osm_id, geometry IN
WITH dta AS ( -- CTE is used because of optimization
SELECT o.osm_id,
o.geometry,
ST_ClusterDBSCAN(o.geometry, eps := zres14, minpoints := 1) OVER () cid
FROM osm_building_polygon o
WHERE ST_Intersects(o.geometry, polyg_world.geometry)
)
SELECT (array_agg(dta.osm_id))[1] AS osm_id,
ST_Buffer(
ST_Union(
ST_Buffer(
ST_SnapToGrid(dta.geometry, 0.000001)
, zres14, 'join=mitre')
)
, -zres14, 'join=mitre') AS geometry
FROM dta
GROUP BY cid
LOOP
-- removing holes smaller than
IF ST_NumInteriorRings(geometry) > 0 THEN -- only from geometries wih holes
geometry := (
-- there are some multi-geometries in this layer
SELECT ST_Collect(gn)
FROM (
-- in some cases are "holes" NULL, because all holes are smaller than
SELECT COALESCE(
-- exterior ring
ST_MakePolygon(ST_ExteriorRing(dmp.geom), holes),
ST_MakePolygon(ST_ExteriorRing(dmp.geom))
) gn
FROM ST_Dump(geometry) dmp, -- 1 dump polygons
LATERAL (
SELECT array_agg(ST_Boundary(rg.geom)) holes -- 2 create array
FROM ST_DumpRings(dmp.geom) rg -- 3 from rings
WHERE rg.path[1] > 0 -- 5 except inner ring
AND ST_Area(rg.geom) >= power(zres12, 2) -- 4 bigger than
) holes
) new_geom
);
END IF;
IF ST_Area(geometry) < power(zres12, 2) THEN
CONTINUE;
END IF;
-- simplify
geometry := ST_SimplifyVW(geometry, zres14vw);
RETURN NEXT;
END LOOP;
END LOOP;
END;
$$ LANGUAGE plpgsql STABLE
STRICT
PARALLEL SAFE;
DROP MATERIALIZED VIEW IF EXISTS osm_building_block_gen1_dup CASCADE;
CREATE MATERIALIZED VIEW osm_building_block_gen1_dup AS
SELECT *
FROM osm_building_block_gen1();
CREATE INDEX ON osm_building_block_gen1_dup USING gist (geometry);
-- etldoc: osm_building_polygon -> osm_building_block_gen_z13
DROP MATERIALIZED VIEW IF EXISTS osm_building_block_gen_z13;
CREATE MATERIALIZED VIEW osm_building_block_gen_z13 AS
(
WITH
counts AS (
SELECT count(osm_id) AS counts,
osm_id
FROM osm_building_block_gen1_dup
GROUP BY osm_id
),
duplicates AS (
SELECT counts.osm_id
FROM counts
WHERE counts.counts > 1
)
SELECT osm.osm_id,
ST_Union(
ST_MakeValid(osm.geometry)) AS geometry
FROM osm_building_block_gen1_dup osm,
duplicates
WHERE osm.osm_id = duplicates.osm_id
GROUP BY osm.osm_id
UNION ALL
SELECT osm.osm_id,
osm.geometry
FROM osm_building_block_gen1_dup osm,
counts
WHERE counts.counts = 1
AND osm.osm_id = counts.osm_id
);
CREATE INDEX ON osm_building_block_gen_z13 USING gist (geometry);
CREATE UNIQUE INDEX ON osm_building_block_gen_z13 USING btree (osm_id);
-- Handle updates
CREATE SCHEMA IF NOT EXISTS buildings;
CREATE TABLE IF NOT EXISTS buildings.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION buildings.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO buildings.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION buildings.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh buildings block';
REFRESH MATERIALIZED VIEW osm_building_block_gen1_dup;
REFRESH MATERIALIZED VIEW osm_building_block_gen_z13;
-- noinspection SqlWithoutWhere
DELETE FROM buildings.updates;
RAISE LOG 'Update buildings block done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE
ON osm_building_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE buildings.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON buildings.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE buildings.refresh();

View file

@ -0,0 +1,10 @@
## housenumber
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#housenumber**
### Mapping Diagram
![Mapping diagram for housenumber](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for housenumber](etl_diagram.png?raw=true)

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,33 @@
-- etldoc: layer_housenumber[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_housenumber | <z14_> z14+" ] ;
CREATE OR REPLACE FUNCTION layer_housenumber(bbox geometry, zoom_level integer)
RETURNS TABLE
(
osm_id bigint,
geometry geometry,
housenumber text
)
AS
$$
SELECT
-- etldoc: osm_housenumber_point -> layer_housenumber:z14_
osm_id,
geometry,
display_housenumber(housenumber)
FROM (
SELECT
osm_id,
geometry,
housenumber,
row_number() OVER(PARTITION BY concat(street, block_number, housenumber) ORDER BY has_name ASC) as rn
FROM osm_housenumber_point
WHERE 1=1
AND zoom_level >= 14
AND geometry && bbox
) t
WHERE rn = 1;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,22 @@
layer:
id: "housenumber"
description: |
Everything in OpenStreetMap which contains a `addr:housenumber` tag useful for labelling housenumbers on a map.
This adds significant size to *z14*. For buildings the centroid of the building is used as housenumber.
Duplicates within a tile are dropped if they have the same street/block_number (records without name tag are prioritized for preservation).
buffer_size: 8
srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
fields:
housenumber: Value of the [`addr:housenumber`](http://wiki.openstreetmap.org/wiki/Key:addr) tag.
If there are multiple values separated by semi-colons, the first and last value separated by a dash.
datasource:
geometry_field: geometry
srid: 900913
query: (SELECT geometry, housenumber FROM layer_housenumber(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./housenumber_display.sql
- ./housenumber_centroid.sql
- ./housenumber.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

View file

@ -0,0 +1,102 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_housenumber_point;
DROP TRIGGER IF EXISTS trigger_store ON osm_housenumber_point;
DROP TRIGGER IF EXISTS trigger_refresh ON housenumber.updates;
CREATE SCHEMA IF NOT EXISTS housenumber;
CREATE TABLE IF NOT EXISTS housenumber.osm_ids
(
osm_id bigint PRIMARY KEY
);
-- etldoc: osm_housenumber_point -> osm_housenumber_point
CREATE OR REPLACE FUNCTION convert_housenumber_point(full_update boolean) RETURNS void AS
$$
UPDATE osm_housenumber_point
SET geometry =
CASE
WHEN ST_NPoints(ST_ConvexHull(geometry)) = ST_NPoints(geometry)
THEN ST_Centroid(geometry)
ELSE ST_PointOnSurface(geometry)
END
WHERE (full_update OR osm_id IN (SELECT osm_id FROM housenumber.osm_ids))
AND ST_GeometryType(geometry) <> 'ST_Point'
AND ST_IsValid(geometry);
-- we don't need exact name just to know if it's present
UPDATE osm_housenumber_point
SET has_name =
CASE
WHEN has_name = '' THEN '0'
ELSE '1'
END
WHERE (full_update OR osm_id IN (SELECT osm_id FROM housenumber.osm_ids));
$$ LANGUAGE SQL;
SELECT convert_housenumber_point(true);
-- Handle updates
CREATE OR REPLACE FUNCTION housenumber.store() RETURNS trigger AS
$$
BEGIN
INSERT INTO housenumber.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE IF NOT EXISTS housenumber.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION housenumber.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO housenumber.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION housenumber.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh housenumber';
-- Analyze tracking and source tables before performing update
ANALYZE housenumber.osm_ids;
ANALYZE osm_housenumber_point;
PERFORM convert_housenumber_point(false);
-- noinspection SqlWithoutWhere
DELETE FROM housenumber.osm_ids;
-- noinspection SqlWithoutWhere
DELETE FROM housenumber.updates;
RAISE LOG 'Refresh housenumber done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_store
AFTER INSERT OR UPDATE
ON osm_housenumber_point
FOR EACH ROW
EXECUTE PROCEDURE housenumber.store();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE
ON osm_housenumber_point
FOR EACH STATEMENT
EXECUTE PROCEDURE housenumber.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON housenumber.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE housenumber.refresh();

View file

@ -0,0 +1,20 @@
CREATE OR REPLACE FUNCTION display_housenumber_nonnumeric(raw_housenumber text)
RETURNS text AS $$
-- Find the position of the semicolon in the input string
-- and extract the first and last value
SELECT substring(raw_housenumber from 1 for position(';' in raw_housenumber) - 1)
|| ''
|| substring(raw_housenumber from position(';' in raw_housenumber) + 1);
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION display_housenumber(raw_housenumber text)
RETURNS text AS $$
SELECT CASE
WHEN raw_housenumber !~ ';' THEN raw_housenumber
WHEN raw_housenumber ~ '[^0-9;]' THEN display_housenumber_nonnumeric(raw_housenumber)
ELSE
(SELECT min(value)::text || '' || max(value)::text
FROM unnest(array_remove(string_to_array(raw_housenumber, ';'), '')::bigint[]) AS value)
END
$$ LANGUAGE SQL IMMUTABLE;

View file

@ -0,0 +1,30 @@
tables:
# etldoc: imposm3 -> osm_housenumber_point
housenumber_point:
type: geometry
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: housenumber
key: addr:housenumber
type: string
- name: street
key: addr:street
type: string
- name: block_number
key: addr:block_number
type: string
- name: has_name
key: name
type: string
type_mappings:
points:
addr:housenumber:
- __any__
polygons:
addr:housenumber:
- __any__

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,40 @@
{
"layers": [
{
"id": "housenumber",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "housenumber",
"minzoom": 17,
"layout": {
"text-font": [
"Noto Sans Regular"
],
"text-size": {
"stops": [
[
17,
9
],
[
22,
11
]
]
},
"text-field": "{housenumber}",
"text-padding": 3,
"text-line-height": -0.15,
"symbol-avoid-edges": false,
"text-allow-overlap": false,
"text-ignore-placement": false
},
"paint": {
"text-color": "rgba(102, 102, 102, 1)",
"text-halo-color": "rgba(255,255,255,0.8)",
"text-halo-width": 1
},
"order": 154
}
]
}

View file

@ -1,6 +0,0 @@
CREATE OR REPLACE FUNCTION layer_kct(bbox geometry, zoom_level int)
RETURNS TABLE(geometry geometry, name text, waycolor text) AS $$
SELECT geometry, NULLIF(name, '') AS name, SPLIT_PART(osmc_symbol, ':', 1) as waycolor
FROM osm_kct_relation
WHERE geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;

View file

@ -1,22 +0,0 @@
tables:
# etldoc: imposm3 -> osm_kct_relation
kct_relation:
columns:
- name: geometry
type: geometry
- key: name
name: name
type: string
- key: osmc:symbol
name: osmc_symbol
type: string
mapping:
kct_blue:
- major
kct_green:
- major
kct_red:
- major
kct_yellow:
- major
type: relation_member

View file

@ -0,0 +1,10 @@
## landcover
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#landcover**
### Mapping Diagram
![Mapping diagram for landcover](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for landcover](etl_diagram.png?raw=true)

Binary file not shown.

After

Width:  |  Height:  |  Size: 415 KiB

View file

@ -0,0 +1,287 @@
DROP TABLE IF EXISTS osm_landcover_gen_z7;
DROP TABLE IF EXISTS osm_landcover_gen_z8;
DROP TABLE IF EXISTS osm_landcover_gen_z9;
DROP TABLE IF EXISTS osm_landcover_gen_z10;
DROP TABLE IF EXISTS osm_landcover_gen_z11;
DROP TABLE IF EXISTS osm_landcover_gen_z12;
DROP TABLE IF EXISTS osm_landcover_gen_z13;
DROP TABLE IF EXISTS simplify_vw_z7 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z8 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z9 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z10 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z11 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z12 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z13 CASCADE;
-- etldoc: osm_landcover_polygon -> simplify_vw_z13
CREATE TABLE simplify_vw_z13 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(13),2)),
0.001)) AS geometry
FROM osm_landcover_polygon
WHERE ST_Area(geometry) > power(zres(12),2)
);
CREATE INDEX ON simplify_vw_z13 USING GIST (geometry);
-- etldoc: simplify_vw_z13 -> osm_landcover_gen_z13
CREATE TABLE osm_landcover_gen_z13 AS
(
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z13
WHERE ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z13
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z13 USING GIST (geometry);
-- etldoc: simplify_vw_z13 -> simplify_vw_z12
CREATE TABLE simplify_vw_z12 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(12),2)),
0.001)) AS geometry
FROM simplify_vw_z13
WHERE ST_Area(geometry) > power(zres(11),2)
);
CREATE INDEX ON simplify_vw_z12 USING GIST (geometry);
-- etldoc: simplify_vw_z12 -> osm_landcover_gen_z12
CREATE TABLE osm_landcover_gen_z12 AS
(
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z12
WHERE ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z12
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z12 USING GIST (geometry);
-- etldoc: simplify_vw_z12 -> simplify_vw_z11
CREATE TABLE simplify_vw_z11 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(11),2)),
0.001)) AS geometry
FROM simplify_vw_z12
WHERE ST_Area(geometry) > power(zres(10),2)
);
CREATE INDEX ON simplify_vw_z11 USING GIST (geometry);
-- etldoc: simplify_vw_z11 -> osm_landcover_gen_z11
CREATE TABLE osm_landcover_gen_z11 AS
(
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z11
WHERE ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z11
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z11 USING GIST (geometry);
-- etldoc: simplify_vw_z11 -> simplify_vw_z10
CREATE TABLE simplify_vw_z10 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(10),2)),
0.001)) AS geometry
FROM simplify_vw_z11
WHERE ST_Area(geometry) > power(zres(9),2)
);
CREATE INDEX ON simplify_vw_z10 USING GIST (geometry);
-- etldoc: simplify_vw_z10 -> osm_landcover_gen_z10
CREATE TABLE osm_landcover_gen_z10 AS
(
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z10
WHERE ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z10
WHERE (ST_NPoints(geometry) >= 300 AND subclass IN ('wood', 'forest'))
OR (subclass NOT IN ('wood', 'forest'))
);
CREATE INDEX ON osm_landcover_gen_z10 USING GIST (geometry);
-- etldoc: simplify_vw_z10 -> simplify_vw_z9
CREATE TABLE simplify_vw_z9 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(9),2)),
0.001)) AS geometry
FROM simplify_vw_z10
WHERE ST_Area(geometry) > power(zres(8),2)
);
CREATE INDEX ON simplify_vw_z9 USING GIST (geometry);
-- etldoc: simplify_vw_z9 -> osm_landcover_gen_z9
CREATE TABLE osm_landcover_gen_z9 AS
(
SELECT subclass, ST_MakeValid((ST_dump(ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) < 300
AND subclass IN ('wood', 'forest')) union_geom300
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM (
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) over () AS cid, geometry
FROM simplify_vw_z9
WHERE ST_NPoints(geometry) >= 300
AND subclass IN ('wood', 'forest')) union_geom_rest
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z9
WHERE subclass NOT IN ('wood', 'forest')
);
CREATE INDEX ON osm_landcover_gen_z9 USING GIST (geometry);
-- etldoc: simplify_vw_z9 -> simplify_vw_z8
CREATE TABLE simplify_vw_z8 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(8),2)),
0.001)) AS geometry
FROM simplify_vw_z9
WHERE ST_Area(geometry) > power(zres(7),2)
);
CREATE INDEX ON simplify_vw_z8 USING GIST (geometry);
-- etldoc: simplify_vw_z8 -> osm_landcover_gen_z8
CREATE TABLE osm_landcover_gen_z8 AS
(
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM
(
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) OVER () AS cid,
geometry
FROM simplify_vw_z8
WHERE subclass IN ('wood', 'forest')
) union_geom
GROUP BY subclass,
cid
UNION ALL
SELECT subclass,
geometry
FROM simplify_vw_z8
WHERE subclass NOT IN ('wood', 'forest')
);
CREATE INDEX ON osm_landcover_gen_z8 USING GIST (geometry);
-- etldoc: simplify_vw_z8 -> simplify_vw_z7
CREATE TABLE simplify_vw_z7 AS
(
SELECT subclass,
ST_MakeValid(
ST_SnapToGrid(
ST_SimplifyVW(geometry, power(zres(7),2)),
0.001)) AS geometry
FROM simplify_vw_z8
WHERE ST_Area(geometry) > power(zres(6),2)
);
CREATE INDEX ON simplify_vw_z7 USING GIST (geometry);
-- etldoc: simplify_vw_z7 -> osm_landcover_gen_z7
CREATE TABLE osm_landcover_gen_z7 AS
(
SELECT subclass,
ST_MakeValid(
(ST_Dump(
ST_Union(geometry))).geom) AS geometry
FROM
(
SELECT subclass,
ST_ClusterDBSCAN(geometry, eps := 0, minpoints := 1) OVER () AS cid,
geometry
FROM simplify_vw_z7
) union_geom
GROUP BY subclass,
cid
);
CREATE INDEX ON osm_landcover_gen_z7 USING GIST (geometry);
DROP TABLE IF EXISTS simplify_vw_z7 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z8 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z9 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z10 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z11 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z12 CASCADE;
DROP TABLE IF EXISTS simplify_vw_z13 CASCADE;

View file

@ -0,0 +1,373 @@
--TODO: Find a way to nicely generalize landcover
--CREATE TABLE IF NOT EXISTS landcover_grouped_gen2 AS (
-- SELECT osm_id, ST_Simplify((ST_Dump(geometry)).geom, 600) AS geometry, landuse, "natural", wetland
-- FROM (
-- SELECT max(osm_id) AS osm_id, ST_Union(ST_Buffer(geometry, 600)) AS geometry, landuse, "natural", wetland
-- FROM osm_landcover_polygon_gen1
-- GROUP BY LabelGrid(geometry, 15000000), landuse, "natural", wetland
-- ) AS grouped_measurements
--);
--CREATE INDEX IF NOT EXISTS landcover_grouped_gen2_geometry_idx ON landcover_grouped_gen2 USING gist(geometry);
CREATE OR REPLACE FUNCTION landcover_class(subclass varchar) RETURNS text AS
$$
SELECT CASE
%%FIELD_MAPPING: class %%
END;
$$ LANGUAGE SQL IMMUTABLE
-- STRICT
PARALLEL SAFE;
-- ne_50m_antarctic_ice_shelves_polys
-- etldoc: ne_50m_antarctic_ice_shelves_polys -> ne_50m_antarctic_ice_shelves_polys_gen_z4
DROP MATERIALIZED VIEW IF EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_antarctic_ice_shelves_polys_gen_z4 AS
(
SELECT
ST_Simplify(geometry, ZRes(6)) as geometry,
'ice_shelf'::text AS subclass
FROM ne_50m_antarctic_ice_shelves_polys
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z4_idx ON ne_50m_antarctic_ice_shelves_polys_gen_z4 USING gist (geometry);
-- ne_110m_glaciated_areas
-- etldoc: ne_110m_glaciated_areas -> ne_110m_glaciated_areas_gen_z1
DROP MATERIALIZED VIEW IF EXISTS ne_110m_glaciated_areas_gen_z1 CASCADE;
CREATE MATERIALIZED VIEW ne_110m_glaciated_areas_gen_z1 AS
(
SELECT
ST_Simplify(geometry, ZRes(3)) as geometry,
'glacier'::text AS subclass
FROM ne_110m_glaciated_areas
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_110m_glaciated_areas_gen_z1_idx ON ne_110m_glaciated_areas_gen_z1 USING gist (geometry);
-- etldoc: ne_110m_glaciated_areas_gen_z1 -> ne_110m_glaciated_areas_gen_z0
DROP MATERIALIZED VIEW IF EXISTS ne_110m_glaciated_areas_gen_z0 CASCADE;
CREATE MATERIALIZED VIEW ne_110m_glaciated_areas_gen_z0 AS
(
SELECT
ST_Simplify(geometry, ZRes(2)) as geometry,
subclass
FROM ne_110m_glaciated_areas_gen_z1
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_110m_glaciated_areas_gen_z0_idx ON ne_110m_glaciated_areas_gen_z0 USING gist (geometry);
-- etldoc: ne_50m_antarctic_ice_shelves_polys_gen_z4 -> ne_50m_antarctic_ice_shelves_polys_gen_z3
DROP MATERIALIZED VIEW IF EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z3 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_antarctic_ice_shelves_polys_gen_z3 AS
(
SELECT
ST_Simplify(geometry, ZRes(5)) as geometry,
subclass
FROM ne_50m_antarctic_ice_shelves_polys_gen_z4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z3_idx ON ne_50m_antarctic_ice_shelves_polys_gen_z3 USING gist (geometry);
-- etldoc: ne_50m_antarctic_ice_shelves_polys_gen_z3 -> ne_50m_antarctic_ice_shelves_polys_gen_z2
DROP MATERIALIZED VIEW IF EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z2 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_antarctic_ice_shelves_polys_gen_z2 AS
(
SELECT
ST_Simplify(geometry, ZRes(4)) as geometry,
subclass
FROM ne_50m_antarctic_ice_shelves_polys_gen_z3
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_antarctic_ice_shelves_polys_gen_z2_idx ON ne_50m_antarctic_ice_shelves_polys_gen_z2 USING gist (geometry);
-- ne_50m_glaciated_areas
-- etldoc: ne_50m_glaciated_areas -> ne_50m_glaciated_areas_gen_z4
DROP MATERIALIZED VIEW IF EXISTS ne_50m_glaciated_areas_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_glaciated_areas_gen_z4 AS
(
SELECT
ST_Simplify(geometry, ZRes(6)) as geometry,
'glacier'::text AS subclass
FROM ne_50m_glaciated_areas
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_glaciated_areas_gen_z4_idx ON ne_50m_glaciated_areas_gen_z4 USING gist (geometry);
-- etldoc: ne_50m_glaciated_areas_gen_z4 -> ne_50m_glaciated_areas_gen_z3
DROP MATERIALIZED VIEW IF EXISTS ne_50m_glaciated_areas_gen_z3 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_glaciated_areas_gen_z3 AS
(
SELECT
ST_Simplify(geometry, ZRes(5)) as geometry,
subclass
FROM ne_50m_glaciated_areas_gen_z4
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_glaciated_areas_gen_z3_idx ON ne_50m_glaciated_areas_gen_z3 USING gist (geometry);
-- etldoc: ne_50m_glaciated_areas_gen_z3 -> ne_50m_glaciated_areas_gen_z2
DROP MATERIALIZED VIEW IF EXISTS ne_50m_glaciated_areas_gen_z2 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_glaciated_areas_gen_z2 AS
(
SELECT
ST_Simplify(geometry, ZRes(4)) as geometry,
subclass
FROM ne_50m_glaciated_areas_gen_z3
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_glaciated_areas_gen_z2_idx ON ne_50m_glaciated_areas_gen_z2 USING gist (geometry);
-- ne_10m_glaciated_areas
-- etldoc: ne_10m_glaciated_areas -> ne_10m_glaciated_areas_gen_z6
DROP MATERIALIZED VIEW IF EXISTS ne_10m_glaciated_areas_gen_z6 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_glaciated_areas_gen_z6 AS
(
SELECT
ST_Simplify(geometry, ZRes(8)) as geometry,
'glacier'::text AS subclass
FROM ne_10m_glaciated_areas
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_glaciated_areas_gen_z6_idx ON ne_10m_glaciated_areas_gen_z6 USING gist (geometry);
-- etldoc: ne_10m_glaciated_areas_gen_z6 -> ne_10m_glaciated_areas_gen_z5
DROP MATERIALIZED VIEW IF EXISTS ne_10m_glaciated_areas_gen_z5 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_glaciated_areas_gen_z5 AS
(
SELECT
ST_Simplify(geometry, ZRes(7)) as geometry,
subclass
FROM ne_10m_glaciated_areas_gen_z6
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_glaciated_areas_gen_z5_idx ON ne_10m_glaciated_areas_gen_z5 USING gist (geometry);
-- ne_10m_antarctic_ice_shelves_polys
-- etldoc: ne_10m_antarctic_ice_shelves_polys -> ne_10m_antarctic_ice_shelves_polys_gen_z6
DROP MATERIALIZED VIEW IF EXISTS ne_10m_antarctic_ice_shelves_polys_gen_z6 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_antarctic_ice_shelves_polys_gen_z6 AS
(
SELECT
ST_Simplify(geometry, ZRes(8)) as geometry,
'ice_shelf'::text AS subclass
FROM ne_10m_antarctic_ice_shelves_polys
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_antarctic_ice_shelves_polys_gen_z6_idx ON ne_10m_antarctic_ice_shelves_polys_gen_z6 USING gist (geometry);
-- etldoc: ne_10m_antarctic_ice_shelves_polys_gen_z6 -> ne_10m_antarctic_ice_shelves_polys_gen_z5
DROP MATERIALIZED VIEW IF EXISTS ne_10m_antarctic_ice_shelves_polys_gen_z5 CASCADE;
CREATE MATERIALIZED VIEW ne_10m_antarctic_ice_shelves_polys_gen_z5 AS
(
SELECT
ST_Simplify(geometry, ZRes(7)) as geometry,
subclass
FROM ne_10m_antarctic_ice_shelves_polys_gen_z6
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_10m_antarctic_ice_shelves_polys_gen_z5_idx ON ne_10m_antarctic_ice_shelves_polys_gen_z5 USING gist (geometry);
-- etldoc: ne_110m_glaciated_areas_gen_z0 -> landcover_z0
CREATE OR REPLACE VIEW landcover_z0 AS
(
SELECT
geometry,
subclass
FROM ne_110m_glaciated_areas_gen_z0
);
-- etldoc: ne_110m_glaciated_areas_gen_z1 -> landcover_z1
CREATE OR REPLACE VIEW landcover_z1 AS
(
SELECT
geometry,
subclass
FROM ne_110m_glaciated_areas_gen_z1
);
CREATE OR REPLACE VIEW landcover_z2 AS
(
-- etldoc: ne_50m_glaciated_areas_gen_z2 -> landcover_z2
SELECT
geometry,
subclass
FROM ne_50m_glaciated_areas_gen_z2
UNION ALL
-- etldoc: ne_50m_antarctic_ice_shelves_polys_gen_z2 -> landcover_z2
SELECT
geometry,
subclass
FROM ne_50m_antarctic_ice_shelves_polys_gen_z2
);
CREATE OR REPLACE VIEW landcover_z3 AS
(
-- etldoc: ne_50m_glaciated_areas_gen_z3 -> landcover_z3
SELECT
geometry,
subclass
FROM ne_50m_glaciated_areas_gen_z3
UNION ALL
-- etldoc: ne_50m_antarctic_ice_shelves_polys_gen_z3 -> landcover_z3
SELECT
geometry,
subclass
FROM ne_50m_antarctic_ice_shelves_polys_gen_z3
);
CREATE OR REPLACE VIEW landcover_z4 AS
(
-- etldoc: ne_50m_glaciated_areas_gen_z4 -> landcover_z4
SELECT
geometry,
subclass
FROM ne_50m_glaciated_areas_gen_z4
UNION ALL
-- etldoc: ne_50m_antarctic_ice_shelves_polys_gen_z4 -> landcover_z4
SELECT
geometry,
subclass
FROM ne_50m_antarctic_ice_shelves_polys_gen_z4
);
CREATE OR REPLACE VIEW landcover_z5 AS
(
-- etldoc: ne_10m_glaciated_areas_gen_z5 -> landcover_z5
SELECT
geometry,
subclass
FROM ne_10m_glaciated_areas_gen_z5
UNION ALL
-- etldoc: ne_10m_antarctic_ice_shelves_polys_gen_z5 -> landcover_z5
SELECT
geometry,
subclass
FROM ne_10m_antarctic_ice_shelves_polys_gen_z5
);
CREATE OR REPLACE VIEW landcover_z6 AS
(
-- etldoc: ne_10m_glaciated_areas_gen_z6 -> landcover_z6
SELECT
geometry,
subclass
FROM ne_10m_glaciated_areas_gen_z6
UNION ALL
-- etldoc: ne_10m_antarctic_ice_shelves_polys_gen_z6 -> landcover_z6
SELECT
geometry,
subclass
FROM ne_10m_antarctic_ice_shelves_polys_gen_z6
);
-- etldoc: layer_landcover[shape=record fillcolor=lightpink, style="rounded, filled", label="layer_landcover | <z0> z0 | <z1> z1 | <z2> z2 | <z3> z3 | <z4> z4 | <z5> z5 | <z6> z6 |<z7> z7 |<z8> z8 |<z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13|<z14_> z14+" ] ;
CREATE OR REPLACE FUNCTION layer_landcover(bbox geometry, zoom_level int)
RETURNS TABLE
(
geometry geometry,
class text,
subclass text
)
AS
$$
SELECT geometry,
landcover_class(subclass) AS class,
subclass
FROM (
-- etldoc: landcover_z0 -> layer_landcover:z0
SELECT geometry,
subclass
FROM landcover_z0
WHERE zoom_level = 0
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z1 -> layer_landcover:z1
SELECT geometry,
subclass
FROM landcover_z1
WHERE zoom_level = 1
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z2 -> layer_landcover:z2
SELECT geometry,
subclass
FROM landcover_z2
WHERE zoom_level = 2
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z3 -> layer_landcover:z3
SELECT geometry,
subclass
FROM landcover_z3
WHERE zoom_level = 3
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z4 -> layer_landcover:z4
SELECT geometry,
subclass
FROM landcover_z4
WHERE zoom_level = 4
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z5 -> layer_landcover:z5
SELECT geometry,
subclass
FROM landcover_z5
WHERE zoom_level = 5
AND geometry && bbox
UNION ALL
-- etldoc: landcover_z6 -> layer_landcover:z6
SELECT geometry,
subclass
FROM landcover_z6
WHERE zoom_level = 6
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z7 -> layer_landcover:z7
SELECT geometry,
subclass
FROM osm_landcover_gen_z7
WHERE zoom_level = 7
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z8 -> layer_landcover:z8
SELECT geometry,
subclass
FROM osm_landcover_gen_z8
WHERE zoom_level = 8
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z9 -> layer_landcover:z9
SELECT geometry,
subclass
FROM osm_landcover_gen_z9
WHERE zoom_level = 9
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z10 -> layer_landcover:z10
SELECT geometry,
subclass
FROM osm_landcover_gen_z10
WHERE zoom_level = 10
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z11 -> layer_landcover:z11
SELECT geometry,
subclass
FROM osm_landcover_gen_z11
WHERE zoom_level = 11
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z12 -> layer_landcover:z12
SELECT geometry,
subclass
FROM osm_landcover_gen_z12
WHERE zoom_level = 12
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_gen_z13 -> layer_landcover:z13
SELECT geometry,
subclass
FROM osm_landcover_gen_z13
WHERE zoom_level = 13
AND geometry && bbox
UNION ALL
-- etldoc: osm_landcover_polygon -> layer_landcover:z14_
SELECT geometry,
subclass
FROM osm_landcover_polygon
WHERE zoom_level >= 14
AND geometry && bbox
) AS zoom_levels;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,89 @@
layer:
id: "landcover"
requires:
tables:
- ne_10m_antarctic_ice_shelves_polys
- ne_10m_glaciated_areas
- ne_50m_antarctic_ice_shelves_polys
- ne_50m_glaciated_areas
- ne_110m_glaciated_areas
description: |
Landcover is used to describe the physical material at the surface of the earth. At lower zoom levels this is
from Natural Earth data for glaciers and ice shelves and at higher zoom levels the landcover is [implied by OSM tags](http://wiki.openstreetmap.org/wiki/Landcover). The most common use case for this layer
is to style wood (`class=wood`) and grass (`class=grass`) areas.
buffer_size: 4
fields:
class:
description: |
Use the **class** to assign natural colors for **landcover**.
values:
farmland:
subclass: ['farmland', 'farm', 'orchard', 'vineyard', 'plant_nursery']
ice:
subclass: ['glacier', 'ice_shelf']
wood:
subclass: ['wood', 'forest']
rock:
subclass: ['bare_rock', 'scree']
grass:
subclass: ['fell', 'flowerbed', 'grassland', 'heath', 'scrub', 'shrubbery', 'tundra', 'grass', 'meadow', 'allotments', 'park', 'village_green', 'recreation_ground', 'garden', 'golf_course']
wetland:
subclass: ['wetland', 'bog', 'swamp', 'wet_meadow', 'marsh', 'reedbed', 'saltern', 'tidalflat', 'saltmarsh', 'mangrove']
sand:
subclass: ['beach', 'sand', 'dune']
subclass:
description: |
Use **subclass** to do more precise styling.
Original value of either the
[`natural`](http://wiki.openstreetmap.org/wiki/Key:natural),
[`landuse`](http://wiki.openstreetmap.org/wiki/Key:landuse),
[`leisure`](http://wiki.openstreetmap.org/wiki/Key:leisure),
or [`wetland`](http://wiki.openstreetmap.org/wiki/Key:wetland) tag.
values:
- allotments
- bare_rock
- beach
- bog
- dune
- scrub
- shrubbery
- farm
- farmland
- fell
- flowerbed
- forest
- garden
- glacier
- grass
- grassland
- golf_course
- heath
- mangrove
- marsh
- meadow
- orchard
- park
- plant_nursery
- recreation_ground
- reedbed
- saltern
- saltmarsh
- sand
- scree
- swamp
- tidalflat
- tundra
- village_green
- vineyard
- wet_meadow
- wetland
- wood
datasource:
geometry_field: geometry
query: (SELECT geometry, class, subclass FROM layer_landcover(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./generalized.sql
- ./landcover.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

View file

@ -0,0 +1,59 @@
tables:
# etldoc: imposm3 -> osm_landcover_polygon
landcover_polygon:
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: area
type: area
- name: subclass
type: mapping_value
- name: mapping_key
type: mapping_key
mapping:
landuse:
- allotments
- farm
- farmland
- orchard
- flowerbed
- plant_nursery
- vineyard
- grass
- grassland
- meadow
- forest
- village_green
- recreation_ground
natural:
- wood
- wetland
- fell
- grassland
- heath
- scrub
- shrubbery
- tundra
- glacier
- bare_rock
- scree
- beach
- sand
- dune
leisure:
- park
- garden
- golf_course
wetland:
- bog
- swamp
- wet_meadow
- marsh
- reedbed
- saltern
- tidalflat
- saltmarsh
- mangrove
type: polygon

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

482
layers/landcover/style.json Normal file
View file

@ -0,0 +1,482 @@
{
"layers": [
{
"id": "landcover_classes",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landcover",
"maxzoom": 13,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": [
"match",
[
"get",
"class"
],
"farmland",
"#eef0d5",
"wood",
"#add19e",
"rock",
"#eee5dc",
"grass",
"#cdebb0",
"sand",
"#f5e9c6",
"wetland",
"#add19e",
"#000"
],
"fill-opacity": {
"stops": [
[
7,
0.5
],
[
10,
1
]
]
},
"fill-antialias": false
},
"metadata": {},
"filter": [
"all",
[
"in",
"class",
"farmland",
"wood",
"rock",
"grass",
"wetland",
"sand"
]
],
"order": 4
},
{
"id": "landcover_class_outline",
"type": "line",
"source": "openmaptiles",
"source-layer": "landcover",
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": "#c7c9ae",
"line-width": 0.5
},
"filter": [
"all",
[
"in",
"class",
"farmland"
]
],
"order": 5
},
{
"id": "landcover_park",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 13,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": "#c8facc",
"fill-antialias": true
},
"filter": [
"all",
[
"==",
"subclass",
"park"
]
],
"order": 6
},
{
"id": "landcover_subclasses",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 13,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": [
"match",
[
"get",
"subclass"
],
"allotments",
"#c9e1bf",
"bare_rock",
"#eee5dc",
"beach",
"#fff1ba",
"bog",
"#d6d99f",
"dune",
"#f5e9c6",
"scrub",
"#c8d7ab",
"farm",
"#f5dcba",
"farmland",
"#eef0d5",
"flowerbed",
"#cdebb0",
"forest",
"#add19e",
"grass",
"#cdebb0",
"grassland",
"#cdebb0",
"golf_course",
"#def6c0",
"heath",
"#d6d99f",
"mangrove",
"#c8d7ab",
"meadow",
"#cdebb0",
"orchard",
"#aedfa3",
"park",
"#c8facc",
"garden",
"#cdebb0",
"plant_nursery",
"#aedfa3",
"recreation_ground",
"#d5ffd9",
"reedbed",
"#cdebb0",
"saltmarsh",
"#cdebb0",
"sand",
"#f5e9c6",
"scree",
"#eee5dc",
"swamp",
"#add19e",
"tidalflat",
"#DED6CF",
"village_green",
"#cdebb0",
"vineyard",
"#aedfa3",
"wet_meadow",
"#cdebb0",
"wetland",
"#add19e",
"wood",
"#add19e",
"marsh",
"#ff0",
"#FFFFFF"
],
"fill-antialias": true
},
"filter": [
"all",
[
"in",
"subclass",
"allotments",
"bare_rock",
"beach",
"dune",
"scrub",
"farm",
"farmland",
"flowerbed",
"forest",
"garden",
"grass",
"grassland",
"golf_course",
"heath",
"meadow",
"orchard",
"plant_nursery",
"recreation_ground",
"reedbed",
"saltmarsh",
"sand",
"scree",
"swamp",
"tidalflat",
"tundra",
"village_green",
"vineyard",
"wet_meadow",
"wetland",
"wood"
]
],
"order": 7
},
{
"id": "landcover_subclass_patterns",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 13,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-opacity": [
"match",
[
"get",
"subclass"
],
"beach",
0.4,
"forest",
0.4,
"bare_rock",
0.3,
"scrub",
0.6,
"garden",
0.6,
"scree",
0.3,
"wood",
0.4,
1
],
"fill-pattern": [
"match",
[
"get",
"subclass"
],
"allotments",
"allotments",
"bare_rock",
"rock_overlay",
"beach",
"beach",
"bog",
"wetland_bog",
"scrub",
"scrub",
"flowerbed",
"flowerbed_high_zoom",
"forest",
"leaftype_unknown",
"garden",
"plant_nursery",
"mangrove",
"wetland_mangrove",
"marsh",
"wetland_marsh",
"orchard",
"orchard",
"plant_nursery",
"plant_nursery",
"reedbed",
"wetland_reed",
"saltmarsh",
"wetland_marsh",
"scree",
"scree_overlay",
"swamp",
"wetland_swamp",
"vineyard",
"vineyard",
"wet_meadow",
"wetland_marsh",
"wetland",
"wetland",
"wood",
"leaftype_unknown",
""
]
},
"metadata": {},
"filter": [
"all",
[
"in",
"subclass",
"allotments",
"bare_rock",
"beach",
"bog",
"dune",
"scrub",
"farm",
"farmland",
"flowerbed",
"forest",
"garden",
"grass",
"grassland",
"golf_course",
"heath",
"mangrove",
"marsh",
"meadow",
"orchard",
"park",
"plant_nursery",
"recreation_ground",
"reedbed",
"saltern",
"saltmarsh",
"sand",
"scree",
"swamp",
"village_green",
"vineyard",
"wet_meadow",
"wetland",
"wood"
]
],
"order": 8
},
{
"id": "landcover_subclass_outline",
"type": "line",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 15,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": [
"match",
[
"get",
"subclass"
],
"allotments",
"#B1C6A8",
"farm",
"#d1b48c",
"farmland",
"#c7c9ae",
"recreation_ground",
"#3c6640",
"#000"
],
"line-width": [
"match",
[
"get",
"subclass"
],
"recreation_ground",
0.3,
0.5
],
"line-opacity": 1
},
"filter": [
"all",
[
"in",
"subclass",
"allotments",
"farm",
"farmland",
"recreation_ground"
]
],
"order": 9
},
{
"id": "landcover_ice",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 5,
"paint": {
"fill-color": "#ddecec",
"fill-antialias": false
},
"metadata": {},
"filter": [
"all",
[
"in",
"class",
"ice"
]
],
"order": 10
},
{
"id": "landcover_ice_outline",
"type": "line",
"source": "openmaptiles",
"source-layer": "landcover",
"minzoom": 5,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": "#9cf",
"line-width": {
"stops": [
[
5,
1
],
[
10,
1.5
]
]
},
"line-dasharray": {
"stops": [
[
5,
[
1,
0
]
],
[
10,
[
4,
2
]
]
]
}
},
"filter": [
"all",
[
"in",
"class",
"ice"
]
],
"order": 11
}
]
}

10
layers/landuse/README.md Normal file
View file

@ -0,0 +1,10 @@
## landuse
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#landuse**
### Mapping Diagram
![Mapping diagram for landuse](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for landuse](etl_diagram.png?raw=true)

10
layers/landuse/class.sql Normal file
View file

@ -0,0 +1,10 @@
-- Unify class names that represent the same type of feature
CREATE OR REPLACE FUNCTION landuse_unify(class text) RETURNS text LANGUAGE plpgsql
AS
$$
BEGIN
RETURN CASE
WHEN class='grave_yard' THEN 'cemetery'
ELSE class END;
END;
$$;

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 KiB

379
layers/landuse/landuse.sql Normal file
View file

@ -0,0 +1,379 @@
-- ne_50m_urban_areas
-- etldoc: ne_50m_urban_areas -> ne_50m_urban_areas_gen_z5
DROP MATERIALIZED VIEW IF EXISTS ne_50m_urban_areas_gen_z5 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_urban_areas_gen_z5 AS
(
SELECT
NULL::bigint AS osm_id,
ST_Simplify(geometry, ZRes(7)) as geometry,
'residential'::text AS landuse,
NULL::text AS amenity,
NULL::text AS leisure,
NULL::text AS tourism,
NULL::text AS place,
NULL::text AS waterway,
scalerank
FROM ne_50m_urban_areas
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_urban_areas_gen_z5_idx ON ne_50m_urban_areas_gen_z5 USING gist (geometry);
-- etldoc: ne_50m_urban_areas_gen_z5 -> ne_50m_urban_areas_gen_z4
DROP MATERIALIZED VIEW IF EXISTS ne_50m_urban_areas_gen_z4 CASCADE;
CREATE MATERIALIZED VIEW ne_50m_urban_areas_gen_z4 AS
(
SELECT
osm_id,
ST_Simplify(geometry, ZRes(6)) as geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM ne_50m_urban_areas_gen_z5
WHERE scalerank <= 2
) /* DELAY_MATERIALIZED_VIEW_CREATION */ ;
CREATE INDEX IF NOT EXISTS ne_50m_urban_areas_gen_z4_idx ON ne_50m_urban_areas_gen_z4 USING gist (geometry);
-- etldoc: osm_landuse_polygon_gen_z6 -> osm_landuse_polygon_gen_z6_union
-- etldoc: osm_residential_gen_z6 -> osm_landuse_polygon_gen_z6_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z6_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z6
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z6
);
-- etldoc: osm_landuse_polygon_gen_z7 -> osm_landuse_polygon_gen_z7_union
-- etldoc: osm_residential_gen_z7 -> osm_landuse_polygon_gen_z7_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z7_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z7
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z7
);
-- etldoc: osm_landuse_polygon_gen_z8 -> osm_landuse_polygon_gen_z8_union
-- etldoc: osm_residential_gen_z8 -> osm_landuse_polygon_gen_z8_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z8_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z8
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z8
);
-- etldoc: osm_landuse_polygon_gen_z9 -> osm_landuse_polygon_gen_z9_union
-- etldoc: osm_residential_gen_z9 -> osm_landuse_polygon_gen_z9_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z9_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z9
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z9
);
-- etldoc: osm_landuse_polygon_gen_z10 -> osm_landuse_polygon_gen_z10_union
-- etldoc: osm_residential_gen_z10 -> osm_landuse_polygon_gen_z10_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z10_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z10
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z10
);
-- etldoc: osm_landuse_polygon_gen_z11 -> osm_landuse_polygon_gen_z11_union
-- etldoc: osm_residential_gen_z11 -> osm_landuse_polygon_gen_z11_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z11_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z11
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z11
);
-- etldoc: osm_landuse_polygon_gen_z12 -> osm_landuse_polygon_gen_z12_union
-- etldoc: osm_residential_gen_z12 -> osm_landuse_polygon_gen_z12_union
CREATE OR REPLACE VIEW osm_landuse_polygon_gen_z12_union AS
(
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z12
WHERE landuse <> 'residential'
UNION ALL
SELECT NULL::bigint AS osm_id,
geometry,
'residential' AS landuse,
'' AS amenity,
'' AS leisure,
'' AS tourism,
'' AS place,
'' AS waterway
FROM osm_residential_gen_z12
);
-- etldoc: layer_landuse[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_landuse |<z4> z4|<z5> z5|<z6> z6|<z7> z7|<z8> z8|<z9> z9|<z10> z10|<z11> z11|<z12> z12|<z13> z13|<z14> z14+" ] ;
CREATE OR REPLACE FUNCTION layer_landuse(bbox geometry, zoom_level int)
RETURNS TABLE
(
osm_id bigint,
geometry geometry,
class text
)
AS
$$
SELECT osm_id,
geometry,
landuse_unify(
COALESCE(
NULLIF(landuse, ''),
NULLIF(amenity, ''),
NULLIF(leisure, ''),
NULLIF(tourism, ''),
NULLIF(place, ''),
NULLIF(waterway, '')
)) AS class
FROM (
-- etldoc: ne_50m_urban_areas_gen_z4 -> layer_landuse:z4
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM ne_50m_urban_areas_gen_z4
WHERE zoom_level = 4
UNION ALL
-- etldoc: ne_50m_urban_areas_gen_z5 -> layer_landuse:z5
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM ne_50m_urban_areas_gen_z5
WHERE zoom_level = 5
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z6_union -> layer_landuse:z6
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z6_union
WHERE zoom_level = 6
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z7_union -> layer_landuse:z7
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z7_union
WHERE zoom_level = 7
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z8_union -> layer_landuse:z8
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z8_union
WHERE zoom_level = 8
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z9_union -> layer_landuse:z9
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z9_union
WHERE zoom_level = 9
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z10_union -> layer_landuse:z10
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z10_union
WHERE zoom_level = 10
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z11_union -> layer_landuse:z11
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z11_union
WHERE zoom_level = 11
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z12_union -> layer_landuse:z12
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z12_union
WHERE zoom_level = 12
UNION ALL
-- etldoc: osm_landuse_polygon_gen_z13 -> layer_landuse:z13
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon_gen_z13
WHERE zoom_level = 13
UNION ALL
-- etldoc: osm_landuse_polygon -> layer_landuse:z14
SELECT osm_id,
geometry,
landuse,
amenity,
leisure,
tourism,
place,
waterway
FROM osm_landuse_polygon
WHERE zoom_level >= 14
) AS zoom_levels
WHERE geometry && bbox;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

View file

@ -0,0 +1,57 @@
layer:
id: "landuse"
requires:
tables:
- ne_50m_urban_areas
description: |
Landuse is used to describe use of land by humans. At lower zoom levels this is
from Natural Earth data for residential (urban) areas and at higher zoom levels mostly OSM `landuse` tags.
buffer_size: 4
fields:
class:
description: |
Use the **class** to assign special colors to areas.
Original value of either the
[`landuse`](http://wiki.openstreetmap.org/wiki/Key:landuse),
[`amenity`](http://wiki.openstreetmap.org/wiki/Key:amenity),
[`leisure`](http://wiki.openstreetmap.org/wiki/Key:leisure),
[`tourism`](http://wiki.openstreetmap.org/wiki/Key:tourism),
[`place`](http://wiki.openstreetmap.org/wiki/Key:place)
or [`waterway`](http://wiki.openstreetmap.org/wiki/Key:waterway) tag.
values:
- railway
- cemetery
- military
- residential
- commercial
- industrial
- garages
- retail
- bus_station
- school
- university
- kindergarten
- college
- library
- hospital
- stadium
- pitch
- playground
- track
- theme_park
- zoo
- suburb
- quarter
- neighbourhood
- dam
- quarry
datasource:
geometry_field: geometry
query: (SELECT geometry, class FROM layer_landuse(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./class.sql
- ./prep_landuse.sql
- ./landuse.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

106
layers/landuse/mapping.yaml Normal file
View file

@ -0,0 +1,106 @@
generalized_tables:
# etldoc: osm_landuse_polygon_gen_z7 -> osm_landuse_polygon_gen_z6
landuse_polygon_gen_z6:
source: landuse_polygon_gen_z7
tolerance: ZRES6
sql_filter: area>power(ZRES6,2)
# etldoc: osm_landuse_polygon_gen_z8 -> osm_landuse_polygon_gen_z7
landuse_polygon_gen_z7:
source: landuse_polygon_gen_z8
tolerance: ZRES7
sql_filter: area>power(ZRES6,2)
# etldoc: osm_landuse_polygon_gen_z9 -> osm_landuse_polygon_gen_z8
landuse_polygon_gen_z8:
source: landuse_polygon_gen_z9
sql_filter: area>power(ZRES6,2) AND (landuse='residential' OR place='suburb' OR place='quarter' OR place='neighbourhood')
tolerance: ZRES8
# etldoc: osm_landuse_polygon_gen_z10 -> osm_landuse_polygon_gen_z9
landuse_polygon_gen_z9:
source: landuse_polygon_gen_z10
sql_filter: area>power(ZRES7,2)
tolerance: ZRES9
# etldoc: osm_landuse_polygon_gen_z11 -> osm_landuse_polygon_gen_z10
landuse_polygon_gen_z10:
source: landuse_polygon_gen_z11
sql_filter: area>power(ZRES8,2)
tolerance: ZRES10
# etldoc: osm_landuse_polygon_gen_z12 -> osm_landuse_polygon_gen_z11
landuse_polygon_gen_z11:
source: landuse_polygon_gen_z12
sql_filter: area>power(ZRES9,2)
tolerance: ZRES11
# etldoc: osm_landuse_polygon_gen_z13 -> osm_landuse_polygon_gen_z12
landuse_polygon_gen_z12:
source: landuse_polygon_gen_z13
sql_filter: area>power(ZRES10,2)
tolerance: ZRES12
# etldoc: osm_landuse_polygon -> osm_landuse_polygon_gen_z13
landuse_polygon_gen_z13:
source: landuse_polygon
sql_filter: area>power(ZRES11,2) AND ST_IsValid(geometry)
tolerance: ZRES13
tables:
# etldoc: imposm3 -> osm_landuse_polygon
landuse_polygon:
type: polygon
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: landuse
key: landuse
type: string
- name: amenity
key: amenity
type: string
- name: leisure
key: leisure
type: string
- name: tourism
key: tourism
type: string
- name: place
key: place
type: string
- name: waterway
key: waterway
type: string
- name: area
type: area
mapping:
landuse:
- railway
- cemetery
- military
- quarry
# zoning
- residential
- commercial
- industrial
- garages
- retail
amenity:
- bus_station
- school
- university
- kindergarten
- college
- library
- hospital
- grave_yard
leisure:
- stadium
- pitch
- playground
- track
tourism:
- theme_park
- zoo
place:
- suburb
- quarter
- neighbourhood
waterway:
- dam

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View file

@ -0,0 +1,176 @@
DROP TABLE IF EXISTS cluster_zres14;
CREATE TABLE cluster_zres14 AS
(
WITH single_geom AS (
SELECT (ST_Dump(geometry)).geom AS geometry
FROM osm_landuse_polygon
WHERE landuse='residential'
)
SELECT ST_ClusterDBSCAN(geometry, eps := zres(14), minpoints := 1) over () AS cid,
geometry
FROM single_geom
);
CREATE INDEX ON cluster_zres14 USING gist(geometry);
DROP TABLE IF EXISTS cluster_zres14_union;
CREATE TABLE cluster_zres14_union AS (
SELECT ST_Buffer(
ST_Union(
ST_Buffer(
ST_SnapToGrid(geometry, 0.01)
, zres(14), 'join=mitre'
)
),-zres(14), 'join=mitre'
) AS geometry
FROM cluster_zres14
GROUP BY cid
);
CREATE INDEX ON cluster_zres14_union USING gist(geometry);
DROP TABLE IF EXISTS cluster_zres12;
CREATE TABLE cluster_zres12 AS
(
WITH single_geom AS (
SELECT (ST_Dump(geometry)).geom AS geometry
FROM osm_landuse_polygon
WHERE landuse='residential'
)
SELECT ST_ClusterDBSCAN(geometry, eps := zres(12), minpoints := 1) over () AS cid,
geometry
FROM single_geom
);
CREATE INDEX ON cluster_zres12 USING gist(geometry);
DROP TABLE IF EXISTS cluster_zres12_union;
CREATE TABLE cluster_zres12_union AS
(
SELECT ST_Buffer(
ST_Union(
ST_Buffer(
ST_SnapToGrid(geometry, 1)
, zres(12), 'join=mitre'
)
), -zres(12), 'join=mitre'
) AS geometry
FROM cluster_zres12
GROUP BY cid
);
CREATE INDEX ON cluster_zres12_union USING gist(geometry);
DROP TABLE IF EXISTS cluster_zres9;
CREATE TABLE cluster_zres9 AS
(
WITH single_geom AS (
SELECT (ST_Dump(geometry)).geom AS geometry
FROM osm_landuse_polygon
WHERE landuse='residential'
)
SELECT ST_ClusterDBSCAN(geometry, eps := zres(9), minpoints := 1) over () AS cid,
geometry
FROM single_geom
);
CREATE INDEX ON cluster_zres9 USING gist(geometry);
DROP TABLE IF EXISTS cluster_zres9_union;
CREATE TABLE cluster_zres9_union AS
(
SELECT ST_Buffer(
ST_Union(
ST_Buffer(
ST_SnapToGrid(geometry, 1)
, zres(9), 'join=mitre'
)
), -zres(9), 'join=mitre'
) AS geometry
FROM cluster_zres9
GROUP BY cid
);
CREATE INDEX ON cluster_zres9_union USING gist(geometry);
-- For z6
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z6
DROP TABLE IF EXISTS osm_residential_gen_z6 CASCADE;
CREATE TABLE osm_residential_gen_z6 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(6), 2)) AS geometry
FROM cluster_zres9_union
WHERE ST_Area(geometry) > power(zres(6), 2)
);
CREATE INDEX ON osm_residential_gen_z6 USING gist(geometry);
-- For z7
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z7
DROP TABLE IF EXISTS osm_residential_gen_z7 CASCADE;
CREATE TABLE osm_residential_gen_z7 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(7), 2)) AS geometry
FROM cluster_zres12_union
WHERE ST_Area(geometry) > power(zres(6), 2)
);
CREATE INDEX ON osm_residential_gen_z7 USING gist(geometry);
-- For z8
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z8
DROP TABLE IF EXISTS osm_residential_gen_z8 CASCADE;
CREATE TABLE osm_residential_gen_z8 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(8), 2)) AS geometry
FROM cluster_zres12_union
WHERE ST_Area(geometry) > power(zres(7), 2)
);
CREATE INDEX ON osm_residential_gen_z8 USING gist(geometry);
-- For z9
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z9
DROP TABLE IF EXISTS osm_residential_gen_z9 CASCADE;
CREATE TABLE osm_residential_gen_z9 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(9), 2)) AS geometry
FROM cluster_zres12_union
WHERE ST_Area(geometry) > power(zres(9), 2)
);
CREATE INDEX ON osm_residential_gen_z9 USING gist(geometry);
-- For z10
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z10
DROP TABLE IF EXISTS osm_residential_gen_z10 CASCADE;
CREATE TABLE osm_residential_gen_z10 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(10), 2)) AS geometry
FROM cluster_zres14_union
WHERE ST_Area(geometry) > power(zres(10), 2)
);
CREATE INDEX ON osm_residential_gen_z10 USING gist(geometry);
-- For z11
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z11
DROP TABLE IF EXISTS osm_residential_gen_z11 CASCADE;
CREATE TABLE osm_residential_gen_z11 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(11), 2)) AS geometry
FROM cluster_zres14_union
WHERE ST_Area(geometry) > power(zres(11), 2)
);
CREATE INDEX ON osm_residential_gen_z11 USING gist(geometry);
-- For z12
-- etldoc: osm_landuse_polygon -> osm_residential_gen_z12
DROP TABLE IF EXISTS osm_residential_gen_z12 CASCADE;
CREATE TABLE osm_residential_gen_z12 AS
(
SELECT ST_SimplifyVW(geometry, power(zres(12), 2)) AS geometry
FROM cluster_zres14_union
WHERE ST_Area(geometry) > power(zres(12), 2)
);
CREATE INDEX ON osm_residential_gen_z12 USING gist(geometry);

369
layers/landuse/style.json Normal file
View file

@ -0,0 +1,369 @@
{
"layers": [
{
"id": "landuse_classes",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landuse",
"minzoom": 7,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": [
"match",
[
"get",
"class"
],
"railway",
"#ebdbe8",
"residential",
"#e0dfdf",
"cemetery",
"#aacbaf",
"military",
"#fceaea",
"commercial",
"#f2dad9",
"industrial",
"#ebdbe8",
"garages",
"#dfddce",
"retail",
"#ffd6d1",
"bus_station",
"#e9e7e2",
"school",
"#ffffe5",
"university",
"#ffffe5",
"kindergarten",
"#ffffe5",
"college",
"#ffffe5",
"hospital",
"#ffffe5",
"stadium",
"#d5ffd9",
"pitch",
"#aae0cb",
"playground",
"#d5ffd9",
"track",
"#aae0cb",
"dam",
"#adadad",
"#000"
],
"fill-opacity": 1
},
"metadata": {},
"filter": [
"all",
[
"in",
"class",
"railway",
"cemetery",
"military",
"residential",
"commercial",
"industrial",
"garages",
"retail",
"bus_station",
"school",
"university",
"kindergarten",
"college",
"hospital",
"stadium",
"pitch",
"playground",
"track",
"dam"
],
[
"==",
"$type",
"Polygon"
]
],
"order": 1
},
{
"id": "landuse_residential",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landuse",
"minzoom": 6,
"maxzoom": 24,
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": {
"stops": [
[
7,
"#d0d0d0"
],
[
11,
"#dddddd"
],
[
12,
"#e0dfdf"
]
]
}
},
"metadata": {},
"filter": [
"all",
[
"in",
"class",
"residential",
"suburbs",
"neighbourhood"
]
],
"order": 2
},
{
"id": "landuse_class_pattern",
"type": "fill",
"source": "openmaptiles",
"source-layer": "landuse",
"layout": {
"visibility": "visible"
},
"paint": {
"fill-color": "#000000",
"fill-opacity": 1,
"fill-pattern": [
"match",
[
"get",
"class"
],
"military",
"military_red_hatch",
"cemetery",
"grave_yard_generic",
""
]
},
"metadata": {},
"filter": [
"all",
[
"in",
"class",
"military",
"cemetery"
]
],
"order": 25
},
{
"id": "landuse_class_outline",
"type": "line",
"source": "openmaptiles",
"source-layer": "landuse",
"minzoom": 13,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": [
"match",
[
"get",
"class"
],
"railway",
"#c6b3c3",
"military",
"#ff5555",
"residential",
"#b9b9b9",
"commercial",
"#f2dad9",
"industrial",
"#c6b3c3",
"retail",
"#d99c95",
"school",
"#A6A68C",
"university",
"#A6A68C",
"kindergarten",
"#A6A68C",
"college",
"#A6A68C",
"hospital",
"#A6A68C",
"stadium",
"#7ca680",
"pitch",
"#7aaa97",
"playground",
"#3c6640",
"track",
"#7aaa96",
"theme_park",
"#660033",
"zoo",
"#660033",
"dam",
"#444444",
"#000"
],
"line-width": [
"match",
[
"get",
"class"
],
"railway",
0.7,
"military",
2,
"residential",
0.5,
"commercial",
0.5,
"industrial",
0.5,
"retail",
0.5,
"school",
0.3,
"university",
0.3,
"kindergarten",
0.3,
"college",
0.3,
"hospital",
0.3,
"stadium",
0.3,
"pitch",
0.5,
"playground",
0.3,
"track",
0.5,
"theme_park",
1,
"zoo",
1,
"dam",
2,
1
],
"line-offset": [
"match",
[
"get",
"class"
],
"military",
1,
0
],
"line-opacity": [
"match",
[
"get",
"class"
],
"military",
0.24,
1
]
},
"filter": [
"all",
[
"in",
"class",
"railway",
"military",
"residential",
"commercial",
"industrial",
"retail",
"school",
"university",
"kindergarten",
"college",
"hospital",
"stadium",
"pitch",
"playground",
"track",
"theme_park",
"zoo",
"dam"
]
],
"order": 26
},
{
"id": "landuse_class_themepark",
"type": "line",
"source": "openmaptiles",
"source-layer": "landuse",
"minzoom": 13,
"layout": {
"line-cap": "square",
"line-join": "round",
"visibility": "visible"
},
"paint": {
"line-color": "#660033",
"line-width": {
"stops": [
[
9,
3.5
],
[
14,
5.5
]
]
},
"line-offset": 2,
"line-opacity": {
"stops": [
[
9,
0.1
],
[
12,
0.3
]
]
}
},
"filter": [
"all",
[
"in",
"class",
"theme_park",
"zoo"
]
],
"order": 27
}
]
}

View file

@ -0,0 +1,7 @@
## Mountain Peaks
### Mapping Diagram
![Mapping diagram for mountain peaks](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for mountain peaks](etl_diagram.png?raw=true)

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

View file

@ -0,0 +1,60 @@
tables:
# etldoc: imposm3 -> osm_peak_point
peak_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: name
key: name
type: string
- name: name_en
key: name:en
type: string
- name: name_de
key: name:de
type: string
- name: tags
type: hstore_tags
- name: ele
key: ele
type: string
- name: wikipedia
key: wikipedia
type: string
mapping:
natural:
- peak
- volcano
- saddle
# etldoc: imposm3 -> osm_mountain_linestring
mountain_linestring:
type: linestring
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: name
key: name
type: string
- name: name_en
key: name:en
type: string
- name: name_de
key: name:de
type: string
- name: tags
type: hstore_tags
- name: wikipedia
key: wikipedia
type: string
mapping:
natural:
- ridge
- cliff
- arete

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View file

@ -0,0 +1,120 @@
-- etldoc: osm_peak_point -> peak_point
-- etldoc: ne_10m_admin_0_countries -> peak_point
CREATE OR REPLACE VIEW peak_point AS
(
SELECT pp.osm_id,
pp.geometry,
pp.name,
pp.name_en,
pp.name_de,
pp.tags,
pp.ele,
ne.iso_a2,
pp.wikipedia
FROM osm_peak_point pp, ne_10m_admin_0_countries ne
WHERE ST_Intersects(pp.geometry, ne.geometry)
);
-- etldoc: layer_mountain_peak[shape=record fillcolor=lightpink,
-- etldoc: style="rounded,filled", label="layer_mountain_peak | <z7_> z7+ | <z13_> z13+" ] ;
CREATE OR REPLACE FUNCTION layer_mountain_peak(bbox geometry,
zoom_level integer,
pixel_width numeric)
RETURNS TABLE
(
osm_id bigint,
geometry geometry,
name text,
name_en text,
name_de text,
class text,
tags hstore,
ele int,
ele_ft int,
customary_ft int,
"rank" int
)
AS
$$
SELECT
-- etldoc: peak_point -> layer_mountain_peak:z7_
osm_id,
geometry,
name,
name_en,
name_de,
tags->'natural' AS class,
tags,
ele::int,
ele_ft::int,
customary_ft,
rank::int
FROM (
SELECT osm_id,
geometry,
NULLIF(name, '') as name,
COALESCE(NULLIF(name_en, ''), NULLIF(name, '')) AS name_en,
COALESCE(NULLIF(name_de, ''), NULLIF(name, ''), NULLIF(name_en, '')) AS name_de,
tags,
substring(ele FROM E'^(-?\\d+)(\\D|$)')::int AS ele,
round(substring(ele FROM E'^(-?\\d+)(\\D|$)')::int * 3.2808399)::int AS ele_ft,
CASE WHEN iso_a2 = 'US' THEN 1 END AS customary_ft,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 100 * pixel_width)
ORDER BY (
(CASE WHEN ele <> '' THEN substring(ele FROM E'^(-?\\d+)(\\D|$)')::int ELSE 0 END) +
(CASE WHEN wikipedia <> '' THEN 10000 ELSE 0 END) +
(CASE WHEN name <> '' THEN 10000 ELSE 0 END)
) DESC
)::int AS "rank"
FROM peak_point
WHERE geometry && bbox
AND (
(ele <> '' AND ele ~ E'^-?\\d{1,4}(\\D|$)')
OR name <> ''
)
) AS ranked_peaks
WHERE zoom_level >= 7
AND (rank <= 5 OR zoom_level >= 14)
UNION ALL
SELECT
-- etldoc: osm_mountain_linestring -> layer_mountain_peak:z13_
osm_id,
geometry,
name,
name_en,
name_de,
tags->'natural' AS class,
tags,
NULL AS ele,
NULL AS ele_ft,
NULL AS customary_ft,
rank::int
FROM (
SELECT osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 100 * pixel_width)
ORDER BY (
(CASE WHEN wikipedia <> '' THEN 10000 ELSE 0 END) +
(CASE WHEN name <> '' THEN 10000 ELSE 0 END)
) DESC
)::int AS "rank"
FROM osm_mountain_linestring
WHERE geometry && bbox
) AS ranked_mountain_linestring
WHERE zoom_level >= 13
ORDER BY "rank" ASC;
$$ LANGUAGE SQL STABLE
PARALLEL SAFE;
-- TODO: Check if the above can be made STRICT -- i.e. if pixel_width could be NULL

View file

@ -0,0 +1,45 @@
layer:
id: "mountain_peak"
requires:
tables:
- ne_10m_admin_0_countries
description: |
[Natural peaks](http://wiki.openstreetmap.org/wiki/Tag:natural%3Dpeak)
buffer_size: 64
srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
fields:
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the peak. Language-specific values are in `name:xx`.
name_en: English name `name:en` if available, otherwise `name`. This is deprecated and will be removed in a future release in favor of `name:en`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`. This is deprecated and will be removed in a future release in favor of `name:de`.
class:
description: |
Use the **class** to differentiate between natural objects.
values:
- peak
- volcano
- saddle
- ridge
- cliff
- arete
ele: Elevation (`ele`) in meters.
ele_ft: Elevation (`ele`) in feet.
customary_ft:
description: |
Value 1 for peaks in location where feet is used as customary unit (USA).
values:
- 1
- NULL
rank: Rank of the peak within one tile (starting at 1 that is the most important peak).
datasource:
geometry_field: geometry
key_field: osm_id
key_field_as_attribute: no
srid: 900913
query: (SELECT osm_id, geometry, name, name_en, name_de, {name_languages}, class, ele, ele_ft, customary_ft, rank FROM layer_mountain_peak(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t
schema:
- ./update_peak_point.sql
- ./update_mountain_linestring.sql
- ./mountain_peak.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

View file

@ -0,0 +1,101 @@
{
"layers": [
{
"id": "mountain_peak",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "mountain_peak",
"maxzoom": 16,
"filter": [
"all",
[
"!in",
"class",
"cliff",
"volcano"
]
],
"layout": {
"text-size": 10,
"icon-image": "peak",
"text-field": {
"stops": [
[
6,
" "
],
[
12,
"{name} {ele}m"
]
]
},
"text-anchor": "top",
"text-offset": [
0,
0.5
],
"text-max-width": 6,
"text-line-height": 1.1,
"text-font": [
"Noto Sans Regular",
"Noto Sans Italic"
]
},
"paint": {
"text-color": "#6e441e",
"text-halo-color": "rgba(255, 255, 255, .8)",
"text-halo-width": 1
},
"order": 197
},
{
"id": "mountain_peak_volcano",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "mountain_peak",
"maxzoom": 16,
"filter": [
"all",
[
"==",
"class",
"volcano"
]
],
"layout": {
"text-size": 10,
"icon-image": "volcano",
"text-field": {
"stops": [
[
6,
" "
],
[
12,
"{name} {ele}m"
]
]
},
"text-anchor": "top",
"text-offset": [
0,
0.5
],
"text-max-width": 6,
"text-line-height": 1.1,
"text-font": [
"Noto Sans Regular",
"Noto Sans Italic"
]
},
"paint": {
"text-color": "#d40000",
"text-halo-color": "rgba(255, 255, 255, .8)",
"text-halo-width": 1
},
"order": 198
}
]
}

View file

@ -0,0 +1,87 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_mountain_linestring;
DROP TRIGGER IF EXISTS trigger_store ON osm_mountain_linestring;
DROP TRIGGER IF EXISTS trigger_refresh ON mountain_linestring.updates;
CREATE SCHEMA IF NOT EXISTS mountain_linestring;
CREATE TABLE IF NOT EXISTS mountain_linestring.osm_ids
(
osm_id bigint PRIMARY KEY
);
-- etldoc: osm_mountain_linestring -> osm_mountain_linestring
CREATE OR REPLACE FUNCTION update_osm_mountain_linestring(full_update boolean) RETURNS void AS
$$
UPDATE osm_mountain_linestring
SET tags = update_tags(tags, geometry)
WHERE (full_update OR osm_id IN (SELECT osm_id FROM mountain_linestring.osm_ids))
AND COALESCE(tags -> 'name:latin', tags -> 'name:nonlatin', tags -> 'name_int') IS NULL
AND tags != update_tags(tags, geometry)
$$ LANGUAGE SQL;
SELECT update_osm_mountain_linestring(true);
-- Handle updates
CREATE OR REPLACE FUNCTION mountain_linestring.store() RETURNS trigger AS
$$
BEGIN
INSERT INTO mountain_linestring.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE IF NOT EXISTS mountain_linestring.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION mountain_linestring.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO mountain_linestring.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION mountain_linestring.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh mountain_linestring';
-- Analyze tracking and source tables before performing update
ANALYZE mountain_linestring.osm_ids;
ANALYZE osm_mountain_linestring;
PERFORM update_osm_mountain_linestring(false);
-- noinspection SqlWithoutWhere
DELETE FROM mountain_linestring.osm_ids;
-- noinspection SqlWithoutWhere
DELETE FROM mountain_linestring.updates;
RAISE LOG 'Refresh mountain_linestring done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_store
AFTER INSERT OR UPDATE
ON osm_mountain_linestring
FOR EACH ROW
EXECUTE PROCEDURE mountain_linestring.store();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE
ON osm_mountain_linestring
FOR EACH STATEMENT
EXECUTE PROCEDURE mountain_linestring.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON mountain_linestring.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE mountain_linestring.refresh();

View file

@ -0,0 +1,87 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_peak_point;
DROP TRIGGER IF EXISTS trigger_store ON osm_peak_point;
DROP TRIGGER IF EXISTS trigger_refresh ON mountain_peak_point.updates;
CREATE SCHEMA IF NOT EXISTS mountain_peak_point;
CREATE TABLE IF NOT EXISTS mountain_peak_point.osm_ids
(
osm_id bigint PRIMARY KEY
);
-- etldoc: osm_peak_point -> osm_peak_point
CREATE OR REPLACE FUNCTION update_osm_peak_point(full_update boolean) RETURNS void AS
$$
UPDATE osm_peak_point
SET tags = update_tags(tags, geometry)
WHERE (full_update OR osm_id IN (SELECT osm_id FROM mountain_peak_point.osm_ids))
AND COALESCE(tags -> 'name:latin', tags -> 'name:nonlatin', tags -> 'name_int') IS NULL
AND tags != update_tags(tags, geometry)
$$ LANGUAGE SQL;
SELECT update_osm_peak_point(true);
-- Handle updates
CREATE OR REPLACE FUNCTION mountain_peak_point.store() RETURNS trigger AS
$$
BEGIN
INSERT INTO mountain_peak_point.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE IF NOT EXISTS mountain_peak_point.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION mountain_peak_point.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO mountain_peak_point.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION mountain_peak_point.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh mountain_peak_point';
-- Analyze tracking and source tables before performing update
ANALYZE mountain_peak_point.osm_ids;
ANALYZE osm_peak_point;
PERFORM update_osm_peak_point(false);
-- noinspection SqlWithoutWhere
DELETE FROM mountain_peak_point.osm_ids;
-- noinspection SqlWithoutWhere
DELETE FROM mountain_peak_point.updates;
RAISE LOG 'Refresh mountain_peak_point done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trigger_store
AFTER INSERT OR UPDATE
ON osm_peak_point
FOR EACH ROW
EXECUTE PROCEDURE mountain_peak_point.store();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE
ON osm_peak_point
FOR EACH STATEMENT
EXECUTE PROCEDURE mountain_peak_point.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON mountain_peak_point.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE mountain_peak_point.refresh();

View file

@ -1,19 +0,0 @@
CREATE OR REPLACE FUNCTION layer_outdoor_poi(bbox geometry, zoom_level int)
RETURNS TABLE(osm_id bigint, geometry geometry, class text, subclass text, name text) AS $$
SELECT
osm_id * 10 + 1,
geometry,
CASE
WHEN subclass = 'memorial'
THEN 'subclass'
ELSE class
END AS class,
CASE
WHEN subclass = 'memorial'
THEN NULLIF(memorial, '')
ELSE subclass
END AS subclass,
NULLIF(name, '') AS name
FROM osm_exploration_point
WHERE zoom_level >= 14 AND geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;

View file

@ -1,32 +0,0 @@
# can't overlap with https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/mapping.yaml
tables:
# etldoc: imposm3 -> osm_exploration_point
exploration_point:
type: point
fields:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: class
type: mapping_key
- name: subclass
type: mapping_value
- key: name
name: name
type: string
- key: memorial
name: memorial
type: string
- key: tourism
name: tourism
type: string
mapping:
historic:
- memorial
military:
- bunker
filters:
reject:
tourism: [__any__]

View file

@ -1,20 +0,0 @@
layer:
id: "outdoor_poi"
description: Outdoor POI missing from OMT
buffer_size: 4
srs: +proj=merc +a=6378137 +b=6378137 +lat_ts=0.0 +lon_0=0.0 +x_0=0.0 +y_0=0.0 +k=1.0 +units=m +nadgrids=@null +wktext +no_defs +over
fields:
class:
subclass:
name:
datasource:
key_field: osm_id
key_field_as_attribute: no
geometry_field: geometry
srid: 900913
query: (SELECT osm_id, geometry, class, subclass, name FROM layer_outdoor_poi(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./layer.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

10
layers/park/README.md Normal file
View file

@ -0,0 +1,10 @@
## park
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#park**
### Mapping Diagram
![Mapping diagram for park](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for park](etl_diagram.png?raw=true)

BIN
layers/park/etl_diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

103
layers/park/mapping.yaml Normal file
View file

@ -0,0 +1,103 @@
generalized_tables:
# etldoc: osm_park_polygon_gen_z5 -> osm_park_polygon_gen_z4
park_polygon_gen_z4:
source: park_polygon_gen_z5
sql_filter: area>power(ZRES3,2)
tolerance: ZRES4
# etldoc: osm_park_polygon_gen_z6 -> osm_park_polygon_gen_z5
park_polygon_gen_z5:
source: park_polygon_gen_z6
sql_filter: area>power(ZRES4,2)
tolerance: ZRES5
# etldoc: osm_park_polygon_gen_z7 -> osm_park_polygon_gen_z6
park_polygon_gen_z6:
source: park_polygon_gen_z7
sql_filter: area>power(ZRES5,2)
tolerance: ZRES6
# etldoc: osm_park_polygon_gen_z8 -> osm_park_polygon_gen_z7
park_polygon_gen_z7:
source: park_polygon_gen_z8
sql_filter: area>power(ZRES6,2)
tolerance: ZRES7
# etldoc: osm_park_polygon_gen_z9 -> osm_park_polygon_gen_z8
park_polygon_gen_z8:
source: park_polygon_gen_z9
sql_filter: area>power(ZRES7,2)
tolerance: ZRES8
# etldoc: osm_park_polygon_gen_z10 -> osm_park_polygon_gen_z9
park_polygon_gen_z9:
source: park_polygon_gen_z10
sql_filter: area>power(ZRES8,2)
tolerance: ZRES9
# etldoc: osm_park_polygon_gen_z11 -> osm_park_polygon_gen_z10
park_polygon_gen_z10:
source: park_polygon_gen_z11
sql_filter: area>power(ZRES9,2)
tolerance: ZRES10
# etldoc: osm_park_polygon_gen_z12 -> osm_park_polygon_gen_z11
park_polygon_gen_z11:
source: park_polygon_gen_z12
sql_filter: area>power(ZRES10,2)
tolerance: ZRES11
# etldoc: osm_park_polygon_gen_z13 -> osm_park_polygon_gen_z12
park_polygon_gen_z12:
source: park_polygon_gen_z13
sql_filter: area>power(ZRES11,2)
tolerance: ZRES12
# etldoc: osm_park_polygon -> osm_park_polygon_gen_z13
park_polygon_gen_z13:
source: park_polygon
sql_filter: area>power(ZRES12,2) AND ST_IsValid(geometry)
tolerance: ZRES13
tables:
# etldoc: imposm3 -> osm_park_polygon
park_polygon:
type: polygon
_resolve_wikidata: false
columns:
- name: osm_id
type: id
- name: geometry
type: validated_geometry
- name: name
key: name
type: string
- name: name_en
key: name:en
type: string
- name: name_de
key: name:de
type: string
- name: tags
type: hstore_tags
- name: landuse
key: landuse
type: string
- name: leisure
key: leisure
type: string
- name: boundary
key: boundary
type: string
- name: protection_title
key: protection_title
type: string
- name: area
type: area
mapping:
leisure:
- nature_reserve
boundary:
- national_park
- protected_area

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

386
layers/park/park.sql Normal file
View file

@ -0,0 +1,386 @@
-- etldoc: layer_park[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_park |<z4> z4 |<z5> z5 |<z6> z6 |<z7> z7 |<z8> z8 |<z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13|<z14> z14+" ] ;
CREATE OR REPLACE FUNCTION layer_park(bbox geometry, zoom_level int, pixel_width numeric)
RETURNS TABLE
(
osm_id bigint,
geometry geometry,
class text,
name text,
name_en text,
name_de text,
tags hstore,
rank int
)
AS
$$
SELECT osm_id,
geometry,
class,
NULLIF(name, '') AS name,
NULLIF(name_en, '') AS name_en,
NULLIF(name_de, '') AS name_de,
tags,
rank
FROM (
SELECT osm_id,
geometry,
COALESCE(
LOWER(REPLACE(NULLIF(protection_title, ''), ' ', '_')),
NULLIF(boundary, ''),
NULLIF(leisure, ''))
AS class,
name,
name_en,
name_de,
tags,
NULL::int AS rank
FROM (
-- etldoc: osm_park_polygon_dissolve_z4 -> layer_park:z4
SELECT NULL::int AS osm_id,
geometry,
NULL AS name,
NULL AS name_en,
NULL AS name_de,
NULL AS tags,
NULL AS leisure,
NULL AS boundary,
NULL AS protection_title
FROM osm_park_polygon_dissolve_z4
WHERE zoom_level = 4
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z5 -> layer_park:z5
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z5
WHERE zoom_level = 5
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z6 -> layer_park:z6
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z6
WHERE zoom_level = 6
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z7 -> layer_park:z7
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z7
WHERE zoom_level = 7
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z8 -> layer_park:z8
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z8
WHERE zoom_level = 8
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z9 -> layer_park:z9
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z9
WHERE zoom_level = 9
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z10 -> layer_park:z10
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z10
WHERE zoom_level = 10
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z11 -> layer_park:z11
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z11
WHERE zoom_level = 11
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z12 -> layer_park:z12
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z12
WHERE zoom_level = 12
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen_z13 -> layer_park:z13
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon_gen_z13
WHERE zoom_level = 13
AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon -> layer_park:z14
SELECT osm_id,
geometry,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title
FROM osm_park_polygon
WHERE zoom_level >= 14
AND geometry && bbox
) AS park_polygon
UNION ALL
SELECT osm_id,
geometry_point AS geometry,
COALESCE(
LOWER(REPLACE(NULLIF(protection_title, ''), ' ', '_')),
NULLIF(boundary, ''),
NULLIF(leisure, '')
) AS class,
name,
name_en,
name_de,
tags,
row_number() OVER (
PARTITION BY LabelGrid(geometry_point, 100 * pixel_width)
ORDER BY
(CASE WHEN boundary = 'national_park' THEN TRUE ELSE FALSE END) DESC,
(COALESCE(NULLIF(tags->'wikipedia', ''), NULLIF(tags->'wikidata', '')) IS NOT NULL) DESC,
area DESC
)::int AS "rank"
FROM (
-- etldoc: osm_park_polygon_gen_z5 -> layer_park:z5
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z5
WHERE zoom_level = 5
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z6 -> layer_park:z6
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z6
WHERE zoom_level = 6
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z7 -> layer_park:z7
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z7
WHERE zoom_level = 7
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z8 -> layer_park:z8
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z8
WHERE zoom_level = 8
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z9 -> layer_park:z9
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z9
WHERE zoom_level = 9
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z10 -> layer_park:z10
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z10
WHERE zoom_level = 10
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z11 -> layer_park:z11
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z11
WHERE zoom_level = 11
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z12 -> layer_park:z12
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z12
WHERE zoom_level = 12
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon_gen_z13 -> layer_park:z13
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon_gen_z13
WHERE zoom_level = 13
AND geometry_point && bbox
AND area > 70000*2^(20-zoom_level)
UNION ALL
-- etldoc: osm_park_polygon -> layer_park:z14
SELECT osm_id,
geometry_point,
name,
name_en,
name_de,
tags,
leisure,
boundary,
protection_title,
area
FROM osm_park_polygon
WHERE zoom_level >= 14
AND geometry_point && bbox
) AS park_point
) AS park_all;
$$ LANGUAGE SQL STABLE
PARALLEL SAFE;
-- TODO: Check if the above can be made STRICT -- i.e. if pixel_width could be NULL

32
layers/park/park.yaml Normal file
View file

@ -0,0 +1,32 @@
layer:
id: "park"
description: |
The park layer in OpenMapTiles contains natural and protected areas from OpenStreetMap,
such as parks tagged with [`boundary=national_park`](https://wiki.openstreetmap.org/wiki/Tag:boundary%3Dnational_park),
[`boundary=protected_area`](https://wiki.openstreetmap.org/wiki/Tag:boundary%3Dprotected_area),
or [`leisure=nature_reserve`](https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve).
buffer_size: 4
fields:
class:
description: |
Use the **class** to differentiate between different kinds of features in the `parks` layer.
The class for `boundary=protected_area` parks is the lower-case of the
[`protection_title`](http://wiki.openstreetmap.org/wiki/key:protection_title)
value with blanks replaced by `_`.
`national_park` is the class of `protection_title=National Park` and `boundary=national_park`.
`nature_reserve` is the class of `protection_title=Nature Reserve` and `leisure=nature_reserve`.
The class for other [`protection_title`](http://wiki.openstreetmap.org/wiki/key:protection_title)
values is similarly assigned.
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the park (point features only). Language-specific values are in `name:xx`.
name_en: English name `name:en` if available, otherwise `name` (point features only). This is deprecated and will be removed in a future release in favor of `name:en`.
name_de: German name `name:de` if available, otherwise `name` or `name:en` (point features only). This is deprecated and will be removed in a future release in favor of `name:de`.
rank: Rank of the park within one tile, starting at 1 that is the most important park (point features only).
datasource:
geometry_field: geometry
query: (SELECT geometry, class, name, name_en, name_de, {name_languages}, rank FROM layer_park(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t
schema:
- ./update_park_polygon.sql
- ./park.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

111
layers/park/style.json Normal file
View file

@ -0,0 +1,111 @@
{
"layers": [
{
"id": "national_parks",
"type": "line",
"source": "openmaptiles",
"source-layer": "park",
"minzoom": 8,
"layout": {
"visibility": "visible"
},
"paint": {
"line-color": "rgba(154, 199, 136, 1)",
"line-width": {
"base": 1,
"stops": [
[
8,
1.2
],
[
9,
1.5
],
[
10,
3.6
],
[
24,
3.6
]
]
},
"line-offset": 1,
"line-opacity": 0.8
},
"order": 20
},
{
"id": "national_parks_thin",
"type": "line",
"source": "openmaptiles",
"source-layer": "park",
"minzoom": 10,
"layout": {
"visibility": "none"
},
"paint": {
"line-color": "rgba(93, 156, 76, 1)",
"line-width": 1.5
},
"order": 21
},
{
"id": "park-national",
"type": "symbol",
"source": "openmaptiles",
"source-layer": "park",
"minzoom": 7,
"maxzoom": 12,
"layout": {
"text-font": [
"Noto Sans Italic"
],
"text-size": 12,
"text-field": "{name:latin}{name:nonlatin}",
"visibility": "visible",
"symbol-spacing": 150,
"text-allow-overlap": false
},
"paint": {
"text-color": {
"stops": [
[
7,
"rgba(70, 164, 70, 1)"
],
[
10,
"#008000"
]
]
},
"text-halo-blur": 0.1,
"text-halo-color": {
"stops": [
[
7,
"rgba(241, 255, 234, 1)"
],
[
10,
"rgba(208, 250, 200, 1)"
]
]
},
"text-halo-width": 0.3
},
"filter": [
"all",
[
"<=",
"rank",
2
]
],
"order": 195
}
]
}

View file

@ -0,0 +1,260 @@
ALTER TABLE osm_park_polygon
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z13
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z12
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z11
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z10
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z9
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z8
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z7
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z6
ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen_z5
ADD COLUMN IF NOT EXISTS geometry_point geometry;
-- etldoc: osm_park_polygon_gen_z4 -> osm_park_polygon_dissolve_z4
DROP MATERIALIZED VIEW IF EXISTS osm_park_polygon_dissolve_z4 CASCADE;
CREATE MATERIALIZED VIEW osm_park_polygon_dissolve_z4 AS
(
SELECT min(osm_id) AS osm_id,
ST_Union(geometry) AS geometry,
boundary
FROM (
SELECT ST_ClusterDBSCAN(geometry, 0, 1) OVER() AS cluster,
osm_id,
geometry,
boundary
FROM osm_park_polygon_gen_z4
) park_cluster
GROUP BY boundary, cluster
);
CREATE UNIQUE INDEX IF NOT EXISTS osm_park_polygon_dissolve_idx ON osm_park_polygon_dissolve_z4 (osm_id);
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z13;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z12;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z11;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z10;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z9;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z8;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z7;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z6;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z5;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen_z4;
DROP TRIGGER IF EXISTS trigger_flag ON osm_park_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON park_polygon.updates;
-- etldoc: osm_park_polygon -> osm_park_polygon
-- etldoc: osm_park_polygon_gen_z13 -> osm_park_polygon_gen_z13
-- etldoc: osm_park_polygon_gen_z12 -> osm_park_polygon_gen_z12
-- etldoc: osm_park_polygon_gen_z11 -> osm_park_polygon_gen_z11
-- etldoc: osm_park_polygon_gen_z10 -> osm_park_polygon_gen_z10
-- etldoc: osm_park_polygon_gen_z9 -> osm_park_polygon_gen_z9
-- etldoc: osm_park_polygon_gen_z8 -> osm_park_polygon_gen_z8
-- etldoc: osm_park_polygon_gen_z7 -> osm_park_polygon_gen_z7
-- etldoc: osm_park_polygon_gen_z6 -> osm_park_polygon_gen_z6
-- etldoc: osm_park_polygon_gen_z5 -> osm_park_polygon_gen_z5
-- etldoc: osm_park_polygon_gen_z4 -> osm_park_polygon_gen_z4
CREATE OR REPLACE FUNCTION update_osm_park_polygon() RETURNS void AS
$$
BEGIN
UPDATE osm_park_polygon
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z13
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z12
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z11
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z10
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z9
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z8
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z7
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z6
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen_z5
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
REFRESH MATERIALIZED VIEW CONCURRENTLY osm_park_polygon_dissolve_z4;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_park_polygon();
CREATE INDEX IF NOT EXISTS osm_park_polygon_point_geom_idx ON osm_park_polygon USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z13_point_geom_idx ON osm_park_polygon_gen_z13 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z12_point_geom_idx ON osm_park_polygon_gen_z12 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z11_point_geom_idx ON osm_park_polygon_gen_z11 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z10_point_geom_idx ON osm_park_polygon_gen_z10 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z9_point_geom_idx ON osm_park_polygon_gen_z9 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z8_point_geom_idx ON osm_park_polygon_gen_z8 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z7_point_geom_idx ON osm_park_polygon_gen_z7 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z6_point_geom_idx ON osm_park_polygon_gen_z6 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z5_point_geom_idx ON osm_park_polygon_gen_z5 USING gist (geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen_z4_polygon_geom_idx ON osm_park_polygon_gen_z4 USING gist (geometry);
CREATE INDEX IF NOT EXISTS osm_park_polygon_dissolve_z4_polygon_geom_idx ON osm_park_polygon_dissolve_z4 USING gist (geometry);
CREATE SCHEMA IF NOT EXISTS park_polygon;
CREATE TABLE IF NOT EXISTS park_polygon.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION park_polygon.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO park_polygon.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION park_polygon.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh park_polygon';
-- Analyze tracking and source tables before performing update
ANALYZE osm_park_polygon_gen_z4;
REFRESH MATERIALIZED VIEW osm_park_polygon_dissolve_z4;
-- noinspection SqlWithoutWhere
DELETE FROM park_polygon.updates;
RAISE LOG 'Refresh park_polygon done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION update_osm_park_polygon_row()
RETURNS trigger
AS
$$
BEGIN
NEW.tags = update_tags(NEW.tags, NEW.geometry);
NEW.geometry_point = ST_PointOnSurface(NEW.geometry);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION update_osm_park_dissolved_polygon_row()
RETURNS trigger
AS
$$
BEGIN
NEW.tags = update_tags(NEW.tags, NEW.geometry);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z13
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z12
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z11
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z10
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z9
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z8
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z7
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z6
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z5
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_polygon_row();
CREATE TRIGGER update_row
BEFORE INSERT OR UPDATE
ON osm_park_polygon_gen_z4
FOR EACH ROW
EXECUTE PROCEDURE update_osm_park_dissolved_polygon_row();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE
ON osm_park_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE park_polygon.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON park_polygon.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE park_polygon.refresh();

10
layers/place/README.md Normal file
View file

@ -0,0 +1,10 @@
## place
### Docs
Read the layer documentation at **http://openmaptiles.org/schema#place**
### Mapping Diagram
![Mapping diagram for place](mapping_diagram.png?raw=true)
### ETL diagram
![ETL diagram for place](etl_diagram.png?raw=true)

View file

@ -0,0 +1,14 @@
CREATE OR REPLACE FUNCTION area_rank(area real) RETURNS int AS
$$
SELECT CASE
WHEN area > 640000000 THEN 1
WHEN area > 160000000 THEN 2
WHEN area > 40000000 THEN 3
WHEN area > 15000000 THEN 4
WHEN area > 10000000 THEN 5
WHEN area > 0 THEN 6
ELSE 7
END;
$$ LANGUAGE SQL IMMUTABLE
STRICT
PARALLEL SAFE;

10
layers/place/capital.sql Normal file
View file

@ -0,0 +1,10 @@
CREATE OR REPLACE FUNCTION normalize_capital_level(capital text)
RETURNS int AS
$$
SELECT CASE
WHEN capital = 'yes' THEN 2
WHEN capital IN ('2', '3', '4', '5', '6') THEN capital::int
END;
$$ LANGUAGE SQL IMMUTABLE
STRICT
PARALLEL SAFE;

79
layers/place/city.sql Normal file
View file

@ -0,0 +1,79 @@
-- etldoc: layer_city[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_city | <z2_14> z2-z14+" ] ;
-- etldoc: osm_city_point -> layer_city:z2_14
CREATE OR REPLACE FUNCTION layer_city(bbox geometry, zoom_level int, pixel_width numeric)
RETURNS TABLE
(
osm_id bigint,
geometry geometry,
name text,
name_en text,
name_de text,
tags hstore,
place city_place,
"rank" int,
capital int
)
AS
$$
SELECT *
FROM (
SELECT osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
place,
"rank",
normalize_capital_level(capital) AS capital
FROM osm_city_point
WHERE geometry && bbox
AND ((zoom_level = 2 AND "rank" = 1)
OR (zoom_level BETWEEN 3 AND 7 AND "rank" <= zoom_level + 1)
)
UNION ALL
SELECT osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
place,
COALESCE("rank", gridrank + 10),
normalize_capital_level(capital) AS capital
FROM (
SELECT osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
place,
"rank",
capital,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 128 * pixel_width)
ORDER BY "rank" ASC NULLS LAST,
place ASC NULLS LAST,
population DESC NULLS LAST,
length(name) ASC
)::int AS gridrank
FROM osm_city_point
WHERE geometry && bbox
AND ((zoom_level = 7 AND place <= 'town'::city_place
OR (zoom_level BETWEEN 8 AND 10 AND place <= 'village'::city_place)
OR (zoom_level BETWEEN 11 AND 13 AND place <= 'suburb'::city_place)
OR (zoom_level >= 14)
))
) AS ranked_places
WHERE (zoom_level BETWEEN 7 AND 8 AND (gridrank <= 4 OR "rank" IS NOT NULL))
OR (zoom_level = 9 AND (gridrank <= 8 OR "rank" IS NOT NULL))
OR (zoom_level = 10 AND (gridrank <= 12 OR "rank" IS NOT NULL))
OR (zoom_level BETWEEN 11 AND 12 AND (gridrank <= 14 OR "rank" IS NOT NULL))
OR (zoom_level >= 13)
) AS city_all;
$$ LANGUAGE SQL STABLE
-- STRICT
PARALLEL SAFE;

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

184
layers/place/mapping.yaml Normal file
View file

@ -0,0 +1,184 @@
name_field: &name
name: name
key: name
type: string
name_en_field: &name_en
name: name_en
key: name:en
type: string
name_de_field: &name_de
name: name_de
key: name:de
type: string
rank_field: &rank
name: rank
key: rank
type: integer
tables:
# etldoc: imposm3 -> osm_continent_point
continent_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- *name
- *name_en
- *name_de
- name: tags
type: hstore_tags
filters:
require:
name: ["__any__"]
mapping:
place:
- continent
# etldoc: imposm3 -> osm_country_point
country_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- *name
- *name_en
- *name_de
- *rank
- name: country_code_iso3166_1_alpha_2
key: country_code_iso3166_1_alpha_2
type: string
- name: iso3166_1_alpha_2
key: ISO3166-1:alpha2
type: string
- name: iso3166_1
key: ISO3166-1
type: string
- name: tags
type: hstore_tags
filters:
require:
name: ["__any__"]
mapping:
place:
- country
# etldoc: imposm3 -> osm_island_polygon
island_polygon:
type: polygon
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- name: area
type: area
- *name
- *name_en
- *name_de
- name: tags
type: hstore_tags
- *rank
filters:
require:
name: ["__any__"]
mapping:
place:
- island
# etldoc: imposm3 -> osm_island_point
island_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- *name
- *name_en
- *name_de
- name: tags
type: hstore_tags
- *rank
filters:
require:
name: ["__any__"]
mapping:
place:
- island
# etldoc: imposm3 -> osm_state_point
state_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- *name
- *name_en
- *name_de
- name: tags
type: hstore_tags
- name: place
key: place
type: string
- name: is_in_country
key: is_in:country
type: string
- name: is_in_country_code
key: is_in:country_code
type: string
- name: ref
key: ref
type: string
- *rank
filters:
require:
name: ["__any__"]
mapping:
place:
- state
- province
# etldoc: imposm3 -> osm_city_point
city_point:
type: point
columns:
- name: osm_id
type: id
- name: geometry
type: geometry
- *name
- *name_en
- *name_de
- name: tags
type: hstore_tags
- name: place
key: place
type: string
- key: population
name: population
type: integer
- key: capital
name: capital
type: string
- *rank
filters:
require:
name: ["__any__"]
mapping:
place:
- city
- town
- village
- hamlet
- borough
- suburb
- quarter
- neighbourhood
- isolated_dwelling

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Some files were not shown because too many files have changed in this diff Show more