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

correct intersections for named area (explicitly check them against t… #41

Merged
merged 3 commits into from
Jan 11, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
8 changes: 5 additions & 3 deletions include/osm2rdf/osm/GeometryHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ typedef std::vector<osm2rdf::osm::Relation::id_t> RelationRelationList;
// Relation: envelope, osm id, geometry, node list, way list, relation list
#if BOOST_VERSION >= 107800
typedef std::tuple<osm2rdf::geometry::Box, osm2rdf::osm::Way::id_t,
osm2rdf::geometry::Relation, RelationNodeList, RelationWayList,
RelationRelationList>
osm2rdf::geometry::Relation, RelationNodeList,
RelationWayList, RelationRelationList>
SpatialRelationValue;
#endif // BOOST_VERSION >= 107800

Expand Down Expand Up @@ -344,7 +344,9 @@ class GeometryHandler {

std::string areaNS(AreaFromType type) const;

void writeTransitiveClosure(const std::vector<osm2rdf::osm::Area::id_t>& successors, const std::string& entryIRI, const std::string& rel);
void writeTransitiveClosure(
const std::vector<osm2rdf::osm::Area::id_t>& successors,
const std::string& entryIRI, const std::string& rel, bool symmetric);

void getBoxIds(
const osm2rdf::geometry::Area& area, const osm2rdf::geometry::Area& inner,
Expand Down
132 changes: 110 additions & 22 deletions src/osm/GeometryHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,31 +707,40 @@ void GeometryHandler<W>::dumpNamedAreaRelations() {
std::cerr << std::endl;
std::cerr << currentTimeFormatted() << " Dumping relations from DAG with "
<< _directedAreaGraph.getNumEdges() << " edges and "
<< _directedAreaGraph.getNumVertices() << " vertices ... "
<< _directedAreaGraph.getNumVertices()
<< " vertices and calculation intersect relationships... "
<< std::endl;

osm2rdf::util::ProgressBar progressBar{_directedAreaGraph.getNumVertices(),
true};
size_t entryCount = 0;
progressBar.update(entryCount);
GeomRelationStats intersectStats;

std::vector<DirectedGraph<Area::id_t>::entry_t> vertices =
_directedAreaGraph.getVertices();
#pragma omp parallel for shared( \
vertices, osm2rdf::ttl::constants::NAMESPACE__OSM_WAY, \
osm2rdf::ttl::constants::NAMESPACE__OSM_RELATION, \
osm2rdf::ttl::constants::IRI__OSM2RDF_CONTAINS_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_CONTAINS_NON_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_NON_AREA, progressBar, \
entryCount) default(none) schedule(static)
#pragma omp parallel for shared( \
vertices, osm2rdf::ttl::constants::NAMESPACE__OSM_WAY, \
osm2rdf::ttl::constants::NAMESPACE__OSM_RELATION, \
osm2rdf::ttl::constants::IRI__OSM2RDF_CONTAINS_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_CONTAINS_NON_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_AREA, \
osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_NON_AREA, \
progressBar, entryCount) \
reduction(+ : intersectStats) default(none) schedule(static)
for (size_t i = 0; i < vertices.size(); i++) {
const auto id = vertices[i];
const auto& entry = _spatialStorageArea[_spatialStorageAreaIndex[id]];
const auto& entryId = std::get<1>(entry);
const auto& entryObjId = std::get<3>(entry);
const auto& entryFromType = std::get<5>(entry);
std::string entryIRI =
_writer->generateIRI(areaNS(entryFromType), entryObjId);

// all areas we can skip via the DAG
SkipSet skip;

// contains relations, simply dump the DAG
for (const auto& dst : _directedAreaGraph.getEdges(id)) {
assert(_spatialStorageAreaIndex[dst] < _spatialStorageArea.size());
const auto& area = _spatialStorageArea[_spatialStorageAreaIndex[dst]];
Expand All @@ -743,21 +752,86 @@ void GeometryHandler<W>::dumpNamedAreaRelations() {

_writer->writeTriple(areaIRI, IRI__OSM2RDF_CONTAINS_AREA, entryIRI);
_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_AREA, entryIRI);
_writer->writeTriple(entryIRI, IRI__OSM2RDF_INTERSECTS_AREA, areaIRI);

// transitive closure
const auto& successors = _directedAreaGraph.findSuccessorsFast(areaId);

writeTransitiveClosure(successors, entryIRI,
IRI__OSM2RDF_INTERSECTS_AREA);
writeTransitiveClosure(successors, entryIRI, IRI__OSM2RDF_CONTAINS_AREA);
skip.insert(areaId);
skip.insert(successors.begin(), successors.end());

writeTransitiveClosure(successors, entryIRI, IRI__OSM2RDF_INTERSECTS_AREA,
true);
writeTransitiveClosure(successors, entryIRI, IRI__OSM2RDF_CONTAINS_AREA,
false);
}

// intersect relation, use R-Tree
const auto& queryResult = indexQryIntersect(entry);

for (const auto& areaRef : queryResult) {
const auto& area = _spatialStorageArea[areaRef.second];
const auto& areaId = std::get<1>(area);
const auto& areaObjId = std::get<3>(area);
const auto& areaFromType = std::get<5>(area);

intersectStats.checked();

// don't compare to itself
if (areaId == entryId) continue;

GeomRelationInfo geomRelInf;

const auto& areaIRI =
_writer->generateIRI(areaNS(areaFromType), areaObjId);

if (skip.find(areaId) != skip.end()) {
geomRelInf.intersects = YES;
intersectStats.skippedByDAG();
} else if (areaIntersectsArea(entry, area, &geomRelInf,
&intersectStats)) {
const auto& successors = _directedAreaGraph.findSuccessorsFast(areaId);
skip.insert(successors.begin(), successors.end());

// transitive closure
writeTransitiveClosure(successors, entryIRI,
IRI__OSM2RDF_INTERSECTS_AREA, true);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_AREA, entryIRI);
_writer->writeTriple(entryIRI, IRI__OSM2RDF_INTERSECTS_AREA, areaIRI);
}
}

#pragma omp critical(progress)
progressBar.update(entryCount++);
}

progressBar.done();

std::cerr << currentTimeFormatted() << " ... done" << std::endl;
std::cerr << currentTimeFormatted() << " ... done.\n"
<< osm2rdf::util::formattedTimeSpacer << " checked "
<< intersectStats.printTotalChecks()
<< " area/area pairs A, B for intersect\n"
<< osm2rdf::util::formattedTimeSpacer << " decided "
<< intersectStats.printSkippedByDAG() << " by DAG\n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printSkippedByBox()
<< " by non-intersecting bounding boxes \n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printSkippedByBoxIdIntersect()
<< " by box id intersect\n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printSkippedByBoxIdIntersectCutout()
<< " by check against box id cutout\n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printSkippedByInner()
<< " by inner simplified geom\n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printSkippedByOuter()
<< " by outer simplified geom\n"
<< osm2rdf::util::formattedTimeSpacer << " "
<< intersectStats.printFullChecks() << " by full geometric check"
<< std::endl;
}

// ____________________________________________________________________________
Expand Down Expand Up @@ -841,10 +915,12 @@ void GeometryHandler<W>::dumpUnnamedAreaRelations() {

// transitive closure
writeTransitiveClosure(successors, entryIRI,
IRI__OSM2RDF_INTERSECTS_NON_AREA);
IRI__OSM2RDF_INTERSECTS_NON_AREA, true);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
entryIRI);
_writer->writeTriple(entryIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
areaIRI);
}

if (geomRelInf.intersects == NO) {
Expand All @@ -862,7 +938,7 @@ void GeometryHandler<W>::dumpUnnamedAreaRelations() {

// transitive closure
writeTransitiveClosure(successors, entryIRI,
IRI__OSM2RDF_CONTAINS_NON_AREA);
IRI__OSM2RDF_CONTAINS_NON_AREA, false);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_CONTAINS_NON_AREA,
entryIRI);
Expand Down Expand Up @@ -1038,13 +1114,16 @@ GeometryHandler<W>::dumpNodeRelations() {

// transitive closure
writeTransitiveClosure(successors, nodeIRI,
IRI__OSM2RDF_INTERSECTS_NON_AREA);
IRI__OSM2RDF_INTERSECTS_NON_AREA, true);
writeTransitiveClosure(successors, nodeIRI,
IRI__OSM2RDF_CONTAINS_NON_AREA);
IRI__OSM2RDF_CONTAINS_NON_AREA, false);

_writer->writeTriple(
areaIRI, osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_NON_AREA,
nodeIRI);
_writer->writeTriple(
nodeIRI, osm2rdf::ttl::constants::IRI__OSM2RDF_INTERSECTS_NON_AREA,
areaIRI);
_writer->writeTriple(
areaIRI, osm2rdf::ttl::constants::IRI__OSM2RDF_CONTAINS_NON_AREA,
nodeIRI);
Expand Down Expand Up @@ -1200,10 +1279,12 @@ void GeometryHandler<W>::dumpWayRelations(

// transitive closure
writeTransitiveClosure(successors, wayIRI,
IRI__OSM2RDF_INTERSECTS_NON_AREA);
IRI__OSM2RDF_INTERSECTS_NON_AREA, true);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
wayIRI);
_writer->writeTriple(wayIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
areaIRI);
} else if (skipNodeContained.find(areaId) != skipNodeContained.end()) {
intersectStats.skippedByNodeContained();
geomRelInf.intersects = YES;
Expand All @@ -1217,10 +1298,12 @@ void GeometryHandler<W>::dumpWayRelations(

// transitive closure
writeTransitiveClosure(successors, wayIRI,
IRI__OSM2RDF_INTERSECTS_NON_AREA);
IRI__OSM2RDF_INTERSECTS_NON_AREA, true);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
wayIRI);
_writer->writeTriple(wayIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
areaIRI);
} else if (wayIntersectsArea(way, area, &geomRelInf, &intersectStats)) {
const auto& successors =
_directedAreaGraph.findSuccessorsFast(areaId);
Expand All @@ -1231,10 +1314,12 @@ void GeometryHandler<W>::dumpWayRelations(

// transitive closure
writeTransitiveClosure(successors, wayIRI,
IRI__OSM2RDF_INTERSECTS_NON_AREA);
IRI__OSM2RDF_INTERSECTS_NON_AREA, true);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
wayIRI);
_writer->writeTriple(wayIRI, IRI__OSM2RDF_INTERSECTS_NON_AREA,
areaIRI);
}

if (geomRelInf.intersects == NO) {
Expand Down Expand Up @@ -1273,7 +1358,7 @@ void GeometryHandler<W>::dumpWayRelations(

// transitive closure
writeTransitiveClosure(successors, wayIRI,
IRI__OSM2RDF_CONTAINS_NON_AREA);
IRI__OSM2RDF_CONTAINS_NON_AREA, false);

_writer->writeTriple(areaIRI, IRI__OSM2RDF_CONTAINS_NON_AREA, wayIRI);
}
Expand Down Expand Up @@ -2453,7 +2538,7 @@ uint8_t GeometryHandler<W>::borderContained(Way::id_t wayId,
template <typename W>
void GeometryHandler<W>::writeTransitiveClosure(
const std::vector<osm2rdf::osm::Area::id_t>& successors,
const std::string& entryIRI, const std::string& rel) {
const std::string& entryIRI, const std::string& rel, bool symmetric) {
// transitive closure
if (_config.writeGeomRelTransClosure) {
for (const auto& succ : successors) {
Expand All @@ -2464,6 +2549,9 @@ void GeometryHandler<W>::writeTransitiveClosure(
_writer->generateIRI(areaNS(succAreaFromType), succAreaId);

_writer->writeTriple(succAreaIRI, rel, entryIRI);
if (symmetric) {
_writer->writeTriple(entryIRI, rel, succAreaIRI);
}
}
}
}
Expand Down
Loading