Skip to content
Commits on Source (9)
......@@ -45,17 +45,19 @@ addons:
- python-dev
- python-nose
- python-mock
- python-shapely
- python3
- python3-dev
- python3-nose
- python3-setuptools
- python3-shapely
install:
- git clone --quiet --depth 1 https://github.com/osmcode/libosmium.git contrib/libosmium
- git clone --quiet --depth 1 https://github.com/mapbox/protozero.git contrib/protozero
- git clone --quiet --depth 1 https://github.com/pybind/pybind11.git contrib/pybind11
- if [ "$TRAVIS_OS_NAME" = 'osx' ]; then
pip${USE_PYTHON_VERSION} install -q nose mock;
pip${USE_PYTHON_VERSION} install -q nose mock shapely;
fi
script:
......
......@@ -4,6 +4,23 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
## [2.15.3] - 2019-08-16
### Added
- `make_simple_handler()` convenience wrapper
- iterator for Tag type (for allowing to convert TagLists into python dicts)
- tests for examples
- tests for MP building and MergeInputReader
### Changed
- use current libosmium and protozero
### Fixed
- remove spurious 404 error message when downloading OSM diffs
## [2.15.2] - 2019-03-09
### Added
......
......@@ -3,7 +3,7 @@ project(pyosmium)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(Osmium 2.14 REQUIRED COMPONENTS io pbf xml)
find_package(Osmium 2.15 REQUIRED COMPONENTS io pbf xml)
include_directories(SYSTEM ${OSMIUM_INCLUDE_DIRS} ${PROTOZERO_INCLUDE_DIR})
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/lib)
......
......@@ -5,7 +5,7 @@ library, a library for working with OpenStreetMap data in a fast and flexible
manner.
[![Travis Build Status](https://api.travis-ci.org/osmcode/pyosmium.svg)](http://travis-ci.org/osmcode/pyosmium)
[![Appeveyor Build status](https://ci.appveyor.com/api/projects/status/dr69wsw855lwrg8w/branch/master?svg=true)](https://ci.appveyor.com/project/lonvia/pyosmium/branch/master)
[![Appeveyor Build status](https://ci.appveyor.com/api/projects/status/ch3gwxucycytako4/branch/master?svg=true)](https://ci.appveyor.com/project/lonvia/pyosmium/branch/master)
......
......@@ -3,34 +3,29 @@ environment:
BZIP2_VER: 1.0.6
EXPAT_VER: 2.2.5
ZLIB_VER: 1.2.11
SHAPELY_VER: 1.6.4
BOOST_PREFIX: C:\Libraries\boost_1_67_0
matrix:
- PYTHON: "C:\\Python27-x64"
- PYTHON_VER: 2.7
PIPINSTALLS: nose wheel mock
MINICONDA: "C:\\Miniconda-x64"
arch: x64
- PYTHON: "C:\\Python36-x64"
- PYTHON_VER: 3.6
PIPINSTALLS: nose wheel
MINICONDA: "C:\\Miniconda36-x64"
arch: x64
- PYTHON: "C:\\Python37-x64"
- PYTHON_VER: 3.7
PIPINSTALLS: nose wheel
MINICONDA: "C:\\Miniconda37-x64"
arch: x64
os: Visual Studio 2015
os: Visual Studio 2017
clone_depth: 1
init:
- git config --global core.autocrlf input
- if "%arch%"=="x86" (
set vcvarsall_arg=x86&&
set build_type=Release)
- if "%arch%"=="x64" (
set vcvarsall_arg=amd64&&
set build_type=Release)
- '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall" %vcvarsall_arg%'
- '"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall" amd64'
- set conda_path=%MINICONDA%\Scripts
- set conda_library_path=%MINICONDA%\envs\pyosmium\Library
......@@ -38,18 +33,15 @@ install:
- set PATH=%PATH%;%conda_path%
- cd c:\
- conda config --set always_yes yes
- conda create --name pyosmium
- conda create --name pyosmium python=%PYTHON_VER%
- activate pyosmium
- conda install bzip2=%BZIP2_VER% expat=%EXPAT_VER% zlib=%ZLIB_VER%
- SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%
- conda install bzip2=%BZIP2_VER% expat=%EXPAT_VER% zlib=%ZLIB_VER% shapely=%SHAPELY_VER% %PIPINSTALLS%
- SET PATH=%MINICONDA%\envs\pyosmium\Scripts;%PATH%
- python --version
- cd c:\dev
- git clone --depth 1 https://github.com/osmcode/libosmium.git pyosmium/contrib/libosmium
- git clone --depth 1 https://github.com/mapbox/protozero.git pyosmium/contrib/protozero
- git clone --depth 1 https://github.com/pybind/pybind11.git pyosmium/contrib/pybind11
- dir c:\dev
- cd c:\
- pip install %PIPINSTALLS%
# clone directory
clone_folder: c:\dev\pyosmium
......@@ -66,10 +58,10 @@ test_script:
after_test:
- cd c:\dev\pyosmium
- copy /y %conda_library_path%\bin\zlib.dll c:\dev\pyosmium\contrib
- copy /y %conda_library_path%\bin\expat.dll c:\dev\pyosmium\contrib
- copy /y %conda_library_path%\bin\libbz2.dll c:\dev\pyosmium\contrib
- "%PYTHON%\\python.exe setup.py bdist_wheel"
- copy /y %conda_library_path%\bin\zlib.dll c:\dev\pyosmium\src\osmium
- copy /y %conda_library_path%\bin\expat.dll c:\dev\pyosmium\src\osmium
- copy /y %conda_library_path%\bin\libbz2.dll c:\dev\pyosmium\src\osmium
- python.exe setup.py bdist_wheel
artifacts:
- path: dist\*
......@@ -71,6 +71,9 @@ find_path(OSMIUM_INCLUDE_DIR osmium/version.hpp
# Check libosmium version number
if(Osmium_FIND_VERSION)
if(NOT EXISTS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp")
message(FATAL_ERROR "Missing ${OSMIUM_INCLUDE_DIR}/osmium/version.hpp. Either your libosmium version is too old, or libosmium wasn't found in the place you said.")
endif()
file(STRINGS "${OSMIUM_INCLUDE_DIR}/osmium/version.hpp" _libosmium_version_define REGEX "#define LIBOSMIUM_VERSION_STRING")
if("${_libosmium_version_define}" MATCHES "#define LIBOSMIUM_VERSION_STRING \"([0-9.]+)\"")
set(_libosmium_version "${CMAKE_MATCH_1}")
......@@ -111,7 +114,7 @@ endif()
if(Osmium_USE_PBF)
find_package(ZLIB)
find_package(Threads)
find_package(Protozero 1.5.1)
find_package(Protozero 1.6.3)
list(APPEND OSMIUM_EXTRA_FIND_VARS ZLIB_FOUND Threads_FOUND PROTOZERO_INCLUDE_DIR)
if(ZLIB_FOUND AND Threads_FOUND AND PROTOZERO_FOUND)
......@@ -324,7 +327,7 @@ if(MSVC)
add_definitions(-DNOMINMAX -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_WARNINGS)
endif()
if(APPLE)
if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# following only available from cmake 2.8.12:
# add_compile_options(-stdlib=libc++)
# so using this instead:
......
pyosmium (2.15.3-1~bpo10+1) buster-backports; urgency=medium
* Rebuild for buster-backports.
-- Bas Couwenberg <sebastic@debian.org> Thu, 22 Aug 2019 06:01:10 +0200
pyosmium (2.15.3-1) unstable; urgency=medium
* New upstream release.
* Bump minimum required libosmium2-dev to 2.15.2.
* Drop obsolete examples file.
* Add python3-shapely to (build) dependencies.
-- Bas Couwenberg <sebastic@debian.org> Sat, 17 Aug 2019 08:39:20 +0200
pyosmium (2.15.2-2~bpo10+1) buster-backports; urgency=medium
* Rebuild for buster-backports.
......
......@@ -11,13 +11,14 @@ Build-Depends: cmake (>= 2.8.12),
libexpat1-dev,
libgdal-dev,
libgeos++-dev,
libosmium2-dev (>= 2.15.1),
libosmium2-dev (>= 2.15.2),
libsparsehash-dev,
pybind11-dev,
python3-all-dev,
python3-setuptools,
python3-mock,
python3-nose,
python3-shapely,
python3-sphinx,
python3-sphinxcontrib.autoprogram
Standards-Version: 4.4.0
......@@ -49,7 +50,8 @@ Depends: ${python3:Depends},
${shlibs:Depends},
${misc:Depends}
Provides: ${python3:Provides}
Suggests: pyosmium-doc
Suggests: python3-shapely,
pyosmium-doc
Description: Osmium library bindings for Python 3
The PyOsmium module allows you to access some of the features of the Osmium
library from Python code.
......
......@@ -45,3 +45,5 @@ Low-level Functions and Classes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: osmium.apply
.. autofunction:: osmium.make_simple_handler
......@@ -29,11 +29,17 @@ class AmenityListHandler(o.SimpleHandler):
self.print_amenity(a.tags, centroid.x, centroid.y)
def main(osmfile):
handler = AmenityListHandler()
handler.apply_file(osmfile)
return 0
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python amenity_list.py <osmfile>")
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(-1)
handler = AmenityListHandler()
handler.apply_file(sys.argv[1])
exit(main(sys.argv[1]))
"""
Simple example that counts the number of changes in an osm diff file.
Shows how to detect the different kind of modifications.
Shows how to detect the different kind of modifications and how to
use the handler generator function instead of a handler class.
"""
import osmium as o
import sys
......@@ -13,7 +14,7 @@ class Stats(object):
self.modified = 0
self.deleted = 0
def add(self, o):
def __call__(self, o):
if o.deleted:
self.deleted += 1
elif o.version == 1:
......@@ -27,32 +28,24 @@ class Stats(object):
print("%s deleted: %d" % (prefix, self.deleted))
class FileStatsHandler(o.SimpleHandler):
def __init__(self):
super(FileStatsHandler, self).__init__()
self.nodes = Stats()
self.ways = Stats()
self.rels = Stats()
def main(osmfile):
nodes = Stats()
ways = Stats()
rels = Stats()
def node(self, n):
self.nodes.add(n)
h = o.make_simple_handler(node=nodes, way=ways, relation=rels)
def way(self, w):
self.ways.add(w)
h.apply_file(osmfile)
def relation(self, r):
self.rels.add(r)
nodes.outstats("Nodes")
ways.outstats("Ways")
rels.outstats("Relations")
return 0
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python osm_file_stats.py <osmfile>")
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(-1)
h = FileStatsHandler()
h.apply_file(sys.argv[1])
h.nodes.outstats("Nodes")
h.ways.outstats("Ways")
h.rels.outstats("Relations")
exit(main(sys.argv[1]))
......@@ -24,15 +24,20 @@ class FileStatsHandler(o.SimpleHandler):
self.rels += 1
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python osm_file_stats.py <osmfile>")
sys.exit(-1)
def main(osmfile):
h = FileStatsHandler()
h.apply_file(sys.argv[1])
h.apply_file(osmfile)
print("Nodes: %d" % h.nodes)
print("Ways: %d" % h.ways)
print("Relations: %d" % h.rels)
return 0
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(-1)
exit(main(sys.argv[1]))
......@@ -17,10 +17,14 @@ class NamesHandler(osmium.SimpleHandler):
def way(self, w):
self.output_pubs(w.tags)
def main(osmfile):
NamesHandler().apply_file(osmfile)
return 0
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python pub_names.py <osmfile>")
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(-1)
NamesHandler().apply_file(sys.argv[1])
exit(main(sys.argv[1]))
"""
Compute the total length of highways in an osm file.
Shows how extract the geometry of a way.
Shows how to extract the geometry of a way.
"""
import osmium as o
import sys
......@@ -20,14 +20,19 @@ class RoadLengthHandler(o.SimpleHandler):
# where nodes of ways near the boundary are missing.
print("WARNING: way %d incomplete. Ignoring." % w.id)
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python road_length.py <osmfile>")
sys.exit(-1)
def main(osmfile):
h = RoadLengthHandler()
# As we need the geometry, the node locations need to be cached. Therefore
# set 'locations' to true.
h.apply_file(sys.argv[1], locations=True)
h.apply_file(osmfile, locations=True)
print('Total way length: %.2f km' % (h.length/1000))
return 0
if __name__ == '__main__':
if len(sys.argv) != 2:
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(-1)
exit(main(sys.argv[1]))
......@@ -7,6 +7,33 @@
namespace py = pybind11;
class TagIterator
{
public:
TagIterator(osmium::Tag const &t, py::object r)
: tag(t), ref(r)
{}
char const *next()
{
switch (index) {
case 0:
++index;
return tag.key();
case 1:
++index;
return tag.value();
};
throw py::stop_iteration();
}
private:
osmium::Tag const &tag;
py::object ref; // keep a reference
size_t index = 0;
};
PYBIND11_MODULE(_osm, m) {
py::enum_<osmium::osm_entity_bits::type>(m, "osm_entity_bits")
......@@ -90,12 +117,20 @@ PYBIND11_MODULE(_osm, m) {
"Check if the given location is inside the box.")
;
py::class_<TagIterator>(m, "TagIterator")
.def("__iter__", [](TagIterator &it) -> TagIterator& { return it; })
.def("__next__", &TagIterator::next)
.def("__len__", [](TagIterator const &it) { return 2; })
;
py::class_<osmium::Tag>(m, "Tag",
"A single OSM tag.")
.def_property_readonly("k", &osmium::Tag::key,
"(read-only) Tag key.")
.def_property_readonly("v", &osmium::Tag::value,
"(read-only) Tag value.")
.def("__iter__", [](py::object s)
{ return TagIterator(s.cast<osmium::Tag const &>(), s); })
;
py::class_<osmium::TagList>(m, "TagList",
......
......@@ -146,6 +146,7 @@ setup(
ext_modules=[CMakeExtension('cmake_example')],
packages = ['osmium', 'osmium/osm', 'osmium/replication'],
package_dir = {'' : 'src'},
package_data = { 'osmium' : [ '*.dll' ] },
cmdclass=dict(build_ext=CMakeBuild, sdist=Pyosmium_sdist),
zip_safe=False,
)
from osmium._osmium import *
from osmium.helper import *
import osmium.io
import osmium.osm
import osmium.index
......
from osmium._osmium import SimpleHandler
def make_simple_handler(node=None, way=None, relation=None, area=None):
""" Convenience function that creates a `SimpleHandler` from a set of
callback functions. Each of the parameters takes an optional callable
that must expect a single positional parameter with the object being
processed.
"""
class __HandlerWithCallbacks(SimpleHandler):
pass
if node is not None:
__HandlerWithCallbacks.node = staticmethod(node)
if way is not None:
__HandlerWithCallbacks.way = staticmethod(way)
if relation is not None:
__HandlerWithCallbacks.relation = staticmethod(relation)
if area is not None:
__HandlerWithCallbacks.area = staticmethod(area)
return __HandlerWithCallbacks()
......@@ -275,7 +275,6 @@ class ReplicationServer(object):
try:
response = self.open_url(self.get_state_url(seq))
except Exception as err:
logging.error(err)
return None
ts = None
......