-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgeocoder.py
100 lines (76 loc) · 4.16 KB
/
geocoder.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
from pprint import pprint
import requests
API_KEY = '40d1649f-0493-4b70-98ba-98533de7710b'
def geocode(address):
# Собираем запрос для геокодера.
geocoder_request = f"http://geocode-maps.yandex.ru/1.x/?apikey={API_KEY}" \
f"&geocode={address}&format=json"
if response := requests.get(geocoder_request):
# Преобразуем ответ в json-объект
json_response = response.json()
else:
raise RuntimeError(
"""Ошибка выполнения запроса:
{request}
Http статус: {status} ({reason})""".format(
request=geocoder_request, status=response.status_code, reason=response.reason))
# Получаем первый топоним из ответа геокодера.
# Согласно описанию ответа он находится по следующему пути:
features = json_response["response"]["GeoObjectCollection"]["featureMember"]
return features[0]["GeoObject"] if features else None
# Получаем координаты объекта по его адресу.
def get_coordinates(address):
toponym = geocode(address)
if not toponym:
return None, None
# Координаты центра топонима:
toponym_coodrinates = toponym["Point"]["pos"]
# Широта, преобразованная в плавающее число:
toponym_longitude, toponym_lattitude = toponym_coodrinates.split(" ")
try:
return {"coords": (float(toponym_longitude), float(toponym_lattitude)),
"name": toponym["metaDataProperty"]["GeocoderMetaData"]["text"],
"postalcode": toponym["metaDataProperty"]["GeocoderMetaData"]["Address"]["postal_code"]}
except KeyError:
return {"coords": (float(toponym_longitude), float(toponym_lattitude)),
"name": toponym["metaDataProperty"]["GeocoderMetaData"]["text"],
"postalcode": "Нет"}
# Получаем параметры объекта для рисования карты вокруг него.
def get_ll_span(address):
toponym = geocode(address)
if not toponym:
return (None, None)
# Координаты центра топонима:
toponym_coodrinates = toponym["Point"]["pos"]
# Долгота и Широта :
toponym_longitude, toponym_lattitude = toponym_coodrinates.split(" ")
# Собираем координаты в параметр ll
ll = ",".join([toponym_longitude, toponym_lattitude])
# Рамка вокруг объекта:
envelope = toponym["boundedBy"]["Envelope"]
# левая, нижняя, правая и верхняя границы из координат углов:
l, b = envelope["lowerCorner"].split(" ")
r, t = envelope["upperCorner"].split(" ")
# Вычисляем полуразмеры по вертикали и горизонтали
dx = abs(float(l) - float(r)) / 2.0
dy = abs(float(t) - float(b)) / 2.0
# Собираем размеры в параметр span
span = f"{dx},{dy}"
return ll, span
# Находим ближайшие к заданной точке объекты заданного типа.
def get_nearest_object(point, kind):
ll = "{0},{1}".format(point[0], point[1])
geocoder_request = f"http://geocode-maps.yandex.ru/1.x/?apikey={API_KEY}" \
f"&geocode={ll}&kind={kind}&format=json"
# Выполняем запрос к геокодеру, анализируем ответ.
response = requests.get(geocoder_request)
if not response:
raise RuntimeError(
f"""Ошибка выполнения запроса:
{geocoder_request}
Http статус: {response.status_code,} ({response.reason})""")
# Преобразуем ответ в json-объект
json_response = response.json()
# Получаем первый топоним из ответа геокодера.
features = json_response["response"]["GeoObjectCollection"]["featureMember"]
return features[0]["GeoObject"]["name"] if features else None