-
Notifications
You must be signed in to change notification settings - Fork 1
/
geofence.py
118 lines (92 loc) · 3.42 KB
/
geofence.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# -*- coding: utf-8 -*-
import requests
from requests.exceptions import ConnectionError, Timeout
from util import parse_timestamp, datetime_to_unix_epoch
import logging
import six
import util
def fetch_objects():
log = logging.getLogger("geofencebroker")
try:
url = "https://www.vegvesen.no/nvdb/api/v2/vegobjekter/911?inkluder=lokasjon,egenskaper,metadata"
req = requests.get(url, timeout=2.0)
if not req.ok:
log.warn("Unable to retrieve NVDB goefence objects")
return None
return req.json()
except (ConnectionError, Timeout) as ce:
log.error(ce)
return None
def get_polygon(vegobjekt):
"""
Input is a "vegobjekt" dictionary from NVDB. Then we'll
extract the POLYGON datatype and convert it a 2-dimensional
list of UTM coordinates.
"""
log = logging.getLogger("geofencebroker")
tmp = [x for x in vegobjekt["egenskaper"] if x["datatype"] == 19]
if not tmp:
log.error("Unable to get POLYGON from vegobjekt!\n\tvegobjekt['egenskaper'] = {}".format(
vegobjekt["egenskaper"]))
return []
# tmp = tmp[0]
# polygon = tmp["verdi"].replace("POLYGON ((", "").replace("))", "")
# polygon = [x.strip().split(" ") for x in polygon.split(",")]
# return polygon
nvdb_polygon = tmp[0]['verdi']
return util.parse_polygon(nvdb_polygon)
def get_name(vegobjekt):
"""Return the navn (id=11212) and beskrivelse (id=11213)
navn = "Oslo Ring 1"
beskrivelse = "Tester ring 1"
<- "Oslo Ring 1 (Tester ring 1)"
"""
name = filter(lambda x: x['id'] == 11212, vegobjekt["egenskaper"])
description = filter(lambda x: x['id'] == 11213, vegobjekt["egenskaper"])
return u"{} ({})".format(unicode(name[0]["verdi"]), unicode(description[0]["verdi"]))
def get_version(vegobjekt):
"""Version id field in NVDB has 'id' == 11214"""
# timestamp = parse_timestamp(vegobjekt["metadata"]["sist_modifisert"])
# unix_epoch = datetime_to_unix_epoch(timestamp)
version = filter(lambda x: x["id"] == 11214, vegobjekt["egenskaper"])
if not version:
return version
version = version[0]
return int(version['verdi'])
def get_polygon_centroid(polygon_input):
"""
ref https://stackoverflow.com/questions/2792443/finding-the-centroid-of-a-polygon
"""
log = logging.getLogger("geofencebroker")
# Convert the 2D list of string UTM coordinates
# to proper float numbers. Need for the calculation
# of the polygon centroid.
polygon = polygon_input
if isinstance(polygon_input[0][0], six.string_types):
polygon = [[float(i) for i in p] for p in polygon_input]
centroid = [0.0, 0.0]
signed_area = 0.0
a = 0.0
p_length = len(polygon) - 1
for i in range(p_length):
x0, y0 = polygon[i][0], polygon[i][1]
x1, y1 = polygon[i + 1][0], polygon[i + 1][1]
a = x0 * y1 - x1 * y0
signed_area += a
centroid[0] += (x0 + x1) * a
centroid[1] += (y0 + y1) * a
x0, y0 = polygon[p_length][0], polygon[p_length][1]
x1, y1 = polygon[0][0], polygon[0][1]
a = x0 * y1 - x1 * y0
signed_area += a
centroid[0] += (x0 + x1) * a
centroid[1] += (y0 + y1) * a
signed_area *= 0.5
try:
centroid[0] /= (6.0 * signed_area)
centroid[1] /= (6.0 * signed_area)
except ZeroDivisionError:
log.exception()
raise
else:
return tuple(centroid)