0
# Roads API
1
2
Snap GPS coordinates to road networks, find nearest roads, and retrieve speed limit information for navigation and tracking applications with support for path interpolation and road segment analysis.
3
4
## Capabilities
5
6
### Road Snapping
7
8
Snap GPS coordinates to the road network for accurate positioning and route tracking.
9
10
```python { .api }
11
def snap_to_roads(client, path, interpolate=False):
12
"""
13
Snap GPS coordinates to the road network.
14
15
Args:
16
client (Client): Google Maps API client instance
17
path (list): List of GPS coordinates as (lat, lng) tuples to snap to roads.
18
Maximum 100 points.
19
interpolate (bool): Whether to interpolate additional points along snapped path
20
to create smoother route representation
21
22
Returns:
23
dict: Response containing:
24
- snappedPoints: List of snapped coordinates with placeId references
25
- warningMessage: Optional warnings about the snapping process
26
27
Raises:
28
googlemaps.exceptions.ApiError: When API returns an error
29
googlemaps.exceptions.TransportError: When HTTP request fails
30
googlemaps.exceptions.Timeout: When request times out
31
"""
32
```
33
34
### Nearest Roads
35
36
Find the nearest roads to given GPS coordinates for road identification and mapping.
37
38
```python { .api }
39
def nearest_roads(client, points):
40
"""
41
Find nearest roads to given GPS coordinates.
42
43
Args:
44
client (Client): Google Maps API client instance
45
points (list): List of GPS coordinates as (lat, lng) tuples.
46
Maximum 100 points.
47
48
Returns:
49
dict: Response containing:
50
- snappedPoints: List of nearest road points with placeId references
51
- No path interpolation is performed
52
53
Raises:
54
googlemaps.exceptions.ApiError: When API returns an error
55
googlemaps.exceptions.TransportError: When HTTP request fails
56
googlemaps.exceptions.Timeout: When request times out
57
"""
58
```
59
60
### Speed Limits
61
62
Retrieve speed limit information for road segments identified by place IDs.
63
64
```python { .api }
65
def speed_limits(client, place_ids):
66
"""
67
Get speed limits for road segments by place IDs.
68
69
Args:
70
client (Client): Google Maps API client instance
71
place_ids (list): List of place IDs for road segments.
72
Maximum 100 place IDs.
73
74
Returns:
75
dict: Response containing:
76
- speedLimits: List of speed limit information for each place ID
77
- Each entry contains speedLimit, units, and placeId
78
79
Raises:
80
googlemaps.exceptions.ApiError: When API returns an error
81
googlemaps.exceptions.TransportError: When HTTP request fails
82
googlemaps.exceptions.Timeout: When request times out
83
"""
84
85
def snapped_speed_limits(client, path):
86
"""
87
Get speed limits along a snapped path.
88
89
Args:
90
client (Client): Google Maps API client instance
91
path (list): List of GPS coordinates as (lat, lng) tuples representing
92
a path. Maximum 100 points.
93
94
Returns:
95
dict: Response containing:
96
- snappedPoints: GPS coordinates snapped to roads with place IDs
97
- speedLimits: Speed limit information for each road segment
98
99
Raises:
100
googlemaps.exceptions.ApiError: When API returns an error
101
googlemaps.exceptions.TransportError: When HTTP request fails
102
googlemaps.exceptions.Timeout: When request times out
103
"""
104
```
105
106
## Usage Examples
107
108
### Basic Road Snapping
109
110
```python
111
import googlemaps
112
113
gmaps = googlemaps.Client(key='YOUR_API_KEY')
114
115
# GPS coordinates that may be slightly off the road
116
gps_points = [
117
(40.714728, -73.998672), # Near NYC street
118
(40.714758, -73.998734), # Slightly off road
119
(40.714812, -73.998842), # Another GPS point
120
(40.714867, -73.998951) # End point
121
]
122
123
# Snap to roads
124
snapped_result = gmaps.snap_to_roads(path=gps_points)
125
126
print("Snapped coordinates:")
127
for i, point in enumerate(snapped_result['snappedPoints']):
128
lat = point['location']['latitude']
129
lng = point['location']['longitude']
130
place_id = point.get('placeId', 'N/A')
131
132
print(f"Point {i+1}: ({lat:.6f}, {lng:.6f}) - Place ID: {place_id}")
133
134
# Check for warnings
135
if 'warningMessage' in snapped_result:
136
print(f"Warning: {snapped_result['warningMessage']}")
137
```
138
139
### Road Snapping with Interpolation
140
141
```python
142
import googlemaps
143
144
gmaps = googlemaps.Client(key='YOUR_API_KEY')
145
146
# Sparse GPS points along a route
147
sparse_path = [
148
(37.7749, -122.4194), # San Francisco start
149
(37.7849, -122.4094), # Middle point
150
(37.7949, -122.3994) # End point
151
]
152
153
# Snap with interpolation for smoother path
154
interpolated_result = gmaps.snap_to_roads(
155
path=sparse_path,
156
interpolate=True
157
)
158
159
print(f"Original points: {len(sparse_path)}")
160
print(f"Snapped points: {len(interpolated_result['snappedPoints'])}")
161
162
# The result will have additional interpolated points
163
print("\nInterpolated snapped path:")
164
for i, point in enumerate(interpolated_result['snappedPoints']):
165
lat = point['location']['latitude']
166
lng = point['location']['longitude']
167
original_index = point.get('originalIndex')
168
169
status = "Original" if original_index is not None else "Interpolated"
170
print(f"Point {i+1}: ({lat:.6f}, {lng:.6f}) - {status}")
171
```
172
173
### Finding Nearest Roads
174
175
```python
176
import googlemaps
177
178
gmaps = googlemaps.Client(key='YOUR_API_KEY')
179
180
# Points that might be off-road (parking lots, buildings, etc.)
181
off_road_points = [
182
(40.758896, -73.985130), # Times Square area
183
(40.748817, -73.985428), # Empire State Building area
184
(40.741895, -73.989308) # Union Square area
185
]
186
187
# Find nearest roads
188
nearest_result = gmaps.nearest_roads(points=off_road_points)
189
190
print("Nearest roads:")
191
for i, point in enumerate(nearest_result['snappedPoints']):
192
lat = point['location']['latitude']
193
lng = point['location']['longitude']
194
place_id = point.get('placeId', 'N/A')
195
original_index = point.get('originalIndex', i)
196
197
print(f"Original point {original_index + 1} -> Nearest road: ({lat:.6f}, {lng:.6f})")
198
print(f" Place ID: {place_id}")
199
```
200
201
### Speed Limit Lookup by Place ID
202
203
```python
204
import googlemaps
205
206
gmaps = googlemaps.Client(key='YOUR_API_KEY')
207
208
# First, snap some points to get place IDs
209
path_points = [
210
(40.714728, -73.998672),
211
(40.714728, -73.998172),
212
(40.714728, -73.997672)
213
]
214
215
snapped = gmaps.snap_to_roads(path=path_points)
216
217
# Extract place IDs from snapped points
218
place_ids = []
219
for point in snapped['snappedPoints']:
220
if 'placeId' in point:
221
place_ids.append(point['placeId'])
222
223
if place_ids:
224
# Get speed limits for these road segments
225
speed_limits_result = gmaps.speed_limits(place_ids=place_ids)
226
227
print("Speed limits for road segments:")
228
for limit_info in speed_limits_result['speedLimits']:
229
place_id = limit_info['placeId']
230
speed_limit = limit_info['speedLimit']
231
units = limit_info['units']
232
233
print(f"Place ID: {place_id}")
234
print(f"Speed Limit: {speed_limit} {units}")
235
print("---")
236
else:
237
print("No place IDs found in snapped results")
238
```
239
240
### Speed Limits Along a Path
241
242
```python
243
import googlemaps
244
245
gmaps = googlemaps.Client(key='YOUR_API_KEY')
246
247
# Define a driving route
248
driving_path = [
249
(40.758896, -73.985130), # Times Square
250
(40.748817, -73.985428), # Empire State Building
251
(40.741895, -73.989308), # Union Square
252
(40.728224, -73.994521), # Washington Square Park
253
(40.718217, -74.000165) # World Trade Center
254
]
255
256
# Get speed limits along the entire path
257
speed_limits_result = gmaps.snapped_speed_limits(path=driving_path)
258
259
print("Speed limits along route:")
260
print("=" * 40)
261
262
# Process snapped points and speed limits
263
snapped_points = speed_limits_result['snappedPoints']
264
speed_limits = speed_limits_result['speedLimits']
265
266
# Create a mapping of place IDs to speed limits
267
speed_limit_map = {limit['placeId']: limit for limit in speed_limits}
268
269
for i, point in enumerate(snapped_points):
270
lat = point['location']['latitude']
271
lng = point['location']['longitude']
272
place_id = point.get('placeId')
273
274
print(f"Point {i+1}: ({lat:.6f}, {lng:.6f})")
275
276
if place_id and place_id in speed_limit_map:
277
limit_info = speed_limit_map[place_id]
278
speed_limit = limit_info['speedLimit']
279
units = limit_info['units']
280
print(f" Speed Limit: {speed_limit} {units}")
281
else:
282
print(" Speed Limit: Not available")
283
print()
284
```
285
286
### Route Analysis with Roads API
287
288
```python
289
import googlemaps
290
291
gmaps = googlemaps.Client(key='YOUR_API_KEY')
292
293
def analyze_route_roads(origin, destination):
294
"""Analyze roads along a route including speed limits."""
295
296
# Get route directions first
297
directions = gmaps.directions(origin, destination)
298
299
if not directions:
300
print("No route found")
301
return
302
303
route = directions[0]
304
305
# Decode the polyline to get path points
306
from googlemaps.convert import decode_polyline
307
polyline = route['overview_polyline']['points']
308
path_points = decode_polyline(polyline)
309
310
# Sample every 10th point to stay within API limits
311
sampled_points = path_points[::max(1, len(path_points) // 50)][:100]
312
313
print(f"Route: {route['legs'][0]['start_address']} to {route['legs'][0]['end_address']}")
314
print(f"Distance: {route['legs'][0]['distance']['text']}")
315
print(f"Duration: {route['legs'][0]['duration']['text']}")
316
print(f"Analyzing {len(sampled_points)} points along route...")
317
print("=" * 60)
318
319
# Get speed limits along the route
320
try:
321
speed_result = gmaps.snapped_speed_limits(path=sampled_points)
322
323
# Analyze speed limits
324
speed_limits = speed_result.get('speedLimits', [])
325
if speed_limits:
326
speeds = [limit['speedLimit'] for limit in speed_limits if 'speedLimit' in limit]
327
if speeds:
328
avg_speed_limit = sum(speeds) / len(speeds)
329
max_speed_limit = max(speeds)
330
min_speed_limit = min(speeds)
331
332
print(f"Speed Limit Analysis:")
333
print(f" Average: {avg_speed_limit:.1f} mph")
334
print(f" Maximum: {max_speed_limit} mph")
335
print(f" Minimum: {min_speed_limit} mph")
336
print(f" Segments analyzed: {len(speeds)}")
337
else:
338
print("No speed limit data available")
339
else:
340
print("No speed limits found along route")
341
342
except Exception as e:
343
print(f"Error getting speed limits: {e}")
344
345
# Example usage
346
analyze_route_roads("JFK Airport, NY", "LaGuardia Airport, NY")
347
```
348
349
### GPS Track Cleaning
350
351
```python
352
import googlemaps
353
354
gmaps = googlemaps.Client(key='YOUR_API_KEY')
355
356
def clean_gps_track(raw_gps_points, interpolate=True):
357
"""Clean and improve GPS tracking data using road snapping."""
358
359
# Split into chunks if too many points (API limit is 100)
360
chunk_size = 100
361
cleaned_track = []
362
363
for i in range(0, len(raw_gps_points), chunk_size):
364
chunk = raw_gps_points[i:i + chunk_size]
365
366
try:
367
# Snap chunk to roads
368
snapped_result = gmaps.snap_to_roads(
369
path=chunk,
370
interpolate=interpolate
371
)
372
373
for point in snapped_result['snappedPoints']:
374
lat = point['location']['latitude']
375
lng = point['location']['longitude']
376
cleaned_track.append((lat, lng))
377
378
except Exception as e:
379
print(f"Error processing chunk {i//chunk_size + 1}: {e}")
380
# Fall back to original points for this chunk
381
cleaned_track.extend(chunk)
382
383
return cleaned_track
384
385
# Example: Clean noisy GPS data
386
noisy_gps_data = [
387
(40.714728, -73.998672), # Good point
388
(40.714858, -73.998834), # Slightly off
389
(40.714728, -73.999672), # Way off (GPS error)
390
(40.714928, -73.998472), # Back on track
391
(40.715028, -73.998272), # Good point
392
]
393
394
print("Original GPS track:")
395
for i, point in enumerate(noisy_gps_data):
396
print(f" {i+1}: {point}")
397
398
cleaned_track = clean_gps_track(noisy_gps_data)
399
400
print(f"\nCleaned GPS track ({len(cleaned_track)} points):")
401
for i, point in enumerate(cleaned_track):
402
print(f" {i+1}: ({point[0]:.6f}, {point[1]:.6f})")
403
```