Skip to content

Commit

Permalink
Merge branch 'master' into add-build-workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickbr committed Jan 13, 2024
2 parents 0a31966 + 42eb3f4 commit 8d87495
Show file tree
Hide file tree
Showing 16 changed files with 319 additions and 547 deletions.
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
# osm2rdf

`osm2rdf` is a tool for converting the complete [OpenStreetMap](https://www.openstreetmap.org) (OSM) data to [RDF Turtle](https://www.w3.org/TR/turtle) (TTL). The produced triples include:
`osm2rdf` is a tool for converting the complete [OpenStreetMap](https://www.openstreetmap.org) (OSM) data to [RDF Turtle](https://www.w3.org/TR/turtle) (TTL).

1. One triple `<o> <key> <value>` for each key-value pair (called "tag" in OSM) of each object.
2. One triple `<o> geo:hasGeometry <wkt>` for the shape of each object (using [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) to represent the shape).
3. One triple `<o1> geo:sfContains <o2>` for each pair of objects, where `<o1>` geometrically contains `<o2>`.
4. One triple `<o1> geo:sfContains <o2>` for each pair of objects, where `<o1>` geometrically intersects `<o2>`.
5. Triples for various other kinds of information (see `osm2rdf --help` for the many options of the tool).
We consider the following prefixes being used in our code and documentation:

```
PREFIX ogc: <http://www.opengis.net/rdf#>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX osm2rdf: <https://osm2rdf.cs.uni-freiburg.de/rdf#>
```

The produced triples include:

1. One triple `<o> <key> <value> .` for each key-value pair (called "tag" in OSM) of each object.
2. Two triples `<o> geo:hasGeometry <geom_o> . <geom_o> geo:asWKT <wkt> .` for the shape of each object (using [WKT](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) to represent the shape).
> Note: using the option `--hasgeometry-as-wkt` will attach the WKT literal directly to the object, i.e. `<o> geo:hasGeometry <wkt> .`
4. One triple `<o1> ogc:sfContains <o2> .` for each pair of objects, where `<o1>` geometrically contains `<o2>`.
5. One triple `<o1> ogc:sfIntersects <o2> .` for each pair of objects, where `<o1>` geometrically intersects `<o2>`.
6. Triples for various other kinds of information (see `osm2rdf --help` for the many options of the tool).

For the complete OSM data, the tool takes around 15 hours on standard hardware and produces around 40 billion triples with a size of around 200 GB for the compressed TTL file.

Expand Down
1 change: 1 addition & 0 deletions include/osm2rdf/config/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ struct Config {
bool addAreaConvexHull = false;
bool addAreaEnvelope = false;
bool addAreaOrientedBoundingBox = false;
bool addAreaWayLinestrings = false;
bool addNodeConvexHull = false;
bool addNodeEnvelope = false;
bool addNodeOrientedBoundingBox = false;
Expand Down
8 changes: 8 additions & 0 deletions include/osm2rdf/config/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,14 @@ const static inline std::string ADD_AREA_ORIENTED_BOUNDING_BOX_OPTION_LONG =
const static inline std::string ADD_AREA_ORIENTED_BOUNDING_BOX_OPTION_HELP =
"Add oriented-bounding-box to areas";

const static inline std::string ADD_AREA_WAY_LINESTRINGS_INFO =
"Adding linestrings for ways which form areas";
const static inline std::string ADD_AREA_WAY_LINESTRINGS_OPTION_SHORT = "";
const static inline std::string ADD_AREA_WAY_LINESTRINGS_OPTION_LONG =
"add-area-way-linestrings";
const static inline std::string ADD_AREA_WAY_LINESTRINGS_OPTION_HELP =
"Add linestrings for ways which form areas";

const static inline std::string HASGEOMETRY_AS_WKT_INFO =
"Letting geo:hasGeometry point directly to WKT serialization literal";
const static inline std::string HASGEOMETRY_AS_WKT_OPTION_SHORT = "";
Expand Down
11 changes: 2 additions & 9 deletions include/osm2rdf/osm/GeometryHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ struct GeomRelationStats {
size_t _skippedByBoxIdIntersectCutout = 0;
size_t _skippedByContainedInInnerRing = 0;
size_t _skippedByBorderContained = 0;
size_t _skippedByNodeContained = 0;
size_t _skippedByInner = 0;
size_t _skippedByOuter = 0;
size_t _skippedByBox = 0;
Expand All @@ -79,7 +78,6 @@ struct GeomRelationStats {
_skippedByOrientedBox += lh._skippedByOrientedBox;
_skippedByConvexHull += lh._skippedByConvexHull;
_skippedByBorderContained += lh._skippedByBorderContained;
_skippedByNodeContained += lh._skippedByNodeContained;
return *this;
}

Expand All @@ -96,7 +94,6 @@ struct GeomRelationStats {
void skippedByOrientedBox() { _skippedByOrientedBox++; }
void skippedByConvexHull() { _skippedByConvexHull++; }
void skippedByBorderContained() { _skippedByBorderContained++; }
void skippedByNodeContained() { _skippedByNodeContained++; }
void fullCheck() { _fullChecks++; }

[[nodiscard]] std::string printPercNum(size_t n) const {
Expand Down Expand Up @@ -146,9 +143,6 @@ struct GeomRelationStats {
[[nodiscard]] std::string printSkippedByOuter() const {
return printPercNum(_skippedByOuter);
}
[[nodiscard]] std::string printSkippedByNodeContained() const {
return printPercNum(_skippedByNodeContained);
}
[[nodiscard]] std::string printFullChecks() const {
return printPercNum(_fullChecks);
}
Expand Down Expand Up @@ -299,16 +293,15 @@ class GeometryHandler {
FRIEND_TEST(OSM_GeometryHandler, dumpUnnamedAreaRelationsSimpleContainsOnly);

// Calculate relations for each node.
NodesContainedInAreasData dumpNodeRelations();
void dumpNodeRelations();
FRIEND_TEST(OSM_GeometryHandler, noNodeGeometricRelations);
FRIEND_TEST(OSM_GeometryHandler, dumpNodeRelationsEmpty1);
FRIEND_TEST(OSM_GeometryHandler, dumpNodeRelationsEmpty2);
FRIEND_TEST(OSM_GeometryHandler, dumpNodeRelationsSimpleIntersects);
FRIEND_TEST(OSM_GeometryHandler, dumpNodeRelationsSimpleContains);

// Calculate relations for each way.
void dumpWayRelations(
const osm2rdf::osm::NodesContainedInAreasData& nodeData);
void dumpWayRelations();
FRIEND_TEST(OSM_GeometryHandler, noWayGeometricRelations);
FRIEND_TEST(OSM_GeometryHandler, dumpWayRelationsEmpty1);
FRIEND_TEST(OSM_GeometryHandler, dumpWayRelationsEmpty2);
Expand Down
1 change: 1 addition & 0 deletions include/osm2rdf/osm/Relation.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Relation {
const noexcept;
[[nodiscard]] const osm2rdf::osm::TagList& tags() const noexcept;
[[nodiscard]] bool hasCompleteGeometry() const noexcept;
[[nodiscard]] bool isArea() const noexcept;
#if BOOST_VERSION >= 107800
[[nodiscard]] bool hasGeometry() const noexcept;
[[nodiscard]] const osm2rdf::geometry::Box& envelope() const noexcept;
Expand Down
1 change: 1 addition & 0 deletions include/osm2rdf/osm/Way.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class Way {
explicit Way(const osmium::Way& way);
[[nodiscard]] id_t id() const noexcept;
[[nodiscard]] bool closed() const noexcept;
[[nodiscard]] bool isArea() const noexcept;
[[nodiscard]] const osm2rdf::geometry::Box& envelope() const noexcept;
[[nodiscard]] const osm2rdf::geometry::Way& geom() const noexcept;
// Return the convex hull.
Expand Down
14 changes: 13 additions & 1 deletion src/config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@
// You should have received a copy of the GNU General Public License
// along with osm2rdf. If not, see <https://www.gnu.org/licenses/>.

#include "osm2rdf/config/Config.h"

#include <filesystem>
#include <iostream>
#include <string>

#include "boost/version.hpp"
#include "omp.h"
#include "osm2rdf/config/Config.h"
#include "osm2rdf/config/Constants.h"
#include "osm2rdf/config/ExitCode.h"
#include "popl.hpp"
Expand Down Expand Up @@ -150,6 +151,11 @@ std::string osm2rdf::config::Config::getInfo(std::string_view prefix) const {
<< prefix
<< osm2rdf::config::constants::ADD_WAY_NODE_SPATIAL_METADATA_INFO;
}
if (addAreaWayLinestrings) {
oss << "\n"
<< prefix
<< osm2rdf::config::constants::ADD_AREA_WAY_LINESTRINGS_INFO;
}
}
if (simplifyWKT > 0) {
oss << "\n" << prefix << osm2rdf::config::constants::SIMPLIFY_WKT_INFO;
Expand Down Expand Up @@ -335,6 +341,11 @@ void osm2rdf::config::Config::fromArgs(int argc, char** argv) {
osm2rdf::config::constants::ADD_AREA_ENVELOPE_RATIO_OPTION_SHORT,
osm2rdf::config::constants::ADD_AREA_ENVELOPE_RATIO_OPTION_LONG,
osm2rdf::config::constants::ADD_AREA_ENVELOPE_RATIO_OPTION_HELP);
auto addAreaWayLinestringsOp =
parser.add<popl::Switch, popl::Attribute::expert>(
osm2rdf::config::constants::ADD_AREA_WAY_LINESTRINGS_OPTION_SHORT,
osm2rdf::config::constants::ADD_AREA_WAY_LINESTRINGS_OPTION_LONG,
osm2rdf::config::constants::ADD_AREA_WAY_LINESTRINGS_OPTION_HELP);
auto addRelationBorderMembersOp = parser.add<popl::Switch>(
osm2rdf::config::constants::ADD_RELATION_BORDER_MEMBERS_OPTION_SHORT,
osm2rdf::config::constants::ADD_RELATION_BORDER_MEMBERS_OPTION_LONG,
Expand Down Expand Up @@ -571,6 +582,7 @@ void osm2rdf::config::Config::fromArgs(int argc, char** argv) {
addAreaEnvelope = addAreaEnvelopeOp->is_set();
addAreaEnvelopeRatio = addAreaEnvelopeRatioOp->is_set();
addAreaOrientedBoundingBox = addAreaOrientedBoundingBoxOp->is_set();
addAreaWayLinestrings = addAreaWayLinestringsOp->is_set();
addRelationBorderMembers = addRelationBorderMembersOp->is_set();
#if BOOST_VERSION >= 107800
addRelationConvexHull = addRelationConvexHullOp->is_set();
Expand Down
31 changes: 18 additions & 13 deletions src/osm/FactHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
// You should have received a copy of the GNU General Public License
// along with osm2rdf. If not, see <https://www.gnu.org/licenses/>.

#include "osm2rdf/osm/FactHandler.h"

#include <iomanip>
#include <iostream>

Expand All @@ -25,7 +27,6 @@
#include "osm2rdf/config/Config.h"
#include "osm2rdf/osm/Area.h"
#include "osm2rdf/osm/Constants.h"
#include "osm2rdf/osm/FactHandler.h"
#include "osm2rdf/osm/Node.h"
#include "osm2rdf/osm/Relation.h"
#include "osm2rdf/osm/Way.h"
Expand All @@ -36,10 +37,10 @@ using osm2rdf::osm::constants::BASE_SIMPLIFICATION_FACTOR;
using osm2rdf::ttl::constants::IRI__GEOSPARQL__AS_WKT;
using osm2rdf::ttl::constants::IRI__GEOSPARQL__HAS_GEOMETRY;
using osm2rdf::ttl::constants::IRI__GEOSPARQL__WKT_LITERAL;
using osm2rdf::ttl::constants::IRI__OSM2RDF__POS;
using osm2rdf::ttl::constants::IRI__OSM2RDF_GEOM__CONVEX_HULL;
using osm2rdf::ttl::constants::IRI__OSM2RDF_GEOM__ENVELOPE;
using osm2rdf::ttl::constants::IRI__OSM2RDF_GEOM__OBB;
using osm2rdf::ttl::constants::IRI__OSM2RDF__POS;
using osm2rdf::ttl::constants::IRI__OSM_NODE;
using osm2rdf::ttl::constants::IRI__OSM_RELATION;
using osm2rdf::ttl::constants::IRI__OSM_TAG;
Expand Down Expand Up @@ -81,7 +82,7 @@ void osm2rdf::osm::FactHandler<W>::area(const osm2rdf::osm::Area& area) {
if (!_config.hasGeometryAsWkt) {
const std::string& geomObj = _writer->generateIRI(
NAMESPACE__OSM2RDF_GEOM, (area.fromWay() ? "wayarea_" : "relarea_") +
std::to_string(area.objId()));
std::to_string(area.objId()));

_writer->writeTriple(subj, IRI__GEOSPARQL__HAS_GEOMETRY, geomObj);
writeBoostGeometry(geomObj, IRI__GEOSPARQL__AS_WKT, area.geom());
Expand All @@ -96,7 +97,8 @@ void osm2rdf::osm::FactHandler<W>::area(const osm2rdf::osm::Area& area) {
writeBox(subj, IRI__OSM2RDF_GEOM__ENVELOPE, area.envelope());
}
if (_config.addAreaOrientedBoundingBox) {
writeBoostGeometry(subj, IRI__OSM2RDF_GEOM__OBB, area.orientedBoundingBox());
writeBoostGeometry(subj, IRI__OSM2RDF_GEOM__OBB,
area.orientedBoundingBox());
}

if (_config.addSortMetadata) {
Expand Down Expand Up @@ -146,7 +148,8 @@ void osm2rdf::osm::FactHandler<W>::node(const osm2rdf::osm::Node& node) {
writeBox(subj, IRI__OSM2RDF_GEOM__ENVELOPE, node.envelope());
}
if (_config.addNodeOrientedBoundingBox) {
writeBoostGeometry(subj, IRI__OSM2RDF_GEOM__OBB, node.orientedBoundingBox());
writeBoostGeometry(subj, IRI__OSM2RDF_GEOM__OBB,
node.orientedBoundingBox());
}
}

Expand Down Expand Up @@ -200,7 +203,7 @@ void osm2rdf::osm::FactHandler<W>::relation(
}

#if BOOST_VERSION >= 107800
if (relation.hasGeometry()) {
if (relation.hasGeometry() && !relation.isArea()) {
if (!_config.hasGeometryAsWkt) {
const std::string& geomObj = _writer->generateIRI(
NAMESPACE__OSM2RDF_GEOM, "relation_" + std::to_string(relation.id()));
Expand Down Expand Up @@ -305,14 +308,16 @@ void osm2rdf::osm::FactHandler<W>::way(const osm2rdf::osm::Way& way) {
osm2rdf::geometry::Linestring locations{way.geom()};
size_t numUniquePoints = locations.size();

if (!_config.hasGeometryAsWkt) {
const std::string& geomObj = _writer->generateIRI(
NAMESPACE__OSM2RDF, "way_" + std::to_string(way.id()));
if (_config.addAreaWayLinestrings || !way.isArea()) {
if (!_config.hasGeometryAsWkt) {
const std::string& geomObj = _writer->generateIRI(
NAMESPACE__OSM2RDF, "way_" + std::to_string(way.id()));

_writer->writeTriple(subj, IRI__GEOSPARQL__HAS_GEOMETRY, geomObj);
writeBoostGeometry(geomObj, IRI__GEOSPARQL__AS_WKT, locations);
} else {
writeBoostGeometry(subj, IRI__GEOSPARQL__HAS_GEOMETRY, locations);
_writer->writeTriple(subj, IRI__GEOSPARQL__HAS_GEOMETRY, geomObj);
writeBoostGeometry(geomObj, IRI__GEOSPARQL__AS_WKT, locations);
} else {
writeBoostGeometry(subj, IRI__GEOSPARQL__HAS_GEOMETRY, locations);
}
}

if (_config.addWayConvexHull) {
Expand Down
Loading

0 comments on commit 8d87495

Please sign in to comment.