UNPKG

devextreme

Version:

HTML5 JavaScript Component Suite for Responsive Web Development

411 lines (409 loc) • 16 kB
/** * DevExtreme (cjs/__internal/ui/map/m_provider.dynamic.azure.js) * Version: 24.2.6 * Build date: Mon Mar 17 2025 * * Copyright (c) 2012 - 2025 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _color = _interopRequireDefault(require("../../../color")); var _renderer = _interopRequireDefault(require("../../../core/renderer")); var _ajax = _interopRequireDefault(require("../../../core/utils/ajax")); var _common = require("../../../core/utils/common"); var _iterator = require("../../../core/utils/iterator"); var _type = require("../../../core/utils/type"); var _window = require("../../../core/utils/window"); var _ui = _interopRequireDefault(require("../../../ui/widget/ui.errors")); var _m_provider = _interopRequireDefault(require("./m_provider.dynamic")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e } } const window = (0, _window.getWindow)(); const AZURE_BASE_LINK = "https://atlas.microsoft.com/"; let AZURE_JS_URL = `${AZURE_BASE_LINK}sdk/javascript/mapcontrol/3/atlas.min.js`; let AZURE_CSS_URL = `${AZURE_BASE_LINK}/sdk/javascript/mapcontrol/3/atlas.min.css`; let CUSTOM_URL; const MAP_MARKER_TOOLTIP_CLASS = "dx-map-marker-tooltip"; const CAMERA_PADDING = 50; const azureMapsLoaded = function() { var _window$atlas; return null === (_window$atlas = window.atlas) || void 0 === _window$atlas ? void 0 : _window$atlas.Map }; let azureMapsLoader; class AzureProvider extends _m_provider.default { _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) })) } })) } _geocodeLocationImpl(location) { return new Promise((resolve => { if (!(0, _type.isDefined)(location)) { resolve(new atlas.data.Position(0, 0)); return } const searchURL = `${AZURE_BASE_LINK}geocode?subscription-key=${this._keyOption("azure")}&api-version=2023-06-01&query=${location}&limit=1`; _ajax.default.sendRequest({ url: CUSTOM_URL ?? searchURL, dataType: "json" }).then((result => { var _result$features$; const coordinates = null === result || void 0 === result || null === (_result$features$ = result.features[0]) || void 0 === _result$features$ || null === (_result$features$ = _result$features$.geometry) || void 0 === _result$features$ ? void 0 : _result$features$.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() { return new Promise((resolve => { if (azureMapsLoaded()) { resolve() } if (!azureMapsLoader) { azureMapsLoader = this._loadMapResources() } azureMapsLoader.then((() => { if (azureMapsLoaded()) { resolve(); return } this._loadMapResources().then(resolve) })) })) } _loadMapResources() { return Promise.all([this._loadMapScript(), this._loadMapStyles()]) } _loadMapScript() { return new Promise((resolve => { _ajax.default.sendRequest({ url: AZURE_JS_URL, dataType: "script" }).then((() => { resolve() })) })) } _loadMapStyles() { return new Promise((resolve => { _ajax.default.sendRequest({ url: AZURE_CSS_URL, dataType: "text" }).then((css => { (0, _renderer.default)("<style>").html(css).appendTo((0, _renderer.default)("head")); resolve() })) })) } _init() { this._createMap(); return Promise.resolve() } _createMap() { this._map = new atlas.Map(this._$container[0], { authOptions: { authType: "subscriptionKey", subscriptionKey: this._keyOption("azure") }, zoom: this._option("zoom"), style: this._mapType(this._option("type")), interactive: !this._option("disabled") }); this.updateControls() } _attachHandlers() { this._map.events.add("move", this._viewChangeHandler.bind(this)); this._map.events.add("click", this._clickActionHandler.bind(this)) } _viewChangeHandler() { const { bounds: bounds } = this._map.getCamera(); this._option("bounds", this._normalizeLocationRect(bounds)); const { center: center } = this._map.getCamera(); this._option("center", this._normalizeLocation(center)); if (!this._preventZoomChangeEvent) { this._option("zoom", this._map.getCamera().zoom) } } _clickActionHandler(e) { if ("click" === e.type) { this._fireClickAction({ location: this._normalizeLocation(e.position) }) } } updateDimensions() { this._map.resize(); return Promise.resolve() } updateDisabled() { const disabled = this._option("disabled"); this._map.setUserInteraction({ interactive: !disabled }); return Promise.resolve() } updateMapType() { const newType = this._mapType(this._option("type")); const currentType = this._map.getStyle().style; if (newType !== currentType) { this._map.setStyle({ style: newType }) } return Promise.resolve() } updateBounds() { return Promise.all([this._resolveLocation(this._option("bounds.northEast")), this._resolveLocation(this._option("bounds.southWest"))]).then((result => { this._map.setCamera({ bounds: [result[1][0], result[1][1], result[0][0], result[0][1]], padding: 50 }) })) } updateCenter() { return this._resolveLocation(this._option("center")).then((center => { this._map.setCamera({ center: center }) })) } updateZoom() { this._map.setCamera({ zoom: this._option("zoom") }); return Promise.resolve() } updateControls() { const { controls: controls } = this._option(); if (controls) { this._map.controls.add([new atlas.control.CompassControl, new atlas.control.PitchControl, new atlas.control.StyleControl({ mapStyles: ["road", "satellite", "satellite_road_labels"] }), new atlas.control.ZoomControl], { position: "top-right" }) } else { const allControls = this._map.controls.getControls(); const controlsToRemove = allControls.slice(2); this._map.controls.remove(controlsToRemove) } return Promise.resolve() } _renderMarker(options) { return this._resolveLocation(options.location).then((location => { const markerOptions = { position: location }; const icon = options.iconSrc || this._option("markerIconSrc"); if (icon) { markerOptions.htmlContent = this._createIconTemplate(icon) } const marker = new atlas.HtmlMarker(markerOptions); this._map.markers.add(marker); const popup = this._renderTooltip(location, options.tooltip); let handler; if (options.onClick || options.tooltip) { const markerClickAction = this._mapWidget._createAction(options.onClick || _common.noop); const markerNormalizedLocation = this._normalizeLocation(location); handler = this._map.events.add("click", marker, (() => { markerClickAction({ location: markerNormalizedLocation }); if (popup) { if (popup.isOpen()) { popup.close() } else { popup.open() } } })) } return { location: location, marker: marker, popup: popup, handler: handler } })) } _renderTooltip(location, options) { if (!options) { return } options = this._parseTooltipOptions(options); const $content = (0, _renderer.default)("<div>").html(options.text).addClass("dx-map-marker-tooltip"); const popup = new atlas.Popup({ content: $content[0], position: location, pixelOffset: [0, -30] }); this._map.popups.add(popup); if (options.visible) { popup.open() } return popup } _destroyMarker(marker) { this._map.markers.remove(marker.marker); if (marker.popup) { this._map.popups.remove(marker.popup) } if (marker.handler) { this._map.events.remove(marker.handler) } } _renderRoute(options) { return Promise.all((0, _iterator.map)(options.locations, (point => this._resolveLocation(point)))).then((locations => new Promise((resolve => { const routeColor = new _color.default(options.color || this._defaultRouteColor()).toHex(); const routeOpacity = options.opacity || this._defaultRouteOpacity(); const queryCoordinates = locations.map((location => `${location[1]},${location[0]}`)); const query = queryCoordinates.join(":"); const routeType = this._movementMode(options.mode); const searchUrl = `${AZURE_BASE_LINK}route/directions/json?subscription-key=${this._keyOption("azure")}&api-version=1.0&query=${query}&travelMode=${routeType}`; _ajax.default.sendRequest({ url: CUSTOM_URL ?? searchUrl, dataType: "json" }).then((result => { if (null !== result && void 0 !== result && result.routes && result.routes.length > 0) { const route = result.routes[0]; const routeCoordinates = route.legs.flatMap((leg => leg.points.map((point => [point.longitude, point.latitude])))); const dataSource = new atlas.source.DataSource; dataSource.add(new atlas.data.Feature(new atlas.data.LineString(routeCoordinates), {})); const lineLayer = new atlas.layer.LineLayer(dataSource, null, { strokeColor: routeColor, strokeOpacity: routeOpacity, strokeWidth: options.weight || this._defaultRouteWeight() }); this._map.sources.add(dataSource); this._map.layers.add(lineLayer); const bounds = atlas.data.BoundingBox.fromPositions(routeCoordinates); if (this._option("autoAdjust")) { this._map.setCamera({ bounds: bounds, padding: 50 }) } resolve({ instance: { dataSource: dataSource, lineLayer: lineLayer }, northEast: [bounds[2], bounds[3]], southWest: [bounds[0], bounds[1]] }) } })).catch((e => { const errorMessage = e.responseJSON.error.message; const dataSource = new atlas.source.DataSource; const lineLayer = new atlas.layer.LineLayer(dataSource, null, {}); _ui.default.log("W1006", errorMessage); resolve({ instance: { dataSource: dataSource, lineLayer: lineLayer } }) })) })))) } _destroyRoute(routeObject) { this._map.layers.remove(routeObject.instance.lineLayer); this._map.sources.remove(routeObject.instance.dataSource) } _fitBounds() { this._updateBounds(); if (this._bounds && this._option("autoAdjust")) { const zoomBeforeFitting = this._map.getCamera().zoom; this._preventZoomChangeEvent = true; this._map.setCamera({ bounds: this._bounds, padding: 50 }); const zoomAfterFitting = this._map.getCamera().zoom; if (zoomBeforeFitting < zoomAfterFitting) { this._map.setCamera({ zoom: zoomBeforeFitting }) } else { this._option("zoom", zoomAfterFitting) } delete this._preventZoomChangeEvent } return Promise.resolve() } _extendBounds(location) { const [longitude, latitude] = location; if (this._bounds) { const newBounds = new atlas.data.BoundingBox([longitude, latitude, longitude, latitude]); this._bounds = atlas.data.BoundingBox.merge(this._bounds, newBounds) } else { this._bounds = new atlas.data.BoundingBox([longitude - 1e-4, latitude - 1e-4, longitude + 1e-4, latitude + 1e-4]) } } clean() { if (this._map) { this._map.events.remove("move", this._viewChangeHandler); this._map.events.remove("click", this._clickActionHandler); this._clearMarkers(); this._clearRoutes(); this._map.dispose() } return Promise.resolve() } } var _default = exports.default = AzureProvider;