Skip to content

Commit 46031a4

Browse files
ROU-12040: Change code to use the new Routes API (#210)
* ROU-11865: Spike for supporting the new Routes API (#205) * Adding new types of google maps * Adding new helper method * Adding new constants * Adding new library * Adding new type checker method * Simplifying the code with new helper methods * Adding new class to render Routes * Changing directions to use new API * Creating helper function Co-authored-by: Marta Carlos <101343976+OS-martacarlos@users.noreply.github.com> * Fixing directions * Update Directions.ts * Centering the map --------- Co-authored-by: Marta Carlos <101343976+OS-martacarlos@users.noreply.github.com> * Adding comments * Fixing regex * Adding new types for the new route API * Transform coordinates to new type * Storing developer sent way points to show on route * Storing route markers * Building route with intermediate points * Move file to location * Rename file * Renaming class * Removing unnecessary code * Improving the security of the regex --------- Co-authored-by: Marta Carlos <101343976+OS-martacarlos@users.noreply.github.com>
1 parent 7a5fd23 commit 46031a4

6 files changed

Lines changed: 564 additions & 101 deletions

File tree

src/Providers/Maps/Google/Constants/Constants.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
namespace Provider.Maps.Google.Constants {
2+
// Regular expression to validate if a string is a set of coordinates. Accepts "12.300,-8.220", "12.300 ,-8.220", and "12.300, -8.220".
3+
export const coordinateValidator = /^-?\d+(?:\.\d+)? ?, ?-?\d+(?:\.\d+)?$/;
4+
25
// Name of the Google Maps Version in the LocalStorage
36
export const googleMapsLocalStorageVersionKey = 'gmVersion';
47

@@ -27,14 +30,22 @@ namespace Provider.Maps.Google.Constants {
2730
/** URL for GoogleMapsApis */
2831
/************************** */
2932
export const googleMapsApiURL = 'https://maps.googleapis.com/maps/api';
33+
// URL for GoogleMaps API to make use of the routes API
34+
export const googleMapsRoutesApiURL = 'https://routes.googleapis.com/directions/v2:computeRoutes';
3035
// URL for GoogleMaps API to make use of the Google Map
3136
export const googleMapsApiMap = `${googleMapsApiURL}/js`;
3237
// URL for GoogleMaps API to make use of the Google StaticMap
3338
export const googleMapsApiStaticMap = `${googleMapsApiURL}/staticmap`;
39+
40+
/****************************** */
41+
/** Options for GoogleMapsApis */
42+
/****************************** */
43+
// When using Google Maps Routes API, these are the options that we want to retrieve.
44+
export const GoogleMapsRouteOptions = 'routes.duration,routes.distanceMeters,routes.polyline.encodedPolyline';
3445
// In order to use the drawingTools we need to add it into the libraries via the URL = drawing
3546
// In order to use the heatmap we need to add it into the libraries via the URL = visualization
3647
// In order to use the searchplaces we need to add it into the libraries via the URL = places (in case the Map is the first to import the scripts)
37-
export const GoogleMapsLibraries = 'drawing,visualization,places,marker';
48+
export const GoogleMapsLibraries = 'drawing,visualization,places,marker,geometry';
3849
// Used to check if modules are available on cycles of 100ms */
3950
export const checkGoogleMapsLibrariesMaxAttempts = 25;
4051
// Version of the Google Maps to be loaded.
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
namespace Provider.Maps.Google.Feature {
2+
export class DirectionsRenderer implements OSFramework.Maps.Interface.IDisposable {
3+
private _isRouteRendered: boolean;
4+
private _map: OSMap.IMapGoogle;
5+
private _pathPolyline: google.maps.Polyline;
6+
private _routeMarkers: google.maps.marker.AdvancedMarkerElement[];
7+
8+
constructor(map: OSMap.IMapGoogle) {
9+
this._map = map;
10+
this._isRouteRendered = false;
11+
this._routeMarkers = [];
12+
}
13+
14+
private _buildMarker(
15+
position: google.maps.LatLng | google.maps.LatLngLiteral,
16+
label: string
17+
): google.maps.marker.AdvancedMarkerElement {
18+
// The pin element is the colored teardrop shape.
19+
const pin = new google.maps.marker.PinElement({
20+
background: '#EA4335', // Red background
21+
borderColor: '#D6352D', // Dark red border
22+
glyphColor: '#FFFFFF', // White letter
23+
scale: 1,
24+
});
25+
26+
// Create the advanced marker.
27+
const marker = new google.maps.marker.AdvancedMarkerElement({
28+
position: {
29+
lat: Helper.Conversions.GetCoordinateValue(position.lat),
30+
lng: Helper.Conversions.GetCoordinateValue(position.lng),
31+
},
32+
map: this._map.provider,
33+
content: pin.element,
34+
});
35+
36+
pin.glyph = label;
37+
38+
return marker;
39+
}
40+
41+
public dispose(): void {
42+
this.removeRoute();
43+
this._map = undefined;
44+
}
45+
46+
public removeRoute(): void {
47+
if (this._pathPolyline) {
48+
this._pathPolyline.setMap(null);
49+
this._pathPolyline = undefined;
50+
}
51+
this._routeMarkers.forEach((marker) => {
52+
marker.map = undefined;
53+
});
54+
this._routeMarkers = [];
55+
this._isRouteRendered = false;
56+
}
57+
58+
public renderRoute(
59+
encodedPolyline: string,
60+
_waypoints?: string[]
61+
): OSFramework.Maps.OSStructures.ReturnMessage {
62+
this._isRouteRendered && this.removeRoute();
63+
64+
if (encodedPolyline) {
65+
const bounds = new google.maps.LatLngBounds();
66+
const routePath = google.maps.geometry.encoding.decodePath(encodedPolyline);
67+
68+
// Create the polyline for the route path.
69+
this._pathPolyline = new google.maps.Polyline({
70+
path: routePath,
71+
strokeColor: '#4285F470', // A solid red color
72+
strokeWeight: 6,
73+
map: this._map.provider,
74+
});
75+
76+
let pointCharacter = 65; // ASCII code for 'A'
77+
78+
const buildMarkerWithLabel = (point: google.maps.LatLng | google.maps.LatLngLiteral) => {
79+
// Create a marker for each point in the route path.
80+
const label = String.fromCharCode(pointCharacter++);
81+
// Build the marker with the point and label.
82+
const marker = this._buildMarker(point, label);
83+
// Store the marker in the route markers array.
84+
this._routeMarkers.push(marker);
85+
bounds.extend(point);
86+
};
87+
88+
buildMarkerWithLabel(routePath[0]);
89+
90+
_waypoints.forEach((waypoint) => {
91+
buildMarkerWithLabel(Helper.Conversions.GetCoordinatesFromString(waypoint));
92+
});
93+
94+
buildMarkerWithLabel(routePath[routePath.length - 1]);
95+
96+
// Set the map bounds to fit the route.
97+
this._map.provider.fitBounds(bounds);
98+
99+
this._isRouteRendered = true;
100+
101+
return {
102+
isSuccess: true,
103+
};
104+
} else {
105+
return {
106+
code: OSFramework.Maps.Enum.ErrorCodes.LIB_FailedSetDirections,
107+
message: 'Encoded polyline is empty or undefined.',
108+
};
109+
}
110+
}
111+
}
112+
}

0 commit comments

Comments
 (0)