planetiler/planetiler-basemap/src/test/java/com/onthegomap/planetiler/basemap/layers/PlaceTest.java

524 wiersze
13 KiB
Java

package com.onthegomap.planetiler.basemap.layers;
import static com.onthegomap.planetiler.TestUtils.newPoint;
import static com.onthegomap.planetiler.TestUtils.rectangle;
import static com.onthegomap.planetiler.basemap.BasemapProfile.NATURAL_EARTH_SOURCE;
import static com.onthegomap.planetiler.basemap.BasemapProfile.OSM_SOURCE;
import static com.onthegomap.planetiler.basemap.layers.Place.getSortKey;
import static com.onthegomap.planetiler.collection.FeatureGroup.SORT_KEY_MAX;
import static com.onthegomap.planetiler.collection.FeatureGroup.SORT_KEY_MIN;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import com.onthegomap.planetiler.geo.GeoUtils;
import com.onthegomap.planetiler.geo.GeometryException;
import com.onthegomap.planetiler.reader.SimpleFeature;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
class PlaceTest extends AbstractLayerTest {
@Test
void testContinent() {
wikidataTranslations.put(49, "es", "América del Norte y América Central");
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "continent",
"name", "North America",
"name:en", "North America",
"name:es", "América del Norte y América Central",
"name:latin", "North America",
"rank", 1,
"_type", "point",
"_minzoom", 0,
"_maxzoom", 3
)), process(pointFeature(Map.of(
"place", "continent",
"wikidata", "Q49",
"name:es", "América del Norte",
"name", "North America",
"name:en", "North America"
))));
}
@Test
void testCountry() {
wikidataTranslations.put(30, "es", "Estados Unidos");
process(SimpleFeature.create(
rectangle(0, 0.25),
Map.of(
"name", "United States",
"scalerank", 0,
"labelrank", 2
),
NATURAL_EARTH_SOURCE,
"ne_10m_admin_0_countries",
0
));
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "country",
"name", "United States of America",
"name_en", "United States of America",
"name:es", "Estados Unidos",
"name:latin", "United States of America",
"iso_a2", "US",
"rank", 6,
"_type", "point",
"_minzoom", 5
)), process(SimpleFeature.create(
newPoint(0.5, 0.5),
Map.of(
"place", "country",
"wikidata", "Q30",
"name:es", "Estados Unidos de América",
"name", "United States of America",
"name:en", "United States of America",
"country_code_iso3166_1_alpha_2", "US"
),
OSM_SOURCE,
null,
0
)));
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "country",
"name", "United States of America",
"name_en", "United States of America",
"name:es", "Estados Unidos",
"name:latin", "United States of America",
"iso_a2", "US",
"rank", 1,
"_type", "point",
"_minzoom", 0
)), process(SimpleFeature.create(
newPoint(0.1, 0.1),
Map.of(
"place", "country",
"wikidata", "Q30",
"name:es", "Estados Unidos de América",
"name", "United States of America",
"name:en", "United States of America",
"country_code_iso3166_1_alpha_2", "US"
),
OSM_SOURCE,
null,
0
)));
}
@Test
void testState() {
wikidataTranslations.put(771, "es", "Massachusetts es");
process(SimpleFeature.create(
rectangle(0, 0.25),
Map.of(
"name", "Massachusetts",
"scalerank", 0,
"labelrank", 2,
"datarank", 1
),
NATURAL_EARTH_SOURCE,
"ne_10m_admin_1_states_provinces",
0
));
process(SimpleFeature.create(
rectangle(0.4, 0.6),
Map.of(
"name", "Massachusetts - not important",
"scalerank", 8,
"labelrank", 8,
"datarank", 1
),
NATURAL_EARTH_SOURCE,
"ne_10m_admin_1_states_provinces",
0
));
// no match
assertFeatures(0, List.of(), process(SimpleFeature.create(
newPoint(1, 1),
Map.of(
"place", "state",
"wikidata", "Q771",
"name", "Massachusetts",
"name:en", "Massachusetts"
),
OSM_SOURCE,
null,
0
)));
// unimportant match
assertFeatures(0, List.of(), process(SimpleFeature.create(
newPoint(0.5, 0.5),
Map.of(
"place", "state",
"wikidata", "Q771",
"name", "Massachusetts",
"name:en", "Massachusetts"
),
OSM_SOURCE,
null,
0
)));
// important match
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "state",
"name", "Massachusetts",
"name_en", "Massachusetts",
"name:es", "Massachusetts es",
"name:latin", "Massachusetts",
"rank", 1,
"_type", "point",
"_minzoom", 2
)), process(SimpleFeature.create(
newPoint(0.1, 0.1),
Map.of(
"place", "state",
"wikidata", "Q771",
"name", "Massachusetts",
"name:en", "Massachusetts"
),
OSM_SOURCE,
null,
0
)));
}
@Test
void testProvince() {
wikidataTranslations.put(95027, "es", "provincia de Lugo");
process(SimpleFeature.create(
rectangle(0, 0.25),
Map.of(
"name", "Nova Scotia",
"scalerank", 3,
"labelrank", 3,
"datarank", 3
),
NATURAL_EARTH_SOURCE,
"ne_10m_admin_1_states_provinces",
0
));
assertFeatures(4, List.of(Map.of(
"_layer", "place",
"class", "province",
"name", "Lugo",
"name:es", "provincia de Lugo",
"rank", 3,
"_type", "point",
"_minzoom", 2
)), process(SimpleFeature.create(
newPoint(0.1, 0.1),
Map.of(
"place", "province",
"wikidata", "Q95027",
"name", "Lugo"
),
OSM_SOURCE,
null,
0
)));
}
@Test
void testIslandPoint() {
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "island",
"name", "Nantucket",
"name_en", "Nantucket",
"name:latin", "Nantucket",
"rank", 7,
"_type", "point",
"_minzoom", 12
)), process(pointFeature(
Map.of(
"place", "island",
"name", "Nantucket",
"name:en", "Nantucket"
))));
}
@Test
void testIslandPolygon() {
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "island",
"name", "Nantucket",
"name_en", "Nantucket",
"name:latin", "Nantucket",
"rank", 3,
"_type", "point",
"_minzoom", 8
)), process(polygonFeatureWithArea(1,
Map.of(
"place", "island",
"name", "Nantucket",
"name:en", "Nantucket"
))));
double rank4area = Math.pow(GeoUtils.metersToPixelAtEquator(0, Math.sqrt(40_000_000 - 1)) / 256d, 2);
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "island",
"name", "Nantucket",
"rank", 4,
"_type", "point",
"_minzoom", 9
)), process(polygonFeatureWithArea(rank4area,
Map.of(
"place", "island",
"name", "Nantucket",
"name:en", "Nantucket"
))));
}
@Test
void testPlaceSortKeyRanking() {
int[] sortKeys = new int[]{
// max
getSortKey(0, Place.PlaceType.CITY, 1_000_000_000, "name"),
getSortKey(0, Place.PlaceType.CITY, 1_000_000_000, "name longer"),
getSortKey(0, Place.PlaceType.CITY, 1_000_000_000, "x".repeat(32)),
getSortKey(0, Place.PlaceType.CITY, 10_000_000, "name"),
getSortKey(0, Place.PlaceType.CITY, 0, "name"),
getSortKey(0, Place.PlaceType.TOWN, 1_000_000_000, "name"),
getSortKey(0, Place.PlaceType.ISOLATED_DWELLING, 1_000_000_000, "name"),
getSortKey(0, null, 1_000_000_000, "name"),
getSortKey(1, Place.PlaceType.CITY, 1_000_000_000, "name"),
getSortKey(10, Place.PlaceType.CITY, 1_000_000_000, "name"),
getSortKey(null, Place.PlaceType.CITY, 1_000_000_000, "name"),
// min
getSortKey(null, null, 0, null),
};
for (int i = 0; i < sortKeys.length; i++) {
if (sortKeys[i] < SORT_KEY_MIN) {
fail("Item at index " + i + " is < " + SORT_KEY_MIN + ": " + sortKeys[i]);
}
if (sortKeys[i] > SORT_KEY_MAX) {
fail("Item at index " + i + " is > " + SORT_KEY_MAX + ": " + sortKeys[i]);
}
}
assertAscending(sortKeys);
}
@Test
void testCountryCapital() {
process(SimpleFeature.create(
newPoint(0, 0),
Map.of(
"name", "Washington, D.C.",
"scalerank", 0,
"wikidataid", "Q61"
),
NATURAL_EARTH_SOURCE,
"ne_10m_populated_places",
0
));
assertFeatures(7, List.of(Map.of(
"_layer", "place",
"class", "city",
"name", "Washington, D.C.",
"rank", 1,
"capital", 2,
"_labelgrid_limit", 0,
"_labelgrid_size", 128d,
"_type", "point",
"_minzoom", 2
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Washington, D.C.",
"population", "672228",
"wikidata", "Q61",
"capital", "yes"
))));
}
@Test
void testStateCapital() {
process(SimpleFeature.create(
newPoint(0, 0),
Map.of(
"name", "Boston",
"scalerank", 2,
"wikidataid", "Q100"
),
NATURAL_EARTH_SOURCE,
"ne_10m_populated_places",
0
));
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"name", "Boston",
"rank", 3,
"capital", 4,
"_type", "point",
"_minzoom", 3
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Boston",
"population", "667137",
"capital", "4"
))));
// no match when far away
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"name", "Boston",
"rank", "<null>"
)), process(SimpleFeature.create(
newPoint(1, 1),
Map.of(
"place", "city",
"name", "Boston",
"wikidata", "Q100",
"population", "667137",
"capital", "4"
),
OSM_SOURCE,
null,
0
)));
// unaccented name match
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"rank", 3
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Böston",
"population", "667137",
"capital", "4"
))));
// wikidata only match
assertFeatures(0, List.of(Map.of(
"_layer", "place",
"class", "city",
"rank", 3
)), process(pointFeature(
Map.of(
"place", "city",
"name", "Other name",
"population", "667137",
"wikidata", "Q100",
"capital", "4"
))));
}
@Test
void testCityWithoutNaturalEarthMatch() {
assertFeatures(7, List.of(Map.of(
"_layer", "place",
"class", "city",
"rank", "<null>",
"_minzoom", 7,
"_labelgrid_limit", 4,
"_labelgrid_size", 128d
)), process(pointFeature(
Map.of(
"place", "city",
"name", "City name"
))));
assertFeatures(13, List.of(Map.of(
"_layer", "place",
"class", "isolated_dwelling",
"rank", "<null>",
"_labelgrid_limit", 0,
"_labelgrid_size", 0d,
"_minzoom", 14
)), process(pointFeature(
Map.of(
"place", "isolated_dwelling",
"name", "City name"
))));
assertFeatures(12, List.of(Map.of(
"_layer", "place",
"class", "isolated_dwelling",
"rank", "<null>",
"_labelgrid_limit", 14,
"_labelgrid_size", 128d,
"_minzoom", 14
)), process(pointFeature(
Map.of(
"place", "isolated_dwelling",
"name", "City name"
))));
}
@Test
void testCitySetRankFromGridrank() throws GeometryException {
var layerName = Place.LAYER_NAME;
assertEquals(List.of(), profile.postProcessLayerFeatures(layerName, 13, List.of()));
assertEquals(List.of(pointFeature(
layerName,
Map.of("rank", 11),
1
)), profile.postProcessLayerFeatures(layerName, 13, List.of(pointFeature(
layerName,
Map.of(),
1
))));
assertEquals(List.of(
pointFeature(
layerName,
Map.of("rank", 11, "name", "a"),
1
), pointFeature(
layerName,
Map.of("rank", 12, "name", "b"),
1
), pointFeature(
layerName,
Map.of("rank", 11, "name", "c"),
2
)
), profile.postProcessLayerFeatures(layerName, 13, List.of(
pointFeature(
layerName,
Map.of("name", "a"),
1
),
pointFeature(
layerName,
Map.of("name", "b"),
1
),
pointFeature(
layerName,
Map.of("name", "c"),
2
)
)));
}
}