0
# Google Maps Services
1
2
Service components for accessing Google Maps platform services including directions, distance matrix calculations, and Street View functionality with comprehensive routing and navigation capabilities.
3
4
## Capabilities
5
6
### DirectionsService Component
7
8
Calculates routes between locations with support for multiple waypoints, travel modes, and routing preferences.
9
10
```typescript { .api }
11
/**
12
* Calculates routes between locations
13
* Supports multiple waypoints, travel modes, and routing options
14
*/
15
interface DirectionsServiceProps {
16
options: google.maps.DirectionsRequest;
17
callback: (
18
result: google.maps.DirectionsResult | null,
19
status: google.maps.DirectionsStatus
20
) => void;
21
22
// Lifecycle events
23
onLoad?: (directionsService: google.maps.DirectionsService) => void;
24
onUnmount?: (directionsService: google.maps.DirectionsService) => void;
25
}
26
27
interface google.maps.DirectionsRequest {
28
destination: string | google.maps.LatLng | google.maps.LatLngLiteral | google.maps.Place;
29
origin: string | google.maps.LatLng | google.maps.LatLngLiteral | google.maps.Place;
30
avoidFerries?: boolean;
31
avoidHighways?: boolean;
32
avoidTolls?: boolean;
33
drivingOptions?: google.maps.DrivingOptions;
34
language?: string;
35
optimizeWaypoints?: boolean;
36
provideRouteAlternatives?: boolean;
37
region?: string;
38
transitOptions?: google.maps.TransitOptions;
39
travelMode?: google.maps.TravelMode;
40
unitSystem?: google.maps.UnitSystem;
41
waypoints?: google.maps.DirectionsWaypoint[];
42
}
43
44
function DirectionsService(props: DirectionsServiceProps): JSX.Element;
45
```
46
47
**Usage Examples:**
48
49
```typescript
50
import React, { useState } from 'react';
51
import {
52
GoogleMap,
53
LoadScript,
54
DirectionsService,
55
DirectionsRenderer
56
} from '@react-google-maps/api';
57
58
// Basic directions service
59
function BasicDirections() {
60
const [directionsResponse, setDirectionsResponse] = useState<google.maps.DirectionsResult | null>(null);
61
const [calculating, setCalculating] = useState(false);
62
63
const origin = { lat: 40.7128, lng: -74.0060 }; // NYC
64
const destination = { lat: 40.7589, lng: -73.9851 }; // Times Square
65
66
const directionsCallback = (
67
result: google.maps.DirectionsResult | null,
68
status: google.maps.DirectionsStatus
69
) => {
70
setCalculating(false);
71
72
if (status === 'OK' && result) {
73
setDirectionsResponse(result);
74
console.log('Directions calculated:', result);
75
} else {
76
console.error('Directions request failed:', status);
77
}
78
};
79
80
React.useEffect(() => {
81
setCalculating(true);
82
}, []);
83
84
return (
85
<LoadScript googleMapsApiKey="YOUR_API_KEY">
86
<GoogleMap
87
center={origin}
88
zoom={13}
89
mapContainerStyle={{ width: '100%', height: '400px' }}
90
>
91
{calculating && (
92
<DirectionsService
93
options={{
94
destination,
95
origin,
96
travelMode: google.maps.TravelMode.DRIVING
97
}}
98
callback={directionsCallback}
99
/>
100
)}
101
102
{directionsResponse && (
103
<DirectionsRenderer directions={directionsResponse} />
104
)}
105
</GoogleMap>
106
</LoadScript>
107
);
108
}
109
110
// Interactive directions with waypoints
111
function InteractiveDirections() {
112
const [directionsResponse, setDirectionsResponse] = useState<google.maps.DirectionsResult | null>(null);
113
const [waypoints, setWaypoints] = useState<google.maps.DirectionsWaypoint[]>([
114
{ location: { lat: 40.7505, lng: -73.9934 }, stopover: true }, // Empire State
115
{ location: { lat: 40.7614, lng: -73.9776 }, stopover: true } // Central Park
116
]);
117
const [travelMode, setTravelMode] = useState<google.maps.TravelMode>(google.maps.TravelMode.DRIVING);
118
const [calculating, setCalculating] = useState(false);
119
120
const calculateRoute = () => {
121
setCalculating(true);
122
setDirectionsResponse(null);
123
};
124
125
const directionsCallback = (
126
result: google.maps.DirectionsResult | null,
127
status: google.maps.DirectionsStatus
128
) => {
129
setCalculating(false);
130
131
if (status === 'OK' && result) {
132
setDirectionsResponse(result);
133
134
// Display route information
135
const route = result.routes[0];
136
const leg = route.legs[0];
137
console.log(`Distance: ${leg.distance?.text}, Duration: ${leg.duration?.text}`);
138
} else {
139
console.error('Directions failed:', status);
140
}
141
};
142
143
return (
144
<LoadScript googleMapsApiKey="YOUR_API_KEY">
145
<div>
146
<div style={{ padding: '10px', background: '#f0f0f0' }}>
147
<div style={{ marginBottom: '10px' }}>
148
<label>Travel Mode: </label>
149
<select
150
value={travelMode}
151
onChange={(e) => setTravelMode(e.target.value as google.maps.TravelMode)}
152
>
153
<option value={google.maps.TravelMode.DRIVING}>Driving</option>
154
<option value={google.maps.TravelMode.WALKING}>Walking</option>
155
<option value={google.maps.TravelMode.BICYCLING}>Bicycling</option>
156
<option value={google.maps.TravelMode.TRANSIT}>Transit</option>
157
</select>
158
</div>
159
160
<button
161
onClick={calculateRoute}
162
disabled={calculating}
163
style={{ marginRight: '10px' }}
164
>
165
{calculating ? 'Calculating...' : 'Calculate Route'}
166
</button>
167
168
<button onClick={() => setDirectionsResponse(null)}>
169
Clear Route
170
</button>
171
172
{directionsResponse && (
173
<div style={{ marginTop: '10px', fontSize: '14px' }}>
174
<div>Distance: {directionsResponse.routes[0]?.legs[0]?.distance?.text}</div>
175
<div>Duration: {directionsResponse.routes[0]?.legs[0]?.duration?.text}</div>
176
</div>
177
)}
178
</div>
179
180
<GoogleMap
181
center={{ lat: 40.7128, lng: -74.0060 }}
182
zoom={13}
183
mapContainerStyle={{ width: '100%', height: '400px' }}
184
>
185
{calculating && (
186
<DirectionsService
187
options={{
188
origin: { lat: 40.7128, lng: -74.0060 },
189
destination: { lat: 40.7589, lng: -73.9851 },
190
waypoints,
191
travelMode,
192
optimizeWaypoints: true,
193
avoidHighways: false,
194
avoidTolls: false
195
}}
196
callback={directionsCallback}
197
/>
198
)}
199
200
{directionsResponse && (
201
<DirectionsRenderer
202
directions={directionsResponse}
203
options={{
204
suppressMarkers: false,
205
suppressInfoWindows: false,
206
draggable: true
207
}}
208
/>
209
)}
210
</GoogleMap>
211
</div>
212
</LoadScript>
213
);
214
}
215
216
// Advanced directions with multiple options
217
function AdvancedDirections() {
218
const [directionsResponse, setDirectionsResponse] = useState<google.maps.DirectionsResult | null>(null);
219
const [routeOptions, setRouteOptions] = useState({
220
avoidHighways: false,
221
avoidTolls: false,
222
avoidFerries: false,
223
provideRouteAlternatives: true,
224
optimizeWaypoints: true
225
});
226
227
const directionsCallback = (
228
result: google.maps.DirectionsResult | null,
229
status: google.maps.DirectionsStatus
230
) => {
231
if (status === 'OK' && result) {
232
setDirectionsResponse(result);
233
234
// Log all available routes
235
result.routes.forEach((route, index) => {
236
console.log(`Route ${index + 1}:`, {
237
distance: route.legs[0]?.distance?.text,
238
duration: route.legs[0]?.duration?.text,
239
summary: route.summary
240
});
241
});
242
}
243
};
244
245
return (
246
<LoadScript googleMapsApiKey="YOUR_API_KEY">
247
<div>
248
<div style={{ padding: '10px', background: '#f0f0f0' }}>
249
<h4>Route Options</h4>
250
251
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}>
252
<label>
253
<input
254
type="checkbox"
255
checked={routeOptions.avoidHighways}
256
onChange={(e) => setRouteOptions(prev => ({
257
...prev,
258
avoidHighways: e.target.checked
259
}))}
260
/>
261
Avoid Highways
262
</label>
263
264
<label>
265
<input
266
type="checkbox"
267
checked={routeOptions.avoidTolls}
268
onChange={(e) => setRouteOptions(prev => ({
269
...prev,
270
avoidTolls: e.target.checked
271
}))}
272
/>
273
Avoid Tolls
274
</label>
275
276
<label>
277
<input
278
type="checkbox"
279
checked={routeOptions.avoidFerries}
280
onChange={(e) => setRouteOptions(prev => ({
281
...prev,
282
avoidFerries: e.target.checked
283
}))}
284
/>
285
Avoid Ferries
286
</label>
287
288
<label>
289
<input
290
type="checkbox"
291
checked={routeOptions.provideRouteAlternatives}
292
onChange={(e) => setRouteOptions(prev => ({
293
...prev,
294
provideRouteAlternatives: e.target.checked
295
}))}
296
/>
297
Show Alternatives
298
</label>
299
</div>
300
301
{directionsResponse && (
302
<div style={{ marginTop: '10px' }}>
303
<div>Found {directionsResponse.routes.length} route(s)</div>
304
{directionsResponse.routes.map((route, index) => (
305
<div key={index} style={{ fontSize: '12px', marginLeft: '10px' }}>
306
Route {index + 1}: {route.legs[0]?.distance?.text} - {route.legs[0]?.duration?.text}
307
</div>
308
))}
309
</div>
310
)}
311
</div>
312
313
<GoogleMap
314
center={{ lat: 40.7128, lng: -74.0060 }}
315
zoom={12}
316
mapContainerStyle={{ width: '100%', height: '400px' }}
317
>
318
<DirectionsService
319
options={{
320
origin: 'New York, NY',
321
destination: 'Philadelphia, PA',
322
travelMode: google.maps.TravelMode.DRIVING,
323
...routeOptions
324
}}
325
callback={directionsCallback}
326
/>
327
328
{directionsResponse && (
329
<DirectionsRenderer
330
directions={directionsResponse}
331
options={{
332
polylineOptions: {
333
strokeColor: '#4285f4',
334
strokeWeight: 6,
335
strokeOpacity: 0.8
336
}
337
}}
338
/>
339
)}
340
</GoogleMap>
341
</div>
342
</LoadScript>
343
);
344
}
345
```
346
347
### DirectionsRenderer Component
348
349
Displays calculated routes on the map with customizable styling and interaction options.
350
351
```typescript { .api }
352
/**
353
* Displays calculated routes on the map
354
* Renders directions result with customizable styling and markers
355
*/
356
interface DirectionsRendererProps {
357
directions?: google.maps.DirectionsResult;
358
options?: google.maps.DirectionsRendererOptions;
359
panel?: HTMLElement;
360
routeIndex?: number;
361
362
// Event handlers
363
onDirectionsChanged?: () => void;
364
365
// Lifecycle events
366
onLoad?: (directionsRenderer: google.maps.DirectionsRenderer) => void;
367
onUnmount?: (directionsRenderer: google.maps.DirectionsRenderer) => void;
368
}
369
370
interface google.maps.DirectionsRendererOptions {
371
directions?: google.maps.DirectionsResult;
372
draggable?: boolean;
373
hideRouteList?: boolean;
374
infoWindow?: google.maps.InfoWindow;
375
markerOptions?: google.maps.MarkerOptions;
376
panel?: HTMLElement;
377
polylineOptions?: google.maps.PolylineOptions;
378
preserveViewport?: boolean;
379
routeIndex?: number;
380
suppressBicyclingLayer?: boolean;
381
suppressInfoWindows?: boolean;
382
suppressMarkers?: boolean;
383
suppressPolylines?: boolean;
384
}
385
386
function DirectionsRenderer(props: DirectionsRendererProps): JSX.Element;
387
```
388
389
**Usage Examples:**
390
391
```typescript
392
// Custom styled directions renderer
393
function StyledDirectionsRenderer() {
394
const [directionsResponse, setDirectionsResponse] = useState<google.maps.DirectionsResult | null>(null);
395
const [selectedRouteIndex, setSelectedRouteIndex] = useState(0);
396
397
const rendererOptions = {
398
suppressMarkers: false,
399
suppressInfoWindows: false,
400
draggable: true,
401
polylineOptions: {
402
strokeColor: '#ff6b6b',
403
strokeWeight: 8,
404
strokeOpacity: 0.8
405
},
406
markerOptions: {
407
icon: {
408
url: 'https://maps.google.com/mapfiles/ms/icons/red-dot.png',
409
scaledSize: new google.maps.Size(32, 32)
410
}
411
}
412
};
413
414
return (
415
<LoadScript googleMapsApiKey="YOUR_API_KEY">
416
<GoogleMap
417
center={{ lat: 40.7128, lng: -74.0060 }}
418
zoom={12}
419
mapContainerStyle={{ width: '100%', height: '400px' }}
420
>
421
<DirectionsService
422
options={{
423
origin: 'Times Square, New York',
424
destination: 'Central Park, New York',
425
travelMode: google.maps.TravelMode.WALKING,
426
provideRouteAlternatives: true
427
}}
428
callback={(result, status) => {
429
if (status === 'OK' && result) {
430
setDirectionsResponse(result);
431
}
432
}}
433
/>
434
435
{directionsResponse && (
436
<DirectionsRenderer
437
directions={directionsResponse}
438
routeIndex={selectedRouteIndex}
439
options={rendererOptions}
440
onLoad={(renderer) => console.log('Directions renderer loaded')}
441
/>
442
)}
443
</GoogleMap>
444
</LoadScript>
445
);
446
}
447
```
448
449
### DistanceMatrixService Component
450
451
Calculates travel distances and times between multiple origins and destinations with support for different travel modes.
452
453
```typescript { .api }
454
/**
455
* Calculates travel distances and times between locations
456
* Supports multiple origins/destinations and different travel modes
457
*/
458
interface DistanceMatrixServiceProps {
459
options: google.maps.DistanceMatrixRequest;
460
callback: (
461
response: google.maps.DistanceMatrixResponse | null,
462
status: google.maps.DistanceMatrixStatus
463
) => void;
464
465
// Lifecycle events
466
onLoad?: (distanceMatrixService: google.maps.DistanceMatrixService) => void;
467
onUnmount?: (distanceMatrixService: google.maps.DistanceMatrixService) => void;
468
}
469
470
interface google.maps.DistanceMatrixRequest {
471
destinations: (string | google.maps.LatLng | google.maps.LatLngLiteral | google.maps.Place)[];
472
origins: (string | google.maps.LatLng | google.maps.LatLngLiteral | google.maps.Place)[];
473
avoidFerries?: boolean;
474
avoidHighways?: boolean;
475
avoidTolls?: boolean;
476
drivingOptions?: google.maps.DrivingOptions;
477
language?: string;
478
region?: string;
479
transitOptions?: google.maps.TransitOptions;
480
travelMode?: google.maps.TravelMode;
481
unitSystem?: google.maps.UnitSystem;
482
}
483
484
function DistanceMatrixService(props: DistanceMatrixServiceProps): JSX.Element;
485
```
486
487
**Usage Examples:**
488
489
```typescript
490
import React, { useState } from 'react';
491
import { GoogleMap, LoadScript, DistanceMatrixService } from '@react-google-maps/api';
492
493
// Distance matrix calculation
494
function DistanceMatrixExample() {
495
const [matrixResult, setMatrixResult] = useState<google.maps.DistanceMatrixResponse | null>(null);
496
const [calculating, setCalculating] = useState(false);
497
498
const origins = [
499
{ lat: 40.7128, lng: -74.0060 }, // NYC
500
{ lat: 40.7589, lng: -73.9851 } // Times Square
501
];
502
503
const destinations = [
504
{ lat: 40.7505, lng: -73.9934 }, // Empire State
505
{ lat: 40.7614, lng: -73.9776 }, // Central Park
506
{ lat: 40.6892, lng: -74.0445 } // Statue of Liberty
507
];
508
509
const calculateMatrix = () => {
510
setCalculating(true);
511
setMatrixResult(null);
512
};
513
514
const matrixCallback = (
515
response: google.maps.DistanceMatrixResponse | null,
516
status: google.maps.DistanceMatrixStatus
517
) => {
518
setCalculating(false);
519
520
if (status === 'OK' && response) {
521
setMatrixResult(response);
522
console.log('Distance matrix calculated:', response);
523
} else {
524
console.error('Distance matrix failed:', status);
525
}
526
};
527
528
return (
529
<LoadScript googleMapsApiKey="YOUR_API_KEY">
530
<div>
531
<div style={{ padding: '10px', background: '#f0f0f0' }}>
532
<button
533
onClick={calculateMatrix}
534
disabled={calculating}
535
style={{ marginBottom: '10px' }}
536
>
537
{calculating ? 'Calculating...' : 'Calculate Distance Matrix'}
538
</button>
539
540
{matrixResult && (
541
<div>
542
<h4>Distance Matrix Results</h4>
543
<table style={{ borderCollapse: 'collapse', width: '100%' }}>
544
<thead>
545
<tr>
546
<th style={{ border: '1px solid #ccc', padding: '5px' }}>Origin</th>
547
<th style={{ border: '1px solid #ccc', padding: '5px' }}>Destination</th>
548
<th style={{ border: '1px solid #ccc', padding: '5px' }}>Distance</th>
549
<th style={{ border: '1px solid #ccc', padding: '5px' }}>Duration</th>
550
</tr>
551
</thead>
552
<tbody>
553
{matrixResult.rows.map((row, originIndex) =>
554
row.elements.map((element, destIndex) => (
555
<tr key={`${originIndex}-${destIndex}`}>
556
<td style={{ border: '1px solid #ccc', padding: '5px' }}>
557
Origin {originIndex + 1}
558
</td>
559
<td style={{ border: '1px solid #ccc', padding: '5px' }}>
560
Destination {destIndex + 1}
561
</td>
562
<td style={{ border: '1px solid #ccc', padding: '5px' }}>
563
{element.distance?.text || 'N/A'}
564
</td>
565
<td style={{ border: '1px solid #ccc', padding: '5px' }}>
566
{element.duration?.text || 'N/A'}
567
</td>
568
</tr>
569
))
570
)}
571
</tbody>
572
</table>
573
</div>
574
)}
575
</div>
576
577
<GoogleMap
578
center={{ lat: 40.7128, lng: -74.0060 }}
579
zoom={12}
580
mapContainerStyle={{ width: '100%', height: '400px' }}
581
>
582
{calculating && (
583
<DistanceMatrixService
584
options={{
585
origins,
586
destinations,
587
travelMode: google.maps.TravelMode.DRIVING,
588
unitSystem: google.maps.UnitSystem.IMPERIAL,
589
avoidHighways: false,
590
avoidTolls: false
591
}}
592
callback={matrixCallback}
593
/>
594
)}
595
</GoogleMap>
596
</div>
597
</LoadScript>
598
);
599
}
600
601
// Travel time comparison across modes
602
function TravelModeComparison() {
603
const [results, setResults] = useState<{[key: string]: google.maps.DistanceMatrixResponse}>({});
604
const [calculating, setCalculating] = useState<{[key: string]: boolean}>({});
605
606
const travelModes = [
607
{ key: 'driving', mode: google.maps.TravelMode.DRIVING, name: 'Driving' },
608
{ key: 'walking', mode: google.maps.TravelMode.WALKING, name: 'Walking' },
609
{ key: 'bicycling', mode: google.maps.TravelMode.BICYCLING, name: 'Bicycling' },
610
{ key: 'transit', mode: google.maps.TravelMode.TRANSIT, name: 'Transit' }
611
];
612
613
const calculateForMode = (modeKey: string, travelMode: google.maps.TravelMode) => {
614
setCalculating(prev => ({ ...prev, [modeKey]: true }));
615
};
616
617
const createCallback = (modeKey: string) => (
618
response: google.maps.DistanceMatrixResponse | null,
619
status: google.maps.DistanceMatrixStatus
620
) => {
621
setCalculating(prev => ({ ...prev, [modeKey]: false }));
622
623
if (status === 'OK' && response) {
624
setResults(prev => ({ ...prev, [modeKey]: response }));
625
}
626
};
627
628
return (
629
<LoadScript googleMapsApiKey="YOUR_API_KEY">
630
<div>
631
<div style={{ padding: '10px', background: '#f0f0f0' }}>
632
<h4>Travel Mode Comparison: NYC to Times Square</h4>
633
634
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: '10px', marginBottom: '20px' }}>
635
{travelModes.map(({ key, mode, name }) => (
636
<button
637
key={key}
638
onClick={() => calculateForMode(key, mode)}
639
disabled={calculating[key]}
640
style={{ padding: '10px' }}
641
>
642
{calculating[key] ? 'Calculating...' : `Calculate ${name}`}
643
</button>
644
))}
645
</div>
646
647
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '20px' }}>
648
{travelModes.map(({ key, name }) => (
649
<div key={key} style={{ background: 'white', padding: '10px', borderRadius: '4px' }}>
650
<h5>{name}</h5>
651
{results[key] ? (
652
<div>
653
<div>Distance: {results[key].rows[0]?.elements[0]?.distance?.text}</div>
654
<div>Duration: {results[key].rows[0]?.elements[0]?.duration?.text}</div>
655
</div>
656
) : (
657
<div>No data</div>
658
)}
659
</div>
660
))}
661
</div>
662
</div>
663
664
<GoogleMap
665
center={{ lat: 40.7128, lng: -74.0060 }}
666
zoom={13}
667
mapContainerStyle={{ width: '100%', height: '300px' }}
668
>
669
{Object.entries(calculating).map(([modeKey, isCalculating]) =>
670
isCalculating && (
671
<DistanceMatrixService
672
key={modeKey}
673
options={{
674
origins: [{ lat: 40.7128, lng: -74.0060 }],
675
destinations: [{ lat: 40.7589, lng: -73.9851 }],
676
travelMode: travelModes.find(m => m.key === modeKey)?.mode || google.maps.TravelMode.DRIVING,
677
unitSystem: google.maps.UnitSystem.IMPERIAL
678
}}
679
callback={createCallback(modeKey)}
680
/>
681
)
682
)}
683
</GoogleMap>
684
</div>
685
</LoadScript>
686
);
687
}
688
```
689
690
### StreetViewService Component
691
692
Provides access to Street View imagery and metadata for locations with panoramic photo availability.
693
694
```typescript { .api }
695
/**
696
* Access to Street View imagery and metadata
697
* Provides information about available Street View panoramas
698
*/
699
interface StreetViewServiceProps {
700
// Lifecycle events
701
onLoad?: (streetViewService: google.maps.StreetViewService) => void;
702
onUnmount?: (streetViewService: google.maps.StreetViewService) => void;
703
}
704
705
function StreetViewService(props: StreetViewServiceProps): JSX.Element;
706
```
707
708
### StreetViewPanorama Component
709
710
Displays Street View panoramas with navigation controls and customizable viewing options.
711
712
```typescript { .api }
713
/**
714
* Displays Street View panoramas
715
* Interactive panoramic street-level imagery with navigation
716
*/
717
interface StreetViewPanoramaProps {
718
options?: google.maps.StreetViewPanoramaOptions;
719
720
// Event handlers
721
onCloseClick?: () => void;
722
onPanoChanged?: () => void;
723
onPositionChanged?: () => void;
724
onPovChanged?: () => void;
725
onResize?: () => void;
726
onStatusChanged?: () => void;
727
onVisibleChanged?: () => void;
728
onZoomChanged?: () => void;
729
730
// Lifecycle events
731
onLoad?: (streetViewPanorama: google.maps.StreetViewPanorama) => void;
732
onUnmount?: (streetViewPanorama: google.maps.StreetViewPanorama) => void;
733
}
734
735
function StreetViewPanorama(props: StreetViewPanoramaProps): JSX.Element;
736
```
737
738
**Usage Examples:**
739
740
```typescript
741
// Street View integration
742
function StreetViewExample() {
743
const [streetViewPosition, setStreetViewPosition] = useState({ lat: 40.7128, lng: -74.0060 });
744
const [streetViewVisible, setStreetViewVisible] = useState(false);
745
746
return (
747
<LoadScript googleMapsApiKey="YOUR_API_KEY">
748
<div>
749
<div style={{ padding: '10px', background: '#f0f0f0' }}>
750
<button
751
onClick={() => setStreetViewVisible(!streetViewVisible)}
752
style={{ marginBottom: '10px' }}
753
>
754
{streetViewVisible ? 'Hide' : 'Show'} Street View
755
</button>
756
</div>
757
758
<div style={{ display: 'flex', height: '400px' }}>
759
<GoogleMap
760
center={streetViewPosition}
761
zoom={15}
762
mapContainerStyle={{ width: '50%', height: '100%' }}
763
onClick={(e) => {
764
if (e.latLng) {
765
setStreetViewPosition(e.latLng.toJSON());
766
}
767
}}
768
/>
769
770
{streetViewVisible && (
771
<div style={{ width: '50%' }}>
772
<StreetViewPanorama
773
options={{
774
position: streetViewPosition,
775
pov: { heading: 34, pitch: 10 },
776
zoom: 1,
777
visible: true
778
}}
779
onLoad={(panorama) => console.log('Street View loaded')}
780
onPositionChanged={() => console.log('Street View position changed')}
781
/>
782
</div>
783
)}
784
</div>
785
</div>
786
</LoadScript>
787
);
788
}
789
```
790
791
### Service Integration Patterns
792
793
Common patterns for combining multiple Google Maps services effectively.
794
795
```typescript { .api }
796
/**
797
* Service integration patterns and best practices
798
*/
799
interface ServiceIntegrationPatterns {
800
// Sequential service calls
801
sequentialServices: boolean; // Avoid simultaneous heavy requests
802
803
// Caching strategies
804
cacheResults: boolean; // Cache directions/distance results
805
cacheTimeout: number; // Cache expiration time
806
807
// Error handling
808
retryOnFailure: boolean; // Retry failed requests
809
maxRetries: number; // Maximum retry attempts
810
fallbackBehavior: string; // Behavior when services fail
811
}
812
813
// Example service orchestration
814
const ServiceOrchestrator = {
815
async calculateRouteWithAlternatives(origin: string, destination: string) {
816
// 1. Get directions
817
const directions = await this.getDirections(origin, destination);
818
819
// 2. Calculate distance matrix for comparison
820
const matrix = await this.getDistanceMatrix([origin], [destination]);
821
822
// 3. Check Street View availability at key points
823
const streetViewAvailable = await this.checkStreetView(destination);
824
825
return {
826
directions,
827
matrix,
828
streetViewAvailable
829
};
830
}
831
};
832
```