overpy-0.4/0000755000175000017500000000000013022347701013124 5ustar phibophibo00000000000000overpy-0.4/PKG-INFO0000644000175000017500000000766613022347701014240 0ustar phibophibo00000000000000Metadata-Version: 1.1 Name: overpy Version: 0.4 Summary: Python Wrapper to access the OpenStreepMap Overpass API Home-page: https://github.com/DinoTools/python-overpy Author: PhiBo (DinoTools) Author-email: UNKNOWN License: MIT Description: Python Overpass Wrapper ======================= A Python Wrapper to access the Overpass API. Have a look at the `documentation`_ to find additional information. .. image:: https://pypip.in/version/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: Latest Version .. image:: https://pypip.in/license/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-overpy.svg?branch=master :target: https://travis-ci.org/DinoTools/python-overpy .. image:: https://coveralls.io/repos/DinoTools/python-overpy/badge.png?branch=master :target: https://coveralls.io/r/DinoTools/python-overpy?branch=master Features -------- * Query Overpass API * Parse JSON and XML response data * Additional helper functions Install ------- **Requirements:** Supported Python versions: * Python 2.7 * Python >= 3.2 * PyPy and PyPy3 **Install:** .. code-block:: console $ pip install overpy Examples -------- Additional examples can be found in the `documentation`_ and in the *examples* directory. .. code-block:: python import overpy api = overpy.Overpass() # fetch all ways and nodes result = api.query(""" way(50.746,7.154,50.748,7.157) ["highway"]; (._;>;); out body; """) for way in result.ways: print("Name: %s" % way.tags.get("name", "n/a")) print(" Highway: %s" % way.tags.get("highway", "n/a")) print(" Nodes:") for node in way.nodes: print(" Lat: %f, Lon: %f" % (node.lat, node.lon)) Helper ~~~~~~ Helper methods are available to provide easy access to often used requests. .. code-block:: python import overpy.helper # 3600062594 is the OSM id of Chemnitz and is the bounding box for the request street = overpy.helper.get_street( "Straße der Nationen", "3600062594" ) # this finds an intersection between Straße der Nationen and Carolastraße in Chemnitz intersection = overpy.helper.get_intersection( "Straße der Nationen", "Carolastraße", "3600062594" ) License ------- Published under the MIT (see LICENSE for more information) .. _`documentation`: http://python-overpy.readthedocs.org/ Keywords: OverPy Overpass OSM OpenStreetMap Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy overpy-0.4/setup.py0000644000175000017500000000316213022347635014646 0ustar phibophibo00000000000000#!/usr/bin/env python import os import sys from setuptools import setup, find_packages base_dir = os.path.dirname(__file__) about = {} with open(os.path.join(base_dir, "overpy", "__about__.py")) as f: exec(f.read(), about) filename_readme = os.path.join(base_dir, "README.rst") if sys.version_info[0] == 2: import io fp = io.open(filename_readme, encoding="utf-8") else: fp = open(filename_readme, encoding="utf-8") long_description = fp.read() setup( name=about["__title__"], version=about["__version__"], description=about["__summary__"], long_description=long_description, license=about["__license__"], url=about["__uri__"], zip_safe=False, author=about["__author__"], classifiers=[ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], keywords="OverPy Overpass OSM OpenStreetMap", install_requires=[], packages=find_packages(exclude=["*.tests", "*.tests.*"]), include_package_data=True, package_data={ #"": ["README"], }, setup_requires=["pytest-runner"], tests_require=["pytest"], ) overpy-0.4/setup.cfg0000644000175000017500000000024013022347701014741 0ustar phibophibo00000000000000[metadata] license-file = LICENSE [aliases] test = pytest [tool:pytest] python_files = tests/*.py [egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 overpy-0.4/README.rst0000644000175000017500000000436713022347635014633 0ustar phibophibo00000000000000Python Overpass Wrapper ======================= A Python Wrapper to access the Overpass API. Have a look at the `documentation`_ to find additional information. .. image:: https://pypip.in/version/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: Latest Version .. image:: https://pypip.in/license/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-overpy.svg?branch=master :target: https://travis-ci.org/DinoTools/python-overpy .. image:: https://coveralls.io/repos/DinoTools/python-overpy/badge.png?branch=master :target: https://coveralls.io/r/DinoTools/python-overpy?branch=master Features -------- * Query Overpass API * Parse JSON and XML response data * Additional helper functions Install ------- **Requirements:** Supported Python versions: * Python 2.7 * Python >= 3.2 * PyPy and PyPy3 **Install:** .. code-block:: console $ pip install overpy Examples -------- Additional examples can be found in the `documentation`_ and in the *examples* directory. .. code-block:: python import overpy api = overpy.Overpass() # fetch all ways and nodes result = api.query(""" way(50.746,7.154,50.748,7.157) ["highway"]; (._;>;); out body; """) for way in result.ways: print("Name: %s" % way.tags.get("name", "n/a")) print(" Highway: %s" % way.tags.get("highway", "n/a")) print(" Nodes:") for node in way.nodes: print(" Lat: %f, Lon: %f" % (node.lat, node.lon)) Helper ~~~~~~ Helper methods are available to provide easy access to often used requests. .. code-block:: python import overpy.helper # 3600062594 is the OSM id of Chemnitz and is the bounding box for the request street = overpy.helper.get_street( "Straße der Nationen", "3600062594" ) # this finds an intersection between Straße der Nationen and Carolastraße in Chemnitz intersection = overpy.helper.get_intersection( "Straße der Nationen", "Carolastraße", "3600062594" ) License ------- Published under the MIT (see LICENSE for more information) .. _`documentation`: http://python-overpy.readthedocs.org/ overpy-0.4/MANIFEST.in0000644000175000017500000000043013022347635014665 0ustar phibophibo00000000000000include README.rst CHANGELOG.rst include LICENSE include MANIFEST.in include docs/make.bat docs.Makefile include docs/source/conf.py include docs/source/*.rst include examples/*.py include tests/*.py include tests/json/*.json include tests/response/*.html include tests/xml/*.xml overpy-0.4/LICENSE0000644000175000017500000000207513022347635014143 0ustar phibophibo00000000000000The MIT License (MIT) Copyright (c) 2014 PhiBo (DinoTools) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. overpy-0.4/CHANGELOG.rst0000644000175000017500000000177513022347635015165 0ustar phibophibo00000000000000Changelog ========= 0.x (`master`_) ~~~~~~~~~~~~~~~ .. note:: This version is not yet released and is under development. 0.4 (2016-12-08) ~~~~~~~~~~~~~~~~ * Add SAX parser * Add option to choose DOM or SAX parser * Fix issues with CI builds with Python 3.2 * Add Python 3.5 to CI builds * Fix issues (Thanks to all contributors) * Add property for default API URL * Add examples * Build Fixes * GitHub templates * Parse center information * Parse geometry information * Support Areas 0.3.1 (2015-04-30) ~~~~~~~~~~~~~~~~~~ * Improve example 0.3.0 (2015-04-30) ~~~~~~~~~~~~~~~~~~ * Improve internal data handling (Dominik) * Add helper functions (Morris Jobke) 0.2.0 (2014-12-27) ~~~~~~~~~~~~~~~~~~ * Added support for xml response data * Added support for exceptions * Added tests with 100% code coverage * Removed Python 2.6 support * Added more examples to the documentation 0.1.0 (2014-12-14) ~~~~~~~~~~~~~~~~~~ Proof of concept * Initial release. .. _`master`: https://github.com/DinoTools/python-overpy overpy-0.4/tests/0000755000175000017500000000000013022347701014266 5ustar phibophibo00000000000000overpy-0.4/tests/test_xml.py0000644000175000017500000001334613022347635016514 0ustar phibophibo00000000000000import pytest import overpy from tests.base_class import BaseTestAreas, BaseTestNodes, BaseTestRelation, BaseTestWay from tests.base_class import read_file class TestAreas(BaseTestAreas): def test_node01(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/area-01.xml"), parser=overpy.XML_PARSER_DOM) self._test_area01(result) # SAX result = api.parse_xml(read_file("xml/area-01.xml"), parser=overpy.XML_PARSER_SAX) self._test_area01(result) class TestNodes(BaseTestNodes): def test_node01(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/node-01.xml"), parser=overpy.XML_PARSER_DOM) self._test_node01(result) # SAX result = api.parse_xml(read_file("xml/node-01.xml"), parser=overpy.XML_PARSER_SAX) self._test_node01(result) class TestRelation(BaseTestRelation): def test_relation01(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/relation-01.xml"), parser=overpy.XML_PARSER_DOM) self._test_relation01(result) # SAX result = api.parse_xml(read_file("xml/relation-01.xml"), parser=overpy.XML_PARSER_SAX) self._test_relation01(result) def test_relation02(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/relation-02.xml"), parser=overpy.XML_PARSER_DOM) self._test_relation02(result) # SAX result = api.parse_xml(read_file("xml/relation-02.xml"), parser=overpy.XML_PARSER_SAX) self._test_relation02(result) def test_relation03(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/relation-03.xml"), parser=overpy.XML_PARSER_DOM) self._test_relation03(result) # SAX result = api.parse_xml(read_file("xml/relation-03.xml"), parser=overpy.XML_PARSER_SAX) self._test_relation03(result) def test_relation04(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/relation-04.xml"), parser=overpy.XML_PARSER_DOM) self._test_relation04(result) # SAX result = api.parse_xml(read_file("xml/relation-04.xml"), parser=overpy.XML_PARSER_SAX) self._test_relation04(result) class TestWay(BaseTestWay): def test_way01(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/way-01.xml"), parser=overpy.XML_PARSER_DOM) self._test_way01(result) # SAX result = api.parse_xml(read_file("xml/way-01.xml"), parser=overpy.XML_PARSER_SAX) self._test_way01(result) def test_way02(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/way-02.xml"), parser=overpy.XML_PARSER_DOM) self._test_way02(result) # SAX result = api.parse_xml(read_file("xml/way-02.xml"), parser=overpy.XML_PARSER_SAX) self._test_way02(result) def test_way03(self): api = overpy.Overpass() # DOM result = api.parse_xml(read_file("xml/way-03.xml"), parser=overpy.XML_PARSER_DOM) self._test_way03(result) # SAX result = api.parse_xml(read_file("xml/way-03.xml"), parser=overpy.XML_PARSER_SAX) self._test_way03(result) def test_way04(self): api = overpy.Overpass() # DOM with pytest.raises(ValueError): api.parse_xml(read_file("xml/way-04.xml"), parser=overpy.XML_PARSER_DOM) # SAX with pytest.raises(ValueError): api.parse_xml(read_file("xml/way-04.xml"), parser=overpy.XML_PARSER_SAX) class TestDataError(object): def _get_element_wrong_type(self): data = "" import xml.etree.ElementTree as ET return ET.fromstring(data) def test_element_wrong_type(self): with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Node.from_xml( self._get_element_wrong_type() ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Relation.from_xml( self._get_element_wrong_type() ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.RelationNode.from_xml( self._get_element_wrong_type() ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.RelationWay.from_xml( self._get_element_wrong_type() ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Way.from_xml( self._get_element_wrong_type() ) def test_node_missing_data(self): import xml.etree.ElementTree as ET # Tag without k attribute data = """""" node = ET.fromstring(data) with pytest.raises(ValueError): overpy.Node.from_xml(node) def test_relation_missing_data(self): import xml.etree.ElementTree as ET # Tag without k attribute data = """""" node = ET.fromstring(data) with pytest.raises(ValueError): overpy.Relation.from_xml(node) def test_way_missing_data(self): import xml.etree.ElementTree as ET # Node without ref attribute data = """""" node = ET.fromstring(data) with pytest.raises(ValueError): overpy.Way.from_xml(node) # Tag without k attribute data = """""" node = ET.fromstring(data) with pytest.raises(ValueError): overpy.Way.from_xml(node) overpy-0.4/tests/test_result_way.py0000644000175000017500000000547313022347635020114 0ustar phibophibo00000000000000import pytest import overpy from tests import read_file, new_server_thread, BaseRequestHandler class HandleResponseJSON01(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/json\r\n") self.request.send(b"\r\n") self.request.send(read_file("json/result-way-01.json", "rb")) class HandleResponseJSON02(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/json\r\n") self.request.send(b"\r\n") self.request.send(read_file("json/result-way-02.json", "rb")) class HandleResponseJSON03(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/json\r\n") self.request.send(b"\r\n") self.request.send(read_file("json/result-way-03.json", "rb")) class TestNodes(object): def test_missing_unresolvable(self): url, t = new_server_thread(HandleResponseJSON01) api = overpy.Overpass() api.url = url result = api.parse_json(read_file("json/result-way-01.json")) assert len(result.nodes) == 0 assert len(result.ways) == 1 way = result.ways[0] assert isinstance(way, overpy.Way) with pytest.raises(overpy.exception.DataIncomplete): way.get_nodes() with pytest.raises(overpy.exception.DataIncomplete): way.get_nodes(resolve_missing=True) assert len(result.nodes) == 0 t.join() def test_missing_partly_unresolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result = api.parse_json(read_file("json/result-way-01.json")) assert len(result.nodes) == 0 assert len(result.ways) == 1 way = result.ways[0] assert isinstance(way, overpy.Way) with pytest.raises(overpy.exception.DataIncomplete): way.get_nodes() with pytest.raises(overpy.exception.DataIncomplete): way.get_nodes(resolve_missing=True) assert len(result.nodes) == 1 t.join() def test_missing_resolvable(self): url, t = new_server_thread(HandleResponseJSON03) api = overpy.Overpass() api.url = url result = api.parse_json(read_file("json/result-way-01.json")) assert len(result.nodes) == 0 assert len(result.ways) == 1 way = result.ways[0] assert isinstance(way, overpy.Way) with pytest.raises(overpy.exception.DataIncomplete): way.get_nodes() nodes = way.get_nodes(resolve_missing=True) assert len(nodes) == 2 t.join()overpy-0.4/tests/test_result.py0000644000175000017500000001203713022347635017226 0ustar phibophibo00000000000000import pytest import overpy from tests import read_file, new_server_thread, BaseRequestHandler class HandleResponseJSON02(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/json\r\n") self.request.send(b"\r\n") self.request.send(read_file("json/result-expand-02.json", "rb")) class TestResult(object): def test_expand_error(self): api = overpy.Overpass() result = api.parse_json(read_file("json/result-expand-01.json")) with pytest.raises(ValueError): result.expand(123) with pytest.raises(ValueError): result.expand(1.23) with pytest.raises(ValueError): result.expand("abc") def test_expand_01(self): api = overpy.Overpass() result1 = api.parse_json(read_file("json/result-expand-01.json")) assert len(result1.nodes) == 2 assert len(result1.ways) == 1 result2 = api.parse_json(read_file("json/result-expand-02.json")) assert len(result2.nodes) == 2 assert len(result2.ways) == 1 result1.expand(result2) # Don't overwrite existing elements assert len(result1.nodes) == 3 assert len(result1.ways) == 2 class TestArea(object): def test_missing_unresolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) with pytest.raises(overpy.exception.DataIncomplete): result1.get_area(123, resolve_missing=True) t.join() def test_missing_resolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) # Node must not be available with pytest.raises(overpy.exception.DataIncomplete): result1.get_area(3605945176) # Node must be available area = result1.get_area(3605945176, resolve_missing=True) assert isinstance(area, overpy.Area) assert area.id == 3605945176 t.join() class TestNode(object): def test_missing_unresolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) with pytest.raises(overpy.exception.DataIncomplete): result1.get_node(123, resolve_missing=True) t.join() def test_missing_resolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) # Node must not be available with pytest.raises(overpy.exception.DataIncomplete): result1.get_node(3233854235) # Node must be available node = result1.get_node(3233854235, resolve_missing=True) assert isinstance(node, overpy.Node) assert node.id == 3233854235 t.join() class TestRelation(object): def test_missing_unresolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) with pytest.raises(overpy.exception.DataIncomplete): result1.get_relation(123, resolve_missing=True) t.join() def test_missing_resolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) # Relation must not be available with pytest.raises(overpy.exception.DataIncomplete): result1.get_relation(2046898) # Relation must be available relation = result1.get_relation(2046898, resolve_missing=True) assert isinstance(relation, overpy.Relation) assert relation.id == 2046898 t.join() class TestWay(object): def test_missing_unresolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) with pytest.raises(overpy.exception.DataIncomplete): result1.get_way(123, resolve_missing=True) t.join() def test_missing_resolvable(self): url, t = new_server_thread(HandleResponseJSON02) api = overpy.Overpass() api.url = url result1 = api.parse_json(read_file("json/result-expand-01.json")) # Way must not be available with pytest.raises(overpy.exception.DataIncomplete): result1.get_way(317146078) # Way must be available way = result1.get_way(317146078, resolve_missing=True) assert isinstance(way, overpy.Way) assert way.id == 317146078 t.join() overpy-0.4/tests/test_request.py0000644000175000017500000001344513022347635017404 0ustar phibophibo00000000000000import pytest import overpy from tests import BaseRequestHandler from tests import read_file, new_server_thread class HandleOverpassBadRequest(BaseRequestHandler): """ Simulate the response if the query string has syntax errors """ def handle(self): self.request.send(b"HTTP/1.0 400 Bad Request\r\n") self.request.send(b"Content-Type text/html; charset=utf-8\r\n") self.request.send(b"\r\n") self.request.send(read_file("response/bad-request.html", "rb")) class HandleOverpassBadRequestEncoding(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 400 Bad Request\r\n") self.request.send(b"Content-Type text/html; charset=utf-8\r\n") self.request.send(b"\r\n") self.request.send(read_file("response/bad-request-encoding.html", "rb")) class HandleOverpassTooManyRequests(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 429 Too Many Requests\r\n") self.request.send(b"Content-Type text/html; charset=utf-8\r\n") self.request.send(b"\r\n") self.request.send(b"Too Many Requests") class HandleOverpassGatewayTimeout(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 504 Gateway Timeout\r\n") self.request.send(b"Content-Type text/html; charset=utf-8\r\n") self.request.send(b"\r\n") self.request.send(b"Gateway Timeout") class HandleOverpassUnknownHTTPStatusCode(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 123 Unknown\r\n") self.request.send(b"Content-Type text/html; charset=utf-8\r\n") self.request.send(b"\r\n") self.request.send(b"Unknown status code") class HandleResponseJSON(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/json\r\n") self.request.send(b"\r\n") self.request.send(read_file("json/way-02.json", "rb")) class HandleResponseXML(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/osm3s+xml\r\n") self.request.send(b"\r\n") self.request.send(read_file("xml/way-02.xml", "rb")) class HandleResponseUnknown(BaseRequestHandler): """ """ def handle(self): self.request.send(b"HTTP/1.0 200 OK\r\n") self.request.send(b"Content-Type: application/foobar\r\n") self.request.send(b"\r\n") self.request.send(read_file("xml/way-02.xml", "rb")) class TestQuery(object): def test_chunk_size(self): url, t = new_server_thread(HandleResponseJSON) api = overpy.Overpass(read_chunk_size=128) api.url = url result = api.query("[out:json];node(50.745,7.17,50.75,7.18);out;") t.join() assert len(result.nodes) > 0 def test_overpass_syntax_error(self): url, t = new_server_thread(HandleOverpassBadRequest) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassBadRequest): # Missing ; after way(1) api.query(( "way(1)" "out body;" )) t.join() def test_overpass_syntax_error_encoding_error(self): with pytest.raises(UnicodeDecodeError): # File should be encoded with iso8859-15 and will raise an exception tmp = read_file("response/bad-request-encoding.html", "rb") tmp.decode("utf-8") url, t = new_server_thread(HandleOverpassBadRequestEncoding) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassBadRequest): # Missing ; after way(1) api.query(( "way(1)" "out body;" )) t.join() def test_overpass_too_many_requests(self): url, t = new_server_thread(HandleOverpassTooManyRequests) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassTooManyRequests): api.query(( "way(1);" "out body;" )) t.join() def test_overpass_gateway_timeout(self): url, t = new_server_thread(HandleOverpassGatewayTimeout) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassGatewayTimeout): api.query(( "way(1);" "out body;" )) t.join() def test_overpass_unknown_status_code(self): url, t = new_server_thread(HandleOverpassUnknownHTTPStatusCode) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassUnknownHTTPStatusCode): api.query(( "way(1);" "out body;" )) t.join() def test_response_json(self): url, t = new_server_thread(HandleResponseJSON) api = overpy.Overpass() api.url = url result = api.query("[out:json];node(50.745,7.17,50.75,7.18);out;") t.join() assert len(result.nodes) > 0 def test_response_unknown(self): url, t = new_server_thread(HandleResponseUnknown) api = overpy.Overpass() api.url = url with pytest.raises(overpy.exception.OverpassUnknownContentType): api.query("[out:xml];node(50.745,7.17,50.75,7.18);out;") t.join() def test_response_xml(self): url, t = new_server_thread(HandleResponseXML) api = overpy.Overpass() api.url = url result = api.query("[out:xml];node(50.745,7.17,50.75,7.18);out;") t.join() assert len(result.nodes) > 0overpy-0.4/tests/test_json.py0000644000175000017500000000556213022347635016666 0ustar phibophibo00000000000000import pytest import overpy from tests.base_class import BaseTestAreas, BaseTestNodes, BaseTestRelation, BaseTestWay from tests.base_class import read_file class TestAreas(BaseTestAreas): def test_area01(self): api = overpy.Overpass() result = api.parse_json(read_file("json/area-01.json")) self._test_area01(result) class TestNodes(BaseTestNodes): def test_node01(self): api = overpy.Overpass() result = api.parse_json(read_file("json/node-01.json")) self._test_node01(result) class TestRelation(BaseTestRelation): def test_relation01(self): api = overpy.Overpass() result = api.parse_json(read_file("json/relation-01.json")) self._test_relation01(result) def test_relation02(self): api = overpy.Overpass() result = api.parse_json(read_file("json/relation-02.json")) self._test_relation02(result) def test_relation03(self): api = overpy.Overpass() result = api.parse_json(read_file("json/relation-03.json")) self._test_relation03(result) def test_relation04(self): api = overpy.Overpass() result = api.parse_json(read_file("json/relation-04.json")) self._test_relation04(result) class TestWay(BaseTestWay): def test_way01(self): api = overpy.Overpass() result = api.parse_json(read_file("json/way-01.json")) self._test_way01(result) def test_way02(self): api = overpy.Overpass() result = api.parse_json(read_file("json/way-02.json")) self._test_way02(result) def test_way03(self): api = overpy.Overpass() result = api.parse_json(read_file("json/way-03.json")) self._test_way03(result) def test_way04(self): api = overpy.Overpass() with pytest.raises(ValueError): api.parse_json(read_file("json/way-04.json")) class TestDataError(object): def test_element_wrong_type(self): with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Node.from_json( { "type": "foo" } ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Relation.from_json( { "type": "foo" } ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.RelationNode.from_json( { "type": "foo" } ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.RelationWay.from_json( { "type": "foo" } ) with pytest.raises(overpy.exception.ElementDataWrongType): overpy.Way.from_json( { "type": "foo" } )overpy-0.4/tests/test_exception.py0000644000175000017500000000274613022347635017714 0ustar phibophibo00000000000000import overpy class TestExceptions(object): def test_element_data_wrong_type(self): e = overpy.exception.ElementDataWrongType("from1") assert e.type_expected == "from1" assert e.type_provided == None assert isinstance(str(e), str) e = overpy.exception.ElementDataWrongType("from2", "to2") assert e.type_expected == "from2" assert e.type_provided == "to2" assert isinstance(str(e), str) def test_overpass_bad_request(self): e = overpy.exception.OverpassBadRequest("query") assert e.query == "query" assert isinstance(e.msgs, list) assert len(e.msgs) == 0 assert str(e) == "" e = overpy.exception.OverpassBadRequest("test\nquery\n123", ["abc", 1]) assert e.query == "test\nquery\n123" assert isinstance(e.msgs, list) assert len(e.msgs) == 2 assert str(e) == "abc\n1" def test_overpass_unknown_content_type(self): e = overpy.exception.OverpassUnknownContentType(None) assert e.content_type == None assert str(e).startswith("No content") e = overpy.exception.OverpassUnknownContentType("content") assert e.content_type == "content" assert str(e).startswith("Unknown content") assert str(e).endswith("content") def test_overpass_unknown_http_status_code(self): e = overpy.exception.OverpassUnknownHTTPStatusCode(123) assert e.code == 123 assert str(e).endswith("123")overpy-0.4/tests/base_class.py0000644000175000017500000003664113022347635016757 0ustar phibophibo00000000000000from decimal import Decimal from datetime import datetime import os import pytest import overpy from tests import read_file class BaseTestAreas(object): def _test_area01(self, result): assert len(result.areas) == 4 assert len(result.nodes) == 0 assert len(result.relations) == 0 assert len(result.ways) == 0 area = result.areas[0] assert isinstance(area, overpy.Area) assert isinstance(area.id, int) assert area.id == 2448756446 assert isinstance(area.tags, dict) assert len(area.tags) == 12 area = result.areas[1] assert isinstance(area, overpy.Area) assert isinstance(area.id, int) assert area.id == 3600055060 assert isinstance(area.tags, dict) assert len(area.tags) == 13 area = result.areas[2] assert isinstance(area, overpy.Area) assert isinstance(area.id, int) assert area.id == 3605945175 assert isinstance(area.tags, dict) assert len(area.tags) == 12 area = result.areas[3] assert isinstance(area, overpy.Area) assert isinstance(area.id, int) assert area.id == 3605945176 assert isinstance(area.tags, dict) assert len(area.tags) == 14 # try to get a single area by id area = result.get_area(3605945175) assert area.id == 3605945175 # try to get a single area by id not available in the result with pytest.raises(overpy.exception.DataIncomplete): result.get_area(123456) # area_ids is an alias for get_node_ids() and should return the same data for area_ids in (result.area_ids, result.get_area_ids()): assert len(area_ids) == 4 assert area_ids[0] == 2448756446 assert area_ids[1] == 3600055060 assert area_ids[2] == 3605945175 assert area_ids[3] == 3605945176 assert len(result.node_ids) == 0 assert len(result.get_node_ids()) == 0 assert len(result.relation_ids) == 0 assert len(result.get_relation_ids()) == 0 assert len(result.way_ids) == 0 assert len(result.get_way_ids()) == 0 class BaseTestNodes(object): def _test_node01(self, result): assert len(result.nodes) == 3 assert len(result.relations) == 0 assert len(result.ways) == 0 node = result.nodes[0] assert isinstance(node, overpy.Node) assert isinstance(node.id, int) assert isinstance(node.lat, Decimal) assert isinstance(node.lon, Decimal) assert node.id == 50878400 assert node.lat == Decimal("50.7461788") assert node.lon == Decimal("7.1742257") assert isinstance(node.tags, dict) assert len(node.tags) == 0 node = result.nodes[1] assert isinstance(node, overpy.Node) assert isinstance(node.id, int) assert isinstance(node.lat, Decimal) assert isinstance(node.lon, Decimal) assert node.id == 100793192 assert node.lat == Decimal("50.7468472") assert node.lon == Decimal("7.1709376") assert isinstance(node.tags, dict) assert len(node.tags) == 1 assert node.tags["highway"] == "turning_circle" node = result.nodes[2] assert isinstance(node, overpy.Node) assert isinstance(node.id, int) assert isinstance(node.lat, Decimal) assert isinstance(node.lon, Decimal) assert node.id == 3233854234 assert node.lat == Decimal("50.7494236") assert node.lon == Decimal("7.1757664") assert isinstance(node.attributes, dict) assert len(node.attributes) == 5 assert node.attributes["changeset"] == 23456789 assert node.attributes["timestamp"] == datetime(2014, 12, 14, 7, 27, 19, 0, None) assert node.attributes["uid"] == 345678 assert node.attributes["user"] == "TestUser" assert node.attributes["version"] == 1 # try to get a single node by id node = result.get_node(50878400) assert node.id == 50878400 # try to get a single node by id not available in the result with pytest.raises(overpy.exception.DataIncomplete): result.get_node(123456) # node_ids is an alias for get_node_ids() and should return the same data for node_ids in (result.node_ids, result.get_node_ids()): assert len(node_ids) == 3 assert node_ids[0] == 50878400 assert node_ids[1] == 100793192 assert node_ids[2] == 3233854234 assert len(result.relation_ids) == 0 assert len(result.get_relation_ids()) == 0 assert len(result.way_ids) == 0 assert len(result.get_way_ids()) == 0 class BaseTestRelation(object): def _test_relation01(self, result): assert len(result.nodes) == 0 assert len(result.relations) == 1 assert len(result.ways) == 0 relation = result.relations[0] assert isinstance(relation, overpy.Relation) assert isinstance(relation.id, int) assert relation.id == 2046898 assert isinstance(relation.tags, dict) assert len(relation.tags) == 6 assert relation.tags["from"] == "Here" assert relation.tags["name"] == "Test relation" assert relation.tags["ref"] == "609" assert relation.tags["route"] == "bus" assert relation.tags["to"] == "There" assert relation.tags["type"] == "route" assert isinstance(relation.attributes, dict) assert len(relation.attributes) == 5 assert relation.attributes["changeset"] == 17433822 assert relation.attributes["timestamp"] == datetime(2014, 12, 15, 13, 13, 11, 0, None) assert relation.attributes["uid"] == 12345 assert relation.attributes["user"] == "Username" assert relation.attributes["version"] == 12 assert len(relation.members) == 5 assert isinstance(relation.members[0], overpy.RelationNode) assert isinstance(relation.members[1], overpy.RelationNode) assert isinstance(relation.members[2], overpy.RelationNode) assert isinstance(relation.members[3], overpy.RelationNode) assert isinstance(relation.members[4], overpy.RelationWay) def _test_relation02(self, result): assert len(result.nodes) == 3 assert len(result.relations) == 1 assert len(result.ways) == 1 relation = result.relations[0] assert isinstance(relation, overpy.Relation) assert isinstance(relation.id, int) assert relation.id == 2046898 assert isinstance(relation.tags, dict) assert len(relation.tags) == 6 assert relation.tags["from"] == "Here" assert relation.tags["name"] == "Test relation" assert relation.tags["ref"] == "609" assert relation.tags["route"] == "bus" assert relation.tags["to"] == "There" assert relation.tags["type"] == "route" assert isinstance(relation.attributes, dict) assert len(relation.attributes) == 5 assert len(relation.members) == 4 member = relation.members[0] assert isinstance(member, overpy.RelationNode) node = member.resolve() assert isinstance(node, overpy.Node) assert node.id == 3233854233 assert member.ref == node.id member = relation.members[1] assert isinstance(member, overpy.RelationNode) node = member.resolve() assert isinstance(node, overpy.Node) assert node.id == 3233854234 assert member.ref == node.id member = relation.members[2] assert isinstance(member, overpy.RelationNode) node = member.resolve() assert isinstance(node, overpy.Node) assert node.id == 3233854235 assert member.ref == node.id member = relation.members[3] assert isinstance(member, overpy.RelationWay) way = member.resolve() assert isinstance(way, overpy.Way) assert way.id == 317146078 assert member.ref == way.id def _test_relation03(self, result): assert len(result.nodes) == 0 assert len(result.relations) == 1 assert len(result.ways) == 0 relation = result.relations[0] assert isinstance(relation, overpy.Relation) assert isinstance(relation.id, int) assert relation.id == 23092 assert isinstance(relation.tags, dict) assert len(relation.tags) == 10 assert isinstance(relation.center_lat, Decimal) assert isinstance(relation.center_lon, Decimal) assert relation.center_lat == Decimal("50.8176646") assert relation.center_lon == Decimal("7.0208539") def _test_relation04(self, result): assert len(result.nodes) == 0 assert len(result.relations) == 1 assert len(result.ways) == 0 relation = result.relations[0] assert isinstance(relation, overpy.Relation) assert isinstance(relation.id, int) assert relation.id == 23092 assert isinstance(relation.tags, dict) assert len(relation.tags) == 10 way = relation.members[2] assert isinstance(way, overpy.RelationWay) assert len(way.attributes) == 0 assert isinstance(way.attributes, dict) assert isinstance(way.geometry, list) assert len(way.geometry) == 2 assert isinstance(way.geometry[0], overpy.RelationWayGeometryValue) assert isinstance(way.geometry[0].lat, Decimal) assert isinstance(way.geometry[0].lon, Decimal) assert way.geometry[0].lat == Decimal("50.8137408") assert way.geometry[0].lon == Decimal("6.9813352") class BaseTestWay(object): def _test_way01(self, result): assert len(result.nodes) == 0 assert len(result.relations) == 0 assert len(result.ways) == 2 way = result.ways[0] assert isinstance(way, overpy.Way) assert isinstance(way.id, int) assert way.id == 317146077 assert isinstance(way.tags, dict) assert len(way.tags) == 1 assert way.tags["building"] == "yes" assert isinstance(way.attributes, dict) assert len(way.attributes) == 0 way = result.ways[1] assert isinstance(way, overpy.Way) assert isinstance(way.id, int) assert way.id == 317146078 assert isinstance(way.tags, dict) assert len(way.tags) == 0 assert isinstance(way.attributes, dict) assert len(way.attributes) == 5 assert way.attributes["changeset"] == 23456789 assert way.attributes["timestamp"] == datetime(2014, 12, 14, 7, 27, 21, 0, None) assert way.attributes["uid"] == 345678 assert way.attributes["user"] == "TestUser" assert way.attributes["version"] == 1 # try to get a single way by id way = result.get_way(317146077) assert way.id == 317146077 # try to get a single way by id not available in the result with pytest.raises(overpy.exception.DataIncomplete): result.get_way(123456) assert len(result.node_ids) == 0 assert len(result.get_node_ids()) == 0 assert len(result.relation_ids) == 0 assert len(result.get_relation_ids()) == 0 # way_ids is an alias for get_way_ids() and should return the same data for way_ids in (result.way_ids, result.get_way_ids()): assert len(way_ids) == 2 assert way_ids[0] == 317146077 assert way_ids[1] == 317146078 def _test_way02(self, result): assert len(result.nodes) == 6 assert len(result.relations) == 0 assert len(result.ways) == 1 node = result.nodes[0] assert isinstance(node, overpy.Node) assert isinstance(node.id, int) assert isinstance(node.lat, Decimal) assert isinstance(node.lon, Decimal) assert node.id == 3233854233 assert node.lat == Decimal("50.7494187") assert node.lon == Decimal("7.1758731") way = result.ways[0] assert isinstance(way, overpy.Way) assert isinstance(way.id, int) assert way.id == 317146077 assert isinstance(way.tags, dict) assert len(way.tags) == 1 assert way.tags["building"] == "yes" nodes = way.nodes assert len(nodes) == 7 node = nodes[0] assert isinstance(node, overpy.Node) assert node.id == 3233854241 # try to get a single way by id way = result.get_way(317146077) assert way.id == 317146077 # try to get a single way by id not available in the result with pytest.raises(overpy.exception.DataIncomplete): result.get_way(123456) # node_ids is an alias for get_node_ids() and should return the same data for node_ids in (result.node_ids, result.get_node_ids()): assert len(node_ids) == 6 assert node_ids[0] == 3233854233 assert node_ids[1] == 3233854234 assert node_ids[2] == 3233854236 assert node_ids[3] == 3233854237 assert node_ids[4] == 3233854238 assert node_ids[5] == 3233854241 assert len(result.relation_ids) == 0 assert len(result.get_relation_ids()) == 0 # way_ids is an alias for get_way_ids() and should return the same data for way_ids in (result.way_ids, result.get_way_ids()): assert len(way_ids) == 1 assert way_ids[0] == 317146077 def _test_way03(self, result): assert len(result.nodes) == 4 assert len(result.relations) == 0 assert len(result.ways) == 1 way = result.ways[0] assert isinstance(way, overpy.Way) assert isinstance(way.id, int) assert way.id == 225576797 assert isinstance(way.tags, dict) assert len(way.tags) == 2 assert way.tags["building"] == "kiosk" assert way.tags["shop"] == "florist" assert isinstance(way.center_lat, Decimal) assert isinstance(way.center_lon, Decimal) assert way.center_lat == Decimal("41.8954998") assert way.center_lon == Decimal("12.5032265") for nodes in (way.nodes, way.get_nodes()): assert len(nodes) == 5 for node in nodes: assert isinstance(node, overpy.Node) assert isinstance(node.id, int) assert nodes[0].id == 2343425525 assert nodes[1].id == 2343425528 assert nodes[2].id == 2343425526 assert nodes[3].id == 2343425523 assert nodes[4].id == 2343425525 # try to get a single way by id way = result.get_way(225576797) assert way.id == 225576797 # try to get a single way by id not available in the result with pytest.raises(overpy.exception.DataIncomplete): result.get_way(123456) # node_ids is an alias for get_node_ids() and should return the same data for node_ids in (result.node_ids, result.get_node_ids()): assert len(node_ids) == 4 assert node_ids[0] == 2343425523 assert node_ids[1] == 2343425525 assert node_ids[2] == 2343425526 assert node_ids[3] == 2343425528 assert len(result.relation_ids) == 0 assert len(result.get_relation_ids()) == 0 # way_ids is an alias for get_way_ids() and should return the same data for way_ids in (result.way_ids, result.get_way_ids()): assert len(way_ids) == 1 assert way_ids[0] == 225576797 overpy-0.4/tests/__init__.py0000644000175000017500000000231613022347635016407 0ustar phibophibo00000000000000import os import sys import time from multiprocessing import Process from threading import Lock PY2 = sys.version_info[0] == 2 if PY2: from SocketServer import TCPServer, BaseRequestHandler else: from socketserver import TCPServer, BaseRequestHandler TCPServer.allow_reuse_address = True HOST = "127.0.0.1" PORT_START = sys.version_info[0] * 10000 + sys.version_info[1] * 100 current_port = PORT_START test_lock = Lock() def read_file(filename, mode="r"): filename = os.path.join(os.path.dirname(__file__), filename) return open(filename, mode).read() def server_thread(server): request = server.get_request() server.process_request(*request) server.server_close() server.socket.close() def new_server_thread(handle_cls, port=None): global current_port if port is None: test_lock.acquire() port = current_port current_port += 1 test_lock.release() server = TCPServer( (HOST, port), handle_cls ) p = Process(target=server_thread, args=(server,)) p.start() # Give the server some time to bind # Is there a better option? time.sleep(0.2) return ( "http://%s:%d" % (HOST, port), p ) overpy-0.4/tests/xml/0000755000175000017500000000000013022347701015066 5ustar phibophibo00000000000000overpy-0.4/tests/xml/way-04.xml0000644000175000017500000000076213022347635016644 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.
overpy-0.4/tests/xml/way-03.xml0000644000175000017500000000233213022347635016636 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.
overpy-0.4/tests/xml/way-02.xml0000644000175000017500000000153013022347635016634 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/way-01.xml0000644000175000017500000000146213022347635016637 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/relation-04.xml0000644000175000017500000006550613022347635017670 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/relation-03.xml0000644000175000017500000001603113022347635017654 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.
overpy-0.4/tests/xml/relation-02.xml0000644000175000017500000000206413022347635017654 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/relation-01.xml0000644000175000017500000000150513022347635017652 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/node-01.xml0000644000175000017500000000107113022347635016760 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/xml/area-01.xml0000644000175000017500000000516113022347635016747 0ustar phibophibo00000000000000 The data included in this document is from www.openstreetmap.org. The data is made available under ODbL. overpy-0.4/tests/response/0000755000175000017500000000000013022347701016124 5ustar phibophibo00000000000000overpy-0.4/tests/response/bad-request.html0000644000175000017500000000111413022347635021231 0ustar phibophibo00000000000000 OSM3S Response

The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.

Error: line 2: parse error: ';' expected - 'out' found.

overpy-0.4/tests/response/bad-request-encoding.html0000644000175000017500000000116313022347635023021 0ustar phibophibo00000000000000 OSM3S Response

The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.

Error: line 2: parse error: ';' expected - 'out' found. äöü

overpy-0.4/tests/json/0000755000175000017500000000000013022347701015237 5ustar phibophibo00000000000000overpy-0.4/tests/json/way-04.json0000644000175000017500000000074213022347635017164 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2016-11-22T23:25:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "way", "id": 225576797, "center": {}, "nodes": [ 2343425525, 2343425528, 2343425526, 2343425523, 2343425525 ], "tags": { "building": "kiosk", "shop": "florist" } } ] }overpy-0.4/tests/json/way-03.json0000644000175000017500000000266113022347635017165 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2016-11-22T22:33:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 2343425523, "lat": 41.8954452, "lon": 12.5032169, "timestamp": "2013-06-13T15:34:01Z", "version": 1, "changeset": 16539126, "user": "Giardia", "uid": 113909 }, { "type": "node", "id": 2343425525, "lat": 41.8954752, "lon": 12.5031604, "timestamp": "2013-06-13T15:34:01Z", "version": 1, "changeset": 16539126, "user": "Giardia", "uid": 113909 }, { "type": "node", "id": 2343425526, "lat": 41.8955244, "lon": 12.5032926, "timestamp": "2013-06-13T15:34:01Z", "version": 1, "changeset": 16539126, "user": "Giardia", "uid": 113909 }, { "type": "node", "id": 2343425528, "lat": 41.8955543, "lon": 12.5032362, "timestamp": "2013-06-13T15:34:01Z", "version": 1, "changeset": 16539126, "user": "Giardia", "uid": 113909 }, { "type": "way", "id": 225576797, "timestamp": "2013-06-13T15:34:01Z", "version": 1, "changeset": 16539126, "user": "Giardia", "uid": 113909, "center": { "lat": 41.8954998, "lon": 12.5032265 }, "nodes": [ 2343425525, 2343425528, 2343425526, 2343425523, 2343425525 ], "tags": { "building": "kiosk", "shop": "florist" } } ] } overpy-0.4/tests/json/way-02.json0000644000175000017500000000171313022347635017161 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "node", "id": 3233854234, "lat": 50.7494236, "lon": 7.1757664 }, { "type": "node", "id": 3233854236, "lat": 50.7494909, "lon": 7.1757741 }, { "type": "node", "id": 3233854237, "lat": 50.7494985, "lon": 7.1756064 }, { "type": "node", "id": 3233854238, "lat": 50.7495391, "lon": 7.1758868 }, { "type": "node", "id": 3233854241, "lat": 50.7495516, "lon": 7.1756125 }, { "type": "way", "id": 317146077, "nodes": [ 3233854241, 3233854238, 3233854233, 3233854234, 3233854236, 3233854237, 3233854241 ], "tags": { "building": "yes" } } ] }overpy-0.4/tests/json/way-01.json0000644000175000017500000000137113022347635017160 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:33:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "way", "id": 317146077, "nodes": [ 3233854241, 3233854238, 3233854233, 3233854234, 3233854236, 3233854237, 3233854241 ], "tags": { "building": "yes" } }, { "type": "way", "id": 317146078, "timestamp": "2014-12-14T07:27:21Z", "version": 1, "changeset": 23456789, "user": "TestUser", "uid": 345678, "nodes": [ 3233854241, 3233854238, 3233854233, 3233854234, 3233854236, 3233854237, 3233854241 ] } ] }overpy-0.4/tests/json/result-way-03.json0000644000175000017500000000121113022347635020467 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "node", "id": 3233854234, "lat": 50.7494287, "lon": 7.1758731 }, { "type": "way", "id": 317146077, "nodes": [ 3233854233, 3233854234 ], "tags": { "building": "yes" } } ] }overpy-0.4/tests/json/result-way-02.json0000644000175000017500000000103613022347635020473 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "way", "id": 317146077, "nodes": [ 3233854233, 3233854234 ], "tags": { "building": "yes" } } ] }overpy-0.4/tests/json/result-way-01.json0000644000175000017500000000066313022347635020477 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "way", "id": 317146077, "nodes": [ 3233854233, 3233854234 ], "tags": { "building": "yes" } } ] }overpy-0.4/tests/json/result-expand-02.json0000644000175000017500000000275113022347635021157 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "area", "id": 3605945176 }, { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "node", "id": 3233854235, "lat": 50.7494287, "lon": 7.1758731 }, { "type": "way", "id": 317146078, "nodes": [ 3233854233, 3233854235 ], "tags": { "building": "yes" } }, { "type": "relation", "id": 2046898, "timestamp": "2014-12-15T13:13:11Z", "version": 12, "changeset": 17433822, "user": "Username", "uid": 12345, "members": [ { "type": "node", "ref": 3233854233, "role": "platform" }, { "type": "node", "ref": 3233854234, "role": "stop" }, { "type": "node", "ref": 3233854235, "role": "platform" }, { "type": "way", "ref": 317146078, "role": "" } ], "tags": { "from": "Here", "name": "Test relation", "ref": "609", "route": "bus", "to": "There", "type": "route" } } ] }overpy-0.4/tests/json/result-expand-01.json0000644000175000017500000000121113022347635021144 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "node", "id": 3233854234, "lat": 50.7494287, "lon": 7.1758731 }, { "type": "way", "id": 317146077, "nodes": [ 3233854233, 3233854234 ], "tags": { "building": "yes" } } ] }overpy-0.4/tests/json/relation-04.json0000644000175000017500000010422113022347635020176 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2016-11-24T21:40:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "relation", "id": 23092, "bounds": { "minlat": 50.7432318, "minlon": 6.9639432, "maxlat": 50.8920975, "maxlon": 7.0777645 }, "members": [ { "type": "way", "ref": 4334856, "role": "", "geometry": [ { "lat": 50.8104598, "lon": 6.9871803 }, { "lat": 50.8117239, "lon": 6.9849282 } ] }, { "type": "way", "ref": 234434903, "role": "", "geometry": [ { "lat": 50.8117239, "lon": 6.9849282 }, { "lat": 50.8137408, "lon": 6.9813352 } ] }, { "type": "way", "ref": 37881522, "role": "", "geometry": [ { "lat": 50.8137408, "lon": 6.9813352 }, { "lat": 50.8140146, "lon": 6.9808445 } ] }, { "type": "way", "ref": 37881521, "role": "", "geometry": [ { "lat": 50.8140146, "lon": 6.9808445 }, { "lat": 50.8193541, "lon": 6.9713457 }, { "lat": 50.8203182, "lon": 6.9697248 }, { "lat": 50.8210652, "lon": 6.9685758 }, { "lat": 50.8217885, "lon": 6.9676136 }, { "lat": 50.8225495, "lon": 6.9667439 }, { "lat": 50.8233005, "lon": 6.9660515 }, { "lat": 50.8238128, "lon": 6.9656463 }, { "lat": 50.8243279, "lon": 6.9653077 } ] }, { "type": "way", "ref": 4356491, "role": "", "geometry": [ { "lat": 50.7433997, "lon": 7.0777645 }, { "lat": 50.7434097, "lon": 7.0775890 }, { "lat": 50.7434629, "lon": 7.0774402 }, { "lat": 50.7435198, "lon": 7.0773718 }, { "lat": 50.7437507, "lon": 7.0771524 } ] }, { "type": "way", "ref": 235363211, "role": "", "geometry": [ { "lat": 50.7437507, "lon": 7.0771524 }, { "lat": 50.7446592, "lon": 7.0762926 } ] }, { "type": "way", "ref": 48290877, "role": "", "geometry": [ { "lat": 50.7446592, "lon": 7.0762926 }, { "lat": 50.7450803, "lon": 7.0757571 }, { "lat": 50.7453888, "lon": 7.0753312 }, { "lat": 50.7457125, "lon": 7.0748518 }, { "lat": 50.7460370, "lon": 7.0743265 }, { "lat": 50.7462718, "lon": 7.0739425 }, { "lat": 50.7464798, "lon": 7.0735173 }, { "lat": 50.7468359, "lon": 7.0727449 } ] }, { "type": "way", "ref": 210683519, "role": "", "geometry": [ { "lat": 50.7468359, "lon": 7.0727449 }, { "lat": 50.7471006, "lon": 7.0720546 }, { "lat": 50.7473135, "lon": 7.0714640 }, { "lat": 50.7475199, "lon": 7.0708095 }, { "lat": 50.7479418, "lon": 7.0693723 } ] }, { "type": "way", "ref": 42743961, "role": "", "geometry": [ { "lat": 50.7464112, "lon": 7.0734310 }, { "lat": 50.7459053, "lon": 7.0743560 }, { "lat": 50.7457638, "lon": 7.0745740 } ] }, { "type": "way", "ref": 210683522, "role": "", "geometry": [ { "lat": 50.7457638, "lon": 7.0745740 }, { "lat": 50.7456300, "lon": 7.0747409 }, { "lat": 50.7454858, "lon": 7.0749187 }, { "lat": 50.7452550, "lon": 7.0752554 }, { "lat": 50.7450000, "lon": 7.0756385 }, { "lat": 50.7448878, "lon": 7.0758027 }, { "lat": 50.7447522, "lon": 7.0759730 }, { "lat": 50.7445514, "lon": 7.0762032 }, { "lat": 50.7443577, "lon": 7.0764098 }, { "lat": 50.7441185, "lon": 7.0766490 } ] }, { "type": "way", "ref": 48290881, "role": "", "geometry": [ { "lat": 50.7441185, "lon": 7.0766490 }, { "lat": 50.7439033, "lon": 7.0768575 }, { "lat": 50.7437722, "lon": 7.0769631 }, { "lat": 50.7436609, "lon": 7.0770394 } ] }, { "type": "way", "ref": 235363214, "role": "", "geometry": [ { "lat": 50.7436609, "lon": 7.0770394 }, { "lat": 50.7435688, "lon": 7.0771154 }, { "lat": 50.7434662, "lon": 7.0771906 }, { "lat": 50.7434058, "lon": 7.0772230 }, { "lat": 50.7433331, "lon": 7.0772525 }, { "lat": 50.7432822, "lon": 7.0772636 }, { "lat": 50.7432318, "lon": 7.0772601 } ] }, { "type": "way", "ref": 4400137, "role": "", "geometry": [ { "lat": 50.8887155, "lon": 6.9676900 }, { "lat": 50.8876384, "lon": 6.9678150 } ] }, { "type": "way", "ref": 230940375, "role": "", "geometry": [ { "lat": 50.8876384, "lon": 6.9678150 }, { "lat": 50.8870572, "lon": 6.9679058 }, { "lat": 50.8858563, "lon": 6.9680103 } ] }, { "type": "way", "ref": 4400140, "role": "", "geometry": [ { "lat": 50.8797318, "lon": 6.9690108 }, { "lat": 50.8799208, "lon": 6.9689396 }, { "lat": 50.8807058, "lon": 6.9688470 }, { "lat": 50.8824762, "lon": 6.9687068 } ] }, { "type": "way", "ref": 4400142, "role": "", "geometry": [ { "lat": 50.8919691, "lon": 6.9670292 }, { "lat": 50.8918982, "lon": 6.9671419 }, { "lat": 50.8918068, "lon": 6.9672404 }, { "lat": 50.8917186, "lon": 6.9673001 }, { "lat": 50.8916153, "lon": 6.9673480 }, { "lat": 50.8914588, "lon": 6.9673816 } ] }, { "type": "way", "ref": 235824476, "role": "", "geometry": [ { "lat": 50.8914588, "lon": 6.9673816 }, { "lat": 50.8892470, "lon": 6.9676302 }, { "lat": 50.8887155, "lon": 6.9676900 } ] }, { "type": "way", "ref": 4400143, "role": "", "geometry": [ { "lat": 50.8887787, "lon": 6.9681629 }, { "lat": 50.8896224, "lon": 6.9680604 }, { "lat": 50.8897525, "lon": 6.9680446 } ] }, { "type": "way", "ref": 235824475, "role": "", "geometry": [ { "lat": 50.8897525, "lon": 6.9680446 }, { "lat": 50.8906556, "lon": 6.9679349 }, { "lat": 50.8912013, "lon": 6.9678862 } ] }, { "type": "way", "ref": 178797123, "role": "", "geometry": [ { "lat": 50.8912013, "lon": 6.9678862 }, { "lat": 50.8913492, "lon": 6.9678648 } ] }, { "type": "way", "ref": 233553030, "role": "", "geometry": [ { "lat": 50.8913492, "lon": 6.9678648 }, { "lat": 50.8916648, "lon": 6.9677762 }, { "lat": 50.8917895, "lon": 6.9677694 }, { "lat": 50.8919294, "lon": 6.9677947 }, { "lat": 50.8920975, "lon": 6.9678618 } ] }, { "type": "way", "ref": 4829989, "role": "", "geometry": [ { "lat": 50.8105743, "lon": 6.9865001 }, { "lat": 50.8088268, "lon": 6.9896207 } ] }, { "type": "way", "ref": 99834112, "role": "", "geometry": [ { "lat": 50.8088268, "lon": 6.9896207 }, { "lat": 50.8066272, "lon": 6.9935457 }, { "lat": 50.8057165, "lon": 6.9951151 } ] }, { "type": "way", "ref": 133081219, "role": "", "geometry": [ { "lat": 50.8057165, "lon": 6.9951151 }, { "lat": 50.8050332, "lon": 6.9962100 }, { "lat": 50.8043133, "lon": 6.9972614 } ] }, { "type": "way", "ref": 234434905, "role": "", "geometry": [ { "lat": 50.8043133, "lon": 6.9972614 }, { "lat": 50.8038004, "lon": 6.9979304 }, { "lat": 50.8032120, "lon": 6.9986363 }, { "lat": 50.8029818, "lon": 6.9989181 } ] }, { "type": "way", "ref": 20661567, "role": "", "geometry": [ { "lat": 50.8849681, "lon": 6.9681126 }, { "lat": 50.8839667, "lon": 6.9682524 }, { "lat": 50.8829770, "lon": 6.9684059 } ] }, { "type": "way", "ref": 230941900, "role": "", "geometry": [ { "lat": 50.8829770, "lon": 6.9684059 }, { "lat": 50.8826286, "lon": 6.9684595 } ] }, { "type": "way", "ref": 20661568, "role": "", "geometry": [ { "lat": 50.8850872, "lon": 6.9685052 }, { "lat": 50.8859127, "lon": 6.9684079 } ] }, { "type": "way", "ref": 20661572, "role": "", "geometry": [ { "lat": 50.8859127, "lon": 6.9684079 }, { "lat": 50.8872823, "lon": 6.9682592 }, { "lat": 50.8876807, "lon": 6.9682539 } ] }, { "type": "way", "ref": 230940374, "role": "", "geometry": [ { "lat": 50.8876807, "lon": 6.9682539 }, { "lat": 50.8887787, "lon": 6.9681629 } ] }, { "type": "way", "ref": 20661573, "role": "", "geometry": [ { "lat": 50.8858563, "lon": 6.9680103 }, { "lat": 50.8849681, "lon": 6.9681126 } ] }, { "type": "way", "ref": 20662817, "role": "", "geometry": [ { "lat": 50.8823655, "lon": 6.9684998 }, { "lat": 50.8806620, "lon": 6.9686453 } ] }, { "type": "way", "ref": 230941903, "role": "", "geometry": [ { "lat": 50.8806620, "lon": 6.9686453 }, { "lat": 50.8793943, "lon": 6.9687847 } ] }, { "type": "way", "ref": 20662819, "role": "", "geometry": [ { "lat": 50.8824762, "lon": 6.9687068 }, { "lat": 50.8827522, "lon": 6.9686901 } ] }, { "type": "way", "ref": 20662824, "role": "", "geometry": [ { "lat": 50.8827522, "lon": 6.9686901 }, { "lat": 50.8839133, "lon": 6.9686122 }, { "lat": 50.8850872, "lon": 6.9685052 } ] }, { "type": "way", "ref": 20662827, "role": "", "geometry": [ { "lat": 50.8826286, "lon": 6.9684595 }, { "lat": 50.8823655, "lon": 6.9684998 } ] }, { "type": "way", "ref": 27492515, "role": "", "geometry": [ { "lat": 50.8029818, "lon": 6.9989181 }, { "lat": 50.8026288, "lon": 6.9992932 } ] }, { "type": "way", "ref": 129125122, "role": "", "geometry": [ { "lat": 50.8093979, "lon": 6.9890430 }, { "lat": 50.8104598, "lon": 6.9871803 } ] }, { "type": "way", "ref": 234434901, "role": "", "geometry": [ { "lat": 50.8063753, "lon": 6.9944172 }, { "lat": 50.8093979, "lon": 6.9890430 } ] }, { "type": "way", "ref": 234434904, "role": "", "geometry": [ { "lat": 50.8053262, "lon": 6.9961817 }, { "lat": 50.8058108, "lon": 6.9953914 }, { "lat": 50.8063753, "lon": 6.9944172 } ] }, { "type": "way", "ref": 27492542, "role": "", "geometry": [ { "lat": 50.8029899, "lon": 6.9991939 }, { "lat": 50.8032828, "lon": 6.9988807 }, { "lat": 50.8038702, "lon": 6.9982129 }, { "lat": 50.8044350, "lon": 6.9974695 }, { "lat": 50.8053262, "lon": 6.9961817 } ] }, { "type": "way", "ref": 27492543, "role": "", "geometry": [ { "lat": 50.8026483, "lon": 6.9995590 }, { "lat": 50.8029899, "lon": 6.9991939 } ] }, { "type": "way", "ref": 29233646, "role": "", "geometry": [ { "lat": 50.8793943, "lon": 6.9687847 }, { "lat": 50.8716935, "lon": 6.9696241 }, { "lat": 50.8701666, "lon": 6.9697243 }, { "lat": 50.8688585, "lon": 6.9697057 }, { "lat": 50.8652424, "lon": 6.9693872 } ] }, { "type": "way", "ref": 235820561, "role": "", "geometry": [ { "lat": 50.8652424, "lon": 6.9693872 }, { "lat": 50.8636340, "lon": 6.9692339 } ] }, { "type": "way", "ref": 29233647, "role": "", "geometry": [ { "lat": 50.8636340, "lon": 6.9692339 }, { "lat": 50.8608791, "lon": 6.9689787 } ] }, { "type": "way", "ref": 235820559, "role": "", "geometry": [ { "lat": 50.8608791, "lon": 6.9689787 }, { "lat": 50.8590168, "lon": 6.9688055 } ] }, { "type": "way", "ref": 235820562, "role": "", "geometry": [ { "lat": 50.8590168, "lon": 6.9688055 }, { "lat": 50.8523854, "lon": 6.9681888 } ] }, { "type": "way", "ref": 29233648, "role": "", "geometry": [ { "lat": 50.8522171, "lon": 6.9684787 }, { "lat": 50.8590359, "lon": 6.9691023 } ] }, { "type": "way", "ref": 29382960, "role": "", "geometry": [ { "lat": 50.8391695, "lon": 6.9667285 }, { "lat": 50.8411491, "lon": 6.9672118 }, { "lat": 50.8425706, "lon": 6.9674985 } ] }, { "type": "way", "ref": 271008229, "role": "", "geometry": [ { "lat": 50.8425706, "lon": 6.9674985 }, { "lat": 50.8443277, "lon": 6.9677563 } ] }, { "type": "way", "ref": 271008238, "role": "", "geometry": [ { "lat": 50.8443277, "lon": 6.9677563 }, { "lat": 50.8453254, "lon": 6.9678465 }, { "lat": 50.8468114, "lon": 6.9679862 } ] }, { "type": "way", "ref": 271008230, "role": "", "geometry": [ { "lat": 50.8468114, "lon": 6.9679862 }, { "lat": 50.8491169, "lon": 6.9681907 } ] }, { "type": "way", "ref": 271008226, "role": "", "geometry": [ { "lat": 50.8491169, "lon": 6.9681907 }, { "lat": 50.8518181, "lon": 6.9684403 } ] }, { "type": "way", "ref": 40033062, "role": "", "geometry": [ { "lat": 50.8391857, "lon": 6.9664246 }, { "lat": 50.8386690, "lon": 6.9662911 } ] }, { "type": "way", "ref": 40033063, "role": "", "geometry": [ { "lat": 50.8386690, "lon": 6.9662911 }, { "lat": 50.8314332, "lon": 6.9644546 } ] }, { "type": "way", "ref": 29384561, "role": "", "geometry": [ { "lat": 50.8523854, "lon": 6.9681888 }, { "lat": 50.8519590, "lon": 6.9681595 } ] }, { "type": "way", "ref": 29384563, "role": "", "geometry": [ { "lat": 50.8519590, "lon": 6.9681595 }, { "lat": 50.8506534, "lon": 6.9680320 } ] }, { "type": "way", "ref": 271008224, "role": "", "geometry": [ { "lat": 50.8506534, "lon": 6.9680320 }, { "lat": 50.8490308, "lon": 6.9678717 } ] }, { "type": "way", "ref": 271008227, "role": "", "geometry": [ { "lat": 50.8490308, "lon": 6.9678717 }, { "lat": 50.8478121, "lon": 6.9677589 } ] }, { "type": "way", "ref": 271008237, "role": "", "geometry": [ { "lat": 50.8478121, "lon": 6.9677589 }, { "lat": 50.8459552, "lon": 6.9676249 }, { "lat": 50.8451822, "lon": 6.9675256 } ] }, { "type": "way", "ref": 271008232, "role": "", "geometry": [ { "lat": 50.8451822, "lon": 6.9675256 }, { "lat": 50.8433946, "lon": 6.9673373 } ] }, { "type": "way", "ref": 271008239, "role": "", "geometry": [ { "lat": 50.8433946, "lon": 6.9673373 }, { "lat": 50.8424071, "lon": 6.9671724 }, { "lat": 50.8411984, "lon": 6.9669289 }, { "lat": 50.8391857, "lon": 6.9664246 } ] }, { "type": "way", "ref": 29384564, "role": "", "geometry": [ { "lat": 50.8518181, "lon": 6.9684403 }, { "lat": 50.8522171, "lon": 6.9684787 } ] }, { "type": "way", "ref": 31282638, "role": "", "geometry": [ { "lat": 50.7547305, "lon": 7.0468957 }, { "lat": 50.7550333, "lon": 7.0462257 } ] }, { "type": "way", "ref": 31282787, "role": "", "geometry": [ { "lat": 50.7548175, "lon": 7.0462659 }, { "lat": 50.7545192, "lon": 7.0469416 } ] }, { "type": "way", "ref": 383262762, "role": "", "geometry": [ { "lat": 50.7545192, "lon": 7.0469416 }, { "lat": 50.7522859, "lon": 7.0519784 }, { "lat": 50.7519030, "lon": 7.0528750 } ] }, { "type": "way", "ref": 31304443, "role": "", "geometry": [ { "lat": 50.7519030, "lon": 7.0528750 }, { "lat": 50.7514373, "lon": 7.0540731 }, { "lat": 50.7512408, "lon": 7.0546346 }, { "lat": 50.7511231, "lon": 7.0549962 }, { "lat": 50.7508172, "lon": 7.0560135 } ] }, { "type": "way", "ref": 128541594, "role": "", "geometry": [ { "lat": 50.7508172, "lon": 7.0560135 }, { "lat": 50.7504938, "lon": 7.0572440 } ] }, { "type": "way", "ref": 31304503, "role": "", "geometry": [ { "lat": 50.7509429, "lon": 7.0561605 }, { "lat": 50.7512483, "lon": 7.0551357 }, { "lat": 50.7513759, "lon": 7.0547500 }, { "lat": 50.7515670, "lon": 7.0542197 }, { "lat": 50.7520213, "lon": 7.0530348 }, { "lat": 50.7524214, "lon": 7.0520935 }, { "lat": 50.7547305, "lon": 7.0468957 } ] }, { "type": "way", "ref": 31363881, "role": "", "geometry": [ { "lat": 50.8026288, "lon": 6.9992932 }, { "lat": 50.8018617, "lon": 7.0000625 }, { "lat": 50.8010270, "lon": 7.0007950 }, { "lat": 50.8001164, "lon": 7.0015291 }, { "lat": 50.7928343, "lon": 7.0072406 }, { "lat": 50.7832350, "lon": 7.0147268 }, { "lat": 50.7826087, "lon": 7.0151803 } ] }, { "type": "way", "ref": 31363891, "role": "", "geometry": [ { "lat": 50.7826087, "lon": 7.0151803 }, { "lat": 50.7823221, "lon": 7.0153822 } ] }, { "type": "way", "ref": 31363892, "role": "", "geometry": [ { "lat": 50.7823221, "lon": 7.0153822 }, { "lat": 50.7802850, "lon": 7.0170023 }, { "lat": 50.7782200, "lon": 7.0186241 } ] }, { "type": "way", "ref": 31363898, "role": "", "geometry": [ { "lat": 50.7826777, "lon": 7.0153975 }, { "lat": 50.7833048, "lon": 7.0149295 }, { "lat": 50.8001641, "lon": 7.0017836 }, { "lat": 50.8010947, "lon": 7.0010142 }, { "lat": 50.8019538, "lon": 7.0002540 }, { "lat": 50.8026483, "lon": 6.9995590 } ] }, { "type": "way", "ref": 31363910, "role": "", "geometry": [ { "lat": 50.7823930, "lon": 7.0156008 }, { "lat": 50.7826777, "lon": 7.0153975 } ] }, { "type": "way", "ref": 31364152, "role": "", "geometry": [ { "lat": 50.7782200, "lon": 7.0186241 }, { "lat": 50.7779774, "lon": 7.0188037 } ] }, { "type": "way", "ref": 31364158, "role": "", "geometry": [ { "lat": 50.7783056, "lon": 7.0188240 }, { "lat": 50.7788577, "lon": 7.0183860 }, { "lat": 50.7803473, "lon": 7.0172040 }, { "lat": 50.7816582, "lon": 7.0161766 }, { "lat": 50.7823930, "lon": 7.0156008 } ] }, { "type": "way", "ref": 31364178, "role": "", "geometry": [ { "lat": 50.7780676, "lon": 7.0190054 }, { "lat": 50.7783056, "lon": 7.0188240 } ] }, { "type": "way", "ref": 31364384, "role": "", "geometry": [ { "lat": 50.7749036, "lon": 7.0214625 }, { "lat": 50.7780676, "lon": 7.0190054 } ] }, { "type": "way", "ref": 31364387, "role": "", "geometry": [ { "lat": 50.7744886, "lon": 7.0214841 }, { "lat": 50.7712930, "lon": 7.0240315 }, { "lat": 50.7695809, "lon": 7.0254447 }, { "lat": 50.7686243, "lon": 7.0263151 } ] }, { "type": "way", "ref": 31364484, "role": "", "geometry": [ { "lat": 50.7748248, "lon": 7.0212347 }, { "lat": 50.7744886, "lon": 7.0214841 } ] }, { "type": "way", "ref": 31364512, "role": "", "geometry": [ { "lat": 50.7745735, "lon": 7.0217089 }, { "lat": 50.7749036, "lon": 7.0214625 } ] }, { "type": "way", "ref": 31364656, "role": "", "geometry": [ { "lat": 50.7686546, "lon": 7.0266216 }, { "lat": 50.7696586, "lon": 7.0256891 }, { "lat": 50.7713905, "lon": 7.0242565 }, { "lat": 50.7745735, "lon": 7.0217089 } ] }, { "type": "way", "ref": 31364667, "role": "", "geometry": [ { "lat": 50.7686243, "lon": 7.0263151 }, { "lat": 50.7676165, "lon": 7.0273126 }, { "lat": 50.7665957, "lon": 7.0283332 }, { "lat": 50.7653333, "lon": 7.0297134 } ] }, { "type": "way", "ref": 271008234, "role": "", "geometry": [ { "lat": 50.7653333, "lon": 7.0297134 }, { "lat": 50.7643799, "lon": 7.0308081 } ] }, { "type": "way", "ref": 31364888, "role": "", "geometry": [ { "lat": 50.7635269, "lon": 7.0321873 }, { "lat": 50.7641966, "lon": 7.0313729 } ] }, { "type": "way", "ref": 122158730, "role": "", "geometry": [ { "lat": 50.7641966, "lon": 7.0313729 }, { "lat": 50.7644716, "lon": 7.0310241 } ] }, { "type": "way", "ref": 31364985, "role": "", "geometry": [ { "lat": 50.7644716, "lon": 7.0310241 }, { "lat": 50.7648596, "lon": 7.0305814 } ] }, { "type": "way", "ref": 271008235, "role": "", "geometry": [ { "lat": 50.7648596, "lon": 7.0305814 }, { "lat": 50.7657812, "lon": 7.0295145 }, { "lat": 50.7666465, "lon": 7.0285903 } ] }, { "type": "way", "ref": 271008231, "role": "", "geometry": [ { "lat": 50.7666465, "lon": 7.0285903 }, { "lat": 50.7679887, "lon": 7.0272481 } ] }, { "type": "way", "ref": 271008233, "role": "", "geometry": [ { "lat": 50.7679887, "lon": 7.0272481 }, { "lat": 50.7686546, "lon": 7.0266216 } ] }, { "type": "way", "ref": 31365377, "role": "", "geometry": [ { "lat": 50.7643799, "lon": 7.0308081 }, { "lat": 50.7640807, "lon": 7.0311662 } ] }, { "type": "way", "ref": 31365425, "role": "", "geometry": [ { "lat": 50.7640807, "lon": 7.0311662 }, { "lat": 50.7638566, "lon": 7.0314272 } ] }, { "type": "way", "ref": 271008236, "role": "", "geometry": [ { "lat": 50.7638566, "lon": 7.0314272 }, { "lat": 50.7628914, "lon": 7.0326760 }, { "lat": 50.7621053, "lon": 7.0336961 } ] }, { "type": "way", "ref": 36447898, "role": "", "geometry": [ { "lat": 50.7621053, "lon": 7.0336961 }, { "lat": 50.7613433, "lon": 7.0347526 } ] }, { "type": "way", "ref": 271008228, "role": "", "geometry": [ { "lat": 50.7613433, "lon": 7.0347526 }, { "lat": 50.7608295, "lon": 7.0354890 } ] }, { "type": "way", "ref": 31366812, "role": "", "geometry": [ { "lat": 50.7588227, "lon": 7.0386254 }, { "lat": 50.7583011, "lon": 7.0394929 }, { "lat": 50.7576749, "lon": 7.0405773 }, { "lat": 50.7569096, "lon": 7.0419812 }, { "lat": 50.7558745, "lon": 7.0439976 }, { "lat": 50.7548175, "lon": 7.0462659 } ] }, { "type": "way", "ref": 31366880, "role": "", "geometry": [ { "lat": 50.7550333, "lon": 7.0462257 }, { "lat": 50.7559939, "lon": 7.0442408 }, { "lat": 50.7570656, "lon": 7.0421620 }, { "lat": 50.7578037, "lon": 7.0408023 }, { "lat": 50.7584541, "lon": 7.0396561 }, { "lat": 50.7589669, "lon": 7.0387984 } ] }, { "type": "way", "ref": 31367017, "role": "", "geometry": [ { "lat": 50.7609333, "lon": 7.0356976 }, { "lat": 50.7619690, "lon": 7.0342371 }, { "lat": 50.7630051, "lon": 7.0328461 }, { "lat": 50.7635269, "lon": 7.0321873 } ] }, { "type": "way", "ref": 31367443, "role": "", "geometry": [ { "lat": 50.7607331, "lon": 7.0359794 }, { "lat": 50.7609333, "lon": 7.0356976 } ] }, { "type": "way", "ref": 31367449, "role": "", "geometry": [ { "lat": 50.7589669, "lon": 7.0387984 }, { "lat": 50.7602933, "lon": 7.0366481 }, { "lat": 50.7607331, "lon": 7.0359794 } ] }, { "type": "way", "ref": 31367526, "role": "", "geometry": [ { "lat": 50.7606164, "lon": 7.0358121 }, { "lat": 50.7601681, "lon": 7.0365126 }, { "lat": 50.7588227, "lon": 7.0386254 } ] }, { "type": "way", "ref": 31367534, "role": "", "geometry": [ { "lat": 50.7608295, "lon": 7.0354890 }, { "lat": 50.7606164, "lon": 7.0358121 } ] }, { "type": "way", "ref": 31369852, "role": "", "geometry": [ { "lat": 50.7779774, "lon": 7.0188037 }, { "lat": 50.7748248, "lon": 7.0212347 } ] }, { "type": "way", "ref": 449397558, "role": "", "geometry": [ { "lat": 50.7479418, "lon": 7.0693723 }, { "lat": 50.7494783, "lon": 7.0624630 } ] }, { "type": "way", "ref": 31797389, "role": "", "geometry": [ { "lat": 50.7494783, "lon": 7.0624630 }, { "lat": 50.7502727, "lon": 7.0588905 }, { "lat": 50.7506441, "lon": 7.0572942 }, { "lat": 50.7509429, "lon": 7.0561605 } ] }, { "type": "way", "ref": 31798039, "role": "", "geometry": [ { "lat": 50.7504938, "lon": 7.0572440 }, { "lat": 50.7501306, "lon": 7.0588140 } ] }, { "type": "way", "ref": 235363212, "role": "", "geometry": [ { "lat": 50.7501306, "lon": 7.0588140 }, { "lat": 50.7492636, "lon": 7.0626737 }, { "lat": 50.7489407, "lon": 7.0641605 } ] }, { "type": "way", "ref": 156492546, "role": "", "geometry": [ { "lat": 50.7489407, "lon": 7.0641605 }, { "lat": 50.7488307, "lon": 7.0647205 }, { "lat": 50.7483739, "lon": 7.0668216 } ] }, { "type": "way", "ref": 156492545, "role": "", "geometry": [ { "lat": 50.7483739, "lon": 7.0668216 }, { "lat": 50.7483009, "lon": 7.0672440 }, { "lat": 50.7478400, "lon": 7.0692844 } ] }, { "type": "way", "ref": 130749935, "role": "", "geometry": [ { "lat": 50.7478400, "lon": 7.0692844 }, { "lat": 50.7477294, "lon": 7.0697394 }, { "lat": 50.7476187, "lon": 7.0701855 }, { "lat": 50.7474997, "lon": 7.0706232 }, { "lat": 50.7473468, "lon": 7.0711189 }, { "lat": 50.7472087, "lon": 7.0715434 }, { "lat": 50.7470472, "lon": 7.0719838 }, { "lat": 50.7469114, "lon": 7.0723163 }, { "lat": 50.7467733, "lon": 7.0726489 }, { "lat": 50.7465937, "lon": 7.0730580 }, { "lat": 50.7464112, "lon": 7.0734310 } ] }, { "type": "way", "ref": 32472877, "role": "", "geometry": [ { "lat": 50.8246828, "lon": 6.9651077 }, { "lat": 50.8253375, "lon": 6.9647718 }, { "lat": 50.8260000, "lon": 6.9645354 }, { "lat": 50.8266134, "lon": 6.9643649 }, { "lat": 50.8272671, "lon": 6.9642646 }, { "lat": 50.8278017, "lon": 6.9642349 } ] }, { "type": "way", "ref": 31798988, "role": "", "geometry": [ { "lat": 50.8278017, "lon": 6.9642349 }, { "lat": 50.8284805, "lon": 6.9642342 }, { "lat": 50.8294617, "lon": 6.9643395 }, { "lat": 50.8302437, "lon": 6.9644810 }, { "lat": 50.8309474, "lon": 6.9646345 } ] }, { "type": "way", "ref": 31798989, "role": "", "geometry": [ { "lat": 50.8590359, "lon": 6.9691023 }, { "lat": 50.8634113, "lon": 6.9695191 } ] }, { "type": "way", "ref": 235820560, "role": "", "geometry": [ { "lat": 50.8634113, "lon": 6.9695191 }, { "lat": 50.8656224, "lon": 6.9697185 } ] }, { "type": "way", "ref": 235820563, "role": "", "geometry": [ { "lat": 50.8656224, "lon": 6.9697185 }, { "lat": 50.8679633, "lon": 6.9699314 } ] }, { "type": "way", "ref": 235820564, "role": "", "geometry": [ { "lat": 50.8679633, "lon": 6.9699314 }, { "lat": 50.8691580, "lon": 6.9700171 }, { "lat": 50.8699302, "lon": 6.9700221 } ] }, { "type": "way", "ref": 235820570, "role": "", "geometry": [ { "lat": 50.8699302, "lon": 6.9700221 }, { "lat": 50.8717399, "lon": 6.9699121 }, { "lat": 50.8746263, "lon": 6.9695939 } ] }, { "type": "way", "ref": 32472855, "role": "", "geometry": [ { "lat": 50.8246253, "lon": 6.9648384 }, { "lat": 50.8242516, "lon": 6.9650453 } ] }, { "type": "way", "ref": 32472856, "role": "", "geometry": [ { "lat": 50.8242516, "lon": 6.9650453 }, { "lat": 50.8237235, "lon": 6.9653841 }, { "lat": 50.8232034, "lon": 6.9657948 }, { "lat": 50.8224317, "lon": 6.9665263 }, { "lat": 50.8216642, "lon": 6.9673886 }, { "lat": 50.8209037, "lon": 6.9684049 }, { "lat": 50.8201541, "lon": 6.9695500 }, { "lat": 50.8192181, "lon": 6.9711445 }, { "lat": 50.8138575, "lon": 6.9806731 } ] }, { "type": "way", "ref": 37881520, "role": "", "geometry": [ { "lat": 50.8138575, "lon": 6.9806731 }, { "lat": 50.8135770, "lon": 6.9811721 } ] }, { "type": "way", "ref": 37881519, "role": "", "geometry": [ { "lat": 50.8135770, "lon": 6.9811721 }, { "lat": 50.8113547, "lon": 6.9851361 } ] }, { "type": "way", "ref": 234434902, "role": "", "geometry": [ { "lat": 50.8113547, "lon": 6.9851361 }, { "lat": 50.8105743, "lon": 6.9865001 } ] }, { "type": "way", "ref": 32472875, "role": "", "geometry": [ { "lat": 50.8243279, "lon": 6.9653077 }, { "lat": 50.8246828, "lon": 6.9651077 } ] }, { "type": "way", "ref": 32473071, "role": "", "geometry": [ { "lat": 50.8309464, "lon": 6.9643368 }, { "lat": 50.8302815, "lon": 6.9641912 } ] }, { "type": "way", "ref": 128522486, "role": "", "geometry": [ { "lat": 50.8302815, "lon": 6.9641912 }, { "lat": 50.8294728, "lon": 6.9640448 }, { "lat": 50.8284964, "lon": 6.9639463 }, { "lat": 50.8277970, "lon": 6.9639432 } ] }, { "type": "way", "ref": 36447896, "role": "", "geometry": [ { "lat": 50.8277970, "lon": 6.9639432 }, { "lat": 50.8272631, "lon": 6.9639682 }, { "lat": 50.8265661, "lon": 6.9640827 }, { "lat": 50.8259717, "lon": 6.9642405 }, { "lat": 50.8252714, "lon": 6.9645096 }, { "lat": 50.8246253, "lon": 6.9648384 } ] }, { "type": "way", "ref": 32473075, "role": "", "geometry": [ { "lat": 50.8314332, "lon": 6.9644546 }, { "lat": 50.8309464, "lon": 6.9643368 } ] }, { "type": "way", "ref": 32473086, "role": "", "geometry": [ { "lat": 50.8309474, "lon": 6.9646345 }, { "lat": 50.8314534, "lon": 6.9647679 } ] }, { "type": "way", "ref": 32473087, "role": "", "geometry": [ { "lat": 50.8314534, "lon": 6.9647679 }, { "lat": 50.8386440, "lon": 6.9665955 } ] }, { "type": "way", "ref": 40033064, "role": "", "geometry": [ { "lat": 50.8386440, "lon": 6.9665955 }, { "lat": 50.8391695, "lon": 6.9667285 } ] }, { "type": "way", "ref": 189189059, "role": "", "geometry": [ { "lat": 50.8746263, "lon": 6.9695939 }, { "lat": 50.8760907, "lon": 6.9694358 } ] }, { "type": "way", "ref": 271008225, "role": "", "geometry": [ { "lat": 50.8760907, "lon": 6.9694358 }, { "lat": 50.8775484, "lon": 6.9692784 } ] }, { "type": "way", "ref": 41550921, "role": "", "geometry": [ { "lat": 50.8775484, "lon": 6.9692784 }, { "lat": 50.8797318, "lon": 6.9690108 } ] } ], "tags": { "TMC:cid_58:tabcd_1:Class": "Road", "TMC:cid_58:tabcd_1:LCLversion": "8.00", "TMC:cid_58:tabcd_1:LocationCode": "7142", "name": "Bundesautobahn 555", "network": "BAB", "operator": "Bundesrepublik Deutschland", "ref": "A 555", "route": "road", "type": "route", "wikipedia": "de:Bundesautobahn 555" } } ] } overpy-0.4/tests/json/relation-03.json0000644000175000017500000002460613022347635020205 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2016-11-23T20:28:03Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "relation", "id": 23092, "center": { "lat": 50.8176646, "lon": 7.0208539 }, "members": [ { "type": "way", "ref": 4334856, "role": "" }, { "type": "way", "ref": 234434903, "role": "" }, { "type": "way", "ref": 37881522, "role": "" }, { "type": "way", "ref": 37881521, "role": "" }, { "type": "way", "ref": 4356491, "role": "" }, { "type": "way", "ref": 235363211, "role": "" }, { "type": "way", "ref": 48290877, "role": "" }, { "type": "way", "ref": 210683519, "role": "" }, { "type": "way", "ref": 42743961, "role": "" }, { "type": "way", "ref": 210683522, "role": "" }, { "type": "way", "ref": 48290881, "role": "" }, { "type": "way", "ref": 235363214, "role": "" }, { "type": "way", "ref": 4400137, "role": "" }, { "type": "way", "ref": 230940375, "role": "" }, { "type": "way", "ref": 4400140, "role": "" }, { "type": "way", "ref": 4400142, "role": "" }, { "type": "way", "ref": 235824476, "role": "" }, { "type": "way", "ref": 4400143, "role": "" }, { "type": "way", "ref": 235824475, "role": "" }, { "type": "way", "ref": 178797123, "role": "" }, { "type": "way", "ref": 233553030, "role": "" }, { "type": "way", "ref": 4829989, "role": "" }, { "type": "way", "ref": 99834112, "role": "" }, { "type": "way", "ref": 133081219, "role": "" }, { "type": "way", "ref": 234434905, "role": "" }, { "type": "way", "ref": 20661567, "role": "" }, { "type": "way", "ref": 230941900, "role": "" }, { "type": "way", "ref": 20661568, "role": "" }, { "type": "way", "ref": 20661572, "role": "" }, { "type": "way", "ref": 230940374, "role": "" }, { "type": "way", "ref": 20661573, "role": "" }, { "type": "way", "ref": 20662817, "role": "" }, { "type": "way", "ref": 230941903, "role": "" }, { "type": "way", "ref": 20662819, "role": "" }, { "type": "way", "ref": 20662824, "role": "" }, { "type": "way", "ref": 20662827, "role": "" }, { "type": "way", "ref": 27492515, "role": "" }, { "type": "way", "ref": 129125122, "role": "" }, { "type": "way", "ref": 234434901, "role": "" }, { "type": "way", "ref": 234434904, "role": "" }, { "type": "way", "ref": 27492542, "role": "" }, { "type": "way", "ref": 27492543, "role": "" }, { "type": "way", "ref": 29233646, "role": "" }, { "type": "way", "ref": 235820561, "role": "" }, { "type": "way", "ref": 29233647, "role": "" }, { "type": "way", "ref": 235820559, "role": "" }, { "type": "way", "ref": 235820562, "role": "" }, { "type": "way", "ref": 29233648, "role": "" }, { "type": "way", "ref": 29382960, "role": "" }, { "type": "way", "ref": 271008229, "role": "" }, { "type": "way", "ref": 271008238, "role": "" }, { "type": "way", "ref": 271008230, "role": "" }, { "type": "way", "ref": 271008226, "role": "" }, { "type": "way", "ref": 40033062, "role": "" }, { "type": "way", "ref": 40033063, "role": "" }, { "type": "way", "ref": 29384561, "role": "" }, { "type": "way", "ref": 29384563, "role": "" }, { "type": "way", "ref": 271008224, "role": "" }, { "type": "way", "ref": 271008227, "role": "" }, { "type": "way", "ref": 271008237, "role": "" }, { "type": "way", "ref": 271008232, "role": "" }, { "type": "way", "ref": 271008239, "role": "" }, { "type": "way", "ref": 29384564, "role": "" }, { "type": "way", "ref": 31282638, "role": "" }, { "type": "way", "ref": 31282787, "role": "" }, { "type": "way", "ref": 383262762, "role": "" }, { "type": "way", "ref": 31304443, "role": "" }, { "type": "way", "ref": 128541594, "role": "" }, { "type": "way", "ref": 31304503, "role": "" }, { "type": "way", "ref": 31363881, "role": "" }, { "type": "way", "ref": 31363891, "role": "" }, { "type": "way", "ref": 31363892, "role": "" }, { "type": "way", "ref": 31363898, "role": "" }, { "type": "way", "ref": 31363910, "role": "" }, { "type": "way", "ref": 31364152, "role": "" }, { "type": "way", "ref": 31364158, "role": "" }, { "type": "way", "ref": 31364178, "role": "" }, { "type": "way", "ref": 31364384, "role": "" }, { "type": "way", "ref": 31364387, "role": "" }, { "type": "way", "ref": 31364484, "role": "" }, { "type": "way", "ref": 31364512, "role": "" }, { "type": "way", "ref": 31364656, "role": "" }, { "type": "way", "ref": 31364667, "role": "" }, { "type": "way", "ref": 271008234, "role": "" }, { "type": "way", "ref": 31364888, "role": "" }, { "type": "way", "ref": 122158730, "role": "" }, { "type": "way", "ref": 31364985, "role": "" }, { "type": "way", "ref": 271008235, "role": "" }, { "type": "way", "ref": 271008231, "role": "" }, { "type": "way", "ref": 271008233, "role": "" }, { "type": "way", "ref": 31365377, "role": "" }, { "type": "way", "ref": 31365425, "role": "" }, { "type": "way", "ref": 271008236, "role": "" }, { "type": "way", "ref": 36447898, "role": "" }, { "type": "way", "ref": 271008228, "role": "" }, { "type": "way", "ref": 31366812, "role": "" }, { "type": "way", "ref": 31366880, "role": "" }, { "type": "way", "ref": 31367017, "role": "" }, { "type": "way", "ref": 31367443, "role": "" }, { "type": "way", "ref": 31367449, "role": "" }, { "type": "way", "ref": 31367526, "role": "" }, { "type": "way", "ref": 31367534, "role": "" }, { "type": "way", "ref": 31369852, "role": "" }, { "type": "way", "ref": 449397558, "role": "" }, { "type": "way", "ref": 31797389, "role": "" }, { "type": "way", "ref": 31798039, "role": "" }, { "type": "way", "ref": 235363212, "role": "" }, { "type": "way", "ref": 156492546, "role": "" }, { "type": "way", "ref": 156492545, "role": "" }, { "type": "way", "ref": 130749935, "role": "" }, { "type": "way", "ref": 32472877, "role": "" }, { "type": "way", "ref": 31798988, "role": "" }, { "type": "way", "ref": 31798989, "role": "" }, { "type": "way", "ref": 235820560, "role": "" }, { "type": "way", "ref": 235820563, "role": "" }, { "type": "way", "ref": 235820564, "role": "" }, { "type": "way", "ref": 235820570, "role": "" }, { "type": "way", "ref": 32472855, "role": "" }, { "type": "way", "ref": 32472856, "role": "" }, { "type": "way", "ref": 37881520, "role": "" }, { "type": "way", "ref": 37881519, "role": "" }, { "type": "way", "ref": 234434902, "role": "" }, { "type": "way", "ref": 32472875, "role": "" }, { "type": "way", "ref": 32473071, "role": "" }, { "type": "way", "ref": 128522486, "role": "" }, { "type": "way", "ref": 36447896, "role": "" }, { "type": "way", "ref": 32473075, "role": "" }, { "type": "way", "ref": 32473086, "role": "" }, { "type": "way", "ref": 32473087, "role": "" }, { "type": "way", "ref": 40033064, "role": "" }, { "type": "way", "ref": 189189059, "role": "" }, { "type": "way", "ref": 271008225, "role": "" }, { "type": "way", "ref": 41550921, "role": "" } ], "tags": { "TMC:cid_58:tabcd_1:Class": "Road", "TMC:cid_58:tabcd_1:LCLversion": "8.00", "TMC:cid_58:tabcd_1:LocationCode": "7142", "name": "Bundesautobahn 555", "network": "BAB", "operator": "Bundesrepublik Deutschland", "ref": "A 555", "route": "road", "type": "route", "wikipedia": "de:Bundesautobahn 555" } } ] } overpy-0.4/tests/json/relation-02.json0000644000175000017500000000277313022347635020205 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T13:34:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 3233854233, "lat": 50.7494187, "lon": 7.1758731 }, { "type": "node", "id": 3233854234, "lat": 50.7494287, "lon": 7.1758731 }, { "type": "node", "id": 3233854235, "lat": 50.7494287, "lon": 7.1758731 }, { "type": "way", "id": 317146078, "nodes": [ 3233854233, 3233854234, 3233854235 ] }, { "type": "relation", "id": 2046898, "timestamp": "2014-12-15T13:13:11Z", "version": 12, "changeset": 17433822, "user": "Username", "uid": 12345, "members": [ { "type": "node", "ref": 3233854233, "role": "platform" }, { "type": "node", "ref": 3233854234, "role": "stop" }, { "type": "node", "ref": 3233854235, "role": "platform" }, { "type": "way", "ref": 317146078, "role": "" } ], "tags": { "from": "Here", "name": "Test relation", "ref": "609", "route": "bus", "to": "There", "type": "route" } } ] }overpy-0.4/tests/json/relation-01.json0000644000175000017500000000221713022347635020175 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-21T20:00:03Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "relation", "id": 2046898, "timestamp": "2014-12-15T13:13:11Z", "version": 12, "changeset": 17433822, "user": "Username", "uid": 12345, "members": [ { "type": "node", "ref": 507464632, "role": "platform" }, { "type": "node", "ref": 2252681768, "role": "stop" }, { "type": "node", "ref": 507464636, "role": "platform" }, { "type": "node", "ref": 1620886108, "role": "stop" }, { "type": "way", "ref": 4893348, "role": "" } ], "tags": { "from": "Here", "name": "Test relation", "ref": "609", "route": "bus", "to": "There", "type": "route" } } ] } overpy-0.4/tests/json/node-01.json0000644000175000017500000000124613022347635017306 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2014-12-14T12:58:02Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "node", "id": 50878400, "lat": 50.7461788, "lon": 7.1742257 }, { "type": "node", "id": 100793192, "lat": 50.7468472, "lon": 7.1709376, "tags": { "highway": "turning_circle" } }, { "type": "node", "id": 3233854234, "lat": 50.7494236, "lon": 7.1757664, "timestamp": "2014-12-14T07:27:19Z", "version": 1, "changeset": 23456789, "user": "TestUser", "uid": 345678 } ] }overpy-0.4/tests/json/area-01.json0000644000175000017500000000445413022347635017275 0ustar phibophibo00000000000000{ "version": 0.6, "generator": "Overpass API", "osm3s": { "timestamp_osm_base": "2016-11-22T21:04:02Z", "timestamp_areas_base": "2016-11-22T20:25:03Z", "copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL." }, "elements": [ { "type": "area", "id": 2448756446, "tags": { "addr:city": "Troisdorf", "addr:postcode": "53840", "area": "yes", "description": "Troisdorf Bahnsteig Gleis 9", "name": "Troisdorf", "public_transport": "platform", "railway": "platform", "ref": "9", "train": "yes", "wheelchair": "no", "wheelchair:description": "Plattformlift ist vorhanden, Betriebsbereitschaft nach 8 Jahren stillstand fraglich.", "width": "5" } } , { "type": "area", "id": 3600055060, "tags": { "TMC:cid_58:tabcd_1:Class": "Area", "TMC:cid_58:tabcd_1:LCLversion": "8.00", "TMC:cid_58:tabcd_1:LocationCode": "2550", "admin_level": "8", "boundary": "administrative", "de:amtlicher_gemeindeschluessel": "05382068", "de:place": "town", "de:regionalschluessel": "053820068068", "name": "Troisdorf", "name:prefix": "Stadt", "type": "boundary", "wikidata": "Q3900", "wikipedia": "de:Troisdorf" } } , { "type": "area", "id": 3605945175, "tags": { "addr:city": "Troisdorf", "addr:postcode": "53840", "description": "Troisdorf Bahnsteig Gleis 1+2", "local_ref": "1;2", "name": "Troisdorf", "public_transport": "platform", "railway": "platform", "ref": "1/2", "tactile_paving": "yes", "train": "yes", "type": "multipolygon", "wheelchair": "yes" } } , { "type": "area", "id": 3605945176, "tags": { "addr:city": "Troisdorf", "addr:postcode": "53840", "description": "Troisdorf Bahnsteig Gleis 5+6", "name": "Troisdorf", "phone": "+49 221 1411055", "public_transport": "platform", "railway": "platform", "ref": "5/6", "tactile_paving": "yes", "train": "yes", "type": "multipolygon", "wheelchair": "yes", "wheelchair:description": "Der Aufzug zu diesem Bahnsteig ist oft defekt, bitte informieren. Betriebszustand kann bei 3S-Zentrale erfragt werden (siehe Telefonnummer, aber Vorsicht, die sind nicht immer informiert!)", "width": "6" } } ] } overpy-0.4/overpy.egg-info/0000755000175000017500000000000013022347701016142 5ustar phibophibo00000000000000overpy-0.4/overpy.egg-info/top_level.txt0000644000175000017500000000001513022347701020670 0ustar phibophibo00000000000000overpy tests overpy-0.4/overpy.egg-info/not-zip-safe0000644000175000017500000000000113022347701020370 0ustar phibophibo00000000000000 overpy-0.4/overpy.egg-info/dependency_links.txt0000644000175000017500000000000113022347701022210 0ustar phibophibo00000000000000 overpy-0.4/overpy.egg-info/SOURCES.txt0000644000175000017500000000261113022347701020026 0ustar phibophibo00000000000000CHANGELOG.rst LICENSE MANIFEST.in README.rst setup.cfg setup.py docs/make.bat docs/source/api.rst docs/source/changelog.rst docs/source/conf.py docs/source/contributing.rst docs/source/example.rst docs/source/index.rst docs/source/introduction.rst examples/get_areas.py examples/get_nodes.py examples/get_ways.py overpy/__about__.py overpy/__init__.py overpy/exception.py overpy/helper.py overpy.egg-info/PKG-INFO overpy.egg-info/SOURCES.txt overpy.egg-info/dependency_links.txt overpy.egg-info/not-zip-safe overpy.egg-info/top_level.txt tests/__init__.py tests/base_class.py tests/test_exception.py tests/test_json.py tests/test_request.py tests/test_result.py tests/test_result_way.py tests/test_xml.py tests/json/area-01.json tests/json/node-01.json tests/json/relation-01.json tests/json/relation-02.json tests/json/relation-03.json tests/json/relation-04.json tests/json/result-expand-01.json tests/json/result-expand-02.json tests/json/result-way-01.json tests/json/result-way-02.json tests/json/result-way-03.json tests/json/way-01.json tests/json/way-02.json tests/json/way-03.json tests/json/way-04.json tests/response/bad-request-encoding.html tests/response/bad-request.html tests/xml/area-01.xml tests/xml/node-01.xml tests/xml/relation-01.xml tests/xml/relation-02.xml tests/xml/relation-03.xml tests/xml/relation-04.xml tests/xml/way-01.xml tests/xml/way-02.xml tests/xml/way-03.xml tests/xml/way-04.xmloverpy-0.4/overpy.egg-info/PKG-INFO0000644000175000017500000000766613022347701017256 0ustar phibophibo00000000000000Metadata-Version: 1.1 Name: overpy Version: 0.4 Summary: Python Wrapper to access the OpenStreepMap Overpass API Home-page: https://github.com/DinoTools/python-overpy Author: PhiBo (DinoTools) Author-email: UNKNOWN License: MIT Description: Python Overpass Wrapper ======================= A Python Wrapper to access the Overpass API. Have a look at the `documentation`_ to find additional information. .. image:: https://pypip.in/version/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: Latest Version .. image:: https://pypip.in/license/overpy/badge.svg :target: https://pypi.python.org/pypi/overpy/ :alt: License .. image:: https://travis-ci.org/DinoTools/python-overpy.svg?branch=master :target: https://travis-ci.org/DinoTools/python-overpy .. image:: https://coveralls.io/repos/DinoTools/python-overpy/badge.png?branch=master :target: https://coveralls.io/r/DinoTools/python-overpy?branch=master Features -------- * Query Overpass API * Parse JSON and XML response data * Additional helper functions Install ------- **Requirements:** Supported Python versions: * Python 2.7 * Python >= 3.2 * PyPy and PyPy3 **Install:** .. code-block:: console $ pip install overpy Examples -------- Additional examples can be found in the `documentation`_ and in the *examples* directory. .. code-block:: python import overpy api = overpy.Overpass() # fetch all ways and nodes result = api.query(""" way(50.746,7.154,50.748,7.157) ["highway"]; (._;>;); out body; """) for way in result.ways: print("Name: %s" % way.tags.get("name", "n/a")) print(" Highway: %s" % way.tags.get("highway", "n/a")) print(" Nodes:") for node in way.nodes: print(" Lat: %f, Lon: %f" % (node.lat, node.lon)) Helper ~~~~~~ Helper methods are available to provide easy access to often used requests. .. code-block:: python import overpy.helper # 3600062594 is the OSM id of Chemnitz and is the bounding box for the request street = overpy.helper.get_street( "Straße der Nationen", "3600062594" ) # this finds an intersection between Straße der Nationen and Carolastraße in Chemnitz intersection = overpy.helper.get_intersection( "Straße der Nationen", "Carolastraße", "3600062594" ) License ------- Published under the MIT (see LICENSE for more information) .. _`documentation`: http://python-overpy.readthedocs.org/ Keywords: OverPy Overpass OSM OpenStreetMap Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.2 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: Implementation :: CPython Classifier: Programming Language :: Python :: Implementation :: PyPy overpy-0.4/overpy/0000755000175000017500000000000013022347701014450 5ustar phibophibo00000000000000overpy-0.4/overpy/helper.py0000644000175000017500000000327413022347635016315 0ustar phibophibo00000000000000__author__ = 'mjob' import overpy def get_street(street, areacode, api=None): """ Retrieve streets in a given bounding area :param overpy.Overpass api: First street of intersection :param String street: Name of street :param String areacode: The OSM id of the bounding area :return: Parsed result :raises overpy.exception.OverPyException: If something bad happens. """ if api is None: api = overpy.Overpass() query = """ area(%s)->.location; ( way[highway][name="%s"](area.location); - ( way[highway=service](area.location); way[highway=track](area.location); ); ); out body; >; out skel qt; """ data = api.query(query % (areacode, street)) return data def get_intersection(street1, street2, areacode, api=None): """ Retrieve intersection of two streets in a given bounding area :param overpy.Overpass api: First street of intersection :param String street1: Name of first street of intersection :param String street2: Name of second street of intersection :param String areacode: The OSM id of the bounding area :return: List of intersections :raises overpy.exception.OverPyException: If something bad happens. """ if api is None: api = overpy.Overpass() query = """ area(%s)->.location; ( way[highway][name="%s"](area.location); node(w)->.n1; way[highway][name="%s"](area.location); node(w)->.n2; ); node.n1.n2; out meta; """ data = api.query(query % (areacode, street1, street2)) return data.get_nodes() overpy-0.4/overpy/exception.py0000644000175000017500000000572713022347635017041 0ustar phibophibo00000000000000class OverPyException(BaseException): """OverPy base exception""" pass class DataIncomplete(OverPyException): """ Raised if the requested data isn't available in the result. Try to improve the query or to resolve the missing data. """ def __init__(self, *args, **kwargs): OverPyException.__init__( self, "Data incomplete try to improve the query to resolve the missing data", *args, **kwargs ) class ElementDataWrongType(OverPyException): """ Raised if the provided element does not match the expected type. :param type_expected: The expected element type :type type_expected: String :param type_provided: The provided element type :type type_provided: String|None """ def __init__(self, type_expected, type_provided=None): self.type_expected = type_expected self.type_provided = type_provided def __str__(self): return "Type expected '%s' but '%s' provided" % ( self.type_expected, str(self.type_provided) ) class OverpassBadRequest(OverPyException): """ Raised if the Overpass API service returns a syntax error. :param query: The encoded query how it was send to the server :type query: Bytes :param msgs: List of error messages :type msgs: List """ def __init__(self, query, msgs=None): self.query = query if msgs is None: msgs = [] self.msgs = msgs def __str__(self): tmp_msgs = [] for tmp_msg in self.msgs: if not isinstance(tmp_msg, str): tmp_msg = str(tmp_msg) tmp_msgs.append(tmp_msg) return "\n".join(tmp_msgs) class OverpassGatewayTimeout(OverPyException): """ Raised if load of the Overpass API service is too high and it can't handle the request. """ def __init__(self): OverPyException.__init__(self, "Server load too high") class OverpassTooManyRequests(OverPyException): """ Raised if the Overpass API service returns a 429 status code. """ def __init__(self): OverPyException.__init__(self, "Too many requests") class OverpassUnknownContentType(OverPyException): """ Raised if the reported content type isn't handled by OverPy. :param content_type: The reported content type :type content_type: None or String """ def __init__(self, content_type): self.content_type = content_type def __str__(self): if self.content_type is None: return "No content type returned" return "Unknown content type: %s" % self.content_type class OverpassUnknownHTTPStatusCode(OverPyException): """ Raised if the returned HTTP status code isn't handled by OverPy. :param code: The HTTP status code :type code: Integer """ def __init__(self, code): self.code = code def __str__(self): return "Unknown/Unhandled status code: %d" % self.codeoverpy-0.4/overpy/__init__.py0000644000175000017500000014006613022347635016576 0ustar phibophibo00000000000000from collections import OrderedDict from datetime import datetime from decimal import Decimal from xml.sax import handler, make_parser import json import re import sys from overpy import exception from overpy.__about__ import ( __author__, __copyright__, __email__, __license__, __summary__, __title__, __uri__, __version__ ) PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 XML_PARSER_DOM = 1 XML_PARSER_SAX = 2 if PY2: from urllib2 import urlopen from urllib2 import HTTPError elif PY3: from urllib.request import urlopen from urllib.error import HTTPError def is_valid_type(element, cls): """ Test if an element is of a given type. :param Element() element: The element instance to test :param Element cls: The element class to test :return: False or True :rtype: Boolean """ return isinstance(element, cls) and element.id is not None class Overpass(object): """ Class to access the Overpass API """ default_read_chunk_size = 4096 default_url = "http://overpass-api.de/api/interpreter" def __init__(self, read_chunk_size=None, url=None, xml_parser=XML_PARSER_SAX): """ :param read_chunk_size: Max size of each chunk read from the server response :type read_chunk_size: Integer :param url: Optional URL of the Overpass server. Defaults to http://overpass-api.de/api/interpreter :type url: str :param xml_parser: The xml parser to use :type xml_parser: Integer """ self.url = self.default_url if url is not None: self.url = url self._regex_extract_error_msg = re.compile(b"\(?P\") self._regex_remove_tag = re.compile(b"<[^>]*?>") if read_chunk_size is None: read_chunk_size = self.default_read_chunk_size self.read_chunk_size = read_chunk_size self.xml_parser = xml_parser def query(self, query): """ Query the Overpass API :param String|Bytes query: The query string in Overpass QL :return: The parsed result :rtype: overpy.Result """ if not isinstance(query, bytes): query = query.encode("utf-8") try: f = urlopen(self.url, query) except HTTPError as e: f = e response = f.read(self.read_chunk_size) while True: data = f.read(self.read_chunk_size) if len(data) == 0: break response = response + data f.close() if f.code == 200: if PY2: http_info = f.info() content_type = http_info.getheader("content-type") else: content_type = f.getheader("Content-Type") if content_type == "application/json": return self.parse_json(response) if content_type == "application/osm3s+xml": return self.parse_xml(response) raise exception.OverpassUnknownContentType(content_type) if f.code == 400: msgs = [] for msg in self._regex_extract_error_msg.finditer(response): tmp = self._regex_remove_tag.sub(b"", msg.group("msg")) try: tmp = tmp.decode("utf-8") except UnicodeDecodeError: tmp = repr(tmp) msgs.append(tmp) raise exception.OverpassBadRequest( query, msgs=msgs ) if f.code == 429: raise exception.OverpassTooManyRequests if f.code == 504: raise exception.OverpassGatewayTimeout raise exception.OverpassUnknownHTTPStatusCode(f.code) def parse_json(self, data, encoding="utf-8"): """ Parse raw response from Overpass service. :param data: Raw JSON Data :type data: String or Bytes :param encoding: Encoding to decode byte string :type encoding: String :return: Result object :rtype: overpy.Result """ if isinstance(data, bytes): data = data.decode(encoding) data = json.loads(data, parse_float=Decimal) return Result.from_json(data, api=self) def parse_xml(self, data, encoding="utf-8", parser=None): """ :param data: Raw XML Data :type data: String or Bytes :param encoding: Encoding to decode byte string :type encoding: String :return: Result object :rtype: overpy.Result """ if parser is None: parser = self.xml_parser if isinstance(data, bytes): data = data.decode(encoding) if PY2 and not isinstance(data, str): # Python 2.x: Convert unicode strings data = data.encode(encoding) return Result.from_xml(data, api=self, parser=parser) class Result(object): """ Class to handle the result. """ def __init__(self, elements=None, api=None): """ :param List elements: :param api: :type api: overpy.Overpass """ if elements is None: elements = [] self._areas = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Area)) self._nodes = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Node)) self._ways = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Way)) self._relations = OrderedDict((element.id, element) for element in elements if is_valid_type(element, Relation)) self._class_collection_map = {Node: self._nodes, Way: self._ways, Relation: self._relations, Area: self._areas} self.api = api def expand(self, other): """ Add all elements from an other result to the list of elements of this result object. It is used by the auto resolve feature. :param other: Expand the result with the elements from this result. :type other: overpy.Result :raises ValueError: If provided parameter is not instance of :class:`overpy.Result` """ if not isinstance(other, Result): raise ValueError("Provided argument has to be instance of overpy:Result()") other_collection_map = {Node: other.nodes, Way: other.ways, Relation: other.relations, Area: other.areas} for element_type, own_collection in self._class_collection_map.items(): for element in other_collection_map[element_type]: if is_valid_type(element, element_type) and element.id not in own_collection: own_collection[element.id] = element def append(self, element): """ Append a new element to the result. :param element: The element to append :type element: overpy.Element """ if is_valid_type(element, Element): self._class_collection_map[element.__class__].setdefault(element.id, element) def get_elements(self, filter_cls, elem_id=None): """ Get a list of elements from the result and filter the element type by a class. :param filter_cls: :param elem_id: ID of the object :type elem_id: Integer :return: List of available elements :rtype: List """ result = [] if elem_id is not None: try: result = [self._class_collection_map[filter_cls][elem_id]] except KeyError: result = [] else: for e in self._class_collection_map[filter_cls].values(): result.append(e) return result def get_ids(self, filter_cls): """ :param filter_cls: :return: """ return list(self._class_collection_map[filter_cls].keys()) def get_node_ids(self): return self.get_ids(filter_cls=Node) def get_way_ids(self): return self.get_ids(filter_cls=Way) def get_relation_ids(self): return self.get_ids(filter_cls=Relation) def get_area_ids(self): return self.get_ids(filter_cls=Area) @classmethod def from_json(cls, data, api=None): """ Create a new instance and load data from json object. :param data: JSON data returned by the Overpass API :type data: Dict :param api: :type api: overpy.Overpass :return: New instance of Result object :rtype: overpy.Result """ result = cls(api=api) for elem_cls in [Node, Way, Relation, Area]: for element in data.get("elements", []): e_type = element.get("type") if hasattr(e_type, "lower") and e_type.lower() == elem_cls._type_value: result.append(elem_cls.from_json(element, result=result)) return result @classmethod def from_xml(cls, data, api=None, parser=XML_PARSER_SAX): """ Create a new instance and load data from xml object. :param data: Root element :type data: xml.etree.ElementTree.Element :param api: :type api: Overpass :param parser: Specify the parser to use(DOM or SAX) :type parser: Integer :return: New instance of Result object :rtype: Result """ result = cls(api=api) if parser == XML_PARSER_DOM: import xml.etree.ElementTree as ET root = ET.fromstring(data) for elem_cls in [Node, Way, Relation, Area]: for child in root: if child.tag.lower() == elem_cls._type_value: result.append(elem_cls.from_xml(child, result=result)) elif parser == XML_PARSER_SAX: if PY2: from StringIO import StringIO else: from io import StringIO source = StringIO(data) sax_handler = OSMSAXHandler(result) parser = make_parser() parser.setContentHandler(sax_handler) parser.parse(source) else: # ToDo: better exception raise Exception("Unknown XML parser") return result def get_area(self, area_id, resolve_missing=False): """ Get an area by its ID. :param area_id: The area ID :type area_id: Integer :param resolve_missing: Query the Overpass API if the area is missing in the result set. :return: The area :rtype: overpy.Area :raises overpy.exception.DataIncomplete: The requested way is not available in the result cache. :raises overpy.exception.DataIncomplete: If resolve_missing is True and the area can't be resolved. """ areas = self.get_areas(area_id=area_id) if len(areas) == 0: if resolve_missing is False: raise exception.DataIncomplete("Resolve missing area is disabled") query = ("\n" "[out:json];\n" "area({area_id});\n" "out body;\n" ) query = query.format( area_id=area_id ) tmp_result = self.api.query(query) self.expand(tmp_result) areas = self.get_areas(area_id=area_id) if len(areas) == 0: raise exception.DataIncomplete("Unable to resolve requested areas") return areas[0] def get_areas(self, area_id=None, **kwargs): """ Alias for get_elements() but filter the result by Area :param area_id: The Id of the area :type area_id: Integer :return: List of elements """ return self.get_elements(Area, elem_id=area_id, **kwargs) def get_node(self, node_id, resolve_missing=False): """ Get a node by its ID. :param node_id: The node ID :type node_id: Integer :param resolve_missing: Query the Overpass API if the node is missing in the result set. :return: The node :rtype: overpy.Node :raises overpy.exception.DataIncomplete: At least one referenced node is not available in the result cache. :raises overpy.exception.DataIncomplete: If resolve_missing is True and at least one node can't be resolved. """ nodes = self.get_nodes(node_id=node_id) if len(nodes) == 0: if not resolve_missing: raise exception.DataIncomplete("Resolve missing nodes is disabled") query = ("\n" "[out:json];\n" "node({node_id});\n" "out body;\n" ) query = query.format( node_id=node_id ) tmp_result = self.api.query(query) self.expand(tmp_result) nodes = self.get_nodes(node_id=node_id) if len(nodes) == 0: raise exception.DataIncomplete("Unable to resolve all nodes") return nodes[0] def get_nodes(self, node_id=None, **kwargs): """ Alias for get_elements() but filter the result by Node() :param node_id: The Id of the node :type node_id: Integer :return: List of elements """ return self.get_elements(Node, elem_id=node_id, **kwargs) def get_relation(self, rel_id, resolve_missing=False): """ Get a relation by its ID. :param rel_id: The relation ID :type rel_id: Integer :param resolve_missing: Query the Overpass API if the relation is missing in the result set. :return: The relation :rtype: overpy.Relation :raises overpy.exception.DataIncomplete: The requested relation is not available in the result cache. :raises overpy.exception.DataIncomplete: If resolve_missing is True and the relation can't be resolved. """ relations = self.get_relations(rel_id=rel_id) if len(relations) == 0: if resolve_missing is False: raise exception.DataIncomplete("Resolve missing relations is disabled") query = ("\n" "[out:json];\n" "relation({relation_id});\n" "out body;\n" ) query = query.format( relation_id=rel_id ) tmp_result = self.api.query(query) self.expand(tmp_result) relations = self.get_relations(rel_id=rel_id) if len(relations) == 0: raise exception.DataIncomplete("Unable to resolve requested reference") return relations[0] def get_relations(self, rel_id=None, **kwargs): """ Alias for get_elements() but filter the result by Relation :param rel_id: Id of the relation :type rel_id: Integer :return: List of elements """ return self.get_elements(Relation, elem_id=rel_id, **kwargs) def get_way(self, way_id, resolve_missing=False): """ Get a way by its ID. :param way_id: The way ID :type way_id: Integer :param resolve_missing: Query the Overpass API if the way is missing in the result set. :return: The way :rtype: overpy.Way :raises overpy.exception.DataIncomplete: The requested way is not available in the result cache. :raises overpy.exception.DataIncomplete: If resolve_missing is True and the way can't be resolved. """ ways = self.get_ways(way_id=way_id) if len(ways) == 0: if resolve_missing is False: raise exception.DataIncomplete("Resolve missing way is disabled") query = ("\n" "[out:json];\n" "way({way_id});\n" "out body;\n" ) query = query.format( way_id=way_id ) tmp_result = self.api.query(query) self.expand(tmp_result) ways = self.get_ways(way_id=way_id) if len(ways) == 0: raise exception.DataIncomplete("Unable to resolve requested way") return ways[0] def get_ways(self, way_id=None, **kwargs): """ Alias for get_elements() but filter the result by Way :param way_id: The Id of the way :type way_id: Integer :return: List of elements """ return self.get_elements(Way, elem_id=way_id, **kwargs) area_ids = property(get_area_ids) areas = property(get_areas) node_ids = property(get_node_ids) nodes = property(get_nodes) relation_ids = property(get_relation_ids) relations = property(get_relations) way_ids = property(get_way_ids) ways = property(get_ways) class Element(object): """ Base element """ def __init__(self, attributes=None, result=None, tags=None): """ :param attributes: Additional attributes :type attributes: Dict :param result: The result object this element belongs to :param tags: List of tags :type tags: Dict """ self._result = result # Try to convert some common attributes # http://wiki.openstreetmap.org/wiki/Elements#Common_attributes self._attribute_modifiers = { "changeset": int, "timestamp": lambda ts: datetime.strptime(ts, "%Y-%m-%dT%H:%M:%SZ"), "uid": int, "version": int, "visible": lambda v: v.lower() == "true" } self.attributes = attributes for n, m in self._attribute_modifiers.items(): if n in self.attributes: self.attributes[n] = m(self.attributes[n]) self.id = None self.tags = tags @classmethod def get_center_from_json(cls, data): """ Get center information from json data :param data: json data :return: tuple with two elements: lat and lon :rtype: tuple """ center_lat = None center_lon = None center = data.get("center") if isinstance(center, dict): center_lat = center.get("lat") center_lon = center.get("lon") if center_lat is None or center_lon is None: raise ValueError("Unable to get lat or lon of way center.") center_lat = Decimal(center_lat) center_lon = Decimal(center_lon) return (center_lat, center_lon) @classmethod def get_center_from_xml_dom(cls, sub_child): center_lat = sub_child.attrib.get("lat") center_lon = sub_child.attrib.get("lon") if center_lat is None or center_lon is None: raise ValueError("Unable to get lat or lon of way center.") center_lat = Decimal(center_lat) center_lon = Decimal(center_lon) return center_lat, center_lon class Area(Element): """ Class to represent an element of type area """ _type_value = "area" def __init__(self, area_id=None, **kwargs): """ :param area_id: Id of the area element :type area_id: Integer :param kwargs: Additional arguments are passed directly to the parent class """ Element.__init__(self, **kwargs) #: The id of the way self.id = area_id def __repr__(self): return "".format(self.id) @classmethod def from_json(cls, data, result=None): """ Create new Area element from JSON data :param data: Element data from JSON :type data: Dict :param result: The result this element belongs to :type result: overpy.Result :return: New instance of Way :rtype: overpy.Area :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. """ if data.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=data.get("type") ) tags = data.get("tags", {}) area_id = data.get("id") attributes = {} ignore = ["id", "tags", "type"] for n, v in data.items(): if n in ignore: continue attributes[n] = v return cls(area_id=area_id, attributes=attributes, tags=tags, result=result) @classmethod def from_xml(cls, child, result=None): """ Create new way element from XML data :param child: XML node to be parsed :type child: xml.etree.ElementTree.Element :param result: The result this node belongs to :type result: overpy.Result :return: New Way oject :rtype: overpy.Way :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match :raises ValueError: If the ref attribute of the xml node is not provided :raises ValueError: If a tag doesn't have a name """ if child.tag.lower() != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=child.tag.lower() ) tags = {} for sub_child in child: if sub_child.tag.lower() == "tag": name = sub_child.attrib.get("k") if name is None: raise ValueError("Tag without name/key.") value = sub_child.attrib.get("v") tags[name] = value area_id = child.attrib.get("id") if area_id is not None: area_id = int(area_id) attributes = {} ignore = ["id"] for n, v in child.attrib.items(): if n in ignore: continue attributes[n] = v return cls(area_id=area_id, attributes=attributes, tags=tags, result=result) class Node(Element): """ Class to represent an element of type node """ _type_value = "node" def __init__(self, node_id=None, lat=None, lon=None, **kwargs): """ :param lat: Latitude :type lat: Decimal or Float :param lon: Longitude :type long: Decimal or Float :param node_id: Id of the node element :type node_id: Integer :param kwargs: Additional arguments are passed directly to the parent class """ Element.__init__(self, **kwargs) self.id = node_id self.lat = lat self.lon = lon def __repr__(self): return "".format(self.id, self.lat, self.lon) @classmethod def from_json(cls, data, result=None): """ Create new Node element from JSON data :param data: Element data from JSON :type data: Dict :param result: The result this element belongs to :type result: overpy.Result :return: New instance of Node :rtype: overpy.Node :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. """ if data.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=data.get("type") ) tags = data.get("tags", {}) node_id = data.get("id") lat = data.get("lat") lon = data.get("lon") attributes = {} ignore = ["type", "id", "lat", "lon", "tags"] for n, v in data.items(): if n in ignore: continue attributes[n] = v return cls(node_id=node_id, lat=lat, lon=lon, tags=tags, attributes=attributes, result=result) @classmethod def from_xml(cls, child, result=None): """ Create new way element from XML data :param child: XML node to be parsed :type child: xml.etree.ElementTree.Element :param result: The result this node belongs to :type result: overpy.Result :return: New Way oject :rtype: overpy.Node :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match :raises ValueError: If a tag doesn't have a name """ if child.tag.lower() != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=child.tag.lower() ) tags = {} for sub_child in child: if sub_child.tag.lower() == "tag": name = sub_child.attrib.get("k") if name is None: raise ValueError("Tag without name/key.") value = sub_child.attrib.get("v") tags[name] = value node_id = child.attrib.get("id") if node_id is not None: node_id = int(node_id) lat = child.attrib.get("lat") if lat is not None: lat = Decimal(lat) lon = child.attrib.get("lon") if lon is not None: lon = Decimal(lon) attributes = {} ignore = ["id", "lat", "lon"] for n, v in child.attrib.items(): if n in ignore: continue attributes[n] = v return cls(node_id=node_id, lat=lat, lon=lon, tags=tags, attributes=attributes, result=result) class Way(Element): """ Class to represent an element of type way """ _type_value = "way" def __init__(self, way_id=None, center_lat=None, center_lon=None, node_ids=None, **kwargs): """ :param node_ids: List of node IDs :type node_ids: List or Tuple :param way_id: Id of the way element :type way_id: Integer :param kwargs: Additional arguments are passed directly to the parent class """ Element.__init__(self, **kwargs) #: The id of the way self.id = way_id #: List of Ids of the associated nodes self._node_ids = node_ids #: The lat/lon of the center of the way (optional depending on query) self.center_lat = center_lat self.center_lon = center_lon def __repr__(self): return "".format(self.id, self._node_ids) @property def nodes(self): """ List of nodes associated with the way. """ return self.get_nodes() def get_nodes(self, resolve_missing=False): """ Get the nodes defining the geometry of the way :param resolve_missing: Try to resolve missing nodes. :type resolve_missing: Boolean :return: List of nodes :rtype: List of overpy.Node :raises overpy.exception.DataIncomplete: At least one referenced node is not available in the result cache. :raises overpy.exception.DataIncomplete: If resolve_missing is True and at least one node can't be resolved. """ result = [] resolved = False for node_id in self._node_ids: try: node = self._result.get_node(node_id) except exception.DataIncomplete: node = None if node is not None: result.append(node) continue if not resolve_missing: raise exception.DataIncomplete("Resolve missing nodes is disabled") # We tried to resolve the data but some nodes are still missing if resolved: raise exception.DataIncomplete("Unable to resolve all nodes") query = ("\n" "[out:json];\n" "way({way_id});\n" "node(w);\n" "out body;\n" ) query = query.format( way_id=self.id ) tmp_result = self._result.api.query(query) self._result.expand(tmp_result) resolved = True try: node = self._result.get_node(node_id) except exception.DataIncomplete: node = None if node is None: raise exception.DataIncomplete("Unable to resolve all nodes") result.append(node) return result @classmethod def from_json(cls, data, result=None): """ Create new Way element from JSON data :param data: Element data from JSON :type data: Dict :param result: The result this element belongs to :type result: overpy.Result :return: New instance of Way :rtype: overpy.Way :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. """ if data.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=data.get("type") ) tags = data.get("tags", {}) way_id = data.get("id") node_ids = data.get("nodes") (center_lat, center_lon) = cls.get_center_from_json(data=data) attributes = {} ignore = ["center", "id", "nodes", "tags", "type"] for n, v in data.items(): if n in ignore: continue attributes[n] = v return cls( attributes=attributes, center_lat=center_lat, center_lon=center_lon, node_ids=node_ids, tags=tags, result=result, way_id=way_id ) @classmethod def from_xml(cls, child, result=None): """ Create new way element from XML data :param child: XML node to be parsed :type child: xml.etree.ElementTree.Element :param result: The result this node belongs to :type result: overpy.Result :return: New Way oject :rtype: overpy.Way :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match :raises ValueError: If the ref attribute of the xml node is not provided :raises ValueError: If a tag doesn't have a name """ if child.tag.lower() != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=child.tag.lower() ) tags = {} node_ids = [] center_lat = None center_lon = None for sub_child in child: if sub_child.tag.lower() == "tag": name = sub_child.attrib.get("k") if name is None: raise ValueError("Tag without name/key.") value = sub_child.attrib.get("v") tags[name] = value if sub_child.tag.lower() == "nd": ref_id = sub_child.attrib.get("ref") if ref_id is None: raise ValueError("Unable to find required ref value.") ref_id = int(ref_id) node_ids.append(ref_id) if sub_child.tag.lower() == "center": (center_lat, center_lon) = cls.get_center_from_xml_dom(sub_child=sub_child) way_id = child.attrib.get("id") if way_id is not None: way_id = int(way_id) attributes = {} ignore = ["id"] for n, v in child.attrib.items(): if n in ignore: continue attributes[n] = v return cls(way_id=way_id, center_lat=center_lat, center_lon=center_lon, attributes=attributes, node_ids=node_ids, tags=tags, result=result) class Relation(Element): """ Class to represent an element of type relation """ _type_value = "relation" def __init__(self, rel_id=None, center_lat=None, center_lon=None, members=None, **kwargs): """ :param members: :param rel_id: Id of the relation element :type rel_id: Integer :param kwargs: :return: """ Element.__init__(self, **kwargs) self.id = rel_id self.members = members #: The lat/lon of the center of the way (optional depending on query) self.center_lat = center_lat self.center_lon = center_lon def __repr__(self): return "".format(self.id) @classmethod def from_json(cls, data, result=None): """ Create new Relation element from JSON data :param data: Element data from JSON :type data: Dict :param result: The result this element belongs to :type result: overpy.Result :return: New instance of Relation :rtype: overpy.Relation :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. """ if data.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=data.get("type") ) tags = data.get("tags", {}) rel_id = data.get("id") (center_lat, center_lon) = cls.get_center_from_json(data=data) members = [] supported_members = [RelationNode, RelationWay, RelationRelation] for member in data.get("members", []): type_value = member.get("type") for member_cls in supported_members: if member_cls._type_value == type_value: members.append( member_cls.from_json( member, result=result ) ) attributes = {} ignore = ["id", "members", "tags", "type"] for n, v in data.items(): if n in ignore: continue attributes[n] = v return cls( rel_id=rel_id, attributes=attributes, center_lat=center_lat, center_lon=center_lon, members=members, tags=tags, result=result ) @classmethod def from_xml(cls, child, result=None): """ Create new way element from XML data :param child: XML node to be parsed :type child: xml.etree.ElementTree.Element :param result: The result this node belongs to :type result: overpy.Result :return: New Way oject :rtype: overpy.Relation :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match :raises ValueError: If a tag doesn't have a name """ if child.tag.lower() != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=child.tag.lower() ) tags = {} members = [] center_lat = None center_lon = None supported_members = [RelationNode, RelationWay, RelationRelation, RelationArea] for sub_child in child: if sub_child.tag.lower() == "tag": name = sub_child.attrib.get("k") if name is None: raise ValueError("Tag without name/key.") value = sub_child.attrib.get("v") tags[name] = value if sub_child.tag.lower() == "member": type_value = sub_child.attrib.get("type") for member_cls in supported_members: if member_cls._type_value == type_value: members.append( member_cls.from_xml( sub_child, result=result ) ) if sub_child.tag.lower() == "center": (center_lat, center_lon) = cls.get_center_from_xml_dom(sub_child=sub_child) rel_id = child.attrib.get("id") if rel_id is not None: rel_id = int(rel_id) attributes = {} ignore = ["id"] for n, v in child.attrib.items(): if n in ignore: continue attributes[n] = v return cls( rel_id=rel_id, attributes=attributes, center_lat=center_lat, center_lon=center_lon, members=members, tags=tags, result=result ) class RelationMember(object): """ Base class to represent a member of a relation. """ def __init__(self, attributes=None, geometry=None, ref=None, role=None, result=None): """ :param ref: Reference Id :type ref: Integer :param role: The role of the relation member :type role: String :param result: """ self.ref = ref self._result = result self.role = role self.attributes = attributes self.geometry = geometry @classmethod def from_json(cls, data, result=None): """ Create new RelationMember element from JSON data :param child: Element data from JSON :type child: Dict :param result: The result this element belongs to :type result: overpy.Result :return: New instance of RelationMember :rtype: overpy.RelationMember :raises overpy.exception.ElementDataWrongType: If type value of the passed JSON data does not match. """ if data.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=data.get("type") ) ref = data.get("ref") role = data.get("role") attributes = {} ignore = ["geometry", "type", "ref", "role"] for n, v in data.items(): if n in ignore: continue attributes[n] = v geometry = data.get("geometry") if isinstance(geometry, list): geometry_orig = geometry geometry = [] for v in geometry_orig: geometry.append( RelationWayGeometryValue( lat=v.get("lat"), lon=v.get("lon") ) ) else: geometry = None return cls( attributes=attributes, geometry=geometry, ref=ref, role=role, result=result ) @classmethod def from_xml(cls, child, result=None): """ Create new RelationMember from XML data :param child: XML node to be parsed :type child: xml.etree.ElementTree.Element :param result: The result this element belongs to :type result: overpy.Result :return: New relation member oject :rtype: overpy.RelationMember :raises overpy.exception.ElementDataWrongType: If name of the xml child node doesn't match """ if child.attrib.get("type") != cls._type_value: raise exception.ElementDataWrongType( type_expected=cls._type_value, type_provided=child.tag.lower() ) ref = child.attrib.get("ref") if ref is not None: ref = int(ref) role = child.attrib.get("role") attributes = {} ignore = ["geometry", "ref", "role", "type"] for n, v in child.attrib.items(): if n in ignore: continue attributes[n] = v geometry = None for sub_child in child: if sub_child.tag.lower() == "nd": if geometry is None: geometry = [] geometry.append( RelationWayGeometryValue( lat=Decimal(sub_child.attrib["lat"]), lon=Decimal(sub_child.attrib["lon"]) ) ) return cls( attributes=attributes, geometry=geometry, ref=ref, role=role, result=result ) class RelationNode(RelationMember): _type_value = "node" def resolve(self, resolve_missing=False): return self._result.get_node(self.ref, resolve_missing=resolve_missing) def __repr__(self): return "".format(self.ref, self.role) class RelationWay(RelationMember): _type_value = "way" def resolve(self, resolve_missing=False): return self._result.get_way(self.ref, resolve_missing=resolve_missing) def __repr__(self): return "".format(self.ref, self.role) class RelationWayGeometryValue(object): def __init__(self, lat, lon): self.lat = lat self.lon = lon def __repr__(self): return "".format(self.lat, self.lon) class RelationRelation(RelationMember): _type_value = "relation" def resolve(self, resolve_missing=False): return self._result.get_relation(self.ref, resolve_missing=resolve_missing) def __repr__(self): return "".format(self.ref, self.role) class RelationArea(RelationMember): _type_value = "area" def resolve(self, resolve_missing=False): return self._result.get_area(self.ref, resolve_missing=resolve_missing) def __repr__(self): return "".format(self.ref, self.role) class OSMSAXHandler(handler.ContentHandler): """ SAX parser for Overpass XML response. """ #: Tuple of opening elements to ignore ignore_start = ('osm', 'meta', 'note', 'bounds', 'remark') #: Tuple of closing elements to ignore ignore_end = ('osm', 'meta', 'note', 'bounds', 'remark', 'tag', 'nd', 'center') def __init__(self, result): """ :param result: Append results to this result set. :type result: overpy.Result """ handler.ContentHandler.__init__(self) self._result = result self._curr = {} #: Current relation member object self.cur_relation_member = None def startElement(self, name, attrs): """ Handle opening elements. :param name: Name of the element :type name: String :param attrs: Attributes of the element :type attrs: Dict """ if name in self.ignore_start: return try: handler = getattr(self, '_handle_start_%s' % name) except AttributeError: raise KeyError("Unknown element start '%s'" % name) handler(attrs) def endElement(self, name): """ Handle closing elements :param name: Name of the element :type name: String """ if name in self.ignore_end: return try: handler = getattr(self, '_handle_end_%s' % name) except AttributeError: raise KeyError("Unknown element end '%s'" % name) handler() def _handle_start_center(self, attrs): """ Handle opening center element :param attrs: Attributes of the element :type attrs: Dict """ center_lat = attrs.get("lat") center_lon = attrs.get("lon") if center_lat is None or center_lon is None: raise ValueError("Unable to get lat or lon of way center.") self._curr["center_lat"] = Decimal(center_lat) self._curr["center_lon"] = Decimal(center_lon) def _handle_start_tag(self, attrs): """ Handle opening tag element :param attrs: Attributes of the element :type attrs: Dict """ try: tag_key = attrs['k'] except KeyError: raise ValueError("Tag without name/key.") self._curr['tags'][tag_key] = attrs.get('v') def _handle_start_node(self, attrs): """ Handle opening node element :param attrs: Attributes of the element :type attrs: Dict """ self._curr = { 'attributes': dict(attrs), 'lat': None, 'lon': None, 'node_id': None, 'tags': {} } if attrs.get('id', None) is not None: self._curr['node_id'] = int(attrs['id']) del self._curr['attributes']['id'] if attrs.get('lat', None) is not None: self._curr['lat'] = Decimal(attrs['lat']) del self._curr['attributes']['lat'] if attrs.get('lon', None) is not None: self._curr['lon'] = Decimal(attrs['lon']) del self._curr['attributes']['lon'] def _handle_end_node(self): """ Handle closing node element """ self._result.append(Node(result=self._result, **self._curr)) self._curr = {} def _handle_start_way(self, attrs): """ Handle opening way element :param attrs: Attributes of the element :type attrs: Dict """ self._curr = { 'center_lat': None, 'center_lon': None, 'attributes': dict(attrs), 'node_ids': [], 'tags': {}, 'way_id': None } if attrs.get('id', None) is not None: self._curr['way_id'] = int(attrs['id']) del self._curr['attributes']['id'] def _handle_end_way(self): """ Handle closing way element """ self._result.append(Way(result=self._result, **self._curr)) self._curr = {} def _handle_start_area(self, attrs): """ Handle opening area element :param attrs: Attributes of the element :type attrs: Dict """ self._curr = { 'attributes': dict(attrs), 'tags': {}, 'area_id': None } if attrs.get('id', None) is not None: self._curr['area_id'] = int(attrs['id']) del self._curr['attributes']['id'] def _handle_end_area(self): """ Handle closing area element """ self._result.append(Area(result=self._result, **self._curr)) self._curr = {} def _handle_start_nd(self, attrs): """ Handle opening nd element :param attrs: Attributes of the element :type attrs: Dict """ if isinstance(self.cur_relation_member, RelationWay): if self.cur_relation_member.geometry is None: self.cur_relation_member.geometry = [] self.cur_relation_member.geometry.append( RelationWayGeometryValue( lat=Decimal(attrs["lat"]), lon=Decimal(attrs["lon"]) ) ) else: try: node_ref = attrs['ref'] except KeyError: raise ValueError("Unable to find required ref value.") self._curr['node_ids'].append(int(node_ref)) def _handle_start_relation(self, attrs): """ Handle opening relation element :param attrs: Attributes of the element :type attrs: Dict """ self._curr = { 'attributes': dict(attrs), 'members': [], 'rel_id': None, 'tags': {} } if attrs.get('id', None) is not None: self._curr['rel_id'] = int(attrs['id']) del self._curr['attributes']['id'] def _handle_end_relation(self): """ Handle closing relation element """ self._result.append(Relation(result=self._result, **self._curr)) self._curr = {} def _handle_start_member(self, attrs): """ Handle opening member element :param attrs: Attributes of the element :type attrs: Dict """ params = { # ToDo: Parse attributes 'attributes': {}, 'ref': None, 'result': self._result, 'role': None } if attrs.get('ref', None): params['ref'] = int(attrs['ref']) if attrs.get('role', None): params['role'] = attrs['role'] cls_map = { "area": RelationArea, "node": RelationNode, "relation": RelationRelation, "way": RelationWay } cls = cls_map.get(attrs["type"]) if cls is None: raise ValueError("Undefined type for member: '%s'" % attrs['type']) self.cur_relation_member = cls(**params) self._curr['members'].append(self.cur_relation_member) def _handle_end_member(self): self.cur_relation_member = None overpy-0.4/overpy/__about__.py0000644000175000017500000000070513022347635016740 0ustar phibophibo00000000000000__all__ = [ "__author__", "__copyright__", "__email__", "__license__", "__summary__", "__title__", "__uri__", "__version__", ] __title__ = "overpy" __summary__ = "Python Wrapper to access the OpenStreepMap Overpass API" __uri__ = "https://github.com/DinoTools/python-overpy" __version__ = "0.4" __author__ = "PhiBo (DinoTools)" __email__ = "" __license__ = "MIT" __copyright__ = "Copyright 2014-2016 %s" % __author__ overpy-0.4/examples/0000755000175000017500000000000013022347701014742 5ustar phibophibo00000000000000overpy-0.4/examples/get_ways.py0000755000175000017500000000067213022347635017154 0ustar phibophibo00000000000000#!/usr/bin/env python import overpy api = overpy.Overpass() # fetch all ways and nodes result = api.query(""" way(50.746,7.154,50.748,7.157) ["highway"]; (._;>;); out body; """) for way in result.ways: print("Name: %s" % way.tags.get("name", "n/a")) print(" Highway: %s" % way.tags.get("highway", "n/a")) print(" Nodes:") for node in way.nodes: print(" Lat: %f, Lon: %f" % (node.lat, node.lon))overpy-0.4/examples/get_nodes.py0000755000175000017500000000104313022347635017272 0ustar phibophibo00000000000000#!/usr/bin/env python import overpy api = overpy.Overpass() # We can also see a node's metadata: jet_deau = 60018172 result = api.query("node({}); out meta;".format(jet_deau)) node = result.get_node(jet_deau) print( "The node for the famous Geneva {} ({},{}) was:".format( node.tags['name'], node.lat, node.lon ) ) attrs = node.attributes print("* last modified {}".format(attrs['timestamp'])) print("* by {} (uid: {})".format(attrs['user'], attrs['uid'])) print("* in changeset {}".format(attrs['changeset'])) overpy-0.4/examples/get_areas.py0000644000175000017500000000067413022347635017263 0ustar phibophibo00000000000000#!/usr/bin/env python import overpy api = overpy.Overpass() # fetch all areas # More info on http://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_API_by_Example result = api.query(""" area[name="Troisdorf"]; out; """) for area in result.areas: print( "Name: %s (%i)" % ( area.tags.get("name", "n/a"), area.id ) ) for n, v in area.tags.items(): print(" Tag: %s = %s" % (n, v)) overpy-0.4/docs/0000755000175000017500000000000013022347701014054 5ustar phibophibo00000000000000overpy-0.4/docs/make.bat0000644000175000017500000001511413022347635015471 0ustar phibophibo00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source set I18NSPHINXOPTS=%SPHINXOPTS% source if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PythonOverpassAPI.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PythonOverpassAPI.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %BUILDDIR%/.. echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end overpy-0.4/docs/source/0000755000175000017500000000000013022347701015354 5ustar phibophibo00000000000000overpy-0.4/docs/source/introduction.rst0000644000175000017500000000301513022347635020634 0ustar phibophibo00000000000000Introduction ============ Requirements ------------ Supported Python versions: * Python 2.7 * Python > 3.2 * PyPy Installation ------------ As a Python egg ~~~~~~~~~~~~~~~ You can install the most recent version using ``pip`` .. code-block:: console $ pip install overpy From a tarball release ~~~~~~~~~~~~~~~~~~~~~~ Download the most recent tarball from github, unpack it and run the following command on the command-line. .. code-block:: console $ python setup.py install Install the development version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Install git and run the following commands on the command-line. .. code-block:: console $ git clone https://github.com/DinoTools/python-overpy.git $ cd python-overpy $ python setup.py install Usage ----- It is recommended to have a look at the documentation of the `Overpass API`_ before using OverPy. For more examples have a look at the :doc:`examples page ` or in the examples directory. .. code-block:: python import overpy api = overpy.Overpass() # fetch all ways and nodes result = api.query(""" way(50.746,7.154,50.748,7.157) ["highway"]; (._;>;); out body; """) for way in result.ways: print("Name: %s" % way.tags.get("name", "n/a")) print(" Highway: %s" % way.tags.get("highway", "n/a")) print(" Nodes:") for node in way.nodes: print(" Lat: %f, Lon: %f" % (node.lat, node.lon)) .. _Overpass API: https://wiki.openstreetmap.org/wiki/Overpass_API overpy-0.4/docs/source/index.rst0000644000175000017500000000044613022347635017227 0ustar phibophibo00000000000000Welcome to Python Overpass API's documentation! =============================================== Contents: .. toctree:: :maxdepth: 2 introduction example api contributing changelog Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` overpy-0.4/docs/source/example.rst0000644000175000017500000001250613022347635017553 0ustar phibophibo00000000000000Examples ======== Basic example ------------- Lets start with an example from the Overpass API documentation. **Query String:** .. code-block:: text :linenos: node(50.745,7.17,50.75,7.18); out; **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query("node(50.745,7.17,50.75,7.18);out;") >>> len(result.nodes) 1984 >>> len(result.ways) 0 >>> len(result.relations) 0 >>> node = result.nodes[2] >>> node.id 100792806 >>> node.tags {} Line 1: Import the required Python module Line 2: Create a new instance of the Overpass() class. This instance is used to query the Overpass API. Line 3: Use the Query-String from above to query the Overpass API service. Line 4,5: Get the number of nodes in the result set. Line 6-9: Get the number of ways and relations available in the result set. Line 10-14: Get the third node from the list. Display the ID and the tags of this node. Use Overpass QL or Overpass XML ------------------------------- Queries are passed directly to the Overpass API service without any modification. So it is possible to use Overpass QL and Overpass XML. Overpass QL ~~~~~~~~~~~ **Query:** .. code-block:: text :linenos: node["name"="Gielgen"]; out body; **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query("""node["name"="Gielgen"];out body;""") >>> len(result.nodes) 6 >>> len(result.ways) 0 >>> len(result.relations) 0 Overpass XML ~~~~~~~~~~~~ **Query:** .. code-block:: xml :linenos: **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query(""" ... ... ... ... ... """) >>> len(result.nodes) 6 >>> len(result.ways) 0 >>> len(result.relations) 0 Parse JSON or XML responses --------------------------- On a request OverPy detects the content type from the response. JSON response ~~~~~~~~~~~~~ **Query String:** .. code-block:: text :linenos: [out:json]; node(50.745,7.17,50.75,7.18); out; **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query("[out:json];node(50.745,7.17,50.75,7.18);out;") >>> len(result.nodes) 1984 >>> len(result.ways) 0 >>> len(result.relations) 0 XML response ~~~~~~~~~~~~ **Query String:** .. code-block:: text :linenos: [out:xml]; node(50.745,7.17,50.75,7.18); out; **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query("[out:xml];node(50.745,7.17,50.75,7.18);out;") >>> len(result.nodes) 1984 >>> len(result.ways) 0 >>> len(result.relations) 0 Ways ---- Get all nodes of a way ~~~~~~~~~~~~~~~~~~~~~~ In this example the Overpass API will only return the Way elements with the name "Gielgenstraße". But there will be no Node elements in the result set. OverPy provides a way to resolve missing nodes. **Query String:** .. code-block:: text :linenos: way ["name"="Gielgenstraße"] (50.7,7.1,50.8,7.25); out; **Use OverPy:** .. code-block:: pycon :linenos: >>> import overpy >>> api = overpy.Overpass() >>> result = api.query("""way["name"="Gielgenstraße"](50.7,7.1,50.8,7.25);out;""") >>> len(result.nodes) 0 >>> len(result.ways) 4 >>> way = result.ways[0] >>> way.nodes Traceback (most recent call last): File "", line 1, in [...] raise exception.DataIncomplete("Resolve missing nodes is disabled") overpy.exception.DataIncomplete: ('Data incomplete try to improve the query to resolve the missing data', 'Resolve missing nodes is disabled') >>> way.get_nodes() Traceback (most recent call last): File "", line 1, in [...] raise exception.DataIncomplete("Resolve missing nodes is disabled") overpy.exception.DataIncomplete: ('Data incomplete try to improve the query to resolve the missing data', 'Resolve missing nodes is disabled') >>> nodes = way.get_nodes(resolve_missing=True) >>> len(nodes) 13 >>> len(result.nodes) 13 >>> len(way.nodes) 13 Line 1-3: Send a query to the Overpass API service. Line 4-6: There are 4 Way elements and 0 Node elements in the result set. Line 7: Get the first way. Line 8-19: Use :attr:`overpy.Way.nodes` class attribute and the :func:`overpy.Way.get_nodes()` function to get the nodes for the way. Both raise an exception because the nodes are not in the result set and auto resolving missing nodes is disabled. Line 20-21: Use the :func:`overpy.Way.get_nodes()` function and let OverPy try to resolve the missing nodes. The function will return all Node elements connected with the Way element. Line 22-25: The resolved nodes have been added to the result set and are available to be used again later. overpy-0.4/docs/source/contributing.rst0000644000175000017500000000004313022347635020620 0ustar phibophibo00000000000000.. include:: ../../CONTRIBUTING.rstoverpy-0.4/docs/source/conf.py0000644000175000017500000002410313022347635016661 0ustar phibophibo00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) sys.path.insert( 0, os.path.abspath( os.path.join( os.path.dirname(__file__), '../../' ) ) ) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.coverage', 'sphinx.ext.viewcode', ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'Python Overpass API' copyright = '2014, PhiBo' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. from overpy import __about__ as overpy_about version = overpy_about.__version__ # The full version, including alpha/beta/rc tags. release = overpy_about.__version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'PythonOverpassAPIdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'PythonOverpassAPI.tex', 'Python Overpass API Documentation', 'PhiBo', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ ('index', 'pythonoverpassapi', 'Python Overpass API Documentation', ['PhiBo'], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ('index', 'PythonOverpassAPI', 'Python Overpass API Documentation', 'PhiBo', 'PythonOverpassAPI', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. epub_title = 'Python Overpass API' epub_author = 'PhiBo' epub_publisher = 'PhiBo' epub_copyright = '2014, PhiBo' # The basename for the epub file. It defaults to the project name. #epub_basename = 'Python Overpass API' # The HTML theme for the epub output. Since the default themes are not optimized # for small screen space, using the same theme for HTML and epub output is # usually not wise. This defaults to 'epub', a theme designed to save visual # space. #epub_theme = 'epub' # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. #epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' # A unique identification for the text. #epub_uid = '' # A tuple containing the cover image and cover page html template filenames. #epub_cover = () # A sequence of (type, uri, title) tuples for the guide element of content.opf. #epub_guide = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_post_files = [] # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # The depth of the table of contents in toc.ncx. #epub_tocdepth = 3 # Allow duplicate toc entries. #epub_tocdup = True # Choose between 'default' and 'includehidden'. #epub_tocscope = 'default' # Fix unsupported image types using the PIL. #epub_fix_images = False # Scale large images. #epub_max_image_width = 0 # How to display URL addresses: 'footnote', 'no', or 'inline'. #epub_show_urls = 'inline' # If false, no index is generated. #epub_use_index = True overpy-0.4/docs/source/changelog.rst0000644000175000017500000000004013022347635020035 0ustar phibophibo00000000000000.. include:: ../../CHANGELOG.rstoverpy-0.4/docs/source/api.rst0000644000175000017500000000131513022347635016665 0ustar phibophibo00000000000000API Reference ============= .. currentmodule:: overpy Overpass API ------------ .. autoclass:: Overpass :members: Result ------ .. autoclass:: Result :members: Elements -------- .. autoclass:: Element :members: .. autoclass:: Area :members: .. autoclass:: Node :members: .. autoclass:: Relation :members: .. autoclass:: Way :members: Relation Members ---------------- .. autoclass:: RelationMember :members: .. autoclass:: RelationArea :members: .. autoclass:: RelationNode :members: .. autoclass:: RelationWay :members: Exceptions ---------- .. automodule:: overpy.exception :members: Helper ------ .. automodule:: overpy.helper :members: