Skip to content

Commit

Permalink
Merge pull request #262 from lonvia/v4
Browse files Browse the repository at this point in the history
New features for upcoming version 4
  • Loading branch information
lonvia authored Aug 17, 2024
2 parents 19747be + 89d0a32 commit c20da5a
Show file tree
Hide file tree
Showing 52 changed files with 2,562 additions and 678 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Install prerequisites
run: |
# Workaround for github/brew problem. Python is already install
# on the Github action runner and then homebrew comes along...
# See also: https://github.com/Homebrew/homebrew-core/issues/173191
rm -f /usr/local/bin/2to3* /usr/local/bin/idle3* /usr/local/bin/pydoc3* /usr/local/bin/python3*
if: ${{ matrix.flavour == 'macos' }}

- uses: ./.github/actions/install-dependencies
with:
version: ${{ matrix.deps }}
Expand Down
48 changes: 27 additions & 21 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS} ${PROTOZERO_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)

if(NOT "${CMAKE_CXX_STANDARD}")
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD 17)
endif()

# required for pybind11 < 2.6
Expand Down Expand Up @@ -60,9 +60,8 @@ function(set_module_output module outdir)
endforeach()
endfunction()

set(PYOSMIUM_MODULES geom index io)

foreach(PYMOD geom index io)
# Modules without any Python code and just one source file.
foreach(PYMOD geom index io area)
pybind11_add_module(${PYMOD} lib/${PYMOD}.cc)
set_module_output(${PYMOD} osmium)
target_link_libraries(${PYMOD} PRIVATE ${OSMIUM_LIBRARIES})
Expand All @@ -71,34 +70,41 @@ foreach(PYMOD geom index io)
endif()
endforeach()

pybind11_add_module(_osm lib/osm.cc)
set_module_output(_osm osmium/osm)
# Modules where additional Python code is in src (C++-part will be private).
foreach(PYMOD osm replication)
pybind11_add_module(_${PYMOD} lib/${PYMOD}.cc)
set_module_output(_${PYMOD} osmium/${PYMOD})
target_link_libraries(_${PYMOD} PRIVATE ${OSMIUM_LIBRARIES})
if(APPLE)
set_target_properties(_${PYMOD} PROPERTIES CXX_VISIBILITY_PRESET "default")
endif()
endforeach()

# Modules with multiple source files.
pybind11_add_module(_osmium
lib/osmium.cc
lib/merge_input_reader.cc
lib/node_location_handler.cc
lib/simple_writer.cc
lib/write_handler.cc
lib/file_iterator.cc)
lib/file_iterator.cc
lib/id_tracker.cc)
set_module_output(_osmium osmium)
pybind11_add_module(_replication lib/replication.cc)
set_module_output(_replication osmium/replication)
pybind11_add_module(_area lib/area.cc)
set_module_output(_area osmium/area)
pybind11_add_module(_filter
target_link_libraries(_osmium PRIVATE ${OSMIUM_LIBRARIES})

pybind11_add_module(filter
lib/filter.cc
lib/empty_tag_filter.cc
lib/key_filter.cc)
set_module_output(_filter osmium/filter)

target_link_libraries(_osmium PRIVATE ${OSMIUM_LIBRARIES})
target_link_libraries(_replication PRIVATE ${OSMIUM_LIBRARIES})
target_link_libraries(_area PRIVATE ${OSMIUM_LIBRARIES})
target_link_libraries(_filter PRIVATE ${OSMIUM_LIBRARIES})
lib/key_filter.cc
lib/tag_filter.cc
lib/id_filter.cc
lib/entity_filter.cc
lib/geo_interface_filter.cc)
set_module_output(filter osmium)
target_link_libraries(filter PRIVATE ${OSMIUM_LIBRARIES})

# workaround for https://github.com/pybind/pybind11/issues/1272
if(APPLE)
set_target_properties(_osmium PROPERTIES CXX_VISIBILITY_PRESET "default")
set_target_properties(_osm PROPERTIES CXX_VISIBILITY_PRESET "default")
set_target_properties(filter PROPERTIES CXX_VISIBILITY_PRESET "default")
endif()

30 changes: 18 additions & 12 deletions lib/area.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,24 +26,26 @@ class AreaManagerSecondPassHandlerBase : public pyosmium::BaseHandler
public:
AreaManagerSecondPassHandlerBase(MpManager *mp_manager)
: m_mp_manager(mp_manager)
{}
{
m_enabled_for = osmium::osm_entity_bits::nwr;
}


bool node(osmium::Node const *n) override
bool node(pyosmium::PyOSMNode &n) override
{
m_mp_manager->handle_node(*n);
m_mp_manager->handle_node(*(n.get()));
return false;
}

bool way(osmium::Way *w) override
bool way(pyosmium::PyOSMWay &w) override
{
m_mp_manager->handle_way(*w);
m_mp_manager->handle_way(*(w.get()));
return false;
}

bool relation(osmium::Relation const *r) override
bool relation(pyosmium::PyOSMRelation &r) override
{
m_mp_manager->handle_relation(*r);
m_mp_manager->handle_relation(*(r.get()));
return false;
}

Expand All @@ -63,8 +65,12 @@ class AreaManagerSecondPassHandler : public AreaManagerSecondPassHandlerBase
AreaManagerSecondPassHandler(MpManager *mp_manager, py::args args)
: AreaManagerSecondPassHandlerBase(mp_manager), m_args(args), m_handlers(m_args)
{
m_mp_manager->set_callback([this](osmium::memory::Buffer &&ab)
{ osmium::apply(ab, this->m_handlers); });
m_mp_manager->set_callback([this](osmium::memory::Buffer &&buffer) {
for (auto &obj : buffer.select<osmium::Area>()) {
pyosmium::PyOSMArea area{&obj};
this->m_handlers.area(area);
}
});
}

private:
Expand Down Expand Up @@ -96,9 +102,9 @@ class AreaManager : public pyosmium::BaseHandler
pyosmium::BaseHandler *first_pass_handler() { return this; }

// first-pass-handler
bool relation(osmium::Relation const *r) override
bool relation(pyosmium::PyOSMRelation &r) override
{
m_mp_manager.relation(*r);
m_mp_manager.relation(*(r.get()));
return false;
}

Expand All @@ -121,7 +127,7 @@ class AreaManager : public pyosmium::BaseHandler

} // namespace

PYBIND11_MODULE(_area, m)
PYBIND11_MODULE(area, m)
{
py::class_<AreaManagerSecondPassHandler, pyosmium::BaseHandler>(m,
"AreaManagerSecondPassHandler");
Expand Down
37 changes: 19 additions & 18 deletions lib/base_filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,34 @@ namespace pyosmium {

class BaseFilter : public BaseHandler {
public:
bool node(osmium::Node const *n) override
bool node(PyOSMNode &o) override
{
return (m_enabled_for & osmium::osm_entity_bits::node)
&& filter_node(n);
&& filter_node(o);
}

bool way(osmium::Way *n) override
bool way(PyOSMWay &o) override
{
return (m_enabled_for & osmium::osm_entity_bits::way)
&& filter_way(n);
&& filter_way(o);
}

bool relation(osmium::Relation const *n) override
bool relation(PyOSMRelation &o) override
{
return (m_enabled_for & osmium::osm_entity_bits::relation)
&& filter_relation(n);
&& filter_relation(o);
}

bool area(osmium::Area const *n) override
bool area(PyOSMArea &o) override
{
return (m_enabled_for & osmium::osm_entity_bits::area)
&& filter_area(n);
&& filter_area(o);
}

bool changeset(osmium::Changeset const *n) override
bool changeset(PyOSMChangeset &o) override
{
return (m_enabled_for & osmium::osm_entity_bits::changeset)
&& filter_changeset(n);
&& filter_changeset(o);
}

BaseFilter *enable_for(osmium::osm_entity_bits::type entities)
Expand All @@ -55,20 +55,21 @@ class BaseFilter : public BaseHandler {

protected:
virtual bool filter(osmium::OSMObject const *) { return false; }
virtual bool filter_node(osmium::Node const *n) { return filter(n); }
virtual bool filter_way(osmium::Way const *w) { return filter(w); }
virtual bool filter_relation(osmium::Relation const *r) { return filter(r); }
virtual bool filter_area(osmium::Area const *a) { return filter(a); }
virtual bool filter_changeset(osmium::Changeset const *) { return false; }

private:
osmium::osm_entity_bits::type m_enabled_for = osmium::osm_entity_bits::all;

virtual bool filter_node(PyOSMNode &o) { return filter(o.get()); }
virtual bool filter_way(PyOSMWay &o) { return filter(o.get()); }
virtual bool filter_relation(PyOSMRelation &o) { return filter(o.get()); }
virtual bool filter_area(PyOSMArea &o) { return filter(o.get()); }
virtual bool filter_changeset(PyOSMChangeset &o) { return false; }
};


void init_empty_tag_filter(pybind11::module &m);
void init_key_filter(pybind11::module &m);
void init_tag_filter(pybind11::module &m);
void init_id_filter(pybind11::module &m);
void init_entity_filter(pybind11::module &m);
void init_geo_interface_filter(pybind11::module &m);

} // namespace

Expand Down
36 changes: 21 additions & 15 deletions lib/base_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,42 @@
#ifndef PYOSMIUM_BASE_HANDLER_HPP
#define PYOSMIUM_BASE_HANDLER_HPP

#include <osmium/handler.hpp>
#include <osmium/osm/entity.hpp>
#include <osmium/io/reader.hpp>

#include "osm_base_objects.h"

namespace pyosmium {

class BaseHandler : public osmium::handler::Handler
class BaseHandler
{
public:
virtual ~BaseHandler() = default;

// 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(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.
// All object handlers return a boolean which indicates if
// processing is finished (true) or should be continued with the next
// handler (false).
virtual bool node(const osmium::Node*) { return false; }
virtual bool way(osmium::Way *) { return false; }
virtual bool relation(const osmium::Relation*) { return false; }
virtual bool changeset(const osmium::Changeset*) { return false; }
virtual bool area(const osmium::Area*) { return false; }
virtual bool node(PyOSMNode &) { return false; }
virtual bool way(PyOSMWay &) { return false; }
virtual bool relation(PyOSMRelation &) { return false; }
virtual bool area(PyOSMArea &) { return false; }
virtual bool changeset(PyOSMChangeset &) { return false; }

virtual void flush() {}

bool is_enabled_for(osmium::osm_entity_bits::type types) const
{
return types & m_enabled_for;
}

protected:
osmium::osm_entity_bits::type m_enabled_for = osmium::osm_entity_bits::all;
};

void apply(osmium::io::Reader &reader, BaseHandler &handler);
void apply_item(osmium::OSMEntity &item, BaseHandler &handler);

} // namespace

#endif // PYOSMIUM_BASE_HANDLER_HPP
Loading

0 comments on commit c20da5a

Please sign in to comment.