Skip to content

Commit

Permalink
Merge pull request #184 from OutSystems/ROU-4776
Browse files Browse the repository at this point in the history
ROU-4776: adding ability to change google maps version
  • Loading branch information
rugoncalves authored Oct 8, 2024
2 parents fa0ace1 + 42b9a0a commit 221d55e
Show file tree
Hide file tree
Showing 16 changed files with 276 additions and 65 deletions.
2 changes: 1 addition & 1 deletion src/OSFramework/Maps/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace OSFramework.Maps.Constants {
export const OSMapsVersion = '2.0.0';

/**
* DataGrid Set platform in use.
* Maps Set OutSystems platform in use (O11/ODC).
* - This value will be set dynamically at the compilation momment!
* - Do not change default string value!
*/
Expand Down
43 changes: 0 additions & 43 deletions src/OSFramework/Maps/Helper/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,6 @@ namespace OSFramework.Maps.Helper.Constants {
export const uniqueIdAttribute = 'name';
/** Tag used to find the container where the SearchPlaces is going to be rendered in run time*/
export const runtimeSearchPlacesUniqueIdCss = '.ss-searchPlaces';
/** Tag used to find the google-maps-script */
export const googleMapsScript = 'google-maps-script';

/************************** */
/** DEF VALUES */
Expand All @@ -80,48 +78,7 @@ namespace OSFramework.Maps.Helper.Constants {
export const drawingPolygonCompleted = 'polygoncomplete';
export const drawingCircleCompleted = 'circlecomplete';
export const drawingRectangleCompleted = 'rectanglecomplete';
/* Default name for drawing completed event - Leaflet*/
export const drawingLeafletCompleted = 'draw:created';
/** Default gradient heatmap colors from google provider */
export const gradientHeatmapColors = [
'rgba(102, 255, 0, 0)',
'rgba(102, 255, 0, 1)',
'rgba(147, 255, 0, 1)',
'rgba(193, 255, 0, 1)',
'rgba(238, 255, 0, 1)',
'rgba(244, 227, 0, 1)',
'rgba(249, 198, 0, 1)',
'rgba(255, 170, 0, 1)',
'rgba(255, 113, 0, 1)',
'rgba(255, 57, 0, 1)',
'rgba(255, 0, 0, 1)',
];

/** Default/Custom cluster icon CSS class */
export const clusterIconCSSClass = 'custom-clustericon';
/** Default Failure auth code */
export const googleMapsAuthFailure = 'gm_authFailure';

/************************** */
/** URL for GoogleMapsApis */
/************************** */
export const googleMapsApiURL = 'https://maps.googleapis.com/maps/api';
/** URL for GoogleMaps API to make use of the Google Map */
export const googleMapsApiMap = `${googleMapsApiURL}/js`;
/** URL for GoogleMaps API to make use of the Google StaticMap */
export const googleMapsApiStaticMap = `${googleMapsApiURL}/staticmap`;
/** Version of the Google Maps to be loaded. */
export const gmversion = '3.57'; //Stable version Mid-February 2024.
// In order to use the drawingTools we need to add it into the libraries via the URL = drawing
// In order to use the heatmap we need to add it into the libraries via the URL = visualization
// 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)
export const gmlibraries = 'drawing,visualization,places,marker';

/******************** */
/** URLs for Leaflet */
/******************** */
export const openStreetMapTileLayer = {
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
};
}
34 changes: 34 additions & 0 deletions src/OSFramework/Maps/Helper/LocalStorage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace OSFramework.Maps.Helper.LocalStorage {
/**
* Get an item from the local storage.
*
* @export
* @param {string} key
* @return {*} {string}
*/
export function GetItem(key: string): string {
return window.localStorage.getItem(key);
}

/**
* Checks if an item exists in the local storage.
*
* @export
* @param {string} key
* @return {*} {boolean}
*/
export function HasItem(key: string): boolean {
return window.localStorage.getItem(key) !== null;
}

/**
* Set an item in the local storage.
*
* @export
* @param {string} key
* @param {string} value
*/
export function SetItem(key: string, value: string): void {
window.localStorage.setItem(key, value);
}
}
53 changes: 53 additions & 0 deletions src/OSFramework/Maps/ProviderVersion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
namespace OSFramework.Maps.ProviderVersion {
/**
* Function that allows to set the version of a specific the provider.
* If the forceRefresh is set to true and the version has changed, the page will be reloaded.
* Otherwise, the version will be updated in the local storage.
*
* @export
* @param {OSFramework.Maps.Enum.ProviderType} provider
* @param {string} version
* @param {boolean} [forceRefresh=false]
*/
export function Change(provider: OSFramework.Maps.Enum.ProviderType, version: string, forceRefresh = false): void {
let versionChanged = false;
switch (provider) {
case OSFramework.Maps.Enum.ProviderType.Google:
versionChanged = Provider.Maps.Google.Version.Change(version);
break;
case OSFramework.Maps.Enum.ProviderType.Leaflet:
versionChanged = Provider.Maps.Leaflet.Version.Change(version);
break;
default:
throw new Error(`There provider '${provider}' is not supported.`);
}

if (forceRefresh && versionChanged) {
// Force refresh the library
window.location.reload();
}
}

/**
* Function that allows to get the version of a specific the provider
*
* @export
* @param {OSFramework.Maps.Enum.ProviderType} provider
* @return {*} {string}
*/
export function Get(provider: OSFramework.Maps.Enum.ProviderType): string {
let version = '';
switch (provider) {
case OSFramework.Maps.Enum.ProviderType.Google:
version = Provider.Maps.Google.Version.Get();
break;
case OSFramework.Maps.Enum.ProviderType.Leaflet:
version = Provider.Maps.Leaflet.Version.Get();
break;
default:
throw new Error(`There provider '${provider}' is not supported.`);
}
return version;
}
}
29 changes: 29 additions & 0 deletions src/OutSystems/Maps/MapAPI/LibraryVersioning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
namespace OutSystems.Maps.MapAPI.ProviderLibrary {
/**
* API that allows to get the version of the provider
*
* @export
* @param {OSFramework.Maps.Enum.ProviderType} provider
* @return {*} {string}
*/
export function GetVersion(provider: OSFramework.Maps.Enum.ProviderType): string {
return OSFramework.Maps.ProviderVersion.Get(provider);
}

/**
* API that allows to set the version of the provider
*
* @export
* @param {OSFramework.Maps.Enum.ProviderType} provider
* @param {string} version
* @param {boolean} [forceRefresh=false]
*/
export function SetVersion(
provider: OSFramework.Maps.Enum.ProviderType,
version: string,
forceRefresh = false
): void {
OSFramework.Maps.ProviderVersion.Change(provider, version, forceRefresh);
}
}
40 changes: 40 additions & 0 deletions src/Providers/Maps/Google/Constants/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
namespace Provider.Maps.Google.Constants {
// Name of the Google Maps Version in the LocalStorage
export const googleMapsLocalStorageVersionKey = 'gmVersion';

// Default Failure auth code
export const googleMapsAuthFailure = 'gm_authFailure';

// Tag used to find the google-maps-script
export const googleMapsScript = 'google-maps-script';

/** Default gradient heatmap colors from google provider */
export const gradientHeatmapColors = [
'rgba(102, 255, 0, 0)',
'rgba(102, 255, 0, 1)',
'rgba(147, 255, 0, 1)',
'rgba(193, 255, 0, 1)',
'rgba(238, 255, 0, 1)',
'rgba(244, 227, 0, 1)',
'rgba(249, 198, 0, 1)',
'rgba(255, 170, 0, 1)',
'rgba(255, 113, 0, 1)',
'rgba(255, 57, 0, 1)',
'rgba(255, 0, 0, 1)',
];

/************************** */
/** URL for GoogleMapsApis */
/************************** */
export const googleMapsApiURL = 'https://maps.googleapis.com/maps/api';
// URL for GoogleMaps API to make use of the Google Map
export const googleMapsApiMap = `${googleMapsApiURL}/js`;
// URL for GoogleMaps API to make use of the Google StaticMap
export const googleMapsApiStaticMap = `${googleMapsApiURL}/staticmap`;
// In order to use the drawingTools we need to add it into the libraries via the URL = drawing
// In order to use the heatmap we need to add it into the libraries via the URL = visualization
// 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)
export const GoogleMapsLibraries = 'drawing,visualization,places,marker';
// Version of the Google Maps to be loaded.
export const googleMapsVersion = '3.58'; //Stable version Mid-November 2024.
}
2 changes: 1 addition & 1 deletion src/Providers/Maps/Google/HeatmapLayer/HeatmapLayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace Provider.Maps.Google.HeatmapLayer {
/** In case the gradient is not defined, use the default from GoogleProvider */
private _gradientColors(gradient: string[]) {
if (gradient.length === 0) {
return OSFramework.Maps.Helper.Constants.gradientHeatmapColors;
return Constants.gradientHeatmapColors;
}
return gradient;
}
Expand Down
6 changes: 2 additions & 4 deletions src/Providers/Maps/Google/OSMap/OSMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ namespace Provider.Maps.Google.OSMap {
* Creates the Map via GoogleMap API
*/
private _createGoogleMap(): void {
const script = document.getElementById(
OSFramework.Maps.Helper.Constants.googleMapsScript
) as HTMLScriptElement;
const script = document.getElementById(Constants.googleMapsScript) as HTMLScriptElement;

// Make sure the GoogleMaps script in the <head> of the html page contains the same apiKey as the one in the configs.
const apiKey = /key=(.*)&libraries/.exec(script.src)[1];
Expand All @@ -97,7 +95,7 @@ namespace Provider.Maps.Google.OSMap {
this._getProviderConfig()
);
// Check if the provider has been created with a valid APIKey
window[OSFramework.Maps.Helper.Constants.googleMapsAuthFailure] = () =>
window[Constants.googleMapsAuthFailure] = () =>
this.mapEvents.trigger(
OSFramework.Maps.Event.OSMap.MapEventType.OnError,
this,
Expand Down
2 changes: 1 addition & 1 deletion src/Providers/Maps/Google/OSMap/StaticMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ namespace Provider.Maps.Google.OSMap {

image.src =
/* eslint-disable prettier/prettier */
`${OSFramework.Maps.Helper.Constants.googleMapsApiStaticMap}?` +
`${Constants.googleMapsApiStaticMap}?` +
'key=' +
this.config.apiKey +
'&center=' +
Expand Down
6 changes: 2 additions & 4 deletions src/Providers/Maps/Google/SearchPlaces/SearchPlaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,7 @@ namespace Provider.Maps.Google.SearchPlaces {
* Creates the SearchPlaces via GoogleMap API
*/
private _createGooglePlaces(): void {
const script = document.getElementById(
OSFramework.Maps.Helper.Constants.googleMapsScript
) as HTMLScriptElement;
const script = document.getElementById(Constants.googleMapsScript) as HTMLScriptElement;

// Make sure the GoogleMaps script in the <head> of the html page contains the same apiKey as the one in the configs.
const apiKey = /key=(.*)&libraries/.exec(script.src)[1];
Expand Down Expand Up @@ -109,7 +107,7 @@ namespace Provider.Maps.Google.SearchPlaces {
// SearchPlaces(input, options)
this._provider = new google.maps.places.Autocomplete(input, configs as unknown);
// Check if the provider has been created with a valid APIKey
window[OSFramework.Maps.Helper.Constants.googleMapsAuthFailure] = () => {
window[Constants.googleMapsAuthFailure] = () => {
this.searchPlacesEvents.trigger(
OSFramework.Maps.Event.SearchPlaces.SearchPlacesEventType.OnError,
this,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ namespace Provider.Maps.Google.SharedComponents {
const script = document.createElement('script');

script.src =
`${OSFramework.Maps.Helper.Constants.googleMapsApiMap}?` +
`${Constants.googleMapsApiMap}?` +
`key=${apiKey}` +
`&libraries=${OSFramework.Maps.Helper.Constants.gmlibraries}` +
`&v=${OSFramework.Maps.Helper.Constants.gmversion}` +
`&libraries=${Constants.GoogleMapsLibraries}` +
`&v=${Version.Get()}` +
`&loading=async` +
`&callback=GMCB` +
(localization.language !== '' ? `&language=${localization.language}` : '') +
(localization.region !== '' ? `&region=${localization.region}` : '');
script.async = true;
script.defer = true;
script.id = OSFramework.Maps.Helper.Constants.googleMapsScript;
script.id = Constants.googleMapsScript;
document.head.appendChild(script);
});
}
Expand Down
62 changes: 62 additions & 0 deletions src/Providers/Maps/Google/Version/Version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
namespace Provider.Maps.Google.Version {
/**
* Auxiliary function to get the current version of Google Maps loaded on the page.
*
* @return {*} {string}
*/
function GetGoogleMapsVersion(): string {
let version = undefined;
if (window.google && window.google.maps && window.google.maps.version) {
const gmVersion = window.google.maps.version;
const indexMajorMinor = gmVersion.lastIndexOf('.');
version = gmVersion.substring(0, indexMajorMinor);
}
return version;
}

/**
* Set the version of Google Maps to be used on the page.
*
* @export
* @param {string} newVersion
* @return {*} {boolean}
*/
export function Change(newVersion: string): boolean {
const currentVersion =
OSFramework.Maps.Helper.LocalStorage.GetItem(Constants.googleMapsLocalStorageVersionKey) ||
Constants.googleMapsVersion;

const googleVersion = GetGoogleMapsVersion();

// If the version that the developer set is different from the current version, and is different from the version loaded, set the return value to true.
const versionChanged = currentVersion !== newVersion && newVersion !== googleVersion;

OSFramework.Maps.Helper.LocalStorage.SetItem(Constants.googleMapsLocalStorageVersionKey, newVersion);

return versionChanged;
}

/**
* Get the current version of Google Maps loaded on the page.
*
* @export
* @return {*} {string}
*/
export function Get(): string {
let currentVersion =
OSFramework.Maps.Helper.LocalStorage.GetItem(Constants.googleMapsLocalStorageVersionKey) ||
Provider.Maps.Google.Constants.googleMapsVersion;
const googleVersion = GetGoogleMapsVersion();

// If the version that the developer set is still not being used, log a warning message and return the current loaded version.
if (googleVersion !== undefined && currentVersion !== googleVersion) {
OSFramework.Maps.Helper.LogWarningMessage(
`Current version of Google Maps loaded is '${googleVersion}', but on the next page refresh the version will tentatively be '${currentVersion}'.`
);
currentVersion = googleVersion;
}

return currentVersion;
}
}
15 changes: 15 additions & 0 deletions src/Providers/Maps/Leaflet/Constants/Constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Provider.Maps.Leaflet.Constants {
// Version of Leaflet
export const leafletVersion = '1.0.2';

/* Default name for drawing completed event - Leaflet*/
export const drawingLeafletCompleted = 'draw:created';

/******************** */
/** URLs for Leaflet */
/******************** */
export const openStreetMapTileLayer = {
url: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
};
}
Loading

0 comments on commit 221d55e

Please sign in to comment.