mirror of
https://github.com/cfpwastaken/planetiler-openmaptiles.git
synced 2026-02-04 04:21:08 +00:00
OpenMapTiles 3.15.0 SNAPSHOT (3) (#160)
* clean-up: mvn spotless:apply
* Long ferries (as per OMT PR 1486)
* regenerate-openmaptiles.sh b3d67ed5b327c9059aeea0b3304772c6b4c8c7e9 (to match content of OMT PR 1489)
* Add aboriginal lands (as per OMT PR 1489)
* handle duplicate route relations (to match OMT PR 1501)
* regenerate-openmaptiles.sh master, to match several OMT PRs which adjusted only YML
* URLs in comments adjusted to match OMT PR 1560
* Convert separated addresses to dashed addresses
* add brunnel (and layer) attributes only for certain zoomlevels, depending on feature size (matching OMT PR 1579)
* unit test testInterstateMotorway(): brunnel tag for test line no longer available at Z8
* unit test testInterstateMotorway() clean-up: Z13 was tested twice
* minor clean-up: fixed unit test naming
* partial fix for differences in transportation_name layer
The difference is between OpenMapTiles/master (OMT) and
planetiler-openmaptiles/omt_3_15_0 (PT-OMT) (e.g. development versions).
The point is, that while PT-OMT was using limit of "8km" for Z9-Z11, OMT
is using limit "ST_Length(geometry) > 8000 / POWER(2, zoom_level - 9)
AND zoom_level BETWEEN 9 AND 11".
Some further differences still visible, hence further commits expected.
* further adjustments to better match what is done with ferries in OMT
... (as per OMT PR 1486)
But FERRY_MIN_PIXEL_SIZE is "too much" in the contexct of Planetiler,
since it is applied within tiles, hence causes gaps in lines if a line
"strikes a little" certain tile. Hence we will need to divert a little.
* ferry minLength tweak + clean-up
* mvn spotless:apply
* fixed minor typo
* minor reformatting
* ferry line length filter replaced with min. zoom calculation
hence the results are much closer to what OMT is doing for Z4-Z9
* testFerry() adjusted to match previous commit
ferry test polygon with area 1 now qualifies for min. zoom 5
* clea-up of unused stuff + mvn spotless:apply
* mvn spotless:apply
* added TODO node for follow-up pull-request/simplification
* clean-up: common getMinZoom() code moved to Utils
* minzoom clipping for brunnel was adjusted do Z9-Z12 -> test adjusted too
* clean-up
* use same tolerance for all transportation items, like OSM does
* clean-up, since ferry and non-ferry procesing is now same
* we need regenerate to work with master branch for now
* first sub-class search for agg_stop simplified a little
* contains() used instead of indexOf() for better readability
* numbers as list, not array, so that getFirst() and getLast() can be used
* better trimming and filtring of housenumbers
* adjusted handling of large house numbers
* several unit tests collapsed to one with @ParameterizedTest + @CsvSource
* AGG_STOP_SUBCLASS_ORDER simplified from Map to List
* fixed major omission from previous commit
* clamp() used to replace min()&max() combo
* agg_stop now implemented
* fixed typo in the error message
* prepare IE and GB boundary geometry outside of synchronized{}
* fixed typo in the error message
* mvn spotless:apply
* switch statements for IE and GB route networks simplified
* avoid RouteNetwork->String mapping, not needed for anyMatch()
* fix: attr. brunnel optional based on size on Z4-Z11, attr. layer optional between Z9-Z11
* tolerance change in transportation reverted, added note to README as per why
* fix: monzoom for sea&co. is Z0-Z14 based on area, for the rest it is Z3-Z14 again based on area
* clean-up: avoid doing area->side->area, do just area
* regenerate-openmaptiles.sh 6c31841f4674f15e15afde346a060cf7c22e6cdd (to match content of OMT PR 1591)
* relevant process() functions adjusted to match changes in transportation/mapping.yaml
* regenerate-openmaptiles.sh master, instead of 6c31841f4674f15e15afde346a060cf7c22e6cdd (to match content of OMT PR 1591, in a cleaner way)
* introduce duplicate housenumber filtering (matching OMT PR 1391)
* (less related) clean-up: use isEmpty() instead if size check
* testContainsHousenumber UT adjusted, since duplicate housenumber filtering is reducing amount of house numbers
* use combination of uic_ref, name, network and operator as key for agg_stop sets
If we rely on only on `uic_ref` we group together also stations which are
too far apart (even different cities). With this combo results seem OK,
e.g. all grouped stations are within around 950m (1000 pixels at Z14) of
each other (1000 being used in `PARTITION BY LabelGrid(...` in
`layers/poi/poi.sql` in OpenMapTiles).
* agg_stop comparison made more explicit, since we want to match same exact one
* mvn spotless:apply
* name now important for agg_stop processing, hence name:es (ab)used for unit tests
* agg_stop: simplified processing of nearest station
Results still same, only ordering is different:
- previously: agg_stop=1 first
- now: FIFO
* agg_stop: forther code simplification
* fixed major typo introduced in previous merge
* setMinPixelSize() + setMinZoom() used instead of areaToMinZoom()
* clean-up: unused stuff removed
* mvn spotless:apply
* setAttrWithMinSize() used instead of getBrunnelMinzoom()
getFerryMinzoom() kept since we'd like to replicate `sql_filter: ST_Length(...` from OMT
* getMinZoomForLength() no longer used, hence removed
* MIN_LENGTH value halved, to partially counter the effect of Planetiler applying the limit before merging
* clean-up: LOG2 not used, hence removed
* Revert "MIN_LENGTH value halved, to partially counter the effect of Planetiler applying the limit before merging"
This reverts commit 8fb67075289f3028d31761dcc9564fc597adab36.
* use 256px as buffer pixel override instead of MIN_LENGTH
Make sure we have enough room (=whole next tile) when checking MIN_LENGTH,
to avoid pieces of otherwise "long enough" lines to be excluded (thus
creating "holes" or missing ends) in some tiles just because length in that
particular tile is bellow limit. Given that MIN_LENGTH values translated to
pixels are quite big (compared to {@code BUFFER_SIZE}), such missing pieces
would be quite noticeable.
This improves items mainly in Z12-Z13.
* added BY_TEMP_HAS_NAME comparator to avoid its repeated construction during run-time
* duplicate houcenumber processing simplified further
* clean-up: get(0) replaced with getFirst()
* clean-up: CPU-intensive prepare() moved out of synchronized block
* regenerate-openmaptiles.sh 3cf77e2a542d8a369bb08bf2538cdde0b3effb2b (to match content of OMT PR 1423)
* unit test adjusted for POI office class changes
* regenerate-openmaptiles.sh master (to match content of OMT PR 1544)
* added charging_station implementation matching OMT PR 1544
* use setMinPixelSizeBelowZoom() instead of uniAreaToMinZoom()
* use setMinPixelSizeBelowZoom() instead of getFerryMinzoom()
* fixed unit test, to match recent tweaks
* regenerate-openmaptiles.sh master (to match content of OMT PR 1605)
* Fix university office/amenity collision (to match OSM PR 1607)
* Remove expressway from ramps
* OsmMarinePoint+ne_10m_geography_marine_polys join via name limited to 50km distance
* regenerate-openmaptiles.sh master (to match content of OMT PR 1604)
* Revert "Add aboriginal lands (as per OMT PR 1489)"
This reverts commit 899a0c5718734d5a746cdd84df2e1308614954c0.
* added handling of aboriginal_lands/OsmBoundaryPolygon into Boundary and Place layers
* big islands can now get rank lower than 3
* Add e-road and a-road for transportation z4
* testPolishHighwayIssue165() adjusted: e-road now takes precendence
* regenerate-openmaptiles.sh master (to match content of OMT PR 1627)
* regenerate-openmaptiles.sh fff7110aeb61882abfafe22d1618fbe6181d96cb (to match content of OMT PR 1620)
* Expanded road route attributes (to match OMT PR 1620)
* unrelated clean-up: use getFirst()
* adjusted handling or null and empty ref
* regenerate-openmaptiles.sh master (to match content of OMT PR 1620)
* pointOnSurface() used instead of centroid() to make sure the point is within the boundary
* adjusted deduplication of route_<n>_<something> attributes
* clean-up of some previous adjustments of importantMarinePoints
* clean-up: removed unused imports
* mvn spotless:apply
* OsmWaterPolygon minzoom calculation reverted to v3.14 and then adjusted for new 1/4 threshold
* part of process(Tables.OsmWaterPolygon, ...) moved to setupOsmWaterPolygonFeature()
* if feature with centerline has minzoom bellow Z9, use also a label point between minzoom and Z8
* bay point vs. centerline difference mentioned in the README
* testWaterNameBay for small bay adjusted, testWaterNameBay for big bay added
* testWaterNameLakeline and testWaterNameMultipleLakelines tweaked to use smaller test areas
* mvn spotless:apply
* added unit test which checks minzoom for admin_level=2 disputed border (derived from way)
* fixed missing admin_level=2 disputed borders at Z3
* landuse fix for Z5: include all features from ne_50m_urban_areas
* minDist and buffer tweaked for residential areas for Z6-Z8 to better match OpenMapTiles
* landuse fix for Z5: unit test updated
* bumped copyright statements
* added/adjusted acknowledgments
* fixed handling of Baikonur border in Kazachstan
* fixed handling of Baikonur border in Kazachstan (2)
* OSM boundaries only for Z5+, non-disputed for Z4+
* OSM boundaries only for Z5+, non-disputed for Z4+ - unit test adjusted
* OSM Lake IDs at low zooms
* testLakeZoomLevels(): NE lakes removed, checked now in testLakeNaturalEarth*()
* Use ne_10m_admin_0_boundary_lines_land_disputed to fix missing South Sudan boundary
* testNaturalEarthCountryBoundaries() extended to cover adjusted handling of ne_10m_admin_0_boundary_lines_land
* OSM lake area limit increased 2x to match smallest NE lake
* OSM lake area limit increased 2x even further to match smallest observed during Planet processing
* clean-up: SMALLEST_OSM_LAKE_AREA renamed to OSM_ID_MATCH_AREA_LIMIT to better match what it is
* mvn spotless:apply
* properly handle center line vs. point also for lakes
* clean-up: min() dropped since nothing sets minzoomCL to value higher than MINZOOM_BAY
* Revert e-road and a-road.
* Revert e-road and a-road. (follow-up)
* added unit test to cover: More roads for z4.
* improved handling of disputed KE:SS border: will work even if left/right reversed
* new PolygonIndex.getIntersecting() used for OSM lake ID matching + increased unit test coverage
* neLakeIndexes simplified into neLakeIndex
* test several NE lakes also in testLakeNaturalEarthByName()
* clean-up: synchronized NOT needed for PolygonIndex.put()
* neLakeNameMaps will stay as is, otherwise same names from several NE tables will clash
* neAllLakeInfos stays, since neLakeNameMaps contains only some and hard(er) to get all from neLakeIndex
* added test for NE lake ame collision: bigger one gets to be matched
* simplified NE->OSM lake matching: ignore small OSM lakes right away
* minor speed-up: compare intersection area instead of intersction area ratio
* fixed minor typo
* minor clean-up
* minor clean-up after previous changes
* adjusted handling of TopologyException to match previous tweaks
* mvn spotless:apply
* tweaked error message, to better mach cases when TopologyException occurs
* adjusted trunks: Z6+ by default, some from Z5, some even from Z4
* adjusted motorways: only some at Z4
* adjusted transportation: clip also construction links to Z9+
* unit tests adjusted to the recent changes
* use merge() to avoid problems with concurrent updates
* synchronized mergeId() added to avoid problems with concurrent updates
* clean-up after cc797f9a
* mvn spotless:apply
* label point in water_name refactored using setMinPixelSizeBelowZoom()
* clean-up: LOG2 removed since no longer used
* refactored handling of TopologyException for easier troubleshooting of problematic polygons
* fix invalid NE lake geometries + further TopologyException handling tweaks
* TopologyException handling removed, since no longer needed after adding NE geometry fixing
* clean-up after previous changes
* OpenMapTiles 3.15 was released so we can use proper tag now
* regenerate-openmaptiles.sh v3.15 to match official OpenMapTiles release
* Revert "clean-up after previous changes"
This reverts commit ee70382150a18acd738c6495da533240d2b18b3a.
* Revert "TopologyException handling removed, since no longer needed after adding NE geometry fixing"
This reverts commit d4fe59c0e5311e5475a057b9feb7c322bff56027.
* minor clean-up
* handle TopologyException also from intersects()
* further tweaks for TopologyException handling
* warnings demoted to debugs since we're going to re-try
* bumped copyright statements
* bumped copyright statements
* print errors+stack-traces only after retries with fixed polygons
since we are not able to raise issues with JTS if we do stuff with
invalid/unfixed polygons
* message about fixing NE lake geometry demoted: warn -> debug
* omt_water message adjusted to make it more clear what it relates to
* do NOT store fixed geom in separate variable to avoid 2nd fixing in fillOsmIdIntoNeLake()
* one more error message rephrased for clearer context
* Revert "print errors+stack-traces only after retries with fixed polygons"
This reverts commit 7440973169a6bb87f276bdf415edcdb0a3922c3c.
* strip stack-trace from TopologyException debug messages
* fix OSM element geometry if not valid before trying to match NE lake
This is same trick as done for NE lakes before.
Thanks to that we then do not need to handle TopologyExceptions and do
retries.
* clean-up
* clean-up: mvn spotless:apply
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2022, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
The vector tile schema has been developed by Klokan Technologies GmbH and
|
The vector tile schema has been developed by Klokan Technologies GmbH and
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -30,7 +30,8 @@ available options.
|
|||||||
lines, to revert this behavior set `--transportation-name-brunnel=true`
|
lines, to revert this behavior set `--transportation-name-brunnel=true`
|
||||||
- `rank` field on `mountain_peak` linestrings only has 3 levels (1: has wikipedia page and name, 2: has name, 3: no name
|
- `rank` field on `mountain_peak` linestrings only has 3 levels (1: has wikipedia page and name, 2: has name, 3: no name
|
||||||
or wikipedia page or name)
|
or wikipedia page or name)
|
||||||
- some line and polygon tolerances are different, can be tweaked with `--simplify-tolerance` parameter
|
- Some line and polygon tolerances are different, can be tweaked with `--simplify-tolerance` parameter
|
||||||
|
- For bigger bays whose label points show above Z9, centerline is used for Z9+
|
||||||
|
|
||||||
## Customizing
|
## Customizing
|
||||||
|
|
||||||
@@ -149,7 +150,7 @@ script with the
|
|||||||
OpenMapTiles release tag:
|
OpenMapTiles release tag:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/regenerate-openmaptiles.sh v3.14
|
./scripts/regenerate-openmaptiles.sh v3.15
|
||||||
```
|
```
|
||||||
|
|
||||||
Then follow the instructions it prints for reformatting generated code.
|
Then follow the instructions it prints for reformatting generated code.
|
||||||
@@ -157,7 +158,7 @@ Then follow the instructions it prints for reformatting generated code.
|
|||||||
If you want to regenerate from a different repository than the default openmaptiles, you can specify the url like this:
|
If you want to regenerate from a different repository than the default openmaptiles, you can specify the url like this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/regenerate-openmaptiles.sh v3.14 https://raw.githubusercontent.com/openmaptiles/openmaptiles/
|
./scripts/regenerate-openmaptiles.sh v3.15 https://raw.githubusercontent.com/openmaptiles/openmaptiles/
|
||||||
```
|
```
|
||||||
|
|
||||||
## License
|
## License
|
||||||
@@ -165,8 +166,8 @@ If you want to regenerate from a different repository than the default openmapti
|
|||||||
All code in this repository is under the [BSD license](./LICENSE.md) and the cartography decisions encoded in the schema
|
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).
|
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
|
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
|
**reference "OpenMapTiles"** with a link to https://openmaptiles.org/. Exceptions to attribution requirement can be granted
|
||||||
on request.
|
on request.
|
||||||
|
|
||||||
For a browsable electronic map based on OpenMapTiles and OpenStreetMap data, the
|
For a browsable electronic map based on OpenMapTiles and OpenStreetMap data, the
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ set -o errexit
|
|||||||
set -o pipefail
|
set -o pipefail
|
||||||
set -o nounset
|
set -o nounset
|
||||||
|
|
||||||
# TODO: change to "v3.15" once that is released
|
TAG="${1:-"v3.15"}"
|
||||||
TAG="${1:-"master"}"
|
|
||||||
echo "tag=${TAG}"
|
echo "tag=${TAG}"
|
||||||
|
|
||||||
BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}"
|
BASE_URL="${2:-"https://raw.githubusercontent.com/openmaptiles/openmaptiles/"}"
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ public class Generate {
|
|||||||
private static final String LINE_SEPARATOR = System.lineSeparator();
|
private static final String LINE_SEPARATOR = System.lineSeparator();
|
||||||
private static final String GENERATED_FILE_HEADER = """
|
private static final String GENERATED_FILE_HEADER = """
|
||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -133,7 +133,7 @@ public class Generate {
|
|||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
Arguments arguments = Arguments.fromArgsOrConfigFile(args);
|
Arguments arguments = Arguments.fromArgsOrConfigFile(args);
|
||||||
PlanetilerConfig planetilerConfig = PlanetilerConfig.from(arguments);
|
PlanetilerConfig planetilerConfig = PlanetilerConfig.from(arguments);
|
||||||
String tag = arguments.getString("tag", "openmaptiles tag to use", "v3.14.0");
|
String tag = arguments.getString("tag", "openmaptiles tag to use", "v3.15.0");
|
||||||
String baseUrl = arguments.getString("base-url", "the url used to download the openmaptiles.yml",
|
String baseUrl = arguments.getString("base-url", "the url used to download the openmaptiles.yml",
|
||||||
"https://raw.githubusercontent.com/openmaptiles/openmaptiles/");
|
"https://raw.githubusercontent.com/openmaptiles/openmaptiles/");
|
||||||
String base = baseUrl + tag + "/";
|
String base = baseUrl + tag + "/";
|
||||||
|
|||||||
@@ -4,12 +4,16 @@ import com.onthegomap.planetiler.Planetiler;
|
|||||||
import com.onthegomap.planetiler.config.Arguments;
|
import com.onthegomap.planetiler.config.Arguments;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import org.openmaptiles.generated.OpenMapTilesSchema;
|
import org.openmaptiles.generated.OpenMapTilesSchema;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main entrypoint for generating a map using the OpenMapTiles schema.
|
* Main entrypoint for generating a map using the OpenMapTiles schema.
|
||||||
*/
|
*/
|
||||||
public class OpenMapTilesMain {
|
public class OpenMapTilesMain {
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(OpenMapTilesMain.class);
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
run(Arguments.fromArgsOrConfigFile(args));
|
run(Arguments.fromArgsOrConfigFile(args));
|
||||||
}
|
}
|
||||||
@@ -52,5 +56,15 @@ public class OpenMapTilesMain {
|
|||||||
// override with --mbtiles=... argument or MBTILES=... env var or mbtiles=... in a config file
|
// override with --mbtiles=... argument or MBTILES=... env var or mbtiles=... in a config file
|
||||||
.setOutput("mbtiles", dataDir.resolve("output.mbtiles"))
|
.setOutput("mbtiles", dataDir.resolve("output.mbtiles"))
|
||||||
.run();
|
.run();
|
||||||
|
|
||||||
|
LOGGER.info("""
|
||||||
|
Acknowledgments
|
||||||
|
Generated vector tiles are produced work of OpenStreetMap data.
|
||||||
|
Such tiles are reusable under CC-BY license granted by OpenMapTiles team:
|
||||||
|
- https://github.com/openmaptiles/openmaptiles/#license
|
||||||
|
Maps made with these vector tiles must display a visible credit:
|
||||||
|
- © OpenMapTiles © OpenStreetMap contributors
|
||||||
|
Thanks to all free, open source software developers and Open Data Contributors!
|
||||||
|
""");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -49,14 +49,14 @@ import org.openmaptiles.Layer;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* All vector tile layer definitions, attributes, and allowed values generated from the
|
* All vector tile layer definitions, attributes, and allowed values generated from the
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/openmaptiles.yaml">OpenMapTiles vector tile schema
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/openmaptiles.yaml">OpenMapTiles vector tile schema
|
||||||
* master</a>.
|
* v3.15</a>.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public class OpenMapTilesSchema {
|
public class OpenMapTilesSchema {
|
||||||
public static final String NAME = "OpenMapTiles";
|
public static final String NAME = "OpenMapTiles";
|
||||||
public static final String DESCRIPTION = "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org";
|
public static final String DESCRIPTION = "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org";
|
||||||
public static final String VERSION = "3.14.0";
|
public static final String VERSION = "3.15.0";
|
||||||
public static final String ATTRIBUTION =
|
public static final String ATTRIBUTION =
|
||||||
"<a href=\"https://www.openmaptiles.org/\" target=\"_blank\">© OpenMapTiles</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>";
|
"<a href=\"https://www.openmaptiles.org/\" target=\"_blank\">© OpenMapTiles</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">© OpenStreetMap contributors</a>";
|
||||||
public static final List<String> LANGUAGES = List.of("am", "ar", "az", "be", "bg", "bn", "br", "bs", "ca", "co", "cs",
|
public static final List<String> LANGUAGES = List.of("am", "ar", "az", "be", "bg", "bn", "br", "bs", "ca", "co", "cs",
|
||||||
@@ -96,7 +96,7 @@ public class OpenMapTilesSchema {
|
|||||||
* boundaries show up. So you might not be able to use border styling for ocean water features.
|
* boundaries show up. So you might not be able to use border styling for ocean water features.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/water/water.yaml">water.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/water/water.yaml">water.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Water extends Layer {
|
public interface Water extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -182,7 +182,7 @@ public class OpenMapTilesSchema {
|
|||||||
public static final MultiExpression<String> Class =
|
public static final MultiExpression<String> Class =
|
||||||
MultiExpression.of(List.of(MultiExpression.entry("dock", matchAny("waterway", "dock")),
|
MultiExpression.of(List.of(MultiExpression.entry("dock", matchAny("waterway", "dock")),
|
||||||
MultiExpression.entry("river", matchAny("water", "river", "stream", "canal", "ditch", "drain")),
|
MultiExpression.entry("river", matchAny("water", "river", "stream", "canal", "ditch", "drain")),
|
||||||
MultiExpression.entry("pond", matchAny("water", "pond", "basin", "wastewater")),
|
MultiExpression.entry("pond", matchAny("water", "pond", "basin", "wastewater", "salt_pond")),
|
||||||
MultiExpression.entry("lake", FALSE), MultiExpression.entry("ocean", FALSE),
|
MultiExpression.entry("lake", FALSE), MultiExpression.entry("ocean", FALSE),
|
||||||
MultiExpression.entry("swimming_pool", matchAny("leisure", "swimming_pool"))));
|
MultiExpression.entry("swimming_pool", matchAny("leisure", "swimming_pool"))));
|
||||||
}
|
}
|
||||||
@@ -195,7 +195,7 @@ public class OpenMapTilesSchema {
|
|||||||
* field applied. Waterways do not have a <code>subclass</code> field.
|
* field applied. Waterways do not have a <code>subclass</code> field.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/waterway/waterway.yaml">waterway.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/waterway/waterway.yaml">waterway.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Waterway extends Layer {
|
public interface Waterway extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -287,7 +287,7 @@ public class OpenMapTilesSchema {
|
|||||||
* layer is to style wood (<code>class=wood</code>) and grass (<code>class=grass</code>) areas.
|
* layer is to style wood (<code>class=wood</code>) and grass (<code>class=grass</code>) areas.
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/landcover/landcover.yaml">landcover.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/landcover/landcover.yaml">landcover.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Landcover extends Layer {
|
public interface Landcover extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -444,7 +444,7 @@ public class OpenMapTilesSchema {
|
|||||||
* residential (urban) areas and at higher zoom levels mostly OSM <code>landuse</code> tags.
|
* residential (urban) areas and at higher zoom levels mostly OSM <code>landuse</code> tags.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/landuse/landuse.yaml">landuse.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/landuse/landuse.yaml">landuse.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Landuse extends Layer {
|
public interface Landuse extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -540,7 +540,7 @@ public class OpenMapTilesSchema {
|
|||||||
* <a href="http://wiki.openstreetmap.org/wiki/Tag:natural%3Dpeak">Natural peaks</a>
|
* <a href="http://wiki.openstreetmap.org/wiki/Tag:natural%3Dpeak">Natural peaks</a>
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/mountain_peak/mountain_peak.yaml">mountain_peak.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/mountain_peak/mountain_peak.yaml">mountain_peak.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface MountainPeak extends Layer {
|
public interface MountainPeak extends Layer {
|
||||||
double BUFFER_SIZE = 64.0;
|
double BUFFER_SIZE = 64.0;
|
||||||
@@ -563,7 +563,10 @@ public class OpenMapTilesSchema {
|
|||||||
* removed in a future release in favor of <code>name:en</code>.
|
* removed in a future release in favor of <code>name:en</code>.
|
||||||
*/
|
*/
|
||||||
public static final String NAME_EN = "name_en";
|
public static final String NAME_EN = "name_en";
|
||||||
/** German name <code>name:de</code> if available, otherwise <code>name</code> or <code>name:en</code>. */
|
/**
|
||||||
|
* German name <code>name:de</code> if available, otherwise <code>name</code> or <code>name:en</code>. This is
|
||||||
|
* deprecated and will be removed in a future release in favor of <code>name:de</code>.
|
||||||
|
*/
|
||||||
public static final String NAME_DE = "name_de";
|
public static final String NAME_DE = "name_de";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -621,7 +624,7 @@ public class OpenMapTilesSchema {
|
|||||||
* <a href="https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve"><code>leisure=nature_reserve</code></a>.
|
* <a href="https://wiki.openstreetmap.org/wiki/Tag:leisure%3Dnature_reserve"><code>leisure=nature_reserve</code></a>.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/park/park.yaml">park.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/park/park.yaml">park.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Park extends Layer {
|
public interface Park extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -684,7 +687,7 @@ public class OpenMapTilesSchema {
|
|||||||
* but for most styles it makes sense to just style <code>admin_level=2</code> and <code>admin_level=4</code>.
|
* but for most styles it makes sense to just style <code>admin_level=2</code> and <code>admin_level=4</code>.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/boundary/boundary.yaml">boundary.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/boundary/boundary.yaml">boundary.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Boundary extends Layer {
|
public interface Boundary extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -794,7 +797,7 @@ public class OpenMapTilesSchema {
|
|||||||
* in the <strong>aeroway</strong> layer.
|
* in the <strong>aeroway</strong> layer.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/aeroway/aeroway.yaml">aeroway.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/aeroway/aeroway.yaml">aeroway.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Aeroway extends Layer {
|
public interface Aeroway extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -854,7 +857,7 @@ public class OpenMapTilesSchema {
|
|||||||
* features like plazas.
|
* features like plazas.
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/transportation/transportation.yaml">transportation.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/transportation/transportation.yaml">transportation.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Transportation extends Layer {
|
public interface Transportation extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -1199,7 +1202,7 @@ public class OpenMapTilesSchema {
|
|||||||
* location:underground are excluded.
|
* location:underground are excluded.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/building/building.yaml">building.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/building/building.yaml">building.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Building extends Layer {
|
public interface Building extends Layer {
|
||||||
double BUFFER_SIZE = 4.0;
|
double BUFFER_SIZE = 4.0;
|
||||||
@@ -1241,7 +1244,7 @@ public class OpenMapTilesSchema {
|
|||||||
* from OSM water bodies. Only the most important lakes contain labels.
|
* from OSM water bodies. Only the most important lakes contain labels.
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/water_name/water_name.yaml">water_name.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/water_name/water_name.yaml">water_name.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface WaterName extends Layer {
|
public interface WaterName extends Layer {
|
||||||
double BUFFER_SIZE = 256.0;
|
double BUFFER_SIZE = 256.0;
|
||||||
@@ -1318,7 +1321,7 @@ public class OpenMapTilesSchema {
|
|||||||
* while for other roads you should use <code>name</code>.
|
* while for other roads you should use <code>name</code>.
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/transportation_name/transportation_name.yaml">transportation_name.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/transportation_name/transportation_name.yaml">transportation_name.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface TransportationName extends Layer {
|
public interface TransportationName extends Layer {
|
||||||
double BUFFER_SIZE = 8.0;
|
double BUFFER_SIZE = 8.0;
|
||||||
@@ -1590,7 +1593,7 @@ public class OpenMapTilesSchema {
|
|||||||
* create a text hierarchy.
|
* create a text hierarchy.
|
||||||
*
|
*
|
||||||
* Generated from
|
* Generated from
|
||||||
* <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/place/place.yaml">place.yaml</a>
|
* <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/place/place.yaml">place.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Place extends Layer {
|
public interface Place extends Layer {
|
||||||
double BUFFER_SIZE = 256.0;
|
double BUFFER_SIZE = 256.0;
|
||||||
@@ -1714,7 +1717,7 @@ public class OpenMapTilesSchema {
|
|||||||
* tag are prioritized for preservation).
|
* tag are prioritized for preservation).
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/housenumber/housenumber.yaml">housenumber.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/housenumber/housenumber.yaml">housenumber.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Housenumber extends Layer {
|
public interface Housenumber extends Layer {
|
||||||
double BUFFER_SIZE = 8.0;
|
double BUFFER_SIZE = 8.0;
|
||||||
@@ -1746,7 +1749,7 @@ public class OpenMapTilesSchema {
|
|||||||
* <a href="http://wiki.openstreetmap.org/wiki/Points_of_interest">Points of interests</a> containing a of a variety
|
* <a href="http://wiki.openstreetmap.org/wiki/Points_of_interest">Points of interests</a> containing a of a variety
|
||||||
* of OpenStreetMap tags. Mostly contains amenities, sport, shop and tourist POIs.
|
* of OpenStreetMap tags. Mostly contains amenities, sport, shop and tourist POIs.
|
||||||
*
|
*
|
||||||
* Generated from <a href="https://github.com/openmaptiles/openmaptiles/blob/master/layers/poi/poi.yaml">poi.yaml</a>
|
* Generated from <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/poi/poi.yaml">poi.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface Poi extends Layer {
|
public interface Poi extends Layer {
|
||||||
double BUFFER_SIZE = 64.0;
|
double BUFFER_SIZE = 64.0;
|
||||||
@@ -1990,7 +1993,7 @@ public class OpenMapTilesSchema {
|
|||||||
* <a href="http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome">Aerodrome labels</a>
|
* <a href="http://wiki.openstreetmap.org/wiki/Tag:aeroway%3Daerodrome">Aerodrome labels</a>
|
||||||
*
|
*
|
||||||
* Generated from <a href=
|
* Generated from <a href=
|
||||||
* "https://github.com/openmaptiles/openmaptiles/blob/master/layers/aerodrome_label/aerodrome_label.yaml">aerodrome_label.yaml</a>
|
* "https://github.com/openmaptiles/openmaptiles/blob/v3.15/layers/aerodrome_label/aerodrome_label.yaml">aerodrome_label.yaml</a>
|
||||||
*/
|
*/
|
||||||
public interface AerodromeLabel extends Layer {
|
public interface AerodromeLabel extends Layer {
|
||||||
double BUFFER_SIZE = 64.0;
|
double BUFFER_SIZE = 64.0;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -50,7 +50,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions
|
* OSM element parsers generated from the <a href="https://github.com/omniscale/imposm3">imposm3</a> table definitions
|
||||||
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/master/openmaptiles.yaml">OpenMapTiles vector tile
|
* in the <a href="https://github.com/openmaptiles/openmaptiles/blob/v3.15/openmaptiles.yaml">OpenMapTiles vector tile
|
||||||
* schema</a>.
|
* schema</a>.
|
||||||
*
|
*
|
||||||
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the columns
|
* These filter and parse the raw OSM key/value attribute pairs on tags into records with fields that match the columns
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -121,6 +121,8 @@ public class Boundary implements
|
|||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(Boundary.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(Boundary.class);
|
||||||
private static final double COUNTRY_TEST_OFFSET = GeoUtils.metersToPixelAtEquator(0, 10) / 256d;
|
private static final double COUNTRY_TEST_OFFSET = GeoUtils.metersToPixelAtEquator(0, 10) / 256d;
|
||||||
|
private static final String COUNTRY_KE = "Kenya";
|
||||||
|
private static final String COUNTRY_SS = "South Sudan";
|
||||||
private final Stats stats;
|
private final Stats stats;
|
||||||
private final boolean addCountryNames;
|
private final boolean addCountryNames;
|
||||||
private final boolean onlyOsmBoundaries;
|
private final boolean onlyOsmBoundaries;
|
||||||
@@ -179,8 +181,21 @@ public class Boundary implements
|
|||||||
BoundaryInfo info = switch (table) {
|
BoundaryInfo info = switch (table) {
|
||||||
case "ne_110m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 0, 0);
|
case "ne_110m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 0, 0);
|
||||||
case "ne_50m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 1, 3);
|
case "ne_50m_admin_0_boundary_lines_land" -> new BoundaryInfo(2, 1, 3);
|
||||||
case "ne_10m_admin_0_boundary_lines_land" -> feature.hasTag("featurecla", "Lease Limit") ? null :
|
case "ne_10m_admin_0_boundary_lines_land" -> {
|
||||||
|
boolean isDisputedSouthSudanAndKenya = false;
|
||||||
|
if (disputed) {
|
||||||
|
String left = feature.getString("adm0_left");
|
||||||
|
String right = feature.getString("adm0_right");
|
||||||
|
if (COUNTRY_SS.equals(left)) {
|
||||||
|
isDisputedSouthSudanAndKenya = COUNTRY_KE.equals(right);
|
||||||
|
} else if (COUNTRY_KE.equals(left)) {
|
||||||
|
isDisputedSouthSudanAndKenya = COUNTRY_SS.equals(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
yield isDisputedSouthSudanAndKenya ? new BoundaryInfo(2, 1, 4) :
|
||||||
|
feature.hasTag("featurecla", "Lease limit") ? null :
|
||||||
new BoundaryInfo(2, 4, 4);
|
new BoundaryInfo(2, 4, 4);
|
||||||
|
}
|
||||||
case "ne_10m_admin_1_states_provinces_lines" -> {
|
case "ne_10m_admin_1_states_provinces_lines" -> {
|
||||||
Double minZoom = Parse.parseDoubleOrNull(feature.getTag("min_zoom"));
|
Double minZoom = Parse.parseDoubleOrNull(feature.getTag("min_zoom"));
|
||||||
yield minZoom != null && minZoom <= 7 ? new BoundaryInfo(4, 1, 4) :
|
yield minZoom != null && minZoom <= 7 ? new BoundaryInfo(4, 1, 4) :
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2023, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2023, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -52,6 +52,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
import org.openmaptiles.OpenMapTilesProfile;
|
import org.openmaptiles.OpenMapTilesProfile;
|
||||||
import org.openmaptiles.generated.OpenMapTilesSchema;
|
import org.openmaptiles.generated.OpenMapTilesSchema;
|
||||||
import org.openmaptiles.generated.Tables;
|
import org.openmaptiles.generated.Tables;
|
||||||
@@ -74,6 +75,14 @@ public class Landuse implements
|
|||||||
7, 2,
|
7, 2,
|
||||||
6, 1
|
6, 1
|
||||||
));
|
));
|
||||||
|
private static final TreeMap<Integer, Double> MINDIST_AND_BUFFER_SIZES = new TreeMap<>(Map.of(
|
||||||
|
5, 0.1,
|
||||||
|
// there is quite huge jump between Z5:NE and Z6:OSM => bigger generalization needed to make the transition more smooth
|
||||||
|
6, 0.5,
|
||||||
|
7, 0.25,
|
||||||
|
8, 0.125,
|
||||||
|
Integer.MAX_VALUE, 0.1
|
||||||
|
));
|
||||||
private static final Set<String> Z6_CLASSES = Set.of(
|
private static final Set<String> Z6_CLASSES = Set.of(
|
||||||
FieldValues.CLASS_RESIDENTIAL,
|
FieldValues.CLASS_RESIDENTIAL,
|
||||||
FieldValues.CLASS_SUBURB,
|
FieldValues.CLASS_SUBURB,
|
||||||
@@ -87,11 +96,10 @@ public class Landuse implements
|
|||||||
public void processNaturalEarth(String table, SourceFeature feature, FeatureCollector features) {
|
public void processNaturalEarth(String table, SourceFeature feature, FeatureCollector features) {
|
||||||
if ("ne_50m_urban_areas".equals(table)) {
|
if ("ne_50m_urban_areas".equals(table)) {
|
||||||
Double scalerank = Parse.parseDoubleOrNull(feature.getTag("scalerank"));
|
Double scalerank = Parse.parseDoubleOrNull(feature.getTag("scalerank"));
|
||||||
if (scalerank != null && scalerank <= 2) {
|
int minzoom = (scalerank != null && scalerank <= 2) ? 4 : 5;
|
||||||
features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE)
|
features.polygon(LAYER_NAME).setBufferPixels(BUFFER_SIZE)
|
||||||
.setAttr(Fields.CLASS, FieldValues.CLASS_RESIDENTIAL)
|
.setAttr(Fields.CLASS, FieldValues.CLASS_RESIDENTIAL)
|
||||||
.setZoomRange(4, 5);
|
.setZoomRange(minzoom, 5);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,10 +143,14 @@ public class Landuse implements
|
|||||||
result.add(item);
|
result.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var merged = zoom <= 12 ?
|
List<VectorTile.Feature> merged;
|
||||||
FeatureMerge.mergeNearbyPolygons(toMerge, 1, 1, 0.1, 0.1) :
|
if (zoom <= 12) {
|
||||||
|
double minDistAndBuffer = MINDIST_AND_BUFFER_SIZES.ceilingEntry(zoom).getValue();
|
||||||
|
merged = FeatureMerge.mergeNearbyPolygons(toMerge, 1, 1, minDistAndBuffer, minDistAndBuffer);
|
||||||
|
} else {
|
||||||
// reduces size of some heavy z13-14 tiles with lots of small polygons
|
// reduces size of some heavy z13-14 tiles with lots of small polygons
|
||||||
FeatureMerge.mergeMultiPolygon(toMerge);
|
merged = FeatureMerge.mergeMultiPolygon(toMerge);
|
||||||
|
}
|
||||||
result.addAll(merged);
|
result.addAll(merged);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -139,13 +139,23 @@ public class Transportation implements
|
|||||||
private static final Set<String> ACCESS_NO_VALUES = Set.of(
|
private static final Set<String> ACCESS_NO_VALUES = Set.of(
|
||||||
"private", "no"
|
"private", "no"
|
||||||
);
|
);
|
||||||
private static final Set<RouteNetwork> TRUNK_AS_MOTORWAY_BY_NETWORK = Set.of(
|
// ... and also Z4_MOTORWAY_NY_NETWORK, except those in Z5_MOTORWAYS_BY_NETWORK:
|
||||||
|
private static final Set<RouteNetwork> Z5_TRUNK_BY_NETWORK = Set.of(
|
||||||
RouteNetwork.CA_TRANSCANADA,
|
RouteNetwork.CA_TRANSCANADA,
|
||||||
RouteNetwork.CA_PROVINCIAL_ARTERIAL,
|
RouteNetwork.CA_PROVINCIAL_ARTERIAL,
|
||||||
RouteNetwork.US_INTERSTATE,
|
RouteNetwork.US_INTERSTATE,
|
||||||
|
RouteNetwork.US_HIGHWAY,
|
||||||
|
RouteNetwork.GB_MOTORWAY,
|
||||||
|
RouteNetwork.GB_TRUNK,
|
||||||
|
RouteNetwork.IE_MOTORWAY,
|
||||||
|
RouteNetwork.IE_NATIONAL,
|
||||||
RouteNetwork.E_ROAD,
|
RouteNetwork.E_ROAD,
|
||||||
RouteNetwork.A_ROAD
|
RouteNetwork.A_ROAD
|
||||||
);
|
);
|
||||||
|
private static final Set<RouteNetwork> Z5_MOTORWAYS_BY_NETWORK = Set.of(
|
||||||
|
RouteNetwork.GB_TRUNK,
|
||||||
|
RouteNetwork.US_HIGHWAY
|
||||||
|
);
|
||||||
private static final Set<String> CA_AB_PRIMARY_AS_ARTERIAL_BY_REF = Set.of(
|
private static final Set<String> CA_AB_PRIMARY_AS_ARTERIAL_BY_REF = Set.of(
|
||||||
"2", "3", "4"
|
"2", "3", "4"
|
||||||
);
|
);
|
||||||
@@ -194,7 +204,7 @@ public class Transportation implements
|
|||||||
entry(FieldValues.CLASS_BUS_GUIDEWAY, 11),
|
entry(FieldValues.CLASS_BUS_GUIDEWAY, 11),
|
||||||
entry(FieldValues.CLASS_SECONDARY, 9),
|
entry(FieldValues.CLASS_SECONDARY, 9),
|
||||||
entry(FieldValues.CLASS_PRIMARY, 7),
|
entry(FieldValues.CLASS_PRIMARY, 7),
|
||||||
entry(FieldValues.CLASS_TRUNK, 5),
|
entry(FieldValues.CLASS_TRUNK, 6),
|
||||||
entry(FieldValues.CLASS_MOTORWAY, 4)
|
entry(FieldValues.CLASS_MOTORWAY, 4)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -245,6 +255,40 @@ public class Transportation implements
|
|||||||
return "residential".equals(highway) || "unclassified".equals(highway);
|
return "residential".equals(highway) || "unclassified".equals(highway);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isTrunkForZ5(String highway, List<RouteRelation> routeRelations) {
|
||||||
|
// Allow trunk roads that are part of a nation's most important route network to show at z5
|
||||||
|
if (!"trunk".equals(highway)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return routeRelations.stream()
|
||||||
|
.map(RouteRelation::networkType)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.anyMatch(Z5_TRUNK_BY_NETWORK::contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isMotorwayWithNetworkForZ4(List<RouteRelation> routeRelations) {
|
||||||
|
// All roads in network included in osm_national_network except gb-trunk and us-highway
|
||||||
|
return routeRelations.stream()
|
||||||
|
.map(RouteRelation::networkType)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(nt -> !Z5_MOTORWAYS_BY_NETWORK.contains(nt))
|
||||||
|
.anyMatch(Z5_TRUNK_BY_NETWORK::contains);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isMotorwayWoNetworkForZ4(List<RouteRelation> routeRelations) {
|
||||||
|
// All motorways without network (e.g. EU, Asia, South America)
|
||||||
|
return routeRelations.stream()
|
||||||
|
.map(RouteRelation::networkType)
|
||||||
|
.noneMatch(Objects::nonNull);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isMotorwayForZ4(List<RouteRelation> routeRelations) {
|
||||||
|
if (isMotorwayWoNetworkForZ4(routeRelations)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return isMotorwayWithNetworkForZ4(routeRelations);
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isDrivewayOrParkingAisle(String service) {
|
private static boolean isDrivewayOrParkingAisle(String service) {
|
||||||
return FieldValues.SERVICE_PARKING_AISLE.equals(service) || FieldValues.SERVICE_DRIVEWAY.equals(service);
|
return FieldValues.SERVICE_PARKING_AISLE.equals(service) || FieldValues.SERVICE_DRIVEWAY.equals(service);
|
||||||
}
|
}
|
||||||
@@ -296,11 +340,7 @@ public class Transportation implements
|
|||||||
String colour = coalesce(
|
String colour = coalesce(
|
||||||
nullIfEmpty(relation.getString("colour")), nullIfEmpty(relation.getString("ref:colour")));
|
nullIfEmpty(relation.getString("colour")), nullIfEmpty(relation.getString("ref:colour")));
|
||||||
|
|
||||||
if ("e-road".equals(network)) {
|
if ("US:I".equals(network)) {
|
||||||
networkType = RouteNetwork.E_ROAD;
|
|
||||||
} else if ("AsianHighway".equals(network)) {
|
|
||||||
networkType = RouteNetwork.A_ROAD;
|
|
||||||
} else if ("US:I".equals(network)) {
|
|
||||||
networkType = RouteNetwork.US_INTERSTATE;
|
networkType = RouteNetwork.US_INTERSTATE;
|
||||||
} else if ("US:US".equals(network)) {
|
} else if ("US:US".equals(network)) {
|
||||||
networkType = RouteNetwork.US_HIGHWAY;
|
networkType = RouteNetwork.US_HIGHWAY;
|
||||||
@@ -495,6 +535,7 @@ public class Transportation implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
String highway = element.highway();
|
String highway = element.highway();
|
||||||
|
String construction = element.construction();
|
||||||
|
|
||||||
int minzoom;
|
int minzoom;
|
||||||
if ("pier".equals(element.manMade())) {
|
if ("pier".equals(element.manMade())) {
|
||||||
@@ -508,18 +549,22 @@ public class Transportation implements
|
|||||||
case FieldValues.CLASS_TRACK, FieldValues.CLASS_PATH -> routeRank == 1 ? 12 :
|
case FieldValues.CLASS_TRACK, FieldValues.CLASS_PATH -> routeRank == 1 ? 12 :
|
||||||
(z13Paths || !nullOrEmpty(element.name()) || routeRank <= 2 || !nullOrEmpty(element.sacScale())) ? 13 : 14;
|
(z13Paths || !nullOrEmpty(element.name()) || routeRank <= 2 || !nullOrEmpty(element.sacScale())) ? 13 : 14;
|
||||||
case FieldValues.CLASS_TRUNK -> {
|
case FieldValues.CLASS_TRUNK -> {
|
||||||
// trunks in some networks to have same min. zoom as highway = "motorway"
|
boolean z5trunk = isTrunkForZ5(highway, routeRelations);
|
||||||
String clazz = routeRelations.stream()
|
// and if it is good for Z5, it may be good also for Z4 (see CLASS_MOTORWAY bellow):
|
||||||
.map(RouteRelation::networkType)
|
String clazz = FieldValues.CLASS_TRUNK;
|
||||||
.filter(Objects::nonNull)
|
if (z5trunk && isMotorwayWithNetworkForZ4(routeRelations)) {
|
||||||
.anyMatch(TRUNK_AS_MOTORWAY_BY_NETWORK::contains) ? FieldValues.CLASS_MOTORWAY : FieldValues.CLASS_TRUNK;
|
clazz = FieldValues.CLASS_MOTORWAY;
|
||||||
yield MINZOOMS.getOrDefault(clazz, Integer.MAX_VALUE);
|
z5trunk = false;
|
||||||
}
|
}
|
||||||
|
yield (z5trunk) ? 5 : MINZOOMS.getOrDefault(clazz, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
case FieldValues.CLASS_MOTORWAY -> isMotorwayForZ4(routeRelations) ?
|
||||||
|
MINZOOMS.getOrDefault(FieldValues.CLASS_MOTORWAY, Integer.MAX_VALUE) : 5;
|
||||||
default -> MINZOOMS.getOrDefault(baseClass, Integer.MAX_VALUE);
|
default -> MINZOOMS.getOrDefault(baseClass, Integer.MAX_VALUE);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLink(highway)) {
|
if (isLink(highway) || isLink(construction)) {
|
||||||
minzoom = Math.max(minzoom, 9);
|
minzoom = Math.max(minzoom, 9);
|
||||||
}
|
}
|
||||||
return minzoom;
|
return minzoom;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -42,14 +42,24 @@ import com.onthegomap.planetiler.VectorTile;
|
|||||||
import com.onthegomap.planetiler.config.PlanetilerConfig;
|
import com.onthegomap.planetiler.config.PlanetilerConfig;
|
||||||
import com.onthegomap.planetiler.expression.MultiExpression;
|
import com.onthegomap.planetiler.expression.MultiExpression;
|
||||||
import com.onthegomap.planetiler.geo.GeometryException;
|
import com.onthegomap.planetiler.geo.GeometryException;
|
||||||
|
import com.onthegomap.planetiler.geo.PolygonIndex;
|
||||||
|
import com.onthegomap.planetiler.reader.SimpleFeature;
|
||||||
import com.onthegomap.planetiler.reader.SourceFeature;
|
import com.onthegomap.planetiler.reader.SourceFeature;
|
||||||
import com.onthegomap.planetiler.stats.Stats;
|
import com.onthegomap.planetiler.stats.Stats;
|
||||||
import com.onthegomap.planetiler.util.Translations;
|
import com.onthegomap.planetiler.util.Translations;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.locationtech.jts.geom.Geometry;
|
||||||
|
import org.locationtech.jts.geom.util.GeometryFixer;
|
||||||
import org.openmaptiles.OpenMapTilesProfile;
|
import org.openmaptiles.OpenMapTilesProfile;
|
||||||
import org.openmaptiles.generated.OpenMapTilesSchema;
|
import org.openmaptiles.generated.OpenMapTilesSchema;
|
||||||
import org.openmaptiles.generated.Tables;
|
import org.openmaptiles.generated.Tables;
|
||||||
import org.openmaptiles.util.Utils;
|
import org.openmaptiles.util.Utils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the logic for generating map elements for oceans and lakes in the {@code water} layer from source features.
|
* Defines the logic for generating map elements for oceans and lakes in the {@code water} layer from source features.
|
||||||
@@ -62,7 +72,8 @@ public class Water implements
|
|||||||
Tables.OsmWaterPolygon.Handler,
|
Tables.OsmWaterPolygon.Handler,
|
||||||
OpenMapTilesProfile.NaturalEarthProcessor,
|
OpenMapTilesProfile.NaturalEarthProcessor,
|
||||||
OpenMapTilesProfile.OsmWaterPolygonProcessor,
|
OpenMapTilesProfile.OsmWaterPolygonProcessor,
|
||||||
ForwardingProfile.FeaturePostProcessor {
|
ForwardingProfile.FeaturePostProcessor,
|
||||||
|
OpenMapTilesProfile.FinishHandler {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* At low zoom levels, use natural earth for oceans and major lakes, and at high zoom levels
|
* At low zoom levels, use natural earth for oceans and major lakes, and at high zoom levels
|
||||||
@@ -71,12 +82,22 @@ public class Water implements
|
|||||||
* which infers ocean polygons by preprocessing all coastline elements.
|
* which infers ocean polygons by preprocessing all coastline elements.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(Water.class);
|
||||||
|
// smallest NE lake is around 4.42E-13, smallest matching OSM lake is 9.34E-13, this is slightly bellow that
|
||||||
|
// and approx. 33% of OSM features are smaller than this, hence to save some CPU cycles:
|
||||||
|
private static final double OSM_ID_MATCH_AREA_LIMIT = Math.pow(4, -20);
|
||||||
|
|
||||||
private final MultiExpression.Index<String> classMapping;
|
private final MultiExpression.Index<String> classMapping;
|
||||||
private final PlanetilerConfig config;
|
private final PlanetilerConfig config;
|
||||||
|
private final Stats stats;
|
||||||
|
private PolygonIndex<LakeInfo> neLakeIndex = PolygonIndex.create();
|
||||||
|
private final Map<String, Map<String, LakeInfo>> neLakeNameMaps = new ConcurrentHashMap<>();
|
||||||
|
private final List<LakeInfo> neAllLakeInfos = new ArrayList<>();
|
||||||
|
|
||||||
public Water(Translations translations, PlanetilerConfig config, Stats stats) {
|
public Water(Translations translations, PlanetilerConfig config, Stats stats) {
|
||||||
this.classMapping = FieldMappings.Class.index();
|
this.classMapping = FieldMappings.Class.index();
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.stats = stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,19 +107,58 @@ public class Water implements
|
|||||||
case "ne_110m_ocean" -> new WaterInfo(0, 1, FieldValues.CLASS_OCEAN);
|
case "ne_110m_ocean" -> new WaterInfo(0, 1, FieldValues.CLASS_OCEAN);
|
||||||
case "ne_50m_ocean" -> new WaterInfo(2, 4, FieldValues.CLASS_OCEAN);
|
case "ne_50m_ocean" -> new WaterInfo(2, 4, FieldValues.CLASS_OCEAN);
|
||||||
case "ne_10m_ocean" -> new WaterInfo(5, 5, FieldValues.CLASS_OCEAN);
|
case "ne_10m_ocean" -> new WaterInfo(5, 5, FieldValues.CLASS_OCEAN);
|
||||||
|
|
||||||
// TODO: get OSM ID from low-zoom natural earth lakes
|
|
||||||
case "ne_110m_lakes" -> new WaterInfo(0, 1, FieldValues.CLASS_LAKE);
|
|
||||||
case "ne_50m_lakes" -> new WaterInfo(2, 3, FieldValues.CLASS_LAKE);
|
|
||||||
case "ne_10m_lakes" -> new WaterInfo(4, 5, FieldValues.CLASS_LAKE);
|
|
||||||
default -> null;
|
default -> null;
|
||||||
};
|
};
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
|
setupNeWaterFeature(features, info.minZoom, info.maxZoom, info.clazz, null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LakeInfo lakeInfo = switch (table) {
|
||||||
|
case "ne_110m_lakes" -> new LakeInfo(0, 1, FieldValues.CLASS_LAKE);
|
||||||
|
case "ne_50m_lakes" -> new LakeInfo(2, 3, FieldValues.CLASS_LAKE);
|
||||||
|
case "ne_10m_lakes" -> new LakeInfo(4, 5, FieldValues.CLASS_LAKE);
|
||||||
|
default -> null;
|
||||||
|
};
|
||||||
|
if (lakeInfo != null) {
|
||||||
|
try {
|
||||||
|
var geom = feature.worldGeometry();
|
||||||
|
if (geom.isValid()) {
|
||||||
|
lakeInfo.geom = geom;
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Fixing geometry of NE lake {}", feature.getLong("ne_id"));
|
||||||
|
lakeInfo.geom = GeometryFixer.fix(geom);
|
||||||
|
}
|
||||||
|
lakeInfo.name = feature.getString("name");
|
||||||
|
lakeInfo.neId = feature.getLong("ne_id");
|
||||||
|
|
||||||
|
var neLakeNameMap = neLakeNameMaps.computeIfAbsent(table, t -> new ConcurrentHashMap<>());
|
||||||
|
|
||||||
|
// need to externally synchronize inserts into ArrayList
|
||||||
|
synchronized (this) {
|
||||||
|
neAllLakeInfos.add(lakeInfo);
|
||||||
|
}
|
||||||
|
neLakeIndex.put(geom, lakeInfo);
|
||||||
|
if (lakeInfo.name != null) {
|
||||||
|
// on name collision, bigger lake gets on the name list
|
||||||
|
neLakeNameMap.merge(lakeInfo.name, lakeInfo,
|
||||||
|
(prev, next) -> next.geom.getArea() > prev.geom.getArea() ? next : prev);
|
||||||
|
}
|
||||||
|
} catch (GeometryException e) {
|
||||||
|
e.log(stats, "omt_water_ne",
|
||||||
|
"Error getting geometry for natural earth feature " + table + " " + feature.getTag("ogc_fid"));
|
||||||
|
// make sure we have this NE lake even if without OSM ID
|
||||||
|
setupNeWaterFeature(features, lakeInfo.minZoom, lakeInfo.maxZoom, lakeInfo.clazz, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupNeWaterFeature(FeatureCollector features, int minZoom, int maxZoom, String clazz, Long osmId) {
|
||||||
features.polygon(LAYER_NAME)
|
features.polygon(LAYER_NAME)
|
||||||
.setBufferPixels(BUFFER_SIZE)
|
.setBufferPixels(BUFFER_SIZE)
|
||||||
.setZoomRange(info.minZoom, info.maxZoom)
|
.setZoomRange(minZoom, maxZoom)
|
||||||
.setAttr(Fields.CLASS, info.clazz);
|
.setAttr(Fields.CLASS, clazz)
|
||||||
}
|
.setAttr(Fields.ID, osmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -121,6 +181,87 @@ public class Water implements
|
|||||||
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
|
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
|
||||||
.setAttrWithMinzoom(Fields.BRUNNEL, Utils.brunnel(element.isBridge(), element.isTunnel()), 12)
|
.setAttrWithMinzoom(Fields.BRUNNEL, Utils.brunnel(element.isBridge(), element.isTunnel()), 12)
|
||||||
.setAttr(Fields.CLASS, clazz);
|
.setAttr(Fields.CLASS, clazz);
|
||||||
|
|
||||||
|
try {
|
||||||
|
attemptNeLakeIdMapping(element);
|
||||||
|
} catch (GeometryException e) {
|
||||||
|
e.log(stats, "omt_water",
|
||||||
|
"Unable to add OSM ID to natural earth water feature", config.logJtsExceptions());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void attemptNeLakeIdMapping(Tables.OsmWaterPolygon element) throws GeometryException {
|
||||||
|
// if OSM lake is too small for Z6 (e.g. area bellow ~4px) we assume there is no matching NE lake
|
||||||
|
var geom = element.source().worldGeometry();
|
||||||
|
if (geom.getArea() < OSM_ID_MATCH_AREA_LIMIT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!geom.isValid()) {
|
||||||
|
geom = GeometryFixer.fix(geom);
|
||||||
|
stats.dataError("omt_fix_water_before_ne_intersect");
|
||||||
|
LOGGER.debug("Fixing geometry of OSM element {} before attempt to add ID to natural earth water feature",
|
||||||
|
element.source().id());
|
||||||
|
}
|
||||||
|
|
||||||
|
// match by name:
|
||||||
|
boolean match = false;
|
||||||
|
if (element.name() != null) {
|
||||||
|
for (var map : neLakeNameMaps.values()) {
|
||||||
|
var lakeInfo = map.get(element.name());
|
||||||
|
if (lakeInfo != null) {
|
||||||
|
match = true;
|
||||||
|
fillOsmIdIntoNeLake(element, geom, lakeInfo, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (match) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// match by intersection:
|
||||||
|
List<LakeInfo> items = neLakeIndex.getIntersecting(geom);
|
||||||
|
for (var lakeInfo : items) {
|
||||||
|
fillOsmIdIntoNeLake(element, geom, lakeInfo, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When we match lakes with `neLakeIndexes` then `intersetsCheckNeeded` should be `false`,
|
||||||
|
* otherwise `true`, to make sure we DO check the intersection but to avoid checking it twice.
|
||||||
|
*/
|
||||||
|
void fillOsmIdIntoNeLake(Tables.OsmWaterPolygon element, Geometry geom, LakeInfo lakeInfo,
|
||||||
|
boolean intersetsCheckNeeded) {
|
||||||
|
final Geometry neGeom = lakeInfo.geom;
|
||||||
|
if (intersetsCheckNeeded && !neGeom.intersects(geom)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final var intersection = neGeom.intersection(geom);
|
||||||
|
|
||||||
|
// Should match following in OpenMapTiles: Distinct on keeps just the first occurence -> order by 'area_ratio DESC'
|
||||||
|
// With a twist: NE geometry is always the same, hence we can make it a little bit faster by dropping "ratio"
|
||||||
|
// and compare only the intersection area: bigger area -> bigger ratio.
|
||||||
|
double area = intersection.getArea();
|
||||||
|
lakeInfo.mergeId(element.source().id(), area);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finish(String sourceName, FeatureCollector.Factory featureCollectors,
|
||||||
|
Consumer<FeatureCollector.Feature> emit) {
|
||||||
|
if (OpenMapTilesProfile.OSM_SOURCE.equals(sourceName)) {
|
||||||
|
var timer = stats.startStage("ne_lakes");
|
||||||
|
for (var item : neAllLakeInfos) {
|
||||||
|
var features = featureCollectors.get(SimpleFeature.fromWorldGeometry(item.geom));
|
||||||
|
setupNeWaterFeature(features, item.minZoom, item.maxZoom, item.clazz, item.osmId);
|
||||||
|
for (var feature : features) {
|
||||||
|
emit.accept(feature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
neLakeNameMaps.clear();
|
||||||
|
neLakeIndex = null;
|
||||||
|
neAllLakeInfos.clear();
|
||||||
|
timer.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,4 +269,35 @@ public class Water implements
|
|||||||
public List<VectorTile.Feature> postProcess(int zoom, List<VectorTile.Feature> items) throws GeometryException {
|
public List<VectorTile.Feature> postProcess(int zoom, List<VectorTile.Feature> items) throws GeometryException {
|
||||||
return items.size() > 1 ? FeatureMerge.mergeOverlappingPolygons(items, config.minFeatureSize(zoom)) : items;
|
return items.size() > 1 ? FeatureMerge.mergeOverlappingPolygons(items, config.minFeatureSize(zoom)) : items;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Information to hold onto from processing an NE lake to determine OSM ID later.
|
||||||
|
*/
|
||||||
|
private static class LakeInfo {
|
||||||
|
String name;
|
||||||
|
int minZoom;
|
||||||
|
int maxZoom;
|
||||||
|
String clazz;
|
||||||
|
Geometry geom;
|
||||||
|
Long osmId;
|
||||||
|
long neId;
|
||||||
|
double area;
|
||||||
|
|
||||||
|
public LakeInfo(int minZoom, int maxZoom, String clazz) {
|
||||||
|
this.name = null;
|
||||||
|
this.minZoom = minZoom;
|
||||||
|
this.maxZoom = maxZoom;
|
||||||
|
this.clazz = clazz;
|
||||||
|
this.osmId = null;
|
||||||
|
this.neId = -1;
|
||||||
|
this.area = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void mergeId(Long newId, double newArea) {
|
||||||
|
if (newArea > area) {
|
||||||
|
osmId = newId;
|
||||||
|
area = newArea;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2021, MapTiler.com & OpenMapTiles contributors.
|
Copyright (c) 2024, MapTiler.com & OpenMapTiles contributors.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Code license: BSD 3-Clause License
|
Code license: BSD 3-Clause License
|
||||||
@@ -85,6 +85,9 @@ public class WaterName implements
|
|||||||
private static final Set<String> SEA_OR_OCEAN_PLACE = Set.of("sea", "ocean");
|
private static final Set<String> SEA_OR_OCEAN_PLACE = Set.of("sea", "ocean");
|
||||||
private static final double IMPORTANT_MARINE_REGIONS_JOIN_DISTANCE =
|
private static final double IMPORTANT_MARINE_REGIONS_JOIN_DISTANCE =
|
||||||
GeoUtils.metersToPixelAtEquator(0, 50_000) / 256d;
|
GeoUtils.metersToPixelAtEquator(0, 50_000) / 256d;
|
||||||
|
private static final int MINZOOM_BAY = 9;
|
||||||
|
private static final int MINZOOM_LAKE = 3;
|
||||||
|
private static final int MINZOOM_SEA_AND_OCEAN = 0;
|
||||||
private final Translations translations;
|
private final Translations translations;
|
||||||
// need to synchronize updates from multiple threads
|
// need to synchronize updates from multiple threads
|
||||||
private final LongObjectMap<Geometry> lakeCenterlines = Hppc.newLongObjectHashMap();
|
private final LongObjectMap<Geometry> lakeCenterlines = Hppc.newLongObjectHashMap();
|
||||||
@@ -215,8 +218,7 @@ public class WaterName implements
|
|||||||
public void process(Tables.OsmWaterPolygon element, FeatureCollector features) {
|
public void process(Tables.OsmWaterPolygon element, FeatureCollector features) {
|
||||||
if (nullIfEmpty(element.name()) != null) {
|
if (nullIfEmpty(element.name()) != null) {
|
||||||
Geometry centerlineGeometry = lakeCenterlines.get(element.source().id());
|
Geometry centerlineGeometry = lakeCenterlines.get(element.source().id());
|
||||||
FeatureCollector.Feature feature;
|
int minzoomCL = MINZOOM_BAY;
|
||||||
int minzoom = 9;
|
|
||||||
String place = element.place();
|
String place = element.place();
|
||||||
String clazz;
|
String clazz;
|
||||||
if ("bay".equals(element.natural())) {
|
if ("bay".equals(element.natural())) {
|
||||||
@@ -225,25 +227,39 @@ public class WaterName implements
|
|||||||
clazz = FieldValues.CLASS_SEA;
|
clazz = FieldValues.CLASS_SEA;
|
||||||
} else {
|
} else {
|
||||||
clazz = FieldValues.CLASS_LAKE;
|
clazz = FieldValues.CLASS_LAKE;
|
||||||
minzoom = 3;
|
minzoomCL = MINZOOM_LAKE;
|
||||||
}
|
}
|
||||||
if (centerlineGeometry != null) {
|
if (centerlineGeometry != null) {
|
||||||
// prefer lake centerline if it exists
|
// prefer lake centerline if it exists, but point will be also used if minzoom below 9 is calculated from area
|
||||||
feature = features.geometry(LAYER_NAME, centerlineGeometry)
|
// note: Here we're diverging from OpenMapTiles: For bays with minzoom (based on area) point is used between
|
||||||
|
// minzoom and Z8 and for Z9+ centerline is used, while OpenMaptiles sticks with points.
|
||||||
|
setupOsmWaterPolygonFeature(
|
||||||
|
element, features.geometry(LAYER_NAME, centerlineGeometry), clazz, minzoomCL)
|
||||||
.setMinPixelSizeBelowZoom(13, 6d * element.name().length());
|
.setMinPixelSizeBelowZoom(13, 6d * element.name().length());
|
||||||
} else {
|
|
||||||
// otherwise just use a label point inside the lake
|
|
||||||
feature = features.pointOnSurface(LAYER_NAME)
|
|
||||||
.setMinZoom(place != null && SEA_OR_OCEAN_PLACE.contains(place) ? 0 : 3)
|
|
||||||
.setMinPixelSize(128); // tiles are 256x256, so 128x128 is 1/4 of a tile
|
|
||||||
}
|
}
|
||||||
feature
|
|
||||||
|
int minzoom = place != null && SEA_OR_OCEAN_PLACE.contains(place) ? MINZOOM_SEA_AND_OCEAN : MINZOOM_LAKE;
|
||||||
|
if (centerlineGeometry == null || minzoom < minzoomCL) {
|
||||||
|
// use a label point inside the lake but ...
|
||||||
|
// ... if centerline already created, adjust maxzoom here to make sure we're not having both at same zoom level
|
||||||
|
int maxzoom = centerlineGeometry != null ? minzoomCL - 1 : 14;
|
||||||
|
setupOsmWaterPolygonFeature(element, features.pointOnSurface(LAYER_NAME), clazz, minzoom)
|
||||||
|
.setMaxZoom(maxzoom)
|
||||||
|
// Show a label if a water feature covers at least 1/4 of a tile or z14+
|
||||||
|
.setMinPixelSizeBelowZoom(13, 128);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private FeatureCollector.Feature setupOsmWaterPolygonFeature(Tables.OsmWaterPolygon element,
|
||||||
|
FeatureCollector.Feature output, String clazz, int minzoom) {
|
||||||
|
output
|
||||||
.setAttr(Fields.CLASS, clazz)
|
.setAttr(Fields.CLASS, clazz)
|
||||||
.setBufferPixels(BUFFER_SIZE)
|
.setBufferPixels(BUFFER_SIZE)
|
||||||
.putAttrs(OmtLanguageUtils.getNames(element.source().tags(), translations))
|
.putAttrs(OmtLanguageUtils.getNames(element.source().tags(), translations))
|
||||||
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
|
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
|
||||||
.setMinZoom(minzoom);
|
.setMinZoom(minzoom);
|
||||||
}
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private record NaturalEarthRegion(
|
private record NaturalEarthRegion(
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ class BoundaryTest extends AbstractLayerTest {
|
|||||||
assertFeatures(0, List.of(Map.of(
|
assertFeatures(0, List.of(Map.of(
|
||||||
"_layer", "boundary",
|
"_layer", "boundary",
|
||||||
"_type", "line",
|
"_type", "line",
|
||||||
|
"_minzoom", 4,
|
||||||
"admin_level", 2
|
"admin_level", 2
|
||||||
)), process(SimpleFeature.create(
|
)), process(SimpleFeature.create(
|
||||||
newLineString(0, 0, 1, 1),
|
newLineString(0, 0, 1, 1),
|
||||||
@@ -115,10 +116,65 @@ class BoundaryTest extends AbstractLayerTest {
|
|||||||
0
|
0
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"_layer", "boundary",
|
||||||
|
"_type", "line",
|
||||||
|
"_minzoom", 1,
|
||||||
|
"admin_level", 2
|
||||||
|
)), process(SimpleFeature.create(
|
||||||
|
newLineString(0, 0, 1, 1),
|
||||||
|
Map.of(
|
||||||
|
"featurecla", "Disputed (please verify)",
|
||||||
|
"adm0_left", "South Sudan",
|
||||||
|
"adm0_right", "Kenya"
|
||||||
|
),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_admin_0_boundary_lines_land",
|
||||||
|
0
|
||||||
|
)));
|
||||||
|
|
||||||
assertFeatures(0, List.of(), process(SimpleFeature.create(
|
assertFeatures(0, List.of(), process(SimpleFeature.create(
|
||||||
newLineString(0, 0, 1, 1),
|
newLineString(0, 0, 1, 1),
|
||||||
Map.of(
|
Map.of(
|
||||||
"featurecla", "Lease Limit"
|
"featurecla", "Lease limit"
|
||||||
|
),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_admin_0_boundary_lines_land",
|
||||||
|
0
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNaturalEarthCountryKeSsBoundaryReversed() {
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"_layer", "boundary",
|
||||||
|
"_minzoom", 1,
|
||||||
|
"admin_level", 2
|
||||||
|
)), process(SimpleFeature.create(
|
||||||
|
newLineString(0, 0, 1, 1),
|
||||||
|
Map.of(
|
||||||
|
"featurecla", "Disputed (please verify)",
|
||||||
|
"adm0_right", "South Sudan",
|
||||||
|
"adm0_left", "Kenya"
|
||||||
|
),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_admin_0_boundary_lines_land",
|
||||||
|
0
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testNaturalEarthCountryNotKeSsBoundary() {
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"_layer", "boundary",
|
||||||
|
"_minzoom", 4,
|
||||||
|
"admin_level", 2
|
||||||
|
)), process(SimpleFeature.create(
|
||||||
|
newLineString(0, 0, 1, 1),
|
||||||
|
Map.of(
|
||||||
|
"featurecla", "Disputed (please verify)",
|
||||||
|
"adm0_left", "South Sudan",
|
||||||
|
"adm0_right", "Uganda"
|
||||||
),
|
),
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
"ne_10m_admin_0_boundary_lines_land",
|
"ne_10m_admin_0_boundary_lines_land",
|
||||||
@@ -382,6 +438,29 @@ class BoundaryTest extends AbstractLayerTest {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testOsmAl2BoundaryDisputedMinZoom() {
|
||||||
|
var relation = new OsmElement.Relation(1);
|
||||||
|
relation.setTag("type", "boundary");
|
||||||
|
relation.setTag("admin_level", "2");
|
||||||
|
relation.setTag("boundary", "administrative");
|
||||||
|
|
||||||
|
assertFeatures(3, List.of(Map.of(
|
||||||
|
"_layer", "boundary",
|
||||||
|
"_type", "line",
|
||||||
|
"_minzoom", 5,
|
||||||
|
|
||||||
|
"disputed", 1,
|
||||||
|
"maritime", 0,
|
||||||
|
"admin_level", 2
|
||||||
|
)), process(lineFeatureWithRelation(
|
||||||
|
profile.preprocessOsmRelation(relation),
|
||||||
|
Map.of(
|
||||||
|
"disputed", "yes"
|
||||||
|
))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testCountryBoundaryEmittedIfNoName() {
|
void testCountryBoundaryEmittedIfNoName() {
|
||||||
var relation = new OsmElement.Relation(1);
|
var relation = new OsmElement.Relation(1);
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ class LanduseTest extends AbstractLayerTest {
|
|||||||
assertFeatures(0, List.of(Map.of(
|
assertFeatures(0, List.of(Map.of(
|
||||||
"_layer", "landuse",
|
"_layer", "landuse",
|
||||||
"class", "residential",
|
"class", "residential",
|
||||||
"_buffer", 4d
|
"_buffer", 4d,
|
||||||
|
"_minzoom", 4
|
||||||
)), process(SimpleFeature.create(
|
)), process(SimpleFeature.create(
|
||||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
||||||
Map.of("scalerank", 1.9),
|
Map.of("scalerank", 1.9),
|
||||||
@@ -27,7 +28,12 @@ class LanduseTest extends AbstractLayerTest {
|
|||||||
"ne_50m_urban_areas",
|
"ne_50m_urban_areas",
|
||||||
0
|
0
|
||||||
)));
|
)));
|
||||||
assertFeatures(0, List.of(), process(SimpleFeature.create(
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"_layer", "landuse",
|
||||||
|
"class", "residential",
|
||||||
|
"_buffer", 4d,
|
||||||
|
"_minzoom", 5
|
||||||
|
)), process(SimpleFeature.create(
|
||||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
||||||
Map.of("scalerank", 2.1),
|
Map.of("scalerank", 2.1),
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
|||||||
@@ -353,7 +353,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "us-state",
|
"network", "us-state",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -580,8 +580,8 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"name", "<null>",
|
"name", "<null>",
|
||||||
"ref", "E 28",
|
"ref", "S7",
|
||||||
"ref_length", 4,
|
"ref_length", 2,
|
||||||
"route_1_network", "e-road",
|
"route_1_network", "e-road",
|
||||||
"route_1_ref", "E 28",
|
"route_1_ref", "E 28",
|
||||||
"route_2_network", "e-road",
|
"route_2_network", "e-road",
|
||||||
@@ -670,6 +670,26 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
)), features);
|
)), features);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMotorwayRoadConstruction() {
|
||||||
|
assertFeatures(13, List.of(Map.of(
|
||||||
|
"_layer", "transportation",
|
||||||
|
"class", "motorway_construction",
|
||||||
|
"oneway", 1,
|
||||||
|
"_minzoom", 4
|
||||||
|
), Map.of(
|
||||||
|
"_layer", "transportation_name",
|
||||||
|
"name", "D4 II/118 – Milín",
|
||||||
|
"class", "motorway_construction",
|
||||||
|
"_minzoom", 6
|
||||||
|
)), process(lineFeature(Map.of(
|
||||||
|
"highway", "construction",
|
||||||
|
"construction", "motorway",
|
||||||
|
"name", "D4 II/118 – Milín",
|
||||||
|
"oneway", "yes"
|
||||||
|
))));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testPrimaryRoadConstruction() {
|
void testPrimaryRoadConstruction() {
|
||||||
assertFeatures(13, List.of(Map.of(
|
assertFeatures(13, List.of(Map.of(
|
||||||
@@ -1154,7 +1174,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "ca-provincial",
|
"network", "ca-provincial",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -1208,7 +1228,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "ca-provincial",
|
"network", "ca-provincial",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -1262,7 +1282,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "ca-provincial",
|
"network", "ca-provincial",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -1316,7 +1336,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "ca-provincial",
|
"network", "ca-provincial",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -1341,7 +1361,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
assertFeatures(13, List.of(Map.of(
|
assertFeatures(13, List.of(Map.of(
|
||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"_minzoom", 5
|
"_minzoom", 6
|
||||||
)), features);
|
)), features);
|
||||||
boolean caProvPresent = StreamSupport.stream(features.spliterator(), false)
|
boolean caProvPresent = StreamSupport.stream(features.spliterator(), false)
|
||||||
.flatMap(f -> f.getAttrsAtZoom(13).entrySet().stream())
|
.flatMap(f -> f.getAttrsAtZoom(13).entrySet().stream())
|
||||||
@@ -1627,7 +1647,7 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
assertFeatures(13, List.of(Map.of(
|
assertFeatures(13, List.of(Map.of(
|
||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"_minzoom", 5
|
"_minzoom", 4
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
@@ -2121,19 +2141,20 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
FeatureCollector features = process(lineFeatureWithRelation(
|
FeatureCollector features = process(lineFeatureWithRelation(
|
||||||
profile.preprocessOsmRelation(rel),
|
profile.preprocessOsmRelation(rel),
|
||||||
Map.of(
|
Map.of(
|
||||||
"highway", "trunk"
|
"highway", "trunk",
|
||||||
|
"name", "National Highway 7",
|
||||||
|
"ref", "7"
|
||||||
)));
|
)));
|
||||||
|
|
||||||
assertFeatures(13, List.of(Map.of(
|
assertFeatures(13, List.of(Map.of(
|
||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"network", "a-road",
|
"_minzoom", 6
|
||||||
"_minzoom", 4
|
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "trunk",
|
"class", "trunk",
|
||||||
"ref", "AH11",
|
"ref", "7",
|
||||||
"network", "a-road"
|
"route_1_ref", "AH11"
|
||||||
)), features);
|
)), features);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2143,24 +2164,24 @@ class TransportationTest extends AbstractLayerTest {
|
|||||||
rel.setTag("type", "route");
|
rel.setTag("type", "route");
|
||||||
rel.setTag("route", "road");
|
rel.setTag("route", "road");
|
||||||
rel.setTag("network", "e-road");
|
rel.setTag("network", "e-road");
|
||||||
rel.setTag("ref", "E 50");
|
rel.setTag("ref", "E 77");
|
||||||
|
|
||||||
FeatureCollector features = process(lineFeatureWithRelation(
|
FeatureCollector features = process(lineFeatureWithRelation(
|
||||||
profile.preprocessOsmRelation(rel),
|
profile.preprocessOsmRelation(rel),
|
||||||
Map.of(
|
Map.of(
|
||||||
"highway", "motorway"
|
"highway", "motorway",
|
||||||
|
"ref", "S7"
|
||||||
)));
|
)));
|
||||||
|
|
||||||
assertFeatures(13, List.of(Map.of(
|
assertFeatures(13, List.of(Map.of(
|
||||||
"_layer", "transportation",
|
"_layer", "transportation",
|
||||||
"class", "motorway",
|
"class", "motorway",
|
||||||
"network", "e-road",
|
|
||||||
"_minzoom", 4
|
"_minzoom", 4
|
||||||
), Map.of(
|
), Map.of(
|
||||||
"_layer", "transportation_name",
|
"_layer", "transportation_name",
|
||||||
"class", "motorway",
|
"class", "motorway",
|
||||||
"ref", "E 50",
|
"ref", "S7",
|
||||||
"network", "e-road"
|
"route_1_ref", "E 77"
|
||||||
)), features);
|
)), features);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class WaterNameTest extends AbstractLayerTest {
|
|||||||
"_maxzoom", 14,
|
"_maxzoom", 14,
|
||||||
"_minpixelsize", "waterway".length() * 6d
|
"_minpixelsize", "waterway".length() * 6d
|
||||||
)), process(SimpleFeature.create(
|
)), process(SimpleFeature.create(
|
||||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1E-7))),
|
||||||
new HashMap<>(Map.<String, Object>of(
|
new HashMap<>(Map.<String, Object>of(
|
||||||
"name", "waterway",
|
"name", "waterway",
|
||||||
"name:es", "waterway es",
|
"name:es", "waterway es",
|
||||||
@@ -112,7 +112,7 @@ class WaterNameTest extends AbstractLayerTest {
|
|||||||
"_maxzoom", 14,
|
"_maxzoom", 14,
|
||||||
"_minpixelsize", "waterway".length() * 6d
|
"_minpixelsize", "waterway".length() * 6d
|
||||||
)), process(SimpleFeature.create(
|
)), process(SimpleFeature.create(
|
||||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1E-7))),
|
||||||
new HashMap<>(Map.<String, Object>of(
|
new HashMap<>(Map.<String, Object>of(
|
||||||
"name", "waterway",
|
"name", "waterway",
|
||||||
"name:es", "waterway es",
|
"name:es", "waterway es",
|
||||||
@@ -126,7 +126,7 @@ class WaterNameTest extends AbstractLayerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testWaterNameBay() {
|
void testWaterNameBaySmall() {
|
||||||
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
||||||
newLineString(0, 0, 1, 1),
|
newLineString(0, 0, 1, 1),
|
||||||
new HashMap<>(Map.<String, Object>of(
|
new HashMap<>(Map.<String, Object>of(
|
||||||
@@ -146,6 +146,55 @@ class WaterNameTest extends AbstractLayerTest {
|
|||||||
"_minzoom", 9,
|
"_minzoom", 9,
|
||||||
"_maxzoom", 14,
|
"_maxzoom", 14,
|
||||||
"_minpixelsize", "bay".length() * 6d
|
"_minpixelsize", "bay".length() * 6d
|
||||||
|
), Map.of(
|
||||||
|
"name", "bay",
|
||||||
|
"name:es", "bay es",
|
||||||
|
|
||||||
|
"_layer", "water_name",
|
||||||
|
"_type", "point",
|
||||||
|
"_minzoom", 3,
|
||||||
|
"_maxzoom", 8,
|
||||||
|
"_minpixelsize", 128d
|
||||||
|
)), process(SimpleFeature.create(
|
||||||
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1E-7))),
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "bay",
|
||||||
|
"name:es", "bay es",
|
||||||
|
"natural", "bay"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
10
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testWaterNameBayBig() {
|
||||||
|
assertFeatures(11, List.of(), process(SimpleFeature.create(
|
||||||
|
newLineString(0, 0, 1, 1),
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"OSM_ID", -10
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.LAKE_CENTERLINE_SOURCE,
|
||||||
|
null,
|
||||||
|
0
|
||||||
|
)));
|
||||||
|
assertFeatures(10, List.of(Map.of(
|
||||||
|
"name", "bay",
|
||||||
|
"name:es", "bay es",
|
||||||
|
|
||||||
|
"_layer", "water_name",
|
||||||
|
"_type", "line",
|
||||||
|
"_minzoom", 9,
|
||||||
|
"_maxzoom", 14
|
||||||
|
), Map.of(
|
||||||
|
"name", "bay",
|
||||||
|
"name:es", "bay es",
|
||||||
|
|
||||||
|
"_layer", "water_name",
|
||||||
|
"_type", "point",
|
||||||
|
"_minzoom", 3,
|
||||||
|
"_maxzoom", 8
|
||||||
)), process(SimpleFeature.create(
|
)), process(SimpleFeature.create(
|
||||||
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
GeoUtils.worldToLatLonCoords(rectangle(0, Math.sqrt(1))),
|
||||||
new HashMap<>(Map.<String, Object>of(
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
|||||||
@@ -2,8 +2,10 @@ package org.openmaptiles.layers;
|
|||||||
|
|
||||||
import static com.onthegomap.planetiler.TestUtils.rectangle;
|
import static com.onthegomap.planetiler.TestUtils.rectangle;
|
||||||
|
|
||||||
|
import com.onthegomap.planetiler.FeatureCollector;
|
||||||
import com.onthegomap.planetiler.geo.GeoUtils;
|
import com.onthegomap.planetiler.geo.GeoUtils;
|
||||||
import com.onthegomap.planetiler.reader.SimpleFeature;
|
import com.onthegomap.planetiler.reader.SimpleFeature;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -15,20 +17,6 @@ class WaterTest extends AbstractLayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testWaterNaturalEarth() {
|
void testWaterNaturalEarth() {
|
||||||
assertFeatures(0, List.of(Map.of(
|
|
||||||
"class", "lake",
|
|
||||||
"intermittent", "<null>",
|
|
||||||
"_layer", "water",
|
|
||||||
"_type", "polygon",
|
|
||||||
"_minzoom", 0
|
|
||||||
)), process(SimpleFeature.create(
|
|
||||||
rectangle(0, 10),
|
|
||||||
Map.of(),
|
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
|
||||||
"ne_110m_lakes",
|
|
||||||
0
|
|
||||||
)));
|
|
||||||
|
|
||||||
assertFeatures(0, List.of(Map.of(
|
assertFeatures(0, List.of(Map.of(
|
||||||
"class", "ocean",
|
"class", "ocean",
|
||||||
"intermittent", "<null>",
|
"intermittent", "<null>",
|
||||||
@@ -43,19 +31,6 @@ class WaterTest extends AbstractLayerTest {
|
|||||||
0
|
0
|
||||||
)));
|
)));
|
||||||
|
|
||||||
assertFeatures(6, List.of(Map.of(
|
|
||||||
"class", "lake",
|
|
||||||
"_layer", "water",
|
|
||||||
"_type", "polygon",
|
|
||||||
"_maxzoom", 5
|
|
||||||
)), process(SimpleFeature.create(
|
|
||||||
rectangle(0, 10),
|
|
||||||
Map.of(),
|
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
|
||||||
"ne_10m_lakes",
|
|
||||||
0
|
|
||||||
)));
|
|
||||||
|
|
||||||
assertFeatures(6, List.of(Map.of(
|
assertFeatures(6, List.of(Map.of(
|
||||||
"class", "ocean",
|
"class", "ocean",
|
||||||
"_layer", "water",
|
"_layer", "water",
|
||||||
@@ -70,6 +45,337 @@ class WaterTest extends AbstractLayerTest {
|
|||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByIntersection() {
|
||||||
|
final var polygon = rectangle(0, 0.1);
|
||||||
|
// NE lakes:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_110m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lake to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"intermittent", "<null>",
|
||||||
|
"id", 123L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon",
|
||||||
|
"_minzoom", 0,
|
||||||
|
"_maxzoom", 1
|
||||||
|
), Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"intermittent", "<null>",
|
||||||
|
"id", 123L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon",
|
||||||
|
"_minzoom", 4,
|
||||||
|
"_maxzoom", 5
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthIntersectionMiss() {
|
||||||
|
final var polygon1 = rectangle(0, 0.1);
|
||||||
|
final var polygon2 = rectangle(0.2, 0.3);
|
||||||
|
// NE lakes:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon1,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_110m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon1,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lake to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", "<null>",
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon"
|
||||||
|
), Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", "<null>",
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon"
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByBiggerIntersection() {
|
||||||
|
final var polygon1 = rectangle(0, 0.1);
|
||||||
|
final var polygon2 = rectangle(0, 0.2);
|
||||||
|
// NE lakes:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_110m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
Map.of(),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lakes to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon1,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
234
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"intermittent", "<null>",
|
||||||
|
"id", 234L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon",
|
||||||
|
"_minzoom", 0,
|
||||||
|
"_maxzoom", 1
|
||||||
|
), Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"intermittent", "<null>",
|
||||||
|
"id", 234L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_type", "polygon",
|
||||||
|
"_minzoom", 4,
|
||||||
|
"_maxzoom", 5
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByName() {
|
||||||
|
final var polygon = rectangle(0, 0.1);
|
||||||
|
// NE lakes:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_50m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lake to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "Test Lake",
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", 123L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_minzoom", 2,
|
||||||
|
"_maxzoom", 3
|
||||||
|
), Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", 123L,
|
||||||
|
"_layer", "water",
|
||||||
|
"_minzoom", 4,
|
||||||
|
"_maxzoom", 5
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByNameIntersectionMiss() {
|
||||||
|
final var polygon1 = rectangle(0, 0.1);
|
||||||
|
final var polygon2 = rectangle(0.2, 0.3);
|
||||||
|
// NE lake:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon1,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_50m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lake to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "Test Lake",
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", "<null>",
|
||||||
|
"_layer", "water"
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByNameAndBiggerIntersection() {
|
||||||
|
final var polygon1 = rectangle(0, 0.1);
|
||||||
|
final var polygon2 = rectangle(0, 0.2);
|
||||||
|
// NE lake:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_50m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lakes to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon1,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "Test Lake",
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygon2,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "Test Lake",
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
234
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", 234L,
|
||||||
|
"_layer", "water"
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testLakeNaturalEarthByNameWithColision() {
|
||||||
|
final var polygonSmaller = rectangle(0, 0.1);
|
||||||
|
final var polygonBigger = rectangle(0, 0.2);
|
||||||
|
// NE lakes:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygonSmaller,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygonBigger,
|
||||||
|
Map.of("name", "Test Lake"),
|
||||||
|
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
||||||
|
"ne_10m_lakes",
|
||||||
|
0
|
||||||
|
));
|
||||||
|
// OSM lake to take the ID from:
|
||||||
|
process(SimpleFeature.create(
|
||||||
|
polygonBigger,
|
||||||
|
new HashMap<>(Map.<String, Object>of(
|
||||||
|
"name", "Test Lake",
|
||||||
|
"natural", "water",
|
||||||
|
"water", "reservoir"
|
||||||
|
)),
|
||||||
|
OpenMapTilesProfile.OSM_SOURCE,
|
||||||
|
null,
|
||||||
|
123
|
||||||
|
));
|
||||||
|
|
||||||
|
List<FeatureCollector.Feature> features = new ArrayList<>();
|
||||||
|
profile.finish(OpenMapTilesProfile.OSM_SOURCE, new FeatureCollector.Factory(params, stats), features::add);
|
||||||
|
assertFeatures(0, List.of(Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", "<null>",
|
||||||
|
"_layer", "water"
|
||||||
|
), Map.of(
|
||||||
|
"class", "lake",
|
||||||
|
"id", 123L,
|
||||||
|
"_layer", "water"
|
||||||
|
)), features);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testWaterOsmWaterPolygon() {
|
void testWaterOsmWaterPolygon() {
|
||||||
assertFeatures(0, List.of(Map.of(
|
assertFeatures(0, List.of(Map.of(
|
||||||
@@ -255,28 +561,7 @@ class WaterTest extends AbstractLayerTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testLakeZoomLevels() {
|
void testLakeZoomLevels() {
|
||||||
assertCoversZoomRange(0, 14, "water",
|
assertCoversZoomRange(6, 14, "water",
|
||||||
process(SimpleFeature.create(
|
|
||||||
rectangle(0, 10),
|
|
||||||
Map.of(),
|
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
|
||||||
"ne_110m_lakes",
|
|
||||||
0
|
|
||||||
)),
|
|
||||||
process(SimpleFeature.create(
|
|
||||||
rectangle(0, 10),
|
|
||||||
Map.of(),
|
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
|
||||||
"ne_50m_lakes",
|
|
||||||
0
|
|
||||||
)),
|
|
||||||
process(SimpleFeature.create(
|
|
||||||
rectangle(0, 10),
|
|
||||||
Map.of(),
|
|
||||||
OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
|
|
||||||
"ne_10m_lakes",
|
|
||||||
0
|
|
||||||
)),
|
|
||||||
process(SimpleFeature.create(
|
process(SimpleFeature.create(
|
||||||
rectangle(0, 10),
|
rectangle(0, 10),
|
||||||
Map.of(
|
Map.of(
|
||||||
|
|||||||
Reference in New Issue
Block a user