[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