Skip to content

Commit

Permalink
Places: don't use Natural Earth at low zooms [#256, #282] (#289)
Browse files Browse the repository at this point in the history
* Places: don't use Natural Earth at low zooms [#256, #282]

* bump tiles version to 4.0.0-alpha.3
  • Loading branch information
bdon authored Aug 23, 2024
1 parent 48bd9fb commit 57cc4b9
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 106 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Tiles v4.0.0-alpha.3
------
- Replace Natural Earth places at low zooms with OSM [#289]

Tiles v4.0.0-alpha.2
------
- Segment name by script via @wipfli [#273]
Expand Down
3 changes: 1 addition & 2 deletions tiles/src/main/java/com/protomaps/basemap/Basemap.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ public Basemap(NaturalEarthDb naturalEarthDb, QrankDb qrankDb) {
var place = new Places(naturalEarthDb);
registerHandler(place);
registerSourceHandler("osm", place::processOsm);
registerSourceHandler("ne", place::processNe);

var poi = new Pois(qrankDb);
registerHandler(poi);
Expand Down Expand Up @@ -101,7 +100,7 @@ public String description() {

@Override
public String version() {
return "4.0.0-alpha.2";
return "4.0.0-alpha.3";
}

@Override
Expand Down
105 changes: 1 addition & 104 deletions tiles/src/main/java/com/protomaps/basemap/layers/Places.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
import com.onthegomap.planetiler.util.ZoomFunction;
import com.protomaps.basemap.feature.FeatureId;
import com.protomaps.basemap.feature.NaturalEarthDb;
import com.protomaps.basemap.names.NeNames;
import com.protomaps.basemap.names.OsmNames;
import com.protomaps.basemap.names.Script;
import com.protomaps.basemap.text.FontRegistry;
import com.protomaps.basemap.text.TextEngine;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
Expand Down Expand Up @@ -70,102 +66,6 @@ static int getSortKey(double minZoom, int kindRank, int populationRank, long pop
9, 4
), 0);

/*
This generates zoom 0 to zoom 6.
*/
public void processNe(SourceFeature sf, FeatureCollector features) {
var sourceLayer = sf.getSourceLayer();

if (!sourceLayer.equals("ne_10m_populated_places")) {
return;
}

// (nvkelso 20230817) We could omit the rest of this function and rely solely on
// OSM for features (but using the NE attributes above.
// We don't do that because OSM has too many names which
// would bloat low zoom file size. Once OSM name localization
// is configurable the below logic should be removed.

// Setup low zoom content
var kind = "";
var kindDetail = "";

// Test for props because of Natural Earth funk
// Test for tz_place because of zoom 0 funk
if (sf.isPoint() && sf.hasTag("featurecla") && sf.hasTag("min_zoom")) {
switch (sf.getString("featurecla")) {
case "Admin-0 capital":
case "Admin-0 capital alt":
case "Admin-0 region capital":
kind = "locality";
break;
case "Admin-1 capital":
case "Admin-1 region capital":
kind = "locality";
break;
case "Populated place":
kind = "locality";
break;
case "Historic place":
kind = "locality";
kindDetail = "hamlet";
break;
case "Scientific station":
kind = "locality";
kindDetail = "scientific_station";
break;
default:
// Important to reset to empty string here
kind = "";
break;
}
}

if (!kind.isEmpty()) {
double minZoom = sf.getString("min_zoom") == null ? 10.0f : Double.parseDouble(sf.getString("min_zoom"));
int populationRank = sf.getString("rank_max") == null ? 0 : (int) Double.parseDouble(sf.getString("rank_max"));
int population = parseIntOrNull(sf.getString("pop_max"));

var feat = features.point(this.name())
.setAttr("name", sf.getString("name"))
.setAttr("pmap:min_zoom", minZoom)
// We subtract 1 to achieve intended compilation balance vis-a-vis 256 zooms in NE and 512 zooms in Planetiler
.setZoomRange((int) minZoom - 1, 6)
.setAttr("pmap:kind", kind)
.setAttr("pmap:kind_detail", kindDetail)
.setAttr("population", population)
.setAttr("pmap:population_rank", populationRank)
// Server sort features so client label collisions are pre-sorted
// we also set the sort keys so the label grid can be sorted predictably (bonus: tile features also sorted)
// since all these are locality, we hard code kindRank to 2 (needs to match OSM section below)
.setSortKey(getSortKey(minZoom, 2, populationRank, population, sf.getString("name")));

String name = sf.getTag("name").toString();
var script = Script.getScript(name);

if (!script.equals("Latin") && !script.equals("Generic")) {
feat.setAttr("pmap:script", script);
FontRegistry fontRegistry = FontRegistry.getInstance();
if (fontRegistry.getScripts().contains(script)) {
String encodedName = TextEngine.encodeRegisteredScripts(name);
feat.setAttr("pmap:pgf:name", encodedName);
}
}


// NOTE: The buffer needs to be consistent with the innteral grid pixel sizes
feat.setPointLabelGridPixelSize(LOCALITY_GRID_SIZE_ZOOM_FUNCTION)
.setPointLabelGridLimit(LOCALITY_GRID_LIMIT_ZOOM_FUNCTION)
.setBufferPixels(64);

if (sf.hasTag("wikidataid")) {
feat.setAttr("wikidata", sf.getString("wikidataid"));
}

NeNames.setNeNames(feat, sf, 0);
}
}

public void processOsm(SourceFeature sf, FeatureCollector features) {
if (sf.isPoint() && sf.hasTag("name") &&
(sf.hasTag("place", "suburb", "town", "village", "locality", "hamlet",
Expand All @@ -174,7 +74,6 @@ public void processOsm(SourceFeature sf, FeatureCollector features) {
String kind = "other";
int kindRank = 6;

int themeMinZoom = 7;
double minZoom = 12.0;
double maxZoom = 15.0;
int population = 0;
Expand All @@ -192,7 +91,6 @@ public void processOsm(SourceFeature sf, FeatureCollector features) {
case "country":
// (nvkelso 20230802) OSM countries are allowlisted to show up at earlier zooms
// TODO: Really these should switch over to NE source
themeMinZoom = 0;
kind = "country";
minZoom = 5.0;
maxZoom = 8.0;
Expand All @@ -207,7 +105,6 @@ public void processOsm(SourceFeature sf, FeatureCollector features) {
case "province":
// (nvkelso 20230802) OSM regions are allowlisted to show up at earlier zooms
// TODO: Really these should switch over to NE source
themeMinZoom = 0;
kind = "region";
minZoom = 8.0;
maxZoom = 11.0;
Expand Down Expand Up @@ -380,7 +277,7 @@ public void processOsm(SourceFeature sf, FeatureCollector features) {
.setAttr("pmap:population_rank", populationRank)
// Generally we use NE and low zooms, and OSM at high zooms
// With exceptions for country and region labels
.setZoomRange(Math.max((int) minZoom, themeMinZoom), (int) maxZoom);
.setZoomRange((int) minZoom, (int) maxZoom);

// Instead of exporting ISO country_code_iso3166_1_alpha_2 (which are sparse), we export Wikidata IDs
if (sf.hasTag("wikidata")) {
Expand Down

0 comments on commit 57cc4b9

Please sign in to comment.