From c865d4e77fb5116bdbabe689337806484272d91e Mon Sep 17 00:00:00 2001 From: Alexander Kozlovskiy Date: Mon, 30 Sep 2024 03:35:06 -0500 Subject: [PATCH 1/6] Map - support Azure provider --- .../devextreme/js/__internal/ui/map/m_map.ts | 2 + .../ui/map/m_provider.dynamic.azure.ts | 456 ++++++++++++++++++ .../ui/map/m_provider.dynamic.google.ts | 11 - .../__internal/ui/map/m_provider.dynamic.ts | 13 + 4 files changed, 471 insertions(+), 11 deletions(-) create mode 100644 packages/devextreme/js/__internal/ui/map/m_provider.dynamic.azure.ts diff --git a/packages/devextreme/js/__internal/ui/map/m_map.ts b/packages/devextreme/js/__internal/ui/map/m_map.ts index 2f70418c9eca..b72404aceaa4 100644 --- a/packages/devextreme/js/__internal/ui/map/m_map.ts +++ b/packages/devextreme/js/__internal/ui/map/m_map.ts @@ -15,12 +15,14 @@ import { addNamespace } from '@js/events/utils/index'; import errors from '@js/ui/widget/ui.errors'; import Widget from '@js/ui/widget/ui.widget'; +import azure from './m_provider.dynamic.azure'; import bing from './m_provider.dynamic.bing'; import google from './m_provider.dynamic.google'; // NOTE external urls must have protocol explicitly specified (because inside Cordova package the protocol is "file:") import googleStatic from './m_provider.google_static'; const PROVIDERS = { + azure, googleStatic, google, bing, diff --git a/packages/devextreme/js/__internal/ui/map/m_provider.dynamic.azure.ts b/packages/devextreme/js/__internal/ui/map/m_provider.dynamic.azure.ts new file mode 100644 index 000000000000..2be2aa747b35 --- /dev/null +++ b/packages/devextreme/js/__internal/ui/map/m_provider.dynamic.azure.ts @@ -0,0 +1,456 @@ +import Color from '@js/color'; +import $ from '@js/core/renderer'; +import ajax from '@js/core/utils/ajax'; +import { noop } from '@js/core/utils/common'; +import { Deferred } from '@js/core/utils/deferred'; +import { map } from '@js/core/utils/iterator'; +import { isDefined } from '@js/core/utils/type'; +import { getWindow } from '@js/core/utils/window'; +import errors from '@js/ui/widget/ui.errors'; + +import DynamicProvider from './m_provider.dynamic'; + +const window = getWindow(); + +declare let atlas: any; + +const AZURE_LINK = 'https://atlas.microsoft.com/'; +const AZURE_JS_URL = `${AZURE_LINK}sdk/javascript/mapcontrol/3/atlas.min.js`; +const AZURE_CSS_URL = `${AZURE_LINK}/sdk/javascript/mapcontrol/3/atlas.min.css`; + +const MAP_MARKER_TOOLTIP_CLASS = 'dx-map-marker-tooltip'; + +const azureMapsLoaded = function () { + // @ts-expect-error + return window.atlas && window.atlas.Map; +}; + +let azureMapsLoader; + +const AzureProvider = DynamicProvider.inherit({ + _mapType(type) { + const mapTypes = { + roadmap: 'road', + satellite: 'satellite', + hybrid: 'satellite_road_labels', + }; + return mapTypes[type] || mapTypes.roadmap; + }, + + _movementMode(type) { + const movementTypes = { + driving: 'car', + walking: 'pedestrian', + }; + return movementTypes[type] || movementTypes.driving; + }, + + _resolveLocation(location) { + return new Promise((resolve) => { + const latLng = this._getLatLng(location); + if (latLng) { + resolve(new atlas.data.Position(latLng.lng, latLng.lat)); + } else { + this._geocodeLocation(location).then((geocodedLocation) => { + resolve(geocodedLocation); + }); + } + }); + }, + + _geocodedLocations: {}, + _geocodeLocationImpl(location) { + return new Promise((resolve) => { + if (!isDefined(location)) { + resolve(new atlas.data.Position(0, 0)); + return; + } + + const searchURL = `${AZURE_LINK}geocode?subscription-key=${this._keyOption('azure')}&api-version=2023-06-01&query=${location}&limit=1`; + + ajax.sendRequest({ + url: searchURL, + dataType: 'json', + }).then((result) => { + const coordinates = result?.features[0]?.geometry?.coordinates; + if (coordinates) { + resolve(new atlas.data.Position(coordinates[0], coordinates[1])); + } else { + resolve(new atlas.data.Position(0, 0)); + } + }); + }); + }, + + _normalizeLocation(location) { + return { + lat: location[1], + lng: location[0], + }; + }, + + _normalizeLocationRect(locationRect) { + return { + northEast: { + lat: locationRect[1], + lng: locationRect[2], + }, + southWest: { + lat: locationRect[3], + lng: locationRect[0], + }, + }; + }, + + _loadImpl() { + if (azureMapsLoaded()) { + return Promise.resolve(); + } + + if (!azureMapsLoader) { + azureMapsLoader = this._loadMapResources(); + } + + return azureMapsLoader; + }, + + _loadMapResources() { + return Promise.all([ + this._loadMapScript(), + this._loadMapStyles(), + ]); + }, + + _loadMapScript() { + return new Promise((resolve) => { + ajax.sendRequest({ + url: AZURE_JS_URL, + dataType: 'script', + }).done(() => { resolve(); }); + }); + }, + + _loadMapStyles() { + return new Promise((resolve) => { + ajax.sendRequest({ + url: AZURE_CSS_URL, + dataType: 'text', + }).done((css) => { + $('