-
Notifications
You must be signed in to change notification settings - Fork 0
/
maps.py
204 lines (165 loc) · 6.63 KB
/
maps.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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
from googlemaps import convert
MAPS_IMAGE_FORMATS = {'png8', 'png', 'png32', 'gif', 'jpg', 'jpg-baseline'}
MAPS_MAP_TYPES = {'roadmap', 'satellite', 'terrain', 'hybrid'}
class StaticMapParam:
"""Base class to handle parameters for Maps Static API."""
def __init__(self):
self.params = []
def __str__(self):
"""Converts a list of parameters to the format expected by
the Google Maps server.
:rtype: str
"""
return convert.join_list('|', self.params)
class StaticMapMarker(StaticMapParam):
"""Handles marker parameters for Maps Static API."""
def __init__(self, locations,
size=None, color=None, label=None):
"""
:param locations: Specifies the locations of the markers on
the map.
:type locations: list
:param size: Specifies the size of the marker.
:type size: str
:param color: Specifies a color of the marker.
:type color: str
:param label: Specifies a single uppercase alphanumeric
character to be displaied on marker.
:type label: str
"""
super(StaticMapMarker, self).__init__()
if size:
self.params.append("size:%s" % size)
if color:
self.params.append("color:%s" % color)
if label:
if len(label) != 1 or (label.isalpha() and not label.isupper()) or not label.isalnum():
raise ValueError("Marker label must be alphanumeric and uppercase.")
self.params.append("label:%s" % label)
self.params.append(convert.location_list(locations))
class StaticMapPath(StaticMapParam):
"""Handles path parameters for Maps Static API."""
def __init__(self, points,
weight=None, color=None,
fillcolor=None, geodesic=None):
"""
:param points: Specifies the point through which the path
will be built.
:type points: list
:param weight: Specifies the thickness of the path in pixels.
:type weight: int
:param color: Specifies a color of the path.
:type color: str
:param fillcolor: Indicates both that the path marks off a
polygonal area and specifies the fill color to use as an
overlay within that area.
:type fillcolor: str
:param geodesic: Indicates that the requested path should be
interpreted as a geodesic line that follows the curvature
of the earth.
:type geodesic: bool
"""
super(StaticMapPath, self).__init__()
if weight:
self.params.append("weight:%s" % weight)
if color:
self.params.append("color:%s" % color)
if fillcolor:
self.params.append("fillcolor:%s" % fillcolor)
if geodesic:
self.params.append("geodesic:%s" % geodesic)
self.params.append(convert.location_list(points))
def static_map(client, size,
center=None, zoom=None, scale=None,
format=None, maptype=None, language=None, region=None,
markers=None, path=None, visible=None, style=None):
"""
Downloads a map image from the Maps Static API.
See https://developers.google.com/maps/documentation/maps-static/intro
for more info, including more detail for each parameter below.
:param size: Defines the rectangular dimensions of the map image.
:type param: int or list
:param center: Defines the center of the map, equidistant from all edges
of the map.
:type center: dict or list or string
:param zoom: Defines the zoom level of the map, which determines the
magnification level of the map.
:type zoom: int
:param scale: Affects the number of pixels that are returned.
:type scale: int
:param format: Defines the format of the resulting image.
:type format: string
:param maptype: defines the type of map to construct. There are several
possible maptype values, including roadmap, satellite, hybrid,
and terrain.
:type maptype: string
:param language: defines the language to use for display of labels on
map tiles.
:type language: string
:param region: defines the appropriate borders to display, based on
geo-political sensitivities.
:type region: string
:param markers: define one or more markers to attach to the image at
specified locations.
:type markers: StaticMapMarker
:param path: defines a single path of two or more connected points to
overlay on the image at specified locations.
:type path: StaticMapPath
:param visible: specifies one or more locations that should remain visible
on the map, though no markers or other indicators will be displayed.
:type visible: list of dict
:param style: defines a custom style to alter the presentation of
a specific feature (roads, parks, and other features) of the map.
:type style: list of dict
:rtype: iterator containing the raw image data, which typically can be
used to save an image file locally. For example:
```
f = open(local_filename, 'wb')
for chunk in client.static_map(size=(400, 400),
center=(52.520103, 13.404871),
zoom=15):
if chunk:
f.write(chunk)
f.close()
```
"""
params = {"size": convert.size(size)}
if not markers:
if not (center or zoom is not None):
raise ValueError(
"both center and zoom are required"
"when markers is not specifed"
)
if center:
params["center"] = convert.latlng(center)
if zoom is not None:
params["zoom"] = zoom
if scale is not None:
params["scale"] = scale
if format:
if format not in MAPS_IMAGE_FORMATS:
raise ValueError("Invalid image format")
params['format'] = format
if maptype:
if maptype not in MAPS_MAP_TYPES:
raise ValueError("Invalid maptype")
params["maptype"] = maptype
if language:
params["language"] = language
if region:
params["region"] = region
if markers:
params["markers"] = markers
if path:
params["path"] = path
if visible:
params["visible"] = convert.location_list(visible)
if style:
params["style"] = convert.components(style)
response = client._request(
"/maps/api/staticmap",
params,
extract_body=lambda response: response,
requests_kwargs={"stream": True},
)
return response.iter_content()