[Python-modules-commits] [python-overpy] 01/04: import python-overpy_0.3.1.orig.tar.gz
Sandro Tosi
morph at moszumanska.debian.org
Thu Aug 4 19:18:07 UTC 2016
This is an automated email from the git hooks/post-receive script.
morph pushed a commit to branch master
in repository python-overpy.
commit 28a7ee574bda14ebcd244eee1a8a54d61fadd644
Author: Sandro Tosi <morph at debian.org>
Date: Thu Aug 4 20:14:57 2016 +0100
import python-overpy_0.3.1.orig.tar.gz
---
PKG-INFO | 121 +++++
README.rst | 100 ++++
overpy.egg-info/PKG-INFO | 121 +++++
overpy.egg-info/SOURCES.txt | 19 +
overpy.egg-info/dependency_links.txt | 1 +
overpy.egg-info/not-zip-safe | 1 +
overpy.egg-info/top_level.txt | 2 +
overpy/__about__.py | 22 +
overpy/__init__.py | 934 +++++++++++++++++++++++++++++++++++
overpy/exception.py | 108 ++++
overpy/helper.py | 64 +++
setup.cfg | 5 +
setup.py | 44 ++
tests/__init__.py | 47 ++
tests/base_class.py | 281 +++++++++++
tests/test_exception.py | 42 ++
tests/test_json.py | 74 +++
tests/test_request.py | 201 ++++++++
tests/test_result.py | 147 ++++++
tests/test_result_way.py | 106 ++++
tests/test_xml.py | 103 ++++
21 files changed, 2543 insertions(+)
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..ec27113
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,121 @@
+Metadata-Version: 1.1
+Name: overpy
+Version: 0.3.1
+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/
+
+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 :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..b68a2b3
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,100 @@
+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/
diff --git a/overpy.egg-info/PKG-INFO b/overpy.egg-info/PKG-INFO
new file mode 100644
index 0000000..ec27113
--- /dev/null
+++ b/overpy.egg-info/PKG-INFO
@@ -0,0 +1,121 @@
+Metadata-Version: 1.1
+Name: overpy
+Version: 0.3.1
+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/
+
+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 :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
diff --git a/overpy.egg-info/SOURCES.txt b/overpy.egg-info/SOURCES.txt
new file mode 100644
index 0000000..53b07f6
--- /dev/null
+++ b/overpy.egg-info/SOURCES.txt
@@ -0,0 +1,19 @@
+README.rst
+setup.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
\ No newline at end of file
diff --git a/overpy.egg-info/dependency_links.txt b/overpy.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/overpy.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/overpy.egg-info/not-zip-safe b/overpy.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/overpy.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/overpy.egg-info/top_level.txt b/overpy.egg-info/top_level.txt
new file mode 100644
index 0000000..4611d9b
--- /dev/null
+++ b/overpy.egg-info/top_level.txt
@@ -0,0 +1,2 @@
+overpy
+tests
diff --git a/overpy/__about__.py b/overpy/__about__.py
new file mode 100644
index 0000000..411cc57
--- /dev/null
+++ b/overpy/__about__.py
@@ -0,0 +1,22 @@
+__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.3.1"
+
+__author__ = "PhiBo (DinoTools)"
+__email__ = ""
+
+__license__ = "MIT"
+__copyright__ = "Copyright 2014-2015 %s" % __author__
diff --git a/overpy/__init__.py b/overpy/__init__.py
new file mode 100644
index 0000000..0690c11
--- /dev/null
+++ b/overpy/__init__.py
@@ -0,0 +1,934 @@
+from collections import OrderedDict
+from decimal import Decimal
+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
+
+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
+
+ def __init__(self, read_chunk_size=None):
+ """
+ :param read_chunk_size: Max size of each chunk read from the server response
+ :type read_chunk_size: Integer
+ """
+ self.url = "http://overpass-api.de/api/interpreter"
+ self._regex_extract_error_msg = re.compile(b"\<p\>(?P<msg>\<strong\s.*?)\</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
+
+ 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 = bytes(query, "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"):
+ """
+
+ :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 isinstance(data, bytes):
+ data = data.decode(encoding)
+ if PY2 and not isinstance(data, str):
+ # Python 2.x: Convert unicode strings
+ data = data.encode(encoding)
+ import xml.etree.ElementTree as ET
+ root = ET.fromstring(data)
+ return Result.from_xml(root, api=self)
+
+
+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._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}
+ 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}
+ 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)
+
+ @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]:
+ 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, root, api=None):
+ """
+ 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
+ :return: New instance of Result object
+ :rtype: Result
+ """
+ result = cls(api=api)
+ for elem_cls in [Node, Way, Relation]:
+ for child in root:
+ if child.tag.lower() == elem_cls._type_value:
+ result.append(elem_cls.from_xml(child, result=result))
+
+ return result
+
+ 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)
+
+ 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
+ self.attributes = attributes
+ self.tags = tags
+
+
+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 "<overpy.Node id={} lat={} lon={}>".format(self.id, self.lat, self.lon)
+
+ @classmethod
+ def from_json(cls, data, result=None):
+ """
+ Create new Node 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 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")
... 1706 lines suppressed ...
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-overpy.git
More information about the Python-modules-commits
mailing list