Porównaj commity

...

438 Commity

Autor SHA1 Wiadomość Data
Tomas Pohanka 1ff5145451
Pre-release update. (#1657)
Update documentation before release v3.15.
2024-04-29 13:16:59 +02:00
Tomas Pohanka e6faa69a70
Fix z7-z4 roads (#1656)
Some US roads were not included in tiles, because the `ST_AsMVTGeom` did not transform geometry (result was NULL). This PR is trying to fix the geometry for `ST_AsMVTGeom`, even if the geometry is marked as valid (`ST_IsValid`). The odd geometry was caused by simplification when it could create `LINESTRING(1 1, 2 2, 1 1)` linestring, which in some cases was not converted into MVT. 

Also, for the US (on zoom 4) keeps just the network `us-interstate` and the `highway=motorway` or `osm_national_network(network)` for the rest of the world.
2024-04-24 11:47:27 +02:00
Tomas Pohanka eae7d7e1ed
Documentation update. (#1654)
- Unifying `name_de` description for `mountain_peak` layer.
- Update the version of PostGIS for `generate-sqltomvt` function.
2024-04-03 15:26:59 +02:00
Tomas Pohanka 382b12ae8a
Drop osm_transportation_name_network table before recreation. (#1653)
Drop the main table for layer `transportation_name` layer before creation.

For the first SQL import, it is OK, but for the second import (e.g. for a different country by `import-osm area=yyy`) without dropping the whole database it will keep `osm_transportation_name_network` filled with data from the first import (after first `import-sql` step)

This PR will drop the already-filled table from the first import and insert data from the reimported area.
2024-04-03 13:43:28 +02:00
Tomas Pohanka 59692656bd
Preserving the highway network in Canada for z4. (#1652)
This PR reverts important Canada TransCanada road to zoom 4.

At zoom 4, the network `gb-trunk` is too dense, so it is moved to zoom 5+.
2024-04-02 14:22:37 +02:00
Tomas Pohanka ee19519905
Add network for GBR and IRL. (#1649)
Fix a missing e-road relation for the United Kingdom and Ireland.
2024-04-02 11:08:50 +02:00
Tomas Pohanka 8266197149
Revert `e-road` and `a-road`. (#1648)
Partial revert the `e-road` and `a-road` added in https://github.com/openmaptiles/openmaptiles/pull/1619.

This PR leads to breaking the change of `network` and `ref` attributes for roads, which are not included in `osm_route_member_network_type`.
2024-04-02 10:09:20 +02:00
zstadler 3f0ba7ceba
Replace `["geometry-type"]` with `"$type"` (#1646)
Related to https://github.com/maplibre/maplibre-style-spec/pull/519 and https://github.com/maplibre/maplibre-gl-js/issues/3516

According to the Style Spec, `["geometry-type"]` is expected to distinguish between LineString and MultiLineString, while `"$type"` does not. For the transportation layer, the distinction is harmful.

All of OMT style layers, except these two, use `"$type"`.
2024-03-28 10:52:38 +01:00
Adam Laža c2ae2503c8
Fix borders z0-z4 (#1647)
This PR fixes two things:
- remove disputed name like `ne_*m_ogc_fid` from lines
- use South Sudan disputed boundary from `ne_10m_admin_0_boundary_lines_land_disputed` so there is no gap.
2024-03-27 13:56:23 +01:00
Tomas Pohanka d709a51de6
Salt pond with class `pond` (#1645)
The salt pond is now under the class `lake`, this PR moves it into class `pond`.
2024-03-21 15:58:58 +01:00
Brian Sperlongano af6dc684ef
Reduce transportation_name segmentation (#1643)
This PR reduces transportation_name layer fragmentation by ensuring the short brunnel segments are merged rather than dropped from view.

---------

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2024-03-21 08:08:56 +01:00
Adam Laža 136e1db4d1
Fix maritime low zooms (#1644)
This PR fixes boundary layer at low zoom levels:

-z4 - remove maritime boundary (Peru, northern and southern end of boundary between Canada and Alaska).
-z1-z4 - do not mix disputed boundary from NE and OSM - linestrings got duplicated. Use only NE data (z0-z4), then OSM data (z5+)
2024-03-18 13:23:38 +01:00
Tomas Pohanka 585b71f666
More roads for z4 and z5. (#1642)
This PR adds more roads to the zoom 4 for the United Kingdom and Ireland. Adding more roads for the USA at zoom 5.
2024-03-13 10:12:03 +01:00
Brian Sperlongano d6fd5ef7cb
Change to pointonsurface (#1641)
Fixes #1640 

This ensures that place and poi points computed from areas result in a point node that is actually inside the area that it's derived from.  Unusual shaped areas (like a banana shape, for example) may produce points that aren't actually contained.
2024-02-29 14:39:13 +01:00
Andrea Mennillo 9f891b625a
Replace spritezero with spreet (#1631)
This updates `build-sprite` and `build-style` to use `spreet`.

It depends on https://github.com/openmaptiles/openmaptiles-tools/pull/442
2024-02-26 15:06:12 +01:00
Tomas Pohanka 5b00c496ef
New omt-tools version. (#1638) 2024-02-26 14:05:42 +01:00
Adam Laža a65495f264
Fix housenumber_display.sql - cast to bigint instead of integer. (#1637)
Fixes `housenumber_display.sql` function and further improves https://github.com/openmaptiles/openmaptiles/pull/1632

Parsing text values that contain `;`, the string was split into array of values which were casted to `integer`. However, that fails for housenumber that exceed Postgres `int` range `-2147483648` to `+2147483647`.
There are such housenumber, e.g.: https://www.openstreetmap.org/way/1091331906#map=19/-3.82721/-38.59269
2024-02-26 13:04:00 +01:00
Andrea Mennillo 2f170fbbd8
Improve poi shop style (#1634)
The main goal is to improve consistency and reduce the number of poi without an icon.

- Remove music from poi cultural, music has only two subclasses music and musical_instrument, both are styled as poi shop
- Remove arts_centre from poi shop, it's already styled as poi cultural
- Remove chocolate icon, chocolate uses confectionery icon (see: https://github.com/openmaptiles/openmaptiles/pull/1628)
- Remove references to ice_cream class from poi shop
- Add missing gallery icon and move it to poi cultural (see: https://wiki.openstreetmap.org/wiki/Tag:tourism%3Dgallery)
- Use the icons alcohol, newsagent, perfumery, trade respectively for wine, kiosk, perfume and wholesale.
- Add a generic fallback icon for shops
2024-02-21 16:25:54 +01:00
Tomas Pohanka de2fa04c37
Docs clean up. (#1636)
Update docs, license year and clean up `.env`.
2024-02-21 13:40:46 +01:00
Tomas Pohanka 44cf6c8e35
Default output filename as `tiles.mbtiles` (#1633)
Keep the default output filename as `tiles.mbtiles`. `tiles.mbtiles` is expected to start TileServer.

Using the `area` as the name causes TileServer not to run. The name could be changed by the user by
 - change `MBTILES_FILE` in `.env`
 - use MBTILES_FILE as an environmental variable before running `quickstart.sh` or `generate-tiles-pg` 

Co-authored-by: Adam Laza <@lazaa32>
2024-02-21 11:52:29 +01:00
Tomas Pohanka b057d5941e
Update GitHub Actions. (#1635)
Bump GitHub Actions from v2 to v4.
2024-02-21 09:08:16 +01:00
Brian Sperlongano b3c32321a3
[WIP] Expanded road route attributes (#1620)
This PR replaces the `route_N` attribute scheme with individual attributes for name and colour on routes.  Thus you will have:
* `route_N_network` to hold the route `network` value
* `route_N_ref` to hold the route `ref` value
* `route_N_name` to hold the route `name` value
* `route_N_colour` to hold the route `colour` or `ref:colour` value
2024-02-20 17:38:11 +01:00
Andrea Mennillo ee8259ced5
style: use red color for volcano (#1630)
Change the color used for a volcano label and icon to #d40000.
2024-02-20 08:56:29 +01:00
Tomas Pohanka 718fd359d3
House number range fix. (#1632)
Fix house number range conversion based on https://github.com/openmaptiles/openmaptiles/issues/1583#issuecomment-1940901006.
2024-02-19 21:27:52 +01:00
Michał Gwóźdź 8d6b95008d
Changed classification of ice_cream and chocolate (#1628)
According to [OpenMapTiles Schema](https://openmaptiles.org/schema/) ice_cream should be a class, not a subclass of the shop, so I think it makes more sense to remove ice_cream from the shop class. I tested this, and after the change, both amenity=ice_cream and shop=ice_cream OSM tags get class=ice_cream + subclass=ice_cream, which is fine, because both OSM tags shop=ice_cream and amenity=ice_cream represents the same thing

The next thing I did was to change the color of the ice_cream icon.
2024-02-19 08:19:15 +01:00
Michał Gwóźdź aa51a6c101
Moved confectionery from ice_cream class to shop (#1627)
Moved confectionery from ice_cream class to shop.
2024-01-31 17:16:11 +01:00
Makien Osman d54ce2e617
🐛 remove duplicate "requires" key (#1626)
Remove duplicate "requires" key from `place.yaml`
2024-01-31 07:38:04 +01:00
Brian Sperlongano 5fd186a311
Add missing NULLIF (#1625)
In some cases that empty aggregated brunnel attributes was coming through in the tiles in the transportation_name layer.
2024-01-30 09:25:58 +01:00
Tomas Pohanka 6d1cb63d8e
Add e-road and a-road for transportation z4. (#1619)
Adding [e-road](https://wiki.openstreetmap.org/wiki/WikiProject_Europe/E-road_network) and [AsianHighway](https://wiki.openstreetmap.org/wiki/Asia/Asian_Highway_Network) (as `a-road`) as part of the network to show up from zoom 4.
2024-01-30 07:31:12 +01:00
Peter Hanecak fe61912c09
Make sure areas above 160000000 get rank 2 or 1 (#1623)
This is a follow-up on https://github.com/openmaptiles/openmaptiles/pull/1604 . Seminole Nation is shown in the screenshot there with rank 3 while based on area it should be 1. This PR fixes `area_rank()` function to handle areas greater than 160000000, e.g. this fixes #1622 .

Co-authored-by: Paul Norman <penorman@mac.com>
2024-01-29 07:51:24 +01:00
Peter Hanecak bb154f4ee8
fix for problem with "James Bay" in water_name (water label) #1595 (#1621)
For important marine points distance between NE and OSM with the same name must by under 50km.
2024-01-25 16:01:39 +01:00
Brian Sperlongano e29827d76c
Move aboriginal lands boundaries to boundary layer (#1604)
This PR adds indigenous lands to the `boundary` layer by adding new area features for these objects, along with generalization up to z4. It borrows heavily from the technical processing chain of the `park` layer.

I added new `class`, `name`, and `name:xx` attributes to the boundary layer, in order to support the new area features. Should we (or someone extending this schema) come up with new objects to place in the boundary layer in the future, `class` would support additional categories.
2024-01-21 10:37:02 +01:00
Tomas Pohanka eb7f6be455
Adding source_ids column if not exists. (#1600)
Adding source_ids column if not exist in the table 
 - osm_transportation_merge_linestring_gen_z11
 - osm_transportation_merge_linestring_gen_z8
 - osm_transportation_name_linestring
 - osm_important_waterway_linestring
2024-01-16 14:03:46 +01:00
Brian Sperlongano a682d50d0d
Document name_* deprecation strategy (#1605)
This PR is a **documentation change only**. It documents the fact that `name:xx` values are present in the tiles and documents that `name_de` and `name_en` will be removed in a future release in favor of `name:de` and `name:en` respectively.
2023-12-30 08:14:35 +01:00
Brian Sperlongano d3a9b36873
Fix university office/amenity collision (#1607)
Fixes #1606
Unblocks ZeLonewolf/openstreetmap-americana#1022

This PR is a bugfix which ensures that `amenity=university` is encoded as `class=college` rather than `class=office`.  It's required because of a subclass collision for `university`, which exists under both class values.
2023-12-28 08:18:00 +01:00
Brian Sperlongano b9c9e69028
Remove expressway from ramps (#1602)
#1313 added `expressway` tagging to the transportation layer. However, this also added the `expressway` attributes to ramps where it doesn't make sense (ramps by definition are controlled-access roads in all cases).  This PR corrects this by dropping the `expressway` attribute from ramps where it doesn't make sense to do so.

See also ZeLonewolf/openstreetmap-americana#1017
2023-12-28 07:11:36 +01:00
Christopher Beddow e61442c49d
feat: add charging station to car POIs (#1544)
Adding charging station to class `fuel`.

Co-authored-by: Christopher Beddow <cbeddow>
Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2023-12-12 13:58:03 +01:00
Martin Fischer 3cf77e2a54
Introduce `office` POI class (#1423)
Omitted values include:

* office=yes ... too generic
* office=vacant ... not really a POI
* deprecated values (like office=administrative)
* tags that don't have a clear meaning (like office=camping,
  office=healthcare, office=transport, office=design)
* tags where another tag is used more often, e.g:
  office=religion is used more often than office=parish
  office=construction_company is used more often than office=construction
  office=engineer is used more often than office=engineering

---------

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2023-12-01 17:43:58 +01:00
Brian Sperlongano 6c31841f46
Remove oneway from shipway/rail (#1591)
This PR removes the `oneway` attribute from ferry lines and rail lines.  These attributes don't really make sense for these feature classes and they are not typically rendered in general-purpose maps.
2023-11-09 16:56:28 +01:00
Zhongxiang Wang dfd20c647c
Fix unexpected error brought by typo: tigger -> trigger & fix `trigger_flag` was created on a wrong target (#1584)
1) The trigger name has a typo of `trigger`, which is incorrectly spelled as `tigger` and doesn't match the following create command: `CREATE TRIGGER trigger_flag`. This may result in an error when invoking `make import-sql`.

```
ERROR:  trigger "trigger_flag" for relation "osm_park_polygon_gen_z4" already exists
xargs: sh: exited with status 255; aborting
```

2) The `trigger_flag` may be created on the wrong target in line [#251](https://github.com/plainheart/openmaptiles/blob/master/layers/park/update_park_polygon.sql#L251).
2023-09-27 12:08:33 +02:00
Michał Gwóźdź febd1abbd2
Update README.md (#1581)
This workshop is extremely helpful in understanding how OpenMapTiles works, especially in creating new layers, which is not properly documented (or I just couldn't find any documentation).
2023-09-21 08:06:29 +02:00
Brian Sperlongano 9de3ff3921
Restore missing route zooms (#1579)
This PR restores missing transportation_name features that are missing from zoom 11 and improves the mechanism by which transportation_name features are merged through lower zooms. This prevents route features from being dropped due to bridge interleaving (when a bridge interrupts an otherwise continuous route).

This fix moves the length check to a later stage of processing and merges bridges/tunnels if they're too small.  This is similar to the work done in the transportation layer to merge bridges that are too small to render lines.  In this layer, bridges are merged when they're too small to justify a separate label.
2023-09-14 15:55:01 +02:00
Brian Sperlongano a7a50d84bc
Convert semi-colon separated house numbers to a range (#1562)
This PR collapses housenumber values into the form min(housenumber)-max(housenumber) for cases where housenumber is a semi-colon separated list. If the list is all numbers, the bounds are the smallest and largest numbers.  If the list includes non-numeric characters, it falls back to the first and last values in the list.
2023-09-13 11:09:41 +02:00
Brian Sperlongano 48a2b1af72
Convert PL/PGSQL to SQL (#1568)
This PR converts three plpgsql functions in the `transportation_name` layer to sql functions, which perform better.
2023-08-06 07:26:24 +02:00
Peter Hanecak 0ca096938e
Fix for classification of CA:ON:primary (#1564)
This PR changes classification of `CA:ON:primary`: "all else" should be `ca-provincial`.
2023-07-11 07:28:20 +02:00
benedikt-brandtner-bikemap a8e6573ba8
boundary.sql parallelization issue fix (#1551)
VectorTiles generated via the [openmaptiles-tools](https://github.com/openmaptiles/openmaptiles-tools) toolchain and using the OpenMaptiles-SQL-Layers as the query-source result in tiles which can contain duplicated keys.

This is because PostGIS `ST_AsMVT` is used to generate the Tiles and due to the way they [implemented parallelization](https://trac.osgeo.org/postgis/ticket/4310).

Although it is not prohibited by the Mapbox-Vector-Tile-Specification MapBox as well as MapLibre depending on version either throw a lot of warnings or even crash when encountering tiles with duplicated keys.
https://github.com/mapbox/vector-tile/issues/55
https://github.com/maplibre/maplibre-native/issues/795

After investigating I identified the boundary layer in zoom-leves 1 - 4 as the only layers containing duplicated keys.
2023-07-10 11:50:31 +02:00
Tomas Pohanka 103e37bd2c
Update readme links. (#1560)
Update links to Slack and lake lines.

Fix #1559
2023-07-05 13:03:42 +02:00
Andrea Mennillo a548093e08
transportation style: remove whitespace in color value (#1550)
Trivial fix for style validation failure with maplibre@3.0.1
2023-06-19 19:20:40 +02:00
benedikt-brandtner-bikemap 66731f3544
LineString Merging Updates (#1538)
This PR addresses two main issues introduced by the new ID-Based Merged-LineString Updates

1. Partial Indexes can only be accessed when the query matches more or less exactly and the query-planner will fail to use indexes when targeted via the join-condition and not the where-condition
    - `osm_transportation_merge_linestring_gen_z9`
    - `osm_transportation_name_network`
    - `osm_shipway_linestring`
    - `osm_aerialway_linestring`
    - `osm_waterway_linestring`
2. When intersecting updated Source-LineStrings with the existing Merged-LineStrings we join the Source-IDs of each existing Merged-LineString. This bloats the table unnecessarily and slows down bigger updates considerably.
    - This is addressed by aggregating the Source-IDs of each existing Merged-LineString into an array and concatinating these arrays when grouping them. Afterwards we add the IDs of updated SourceLineStrings and deduplicate the result before adding it to the Source-IDs-Table.
2023-06-19 10:12:57 +02:00
benedikt-brandtner-bikemap d8a264cd0c
remove leakproof attribute from functions; (#1535)
LEAKPROOF requires the executing user to have superuser privileges when creating the functions which would be the only statement required to be executed as a superuser.
2023-06-14 11:31:12 +02:00
benedikt-brandtner-bikemap d0d87e52d5
fixed analyzing of changes table in refresh_[shipway/aerialway]_linestring (#1536)
Fixes a typo analyzing the `name_changes` table during execution of `transportation_name.refresh_shipway_linestring` and `transportation_name.refresh_aerialway_linestring`
2023-06-13 18:13:17 +02:00
Christopher Beddow 80bc6518ab
Paint (#1435)
Paint shop is missing from the schema, so shops of this type do not appear on the map beside other POIs
---------

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2023-05-16 14:19:29 +02:00
Yaser Kalali 692b0a7afe
Fix issues in compose and quickstart.sh (#1530)
* Chore(quickstart.sh):

Handle spaces in fonts name when calculating their md5 digest

* Chore(Makefile):

Change docker pull to docker-compose pull to read image from compose file
2023-05-15 12:36:15 +02:00
Brian Sperlongano aea2b734da
Update park layer description to include indigenous lands addition (#1526)
This PR updates the park layer description to reflect #1489 and clarify why we chose to place them in this layer (technology reasons).
2023-05-10 10:25:31 +02:00
William Edmisten 5153dffe4a
Use area name for mbtiles in quickstart.sh (#1523)
Some parts of quickstart.sh reference `${area}.mbtiles`, but the file that gets created with the default `.env` is `tiles.mbtiles`. We should either reference `$MBTILES_FILE` instead, or override the filename with `${area}.mbtiles` (which is the approach taken by this PR).
2023-05-10 09:33:44 +02:00
Brian Sperlongano 9969c5c741
Remove unused indexes (#1520)
Based on analysis from planet builds for this layer as well as running updates via the integrity script as discussed in #1516, these three indexes are not used and can be removed.
2023-05-10 07:39:45 +02:00
benedikt-brandtner-bikemap 91dd853a89
Transportation_route_member_coalesced constraint errors
Multi-Column Primary-Keys (Unique-Constraints) must not contain NULL values in postgres up until version 15.

This PR coalesces NULL to empty strings for the primary columns during `transportation_route_member_coalesced` updates and import.

Additionally adds the missing `concurrency_index` to UPSERT statement of `transportation_route_member_coalesced`
2023-04-26 22:19:34 +02:00
Brian Sperlongano b3d67ed5b3
Add aboriginal lands (#1489)
This PR adds support for `boundary=aboriginal_lands` by adding it to the `park` layer. While these lands are certainly not "parks", they have similar treatment from a technology perspective and can benefit from the existing processing chain established in that layer. I set all of these objects to `class=aboriginal_lands` in the tiles, including at the lowest zoom in order to separate it from the protected area merging implemented in #1160. In order to distinguish these from general parks, I expose the `class` attribute for these objects at z4 and also ensure that the z4 generalization is performed separately for protected areas versus aboriginal lands.

This unblocks #ZeLonewolf/openstreetmap-americana#105, which describes why having indigenous land boundaries is an important general feature on the map. This is also consistent with my suggested implementation in https://github.com/openmaptiles/openmaptiles/issues/1296#issuecomment-967749403.
2023-04-04 13:20:41 +02:00
Brian Sperlongano 6f2b39e657
Fix index typo (#1522)
This PR fixes a copy/paste error which caused the z2 boundary layer index to be created twice and the z1 index to not be created at all.
2023-03-28 10:33:18 +02:00
benedikt-brandtner-bikemap f3dbb0a839
Refresh osm_park_polygon_dissolve_z4 materialized view after update in update_park_polygon.sql (#1515)
Refresh osm_park_polygon_dissolve_z4 materialized view after update in update_park_polygon.sql.
2023-03-23 13:30:23 +01:00
benedikt-brandtner-bikemap 54e24207a1
Improved update performance of waterway layer (#1514)
Improved update performance of waterway layer
- Refactored LineString-merging and diff updates in update_important_waterway.sql
2023-03-23 08:05:15 +01:00
benedikt-brandtner-bikemap d937705292
Update Performance water_name Layer (#1513)
Improved update performance of water_name layer
- Implemented diff updates for update_water_lakeline.sql and update_water_point.sql
- Unified update_water_lakeline.sql and update_water_point.sql to update_water_name.sql
- Refactored IDs to be unique in water_name_marine.osm_ids
- Restricted updates to INSERT and UPDATE operations during water_name_marine.refresh
- Added analyze statements before update queries during water_name_marine.refresh
2023-03-22 21:28:21 +01:00
benedikt-brandtner-bikemap b2a57b3755
Update Performance transportation_name Layer (#1512)
Improved update performance of transportation_name layer
- Refactored LineString-merging and diff updates in update_transportation_name.sql
- Refactored transportation_route_member_coalesced materialized view to table
- Added analyze statements before update queries during transportation_name.refresh_network and update_osm_route_member
2023-03-22 19:39:18 +01:00
benedikt-brandtner-bikemap 8321574565
Improved update performance of transportation layer (#1511)
Improved update performance of transportation layer
- Refactored LineString-merging and diff updates in update_transportation_merge.sql
2023-03-22 16:48:27 +01:00
benedikt-brandtner-bikemap 0e8e2512e8
Update Performance poi Layer (#1510)
Improved update performance of poi layer
- Refactored update_poi_point.sql to partial diff update
- Refactored IDs to be unique in poi_polygon.osm_ids
- Restricted updates to INSERT and UPDATE operations during poi_polygon.refresh
- Added analyze statements before update queries during poi_polygon.refresh
2023-03-22 15:07:10 +01:00
benedikt-brandtner-bikemap 3caa11aee9
Improved update performance of place layer (#1509)
Improved update performance of place layer
- Refactored IDs to be unique in the following tables
  - place_city.osm_ids
  - place_continent_point.osm_ids
  - place_country.osm_ids
  - place_island_point.osm_ids
  - place_island_polygon.osm_ids
  - place_state.osm_ids
- Added analyze statements before update queries and restricted updates to INSERT and UPDATE operations during execution of the following functions
  - place_city.refresh
  - place_continent_point.refresh
  - place_country.refresh
  - place_island_point.refresh
  - place_island_polygon.refresh
  - place_state.refresh
2023-03-22 14:00:10 +01:00
benedikt-brandtner-bikemap 1126e30d0d
Improved update performance of mountain_peak layer (#1508)
Improved update performance of mountain_peak layer
- Refactored IDs to be unique in mountain_linestring.osm_ids and mountain_peak_point.osm_ids
- Restricted updates to INSERT and UPDATE operations during mountain_linestring.refresh and mountain_peak_point.refresh
- Added analyze statements before update queries during mountain_linestring.refresh and mountain_peak_point.refresh
2023-03-22 12:13:05 +01:00
benedikt-brandtner-bikemap d97d86320b
Do not raise errors with diagnostics code after local test in order to let executors of the script propagate the appropriate status-code (#1519)
Propagate the appropriate status-code during failed unit-test runs. (eg.: CI-Runs)
2023-03-22 07:56:34 +01:00
benedikt-brandtner-bikemap 7bdf1ae409
Improved update performance of housenumber layer (#1507)
Improved update performance of housenumber layer
- Refactored IDs to be unique in housenumber.osm_ids
- Restricted updates to INSERT and UPDATE operations during housenumber.refresh
- Added analyze statements before update queries during housenumber.refresh
2023-03-21 20:24:47 +01:00
benedikt-brandtner-bikemap d8a8c81f79
Improved update performance of aerodrome_label layer (#1506)
Improved update performance of aerodrome_label layer
- Refactored IDs to be unique in aerodrome_label.osm_ids
- Restricted updates to INSERT and UPDATE operations during aerodrome_label.refresh
- Added analyze statements before update queries during aerodrome_label.refresh

See #1433 for more detailed discussion.
2023-03-21 18:09:32 +01:00
benedikt-brandtner-bikemap f918f4d607
Local Test Fixes (#1505)
This PR fixes local tests affected by the changes introduced in #1440 #1444 #1361 #1501
2023-03-21 11:33:50 +01:00
Brian Sperlongano 81d29fff2b
Add convenience script to run the integrity test locally (#1495)
This PR adds a script that allows a developer to run the "integrity" CI script without actually creating a PR.
2023-03-17 07:53:21 +01:00
William Edmisten 02dcc41e1f
Support new docker compose version (#1497)
Currently the Makefile and `quickstart.sh` expect the [deprecated docker compose V1](https://docs.docker.com/compose/#compose-v2-and-the-new-docker-compose-command) syntax, `docker-compose`.
The new V2 syntax uses `docker compose` instead.
2023-03-15 22:16:00 +01:00
Brian Sperlongano e5a5acfa99
Render long-distance ferries at longer zooms (#1486)
In some areas of the world, ship transportation is the main means of long-distance travel.  For example, in Alaska, the [Alaska Marine Highway System](https://dot.alaska.gov/amhs/route.shtml) is the principal means of transportation through the Alaska Panhandle and down the Aleutian island chain.  The AMHS carries the same importance that the Interstate Highway System has on land, and these ferry routes are exceptionally long distance.
2023-03-15 16:55:47 +01:00
Brian Sperlongano d8c367f42c
Remove bridge/tunnel attributes from tiny bridges (#1283)
This PR now removes bridge/tunnel/ford attributes from the `transportation` layer from sections of bridge/tunnel etc that are too small to be meaningfully visible at a particular zoom level.  This allows those segments to be generalized into geometries along with the surrounding sections of road, thereby dropping lots of useless little pieces of geometry in lower-zoom tiles.
2023-03-15 13:22:08 +01:00
Brian Sperlongano 0c6dd1fecb
Update Slack link (#1494)
This PR updates the link to Slack in the contributor's guide.
2023-03-06 19:14:01 +01:00
Brian Sperlongano b7edcf6153
Convert osm_route_member unique index to trigger (#1501)
This PR changes the three-column unique index to an on-insert trigger. This should fix the issues we're having with CI failures and still achieve the behavior of coalescing duplicate routes. 

I moved the concurrency_index calculation into an intermediate materialized view to separate the de-duplication capability from both DENSE_RANK() and from imposm updates.
2023-03-06 17:10:30 +01:00
Tomas Pohanka 624cf7a8a3
Minor docs enhancement. (#1481)
Update docs, links, and comments.
2023-01-30 14:04:47 +01:00
Brian Sperlongano 5e9b7c475d
Add grade 1 tracks to paved (#1485)
This PR sets `surface=paved` for `highway=track` + `tracktype=grade1` if no other value of `surface` is set.  Roads tagged in this way are [generally paved](https://wiki.openstreetmap.org/wiki/Key:tracktype) and therefore encoding them as a paved road is appropriate.
2023-01-26 19:24:44 +01:00
Tomas Pohanka d2c69b0d45
Fix stops aggregation in osm_poi_point. (#1480)
This PR fixing the stops aggregations which now returns always `NULL` and wasn't reflected in the tiles.
2023-01-26 17:57:31 +01:00
Brian Sperlongano bc9bbd2e67
Coalesce duplicate route concurrencies (#1361)
# Problem description
#1128 introduced route relation concurrency information in OpenMapTiles via the `route_X` attributes.  The original implementation assumed that there would be a single route relation for each `network` and `ref` pair.  However, it is increasingly common practice to tag a separate route relation for each direction of a route in order to provide awareness to routers and other data consumers of the directionality of a route.  This standard and growing practice is described on the [OSM wiki page on route directions](https://wiki.openstreetmap.org/wiki/Route_directions).  Thus, the naïve implementation of #1128 caused duplicate entries to be added as `route_X` attributes in the case where separate route relations were used for directional routes.

# Solution description
This PR adds grouping when computing route concurrency information, such that duplicate entries are coalesced in a predictable way.  Since this grouping is done only within a route membership join of a single member way, the computational complexity should be trivial.
2023-01-26 16:15:47 +01:00
Brian Sperlongano efa6b27fba
Render POIs for large universities at low zoom (#1479)
This PR adapts the code used in #1457 to allow POIs to render up to z10 for very large features. I set the threshold at a very conservative value of 10% of a tile. Thus, it will render if an area POI covers at least 10% of a tile at a given zoom. Only for 'university' and  'college'.

Additionally, this consolidates a double UNION ALL on the same table with a WHERE/CASE combination, which is simpler.
2023-01-19 19:29:29 +01:00
Brian Sperlongano f9e358c962
Add substantial missing languages in the US (#1477)
This PR adds eight missing languages, all of which are among the top 25 languages spoken in the United States, as discussed in ZeLonewolf/openstreetmap-americana#586, and have at least 10,000 `name:xx` usages in the database. Additionally, most of these languages are the primary or national language in the countries where they are most commonly spoken.
2023-01-17 10:38:31 +01:00
ttomasz 3b4650fca1
Tile duplicate housenumber filtering (#1391)
This PR introduces simple filtering of duplicate housenumbers.

Simple means that filtering is done withing the tile.
Duplicates are defined as same housenumber, street, block_number[1].

Duplicates are usually caused by POIs. People like to add addresses to them. Most POIs have names so to prioritize addresses we pick features without names first.

Formula is: `row_number() OVER(PARTITION BY concat(street, block_number, housenumber) ORDER BY has_name ASC) == 1`
2023-01-17 09:34:27 +01:00
Brian Sperlongano 168e8300c0
Allow lakelines at native sizes (#1475)
This PR reduces the minimum lake line zoom to z3, allowing the largest lakes to show a renderable label. The lakeline function is restricted by the LineLabel() function, which limits lakelines to only those that are big enough to render a text label.  Therefore, further restricting lakelines by zoom is not necessary.
2023-01-16 11:33:43 +01:00
Brian Sperlongano edb42f2db3
Routes of Ireland (#1466)
This PR follows #1465 to implement pseudo-route relations for Republic of Ireland road routes as described in the [OSM wiki](https://wiki.openstreetmap.org/wiki/Ireland/Roads). Irish road routes work in the same way as UK road routes in that signage is derived from highway classification on a 1:1 basis. The scheme described in the OSM wiki is confirmed via [overpass query](https://overpass-turbo.eu/s/1por).

This feature follows the implementation currently used for UK road routes, in which a 10m Natural Earth polygon is used to determine which roads are located within Ireland to apply this processing.

This PR implements 3 classes of routes:
* M-roads, which are `highway=motorway` and signed with blue/white lettering.
* N-roads ("national roads"), which are `highway=trunk` or `highway=primary` and are signed with green/yellow lettering.
* R- and L-roads ("regional and local roads"), which are `highway=secondary`, `highway=tertiary` or `highway=unclassified`, and signed with white/black lettering
2023-01-15 13:52:43 +01:00
Brian Sperlongano 8b5aa3273e
Add other river-like water area features to class=river (#1467)
Currently, river areas (`natural=water` + `water=river`) are rendered in the tiles as `class=river`.  However, canal, stream, ditch, and drain water areas are rendered as `class=lake`.  Since these types of objects are all flowing water, they should be grouped together into `class=river`, which allows for styles that render flowing water differently to do so on a consistent basis.
2023-01-14 13:36:02 +01:00
James Westman 569e9cd5b4
Add borough to supported place classes (#1470)
Adds a new class value for the place layer, `borough`, and adds it to the OSM style with the same appearance as hamlets and suburbs.
2023-01-10 16:36:08 +01:00
Brian Sperlongano 5f7b2c11b3
Add GB primary/secondary routes (#1465)
This PR adds an additional pseudo-network for UK non-primary [routes](https://en.wikipedia.org/wiki/Great_Britain_road_numbering_scheme), which are signed with black on white signage with "A" and "B" prefixes. This scheme is described on the [OSM wiki](https://wiki.openstreetmap.org/wiki/Roads_in_the_United_Kingdom). Adding this third psuedo network is needed for generating shields for UK white/black signage for non-primary routes. 
Additionally, this fixes a minor bug under which single-digit refs would have been included.  Single-digit refs don't exist in the UK, because the numbering scheme is always prefixed by a letter, e.g. "A4".

I also included documentation updates and fixed the typo where a view was named "bg" instead of "gb".
2023-01-10 14:50:24 +01:00
Brian Sperlongano af8c6883dd
Revamp water label display logic (#1457)
* At zooms 9-13, water labels will now be rendered for water features that are at least 0.25 tiles in size.  This means that water features that are the same size as a 128x128 pixel square will get a point label.
* Labels for large water features are now shown at the lowest zoom at which it's appropriate to show a label.
* Bay and strait names (`natural=bay` and `natural=strait`) are included. 
* Large seas modeled as areas (e.g. Caspian Sea) render as `class=sea` rather than `class=lake`
2023-01-10 13:39:54 +01:00
Daniel Schep cd77b07e46
improve `class=path` styling (#1450)
This PR addresses that by:

* rendering oneway arrows on more than `subclass=cycleway`
* less opacity for path/footway casing
* adding the thin black casing to bridges
* adding `subclass=steps` & `subclass=bridleway` rendering
* render `bicycle=designated` as `subclass=cycleway` and `horse=designated` as `subclass=bridleway` (bike taking priority)
* improved tunnel rendering with double casing & adding main line
* made casing min zoom consistent across subclasses

All of these changes were made to mimic OSM Carto.
2023-01-06 10:08:03 +01:00
Brian Sperlongano 4d5fa84184
Add class=pond to the water layer (#1456)
This PR proposes to add a new class, "pond" to the water layer, which allows for a style to de-emphasize minor bodies of water (tagged `water=pond,basin,wastewater`) when compared to more significant objects tagged reservoir/lake.  This PR retains the default behavior of classifying a water body as a "lake" if more specific tagging is not added.
2023-01-06 08:44:11 +01:00
Brian Sperlongano 29e49f9424
Sub-national routes in Canada and refactor national network list (#1446)
This PR defines the set of routes in Canada which are equivalent in national importance to the US Interstate Highway System, and are therefore appropriate to render at zoom 4. This creates a sane, connected highway network at this zoom level across the USA and Canada.

This adds two additional network types for Canadian highways, ca-provincial for provincial-level roads, and ca-provincial-arterial for "highest importance" roads that are not part of the Trans-Canada highway but should be regarded as equivalent for low-zoom rendering purposes.

Additionally, this extracts out the country-specific network checks to a separate function in order to define "equivalent top-level networks" by country, providing a place to add additional national definitions as they're added by contributors.
2023-01-05 17:36:36 +01:00
Brian Sperlongano c4d86d44a6
Fix zoom ordering (#1444)
This PR improves the behavior introduced in #1440, which inadvertently included all motorways at z4, which was unintended.  Instead, this PR provides an appropriate progression from z4 to z5 with the highest national-importance highways being rendered at z4 (including where they degrade to trunk, as in Canada), and all motorways being added to the mix at z5.
2022-11-28 19:19:29 +01:00
Adam Laža aa9c39ba3b
Add `build-style` and `download-fonts` targets. (#1445)
This PR adds `build-style` and `download-fonts` targets to `start-tileserver` target. 

Calling `build-style` and `download-fonts` ensures that there is the OSM OpenMapTiles style build and ready and fonts downloaded.
2022-11-28 15:56:00 +01:00
Brian Sperlongano ca4a64ba72
Add transcanada highway to z4 (#1440)
This adds support to show the Trans-Canada Highway at zoom 4.  Despite being the most important highway network in Canada, portions are `highway=trunk` due to the remoteness of the countryside.  However, it's still important to show a connected highway network at the lowest zoom without showing all trunk roads at this zoom.

This change also adds support for US Interstate Highways to be drawn at z4 when they're tagged as trunks.  There's only a few examples of this, but it removes those (tiny) gaps from the generalized road geometries. As we identify additional countries which should have their most important road network rendered at the lowest road zoom even if they're trunk, we can add them to the list of networks that get this treatment.
2022-11-15 17:33:29 +01:00
Thomas Helmrich 567939b5ce
added information about how to prevent a possible error during 'generate-tiles-pg' (#1432)
Added a comment within docker-compose.yml to prevent an error during `make generate-tiles-pg`
2022-10-20 11:11:44 +02:00
Tomas Pohanka 4cb65b0a4f
Prerelease update docs. (#1425)
Update documentation before release v3.14.
2022-10-07 08:58:46 +02:00
Adam Laža f21b677083
OSM OpenMapTiles style (#1420)
* OpenMapTiles style

* Rename style snippets from layer_name.json to defaultstyle.json

* Add README to icons dir.

* Add README to icons dir.

* Rename snippets to style.json

* Fix spritezero - move icons to svg subdir

* Move icons from style/icons/svg directly to style/icons

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2022-10-06 16:09:21 +02:00
Tomas Pohanka cd0ffacc72
Update capital possible values (#1421)
Update documentation about a place - capital possible values.

Based on https://github.com/openmaptiles/openmaptiles/pull/1401
2022-09-28 14:42:51 +02:00
bgo-eiu 6212c056ea
Added quarry to landuse list (#1404)
This includes quarry in the list of landuse features

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2022-09-08 11:43:48 +02:00
Tomas Pohanka 6e73058a23
Class shipway (#1415)
In `transportation_name` layer for `shipway` used Instead of `subclass` use `class` attribute for `ferry`. But `subclass` remains.
2022-09-08 09:10:42 +02:00
Tomas Pohanka e079e82cb1
Better generalization for `landuse=residential`. (#1414)
This PR creates larger polygons of `residential` land-use areas for upper zoom levels (especially for zoom 6 - 10).

Clusters are created with the same logic as for [`building on z13`](b14da2eafb/layers/building/update_building.sql (L34-L49)).

The generalization of land-use prolongs the `import-sql` step of the `landuse` layer. But it is still faster than the `building z13` generalization which with the parallel importing keeps the whole `import-sql` time untouched.
2022-09-02 10:01:41 +02:00
Tomas Pohanka 029033a593
Filter a bigger areas for landcover z7 - z13 (#1413) 2022-09-01 15:02:15 +02:00
Tomas Pohanka b14da2eafb
Update to Natural Earth v5.1.2 (#1409)
This PR updating Natural Earth dataset from v4.1 to 5.1.2. It is in cooperation with https://github.com/openmaptiles/openmaptiles-tools/pull/414, where is `import-data` docker image updated.

PR removes manual fixes for lake merging (already fixed in version 5.1.2)

Switched comparison from `gn_ascii` (removed from NE5) to `name_en`.

Could be merged after https://github.com/openmaptiles/openmaptiles-tools/pull/413. After OMT-T is merged, it will use `latest` image (until the release of OMT-T v7)
2022-08-02 15:47:43 +02:00
Tomas Pohanka dae00f2604
Add missing requires NE tables to layers. (#1410)
Adding missing requires Natural Earth tables for layers.
2022-08-02 14:22:58 +02:00
zstadler 1c1231e430
Update UPDATE.md including Makefile improvements (#1408)
- Add `make import-diff` and `make generate-changed-tiles`
- Update `UPDATE.md` accordingly
- Other updates and clarifications in `UPDATE.md`
2022-07-26 18:59:34 +02:00
Clay Smalley 337f81284d
Add highway=bus_guideway (#1407)
Guided busways (or bus guideways in OSM terminology) are special roadways along which bus operators can travel smoothly at high speeds without steering. These are tagged highway=bus_guideway on OpenStreetMap.

Currently, highway=busway is surfaced in OpenMapTiles as the busway class in the transportation layer, but highway=bus_guideway is not present. These two types of roadways serve generally similar purposes, so it would make sense to have guided busways at the same zoom levels.
2022-07-26 15:26:57 +02:00
Brian Sperlongano 5e51627895
Remove support for waterway=riverbank (#1405)
This PR removes support for `waterway=riverbank`.  Usage of waterway=riverbank has [declined to globally insignificant levels](https://taginfo.openstreetmap.org/tags/waterway=riverbank).

In other projects:
* Support for `waterway=riverbank` was removed from the iD editor in openstreetmap/iD#5591
* Removal of `waterway=riverbank` was tracked for JOSM in [JOSM ticket 21630](https://josm.openstreetmap.de/ticket/21630) and was completed in revision [18519](https://josm.openstreetmap.de/changeset/18519/josm)
* Removal of `waterway=riverbank` from openltmap (Lithuania vector map) occurred in [[1]](507f095b35)
2022-07-26 14:34:02 +02:00
Brian Sperlongano 9c78c15943
Add support for county seats (capital=6) (#1401)
This PR adds support for `capital=6` in the place layer, which is used for tagging county seats in the US.  A county seat is the capital of a county.  In addition, I reorganized the code a bit to be simpler.

As noted in ZeLonewolf/openstreetmap-americana#384, we would like to render county seats along with state and national capitals, as this is typical styling on American-style maps.

Update with also with `capital=3` and `capital=5`
2022-07-26 13:19:16 +02:00
SahAssar dc1e21fccc
Change typecheck to perform within the current namespace/schema (#1389)
This PR fixes #1388 by doing a test cast for the type and if it fails adding the type.
2022-07-26 12:26:46 +02:00
Jeroen Hoek da7b1b1645
Add natural=shrubbery to landcover (#1397)
This adds `natural=shrubbery` to landcover (next to the similar `natural=scrub`).

Fixes #1396
2022-06-01 18:20:35 +02:00
Ryan Russell b3af3d47d6
docs - fix functions (#1395)
fix typo
2022-06-01 10:01:44 +02:00
ttomasz 82b00c1389
Add POI parcel locker (#1390)
closes #1370 

This PR adds a parcel locker to post class.

Similarly to ATMs from PR #1375 if a name is not present we try to use `brand` or `operator`. Here we also try to add `ref` to the brand or operator since it can disambiguate parcel lockers that are next to each other (which happens).
2022-06-01 09:32:10 +02:00
Tomas Pohanka 7d52c9a9e5
Update before minor release (#1386) 2022-05-06 07:49:57 +02:00
Tomas Pohanka 5820534153
Add swimming pool to class attribute. (#1385)
This PR adds swimming pools as a class in the water layer. Until now all swimming pools were classified as `lake`.
2022-05-05 20:57:51 +02:00
Tomas Pohanka 51751b5b78
Add OSM ID to the lakes (#1383)
This PR adding OSM ID to the lakes

OSM lakes are used from zoom 6
From zoom 0 to zoom 5 are used Natural Earth lakes. 
  - There is a new joining mat. view (`match_osm_ne_id`) contains which Natural Earth ID should convert to OSM ID. This logic is used to keep a consistent ID between switching between NE (zooms 0 - 5) and OSM (zooms 6 - 12). For smaller areas (not the whole planet), where are not available OSM lakes, the NE lakes keep their NE ID.
  - There are also switch the final views to the mat. views - this should slightly increase performance (get rid of multipolygons).
  - FIX typo for zooms 0 - 3 (`lakes` instead of `lake`).
2022-05-05 14:26:57 +02:00
Adam Laža ef9a68b19a
GE-871 upsert network_type column in update_osm_route_member (#1384)
Fixes #1374 

This PR fixes `update_osm_route_member()` function. Before this the column `network_type` became empty after daily-update.
This PR adds `network_type` into upsert together with `rank` and `concurrency_index` columns.
This bug had occurred once already and had been fixed in https://github.com/openmaptiles/openmaptiles/pull/1239 but then some columns were added and these new columns were not added into the upsert.
2022-05-05 13:14:35 +02:00
Frédéric Rodrigo b8e87fbf07
Use diff generalization on osm_important_waterway_linestring_gen_z* (#1359)
Replace the `REFRESH MATERIALIZED` on `osm_important_waterway_linestring*` by differential update.

The way of doing this is the same as other differential updates.
2022-05-04 15:43:25 +02:00
Frédéric Rodrigo bff74511b6
Use diff update on osm_transportation_merge_linestring (#1357)
Replace the `REFRESH MATERIALIZED` on `osm_transportation_merge_linestring_gen_z*` by differential update.

The way of doing this is the same as other differential updates. But in this case there two `GROUP BY` level. So all the the process have to be done twice.
2022-05-04 14:22:15 +02:00
zstadler 5add9a5cef
Restore controlability with environment variables (#1364)
Since PR #922 the contents of `.env` are included in `Makefile` in order for `make` to by aligned with the `docker-compose` settings.

```
# Make all .env variables available for make targets
include .env
```

The down-side of employing the `include` mechanism is that the settings  in `.env` now take higher precedence than the shell environment variables. As a result, controlling the OpenMapTiles flow because more difficult. For example, tests for `DIFF_MODE=true` had to modify the contents of `.env` in order to work:
b0e7f7884c/.github/workflows/integrity.yml (L45-L47) and
b0e7f7884c/Makefile (L629-L630)

Users were also faced with similar difficulties.

This PR restores the ability to control `make` and `quickstart.sh` using environment variable while keeping the use of the `.env` at a lower priority.

The result is restoring the ability to easily adjust the OpenMapTiles flow using environment variables, such as:
```
PGPORT=54321 DIFF_MODE=true ./quickstart.sh monaco
```

#### Notes: 
1. This PR depends on #1363
2. This PR includes some clean-up of `Makefile`
2022-04-28 09:30:15 +02:00
Brian Sperlongano df6906b7b5
Remove unneeded waterway='' check (#1377)
This PR removes an unnecessary check in water.yml.

generated SQL before:
```
SELECT CASE
           WHEN waterway='riverbank' THEN 'river'
           WHEN "waterway" = 'dock' THEN 'dock'
           WHEN "water" = 'river'
               OR "waterway" = 'riverbank'
               THEN 'river'
           WHEN "waterway" = '' THEN 'lake'
           ELSE 'lake'
           END;
```

generated SQL after:
```
SELECT CASE
           WHEN waterway='riverbank' THEN 'river'
           WHEN "waterway" = 'dock' THEN 'dock'
           WHEN "water" = 'river'
               OR "waterway" = 'riverbank'
               THEN 'river'
           ELSE 'lake'
           END;
```

The `waterway=''` test is purely redundant because it returns the same value as the fall-through ELSE case: `lake`.
2022-04-25 13:42:01 +02:00
ttomasz ca9e8f4e52
adds ATM to POI layer (#1375)
This PR adds ATM to POI layer.
If ATM isn't provided with a name tag we'll try to use operator or network instead.
2022-04-25 10:29:08 +02:00
zstadler 2d0b7159d0
Update aerodrome_label class in DIFF_MODE=true (#1371)
The class field was not updated if needed during the import of changes in DIFF_MODE=true.
2022-04-20 05:50:37 +02:00
zstadler 22915df783
Allow non-default `PGPORT` (#1363)
- Allow use of environment variables in addition to .env
- Remove .env-postgres and the need to synchronize it with .env

Resolves #1354
Related to https://github.com/openmaptiles/openmaptiles-tools/pull/403
2022-04-19 21:33:03 +02:00
Matt Riggott 8693822d50
Add documentation on islands in place layer (#1362)
Islands have been part of the OpenMapTiles schema for more than five years (see commits d664a2fe and 01db9a4e and issue #68), but they're not documented in [the layer definition](https://github.com/openmaptiles/openmaptiles/blob/master/layers/place/place.yaml) or [on openmaptiles.org](https://openmaptiles.org/schema/#place). This PR fixes that by updating `layers/place/place.yaml`.
2022-03-14 08:29:47 +01:00
zstadler b0e7f7884c
Use `docker-compose up -d` for on-going processes (#1353)
Make targets `start-tileserver`, `start-maputnik`, and `update-osm` initialize on-going processes rather than perform a one-time task. It is more appropriate to execute them using `docker-compose up -d`. With the current `docker-compose run` execution, the user needs to run `make` as a background process. This PR also allows the use of `docker-compose logs` rather than the need to handle `stdout` and `stderr` redirection and avoids the dependency of `stdin` handling for `docker-compose run`

Using `docker-compose` rather than `docker`
Use appropriate` start-*` and `stop-*` make target names

Resolves #1352
2022-02-22 12:43:59 +01:00
Matt Riggott b13ab9491f
Add more aerialway tags to transportation layer (#1343)
Before this, only `aerialway=cable_car` and `aerialway=gondola` were included in the tiles. That misses some widely-used tags, notably `aerialway=chair_lift`, `aerialway=drag_lift`, and `aerialway=platter`. The usage of all the tags added in this commit, by fraction of all aerialway way keys (according to TagInfo), is:

| Tag                    | Usage  |
|------------------------|-------:|
| `aerialway=chair_lift` | 25.51% |
| `aerialway=drag_lift`  | 12.93% |
| `aerialway=platter`    | 11.35% |
| `aerialway=t-bar`      |  7.93% |
| `aerialway=j-bar`      |  0.63% |
| `aerialway=mixed_lift` |  0.24% |

Some of these tags were also added in PR #620 back in May 2019, but were removed again before it was merged.

Fixes #1342.
2022-02-17 13:08:39 +01:00
Tomas Pohanka 81ddab9f9a
Updates documentation for 3.13 (#1350)
Adding missing information in `layers.yaml` files for 3.13
2022-02-09 12:38:47 +01:00
Adam Laža 7f08414f20
Use equal operator in combination with coalesce() function instead of IS NOT DISTINCT FROM operator. (#1344)
Updates on `transporation_name` layer take much more time than before.

In 3.13 there had been introduced highway concurrency into `transportation` and `transportation_name` so I expected the update process will take more time but not that much. Because of this it's impossible to use updates on larger areas because the process takes too long.

The issue is caused by `IS NOT DISTINCT FROM` operator over `tags` (hstore) columns. I replaced it with `=` operator in combination with `coalesce()` function which returns the same results but in shorter time.
2022-02-04 15:25:47 +01:00
Alexander Menk ff8cecf8ab
Doc: Updating tiles (#1340)
This tried to improve the documentation on Updates
2022-02-04 14:19:33 +01:00
ePirat a236bbec5c
Fix version check in quickstart.sh (#1333)
When docker compose returns a version with v prefix,
the version check would incorrectly treat it as version component
of 000, leading to always failing the docker-compose version check
even if the version is recent enough.

This happens at least with docker-compose 2.2.1 where
  docker-compose version --short
returns v2.2.1 with the leading v.
2022-02-04 13:50:47 +01:00
Adam Laža 2e04f83166
Fix paths and tracks in transportation layer z12 and z13 (#1334)
This PR fixes a bug that causes that `track` lines disappear at z13. This bug was introduced in https://github.com/openmaptiles/openmaptiles/pull/1190, which adds rendering of paths and tracks at z12 and z13.

Before this PR:
z12: lines with `route_rank = 1` are added (no matter what `highway`).
z13: lines with `route_rank BETWEEN 1 AND 2` and `highway = 'path'` are added.
-> tracks with `route_rank=1` are added at z12 but not at z13.

After this PR
z12: lines with `route_rank = 1` and `highway IN ('path', 'track')` are added.
z13: lines with `route_rank BETWEEN 1 AND 2` and `highway IN ('path', 'track')` are added .
-> only tracks and paths are added at z12 and z13 (which was IMHO the goal of https://github.com/openmaptiles/openmaptiles/pull/1190)

* Add only the most important paths and tracks (route_rank=1) to z12 and more important ones (route_rank between 1-2 or sac_scale or has name) to z13.
2022-01-05 07:28:34 +01:00
Tomas Pohanka 7d08e5b97e
Remove FILTER_MAPNIK_OUTPUT (#1327)
Remove `FILTER_MAPNIK_OUTPUT` variables from docker-compose which stop raising warnings during start-up dockers.

This functionality was removed in https://github.com/openmaptiles/openmaptiles-tools/pull/349.

The current version of the mapnik does not need `FILTER_MAPNIK_OUTPUT`.
2021-12-08 13:40:48 +01:00
Tomas Pohanka 73dcd23497
Run get_basic_name after osml10n_street_abbrev_* (#1326)
PR move `get_basic_names(tags, geometry)` function from `transportation_name_tags` function and adding it after `transportation_name_tags` resolve street abbrevation.

PR runs through `test-sql` test without error. Adding to `osm_transportation_name_network` (table and for update) was done in consequence of `test-sql` errors ([update test 500](a747d98550/tests/test-post-update.sql (L53))). Originally `get_basic_names` was just in `osm_transportation_name_linestring` table.

FIX #1324

![seattle_fix](https://user-images.githubusercontent.com/5182210/145085141-7857e97e-9b83-4467-bb98-84cc4a2e0623.png)
2021-12-08 08:20:15 +01:00
Tomas Pohanka a747d98550
Update TESTING.md (#1325)
Fix typo
2021-12-07 19:13:17 +01:00
Tomas Pohanka 44ae83718c
Remove `STRICT` statement (#1320)
Remove `STRICT` statement from `transportation_name_tags` function.

Concurrently with remove `STRICT` from `get_basic_names` and `get_latin_name` in OMT-T

FIX #1319
2021-12-07 17:59:04 +01:00
Cody B. Daig 7838221b16
Update Quickstart.md with proper make list commands (#1316)
`make list` insn't a valid command. This updates the documentation with the proper commands.
2021-11-27 03:50:40 -05:00
Tomas Pohanka edaf9179b0
Update openmaptiles.yaml (#1315)
Preparation for release 3.13
2021-11-26 12:19:48 +01:00
Yuri Astrakhan 4eb8feb0ad
Use tools v6.1, improve .env docs (#1281)
* Add info about using MID_ZOOM to optimize tile generation
* Remove params for generation that are now automatically detected


Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2021-11-26 11:31:01 +01:00
Nicholas Skehin 207396269e
Implement aerialway labels (#1309)
This PR adds labels to `aerialway` linestrings after zoom level 12. I roughly followed PR https://github.com/openmaptiles/openmaptiles/pull/1179

These are useful in ski resorts and should not inflate the size of the tiles by much as aerialways are rare:
![Screenshot from 2021-11-18 12-18-58](https://user-images.githubusercontent.com/632493/142680225-1875904b-d146-4932-8a22-8c36919b875d.png)


Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2021-11-26 10:16:41 +01:00
Brian Sperlongano 7f23feab88
Add expressway tagging to the transportation layer (#1313)
Fixes #1148 

This PR adds expressway tagging to the `transportation` layer, by setting `expressway=1` for non-motorway roads tagged `expressway=yes`, and omitting the tag otherwise.  Additionally, I've added a few unit tests to verify that the expressway tagging is being imported and updated into the intermediate tables.

Here is an example of expressway tagging on US-1 in Rhode Island, USA:

![image](https://user-images.githubusercontent.com/3254090/143501278-db3671b2-2efa-4998-bffd-9ddfec63579b.png)
2021-11-26 07:55:20 +01:00
Brian Sperlongano ec74480414
BUGFIX: Fix name-based way fragmentation in transportation_name (#1295)
I discovered this bug while investigating issues with the updates process related to #1190 #1292, and #814.

The `transportation_name` layer produces slightly different `tags` hstore values in the `osm_transportation_name_linestring` table during the initial import versus when running an update.  As currently written, the import code produces null-value keys in the `tags` column, while the update code suppresses them.  This PR removes that difference and makes the import code use same method that is currently used in the update code.

With a test case I've written, the import code produces a tags hstore that looks like this:
`"name"=>"OpenMapTiles Secondary 2", "name:de"=>NULL, "name:en"=>NULL, "name_int"=>"OpenMapTiles Secondary 2", "name:latin"=>"OpenMapTiles Secondary 2"`

...while the update code produces a tags hstore that looks like this:

`"name"=>"OpenMapTiles Secondary 2", "name_int"=>"OpenMapTiles Secondary 2", "name:latin"=>"OpenMapTiles Secondary 2"`

Note the missing NULL values.

This bug causes a small amount of space wastage after an update is run, because the update matching code detects the `tags` value as different, resulting in a duplicate copy of the tags value if that row is updated.  This causes duplicate objects and breaks GROUP BY clauses that expect to group same-tagged features together.  I've tested this by inspection of a generated mbtiles, database spot checks, and the unit test code included in this PR.
2021-11-25 10:45:11 +01:00
Brian Sperlongano 0cff3449b5
Implement non-blocking refresh (#1308)
This PR implements non-blocking updates in the park layer.

The approach was to use the `REFRESH MATERIALIZED VIEW CONCURRENTLY` feature in postgres.  In order to achieve this, a unique index was added on the z4 dissolved park area table.  The `ST_Union` / `ST_Dump` sequence was changed to an explicit cluster DB scan (an equivalent operation) so that a unique osm ID could be generated from each dissolved polygon.

Below is a screen shot from Idaho, USA showing that the dissolved z4 still works as expected.

![image](https://user-images.githubusercontent.com/3254090/142341513-588045f0-7757-4acd-99e5-a50bbe6b0682.png)
2021-11-24 11:17:29 +01:00
Brian Sperlongano cdff735be1
Remove blank name tags (#1307)
This PR performs the same fix on the park layer that #1268 applied to the waterway layer.  It removes blank name, name_en, and name_de from the tiles.
2021-11-18 18:27:19 +01:00
Eva Jelinkova 054d3a7e4d
add province, increase scalerank + labelrank (#1306)
Add `province` (next to `state`) tag into `osm_state_point`
2021-11-18 18:05:02 +01:00
Brian Sperlongano 75d8c80228
Selective rendering of tracks and paths at z12-13 (#1190)
Closes #271

This PR adds track and path rendering at lower zooms than currently provided, and also achieves near-parity with openstreetmap-carto on track and path rendering. A previously-abandoned attempt, with significant discussion, was #1169.
2021-11-18 17:35:34 +01:00
zstadler 7f531c1dbb
Update "Verifying that updates still work" (#1290)
Convert the instructions into a single script that anyone can copy-paste to a terminal.
Add `make destroy-db` to the initialization part.
2021-11-16 07:58:16 +01:00
Eva Jelinkova 93d57a8d03
adding customary_ft for peaks in US (#1298)
Add tagging that will mark unit that is customary in the country. US peaks will include the tag `customary_ft=1`.
2021-11-15 16:55:35 +01:00
Brian Sperlongano d7ea45349e
Add highway tests (#1294)
This PR adds unit tests for the transportation layer, and fixes several bugs in the unit testing code.  It verifies the correct zoom association to the various highway classes, and verifies that updates to highway attributes are populated.

Additionally, the documentation for unit tests in the CONTRIB guide is updated to note the specific make commands for developers to run.
2021-11-11 08:27:01 +01:00
Eva Jelinkova 26cfe69a9c
Waterway zoomlevel 6 - 8 corresponding with water (#1291)
This PR is solving https://github.com/openmaptiles/openmaptiles/issues/406, partially also https://github.com/openmaptiles/openmaptiles/issues/320.
It is changing source of data for zoomlevel 6 - 8 in `waterway` layer to OSM (relation `waterway = river`), this way it corresponds with `water` layer.
Testing on Europe, z0 - z9 tiles increase size from 20.7 MB to 21.4 MB. We can discuss the level of generalization, but I think this size change is not critical.
2021-11-10 20:26:14 +01:00
zstadler 1be440404b
Update etl diagram for poi layer (#1297)
Add the missing `osm_poi_stop_centroid` and `osm_poi_stop_rank` materialized views.
2021-11-10 19:49:18 +01:00
Falke Design ebeafc65fa
Add requires.tables to <layer>.yaml (#1236)
**NOTE** this can only be merged after the next tools version is released.

Added required Postgres tables to the `<layer>.yaml` definition.
Close: #1220

PR of tools: https://github.com/openmaptiles/openmaptiles-tools/pull/370
2021-11-05 10:04:54 +01:00
zstadler 5b2e43497e
`transportation_name` update to consider `tags` (#1289)
Following 8bb77b67a1 (r59190611)
2021-11-04 13:51:28 +01:00
Brian Sperlongano dffb9c66d6
Document updates testing process (#1284)
This PR adds documentation for how to test the updates process.  The procedure is largely copied from @zstadler's work on #1230.
2021-11-01 10:43:37 +01:00
Brian Sperlongano 79f8db03f9
Fix blank names (#1268)
This PR fixes a bug in the `waterway` layer in which empty `name_en` and `name_de` tags were being added to the tiles.

`name_en` and `name_de` are legacy tags, intended to be removed in v4.0.  Thus, any legacy consumers that have not yet transitioned to `name:en` and `name:de` etc are currently NOT rendering labels for these features when `name:en` and `name:de` are not tagged on the feature.  Therefore there are two possible approaches:

1.  Remove these tags which are not rendering anyways from the tile, which keeps the bug in place, but shouldn't matter because no data consumer has taken notice of the issue (it would probably be easier to migrate to the new tag than to post a bug report!), _and they're going to be removed eventually anyways_.  That's the approach in this PR.
2021-11-01 09:05:01 +01:00
Brian Sperlongano c7e7fae9ee
Add support for Bus Rapid Transit (highway=busway) (#1271)
This PR adds support for bus rapid transit (BRT) systems, mapped with the [approved tag](https://wiki.openstreetmap.org/wiki/Proposed_features/Tag:highway%3Dbusway) `highway=busway`. BRT systems commonly appear in maps that also show light rail.  Below are two examples of BRT in such maps.

![image (1)](https://user-images.githubusercontent.com/3254090/138018375-ac1f60c3-8059-4f95-bf1d-a659ca0c0103.png)
![image](https://user-images.githubusercontent.com/3254090/138018376-f809aeb3-17ba-495e-b33c-9fe54a0fa840.png)

Since BRT is equivalent in nature to light rail systems, this PR matches the zoom level of light rail, which is rendered at zoom 11+.  BRT systems are relatively uncommon, so adding this support should have negligible impact on tile size.

Below is a data rendering of [a BRT system](https://www.openstreetmap.org/relation/4051383#map=12/40.4068/-79.8646) in Pittsburgh, Pennsylvania.

![image](https://user-images.githubusercontent.com/3254090/138021552-ce974f2f-cfbd-42a0-9848-42ed44da453e.png)
2021-11-01 08:40:07 +01:00
Nic Hubbard 6caab9fa09
Update QUICKSTART.md (#1282)
Updated the output of `make help`.
2021-10-29 18:08:50 -04:00
Brian Sperlongano a0d915942a
Allow oneway=-1,1 only (#1267)
This PR removes cases of `oneway=0` as this is an assumed default.  It is not necessary to have this tag on every road or path and by removing it we can save space in the tiles by only including the meaningful values.  It leaves intact `oneway=1` and `oneway=-1`, the latter of which indicates a oneway in the opposite direction of the way.

Unblocks #1265
2021-10-28 15:39:34 +02:00
Brian Sperlongano cded42349f
Remove unnecessary ramp tagging (#1266)
This PR removes unnecessary `ramp` tagging from the `transportation` layer.  The `ramp` tag is used for two situations.  First, it is set for all `highway=***_link` tags to indicate a highway ramp.  The second situation is when the `ramp` tag is set on a highway object, which indicates the presence of a ramp, such as one that would be used for a wheelchair.  `ramp=0` is a reasonable default in these situations; by removing cases of `ramp=0` and presenting only `ramp=1` to the tiles, we can save considerable size in the tiles.  Additionally, there appears to be a bug in which all objects tagged `highway=steps` are inexplicably tagged `ramp=1`.

The changes as follows:

1. Remove `ramp=0` where it appears in the tile.
2. `highway=steps` no longer assumes `ramp=1` in cases where `ramp=*` is not explicitly set.

In the current behavior, `ramp=0` is tagged only in at z13+ but suppressed in lower zooms:
![image](https://user-images.githubusercontent.com/3254090/137589213-5a3432df-8c19-47bf-b556-7be15479790c.png)
![image](https://user-images.githubusercontent.com/3254090/137589296-f3126264-fb07-4346-ba70-c1f1b007a709.png)
![image](https://user-images.githubusercontent.com/3254090/137589306-30f9821b-3160-4b45-98b3-f2b8a0ae3a13.png)

This PR unifies `ramp=0` suppression between z13+ and z12-.
2021-10-28 15:08:56 +02:00
Brian Sperlongano be37f3a565
Framework for SQL-based unit tests for import and updates (#1249)
This PR adds the ability to create SQL tests that ensure that OSM data is properly imported and updated in the OpenMapTiles data schema. The tests work by injecting test OSM data and updates into the database and checking to ensure that the data is properly loaded into the database using standard SQL statements.  With this framework in place, developers can now write small tests to inject known data into the database and ensure that imports and updates are working correctly.

In addition to the framework, basic tests are provided for four layers.  These initial tests are in no way comprehensive, but they provide a structure and framework for developers to add their own tests or expand the existing ones to cover more cases.

Usage:

`make clean && make sql-test`

## 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 contains OSM id numbers that are distinct 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.
1. **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.
1. **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`.
1. **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.
2021-10-28 13:38:46 +02:00
Brian Sperlongano 5833e8ce6e
Suppress rendering of underground buildings (#1241)
This PR does the following:
1. Suppresses underground buildings from rendering, when such buildings are tagged `location=underground`.  Based on the wiki documentation, the `layer` tag does not determine whether a feature is above of below ground.
2. Unifies the building and building relation imposm exclusion mappings.

The following underground building feature in Luxembourg is used as the test object:
https://www.openstreetmap.org/way/582873794
2021-10-28 13:09:06 +02:00
Petr Pridal 15eb75539d
Update LICENSE.md 2021-10-26 09:52:11 +02:00
Brian Sperlongano 9e74fb6299
Fix park layer ETL diagram (#1278)
This PR fixes an ETL diagram documentation error in the park layer.
2021-10-25 08:12:17 -04:00
Falke Design ce94fecaa8
Add boundaries `import-data` info to Readme (#1215)
* Add boundaries info to Readme

* make NE usage less specific - it may change later.

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2021-10-19 11:26:47 -04:00
Brian Sperlongano 829f28d27b
Fix logic error in transportation layer filter (#1270)
This PR fixes a bug in the `WHERE` clauses in the transportation layer generalization tables for zoom 10.    The intended behavior of the layer is to suppress `highway=tertiary` and `highway=tertiary_link` at zoom 10 and lower.  However, due to this bug, these objects were not suppressed as intended, because an `OR` was used in the SQL where an `AND` was needed instead.

This bug was inadvertently introduced in #1172 😞
2021-10-19 10:31:51 -04:00
Brian Sperlongano f744f9c009
Upgrade to omt-tools v6, Imposm 0.11.1 and migrate SQL (#1246)
This PR migrates the SQL in the transportation and transportation_name layer to use the new imposm3 mappings which now map a separate primary key ID.
2021-10-14 11:38:28 -04:00
Matt Riggott ac577fe014
Remove mention of now-gone `make import-borders` (#1259)
After commit b4b897999d the `make import-borders` rule no longer exists, but it's still mentioned in the README a couple of times. This PR removes those references.

Some [cleanup files are also mentioned in `.env`](4d6945b935/.env (L42-L44)). I'm not sure if those lines can be removed too, because the variables are used in [`bin/import-borders`](3796c4eab0/bin/import-borders (L8-L10)) in the `openmaptiles/openmaptiles-tools` repo.
2021-10-14 07:14:03 +02:00
Yuri Astrakhan 5fb15d5c31
Re-create cache dir after destroying (#1263)
Cache dir should always exist, so after deleting it,
it must be recreated. This is done in `make init-dirs`,
but if gets destroyed here, it won't auto-recreate.
2021-10-13 15:54:19 -04:00
Brian Sperlongano aaa68048d9
Remove unneeded toll code (#1262)
This PR removes unneeded `CASE` clauses which converts `toll` tags to booleans.  However, the `toll` tag is already mapped as a boolean by imposm, therefore this processing can be simplified.
2021-10-13 20:43:14 +02:00
Matt Riggott 4d6945b935
Simplify landcover layer generalisation SQL (#1255)
I was reading through the SQL used to generalise the landcover layer ([`layers/landcover/generalized.sql`](596f44aa26/layers/landcover/generalized.sql)) and I noticed that when creating the generalised landcover tables for zooms 9-13, the SQL was doing something like this:

```sql
SELECT * FROM simplify_vw_z13 WHERE ST_NPoints(geometry) < 50
UNION ALL
SELECT * FROM simplify_vw_z13 WHERE ST_NPoints(geometry) >= 50 AND ST_NPoints(geometry) < 300
```

As in, the simplification/clustering of landcover generalisations was being done in two steps: once for polygons with fewer than fifty points, and once for polygons with 50+ points.

As far as I can see, there's no benefit to doing this — it's probably just an artefact of the dev work done for the [original pull request](https://github.com/openmaptiles/openmaptiles/pull/1035). Of course, I might be completely missing the reason for clustering polygons into two groups (<50 points and 50+ points). But assuming I haven't, I've created this pull request to simplify the SQL used in the generalisation, merging the two steps into something like this:

```sql
SELECT * FROM simplify_vw_z13 WHERE ST_NPoints(geometry) < 300
```

The effect is to slightly reduce the number of landcover features (polygons with <50 points can now be clustered/unioned with those 50+), and to reduce the time taken to generalise the landcover tables (in a small test using OSM's Iceland data I saw a 7% reduction in the time spent). It doesn't alter the features that are shown on the map.

Builds upon work from commits 4a1b0afa26 and da689f9e42.
2021-10-08 08:51:20 +02:00
Brian Sperlongano 91c6d3bbd1
Update ETL docs on landcover layer (#1258)
While reviewing #1255, it became apparent that the ETL documentation for the landcover layer was incomplete.  This PR updates the ETL documentation in `generalized.sql` so that each table has a node in the ETL diagram.
2021-10-07 15:54:13 -04:00
zstadler 8ec986e01d
Expose `make all` errors (#1254)
Avoid redirection of error messages to output files
- build/openmaptiles.tm2source/data.yml
- build/mapping.yaml

Currently, if an error occurs when `make all` creates any of these files, the error message is not printed to the console.
```
docker-compose run --rm --user=1000:1000 openmaptiles-tools generate-tm2source openmaptiles.yaml --host="postgres" --port=5432 --database="openmaptiles" --user="openmaptiles" --password="openmaptiles" > build/openmaptiles.tm2source/data.yml
Creating openmaptiles_openmaptiles-tools_run ... done
ERROR: 1
make: *** [Makefile:257: build/openmaptiles.tm2source/data.yml] Error 1
```

An inexperienced user would not know where to look for the details.

With this PR, the error is sent to the console:
```
docker-compose run --rm --user=1000:1000 openmaptiles-tools bash -c \
        'generate-tm2source openmaptiles.yaml --host="postgres" --port=5432 --database="openmaptiles" --user="openmaptiles" --password="openmaptiles" > build/openmaptiles.tm2source/data.yml'
Creating openmaptiles_openmaptiles-tools_run ... done
Could not parse /tileset/layers/aeroway/mapping.yaml
found undefined alias 'refkjbkjkhh'
  in "/tileset/layers/aeroway/mapping.yaml", line 94, column 7
ERROR: 1
make: *** [Makefile:257: build/openmaptiles.tm2source/data.yml] Error 1
```

Redirection of stdout is now done in the container, leaving stderr to go to the host.
2021-10-06 18:02:52 +02:00
zstadler 596f44aa26
Integrity check for DIFF mode (#1245)
This test applies 2-3 months of weekly updates on the `europe/monaco` extract from [Geofabrik](http://download.geofabrik.de/europe/).

It is worth noting that the contents of the updates may vary, and some SQL update flows may not be tested if the relevant changes did not occur during that period.

Resolves #1226
2021-09-29 15:55:19 +02:00
zstadler ed65036766
Restore `make psql` acceptance of SQL from stdin (#1250)
Following https://osmus.slack.com/archives/CH6GFAFRC/p1632824401121100?thread_ts=1632711389.118900&cid=CH6GFAFRC
2021-09-29 14:51:00 +02:00
Brian Sperlongano 718e79a704
Fix park polygon update SQL (#1248)
This PR fixes a bug in the park polygon update code introduced in #1160.  Because park polygons at zoom 4 are dissolved, the centroid is not present in the table at that layer.  Thus, a separate update trigger is needed to avoid errors.  This PR adds the separate trigger for the zoom 4 park layer.

This PR likely resolves an unidentified blocker for #1245
2021-09-29 13:40:16 +02:00
Brian Sperlongano b4b897999d
Replace osmborder with imposm/SQL (#1213)
Fixes #1156
Fixes #810
Fixes #1228

This PR replaces `osmborder`, which is no longer maintained, with `imposm` mappings and SQL code to generate borders.  Key features that were moved into the imposm/SQL layer:
1. Grouping by `osm_id` and aggregating by lowest `admin_level` value so that there's only one copy of ways that are members of multiple relations.
2. Filtering out of point features in boundary relations (typically `admin_centre` and `label` roles).
3. Move disputed boundary detection logic into SQL.

This will increase the database size slightly because of the limits of what imposm can do, as some of the filtering is done in the SQL layer after importing, rather than being done in `osmborder`.
2021-09-29 11:08:55 +02:00
Brian Sperlongano bfdbd829dc
Fix typo in transportation update (#1247)
This PR fixes a copy/paste error (identified by @zstadler's ongoing excellent work for update unit tests) in the `transportation_name` update code.
2021-09-24 16:16:31 +02:00
Brian Sperlongano 88389f2a2c
BUGFIX: Route concurrency data is wiped after route member updates (#1239)
This PR is a bugfix for the `transportation_name` layer.  Currently, the updates process does not work, as noted by @zstadler in #1230.  The issue is that the computed `concurrency_index` column in `osm_route_member` is never updated after the initial updates.  Therefore, whenever route member ways are updated, they will lose their route concurrency index, and hence route concurrencies will be lost in the `transportation_name` tiles.  This PR adds the missing concurrency index update code to the transportation/network update triggers.

This PR as written also incorporates the fixes in #1230 and #1233.

The following SQL is a unit test to demonstrate that these triggers work correctly:

```
select count(*) from osm_route_member where concurrency_index > 5;
select count(*) from osm_transportation_name_network where route_6 is not null;

update osm_route_member set concurrency_index=NULL where concurrency_index > 5;

select count(*) from osm_route_member where concurrency_index > 5;
select count(*) from osm_transportation_name_network where route_6 is not null;
```

If working correctly, both pairs of `count(*)` values should return the same pair of numbers.
2021-09-21 12:56:25 +02:00
Falke Design 6f0ab57547
Print error of `import-sql` at the end of the output (#1237)
Because of the parallel processing of `import-sql` the error message is printed in the middle of the output. With this PR the error is displayed again at the end:
![grafik](https://user-images.githubusercontent.com/19800037/133897373-656ed3d0-e580-4f67-9290-0e83949d63d7.png)

Issue: https://github.com/openmaptiles/openmaptiles-tools/pull/370

```
awk '1{print; fflush()} $$0~".*ERROR" {txt=$$0} END{ if(txt){print "\n*** ERROR detected, aborting:"; print txt; exit(1)} }'
```
Explanation:
- `1{print; fflush()}` means if true then print output -> `1{}` same as `if(true){}`
- `$$0~".*ERROR" {txt=$$0}` get first argument `$$0` (line of output) and check if it contains (regex string) `ERROR`. If true save line to var `txt`: `{txt=$$0}`
- `END{ ... }` if last line of output is reached
- `if(txt){print "\n*** ERROR detected, aborting:"; print txt; exit(1)}` if error was found in a line / var `txt` is existing print it out
2021-09-21 10:42:50 +02:00
Brian Sperlongano 8b6e69e440
BUGFIX: Ignore duplicate route concurrencies (#1233)
While troubleshooting #1230, I discovered that there were cases where a way was a member of the same route relation more than once, such as: https://www.openstreetmap.org/way/17439235

<img src="https://user-images.githubusercontent.com/3254090/133726616-acd01332-343e-4930-ad3d-1fb3c3190a4c.png" width=280/>

This segment would end up showing duplicate highway shields in a rendered style, which is not desirable.  While I personally think this style of tagging is wrong, it's a relatively easy fix to remove those duplicates.  This PR replaces `ROW_NUMBER()` with `DENSE_RANK()` in the concurrency index generation code and adds a `DISTINCT` constraint on the concurrency join to handle multiple member rows with the same concurrency index.

Since I was in this file, I also fixed the copy/paste error in generating the route names.

Screenshot from database showing correct mapping:
![image](https://user-images.githubusercontent.com/3254090/133725554-1aa5dbbc-59a8-4674-a446-b92adb96c2a1.png)
2021-09-20 18:40:36 +02:00
zstadler 5b0c28929f
Integrity check to generate zoom 14 tiles (#1231)
Setting the MIN/MAX zoom levels in the `env` section had no effect since the values in the `.env` file have higher precedence.

See the currently effective `maxzoom = 7` value in [a typical integrity check log]( https://github.com/openmaptiles/openmaptiles/pull/1223/checks#step:3:3546).
2021-09-20 17:09:18 +02:00
Jaroslav Hanslík d49f524edd
Removed useless NULLIF calls (#1214)
`NULLIF(wikipedia, '') IS NOT NULL` replaced by `wikipedia <> ''`
https://stackoverflow.com/questions/23766084/best-way-to-check-for-empty-or-null-value
2021-09-20 11:19:24 +02:00
Brian Sperlongano e8a3bc18c5
Remove landuse=park from landcover (#1208)
The tag `landuse=park` is a rare tagging mistake of `leisure=park`.  The OSM wiki [lists this tag as a mistake](https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dpark).  It is included in the landcover layer with a note that there were (at the time) 600 parks tagged in this way.  There are currently a bit over 100 objects tagged with this mistake.  Based on the wiki documentation and obvious decline of this tag, we should remove it so that we're not introducing mapping mistakes into the database and not inadvertently providing mapper feedback that encourages the use of mistake tagging.
2021-09-20 10:23:26 +02:00
Brian Sperlongano 849aca8da7
Refactor z12-14 transportation filter logic (#1207)
This PR is a refactor.  The purpose of this PR is to refactor the logic in the z12-z14 transportation layer to increase readability and reduce code complexity.

In addition, this fixes bugs in the original filter code:
* Create filter parity between `service` and `service_construction` highway classes.
* Removal of unintended `class` values `minor_construction`, `path_construction`, `service_construction`, and `track_construction` from zoom 12 filter by explicitly listing the highway classes that are included.
2021-09-20 08:07:38 +02:00
Falke Design d19aa5bf24
Makefile: Replace static DB properties with the variables (#1222)
* Replace static DB properties with the variables
2021-09-17 12:04:40 -04:00
Brian Sperlongano 5e37a811fb
Update devdocs (#1223) 2021-09-11 15:56:10 -04:00
Falke Design bf68366ed5
Add workflow to readme (#1203)
Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2021-09-08 13:43:10 -04:00
Falke Design 87a37da243
Fix #1151 check if bc command is available (#1201)
On some systems the `bc` command is not installed, so I added a check if the command can be used.

It is a simply calculation from KB to GB.  If `bc` is missing, then it is displayed in KB.

fix: #1151
2021-09-01 15:13:35 +02:00
Yuri Astrakhan d205f4a433
Fix Ctrl+C when generating tiles (#1205)
Adding -T fixes the issue when users are unable to stop tile genartion with ctrl+c

For some reason it doesn't work without it, even though the process of building
and running both docker images is the same.
2021-09-01 14:18:06 +02:00
Brian Sperlongano f947cbffc3
Add enhanced mountain features (#1202)
This PR adds support for several features in the `natural` key, including `saddle`, `ridge`, `arete`, and `cliff`.  These features all currently render in openstreetmap-carto, so adding these features would advance OpenMapTiles towards its goal of parity with the standard renderer, as indicated in https://github.com/openstreetmap/operations/issues/565#issuecomment-907303115.

This PR also adds the features requested in #274, with the exception of valleys, which I've left out of this PR because there are different complexities to mapping valleys that should be addressed as a separate (future) PR.

### Examples of mountain features in paper maps
These features are regularly found in American-style maps and thus is of interest to the openstreetmap-americana map style.  Below are examples of these mountain-related features found in general purpose maps:

<img src="https://user-images.githubusercontent.com/3254090/131270340-af80c7bf-9416-40a3-9b64-56418abb2aef.png" width=400/>
<img src="https://user-images.githubusercontent.com/3254090/131270375-b9eb2095-7708-443d-b7bc-22bf8adab721.png" width=400/>
<img src="https://user-images.githubusercontent.com/3254090/131270423-64447ad3-d90a-4615-82e1-91175a8f8a6b.png" width=400/>
<img src="https://user-images.githubusercontent.com/3254090/131270506-2248db9f-ded5-443f-82ed-b0e8d4d12a70.png" width=400/>

### Approach
This PR extends the existing `mountain_peak` layer by adding other mountain features.  We may want to consider renaming this layer in version 4.0 to be more inclusive of other mountain features including the potential future addition of valleys.  However, the features added in this PR are associated with mountains and so their inclusion in this layer is the most appropriate location.

A new `osm_mountain_linestring` mapping maps the new linear mountain features, with similar ranking logic as is used for the existing `peak`/`volcano` features.  Additionally, `natural=saddle` is added to the `osm_peak_point` mapping and ranked using the formula for peaks.  Since saddles will have lower elevations than peaks, important saddles will be preempted by important peaks.

The new linestring features are rendered only at zoom 13-14, in order to match the zoom at which they appear in openstreetmap-carto.  However, it may be appropriate in a future PR to extend the rendering of these features as generalized linestrings at lower zooms.

### Test Renderings
Below is a test rendering showing aretes and peaks in Austria, just north of the Swiss border, followed by a screen shot of the [same location](https://www.openstreetmap.org/#map=14/46.8682/10.0863) in openstreetmap-carto:

**OpenMapTiles, zoom 14**
<img src="https://user-images.githubusercontent.com/3254090/131271258-5cd90bdb-cac2-41d8-887f-b4bf6be83673.png" width=400/>
**openstreetmap-carto, zoom r14/v13:**
<img src="https://user-images.githubusercontent.com/3254090/131271332-32d5bcfc-41c6-4625-829c-df063b7af523.png" width=400/>
2021-09-01 12:21:18 +02:00
Falke Design 910db7f60c
Remove area checks in Makefile for `import-borders` & `generate-tiles-pg` (#1200)
While importing multiple .pbf files into postgres I was confronted with some unnecessary problems:

1. I wanted to use the borders of the planet which I had already generated. But `make import-borders` needs a .pbf file which is not necessary if the line.csv file is already existing -> So I added a check if the line.csv is **not** existing it checks for the `area parameter` / .pbf file
2. `make generate-tiles-pg` is only possible with a specified `area parameter` BUT the area is not used / needed for generation -> So I removed the area check
2021-09-01 10:10:29 +02:00
Brian Sperlongano 3818979143
Suppress service roads at certain zooms (#1192)
Fixes #1191

This PR suppresses `highway=service` at zoom 12, where it is not a useful level of detail.  This makes OpenMapTiles consistent with openstreetmap-carto, which does not begin showing `highway=service` until raster zoom 14 / vector zoom 13.

Additionally, this PR suppresses `highway=service` + `service=parking_aisle` / `service=driveway` from zooms 12-13, as this detail is excessive below zoom 14.  As a point of comparison, openstreetmap-carto does not begin showing `service=parking_aisle` / `service=driveway` until raster zoom 16 (vector zoom 15).
2021-09-01 09:18:45 +02:00
Brian Sperlongano d427d58e36
Water layer river mapping bug fixes (#1182)
This PR is a bugfix for the `water` layer.

* `waterway=stream`, `waterway=river`, `waterway=canal`, `waterway=ditch`, and `waterway=drain` are all linear features, not area features.  Thus, these objects are being unnecessarily mapped into the `osm_water_polygon` polygon table, and this PR removes these unneeded mappings.
* The combination `natural=water` + `water=river` is the most popular tagging for river areas.  However, the current mapping causes rivers tagged in this way to be rendered in the vector tiles as a `lake`.  This PR adds a check for the `water=river` tag and tags both variants of river areas as `class=river`.

`natural=water` + `water=river` river mapping:
![image](https://user-images.githubusercontent.com/3254090/129825551-388491de-549e-4843-80cc-01dba358c360.png)

`waterway=riverbank` river mapping:
![image](https://user-images.githubusercontent.com/3254090/129825618-4239eae7-a2bc-4a82-9931-fda2c02c2b40.png)


Lake mapping for a `natural=water` (with no other tagging):
![image](https://user-images.githubusercontent.com/3254090/129825554-9394b3d3-988a-4e92-a9f8-b198c695ec37.png)
2021-09-01 08:24:01 +02:00
Brian Sperlongano 0e17d53f42
Implement park rendering at z4-5 (#1160)
Unblocks ZeLonewolf/openstreetmap-americana#51

Currently, OpenMapTiles renders protected areas at zoom 6 and higher.  However, the western United States has protected areas that are so vast that it makes sense to render these areas as low as zoom 4, as noted in ZeLonewolf/openstreetmap-americana#51

This PR extends the generalization of park features from its current termination at zoom 6 to zoom 4.

Here is an example from the Americana style of rendering protected areas at zoom 6, which is currently the lowest supported zoom:
https://zelonewolf.github.io/openstreetmap-americana/#6/45.313/-111.721

We would like to provide rendering at zoom 4 (no labels) and zoom 5 (with labels) in the Americana style.  Below are samples generated from this PR for Idaho, USA:

Zoom 4:
![image](https://user-images.githubusercontent.com/3254090/126924222-e21865e9-b184-479a-abd5-46238bd106f8.png)

Zoom 5:
![image](https://user-images.githubusercontent.com/3254090/126924230-01853e8c-d3e0-41e8-b10f-06415da529d8.png)
2021-09-01 07:20:52 +02:00
Yuri Astrakhan f15ecbf07e
Update README.md tilegen target (#1199) 2021-08-27 22:34:00 -04:00
Brian Sperlongano 1fb7841a6e
Fix name of PR comment donor (#1196) 2021-08-27 09:56:02 -04:00
Brian Sperlongano 4525ce6a84
Convert CI to use workflow triggers (#1189)
Fixes #948 

This PR does the following:
1. Changes the trigger for the PR comment updater from the cron method to workflow_run, triggered on completion of the test cases.  This should remove the delay between the completion of the performance tests and the updating of the corresponding comment in the PR.
2. Separates the integrity check and performance check into separate workflows and allows them to run in parallel.  This will allow the project to take advantage of multiple CI runners if they're available (which appears to be the case).

In addition, this fixes an issue with post-merge undeleted/updated branches on PRs.  The current "cron" method causes the CI to run the pr-update job over and over forever, unnecessarily.

As described in github/docs#799, and the [github docs](https://docs.github.com/en/actions/reference/events-that-trigger-workflows#workflow_run), a `workflow_run` trigger will only fire when the workflow file is on the main branch.  Thus, this change will not fire the PR updater on this PR.  Thus there's no way to test this working properly without merging onto master and then testing on one of the other PRs.
2021-08-27 14:16:48 +02:00
Yuri Astrakhan 1cea73cb7c
Use st-asmvt pg tilegen in quickstart (#1193)
* Use generate-tiles-pg target in quickstart
* update makefile documentation
2021-08-25 21:35:06 -04:00
Brian Sperlongano b88bd6abb5
Add locksmith shop (#1188)
Fixes #566

This PR adds support for `shop=locksmith`.

Example OSM object: https://www.openstreetmap.org/way/874850561

Rendered tile:
![image](https://user-images.githubusercontent.com/3254090/130335938-e76cf3d2-dfe7-4398-a647-463fc216d674.png)
2021-08-23 18:31:25 +02:00
Brian Sperlongano 7e9a6812d7
Add international airports at z8-9 (#1187)
Closes #1082

This PR moves the aerodrome/aerodrome_type consolidation (via template) into the lower-level `osm_aerodrome_label_point` table, and creates a partial index on class `international` for airports with an `iata` code.  The presence of an `iata` code is more significant than an `icao` code which exists at many smaller, general aviation airport.  Therefore, `international` + `iata` should be a sufficient filter.

Zoom 8 international airports in the NYC area (blue dots):
![image](https://user-images.githubusercontent.com/3254090/130335311-10b7aa35-d2f9-42cc-a054-878048012040.png)

Zoom 10 in the same area:
![image](https://user-images.githubusercontent.com/3254090/130335327-3989cfba-80ca-46dd-a157-45b375f84a8d.png)
2021-08-23 14:14:50 +02:00
Brian Sperlongano aee838e29f
Change zoom level for NE states/provinces (#1184)
Fixes #1055 

This PR moves Natural Earth zoom 7.7 boundary lines into zoom 4.

> Hi, thank you for PR. In github-actions statistics there is a pretty high size increase in zooms 3, 2, 1, which are using data from zoom 4. Maybe keep your change to move `min_zoom <= 7.7` just for zoom 4, but for zoom 3 add a condition `min_zoom <= 7` (that subsequently the condition bubbles into zoom 2 and 1). What do you think?

I agree that this makes sense, and thank you for pointing it out.  It didn't occur to me that the zoom 1-3 tables were unbounded.  I made the change to pull the `min_zoom` column into the zoom 4 generalized table and filter for `min_zoom< 7`.

With this change, here is Algeria, zoom 3:
![image](https://user-images.githubusercontent.com/3254090/130368190-616891f4-4a53-4780-926b-561007291f33.png)

Algeria, zoom 4:
![image](https://user-images.githubusercontent.com/3254090/130368194-d4e722bb-559b-4e2a-bb82-a5d1bd95985c.png)
2021-08-23 11:49:19 +02:00
Brian Sperlongano a93b708327
Implement shipway labels (#1179)
Fixes #403 

This PR adds labels to shipway linestrings in the `transportation_name` level, up through zoom 12.

![image](https://user-images.githubusercontent.com/3254090/129659827-662ee13c-27f3-4e62-a7f4-45dbd535b770.png)
2021-08-23 10:52:15 +02:00
Brian Sperlongano 6ef138635d
Fix negative feature IDs (#1185)
This PR removes the possibility of negative feature IDs for the `aerodrome_label` layer by defining the feature as the absolute value of the OSM id (imposm maps relations with negative numbers).  There is a very unlikely  scenario in which a relation and a way have the same ID (and are also in the same tile), however, unique IDs are not a strict requirement of MVT.

Noted in:
https://github.com/openmaptiles/openmaptiles/pull/1176#issuecomment-902503655

Positive feature ID for Quonset State Airport, which is mapped as a relation:
![image](https://user-images.githubusercontent.com/3254090/130232322-c797d491-ece9-4889-9695-ffb6f3ac011f.png)
2021-08-20 16:40:02 +02:00
Brian Sperlongano 36bd917e05
Implement feature IDs in aerodrome_label and mountain_peak (#1176) 2021-08-19 21:03:40 +02:00
Brian Sperlongano 7ca751ec7a
Add toll tagging (#1177)
Fixes #366

This PR sets `toll=1` in the `transportation` layer when a road is tagged as a toll road in OSM (with the tag `toll=yes`).  If a road is tagged with any other value of `tag=*`, the value is suppressed in the tile, since non-toll roads can be presumed as the default and therefore this PR should have only negligible impact in the tiles.

Support for toll road tagging is of interest in the American mapping community, because toll roads have historically been styled differently on American-style maps, for example:
![image](https://user-images.githubusercontent.com/3254090/129505967-5916eace-596a-4c89-ac5d-0aab3e641ed7.png)


Screen shot of a toll road being generated in the `transportation` layer tiles:
![image](https://user-images.githubusercontent.com/3254090/129505683-eb315643-95ff-455b-a606-f379f776f92d.png)
2021-08-19 07:12:10 +02:00
zstadler e37076c133
Add spring water bodies (#1167)
The [OSM wiki](https://wiki.openstreetmap.org/wiki/Tag:natural%3Dspring) says `natural=spring` may be used on areas.
2021-08-18 17:46:15 +02:00
Brian Sperlongano d186856ac5
Add support for cemetery tagged as grave_yard (#1175)
Fixes #1057

This PR adds `amenity=grave_yard` to the `landuse` layer.  A unification function was implemented which encodes all `class=grave_yard` as `class=cemetery` in the tiles, which adds these features for existing users of `class=cemetery` with no change.  The unification function can serve as a basis for any other tags that we might want to unify in the `landuse` layer.

Tile rendering for an `amenity=grave_yard`.  ([Location](https://www.openstreetmap.org/way/857383420))
![image](https://user-images.githubusercontent.com/3254090/129456504-187d307a-2a20-4b13-af0a-a2850503bb4f.png)

Tile rendering for a `landuse=cemetery`.  ([Location](https://www.openstreetmap.org/way/385779531))
![image](https://user-images.githubusercontent.com/3254090/129456654-494c0eb4-9785-467c-b1a0-44abb7f9d5e9.png)
2021-08-18 09:09:51 +02:00
Brian Sperlongano 45d825e212
Implement private road tagging (#1174)
Fixes #1066 

This PR adds a new field `access` in the transportation layer, which will be set to `no` if the `access` tag is either `no` or `private`.  While `private` is the more popular value by a 17:1 ratio, I went with `no` because it's smaller in the tiles.  In addition, the text `no` opens up the future possibility of other text-based access values such as `destination`, `customers`, or `permit`.

The screenshot below shows an example of access tagging for a road on a military base:

![image](https://user-images.githubusercontent.com/3254090/129431491-9acbaeca-bf18-4384-8177-2c198834865c.png)
2021-08-14 07:04:17 +02:00
Brian Sperlongano fdb9ae58cd
Transportation generalization table optimization and cleanup (#1172)
This PR updates the `transportation` layer creation scripts to simplify the SQL and remove unneeded sub-selects, checks and conditionals, fix indexes, and improve inline documentation. 

Currently, there are two sequences of materialized view creations.  There is one from zoom 11 through 9, and a second one for zoom 8 through 4.  This PR removes that break in the sequence of transportation table materialized view creations, in favor of one in which high-zoom views are created first, and then each lower zoom is created from the zoom above.

Instead, the current generalized zoom 8 transportation table is built directly from `osm_transportation_linestring` rather than being built from the zoom 9 transportation table.  This means that when building the zoom 8 table, it must scan the entire transportation network rather than just selecting from the pre-filtered zoom 9 table.

This PR removes an unneeded sub-select in the build of the zoom 8 table, which appears to be a leftover from an old version of the SQL that did some sort of merge.  Once this PR is implemented all zooms from 11 through 4 will be linked via a progressive series of materialized views.

Lastly, this adds in missing materialized view refreshes for zooms 9-11, which appear to have been entirely missing, and as far as I can tell aren't getting updated in the current version of this code.

In addition, the following optimizations were added as part of this commit:

1. Updates the `osm_highway_linestring_highway_partial_idx` partial index to match the `SELECT..WHERE` clause actually present in `transportation/update_route_member.sql`, which is where it appears to be actually used, and update inline documentation to reflect this.

2. Collapses unnecessary sub-select block in `osm_transportation_merge_linestring_gen_z11`, and removes unnecessary ST_IsValid() call, which already provided in `mapping.yaml`, and update inline documentation to reflect these assumptions.

3. Updates `WHERE` blocks to remove unnecesary checks and further document assumptions.  The `highway=construction` check is unnecessary in all cases, because it is sufficient to check the `construction` key alone.  If `construction=*` is set, then `highway=construction` is implied.

4. Two indexes were added to `layers/transportation/update_route_member.sql` to improve route population performance.

In testing locally, I'm seeing performance improvements around 10% in the generation of the `transportation` layer, based on modifying `openmaptiles.yaml` to generate only the transportation layer and then repeatedly running `time make import-sql`, however, this timing might be impacted by docker, so I would ask for confirmation of acceptable performance.

In addition, this PR shortens the length of the transportation update SQL file by 30 lines, which makes it easier for contributors to work with.
2021-08-13 18:00:33 +02:00
Brian Sperlongano f78d42ec84
Remove unused osm_transportation_merge_linestring table (#1171)
PR #1168 removed several `WHERE` clauses in the `transportation_merge_*` table series.  With those removed, it appears that `osm_transportation_merge_linestring_gen_z8` and `osm_transportation_merge_linestring` are nearly identical, with the former simply adding an `ST_Simplify()` operation.

A grep of the codebase indicates that the _only_ use for `osm_transportation_merge_linestring` is to hold the intermediate result of an `ST_Dump(geometry))` before it is fed into `ST_Simplify()`.  Therefore, it appears that we're holding an entire zoom 8 copy of the transportation layer (all motorway/trunk/primary roads) in a materialized view for absolutely no reason at all.

This PR removes the `osm_transportation_merge_linestring` intermediate table and changes the definition of `osm_transportation_merge_linestring_gen_z8` to perform the `ST_Dump()` and `ST_Simplify()` transformations directly from the `osm_highway_linestring` table in a single operation.
2021-08-11 10:46:17 +02:00
Brian Sperlongano 09078f6d7d
Remove useless WHERE clauses from the transportation layer (#1168)
This PR removes several redundant/unnecessary WHERE clauses from the transportation layer.  Specifically:

The table `osm_transportation_merge_linestring` is a view of `osm_highway_linestring` which exposes only motorway/trunk/primary roads:
9e4be3e3b0/layers/transportation/update_transportation_merge.sql (L122-L123)

However, the create statement for the table `osm_transportation_merge_linestring_gen_z8`, which is a view of `osm_transportation_merge_linestring`, also contains  a `WHERE` clause which selects down to motorway/trunk/primary roads.  This `WHERE` is unnecessary:
9e4be3e3b0/layers/transportation/update_transportation_merge.sql (L144-L145)

This unneeded `WHERE` clause is similarly present in the create statement for `osm_transportation_merge_linestring_gen_z7`, which is a view of `osm_transportation_merge_linestring_gen_z8`:
9e4be3e3b0/layers/transportation/update_transportation_merge.sql (L163-L164)

Likewise, there is a similar redundant `WHERE` clause in the `osm_transportation_merge_linestring_gen_z5` and `osm_transportation_merge_linestring_gen_z6` tables, both of which select down to `motorway` and `trunk`.  This `WHERE` clause is only needed on the z6 table, and is redundant on the z5 table.

I am not sure what the performance penalty is for these redundant `WHERE` clauses, but there does not appear to be any reason to keep them, and they may incur a performance cost.
2021-08-10 17:55:16 +02:00
zstadler 893d1df4c5
Update descritopn of the water layer's class (#1166)
Clarify that OSM water bodies that do not have a `waterway` tag are classified as `lake`.

This refers to the following tags:
9e4be3e3b0/layers/water/mapping.yaml (L86-L95)
2021-08-10 16:16:40 +02:00
Brian Sperlongano 08bb2a06c0
Add network to transport layer (#1158)
Closes #1153 

This PR populates the existing `network_type` field in the route table with highway route network information, using the most important value in cases of concurrencies.  In order to expose this value, two files `network_type.sql` and `update_route_member.sql` were moved from the `transportation_name` layer to the `transportation` layer.

Below is a representative zoom level 6 with motorways only shown for `us-interstate` network types.  This sample was generated from this PR using a [custom branch](https://github.com/ZeLonewolf/openstreetmap-americana/tree/selective-highway-zoom) of openstreetmap-americana.  This provides a simplified rendering of the highway network which excludes many minor motorway roads and sections.
![image](https://user-images.githubusercontent.com/3254090/126420985-c380b54b-a991-4a7c-a4c1-40a5cf5ec6b0.png)

Below is zoom level 6 on the current [openstreetmap-americana](https://zelonewolf.github.io/openstreetmap-americana/#6/42.148/-73.712).  Notice the many additional stubs, motorway islands, and minor routes which are present.  Instead of rendering `highway=trunk` to make this network look nice, we can instead suppress non-interstate roads and withhold motorway+trunk rendering to a closer zoom:
![image](https://user-images.githubusercontent.com/3254090/126421148-71e780ec-991d-4e38-a82a-85015b349e97.png)
2021-08-04 10:10:16 +02:00
Brian Sperlongano 9e4be3e3b0
Remove unused network type params (#1155)
Changes in #1143 removed the need for `name` and `ref` parameters in the network-to-network_type conversion function.  This PR removes this dead code.

Verified by running ./quickstart rhode-island which completed successfully.
2021-07-26 16:37:12 +02:00
Brian Sperlongano 951aa907b2
Fix SQL failures in transportation_name update code (#1154)
This PR fixed bugs introduced in #1147 and #1119 which broke the update triggers in `transportation_name_update`.  I noticed this issue while I was working a different PR and tried to update a table in the `transportation` layer.

**Test**

The following code currently fails because of cascading update failures, but will complete successfully after this PR is merged.
```
UPDATE osm_highway_linestring hl
    SET network = rm.network_type
    FROM osm_route_member rm
    WHERE hl.osm_id=rm.member;
```
2021-07-26 15:22:36 +02:00
Brian Sperlongano b011b27e52
Implement concurrent highway routes (#1152)
Fixes #1128

This PR adds 6 new columns to the `transportation_name` column, named `route_1` through `route_6`.  These columns contain route information for a section of roadway.  The value is stored in the form **network=ref**.  For example, Interstate 95 in the United States would be `US:I=95`.  Thus, each `route_N` value contains enough information to render a highway shield.  Since a section of road can be a part of more than one route, the `route_2`, `route_3`, etc, will contain the 2nd, 3rd, etc., concurrent routes.

The technical approach was to extend the change in #1135, which added ordered concurrency indexes to the `osm_route_member` table by joining up to the the first six entries to the `osm_transportation_name_network` table.  In addition, that PR provided a ranking system for concurrent highways, ordering first by `network_type` (for example, `us-interstate`, `us-state`, etc), then alphabetically by network name, and then by ref in ascending order.  This ordering of concurrent route memberships is now exposed in this PR in the sequential `route_N` values, meaning that rendered concurrent highway shields will be reasonably sorted.

The renderings below were generated using this branch of OpenMapTiles, as well as a separate branch of openstreetmap-americana:
https://github.com/ZeLonewolf/openstreetmap-americana/tree/openmaptilers-new-features-test

The rendering approach is to use the [formatted expressions](https://maplibre.org/maplibre-gl-js-docs/style-spec/expressions/) feature in mapLibre to insert images into a string of text.  Blank shields are added to the sprite sheet for all possible route networks.  Next, a [styleimagemissing](https://maplibre.org/maplibre-gl-js-docs/api/map/) callback is registered.  As each shield ID is requested, the callback retrieves the sprite shield blank associated with the route's network, draw the `ref` text on the shield, and insert the complete shield back into the map.

Of note, this approach currently results in shields which are rotated about the road rather than being viewport aligned.  This issue is currently documented as maplibre/maplibre-gl-js#188.  A separate repository (https://github.com/ZeLonewolf/maplibre-shield-rotation-sample) has been created as a test case to fix this rotation issue.

Adding route concurrency information to OpenMapTiles would be a major step forward in achieving comprehensive highway shield renderings in a vector map!

**Renderings**:

![routes_1](https://user-images.githubusercontent.com/3254090/126054350-fa7475a7-1b60-4989-bbc2-107678e6c73b.png)
![routes_2](https://user-images.githubusercontent.com/3254090/126054351-fe73bc70-d75f-4ab5-8365-0ee3c3d3eab0.png)
![routes_3](https://user-images.githubusercontent.com/3254090/126054353-a1e74c8f-df21-423c-a300-b7f1a7c9231c.png)
![routes_4](https://user-images.githubusercontent.com/3254090/126054355-6b5dcc83-c611-42b3-bb67-d4f26d789744.png)
2021-07-26 14:28:36 +02:00
Brian Sperlongano 3c15679555
Update brunnel aggregation to avoid splitting highways (#1141)
Fixes #1131

This change does the following:
1. Excludes roads from `transportation_name` that don't have a `name` or a `ref`
2. Updates the road name merging logic to exclude changes in `brunnel` status.  This will ensure that minor bridges don't disrupt the continuity of named roads as the map zooms out.
3. The `brunnel` tag will now only be set when a bridge or tunnel is distinctly named.  Distinctly named is defined as "has a different name from the road on either side".

This example shows an unnamed interstate highway rendered as a continuous feature at low zoom.  This road has many small bridges along its length:

![image](https://user-images.githubusercontent.com/3254090/124370289-b30faa80-dc43-11eb-80d6-034c18ce99ad.png)


This example shows a named bridge rendered with `brunnel` tag set:

![image](https://user-images.githubusercontent.com/3254090/124370298-d0dd0f80-dc43-11eb-8a78-183420a6bd62.png)
2021-07-13 14:44:59 +02:00
Brian Sperlongano 197ea39ae3
Remove unused osm_id column (#1147)
Fixes #1146

This PR removes the always-null osm_id column from the `transportation_name_linestring` table and the series of generalized tables that derive from it.

Demonstration of `transportation_name` objects behaving normally after the column has been removed:

![image](https://user-images.githubusercontent.com/3254090/124684944-4512ef80-de9e-11eb-998c-b66bc23be09e.png)
2021-07-13 13:39:28 +02:00
Frédéric Rodrigo a851f2c9e9
Review index on osm_waterway_linestring on osm_important_waterway_linestring_gen_z* (#1130)
Review index waterway.

* Remove not used index
* Fit index `osm_waterway_linestring_waterway_partial_idx` to query
2021-07-09 09:35:46 +02:00
Brian Sperlongano 4eb240466e
Simplify Trans-Canada Highway logic (#1143)
Fixes #1142

Screenshot from Alberta showing TCH still shown in `transportation_name` layer:
![image](https://user-images.githubusercontent.com/3254090/124532399-77f5ae80-ddde-11eb-8929-36970ebb8386.png)

Screenshot from Ontario showing TCH still shown in `transportation_name` layer:
![image](https://user-images.githubusercontent.com/3254090/124532512-b68b6900-ddde-11eb-9b6a-636c872375c1.png)
2021-07-06 08:43:26 +02:00
Brian Sperlongano c8377d38ac
include route relation ref in existence check (#1139)
Fixes #1138
Unblocks #1131
Unblocks #1128 

Below is an example of a way that is part of a route relation (in this case, RI-3), but does not have a ref set on the way itself:
![image](https://user-images.githubusercontent.com/3254090/124366616-1509e900-dc1f-11eb-87ab-aadd4f21287d.png)

This screenshot demonstrates that the `transportation_name` object now contains the ref from the route relation:
![image](https://user-images.githubusercontent.com/3254090/124366563-b5abd900-dc1e-11eb-9fd9-96315ddf7682.png)
2021-07-05 11:21:35 +02:00
Brian Sperlongano 1b0b1fd121
Compute separate concurrency_index on osm_route_member (#1135)
Closes #1134 

Adds a `concurrency_index` column to `osm_route_member` as described in #1134.  For example, listing concurrencies on a [segment of the Washington Bridge](https://www.openstreetmap.org/way/43080535) in Providence, Rhode Island, USA:

```
openmaptiles=# select osm_id, network, ref, network_type, name, concurrency_index from osm_route_member where member=43080535 order by concurrency_index asc;
  osm_id  | network | ref | network_type  |     name      | concurrency_index
----------+---------+-----+---------------+---------------+-------------------
 -1694950 | US:I    | 195 | us-interstate | I 195 (RI/MA) |                 1
 -2308410 | US:US   | 6   | us-highway    | US 6 (RI)     |                 2
 -1347856 | US:US   | 1A  | us-highway    | US 1A (RI)    |                 3
 -2309143 | US:US   | 44  | us-highway    | US 44 (RI)    |                 4
(4 rows)
```
2021-07-02 15:00:25 +02:00
Brian Sperlongano 3f70b878e2
nulling subclass when not present (#1132)
PR #1119 (adding support for `highway=motorway_junction`) missed a few cases where NULLIF functions were needed in order to suppress empty-string `subclass` tags from appearing in vector tiles, resulting in unnecessary  `subclass` entries on `transportation_name` objects where it was not needed, for example:
![image](https://user-images.githubusercontent.com/3254090/123889414-7a11c600-d923-11eb-938c-f278b9bf1ffa.png)

This PR adds the missing NULLIF function so that those empty tags are suppressed:
![image](https://user-images.githubusercontent.com/3254090/123889540-b6452680-d923-11eb-8f0b-5c8c03640059.png)
2021-06-30 07:06:22 +02:00
Frédéric Rodrigo a0847b85f1
Update osm_poi_point only on change (#1129)
After each diff import the table `osm_poi_point` is fully rewritten due to a full update of the field tags. It is now good to do an a update, event if the content does not change, postgres delete and reinsert internally the record. Resulting in more write and internal table size raising.

Note: not directly linked, but there is a problem in this case, the autocaccum is not sufficient to keep this table size moderate, but grow indefinitely.
2021-06-29 15:05:45 +02:00
Tomas Pohanka 9600cecf00
Add notice into README about import-osm (#1118)
Adding information when run `make import-osm`.

closes https://github.com/openmaptiles/openmaptiles/issues/1116
2021-06-28 22:54:00 +02:00
Frédéric Rodrigo 3b8248af63
Switch from amenity=embassy to office=diplomatic #1084 (#1085)
Switch from amenity=embassy to office=diplomatic as was about here #1084.
2021-06-28 16:58:21 +02:00
Brian Sperlongano 79c2ec929d
Add new layer to serve highway=motorway_junction nodes (#1119)
This PR adds a layer for `highway=motorway_junction` features.

This implementation of highway exits in the transportation_name layer add to the existing layer table structure, and renames the internal column name from "construction" (which was already overloaded with non-construction usages) to "subclass", which will be less confusing to future developers.  The string 'junction' is used as the universal sub-class for highway exits.

A new documentation PR has been opened at openmaptiles/www.openmaptiles.org#69 to reflect these changes in the documentation.
2021-06-28 14:35:27 +02:00
Brian Sperlongano 8d91cb3d94
Improve "make help" output (#1121)
This PR makes three improvements to the current `make help` output:

1. Adds additional help entries for useful `make` targets that were not currently in `make help`
2. Pipes the help output through `less` so that the user can scroll up or down through the various `make` targets if it overflows the length of the user's screen
3. Re-groups the "developer" targets into separate entries for database and docker-related commands

In addition, an unneeded whitespace was removed from line 7 of the Makefile.
2021-06-09 12:36:27 +02:00
Tomas Pohanka da88949067
WSL folder recommend (#1110)
Add a recommendation for folder use in WSL into README.

Extend #1108
2021-05-26 17:37:33 +02:00
Yuri Astrakhan ae9498547d
Workflow updates - bump vers, print perfcache info (#1111) 2021-04-30 11:43:04 -04:00
Tomas Pohanka d0ebdde458
Fix transportation road segments disconnection (#1109)
To avoid discontinuous transportation lines between zooms 9 and 11. 
 - Originally limit geometry by length for z9 - z11 (`ST_Length(geometry) > ZRes(11)`)
 - highway z9 to z11 was generalized during import-osm
 - now just create a filtered and generalized z11 table
 - then merge segments in the same way as from (full-featured) osm_highway_linestring and used this merged z11 for mat.view z10 and z9

Close #1107
2021-04-30 15:39:56 +02:00
zstadler 68ec5c7ac8
Update makefile to catch WSL folder error (#1108)
- Resolve #1103
- Remove dead code
2021-04-30 07:57:12 +02:00
Jeremias Volker 76d5d753d8
Fix own OSM instructions (#1101)
Before it was throwing `ERROR:  make generate-bbox-file area=<area-id>` and `Area source has not been specified. Auto-detecting...
ID 'my' was not found in Geofabrik.` `make: *** [download] Error 1`

* Use more meaningful area name

* rename user data example

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2021-04-20 14:59:43 +02:00
Eva Jelinkova f4a1a2537a
Water - add ogc_fid for NE sources, edit etldoc (#1098)
1) Adding ogc_fid column into materialized views of NE lakes (for having option to filter or compare)
2) Edit bug in etldoc

* add ogc_fid for NE sources, edit etldoc

* etl_diagram update
2021-04-12 12:09:45 +02:00
Rémy Léone 231a1d192c
update docker-compose version (#1091)
update docker-compose version from 2.3 to 3
2021-04-09 13:42:58 +02:00
Yuri Astrakhan 1f6eb7b4a3
Improve logging - show BBOX if exists (#1096)
The generate-bbox target will now show the value of BBOX if it is already generated.
2021-03-30 21:02:34 +02:00
Rémy Léone d5480d2369
Update naming convention for networks (#1093)
* Update naming convention for networks

* move to postgres
2021-03-30 08:46:42 +02:00
zstadler 2943e9dc8d
Avoid grep errors in `clean-unnecessary-docker` (#1089)
When `make clean-unnecessary-docker` is run twice, or when there are no docker images tagges as "<none>", make fails because grep fails:

```
Deleting unnecessary container(s)...
Deleting unnecessary image(s)...
make: *** [Makefile:562: clean-unnecessary-docker] Error 1
```

Using `awk` to _also_ search for "<none>", instead of `grep`, solves this issue.
2021-03-16 17:20:25 +01:00
Tomas Pohanka fadc4a3ba6
Explicit mention for using `iso_a2` attribute. (#1073)
Resolve #939
2021-03-16 11:21:25 +01:00
Tomas Pohanka bf9e6a19cd
osm_route_member bugfix (#1088)
`!=` is not handling `NULL` values.

Then all networks are `road` and not e.g. `us-interstate` or `ca-transcanada`.
2021-03-16 10:55:26 +01:00
Frédéric Rodrigo 50d569dfee
Remove useless indices on osm_transportation_merge_linestring_genX (#1079)
On creation of materialized views `osm_transportation_merge_linestring_gen_zX`, an index is created each time the new view and not used else where than the next generalization step.
It does not worth it to to a scan on the table to create index that will be used only once, while the next generalisation step can also be done in one full scan.
So, removing these indices.
2021-03-05 09:42:27 +01:00
Adam Laža d69ae015ad
Mount /export dir in docker-compose.yaml (#1071)
Mount /export dir in docker-compose.yaml
This PR allows `using make generate-tiles-pg` without editing `.env`.
Resolves #1070
Related to PR #1069
2021-02-05 14:58:42 +01:00
Jeroen Hoek 295688eb80
Add place=quarter to city subdivisions (#1065)
This adds `place=quarter` which was introduced in 2011 as a subdivision
of villages/towns/cities as a value that sits between `place=suburb` and
`place=neighbourhood`. It has by now been used over 40,000 times and is
rendered in the OSM-Carto.
2021-01-18 14:47:25 +01:00
Adam Laža c4c3089f40
Update openmaptiles.yaml - set center to 0,0,1 (#1063) 2021-01-14 18:13:00 +01:00
Adam Laža 4b26c63574
Upgrade version to 3.12.1 (#1062)
* Release 3.12 prerequisite

* Upgrade version.

Co-authored-by: Tomáš <tompohys@gmail.com>
2021-01-14 17:21:43 +01:00
tilmanb 077ec78f63
typo and spelling fixes in the output (#1060)
This simply fixes some spelling and/or grammar errors in the quickstart script output
2021-01-10 16:55:52 +01:00
Adam Laža 461043960e
Bugfix landcover osm (#1061)
* Release 3.12 prerequisite

* Add missing osm_id column to osm_landcover_polygon

Co-authored-by: Tomáš <tompohys@gmail.com>
2021-01-08 15:44:11 +01:00
Sergii Golubev 2aa9630b41
add forgotten 'garages' landuse to the docs (#1059)
In https://github.com/openmaptiles/openmaptiles/pull/720 I've forgotten to add the `garages` class to the docs. This PR is fixing that issue,
2020-12-29 14:26:14 +02:00
Tomas Pohanka 485eb6892c
Release 3.12 prerequisite (#1056) 2020-12-16 14:38:58 +02:00
Adam Laža 5772e61244
Bugfix in osm_landcover_gen_z10. (#1054)
Add missing `NOT` in WHERE condition.
It causes there are duplicated features of subclass `wood` and `forest` and features of other subclasses are missing.
2020-12-14 12:47:45 +02:00
Adam Laža 512b3435ad
Bugfix update_aerodrome_label_point() (#1051)
Bug introduced in #944.
Missing exclamation mark in not equal operator caused that tags were not updated thus there were missing `name_int`, `name:latin` and `name:nonlatin`.
2020-12-08 17:27:12 +02:00
Dalibor Janák b2b8716840
Update links in readme (#1050)
Updated not existing links to openmaptiles.com.
2020-12-08 16:57:40 +02:00
Taro Matsuzawa aka. btm 924558d7d9
Enable pgquery (#1048)
I try to use pgquery, it needs some configuration in .env file.
I think if we use pgquery instead of mapnik, the performace will be good.
2020-12-08 15:56:01 +02:00
Andrii Korzh 01d53a26c6
Fix detected area filename (#1049)
User can be confused that script detected non existing file.
2020-12-07 17:30:16 +02:00
Adam Laža 77f5d76e37
Refactor schema, one _gen_z view per zoom. (#1045)
* Refactor layer aeroway.

* Refactor layer boundary.

* Refactor layer landcover.

* Refactor layer landuse.

* Refactor layer park.

* Refactor layer transportation.

* Refactor layer water.

* Refactor layer waterway.

* Re-generate water* layers etl_diagrams.

* Regenerate etl_diagrams for waterway.

* Cast NULL to text.
2020-11-26 13:54:00 +01:00
Tomas Pohanka 0c6fe2d9ba
Building aggregation fix (#1044)
This PR solving the speed and memory issue with buildings aggregation on zoom level 13. The problem was to create ST_ClusterDBScan which failed after try to cluster a larger area. Now it will make cluster only in "small" polygon using 'country_osm_grid` which covers the world's lands. 

This PR solving #1022 and #974
2020-11-24 12:27:06 +02:00
Tomas Pohanka 24b9328a5f
Remove unused generalization from waterway (#1043)
During the import-osm step, there are three generalized tables for the waterway that are not used for subsequent processing.
Thanks @lazaa32 for the notice.
2020-11-24 11:30:00 +02:00
Adam Laža da689f9e42
Fix landcover generalization. (#1042)
This PR brings few modification which make it possible to generalize landcover on larger areas. Tested on Europe.

- Use ST_SnapToGrid to avoid ERROR:  GEOSUnaryUnion: TopologyException: found non-noded intersection between LINESTRING.
- Cluster only landcover subclasses: wood and forest.
- Use less generalized tables as a starting point for next step generalization.
2020-11-24 10:33:06 +02:00
Tomas Pohanka 0776cd3eed
README - Rename target for bbox-file by new tool 5.3 (#1040)
Changed in Use 5.3 - new bbox value (#1012)
2020-11-13 14:34:41 +02:00
Tomas Pohanka 3ef364552e
add state name to national borders (#1039)
This PR adds state name to national borders (`admin_level=2`)

From zoom level 3 there is an added `adm0_l` and `adm0_r` attribute for national borders.

There is 3 main steps: 
1) union border lines from OSM and keep separate LineString between intersects
2) create polygons from step 1), create a point in each state polygon, add to this point a state abbreviation from NaturalEarth Data
3) create a short parallel line on the left and right of a small part of the border in 70m distance, and add information about which state overlap this short line.
2020-11-12 12:14:13 +02:00
Tomas Pohanka d180988f5f
Move "qa" tools from OMT to OMT-T (#1031)
With the new release of OMT-T (5.3) are available tools [`layer-stat`](https://github.com/openmaptiles/openmaptiles-tools/pull/293). 

With the new release of OMT-T can be replaced `make` target `generate-qareports` by `generate-qa`

Used as:
```
make generate-qa STAT_FUNCTION=frequency LAYER=transportation ATTRIBUTE=class
```
2020-11-12 11:23:06 +02:00
Eva Jelinkova 0aa6648bd9
adding brunnel into z<9 (#1038)
Following https://github.com/openmaptiles/openmaptiles/pull/1027, solving https://github.com/openmaptiles/openmaptiles/issues/999.

Adding brunnel attributes to merge tables of `transportation` layer, now it is possible to style/filter tunnels, bridges and fords in all zoom levels. Tested on Switzerland and Europe. Changes in generation speed and filesize minimal.
2020-11-11 15:37:09 +02:00
Tomas Pohanka 4a1b0afa26
reworked landcover layer (#1035)
Instead of using [Douglas-Peucker algorithm](https://postgis.net/docs/ST_SimplifyPreserveTopology.html) which is using for generalized tables [imposm](https://imposm.org/docs/imposm3/latest/mapping.html#generalized-tables) it is used [Visvalingam-Whyatt algorithm](https://postgis.net/docs/ST_SimplifyVW.html).

Solution:
remove imposm generalized tables (during `import-osm`) and create generalization in `import-sql` step for zooms 7-14. Zooms 0-6 are from Natural Earth data.

Upper zoom levels (7 and 8) are ok to merge with no big impact on creation speed. In Canada from z9 it took too long. Between zoom levels 10 - 13 there can be union polygons with less than 300 edge points (empirical number based on a test on Canada forest, can be discussed). Polygons with more than 300 edge points are just simplified. Zoom 14 is from the original dataset `osm_landcover_polygon`.

There is also removed `osm_id` which is never used and not passed into vector tiles.
2020-11-11 15:11:48 +02:00
Adam Laža 0dc8c3256c
Rename generic layer.sql to actual_layer_name .sql (#1034)
Following layers had generic `layer.sql` name.

- `aerodrome_label`
- `aeroway`
- `housenumber`
- `mountain_peak`
- `park`
- `place`
- `poi`
- `transportation`
- `transportation_name`
- `water_name`

This PR renames `layer.sql` to `aerodrome_label.sql`, `aeroway.sql`...
2020-11-09 11:43:35 +02:00
Eva Jelinkova a36db48a3e
Revert "#766 remove housenumbers inside polygon and same number (#983)" (#1033)
This reverts commit 1685eaccbd.
2020-11-04 21:53:15 +01:00
Eva Jelinkova 8ba2e18dea
Revert "Housenumbers - diff update, multipolygons (#990)" (#1032)
This reverts commit f7d7a0ced3.
2020-11-04 21:07:09 +01:00
Yuri Astrakhan 97ffabcb49
Use 5.3 - new bbox value (#1012)
Migrate to tools 5.3 and use the new bbox value.

* Use 5.3 - new bbox value
* Return correct bbox for meta-generate
mbtiles-tools meta-generate is now able to use bbox from *.bbox file

Thanks @nyurik
2020-10-26 18:39:49 +02:00
Tomas Pohanka 72af34612a
Add gates to airports (#1029) 2020-10-19 12:24:16 +03:00
zstadler 09b68ed1c2
Allow `BBOX` to be set in `.env` file (#1013)
* Allow setting `BBOX` to be set in `.env` file

Currently, the `BBOX` setting in `.env` is ignored for all areas except `planet`.
On the other hand, the `planet` area is an overkill for any `BBOX` setting other than the default - `-180.0,-85.0511,180.0,85.0511`.

With this PR, `quickstart.sh` would not override a modified `BBOX` value in `.env`. 

Also, this provides a way to avoid the pessimistic `BBOX` computation for `osmfr` extracts, as described in https://github.com/openmaptiles/openmaptiles-tools/pull/297#issuecomment-700792702

#### Currently
- If the user does not do anything, `quickstart.sh` and `make generate-tiles` create an `mbtiles` file for the full extent of the data source. This applies to `planet` and other data sources.
- If a user sets the `BBOX` value in `.env` and a `planet` data source is used, `quickstart.sh` and `make generate-tiles` create an `mbtiles` file for the extent set in the `.env` file.
- If a user sets the `BBOX` value in `.env` and a non-`planet` data source is used, it is ignored - `quickstart.sh` and `make generate-tiles` create an `mbtiles` file for the full extent of the data source.

#### Problem statement
While users of a `planet` data source have a simple way to override the default extend of the tile generation, users of other data sources have no simple way of doing that. In fact, for such users the `BBOX` setting in the `.env` file is ignored and therefore misleading.

#### Proposal
- If the user does not do anything, `quickstart.sh` and `make generate-tiles` create an `mbtiles` file for the full extent of the data source. This applies to `planet` and other data sources.
- If a user sets the `BBOX` value in `.env`, `quickstart.sh` and `make generate-tiles` create an `mbtiles` file for the extent set in the `.env` file. This applies to `planet` and other data sources.
2020-10-15 11:38:11 +03:00
Eva Jelinkova 341c4df171
Brunnel changes in transportation and transportation_name layers (#1027)
https://github.com/openmaptiles/openmaptiles/issues/999

- Point 1 solved only partially - there is `brunnel` value added into zooms 9, 10, 11. For zooms 8 and smaller it would need change in osm_transportation_merge_ tables - I am going to try it but maybe its SQL costs will be to high.

- Point 2 solved.
2020-10-14 15:26:43 +03:00
Tomas Pohanka b7429ce6f5
union ocean regular squares into complex polygon (#1021)
The ocean layer (table osm_ocean_polygon insert by `make import-data`) is made from squares that have a 10m buffer. 

This creates extra geometry in vector tiles as:

Union of full ocean squares should decrease the size of the water layer.

there are 8042 polygons (squares, 5 points, more then 100km<sup>2</sup>), which was reduced to 22 polygons - 1184kB vs 40kB respectively. 

In mbtiles should be the size reduction even more significant, due to the creation of more polygons based on a 10m buffer of each square.
2020-10-14 14:56:04 +03:00
Tomas Pohanka 72165933be
add ST_IsValid where ST_PointOnSurface (#1025)
Same as #1015 for another ST_PointOnSurface
2020-10-13 16:28:20 +03:00
Tomas Pohanka 88c13f713f
Korean and Japanese Latin (#1026)
Korean moved from `ko_rm` to `ko-Latn`. Same as Japanese deprecated `ja_rm` in advance of `ja-Latn`, but still have twice more records. For Japanese add Hiragana form.

fix #537 
listed in #930
2020-10-13 15:52:15 +03:00
Frédéric Rodrigo cfc243e848
Add protocol to postserve --serve paramter (#1007)
The current option of postserve in the docker-compose produce an invalid tilejson.
```json
"tiles": ["localhost:8090/tiles/{z}/{x}/{y}.pbf"]
```
`tiles` should be URL. The protocol is missing.

Not sure about the best way to fix this. Just adding `http://` to the docker-compose.yaml does not allow https usage. But setting protocol in `OMT_HOST` seems weird.

Could add an extra OMT_PROTOCOL with `http` as default.
2020-10-12 16:45:09 +03:00
Eva Jelinkova 7a7e9326b9
adding ST_IsValid to housnumber geometry (#1015)
Adding check of geometry in layers/housenumber/housenumber_centroid.sql.
2020-10-12 15:05:20 +03:00
Eva Jelinkova 3d21523fbe
aerialway class for the transportation layer (#1011)
Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2020-10-12 12:44:33 +02:00
Frédéric Rodrigo 36b7533d3b
Add timers to trigger function (#1006)
Add timer to all trigger refresh functions to help point where the time is spend on update.
2020-10-08 16:57:16 +03:00
zstadler e8bf4aa94a
Update makefile for hierarchical area names (#1009)
- Use `find` instead of `wildcard` to detect existing `.osm.pbf` files
- Use `patsubst` to extract an `area` from a filename
- Clarify messssage, especially for errors

Resolve https://github.com/openmaptiles/openmaptiles/issues/1008
2020-10-01 08:10:01 +03:00
Frédéric Rodrigo 883a997dcf
Remove large unused index osm_highway_linestring_highway_idx (#1002)
The index `osm_highway_linestring_highway_idx` is not used. There is also a used partial index `osm_highway_linestring_highway_partial_idx`.

I cross check the usage of the index from postgres query stats and all SQL query code where the table `osm_highway_linestring` is refered.

This index is relatively big.
2020-09-30 11:30:18 +03:00
Frédéric Rodrigo a3ce04fe23
Add landuse=salt_pond as water (#1000)
Add salt pond as water.

Most of salt pond are already tagged with natural=water even if it's not required. So the load added by this tag is very light.
2020-09-29 07:53:35 +03:00
zstadler 424c4ee8a3
Remove workaround for quickstart.sh (#998) 2020-09-28 22:28:34 +03:00
Frédéric Rodrigo c8f919e9d6
Better update of osm_important_waterway_linestring, use frist and last version of osm object (#997)
Current implementation of osm_important_waterway_linestring have two bugs:
* The distinct on is_old keep the oldest version of the old object, and the oldest version of the new object, but need the last version of the new object.
* Delete the old version of the object and rebuild the using the new version of the object. But we need to remove matchings the old and the new version of the object, then rebuild the two.

Then only delete and update using first and last version of the object, intermediate versions are ignored.

Similar implementation of what is done in #996.
2020-09-28 17:07:37 +03:00
Frédéric Rodrigo 8bb77b67a1
Diff update osm transportation name network linestring (#996)
Replacing materialized view by a tables with update from trigger on change only.

Differential update of `osm_transportation_name_linestring`, `osm_transportation_name_linestring` and `osm_transportation_name_linestring_genX`).

At the end of the transaction the dependent rows are updated.

The goal is to update more quickly the content of derivated tables by just updating the changing content. It replaces the update of materialized view because their need a full recompute (with lock issue).

It is the last part of the replacement of materialized view for the transportation layer.

It addresses #814 and a part of #809.
2020-09-28 15:56:10 +03:00
Frédéric Rodrigo 47cdfc2c8b
Move where condition from osm_transportation_name_linestring to materialized view osm_transportation_name_network (fix) (#993)
On PR #991 the differential update was not updated like the main code.

Make similar change to the update code.
2020-09-23 11:10:59 +03:00
zstadler d8b5e8e82d
openmaptiles-tools: consider MIN_ZOOM/MAX_ZOOM env (#992)
Allow MIN_ZOOM, and MAX_ZOOM to be overwritten from shell for `quickstart.sh`, `make generate-dc-config`, and other `docker-compose openmaptiles-tools` uses.

For example,
```
export MAX_ZOOM=14; ./quickstart.sh monaco
```
ignores the `MAX_ZOOM=14` environment variable and uses the `MAX_ZOOM=7` value from `.env` file

This PR will also make this code unecessary
5c640daf4f/.github/workflows/tests.yml (L26-L28)
2020-09-23 10:09:22 +03:00
swiss-knight 0245b21634
NOOP: Minor Makefile clean up (#994)
Minor fix.
2020-09-22 11:27:45 +03:00
Eva Jelinkova f7d7a0ced3
Housenumbers - diff update, multipolygons (#990)
Following https://github.com/openmaptiles/openmaptiles/pull/983 - removing points also on multipolygons and checking only new geometry when updated.
2020-09-21 14:47:55 +03:00
zstadler 45f5b53c9c
Stitch `transportation_name` by all language tags (#989)
When OSM roads in the `transportation_name` layer are stitched together, their grouping does not consider all `name:*` tags.
As a result, roads with different `name:*` tags may be stitched together.

The `waterway` layer performs the grouping properly, for the same purpose:
1685eaccbd/layers/waterway/update_important_waterway.sql (L34)

Co-authored-by: Frédéric Rodrigo <fred.rodrigo@gmail.com>
2020-09-21 12:38:13 +03:00
Frédéric Rodrigo 5c640daf4f
Move where condition from osm_transportation_name_linestring to materialized view osm_transportation_name_network (#991)
Reduce the size of the materialized view osm_transportation_name_network by moving the weare clause.
osm_transportation_name_network is only used for osm_transportation_name_linestring.

Co-authored-by: zstadler <zeev.stadler@gmail.com>
2020-09-21 10:02:20 +03:00
Frédéric Rodrigo 550b1f8f90
Replace materialized view osm_transportation_name_network by a table with diff update (#987)
Replacing materialized view by a tables with update from trigger on change only.

The osm_id of object changing on table osm_route_member and osm_highway_linestring are logged.
At the end of the transaction the dependent row of osm_transportation_name_network are updated.

The goal is to update more quickly the content of derivated tables by just updating the changing content. It replaces the update of materialized view because their need a full recompute (with lock issue).

Note, it is only a part of the materialized view of the transportation layer, I am also working on the other parts, other parts are in #892 (omaterialized view on sm_transportation_name_linestring and osm_transportation_name_linestring_genX).

It addresses #814 and a part of #809.
2020-09-18 16:49:55 +03:00
Taro Matsuzawa aka. btm 1685eaccbd
#766 remove housenumbers inside polygon and same number (#983) 2020-09-16 17:06:48 +02:00
zstadler fb7c1ef42b
Update Makefile (#984)
Update `make help` according to #750
2020-09-15 08:18:18 +03:00
zstadler c82c706bc3
Clean output of `list-views` and `list-table` (#985)
Avoid printing a fixed `public,` prefix in the output of `make list-views` and `make list-table`.
As `make help` says, `list-views` and `list-table` list only the public schema views and tables.

New output:

```
viewname
boundary_z0
boundary_z1
boundary_z10
boundary_z11
boundary_z12
boundary_z13
boundary_z3
boundary_z4
boundary_z5
boundary_z6
boundary_z7
boundary_z8
boundary_z9
geography_columns
geometry_columns
...
```

Existing output:

```
schemaname,viewname
public,boundary_z0
public,boundary_z1
public,boundary_z10
public,boundary_z11
public,boundary_z12
public,boundary_z13
public,boundary_z3
public,boundary_z4
public,boundary_z5
public,boundary_z6
public,boundary_z7
public,boundary_z8
public,boundary_z9
public,geography_columns
public,geometry_columns
...
```
2020-09-14 15:07:35 -04:00
Frédéric Rodrigo df56b75719
Clean update_route_member.sql (#981)
Clean and do refactoring on `update_route_member.sql` as first step to replace materialized view osm_transportation_name_network by tables with diff update. See #892.
2020-09-14 19:13:32 +03:00
Taro Matsuzawa aka. btm 7b2df3b64f
write how to generate dc-config (#982)
Added document about how to generate dc-config in QUICKSTART.md.
2020-09-14 18:20:24 +03:00
Jorge Sanz bd444c0d1a
Show more state borders at low zoom levels (#979)
* Change NE 50m by NE 10m state provinces dataset

* update documentation

Fixes #977 

This PR implements the change discussed at #977 to replace Natural Earth 10m states and provinces by the 50m version, since the 10m only covers state borders for US, Canada, Brazil, and Australia.

A few remarks:

* This change only affects zooms 1 to 4, not making any change in borders based in the `OSM Borders`  source. 
* The `min_zoom<=7` shows the first level regions (level 4 in OSM) as you can check for example for France, Italy, or Spain.
* I don't think it's necessary to simplify the geometries, it would mean adding a new materialized view, or a slower tile generation process.
* This change does not need any change in the styles, even someone could argue it could be interesting to add the country code in this layer as a new field, allowing style editors to filter features by country, but I would prefer to leave that change for another PR.
2020-09-10 09:41:43 +03:00
Eva Jelinkova 1356d724d4
adding disputed_name to NE sources (#976)
`disputed_name` is filled for disputed lines of NaturalEarth sources - it contains `ogc_fid` as suggested in https://github.com/openmaptiles/openmaptiles/issues/964. This way it is possible to filter disputed lines in style.
2020-09-03 21:09:15 +03:00
zstadler de95843e02
Allow setting TILESET_FILE by shell or Makefile (#975)
Following the 10efc29280 (r41977444) comment
2020-09-02 13:14:55 -04:00
Jorge Sanz 194b2fbb70
Add state labels at low zoom levels (#969)
* Remove state labels zoom, rank, and country conditions from layer function

* Don't add labels for zooms 0 and 1

If we check Bright, Positron, or Dark styles, they all show a huge lack of data about states and regions. At zoom 2, for big countries like Canada, Brazil, China or Australia there are big patches of white space (aka cartographer's *horror vacui* 😅)
2020-09-02 09:02:43 +03:00
David Zhao a4671b84f0
Expose COPY_CONCURRENCY to users (#972)
Allow users to override how the number of threads used when generating map vector tiles.
2020-09-01 14:46:53 +03:00
naveenkumar 4807ccee24
adding hi(hindi),ta(tamil) and te(telugu) language (#973) 2020-09-01 12:25:17 +03:00
Frédéric Rodrigo 04d1b66e67
Incremental update marine point (#952)
Replacing update on the whole table with an update only on changed rows.

The goal is to update more quickly by just updating the changing content.
The update now focus on osm_id of changed rows, it use index. Add a where clause tags != update_tags(tags, geometry) to ensure only update when changed.

It requires one more trigger and a table to store changed osm_id.

The UPDATE is keep in a function to be reusable for initial setup and trigger update.

It is a based on the already merged https://github.com/openmaptiles/openmaptiles/pull/944

It is a separated PR as less obvious than previous. It replaces the reset of the `rank` field to NULL by missing value resulting of `LEFT JOIN`. It avoid triggering a new update on the table by reset the value then re-seting it to initial or new value.

It addresses #814.

Thanks @frodrigo
2020-08-30 16:16:54 +03:00
Frédéric Rodrigo 82616eaac0
Make update_city_point use incremental update #814 (#951)
Replacing update on the whole table with an update only on changed rows.

The goal is to update more quickly by just updating the changing content.
The update now focus on osm_id of changed rows, it use index. Add a where clause tags != update_tags(tags, geometry) to ensure only update when changed.

It requires one more trigger and a table to store changed osm_id.

The UPDATE is keep in a function to be reusable for initial setup and trigger update.

It is a based on the already merged https://github.com/openmaptiles/openmaptiles/pull/944

It is a separated PR as less obvious than previous. It replaces the reset of the `rank` field to NULL by missing value resulting of `LEFT JOIN`. It avoid triggering a new update on the table by reset the value then re-seting it to initial or new value.

It addresses #814.

Thanks @frodrigo
2020-08-30 15:29:50 +03:00
Frédéric Rodrigo bb2a4328f3
Make more simple incremental update (#944)
Replacing update on the whole table with an update only on changed rows.

The goal is to update more quickly by just updating the changing content.
The update now focus on osm_id of changed rows, it use index. Add a where clause tags != update_tags(tags, geometry) en ensure only update when changed.

It requires one more trigger and a table to store changed osm_id.

The UPDATE is keep in a function to be reusable for initial setup and trigger update.

I try many code layout before done it in this way with the goal to keep the code for initial pass and for update. It should have low impact on initial data load. Better performance for row update can be achieve with BEFORE UPDATE, but require to duplicate the logic.

It is not based on the already merged https://github.com/openmaptiles/openmaptiles/pull/896 because calling and update within a function for each updated row was not efficient for larger table (like housenumber).

It addresses #814.


* Remake update_peak_point use incremental update #814

* Make update_aerodrome_label_point use incremental update #814

* Make housenumber_centroid use incremental update #814

* Make update_continent_point use incremental update #814

* Make update_island_point use incremental update #814

* Make update_island_polygon use incremental update #814

* Remove dead code in update_state_point.sql

* Make update_state_point use incremental update #814

* Remove dead code in update_country_point.sql

* Make update_country_point use incremental update #814

* Make osm_poi_polygon use incremental update #814

Thanks @frodrigo
2020-08-28 11:03:27 +02:00
Frédéric Rodrigo 10efc29280
Make tileset def openmaptiles.yaml a variable (#968)
Move the hard coded `openmaptiles.yaml` from Makefile to a variable. Allows use other tileset definition.
A step forward easy alternative layer definition.
2020-08-27 12:43:09 -04:00
zstadler 1daacf354e
Use line buffering by `awk` in `make import-sql` (#962)
Resolve https://github.com/openmaptiles/openmaptiles/issues/958
2020-08-10 10:41:14 +02:00
Frédéric Rodrigo 232379b3ca
Do insensitive case compare using lower() and not ILIKE (#961)
* Replace ILIKE by lower() for insensitive case compare

* Refactoring SQL insensitive case compare
2020-08-06 09:14:47 +02:00
zstadler 6a512af90f
Special cache handling for Docker Toolbox on Windows (#957)
resolves https://github.com/openmaptiles/openmaptiles/issues/807
2020-08-03 18:12:09 +02:00
zstadler 751551f910
Add `$OMT_HOST` support to `make start-postserve` (#956)
Resolve https://github.com/openmaptiles/openmaptiles/issues/955
2020-07-28 18:28:04 +02:00
zstadler 897846380a
Rephrase `area` detection messages (#954)
Thanks @zstadler.
2020-07-28 07:25:52 +02:00
Frédéric Rodrigo 9bb17792a6
Remove alignment of AS in SQL and few others (#932)
* Remove alignment of AS in SQL

* Remove alignment of CREATE TABLE in SQL
2020-07-22 13:48:25 +02:00
Frédéric Rodrigo 13aaa404d9
Fix More fail safe incremental update on water_lakeline and water_point (#949) (#950) 2020-07-22 12:17:33 +02:00
Frédéric Rodrigo 098f2d1ce2
Fix peak doc (#941) 2020-07-21 18:05:46 +02:00
Frédéric Rodrigo dd1b2d3b15
More fail safe incremental update on water_lakeline and water_point (#949)
Improve 97216c5c19 and #853

In case of replay update it may fails because of already existing primary key on osm_id.

Add a on conflict clause to make it fail safe.
2020-07-21 17:35:49 +02:00
Tomas Pohanka c86f4a557a
Build aggregation on zoom level 13 (#936)
* Building aggregation at zoom 13
2020-06-18 14:01:06 +02:00
Frédéric Rodrigo 6ac544fc96
Make update_osm_peak_point use incremental update #814 (#896)
Thanks a lot @frodrigo.
2020-06-17 19:58:12 +02:00
Yuri Astrakhan 2b95d1cffa
Fix & optimize incorrect function declarations (#918)
* All functions that access database must be declared as `STABLE`, not `IMMUTABLE` -- because database can change at any moment, e.g. during an update
* there are a few functions that could be made `STRICT` -- passing `NULL` as a parameter will always result in a `NULL`, but for some reason that causes a significant decrease in perf.
* tagged one function as parallel safe

NOTE: somehow `ST_AsMVT()` method of tile generation is showing 70-90% slowdown with this patch. I am not sure of why this is happening. If the reason is the `IMMUTABLE` -> `STABLE` change, we may have to dig deeper into PG optimization
2020-06-17 12:15:26 -04:00
Yuri Astrakhan ad8bd41567
Do not wait for integrity test (#934)
It's ok if integrity test fails -- makes the whole testing process faster by 10 minutes at a cost of some extra CPU cycles.
2020-06-14 11:02:44 -04:00
Tomas Pohanka 8f31655564
Change GitHub Actions to dedicated server (#929)
* Change GitHub Action to the dedicated server Ralph

* bugfix - let quickstart generate-tiles up to zoom 14
2020-06-12 11:04:33 +02:00
Yuri Astrakhan f889853cb6
aerodrome_label: Remove unused function parameter (#919)
Minor optimization - in function `layer_aerodrome_label(bbox, zoom_level, pixel_width)` last parameter is not being used, so removing.
2020-06-11 14:24:55 -04:00
Yuri Astrakhan 447a8380e0
Fix incorrect Imposm config updates (#922)
* Current code incorrectly passes `IMPOSM_CONFIG_FILE` to the `generate-tiles` image, but should pass it to the tools.
* add a test to ensure imposm config exists
* add a test to ensure area is set during updates
2020-06-09 10:00:10 -04:00
Yuri Astrakhan 491bb10bd7
Expose MAX_PARALLEL_PSQL to users (#927)
Allow users to override how many import-sql files are loaded in parallel at the same time.

This change should be a noop
2020-06-09 09:53:02 -04:00
zstadler 5e65ac8c52
Add area-base filtering for park names in lower zoom levels (#911)
Resolve https://github.com/openmaptiles/openmaptiles/issues/776

Thanks @zstadler for this PR.
2020-06-09 10:53:18 +02:00
zstadler ffd237d5c8
Fix `clean-unnecessary-docker` make target (#921)
Add missing `-q` flag
2020-06-08 12:40:04 -04:00
Yuri Astrakhan 0b1511d60d
NOOP water - Move updating sql into separate file (#920)
Use `update_water.sql` for all queries that update db
to be consistent with the other layers.
2020-06-08 12:32:09 -04:00
Yuri Astrakhan 60a3e1ea70
Fix Makefile duplicate runs (#923)
Make sure that core targets (i.e. part of the `all` target like build-sql and build yaml files) do not run multiple times if they already exist.

Makefile for some reason does not like it when a real target depends on a PHONY target, and re-runs it. I added an `if` statement to skip building targets if their result already exists.
2020-06-08 12:26:11 -04:00
Yuri Astrakhan 6457419e0d
NOOP: Format all layer's SQL code (#917)
I would like to reformat all of our SQL to have a concise coding style.
This makes it far easier to understand the code for a casual contributor,
and lets us spot errors more easily.

Most importantly, it makes it much easier to grep (search) the code because it is more likely to be in the same syntax

Some key changes:
* SQL keywords are always UPPERCASE, e.g. `SELECT WHEN AS END ...`
* types, variables, aliases, and field names (identifiers) are always lower case
* `LANGUAGE 'plpgsql'` is now `LANGUAGE plpgsql` (no quotes)
* a few minor spacing/semicolon cleanups

P.S. Per @TomPohys request, `TABLE` is spelled using upper case despite being a type for consistency with PG Docs. Same for `LANGUAGE SQL` vs `LANGUAGE plpgsql`.
2020-06-08 12:19:55 -04:00
Yuri Astrakhan 805d95df09
Fix import-borders if runs multiple times (#916)
Running './quickstart monaco' twice in a row will cause an error the second time.
2020-06-05 12:48:48 -04:00
Yuri Astrakhan 1a9f6132c3
New generate-dc-config target, rm QUICKSTART_MIN/MAX_ZOOM (#915)
* Set `MAX_ZOOM` to 7 by default.
* Remove `QUICKSTART_MIN/MAX_ZOOM` - unneeded complexity with two env vars. We can just use `MIN_ZOOM` and `MAX_ZOOM`. See also #261
* Generate dc-config yaml file with a new `make generate-dc-config` step. It will compute BBOX based on the downloaded data file. This step is not needed for planet generation.
* Generate Imposm replication file only when `DIFF_MODE` is `true`. Not needed otherwise. If the data source does not support it, it will throw an error.
2020-06-04 15:45:04 -04:00
Yuri Astrakhan 1486b7e0cb
Rework download area support (#908)
Closes #904
* Make all data-related targets like `download*`, `import-osm`, `import-borders`, and `generate-tiles` into `area`-aware -- making it possible for multiple data files to coexist inside the `./data` dir.
* Add `make download area=... [url=...]` command to automatically download any kind of area by checking Geofabrik, BBBike, and OSM.fr, optionally from a custom URL. Supports `area=planet` too.
* Do not re-download area with `make download-*` if it already exists.
* Automatically rename `<area>-latest.osm.pbf` into `<area>.osm.pbf`
* If `area=...` parameter is not given to `make`, see if there is exactly one `*.osm.pbf` file, and if so, use `*` as the `area`.
* Configure many variables in the .env file, overriding the defaults in tools
* If `<area>.osm.pbf` exists, but `<area>.dc-config.pbf` is missing, generate it using `download-osm make-dc` command.

Also:
* closes #614
* closes #647
* partially addresses #261
2020-06-03 15:37:45 -04:00
Yuri Astrakhan fca53ef0ee
Minor makefile/quickstart cleanup (#907)
* Make a few spacing adjustments for ease-of-reading and consistency
* fix bbbike naming and other source urls
* remove unneeded `override`
* added `list-bbbike` target
2020-06-01 12:54:30 -04:00
Yuri Astrakhan 546f26e68a
MVT: use gzip and generate for v3.0 (#906)
This only changes the generated `getmvt(...)` function used by mvt users.

Beginning with tools 5.1, postgis docker images uses postgis v3.0, and includes gzip extension
2020-06-01 12:46:34 -04:00
Yuri Astrakhan 1a31b9212e
Minor fix import-borders file param (#905)
just like import-osm, import-borders can accept PBF_FILE param
2020-06-01 12:33:26 -04:00
Yuri Astrakhan 907fc58ee2
Use tools v5.2 (#903)
* Use [tools v5.2](https://github.com/openmaptiles/openmaptiles-tools/releases/tag/v5.2.0)
* Use `mbtiles-tools meta-generate` instead of the removed `generate-metadata` script.
* Remove `show-metadata` make target - it was just added and is not needed.

## Relevant changes
* Upgrade [osml10n PG extension](https://github.com/giggls/mapnik-german-l10n) to the faster v2.5.9 (significant performance improvements merged upstream by @nyurik)
2020-06-01 12:15:36 -04:00
Adam c6fff879ac
remove automatic osmfr choice (#902)
Resolves #895
2020-05-27 16:34:53 +02:00
Jan-Philipp Benecke 99c6be722d
Add "shop=car_parts" (#874)
Thanks
2020-05-27 16:08:53 +02:00
Yuri Astrakhan 28af9c0d9a
Add BORDERS_CLEANUP param to .env (#886)
This should be a noop, but will help users that it is available.
2020-05-26 15:37:13 -04:00
Yuri Astrakhan dbf130deb0
Allow custom ports for postserve/tileserver (#887)
* `make start-postserve PPORT=8000`
* `make start-tileserver TPORT=9000`

Note that both ports need to be the same on host and inside the docker container because the services include a URL to the tiles as part of their manifest.
2020-05-26 15:19:52 -04:00
Frédéric Rodrigo 495e8bd370
Align update.sql file naming to other layers (#897)
Code clean.

Use the same naming convention for the SLQ update file as other layer.
2020-05-26 21:03:07 +02:00
Tomas Pohanka b2ab969128
Update steps for 'Using your own OSM data' (#889)
Add more clear step into quickstart.md for using own OSM data
fix #843
2020-05-26 20:50:00 +02:00
Frédéric Rodrigo 6feefb4145
Use osm_id as feature id for building layer (#827)
Change the feature_id of objects in the tiles from arbitrary number to osm_id.

From discussion here https://github.com/openmaptiles/openmaptiles/pull/725#issuecomment-619059931

Note the multiploygon building are load with negative relation osm_id. But the use in feature_id do an overflow (eg -7980888 -> 18446744073701570000). We can keep as is or not.

No stats done for yet. Trying to let the CI do it.
2020-05-26 20:44:36 +02:00
Yuri Astrakhan cec49b23ba
Save DB schema during test run (#891)
Places the output of `pg_dump --schema-only` into the saved build artifact as `schema.sql`

Closes #877
2020-05-26 14:30:27 -04:00
Yuri Astrakhan 19673b5592
Print generated metadata during quickstart (#894)
Add a new `show-metadata` target to show all settings
in the .mbtiles file.
2020-05-26 13:35:52 -04:00
Yuri Astrakhan d0ff8be5f4
Use CleanNumeric in buildings layer (#858)
`nullif(as_numeric(height),-1)` is doing a double conversion -- null into -1 followed by -1 back into null. Remove that, and delete unused `as_numeric`
2020-05-24 16:59:35 -04:00
Yuri Astrakhan a82397940a
Hide Mapnik warnings once available (5.1) (#884)
Uses the patch by @zstadler to filter out irrelevant Mapnik warnings.
This will be ignored until tools v5.1 is used.
2020-05-24 16:04:05 -04:00
Yuri Astrakhan 04ae4a6b50
Upgrade to tools v5.1 (#883) 2020-05-24 15:56:03 -04:00
Frédéric Rodrigo 2622c5bfac
Update route member tagging support of Trans-Canada Highway (#864)
* Fix space at start in update_osm_route_member()

* Update Canada network route name

* Update Canadian route network
2020-05-22 15:52:51 +02:00
Frédéric Rodrigo e808590a4a
Add landuse=basin as water (#876)
Add support of tag landuse=basin as water polygon.
2020-05-22 14:45:18 +02:00
Jan-Philipp Benecke f5d34b5949
Mapping leisure=swimming_pool as water (#878)
Adds tag leisure=swimming_pool as water polygon
2020-05-22 10:31:47 +02:00
Yuri Astrakhan 6a41245288
Generate getmvt() func with build-sql (#880)
Add `getmvt` sql function as part of the build-sql make step. The function will be imported into PG during the `import-sql` step after all other SQL is done.  This is a noop for the `generate-tiles` approach.
2020-05-20 13:52:18 -04:00
Yuri Astrakhan bac0f25b1d
Remove parallel safe on layer_building for now (#882)
layer_building uses osm_all_buildings, which uses a
non-parallel-safe as_numeric.  Marking it as non-parallel safe
for now until we switch to CleanNumeric later.
2020-05-20 13:38:11 -04:00
Frédéric Rodrigo 97216c5c19
Replace materialized view of water by tables with diff update (#853)
Replacing materialized view by a tables with update from trigger on change only.

Start with the most simple cases.

Just replicate the change on:
* `osm_water_polygon` to `osm_water_lakeline`,
* `osm_water_polygon` to `osm_water_point`.

Use a view to factorize the `osm_water_lakeline` and `osm_water_point_view` definition and reuse it in the trigger.

The update of `osm_important_waterway_linestring` is more complex, as it is a merge of `osm_waterway_linestring`. It not done in the same way. At the end of the transaction we remove impacted and recompute them.

The goal is to update more quickly the content of derivated table by just updating the changing content. It replaces the update of materialized view because their need a full recompute (with lock issue).

Note, an advanced version of differential update over materialized view as already implemented in the building cluster PR #725.

It addresses #814 and a part of #809.
2020-05-20 13:14:22 -04:00
Yuri Astrakhan be75e7662f
wait longer for preloaded image (#881)
preloaded postgis image can take longer than 60 seconds to start
on slower machines. Increase the timeout to 3 minutes.
2020-05-20 11:50:54 -04:00
Yuri Astrakhan 0d6cc6b43e
Properly init dirs, docs (#879)
* make sure all required dirs are initialized before running any of the docker commands. Otherwise docker will create them as root.
* minor docs cleanup
2020-05-20 11:27:42 -04:00
Yuri Astrakhan e12f09ae57
Generate multiple parallelizable SQL files (#839)
Generate multiple SQL files to be imported in parallel.
The files will respect the cross-layer dependencies,
so they can be all ingested at the same time.
2020-05-18 14:26:51 -04:00
Eva Jelinkova d8095e8ee9
Update Readme.md - start-db command (#872) 2020-05-15 15:01:29 -04:00
Frédéric Rodrigo dcee493da6
Simplify update_gbr_route_members() (#870)
Code cleaning.

The function `update_gbr_route_members()` use two sub queries, but only one is relay needed.
2020-05-15 11:24:57 -04:00
zstadler aea7d73ece
quickstart support for osmfr and bbike areas (#861)
* quickstart support for osmfr and bbike areas

- Use the `--empty` flag to start with an empty database
- Geofabrik as the default server
- osmfr is used for hierarchical area names such as `europe/austria`
- bbbike is used for Capitalized area names such as `Adelaide`
2020-05-15 01:14:14 -04:00
zstadler e10aa33268
Update Makefile (#869)
Missed another typo
2020-05-15 00:08:37 -04:00
zstadler 63e150244d
Fix Typo (#868)
Avoid `http://http://...`
2020-05-14 17:59:12 -04:00
zstadler 12542eb687
Unified naming convention for make targets (#862)
Following https://github.com/openmaptiles/openmaptiles/pull/821#issuecomment-625773180
2020-05-09 13:30:57 -04:00
Yuri Astrakhan dd3cb077a2
Improve GH action update-pr log messages (#860) 2020-05-07 17:20:06 -04:00
Yuri Astrakhan 632a33ed05
attempt to reset hardware before each test (#859)
* Trims SSD drives, flushes cache before each performance test. Unfortunately these are still incomplete -- need to use real hardware machines for all these to take effect.
* A bit more output in PR updater
2020-05-07 15:33:28 -04:00
Frédéric Rodrigo 9f9facc8c6
Remove support of relation type=associatedStreet, few valuable data, most false positive (#841)
Thank you @frodrigo for PR.
2020-05-07 14:37:00 +02:00
Eva Jelinkova 11566f89c7
adding more data in zoom 7 and 8 (#617) 2020-05-07 11:01:58 +02:00
Yuri Astrakhan d9fb768af8
Github Actions: Debug bbox test params (#857)
Somehow test fails on options in github actions, add debugging output for that cmd
2020-05-06 13:51:38 -04:00
Yuri Astrakhan 864eba51b3
Update README.md (#854) 2020-05-06 12:14:55 -04:00
Yuri Astrakhan c35cc59bda
Profiling tests: Large test data and wikidata caching (#855)
* Adds a script to downloads multiple areas and compute their test parameters
* added a large test that uses a combined 76MB file with equatorial-guinea, liechtenstein, district-of-columbia, greater-london
* cache wikidata downloads
2020-05-06 11:36:15 -04:00
Yuri Astrakhan b6f1e1374b
parametrized pbf file (#856)
* `make import-data` now accepts `PBF_FILE=...` parameter (see #820)
* quickstart uses specific data file when importing
2020-05-06 11:27:14 -04:00
Yuri Astrakhan 36c63ab41b
auto-build master-tools branch (#842)
`master-tools` branch is the same as `master` branch, except that it uses `latest` from the tools repo. This allows us to quickly track if master is compiling correct.
2020-05-05 12:18:34 -04:00
Yuri Astrakhan e0f111c9ef
Disable TTY in test-perf (sets proper width) (#849)
No TTY forces test-perf to use the default screen width for the output
2020-05-05 12:08:08 -04:00
Yuri Astrakhan 0cae7b9fd6
Upgrade to tools v5 - rm import-osm, new downloader... (#785)
Update to tools v5. See https://github.com/openmaptiles/openmaptiles-tools/releases/tag/v5.0.0 for the list of all changes. Other OMT-repo specific changes:

* removes `import-osm` docker usage, replacing it with `openmaptiles-tools`
* quickstart builds faster because it uses postgres with preloaded water, natural earth, and lake centerlines tables.

### Makefile targets
* `tools-dev` will open a shell in a docker to experiment and debug (instead of `import-sql-dev` and `import-osm-dev`)
* separated `start-maputnik` from `start-postserve`
* renamed `clean-docker` into `db-destroy` to make it more explicit
* cleaner `db-start`, `db-stop`, `db-destroy` targets
* `db-start-preloaded` is the same as `db-start`, except that it uses `postgis-preloaded` -- an image with preloaded water, natural-earth, and lake centerline data
* `db-start` will not recreate the container if it already exists -- this way if it was started as preloaded, it will not be rebuilt.
* better output messages

### Quickstart
* uses `postgis-preloaded` image by default to make quickstart quicker.  To start with a clean db, pass 2 parameters to quickstart, e.g. `./quickstart.sh albania empty`
2020-05-05 11:53:09 -04:00
Yuri Astrakhan 785ec93799
Improve workflow PR updates (#847)
Include closed PRs in the update cycle, because there could be a case that PR got closed before the job had a chance to finish, and we should still update it.
2020-05-05 09:56:49 -04:00
Yuri Astrakhan 365a2349f2
Use --bbox for test-perf testing (#850)
This approach allows us to change test data at any moment, without changing test-perf code.
2020-05-04 23:38:28 -04:00
Yuri Astrakhan 0d0d9c6b89
Don't hide makefile errors in pipes (#848)
Follow up to #846 - make sure that if an error happens inside a target whose output is piped, we stop.
2020-05-04 16:41:55 -04:00
zstadler 29973669ae
Warning-check for `make import-sql` (#846)
Always check `make import-sql` for warnings. Not only when invoked by `quickstart.sh`.
2020-05-04 13:28:23 -04:00
Yuri Astrakhan 68911900c9
More performance profiling details (#845)
Results now show a table of how long each step took, as well as the PG database size change.

* use `time` to compute profiling for each step
* call postgres to get database size
2020-05-04 12:18:39 -04:00
Yuri Astrakhan 5445a70c30
workflow improvements (#840)
* 20 min seems to be too short, it skips some PRs
* fixed to proper URL printing in logs
2020-04-30 11:50:45 -04:00
Frédéric Rodrigo 99f9336e5e
Merge ways and relations fetch from table osm_building_polygon (#757)
Build on top of PR #755, to be merged first.

Since we want every thing from osm_building_polygon (osm_id >= 0 and osm_id < 0), we can merge the two queries.

Note: the obp.osm_id >= 0 on the left join only apply to the left join part.
2020-04-29 16:03:22 +02:00
Yuri Astrakhan 5f277b5023
Workflow - use insecure curl when can (#838)
Turned out that some update jobs failed due to

```
{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v3"
}
```

This is probably due to credentials expiring (long workflow startup?),
or some internal github issue.

For now, removing authenticated `curl` calls because most
of them can be done anonymously, and keeping them only when needed.
2020-04-28 23:38:06 -04:00
Yuri Astrakhan d5569fb679
display raw data on error in workflow (#837)
trying to figure out what strange data is returned
by github that is not returned when testing locally
2020-04-28 21:41:07 -04:00
Yuri Astrakhan e037b5a7f6
PR workflow - error reporting and cleanup (#836)
optimize a bit the CI workflow PR commenting logic
to avoid some errors and better debugging messages.
2020-04-28 15:37:07 -04:00
Yuri Astrakhan f030f7ace7
Improve PR comment updater, bug fixes (#835)
* use proper number parsing
* skip PRs that weren't recently updated
* Better reporting
2020-04-28 11:10:24 -04:00
Kyle Barron cc6fccb4df
Add amenity=drinking_water (#765)
* Add amenity=drinking_water

Fixes #569.

From test:
Generated 118,970 tiles in 0:06:20.7, 312.4 tiles/s +1.3%, 155.5 bytes/tile +0.0%

* updated devdoc image  - Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2020-04-28 12:51:26 +02:00
Frédéric Rodrigo 86a6f93b29
Micro SQL improvement of building layer (#755)
Thank you @frodrigo for this improvement.
2020-04-28 12:05:58 +02:00
Frédéric Rodrigo cb2cc09d20
Remove support of relation type=street, few valuable data, most false positive (#754)
Thank you @frodrigo for this PR. Tests are looking good.
2020-04-28 10:36:44 +02:00
Yuri Astrakhan 33b91cee90
minor CI fix to handle no PRs (#834)
* delete output escaping (forgot to remove it -- was used for the older system)
* stop early if there are no pull requests (e.g. in case this is a fork)
2020-04-27 03:42:37 -04:00
Yuri Astrakhan 75a47109ee
Implement PR performance auto-update (#833)
A cron-based approach to find pull requests, possibly from forks,
that finished profiling, and post their results as comments.

See in-depth explanation of how this works at
https://github.com/nyurik/auto_pr_comments_from_forks
2020-04-27 02:37:57 -04:00
Yuri Astrakhan 479b83c0f0
in a CI test, print less junk (#831) 2020-04-24 16:44:02 -04:00
Petr Pridal 83f8a23bd3
Merge pull request #828 from nyurik/maptiler-change
klokantech/tileserver-gl -> maptiler/tileserver-gl
2020-04-24 21:17:26 +02:00
Petr Pridal 08b5fcd457
Merge branch 'master' into maptiler-change 2020-04-24 20:39:46 +02:00
zstadler ed32b115b3
Update Makefile (#825)
Add `/bin/sh` support

Co-authored-by: Yuri Astrakhan <YuriAstrakhan@gmail.com>
2020-04-24 14:38:36 -04:00
zstadler 3104badf63
`make generate-qareports` depends on `db-start` (#826)
Co-authored-by: Yuri Astrakhan <YuriAstrakhan@gmail.com>
2020-04-24 14:29:59 -04:00
Yuri Astrakhan 79be9bb0bc Merge branch 'master' into maptiler-change 2020-04-24 14:08:36 -04:00
Yuri Astrakhan d7873db0c0
Implement PR performance testing (#824)
* On pull request and on commit, run base test followed by the test of the change,
comparing the results, and publishing the results to the Pull Request.
If the pull request is updated, the resulting comment will be updated.

* also save quickstart.log as an artifact

Note that due to GitHub workflow security restrictions, it is not possible to post PR comments if the change originated from a fork.  I am still looking for workarounds.

To view what would have been posted, in the build results at the bottom, open `PR performance` details, and expand the ` Comment on Pull Request` (and its subitem).

Optimizations: the process keeps two caches -- one for the data test file, and one for the results of the performance run for the "base" revision.  If this or other PR has been executed for the same revision and the same test data, performance test will only run for the proposed changes, not for the base.

Co-authored-by: Tomas Pohanka <TomPohys@gmail.com>
2020-04-24 09:20:59 -04:00
Frédéric Rodrigo 5da406f4a2
Filter osm_building_polygon on polygon (#758) 2020-04-23 08:23:52 +02:00
Yuri Astrakhan 95ddc34295
Minor makefile cleanup followup #821 (#823)
Per @zstadler recommendations in
21053e4a5f
2020-04-22 14:55:13 -04:00
Yuri Astrakhan 21053e4a5f
Makefile target cleanup, minor improvements (#821)
* allow postgres image to be overwritten with an env var
* allow DIFF_MODE var to be overwritten with an env var
* add /mapping and /cache dirs into tools image
* make `build-sql` target explicit rather than relying on a filename
* `tools-dev` will open a shell in a docker to experiment and debug (instead of `import-sql-dev` and `import-osm-dev`)
* separated `start-maputnik` from `start-postserve`
* renamed `clean-docker` into `db-destroy` to make it more explicit
* cleaner `db-start`, `db-stop`, `db-destroy` targets
* better output messages
2020-04-22 11:15:20 -04:00
Frédéric Rodrigo 8f9770e546
Reorder POI data update and trigger creation to avoid refresh of materialized view on initial import (#780)
Reorder POI data update and trigger creation to avoid refresh of materialized view after update done by initial import.

I checked the other updates and there are OK.
2020-04-22 03:03:10 -04:00
Yuri Astrakhan 2ca55abb7d
Use new import-data image (#818)
This is a partial migration of https://github.com/openmaptiles/openmaptiles/pull/785

* Use `import-data` instead of `import-lakelines`, `import-water`, and `import-natural-earth`
* Upgrade docker-compose.yml to version 2.3 (allows some extra env var usage in yaml file itself)
* Remove `openmaptiles-tools:latest` usage -- no longer needed, can use current version 4.1
* `db-start` does not do a container recreation in case docker-compose.yml definition has changed.
* a few minor cleanups in quickstart.sh
2020-04-22 02:48:57 -04:00
Yuri Astrakhan 3f2f400450 Merge branch 'master' into maptiler-change 2020-04-22 02:47:33 -04:00
Yuri Astrakhan a26ccedf08
Bug: Fix start-tileserver makefile target (#816)
It is not possible to open port 80 without ROOT inside docker container.
Change default port for start-tileserver target to use port 8080.

Documented in https://github.com/maptiler/tileserver-gl/issues/439
2020-04-22 02:43:58 -04:00
adrian 460550ac78 this image has moved. its now maptiler.
https://github.com/klokantech/tileserver-gl directs to https://github.com/maptiler/tileserver-gl

(as of writing) this updates the version of tileserver-gl from 2.6.0 to 3.0.0.
2020-04-21 13:51:03 -04:00
zstadler be3c96f835
Update Makefile (#812)
- Add `download-osmfr` and `download-bbbike` targets
- Port `DC_OPTS` to Windows
- Use make conditions instead of shell. Also simplifies `make -n` output
- Use remote Docker machine's IP, if defined, rather than `localhost` in `http://...` messages. Also applicable for Docker Toolbox for Windows.
- Align texts in `make help` output
- Update and bug-fix in `make remove-docker-images`
2020-04-21 13:36:07 -04:00
Yuri Astrakhan 0683185717
Add `requires` to 2 layer definitions (#797)
Mark waterway and transoprtation_name as having a dependency on another layer.
This is currently an unused parameter, but tools will use it later for faster
sql code generation.

Closes #796
2020-04-21 12:36:44 -04:00
Frédéric Rodrigo b850819218
Narrow osm_building_relation_building_idx with condition building = '' (#771) 2020-04-21 11:12:29 +02:00
Tomas Pohanka 7f24c099ee
Add `boundary=protected_area` parks
@zstadler, thank you for PR.

Add `boundary=protected_area` parks

No performance impact, a very slight increase in size, but with a very good impact on features completeness.

Thanks
2020-04-21 10:41:18 +02:00
zstadler 746a2dc7b9
Support multiple openmaptiles instances by specifying a Docker Compose project (#806)
The implementation adds the `DC_PROJECT` parameter. It can also be set by an environment variable in the hosting shell. The environment variable can be overwritten by a make parameter, including `DC_PROJECT=` which restores the automatic project name.

#### _NOTE:_
It may be worthwhile to review the following make targets that are currently not impacted by the PR:
- `make start-postserve`
- `make list-docker-images`
- `make remove-docker-images`
- `make docker-unnecessary-clean`

This PR was suggested by @nyurik:

> zstadler  3:30 PM
Is it possible to run two instances of openmaptiles, and the postgis container in particular, on the same Linux host?
nyurik  4:17 PM
use docker-compose --project-name -- that should allow you to run everything in parallel
4:17
might need to update make file
4:17
btw, that would be a good PR for makefile -- to specify --project-name based on the current DIR name, but so that it can be overwritten by a makefile param


Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2020-04-09 12:05:01 -04:00
Yuri Astrakhan 4f5ea5f26e
Use v4.1, move import-wikidata before import-sql (#805)
import-wikidata should run before import-sql, and v4.1 allows for that.
Also it optimizes the wd_names table to just be a simple Wikidata ID -> labels lookup, with a proper index.

Minor other changes:
* `test-perf-null` target is now part of the Makefile
* `./data/osmstat.txt` is no longer created
* area download file now in this format:   `${osm_area}-latest.osm.pbf`
2020-04-09 10:49:35 -04:00
zstadler 2584489ad7
Continue conflict resolution 2020-04-04 13:16:59 +03:00
zstadler 88e9127bfd
Merge branch 'master' into protected_area 2020-04-04 12:50:03 +03:00
Tomas Pohanka f55579cd16
Update badge for GitHub Actions
fix #802 
fix #790
2020-04-03 11:37:11 +02:00
Tomas Pohanka a8c39259df
Merge pull request #802 from openmaptiles/github_action
run CI in GitHub Actions

subsequently, Travis will be stoped
2020-04-03 09:56:30 +02:00
Tomas Pohanka 2382906fa2
Delete unnecessary travis.yml 2020-04-03 09:54:52 +02:00
Tomas Pohanka 94881752d5
run CI in GitHub Actions
Use GitHub Action instead of TravisCI.

Do the same as Travis, but with full integration in GitHub.

based on https://github.com/openmaptiles/openmaptiles/issues/790
2020-04-01 16:46:42 +02:00
Ludovic Delauné 924ccd6015
remove useless sql selection (#752) 2020-03-13 15:14:30 -04:00
Yuri Astrakhan 490acf9beb
Use tools v4 with on-the-fly boundary generation (#750)
* Switch OMT to use the new tools v4.0.0
* borders are dynamically generated from the PBF file instead of downloading a prepared CSV file
* all tools are executed as current user instead of root, thus files are easier to modify/delete if needed
* all data is stored in the local file system instead of docker volumes (Docker currently has a limitation of non-root operation for internal volumes). This also makes it easier to examine and test it.
* New `init-dirs` make target creates all the needed dirs - `build, data, cache`
* `make clean` deletes the whole `build` dir instead of individual files.
* `clean-docker` for backward compatibility deletes `cache` dirs (it used to be a volume)
* all `psql` calls are now done with `ON_ERROR_STOP=1`
* got rid of `pgclimb-*` targets -- same results can be done with `psql` (`pgclimb-list-views` & `pgclimb-list-tables` renamed to `list-views` and `list-tables`)
2020-03-06 13:15:54 -05:00
Yuri Astrakhan 036a96fb40 use awk instead of gawk 2020-02-24 12:08:27 -05:00
Skylar Ittner 2f60ca0730 Add merge script, update imposm3 behavior info
Add a one-liner script to take the tile lists from the dated subfolders, merge and deduplicate them, and write it out to tiles.txt.  
Also update docs to reflect current behavior of `docker-compose run update-osm`.
2020-02-21 22:09:31 -05:00
Yuri Astrakhan 2edbbfa1a0 Updated etl diagrams from latest tools
* gets rid of duplicate connecting lines in etl graphs
2020-02-14 16:22:48 -05:00
Ondřej Machulda 37ac2e82ee Remove trailing whitespace in openmaptiles.yaml 2020-02-11 08:59:25 -05:00
Yuri Astrakhan a803bc3d11
cleanup trailing spaces (#777)
minor noop
2020-02-11 01:13:01 -05:00
Jorge Sanz ace759590e
Parallel capability to layer functions (#728)
This PR allows queries to be parallelized on recent versions of Postgres. The `PARALLEL SAFE` modifier has been added to the layer functions and a PLPGSQL function to convert strings into number has been replaced.

`PARALLEL SAFE` is a modifier for `CREATE FUNCTION` available since Postgres 9.6, so this change does not break current OpenMapTiles supported database version. More details about this topic [here](https://www.postgresql.org/docs/current/parallel-safety.html) and at the reference documentation for [`CREATE FUNCTION`](https://www.postgresql.org/docs/current/sql-createfunction.html).

### Testing procedure

The procedure to test this was:

* Imported `spain.pbf` in a clean environment
* Dumped the OpenMapTiles database from the Postgres Docker image
* Created a clean Postgres 12 database using the default Docker image
* Installed `postgis` 3 from the default Debian package and `osml10n` 2.5.8 from the repository (`make`, etc.)
* Restored the dump
* Lowered the postgres planner parameters for triggering parallel plans:
```sql
set parallel_setup_cost = 5;
set parallel_tuple_cost = 0.005;
```
* Manually added the `PARALLEL SAFE` modifier to each function involved in layer queries (not on updates or inserting functions).
* For each layer, run a testing query to confirm parallel workers were created, something like this:
```sql
explain analyze 
select * from layer_aerodrome_label(tilebbox(8,128,95),10,null)
union all
select * from layer_aerodrome_label(tilebbox(8,128,97),10,null);
```
* After all the layers were processed and confirmed to start parallel executions, a more complete example was run. This example just retrieves the geometries for all the layers from the same tile but without using any MVT related function.

<details><summary>Testing query</summary>

```sql
-- Using the function layer_landuse
explain analyze 
select geometry from layer_water(tilebbox(14,8020,6178),14)
union all
select geometry from layer_waterway(tilebbox(14,8020,6178),14)
union all
select geometry from layer_landcover(tilebbox(14,8020,6178),14)
union all
select geometry from layer_landuse(tilebbox(14,8020,6178),14)
union all
select geometry from layer_mountain_peak(tilebbox(14,8020,6178),14)
union all
select geometry from layer_park(tilebbox(14,8020,6178),14)
union all
select geometry from layer_boundary(tilebbox(14,8020,6178),14)
union all
select geometry from layer_aeroway(tilebbox(14,8020,6178),14)
union all
select geometry from layer_transportation(tilebbox(14,8020,6178),14)
union all
select geometry from layer_building(tilebbox(14,8020,6178),14)
union all
select geometry from layer_water_name(tilebbox(14,8020,6178),14)
union all
select geometry from layer_transportation_name(tilebbox(14,8020,6178),14)
union all
select geometry from layer_place(tilebbox(14,8020,6178),14)
union all
select geometry from layer_housenumber(tilebbox(14,8020,6178),14)
union all
select geometry from layer_poi(tilebbox(14,8020,6178),14)
union all
select geometry from layer_aerodrome_label(tilebbox(14,8020,6178),14);
```
</details>

You can inspect the execution plan and results on [this page](https://explain.dalibo.com/plan/3z). Also [attaching](https://github.com/openmaptiles/openmaptiles/files/3951822/explain-tile-simple.tar.gz) the query and JSON output for future reference. The website gives a ton of details, but you may want to search for nodes mentioning `workers` or `parallel` like in this area referring to `osm_border` or `osm_aeroway_linestring` entities

![image](https://user-images.githubusercontent.com/188264/70647153-9cac9300-1c48-11ea-96ea-ac7a1e2f4a79.png)

### Next steps

Since the execution plan is not showing a parallel append at the top level, meaning it's not running each layer individually, I want to continue experimenting with parameters and queries to see if it's possible to even parallelize more the request.

I will post my finding here, even no change in the code should happen.


cc. @nyurik

Co-authored-by: Yuri Astrakhan <yuriastrakhan@gmail.com>
2020-01-31 19:36:02 -05:00
Frédéric Rodrigo b1eeff573e
Remove table building_multipolygon as multipolygon are already in table osm_building_polygon (#756)
Buildings from ways and multipolygons are loaded in table `osm_building_polygon`. But a table for `osm_building_multipolygon` is also loaded, the content is not used except to ensure an `osm_id` is from a multipolygon. To check if the object is from a multipolygon we have only to check if `osm_id` is negative. It is the counter part of e0c8ece375/layers/building/building.sql (L89)

I checked the objects are the same after this change.
2020-01-31 19:34:08 -05:00
Yuri Astrakhan 6801353e15
Declared field mapping 2 (#734)
Make a few more mappings declarative, and removes values declared in both SQL and the yaml file.

Here's the diff comparing `build/tileset.sql` in master vs the new PR. The changes are mostly stylistic, except when a nested `if` statement is expanded into individual `if ... and ...` conditions (logically identical)

```diff
55c55
diff --git a/build/tileset.sql b/build/tileset.sql
index 4e59357..7c6c444 100644
--- a/build/tileset.sql
+++ b/build/tileset.sql
@@ -52,7 +52,7 @@ CREATE INDEX IF NOT EXISTS osm_ocean_polygon_gen4_idx ON osm_ocean_polygon_gen4
 CREATE OR REPLACE FUNCTION water_class(waterway TEXT) RETURNS TEXT AS $$
     SELECT CASE
            WHEN "waterway" IN ('', 'lake') THEN 'lake'
-           WHEN "waterway"='dock' THEN 'dock'
+           WHEN "waterway" = 'dock' THEN 'dock'
            ELSE 'river'
    END;
 $$ LANGUAGE SQL IMMUTABLE;
@@ -1813,24 +1813,41 @@ CREATE OR REPLACE FUNCTION highway_class(highway TEXT, public_transport TEXT, co
         WHEN "highway" IN ('tertiary', 'tertiary_link') THEN 'tertiary'
         WHEN "highway" IN ('unclassified', 'residential', 'living_street', 'road') THEN 'minor'
         WHEN "highway" IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor')
-            OR "public_transport"='platform'
+            OR "public_transport" = 'platform'
             THEN 'path'
-        WHEN "highway"='service' THEN 'service'
-        WHEN "highway"='track' THEN 'track'
-        WHEN "highway"='raceway' THEN 'raceway'
-        WHEN highway = 'construction' THEN CASE
-          WHEN construction IN ('motorway', 'motorway_link') THEN 'motorway_construction'
-          WHEN construction IN ('trunk', 'trunk_link') THEN 'trunk_construction'
-          WHEN construction IN ('primary', 'primary_link') THEN 'primary_construction'
-          WHEN construction IN ('secondary', 'secondary_link') THEN 'secondary_construction'
-          WHEN construction IN ('tertiary', 'tertiary_link') THEN 'tertiary_construction'
-          WHEN construction IN ('', 'unclassified', 'residential', 'living_street', 'road') THEN 'minor_construction'
-          WHEN construction IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor')
-              OR public_transport = 'platform' THEN 'path_construction'
-          WHEN construction = 'service' THEN 'service_construction'
-          WHEN construction = 'track' THEN 'track_construction'
-          WHEN construction = 'raceway' THEN 'raceway_construction'
-        END
+        WHEN "highway" = 'service' THEN 'service'
+        WHEN "highway" = 'track' THEN 'track'
+        WHEN "highway" = 'raceway' THEN 'raceway'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('motorway', 'motorway_link')
+            THEN 'motorway_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('trunk', 'trunk_link')
+            THEN 'trunk_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('primary', 'primary_link')
+            THEN 'primary_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('secondary', 'secondary_link')
+            THEN 'secondary_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('tertiary', 'tertiary_link')
+            THEN 'tertiary_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" IN ('', 'unclassified', 'residential', 'living_street', 'road')
+            THEN 'minor_construction'
+        WHEN "highway" = 'construction'
+            AND ("construction" IN ('pedestrian', 'path', 'footway', 'cycleway', 'steps', 'bridleway', 'corridor') OR "public_transport" = 'platform')
+            THEN 'path_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" = 'service'
+            THEN 'service_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" = 'track'
+            THEN 'track_construction'
+        WHEN "highway" = 'construction'
+            AND "construction" = 'raceway'
+            THEN 'raceway_construction'
     END;
 $$ LANGUAGE SQL IMMUTABLE;
 
@@ -4073,6 +4090,12 @@ RETURNS TEXT AS $$
         WHEN "subclass" IN ('fast_food', 'food_court') THEN 'fast_food'
         WHEN "subclass" IN ('park', 'bbq') THEN 'park'
         WHEN "subclass" IN ('bus_stop', 'bus_station') THEN 'bus'
+        WHEN ("subclass" = 'station' AND "mapping_key" = 'railway')
+            OR "subclass" IN ('halt', 'tram_stop', 'subway')
+            THEN 'railway'
+        WHEN "subclass" = 'station'
+            AND "mapping_key" = 'aerialway'
+            THEN 'aerialway'
         WHEN "subclass" IN ('subway_entrance', 'train_station_entrance') THEN 'entrance'
         WHEN "subclass" IN ('camp_site', 'caravan_site') THEN 'campsite'
         WHEN "subclass" IN ('laundry', 'dry_cleaning') THEN 'laundry'
@@ -4082,7 +4105,7 @@ RETURNS TEXT AS $$
         WHEN "subclass" IN ('hotel', 'motel', 'bed_and_breakfast', 'guest_house', 'hostel', 'chalet', 'alpine_hut', 'dormitory') THEN 'lodging'
         WHEN "subclass" IN ('chocolate', 'confectionery') THEN 'ice_cream'
         WHEN "subclass" IN ('post_box', 'post_office') THEN 'post'
-        WHEN "subclass"='cafe' THEN 'cafe'
+        WHEN "subclass" = 'cafe' THEN 'cafe'
         WHEN "subclass" IN ('school', 'kindergarten') THEN 'school'
         WHEN "subclass" IN ('alcohol', 'beverages', 'wine') THEN 'alcohol_shop'
         WHEN "subclass" IN ('bar', 'nightclub') THEN 'bar'
@@ -4098,9 +4121,6 @@ RETURNS TEXT AS $$
         WHEN "subclass" IN ('bag', 'clothes') THEN 'clothing_store'
         WHEN "subclass" IN ('swimming_area', 'swimming') THEN 'swimming'
         WHEN "subclass" IN ('castle', 'ruins') THEN 'castle'
-        WHEN (subclass = 'station' AND mapping_key = 'railway')
-          OR (subclass IN ('halt', 'tram_stop', 'subway')) THEN 'railway'
-        WHEN (subclass = 'station' AND mapping_key = 'aerialway') THEN 'aerialway'
         ELSE subclass
     END;
 $$ LANGUAGE SQL IMMUTABLE;
@@ -4301,22 +4321,22 @@ $$
     COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
     tags,
     CASE
-      WHEN "aerodrome"='international'
-          OR "aerodrome_type"='international'
+      WHEN "aerodrome" = 'international'
+          OR "aerodrome_type" = 'international'
           THEN 'international'
-      WHEN "aerodrome"='public'
-          OR "aerodrome_type"='civil'
+      WHEN "aerodrome" = 'public'
+          OR "aerodrome_type" = 'civil'
           OR "aerodrome_type" LIKE '%public%'
           THEN 'public'
-      WHEN "aerodrome"='regional'
-          OR "aerodrome_type"='regional'
+      WHEN "aerodrome" = 'regional'
+          OR "aerodrome_type" = 'regional'
           THEN 'regional'
-      WHEN "aerodrome"='military'
+      WHEN "aerodrome" = 'military'
           OR "aerodrome_type" LIKE '%military%'
-          OR "military"='airfield'
+          OR "military" = 'airfield'
           THEN 'military'
-      WHEN "aerodrome"='private'
-          OR "aerodrome_type"='private'
+      WHEN "aerodrome" = 'private'
+          OR "aerodrome_type" = 'private'
           THEN 'private'
       ELSE 'other'
     END AS class,
```
2020-01-31 00:22:21 -05:00
zstadler 5657ede450 Add `boundary=protected_area` parks
Update the **class** of the **park* layer in a backward-compatible way.

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.

Resolve https://github.com/openmaptiles/openmaptiles/issues/760
2020-01-27 11:12:57 +02:00
Yuri Astrakhan 9f4d48cf25
Remove unused import-sql image (#738)
import-sql image is not used anywhere in OMT, deleting.
2020-01-24 14:40:03 -05:00
Yuri Astrakhan 9d6dbfc64f
Use one pass docs image generation (#751)
quicker and cleaner diagram image generation.
Remove etl-graph and mapping-graph targets - redundant

Also, the obsolete "fields" is still in Imposm's code and both names are accepted,
but "fields" is not documented anywhere (PR submitted), and could be removed at any moment.

Our docs were not supporting it until this PR, so renaming it at the same time.

Several images have been updated due to a more inclusive mapping scan
Requires https://github.com/openmaptiles/openmaptiles-tools/pull/147 (merged)
2020-01-22 21:55:22 -05:00
Yuri Astrakhan c9e7ad90c6
Remove unneeded "else null" in conditions (#732)
Minor code cleanup:
SQL already returns NULL in the "WHEN" condition
if it is not matched by any of the cases.

Co-authored-by: Eva Jelinkova <evka.jelinkova@gmail.com>
2020-01-22 17:24:28 -05:00
Yuri Astrakhan 3449cecb22
Migrate to new Wikidata importer (#735)
* Use _resolve_wikidata in layer mapping.yaml

Mark all tables that should not be populated with the Wikidata
international labels with a special OMT-specific flag.

This should be ok to merge even before the new tools version
is used because imposm seems to ignore anything it doesn't understand.

The next tools version will remove it when generating imposm mapping file.

* Migrate to new Wikidata importer

Uses latest tools to populate the wd_names table
during the quickstart.  This can be merged already,
or we can wait for the next tools version.
2020-01-22 16:16:38 -05:00
Yuri Astrakhan 1bc3f138b4
Create boundary materialized views (#740)
* Move simplified border tables to OMT as MAT VIEWs

Consolidate derived table creation in OMT repository.
Move all non-original simplified geometry tables from import-osmborder
image to this repo, allowing further optimization.

Later we can remove derived table creation fro mthe import-osmborder image.
2020-01-21 09:44:29 -05:00
Yuri Astrakhan e6e92036a0
Use _resolve_wikidata in layer mapping.yaml (#731)
Mark all tables that should not be populated with the Wikidata
international labels with a special OMT-specific flag.

This should be ok to merge even before the new tools version
is used because imposm seems to ignore anything it doesn't understand.

The next tools version will remove it when generating imposm mapping file.
2020-01-21 09:43:21 -05:00
Yuri Astrakhan 11f4856d48
Add simplified water materialized views (#739)
Move materialized view creation from the tools repo.

This PR should be merged before the https://github.com/openmaptiles/openmaptiles-tools/pull/115

Merge the other PR shortly after this one to avoid doing the same work twice - first creating simplified table, then dropping it and recreating them as materialized views.
2020-01-20 12:12:19 -05:00
Yuri Astrakhan 1d91b9ef6e
Noop: tag sql MAT VIEWS with a special comment (#733)
Tag all SQL materialized views with a machine-readable comment
to indicate that this materialized view can be created without
data:

   /* DELAY_MATERIALIZED_VIEW_CREATION */

In the next version of tools this comment can be optionally
replaced with the "WITH NO DATA" parameter, thus allowing
a much faster execution of the SQL script. All materialized
viewes will be populated with data in parallel afterwards
using the `refresh-views` tools script.
2020-01-20 12:02:49 -05:00
Dalibor Janák 4e13a17e1a
Merge pull request #693 from Sophox/field-injection
Manage field mapping in SQL declaratively
2020-01-17 13:48:14 +01:00
Yuri Astrakhan e4a9d90dec
noop: minor makefile targets cleanup (#737)
Avoid duplicating target name with `$@`.
This prevents accidental typo bugs.
2019-12-20 12:09:08 -05:00
Yuri Astrakhan 1614a4656c Manage field mapping in SQL declaratively
Simplify some of the OSM->OMT field value mappings using declarative syntax.

This approach is not for all cases, but in many it removes
the need of storing the same field in both the .yaml and .sql files.

TODO: support more complex AND/OR cases
2019-12-19 11:25:29 -05:00
499 zmienionych plików z 31989 dodań i 5163 usunięć

53
.env
Wyświetl plik

@ -1,13 +1,46 @@
POSTGRES_DB=openmaptiles
POSTGRES_USER=openmaptiles
POSTGRES_PASSWORD=openmaptiles
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
QUICKSTART_MIN_ZOOM=0
QUICKSTART_MAX_ZOOM=7
DIFF_MODE=false
TOOLS_VERSION=3.1.0
# This file defines default environment variables for all images
# Layers definition and meta data
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=openmaptiles
PGUSER=openmaptiles
PGPASSWORD=openmaptiles
PGHOST=postgres
PGPORT=5432
# BBOX may get overwritten by the computed bbox of the specific area:
# make generate-bbox-file
# By default, the Makefile will use the content of data/$(area).bbox file if it exists.
BBOX=-180.0,-85.0511,180.0,85.0511
# Which zooms to generate with make generate-tiles-pg
MIN_ZOOM=0
MAX_ZOOM=14
MAX_ZOOM=7
# `MID_ZOOM` setting only works with `make generate-tiles-pg` command. Make sure MID_ZOOM < MAX_ZOOM.
# See https://github.com/openmaptiles/openmaptiles-tools/pull/383
# MID_ZOOM=11
# Use true (case sensitive) to allow data updates
DIFF_MODE=false
# The current setup assumes this file is placed inside the data/ dir
MBTILES_FILE=tiles.mbtiles
# This is the current repl_config.json location, pre-configured in the tools Dockerfile
# Makefile and quickstart replace it with the dynamically generated one, but we keep it here in case some other method is used to run.
IMPOSM_CONFIG_FILE=/usr/src/app/config/repl_config.json
# Number of parallel processes to use when importing sql files
MAX_PARALLEL_PSQL=5
# Number of parallel threads to use when generating vector map tiles
COPY_CONCURRENCY=10
# Variables for generate tiles using tilelive-pgquery
PGHOSTS_LIST=

Wyświetl plik

@ -0,0 +1,62 @@
#!/usr/bin/env bash
set -euo pipefail
#
# Download several areas, combine them into a single file, and print --bbox params needed to run test-perf
#
# List of Geofabrik areas
TEST_AREAS=(equatorial-guinea liechtenstein district-of-columbia greater-london)
: "${DATA_DIR:=/tileset/data/test}"
: "${DATA_FILE_SUFFIX:=-latest.osm.pbf}"
: "${RESULT_FILE:=test${DATA_FILE_SUFFIX}}"
mkdir -p "$DATA_DIR"
cd "$DATA_DIR"
echo -e $"\n=========== downloading areas" "${TEST_AREAS[@]}" "==========================="
for area in "${TEST_AREAS[@]}"; do
file="${area}${DATA_FILE_SUFFIX}"
if [ -f "$file" ]; then
echo "File $file already exists, skipping download"
else
download-osm geofabrik "${area}" -- -d "$DATA_DIR"
if [ ! -f "$file" ]; then
echo "Unexpected error while downloading $file, aborting"
exit 1
fi
fi
done
echo -e $"\n=========== Merging" "${TEST_AREAS[@]}" "into ${RESULT_FILE} ====="
rm -f "${RESULT_FILE}"
OSMOSIS_ARG="--read-pbf ${TEST_AREAS[0]}${DATA_FILE_SUFFIX} $(printf " --read-pbf %s${DATA_FILE_SUFFIX} --merge" "${TEST_AREAS[@]:1}")"
# shellcheck disable=SC2086
( set -x; osmosis ${OSMOSIS_ARG} --write-pbf "${RESULT_FILE}" )
echo -e $"\n=========== Computing test BBOXes ======================="
echo -e $"\n File ${RESULT_FILE} ($(du -b "$RESULT_FILE" | cut -f1)) has been generated with these test areas:\n"
for area in "${TEST_AREAS[@]}"; do
file="${area}${DATA_FILE_SUFFIX}"
STATS=$(osmconvert --out-statistics "$file" )
LON_MIN=$( echo "$STATS" | grep "lon min:" | cut -d":" -f 2 | awk '{gsub(/^ +| +$/,"")} {print $0}' )
LON_MAX=$( echo "$STATS" | grep "lon max:" | cut -d":" -f 2 | awk '{gsub(/^ +| +$/,"")} {print $0}' )
LAT_MIN=$( echo "$STATS" | grep "lat min:" | cut -d":" -f 2 | awk '{gsub(/^ +| +$/,"")} {print $0}' )
LAT_MAX=$( echo "$STATS" | grep "lat max:" | cut -d":" -f 2 | awk '{gsub(/^ +| +$/,"")} {print $0}' )
BBOX="${LON_MIN},${LAT_MIN},${LON_MAX},${LAT_MAX}"
FILE_SIZE="$(du -b "$file" | cut -f1)"
cat <<EOF | (PYTHONPATH=/usr/src/app python)
from openmaptiles.perfutils import TestCase
tc = TestCase('${area}', 'a', bbox='${BBOX}')
info = f"# {tc.id} {tc.size():,} tiles at z14, \
{$FILE_SIZE/1024/1024:,.1f}MB, {$FILE_SIZE/tc.size():,.1f} bytes/tile \
[{tc.start[0]}/{tc.start[1]}]x[{tc.before[0] - 1}/{tc.before[1] - 1}]"
print(f" --bbox {tc.bbox:46} {info}")
EOF
done
echo ""

71
.github/workflows/integrity.yml vendored 100644
Wyświetl plik

@ -0,0 +1,71 @@
# Workflow to run basic integrity checks on OMT`s new Pull Requests and commits pushed into OMT repo
name: OpenMapTiles Integrity CI
on:
push:
branches: [ master, master-tools ]
pull_request:
jobs:
integrity_test:
name: Run integrity test
runs-on: ubuntu-latest
steps:
- name: Checkout the changes
uses: actions/checkout@v4
- name: Run quickstart for a small area
env:
area: monaco
QUIET: 1
run: |
echo MIN_ZOOM=0 >> .env
echo MAX_ZOOM=14 >> .env
./quickstart.sh $area
- name: Save quickstart.log
uses: actions/upload-artifact@v4
with:
name: quickstart.log
path: quickstart.log
- name: Test etldoc images
run: |
export TEST_MODE=yes
make generate-devdoc
- name: Run quickstart and update in DIFF mode
env:
area: europe/monaco
QUIET: 1
run: |
echo MIN_ZOOM=0 >> .env
echo MAX_ZOOM=14 >> .env
echo DIFF_MODE=true >> .env
# Cleanup
rm -fr data build cache
# Create data/$area.repl.json
make download-geofabrik area=$area
# Download 2+ month old data
export old_date=$(date --date="$(date +%Y-%m-15) -2 month" +'%y%m01')
echo Downloading $old_date extract of $area
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "wget -O data/$area.osm.pbf http://download.geofabrik.de/$area-$old_date.osm.pbf"
# Initial import and tile generation
./quickstart.sh $area
sleep 2
echo Downloading updates
# Loop to recover from potential "ERROR 429: Too Many Requests"
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "
while ! osmupdate --keep-tempfiles --base-url=$(sed -n 's/ *\"replication_url\": //p' data/$area.repl.json) data/$area.osm.pbf data/changes.osc.gz ; do
sleep 2;
echo Sleeping...;
sleep 630;
done"
echo Downloading updates completed
echo Importing updates
make import-diff
echo Generating new tiles
make generate-tiles-pg

300
.github/workflows/performance.yml vendored 100644
Wyświetl plik

@ -0,0 +1,300 @@
# Workflow to run performance tests OMT`s new Pull Requests and commits pushed into OMT repo
name: OpenMapTiles Performance CI
on:
push:
branches: [ master, master-tools ]
pull_request:
jobs:
performance:
name: Evaluate performance
runs-on: self-hosted
env:
## Smaller tests (runs everything in about 30 minutes)
## Two test areas: equatorial-guinea and liechtenstein
#TEST_DATA_URL: "https://drive.google.com/uc?export=download&id=12vw07f9W0MiAHIqMztRiIMwahJfqTi21"
#TEST_PERF_PARAMS: "--minzoom 0 --maxzoom 14 --bbox 5.4172943,-1.6732196,12.3733400,4.3475256 --bbox 9.0900979,46.9688169,9.6717077,47.5258072"
# Large test, size is 79,472,850
# --bbox 5.4172943,-1.6732196,12.3733400,4.3475256 `# equatorial-guinea 87,768 tiles at z14, 2.1MB, 24.9 bytes/tile [8438/7993]x[8755/8268]` \
# --bbox 9.0900979,46.9688169,9.6717077,47.5258072 `# liechtenstein 1,064 tiles at z14, 2.2MB, 2,217.0 bytes/tile [8605/5727]x[8632/5764]` \
# --bbox -78.7749754,38.7820235,-76.8957735,39.6985009 `# district-of-columbia 4,785 tiles at z14, 16.0MB, 3,508.9 bytes/tile [4606/6220]x[4692/6274]` \
# --bbox -0.6124681,51.2268449,0.3996690,51.7873570 `# greater-london 1,974 tiles at z14, 55.5MB, 29,458.3 bytes/tile [8164/5427]x[8210/5468]` \
TEST_DATA_URL: "https://drive.google.com/uc?export=download&id=18nP3f06aBBiEKhUNmAkqq30gqQnU2_VJ"
TEST_PERF_PARAMS: >-
--minzoom 0 --maxzoom 14
--bbox 5.4172943,-1.6732196,12.3733400,4.3475256
--bbox 9.0900979,46.9688169,9.6717077,47.5258072
--bbox -78.7749754,38.7820235,-76.8957735,39.6985009
--bbox -0.6124681,51.2268449,0.3996690,51.7873570
## Large test data -- we should switch to it after everything is working ok
# TEST_DATA_URL: "https://drive.google.com/uc?export=download&id=1kw7XPDPd1Rc-Zi2XxGLTXdinUSq-S4pT"
# TEST_PERF_PARAMS: "--minzoom 0 --maxzoom 14 --test hungary --test isle-of-man"
steps:
- name: Cleanup workdir
id: cleanup
run: |
set -euo pipefail
pwd
ls -al .
shopt -s dotglob
rm -rf *
- name: Cache test data download
id: cache-testdata
uses: actions/cache@v4
with:
path: ci_cache
key: "v2-${{ env.TEST_DATA_URL }}"
- name: Download test data on cache miss
if: steps.cache-testdata.outputs.cache-hit != 'true'
run: |
echo "Data file does not exist, downloading $TEST_DATA_URL"
mkdir -p ci_cache
curl --silent --show-error --location --output ci_cache/perf-test-areas-latest.osm.pbf "$TEST_DATA_URL"
- name: Get code
uses: actions/checkout@v4
with:
# Fetch the last two commits in case this is a PR,
# and we need to profile the base branch first
fetch-depth: 2
path: code
- name: Compute git revision hash to cache
id: calc
run: |
# If this is a pull request, we should cache the parent (base) revision
# Otherwise cache the current one
cd code
REV_HASH=$(git log -1 --format="%H")
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
# Take the first parent of the grafted commit (cannot use HEAD^1 with shallow clones)
REV_HASH=$(git cat-file -p $REV_HASH | awk 'NR > 1 {if(/^parent/){print $2; exit}}')
fi
echo "hash=$REV_HASH" >> $GITHUB_OUTPUT
- name: Set up caching for the performance results
uses: actions/cache@v4
with:
path: perf_cache
# If profiling result cache has incompatible format, increase this "v" number
key: "v13-${{ steps.calc.outputs.hash }}-${{ env.TEST_DATA_URL }}"
- name: Load test data into DB and run performance test
id: main
env:
CACHE_SHA: "${{ steps.calc.outputs.hash }}"
run: |
profile() {
TIME_FORMAT="# %C
P\t%P\tPercentage of the CPU that this job got. This is just user + system times divided by the total running time. It also prints a percentage sign.
x\t%x\tExit status of the command.
-\t-----\t-- Time --------------------------------------------------------------------------------------------------
e\t%e\tElapsed real (wall clock) time used by the process, in seconds.
E\t%E\tElapsed real (wall clock) time used by the process, in [hours:]minutes:seconds.
U\t%U\tTotal number of CPU-seconds that the process used directly (in user mode), in seconds.
S\t%S\tTotal number of CPU-seconds used by the system on behalf of the process (in kernel mode), in seconds.
-\t-----\t-- Context Switches --------------------------------------------------------------------------------------
c\t%c\tNumber of times the process was context-switched involuntarily (because the time slice expired).
w\t%w\tNumber of times that the program was context-switched voluntarily, for instance while waiting for an I/O operation to complete.
-\t-----\t-- Page faults -------------------------------------------------------------------------------------------
F\t%F\tNumber of major, or I/O-requiring, page faults that occurred while the process was running. These are faults where the page has actually migrated out of primary memory.
R\t%R\tNumber of minor, or recoverable, page faults. These are pages that are not valid (so they fault) but which have not yet been claimed by other virtual pages. Thus the data in the page is still valid but the system tables must be updated.
W\t%W\tNumber of times the process was swapped out of main memory.
-\t-----\t-- Memory ------------------------------------------------------------------------------------------------
K\t%K\tAverage total (data+stack+text) memory use of the process, in Kilobytes.
t\t%t\tAverage resident set size of the process, in Kilobytes.
p\t%p\tAverage unshared stack size of the process, in Kilobytes.
M\t%M\tMaximum resident set size of the process during its lifetime, in Kilobytes.
D\t%D\tAverage size of the process's unshared data area, in Kilobytes.
X\t%X\tAverage amount of shared text in the process, in Kilobytes.
Z\t%Z\tSystem's page size, in bytes. This is a per-system constant, but varies between systems.
-\t-----\t-- Other -------------------------------------------------------------------------------------------------
I\t%I\tNumber of file system inputs by the process.
O\t%O\tNumber of file system outputs by the process.
k\t%k\tNumber of signals delivered to the process.
r\t%r\tNumber of socket messages received by the process.
s\t%s\tNumber of socket messages sent by the process.
"
# reset system for a more predictable results (hopefully)
sudo -- bash -c "
set -euo pipefail
echo 'Hardware reset $1 ...'
# Run the TRIM command (for SSDs)
/sbin/fstrim --all
# Run sync to minimize the number of dirty objects on the system
/bin/sync
# Give sync a little bit of time to finish. See https://linux.die.net/man/8/sync
sleep 5
# Free slab objects and pagecache
echo 3 > /proc/sys/vm/drop_caches
# Request compaction to reduce memory fragmentation
echo 1 > /proc/sys/vm/compact_memory
echo 'Hardware reset $1 done'
"
# Must use full path to get the full-featured version of time
# profile-*.tsv filenames are parsed using ${file:8:-4} below
/usr/bin/time --format "$TIME_FORMAT" --output "${PROFILE_DIR}/profile-${1}.tsv" "${@:2}"
}
create_db() {
make clean
make init-dirs
cp ../ci_cache/perf-test-areas-latest.osm.pbf data/perf-test-areas.osm.pbf
make destroy-db
make all
make start-db
profile 1_data make import-data
profile 2_osm make import-osm
if [ -f ../ci_cache/wikidata-cache.json ]; then
cp ../ci_cache/wikidata-cache.json cache/wikidata-cache.json
fi
profile 3_wikidata make import-wikidata
profile 4_sql make import-sql
# Get database total size, in MB
# Once Makefile has a few more improvements, we can use this approach instead:
# echo $'\\set QUIET on \\a \\x off \\t \\\\ select pg_database_size(current_database())/1024/1024;' | make -s psql
DB_SIZE_MB=$(docker-compose run --rm -u $(id -u):$(id -g) openmaptiles-tools psql.sh -qtAc 'select pg_database_size(current_database())/1024/1024;')
docker-compose run --rm -u $(id -u):$(id -g) openmaptiles-tools pg_dump --schema-only > "${PROFILE_DIR}/schema.sql"
echo "$DB_SIZE_MB" > "${PROFILE_DIR}/db_size.tsv"
}
echo "Ensuring we have the needed dirs"
pwd
mkdir -p perf_cache
mkdir -p artifacts
mkdir -p pr_message
cd code
CURRENT_SHA=$(git log -1 --format="%H")
if [ ! -f ../perf_cache/results.json ]; then
echo "We do not have cached performance results, create them..."
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
git reset --hard ${CURRENT_SHA}^1
fi
docker-compose pull
PROFILE_DIR=../perf_cache
create_db
if [ ! -f ../ci_cache/wikidata-cache.json ]; then
cp cache/wikidata-cache.json ../ci_cache/wikidata-cache.json
fi
(set -x; profile test-perf docker-compose run --rm -T openmaptiles-tools \
test-perf openmaptiles.yaml $TEST_PERF_PARAMS \
--record /tileset/results.json)
echo "Done generating base perf results, moving them to ../perf_cache"
pwd
mv results.json ../perf_cache
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
# For pull requests, restore to the PR version before continuing
git reset --hard ${CURRENT_SHA}
fi
else
echo "Found cached performance results"
fi
docker-compose pull
pushd ../perf_cache
echo "Should be in perf_cache"
pwd
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
cp results.json ../artifacts/base-results.json
# Copy all tsv files, not just the ones with "profile-" prefix.
for file in *.tsv; do
cp "$file" "../artifacts/base-$file"
done
else
cp results.json ../artifacts/results.json
# Copy all tsv files, not just the ones with "profile-" prefix.
cp *.tsv ../artifacts
fi
popd
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
echo "Comparing pull request results with the base..."
PROFILE_DIR=../artifacts
create_db
echo "Copying existing perf_cache results to current dir"
pwd
cp ../perf_cache/results.json .
OUTPUT="$(set -x; profile test-perf docker-compose run --rm -T openmaptiles-tools \
test-perf openmaptiles.yaml $TEST_PERF_PARAMS \
--compare /tileset/results.json --record /tileset/pr-results.json)"
rm results.json
mv pr-results.json ../artifacts/
# Split into two parts -- before and after the ===== SUMMARY =====
OUT_SUMMARY="${OUTPUT##*========}"
OUT_DETAILS="${OUTPUT%%========*}"
pushd ../artifacts
PROFILING_MSG="step | total time | change | user time | change
--- | --- | --- | --- | ---
"
for file in profile*.tsv; do
new_total_time_fmt=$(grep -E '^E' "$file" | cut -d$'\t' -f 2)
old_total_time=$(grep -E '^e' "base-$file" | cut -d$'\t' -f 2)
new_total_time=$(grep -E '^e' "$file" | cut -d$'\t' -f 2)
old_user_time=$(grep -E '^U' "base-$file" | cut -d$'\t' -f 2)
new_user_time=$(grep -E '^U' "$file" | cut -d$'\t' -f 2)
PROFILING_MSG="${PROFILING_MSG}${file:8:-4} \
| ${new_total_time_fmt} | $( echo "$old_total_time $new_total_time" | awk '{ if ($1 == 0) print "-"; else printf "%.1f%%", ($2-$1)*100/$1 }' ) \
| $( echo "$old_user_time $new_user_time" | awk '{ if ($1 == 0) print "%s | -", $2 ; else printf "%s | %.1f%%", $2, ($2-$1)*100/$1 }' ) \
"$'\n'
done
DB_SIZE_CHANGE=$( echo "$(cat base-db_size.tsv) $(cat db_size.tsv)" | \
awk '{ printf "PostgreSQL DB size in MB: %s ⇒ %s", $1, $2; if ($1 != 0) printf " (%.1f%% change)", ($2-$1)*100/$1 }' )
popd
cat > ../pr_message/message.md <<EOF
Results evaluating commit $(git log HEAD^2 -1 --format="%H") (merged with base $CACHE_SHA as $GITHUB_SHA). See [run details](https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID).
$DB_SIZE_CHANGE
$PROFILING_MSG
\`\`\`
$OUT_SUMMARY
\`\`\`
<details>
<summary>expand for details...</summary>
\`\`\`
$OUT_DETAILS
\`\`\`
</details>
EOF
fi
- name: Save performance artifacts
uses: actions/upload-artifact@v4
with:
name: performance_results
path: artifacts
- name: Save PR message artifact
if: github.event_name == 'pull_request'
uses: actions/upload-artifact@v4
with:
name: pr_message
path: pr_message

246
.github/workflows/pr-updater.yml vendored 100644
Wyświetl plik

@ -0,0 +1,246 @@
name: Update PR comments
on:
workflow_run:
workflows: ["OpenMapTiles Performance CI"]
types: [completed]
jobs:
update_PRs:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- name: main
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
WORKFLOW_NAME: "OpenMapTiles Performance CI"
# the name of the artifact whose content comment published by PR. Must have a single markdown file inside.
MSG_ARTIFACT_NAME: "pr_message"
# How far back to look for finished runs, in minutes.
# Set to 10-20 minutes higher than cron's job frequency set above.
IGNORE_RUNS_OLDER_THAN: 80
# How far back to look for updated pull requests, in minutes.
# Should be bigger than IGNORE_RUNS_OLDER_THAN by the maximum time a pull request jobs may take
IGNORE_PRS_OLDER_THAN: 80
run: |
#
# Strategy:
# * get all recently updated pull requests
# * get all recent workflow runs
# * match pull requests and their current SHA with the last workflow run for the same SHA
# * for each found match of <pull-request-number> and <workflow-run-id> :
# * download artifact from the workflow run -- expects a single file with markdown content
# * look through existing PR comments to see if we have posted a comment before
# (uses a hidden magical header to identify our comment)
# * either create or update the comment with the new text (if changed)
#
export GITHUB_API="https://api.github.com/repos/$GITHUB_REPOSITORY"
export COMMENT_MAGIC_HEADER='<!--'" Do not edit. This comment will be auto-updated with artifact '$MSG_ARTIFACT_NAME' created by action '$WORKFLOW_NAME' -->"
# A useful wrapper around CURL
crl() {
curl --silent --show-error --location --retry 1 "${@:2}" \
-H "Accept: application/vnd.github.antiope-preview+json, application/vnd.github.v3+json" \
"$1"
}
auth_crl() {
crl "$1" -H "authorization: Bearer $GITHUB_TOKEN" "${@:2}"
}
#
# Parse current pull requests
#
# Get all pull requests, most recently updated first
# (this way we don't need to page through all of them)
# Filter out PRs that are older than $IGNORE_PRS_OLDER_THAN minutes
# Result is an object, mapping a "key" to the pull request number:
# {
# "nyurik/openmaptiles/nyurik-patch-1/4953dd2370b9988a7832d090b5e47b3cd867f594": 6,
# ...
# }
PULL_REQUESTS_RAW="$( crl "$GITHUB_API/pulls?sort=updated&direction=desc" )"
if ! PULL_REQUESTS="$(jq --arg IGNORE_PRS_OLDER_THAN "$IGNORE_PRS_OLDER_THAN" '
map(
# Only select unlocked pull requests updated within last $IGNORE_PRS_OLDER_THAN minutes
select(.locked==false
and (now - (.updated_at|fromdate)) / 60 < ($IGNORE_PRS_OLDER_THAN | tonumber))
# Prepare for "from_entries" by creating a key/value object
# The key is a combination of repository name, branch name, and latest SHA
| { key: (.head.repo.full_name + "/" + .head.ref + "/" + .head.sha), value: .number }
)
| from_entries
' <( echo "$PULL_REQUESTS_RAW" ) )"; then
echo "Error parsing pull requests"
echo "$PULL_REQUESTS_RAW"
exit 1
fi
# Count how many pull requests we should process, and exit early if there are none
PR_COUNT="$(jq 'length' <( echo "$PULL_REQUESTS" ) )"
if [ "$PR_COUNT" -eq 0 ]; then
echo "There are no pull requests updated in the last $IGNORE_PRS_OLDER_THAN minutes. Exiting."
exit
else
echo "$PR_COUNT pull requests have been updated in the last $IGNORE_PRS_OLDER_THAN minutes"
echo "$PULL_REQUESTS" | jq -r 'keys|.[]|" * " + .'
fi
#
# Resolve workflow name into workflow ID
#
WORKFLOW_ID="$(crl "$GITHUB_API/actions/workflows" \
| jq --arg WORKFLOW_NAME "$WORKFLOW_NAME" '
.workflows[] | select(.name == $WORKFLOW_NAME) | .id
')"
if [ -z "$WORKFLOW_ID" ]; then
echo "Unable to find workflow '$WORKFLOW_NAME' in $GITHUB_REPOSITORY"
exit 1
else
echo "Resolved workflow '$WORKFLOW_NAME' to ID $WORKFLOW_ID"
fi
#
# Match pull requests with the workflow runs
#
# Get all workflow runs that were triggered by pull requests
WORKFLOW_PR_RUNS="$(crl "$GITHUB_API/actions/workflows/${WORKFLOW_ID}/runs?event=pull_request")"
# For each workflow run, match it with the pull request to get the PR number
# A match is based on "source repository + branch + SHA" key
# In rare cases (e.g. force push to an older revision), there could be more than one match
# for a given PR number, so just use the most recent one.
# Result is a table (list of lists) - each row with PR number, JOB ID, and the above key
PR_JOB_MAP="$(jq --arg IGNORE_RUNS_OLDER_THAN "$IGNORE_RUNS_OLDER_THAN" '
# second input is the pull request map - use it to lookup PR numbers
input as $PULL_REQUESTS
| .workflow_runs
| map(
# Create a new object with the relevant values
{
id,
updated_at,
# create lookup key based on source repository + branch + SHA
key: (.head_repository.full_name + "/" + .head_branch + "/" + .head_sha),
# was this a successful run?
# do not include .conclusion=="success" because errors could also post messages
success: (.status=="completed")
}
# lookup PR number from $PULL_REQUESTS using the above key
| . += { pr_number: $PULL_REQUESTS[.key] }
# Remove runs that were not in the list of the PRs
| select(.pr_number)
)
# Keep just the most recent run per pull request
| group_by(.pr_number)
| map(
sort_by(.updated_at)
| last
# If the most recent run did not succeed, or if the run is too old, ignore it
| select(.success and (now - (.updated_at|fromdate)) / 60 < ($IGNORE_RUNS_OLDER_THAN | tonumber))
# Keep just the pull request number mapping to run ID
| { pr_number, id, key }
)
' <( echo "$WORKFLOW_PR_RUNS" ) <( echo "$PULL_REQUESTS" ) )"
# Count how many jobs we should process, and exit early if there are none
JOBS_COUNT="$(jq 'length' <( echo "$PR_JOB_MAP" ) )"
if [ "$JOBS_COUNT" -eq 0 ]; then
echo "There are no recent workflow job runs in the last $IGNORE_RUNS_OLDER_THAN minutes. Exiting."
exit
else
echo "$JOBS_COUNT '$WORKFLOW_NAME' jobs have been updated in the last $IGNORE_RUNS_OLDER_THAN minutes"
echo "$PR_JOB_MAP" | jq -r '.[] | " * PR #\(.pr_number) Job #\(.id) -- \(.key) "'
fi
#
# Iterate over the found pairs of PR number + run ID, and update them all
#
echo "$PR_JOB_MAP" | jq -r '.[] | [ .pr_number, .id, .key ] | @sh' | \
while read -r PR_NUMBER RUN_ID RUN_KEY; do
echo "Processing '$WORKFLOW_NAME' run #$RUN_ID for pull request #$PR_NUMBER $RUN_KEY..."
ARTIFACTS="$(crl "$GITHUB_API/actions/runs/$RUN_ID/artifacts")"
# Find the artifact download URL for the artifact with the expected name
ARTIFACT_URL="$(jq -r --arg MSG_ARTIFACT_NAME "$MSG_ARTIFACT_NAME" '
.artifacts
| map(select(.name == $MSG_ARTIFACT_NAME and .expired == false))
| first
| .archive_download_url
| select(.!=null)
' <( echo "$ARTIFACTS" ) )"
if [ -z "$ARTIFACT_URL" ]; then
echo "Unable to find an artifact named '$MSG_ARTIFACT_NAME' in workflow $RUN_ID (PR #$PR_NUMBER), skipping..."
continue
fi
echo "Downloading artifact $ARTIFACT_URL (assuming single text file per artifact)..."
if ! MESSAGE="$(auth_crl "$ARTIFACT_URL" | gunzip)"; then
echo "Unable to download or parse message from artifact '$MSG_ARTIFACT_NAME' in workflow $RUN_ID (PR #$PR_NUMBER), skipping..."
continue
fi
if [ -z "$MESSAGE" ]; then
echo "Empty message in artifact '$MSG_ARTIFACT_NAME' in workflow $RUN_ID (PR #$PR_NUMBER), skipping..."
continue
fi
# Create a message body by appending a magic header
# and stripping any starting and ending whitespace from the original message
MESSAGE_BODY="$(jq -n \
--arg COMMENT_MAGIC_HEADER "$COMMENT_MAGIC_HEADER" \
--arg MESSAGE "$MESSAGE" \
'{ body: ($COMMENT_MAGIC_HEADER + "\n" + ($MESSAGE | sub( "^[\\s\\p{Cc}]+"; "" ) | sub( "[\\s\\p{Cc}]+$"; "" ))) }' \
)"
EXISTING_PR_COMMENTS="$(crl "$GITHUB_API/issues/$PR_NUMBER/comments")"
# Get the comment URL for the first comment that begins with the magic header, or empty string
OLD_COMMENT="$(jq --arg COMMENT_MAGIC_HEADER "$COMMENT_MAGIC_HEADER" '
map(select(.body | startswith($COMMENT_MAGIC_HEADER)))
| first
| select(.!=null)
' <( echo "$EXISTING_PR_COMMENTS" ) )"
if [ -z "$OLD_COMMENT" ]; then
COMMENT_HTML_URL="$(auth_crl "$GITHUB_API/issues/$PR_NUMBER/comments" \
-X POST \
-H "Content-Type: application/json" \
--data "$MESSAGE_BODY" \
| jq -r '.html_url' )"
COMMENT_INFO="New comment $COMMENT_HTML_URL was created"
else
# Make sure the content of the message has changed
COMMENT_URL="$(jq -r '
(input | .body) as $body
| select(.body | . != $body)
| .url
' <( echo "$OLD_COMMENT" ) <( echo "$MESSAGE_BODY" ) )"
if [ -z "$COMMENT_URL" ]; then
echo "The message has already been posted from artifact '$MSG_ARTIFACT_NAME' in workflow $RUN_ID (PR #$PR_NUMBER), skipping..."
continue
fi
COMMENT_HTML_URL="$(auth_crl "$COMMENT_URL" \
-X PATCH \
-H "Content-Type: application/json" \
--data "$MESSAGE_BODY" \
| jq -r '.html_url' )"
COMMENT_INFO="Existing comment $COMMENT_HTML_URL was updated"
fi
echo "$COMMENT_INFO from workflow $WORKFLOW_NAME #$RUN_ID"
done

22
.github/workflows/sql-tests.yml vendored 100644
Wyświetl plik

@ -0,0 +1,22 @@
# Workflow to run unit tests on OMT`s new Pull Requests and commits pushed into OMT repo
name: OpenMapTiles SQL Test CI
on:
push:
branches: [ master, master-tools ]
pull_request:
jobs:
unit_tests:
name: Run unit test
runs-on: ubuntu-latest
steps:
- name: Checkout the changes
uses: actions/checkout@v4
- name: Run unit tests
run: |
make clean && make test-sql

6
.gitignore vendored
Wyświetl plik

@ -11,12 +11,12 @@ quickstart.log
# imput / output data
data/*
# input wikidata
wikidata/*
# generated source files
build/*
# Import cache
cache/*
# any IDE files
.idea/
.vscode/

Wyświetl plik

@ -1,11 +0,0 @@
sudo: required
language: bash
services:
- docker
script:
- set -e
- TEST_MODE=yes make generate-devdoc
- ./quickstart.sh

Wyświetl plik

@ -1,6 +1,6 @@
# 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://osmus-slack.herokuapp.com/)).
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.
@ -32,16 +32,57 @@ Your pull request must:
* Use clear commit messages.
* Be possible to merge automatically.
When you modify rules of importing data in `mapping.yaml` or `*.sql`, please update also:
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. if needed, generate new `mapping_diagram.png` or `etl_diagram.png` using commands below:
```
make mapping-graph-[layer]
make etl-graph-[layer]
```
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
```

Wyświetl plik

@ -1,4 +1,4 @@
Copyright (c) 2016, KlokanTech.com & OpenMapTiles contributors.
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
All rights reserved.
The vector tile schema has been developed by Klokan Technologies GmbH and
@ -55,6 +55,6 @@ 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.
Exceptions to OpenMapTiles attribution requirement can be in a written form granted
by Klokan Technologies GmbH (info@klokantech.com).
The project contributors grant Klokan Technologies GmbH the license to give such
by MapTiler (info@maptiler.com).
The project contributors grant MapTiler AG the license to give such
exceptions on a commercial basis.

809
Makefile
Wyświetl plik

@ -1,286 +1,697 @@
# Options to run with docker and docker-compose - ensure the container is destroyed on exit
DC_OPTS?=--rm
#
# First section - common variable initialization
#
# container runs as the current user rather than root (so that created files are not root-owned)
DC_USER_OPTS?=$(DC_OPTS) -u $$(id -u $${USER}):$$(id -g $${USER})
# Ensure that errors don't hide inside pipes
SHELL = /bin/bash
.SHELLFLAGS = -o pipefail -c
# Layers definition and meta data
TILESET_FILE := $(or $(TILESET_FILE),$(shell (. .env; echo $${TILESET_FILE})),openmaptiles.yaml)
# Options to run with docker and docker-compose - ensure the container is destroyed on exit
# Containers run as the current user rather than root (so that created files are not root-owned)
DC_OPTS ?= --rm --user=$(shell id -u):$(shell id -g)
# If set to a non-empty value, will use postgis-preloaded instead of postgis docker image
USE_PRELOADED_IMAGE ?=
# Local port to use with postserve
PPORT ?= 8090
export PPORT
# Local port to use with tileserver
TPORT ?= 8080
export TPORT
STYLE_FILE := build/style/style.json
STYLE_HEADER_FILE := style/style-header.json
# Support newer `docker compose` syntax in addition to `docker-compose`
ifeq (, $(shell which docker-compose))
DOCKER_COMPOSE_COMMAND := docker compose
$(info Using docker compose V2 (docker compose))
else
DOCKER_COMPOSE_COMMAND := docker-compose
$(info Using docker compose V1 (docker-compose))
endif
# Allow a custom docker-compose project name
DC_PROJECT := $(or $(DC_PROJECT),$(shell (. .env; echo $${DC_PROJECT})))
ifeq ($(DC_PROJECT),)
DC_PROJECT := $(notdir $(shell pwd))
DOCKER_COMPOSE := $(DOCKER_COMPOSE_COMMAND)
else
DOCKER_COMPOSE := $(DOCKER_COMPOSE_COMMAND) --project-name $(DC_PROJECT)
endif
# Make some operations quieter (e.g. inside the test script)
ifeq ($(or $(QUIET),$(shell (. .env; echo $${QUIET})))),)
QUIET_FLAG :=
else
QUIET_FLAG := --quiet
endif
# Use `xargs --no-run-if-empty` flag, if supported
XARGS := xargs $(shell xargs --no-run-if-empty </dev/null 2>/dev/null && echo --no-run-if-empty)
# If running in the test mode, compare files rather than copy them
TEST_MODE?=no
ifeq ($(TEST_MODE),yes)
COPY_TO_GIT=diff
# create images in ./build/devdoc and compare them to ./layers
GRAPH_PARAMS=./build/devdoc ./layers
else
COPY_TO_GIT=cp
# update graphs in the ./layers dir
GRAPH_PARAMS=./layers
endif
# Set OpenMapTiles host
export OMT_HOST := http://$(firstword $(subst :, ,$(subst tcp://,,$(DOCKER_HOST))) localhost)
# This defines an easy $(newline) value to act as a "\n". Make sure to keep exactly two empty lines after newline.
define newline
endef
# Use the old Postgres connection values as a fallback
PGHOST := $(or $(PGHOST),$(shell (. .env; echo $${PGHOST})),$(POSTGRES_HOST),$(shell (. .env; echo $${POSTGRES_HOST})),postgres)
PGPORT := $(or $(PGPORT),$(shell (. .env; echo $${PGPORT})),$(POSTGRES_PORT),$(shell (. .env; echo $${POSTGRES_PORT})),postgres)
PGDATABASE := $(or $(PGDATABASE),$(shell (. .env; echo $${PGDATABASE})),$(POSTGRES_DB),$(shell (. .env; echo $${POSTGRES_DB})),postgres)
PGUSER := $(or $(PGUSER),$(shell (. .env; echo $${PGUSER})),$(POSTGRES_USER),$(shell (. .env; echo $${POSTGRES_USER})),postgres)
PGPASSWORD := $(or $(PGPASSWORD),$(shell (. .env; echo $${PGPASSWORD})),$(POSTGRES_PASSWORD),$(shell (. .env; echo $${POSTGRES_PASSWORD})),postgres)
#
# Determine area to work on
# If $(area) parameter is not set, and only one *.osm.pbf file is found in ./data, use it as $(area).
# Otherwise, all make targets requiring an area will show an error.
# Note: If no *.osm.pbf files are found, once the users call "make download area=..."
# they will not need to use an "area=" parameter again because there will be just a single file.
#
# historically we have been using $(area) rather than $(AREA), so make both work
area ?= $(AREA)
# Ensure the $(area) param is set, or try to automatically determine it based on available data files
ifeq ($(area),)
# An $(area) parameter is not set. If only one *.osm.pbf file is found in ./data, use it as $(area).
data_files := $(shell find data -name '*.osm.pbf' 2>/dev/null)
ifneq ($(word 2,$(data_files)),)
define assert_area_is_given
@echo ""
@echo "ERROR: The 'area' parameter or environment variable have not been set, and there several 'area' options:"
@$(patsubst data/%.osm.pbf,echo " '%'";,$(data_files))
@echo ""
@echo "To specify an area use:"
@echo " make $@ area=<area-id>"
@echo ""
@exit 1
endef
else
ifeq ($(word 1,$(data_files)),)
define assert_area_is_given
@echo ""
@echo "ERROR: The 'area' parameter (or env var) has not been set, and there are no data/*.osm.pbf files"
@echo ""
@echo "To specify an area use"
@echo " make $@ area=<area-id>"
@echo ""
@echo "To download an area, use make download area=<area-id>"
@echo "To list downloadable areas, use make list-geofabrik and/or make list-bbbike"
@exit 1
@echo ""
endef
else
# Keep just the name of the data file, without the .osm.pbf extension
area := $(patsubst data/%.osm.pbf,%,$(data_files))
# Rename area-latest.osm.pbf to area.osm.pbf
# TODO: This if statement could be removed in a few months once everyone is using the file without the `-latest`?
ifneq ($(area),$(area:-latest=))
$(shell mv "data/$(area).osm.pbf" "data/$(area:-latest=).osm.pbf")
area := $(area:-latest=)
$(warning ATTENTION: File data/$(area)-latest.osm.pbf was renamed to $(area).osm.pbf.)
AREA_INFO := Detected area=$(area) based on finding a 'data/$(area)-latest.osm.pbf' file - renamed to '$(area).osm.pbf'. Use 'area' parameter or environment variable to override.
else
AREA_INFO := Detected area=$(area) based on finding a 'data/$(area).osm.pbf' file. Use 'area' parameter or environment variable to override.
endif
endif
endif
endif
ifneq ($(AREA_INFO),)
define assert_area_is_given
@echo "$(AREA_INFO)"
endef
endif
# If set, this file will be downloaded in download-osm and imported in the import-osm targets
PBF_FILE ?= data/$(area).osm.pbf
# For download-osm, allow URL parameter to download file from a given URL. Area param must still be provided.
DOWNLOAD_AREA := $(or $(url), $(area))
# The mbtiles file is placed into the $EXPORT_DIR=/export (mapped to ./data)
MBTILES_FILE := $(or $(MBTILES_FILE),$(shell (. .env; echo $${MBTILES_FILE})),$(area).mbtiles)
MBTILES_LOCAL_FILE = data/$(MBTILES_FILE)
DIFF_MODE := $(or $(DIFF_MODE),$(shell (. .env; echo $${DIFF_MODE})))
ifeq ($(DIFF_MODE),true)
# import-osm implementation requires IMPOSM_CONFIG_FILE to be set to a valid file
# For one-time only imports, the default value is fine.
# For diff mode updates, use the dynamically-generated area-based config file
export IMPOSM_CONFIG_FILE = data/$(area).repl.json
endif
# Load area-specific bbox file that gets generated by the download-osm --bbox
AREA_BBOX_FILE ?= data/$(area).bbox
ifneq (,$(wildcard $(AREA_BBOX_FILE)))
cat := $(if $(filter $(OS),Windows_NT),type,cat)
BBOX := $(shell $(cat) ${AREA_BBOX_FILE})
export BBOX
endif
# Consult .env if needed
MIN_ZOOM := $(or $(MIN_ZOOM),$(shell (. .env; echo $${MIN_ZOOM})),0)
MAX_ZOOM := $(or $(MAX_ZOOM),$(shell (. .env; echo $${MAX_ZOOM})),7)
PPORT := $(or $(PPORT),$(shell (. .env; echo $${PPORT})),7)
TPORT := $(or $(TPORT),$(shell (. .env; echo $${TPORT})),7)
define HELP_MESSAGE
==============================================================================
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 $(OMT_HOST):8088 ]
make stop-maputnik # stop Maputnik Editor + dynamic tile server
make start-postserve # start dynamic tile server [ see $(OMT_HOST):$(PPORT) ]
make stop-postserve # stop dynamic tile server
make start-tileserver # start maptiler/tileserver-gl [ see $(OMT_HOST):$(TPORT) ]
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
==============================================================================
endef
export HELP_MESSAGE
#
# TARGETS
#
.PHONY: all
all: build/openmaptiles.tm2source/data.yml build/mapping.yaml build/tileset.sql
all: init-dirs build/openmaptiles.tm2source/data.yml build/mapping.yaml build-sql build-style
.PHONY: help
help:
@echo "=============================================================================="
@echo " OpenMapTiles https://github.com/openmaptiles/openmaptiles "
@echo "Hints for testing areas "
@echo " make download-geofabrik-list # list actual geofabrik OSM extracts for download -> <<your-area>> "
@echo " make list # list actual geofabrik OSM extracts for download -> <<your-area>> "
@echo " ./quickstart.sh <<your-area>> # example: ./quickstart.sh madagascar "
@echo " "
@echo "Hints for designers:"
@echo " make start-postserve # start Postserver + Maputnik Editor [ see localhost:8088 ] "
@echo " make start-tileserver # start klokantech/tileserver-gl [ see localhost:8080 ] "
@echo " "
@echo "Hints for developers:"
@echo " make # build source code"
@echo " make download-geofabrik area=albania # download OSM data from geofabrik, and create config file"
@echo " make psql # start PostgreSQL console"
@echo " make psql-list-tables # list all PostgreSQL tables"
@echo " make psql-vacuum-analyze # PostgreSQL: VACUUM ANALYZE"
@echo " make psql-analyze # PostgreSQL: ANALYZE"
@echo " make generate-qareports # generate reports [./build/qareports]"
@echo " make generate-devdoc # generate devdoc including graphs for all layers [./build/devdoc]"
@echo " make etl-graph # hint for generating a single etl graph"
@echo " make mapping-graph # hint for generating a single mapping graph"
@echo " make import-sql-dev # start import-sql /bin/bash terminal"
@echo " make import-osm-dev # start import-osm /bin/bash terminal (imposm3)"
@echo " make clean-docker # remove docker containers, PG data volume"
@echo " make forced-clean-sql # drop all PostgreSQL tables for clean environment"
@echo " make docker-unnecessary-clean # clean unnecessary docker image(s) and container(s)"
@echo " make refresh-docker-images # refresh openmaptiles docker images from Docker HUB"
@echo " make remove-docker-images # remove openmaptiles docker images"
@echo " make pgclimb-list-views # list PostgreSQL public schema views"
@echo " make pgclimb-list-tables # list PostgreSQL public schema tables"
@echo " cat .env # list PG database and MIN_ZOOM and MAX_ZOOM information"
@echo " cat quickstart.log # backup of the last ./quickstart.sh"
@echo " make help # help about available commands"
@echo "=============================================================================="
@echo "$$HELP_MESSAGE" | less
.PHONY: build
build:
mkdir -p build
define win_fs_error
( \
echo "" ;\
echo "ERROR: Windows native filesystem" ;\
echo "" ;\
echo "Please avoid running OpenMapTiles in a Windows filesystem." ;\
echo "See https://github.com/openmaptiles/openmaptiles/issues/1095#issuecomment-817095465" ;\
echo "" ;\
exit 1 ;\
)
endef
build/openmaptiles.tm2source/data.yml: build
mkdir -p build/openmaptiles.tm2source
docker-compose run $(DC_OPTS) openmaptiles-tools generate-tm2source openmaptiles.yaml --host="postgres" --port=5432 --database="openmaptiles" --user="openmaptiles" --password="openmaptiles" > build/openmaptiles.tm2source/data.yml
.PHONY: init-dirs
init-dirs:
@mkdir -p build/sql/parallel
@mkdir -p build/openmaptiles.tm2source
@mkdir -p build/style
@mkdir -p data
@mkdir -p cache
@ ! ($(DOCKER_COMPOSE) 2>/dev/null run $(DC_OPTS) openmaptiles-tools df --output=fstype /tileset| grep -q 9p) < /dev/null || ($(win_fs_error))
build/mapping.yaml: build
docker-compose run $(DC_OPTS) openmaptiles-tools generate-imposm3 openmaptiles.yaml > build/mapping.yaml
build/openmaptiles.tm2source/data.yml: init-dirs
ifeq (,$(wildcard build/openmaptiles.tm2source/data.yml))
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c \
'generate-tm2source $(TILESET_FILE) > $@'
endif
build/tileset.sql: build
docker-compose run $(DC_OPTS) openmaptiles-tools generate-sql openmaptiles.yaml > build/tileset.sql
build/mapping.yaml: init-dirs
ifeq (,$(wildcard build/mapping.yaml))
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c \
'generate-imposm3 $(TILESET_FILE) > $@'
endif
.PHONY: build-sql
build-sql: init-dirs
ifeq (,$(wildcard build/sql/run_last.sql))
@mkdir -p build/sql/parallel
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c \
'generate-sql $(TILESET_FILE) --dir ./build/sql \
&& generate-sqltomvt $(TILESET_FILE) \
--key --gzip --postgis-ver 3.3.4 \
--function --fname=getmvt >> ./build/sql/run_last.sql'
endif
.PHONY: build-sprite
build-sprite: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c 'spreet /style/icons build/style/sprite && \
spreet --retina /style/icons build/style/sprite@2x'
.PHONY: build-style
build-style: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c 'style-tools recompose $(TILESET_FILE) $(STYLE_FILE) \
$(STYLE_HEADER_FILE) && \
spreet /style/icons build/style/sprite && spreet --retina /style/icons build/style/sprite@2x'
.PHONY: download-fonts
download-fonts:
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash -c '[ ! -d "/export/fonts" ] && mkdir /export/fonts && \
echo "Downloading fonts..." && wget -qO /export/noto-sans.zip --show-progress \
https://github.com/openmaptiles/fonts/releases/download/v2.0/noto-sans.zip && \
echo "Unzipping fonts..." && unzip -q /export/noto-sans.zip -d /export/fonts && rm /export/noto-sans.zip || \
echo "Fonts already exist."'
.PHONY: clean
clean:
rm -f build/openmaptiles.tm2source/data.yml && rm -f build/mapping.yaml && rm -f build/tileset.sql
clean: clean-test-data
rm -rf build
.PHONY: clean-docker
clean-docker:
docker-compose down -v --remove-orphans
docker-compose rm -fv
docker volume ls -q | grep openmaptiles | xargs -r docker volume rm || true
clean-test-data:
rm -rf data/changes.state.txt
rm -rf data/last.state.txt
rm -rf data/changes.repl.json
.PHONY: db-start
db-start:
docker-compose up -d postgres
.PHONY: destroy-db
DOCKER_PROJECT = $(shell echo $(DC_PROJECT) | tr A-Z a-z | tr -cd '[:alnum:]')
destroy-db:
$(DOCKER_COMPOSE) down -v --remove-orphans
$(DOCKER_COMPOSE) rm -fv
docker volume ls -q -f "name=^$(DOCKER_PROJECT)_" | $(XARGS) docker volume rm
rm -rf cache
mkdir cache
.PHONY: start-db-nowait
start-db-nowait: init-dirs
@echo "Starting postgres docker compose target using $${POSTGIS_IMAGE:-default} image (no recreate if exists)" && \
$(DOCKER_COMPOSE) up --no-recreate -d postgres
.PHONY: start-db
start-db: start-db-nowait
@echo "Wait for PostgreSQL to start..."
docker-compose run $(DC_OPTS) import-osm ./pgwait.sh
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools pgwait
.PHONY: download-geofabrik
download-geofabrik:
@echo =============== download-geofabrik =======================
@echo Download area : $(area)
@echo [[ example: make download-geofabrik area=albania ]]
@echo [[ list areas: make download-geofabrik-list ]]
docker-compose run $(DC_OPTS) import-osm ./download-geofabrik.sh $(area)
ls -la ./data/$(area).*
@echo "Generated config file: ./data/docker-compose-config.yml"
@echo " "
cat ./data/docker-compose-config.yml
@echo " "
# Wrap start-db target but use the preloaded image
.PHONY: start-db-preloaded
start-db-preloaded: export POSTGIS_IMAGE=openmaptiles/postgis-preloaded
start-db-preloaded: export COMPOSE_HTTP_TIMEOUT=180
start-db-preloaded: start-db
.PHONY: stop-db
stop-db:
@echo "Stopping PostgreSQL..."
$(DOCKER_COMPOSE) stop postgres
.PHONY: list-geofabrik
list-geofabrik: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools download-osm list geofabrik
.PHONY: list-bbbike
list-bbbike: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools download-osm list bbbike
#
# download, download-geofabrik, download-osmfr, and download-bbbike are handled here
# The --imposm-cfg will fail for some of the sources, but we ignore that error -- only needed for diff mode
#
OSM_SERVERS := geofabrik osmfr bbbike
ALL_DOWNLOADS := $(addprefix download-,$(OSM_SERVERS)) download
OSM_SERVER=$(patsubst download,,$(patsubst download-%,%,$@))
.PHONY: $(ALL_DOWNLOADS)
$(ALL_DOWNLOADS): init-dirs
@$(assert_area_is_given)
ifneq ($(url),)
$(if $(OSM_SERVER),$(error url parameter can only be used with non-specific download target:$(newline) make download area=$(area) url="$(url)"$(newline)))
endif
ifeq (,$(wildcard $(PBF_FILE)))
ifeq ($(DIFF_MODE),true)
@echo "Downloading $(DOWNLOAD_AREA) with replication support into $(PBF_FILE) and $(IMPOSM_CONFIG_FILE) from $(if $(OSM_SERVER),$(OSM_SERVER),any source)"
@$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools download-osm $(OSM_SERVER) "$(DOWNLOAD_AREA)" \
--imposm-cfg "$(IMPOSM_CONFIG_FILE)" \
--bbox "$(AREA_BBOX_FILE)" \
--output "$(PBF_FILE)"
else
@echo "Downloading $(DOWNLOAD_AREA) into $(PBF_FILE) from $(if $(OSM_SERVER),$(OSM_SERVER),any source)"
@$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools download-osm $(OSM_SERVER) "$(DOWNLOAD_AREA)" \
--bbox "$(AREA_BBOX_FILE)" \
--output "$(PBF_FILE)"
endif
@echo ""
else
ifeq ($(DIFF_MODE),true)
ifeq (,$(wildcard $(IMPOSM_CONFIG_FILE)))
$(error \
$(newline) Data files $(PBF_FILE) already exists, but $(IMPOSM_CONFIG_FILE) does not. \
$(newline) You probably downloaded the data file before setting DIFF_MODE=true. \
$(newline) You can delete the data file $(PBF_FILE) and re-run make download \
$(newline) to re-download and generate config, or manually create $(IMPOSM_CONFIG_FILE) \
$(newline) See example https://github.com/openmaptiles/openmaptiles-tools/blob/v5.2/bin/config/repl_config.json \
$(newline))
else
@echo "Data files $(PBF_FILE) and replication config $(IMPOSM_CONFIG_FILE) already exists, skipping the download."
endif
else
@echo "Data files $(PBF_FILE) already exists, skipping the download."
endif
endif
.PHONY: generate-bbox-file
generate-bbox-file:
@$(assert_area_is_given)
ifeq (,$(wildcard $(AREA_BBOX_FILE)))
@$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools download-osm bbox "$(PBF_FILE)" "$(AREA_BBOX_FILE)"
else
@echo "Configuration file $(AREA_BBOX_FILE) already exists, no need to regenerate. BBOX=$(BBOX)"
endif
.PHONY: psql
psql: db-start
docker-compose run $(DC_OPTS) import-osm ./psql.sh
psql: start-db-nowait
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools sh -c 'pgwait && psql.sh'
# Special cache handling for Docker Toolbox on Windows
ifeq ($(MSYSTEM),MINGW64)
DC_CONFIG_CACHE := -f docker-compose.yml -f docker-compose-$(MSYSTEM).yml
DC_OPTS_CACHE := $(filter-out --user=%,$(DC_OPTS))
else
DC_OPTS_CACHE := $(DC_OPTS)
endif
.PHONY: import-osm
import-osm: db-start all
docker-compose run $(DC_OPTS) import-osm
import-osm: all start-db-nowait
@$(assert_area_is_given)
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && import-osm $(PBF_FILE)'
.PHONY: start-update-osm
start-update-osm: start-db
@$(assert_area_is_given)
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) up -d update-osm
.PHONY: stop-update-osm
stop-update-osm:
$(DOCKER_COMPOSE) stop update-osm
.PHONY: import-diff
import-diff: start-db-nowait
@$(assert_area_is_given)
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && import-diff'
.PHONY: import-data
import-data: start-db
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) import-data
.PHONY: import-sql
import-sql: db-start all
docker-compose run $(DC_OPTS) openmaptiles-tools import-sql
.PHONY: import-osmsql
import-osmsql: db-start all
docker-compose run $(DC_OPTS) import-osm
docker-compose run $(DC_OPTS) openmaptiles-tools import-sql
import-sql: all start-db-nowait
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools sh -c 'pgwait && import-sql' | \
awk -v s=": WARNING:" '1{print; fflush()} $$0~s{print "\n*** WARNING detected, aborting"; exit(1)}' | \
awk '1{print; fflush()} $$0~".*ERROR" {txt=$$0} END{ if(txt){print "\n*** ERROR detected, aborting:"; print txt; exit(1)} }'
.PHONY: generate-tiles
generate-tiles: db-start all
rm -rf data/tiles.mbtiles
if [ -f ./data/docker-compose-config.yml ]; then \
docker-compose -f docker-compose.yml -f ./data/docker-compose-config.yml run $(DC_OPTS) generate-vectortiles; \
else \
docker-compose run $(DC_OPTS) generate-vectortiles; \
generate-tiles: all start-db
@echo "WARNING: This Mapnik-based method of tile generation is obsolete. Use generate-tiles-pg instead."
@echo "Generating tiles into $(MBTILES_LOCAL_FILE) (will delete if already exists)..."
@rm -rf "$(MBTILES_LOCAL_FILE)"
$(DOCKER_COMPOSE) run $(DC_OPTS) generate-vectortiles
@echo "Updating generated tile metadata ..."
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools \
mbtiles-tools meta-generate "$(MBTILES_LOCAL_FILE)" $(TILESET_FILE) --auto-minmax --show-ranges
.PHONY: generate-tiles-pg
generate-tiles-pg: all start-db
@echo "Generating tiles into $(MBTILES_LOCAL_FILE) (will delete if already exists) using PostGIS ST_MVT()..."
@rm -rf "$(MBTILES_LOCAL_FILE)"
# For some reason Ctrl+C doesn't work here without the -T. Must be pressed twice to stop.
$(DOCKER_COMPOSE) run -T $(DC_OPTS) openmaptiles-tools generate-tiles
@echo "Updating generated tile metadata ..."
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools \
mbtiles-tools meta-generate "$(MBTILES_LOCAL_FILE)" $(TILESET_FILE) --auto-minmax --show-ranges
.PHONY: data/tiles.txt
data/tiles.txt:
find ./data -name "*.tiles" -exec cat {} \; -exec rm {} \; | \
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools \
tile_multiplier $(MIN_ZOOM) $(MAX_ZOOM) >> data/tiles.txt
.PHONY: generate-changed-tiles
generate-changed-tiles: data/tiles.txt
# Re-generating updated tiles, if needed
if [ -s data/tiles.txt ] ; then \
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools refresh-views; \
$(DOCKER_COMPOSE) run $(DC_OPTS) -e LIST_FILE=data/tiles.txt openmaptiles-tools generate-tiles; \
rm data/tiles.txt; \
fi
docker-compose run $(DC_OPTS) openmaptiles-tools generate-metadata ./data/tiles.mbtiles
docker-compose run $(DC_OPTS) openmaptiles-tools chmod 666 ./data/tiles.mbtiles
.PHONY: start-tileserver
start-tileserver:
start-tileserver: init-dirs build-style download-fonts
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Download/refresh klokantech/tileserver-gl docker image"
@echo "* see documentation: https://github.com/klokantech/tileserver-gl"
@echo "* Download/refresh maptiler/tileserver-gl docker image"
@echo "* see documentation: https://github.com/maptiler/tileserver-gl"
@echo "* "
@echo "***********************************************************"
@echo " "
docker pull klokantech/tileserver-gl
$(DOCKER_COMPOSE_COMMAND) pull tileserver-gl
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Start klokantech/tileserver-gl "
@echo "* ----------------------------> check localhost:8080 "
@echo "* Start maptiler/tileserver-gl "
@echo "* ----------------------------> check $(OMT_HOST):$(TPORT) "
@echo "* "
@echo "***********************************************************"
@echo " "
docker run $(DC_OPTS) -it --name tileserver-gl -v $$(pwd)/data:/data -p 8080:80 klokantech/tileserver-gl
$(DOCKER_COMPOSE) up -d tileserver-gl
.PHONY: stop-tileserver
stop-tileserver:
$(DOCKER_COMPOSE) stop tileserver-gl
.PHONY: start-postserve
start-postserve: db-start
start-postserve: start-db
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Bring up postserve at localhost:8090"
@echo "* Bring up postserve at $(OMT_HOST):$(PPORT)"
@echo "* --> can view it locally (use make start-maputnik)"
@echo "* --> or can use https://maputnik.github.io/editor"
@echo "* "
@echo "* set data source / TileJSON URL to $(OMT_HOST):$(PPORT)"
@echo "* "
@echo "***********************************************************"
@echo " "
docker-compose up -d postserve
docker pull maputnik/editor
$(DOCKER_COMPOSE) up -d postserve
.PHONY: stop-postserve
stop-postserve:
$(DOCKER_COMPOSE) stop postserve
.PHONY: start-maputnik
start-maputnik: stop-maputnik start-postserve
@echo " "
@echo "***********************************************************"
@echo "* "
@echo "* Start maputnik/editor "
@echo "* ---> go to http://localhost:8088"
@echo "* ---> set 'data source' to http://localhost:8090"
@echo "* ---> go to $(OMT_HOST):8088 "
@echo "* ---> set data source / TileJSON URL to $(OMT_HOST):$(PPORT)"
@echo "* "
@echo "***********************************************************"
@echo " "
docker rm -f maputnik_editor || true
docker run $(DC_OPTS) --name maputnik_editor -d -p 8088:8888 maputnik/editor
$(DOCKER_COMPOSE) up -d maputnik_editor
.PHONY: generate-qareports
generate-qareports:
./qa/run.sh
.PHONY: stop-maputnik
stop-maputnik:
-$(DOCKER_COMPOSE) stop maputnik_editor
build/devdoc:
mkdir -p ./build/devdoc
layers = $(notdir $(wildcard layers/*)) # all layers
.PHONY: etl-graph
etl-graph:
@echo 'Use'
@echo ' make etl-graph-[layer] to generate etl graph for [layer]'
@echo ' example: make etl-graph-poi'
@echo 'Valid layers: $(layers)'
# generate etl graph for a certain layer, e.g. etl-graph-building, etl-graph-place
etl-graph-%: layers/% build/devdoc
docker-compose run $(DC_USER_OPTS) openmaptiles-tools generate-etlgraph layers/$*/$*.yaml ./build/devdoc
@$(COPY_TO_GIT) ./build/devdoc/etl_$*.png layers/$*/etl_diagram.png
mappingLayers = $(notdir $(patsubst %/mapping.yaml,%, $(wildcard layers/*/mapping.yaml))) # layers with mapping.yaml
# generate mapping graph for a certain layer, e.g. mapping-graph-building, mapping-graph-place
.PHONY: mapping-graph
mapping-graph:
@echo 'Use'
@echo ' make mapping-graph-[layer] to generate mapping graph for [layer]'
@echo ' example: make mapping-graph-poi'
@echo 'Valid layers: $(mappingLayers)'
mapping-graph-%: ./layers/%/mapping.yaml build/devdoc
docker-compose run $(DC_USER_OPTS) openmaptiles-tools generate-mapping-graph layers/$*/$*.yaml ./build/devdoc/mapping-diagram-$*
@$(COPY_TO_GIT) ./build/devdoc/mapping-diagram-$*.png layers/$*/mapping_diagram.png
# STAT_FUNCTION=frequency|toplength|variance
.PHONY: generate-qa
generate-qa: all start-db-nowait
@echo " "
@echo "e.g. make generate-qa STAT_FUNCTION=frequency LAYER=transportation ATTRIBUTE=class"
@echo " "
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools \
layer-stats $(STAT_FUNCTION) $(TILESET_FILE) $(LAYER) $(ATTRIBUTE) -m 0 -n 14 -v
# generate all etl and mapping graphs
generate-devdoc: $(addprefix etl-graph-,$(layers)) $(addprefix mapping-graph-,$(mappingLayers))
.PHONY: generate-devdoc
generate-devdoc: init-dirs
mkdir -p ./build/devdoc && \
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools sh -c \
'generate-etlgraph $(TILESET_FILE) $(GRAPH_PARAMS) && \
generate-mapping-graph $(TILESET_FILE) $(GRAPH_PARAMS)'
.PHONY: import-sql-dev
import-sql-dev:
docker-compose run $(DC_OPTS) openmaptiles-tools bash
.PHONY: bash
bash: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools bash
.PHONY: import-osm-dev
import-osm-dev:
docker-compose run $(DC_OPTS) import-osm /bin/bash
.PHONY: import-wikidata
import-wikidata: init-dirs
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools import-wikidata --cache /cache/wikidata-cache.json $(TILESET_FILE)
# the `download-geofabrik` error message mention `list`, if the area parameter is wrong. so I created a similar make command
.PHONY: list
list:
docker-compose run $(DC_OPTS) import-osm ./download-geofabrik-list.sh
.PHONY: reset-db-stats
reset-db-stats: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -P pager=off -c 'SELECT pg_stat_statements_reset();'
# same as a `make list`
.PHONY: download-geofabrik-list
download-geofabrik-list:
docker-compose run $(DC_OPTS) import-osm ./download-geofabrik-list.sh
.PHONY: list-views
list-views: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -A -F"," -P pager=off -P footer=off \
-c "select viewname from pg_views where schemaname='public' order by viewname;"
.PHONY: download-wikidata
download-wikidata:
mkdir -p wikidata && docker-compose run $(DC_OPTS) --entrypoint /usr/src/app/download-gz.sh import-wikidata
.PHONY: list-tables
list-tables: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -A -F"," -P pager=off -P footer=off \
-c "select tablename from pg_tables where schemaname='public' order by tablename;"
.PHONY: psql-list-tables
psql-list-tables:
docker-compose run $(DC_OPTS) import-osm ./psql.sh -P pager=off -c "\d+"
psql-list-tables: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -P pager=off -c "\d+"
.PHONY: psql-pg-stat-reset
psql-pg-stat-reset:
docker-compose run $(DC_OPTS) import-osm ./psql.sh -P pager=off -c 'SELECT pg_stat_statements_reset();'
.PHONY: forced-clean-sql
forced-clean-sql:
docker-compose run $(DC_OPTS) import-osm ./psql.sh -c "DROP SCHEMA IF EXISTS public CASCADE ; CREATE SCHEMA IF NOT EXISTS public; "
docker-compose run $(DC_OPTS) import-osm ./psql.sh -c "CREATE EXTENSION hstore; CREATE EXTENSION postgis; CREATE EXTENSION unaccent; CREATE EXTENSION fuzzystrmatch; CREATE EXTENSION osml10n; CREATE EXTENSION pg_stat_statements;"
docker-compose run $(DC_OPTS) import-osm ./psql.sh -c "GRANT ALL ON SCHEMA public TO public;COMMENT ON SCHEMA public IS 'standard public schema';"
.PHONY: pgclimb-list-views
pgclimb-list-views:
docker-compose run $(DC_OPTS) import-osm ./pgclimb.sh -c "select schemaname,viewname from pg_views where schemaname='public' order by viewname;" csv
.PHONY: pgclimb-list-tables
pgclimb-list-tables:
docker-compose run $(DC_OPTS) import-osm ./pgclimb.sh -c "select schemaname,tablename from pg_tables where schemaname='public' order by tablename;" csv
.PHONY: psql-vacuum-analyze
psql-vacuum-analyze:
.PHONY: vacuum-db
vacuum-db: init-dirs
@echo "Start - postgresql: VACUUM ANALYZE VERBOSE;"
docker-compose run $(DC_OPTS) import-osm ./psql.sh -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: psql-analyze
psql-analyze:
@echo "Start - postgresql: ANALYZE VERBOSE ;"
docker-compose run $(DC_OPTS) import-osm ./psql.sh -P pager=off -c 'ANALYZE VERBOSE;'
.PHONY: analyze-db
analyze-db: init-dirs
@echo "Start - postgresql: ANALYZE VERBOSE;"
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools psql.sh -v ON_ERROR_STOP=1 -P pager=off -c 'ANALYZE VERBOSE;'
.PHONY: list-docker-images
list-docker-images:
docker images | grep openmaptiles
.PHONY: refresh-docker-images
refresh-docker-images:
docker-compose pull --ignore-pull-failures
refresh-docker-images: init-dirs
ifneq ($(NO_REFRESH),)
@echo "Skipping docker image refresh"
else
@echo ""
@echo "Refreshing docker images... Use NO_REFRESH=1 to skip."
ifneq ($(USE_PRELOADED_IMAGE),)
POSTGIS_IMAGE=openmaptiles/postgis-preloaded \
$(DOCKER_COMPOSE_COMMAND) pull --ignore-pull-failures $(QUIET_FLAG) openmaptiles-tools generate-vectortiles postgres
else
$(DOCKER_COMPOSE_COMMAND) pull --ignore-pull-failures $(QUIET_FLAG) openmaptiles-tools generate-vectortiles postgres import-data
endif
endif
.PHONY: remove-docker-images
remove-docker-images:
@echo "Deleting all openmaptiles related docker image(s)..."
@docker-compose down
@docker images | grep "openmaptiles" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
@docker images | grep "osm2vectortiles/mapbox-studio" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
@docker images | grep "klokantech/tileserver-gl" | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi -f
@$(DOCKER_COMPOSE) down
@docker images "openmaptiles/*" -q | $(XARGS) docker rmi -f
@docker images "maputnik/editor" -q | $(XARGS) docker rmi -f
@docker images "maptiler/tileserver-gl" -q | $(XARGS) docker rmi -f
.PHONY: docker-unnecessary-clean
docker-unnecessary-clean:
.PHONY: clean-unnecessary-docker
clean-unnecessary-docker:
@echo "Deleting unnecessary container(s)..."
@docker ps -a | grep Exited | awk -F" " '{print $$1}' | xargs --no-run-if-empty docker rm
@docker ps -a -q --filter "status=exited" | $(XARGS) docker rm
@echo "Deleting unnecessary image(s)..."
@docker images | grep \<none\> | awk -F" " '{print $$3}' | xargs --no-run-if-empty docker rmi
@docker images | awk -F" " '/<none>/{print $$3}' | $(XARGS) docker rmi
.PHONY: test-perf-null
test-perf-null: init-dirs
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools test-perf $(TILESET_FILE) --test null --no-color
.PHONY: build-test-pbf
build-test-pbf: init-dirs
$(DOCKER_COMPOSE_COMMAND) run $(DC_OPTS) openmaptiles-tools /tileset/.github/workflows/build-test-data.sh
.PHONY: debug
debug: ## Use this target when developing Makefile itself to verify loaded environment variables
@$(assert_area_is_given)
@echo file_exists = $(wildcard $(AREA_BBOX_FILE))
@echo AREA_BBOX_FILE = $(AREA_BBOX_FILE) , $$AREA_ENV_FILE
@echo BBOX = $(BBOX) , $$BBOX
@echo MIN_ZOOM = $(MIN_ZOOM) , $$MIN_ZOOM
@echo MAX_ZOOM = $(MAX_ZOOM) , $$MAX_ZOOM
build/import-tests.osm.pbf: init-dirs
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'osmconvert tests/import/*.osm -o=build/import-tests.osm.pbf'
data/changes.state.txt:
cp -f tests/changes.state.txt data/
data/last.state.txt:
cp -f tests/last.state.txt data/
data/changes.repl.json:
cp -f tests/changes.repl.json data/
data/changes.osc.gz: init-dirs
@echo " UPDATE unit test data..."
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'osmconvert tests/update/*.osc --merge-versions -o=data/changes.osc && gzip -f data/changes.osc'
test-sql: clean refresh-docker-images destroy-db start-db-nowait build/import-tests.osm.pbf data/changes.state.txt data/last.state.txt data/changes.repl.json build/mapping.yaml data/changes.osc.gz build/openmaptiles.tm2source/data.yml build/mapping.yaml build-sql
$(eval area := changes)
@echo "Load IMPORT test data"
sed -ir "s/^[#]*\s*MAX_ZOOM=.*/MAX_ZOOM=14/" .env
sed -ir "s/^[#]*\s*DIFF_MODE=.*/DIFF_MODE=false/" .env
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && import-osm build/import-tests.osm.pbf'
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) import-data
@echo "Apply OpenMapTiles SQL schema to test data @ Zoom 14..."
$(DOCKER_COMPOSE) run $(DC_OPTS) openmaptiles-tools sh -c 'pgwait && import-sql' | \
awk -v s=": WARNING:" '1{print; fflush()} $$0~s{print "\n*** WARNING detected, aborting"; exit(1)}' | \
awk '1{print; fflush()} $$0~".*ERROR" {txt=$$0} END{ if(txt){print "\n*** ERROR detected, aborting:"; print txt; exit(1)} }'
@echo "Test SQL output for Import Test Data"
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && psql.sh < tests/test-post-import.sql' 2>&1 | \
awk -v s="ERROR:" '1{print; fflush()} $$0~s{print "*** ERROR detected, aborting"; exit(1)}'
@echo "Run UPDATE process on test data..."
sed -ir "s/^[#]*\s*DIFF_MODE=.*/DIFF_MODE=true/" .env
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && import-diff'
@echo "Test SQL output for Update Test Data"
$(DOCKER_COMPOSE) $(DC_CONFIG_CACHE) run $(DC_OPTS_CACHE) openmaptiles-tools sh -c 'pgwait && psql.sh < tests/test-post-update.sql' 2>&1 | \
awk -v s="ERROR:" '1{print; fflush()} $$0~s{print "*** ERROR detected, aborting"; exit(1)}'

Wyświetl plik

@ -2,7 +2,7 @@
### Req:
* CPU: AMD64 ( = Intel 64 bit)
* The base docker debian images are x86_64 based, so the ARM,MIPS currently not supported!
* 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.
@ -59,7 +59,7 @@ If you have problems with the quickstart
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`
* 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" ]
@ -363,12 +363,13 @@ This is generating `.mbtiles` for your area : [ MIN_ZOOM: "0" - MAX_ZOOM: "7"
./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 inside/
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 my.osm.pbf data/
./quickstart.sh my
mv mydata.osm.pbf data/
make generate-bbox-file area=mydata
./quickstart.sh mydata
```
### Check postserve
@ -384,20 +385,26 @@ and the generated maps are going to be available in webbrowser on [localhost:808
This is only a quick preview, because your mbtiles only generated to zoom level 7 !
### Change MIN_ZOOM and MAX_ZOOM
### Set which zooms to generate
modify the settings in the `.env` file, the defaults :
* QUICKSTART_MIN_ZOOM=0
* QUICKSTART_MAX_ZOOM=7
and re-start `./quickstart.sh `
* the new config file re-generating to here ./data/docker-compose-config.yml
* Known problems:
* If you use same area - then the ./data/docker-compose-config.yml not re-generating, so you have to modify by hand!
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
* 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
@ -408,36 +415,63 @@ the current output:
```
==============================================================================
OpenMapTiles https://github.com/openmaptiles/openmaptiles
OpenMapTiles https://github.com/openmaptiles/openmaptiles
Hints for testing areas
make download-geofabrik-list # list actual geofabrik OSM extracts for download -> <<your-area>>
make list # list actual geofabrik OSM extracts for download -> <<your-area>>
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-postserve # start Postserver + Maputnik Editor [ see localhost:8088 ]
make start-tileserver # start klokantech/tileserver-gl [ see localhost:8080 ]
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 download-geofabrik area=albania # download OSM data from geofabrik, and create config file
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 psql-vacuum-analyze # PostgreSQL: VACUUM ANALYZE
make psql-analyze # PostgreSQL: ANALYZE
make generate-qareports # generate reports [./build/qareports]
make generate-devdoc # generate devdoc [./build/devdoc]
make import-sql-dev # start import-sql /bin/bash terminal
make import-osm-dev # start import-osm /bin/bash terminal (imposm3)
make clean-docker # remove docker containers, PG data volume
make forced-clean-sql # drop all PostgreSQL tables for clean environment
make docker-unnecessary-clean # clean unnecessary docker image(s) and container(s)
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 pgclimb-list-views # list PostgreSQL public schema views
make pgclimb-list-tables # list PostgreSQL public schema tables
cat .env # list PG database and MIN_ZOOM and MAX_ZOOM information
cat ./quickstart.log # backup of the last ./quickstart.sh
make help # help about available commands
make list-docker-images # show a list of available docker images
==============================================================================
```

104
README.md
Wyświetl plik

@ -1,6 +1,6 @@
## OpenMapTiles [![Build Status](https://travis-ci.org/openmaptiles/openmaptiles.svg?branch=master)](https://travis-ci.org/openmaptiles/openmaptiles)
## OpenMapTiles [![Build Status](https://github.com/openmaptiles/openmaptiles/workflows/OpenMapTiles%20Integrity%20CI/badge.svg?branch=master)](https://github.com/openmaptiles/openmaptiles/actions)
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 [openmaptiles.com](https://openmaptiles.com/).
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.
@ -8,10 +8,11 @@ Please keep in mind that OpenMapTiles schema should display general topographic
- :link: Schema https://openmaptiles.org/schema
- :link: Docs https://openmaptiles.org/docs
- :link: Production package: https://openmaptiles.com/production-package/
- :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: Discuss at the #openmaptiles channel at [OSM Slack](https://osmus-slack.herokuapp.com/)
- :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
@ -20,14 +21,15 @@ 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)
- [Klokantech Basic](https://github.com/openmaptiles/klokantech-basic-gl-style)
- [Klokantech 3D](https://github.com/openmaptiles/klokantech-3d-gl-style)
- [Fiord Color](https://github.com/openmaptiles/fiord-color-gl-style)
- [Toner](https://github.com/openmaptiles/toner-gl-style)
- [OSM Liberty](https://github.com/maputnik/osm-liberty)
We also ported over our favorite old raster styles (TM2).
@ -71,6 +73,10 @@ 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.
@ -83,10 +89,10 @@ make
```
You can execute the following manual steps (for better understanding)
or use the provided `quickstart.sh` script.
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
./quickstart.sh <area>
```
### Prepare the Database
@ -94,43 +100,44 @@ or use the provided `quickstart.sh` script.
Now start up the database container.
```bash
docker-compose up -d postgres
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/lukasmartinelli/osm-lakelines).
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
docker-compose run import-water
docker-compose run import-natural-earth
docker-compose run import-lakelines
docker-compose run import-osmborder
make import-data
```
**[Optional]**
Import latest 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.
Beware that current [Wikidata dump](https://dumps.wikimedia.org/wikidatawiki/entities/latest-all.json.gz) is more than 55GB, it takes time to download and import it. If you just want to have a quickstart on OpenMapTiles, just skip this step.
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-wikidata
docker-compose run import-wikidata
make download area=albania
```
[Download OpenStreetMap data extracts](http://download.geofabrik.de/) and store the PBF file in the `./data` directory.
[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
cd data
wget http://download.geofabrik.de/europe/albania-latest.osm.pbf
make import-osm
```
[Import OpenStreetMap data](https://github.com/openmaptiles/openmaptiles-tools/tree/master/docker/import-osm) with the mapping rules from
`build/mapping.yaml` (which has been created by `make`).
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
docker-compose run import-osm
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`.
@ -140,18 +147,47 @@ make
make import-sql
```
Now you are ready to **generate the vector tiles**. Using environment variables
you can limit the bounding box and zoom levels of what you want to generate (`docker-compose.yml`).
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.
```
docker-compose run generate-vectortiles
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) and the cartography decisions encoded in the schema and SQL are licensed under [CC-BY](./LICENSE.md).
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.
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:

18
TESTING.md 100644
Wyświetl plik

@ -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.

104
UPDATE.md
Wyświetl plik

@ -1,38 +1,116 @@
# Keep the vector tiles updated
# 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 OSM change feed
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 the new imposm3 feature to keep the database updated (thanks to the [work by @stirringhalo](https://github.com/openmaptiles/openmaptiles/pull/131)). This will automatically download
the OSM change feed and import it into the database.
After each run you should also have a list of tiles that have 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 run update-osm
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
Given you have a file `changes.osc.gz` in your import folder. Once you ran the import command you should also have a list of tiles that have updated.
You may perform a one-time import of OSM changes from the `changes.osc.gz` file in your import folder using
```
docker-compose run import-osm-diff
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
After the import has finished **imposm3** will store a list of tiles in text format in the `diffdir`.
Copy the as `tiles.txt` to the import folder.
Now run the command to read the tilelist and write the vector tiles for it to a new MBTiles.
To generate all changed tiles, based on the lists of all updated tiles, and update the existing MBtiles file, please use
```
docker-compose run generate-changed-vectortiles
make generate-changed-tiles
```

Wyświetl plik

@ -0,0 +1,11 @@
# This version must match the MAKE_DC_VERSION in docker-compose.yml
version: "3"
volumes:
cache:
services:
openmaptiles-tools:
volumes:
- cache:/cache

Wyświetl plik

@ -1,99 +1,76 @@
version: "2"
# This version must match the MAKE_DC_VERSION value below
version: "3"
volumes:
pgdata:
cache:
services:
networks:
postgres:
image: "openmaptiles/postgis:${TOOLS_VERSION}"
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
# Use "shm_size: 512m" if you want to prevent a possible 'No space left on device' during 'make generate-tiles-pg'
volumes:
- pgdata:/var/lib/postgresql/data
networks:
- postgres_conn
- postgres
ports:
- "5432"
env_file: .env
import-natural-earth:
image: "openmaptiles/import-natural-earth:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres_conn
import-water:
image: "openmaptiles/import-water:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres_conn
import-lakelines:
image: "openmaptiles/import-lakelines:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres_conn
import-osm:
image: "openmaptiles/import-osm:${TOOLS_VERSION}"
- "${PGPORT:-5432}:${PGPORT:-5432}"
env_file: .env
environment:
DIFF_MODE: ${DIFF_MODE}
networks:
- postgres_conn
volumes:
- ./data:/import
- ./build:/mapping
- cache:/cache
import-osmborder:
image: "openmaptiles/import-osmborder:${TOOLS_VERSION}"
# postgress container uses old variable names
POSTGRES_DB: ${PGDATABASE:-openmaptiles}
POSTGRES_USER: ${PGUSER:-openmaptiles}
POSTGRES_PASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
import-data:
image: "openmaptiles/import-data:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres_conn
import-osm-diff:
image: "openmaptiles/import-osm:${TOOLS_VERSION}"
- postgres
openmaptiles-tools: &openmaptiles-tools
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
env_file: .env
command: ./import_diff.sh
environment:
# Must match the version of this file (first line)
# download-osm will use it when generating a composer file
MAKE_DC_VERSION: "3"
# Allow DIFF_MODE, MIN_ZOOM, and MAX_ZOOM to be overwritten from shell
DIFF_MODE: ${DIFF_MODE}
MIN_ZOOM: ${MIN_ZOOM}
MAX_ZOOM: ${MAX_ZOOM}
#Provide BBOX from *.bbox file if exists, else from .env
BBOX: ${BBOX}
# Imposm configuration file describes how to load updates when enabled
IMPOSM_CONFIG_FILE: ${IMPOSM_CONFIG_FILE}
# Control import-sql processes
MAX_PARALLEL_PSQL: ${MAX_PARALLEL_PSQL}
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
MBTILES_FILE: ${MBTILES_FILE}
networks:
- postgres_conn
- postgres
volumes:
- .:/tileset
- ./data:/import
- ./data:/export
- ./build/sql:/sql
- ./build:/mapping
- cache:/cache
- ./cache:/cache
- ./style:/style
update-osm:
image: "openmaptiles/import-osm:${TOOLS_VERSION}"
env_file: .env
environment:
DIFF_MODE: ${DIFF_MODE}
command: ./import_update.sh
networks:
- postgres_conn
volumes:
- ./data:/import
- ./build:/mapping
- cache:/cache
import-sql:
# This target is obsolete, and was left for backwards compatibility
# Use openmaptiles-tools target instead
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
command: import-sql
env_file: .env
networks:
- postgres_conn
volumes:
- .:/tileset
- ./build:/sql
import-wikidata:
image: "openmaptiles/import-wikidata:${TOOLS_VERSION}"
env_file: .env
command: import-wikidata
networks:
- postgres_conn
volumes:
- ./wikidata:/import
openmaptiles-tools:
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
env_file: .env
networks:
- postgres_conn
volumes:
- .:/tileset
- ./build:/sql
<<: *openmaptiles-tools
command: import-update
generate-changed-vectortiles:
image: "openmaptiles/generate-vectortiles:${TOOLS_VERSION}"
command: ./export-list.sh
@ -101,31 +78,66 @@ services:
- ./data:/export
- ./build/openmaptiles.tm2source:/tm2source
networks:
- postgres_conn
- postgres
env_file: .env
environment:
MBTILES_NAME: ${MBTILES_FILE}
# Control tilelive-copy threads
COPY_CONCURRENCY: ${COPY_CONCURRENCY}
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
generate-vectortiles:
image: "openmaptiles/generate-vectortiles:${TOOLS_VERSION}"
volumes:
- ./data:/export
- ./build/openmaptiles.tm2source:/tm2source
networks:
- postgres_conn
- postgres
env_file: .env
environment:
MBTILES_NAME: ${MBTILES_FILE}
BBOX: ${BBOX}
MIN_ZOOM: ${MIN_ZOOM}
MAX_ZOOM: ${MAX_ZOOM}
# Control tilelive-copy threads
COPY_CONCURRENCY: ${COPY_CONCURRENCY}
#
PGDATABASE: ${PGDATABASE:-openmaptiles}
PGUSER: ${PGUSER:-openmaptiles}
PGPASSWORD: ${PGPASSWORD:-openmaptiles}
PGPORT: ${PGPORT:-5432}
postserve:
image: "openmaptiles/openmaptiles-tools:${TOOLS_VERSION}"
command: postserve openmaptiles.yaml --verbose
command: "postserve ${TILESET_FILE} --verbose --serve=${OMT_HOST:-http://localhost}:${PPORT:-8090}"
env_file: .env
environment:
TILESET_FILE: ${TILESET_FILE}
networks:
- postgres_conn
- postgres
ports:
- "8090:8090"
- "${PPORT:-8090}:${PPORT:-8090}"
volumes:
- .:/tileset
networks:
postgres_conn:
driver: bridge
maputnik_editor:
image: "maputnik/editor"
ports:
- "8088:8888"
tileserver-gl:
image: "maptiler/tileserver-gl:latest"
command:
- --port
- "${TPORT:-8080}"
- --config
- "/style/config.json"
ports:
- "${TPORT:-8080}:${TPORT:-8080}"
volumes:
- ./data:/data
- ./style:/style
- ./build:/build

37
integrity.sh 100755
Wyświetl plik

@ -0,0 +1,37 @@
#!/bin/sh
# A script to run the "integrity" continuous integration script.
area=monaco
echo MIN_ZOOM=0 >> .env
echo MAX_ZOOM=14 >> .env
./quickstart.sh $area
export TEST_MODE=yes
make generate-devdoc
area=europe/monaco
echo DIFF_MODE=true >> .env
# Cleanup
rm -fr data build cache
# Create data/$area.repl.json
make download-geofabrik area=$area
# Download 2+ month old data
export old_date=$(date --date="$(date +%Y-%m-15) -2 month" +'%y%m01')
echo Downloading $old_date extract of $area
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "wget -O data/$area.osm.pbf http://download.geofabrik.de/$area-$old_date.osm.pbf"
# Initial import and tile generation
./quickstart.sh $area
sleep 2
echo Downloading updates
# Loop to recover from potential "ERROR 429: Too Many Requests"
docker-compose run --rm --user=$(id -u):$(id -g) openmaptiles-tools sh -c "
while ! osmupdate --keep-tempfiles --base-url=$(sed -n 's/ *\"replication_url\": //p' data/$area.repl.json) data/$area.osm.pbf data/changes.osc.gz ; do
sleep 2;
echo Sleeping...;
sleep 630;
done"
echo Downloading updates completed
echo Importing updates
make import-diff
echo Generating new tiles
make generate-tiles-pg

Wyświetl plik

@ -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;

Wyświetl plik

@ -1,13 +1,13 @@
layer:
id: "aerodrome_label"
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.
name_en: English name `name:en` if available, otherwise `name`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`.
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.
@ -15,25 +15,36 @@ layer:
[`aerodrome`](http://wiki.openstreetmap.org/wiki/Proposed_features/Aerodrome)
and `aerodrome:type` tags.
values:
- international
- public
- regional
- military
- private
- other
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: osm_id
key_field: id
key_field_as_attribute: no
srid: 900913
query: (SELECT osm_id, geometry, name, name_en, name_de, {name_languages}, class, iata, icao, ele, ele_ft FROM layer_aerodrome_label (!bbox!, z(!scale_denominator!), !pixel_width!)) AS t
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.sql
- ./layer.sql
- ./update_aerodrome_label_point.sql
- ./aerodrome_label.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 17 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 21 KiB

Wyświetl plik

@ -1,60 +0,0 @@
-- etldoc: layer_aerodrome_label[shape=record fillcolor=lightpink, style="rounded,filled", label="layer_aerodrome_label | <z10_> z10+" ] ;
CREATE OR REPLACE FUNCTION layer_aerodrome_label(
bbox geometry,
zoom_level integer,
pixel_width numeric)
RETURNS TABLE(
osm_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
$$
-- etldoc: osm_aerodrome_label_point -> layer_aerodrome_label:z10_
SELECT
osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
CASE
WHEN aerodrome = 'international'
OR aerodrome_type = 'international'
THEN 'international'
WHEN
aerodrome = 'public'
OR aerodrome_type LIKE '%public%'
OR aerodrome_type = 'civil'
THEN 'public'
WHEN
aerodrome = 'regional'
OR aerodrome_type = 'regional'
THEN 'regional'
WHEN
aerodrome = 'military'
OR aerodrome_type LIKE '%military%'
OR military = 'airfield'
THEN 'military'
WHEN
aerodrome = 'private'
OR aerodrome_type = 'private'
THEN 'private'
ELSE 'other'
END 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 IMMUTABLE;

Wyświetl plik

@ -3,7 +3,7 @@ tables:
# etldoc: imposm3 -> osm_aerodrome_label_point
aerodrome_label_point:
type: geometry
fields:
columns:
- name: osm_id
type: id
- name: geometry

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 10 KiB

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -1,51 +0,0 @@
DROP TRIGGER IF EXISTS trigger_flag ON osm_aerodrome_label_point;
DROP TRIGGER IF EXISTS trigger_refresh ON aerodrome_label.updates;
-- etldoc: osm_aerodrome_label_point -> osm_aerodrome_label_point
CREATE OR REPLACE FUNCTION update_aerodrome_label_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_aerodrome_label_point
SET geometry = ST_Centroid(geometry)
WHERE ST_GeometryType(geometry) <> 'ST_Point';
UPDATE osm_aerodrome_label_point
SET tags = update_tags(tags, geometry)
WHERE COALESCE(tags->'name:latin', tags->'name:nonlatin', tags->'name_int') IS NULL;
END;
$$ LANGUAGE plpgsql;
SELECT update_aerodrome_label_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS aerodrome_label;
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
$BODY$
BEGIN
RAISE LOG 'Refresh aerodrome_label';
PERFORM update_aerodrome_label_point();
DELETE FROM aerodrome_label.updates;
RETURN null;
END;
$BODY$
language plpgsql;
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE 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();

Wyświetl plik

@ -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();

Wyświetl plik

@ -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;

Wyświetl plik

@ -19,11 +19,12 @@ layer:
- helipad
- taxiway
- apron
- gate
datasource:
geometry_field: geometry
query: (SELECT geometry, ref, class FROM layer_aeroway(!bbox!, z(!scale_denominator!))) AS t
schema:
- ./layer.sql
- ./aeroway.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 105 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 165 KiB

Wyświetl plik

@ -1,43 +0,0 @@
-- 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_gen3 -> layer_aeroway:z10
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen3 WHERE zoom_level = 10
UNION ALL
-- etldoc: osm_aeroway_linestring_gen2 -> layer_aeroway:z11
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen2 WHERE zoom_level = 11
UNION ALL
-- etldoc: osm_aeroway_linestring_gen1 -> layer_aeroway:z12
SELECT geometry, aeroway, ref
FROM osm_aeroway_linestring_gen1 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_gen3 -> layer_aeroway:z10
-- etldoc: osm_aeroway_polygon_gen3 -> layer_aeroway:z11
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen3 WHERE zoom_level BETWEEN 10 AND 11
UNION ALL
-- etldoc: osm_aeroway_polygon_gen2 -> layer_aeroway:z12
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen2 WHERE zoom_level = 12
UNION ALL
-- etldoc: osm_aeroway_polygon_gen1 -> layer_aeroway:z13
SELECT geometry, aeroway, ref
FROM osm_aeroway_polygon_gen1 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
) AS zoom_levels
WHERE geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -1,34 +1,40 @@
generalized_tables:
# etldoc: imposm3 -> osm_aeroway_linestring_gen3
aeroway_linestring_gen3:
source: aeroway_linestring_gen2
# etldoc: osm_aeroway_linestring_gen_z11 -> osm_aeroway_linestring_gen_z10
aeroway_linestring_gen_z10:
source: aeroway_linestring_gen_z11
tolerance: ZRES11
# etldoc: imposm3 -> osm_aeroway_linestring_gen2
aeroway_linestring_gen2:
source: aeroway_linestring_gen1
# etldoc: osm_aeroway_linestring_gen_z12 -> osm_aeroway_linestring_gen_z11
aeroway_linestring_gen_z11:
source: aeroway_linestring_gen_z12
tolerance: ZRES12
# etldoc: imposm3 -> osm_aeroway_linestring_gen1
aeroway_linestring_gen1:
# etldoc: osm_aeroway_linestring -> osm_aeroway_linestring_gen_z12
aeroway_linestring_gen_z12:
source: aeroway_linestring
sql_filter: ST_IsValid(geometry)
tolerance: ZRES13
# etldoc: imposm3 -> osm_aeroway_polygon_gen3
aeroway_polygon_gen3:
source: aeroway_polygon_gen2
# 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: imposm3 -> osm_aeroway_polygon_gen2
aeroway_polygon_gen2:
source: aeroway_polygon_gen1
# 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: imposm3 -> osm_aeroway_polygon_gen1
aeroway_polygon_gen1:
# 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
@ -50,7 +56,7 @@ tables:
# etldoc: imposm3 -> osm_aeroway_polygon
aeroway_polygon:
type: polygon
fields:
columns:
- *ref
- name: osm_id
type: id
@ -67,7 +73,7 @@ tables:
# etldoc: imposm3 -> osm_aeroway_linestring
aeroway_linestring:
type: linestring
fields:
columns:
- *ref
- name: osm_id
type: id
@ -80,3 +86,19 @@ tables:
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

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 31 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 32 KiB

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -1,19 +1,35 @@
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.
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.
@ -46,8 +62,10 @@ layer:
buffer_size: 4
datasource:
geometry_field: geometry
query: (SELECT geometry, admin_level, disputed, disputed_name, claimed_by, maritime FROM layer_boundary(!bbox!, z(!scale_denominator!))) AS t
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

Wyświetl plik

@ -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);

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 457 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 750 KiB

Wyświetl plik

@ -1,95 +1,95 @@
generalized_tables:
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen11
border_disp_linestring_gen11:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 9600
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen10
border_disp_linestring_gen10:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 4800
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen9
border_disp_linestring_gen9:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 2400
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen8
border_disp_linestring_gen8:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 1200
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen7
border_disp_linestring_gen7:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 600
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen6
border_disp_linestring_gen6:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 300
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen5
border_disp_linestring_gen5:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 160
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen4
border_disp_linestring_gen4:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 80
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen3
border_disp_linestring_gen3:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 40
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen2
border_disp_linestring_gen2:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 20
# etldoc: osm_border_disp_linestring -> osm_border_disp_linestring_gen1
border_disp_linestring_gen1:
source: border_disp_linestring
sql_filter: admin_level = 2
tolerance: 10
# etldoc: osm_border_disp_relation -> osm_border_disp_linestring
# etldoc: osm_border_linestring -> osm_border_disp_linestring
border_disp_linestring:
source: border_disp_relation
sql_filter: ST_GeometryType(geometry) = 'ST_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_disp_relation
border_disp_relation:
# etldoc: imposm3 -> osm_border_linestring
border_linestring:
type: relation_member
fields:
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
- key: boundary
name: boundary
type: string
# Used for disputed boundary, e.g. "Line of actual control"
from_member: true
- key: admin_level
name: admin_level
type: integer
@ -99,15 +99,62 @@ tables:
- 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:
type: [boundary]
boundary:
- administrative
border_status:
- dispute
boundary_type:
- maritime
# etldoc: imposm3 -> osm_boundary_polygon
boundary_polygon:
type: polygon
filters:
require:
#admin_level: ['2']
admin_level: [__any__]
claimed_by: [__any__]
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

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 4.4 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 22 KiB

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -0,0 +1,221 @@
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;
DROP TRIGGER IF EXISTS trigger_flag ON osm_boundary_polygon;
DROP TRIGGER IF EXISTS trigger_refresh ON boundary_polygon.updates;
-- 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 SCHEMA IF NOT EXISTS boundary_polygon;
CREATE TABLE IF NOT EXISTS boundary_polygon.updates
(
id serial PRIMARY KEY,
t text,
UNIQUE (t)
);
CREATE OR REPLACE FUNCTION boundary_polygon.flag() RETURNS trigger AS
$$
BEGIN
INSERT INTO boundary_polygon.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION boundary_polygon.refresh() RETURNS trigger AS
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh boundary_polygon';
-- Analyze tracking and source tables before performing update
ANALYZE osm_boundary_polygon_gen_z5;
REFRESH MATERIALIZED VIEW osm_boundary_polygon_gen_z5;
-- noinspection SqlWithoutWhere
DELETE FROM boundary_polygon.updates;
RAISE LOG 'Refresh boundary_polygon done in %', age(clock_timestamp(), t);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
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();
CREATE TRIGGER trigger_flag
AFTER INSERT OR UPDATE OR DELETE
ON osm_boundary_polygon
FOR EACH STATEMENT
EXECUTE PROCEDURE boundary_polygon.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT
ON boundary_polygon.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE boundary_polygon.refresh();

Wyświetl plik

@ -1,145 +1,120 @@
-- etldoc: layer_building[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_building | <z13> z13 | <z14_> z14+ " ] ;
CREATE OR REPLACE FUNCTION as_numeric(text) RETURNS NUMERIC AS $$
-- Inspired by http://stackoverflow.com/questions/16195986/isnumeric-with-postgresql/16206123#16206123
DECLARE test NUMERIC;
BEGIN
test = $1::NUMERIC;
RETURN test;
EXCEPTION WHEN others THEN
RETURN -1;
END;
$$ STRICT
LANGUAGE plpgsql IMMUTABLE;
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 INDEX IF NOT EXISTS osm_building_relation_building_idx ON osm_building_relation(building) WHERE ST_GeometryType(geometry) = 'ST_Polygon';
CREATE INDEX IF NOT EXISTS osm_building_relation_member_idx ON osm_building_relation(member);
--CREATE INDEX IF NOT EXISTS osm_building_associatedstreet_role_idx ON osm_building_associatedstreet(role) WHERE ST_GeometryType(geometry) = 'ST_Polygon';
--CREATE INDEX IF NOT EXISTS osm_building_street_role_idx ON osm_building_street(role) WHERE ST_GeometryType(geometry) = 'ST_Polygon';
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
FROM osm_building_relation
WHERE building = ''
AND ST_GeometryType(geometry) = 'ST_Polygon'
UNION ALL
CREATE OR REPLACE VIEW osm_all_buildings AS (
-- etldoc: osm_building_relation -> layer_building:z14_
-- Buildings built from relations
SELECT member AS osm_id,geometry,
COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height,
COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height,
COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels,
COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level,
nullif(material, '') AS material,
nullif(colour, '') AS colour,
FALSE as hide_3d
FROM
osm_building_relation WHERE building = '' AND ST_GeometryType(geometry) = 'ST_Polygon'
UNION ALL
-- etldoc: osm_building_associatedstreet -> layer_building:z14_
-- Buildings in associatedstreet relations
SELECT member AS osm_id,geometry,
COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height,
COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height,
COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels,
COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level,
nullif(material, '') AS material,
nullif(colour, '') AS colour,
FALSE as hide_3d
FROM
osm_building_associatedstreet WHERE role = 'house' AND ST_GeometryType(geometry) = 'ST_Polygon'
UNION ALL
-- etldoc: osm_building_street -> layer_building:z14_
-- Buildings in street relations
SELECT member AS osm_id,geometry,
COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height,
COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height,
COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels,
COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level,
nullif(material, '') AS material,
nullif(colour, '') AS colour,
FALSE as hide_3d
FROM
osm_building_street WHERE role = 'house' AND ST_GeometryType(geometry) = 'ST_Polygon'
UNION ALL
-- etldoc: osm_building_multipolygon -> layer_building:z14_
-- Buildings that are inner/outer
SELECT osm_id,geometry,
COALESCE(nullif(as_numeric(height),-1),nullif(as_numeric(buildingheight),-1)) as height,
COALESCE(nullif(as_numeric(min_height),-1),nullif(as_numeric(buildingmin_height),-1)) as min_height,
COALESCE(nullif(as_numeric(levels),-1),nullif(as_numeric(buildinglevels),-1)) as levels,
COALESCE(nullif(as_numeric(min_level),-1),nullif(as_numeric(buildingmin_level),-1)) as min_level,
nullif(material, '') AS material,
nullif(colour, '') AS colour,
FALSE as hide_3d
FROM
osm_building_polygon obp WHERE EXISTS (SELECT 1 FROM osm_building_multipolygon obm WHERE obp.osm_id = obm.osm_id)
UNION ALL
-- etldoc: osm_building_polygon -> layer_building:z14_
-- Standalone buildings
SELECT obp.osm_id,obp.geometry,
COALESCE(nullif(as_numeric(obp.height),-1),nullif(as_numeric(obp.buildingheight),-1)) as height,
COALESCE(nullif(as_numeric(obp.min_height),-1),nullif(as_numeric(obp.buildingmin_height),-1)) as min_height,
COALESCE(nullif(as_numeric(obp.levels),-1),nullif(as_numeric(obp.buildinglevels),-1)) as levels,
COALESCE(nullif(as_numeric(obp.min_level),-1),nullif(as_numeric(obp.buildingmin_level),-1)) as min_level,
nullif(obp.material, '') AS material,
nullif(obp.colour, '') AS colour,
CASE WHEN obr.role='outline' THEN TRUE ELSE FALSE END as hide_3d
FROM
osm_building_polygon obp
LEFT JOIN osm_building_relation obr ON (obr.member = obp.osm_id)
WHERE obp.osm_id >= 0
);
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
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) AS $$
SELECT geometry, osm_id, render_height, render_min_height,
RETURNS TABLE
(
geometry geometry,
osm_id bigint,
render_height int,
render_min_height int,
colour text,
hide_3d boolean
)
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 ELSE NULL::boolean END AS hide_3d
FROM (
-- etldoc: osm_building_polygon_gen1 -> layer_building:z13
SELECT
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
FROM osm_building_polygon_gen1
WHERE zoom_level = 13 AND geometry && bbox
UNION ALL
-- etldoc: osm_building_polygon -> layer_building:z14_
SELECT 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
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 IMMUTABLE;
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
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
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
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

Wyświetl plik

@ -1,22 +1,27 @@
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)). The buildings are not yet ready for 3D rendering support and any help to improve
this is welcomed.
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:
query: (SELECT geometry, render_height, render_min_height, colour, hide_3d FROM layer_building(!bbox!, z(!scale_denominator!))) AS t
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 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 after the method of Paul Norman in [OSM Clear](https://github.com/ClearTables/osm-clear). For future 3D rendering of buildings.
An approximated height from levels and height of the building or building:part.
render_min_height: |
An approximated height from levels and height of the bottom of the building or building:part after the method of Paul Norman in [OSM Clear](https://github.com/ClearTables/osm-clear). For future 3D rendering of buildings.
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.
schema:
- ./update_building.sql
- ./building.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml
mapping_file: ./mapping.yaml

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 73 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 36 KiB

Wyświetl plik

@ -1,14 +1,14 @@
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
#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:
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -60,200 +60,19 @@ tables:
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_street
building_street:
fields:
- 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: [street]
type: relation_member
# etldoc: imposm3 -> osm_building_associatedstreet
building_associatedstreet:
fields:
- 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: [associatedStreet]
type: relation_member
# etldoc: imposm3 -> osm_building_relation
building_relation:
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -342,76 +161,3 @@ tables:
mapping:
type: [building]
type: relation_member
# etldoc: imposm3 -> osm_building_multipolygon
building_multipolygon:
fields:
- 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: member
type: member_id
- name: index
type: member_index
- name: role
type: member_role
from_member: true
- name: type
type: member_type
mapping:
type: [multipolygon]
filters:
reject:
building: ["no","none","No"]
building:part: ["no","none","No"]
man_made: ["bridge"]
type: relation_member

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 42 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 28 KiB

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -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();

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 16 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 16 KiB

Wyświetl plik

@ -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;

Wyświetl plik

@ -3,17 +3,20 @@ layer:
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.
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
- ./layer.sql
- ./housenumber.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Wyświetl plik

@ -1,51 +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;
-- etldoc: osm_housenumber_point -> osm_housenumber_point
CREATE OR REPLACE FUNCTION convert_housenumber_point() RETURNS VOID AS $$
BEGIN
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 ST_GeometryType(geometry) <> 'ST_Point';
END;
$$ LANGUAGE plpgsql;
SELECT convert_housenumber_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS housenumber;
CREATE TABLE IF NOT EXISTS housenumber.updates(id serial primary key, t text, unique (t));
CREATE OR REPLACE FUNCTION housenumber.flag() RETURNS trigger AS $$
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.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
INSERT INTO housenumber.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ language plpgsql;
$$ 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
$BODY$
BEGIN
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh housenumber';
PERFORM convert_housenumber_point();
-- 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;
RETURN null;
END;
$BODY$
language plpgsql;
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 OR DELETE ON osm_housenumber_point
AFTER INSERT OR UPDATE
ON osm_housenumber_point
FOR EACH STATEMENT
EXECUTE PROCEDURE housenumber.flag();
EXECUTE PROCEDURE housenumber.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON housenumber.updates
AFTER INSERT
ON housenumber.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE housenumber.refresh();
EXECUTE PROCEDURE housenumber.refresh();

Wyświetl plik

@ -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;

Wyświetl plik

@ -1,10 +0,0 @@
-- 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 $$
-- etldoc: osm_housenumber_point -> layer_housenumber:z14_
SELECT osm_id, geometry, housenumber FROM osm_housenumber_point
WHERE zoom_level >= 14 AND geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -4,7 +4,7 @@ tables:
# etldoc: imposm3 -> osm_housenumber_point
housenumber_point:
type: geometry
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -12,6 +12,15 @@ tables:
- 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:

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 11 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 12 KiB

Wyświetl plik

@ -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
}
]
}

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 208 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 415 KiB

Wyświetl plik

@ -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;

Wyświetl plik

@ -9,132 +9,365 @@
--);
--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
WHEN subclass IN ('farmland', 'farm', 'orchard', 'vineyard', 'plant_nursery') THEN 'farmland'
WHEN subclass IN ('glacier', 'ice_shelf') THEN 'ice'
WHEN subclass IN ('wood', 'forest') THEN 'wood'
WHEN subclass IN ('bare_rock', 'scree') THEN 'rock'
WHEN subclass IN ('fell', 'grassland', 'heath', 'scrub', 'tundra', 'grass', 'meadow', 'allotments',
'park', 'village_green', 'recreation_ground', 'garden', 'golf_course') THEN 'grass'
WHEN subclass IN ('wetland', 'bog', 'swamp', 'wet_meadow', 'marsh', 'reedbed',
'saltern', 'tidalflat', 'saltmarsh', 'mangrove') THEN 'wetland'
WHEN subclass IN ('beach', 'sand', 'dune') THEN 'sand'
ELSE NULL
END;
$$ LANGUAGE SQL IMMUTABLE;
CREATE OR REPLACE FUNCTION landcover_class(subclass varchar) RETURNS text AS
$$
SELECT CASE
%%FIELD_MAPPING: class %%
END;
$$ LANGUAGE SQL IMMUTABLE
-- STRICT
PARALLEL SAFE;
-- etldoc: ne_110m_glaciated_areas -> landcover_z0
CREATE OR REPLACE VIEW landcover_z0 AS (
SELECT NULL::bigint AS osm_id, geometry, 'glacier'::text AS subclass FROM ne_110m_glaciated_areas
);
-- 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);
CREATE OR REPLACE VIEW landcover_z2 AS (
-- etldoc: ne_50m_glaciated_areas -> landcover_z2
SELECT NULL::bigint AS osm_id, geometry, 'glacier'::text AS subclass FROM ne_50m_glaciated_areas
UNION ALL
-- etldoc: ne_50m_antarctic_ice_shelves_polys -> landcover_z2
SELECT NULL::bigint AS osm_id, geometry, 'ice_shelf'::text AS subclass FROM ne_50m_antarctic_ice_shelves_polys
);
-- 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);
CREATE OR REPLACE VIEW landcover_z5 AS (
-- etldoc: ne_10m_glaciated_areas -> landcover_z5
SELECT NULL::bigint AS osm_id, geometry, 'glacier'::text AS subclass FROM ne_10m_glaciated_areas
UNION ALL
-- etldoc: ne_10m_antarctic_ice_shelves_polys -> landcover_z5
SELECT NULL::bigint AS osm_id, geometry, 'ice_shelf'::text AS subclass FROM ne_10m_antarctic_ice_shelves_polys
);
-- 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);
CREATE OR REPLACE VIEW landcover_z7 AS (
-- etldoc: osm_landcover_polygon_gen7 -> landcover_z7
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen7
);
-- 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);
CREATE OR REPLACE VIEW landcover_z8 AS (
-- etldoc: osm_landcover_polygon_gen6 -> landcover_z8
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen6
);
-- 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);
CREATE OR REPLACE VIEW landcover_z9 AS (
-- etldoc: osm_landcover_polygon_gen5 -> landcover_z9
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen5
);
-- 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);
CREATE OR REPLACE VIEW landcover_z10 AS (
-- etldoc: osm_landcover_polygon_gen4 -> landcover_z10
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen4
);
-- 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);
CREATE OR REPLACE VIEW landcover_z11 AS (
-- etldoc: osm_landcover_polygon_gen3 -> landcover_z11
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen3
);
-- 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);
CREATE OR REPLACE VIEW landcover_z12 AS (
-- etldoc: osm_landcover_polygon_gen2 -> landcover_z12
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen2
);
-- 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);
CREATE OR REPLACE VIEW landcover_z13 AS (
-- etldoc: osm_landcover_polygon_gen1 -> landcover_z13
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon_gen1
);
-- 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);
CREATE OR REPLACE VIEW landcover_z14 AS (
-- etldoc: osm_landcover_polygon -> landcover_z14
SELECT osm_id, geometry, subclass FROM osm_landcover_polygon
);
-- 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: layer_landcover[shape=record fillcolor=lightpink, style="rounded, filled", label="layer_landcover | <z0_1> z0-z1 | <z2_4> z2-z4 | <z5_6> z5-z6 |<z7> z7 |<z8> z8 |<z9> z9 |<z10> z10 |<z11> z11 |<z12> z12|<z13> z13|<z14_> z14+" ] ;
-- 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(osm_id bigint, geometry geometry, class text, subclass text) AS $$
SELECT osm_id, geometry,
landcover_class(subclass) AS class,
subclass
FROM (
-- etldoc: landcover_z0 -> layer_landcover:z0_1
SELECT * FROM landcover_z0
WHERE zoom_level BETWEEN 0 AND 1 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z2 -> layer_landcover:z2_4
SELECT * FROM landcover_z2
WHERE zoom_level BETWEEN 2 AND 4 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z5 -> layer_landcover:z5_6
SELECT * FROM landcover_z5
WHERE zoom_level BETWEEN 5 AND 6 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z7 -> layer_landcover:z7
SELECT *
FROM landcover_z7 WHERE zoom_level = 7 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z8 -> layer_landcover:z8
SELECT *
FROM landcover_z8 WHERE zoom_level = 8 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z9 -> layer_landcover:z9
SELECT *
FROM landcover_z9 WHERE zoom_level = 9 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z10 -> layer_landcover:z10
SELECT *
FROM landcover_z10 WHERE zoom_level = 10 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z11 -> layer_landcover:z11
SELECT *
FROM landcover_z11 WHERE zoom_level = 11 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z12 -> layer_landcover:z12
SELECT *
FROM landcover_z12 WHERE zoom_level = 12 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z13 -> layer_landcover:z13
SELECT *
FROM landcover_z13 WHERE zoom_level = 13 AND geometry && bbox
UNION ALL
-- etldoc: landcover_z14 -> layer_landcover:z14_
SELECT *
FROM landcover_z14 WHERE zoom_level >= 14 AND geometry && bbox
) AS zoom_levels;
$$ LANGUAGE SQL IMMUTABLE;
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;

Wyświetl plik

@ -1,5 +1,12 @@
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
@ -10,12 +17,20 @@ layer:
description: |
Use the **class** to assign natural colors for **landcover**.
values:
- farmland
- ice
- wood
- grass
- wetland
- sand
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', '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.
@ -31,6 +46,7 @@ layer:
- bog
- dune
- scrub
- shrubbery
- farm
- farmland
- fell
@ -65,6 +81,7 @@ layer:
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

Wyświetl plik

@ -1,52 +1,7 @@
generalized_tables:
# etldoc: imposm3 -> osm_landcover_polygon_gen7
landcover_polygon_gen7:
source: landcover_polygon_gen6
sql_filter: area>power(ZRES5,2)
tolerance: ZRES7
# etldoc: imposm3 -> osm_landcover_polygon_gen6
landcover_polygon_gen6:
source: landcover_polygon_gen5
sql_filter: area>power(ZRES6,2)
tolerance: ZRES8
# etldoc: imposm3 -> osm_landcover_polygon_gen5
landcover_polygon_gen5:
source: landcover_polygon_gen4
sql_filter: area>power(ZRES7,2)
tolerance: ZRES9
# etldoc: imposm3 -> osm_landcover_polygon_gen4
landcover_polygon_gen4:
source: landcover_polygon_gen3
sql_filter: area>power(ZRES8,2)
tolerance: ZRES10
# etldoc: imposm3 -> osm_landcover_polygon_gen3
landcover_polygon_gen3:
source: landcover_polygon_gen2
sql_filter: area>power(ZRES8,2)
tolerance: ZRES11
# etldoc: imposm3 -> osm_landcover_polygon_gen2
landcover_polygon_gen2:
source: landcover_polygon_gen1
sql_filter: area>power(ZRES9,2)
tolerance: ZRES12
# etldoc: imposm3 -> osm_landcover_polygon_gen1
landcover_polygon_gen1:
source: landcover_polygon
sql_filter: area>power(ZRES10,2) AND ST_IsValid(geometry)
tolerance: ZRES13
tables:
# etldoc: imposm3 -> osm_landcover_polygon
landcover_polygon:
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -71,8 +26,6 @@ tables:
- forest
- village_green
- recreation_ground
# There are 600 parks tagged with landuse=park instead of leisure=park
- park
natural:
- wood
- wetland
@ -80,6 +33,7 @@ tables:
- grassland
- heath
- scrub
- shrubbery
- tundra
- glacier
- bare_rock

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 66 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 67 KiB

Wyświetl plik

@ -0,0 +1,476 @@
{
"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",
"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",
"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",
"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",
"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
}
]
}

Wyświetl plik

@ -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;
$$;

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 158 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 333 KiB

Wyświetl plik

@ -1,111 +1,379 @@
-- etldoc: ne_50m_urban_areas -> landuse_z4
CREATE OR REPLACE VIEW landuse_z4 AS (
SELECT NULL::bigint AS osm_id, 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
WHERE scalerank <= 2
-- 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: ne_50m_urban_areas -> landuse_z5
CREATE OR REPLACE VIEW landuse_z5 AS (
SELECT NULL::bigint AS osm_id, 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
-- 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_gen7 -> landuse_z6
CREATE OR REPLACE VIEW landuse_z6 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen7
-- 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_gen6 -> landuse_z8
CREATE OR REPLACE VIEW landuse_z8 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen6
-- 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_gen5 -> landuse_z9
CREATE OR REPLACE VIEW landuse_z9 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen5
-- 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_gen4 -> landuse_z10
CREATE OR REPLACE VIEW landuse_z10 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen4
-- 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_gen3 -> landuse_z11
CREATE OR REPLACE VIEW landuse_z11 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen3
);
-- etldoc: osm_landuse_polygon_gen2 -> landuse_z12
CREATE OR REPLACE VIEW landuse_z12 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen2
);
-- etldoc: osm_landuse_polygon_gen1 -> landuse_z13
CREATE OR REPLACE VIEW landuse_z13 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon_gen1
);
-- etldoc: osm_landuse_polygon -> landuse_z14
CREATE OR REPLACE VIEW landuse_z14 AS (
SELECT osm_id, geometry, landuse, amenity, leisure, tourism, place, waterway, NULL::int as scalerank
FROM osm_landuse_polygon
-- 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+" ] ;
-- 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,
COALESCE(
NULLIF(landuse, ''),
NULLIF(amenity, ''),
NULLIF(leisure, ''),
NULLIF(tourism, ''),
NULLIF(place, ''),
NULLIF(waterway, '')
) AS class
FROM (
-- etldoc: landuse_z4 -> layer_landuse:z4
SELECT * FROM landuse_z4
WHERE zoom_level = 4
UNION ALL
-- etldoc: landuse_z5 -> layer_landuse:z5
SELECT * FROM landuse_z5
WHERE zoom_level = 5
UNION ALL
-- etldoc: landuse_z6 -> layer_landuse:z6
-- etldoc: landuse_z6 -> layer_landuse:z7
SELECT * FROM landuse_z6 WHERE zoom_level BETWEEN 6 AND 7
UNION ALL
-- etldoc: landuse_z8 -> layer_landuse:z8
SELECT * FROM landuse_z8 WHERE zoom_level = 8
UNION ALL
-- etldoc: landuse_z9 -> layer_landuse:z9
SELECT * FROM landuse_z9 WHERE zoom_level = 9
UNION ALL
-- etldoc: landuse_z10 -> layer_landuse:z10
SELECT * FROM landuse_z10 WHERE zoom_level = 10
UNION ALL
-- etldoc: landuse_z11 -> layer_landuse:z11
SELECT * FROM landuse_z11 WHERE zoom_level = 11
UNION ALL
-- etldoc: landuse_z12 -> layer_landuse:z12
SELECT * FROM landuse_z12 WHERE zoom_level = 12
UNION ALL
-- etldoc: landuse_z13 -> layer_landuse:z13
SELECT * FROM landuse_z13 WHERE zoom_level = 13
UNION ALL
-- etldoc: landuse_z14 -> layer_landuse:z14
SELECT * FROM landuse_z14 WHERE zoom_level >= 14
) AS zoom_levels
WHERE geometry && bbox;
$$ LANGUAGE SQL IMMUTABLE;
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;

Wyświetl plik

@ -1,5 +1,8 @@
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.
@ -22,6 +25,7 @@ layer:
- residential
- commercial
- industrial
- garages
- retail
- bus_station
- school
@ -37,12 +41,16 @@ layer:
- 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

Wyświetl plik

@ -1,35 +1,41 @@
generalized_tables:
# etldoc: imposm3 -> osm_landuse_polygon_gen7
landuse_polygon_gen7:
source: landuse_polygon_gen6
# 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
# etldoc: imposm3 -> osm_landuse_polygon_gen6
landuse_polygon_gen6:
source: landuse_polygon_gen5
sql_filter: area>power(ZRES6,2) AND (landuse='residential' OR place='suburb' OR place='neighbourhood')
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: imposm3 -> osm_landuse_polygon_gen5
landuse_polygon_gen5:
source: landuse_polygon_gen4
# 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: imposm3 -> osm_landuse_polygon_gen4
landuse_polygon_gen4:
source: landuse_polygon_gen3
# 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: imposm3 -> osm_landuse_polygon_gen3
landuse_polygon_gen3:
source: landuse_polygon_gen2
# 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: imposm3 -> osm_landuse_polygon_gen2
landuse_polygon_gen2:
source: landuse_polygon_gen1
# 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: imposm3 -> osm_landuse_polygon_gen1
landuse_polygon_gen1:
# 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
@ -38,7 +44,7 @@ tables:
# etldoc: imposm3 -> osm_landuse_polygon
landuse_polygon:
type: polygon
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -68,6 +74,7 @@ tables:
- railway
- cemetery
- military
- quarry
# zoning
- residential
- commercial
@ -82,6 +89,7 @@ tables:
- college
- library
- hospital
- grave_yard
leisure:
- stadium
- pitch
@ -92,6 +100,7 @@ tables:
- zoo
place:
- suburb
- quarter
- neighbourhood
waterway:
- dam

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 67 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 63 KiB

Wyświetl plik

@ -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);

Wyświetl plik

@ -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
}
]
}

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 16 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 46 KiB

Wyświetl plik

@ -1,55 +0,0 @@
-- etldoc: layer_mountain_peak[shape=record fillcolor=lightpink,
-- etldoc: style="rounded,filled", label="layer_mountain_peak | <z7_> z7+" ] ;
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,
"rank" int) AS
$$
-- etldoc: osm_peak_point -> layer_mountain_peak:z7_
SELECT
osm_id,
geometry,
name,
name_en,
name_de,
tags -> 'natural' AS class,
tags,
ele::int,
ele_ft::int,
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,
substring(ele from E'^(-?\\d+)(\\D|$)')::int AS ele,
round(substring(ele from E'^(-?\\d+)(\\D|$)')::int*3.2808399)::int AS ele_ft,
row_number() OVER (
PARTITION BY LabelGrid(geometry, 100 * pixel_width)
ORDER BY (
substring(ele from E'^(-?\\d+)(\\D|$)')::int +
(CASE WHEN NULLIF(wikipedia, '') is not null THEN 10000 ELSE 0 END) +
(CASE WHEN NULLIF(name, '') is not null THEN 10000 ELSE 0 END)
) DESC
)::int AS "rank"
FROM osm_peak_point
WHERE geometry && bbox
AND ele is not null
AND ele ~ E'^-?\\d{1,4}(\\D|$)'
) AS ranked_peaks
WHERE zoom_level >= 7 AND (rank <= 5 OR zoom_level >= 14)
ORDER BY "rank" ASC;
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -3,7 +3,7 @@ tables:
# etldoc: imposm3 -> osm_peak_point
peak_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -29,3 +29,32 @@ tables:
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

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 4.7 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 14 KiB

Wyświetl plik

@ -0,0 +1,118 @@
-- 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,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, 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 (
substring(ele FROM E'^(-?\\d+)(\\D|$)')::int +
(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 IS NOT NULL
AND ele ~ E'^-?\\d{1,4}(\\D|$)'
) 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

Wyświetl plik

@ -1,31 +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.
name_en: English name `name:en` if available, otherwise `name`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`.
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 mountain peak and volcano.
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 feets.
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, rank FROM layer_mountain_peak(!bbox!, z(!scale_denominator!), !pixel_width!)) AS t
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
- ./layer.sql
- ./update_mountain_linestring.sql
- ./mountain_peak.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -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();

Wyświetl plik

@ -1,48 +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;
-- etldoc: osm_peak_point -> osm_peak_point
CREATE OR REPLACE FUNCTION update_osm_peak_point() RETURNS VOID AS $$
BEGIN
UPDATE osm_peak_point
SET tags = update_tags(tags, geometry)
WHERE COALESCE(tags->'name:latin', tags->'name:nonlatin', tags->'name_int') IS NULL;
END;
$$ LANGUAGE plpgsql;
SELECT update_osm_peak_point();
-- Handle updates
CREATE SCHEMA IF NOT EXISTS mountain_peak_point;
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 $$
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.updates(t) VALUES ('y') ON CONFLICT(t) DO NOTHING;
RETURN null;
INSERT INTO mountain_peak_point.osm_ids VALUES (NEW.osm_id) ON CONFLICT (osm_id) DO NOTHING;
RETURN NULL;
END;
$$ language plpgsql;
$$ 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
$BODY$
BEGIN
$$
DECLARE
t TIMESTAMP WITH TIME ZONE := clock_timestamp();
BEGIN
RAISE LOG 'Refresh mountain_peak_point';
PERFORM update_osm_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;
RETURN null;
END;
$BODY$
language plpgsql;
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 OR DELETE ON osm_peak_point
AFTER INSERT OR UPDATE
ON osm_peak_point
FOR EACH STATEMENT
EXECUTE PROCEDURE mountain_peak_point.flag();
EXECUTE PROCEDURE mountain_peak_point.flag();
CREATE CONSTRAINT TRIGGER trigger_refresh
AFTER INSERT ON mountain_peak_point.updates
AFTER INSERT
ON mountain_peak_point.updates
INITIALLY DEFERRED
FOR EACH ROW
EXECUTE PROCEDURE mountain_peak_point.refresh();
EXECUTE PROCEDURE mountain_peak_point.refresh();

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 153 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 194 KiB

Wyświetl plik

@ -1,125 +0,0 @@
-- etldoc: layer_park[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_park |<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, name, name_en, name_de, tags, rank
FROM (
SELECT osm_id, geometry,
COALESCE(NULLIF(boundary, ''), NULLIF(leisure, '')) AS class,
name, name_en, name_de, tags,
NULL::int as rank
FROM (
-- etldoc: osm_park_polygon_gen8 -> layer_park:z6
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen8
WHERE zoom_level = 6 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen7 -> layer_park:z7
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen7
WHERE zoom_level = 7 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen6 -> layer_park:z8
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen6
WHERE zoom_level = 8 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen5 -> layer_park:z9
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen5
WHERE zoom_level = 9 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen4 -> layer_park:z10
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen4
WHERE zoom_level = 10 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen3 -> layer_park:z11
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen3
WHERE zoom_level = 11 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen2 -> layer_park:z12
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen2
WHERE zoom_level = 12 AND geometry && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen1 -> layer_park:z13
SELECT osm_id, geometry, name, name_en, name_de, tags, leisure, boundary, NULL::int as scalerank
FROM osm_park_polygon_gen1
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, NULL::int as scalerank
FROM osm_park_polygon
WHERE zoom_level >= 14 AND geometry && bbox
) AS park_polygon
UNION ALL
SELECT osm_id, geometry_point AS geometry,
COALESCE(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_gen8 -> layer_park:z6
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen8
WHERE zoom_level = 6 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen7 -> layer_park:z7
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen7
WHERE zoom_level = 7 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen6 -> layer_park:z8
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen6
WHERE zoom_level = 8 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen5 -> layer_park:z9
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen5
WHERE zoom_level = 9 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen4 -> layer_park:z10
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen4
WHERE zoom_level = 10 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen3 -> layer_park:z11
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen3
WHERE zoom_level = 11 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen2 -> layer_park:z12
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen2
WHERE zoom_level = 12 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon_gen1 -> layer_park:z13
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon_gen1
WHERE zoom_level = 13 AND geometry_point && bbox
UNION ALL
-- etldoc: osm_park_polygon -> layer_park:z14
SELECT osm_id, geometry_point, name, name_en, name_de, tags, leisure, boundary, area
FROM osm_park_polygon
WHERE zoom_level >= 14 AND geometry_point && bbox
) AS park_point
) AS park_all;
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -1,48 +1,60 @@
generalized_tables:
# etldoc: imposm3 -> osm_park_polygon_gen8
park_polygon_gen8:
source: park_polygon_gen7
# 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: ZRES8
tolerance: ZRES6
# etldoc: imposm3 -> osm_park_polygon_gen7
park_polygon_gen7:
source: park_polygon_gen6
# 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: imposm3 -> osm_park_polygon_gen6
park_polygon_gen6:
source: park_polygon_gen5
sql_filter: area>power(ZRES7,2)
# 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: imposm3 -> osm_park_polygon_gen5
park_polygon_gen5:
source: park_polygon_gen4
sql_filter: area>power(ZRES8,2)
# 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: imposm3 -> osm_park_polygon_gen4
park_polygon_gen4:
source: park_polygon_gen3
sql_filter: area>power(ZRES9,2)
tolerance: ZRES11
# etldoc: imposm3 -> osm_park_polygon_gen3
park_polygon_gen3:
source: park_polygon_gen2
# 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: imposm3 -> osm_park_polygon_gen2
park_polygon_gen2:
source: park_polygon_gen1
# 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: imposm3 -> osm_park_polygon_gen1
park_polygon_gen1:
# 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
@ -52,7 +64,8 @@ tables:
# etldoc: imposm3 -> osm_park_polygon
park_polygon:
type: polygon
fields:
_resolve_wikidata: false
columns:
- name: osm_id
type: id
- name: geometry
@ -77,6 +90,9 @@ tables:
- name: boundary
key: boundary
type: string
- name: protection_title
key: protection_title
type: string
- name: area
type: area
mapping:
@ -84,3 +100,4 @@ tables:
- nature_reserve
boundary:
- national_park
- protected_area

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 10 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 13 KiB

Wyświetl plik

@ -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

Wyświetl plik

@ -1,25 +1,32 @@
layer:
id: "park"
description: |
The park layer contains parks from OpenStreetMap tagged with either [`boundary=national_park`](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dnational_park) or [`leisure=nature_reserve`](http://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve).
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 parks.
values:
- national_park
- nature_reserve
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the park (point features only).
name_en: English name `name:en` if available, otherwise `name` (point features only).
name_de: German name `name:de` if available, otherwise `name` or `name:en` (point features only).
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
- ./layer.sql
- ./park.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

Wyświetl plik

@ -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
}
]
}

Wyświetl plik

@ -1,140 +1,260 @@
ALTER TABLE osm_park_polygon ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen1 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen2 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen3 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen4 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen5 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen6 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen7 ADD COLUMN IF NOT EXISTS geometry_point geometry;
ALTER TABLE osm_park_polygon_gen8 ADD COLUMN IF NOT EXISTS geometry_point geometry;
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_gen1;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen2;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen3;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen4;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen5;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen6;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen7;
DROP TRIGGER IF EXISTS update_row ON osm_park_polygon_gen8;
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_gen1 -> osm_park_polygon_gen1
-- etldoc: osm_park_polygon_gen2 -> osm_park_polygon_gen2
-- etldoc: osm_park_polygon_gen3 -> osm_park_polygon_gen3
-- etldoc: osm_park_polygon_gen4 -> osm_park_polygon_gen4
-- etldoc: osm_park_polygon_gen5 -> osm_park_polygon_gen5
-- etldoc: osm_park_polygon_gen6 -> osm_park_polygon_gen6
-- etldoc: osm_park_polygon_gen7 -> osm_park_polygon_gen7
-- etldoc: osm_park_polygon_gen8 -> osm_park_polygon_gen8
CREATE OR REPLACE FUNCTION update_osm_park_polygon() RETURNS VOID AS $$
-- 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_centroid(geometry);
UPDATE osm_park_polygon
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen1
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z13
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen2
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z12
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen3
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z11
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen4
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z10
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen5
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z9
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen6
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z8
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen7
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(geometry);
UPDATE osm_park_polygon_gen_z7
SET tags = update_tags(tags, geometry),
geometry_point = ST_PointOnSurface(geometry);
UPDATE osm_park_polygon_gen8
SET tags = update_tags(tags, geometry),
geometry_point = st_centroid(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_gen1_point_geom_idx ON osm_park_polygon_gen1 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen2_point_geom_idx ON osm_park_polygon_gen2 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen3_point_geom_idx ON osm_park_polygon_gen3 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen4_point_geom_idx ON osm_park_polygon_gen4 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen5_point_geom_idx ON osm_park_polygon_gen5 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen6_point_geom_idx ON osm_park_polygon_gen6 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen7_point_geom_idx ON osm_park_polygon_gen7 USING gist(geometry_point);
CREATE INDEX IF NOT EXISTS osm_park_polygon_gen8_point_geom_idx ON osm_park_polygon_gen8 USING gist(geometry_point);
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
RETURNS trigger
AS
$BODY$
$$
BEGIN
NEW.tags = update_tags(NEW.tags, NEW.geometry);
NEW.geometry_point = st_centroid(NEW.geometry);
RETURN NEW;
NEW.tags = update_tags(NEW.tags, NEW.geometry);
NEW.geometry_point = ST_PointOnSurface(NEW.geometry);
RETURN NEW;
END;
$BODY$
LANGUAGE plpgsql;
$$ 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
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_gen1
FOR EACH 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_gen2
FOR EACH 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_gen3
FOR EACH 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_gen4
FOR EACH 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_gen5
FOR EACH 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_gen6
FOR EACH 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_gen7
FOR EACH 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_gen8
FOR EACH 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();

Wyświetl plik

@ -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;

Wyświetl plik

@ -1,8 +1,10 @@
CREATE OR REPLACE FUNCTION normalize_capital_level(capital TEXT)
RETURNS INT AS $$
SELECT CASE
WHEN capital IN ('yes', '2') THEN 2
WHEN capital = '4' THEN 4
ELSE NULL
END;
$$ LANGUAGE SQL IMMUTABLE STRICT;
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;

Wyświetl plik

@ -1,55 +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 IMMUTABLE;
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;

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 141 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 152 KiB

Wyświetl plik

@ -1,9 +0,0 @@
CREATE OR REPLACE FUNCTION island_rank(area REAL) RETURNS INT AS $$
SELECT CASE
WHEN area < 10000000 THEN 6
WHEN area BETWEEN 1000000 AND 15000000 THEN 5
WHEN area BETWEEN 15000000 AND 40000000 THEN 4
WHEN area > 40000000 THEN 3
ELSE 7
END;
$$ LANGUAGE SQL IMMUTABLE STRICT;

Wyświetl plik

@ -1,99 +0,0 @@
-- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_place | <z0_3> z0-3|<z4_7> z4-7|<z8_11> z8-11| <z12_14> z12-z14+" ] ;
CREATE OR REPLACE FUNCTION layer_place(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, class text, "rank" int, capital INT, iso_a2
TEXT) AS $$
SELECT * FROM (
-- etldoc: osm_continent_point -> layer_place:z0_3
SELECT
osm_id*10, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'continent' AS class, 1 AS "rank", NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_continent_point
WHERE geometry && bbox AND zoom_level < 4
UNION ALL
-- etldoc: osm_country_point -> layer_place:z0_3
-- etldoc: osm_country_point -> layer_place:z4_7
-- etldoc: osm_country_point -> layer_place:z8_11
-- etldoc: osm_country_point -> layer_place:z12_14
SELECT
osm_id*10, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'country' AS class, "rank", NULL::int AS capital,
iso3166_1_alpha_2 AS iso_a2
FROM osm_country_point
WHERE geometry && bbox AND "rank" <= zoom_level + 1 AND name <> ''
UNION ALL
-- etldoc: osm_state_point -> layer_place:z0_3
-- etldoc: osm_state_point -> layer_place:z4_7
-- etldoc: osm_state_point -> layer_place:z8_11
-- etldoc: osm_state_point -> layer_place:z12_14
SELECT
osm_id*10, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'state' AS class, "rank", NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_state_point
WHERE geometry && bbox AND
name <> '' AND
("rank" + 2 <= zoom_level) AND (
zoom_level >= 5 OR
is_in_country IN ('United Kingdom', 'USA', 'Россия', 'Brasil', 'China', 'India') OR
is_in_country_code IN ('AU', 'CN', 'IN', 'BR', 'US'))
UNION ALL
-- etldoc: osm_island_point -> layer_place:z12_14
SELECT
osm_id*10, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'island' AS class, 7 AS "rank", NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_island_point
WHERE zoom_level >= 12
AND geometry && bbox
UNION ALL
-- etldoc: osm_island_polygon -> layer_place:z8_11
-- etldoc: osm_island_polygon -> layer_place:z12_14
SELECT
osm_id*10, geometry, name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'island' AS class, island_rank(area) AS "rank", NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_island_polygon
WHERE geometry && bbox AND
((zoom_level = 8 AND island_rank(area) <= 3)
OR (zoom_level = 9 AND island_rank(area) <= 4)
OR (zoom_level >= 10))
UNION ALL
-- etldoc: layer_city -> layer_place:z0_3
-- etldoc: layer_city -> layer_place:z4_7
-- etldoc: layer_city -> layer_place:z8_11
-- etldoc: layer_city -> layer_place:z12_14
SELECT
osm_id*10, geometry, name, name_en, name_de,
tags,
place::text AS class, "rank", capital,
NULL::text AS iso_a2
FROM layer_city(bbox, zoom_level, pixel_width)
ORDER BY "rank" ASC
) AS place_all
$$ LANGUAGE SQL IMMUTABLE;

Wyświetl plik

@ -20,7 +20,7 @@ tables:
# etldoc: imposm3 -> osm_continent_point
continent_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -40,7 +40,7 @@ tables:
# etldoc: imposm3 -> osm_country_point
country_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -70,7 +70,7 @@ tables:
# etldoc: imposm3 -> osm_island_polygon
island_polygon:
type: polygon
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -93,7 +93,7 @@ tables:
# etldoc: imposm3 -> osm_island_point
island_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -114,7 +114,7 @@ tables:
# etldoc: imposm3 -> osm_state_point
state_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -124,6 +124,9 @@ tables:
- *name_de
- name: tags
type: hstore_tags
- name: place
key: place
type: string
- name: is_in_country
key: is_in:country
type: string
@ -140,11 +143,12 @@ tables:
mapping:
place:
- state
- province
# etldoc: imposm3 -> osm_city_point
city_point:
type: point
fields:
columns:
- name: osm_id
type: id
- name: geometry
@ -173,6 +177,8 @@ tables:
- town
- village
- hamlet
- borough
- suburb
- quarter
- neighbourhood
- isolated_dwelling

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 50 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 55 KiB

Wyświetl plik

@ -0,0 +1,165 @@
-- etldoc: layer_place[shape=record fillcolor=lightpink, style="rounded,filled",
-- etldoc: label="layer_place | <z0_3> z0-3|<z4_7> z4-7|<z8_11> z8-11| <z12_14> z12-z14+" ] ;
CREATE OR REPLACE FUNCTION layer_place(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,
class text,
"rank" int,
capital int,
iso_a2 text
)
AS
$$
SELECT *
FROM (
SELECT
-- etldoc: osm_continent_point -> layer_place:z0_3
osm_id * 10 AS osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'continent' AS class,
1 AS "rank",
NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_continent_point
WHERE geometry && bbox
AND zoom_level < 4
UNION ALL
SELECT
-- etldoc: osm_country_point -> layer_place:z0_3
-- etldoc: osm_country_point -> layer_place:z4_7
-- etldoc: osm_country_point -> layer_place:z8_11
-- etldoc: osm_country_point -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'country' AS class,
"rank",
NULL::int AS capital,
iso3166_1_alpha_2 AS iso_a2
FROM osm_country_point
WHERE geometry && bbox
AND "rank" <= zoom_level + 1
AND name <> ''
UNION ALL
SELECT
-- etldoc: osm_state_point -> layer_place:z0_3
-- etldoc: osm_state_point -> layer_place:z4_7
-- etldoc: osm_state_point -> layer_place:z8_11
-- etldoc: osm_state_point -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
place::text AS class,
"rank",
NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_state_point
WHERE geometry && bbox
AND name <> ''
AND zoom_level > 1
UNION ALL
SELECT
-- etldoc: osm_island_point -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'island' AS class,
7 AS "rank",
NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_island_point
WHERE zoom_level >= 12
AND geometry && bbox
UNION ALL
SELECT
-- etldoc: osm_island_polygon -> layer_place:z8_11
-- etldoc: osm_island_polygon -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry,
name,
COALESCE(NULLIF(name_en, ''), name) AS name_en,
COALESCE(NULLIF(name_de, ''), name, name_en) AS name_de,
tags,
'island' AS class,
area_rank(area) AS "rank",
NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_island_polygon
WHERE geometry && bbox
AND ((zoom_level = 8 AND area_rank(area) <= 3)
OR (zoom_level = 9 AND area_rank(area) <= 4)
OR (zoom_level >= 10))
UNION ALL
SELECT
-- etldoc: osm_boundary_polygon -> layer_place:z6_11
-- etldoc: osm_boundary_polygon -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry_point,
name,
NULL::text AS name_en, -- deprecated
NULL::text AS name_de, -- deprecated
tags,
'aboriginal_lands' AS class,
area_rank(area) AS "rank",
NULL::int AS capital,
NULL::text AS iso_a2
FROM osm_boundary_polygon
WHERE geometry_point && bbox
AND ((zoom_level = 6 AND area_rank(area) <= 1)
OR (zoom_level = 7 AND area_rank(area) <= 2)
OR (zoom_level = 8 AND area_rank(area) <= 3)
OR (zoom_level = 9 AND area_rank(area) <= 4)
OR (zoom_level >= 10))
UNION ALL
SELECT
-- etldoc: layer_city -> layer_place:z0_3
-- etldoc: layer_city -> layer_place:z4_7
-- etldoc: layer_city -> layer_place:z8_11
-- etldoc: layer_city -> layer_place:z12_14
osm_id * 10 AS osm_id,
geometry,
name,
name_en,
name_de,
tags,
place::text AS class,
"rank",
capital,
NULL::text AS iso_a2
FROM layer_city(bbox, zoom_level, pixel_width)
ORDER BY "rank" ASC
) AS place_all
$$ LANGUAGE SQL STABLE
PARALLEL SAFE;
-- TODO: Check if the above can be made STRICT -- i.e. if pixel_width could be NULL

Wyświetl plik

@ -1,49 +1,64 @@
layer:
id: "place"
requires:
tables:
- ne_10m_admin_1_states_provinces
- ne_10m_admin_0_countries
- ne_10m_populated_places
layers:
- boundary
description: |
The place layer consists out of [countries](http://wiki.openstreetmap.org/wiki/Tag:place%3Dcountry),
[states](http://wiki.openstreetmap.org/wiki/Tag:place%3Dstate) and [cities](http://wiki.openstreetmap.org/wiki/Key:place).
[states](http://wiki.openstreetmap.org/wiki/Tag:place%3Dstate), [cities](http://wiki.openstreetmap.org/wiki/Key:place)
and [islands](https://wiki.openstreetmap.org/wiki/Tag:place%3Disland).
Apart from the roads this is also one of the more important layers to create a beautiful map.
We suggest you use different font styles and sizes to create a text hierarchy.
fields:
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the POI.
name_en: English name `name:en` if available, otherwise `name`.
name_de: German name `name:de` if available, otherwise `name` or `name:en`.
name: The OSM [`name`](http://wiki.openstreetmap.org/wiki/Key:name) value of the place. 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`.
capital:
description: |
The **capital** field marks the
[`admin_level`](http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative#admin_level)
of the boundary the place is a capital of.
values: [2, 4]
values: [2, 3, 4, 5, 6]
class:
description: |
Original value of the
[`place`](http://wiki.openstreetmap.org/wiki/Key:place) tag.
Distinguish between continents, countries, states and
Distinguish between continents, countries, states, islands and
places like settlements or smaller entities.
Use **class** to separately style the different places and build
a text hierarchy according to their importance.
a text hierarchy according to their importance. For places derived
from boundaries, the original value of the
[`boundary`](http://wiki.openstreetmap.org/wiki/Key:boundary) tag.
values:
- continent
- country
- state
- province
- city
- town
- village
- hamlet
- borough
- suburb
- quarter
- neighbourhood
- isolated_dwelling
- island
- aboriginal_lands
iso_a2:
description: |
Two-letter country code [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2).
Two-letter country code [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Available only for `class=country`.
Original value of the
[`country_code_iso3166_1_alpha_2`](http://wiki.openstreetmap.org/wiki/Tag:place%3Dcountry) tag.
rank:
description: |
Countries, states and the most important cities all have a
**rank** to boost their importance on the map.
The **rank** field for counries and states ranges from
The **rank** field for countries and states ranges from
`1` to `6` while the **rank** field for cities ranges from
`1` to `10` for the most important cities
and continues from `10` serially based on the
@ -65,14 +80,14 @@ schema:
- ./types.sql
- ./capital.sql
- ./city.sql
- ./island_rank.sql
- ./area_rank.sql
- ./update_continent_point.sql
- ./update_country_point.sql
- ./update_island_polygon.sql
- ./update_island_point.sql
- ./update_state_point.sql
- ./update_city_point.sql
- ./layer.sql
- ./place.sql
datasources:
- type: imposm3
mapping_file: ./mapping.yaml

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