Source code for django_website.Primitives.OSMPrimitives

from decimal import *
import time
from typing import List
from datetime import datetime
import json
from itertools import groupby
from dateutil.parser import parse

def _ElementJsonToOSMObject(jsonDict):
    """
    Parses an OpenStreetMap object into an :class:`OSMNode`, :class:`OSMWay` or :class:`OSMRelation`.

    Parameters
    ----------

    jsonDict : dict
        The dict object representing one of the OpenStreetMap objects

    Returns
    -------
    :class:`OSMNode`, :class:`OSMWay` or :class:`OSMRelation`
    
    """
    if jsonDict['type'] == 'node':
        return OSMNode(jsonDict['id'], jsonDict['type'], jsonDict['lat'], jsonDict['lon'], jsonDict.get('tags'))
    elif jsonDict['type'] == 'way':
        return OSMWay(jsonDict['id'], jsonDict['type'], jsonDict['nodes'], jsonDict.get('tags'))
    elif jsonDict['type'] == 'relation':
        return OSMRelation(jsonDict['id'], jsonDict['type'], _JsonMemberListToOSMRelationMember(jsonDict['members']), jsonDict.get('tags'))
    else:
            raise Exception("OSM Element type (%s) not implemented!" % jsonDict['type'])

def _JsonMemberListToOSMRelationMember(self, jsonMemberList):
    """
    Parses an OSMRelationMember dict into an OSMRelationMember object.

    Parameters
    ----------

    jsonMemberList : dict
        The dict object representing an :class:`OSMRelationMember`.

    Returns
    -------
    An arrays containing each parsed :class:`OSMRelationMember`.
    
    """
    members = []
    for member in jsonMemberList:
        members.append(OSMRelationMember(member['type'], member['ref'], member['role']))
    return members


[docs]class OSMObject(object): """Base class for other OSM objects: Attribute Name: default value version: 0 visible: True timestamp: None changeset: 0 user: '' #user's name uid: 0 #user's id """ _optDefAttributes={"version": 0, "visible": True, "timestamp": None, "changeset": 0, "user": "", "uid": 0} ## 'tags' attribute is set as an empty dictionary so that it's possible to try ## to look up for a 'name' tag even when an (faulty) object doesn't have any tags def __init__(self, id: int, type:str, tags={}, **kwargs): self.id = id self.type = type self.tags = tags for kw in OSMObject._optDefAttributes: setattr(self, kw, kwargs.get('kw') if kw in kwargs else OSMObject._optDefAttributes.get('kw'))
[docs]class OSMNode(OSMObject): """ Class used as an OpenStreetMap Node object wrapper fields: - lat : Decimal Represents this OSMNode latitude - lon : Decimal Represents this OSMNode longitude - tags : dict Each :class:`OSMNode`, :class:`OSMWay` and :class:`OSMRelation` can contain an arbitratry number of tags, each of which corresponds to some attribute of that OSM object (e.g. an OSMNode could have a tag 'highway' with the value 'traffic_signals'). """ def __init__(self, id: int, type: str, lat: Decimal, lon: Decimal, tags={}): super().__init__(id, type, tags) self.lat = lat self.lon = lon
[docs]class OSMWay(OSMObject): """ Class used as an OpenStreetMap Way object wrapper. In this abstraction an OSMWay is only considered to be a set of nodes contained in the field nodes. fields: - nodes : List[int] The set of nodes contained in this OSMWay. An OSMWay is used to represent usually linear features such as avenues and streets. - tags : dict See tags in :class:`OSMNode` """ def __init__(self, id: int, type, nodes: List[int], tags={}): super().__init__(id, type, tags) self.nodes = nodes
[docs]class OSMRelation(OSMObject): """ A OpenStreetMap relation represents 'belongs to' relations (i.e. :class:`OSMNode` objects belonging to the same :class:`OSMWay` or a collection of :class:`OSMWay` objects that belongs to the same OSMRelation which represets for example the boundaries of some region.) fields: - id : int Represents the relation id as informed by OpenStreetMap database - type : str It can be anything for example 'boundary'. - members : List[OSMObject] An OSMRelation can be composed by any number and type of objects (e.g. an OSMRelation with type 'route' can contain different OSMWays that compose the route of a bus). """ def __init__(self, id: int, type, members: List[OSMObject], tags={}): super().__init__(id, type, tags) self.members = members
[docs]class OSM3S: """Timestamp and copyright info""" def __init__(self, timestamp_osm_base = None, copyright = ""): if not timestamp_osm_base is None: self.timestamp_osm_base = parse(timestamp_osm_base) self.copyright = copyright
[docs] def JsonToOSM3S(jsonString): """Parses an string to an OSM3S object""" return DictToOSM3S(json.loads(jsonString));
[docs] def DictToOSM3S(jsonDict): """Parses an dict object into an OSM3S object""" return OSM3S(jsonDict['timestamp_osm_base'], jsonDict['copyright'])
[docs]class OSMRelationMember: """An element that 'belogs' to another (i.e. An :class:`OSMNode` that belongs to an :class:`OSMWay`)""" def __init__(self, type, ref, role): self.type = type self.ref = ref self.role = role
[docs]class OSMResult: """Represents a query result to an OpenStreetMap server""" def __init__(self, version: float, generator: str, osm3s: OSM3S, elements: list = []): self.version = version self.generator = generator self.osm3s = osm3s self.Nodes = {} self.Ways = {} self.Relations = {} for element in elements: osmObject = _ElementJsonToOSMObject(element) if type(osmObject) is OSMNode: self.Nodes[osmObject.id] = osmObject elif type(osmObject) is OSMWay: self.Ways[osmObject.id] = osmObject elif type(osmObject) is OSMRelation: self.Relations[osmObject.id] = osmObject
[docs] def fromJsonString(jsonString): """Parses a json string into a OSMResult object""" return OSMResult.fromJsonDict(json.loads(jsonString))
[docs] def fromJsonDict(jsonDict): """Parses a dict into a OSMResult""" version = jsonDict['version'] generator = jsonDict['generator'] osm3sDict = OSM3S.DictToOSM3S(jsonDict['osm3s']) return OSMResult(version, generator, osm3sDict, jsonDict['elements'])