kopia lustrzana https://github.com/onthegomap/planetiler
Gracefully handle exceptions from profile (#65)
rodzic
8d90470d55
commit
e092586dfc
|
|
@ -14,6 +14,8 @@ import java.io.Closeable;
|
|||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.function.Consumer;
|
||||
import org.locationtech.jts.geom.Envelope;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Base class for utilities that read {@link SourceFeature SourceFeatures} from a simple data source where geometries
|
||||
|
|
@ -25,6 +27,8 @@ import org.locationtech.jts.geom.Envelope;
|
|||
*/
|
||||
public abstract class SimpleReader implements Closeable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(SimpleReader.class);
|
||||
|
||||
protected final Stats stats;
|
||||
protected final String sourceName;
|
||||
private final Profile profile;
|
||||
|
|
@ -60,9 +64,13 @@ public abstract class SimpleReader implements Closeable {
|
|||
featuresRead.incrementAndGet();
|
||||
FeatureCollector features = featureCollectors.get(sourceFeature);
|
||||
if (sourceFeature.latLonGeometry().getEnvelopeInternal().intersects(latLonBounds)) {
|
||||
profile.processFeature(sourceFeature, features);
|
||||
for (FeatureCollector.Feature renderable : features) {
|
||||
renderer.accept(renderable);
|
||||
try {
|
||||
profile.processFeature(sourceFeature, features);
|
||||
for (FeatureCollector.Feature renderable : features) {
|
||||
renderer.accept(renderable);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error processing " + sourceFeature, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -160,29 +160,41 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
|
|||
}
|
||||
if (readerElement instanceof ReaderNode node) {
|
||||
PASS1_NODES.inc();
|
||||
profile.preprocessOsmNode(OsmElement.fromGraphopper(node));
|
||||
try {
|
||||
profile.preprocessOsmNode(OsmElement.fromGraphopper(node));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error preprocessing OSM node " + node.getId(), e);
|
||||
}
|
||||
// TODO allow limiting node storage to only ones that profile cares about
|
||||
nodeLocationDb.put(node.getId(), GeoUtils.encodeFlatLocation(node.getLon(), node.getLat()));
|
||||
} else if (readerElement instanceof ReaderWay way) {
|
||||
PASS1_WAYS.inc();
|
||||
profile.preprocessOsmWay(OsmElement.fromGraphopper(way));
|
||||
try {
|
||||
profile.preprocessOsmWay(OsmElement.fromGraphopper(way));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error preprocessing OSM way " + way.getId(), e);
|
||||
}
|
||||
} else if (readerElement instanceof ReaderRelation rel) {
|
||||
PASS1_RELATIONS.inc();
|
||||
// don't leak graphhopper classes out through public API
|
||||
OsmElement.Relation osmRelation = OsmElement.fromGraphopper(rel);
|
||||
List<OsmRelationInfo> infos = profile.preprocessOsmRelation(osmRelation);
|
||||
if (infos != null) {
|
||||
for (OsmRelationInfo info : infos) {
|
||||
relationInfo.put(rel.getId(), info);
|
||||
relationInfoSizes.addAndGet(info.estimateMemoryUsageBytes());
|
||||
for (ReaderRelation.Member member : rel.getMembers()) {
|
||||
int type = member.getType();
|
||||
// TODO handle nodes in relations and super-relations
|
||||
if (type == ReaderRelation.Member.WAY) {
|
||||
wayToRelations.put(member.getRef(), encodeRelationMembership(member.getRole(), rel.getId()));
|
||||
try {
|
||||
List<OsmRelationInfo> infos = profile.preprocessOsmRelation(osmRelation);
|
||||
if (infos != null) {
|
||||
for (OsmRelationInfo info : infos) {
|
||||
relationInfo.put(rel.getId(), info);
|
||||
relationInfoSizes.addAndGet(info.estimateMemoryUsageBytes());
|
||||
for (ReaderRelation.Member member : rel.getMembers()) {
|
||||
int type = member.getType();
|
||||
// TODO handle nodes in relations and super-relations
|
||||
if (type == ReaderRelation.Member.WAY) {
|
||||
wayToRelations.put(member.getRef(), encodeRelationMembership(member.getRole(), rel.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error preprocessing OSM relation " + rel.getId(), e);
|
||||
}
|
||||
// TODO allow limiting multipolygon storage to only ones that profile cares about
|
||||
if (isMultipolygon(rel)) {
|
||||
|
|
@ -263,9 +275,19 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
|
|||
// write them intermediate storage
|
||||
if (feature != null) {
|
||||
FeatureCollector features = featureCollectors.get(feature);
|
||||
profile.processFeature(feature, features);
|
||||
for (FeatureCollector.Feature renderable : features) {
|
||||
renderer.accept(renderable);
|
||||
try {
|
||||
profile.processFeature(feature, features);
|
||||
for (FeatureCollector.Feature renderable : features) {
|
||||
renderer.accept(renderable);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String type = switch (readerElement.getType()) {
|
||||
case ReaderElement.NODE -> "node";
|
||||
case ReaderElement.WAY -> "way";
|
||||
case ReaderElement.RELATION -> "relation";
|
||||
default -> "element";
|
||||
};
|
||||
LOGGER.error("Error processing OSM " + type + " " + readerElement.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -292,9 +314,13 @@ public class OsmReader implements Closeable, MemoryEstimator.HasEstimate {
|
|||
|
||||
pipeline.awaitAndLog(logger, config.logInterval());
|
||||
|
||||
profile.finish(name,
|
||||
new FeatureCollector.Factory(config, stats),
|
||||
createFeatureRenderer(writer, config, writer));
|
||||
try {
|
||||
profile.finish(name,
|
||||
new FeatureCollector.Factory(config, stats),
|
||||
createFeatureRenderer(writer, config, writer));
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error calling profile.finish", e);
|
||||
}
|
||||
timer.stop();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1607,4 +1607,19 @@ public class PlanetilerTests {
|
|||
assertEquals(2146, features, "num buildings");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHandleProfileException() throws Exception {
|
||||
var results = runWithOsmElements(
|
||||
Map.of("threads", "1"),
|
||||
List.of(
|
||||
with(new ReaderNode(1, 0, 0), t -> t.setTag("attr", "value"))
|
||||
),
|
||||
(in, features) -> {
|
||||
throw new IllegalStateException("intentional exception!");
|
||||
}
|
||||
);
|
||||
|
||||
assertSubmap(Map.of(), results.tiles);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue