kopia lustrzana https://github.com/onthegomap/planetiler
101 wiersze
3.5 KiB
Java
101 wiersze
3.5 KiB
Java
package com.onthegomap.planetiler.custommap;
|
|
|
|
import static com.onthegomap.planetiler.expression.DataType.GET_TAG;
|
|
|
|
import com.onthegomap.planetiler.expression.DataType;
|
|
import com.onthegomap.planetiler.reader.WithTags;
|
|
import java.util.HashMap;
|
|
import java.util.LinkedHashMap;
|
|
import java.util.Map;
|
|
import java.util.function.BiFunction;
|
|
import java.util.function.Function;
|
|
import java.util.function.UnaryOperator;
|
|
|
|
/**
|
|
* Utility that parses attribute values from source features, based on YAML config.
|
|
*/
|
|
public class TagValueProducer {
|
|
public static final TagValueProducer EMPTY = new TagValueProducer(null);
|
|
|
|
private final Map<String, BiFunction<WithTags, String, Object>> valueRetriever = new HashMap<>();
|
|
|
|
private final Map<String, String> keyType = new HashMap<>();
|
|
|
|
public TagValueProducer(Map<String, Object> map) {
|
|
if (map == null) {
|
|
return;
|
|
}
|
|
|
|
map.forEach((key, value) -> {
|
|
if (value instanceof String stringType) {
|
|
valueRetriever.put(key, DataType.from(stringType));
|
|
keyType.put(key, stringType);
|
|
} else if (value instanceof Map<?, ?> renameMap) {
|
|
String inputKey = renameMap.containsKey("input") ? renameMap.get("input").toString() : key;
|
|
var getter =
|
|
renameMap.containsKey("type") ? DataType.from(renameMap.get("type").toString()) : DataType.GET_TAG;
|
|
//When requesting the output value, actually retrieve the input key with the desired getter
|
|
if (inputKey.equals(key)) {
|
|
valueRetriever.put(key, getter);
|
|
} else {
|
|
valueRetriever.put(key, (withTags, requestedKey) -> getter.convertFrom(valueForKey(withTags, inputKey)));
|
|
}
|
|
if (renameMap.containsKey("type")) {
|
|
keyType.put(key, renameMap.get("type").toString());
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns a function that extracts the value for {@code key} from a {@link WithTags} instance.
|
|
*/
|
|
public BiFunction<WithTags, String, Object> valueGetterForKey(String key) {
|
|
return valueRetriever.getOrDefault(key, GET_TAG);
|
|
}
|
|
|
|
/**
|
|
* Returns a function that extracts the value for {@code key} from a {@link WithTags} instance.
|
|
*/
|
|
public Function<Contexts.FeaturePostMatch, Object> valueProducerForKey(String key) {
|
|
var getter = valueGetterForKey(key);
|
|
return context -> getter.apply(context.parent().feature(), key);
|
|
}
|
|
|
|
/**
|
|
* Returns the mapped value for a key where the key is not known ahead of time.
|
|
*/
|
|
public Object valueForKey(WithTags feature, String key) {
|
|
return valueGetterForKey(key).apply(feature, key);
|
|
}
|
|
|
|
/**
|
|
* Returns copy of {@code keyedMap} where the keys have been transformed by the parser associated with {code key}.
|
|
*/
|
|
public <T> Map<Object, T> remapKeysByType(String key, Map<Object, T> keyedMap) {
|
|
Map<Object, T> newMap = new LinkedHashMap<>();
|
|
|
|
String dataType = keyType.get(key);
|
|
UnaryOperator<Object> parser;
|
|
|
|
if (dataType == null || (parser = DataType.from(dataType).parser()) == null) {
|
|
newMap.putAll(keyedMap);
|
|
} else {
|
|
keyedMap.forEach((mapKey, value) -> newMap.put(parser.apply(mapKey), value));
|
|
}
|
|
|
|
return newMap;
|
|
}
|
|
|
|
/** Returns a new map where every tag has been transformed (or inferred) by the registered conversions. */
|
|
public Map<String, Object> mapTags(WithTags feature) {
|
|
if (valueRetriever.isEmpty()) {
|
|
return feature.tags();
|
|
} else {
|
|
Map<String, Object> result = new HashMap<>(feature.tags());
|
|
valueRetriever.forEach((key, retriever) -> result.put(key, retriever.apply(feature, key)));
|
|
return result;
|
|
}
|
|
}
|
|
}
|