-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgeocode.py
107 lines (84 loc) · 3.2 KB
/
geocode.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
#! /usr/bin/python -B
# -*- coding: utf-8 -*-
import json
import sys
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
URL = "https://maps.googleapis.com/maps/api/geocode/json"
JSON_FILENAME = "places.geojson"
KEY_FILENAME = "gmaps.key"
def find_lat_lng(session, key, place):
point = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [None, None]},
"properties": {"name": place, "show_on_map": True},
}
req = session.get(URL, params={"address": place, "key": key})
geo_value = req.json()
if geo_value["status"] != "OK":
print(f"Could not find address for '{place}'")
point["properties"]["show_on_map"] = False
return None
lat_lng = geo_value["results"][0]["geometry"]["location"]
point["geometry"]["coordinates"] = [lat_lng["lng"], lat_lng["lat"]]
return point
def main():
try:
path = sys.argv[1]
except IndexError:
path = ""
with open(f"{path}{KEY_FILENAME}", "r", encoding="UTF-8") as key_file:
key = key_file.readline().strip()
json_path = f"{path}{JSON_FILENAME}"
try:
with open(f"{path}places_log.txt", "r", encoding="UTF-8") as places_file:
places = places_file.readlines()
places = [pl.strip() for pl in places]
if len(set(places)) != len(places):
print("You have double entry in 'places_log.txt'; fix that.")
return 1
except IOError as err:
print(f"I/O error({err.errno}): {err.strerror}")
return 1
try:
with open(json_path, "r", encoding="UTF-8") as places_gps_file:
data = json.load(places_gps_file)
features = data["features"]
except:
# Either the file was not here on the JSON was invalid.
# We will rewrite the whole file then.
features = []
for feat in features:
if feat["properties"]["name"] in places:
# We already have the coordinates of that place
places.remove(feat["properties"]["name"])
else:
# This feature should not be here anymore; it as been removed from
# places.
features.remove(feat)
# Create a session object with some backoff and retry to avoid hitting
# quota limits
session = requests.Session()
retry = Retry(connect=3, backoff_factor=0.5)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)
# Find the gps coordinates of the new places
for place in places:
point = find_lat_lng(session, key, place)
if point is None:
continue
features.append(point)
features = sorted(features, key=lambda x: x["properties"]["name"])
places_gps = {
"type": "FeatureCollection",
"features": features,
}
# Rewrite totally the file, it's slow but let us handle deleted entry
# in places_log.txt easily
with open(json_path, "w", encoding="UTF-8") as places_file:
data = json.dumps(places_gps, sort_keys=True, indent=4, separators=(",", ":"))
places_file.write(data)
if __name__ == "__main__":
sys.exit(main())