From 6f5ec839c60593562a5921fddc3b654e81432c30 Mon Sep 17 00:00:00 2001 From: xiaorui Date: Fri, 28 Feb 2025 20:40:46 +0100 Subject: [PATCH 1/2] feat: filter ways --- src/OSM/features/simplifyOSM.h | 26 ++++++++++ src/OSM/map/OSMMap.h | 74 ++++++++++++++++++++-------- src/OSM/map/OSMNode.h | 36 ++++++++++++++ src/OSM/map/OSMRelation.h | 37 ++++++++++++++ src/OSM/map/OSMType.h | 64 ------------------------ src/OSM/map/OSMWay.h | 50 +++++++++++++++++++ src/OSM/processor/OSMParser.h | 9 +++- src/OSM/processor/OSMProcessorBase.h | 2 + src/OSM/processor/filterWays.h | 38 ++++++++++++++ 9 files changed, 251 insertions(+), 85 deletions(-) create mode 100644 src/OSM/map/OSMNode.h create mode 100644 src/OSM/map/OSMRelation.h delete mode 100644 src/OSM/map/OSMType.h create mode 100644 src/OSM/map/OSMWay.h create mode 100644 src/OSM/processor/filterWays.h diff --git a/src/OSM/features/simplifyOSM.h b/src/OSM/features/simplifyOSM.h index 2d5e646..da357fe 100644 --- a/src/OSM/features/simplifyOSM.h +++ b/src/OSM/features/simplifyOSM.h @@ -7,11 +7,34 @@ #include #include #include +#include #include +#include namespace TSMM::OSM { + bool isWayFiltered(std::shared_ptr &way) + { + std::string keyString = "highway"; + std::unordered_set leftWayTags; + leftWayTags.insert("motorway"); + leftWayTags.insert("trunk"); + leftWayTags.insert("primary"); + leftWayTags.insert("secondary"); + leftWayTags.insert("tertiary"); + leftWayTags.insert("residential"); + + const auto waytags = way->tags(); + if (waytags.count(keyString)) + { + if (leftWayTags.count(waytags.at(keyString))) + return false; + return true; + } + return true; + } + class SimplifyOSM { std::shared_ptr map_; @@ -34,6 +57,7 @@ namespace TSMM::OSM std::cerr << "Exception: " << e.what() << "\n"; exit(1);// Exit with error code } + int m = 1; } void process() @@ -41,8 +65,10 @@ 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); diff --git a/src/OSM/map/OSMMap.h b/src/OSM/map/OSMMap.h index e25bd47..e8a9a14 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,9 +19,9 @@ 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) @@ -30,9 +33,9 @@ namespace TSMM::OSM 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(); } @@ -42,38 +45,69 @@ namespace TSMM::OSM { for (const auto &way: ways_) { + 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}; + for (const auto &nId: way.second->nodeRefs()) + { + 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 + for (const auto &tags: way.second->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..122e2e0 --- /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 deactive() { 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..6f470b8 100644 --- a/src/OSM/processor/OSMParser.h +++ b/src/OSM/processor/OSMParser.h @@ -27,7 +27,14 @@ namespace TSMM::OSM void way(const osmium::Way &way) { - map_->addWay(way.id()); + std::vector nodeRef; + std::unordered_map tags; + for (const auto &node_ref: way.nodes()) + nodeRef.push_back(node_ref.ref());// Store only node IDs + for (const auto &tag: way.tags()) + 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..af76acf --- /dev/null +++ b/src/OSM/processor/filterWays.h @@ -0,0 +1,38 @@ + +#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 + { + + for (auto &way: map.ways()) + { + if (callBack_(way.second)) + way.second->deactive(); + } + } + + private: + std::vector targetTags_; + CallBack callBack_; + }; + +}// namespace TSMM::OSM + + +#endif//FILTERWAYS_H From 2fe1fe6d78f4ad35701d6f55cb57962b8c152887 Mon Sep 17 00:00:00 2001 From: xiaorui Date: Mon, 10 Mar 2025 20:39:52 +0100 Subject: [PATCH 2/2] filter ways --- src/OSM/features/simplifyOSM.h | 17 +++-------------- src/OSM/map/OSMMap.h | 20 ++++++++------------ src/OSM/map/OSMWay.h | 4 ++-- src/OSM/processor/OSMParser.h | 7 +++++-- src/OSM/processor/filterWays.h | 11 ++++------- 5 files changed, 22 insertions(+), 37 deletions(-) diff --git a/src/OSM/features/simplifyOSM.h b/src/OSM/features/simplifyOSM.h index da357fe..fd6197a 100644 --- a/src/OSM/features/simplifyOSM.h +++ b/src/OSM/features/simplifyOSM.h @@ -13,18 +13,11 @@ 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"; - std::unordered_set leftWayTags; - leftWayTags.insert("motorway"); - leftWayTags.insert("trunk"); - leftWayTags.insert("primary"); - leftWayTags.insert("secondary"); - leftWayTags.insert("tertiary"); - leftWayTags.insert("residential"); - const auto waytags = way->tags(); if (waytags.count(keyString)) { @@ -42,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); @@ -57,7 +49,6 @@ namespace TSMM::OSM std::cerr << "Exception: " << e.what() << "\n"; exit(1);// Exit with error code } - int m = 1; } void process() @@ -72,9 +63,7 @@ namespace TSMM::OSM 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 e8a9a14..deee601 100644 --- a/src/OSM/map/OSMMap.h +++ b/src/OSM/map/OSMMap.h @@ -26,8 +26,7 @@ namespace TSMM::OSM 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"); @@ -38,13 +37,12 @@ namespace TSMM::OSM 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()) { { @@ -58,27 +56,25 @@ namespace TSMM::OSM { ///< add node ref osmium::builder::WayNodeListBuilder wayNodeListBuilder{buffer, &builder}; - for (const auto &nId: way.second->nodeRefs()) - { + 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 - for (const auto &tags: way.second->tags()) - { + std::for_each(way.second->tags().begin(), way.second->tags().end(), [&](const auto &tags) { tl_builder.add_tag(tags.first, tags.second); - } + }); } } buffer.commit(); } - } + }); } diff --git a/src/OSM/map/OSMWay.h b/src/OSM/map/OSMWay.h index 122e2e0..93d16c5 100644 --- a/src/OSM/map/OSMWay.h +++ b/src/OSM/map/OSMWay.h @@ -26,7 +26,7 @@ namespace TSMM::OSM id_t id() const { return id_; } - void deactive() { isActive_ = false; } + void deactivate() { isActive_ = false; } bool isActive() const { return isActive_; } const std::unordered_map &tags() const @@ -34,7 +34,7 @@ namespace TSMM::OSM return tags_; } - const std::vector& nodeRefs() const + const std::vector &nodeRefs() const { return nodeRefs_; } diff --git a/src/OSM/processor/OSMParser.h b/src/OSM/processor/OSMParser.h index 6f470b8..7cb4528 100644 --- a/src/OSM/processor/OSMParser.h +++ b/src/OSM/processor/OSMParser.h @@ -29,10 +29,13 @@ namespace TSMM::OSM { std::vector nodeRef; std::unordered_map tags; - for (const auto &node_ref: way.nodes()) + std::for_each(way.nodes().begin(), way.nodes().end(), [&](const auto &node_ref) { nodeRef.push_back(node_ref.ref());// Store only node IDs - for (const auto &tag: way.tags()) + }); + + 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); } diff --git a/src/OSM/processor/filterWays.h b/src/OSM/processor/filterWays.h index af76acf..688c4d1 100644 --- a/src/OSM/processor/filterWays.h +++ b/src/OSM/processor/filterWays.h @@ -19,16 +19,13 @@ namespace TSMM::OSM void process(OSMMap &map) override { - - for (auto &way: map.ways()) - { - if (callBack_(way.second)) - way.second->deactive(); - } + std::for_each(map.ways().begin(), map.ways().end(), [&](auto &pair) { + if (callBack_(pair.second)) + pair.second->deactivate(); + }); } private: - std::vector targetTags_; CallBack callBack_; };