-
-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #241 from lonvia/generic-apply-II
Generalize osmium.apply() to work with an arbitrary number of handlers
- Loading branch information
Showing
11 changed files
with
329 additions
and
143 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,114 +2,34 @@ | |
* | ||
* This file is part of pyosmium. (https://osmcode.org/pyosmium/) | ||
* | ||
* Copyright (C) 2023 Sarah Hoffmann <[email protected]> and others. | ||
* Copyright (C) 2024 Sarah Hoffmann <[email protected]> and others. | ||
* For a full list of authors see the git log. | ||
*/ | ||
#ifndef PYOSMIUM_BASE_HANDLER_HPP | ||
#define PYOSMIUM_BASE_HANDLER_HPP | ||
|
||
#include <osmium/area/assembler.hpp> | ||
#include <osmium/area/multipolygon_manager.hpp> | ||
#include <osmium/handler.hpp> | ||
#include <osmium/handler/node_locations_for_ways.hpp> | ||
#include <osmium/index/map/all.hpp> | ||
|
||
class BaseHandler : public osmium::handler::Handler | ||
{ | ||
using IndexType = | ||
osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>; | ||
using IndexFactory = | ||
osmium::index::MapFactory<osmium::unsigned_object_id_type, osmium::Location>; | ||
using MpManager = | ||
osmium::area::MultipolygonManager<osmium::area::Assembler>; | ||
|
||
|
||
protected: | ||
enum pre_handler { | ||
no_handler, | ||
location_handler, | ||
area_handler | ||
}; | ||
|
||
public: | ||
virtual ~BaseHandler() = default; | ||
virtual osmium::osm_entity_bits::type enabled_callbacks() = 0; | ||
|
||
// work around pybind's bad copy policy | ||
// (see https://github.com/pybind/pybind11/issues/1241) | ||
void node(const osmium::Node &o) { node(&o); } | ||
void way(const osmium::Way &o) { way(&o); } | ||
void way(osmium::Way &o) { way(&o); } | ||
void relation(const osmium::Relation &o) { relation(&o); } | ||
void changeset(const osmium::Changeset &o) { changeset(&o); } | ||
void area(const osmium::Area &o) { area(&o); } | ||
|
||
// actual handler functions | ||
virtual void node(const osmium::Node*) {} | ||
virtual void way(const osmium::Way*) {} | ||
virtual void way(osmium::Way *) {} | ||
virtual void relation(const osmium::Relation*) {} | ||
virtual void changeset(const osmium::Changeset*) {} | ||
virtual void area(const osmium::Area*) {} | ||
|
||
|
||
private: | ||
void apply_with_location(osmium::io::Reader &r, const std::string &idx) | ||
{ | ||
const auto &map_factory = IndexFactory::instance(); | ||
auto index = map_factory.create_map(idx); | ||
osmium::handler::NodeLocationsForWays<IndexType> location_handler(*index); | ||
location_handler.ignore_errors(); | ||
|
||
osmium::apply(r, location_handler, *this); | ||
} | ||
|
||
void apply_with_area(osmium::io::Reader &r, MpManager &mp_manager, | ||
const std::string &idx) | ||
{ | ||
const auto &map_factory = IndexFactory::instance(); | ||
auto index = map_factory.create_map(idx); | ||
osmium::handler::NodeLocationsForWays<IndexType> location_handler(*index); | ||
location_handler.ignore_errors(); | ||
|
||
osmium::apply(r, location_handler, *this, | ||
mp_manager.handler([this](const osmium::memory::Buffer &ab) | ||
{ osmium::apply(ab, *this); })); | ||
} | ||
|
||
protected: | ||
void apply(const osmium::io::File &file, osmium::osm_entity_bits::type types, | ||
pre_handler pre = no_handler, | ||
const std::string &idx = "flex_mem") | ||
{ | ||
switch (pre) { | ||
case no_handler: | ||
{ | ||
osmium::io::Reader reader(file, types); | ||
osmium::apply(reader, *this); | ||
reader.close(); | ||
break; | ||
} | ||
case location_handler: | ||
{ | ||
osmium::io::Reader reader(file, types); | ||
apply_with_location(reader, idx); | ||
reader.close(); | ||
break; | ||
} | ||
case area_handler: | ||
{ | ||
osmium::area::Assembler::config_type assembler_config; | ||
MpManager mp_manager{assembler_config}; | ||
|
||
osmium::relations::read_relations(file, mp_manager); | ||
|
||
osmium::io::Reader reader2(file); | ||
apply_with_area(reader2, mp_manager, idx); | ||
reader2.close(); | ||
break; | ||
} | ||
} | ||
} | ||
|
||
}; | ||
|
||
#endif // PYOSMIUM_BASE_HANDLER_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ | |
* | ||
* This file is part of pyosmium. (https://osmcode.org/pyosmium/) | ||
* | ||
* Copyright (C) 2023 Sarah Hoffmann <[email protected]> and others. | ||
* Copyright (C) 2024 Sarah Hoffmann <[email protected]> and others. | ||
* For a full list of authors see the git log. | ||
*/ | ||
#include <pybind11/pybind11.h> | ||
|
@@ -133,7 +133,7 @@ class MergeInputReader | |
objects.sort(osmium::object_order_type_id_reverse_version()); | ||
osmium::item_type prev_type = osmium::item_type::undefined; | ||
osmium::object_id_type prev_id = 0; | ||
for (const auto &item: objects) { | ||
for (auto &item: objects) { | ||
if (item.type() != prev_type || item.id() != prev_id) { | ||
prev_type = item.type(); | ||
prev_id = item.id(); | ||
|
@@ -142,7 +142,7 @@ class MergeInputReader | |
} | ||
} else { | ||
objects.sort(osmium::object_order_type_id_version()); | ||
osmium::apply(objects.cbegin(), objects.cend(), handler); | ||
osmium::apply(objects.begin(), objects.end(), handler); | ||
} | ||
|
||
objects = osmium::ObjectPointerCollection(); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* SPDX-License-Identifier: BSD-2-Clause | ||
* | ||
* This file is part of pyosmium. (https://osmcode.org/pyosmium/) | ||
* | ||
* Copyright (C) 2024 Sarah Hoffmann <[email protected]> and others. | ||
* For a full list of authors see the git log. | ||
*/ | ||
#include <pybind11/pybind11.h> | ||
|
||
#include <osmium/index/map/all.hpp> | ||
#include <osmium/handler/node_locations_for_ways.hpp> | ||
|
||
#include "base_handler.h" | ||
|
||
using LocationTable = | ||
osmium::index::map::Map<osmium::unsigned_object_id_type, osmium::Location>; | ||
using NodeLocationHandler = | ||
osmium::handler::NodeLocationsForWays<LocationTable>; | ||
|
||
|
||
class NodeLocationsForWays : public BaseHandler | ||
{ | ||
public: | ||
NodeLocationsForWays(LocationTable &idx) | ||
: handler(idx) | ||
{} | ||
|
||
void node(const osmium::Node *o) override | ||
{ | ||
handler.node(*o); | ||
} | ||
|
||
void way(osmium::Way *o) override | ||
{ | ||
if (apply_nodes_to_ways) { | ||
handler.way(*o); | ||
} | ||
} | ||
|
||
bool get_apply_nodes_to_ways() const { return apply_nodes_to_ways; } | ||
|
||
void set_apply_nodes_to_ways(bool val) { apply_nodes_to_ways = val; } | ||
|
||
void ignore_errors() { handler.ignore_errors(); } | ||
|
||
private: | ||
NodeLocationHandler handler; | ||
bool apply_nodes_to_ways = true; | ||
}; | ||
|
||
namespace py = pybind11; | ||
|
||
void init_node_location_handler(py::module &m) | ||
{ | ||
py::class_<NodeLocationsForWays, BaseHandler>(m, "NodeLocationsForWays") | ||
.def(py::init<LocationTable&>(), py::keep_alive<1, 2>()) | ||
.def("ignore_errors", &NodeLocationsForWays::ignore_errors) | ||
.def_property("apply_nodes_to_ways", | ||
&NodeLocationsForWays::get_apply_nodes_to_ways, | ||
&NodeLocationsForWays::set_apply_nodes_to_ways, | ||
"When set to false, locations are only collected " | ||
"and not automatically applied to way nodes.") | ||
; | ||
|
||
} |
Oops, something went wrong.