| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /**
- * DevExtreme (ui/map/provider.dynamic.google.js)
- * Version: 19.1.16
- * Build date: Tue Oct 18 2022
- *
- * Copyright (c) 2012 - 2022 Developer Express Inc. ALL RIGHTS RESERVED
- * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
- */
- "use strict";
- var $ = require("../../core/renderer");
- var window = require("../../core/utils/window").getWindow();
- var noop = require("../../core/utils/common").noop;
- var devices = require("../../core/devices");
- var Promise = require("../../core/polyfills/promise");
- var extend = require("../../core/utils/extend").extend;
- var map = require("../../core/utils/iterator").map;
- var DynamicProvider = require("./provider.dynamic");
- var errors = require("../widget/ui.errors");
- var Color = require("../../color");
- var ajax = require("../../core/utils/ajax");
- var isDefined = require("../../core/utils/type").isDefined;
- var GOOGLE_MAP_READY = "_googleScriptReady";
- var GOOGLE_URL = "https://maps.googleapis.com/maps/api/js?callback=" + GOOGLE_MAP_READY;
- var INFO_WINDOW_CLASS = "gm-style-iw";
- var CustomMarker;
- var initCustomMarkerClass = function() {
- CustomMarker = function(options) {
- this._position = options.position;
- this._offset = options.offset;
- this._$overlayContainer = $("<div>").css({
- position: "absolute",
- display: "none",
- cursor: "pointer"
- }).append(options.html);
- this.setMap(options.map)
- };
- CustomMarker.prototype = new google.maps.OverlayView;
- CustomMarker.prototype.onAdd = function() {
- var $pane = $(this.getPanes().overlayMouseTarget);
- $pane.append(this._$overlayContainer);
- this._clickListener = google.maps.event.addDomListener(this._$overlayContainer.get(0), "click", function(e) {
- google.maps.event.trigger(this, "click");
- e.preventDefault()
- }.bind(this));
- this.draw()
- };
- CustomMarker.prototype.onRemove = function() {
- google.maps.event.removeListener(this._clickListener);
- this._$overlayContainer.remove()
- };
- CustomMarker.prototype.draw = function() {
- var position = this.getProjection().fromLatLngToDivPixel(this._position);
- this._$overlayContainer.css({
- left: position.x + this._offset.left,
- top: position.y + this._offset.top,
- display: "block"
- })
- }
- };
- var googleMapsLoaded = function() {
- return window.google && window.google.maps
- };
- var googleMapsLoader;
- var GoogleProvider = DynamicProvider.inherit({
- _mapType: function(type) {
- var mapTypes = {
- hybrid: google.maps.MapTypeId.HYBRID,
- roadmap: google.maps.MapTypeId.ROADMAP,
- satellite: google.maps.MapTypeId.SATELLITE
- };
- return mapTypes[type] || mapTypes.hybrid
- },
- _movementMode: function(type) {
- var movementTypes = {
- driving: google.maps.TravelMode.DRIVING,
- walking: google.maps.TravelMode.WALKING
- };
- return movementTypes[type] || movementTypes.driving
- },
- _resolveLocation: function(location) {
- return new Promise(function(resolve) {
- var latLng = this._getLatLng(location);
- if (latLng) {
- resolve(new google.maps.LatLng(latLng.lat, latLng.lng))
- } else {
- this._geocodeLocation(location).then(function(geocodedLocation) {
- resolve(geocodedLocation)
- })
- }
- }.bind(this))
- },
- _geocodedLocations: {},
- _geocodeLocationImpl: function(location) {
- return new Promise(function(resolve) {
- if (!isDefined(location)) {
- resolve(new google.maps.LatLng(0, 0));
- return
- }
- var geocoder = new google.maps.Geocoder;
- geocoder.geocode({
- address: location
- }, function(results, status) {
- if (status === google.maps.GeocoderStatus.OK) {
- resolve(results[0].geometry.location)
- } else {
- errors.log("W1006", status);
- resolve(new google.maps.LatLng(0, 0))
- }
- })
- })
- },
- _normalizeLocation: function(location) {
- return {
- lat: location.lat(),
- lng: location.lng()
- }
- },
- _normalizeLocationRect: function(locationRect) {
- return {
- northEast: this._normalizeLocation(locationRect.getNorthEast()),
- southWest: this._normalizeLocation(locationRect.getSouthWest())
- }
- },
- _loadImpl: function() {
- return new Promise(function(resolve) {
- if (googleMapsLoaded()) {
- resolve()
- } else {
- if (!googleMapsLoader) {
- googleMapsLoader = this._loadMapScript()
- }
- googleMapsLoader.then(function() {
- if (googleMapsLoaded()) {
- resolve();
- return
- }
- this._loadMapScript().then(resolve)
- }.bind(this))
- }
- }.bind(this)).then(function() {
- initCustomMarkerClass()
- })
- },
- _loadMapScript: function() {
- return new Promise(function(resolve) {
- var key = this._keyOption("google");
- window[GOOGLE_MAP_READY] = resolve;
- ajax.sendRequest({
- url: GOOGLE_URL + (key ? "&key=" + key : ""),
- dataType: "script"
- })
- }.bind(this)).then(function() {
- try {
- delete window[GOOGLE_MAP_READY]
- } catch (e) {
- window[GOOGLE_MAP_READY] = void 0
- }
- })
- },
- _init: function() {
- return new Promise(function(resolve) {
- this._resolveLocation(this._option("center")).then(function(center) {
- var showDefaultUI = this._option("controls");
- this._map = new google.maps.Map(this._$container[0], {
- zoom: this._option("zoom"),
- center: center,
- disableDefaultUI: !showDefaultUI
- });
- var listener = google.maps.event.addListener(this._map, "idle", function() {
- resolve(listener)
- })
- }.bind(this))
- }.bind(this)).then(function(listener) {
- google.maps.event.removeListener(listener)
- })
- },
- _attachHandlers: function() {
- this._boundsChangeListener = google.maps.event.addListener(this._map, "bounds_changed", this._boundsChangeHandler.bind(this));
- this._clickListener = google.maps.event.addListener(this._map, "click", this._clickActionHandler.bind(this))
- },
- _boundsChangeHandler: function() {
- var bounds = this._map.getBounds();
- this._option("bounds", this._normalizeLocationRect(bounds));
- var center = this._map.getCenter();
- this._option("center", this._normalizeLocation(center));
- if (!this._preventZoomChangeEvent) {
- this._option("zoom", this._map.getZoom())
- }
- },
- _clickActionHandler: function(e) {
- this._fireClickAction({
- location: this._normalizeLocation(e.latLng)
- })
- },
- updateDimensions: function() {
- var center = this._option("center");
- google.maps.event.trigger(this._map, "resize");
- this._option("center", center);
- return this.updateCenter()
- },
- updateMapType: function() {
- this._map.setMapTypeId(this._mapType(this._option("type")));
- return Promise.resolve()
- },
- updateBounds: function() {
- return Promise.all([this._resolveLocation(this._option("bounds.northEast")), this._resolveLocation(this._option("bounds.southWest"))]).then(function(result) {
- var bounds = new google.maps.LatLngBounds;
- bounds.extend(result[0]);
- bounds.extend(result[1]);
- this._map.fitBounds(bounds)
- }.bind(this))
- },
- updateCenter: function() {
- return this._resolveLocation(this._option("center")).then(function(center) {
- this._map.setCenter(center);
- this._option("center", this._normalizeLocation(center))
- }.bind(this))
- },
- updateZoom: function() {
- this._map.setZoom(this._option("zoom"));
- return Promise.resolve()
- },
- updateControls: function() {
- var showDefaultUI = this._option("controls");
- this._map.setOptions({
- disableDefaultUI: !showDefaultUI
- });
- return Promise.resolve()
- },
- isEventsCanceled: function(e) {
- var gestureHandling = this._map && this._map.get("gestureHandling");
- var isInfoWindowContent = $(e.target).closest(".".concat(INFO_WINDOW_CLASS)).length > 0;
- if (isInfoWindowContent || "desktop" !== devices.real().deviceType && "cooperative" === gestureHandling) {
- return false
- }
- return this.callBase()
- },
- _renderMarker: function(options) {
- return this._resolveLocation(options.location).then(function(location) {
- var marker;
- if (options.html) {
- marker = new CustomMarker({
- map: this._map,
- position: location,
- html: options.html,
- offset: extend({
- top: 0,
- left: 0
- }, options.htmlOffset)
- })
- } else {
- marker = new google.maps.Marker({
- position: location,
- map: this._map,
- icon: options.iconSrc || this._option("markerIconSrc")
- })
- }
- var infoWindow = this._renderTooltip(marker, options.tooltip);
- var listener;
- if (options.onClick || options.tooltip) {
- var markerClickAction = this._mapWidget._createAction(options.onClick || noop);
- var markerNormalizedLocation = this._normalizeLocation(location);
- listener = google.maps.event.addListener(marker, "click", function() {
- markerClickAction({
- location: markerNormalizedLocation
- });
- if (infoWindow) {
- infoWindow.open(this._map, marker)
- }
- }.bind(this))
- }
- return {
- location: location,
- marker: marker,
- listener: listener
- }
- }.bind(this))
- },
- _renderTooltip: function(marker, options) {
- if (!options) {
- return
- }
- options = this._parseTooltipOptions(options);
- var infoWindow = new google.maps.InfoWindow({
- content: options.text
- });
- if (options.visible) {
- infoWindow.open(this._map, marker)
- }
- return infoWindow
- },
- _destroyMarker: function(marker) {
- marker.marker.setMap(null);
- if (marker.listener) {
- google.maps.event.removeListener(marker.listener)
- }
- },
- _renderRoute: function(options) {
- return Promise.all(map(options.locations, function(point) {
- return this._resolveLocation(point)
- }.bind(this))).then(function(locations) {
- return new Promise(function(resolve) {
- var origin = locations.shift();
- var destination = locations.pop();
- var waypoints = map(locations, function(location) {
- return {
- location: location,
- stopover: true
- }
- });
- var request = {
- origin: origin,
- destination: destination,
- waypoints: waypoints,
- optimizeWaypoints: true,
- travelMode: this._movementMode(options.mode)
- };
- (new google.maps.DirectionsService).route(request, function(response, status) {
- if (status === google.maps.DirectionsStatus.OK) {
- var color = new Color(options.color || this._defaultRouteColor()).toHex();
- var directionOptions = {
- directions: response,
- map: this._map,
- suppressMarkers: true,
- preserveViewport: true,
- polylineOptions: {
- strokeWeight: options.weight || this._defaultRouteWeight(),
- strokeOpacity: options.opacity || this._defaultRouteOpacity(),
- strokeColor: color
- }
- };
- var route = new google.maps.DirectionsRenderer(directionOptions);
- var bounds = response.routes[0].bounds;
- resolve({
- instance: route,
- northEast: bounds.getNorthEast(),
- southWest: bounds.getSouthWest()
- })
- } else {
- errors.log("W1006", status);
- resolve({
- instance: new google.maps.DirectionsRenderer({})
- })
- }
- }.bind(this))
- }.bind(this))
- }.bind(this))
- },
- _destroyRoute: function(routeObject) {
- routeObject.instance.setMap(null)
- },
- _fitBounds: function() {
- this._updateBounds();
- if (this._bounds && this._option("autoAdjust")) {
- var zoomBeforeFitting = this._map.getZoom();
- this._preventZoomChangeEvent = true;
- this._map.fitBounds(this._bounds);
- this._boundsChangeHandler();
- var zoomAfterFitting = this._map.getZoom();
- if (zoomBeforeFitting < zoomAfterFitting) {
- this._map.setZoom(zoomBeforeFitting)
- } else {
- this._option("zoom", zoomAfterFitting)
- }
- delete this._preventZoomChangeEvent
- }
- return Promise.resolve()
- },
- _extendBounds: function(location) {
- if (this._bounds) {
- this._bounds.extend(location)
- } else {
- this._bounds = new google.maps.LatLngBounds;
- this._bounds.extend(location)
- }
- },
- clean: function() {
- if (this._map) {
- google.maps.event.removeListener(this._boundsChangeListener);
- google.maps.event.removeListener(this._clickListener);
- this._clearMarkers();
- this._clearRoutes();
- delete this._map;
- this._$container.empty()
- }
- return Promise.resolve()
- }
- });
- module.exports = GoogleProvider;
|