name translations for mountain peaks

pull/1/head
Mike Barry 2021-06-16 06:01:39 -04:00
rodzic 3ee817c48a
commit 4faf84868b
30 zmienionych plików z 653 dodań i 67 usunięć

Wyświetl plik

@ -332,5 +332,10 @@ public class FeatureCollector implements Iterable<FeatureCollector.Feature> {
", attrs=" + attrs +
'}';
}
public Feature setAttrs(Map<String, Object> names) {
attrs.putAll(names);
return this;
}
}
}

Wyświetl plik

@ -51,7 +51,9 @@ public class Parse {
private static final Set<String> forwardDirections = Set.of("1", "yes", "true");
public static int direction(Object string) {
if (forwardDirections.contains(string(string))) {
if (string == null) {
return 0;
} else if (forwardDirections.contains(string(string))) {
return 1;
} else if ("-1".equals(string)) {
return -1;

Wyświetl plik

@ -1,27 +1,89 @@
package com.onthegomap.flatmap;
import com.graphhopper.reader.ReaderElement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Translations {
private boolean shouldTransliterate = true;
private final Set<String> languageSet;
private final List<TranslationProvider> providers = new ArrayList<>();
private Translations(List<String> languages) {
this.languageSet = new HashSet<>();
for (String language : languages) {
String withoutPrefix = language.replaceFirst("^name:", "");
languageSet.add(withoutPrefix);
languageSet.add("name:" + withoutPrefix);
}
}
public static Translations nullProvider(List<String> languages) {
return new Translations(languages);
}
public static Translations defaultProvider(List<String> languages) {
// TODO
return new Translations();
return nullProvider(languages).addTranslationProvider(new OsmTranslationProvider());
}
public static Translations defaultTranslationProvider() {
return null;
public Translations addTranslationProvider(TranslationProvider provider) {
providers.add(provider);
return this;
}
public void addTranslationProvider(Wikidata.WikidataTranslations load) {
// TODO
public Map<String, Object> getTranslations(Map<String, Object> properties) {
Map<String, Object> result = new HashMap<>();
addTranslations(result, properties);
return result;
}
public void addTranslations(Map<String, Object> result, Map<String, Object> properties) {
for (TranslationProvider provider : providers) {
Map<String, String> translations = provider.getNameTranslations(properties);
if (translations != null && !translations.isEmpty()) {
for (var entry : translations.entrySet()) {
String key = entry.getKey();
if (languageSet.contains(key)) {
result.put(key.startsWith("name:") ? key : "name:" + key, entry.getValue());
}
}
}
}
}
public boolean getShouldTransliterate() {
return shouldTransliterate;
}
public Translations setShouldTransliterate(boolean shouldTransliterate) {
this.shouldTransliterate = shouldTransliterate;
return this;
}
public interface TranslationProvider {
Map<String, String> getNameTranslations(ReaderElement elem);
Map<String, String> getNameTranslations(Map<String, Object> elem);
}
public static class OsmTranslationProvider implements TranslationProvider {
@Override
public Map<String, String> getNameTranslations(Map<String, Object> elem) {
Map<String, String> result = new HashMap<>();
for (String key : elem.keySet()) {
if (key.startsWith("name:")) {
Object value = elem.get(key);
if (value instanceof String stringVal) {
result.put(key, stringVal);
}
}
}
return result;
}
}
}

Wyświetl plik

@ -11,6 +11,7 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.graphhopper.coll.GHLongObjectHashMap;
import com.graphhopper.reader.ReaderElement;
import com.graphhopper.reader.ReaderElementUtils;
import com.graphhopper.util.StopWatch;
import com.onthegomap.flatmap.monitoring.ProgressLoggers;
import com.onthegomap.flatmap.monitoring.Stats;
@ -199,10 +200,10 @@ public class Wikidata {
}
}
public static long parseQid(String qid) {
public static long parseQid(Object qid) {
long result = 0;
if (qid != null) {
Matcher matcher = qidPattern.matcher(qid);
if (qid instanceof String qidString) {
Matcher matcher = qidPattern.matcher(qidString);
if (matcher.matches()) {
String idString = matcher.group(1);
result = Parse.parseLong(idString);
@ -223,7 +224,7 @@ public class Wikidata {
if (elem.hasTag("wikidata")) {
qidTracker.qid = 0;
// TODO send reader element through profile
qidTracker.getNameTranslations(elem);
qidTracker.getNameTranslations(ReaderElementUtils.getProperties(elem));
if (qidTracker.qid > 0) {
next.accept(qidTracker.qid);
}
@ -326,8 +327,8 @@ public class Wikidata {
}
@Override
public Map<String, String> getNameTranslations(ReaderElement elem) {
long wikidataId = parseQid(elem.getTag("wikidata"));
public Map<String, String> getNameTranslations(Map<String, Object> elem) {
long wikidataId = parseQid(elem.get("wikidata"));
if (wikidataId > 0) {
return get(wikidataId);
}

Wyświetl plik

@ -4,8 +4,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
import com.graphhopper.reader.ReaderElement;
import com.graphhopper.reader.ReaderNode;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@ -16,6 +14,7 @@ import java.net.http.HttpResponse.BodySubscriber;
import java.net.http.HttpResponse.BodySubscribers;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@ -37,11 +36,11 @@ public class WikidataTest {
translations.put(1, "en", "en value");
translations.put(1, "es", "es value");
assertEquals(expected, translations.get(1));
ReaderElement elem = new ReaderNode(2, 2, 2);
Map<String, Object> elem = new HashMap<>();
assertNull(translations.getNameTranslations(elem));
elem.setTag("wikidata", "Qgarbage");
elem.put("wikidata", "Qgarbage");
assertNull(translations.getNameTranslations(elem));
elem.setTag("wikidata", "Q1");
elem.put("wikidata", "Q1");
assertEquals(expected, translations.getNameTranslations(elem));
}
@ -160,7 +159,6 @@ public class WikidataTest {
stringSubscriber.onComplete();
}
}));
String body = stringSubscriber.getBody().toCompletableFuture().join();
return body;
return stringSubscriber.getBody().toCompletableFuture().join();
}
}

Wyświetl plik

@ -23,6 +23,12 @@
<artifactId>snakeyaml</artifactId>
<version>1.29</version>
</dependency>
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>69.1</version>
</dependency>
<dependency>
<groupId>com.onthegomap</groupId>
<artifactId>flatmap-core</artifactId>

Wyświetl plik

@ -339,8 +339,11 @@ public class Generate {
package %s;
import static com.onthegomap.flatmap.openmaptiles.Expression.*;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.MultiExpression;
import com.onthegomap.flatmap.openmaptiles.Layer;
import com.onthegomap.flatmap.Translations;
import java.util.List;
import java.util.Map;
@ -349,8 +352,9 @@ public class Generate {
public static final String DESCRIPTION = %s;
public static final String VERSION = %s;
public static final String ATTRIBUTION = %s;
public static final List<String> LANGUAGES = List.of(%s);
public static List<Layer> createInstances() {
public static List<Layer> createInstances(Translations translations, Arguments args, Stats stats) {
return List.of(
%s
);
@ -362,9 +366,10 @@ public class Generate {
quote(info.description),
quote(info.version),
quote(info.attribution),
info.languages.stream().map(Generate::quote).collect(joining(", ")),
layers.stream()
.map(
l -> "new com.onthegomap.flatmap.openmaptiles.layers.%s()"
l -> "new com.onthegomap.flatmap.openmaptiles.layers.%s(translations, args, stats)"
.formatted(lowerUnderscoreToUpperCamel(l.layer.id)))
.collect(joining(",\n"))
.indent(6).trim()

Wyświetl plik

@ -0,0 +1,135 @@
package com.onthegomap.flatmap.openmaptiles;
import static com.onthegomap.flatmap.openmaptiles.Utils.coalesce;
import static com.onthegomap.flatmap.openmaptiles.Utils.coalesceLazy;
import static com.onthegomap.flatmap.openmaptiles.Utils.nullIf;
import com.ibm.icu.text.Transliterator;
import com.onthegomap.flatmap.Translations;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* This class is ported from https://github.com/openmaptiles/openmaptiles-tools/blob/master/sql/zzz_language.sql
*/
public class LanguageUtils {
private static void putIfNotNull(Map<String, Object> dest, String key, Object value) {
if (value != null && !value.equals("")) {
dest.put(key, value);
}
}
private static String string(Object obj) {
return nullIf(obj == null ? null : obj.toString(), "");
}
private static final Pattern NONLATIN = Pattern
.compile("[^\\x{0000}-\\x{024f}\\x{1E00}-\\x{1EFF}\\x{0300}-\\x{036f}\\x{0259}]");
static boolean isLatin(String string) {
return string != null && !NONLATIN.matcher(string).find();
}
private static final Pattern ROMANIZED_KEY = Pattern.compile("^name:.+(_rm|-Latn)$");
private static final Transliterator TO_LATIN_TRANSLITERATOR = Transliterator.getInstance("Any-Latin");
private static String findLatinName(Map<String, Object> properties) {
String result = coalesce(
string(properties.get("name:fr")),
string(properties.get("name:es")),
string(properties.get("name:pt")),
string(properties.get("name:de"))
);
if (result == null) {
for (String key : properties.keySet()) {
if (ROMANIZED_KEY.matcher(key).matches()) {
result = string(properties.get(key));
if (result != null) {
break;
}
}
}
}
return result;
}
private static String transliterate(Map<String, Object> properties) {
String name = string(properties.get("name"));
return name == null ? null : TO_LATIN_TRANSLITERATOR.transform(name);
}
private static final Pattern LETTER = Pattern.compile("[A-Za-zÀ-ÖØ-öø-ÿĀ-ɏ]+");
private static final Pattern EMPTY_PARENS = Pattern.compile("(\\([ -.]*\\)|\\[[ -.]*])");
private static final Pattern LEADING_TRAILING_JUNK = Pattern.compile("(^\\s*([./-]\\s*)*|(\\s+[./-])*\\s*$)");
private static final Pattern WHITESPACE = Pattern.compile("\\s+");
static String removeNonLatin(String name) {
if (name == null) {
return null;
}
var matcher = LETTER.matcher(name);
if (matcher.find()) {
String result = matcher.replaceAll("");
result = EMPTY_PARENS.matcher(result).replaceAll("");
result = LEADING_TRAILING_JUNK.matcher(result).replaceAll("");
return WHITESPACE.matcher(result).replaceAll(" ");
}
return name.trim();
}
public static Map<String, Object> getNames(Map<String, Object> properties) {
return getNames(properties, null);
}
public static Map<String, Object> getNames(Map<String, Object> properties, Translations translations) {
Map<String, Object> result = new HashMap<>();
String name = string(properties.get("name"));
String intName = string(properties.get("int_name"));
String nameEn = string(properties.get("name:en"));
String nameDe = string(properties.get("name:de"));
boolean isLatin = isLatin(name);
String latin = coalesceLazy(
coalesce(
isLatin ? name : null,
nameEn,
intName
),
LanguageUtils::findLatinName,
properties
);
if (latin == null) {
latin = findLatinName(properties);
}
if (latin == null && translations != null && translations.getShouldTransliterate()) {
latin = transliterate(properties);
}
String nonLatin = isLatin ? null : removeNonLatin(name);
if (coalesce(nonLatin, "").equals(latin)) {
nonLatin = null;
}
putIfNotNull(result, "name", name);
putIfNotNull(result, "name_en", coalesce(nameEn, name));
putIfNotNull(result, "name_de", coalesce(nameDe, name, nameEn));
putIfNotNull(result, "name:latin", latin);
putIfNotNull(result, "name:nonlatin", nonLatin);
putIfNotNull(result, "name_int", coalesce(
intName,
nameEn,
latin,
name
));
if (translations != null) {
translations.addTranslations(result, properties);
}
return result;
}
}

Wyświetl plik

@ -1,6 +1,7 @@
package com.onthegomap.flatmap.openmaptiles;
import com.graphhopper.reader.ReaderRelation;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.FeatureCollector;
import com.onthegomap.flatmap.FeatureMerge;
import com.onthegomap.flatmap.Profile;
@ -8,6 +9,7 @@ import com.onthegomap.flatmap.SourceFeature;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.VectorTileEncoder;
import com.onthegomap.flatmap.geo.GeometryException;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
import com.onthegomap.flatmap.openmaptiles.generated.Tables;
import com.onthegomap.flatmap.read.OpenStreetMapReader;
@ -30,9 +32,9 @@ public class OpenMapTilesProfile implements Profile {
private final List<Layer> layers;
private final Map<Class<? extends Tables.Row>, List<Tables.RowHandler<Tables.Row>>> osmDispatchMap;
public OpenMapTilesProfile(Translations translations) {
public OpenMapTilesProfile(Translations translations, Arguments arguments, Stats stats) {
this.osmMappings = Tables.MAPPINGS.index();
this.layers = Layers.createInstances();
this.layers = Layers.createInstances(translations, arguments, stats);
osmDispatchMap = new HashMap<>();
Tables.generateDispatchMap(layers).forEach((clazz, handlers) -> {
osmDispatchMap.put(clazz, handlers.stream().map(handler -> {
@ -76,8 +78,10 @@ public class OpenMapTilesProfile implements Profile {
for (var match : osmMappings.getMatchesWithTriggers(sourceFeature.properties())) {
var row = match.match().create(sourceFeature, match.keys().get(0));
var handlers = osmDispatchMap.get(row.getClass());
for (Tables.RowHandler<Tables.Row> handler : handlers) {
handler.process(row, features);
if (handlers != null) {
for (Tables.RowHandler<Tables.Row> handler : handlers) {
handler.process(row, features);
}
}
}
}

Wyświetl plik

@ -4,6 +4,7 @@ import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.FlatMapRunner;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.Wikidata;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
import java.nio.file.Path;
import java.util.List;
@ -16,12 +17,12 @@ public class OpenMaptilesMain {
runner
.setProfile(createProfileWithWikidataTranslations(runner))
.addShapefileSource("EPSG:3857", OpenMapTilesProfile.LAKE_CENTERLINE_SOURCE,
sourcesDir.resolve("lake_centerline.shp.zip"))
.addShapefileSource(OpenMapTilesProfile.WATER_POLYGON_SOURCE,
sourcesDir.resolve("water-polygons-split-3857.zip"))
.addNaturalEarthSource(OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
sourcesDir.resolve("natural_earth_vector.sqlite.zip"))
// .addShapefileSource("EPSG:3857", OpenMapTilesProfile.LAKE_CENTERLINE_SOURCE,
// sourcesDir.resolve("lake_centerline.shp.zip"))
// .addShapefileSource(OpenMapTilesProfile.WATER_POLYGON_SOURCE,
// sourcesDir.resolve("water-polygons-split-3857.zip"))
// .addNaturalEarthSource(OpenMapTilesProfile.NATURAL_EARTH_SOURCE,
// sourcesDir.resolve("natural_earth_vector.sqlite.zip"))
.addOsmSource(OpenMapTilesProfile.OSM_SOURCE, sourcesDir.resolve("north-america_us_massachusetts.pbf"))
.setOutput("mbtiles", Path.of("data", "massachusetts.mbtiles"))
.run();
@ -31,12 +32,14 @@ public class OpenMaptilesMain {
Arguments arguments = runner.arguments();
boolean fetchWikidata = arguments.get("fetch_wikidata", "fetch wikidata translations", false);
boolean useWikidata = arguments.get("use_wikidata", "use wikidata translations", true);
boolean transliterate = arguments.get("transliterate", "attempt to transliterate latin names", true);
Path wikidataNamesFile = arguments.file("wikidata_cache", "wikidata cache file",
Path.of("data", "sources", "wikidata_names.json"));
// most common languages: "en,ru,ar,zh,ja,ko,fr,de,fi,pl,es,be,br,he"
List<String> languages = arguments.get("name_languages", "languages to use",
"en,ru,ar,zh,ja,ko,fr,de,fi,pl,es,be,br,he".split(","));
var translations = Translations.defaultProvider(languages);
var profile = new OpenMapTilesProfile(translations);
Layers.LANGUAGES.toArray(String[]::new));
var translations = Translations.defaultProvider(languages).setShouldTransliterate(transliterate);
var profile = new OpenMapTilesProfile(translations, arguments, runner.stats());
if (useWikidata) {
if (fetchWikidata) {

Wyświetl plik

@ -1,5 +1,9 @@
package com.onthegomap.flatmap.openmaptiles;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Supplier;
public class Utils {
public static <T> T coalesce(T a, T b) {
@ -11,14 +15,25 @@ public class Utils {
}
public static <T> T coalesce(T a, T b, T c, T d) {
return a != null ? a : b != null ? b : c != null ? d : d;
return a != null ? a : b != null ? b : c != null ? c : d;
}
public static <T> T coalesceLazy(T a, Supplier<T> b) {
return a != null ? a : b.get();
}
public static <T, U> T coalesceLazy(T a, Function<U, T> b, U arg) {
return a != null ? a : b.apply(arg);
}
public static <T> T nullIf(T a, T nullValue) {
return nullValue.equals(a) ? null : a;
}
public static Integer metersToFeet(Integer meters) {
return meters != null ? (int) (meters * 3.2808399) : null;
public static Map<String, Object> elevationTags(int meters) {
return Map.of(
"ele", meters,
"ele_ft", (int) Math.round(meters * 3.2808399)
);
}
}

Wyświetl plik

@ -5,6 +5,9 @@ import static com.onthegomap.flatmap.openmaptiles.Expression.and;
import static com.onthegomap.flatmap.openmaptiles.Expression.matchAny;
import static com.onthegomap.flatmap.openmaptiles.Expression.or;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.Layer;
import com.onthegomap.flatmap.openmaptiles.MultiExpression;
import java.util.List;
@ -16,25 +19,31 @@ public class Layers {
public static final String DESCRIPTION = "A tileset showcasing all layers in OpenMapTiles. https://openmaptiles.org";
public static final String VERSION = "3.12.1";
public static final String ATTRIBUTION = "<a href=\"https://www.openmaptiles.org/\" target=\"_blank\">&copy; OpenMapTiles</a> <a href=\"https://www.openstreetmap.org/copyright\" target=\"_blank\">&copy; OpenStreetMap contributors</a>";
public static final List<String> LANGUAGES = List
.of("am", "ar", "az", "be", "bg", "br", "bs", "ca", "co", "cs", "cy", "da", "de", "el", "en", "eo", "es", "et",
"eu", "fi", "fr", "fy", "ga", "gd", "he", "hi", "hr", "hu", "hy", "id", "is", "it", "ja", "ja_kana", "ja_rm",
"ja-Latn", "ja-Hira", "ka", "kk", "kn", "ko", "ko-Latn", "ku", "la", "lb", "lt", "lv", "mk", "mt", "ml", "nl",
"no", "oc", "pl", "pt", "rm", "ro", "ru", "sk", "sl", "sq", "sr", "sr-Latn", "sv", "ta", "te", "th", "tr", "uk",
"zh");
public static List<Layer> createInstances() {
public static List<Layer> createInstances(Translations translations, Arguments args, Stats stats) {
return List.of(
new com.onthegomap.flatmap.openmaptiles.layers.Water(),
new com.onthegomap.flatmap.openmaptiles.layers.Waterway(),
new com.onthegomap.flatmap.openmaptiles.layers.Landcover(),
new com.onthegomap.flatmap.openmaptiles.layers.Landuse(),
new com.onthegomap.flatmap.openmaptiles.layers.MountainPeak(),
new com.onthegomap.flatmap.openmaptiles.layers.Park(),
new com.onthegomap.flatmap.openmaptiles.layers.Boundary(),
new com.onthegomap.flatmap.openmaptiles.layers.Aeroway(),
new com.onthegomap.flatmap.openmaptiles.layers.Transportation(),
new com.onthegomap.flatmap.openmaptiles.layers.Building(),
new com.onthegomap.flatmap.openmaptiles.layers.WaterName(),
new com.onthegomap.flatmap.openmaptiles.layers.TransportationName(),
new com.onthegomap.flatmap.openmaptiles.layers.Place(),
new com.onthegomap.flatmap.openmaptiles.layers.Housenumber(),
new com.onthegomap.flatmap.openmaptiles.layers.Poi(),
new com.onthegomap.flatmap.openmaptiles.layers.AerodromeLabel()
new com.onthegomap.flatmap.openmaptiles.layers.Water(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Waterway(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Landcover(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Landuse(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.MountainPeak(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Park(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Boundary(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Aeroway(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Transportation(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Building(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.WaterName(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.TransportationName(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Place(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Housenumber(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.Poi(translations, args, stats),
new com.onthegomap.flatmap.openmaptiles.layers.AerodromeLabel(translations, args, stats)
);
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class AerodromeLabel implements Layers.AerodromeLabel {
public AerodromeLabel(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Aeroway implements Layers.Aeroway {
public Aeroway(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Boundary implements Layers.Boundary {
public Boundary(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Building implements Layers.Building {
public Building(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Housenumber implements Layers.Housenumber {
public Housenumber(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Landcover implements Layers.Landcover {
public Landcover(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Landuse implements Layers.Landuse {
public Landuse(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,32 +1,52 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import static com.onthegomap.flatmap.openmaptiles.Utils.coalesce;
import static com.onthegomap.flatmap.openmaptiles.Utils.metersToFeet;
import static com.onthegomap.flatmap.openmaptiles.LanguageUtils.getNames;
import static com.onthegomap.flatmap.openmaptiles.Utils.elevationTags;
import static com.onthegomap.flatmap.openmaptiles.Utils.nullIf;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.FeatureCollector;
import com.onthegomap.flatmap.Parse;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.VectorTileEncoder;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.OpenMapTilesProfile;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
import com.onthegomap.flatmap.openmaptiles.generated.Tables;
import java.util.List;
public class MountainPeak implements
Layers.MountainPeak,
Tables.OsmPeakPoint.Handler {
Tables.OsmPeakPoint.Handler,
OpenMapTilesProfile.FeaturePostProcessor {
private final Translations translations;
public MountainPeak(Translations translations, Arguments args, Stats stats) {
this.translations = translations;
}
@Override
public void process(Tables.OsmPeakPoint element, FeatureCollector features) {
Integer meters = Parse.parseIntSubstring(element.ele());
if (meters != null) {
if (meters != null && Math.abs(meters) < 10_000) {
features.point(LAYER_NAME)
.setAttr(Fields.NAME, element.name())
.setAttr(Fields.NAME_EN, coalesce(nullIf(element.nameEn(), ""), element.name()))
.setAttr(Fields.NAME_DE, coalesce(nullIf(element.nameDe(), ""), element.name()))
.setAttr(Fields.CLASS, element.source().getTag("natural"))
.setAttr(Fields.ELE, meters)
.setAttr(Fields.ELE_FT, metersToFeet(meters))
.setAttrs(getNames(element.source().properties(), translations))
.setAttrs(elevationTags(meters))
.setBufferPixels(BUFFER_SIZE)
.setZorder(
meters +
(nullIf(element.wikipedia(), "") == null ? 10_000 : 0) +
(nullIf(element.name(), "") == null ? 10_000 : 0)
)
.setZoomRange(7, 14)
.setLabelGridSizeAndLimit(13, 100, 5);
}
}
@Override
public void postProcess(int zoom, List<VectorTileEncoder.Feature> items) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Park implements Layers.Park {
public Park(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Place implements Layers.Place {
public Place(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Poi implements Layers.Poi {
public Poi(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Transportation implements Layers.Transportation {
public Transportation(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class TransportationName implements Layers.TransportationName {
public TransportationName(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,13 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Water implements Layers.Water {
public Water(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,6 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class WaterName implements Layers.WaterName {
public WaterName(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -1,7 +1,12 @@
package com.onthegomap.flatmap.openmaptiles.layers;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.openmaptiles.generated.Layers;
public class Waterway implements Layers.Waterway {
public Waterway(Translations translations, Arguments args, Stats stats) {
}
}

Wyświetl plik

@ -0,0 +1,194 @@
package com.onthegomap.flatmap.openmaptiles;
import static com.onthegomap.flatmap.TestUtils.assertSubmap;
import static com.onthegomap.flatmap.openmaptiles.LanguageUtils.getNames;
import static com.onthegomap.flatmap.openmaptiles.LanguageUtils.isLatin;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.Wikidata;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
public class LanguageUtilsTest {
private final Wikidata.WikidataTranslations wikidataTranslations = new Wikidata.WikidataTranslations();
private final Translations translations = Translations.defaultProvider(List.of("en", "es", "de"))
.addTranslationProvider(wikidataTranslations);
@Test
public void testSimpleExample() {
assertSubmap(Map.of(
"name", "name",
"name_en", "english name",
"name_de", "german name"
), getNames(Map.of(
"name", "name",
"name:en", "english name",
"name:de", "german name"
), translations));
assertSubmap(Map.of(
"name", "name",
"name_en", "name",
"name_de", "german name"
), getNames(Map.of(
"name", "name",
"name:de", "german name"
), translations));
assertSubmap(Map.of(
"name", "name",
"name_en", "english name",
"name_de", "name"
), getNames(Map.of(
"name", "name",
"name:en", "english name"
), translations));
}
@ParameterizedTest
@CsvSource({
"abc, true",
"5!, true",
"5~, true",
"é, true",
"éś, true",
"ɏə, true",
"ɐ, false",
"ᵿἀ, false",
"Ḁỿ, true",
"\u02ff\u0370, false",
"\u0030\u036f, true",
"日本, false",
"abc本123, false",
})
public void testIsLatin(String in, boolean isLatin) {
if (!isLatin) {
assertFalse(isLatin(in));
} else {
assertEquals(isLatin ? in : null, getNames(Map.of(
"name", in
), translations).get("name:latin"));
}
}
@ParameterizedTest
@CsvSource(value = {
"abcaāíìś+, null",
"abca日āíìś+, 日+",
"(abc), null",
"日本 (Japan), 日本",
"日本 [Japan - Nippon], 日本",
" Japan - Nippon (Japan) - Japan - 日本 - Japan - Nippon (Japan), 日本",
"Japan - 日本~+ , 日本~+",
"Japan / 日本 / Japan , 日本",
}, nullValues = "null")
public void testRemoveNonLatin(String in, String out) {
assertEquals(out, getNames(Map.of(
"name", in
), translations).get("name:nonlatin"));
}
@ParameterizedTest
@CsvSource({
"name, a, true",
"name:en, a, true",
"int_name, a, true",
"name:fr, a, true",
"name:es, a, true",
"name:pt, a, true",
"name:de, a, true",
"name:ar, a, false",
"name:it, a, false",
"name:jp, a, false",
"name:jp-Latn, a, true",
"name:jp_rm, a, true",
})
public void testLatinFallbacks(String key, String value, boolean use) {
assertEquals(use ? value : null, getNames(Map.of(
key, value
), translations).get("name:latin"));
}
@ParameterizedTest
@CsvSource({
"キャンパス, kyanpasu",
"Αλφαβητικός Κατάλογος, Alphabētikós Katálogos",
"биологическом, biologičeskom",
})
public void testTransliterate(String in, String out) {
assertEquals(out, getNames(Map.of(
"name", in
), translations).get("name:latin"));
translations.setShouldTransliterate(false);
assertNull(getNames(Map.of(
"name", in
), translations).get("name:latin"));
}
@Test
public void testUseWikidata() {
wikidataTranslations.put(123, "es", "es name");
assertSubmap(Map.of(
"name:es", "es name"
), getNames(Map.of(
"name", "name",
"wikidata", "Q123"
), translations));
}
@Test
public void testUseOsm() {
assertSubmap(Map.of(
"name:es", "es name osm"
), getNames(Map.of(
"name", "name",
"wikidata", "Q123",
"name:es", "es name osm"
), translations));
}
@Test
public void testPreferWikidata() {
wikidataTranslations.put(123, "es", "wd es name");
assertSubmap(Map.of(
"name:es", "wd es name",
"name:de", "de name osm"
), getNames(Map.of(
"name", "name",
"wikidata", "Q123",
"name:es", "es name osm",
"name:de", "de name osm"
), translations));
}
@Test
public void testDontUseTranslationsWhenNotSpecified() {
var result = getNames(Map.of(
"name", "name",
"wikidata", "Q123",
"name:es", "es name osm",
"name:de", "de name osm"
));
assertNull(result.get("name:es"));
assertNull(result.get("name:de"));
assertEquals("name", result.get("name"));
}
@Test
public void testIgnoreLanguages() {
wikidataTranslations.put(123, "ja", "ja name wd");
var result = getNames(Map.of(
"name", "name",
"wikidata", "Q123",
"name:ja", "ja name osm"
));
assertNull(result.get("name:ja"));
}
}

Wyświetl plik

@ -6,11 +6,13 @@ import static com.onthegomap.flatmap.TestUtils.newPoint;
import static com.onthegomap.flatmap.openmaptiles.OpenMapTilesProfile.OSM_SOURCE;
import static org.junit.jupiter.api.Assertions.assertEquals;
import com.onthegomap.flatmap.Arguments;
import com.onthegomap.flatmap.CommonParams;
import com.onthegomap.flatmap.FeatureCollector;
import com.onthegomap.flatmap.SourceFeature;
import com.onthegomap.flatmap.TestUtils;
import com.onthegomap.flatmap.Translations;
import com.onthegomap.flatmap.Wikidata;
import com.onthegomap.flatmap.monitoring.Stats;
import com.onthegomap.flatmap.read.ReaderFeature;
import java.util.HashMap;
@ -21,8 +23,16 @@ import org.junit.jupiter.api.Test;
public class OpenMaptilesProfileTest {
private final OpenMapTilesProfile profile = new OpenMapTilesProfile(Translations.defaultTranslationProvider());
private final Translations translations = Translations.defaultProvider(List.of("en", "es", "de"));
private final Wikidata.WikidataTranslations wikidataTranslations = new Wikidata.WikidataTranslations();
{
translations.addTranslationProvider(wikidataTranslations);
}
private final CommonParams params = CommonParams.defaults();
private final OpenMapTilesProfile profile = new OpenMapTilesProfile(translations, Arguments.of(),
new Stats.InMemory());
private final Stats stats = new Stats.InMemory();
private final FeatureCollector.Factory featureCollectorFactory = new FeatureCollector.Factory(params, stats);
@ -66,9 +76,15 @@ public class OpenMaptilesProfileTest {
"ele", "100"
))));
// no elevation
assertFeatures(14, List.of(), process(pointFeature(Map.of(
"natural", "volcano"
))));
// bogus elevation
assertFeatures(14, List.of(), process(pointFeature(Map.of(
"natural", "volcano",
"ele", "11000"
))));
}
@Test
@ -105,6 +121,27 @@ public class OpenMaptilesProfileTest {
))));
}
@Test
public void testMountainPeakNameTranslations() {
wikidataTranslations.put(123, "en", "wikidata en");
wikidataTranslations.put(123, "es", "wikidata es");
wikidataTranslations.put(123, "de", "wikidata de");
var feature = process(pointFeature(Map.of(
"natural", "peak",
"name", "name",
"name:en", "english name",
"name:de", "german name",
"wikidata", "Q123",
"ele", "100"
)));
assertFeatures(14, List.of(Map.of(
"name", "name",
"name_en", "english name",
"name_de", "german name",
"name:es", "wikidata es"
)), feature);
}
@Test
public void testMountainPeakMustBePoint() {
assertFeatures(14, List.of(), process(lineFeature(Map.of(