Skip to content

Commit

Permalink
Improve OHM support (#70)
Browse files Browse the repository at this point in the history
* Dataset selection (OSM / OHM)

* Add node/relation/way timestamp meta information

* Make the constant APPROX_CONTAINS_SLACK a configurable value.

* Format FactHandler.cpp

* Implement parsing of "Exact dates" as described at https://wiki.openstreetmap.org/wiki/Key:start_date#Exact_dates

* Remove obsolete IRI__OSM2RDF_CONTAINS and IRI__OSM2RDF_INTERSECTS

---------

Co-authored-by: Patrick Brosi <[email protected]>
  • Loading branch information
lehmann-4178656ch and patrickbr authored Jan 29, 2024
1 parent 69f8dad commit 86d18e5
Show file tree
Hide file tree
Showing 18 changed files with 1,136 additions and 182 deletions.
8 changes: 8 additions & 0 deletions include/osm2rdf/config/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ enum GeoTriplesMode {
full = 2
};

enum SourceDataset {
OSM = 0,
OHM = 1
};

struct Config {
// Select what to do
std::string storeLocationsOnDisk;
Expand All @@ -53,13 +58,16 @@ struct Config {
bool noWayGeometricRelations = false;
double simplifyGeometries = 0;

SourceDataset sourceDataset = OSM;

// the epsilon for the inner/outer douglas-peucker is based on the
// circumference of a hypothetical circle. By dividing by ~pi, we base the
// epsilon on 1/n of the radius of this hypothetical circle (n = 20 in this
// case). Think of this is maximum portion of the radius that is
// "collapsed away" by the inner simplification, or added by the outer
// simplification
double simplifyGeometriesInnerOuter = 1 / (3.14 * 20);
double approxContainsSlack = 0.05;
bool dontUseInnerOuterGeoms = false;
bool approximateSpatialRels = false;

Expand Down
20 changes: 18 additions & 2 deletions include/osm2rdf/config/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ const static inline std::string NO_FACTS_OPTION_SHORT = "";
const static inline std::string NO_FACTS_OPTION_LONG = "no-facts";
const static inline std::string NO_FACTS_OPTION_HELP = "Do not dump facts";

const static inline std::string SOURCE_DATASET_INFO =
"Source dataset";
const static inline std::string SOURCE_DATASET_OPTION_SHORT = "";
const static inline std::string SOURCE_DATASET_OPTION_LONG =
"source-dataset";
const static inline std::string SOURCE_DATASET_OPTION_HELP =
"Source dataset, either 'OSM', or 'OHM'";

const static inline std::string OSM2RDF_GEO_TRIPLES_INFO =
"Writing mode of osm2rdf-style geometric triples";
const static inline std::string OSM2RDF_GEO_TRIPLES_OPTION_SHORT = "";
Expand Down Expand Up @@ -262,8 +270,16 @@ const static inline std::string APPROX_SPATIAL_REL_OPTION_SHORT =
const static inline std::string APPROX_SPATIAL_REL_OPTION_LONG =
"approximate-spatial-relations";
const static inline std::string APPROX_SPATIAL_REL_OPTION_HELP = "Use "
"simplified inner/outer geometries for approximate calcuation of spatial "
"relations";
"simplified inner/outer geometries for approximate calculation of spatial "
"relations";

const static inline std::string APPROX_CONTAINS_SLACK_INFO =
"Slack for approximate contains";
const static inline std::string APPROX_CONTAINS_SLACK_OPTION_SHORT =
"";
const static inline std::string APPROX_CONTAINS_SLACK_OPTION_LONG =
"approximate-contains-slack";
const static inline std::string APPROX_CONTAINS_SLACK_OPTION_HELP = "";

const static inline std::string SIMPLIFY_WKT_INFO = "Simplifying WKT";
const static inline std::string SIMPLIFY_WKT_OPTION_SHORT = "s";
Expand Down
27 changes: 26 additions & 1 deletion include/osm2rdf/osm/FactHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@

namespace osm2rdf::osm {

enum DateTimeType {
invalid = 0,
date_yyyy = 1,
date_yyyy_mm = 2,
date_yyyy_mm_dd = 3,
date_time = 4
};

template <typename W>
class FactHandler {
public:
Expand All @@ -48,7 +56,6 @@ class FactHandler {
FRIEND_TEST(OSM_FactHandler, writeBoostGeometryWaySimplify3);

protected:

void writeBox(const std::string& s, const std::string& p,
const osm2rdf::geometry::Box& box);
FRIEND_TEST(OSM_FactHandler, writeBoxPrecision1);
Expand Down Expand Up @@ -77,6 +84,24 @@ class FactHandler {
FRIEND_TEST(OSM_FactHandler, writeTagListWikipediaWithLang);
FRIEND_TEST(OSM_FactHandler, writeTagListWikipediaWithoutLang);
FRIEND_TEST(OSM_FactHandler, writeTagListSkipWikiLinks);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateInvalid);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateInvalid2);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateInvalid3);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYear1);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYear2);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYear3);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYear4);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonth1);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonth2);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonth3);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonth4);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonthDay1);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonthDay2);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonthDay3);
FRIEND_TEST(OSM_FactHandler, writeTagListStartDateYearMonthDay4);

void writeSecondsAsISO(const std::string& s, const std::string& p,
const std::time_t& t);

bool hasSuffix(const std::string& s, const std::string& suffix) const;

Expand Down
2 changes: 0 additions & 2 deletions include/osm2rdf/osm/GeometryHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,6 @@ const static int NUM_GRID_CELLS = 5000;
const static double GRID_W = 360.0 / NUM_GRID_CELLS;
const static double GRID_H = 180.0 / NUM_GRID_CELLS;

const double APPROX_CONTAINS_SLACK = 0.05;

struct GeomRelationStats {
size_t _totalChecks = 0;
size_t _fullChecks = 0;
Expand Down
4 changes: 4 additions & 0 deletions include/osm2rdf/osm/Node.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef OSM2RDF_OSM_NODE_H_
#define OSM2RDF_OSM_NODE_H_

#include "Generic.h"
#include "boost/serialization/nvp.hpp"
#include "osm2rdf/geometry/Box.h"
#include "osm2rdf/geometry/Location.h"
Expand All @@ -36,6 +37,7 @@ class Node {
explicit Node(const osmium::Node& node);
explicit Node(const osmium::NodeRef& nodeRef);
[[nodiscard]] id_t id() const noexcept;
[[nodiscard]] std::time_t timestamp() const noexcept;
[[nodiscard]] osm2rdf::geometry::Box envelope() const noexcept;
[[nodiscard]] const osm2rdf::geometry::Location& geom() const noexcept;
[[nodiscard]] const osm2rdf::osm::TagList& tags() const noexcept;
Expand All @@ -47,13 +49,15 @@ class Node {

protected:
id_t _id;
std::time_t _timestamp;
osm2rdf::geometry::Location _geom;
osm2rdf::osm::TagList _tags;

friend class boost::serialization::access;
template <class Archive>
void serialize(Archive& ar, [[maybe_unused]] const unsigned int version) {
ar& boost::serialization::make_nvp("_id", _id);
ar& boost::serialization::make_nvp("_timestamp", _timestamp);
ar& boost::serialization::make_nvp("_geom", _geom);
ar& boost::serialization::make_nvp("_tags", _tags);
}
Expand Down
3 changes: 3 additions & 0 deletions include/osm2rdf/osm/Relation.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Relation {
Relation();
explicit Relation(const osmium::Relation& relation);
[[nodiscard]] id_t id() const noexcept;
[[nodiscard]] std::time_t timestamp() const noexcept;
[[nodiscard]] const std::vector<osm2rdf::osm::RelationMember>& members()
const noexcept;
[[nodiscard]] const osm2rdf::osm::TagList& tags() const noexcept;
Expand All @@ -60,6 +61,7 @@ class Relation {

protected:
id_t _id;
std::time_t _timestamp;
std::vector<osm2rdf::osm::RelationMember> _members;
osm2rdf::osm::TagList _tags;
#if BOOST_VERSION >= 107800
Expand All @@ -74,6 +76,7 @@ class Relation {
template <class Archive>
void serialize(Archive& ar, [[maybe_unused]] const unsigned int version) {
ar& boost::serialization::make_nvp("_id", _id);
ar& boost::serialization::make_nvp("_timestamp", _timestamp);
ar& boost::serialization::make_nvp("_members", _members);
ar& boost::serialization::make_nvp("_tags", _tags);
#if BOOST_VERSION >= 107800
Expand Down
3 changes: 3 additions & 0 deletions include/osm2rdf/osm/Way.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Way {
Way();
explicit Way(const osmium::Way& way);
[[nodiscard]] id_t id() const noexcept;
[[nodiscard]] std::time_t timestamp() const noexcept;
[[nodiscard]] bool closed() const noexcept;
[[nodiscard]] bool isArea() const noexcept;
[[nodiscard]] const osm2rdf::geometry::Box& envelope() const noexcept;
Expand All @@ -60,6 +61,7 @@ class Way {

protected:
id_t _id;
std::time_t _timestamp;
std::vector<osm2rdf::osm::Node> _nodes;
osm2rdf::geometry::Way _geom;
osm2rdf::geometry::Box _envelope;
Expand All @@ -71,6 +73,7 @@ class Way {
template <class Archive>
void serialize(Archive& ar, [[maybe_unused]] const unsigned int version) {
ar& boost::serialization::make_nvp("_id", _id);
ar& boost::serialization::make_nvp("_timestamp", _timestamp);
ar& boost::serialization::make_nvp("_nodes", _nodes);
ar& boost::serialization::make_nvp("_geom", _geom);
ar& boost::serialization::make_nvp("_envelope", _envelope);
Expand Down
20 changes: 17 additions & 3 deletions include/osm2rdf/ttl/Constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,16 @@ namespace osm2rdf::ttl::constants {

// Real constants
const static inline std::string NAMESPACE__GEOSPARQL = "geo";
const static inline std::string NAMESPACE__OHM_NODE = "ohmnode";
const static inline std::string NAMESPACE__OHM_RELATION = "ohmrel";
const static inline std::string NAMESPACE__OHM_WAY = "ohmway";
const static inline std::string NAMESPACE__OHM = "ohm";
const static inline std::string NAMESPACE__OPENGIS = "ogc";
const static inline std::string NAMESPACE__OSM_NODE = "osmnode";
const static inline std::string NAMESPACE__OSM_RELATION = "osmrel";
const static inline std::string NAMESPACE__OSM_TAG = "osmkey";
const static inline std::string NAMESPACE__OSM_WAY = "osmway";
const static inline std::string NAMESPACE__OSM_META = "osmmeta";
const static inline std::string NAMESPACE__OSM = "osm";
const static inline std::string NAMESPACE__OSM2RDF = "osm2rdf";
const static inline std::string NAMESPACE__OSM2RDF_GEOM = "osm2rdfgeom";
Expand All @@ -50,13 +55,11 @@ inline std::string IRI__OPENGIS_INTERSECTS;
inline std::string IRI__OSM2RDF_INTERSECTS_NON_AREA;
inline std::string IRI__OSM2RDF_INTERSECTS_AREA;

inline std::string IRI__OSM2RDF_CONTAINS;
inline std::string IRI__OSM2RDF_INTERSECTS;

inline std::string IRI__OSM2RDF_GEOM__CONVEX_HULL;
inline std::string IRI__OSM2RDF_GEOM__ENVELOPE;
inline std::string IRI__OSM2RDF_GEOM__OBB;
inline std::string IRI__OSM2RDF__POS;
inline std::string IRI__OSMMETA_TIMESTAMP;
inline std::string IRI__OSMWAY_IS_CLOSED;
inline std::string IRI__OSMWAY_NEXT_NODE;
inline std::string IRI__OSMWAY_NEXT_NODE_DISTANCE;
Expand All @@ -70,14 +73,25 @@ inline std::string IRI__OSM_WAY;

inline std::string IRI__RDF_TYPE;

inline std::string IRI__XSD_DATE;
inline std::string IRI__XSD_DATE_TIME;
inline std::string IRI__XSD_DECIMAL;
inline std::string IRI__XSD_DOUBLE;
inline std::string IRI__XSD_FLOAT;
inline std::string IRI__XSD_INTEGER;
inline std::string IRI__XSD_YEAR;
inline std::string IRI__XSD_YEAR_MONTH;

inline std::string LITERAL__NO;
inline std::string LITERAL__YES;

// Arrays holding values depending on the used dataset
inline std::string DATASET_ID[2] = {"osm", "ohm"};
inline std::string DATASET_NAMESPACE[2] = {NAMESPACE__OSM, NAMESPACE__OHM};
inline std::string NODE_NAMESPACE[2] = {NAMESPACE__OSM_NODE, NAMESPACE__OHM_NODE};
inline std::string RELATION_NAMESPACE[2] = {NAMESPACE__OSM_RELATION, NAMESPACE__OHM_RELATION};
inline std::string WAY_NAMESPACE[2] = {NAMESPACE__OSM_WAY, NAMESPACE__OHM_WAY};

} // namespace osm2rdf::ttl::constants

#endif // OSM2RDF_TTL_CONSTANTS_H
48 changes: 44 additions & 4 deletions src/config/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@
// ____________________________________________________________________________
std::string osm2rdf::config::Config::getInfo(std::string_view prefix) const {
std::ostringstream oss;
std::string datasetStrings[2] = {"OSM", "OHM"};
oss << prefix << osm2rdf::config::constants::HEADER;
oss << "\n" << prefix << osm2rdf::config::constants::SECTION_IO;
oss << "\n"
<< prefix << osm2rdf::config::constants::INPUT_INFO << " "
<< prefix << osm2rdf::config::constants::INPUT_INFO << " "
<< input;
oss << "\n"
<< prefix << osm2rdf::config::constants::OUTPUT_INFO << " "
<< prefix << osm2rdf::config::constants::SOURCE_DATASET_INFO << ": "
<< (datasetStrings[sourceDataset]);
oss << "\n"
<< prefix << osm2rdf::config::constants::OUTPUT_INFO << " "
<< output;
oss << "\n"
<< prefix << osm2rdf::config::constants::OUTPUT_FORMAT_INFO << " "
<< prefix << osm2rdf::config::constants::OUTPUT_FORMAT_INFO << " "
<< outputFormat;
oss << "\n"
<< prefix << osm2rdf::config::constants::CACHE_INFO << " "
<< prefix << osm2rdf::config::constants::CACHE_INFO << " "
<< cache;
oss << "\n" << prefix << osm2rdf::config::constants::SECTION_FACTS;
if (noFacts) {
Expand Down Expand Up @@ -122,6 +126,10 @@ std::string osm2rdf::config::Config::getInfo(std::string_view prefix) const {
<< prefix << osm2rdf::config::constants::OGC_GEO_TRIPLES_INFO << ": "
<< (modeStrings[ogcGeoTriplesMode]);

oss << "\n"
<< prefix << osm2rdf::config::constants::APPROX_CONTAINS_SLACK_INFO
<< ": " << approxContainsSlack;

if (ogcGeoTriplesMode || osm2rdfGeoTriplesMode) {
if (noAreaGeometricRelations) {
oss << "\n"
Expand Down Expand Up @@ -226,6 +234,12 @@ void osm2rdf::config::Config::fromArgs(int argc, char** argv) {
osm2rdf::config::constants::NO_WAY_FACTS_OPTION_LONG,
osm2rdf::config::constants::NO_WAY_FACTS_OPTION_HELP);

auto sourceDatasetOp =
parser.add<popl::Value<std::string>, popl::Attribute::advanced>(
osm2rdf::config::constants::SOURCE_DATASET_OPTION_SHORT,
osm2rdf::config::constants::SOURCE_DATASET_OPTION_LONG,
osm2rdf::config::constants::SOURCE_DATASET_OPTION_HELP, "OSM");

auto noAreaGeometricRelationsOp =
parser.add<popl::Switch, popl::Attribute::expert>(
osm2rdf::config::constants::NO_AREA_GEOM_RELATIONS_OPTION_SHORT,
Expand Down Expand Up @@ -366,6 +380,13 @@ void osm2rdf::config::Config::fromArgs(int argc, char** argv) {
osm2rdf::config::constants::CACHE_OPTION_LONG,
osm2rdf::config::constants::CACHE_OPTION_HELP, cache);

auto approxContainsSlackOp =
parser.add<popl::Value<double>, popl::Attribute::expert>(
osm2rdf::config::constants::APPROX_CONTAINS_SLACK_OPTION_SHORT,
osm2rdf::config::constants::APPROX_CONTAINS_SLACK_OPTION_LONG,
osm2rdf::config::constants::APPROX_CONTAINS_SLACK_OPTION_HELP,
approxContainsSlack);

try {
parser.parse(argc, argv);

Expand Down Expand Up @@ -449,6 +470,25 @@ void osm2rdf::config::Config::fromArgs(int argc, char** argv) {
noWayFacts |= noWaysOp->is_set();
noWayGeometricRelations |= noWaysOp->is_set();

// Dataset selection
if (sourceDatasetOp->is_set()) {
if (sourceDatasetOp->value() == "OSM") {
sourceDataset = OSM;
approxContainsSlack = 0.05;
} else if (sourceDatasetOp->value() == "OHM") {
sourceDataset = OHM;
approxContainsSlack = 0;
} else {
throw popl::invalid_option(
sourceDatasetOp.get(),
popl::invalid_option::Error::invalid_argument,
popl::OptionName::long_name, sourceDatasetOp->value(), "");
}
}
if (approxContainsSlackOp->is_set()) {
approxContainsSlack = approxContainsSlackOp->value();
}

// Select amount to dump
addAreaWayLinestrings = addAreaWayLinestringsOp->is_set();
addWayMetadata = addWayMetadataOp->is_set();
Expand Down
Loading

0 comments on commit 86d18e5

Please sign in to comment.