[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