diff --git a/src/OSM/features/simplifyOSM.h b/src/OSM/features/simplifyOSM.h index 2d5e646..fd6197a 100644 --- a/src/OSM/features/simplifyOSM.h +++ b/src/OSM/features/simplifyOSM.h @@ -7,10 +7,26 @@ #include #include #include +#include #include +#include namespace TSMM::OSM { + static inline std::unordered_set leftWayTags{"motorway", "trunk", "primary", "secondary", "tertiary", "residential"}; + + bool isWayFiltered(std::shared_ptr &way) + { + std::string keyString = "highway"; + const auto waytags = way->tags(); + if (waytags.count(keyString)) + { + if (leftWayTags.count(waytags.at(keyString))) + return false; + return true; + } + return true; + } class SimplifyOSM { @@ -19,9 +35,8 @@ namespace TSMM::OSM public: - explicit SimplifyOSM(Conf &conf) : map_(nullptr), conf_(std::move(conf)) + explicit SimplifyOSM(Conf &conf) : map_(std::make_shared()), conf_(std::move(conf)) { - map_ = std::make_shared(); try { osmium::io::Reader reader(conf_.inPath_, osmium::osm_entity_bits::node | osmium::osm_entity_bits::way | osmium::osm_entity_bits::relation); @@ -41,14 +56,14 @@ namespace TSMM::OSM // specific ways to process osmmap // for example: linkways --> buffer ways --> store the map std::vector processPipeLine; + OSMProcessorBase *wayFilter = new FilterWays(isWayFiltered); OSMProcessorBase *linkWays = new LinkWays(); OSMProcessorBase *bufferWays = new BufferWays(); + processPipeLine.push_back(wayFilter); processPipeLine.push_back(linkWays); processPipeLine.push_back(bufferWays); - for (auto &pipe: processPipeLine) - pipe->process(*map_); - + std::for_each(processPipeLine.begin(), processPipeLine.end(), [&](auto &pipe) { pipe->process(*map_); }); map_->save(conf_.outPath_); } }; diff --git a/src/OSM/map/OSMMap.h b/src/OSM/map/OSMMap.h index e25bd47..deee601 100644 --- a/src/OSM/map/OSMMap.h +++ b/src/OSM/map/OSMMap.h @@ -2,12 +2,15 @@ #define OSMMAP_H #include -#include +#include +#include +#include #include #include #include #include #include + #include namespace TSMM::OSM @@ -16,64 +19,91 @@ namespace TSMM::OSM class OSMMap { - std::unordered_map> nodes_; - std::unordered_map> ways_; - std::unordered_map> relations_; + std::unordered_map> nodes_; + std::unordered_map> ways_; + std::unordered_map> relations_; osmium::memory::Buffer buffer_{10240, osmium::memory::Buffer::auto_grow::yes}; void buildNodes(osmium::memory::Buffer &buffer) { - for (const auto &node: nodes_) - { + std::for_each(nodes_.begin(), nodes_.end(), [&](const auto &node) { { osmium::builder::NodeBuilder builder{buffer}; builder.set_user("tsmm"); osmium::Node &obj = builder.object(); - obj.set_id(node.second->id_); - obj.set_uid(node.second->id_); - obj.set_location(osmium::Location{node.second->lon_, node.second->lat_}); + obj.set_id(node.second->id()); + obj.set_uid(node.second->id()); + obj.set_location(osmium::Location{node.second->lon(), node.second->lat()}); } buffer.commit(); - } + }); } void buildWays(osmium::memory::Buffer &buffer) { - for (const auto &way: ways_) - { + std::for_each(ways_.begin(), ways_.end(), [&](const auto &way) { + if (way.second->isActive()) { - osmium::builder::WayBuilder builder{buffer}; - builder.set_user("tsmm"); - osmium::Way &obj = builder.object(); - - obj.set_id(way.second->id_); - obj.set_uid(way.second->id_); + { + osmium::builder::WayBuilder builder{buffer}; + builder.set_user("tsmm"); + osmium::Way &obj = builder.object(); + + obj.set_id(way.second->id()); + obj.set_uid(way.second->id()); + + { + ///< add node ref + osmium::builder::WayNodeListBuilder wayNodeListBuilder{buffer, &builder}; + std::for_each(way.second->nodeRefs().begin(), way.second->nodeRefs().end(), [&](const auto &nId) { + osmium::Location node(nodes_[nId]->lon(), nodes_[nId]->lat()); + osmium::NodeRef nodeRef{nId, node}; + wayNodeListBuilder.add_node_ref(nodeRef); + }); + } + + { + ///< add way tags + osmium::builder::TagListBuilder tl_builder{buffer, &builder}; + // add road level tag + std::for_each(way.second->tags().begin(), way.second->tags().end(), [&](const auto &tags) { + tl_builder.add_tag(tags.first, tags.second); + }); + } + } + buffer.commit(); } - buffer.commit(); - } + }); } + void buildRelations(osmium::memory::Buffer &buffer) {} public: - void addNode(long long id, double lat, double lon) + void addNode(OSMWay::id_t id, double lat, double lon) { - nodes_[id] = std::make_shared(id, lat, lon); + nodes_[id] = std::make_shared(id, lat, lon); } - void addWay(long long id) + void addWay(OSMWay::id_t id, std::vector &nodeRef, std::unordered_map &tags) { - ways_[id] = std::make_shared(id); + + ways_[id] = std::make_shared(id, nodeRef, tags); } - void addRelation(long long id) + void addRelation(OSMRelation::id_t id) { - relations_[id] = std::make_shared(id); + relations_[id] = std::make_shared(id); } + std::unordered_map> ways() const + { + return ways_; + } + void save(const std::string &path) { std::size_t bufferSize = 10240; diff --git a/src/OSM/map/OSMNode.h b/src/OSM/map/OSMNode.h new file mode 100644 index 0000000..076fd0d --- /dev/null +++ b/src/OSM/map/OSMNode.h @@ -0,0 +1,36 @@ +#ifndef OSMNODE_H +#define OSMNODE_H +#include +#include +namespace TSMM::OSM +{ + + class OSMNode + { + + public: + typedef std::int64_t id_t; + + + OSMNode(id_t id, double lat, double lon) : id_(id), lat_(lat), lon_(lon), isActive_(true) {} + + void addTag(const std::string &key, const std::string &value) + { + tags_[key] = value; + } + + id_t id() const { return id_; } + double lat() const { return lat_; } + double lon() const { return lon_; } + + + private: + id_t id_; + double lat_, lon_; + bool isActive_; + std::unordered_map tags_; + }; + +}// namespace TSMM::OSM + +#endif//OSMNODE_H diff --git a/src/OSM/map/OSMRelation.h b/src/OSM/map/OSMRelation.h new file mode 100644 index 0000000..07d2cdc --- /dev/null +++ b/src/OSM/map/OSMRelation.h @@ -0,0 +1,37 @@ +#ifndef OSMRELATION_H +#define OSMRELATION_H +#include +#include +#include +namespace TSMM::OSM +{ + + class OSMRelation + { + public: + typedef std::int64_t id_t; + + + explicit OSMRelation(id_t id) : id_(id), isActive_(true) {} + void addMember(const std::string &type, long long refId) + { + members_.emplace_back(type, refId); + } + + void addTag(const std::string &key, const std::string &value) + { + tags_[key] = value; + } + + id_t id() const { return id_; } + + private: + id_t id_; + bool isActive_; + std::vector> members_;// Type ("node", "way", "relation") and ID + std::unordered_map tags_; + }; +}// namespace TSMM::OSM + + +#endif//OSMRELATION_H diff --git a/src/OSM/map/OSMType.h b/src/OSM/map/OSMType.h deleted file mode 100644 index 883de43..0000000 --- a/src/OSM/map/OSMType.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef TYPE_H -#define TYPE_H -#include -#include - - -namespace TSMM::OSMType -{ - // OSM Node: Represents a point with latitude, longitude, and tags - struct Node { - long long id_; - double lat_, lon_; - std::unordered_map tags_; - - Node(long long id, double lat, double lon) : id_(id), lat_(lat), lon_(lon) {} - - void addTag(const std::string &key, const std::string &value) - { - tags_[key] = value; - } - }; - - // OSM Way: Represents a series of nodes (roads, rivers, buildings, etc.) - struct Way { - long long id_; - std::vector nodeRefs_;// Stores references to OSMNode IDs - std::unordered_map tags_; - - explicit Way(long long id) : id_(id) {} - - void addNode(long long nodeId) - { - nodeRefs_.push_back(nodeId); - } - - void addTag(const std::string &key, const std::string &value) - { - tags_[key] = value; - } - }; - - // OSM Relation: A group of nodes, ways, or other relations - struct Relation { - long long id_; - std::vector> members_;// Type ("node", "way", "relation") and ID - std::unordered_map tags_; - - explicit Relation(long long id) : id_(id) {} - - void addMember(const std::string &type, long long refId) - { - members_.emplace_back(type, refId); - } - - void addTag(const std::string &key, const std::string &value) - { - tags_[key] = value; - } - }; - -}// namespace TSMM::OSMType - - -#endif//TYPE_H diff --git a/src/OSM/map/OSMWay.h b/src/OSM/map/OSMWay.h new file mode 100644 index 0000000..93d16c5 --- /dev/null +++ b/src/OSM/map/OSMWay.h @@ -0,0 +1,50 @@ +#ifndef OSMWAY_H +#define OSMWAY_H +#include +#include +#include +namespace TSMM::OSM +{ + class OSMWay + { + + public: + typedef std::int64_t id_t; + + OSMWay(id_t id, std::vector &nodeRef, std::unordered_map &tags) + : id_(id), isActive_(true), nodeRefs_(std::move(nodeRef)), tags_(std::move(tags)) {} + + void addNode(long long nodeId) + { + nodeRefs_.push_back(nodeId); + } + + void addTag(const std::string &key, const std::string &value) + { + tags_[key] = value; + } + + id_t id() const { return id_; } + + void deactivate() { isActive_ = false; } + bool isActive() const { return isActive_; } + + const std::unordered_map &tags() const + { + return tags_; + } + + const std::vector &nodeRefs() const + { + return nodeRefs_; + } + + private: + id_t id_; + bool isActive_; + std::vector nodeRefs_;// Stores references to OSMNode IDs + std::unordered_map tags_; + }; +}// namespace TSMM::OSM + +#endif//OSMWAY_H diff --git a/src/OSM/processor/OSMParser.h b/src/OSM/processor/OSMParser.h index 9f61e1d..7cb4528 100644 --- a/src/OSM/processor/OSMParser.h +++ b/src/OSM/processor/OSMParser.h @@ -27,7 +27,17 @@ namespace TSMM::OSM void way(const osmium::Way &way) { - map_->addWay(way.id()); + std::vector nodeRef; + std::unordered_map tags; + std::for_each(way.nodes().begin(), way.nodes().end(), [&](const auto &node_ref) { + nodeRef.push_back(node_ref.ref());// Store only node IDs + }); + + std::for_each(way.tags().begin(), way.tags().end(), [&](const auto &tag) { + tags.insert(std::make_pair(tag.key(), tag.value())); + }); + + map_->addWay(way.id(), nodeRef, tags); } void relation(const osmium::Relation &relation) diff --git a/src/OSM/processor/OSMProcessorBase.h b/src/OSM/processor/OSMProcessorBase.h index 076f59a..e319c85 100644 --- a/src/OSM/processor/OSMProcessorBase.h +++ b/src/OSM/processor/OSMProcessorBase.h @@ -11,6 +11,8 @@ namespace TSMM::OSM { public: + OSMProcessorBase() = default; + virtual ~OSMProcessorBase() = default; virtual void process(OSMMap &map) = 0; }; }// namespace TSMM::OSM diff --git a/src/OSM/processor/filterWays.h b/src/OSM/processor/filterWays.h new file mode 100644 index 0000000..688c4d1 --- /dev/null +++ b/src/OSM/processor/filterWays.h @@ -0,0 +1,35 @@ + +#ifndef FILTERWAYS_H +#define FILTERWAYS_H + +#include +#include + +namespace TSMM::OSM +{ + + class FilterWays : public OSMProcessorBase + { + + public: + using CallBack = std::function &)>; + explicit FilterWays(CallBack call_back) : OSMProcessorBase(), callBack_(std::move(call_back)) + { + } + + void process(OSMMap &map) override + { + std::for_each(map.ways().begin(), map.ways().end(), [&](auto &pair) { + if (callBack_(pair.second)) + pair.second->deactivate(); + }); + } + + private: + CallBack callBack_; + }; + +}// namespace TSMM::OSM + + +#endif//FILTERWAYS_H