Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parquet/no-build-tool java profile usability improvements #914

Merged
merged 10 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions planetiler-core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,10 @@
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.snakeyaml</groupId>
<artifactId>snakeyaml-engine</artifactId>
</dependency>
<dependency>
<groupId>io.prometheus</groupId>
<artifactId>simpleclient</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Feature point(String layer) {
return geometry(layer, source.worldGeometry());
} catch (GeometryException e) {
e.log(stats, "feature_point", "Error getting point geometry for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -106,7 +106,7 @@ public Feature line(String layer) {
return geometry(layer, source.line());
} catch (GeometryException e) {
e.log(stats, "feature_line", "Error constructing line for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -126,7 +126,7 @@ public Feature partialLine(String layer, double start, double end) {
return geometry(layer, source.partialLine(start, end));
} catch (GeometryException e) {
e.log(stats, "feature_partial_line", "Error constructing partial line for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -146,10 +146,27 @@ public Feature polygon(String layer) {
return geometry(layer, source.polygon());
} catch (GeometryException e) {
e.log(stats, "feature_polygon", "Error constructing polygon for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

/**
* Starts building a new polygon, line, or point map feature based on the geometry type of the input feature.
*
* @param layer the output vector tile layer this feature will be written to
* @return a feature that can be configured further.
*/
public Feature anyGeometry(String layer) {
return source.canBePolygon() ? polygon(layer) :
source.canBeLine() ? line(layer) :
source.isPoint() ? point(layer) :
empty(layer);
}

private Feature empty(String layer) {
return new Feature(layer, EMPTY_GEOM, source.id());
}

/**
* Starts building a new point map feature with geometry from {@link Geometry#getCentroid()} of the source feature.
*
Expand All @@ -161,7 +178,7 @@ public Feature centroid(String layer) {
return geometry(layer, source.centroid());
} catch (GeometryException e) {
e.log(stats, "feature_centroid", "Error getting centroid for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -178,7 +195,7 @@ public Feature centroidIfConvex(String layer) {
return geometry(layer, source.centroidIfConvex());
} catch (GeometryException e) {
e.log(stats, "feature_centroid_if_convex", "Error constructing centroid if convex for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -194,7 +211,7 @@ public Feature pointOnSurface(String layer) {
return geometry(layer, source.pointOnSurface());
} catch (GeometryException e) {
e.log(stats, "feature_point_on_surface", "Error constructing point on surface for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand All @@ -216,7 +233,7 @@ public Feature innermostPoint(String layer, double tolerance) {
return geometry(layer, source.innermostPoint(tolerance));
} catch (GeometryException e) {
e.log(stats, "feature_innermost_point", "Error constructing innermost point for " + source);
return new Feature(layer, EMPTY_GEOM, source.id());
return empty(layer);
}
}

Expand Down Expand Up @@ -297,6 +314,23 @@ default T inheritAttrFromSource(String key) {
return setAttr(key, collector().source.getTag(key));
}

/** Copies the values for {@code keys} attributes from source feature to the output feature. */
default T inheritAttrsFromSource(String... keys) {
for (var key : keys) {
inheritAttrFromSource(key);
}
return self();
}


/** Copies the values for {@code keys} attributes from source feature to the output feature. */
default T inheritAttrsFromSourceWithMinzoom(int minzoom, String... keys) {
for (var key : keys) {
setAttrWithMinzoom(key, collector().source.getTag(key), minzoom);
}
return self();
}

/**
* Sets an attribute on the output feature to either a string, number, boolean, or instance of {@link ZoomFunction}
* to change the value for {@code key} by zoom-level.
Expand All @@ -319,7 +353,7 @@ default T setAttrWithMinzoom(String key, Object value, int minzoom) {
* size.
*/
default T setAttrWithMinSize(String key, Object value, double minPixelSize) {
return setAttrWithMinzoom(key, value, collector().getMinZoomForPixelSize(minPixelSize));
return setAttrWithMinzoom(key, value, getMinZoomForPixelSize(minPixelSize));
}

/**
Expand All @@ -334,7 +368,11 @@ default T setAttrWithMinSize(String key, Object value, double minPixelSize) {
default T setAttrWithMinSize(String key, Object value, double minPixelSize, int minZoomIfBigEnough,
int minZoomToShowAlways) {
return setAttrWithMinzoom(key, value,
Math.clamp(collector().getMinZoomForPixelSize(minPixelSize), minZoomIfBigEnough, minZoomToShowAlways));
Math.clamp(getMinZoomForPixelSize(minPixelSize), minZoomIfBigEnough, minZoomToShowAlways));
}

default int getMinZoomForPixelSize(double minPixelSize) {
return collector().getMinZoomForPixelSize(minPixelSize);
}

/**
Expand Down Expand Up @@ -410,7 +448,7 @@ public final class Feature implements WithZoomRange<Feature>, WithAttrs<Feature>
private ZoomFunction<Number> labelGridPixelSize = null;
private ZoomFunction<Number> labelGridLimit = null;

private boolean attrsChangeByZoom = false;
private boolean mustUnwrapValues = false;
private CacheByZoom<Map<String, Object>> attrCache = null;
private CacheByZoom<List<RangeWithTags>> partialRangeCache = null;

Expand Down Expand Up @@ -817,18 +855,21 @@ private Map<String, Object> computeAttrsAtZoom(int zoom) {
}

private static Object unwrap(Object object, int zoom) {
if (object instanceof ZoomFunction<?> fn) {
object = fn.apply(zoom);
}
if (object instanceof Struct struct) {
object = struct.rawValue();
for (int i = 0; i < 100; i++) {
switch (object) {
case ZoomFunction<?> fn -> object = fn.apply(zoom);
case Struct struct -> object = struct.rawValue();
case null, default -> {
return object;
}
}
}
return object;
throw new IllegalStateException("Failed to unwrap at z" + zoom + ": " + object);
}

/** Returns the attribute to put on all output vector tile features at a zoom level. */
public Map<String, Object> getAttrsAtZoom(int zoom) {
if (!attrsChangeByZoom) {
if (!mustUnwrapValues) {
return attrs;
}
if (attrCache == null) {
Expand All @@ -840,8 +881,8 @@ public Map<String, Object> getAttrsAtZoom(int zoom) {

@Override
public Feature setAttr(String key, Object value) {
if (value instanceof ZoomFunction) {
attrsChangeByZoom = true;
if (value instanceof ZoomFunction || value instanceof Struct) {
mustUnwrapValues = true;
}
if (value != null) {
attrs.put(key, value);
Expand All @@ -852,8 +893,8 @@ public Feature setAttr(String key, Object value) {
@Override
public Feature putAttrs(Map<String, Object> attrs) {
for (Object value : attrs.values()) {
if (value instanceof ZoomFunction) {
attrsChangeByZoom = true;
if (value instanceof ZoomFunction || value instanceof Struct) {
mustUnwrapValues = true;
break;
}
}
Expand Down Expand Up @@ -957,7 +998,7 @@ Partial withAttr(String key, Object value) {
return new Partial(omit, MapUtil.with(attrs, key, value));
}
}
MergingRangeMap<Partial> result = MergingRangeMap.unit(new Partial(false, attrs), Partial::merge);
MergingRangeMap<Partial> result = MergingRangeMap.unit(new Partial(false, getAttrsAtZoom(zoom)), Partial::merge);
for (var override : partialOverrides) {
result.update(override.range(), m -> switch (override) {
case Attr attr -> m.withAttr(attr.key, unwrap(attr.value, zoom));
Expand Down Expand Up @@ -1018,6 +1059,9 @@ public LinearRange setMaxZoom(int max) {

@Override
public LinearRange setAttr(String key, Object value) {
if (value instanceof ZoomFunction<?> || value instanceof Struct) {
mustUnwrapValues = true;
}
return add(new Attr(range, key, value));
}

Expand Down Expand Up @@ -1049,6 +1093,12 @@ public LinearRange linearRange(Range<Double> range) {
return entireLine().linearRange(range);
}


@Override
public int getMinZoomForPixelSize(double minPixelSize) {
return WithAttrs.super.getMinZoomForPixelSize(minPixelSize / (range.upperEndpoint() - range.lowerEndpoint()));
}

@Override
public FeatureCollector collector() {
return FeatureCollector.this;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.onthegomap.planetiler;

import com.onthegomap.planetiler.reader.SourceFeature;

/**
* Subcomponent of {@link Profile} that handles processing layers from a feature, and optionally when that source is
* finished.
*/
@FunctionalInterface
public interface FeatureProcessor<T extends SourceFeature> {

/**
* Generates output features for any input feature that should appear in the map.
* <p>
* Multiple threads may invoke this method concurrently for a single data source so implementations should ensure
* thread-safe access to any shared data structures. Separate data sources are processed sequentially.
* <p>
* All OSM nodes are processed first, then ways, then relations.
*
* @param sourceFeature the input feature from a source dataset (OSM element, shapefile element, etc.)
* @param features a collector for generating output map features to emit
*/
void processFeature(T sourceFeature, FeatureCollector features);
}
Loading
Loading