kopia lustrzana https://github.com/onthegomap/planetiler
progress on generating domain models
rodzic
84294010fe
commit
31097c669f
26
core/pom.xml
26
core/pom.xml
|
@ -15,7 +15,6 @@
|
|||
<properties>
|
||||
<graphhopper.version>2.3</graphhopper.version>
|
||||
<geotools.version>25.0</geotools.version>
|
||||
<junit.version>5.7.1</junit.version>
|
||||
<log4j.version>2.14.1</log4j.version>
|
||||
<prometheus.version>0.11.0</prometheus.version>
|
||||
</properties>
|
||||
|
@ -111,31 +110,6 @@
|
|||
<artifactId>simpleclient_hotspot</artifactId>
|
||||
<version>${prometheus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -1,8 +1,81 @@
|
|||
package com.onthegomap.flatmap;
|
||||
|
||||
import com.carrotsearch.hppc.ObjectIntMap;
|
||||
import com.graphhopper.coll.GHObjectIntHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Parse {
|
||||
|
||||
public static long parseLong(String idString) {
|
||||
return Long.parseLong(idString);
|
||||
public static Long parseLongOrNull(Object tag) {
|
||||
try {
|
||||
return tag == null ? null : tag instanceof Number number ? number.longValue() : Long.parseLong(tag.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static long parseLong(Object tag) {
|
||||
try {
|
||||
return tag == null ? 0 : tag instanceof Number number ? number.longValue() : Long.parseLong(tag.toString());
|
||||
} catch (NumberFormatException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Set<String> booleanFalseValues = Set.of("", "0", "false", "no");
|
||||
|
||||
public static boolean bool(Object tag) {
|
||||
return !(tag == null || booleanFalseValues.contains(tag.toString()));
|
||||
}
|
||||
|
||||
public static int boolInt(Object tag) {
|
||||
return bool(tag) ? 1 : 0;
|
||||
}
|
||||
|
||||
private static final Set<String> forwardDirections = Set.of("1", "yes", "true");
|
||||
|
||||
public static int direction(Object string) {
|
||||
if (forwardDirections.contains(string(string))) {
|
||||
return 1;
|
||||
} else if ("-1".equals(string)) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static final ObjectIntMap<String> defaultRank = new GHObjectIntHashMap<>();
|
||||
|
||||
static {
|
||||
defaultRank.put("minor", 3);
|
||||
defaultRank.put("road", 3);
|
||||
defaultRank.put("unclassified", 3);
|
||||
defaultRank.put("residential", 3);
|
||||
defaultRank.put("tertiary_link", 3);
|
||||
defaultRank.put("tertiary", 4);
|
||||
defaultRank.put("secondary_link", 3);
|
||||
defaultRank.put("secondary", 5);
|
||||
defaultRank.put("primary_link", 3);
|
||||
defaultRank.put("primary", 6);
|
||||
defaultRank.put("trunk_link", 3);
|
||||
defaultRank.put("trunk", 8);
|
||||
defaultRank.put("motorway_link", 3);
|
||||
defaultRank.put("motorway", 9);
|
||||
}
|
||||
|
||||
private static String string(Object object) {
|
||||
return object == null ? null : object.toString();
|
||||
}
|
||||
|
||||
public static int wayzorder(Map<String, Object> tags) {
|
||||
long z = Parse.parseLong(tags.get("layer")) * 10 +
|
||||
defaultRank.getOrDefault(
|
||||
string(tags.get("highway")),
|
||||
tags.containsKey("railway") ? 7 : 0
|
||||
) +
|
||||
(Parse.boolInt(tags.get("tunnel")) * -10L) +
|
||||
(Parse.boolInt(tags.get("bridge")) * 10L);
|
||||
return Math.abs(z) < 10_000 ? (int) z : 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,4 +174,25 @@ public abstract class SourceFeature {
|
|||
public final long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getString(String key) {
|
||||
Object value = getTag(key);
|
||||
return value == null ? null : value.toString();
|
||||
}
|
||||
|
||||
public boolean getBoolean(String key) {
|
||||
return Parse.bool(getTag(key));
|
||||
}
|
||||
|
||||
public long getLong(String key) {
|
||||
return Parse.parseLong(getTag(key));
|
||||
}
|
||||
|
||||
public int getDirection(String key) {
|
||||
return Parse.direction(getTag(key));
|
||||
}
|
||||
|
||||
public int getWayZorder() {
|
||||
return Parse.wayzorder(properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package com.onthegomap.flatmap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
import org.junit.jupiter.api.DynamicTest;
|
||||
import org.junit.jupiter.api.TestFactory;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
public class ParseTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"0, false, 0",
|
||||
"false, false, 0",
|
||||
"no, false, 0",
|
||||
"yes, true, 1",
|
||||
"true, true, 1",
|
||||
"ok, true, 1",
|
||||
})
|
||||
public void testBoolean(String in, boolean out, int boolint) {
|
||||
assertEquals(out, Parse.bool(in));
|
||||
assertEquals(boolint, Parse.boolInt(in));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource(value = {
|
||||
"0, 0, 0",
|
||||
"false, 0, null",
|
||||
"123, 123, 123"
|
||||
}, nullValues = {"null"})
|
||||
public void testLong(String in, long out, Long obj) {
|
||||
assertEquals(out, Parse.parseLong(in));
|
||||
assertEquals(obj, Parse.parseLongOrNull(in));
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({
|
||||
"1, 1",
|
||||
"yes, 1",
|
||||
"true, 1",
|
||||
"-1, -1",
|
||||
"2, 0",
|
||||
"0, 0"
|
||||
})
|
||||
public void testDirection(String in, int out) {
|
||||
assertEquals(out, Parse.direction(in));
|
||||
}
|
||||
|
||||
@TestFactory
|
||||
public Stream<DynamicTest> testWayzorder() {
|
||||
return Stream.<Map.Entry<Map<String, Object>, Integer>>of(
|
||||
Map.entry(Map.of(), 0),
|
||||
Map.entry(Map.of("layer", 1), 10),
|
||||
Map.entry(Map.of("layer", -3), -30),
|
||||
Map.entry(Map.of("highway", "motorway"), 9),
|
||||
Map.entry(Map.of("railway", "anything"), 7),
|
||||
Map.entry(Map.of("railway", "anything", "tunnel", "1"), -3),
|
||||
Map.entry(Map.of("railway", "anything", "bridge", "1"), 17)
|
||||
).map(entry -> dynamicTest(entry.getKey().toString(),
|
||||
() -> assertEquals(entry.getValue(), Parse.wayzorder(entry.getKey()))));
|
||||
}
|
||||
}
|
|
@ -19,9 +19,9 @@
|
|||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.dataformat</groupId>
|
||||
<artifactId>jackson-dataformat-yaml</artifactId>
|
||||
<version>${jackson.version}</version>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.29</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
package com.onthegomap.flatmap.openmaptiles;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public interface Expression {
|
||||
|
||||
static And and(Expression... children) {
|
||||
return and(List.of(children));
|
||||
}
|
||||
|
||||
static And and(List<Expression> children) {
|
||||
return new And(children);
|
||||
}
|
||||
|
||||
static Or or(Expression... children) {
|
||||
return or(List.of(children));
|
||||
}
|
||||
|
||||
static Or or(List<Expression> children) {
|
||||
return new Or(children);
|
||||
}
|
||||
|
||||
static MatchAny matchAny(String field, String... values) {
|
||||
return matchAny(field, List.of(values));
|
||||
}
|
||||
|
||||
static MatchAny matchAny(String field, List<String> values) {
|
||||
return new MatchAny(field, values);
|
||||
}
|
||||
|
||||
static MatchField matchField(String field) {
|
||||
return new MatchField(field);
|
||||
}
|
||||
|
||||
private static String listToString(List<?> items) {
|
||||
return items.stream().map(Object::toString).collect(Collectors.joining(", "));
|
||||
}
|
||||
|
||||
default Expression simplify() {
|
||||
return simplify(this);
|
||||
}
|
||||
|
||||
private static Expression simplifyOnce(Expression expression) {
|
||||
if (expression instanceof Or or) {
|
||||
if (or.children.size() == 1) {
|
||||
return simplifyOnce(or.children.get(0));
|
||||
}
|
||||
return or(or.children.stream()
|
||||
// hoist children
|
||||
.flatMap(child -> child instanceof Or childOr ? childOr.children.stream() : Stream.of(child))
|
||||
.map(Expression::simplifyOnce).toList());
|
||||
} else if (expression instanceof And and) {
|
||||
if (and.children.size() == 1) {
|
||||
return simplifyOnce(and.children.get(0));
|
||||
}
|
||||
return and(and.children.stream()
|
||||
// hoist children
|
||||
.flatMap(child -> child instanceof And childAnd ? childAnd.children.stream() : Stream.of(child))
|
||||
.map(Expression::simplifyOnce).toList());
|
||||
} else {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
|
||||
private static Expression simplify(Expression initial) {
|
||||
Expression simplified = initial;
|
||||
Set<Expression> seen = new HashSet<>();
|
||||
seen.add(simplified);
|
||||
while (true) {
|
||||
simplified = simplifyOnce(simplified);
|
||||
if (seen.contains(simplified) || seen.size() > 100) {
|
||||
return simplified;
|
||||
}
|
||||
seen.add(simplified);
|
||||
}
|
||||
}
|
||||
|
||||
record And(List<Expression> children) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "and(" + listToString(children) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
record Or(List<Expression> children) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "or(" + listToString(children) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
record MatchExact(String field, String value) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "matchExact(" + Generate.quote(field) + ", " + Generate.quote(value) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
record MatchAny(String field, List<String> values) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "matchAny(" + Generate.quote(field) + ", " + values.stream().map(Generate::quote)
|
||||
.collect(Collectors.joining(", ")) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
record MatchField(String field) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "matchField(" + Generate.quote(field) + ")";
|
||||
}
|
||||
}
|
||||
|
||||
record MatchWildcard(String field, String wildcard) implements Expression {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "matchWildcard(" + Generate.quote(field) + ", " + Generate.quote(wildcard) + ")";
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
package com.onthegomap.flatmap.openmaptiles;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public record FieldMapping(Map<String, Expression> mappings) {}
|
|
@ -1,27 +1,41 @@
|
|||
package com.onthegomap.flatmap.openmaptiles;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.and;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.matchAny;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.matchField;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.or;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.onthegomap.flatmap.Arguments;
|
||||
import com.onthegomap.flatmap.FileUtils;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
public class Generate {
|
||||
|
||||
private static Logger LOGGER = LoggerFactory.getLogger(Generate.class);
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);
|
||||
|
||||
private static record OpenmaptilesConfig(
|
||||
OpenmaptilesTileSet tileset
|
||||
|
@ -38,7 +52,6 @@ public class Generate {
|
|||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private static record LayerDetails(
|
||||
String id,
|
||||
String requires,
|
||||
String description,
|
||||
Map<String, JsonNode> fields,
|
||||
double buffer_size
|
||||
|
@ -55,55 +68,378 @@ public class Generate {
|
|||
List<Datasource> datasources
|
||||
) {}
|
||||
|
||||
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
|
||||
property = "columnId")
|
||||
private static record Imposm3Column(
|
||||
String columnId,
|
||||
String type,
|
||||
String name,
|
||||
String key
|
||||
String key,
|
||||
boolean from_member
|
||||
) {}
|
||||
|
||||
private static record Imposm3Filters(
|
||||
Map<String, List<String>> reject,
|
||||
Map<String, List<String>> require
|
||||
) {}
|
||||
|
||||
private static record Imposm3Table(
|
||||
String type,
|
||||
@JsonProperty("_resolve_wikidata") boolean resolveWikidata,
|
||||
List<Imposm3Column> columns,
|
||||
JsonNode mapping
|
||||
Imposm3Filters filters,
|
||||
JsonNode mapping,
|
||||
Map<String, Map<String, List<String>>> type_mappings
|
||||
) {}
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
private static record Imposm3Mapping(
|
||||
Map<String, Imposm3Table> tables
|
||||
) {}
|
||||
|
||||
public static void main(String[] args) throws IOException, URISyntaxException {
|
||||
var objectMapper = new ObjectMapper(new YAMLFactory());
|
||||
private static final ObjectMapper mapper = new ObjectMapper();
|
||||
private static final Yaml yaml;
|
||||
|
||||
static {
|
||||
var options = new LoaderOptions();
|
||||
options.setMaxAliasesForCollections(1_000);
|
||||
yaml = new Yaml(options);
|
||||
}
|
||||
|
||||
private static <T> T load(URL url, Class<T> clazz) throws IOException {
|
||||
LOGGER.info("reading " + url);
|
||||
try (var stream = url.openStream()) {
|
||||
Map<String, Object> parsed = yaml.load(stream);
|
||||
return mapper.convertValue(parsed, clazz);
|
||||
}
|
||||
}
|
||||
|
||||
static <T> T parseYaml(String string, Class<T> clazz) {
|
||||
Map<String, Object> parsed = yaml.load(string);
|
||||
return mapper.convertValue(parsed, clazz);
|
||||
}
|
||||
|
||||
static JsonNode parseYaml(String string) {
|
||||
return parseYaml(string, JsonNode.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Arguments arguments = Arguments.fromJvmProperties();
|
||||
String tag = arguments.get("tag", "openmaptiles tag to use", "v3.12.2");
|
||||
String base = "https://raw.githubusercontent.com/openmaptiles/openmaptiles/" + tag + "/";
|
||||
|
||||
base = "jar:file:/tmp/openmaptiles-3.12.2.zip!/openmaptiles-3.12.2/";
|
||||
var rootUrl = new URL(base + "openmaptiles.yaml");
|
||||
LOGGER.info("reading " + rootUrl);
|
||||
OpenmaptilesConfig config = objectMapper.readValue(rootUrl, OpenmaptilesConfig.class);
|
||||
OpenmaptilesConfig config = load(rootUrl, OpenmaptilesConfig.class);
|
||||
|
||||
List<LayerConfig> layers = new ArrayList<>();
|
||||
Set<URI> mappingFiles = new LinkedHashSet<>();
|
||||
Set<String> mappingFiles = new LinkedHashSet<>();
|
||||
for (String layerFile : config.tileset.layers) {
|
||||
URL layerURL = new URL(base + layerFile);
|
||||
LOGGER.info("reading " + layerURL);
|
||||
LayerConfig layer = objectMapper.readValue(layerURL, LayerConfig.class);
|
||||
LayerConfig layer = load(layerURL, LayerConfig.class);
|
||||
layers.add(layer);
|
||||
for (Datasource datasource : layer.datasources) {
|
||||
if ("imposm3".equals(datasource.type)) {
|
||||
mappingFiles.add(layerURL.toURI().resolve(datasource.mapping_file).normalize());
|
||||
String mappingPath = Path.of(layerFile).resolveSibling(datasource.mapping_file).normalize().toString();
|
||||
mappingFiles.add(base + mappingPath);
|
||||
} else {
|
||||
LOGGER.warn("Unknown datasource type: " + datasource.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (URI uri : mappingFiles) {
|
||||
LOGGER.info("reading " + uri);
|
||||
Imposm3Mapping layer = objectMapper.readValue(uri.toURL(), Imposm3Mapping.class);
|
||||
LOGGER.info(layer.toString());
|
||||
Map<String, Imposm3Table> tables = new LinkedHashMap<>();
|
||||
for (String uri : mappingFiles) {
|
||||
Imposm3Mapping layer = load(new URL(uri), Imposm3Mapping.class);
|
||||
tables.putAll(layer.tables);
|
||||
}
|
||||
|
||||
String packageName = "com.onthegomap.flatmap.openmaptiles.generated";
|
||||
String[] packageParts = packageName.split("\\.");
|
||||
Path output = Path.of("openmaptiles", "src", "main", "java")
|
||||
.resolve(Path.of(packageParts[0], Arrays.copyOfRange(packageParts, 1, packageParts.length)));
|
||||
|
||||
FileUtils.deleteDirectory(output);
|
||||
Files.createDirectories(output);
|
||||
|
||||
emitLayerDefinitions(layers, packageName, output);
|
||||
emitTableDefinitions(tables, packageName, output);
|
||||
|
||||
// layers.forEach((layer) -> LOGGER.info("layer: " + layer.layer.id));
|
||||
// tables.forEach((key, val) -> LOGGER.info("table: " + key));
|
||||
}
|
||||
|
||||
private static void emitTableDefinitions(Map<String, Imposm3Table> tables, String packageName, Path output)
|
||||
throws IOException {
|
||||
StringBuilder tablesClass = new StringBuilder();
|
||||
tablesClass.append("""
|
||||
// AUTOGENERATED BY Generate.java -- DO NOT MODIFY
|
||||
package %s;
|
||||
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.*;
|
||||
import com.onthegomap.flatmap.openmaptiles.FieldMapping;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Tables {
|
||||
""".formatted(packageName));
|
||||
|
||||
for (var entry : tables.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
Imposm3Table table = entry.getValue();
|
||||
List<OsmTableField> fields = getFields(table);
|
||||
if (fields.size() <= 1) {
|
||||
tablesClass.append("public static record %s(%s) {}".formatted(
|
||||
lowerUnderscoreToUpperCamel("osm_" + key),
|
||||
fields.stream().map(c -> c.clazz + " " + lowerUnderscoreToLowerCamel(c.name))
|
||||
.collect(joining(", "))).indent(2));
|
||||
} else {
|
||||
tablesClass.append("""
|
||||
public static record %s(%s) {
|
||||
public %s(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(%s);
|
||||
}
|
||||
}
|
||||
""".formatted(
|
||||
lowerUnderscoreToUpperCamel("osm_" + key),
|
||||
fields.stream().map(c -> c.clazz + " " + lowerUnderscoreToLowerCamel(c.name))
|
||||
.collect(joining(", ")),
|
||||
lowerUnderscoreToUpperCamel("osm_" + key),
|
||||
fields.stream().map(c -> c.extractCode).collect(joining(", "))
|
||||
).indent(2));
|
||||
}
|
||||
}
|
||||
|
||||
tablesClass.append("}");
|
||||
Files.writeString(output.resolve("Tables.java"), tablesClass);
|
||||
}
|
||||
|
||||
private static List<OsmTableField> getFields(Imposm3Table tableDefinition) {
|
||||
List<OsmTableField> result = new ArrayList<>();
|
||||
result.add(new OsmTableField("com.onthegomap.flatmap.SourceFeature", "source", "source"));
|
||||
// TODO columns used, and from_member
|
||||
for (Imposm3Column col : tableDefinition.columns) {
|
||||
switch (col.type) {
|
||||
case "id", "validated_geometry", "area", "hstore_tags", "geometry" -> {
|
||||
// do nothing - already on source feature
|
||||
}
|
||||
case "member_id", "member_role", "member_type", "member_index" -> {
|
||||
|
||||
}
|
||||
case "mapping_key" -> {
|
||||
// TODO?
|
||||
}
|
||||
case "mapping_value" -> {
|
||||
// TODO??
|
||||
}
|
||||
case "string" -> result
|
||||
.add(new OsmTableField("String", col.name,
|
||||
"source.getString(\"%s\")".formatted(Objects.requireNonNull(col.key, col.toString()))));
|
||||
case "bool" -> result
|
||||
.add(new OsmTableField("boolean", col.name,
|
||||
"source.getBoolean(\"%s\")".formatted(Objects.requireNonNull(col.key, col.toString()))));
|
||||
case "integer" -> result
|
||||
.add(new OsmTableField("long", col.name,
|
||||
"source.getLong(\"%s\")".formatted(Objects.requireNonNull(col.key, col.toString()))));
|
||||
case "wayzorder" -> result.add(new OsmTableField("int", col.name, "source.getWayZorder()"));
|
||||
case "direction" -> result.add(new OsmTableField("int", col.name,
|
||||
"source.getDirection(\"%s\")".formatted(Objects.requireNonNull(col.key, col.toString()))));
|
||||
default -> throw new IllegalArgumentException("Unhandled column: " + col.type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static record OsmTableField(
|
||||
String clazz,
|
||||
String name,
|
||||
String extractCode
|
||||
) {}
|
||||
|
||||
private static void emitLayerDefinitions(List<LayerConfig> layers, String packageName, Path output)
|
||||
throws IOException {
|
||||
StringBuilder layersClass = new StringBuilder();
|
||||
layersClass.append("""
|
||||
// AUTOGENERATED BY Generate.java -- DO NOT MODIFY
|
||||
package %s;
|
||||
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.*;
|
||||
import com.onthegomap.flatmap.openmaptiles.FieldMapping;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Layers {
|
||||
""".formatted(packageName));
|
||||
for (var layer : layers) {
|
||||
String layerName = layer.layer.id;
|
||||
String className = lowerUnderscoreToUpperCamel(layerName);
|
||||
|
||||
StringBuilder fields = new StringBuilder();
|
||||
StringBuilder fieldValues = new StringBuilder();
|
||||
StringBuilder fieldMappings = new StringBuilder();
|
||||
|
||||
layer.layer.fields.forEach((name, value) -> {
|
||||
JsonNode valuesNode = value.get("values");
|
||||
List<String> valuesForComment = valuesNode == null ? List.of() : valuesNode.isArray() ?
|
||||
iterToList(valuesNode.elements()).stream().map(Objects::toString).toList() :
|
||||
iterToList(valuesNode.fieldNames());
|
||||
String javadocDescription = escapeJavadoc(getFieldDescription(value));
|
||||
fields.append("""
|
||||
%s
|
||||
public static final String %s = %s;
|
||||
""".formatted(
|
||||
valuesForComment.isEmpty() ? "/** %s */".formatted(javadocDescription) : """
|
||||
|
||||
/**
|
||||
* %s
|
||||
* <p>
|
||||
* allowed values:
|
||||
* <ul>
|
||||
* %s
|
||||
* </ul>
|
||||
*/
|
||||
""".stripTrailing().formatted(javadocDescription,
|
||||
valuesForComment.stream().map(v -> "<li>" + v).collect(joining("\n * "))),
|
||||
name.toUpperCase(Locale.ROOT),
|
||||
quote(name)
|
||||
).indent(4));
|
||||
|
||||
List<String> values = valuesNode == null ? List.of() : valuesNode.isArray() ?
|
||||
iterToList(valuesNode.elements()).stream().filter(JsonNode::isTextual).map(JsonNode::textValue)
|
||||
.map(t -> t.replaceAll(" .*", "")).toList() :
|
||||
iterToList(valuesNode.fieldNames());
|
||||
if (values.size() > 0) {
|
||||
fieldValues.append("""
|
||||
public static final class %s {
|
||||
%s
|
||||
}
|
||||
""".formatted(
|
||||
lowerUnderscoreToUpperCamel(name),
|
||||
values.stream()
|
||||
.map(v -> "public static final String %s = %s;"
|
||||
.formatted(v.toUpperCase(Locale.ROOT).replace('-', '_'), quote(v)))
|
||||
.collect(joining("\n")).indent(2).strip()
|
||||
).indent(4));
|
||||
}
|
||||
|
||||
if (valuesNode != null && valuesNode.isObject()) {
|
||||
FieldMapping mapping = generateFieldMapping(valuesNode);
|
||||
fieldMappings.append(" public static final FieldMapping %s = %s;\n"
|
||||
.formatted(lowerUnderscoreToUpperCamel(name), generateCode(mapping)));
|
||||
}
|
||||
});
|
||||
|
||||
layersClass.append("""
|
||||
/** %s */
|
||||
public static class %s {
|
||||
public static final double BUFFER_SIZE = %s;
|
||||
public static final String NAME = %s;
|
||||
public static final class Fields {
|
||||
%s
|
||||
}
|
||||
public static final class FieldValues {
|
||||
%s
|
||||
}
|
||||
public static final class FieldMappings {
|
||||
%s
|
||||
}
|
||||
}
|
||||
""".formatted(
|
||||
escapeJavadoc(layer.layer.description),
|
||||
className,
|
||||
layer.layer.buffer_size,
|
||||
quote(layerName),
|
||||
fields.toString().strip(),
|
||||
"// TODO", // fieldValues.toString().strip(),
|
||||
fieldMappings.toString().strip()
|
||||
).indent(2));
|
||||
}
|
||||
|
||||
layersClass.append("}");
|
||||
Files.writeString(output.resolve("Layers.java"), layersClass);
|
||||
}
|
||||
|
||||
static FieldMapping generateFieldMapping(JsonNode valuesNode) {
|
||||
FieldMapping mapping = new FieldMapping(new LinkedHashMap<>());
|
||||
valuesNode.fields().forEachRemaining(entry -> {
|
||||
String field = entry.getKey();
|
||||
JsonNode node = entry.getValue();
|
||||
Expression expression = or(parseExpression(node).toList()).simplify();
|
||||
if (!expression.equals(or()) && !expression.equals(and())) {
|
||||
mapping.mappings().put(field, expression);
|
||||
}
|
||||
});
|
||||
return mapping;
|
||||
}
|
||||
|
||||
private static Stream<Expression> parseExpression(JsonNode node) {
|
||||
if (node.isObject()) {
|
||||
List<String> keys = iterToList(node.fieldNames());
|
||||
if (keys.contains("__AND__")) {
|
||||
if (keys.size() > 1) {
|
||||
throw new IllegalArgumentException("Cannot combine __AND__ with others");
|
||||
}
|
||||
return Stream.of(and(parseExpression(node.get("__AND__")).toList()));
|
||||
} else if (keys.contains("__OR__")) {
|
||||
if (keys.size() > 1) {
|
||||
throw new IllegalArgumentException("Cannot combine __OR__ with others");
|
||||
}
|
||||
return Stream.of(or(parseExpression(node.get("__OR__")).toList()));
|
||||
} else {
|
||||
return iterToList(node.fields()).stream().map(entry -> {
|
||||
String field = entry.getKey();
|
||||
List<String> value = toFlatList(entry.getValue()).map(JsonNode::textValue).filter(Objects::nonNull).toList();
|
||||
return value.isEmpty() ? matchField(field) : matchAny(field, value);
|
||||
});
|
||||
}
|
||||
} else if (node.isArray()) {
|
||||
return iterToList(node.elements()).stream().flatMap(Generate::parseExpression);
|
||||
} else if (node.isNull()) {
|
||||
return Stream.empty();
|
||||
} else {
|
||||
throw new IllegalArgumentException("parseExpression input not handled: " + node);
|
||||
}
|
||||
}
|
||||
|
||||
private static Stream<JsonNode> toFlatList(JsonNode node) {
|
||||
return node.isArray() ? iterToList(node.elements()).stream().flatMap(Generate::toFlatList) : Stream.of(node);
|
||||
}
|
||||
|
||||
private static String generateCode(FieldMapping mapping) {
|
||||
return "new FieldMapping(Map.ofEntries(" + mapping.mappings().entrySet().stream()
|
||||
.map(s -> "Map.entry(%s, %s)".formatted(quote(s.getKey()), s.getValue()))
|
||||
.collect(joining(", ")) + "))";
|
||||
}
|
||||
|
||||
private static String lowerUnderscoreToLowerCamel(String name) {
|
||||
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
|
||||
}
|
||||
|
||||
private static String lowerUnderscoreToUpperCamel(String name) {
|
||||
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, name);
|
||||
}
|
||||
|
||||
private static <T> List<T> iterToList(Iterator<T> iter) {
|
||||
List<T> result = new ArrayList<>();
|
||||
iter.forEachRemaining(result::add);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static String escapeJavadoc(String description) {
|
||||
return description.replaceAll("[\n\r*\\s]+", " ");
|
||||
}
|
||||
|
||||
private static String getFieldDescription(JsonNode value) {
|
||||
if (value.isTextual()) {
|
||||
return value.textValue();
|
||||
} else {
|
||||
return value.get("description").textValue();
|
||||
}
|
||||
}
|
||||
|
||||
static String quote(String other) {
|
||||
if (other == null) {
|
||||
return "null";
|
||||
}
|
||||
if (other.contains("\"")) {
|
||||
throw new IllegalStateException("cannot quote: " + other);
|
||||
}
|
||||
return '"' + other + '"';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
public class OpenMapTilesProfile implements Profile {
|
||||
|
||||
private static boolean MERGE_Z13_BUILDINGS = false;
|
||||
private static final boolean MERGE_Z13_BUILDINGS = false;
|
||||
|
||||
public static final String LAKE_CENTERLINE_SOURCE = "lake_centerlines";
|
||||
public static final String WATER_POLYGON_SOURCE = "water_polygons";
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,339 @@
|
|||
// AUTOGENERATED BY Generate.java -- DO NOT MODIFY
|
||||
package com.onthegomap.flatmap.openmaptiles.generated;
|
||||
|
||||
public class Tables {
|
||||
|
||||
public static record OsmWaterPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String natural,
|
||||
String landuse, String waterway, boolean isIntermittent, boolean isTunnel, boolean isBridge
|
||||
) {
|
||||
|
||||
public OsmWaterPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("natural"), source.getString("landuse"), source.getString("waterway"),
|
||||
source.getBoolean("intermittent"), source.getBoolean("tunnel"), source.getBoolean("bridge"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmWaterwayLinestring(
|
||||
com.onthegomap.flatmap.SourceFeature source, String waterway, String name, String nameEn, String nameDe,
|
||||
boolean isTunnel, boolean isBridge, boolean isIntermittent
|
||||
) {
|
||||
|
||||
public OsmWaterwayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("waterway"), source.getString("name"), source.getString("name:en"),
|
||||
source.getString("name:de"), source.getBoolean("tunnel"), source.getBoolean("bridge"),
|
||||
source.getBoolean("intermittent"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmLandcoverPolygon(com.onthegomap.flatmap.SourceFeature source) {}
|
||||
|
||||
public static record OsmLandusePolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String landuse, String amenity, String leisure, String tourism,
|
||||
String place, String waterway
|
||||
) {
|
||||
|
||||
public OsmLandusePolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("landuse"), source.getString("amenity"), source.getString("leisure"),
|
||||
source.getString("tourism"), source.getString("place"), source.getString("waterway"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmPeakPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String ele, String wikipedia
|
||||
) {
|
||||
|
||||
public OsmPeakPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("ele"), source.getString("wikipedia"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmParkPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String landuse,
|
||||
String leisure, String boundary, String protectionTitle
|
||||
) {
|
||||
|
||||
public OsmParkPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("landuse"), source.getString("leisure"), source.getString("boundary"),
|
||||
source.getString("protection_title"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmBorderDispRelation(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String boundary, long adminLevel, String claimedBy,
|
||||
String disputedBy, boolean maritime
|
||||
) {
|
||||
|
||||
public OsmBorderDispRelation(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("boundary"), source.getLong("admin_level"),
|
||||
source.getString("claimed_by"), source.getString("disputed_by"), source.getBoolean("maritime"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmAerowayPolygon(com.onthegomap.flatmap.SourceFeature source, String ref) {
|
||||
|
||||
public OsmAerowayPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("ref"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmAerowayLinestring(com.onthegomap.flatmap.SourceFeature source, String ref, String aeroway) {
|
||||
|
||||
public OsmAerowayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("ref"), source.getString("aeroway"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmAerowayPoint(com.onthegomap.flatmap.SourceFeature source, String ref, String aeroway) {
|
||||
|
||||
public OsmAerowayPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("ref"), source.getString("aeroway"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmHighwayLinestring(
|
||||
com.onthegomap.flatmap.SourceFeature source, String highway, String construction, String ref, String network,
|
||||
int zOrder, long layer, long level, boolean indoor, String name, String nameEn, String nameDe, String shortName,
|
||||
boolean isTunnel, boolean isBridge, boolean isRamp, boolean isFord, int isOneway, boolean isArea, String service,
|
||||
String usage, String publicTransport, String manMade, String bicycle, String foot, String horse, String mtbScale,
|
||||
String surface
|
||||
) {
|
||||
|
||||
public OsmHighwayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("highway"), source.getString("construction"), source.getString("ref"),
|
||||
source.getString("network"), source.getWayZorder(), source.getLong("layer"), source.getLong("level"),
|
||||
source.getBoolean("indoor"), source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("short_name"), source.getBoolean("tunnel"), source.getBoolean("bridge"),
|
||||
source.getBoolean("ramp"), source.getBoolean("ford"), source.getDirection("oneway"), source.getBoolean("area"),
|
||||
source.getString("service"), source.getString("usage"), source.getString("public_transport"),
|
||||
source.getString("man_made"), source.getString("bicycle"), source.getString("foot"), source.getString("horse"),
|
||||
source.getString("mtb:scale"), source.getString("surface"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmRailwayLinestring(
|
||||
com.onthegomap.flatmap.SourceFeature source, String railway, String ref, String network, int zOrder, long layer,
|
||||
long level, boolean indoor, String name, String nameEn, String nameDe, String shortName, boolean isTunnel,
|
||||
boolean isBridge, boolean isRamp, boolean isFord, int isOneway, boolean isArea, String service, String usage
|
||||
) {
|
||||
|
||||
public OsmRailwayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("railway"), source.getString("ref"), source.getString("network"),
|
||||
source.getWayZorder(), source.getLong("layer"), source.getLong("level"), source.getBoolean("indoor"),
|
||||
source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("short_name"), source.getBoolean("tunnel"), source.getBoolean("bridge"),
|
||||
source.getBoolean("ramp"), source.getBoolean("ford"), source.getDirection("oneway"), source.getBoolean("area"),
|
||||
source.getString("service"), source.getString("usage"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmAerialwayLinestring(
|
||||
com.onthegomap.flatmap.SourceFeature source, String aerialway, int zOrder, long layer, String name, String nameEn,
|
||||
String nameDe, String shortName, boolean isTunnel, boolean isBridge, boolean isRamp, boolean isFord, int isOneway,
|
||||
boolean isArea, String service, String usage
|
||||
) {
|
||||
|
||||
public OsmAerialwayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("aerialway"), source.getWayZorder(), source.getLong("layer"),
|
||||
source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("short_name"), source.getBoolean("tunnel"), source.getBoolean("bridge"),
|
||||
source.getBoolean("ramp"), source.getBoolean("ford"), source.getDirection("oneway"), source.getBoolean("area"),
|
||||
source.getString("service"), source.getString("usage"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmShipwayLinestring(
|
||||
com.onthegomap.flatmap.SourceFeature source, String shipway, int zOrder, long layer, String name, String nameEn,
|
||||
String nameDe, String shortName, boolean isTunnel, boolean isBridge, boolean isRamp, boolean isFord, int isOneway,
|
||||
boolean isArea, String service, String usage
|
||||
) {
|
||||
|
||||
public OsmShipwayLinestring(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("route"), source.getWayZorder(), source.getLong("layer"), source.getString("name"),
|
||||
source.getString("name:en"), source.getString("name:de"), source.getString("short_name"),
|
||||
source.getBoolean("tunnel"), source.getBoolean("bridge"), source.getBoolean("ramp"), source.getBoolean("ford"),
|
||||
source.getDirection("oneway"), source.getBoolean("area"), source.getString("service"),
|
||||
source.getString("usage"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmHighwayPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String highway, int zOrder, long layer, long level, boolean indoor,
|
||||
boolean isArea, String publicTransport, String manMade
|
||||
) {
|
||||
|
||||
public OsmHighwayPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("highway"), source.getWayZorder(), source.getLong("layer"), source.getLong("level"),
|
||||
source.getBoolean("indoor"), source.getBoolean("area"), source.getString("public_transport"),
|
||||
source.getString("man_made"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmRouteMember(
|
||||
com.onthegomap.flatmap.SourceFeature source, String ref, String network, String name
|
||||
) {
|
||||
|
||||
public OsmRouteMember(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("ref"), source.getString("network"), source.getString("name"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmBuildingPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String material, String colour, String building, String buildingpart,
|
||||
String buildingheight, String buildingminHeight, String buildinglevels, String buildingminLevel, String height,
|
||||
String minHeight, String levels, String minLevel
|
||||
) {
|
||||
|
||||
public OsmBuildingPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("building:material"), source.getString("building:colour"),
|
||||
source.getString("building"), source.getString("building:part"), source.getString("building:height"),
|
||||
source.getString("building:min_height"), source.getString("building:levels"),
|
||||
source.getString("building:min_level"), source.getString("height"), source.getString("min_height"),
|
||||
source.getString("levels"), source.getString("min_level"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmBuildingRelation(
|
||||
com.onthegomap.flatmap.SourceFeature source, String building, String material, String colour, String buildingpart,
|
||||
String buildingheight, String height, String buildingminHeight, String minHeight, String buildinglevels,
|
||||
String levels, String buildingminLevel, String minLevel, String relbuildingheight, String relheight,
|
||||
String relbuildingminHeight, String relminHeight, String relbuildinglevels, String rellevels,
|
||||
String relbuildingminLevel, String relminLevel
|
||||
) {
|
||||
|
||||
public OsmBuildingRelation(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("building"), source.getString("building:material"),
|
||||
source.getString("building:colour"), source.getString("building:part"), source.getString("building:height"),
|
||||
source.getString("height"), source.getString("building:min_height"), source.getString("min_height"),
|
||||
source.getString("building:levels"), source.getString("levels"), source.getString("building:min_level"),
|
||||
source.getString("min_level"), source.getString("building:height"), source.getString("height"),
|
||||
source.getString("building:min_height"), source.getString("min_height"), source.getString("building:levels"),
|
||||
source.getString("levels"), source.getString("building:min_level"), source.getString("min_level"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmMarinePoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String place, long rank,
|
||||
boolean isIntermittent
|
||||
) {
|
||||
|
||||
public OsmMarinePoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("place"), source.getLong("rank"), source.getBoolean("intermittent"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmContinentPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe
|
||||
) {
|
||||
|
||||
public OsmContinentPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmCountryPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, long rank,
|
||||
String countryCodeIso31661Alpha2, String iso31661Alpha2, String iso31661
|
||||
) {
|
||||
|
||||
public OsmCountryPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getLong("rank"), source.getString("country_code_iso3166_1_alpha_2"),
|
||||
source.getString("ISO3166-1:alpha2"), source.getString("ISO3166-1"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmIslandPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, long rank
|
||||
) {
|
||||
|
||||
public OsmIslandPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getLong("rank"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmIslandPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, long rank
|
||||
) {
|
||||
|
||||
public OsmIslandPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getLong("rank"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmStatePoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String isInCountry,
|
||||
String isInCountryCode, String ref, long rank
|
||||
) {
|
||||
|
||||
public OsmStatePoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("is_in:country"), source.getString("is_in:country_code"), source.getString("ref"),
|
||||
source.getLong("rank"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmCityPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String place,
|
||||
long population, String capital, long rank
|
||||
) {
|
||||
|
||||
public OsmCityPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("place"), source.getLong("population"), source.getString("capital"), source.getLong("rank"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmHousenumberPoint(com.onthegomap.flatmap.SourceFeature source, String housenumber) {
|
||||
|
||||
public OsmHousenumberPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("addr:housenumber"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmPoiPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String station,
|
||||
String funicular, String information, String uicRef, String religion, long level, boolean indoor, long layer,
|
||||
String sport
|
||||
) {
|
||||
|
||||
public OsmPoiPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("station"), source.getString("funicular"), source.getString("information"),
|
||||
source.getString("uic_ref"), source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"),
|
||||
source.getLong("layer"), source.getString("sport"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmPoiPolygon(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String station,
|
||||
String funicular, String information, String uicRef, String religion, long level, boolean indoor, long layer,
|
||||
String sport
|
||||
) {
|
||||
|
||||
public OsmPoiPolygon(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("station"), source.getString("funicular"), source.getString("information"),
|
||||
source.getString("uic_ref"), source.getString("religion"), source.getLong("level"), source.getBoolean("indoor"),
|
||||
source.getLong("layer"), source.getString("sport"));
|
||||
}
|
||||
}
|
||||
|
||||
public static record OsmAerodromeLabelPoint(
|
||||
com.onthegomap.flatmap.SourceFeature source, String name, String nameEn, String nameDe, String aerodromeType,
|
||||
String aerodrome, String military, String iata, String icao, String ele
|
||||
) {
|
||||
|
||||
public OsmAerodromeLabelPoint(com.onthegomap.flatmap.SourceFeature source) {
|
||||
this(source, source.getString("name"), source.getString("name:en"), source.getString("name:de"),
|
||||
source.getString("aerodrome:type"), source.getString("aerodrome"), source.getString("military"),
|
||||
source.getString("iata"), source.getString("icao"), source.getString("ele"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.onthegomap.flatmap.openmaptiles;
|
||||
|
||||
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 static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class ExpressionTest {
|
||||
|
||||
@Test
|
||||
public void testSimplify() {
|
||||
assertEquals(matchAny("a", "b"), matchAny("a", "b").simplify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyAdjacentOrs() {
|
||||
assertEquals(or(matchAny("a", "b"), matchAny("c", "d")),
|
||||
or(or(matchAny("a", "b")), or(matchAny("c", "d"))).simplify()
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyOrWithOneChild() {
|
||||
assertEquals(matchAny("a", "b"), or(matchAny("a", "b")).simplify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyOAndWithOneChild() {
|
||||
assertEquals(matchAny("a", "b"), and(matchAny("a", "b")).simplify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyDeeplyNested() {
|
||||
assertEquals(matchAny("a", "b"), or(or(and(and(matchAny("a", "b"))))).simplify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyDeeplyNested2() {
|
||||
assertEquals(or(matchAny("a", "b"), matchAny("b", "c")),
|
||||
or(or(and(and(matchAny("a", "b"))), matchAny("b", "c"))).simplify());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimplifyDeeplyNested3() {
|
||||
assertEquals(or(and(matchAny("a", "b"), matchAny("c", "d")), matchAny("b", "c")),
|
||||
or(or(and(and(matchAny("a", "b")), matchAny("c", "d")), matchAny("b", "c"))).simplify());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package com.onthegomap.flatmap.openmaptiles;
|
||||
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.and;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.matchAny;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.matchField;
|
||||
import static com.onthegomap.flatmap.openmaptiles.Expression.or;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class GenerateTest {
|
||||
|
||||
@Test
|
||||
public void testParseSimple() {
|
||||
FieldMapping parsed = Generate.generateFieldMapping(Generate.parseYaml("""
|
||||
output:
|
||||
key: value
|
||||
key2:
|
||||
- value2
|
||||
- '%value3%'
|
||||
"""));
|
||||
assertEquals(new FieldMapping(Map.of(
|
||||
"output", or(
|
||||
matchAny("key", "value"),
|
||||
matchAny("key2", "value2", "%value3%")
|
||||
)
|
||||
)), parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAnd() {
|
||||
FieldMapping parsed = Generate.generateFieldMapping(Generate.parseYaml("""
|
||||
output:
|
||||
__AND__:
|
||||
key1: val1
|
||||
key2: val2
|
||||
"""));
|
||||
assertEquals(new FieldMapping(Map.of(
|
||||
"output", and(
|
||||
matchAny("key1", "val1"),
|
||||
matchAny("key2", "val2")
|
||||
)
|
||||
)), parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndWithOthers() {
|
||||
FieldMapping parsed = Generate.generateFieldMapping(Generate.parseYaml("""
|
||||
output:
|
||||
- key0: val0
|
||||
- __AND__:
|
||||
key1: val1
|
||||
key2: val2
|
||||
"""));
|
||||
assertEquals(new FieldMapping(Map.of(
|
||||
"output", or(
|
||||
matchAny("key0", "val0"),
|
||||
and(
|
||||
matchAny("key1", "val1"),
|
||||
matchAny("key2", "val2")
|
||||
)
|
||||
)
|
||||
)), parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseAndContainingOthers() {
|
||||
FieldMapping parsed = Generate.generateFieldMapping(Generate.parseYaml("""
|
||||
output:
|
||||
__AND__:
|
||||
- key1: val1
|
||||
- __OR__:
|
||||
key2: val2
|
||||
key3: val3
|
||||
"""));
|
||||
assertEquals(new FieldMapping(Map.of(
|
||||
"output", and(
|
||||
matchAny("key1", "val1"),
|
||||
or(
|
||||
matchAny("key2", "val2"),
|
||||
matchAny("key3", "val3")
|
||||
)
|
||||
)
|
||||
)), parsed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseContainsKey() {
|
||||
FieldMapping parsed = Generate.generateFieldMapping(Generate.parseYaml("""
|
||||
output:
|
||||
key1: val1
|
||||
key2:
|
||||
"""));
|
||||
assertEquals(new FieldMapping(Map.of(
|
||||
"output", or(
|
||||
matchAny("key1", "val1"),
|
||||
matchField("key2")
|
||||
)
|
||||
)), parsed);
|
||||
}
|
||||
}
|
52
pom.xml
52
pom.xml
|
@ -15,6 +15,7 @@
|
|||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<jackson.version>2.12.3</jackson.version>
|
||||
<junit.version>5.7.1</junit.version>
|
||||
</properties>
|
||||
|
||||
<scm>
|
||||
|
@ -43,6 +44,57 @@
|
|||
<module>openmaptiles</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<version>3.9.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
Ładowanie…
Reference in New Issue