Skip to content

Commit

Permalink
Centroid(...) should return nil on error
Browse files Browse the repository at this point in the history
Previously, calling Centroid(...) on an invalid geometry (such as
https://www.openstreetmap.org/relation/9769005, which I think gets
simplified to having 0 rings) would throw, killing the lua process.

Instead, return nil.
  • Loading branch information
cldellow committed Jan 18, 2024
1 parent c490b5c commit dedbfe7
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
2 changes: 1 addition & 1 deletion include/osm_lua_processing.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ class OsmLuaProcessing {
double Length();

// Return centroid lat/lon
std::vector<double> Centroid(kaguya::VariadicArgType algorithm);
kaguya::optional<std::vector<double>> Centroid(kaguya::VariadicArgType algorithm);

enum class CentroidAlgorithm: char { Centroid = 0, Polylabel = 1 };
CentroidAlgorithm defaultCentroidAlgorithm() const { return CentroidAlgorithm::Polylabel; }
Expand Down
13 changes: 9 additions & 4 deletions src/osm_lua_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ bool rawCoveredBy(const std::string& layerName) { return osmLuaProcessing->Cover
bool rawIsClosed() { return osmLuaProcessing->IsClosed(); }
double rawArea() { return osmLuaProcessing->Area(); }
double rawLength() { return osmLuaProcessing->Length(); }
std::vector<double> rawCentroid(kaguya::VariadicArgType algorithm) { return osmLuaProcessing->Centroid(algorithm); }
kaguya::optional<std::vector<double>> rawCentroid(kaguya::VariadicArgType algorithm) { return osmLuaProcessing->Centroid(algorithm); }
void rawLayer(const std::string& layerName, bool area) { return osmLuaProcessing->Layer(layerName, area); }
void rawLayerAsCentroid(const std::string &layerName, kaguya::VariadicArgType nodeSources) { return osmLuaProcessing->LayerAsCentroid(layerName, nodeSources); }
void rawMinZoom(const double z) { return osmLuaProcessing->MinZoom(z); }
Expand Down Expand Up @@ -788,16 +788,21 @@ OsmLuaProcessing::CentroidAlgorithm OsmLuaProcessing::parseCentroidAlgorithm(con
throw std::runtime_error("unknown centroid algorithm " + algorithm);
}

std::vector<double> OsmLuaProcessing::Centroid(kaguya::VariadicArgType algorithmArgs) {
kaguya::optional<std::vector<double>> OsmLuaProcessing::Centroid(kaguya::VariadicArgType algorithmArgs) {
CentroidAlgorithm algorithm = defaultCentroidAlgorithm();

for (auto needleRef : algorithmArgs) {
const std::string needle = needleRef.get<std::string>();
algorithm = parseCentroidAlgorithm(needle);
break;
}
Point c = calculateCentroid(algorithm);
return std::vector<double> { latp2lat(c.y()/10000000.0), c.x()/10000000.0 };
try {
Point c = calculateCentroid(algorithm);
return std::vector<double> { latp2lat(c.y()/10000000.0), c.x()/10000000.0 };
} catch (geom::centroid_exception &err) {
if (verbose) cerr << "Problem geometry " << (isRelation ? "relation " : isWay ? "way " : "node " ) << originalOsmID << ": " << err.what() << endl;
return kaguya::optional<std::vector<double>>();
}
}

// Accept a relation in relation_scan phase
Expand Down

0 comments on commit dedbfe7

Please sign in to comment.