Skip to content

Commit

Permalink
Merge pull request #41 from phanecak-maptiler/missing_gulfs
Browse files Browse the repository at this point in the history
Missing gulfs
  • Loading branch information
phanecak-maptiler authored Mar 11, 2024
2 parents 8a97fd6 + 1f6deaf commit 8f00f2a
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 30 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ available options.
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
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

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.4.0</version>
<version>3.4.1</version>
<configuration>
<from>
<image>
Expand Down
85 changes: 57 additions & 28 deletions src/main/java/org/openmaptiles/layers/WaterName.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,13 @@ public class WaterName implements
*/

private static final Logger LOGGER = LoggerFactory.getLogger(WaterName.class);
private static final double LOG2 = Math.log(2);
private static final Set<String> SEA_OR_OCEAN_PLACE = Set.of("sea", "ocean");
private static final double IMPORTANT_MARINE_REGIONS_JOIN_DISTANCE =
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;
// need to synchronize updates from multiple threads
private final LongObjectMap<Geometry> lakeCenterlines = Hppc.newLongObjectHashMap();
Expand Down Expand Up @@ -214,38 +218,63 @@ public void process(Tables.OsmMarinePoint element, FeatureCollector features) {
@Override
public void process(Tables.OsmWaterPolygon element, FeatureCollector features) {
if (nullIfEmpty(element.name()) != null) {
Geometry centerlineGeometry = lakeCenterlines.get(element.source().id());
FeatureCollector.Feature feature;
int minzoom = 9;
String place = element.place();
String clazz;
if ("bay".equals(element.natural())) {
clazz = FieldValues.CLASS_BAY;
} else if ("sea".equals(place)) {
clazz = FieldValues.CLASS_SEA;
} else {
clazz = FieldValues.CLASS_LAKE;
minzoom = 3;
}
if (centerlineGeometry != null) {
// prefer lake centerline if it exists
feature = features.geometry(LAYER_NAME, centerlineGeometry)
.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
try {
Geometry centerlineGeometry = lakeCenterlines.get(element.source().id());
int minzoom = MINZOOM_BAY;
String place = element.place();
String clazz;
if ("bay".equals(element.natural())) {
clazz = FieldValues.CLASS_BAY;
} else if ("sea".equals(place)) {
clazz = FieldValues.CLASS_SEA;
} else {
clazz = FieldValues.CLASS_LAKE;
minzoom = MINZOOM_LAKE;
}
if (centerlineGeometry != null) {
// prefer lake centerline if it exists, but point will be also used if minzoom bellow 9 is calculated from area
// 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, Math.min(minzoom, MINZOOM_BAY))
.setMinPixelSizeBelowZoom(13, 6d * element.name().length());
}

// Show a label if a water feature covers at least 1/4 of a tile or z14+
Geometry geometry = element.source().worldGeometry();
double area = geometry.getArea();
minzoom = (int) Math.floor(-1d - Math.log(Math.sqrt(area)) / LOG2);
if (place != null && SEA_OR_OCEAN_PLACE.contains(place)) {
minzoom = Math.clamp(minzoom, MINZOOM_SEA_AND_OCEAN, 14);
} else {
minzoom = Math.clamp(minzoom, MINZOOM_LAKE, 14);
}

if (centerlineGeometry == null || minzoom < MINZOOM_BAY) {
// otherwise just use a label point inside the lake
var feature = setupOsmWaterPolygonFeature(element, features.pointOnSurface(LAYER_NAME), clazz, minzoom);
if (centerlineGeometry != null) {
// centerline already created, so make sure we're not having both at same zoom level
feature.setMaxZoom(MINZOOM_BAY - 1);
}
}
} catch (GeometryException e) {
e.log(stats, "omt_water_polygon", "Unable to get geometry for water polygon " + element.source().id());
}
feature
.setAttr(Fields.CLASS, clazz)
.setBufferPixels(BUFFER_SIZE)
.putAttrs(OmtLanguageUtils.getNames(element.source().tags(), translations))
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
.setMinZoom(minzoom);
}
}

private FeatureCollector.Feature setupOsmWaterPolygonFeature(Tables.OsmWaterPolygon element,
FeatureCollector.Feature output, String clazz, int minzoom) {
output
.setAttr(Fields.CLASS, clazz)
.setBufferPixels(BUFFER_SIZE)
.putAttrs(OmtLanguageUtils.getNames(element.source().tags(), translations))
.setAttr(Fields.INTERMITTENT, element.isIntermittent() ? 1 : 0)
.setMinZoom(minzoom);
return output;
}

private record NaturalEarthRegion(
Geometry geometry,
int scalerank
Expand Down

0 comments on commit 8f00f2a

Please sign in to comment.