[pyosmium] 02/05: Imported Upstream version 2.1.0

Sebastiaan Couwenberg sebastic at moszumanska.debian.org
Thu May 21 07:46:10 UTC 2015


This is an automated email from the git hooks/post-receive script.

sebastic pushed a commit to branch master
in repository pyosmium.

commit bbbc466fa5a8f9b7067e1694251064bb360a49d7
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date:   Wed May 20 21:57:34 2015 +0200

    Imported Upstream version 2.1.0
---
 .travis.yml                         |  33 ++++----
 README.md                           |  27 +++++--
 doc/.gitignore                      |   1 +
 doc/conf.py                         |   4 +-
 doc/index.rst                       |   3 +-
 doc/intro.rst                       | 149 +++++++++++++++++++++++++++++++++++-
 examples/amenity_list.py            |  16 +++-
 examples/create_nodecache.py        |   2 +-
 examples/osm_file_stats.py          |  21 +++--
 examples/pub_names.py               |  12 ++-
 examples/road_length.py             |  20 ++++-
 lib/geom.cc                         |  18 ++++-
 lib/osm.cc                          |  34 +++++++-
 test/{test_helper.py => helpers.py} |   0
 test/test_geom.py                   |  40 ++++++++++
 test/test_io.py                     |   2 +-
 test/test_osm.py                    |   7 +-
 17 files changed, 344 insertions(+), 45 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index d855c02..19a41aa 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,3 +1,9 @@
+#-----------------------------------------------------------------------------
+#
+#  Configuration for continuous integration service at travis-ci.org
+#
+#-----------------------------------------------------------------------------
+
 language: cpp
 
 compiler:
@@ -9,34 +15,29 @@ env:
  - USE_PYTHON_VERSION=3
 
 before_install:
- # we need at least g++-4.8 for c++11 features
+ # upgrade compiler (we need at least g++-4.8 for C++11 features)
  - sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test
- - sudo apt-get update --yes --quiet
+ - sudo apt-get update --yes -qq
+ - gcc_version=4.8
+ - sudo apt-get install --yes gcc-${gcc_version} g++-${gcc_version}
+ - gcc-${gcc_version} --version
+ # make sure compiler executables point to the just installed version
+ - sudo ln -sf /usr/bin/cpp-${gcc_version} /usr/bin/cpp
+ - sudo ln -sf /usr/bin/gcc-${gcc_version} /usr/bin/gcc
+ - sudo ln -sf /usr/bin/g++-${gcc_version} /usr/bin/g++
+ # install dependencies
+ - sudo apt-get install --yes make python3-dev python3 libboost-dev libboost-python-dev libprotobuf-dev protobuf-compiler libsparsehash-dev python-nose python3-nose
 
 install:
- # upgrade compilers
- - sudo apt-get install --yes gcc-4.8 g++-4.8
- # make sure 'cpp' is the just installed current one
- - sudo rm /usr/bin/cpp
- - sudo ln -s /usr/bin/cpp-4.8 /usr/bin/cpp
- # innstall dependencies
- - sudo apt-get install --yes make python3-dev python3 libboost-dev libboost-python-dev libprotobuf-dev protobuf-compiler libsparsehash-dev python-nose python3-nose
  - cd ..
  - git clone https://github.com/osmcode/libosmium.git
- # OSMPBF is too old, install from git
- #- sudo apt-get install --yes libosmpbf-dev
  - git clone https://github.com/scrosby/OSM-binary.git
  - cd OSM-binary/src
  - make
  - sudo make install
 
-#before_script:
-# - true
-
 script:
  - cd $TRAVIS_BUILD_DIR
- - if [ "${CXX}" = 'g++' ]; then export CXX=g++-4.8; fi;
- - if [ "${CC}" = 'gcc' ]; then export CC=gcc-4.8; fi;
  - python${USE_PYTHON_VERSION} setup.py build
  - cd test
  - python${USE_PYTHON_VERSION} run_tests.py
diff --git a/README.md b/README.md
index 0a82bad..3e6a983 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,20 @@
 # pyosmium
 
-Provides Python bindings for the [libosmium](https://github.com/osmcode/libosmium) C++
+Provides Python bindings for the [Libosmium](https://github.com/osmcode/libosmium) C++
 library, a library for working with OpenStreetMap data in a fast and flexible
 manner.
 
 [![Build Status](https://secure.travis-ci.org/osmcode/pyosmium.png)](http://travis-ci.org/osmcode/pyosmium)
 
-## Depends
+
+## Dependencies
 
 Python >= 2.7 is supported (that includes python 3.x).
 
 pyosmium uses [Boost.Python](http://www.boost.org/doc/libs/1_56_0/libs/python/doc/index.html)
 to create the bindings. On Debian/Ubuntu install `libboost-python-dev`.
 
+
 ## Installation
 
 To compile the bindings, run
@@ -23,18 +25,20 @@ To compile and install the bindings, run
 
     python setup.py install
 
-libosmium is expected to reside in the same directory as pyosmium or to be
+Libosmium is expected to reside in the same directory as pyosmium or to be
 installed globally.
 
+
 ## Examples
 
 The `example` directory contains small examples on how to use the library.
-They are for most parts ports of the examples in Libosmium and osmium-contrib.
+They are mostly ports of the examples in Libosmium and osmium-contrib.
+
 
 ## Testing
 
 There is a small test suite in the test directory. This provides regression
-test for the python bindings, it is not meant to be a test suite for libosmium.
+test for the python bindings, it is not meant to be a test suite for Libosmium.
 
 You'll need the Python `nose` module. On Debian/Ubuntu install the package
 `python-nose`.
@@ -44,10 +48,23 @@ The suite can be run with:
     cd test
     python run_tests.py
 
+
+## Documentation
+
+To build the documentation you need [Sphinx](http://sphinx-doc.org/).
+On Debian/Ubuntu install `python-sphinx` or `python3-sphinx`.
+
+Then run:
+
+    cd doc
+    make html
+
+
 ## License
 
 Pyosmium is available under the BSD 2-Clause License. See LICENSE.TXT.
 
+
 ## Authors
 
 Sarah Hoffmann (lonvia at denofr.de)
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000..e35d885
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1 @@
+_build
diff --git a/doc/conf.py b/doc/conf.py
index 77ac1ec..883b890 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -63,9 +63,9 @@ copyright = '2015, Sarah Hoffmann'
 # built documents.
 #
 # The short X.Y version.
-version = '2.0'
+version = '2.1'
 # The full version, including alpha/beta/rc tags.
-release = '2.0.0'
+release = '2.1.0'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/doc/index.rst b/doc/index.rst
index e7ac56a..ebb7fb4 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -7,7 +7,8 @@ Welcome to Pyosmium's documentation!
 ====================================
 
 Pyosmium is a library to process OSM files in different formats. It is
-a wrapper of the C++ library osmium and profits from its fast implementation.
+a wrapper of the C++ library `osmium <http://osmcode.org/libosmium/>`_
+and profits from its fast implementation.
 
 .. toctree::
    :maxdepth: 2
diff --git a/doc/intro.rst b/doc/intro.rst
index ee8c1e5..1cdb4b8 100644
--- a/doc/intro.rst
+++ b/doc/intro.rst
@@ -2,5 +2,150 @@ Basic Usage
 ===========
 
 The following chapter gives a practical introduction on how to use Pyosmium.
-For a more detailed introduction into the design of the library, the reader
-is referred to the osmium documentation.
+It is assumed that you already have a basic knowledge about the
+`OSM data model`_.
+
+For a more detailed introduction into the design of the osmium library, the
+reader is referred to the `osmium documentation`_.
+
+.. _OSM data model: http://wiki.openstreetmap.org/wiki/Elements
+.. _osmium documentation: http://osmcode.org/libosmium/manual/libosmium-manual.html
+
+Using Handler Classes
++++++++++++++++++++++
+
+OSM file parsing by osmium is built around the concept of handlers. A handler
+is a class with a set of callback functions. Each function processes exactly
+one type of object as it is read from the file.
+
+Let's start with a very simple handler that counts the nodes in the
+input file::
+
+    import osmium
+
+    class CounterHandler(osmium.SimpleHandler):
+        def __init__(self):
+            osmium.SimpleHandler.__init__(self)
+            self.num_nodes = 0
+
+        def node(self, n):
+            self.num_nodes += 1
+
+A handler first of all needs to inherit from one of the handler classes.
+At the moment this is always :py:class:`osmium.SimpleHandler`. Then it
+needs to implement functions for each object type it wants to process. In
+out case it is exactly one function `node()`. All other potential callbacks
+can be safely ignored.
+
+Now the handler needs to be applied to an OSM file. The easiest way to
+accomplish that is to call the :py:meth:`~osmium.SimpleHandler.apply_file`
+convenience function, which in its simplest form only requires the file name
+as a parameter. The main routine of the node counting application
+therefore looks like this::
+
+    if __name__ == '__main__':
+
+        h = CounterHandler()
+
+        h.apply_file("test.osm.pbf")
+
+        print("Number of nodes: %d" % h.num_nodes)
+
+That already finishes our node counting program.
+
+Inspecting the OSM objects
+++++++++++++++++++++++++++
+
+Counting nodes is actually boring because it completely ignores the
+content of the nodes. So let's change the handler to only count hotels
+(normally tagged with ``tourism=hotel``). They may be tagged as nodes, ways
+or relations, so handler functions for all three types need to be implemented::
+
+    import osmium
+
+    class HotelCounterHandler(osmium.SimpleHandler):
+        def __init__(self):
+            osmium.SimpleHandler.__init__(self)
+            self.num_nodes = 0
+
+        def count_hotel(self, tags):
+            if tags['tourism'] == 'hotel':
+                self.num_nodes += 1
+
+        def node(self, n):
+            self.count_hotel(n.tags)
+
+        def way(self, w):
+            self.count_hotel(w.tags)
+
+        def relation(self, r):
+            self.count_hotel(r.tags)
+
+A reference to the object is always given as the only parameter to the
+handler functions. The objects have some common methods and attributes,
+listed in :py:class:`osmium.osm.OSMObject`, and some that are specific to
+each type. As all objects have tags, it is possible to reuse the same
+implementation for all types. The main function remains the same.
+
+It is important to remember that the object
+references that are handed to the handler are only temporary. They will
+become invalid as soon as the function returns. Handler functions *must*
+copy any data that should be kept for later use into their own data
+structures. This also includes attributes like tag lists.
+
+Handling Geometries
++++++++++++++++++++
+
+Because of the way that OSM data is structured, osmium needs to internally
+cache node geometries, when the handler wants to process the geometries of
+ways and areas. The :py:meth:`~!osmium.SimpleHandler.apply_file` method cannot
+deduct by itself, if this cache is needed. Therefore locations need to be
+explicitly enabled by setting the location parameter to true::
+
+    h.apply_file("test.osm.pbf", locations=True, idx='sparse_mem_array')
+
+The third parameter `idx` is optional and states what kind of cache
+osmium is supposed to use. The default `sparse_mem_array` is a good
+choice for small to medium size extracts of OSM data. If you plan to
+process the whole planet file, `dense_mmap_array` is better suited.
+If you want the cache to be persistent across invocations, you
+can use `dense_file_array` giving an additional file location for the
+cache like that::
+
+    h.apply_file("test.osm.pbf", locations=True, idx='sparse_file_array,example.nodecache')
+
+where `example.nodecache` is the name of the cache file.
+
+Interfacing with Shapely
+++++++++++++++++++++++++
+
+Pyosmium is a library for processing OSM files and therefore offers almost
+no functionality for processing geometries further. For this other libraries
+exist. To interface with these libraries you can simply convert the osmium
+geometries into WKB or WKT format and import the result. The following
+example uses the libgeos wrapper `Shapely`_ to compute the total way length::
+
+    import osmium
+    import shapely.wkb as wkblib
+
+    # A global factory that creates WKB from a osmium geometry
+    wkbfab = osmium.geom.WKBFactory()
+
+    class WayLenHandler(osmium.SimpleHandler):
+        def __init__(self):
+            osmium.SimpleHandler.__init__(self)
+            self.total = 0
+
+        def way(self, w):
+            wkb = wkbfab.create_linestring(w)
+            line = wkblib.loads(wkb, hex=True)
+            # Length is computed in WGS84 projection, which is practically meaningless.
+            # Lets pretend we didn't notice, it is an example after all.
+            self.total += line.length
+
+    if __name__ == '__main__':
+        h = WayLenHandler()
+        h.apply_file("test.osm.pbf", locations=True)
+        print("Total length: %f" % h.total)
+
+.. _Shapely: http://toblerity.org/shapely/index.html
diff --git a/examples/amenity_list.py b/examples/amenity_list.py
index f3bc950..3921cf9 100644
--- a/examples/amenity_list.py
+++ b/examples/amenity_list.py
@@ -1,3 +1,10 @@
+"""
+Extract all objects with an amenity tag from an osm file and list them
+with their name and position.
+
+This example shows how geometries from osmium objects can be imported
+into shapely using the WKBFactory.
+"""
 import osmium as o
 import sys
 import shapely.wkb as wkblib
@@ -22,6 +29,11 @@ class AmenityListHandler(o.SimpleHandler):
             self.print_amenity(a.tags, centroid.x, centroid.y)
 
 
-handler = AmenityListHandler()
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print "Usage: python amenity_list.py <osmfile>"
+        sys.exit(-1)
+
+    handler = AmenityListHandler()
 
-handler.apply_file(sys.argv[1])
+    handler.apply_file(sys.argv[1])
diff --git a/examples/create_nodecache.py b/examples/create_nodecache.py
index 8e9ac55..02bd4e2 100644
--- a/examples/create_nodecache.py
+++ b/examples/create_nodecache.py
@@ -3,7 +3,7 @@ import sys
 
 if len(sys.argv) != 3:
     print("Usage: python create_nodecache.py <osm file> <node cache>")
-    exit()
+    exit(-1)
 
 reader = o.io.Reader(sys.argv[1], o.osm.osm_entity_bits.NODE)
 
diff --git a/examples/osm_file_stats.py b/examples/osm_file_stats.py
index c5dcf09..52ea56c 100644
--- a/examples/osm_file_stats.py
+++ b/examples/osm_file_stats.py
@@ -1,3 +1,8 @@
+"""
+Simple example that counts the number of objects in an osm file.
+
+Shows how to write a handler for the different types of objects.
+"""
 import osmium as o
 import sys
 
@@ -18,9 +23,15 @@ class FileStatsHandler(o.SimpleHandler):
         self.rels += 1
 
 
-h = FileStatsHandler()
-h.apply_file(sys.argv[1])
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print "Usage: python osm_file_stats.py <osmfile>"
+        sys.exit(-1)
+
+    h = FileStatsHandler()
+
+    h.apply_file(sys.argv[1])
 
-print("Nodes: %d" % h.nodes)
-print("Ways: %d" % h.ways)
-print("Relations: %d" % h.rels)
+    print("Nodes: %d" % h.nodes)
+    print("Ways: %d" % h.ways)
+    print("Relations: %d" % h.rels)
diff --git a/examples/pub_names.py b/examples/pub_names.py
index 69d4f9d..b71c050 100644
--- a/examples/pub_names.py
+++ b/examples/pub_names.py
@@ -1,3 +1,6 @@
+"""
+Search for pubs in an osm file and list their names.
+"""
 import osmium
 import sys
 
@@ -14,6 +17,11 @@ class NamesHandler(osmium.SimpleHandler):
     def way(self, w):
         self.output_pubs(w.tags)
 
-h = NamesHandler()
-h.apply_file(sys.argv[1])
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print "Usage: python pub_names.py <osmfile>"
+        sys.exit(-1)
+
+    h = NamesHandler()
+    h.apply_file(sys.argv[1])
 
diff --git a/examples/road_length.py b/examples/road_length.py
index 915336d..b36cc3e 100644
--- a/examples/road_length.py
+++ b/examples/road_length.py
@@ -1,3 +1,8 @@
+"""
+Compute the total length of highways in an osm file.
+
+Shows how extract the geometry of a way.
+"""
 import osmium as o
 import sys
 
@@ -11,9 +16,18 @@ class RoadLengthHandler(o.SimpleHandler):
             try:
                 self.length += o.geom.haversine_distance(w.nodes)
             except o.InvalidLocationError:
+                # A location error might occur if the osm file is an extract
+                # where nodes of ways near the boundary are missing.
                 print("WARNING: way %d incomplete. Ignoring." % w.id)
 
-h = RoadLengthHandler()
-h.apply_file(sys.argv[1], locations=True)
+if __name__ == '__main__':
+    if len(sys.argv) != 2:
+        print "Usage: python road_length.py <osmfile>"
+        sys.exit(-1)
+
+    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)
 
-print('Total way length: %.2f km' % (h.length/1000))
+    print('Total way length: %.2f km' % (h.length/1000))
diff --git a/lib/geom.cc b/lib/geom.cc
index 9a0ba99..a650c39 100644
--- a/lib/geom.cc
+++ b/lib/geom.cc
@@ -17,6 +17,16 @@ BOOST_PYTHON_MODULE(_geom)
     using namespace boost::python;
     docstring_options doc_options(true, true, false);
 
+    enum_<osmium::geom::use_nodes>("use_nodes")
+        .value("UNIQUE", osmium::geom::use_nodes::unique)
+        .value("ALL", osmium::geom::use_nodes::all)
+    ;
+
+    enum_<osmium::geom::direction>("direction")
+        .value("BACKWARD", osmium::geom::direction::backward)
+        .value("FORWARD", osmium::geom::direction::forward)
+    ;
+
     def("haversine_distance", static_cast<double (*)(const osmium::WayNodeList&)>(&osmium::geom::haversine::distance),
         arg("list"),
         "Compute the distance using the Haversine algorithm which takes the "
@@ -39,10 +49,14 @@ BOOST_PYTHON_MODULE(_geom)
              (arg("self"), arg("ref")),
              "Create a point geometry from a :py:class:`osmium.osm.NodeRef`.")
         .def("create_linestring", static_cast<std::string (WKBFactory::*)(const osmium::WayNodeList&, osmium::geom::use_nodes, osmium::geom::direction)>(&WKBFactory::create_linestring),
-             (arg("self"), arg("list"), arg("use_nodes")="unique", arg("direction")="forward" ),
+             (arg("self"), arg("list"),
+              arg("use_nodes")=osmium::geom::use_nodes::unique,
+              arg("direction")=osmium::geom::direction::forward),
              "Create a LineString geometry from a :py:class:`osmium.osm.WayNodeList`.")
         .def("create_linestring", static_cast<std::string (WKBFactory::*)(const osmium::Way&, osmium::geom::use_nodes, osmium::geom::direction)>(&WKBFactory::create_linestring),
-             (arg("self"), arg("way"), arg("use_nodes")="unique", arg("direction")="forward" ),
+             (arg("self"), arg("way"),
+              arg("use_nodes")=osmium::geom::use_nodes::unique,
+              arg("direction")=osmium::geom::direction::forward),
              "Create a LineString geometry from a :py:class:`osmium.osm.Way`.")
         .def("create_multipolygon", &WKBFactory::create_multipolygon,
              (arg("self"), arg("area")),
diff --git a/lib/osm.cc b/lib/osm.cc
index 85d39eb..c39e08c 100644
--- a/lib/osm.cc
+++ b/lib/osm.cc
@@ -78,7 +78,39 @@ BOOST_PYTHON_MODULE(_osm)
                       "that it is within the usual bounds.")
     ;
     class_<osmium::Box>("Box",
-                        "A bounding box around a geographic area.")
+        "A bounding box around a geographic area. Such a box consists of two "
+        ":py:class:`osmium.osm.Location`s. Those locations may be invalid in "
+        "which case the box is considered invalid, too.")
+        .def(init<double, double, double, double>())
+        .def(init<osmium::Location, osmium::Location>())
+        .add_property("bottom_left",
+                      make_function(static_cast<osmium::Location& (osmium::Box::*)()>(&osmium::Box::bottom_left),
+                                    return_value_policy<reference_existing_object>()),
+             "(read-only) Bottom-left corner of the bounding box.")
+        .add_property("top_right",
+                      make_function(static_cast<osmium::Location& (osmium::Box::*)()>(&osmium::Box::top_right),
+                                    return_value_policy<reference_existing_object>()),
+             "(read-only) Top-right corner of the bounding box.")
+        .def("extend",
+              make_function(static_cast<osmium::Box& (osmium::Box::*)(const osmium::Location&)>(&osmium::Box::extend),
+                            return_value_policy<reference_existing_object>()),
+             //(arg("self"), arg("location")),
+             "Extend the box to include the given location. If the location "
+             "is invalid the box remains unchanged. If the box is invalid, it "
+             "will contain only the location after the operation.")
+        .def("extend",
+              make_function(static_cast<osmium::Box& (osmium::Box::*)(const osmium::Box&)>(&osmium::Box::extend),
+                            return_value_policy<reference_existing_object>()),
+             //(arg("self"), arg("box")),
+             "Extend the box to include the given box. If the box to be added "
+             "is invalid the input box remains unchanged. If the input box is invalid, it "
+             "will become equal to the box that was added.")
+        .def("valid", &osmium::Box::valid, args("self"),
+             "Check if the box coordinates are defined and with the usual bounds.")
+        .def("size", &osmium::Box::size, args("self"),
+             "Return the size in square degrees.")
+        .def("contains", &osmium::Box::contains, (arg("self"), arg("location")),
+             "Check if the given location is inside the box.")
     ;
     class_<osmium::Tag, boost::noncopyable>("Tag",
             "A single OSM tag.",
diff --git a/test/test_helper.py b/test/helpers.py
similarity index 100%
rename from test/test_helper.py
rename to test/helpers.py
diff --git a/test/test_geom.py b/test/test_geom.py
new file mode 100644
index 0000000..74bdd84
--- /dev/null
+++ b/test/test_geom.py
@@ -0,0 +1,40 @@
+from nose.tools import *
+import unittest
+
+from helpers import create_osm_file, osmobj, HandlerTestBase
+import osmium as o
+
+wkbfab = o.geom.WKBFactory()
+
+class TestWkbCreateNode(HandlerTestBase, unittest.TestCase):
+    data = [osmobj('N', id=1)]
+
+    class Handler(o.SimpleHandler):
+        def node(self, n):
+            wkb = wkbfab.create_point(n)
+
+class TestWkbCreateWay(HandlerTestBase, unittest.TestCase):
+    data = [osmobj('N', id=1, lat=0, lon=0),
+            osmobj('N', id=2, lat=0, lon=1),
+            osmobj('N', id=3, lat=1, lon=0),
+            osmobj('W', id=1, nodes = [1,2,3])]
+    apply_locations = True
+
+    class Handler(o.SimpleHandler):
+        def way(self, w):
+            wkb = wkbfab.create_linestring(w)
+            wkb = wkbfab.create_linestring(w, direction=o.geom.direction.BACKWARD)
+            wkb = wkbfab.create_linestring(w, use_nodes=o.geom.use_nodes.ALL)
+
+class TestWkbCreatePoly(HandlerTestBase, unittest.TestCase):
+    data = [osmobj('N', id=1, lat=0, lon=0),
+            osmobj('N', id=2, lat=0, lon=1),
+            osmobj('N', id=3, lat=1, lon=0),
+            osmobj('W', id=23,
+                   nodes = [1,2,3,1], tags = { "area" : "yes" }),
+           ]
+    apply_locations = True
+
+    class Handler(o.SimpleHandler):
+        def area(self, a):
+            wkb = wkbfab.create_multipolygon(a)
diff --git a/test/test_io.py b/test/test_io.py
index a36e371..91db118 100644
--- a/test/test_io.py
+++ b/test/test_io.py
@@ -2,7 +2,7 @@ from nose.tools import *
 import unittest
 import os
 
-from test_helper import create_osm_file, osmobj
+from helpers import create_osm_file, osmobj
 
 import osmium as o
 
diff --git a/test/test_osm.py b/test/test_osm.py
index 79fcf96..b8fc14c 100644
--- a/test/test_osm.py
+++ b/test/test_osm.py
@@ -3,7 +3,7 @@ import unittest
 import os
 from datetime import datetime
 
-from test_helper import create_osm_file, osmobj, HandlerTestBase
+from helpers import create_osm_file, osmobj, HandlerTestBase
 
 import osmium as o
 
@@ -144,4 +144,7 @@ class TestChangesetAttributes(HandlerTestBase, unittest.TestCase):
             assert_false(c.open)
             assert_equals(2, c.num_changes)
             assert_equals(0, len(c.tags))
-
+            assert_equals(-1464925, c.bounds.top_right.x)
+            assert_equals(515288620, c.bounds.top_right.y)
+            assert_equals(-1465242, c.bounds.bottom_left.x)
+            assert_equals(515288506, c.bounds.bottom_left.y)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/pyosmium.git



More information about the Pkg-grass-devel mailing list