@syncfusion/ej2-maps 19.4.55 → 19.4.56-105067

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.eslintrc.json +18 -3
  2. package/.github/PULL_REQUEST_TEMPLATE/Bug.md +72 -72
  3. package/.github/PULL_REQUEST_TEMPLATE/Feature.md +49 -49
  4. package/CHANGELOG.md +441 -430
  5. package/README.md +73 -73
  6. package/dist/ej2-maps.umd.min.js +1 -10
  7. package/dist/ej2-maps.umd.min.js.map +1 -1
  8. package/dist/es6/ej2-maps.es2015.js +1205 -644
  9. package/dist/es6/ej2-maps.es2015.js.map +1 -1
  10. package/dist/es6/ej2-maps.es5.js +1243 -683
  11. package/dist/es6/ej2-maps.es5.js.map +1 -1
  12. package/dist/global/ej2-maps.min.js +1 -10
  13. package/dist/global/ej2-maps.min.js.map +1 -1
  14. package/dist/global/index.d.ts +0 -9
  15. package/dist/ts/maps/layers/bing-map.ts +50 -0
  16. package/dist/ts/maps/layers/bubble.ts +290 -0
  17. package/dist/ts/maps/layers/color-mapping.ts +226 -0
  18. package/dist/ts/maps/layers/data-label.ts +418 -0
  19. package/dist/ts/maps/layers/layer-panel.ts +1480 -0
  20. package/dist/ts/maps/layers/legend.ts +2236 -0
  21. package/dist/ts/maps/layers/marker.ts +453 -0
  22. package/dist/ts/maps/layers/navigation-selected-line.ts +167 -0
  23. package/dist/ts/maps/maps.ts +2886 -0
  24. package/dist/ts/maps/model/base.ts +1843 -0
  25. package/dist/ts/maps/model/constants.ts +200 -0
  26. package/dist/ts/maps/model/export-image.ts +178 -0
  27. package/dist/ts/maps/model/export-pdf.ts +170 -0
  28. package/dist/ts/maps/model/interface.ts +823 -0
  29. package/dist/ts/maps/model/print.ts +104 -0
  30. package/dist/ts/maps/model/theme.ts +554 -0
  31. package/dist/ts/maps/user-interaction/annotation.ts +127 -0
  32. package/dist/ts/maps/user-interaction/highlight.ts +233 -0
  33. package/dist/ts/maps/user-interaction/selection.ts +321 -0
  34. package/dist/ts/maps/user-interaction/tooltip.ts +387 -0
  35. package/dist/ts/maps/user-interaction/zoom.ts +1767 -0
  36. package/dist/ts/maps/utils/enum.ts +368 -0
  37. package/dist/ts/maps/utils/helper.ts +3421 -0
  38. package/helper/e2e/index.js +3 -3
  39. package/helper/e2e/maps-helper.js +13 -13
  40. package/license +9 -9
  41. package/package.json +85 -85
  42. package/src/maps/layers/bing-map.d.ts +4 -0
  43. package/src/maps/layers/bing-map.js +16 -3
  44. package/src/maps/layers/bubble.d.ts +1 -2
  45. package/src/maps/layers/bubble.js +7 -12
  46. package/src/maps/layers/data-label.d.ts +1 -4
  47. package/src/maps/layers/data-label.js +32 -35
  48. package/src/maps/layers/layer-panel.d.ts +18 -1
  49. package/src/maps/layers/layer-panel.js +226 -72
  50. package/src/maps/layers/legend.d.ts +5 -2
  51. package/src/maps/layers/legend.js +170 -61
  52. package/src/maps/layers/marker.d.ts +2 -4
  53. package/src/maps/layers/marker.js +49 -48
  54. package/src/maps/layers/navigation-selected-line.d.ts +1 -2
  55. package/src/maps/layers/navigation-selected-line.js +7 -13
  56. package/src/maps/maps-model.d.ts +259 -251
  57. package/src/maps/maps.d.ts +24 -3
  58. package/src/maps/maps.js +164 -97
  59. package/src/maps/model/base-model.d.ts +1025 -1021
  60. package/src/maps/model/base.d.ts +5 -1
  61. package/src/maps/model/base.js +24 -24
  62. package/src/maps/model/constants.d.ts +6 -0
  63. package/src/maps/model/constants.js +6 -0
  64. package/src/maps/model/export-image.d.ts +2 -4
  65. package/src/maps/model/export-image.js +34 -33
  66. package/src/maps/model/export-pdf.d.ts +4 -6
  67. package/src/maps/model/export-pdf.js +31 -32
  68. package/src/maps/model/interface.d.ts +34 -26
  69. package/src/maps/model/print.d.ts +2 -5
  70. package/src/maps/model/print.js +32 -18
  71. package/src/maps/model/theme.js +7 -4
  72. package/src/maps/user-interaction/annotation.d.ts +1 -2
  73. package/src/maps/user-interaction/annotation.js +3 -4
  74. package/src/maps/user-interaction/highlight.d.ts +1 -2
  75. package/src/maps/user-interaction/highlight.js +11 -10
  76. package/src/maps/user-interaction/selection.d.ts +1 -2
  77. package/src/maps/user-interaction/selection.js +42 -19
  78. package/src/maps/user-interaction/tooltip.d.ts +3 -5
  79. package/src/maps/user-interaction/tooltip.js +27 -14
  80. package/src/maps/user-interaction/zoom.d.ts +3 -8
  81. package/src/maps/user-interaction/zoom.js +282 -162
  82. package/src/maps/utils/enum.d.ts +5 -1
  83. package/src/maps/utils/helper.d.ts +9 -1
  84. package/src/maps/utils/helper.js +82 -33
@@ -0,0 +1,1767 @@
1
+ /* eslint-disable max-len */
2
+ /* eslint-disable @typescript-eslint/no-unused-vars */
3
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
4
+ import { Maps, Orientation, ITouches, ZoomSettings } from '../../index';
5
+ import { Point, getElementByID, Size, PathOption, Rect, convertGeoToPoint, CircleOption, convertTileLatLongToPoint } from '../utils/helper';
6
+ import { RectOption, PolygonOption, createTooltip, calculateScale, getTouchCenter, getTouches, targetTouches } from '../utils/helper';
7
+ import { MapLocation, zoomAnimate, smoothTranslate , measureText, textTrim, clusterTemplate, marker } from '../utils/helper';
8
+ import { markerTemplate, removeElement, getElement, clusterSeparate, markerColorChoose } from '../utils/helper';
9
+ import { markerShapeChoose } from '../utils/helper';
10
+ import { isNullOrUndefined, EventHandler, Browser, remove, createElement } from '@syncfusion/ej2-base';
11
+ import { MarkerSettings, LayerSettings, changeBorderWidth, IMarkerRenderingEventArgs, markerRendering } from '../index';
12
+ import { IMapZoomEventArgs, IMapPanEventArgs } from '../model/interface';
13
+ import { pan } from '../model/constants';
14
+ import { getValueFromObject } from '../utils/helper';
15
+ import { PanDirection } from '../utils/enum';
16
+ import { FontModel, DataLabelSettingsModel, BorderModel } from '../model/base-model';
17
+ import { MapsTooltip } from './tooltip';
18
+
19
+ /**
20
+ * Zoom module used to process the zoom for maps
21
+ */
22
+ export class Zoom {
23
+ private maps: Maps;
24
+ public toolBarGroup: Element;
25
+ private currentToolbarEle: Element;
26
+ public zoomingRect: Rect;
27
+ public selectionColor: string;
28
+ private fillColor: string;
29
+ private zoomElements: Element;
30
+ private panElements: Element;
31
+ public isPanning: boolean = false;
32
+ public mouseEnter: boolean = false;
33
+ public baseTranslatePoint: Point;
34
+ private wheelEvent: string;
35
+ private cancelEvent: string;
36
+ public currentScale: number;
37
+ public isTouch: boolean = false;
38
+ public rectZoomingStart: boolean = false;
39
+ public touchStartList: ITouches[] | TouchList;
40
+ public touchMoveList: ITouches[] | TouchList;
41
+ public previousTouchMoveList: ITouches[] | TouchList;
42
+ public mouseDownPoints: Point;
43
+ public mouseMovePoints: Point;
44
+ public isDragZoom: boolean;
45
+ public currentLayer: LayerSettings;
46
+ private panColor: string;
47
+ public zoomColor: string;
48
+ public browserName: string = Browser.info.name;
49
+ // eslint-disable-next-line @typescript-eslint/ban-types
50
+ public isPointer: Boolean = Browser.isPointer;
51
+ private handled: boolean = false;
52
+ private fingers: number;
53
+ public firstMove: boolean;
54
+ private interaction: string;
55
+ private lastScale: number;
56
+ private pinchFactor: number = 1;
57
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
58
+ private startTouches: any[] = [];
59
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
60
+ private zoomshapewidth: any;
61
+ private index: number;
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ public intersect: any[] = [];
64
+ private templateCount: number;
65
+ private distanceX: number;
66
+ private distanceY: number;
67
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
+ public mouseDownLatLong: any = { x: 0, y: 0 };
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
+ public mouseMoveLatLong: any = { x: 0, y: 0 };
71
+ /**
72
+ * @private
73
+ */
74
+ public isSingleClick: boolean = false;
75
+ /** @private */
76
+ public layerCollectionEle: Element;
77
+ constructor(maps: Maps) {
78
+ this.maps = maps;
79
+ this.wheelEvent = this.browserName === 'mozilla' ? (this.isPointer ? 'mousewheel' : 'DOMMouseScroll') : 'mousewheel';
80
+ this.cancelEvent = this.isPointer ? 'pointerleave' : 'mouseleave';
81
+ this.selectionColor = this.maps.zoomSettings.selectionColor;
82
+ this.fillColor = this.maps.zoomSettings.color;
83
+ this.addEventListener();
84
+ }
85
+
86
+ /**
87
+ * To perform zooming for maps
88
+ *
89
+ * @param {Point} position - Specifies the position.
90
+ * @param {number} newZoomFactor - Specifies the zoom factor.
91
+ * @param {string} type - Specifies the type.
92
+ * @returns {void}
93
+ */
94
+ public performZooming(position: Point, newZoomFactor: number, type: string): void {
95
+ const map: Maps = this.maps;
96
+ map.previousProjection = map.projectionType;
97
+ map.defaultState = false;
98
+ map.initialCheck = false;
99
+ map.markerZoomedState = false;
100
+ map.zoomPersistence = map.enablePersistence;
101
+ const prevLevel: number = map.tileZoomLevel;
102
+ const scale: number = map.previousScale = map.scale;
103
+ const maxZoom: number = map.zoomSettings.maxZoom;
104
+ const minZoom: number = map.zoomSettings.minZoom;
105
+ newZoomFactor = (minZoom > newZoomFactor && type === 'ZoomIn') ? minZoom + 1 : newZoomFactor;
106
+ const prevTilePoint: Point = map.tileTranslatePoint;
107
+ if ((!map.isTileMap) && ((type === 'ZoomIn' ? newZoomFactor >= minZoom && newZoomFactor <= maxZoom : newZoomFactor >= minZoom)
108
+ || map.isReset)) {
109
+ const availSize: Rect = map.mapAreaRect;
110
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
111
+ const minBounds: any = map.baseMapRectBounds['min'] as any;
112
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
113
+ const maxBounds: any = map.baseMapRectBounds['max'] as any;
114
+ let mapTotalWidth: number = Math.abs(minBounds['x'] - maxBounds['x']);
115
+ let mapTotalHeight: number = Math.abs(minBounds['y'] - maxBounds['y']);
116
+ let translatePointX: number;
117
+ let translatePointY: number;
118
+ if (newZoomFactor < 1.2 && map.projectionType !== 'Eckert5') {
119
+ if (mapTotalWidth === 0 || mapTotalHeight === 0 || mapTotalWidth === mapTotalHeight) {
120
+ mapTotalWidth = availSize.width / 2;
121
+ mapTotalHeight = availSize.height;
122
+ }
123
+ newZoomFactor = parseFloat(Math.min(availSize.width / mapTotalWidth, availSize.height / mapTotalHeight).toFixed(2));
124
+ newZoomFactor = newZoomFactor > 1.05 ? 1 : newZoomFactor;
125
+ map.translatePoint = this.calculateInitalZoomTranslatePoint(newZoomFactor, mapTotalWidth, mapTotalHeight, availSize, minBounds, map);
126
+ } else {
127
+ const point: Point = map.translatePoint;
128
+ translatePointX = point.x - (((availSize.width / scale) - (availSize.width / newZoomFactor)) / (availSize.width / position.x));
129
+ translatePointY = point.y - (((availSize.height / scale) - (availSize.height / newZoomFactor)) / (availSize.height / position.y));
130
+ const currentHeight: number = Math.abs(map.baseMapRectBounds['max']['y'] - map.baseMapRectBounds['min']['y']) * newZoomFactor;
131
+ translatePointX = (currentHeight < map.mapAreaRect.height) ? (availSize.x + ((-(minBounds['x'])) + ((availSize.width / 2) - (mapTotalWidth / 2)))) : translatePointX;
132
+ translatePointY = (currentHeight < map.mapAreaRect.height) ? (availSize.y + ((-(minBounds['y'])) + ((availSize.height / 2) - (mapTotalHeight / 2)))) : translatePointY;
133
+ map.translatePoint = new Point(translatePointX, translatePointY);
134
+ }
135
+ map.scale = newZoomFactor;
136
+ if (this.triggerZoomEvent(prevTilePoint, prevLevel, type)) {
137
+ map.translatePoint = map.previousPoint;
138
+ map.scale = map.mapScaleValue = map.previousScale;
139
+ } else {
140
+ this.applyTransform(map);
141
+ }
142
+ } else if ((map.isTileMap) && (newZoomFactor >= minZoom && newZoomFactor <= maxZoom)) {
143
+ this.getTileTranslatePosition(prevLevel, newZoomFactor, position, type);
144
+ map.tileZoomLevel = newZoomFactor;
145
+ map.zoomSettings.zoomFactor = newZoomFactor;
146
+ map.scale = Math.pow(2, newZoomFactor - 1);
147
+ if (type === 'ZoomOut' && map.zoomSettings.resetToInitial && map.applyZoomReset && newZoomFactor <= map.initialZoomLevel) {
148
+ map.initialCheck = true;
149
+ map.zoomPersistence = false;
150
+ map.tileTranslatePoint.x = map.initialTileTranslate.x;
151
+ map.tileTranslatePoint.y = map.initialTileTranslate.y;
152
+ newZoomFactor = map.tileZoomLevel = map.mapScaleValue = map.initialZoomLevel;
153
+ map.scale = Math.pow(2, newZoomFactor - 1);
154
+ }
155
+ map.translatePoint.y = (map.tileTranslatePoint.y - (0.01 * map.mapScaleValue)) / map.scale;
156
+ map.translatePoint.x = (map.tileTranslatePoint.x - (0.01 * map.mapScaleValue)) / map.scale;
157
+ if (this.triggerZoomEvent(prevTilePoint, prevLevel, type)) {
158
+ map.translatePoint = map.tileTranslatePoint = new Point(0, 0);
159
+ map.scale = map.previousScale;
160
+ map.tileZoomLevel = prevLevel;
161
+ map.zoomSettings.zoomFactor = map.previousScale;
162
+ } else {
163
+ if (document.querySelector('.GroupElement')) {
164
+ (document.querySelector('.GroupElement') as HTMLElement).style.display = 'none';
165
+ }
166
+ if (document.getElementById(this.maps.element.id + '_LayerIndex_1')) {
167
+ document.getElementById(this.maps.element.id + '_LayerIndex_1').style.display = 'none';
168
+ }
169
+ this.markerLineAnimation(map);
170
+ map.mapLayerPanel.generateTiles(newZoomFactor, map.tileTranslatePoint, type + 'wheel', null, position);
171
+ const element1: HTMLElement = document.getElementById(this.maps.element.id + '_tiles');
172
+ const animationDuration: number = this.maps.layersCollection[0].animationDuration;
173
+ setTimeout(() => {
174
+ // if (type === 'ZoomOut') {
175
+ // element1.removeChild(element1.children[element1.childElementCount - 1]);
176
+ // if (element1.childElementCount) {
177
+ // element1.removeChild(element1.children[element1.childElementCount - 1]);
178
+ // } else {
179
+ // element1 = element1;
180
+ // }
181
+ // }
182
+ this.applyTransform(this.maps);
183
+ if (document.getElementById(this.maps.element.id + '_LayerIndex_1')) {
184
+ document.getElementById(this.maps.element.id + '_LayerIndex_1').style.display = 'block';
185
+ }
186
+ }, animationDuration);
187
+ }
188
+ }
189
+ this.maps.zoomNotApplied = false;
190
+ }
191
+
192
+ private calculateInitalZoomTranslatePoint(newZoomFactor: number, mapTotalWidth: number, mapTotalHeight: number, availSize: Rect, minBounds: any, map: Maps): Point {
193
+ mapTotalWidth *= newZoomFactor;
194
+ mapTotalHeight *= newZoomFactor;
195
+ let widthDiff: number = minBounds['x'] !== 0 && map.translateType === 'layers' ? map.availableSize.width - availSize.width : 0;
196
+ var translatePointX = availSize.x + ((-(minBounds['x'])) + ((availSize.width / 2) - (mapTotalWidth / 2))) - widthDiff;
197
+ var translatePointY = availSize.y + ((-(minBounds['y'])) + ((availSize.height / 2) - (mapTotalHeight / 2)));
198
+ return new Point(translatePointX, translatePointY);
199
+ }
200
+
201
+ private triggerZoomEvent(prevTilePoint: Point, prevLevel: number, type: string): boolean {
202
+ const map: Maps = this.maps; let zoomArgs: IMapZoomEventArgs;
203
+ if (!map.isTileMap) {
204
+ zoomArgs = {
205
+ cancel: false, name: 'zoom', type: type, maps: map,
206
+ tileTranslatePoint: {}, translatePoint: { previous: map.previousPoint, current: map.translatePoint },
207
+ tileZoomLevel: {}, scale: { previous: map.previousScale, current: map.scale }
208
+ };
209
+ } else {
210
+ zoomArgs = {
211
+ cancel: false, name: 'zoom', type: type, maps: map,
212
+ tileTranslatePoint: { previous: prevTilePoint, current: map.tileTranslatePoint }, translatePoint: { previous: map.previousPoint, current: map.translatePoint },
213
+ tileZoomLevel: { previous: prevLevel, current: map.tileZoomLevel }, scale: { previous: map.previousScale, current: map.scale }
214
+ };
215
+ }
216
+ map.trigger('zoom', zoomArgs);
217
+ return zoomArgs.cancel;
218
+ }
219
+
220
+ private getTileTranslatePosition(prevLevel: number, currentLevel: number, position: Point, type?: string): void {
221
+ const map: Maps = this.maps;
222
+ const tileDefaultSize: number = 256;
223
+ const padding: number = type === 'ZoomOut' ? 10 : (type === 'Reset' && currentLevel > 1) ? 0 : 10;
224
+ const bounds: Size = map.availableSize;
225
+ const prevSize: number = Math.pow(2, prevLevel) * 256;
226
+ const totalSize: number = Math.pow(2, currentLevel) * 256;
227
+ const x: number = ((position.x - map.tileTranslatePoint.x) / prevSize) * 100;
228
+ const y: number = ((position.y - map.tileTranslatePoint.y) / prevSize) * 100;
229
+ map.tileTranslatePoint.x = (currentLevel === 1) ? (bounds.width / 2) - ((tileDefaultSize * 2) / 2) :
230
+ position.x - ((x * totalSize) / 100);
231
+ map.tileTranslatePoint.y = (currentLevel === 1) ? ((bounds.height / 2) - ((tileDefaultSize * 2) / 2) + (padding * 2)) :
232
+ position.y - ((y * totalSize) / 100);
233
+ }
234
+
235
+ public performRectZooming(): void {
236
+ this.isDragZoom = true;
237
+ const map: Maps = this.maps;
238
+ const size: Size = map.availableSize;
239
+ map.previousProjection = map.projectionType;
240
+ const prevLevel: number = map.tileZoomLevel;
241
+ const prevTilePoint: Point = map.tileTranslatePoint;
242
+ const zoomRect: Rect = this.zoomingRect;
243
+ const maxZoom: number = map.zoomSettings.maxZoom;
244
+ const minZoom: number = map.zoomSettings.minZoom;
245
+ let isZoomCancelled: boolean;
246
+ if (zoomRect.height > 0 && zoomRect.width > 0) {
247
+ const x: number = this.zoomingRect.x + (this.zoomingRect.width / 2);
248
+ const y: number = this.zoomingRect.y + (this.zoomingRect.height / 2);
249
+ let zoomCalculationFactor: number;
250
+ if (!map.isTileMap) {
251
+ const scale: number = map.previousScale = map.scale;
252
+ zoomCalculationFactor = scale + Math.round((((size.width / zoomRect.width) + (size.height / zoomRect.height)) / 2));
253
+ const translatePoint: Point = map.previousPoint = map.translatePoint;
254
+ const translatePointX: number = translatePoint.x - (((size.width / scale) - (size.width / zoomCalculationFactor)) / (size.width / x));
255
+ const translatePointY: number = translatePoint.y - (((size.height / scale) - (size.height / zoomCalculationFactor)) / (size.height / y));
256
+ map.translatePoint = new Point(translatePointX, translatePointY);
257
+ map.scale = zoomCalculationFactor;
258
+ isZoomCancelled = this.triggerZoomEvent(prevTilePoint, prevLevel, '');
259
+ if (isZoomCancelled) {
260
+ map.translatePoint = map.previousPoint;
261
+ map.scale = map.previousScale;
262
+ }
263
+ } else {
264
+ zoomCalculationFactor = prevLevel + (Math.round(prevLevel + (((size.width / zoomRect.width) + (size.height / zoomRect.height)) / 2)));
265
+ zoomCalculationFactor = (zoomCalculationFactor >= minZoom && zoomCalculationFactor <= maxZoom) ? zoomCalculationFactor : maxZoom;
266
+ map.zoomSettings.zoomFactor = zoomCalculationFactor;
267
+ this.getTileTranslatePosition(prevLevel, zoomCalculationFactor, { x: x, y: y });
268
+ map.tileZoomLevel = zoomCalculationFactor;
269
+ map.translatePoint.x = (map.tileTranslatePoint.x - (0.5 * Math.pow(2, zoomCalculationFactor))) /
270
+ (Math.pow(2, zoomCalculationFactor));
271
+ map.translatePoint.y = (map.tileTranslatePoint.y - (0.5 * Math.pow(2, zoomCalculationFactor))) /
272
+ (Math.pow(2, zoomCalculationFactor));
273
+ map.scale = (Math.pow(2, zoomCalculationFactor));
274
+ isZoomCancelled = this.triggerZoomEvent(prevTilePoint, prevLevel, '');
275
+ if (isZoomCancelled) {
276
+ map.translatePoint = map.tileTranslatePoint = new Point(0, 0);
277
+ map.scale = map.tileZoomLevel = map.zoomSettings.zoomFactor = prevLevel;
278
+ } else {
279
+ map.mapLayerPanel.generateTiles(zoomCalculationFactor, map.tileTranslatePoint);
280
+ }
281
+ }
282
+ if (!isZoomCancelled) {
283
+ map.mapScaleValue = zoomCalculationFactor;
284
+ this.applyTransform(map, true);
285
+ this.maps.zoomNotApplied = false;
286
+ this.zoomingRect = null;
287
+ }
288
+ }
289
+ }
290
+
291
+ private setInteraction(newInteraction: string): void {
292
+ this.lastScale = 1;
293
+ this.interaction = newInteraction;
294
+ }
295
+
296
+ private updateInteraction(): void {
297
+ if (this.fingers === 2) {
298
+ this.setInteraction('zoom');
299
+ } else {
300
+ this.setInteraction(null);
301
+ }
302
+ }
303
+
304
+ public performPinchZooming(e: PointerEvent | TouchEvent): void {
305
+ const map: Maps = this.maps;
306
+ const prevLevel: number = map.tileZoomLevel;
307
+ const availSize: Rect = map.mapAreaRect;
308
+ map.previousScale = map.scale;
309
+ map.previousPoint = map.translatePoint;
310
+ const prevTilePoint: Point = map.tileTranslatePoint;
311
+ const scale: number = calculateScale(<ITouches[]>this.touchStartList, <ITouches[]>this.touchMoveList);
312
+ const touchCenter: Point = getTouchCenter(getTouches(<ITouches[]>this.touchMoveList, this.maps));
313
+ const newScale: number = scale / this.lastScale;
314
+ this.lastScale = scale;
315
+ this.pinchFactor *= newScale;
316
+ this.pinchFactor = Math.min(this.maps.zoomSettings.maxZoom, Math.max(this.pinchFactor, this.maps.zoomSettings.minZoom));
317
+ let zoomCalculationFactor: number = this.pinchFactor;
318
+ let zoomArgs: IMapZoomEventArgs;
319
+ let isZoomCancelled: boolean;
320
+ if (!map.isTileMap) {
321
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
322
+ const minBounds: any = map.baseMapRectBounds['min'] as any;
323
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
324
+ const maxBounds: any = map.baseMapRectBounds['max'] as any;
325
+ let mapTotalHeight: number = Math.abs(minBounds['y'] - maxBounds['y']);
326
+ let mapTotalWidth: number = Math.abs(minBounds['x'] - maxBounds['x']);
327
+ const translatePoint: Point = map.translatePoint;
328
+ let translatePointX: number;
329
+ let translatePointY: number;
330
+ if (zoomCalculationFactor < 1.2 && map.projectionType !== 'Eckert5') {
331
+ if (mapTotalWidth === 0 || mapTotalHeight === 0 || mapTotalWidth === mapTotalHeight) {
332
+ mapTotalWidth = availSize.width / 2;
333
+ mapTotalHeight = availSize.height;
334
+ }
335
+ zoomCalculationFactor = parseFloat(Math.min(availSize.width / mapTotalWidth, availSize.height / mapTotalHeight).toFixed(2));
336
+ zoomCalculationFactor = zoomCalculationFactor > 1.05 ? 1 : zoomCalculationFactor;
337
+ map.translatePoint = this.calculateInitalZoomTranslatePoint(zoomCalculationFactor, mapTotalWidth, mapTotalHeight, availSize, minBounds, map);
338
+ }
339
+ else {
340
+ const currentHeight: number = Math.abs(map.baseMapRectBounds['max']['y'] - map.baseMapRectBounds['min']['y']) * zoomCalculationFactor;
341
+ translatePointX = translatePoint.x - (((availSize.width / map.scale) - (availSize.width / zoomCalculationFactor)) / (availSize.width / touchCenter.x));
342
+ translatePointY = translatePoint.y - (((availSize.height / map.scale) - (availSize.height / zoomCalculationFactor)) / (availSize.height / touchCenter.y));
343
+ translatePointX = (currentHeight < map.mapAreaRect.height) ? (availSize.x + ((-(minBounds['x'])) + ((availSize.width / 2) - (mapTotalWidth / 2)))) : translatePointX;
344
+ translatePointY = (currentHeight < map.mapAreaRect.height) ? (availSize.y + ((-(minBounds['y'])) + ((availSize.height / 2) - (mapTotalHeight / 2)))) : translatePointY;
345
+ map.translatePoint = new Point(translatePointX, translatePointY);
346
+ }
347
+ map.scale = zoomCalculationFactor;
348
+ isZoomCancelled = this.triggerZoomEvent(prevTilePoint, prevLevel, '');
349
+ if (isZoomCancelled) {
350
+ map.translatePoint = map.previousPoint;
351
+ map.scale = map.previousScale;
352
+ }
353
+ } else {
354
+ const newTileFactor: number = zoomCalculationFactor;
355
+ this.getTileTranslatePosition(prevLevel, newTileFactor, { x: touchCenter.x, y: touchCenter.y });
356
+ map.tileZoomLevel = newTileFactor;
357
+ map.translatePoint.x = (map.tileTranslatePoint.x - (0.5 * Math.pow(2, newTileFactor))) /
358
+ (Math.pow(2, newTileFactor));
359
+ map.translatePoint.y = (map.tileTranslatePoint.y - (0.5 * Math.pow(2, newTileFactor))) /
360
+ (Math.pow(2, newTileFactor));
361
+ map.scale = (Math.pow(2, newTileFactor));
362
+ isZoomCancelled = this.triggerZoomEvent(prevTilePoint, prevLevel, '');
363
+ if (isZoomCancelled) {
364
+ map.translatePoint = map.tileTranslatePoint = new Point(0, 0);
365
+ map.scale = map.previousScale;
366
+ map.tileZoomLevel = prevLevel;
367
+ map.zoomSettings.zoomFactor = map.previousScale;
368
+ } else {
369
+ map.mapLayerPanel.generateTiles(newTileFactor, map.tileTranslatePoint);
370
+ }
371
+ }
372
+ if (!isZoomCancelled) {
373
+ this.applyTransform(map);
374
+ }
375
+ }
376
+
377
+ public drawZoomRectangle(): void {
378
+ const map: Maps = this.maps;
379
+ const down: Point = this.mouseDownPoints;
380
+ const move: Point = this.mouseMovePoints;
381
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
382
+ const border: any = { width: 1, color: '#009900' };
383
+ const width: number = Math.abs(move.x - down.x);
384
+ const height: number = Math.abs(move.y - down.y);
385
+ const x: number = ((move.x > down.x) ? down.x : down.x - width);
386
+ const y: number = ((move.y > down.y) ? down.y : down.y - height);
387
+ const elementRect: ClientRect = getElementByID(map.element.id).getBoundingClientRect();
388
+ if ((x > map.mapAreaRect.x && x < (map.mapAreaRect.x + map.mapAreaRect.width)) &&
389
+ (y > map.mapAreaRect.y) && (y < map.mapAreaRect.y + map.mapAreaRect.height)) {
390
+ this.zoomingRect = new Rect(x, y, width, height);
391
+ const rectSVGObject: Element = map.renderer.createSvg({
392
+ id: map.element.id + '_Selection_Rect_Zooming',
393
+ width: map.availableSize.width,
394
+ height: map.availableSize.height
395
+ });
396
+ const rectOption: RectOption = new RectOption(
397
+ map.element.id + '_ZoomRect', '#d3d3d3', border, 0.5, this.zoomingRect, 0, 0, '', '3'
398
+ );
399
+ rectSVGObject.appendChild(map.renderer.drawRectangle(rectOption));
400
+ getElementByID(map.element.id + '_Secondary_Element').appendChild(rectSVGObject);
401
+ }
402
+ }
403
+ /**
404
+ * To animate the zooming process
405
+ *
406
+ * @param {Element} element - Specifies the element
407
+ * @param {boolean} animate - Specifies the boolean value
408
+ * @param {number} x - Specifies the x value
409
+ * @param {number} y - Specifies the y value
410
+ * @param {number} scale - Specifies the scale value
411
+ * @returns {void}
412
+ */
413
+ private animateTransform(element: Element, animate: boolean, x: number, y: number, scale: number): void {
414
+ const duration: number = this.currentLayer.animationDuration;
415
+ if (!animate || duration === 0 || this.maps.isTileMap) {
416
+ element.setAttribute('transform', 'scale(' + (scale) + ') translate( ' + x + ' ' + y + ' )');
417
+ return;
418
+ }
419
+ if (!this.maps.isTileMap) {
420
+ zoomAnimate(element, 0, duration, new MapLocation(x, y), scale, this.maps.mapAreaRect, this.maps);
421
+ }
422
+ }
423
+
424
+ public applyTransform(maps: Maps, animate?: boolean): void {
425
+ let layerIndex: number;
426
+ this.templateCount = 0;
427
+ let layer: LayerSettings;
428
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
429
+ let zoomshapelocation: any;
430
+ let i: number; let markerStyle: string;
431
+ const scale: number = maps.scale;
432
+ const x: number = maps.translatePoint.x;
433
+ const y: number = maps.translatePoint.y;
434
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
435
+ const collection: any[] = []; maps.zoomShapeCollection = [];
436
+ if (document.getElementById(maps.element.id + '_mapsTooltip')) {
437
+ removeElement(maps.element.id + '_mapsTooltip');
438
+ }
439
+ if (this.layerCollectionEle) {
440
+ for (let i: number = 0; i < this.layerCollectionEle.childElementCount; i++) {
441
+ const layerElement: Element = this.layerCollectionEle.childNodes[i] as Element;
442
+ if (layerElement.tagName === 'g') {
443
+ this.templateCount++;
444
+ this.index = layerElement.id.indexOf('_LayerIndex_') > -1 && parseFloat(layerElement.id.split('_LayerIndex_')[1].split('_')[0]);
445
+ this.currentLayer = <LayerSettings>maps.layersCollection[this.index];
446
+ const factor: number = maps.mapLayerPanel.calculateFactor(this.currentLayer);
447
+ for (let j: number = 0; j < layerElement.childElementCount; j++) {
448
+ let currentEle: Element = layerElement.childNodes[j] as Element;
449
+ if (!(currentEle.id.indexOf('_Markers_Group') > -1) && (!(currentEle.id.indexOf('_bubble_Group') > -1))
450
+ && (!(currentEle.id.indexOf('_dataLableIndex_Group') > -1))
451
+ ) {
452
+ if (maps.isTileMap && (currentEle.id.indexOf('_line_Group') > -1)) {
453
+ currentEle.remove();
454
+ if (layerElement.children.length > 0 && layerElement.children[0]) {
455
+ layerElement.insertBefore(
456
+ maps.navigationLineModule.renderNavigation(
457
+ this.currentLayer, maps.tileZoomLevel, this.index
458
+ ),
459
+ layerElement.children[1]
460
+ );
461
+ } else {
462
+ layerElement.appendChild(maps.navigationLineModule.renderNavigation(this.currentLayer, maps.tileZoomLevel, this.index));
463
+ }
464
+ } else if (currentEle.id.indexOf('Legend') == -1) {
465
+ changeBorderWidth(currentEle, this.index, scale, maps);
466
+ maps.zoomTranslatePoint = maps.translatePoint;
467
+ this.animateTransform(currentEle, animate, x, y, scale);
468
+ }
469
+
470
+ } else if (currentEle.id.indexOf('_Markers_Group') > -1) {
471
+ if (!this.isPanning && !isNullOrUndefined(currentEle.childNodes[0])) {
472
+ this.markerTranslates(<Element>currentEle.childNodes[0], factor, x, y, scale, 'Marker', layerElement, animate);
473
+ }
474
+ currentEle = layerElement.childNodes[j] as Element;
475
+ let markerAnimation: boolean;
476
+ if (!isNullOrUndefined(currentEle) && currentEle.id.indexOf('Markers') !== -1) {
477
+ for (let k: number = 0; k < currentEle.childElementCount; k++) {
478
+ this.markerTranslate(<Element>currentEle.childNodes[k], factor, x, y, scale, 'Marker', animate);
479
+ const layerIndex : number = parseInt(currentEle.childNodes[k]['id'].split('_LayerIndex_')[1].split('_')[0], 10);
480
+ const dataIndex : number = parseInt(currentEle.childNodes[k]['id'].split('_dataIndex_')[1].split('_')[0], 10);
481
+ const markerIndex : number = parseInt(currentEle.childNodes[k]['id'].split('_MarkerIndex_')[1].split('_')[0], 10);
482
+ markerAnimation = this.currentLayer.markerSettings[markerIndex].animationDuration > 0;
483
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
484
+ const markerSelectionValues : any = this.currentLayer.markerSettings[markerIndex].dataSource[dataIndex];
485
+ for (let x : number = 0; x < this.currentLayer.markerSettings[markerIndex].initialMarkerSelection.length; x++) {
486
+ if (this.currentLayer.markerSettings[markerIndex].initialMarkerSelection[x]['latitude'] ===
487
+ markerSelectionValues['latitude'] ||
488
+ this.currentLayer.markerSettings[markerIndex].initialMarkerSelection[x]['longitude'] ===
489
+ markerSelectionValues['longitude']) {
490
+ maps.markerSelection(this.currentLayer.markerSettings[markerIndex].selectionSettings,
491
+ maps, currentEle.children[k],
492
+ this.currentLayer.markerSettings[markerIndex].dataSource[dataIndex]
493
+ );
494
+ }
495
+ }
496
+ if ((this.currentLayer.animationDuration > 0 || (maps.layersCollection[0].animationDuration > 0 && this.currentLayer.type === 'SubLayer')) && !this.isPanning) {
497
+ if (maps.isTileMap) {
498
+ const groupElement: Element = document.querySelector('.GroupElement');
499
+ if (groupElement && !(document.querySelector('.ClusterGroupElement')) && markerAnimation) {
500
+ (groupElement as HTMLElement).style.display = 'none';
501
+ }
502
+ } else {
503
+ markerStyle = 'visibility:hidden';
504
+ currentEle.setAttribute('style', markerStyle);
505
+ }
506
+ }
507
+ }
508
+ if (this.isPanning && maps.markerModule.sameMarkerData.length > 0) {
509
+ clusterSeparate(maps.markerModule.sameMarkerData, maps, currentEle, true);
510
+ } else if (maps.markerModule.sameMarkerData.length > 0) {
511
+ maps.markerModule.sameMarkerData = [];
512
+ if (document.getElementById(maps.element.id + '_mapsTooltip')) {
513
+ removeElement(maps.element.id + '_mapsTooltip');
514
+ }
515
+ }
516
+ if (document.getElementById(maps.element.id + '_mapsTooltip') && maps.mapsTooltipModule.tooltipTargetID.indexOf('_MarkerIndex_')
517
+ && !this.isPanning) {
518
+ const mapsTooltip: MapsTooltip = maps.mapsTooltipModule;
519
+ const tooltipElement: Element = currentEle.querySelector('#' + mapsTooltip.tooltipTargetID);
520
+ if (!isNullOrUndefined(tooltipElement)) {
521
+ if (tooltipElement['style']['visibility'] === 'hidden') {
522
+ removeElement(maps.element.id + '_mapsTooltip');
523
+ } else {
524
+ let x: number = parseFloat(tooltipElement.getAttribute('transform').split('(')[1].split(')')[0].split(' ')[1]);
525
+ let y: number = parseFloat(tooltipElement.getAttribute('transform').split('(')[1].split(')')[0].split(' ')[2]);
526
+ if (maps.isTileMap) {
527
+ x += +getElement(maps.element.id + '_tile_parent')['style']['left'].split('px')[0];
528
+ y += +getElement(maps.element.id + '_tile_parent')['style']['top'].split('px')[0];
529
+ }
530
+ mapsTooltip.svgTooltip.location.x = x;
531
+ mapsTooltip.svgTooltip.location.y = y;
532
+ mapsTooltip.svgTooltip.enableAnimation = false;
533
+ }
534
+ }
535
+ }
536
+ }
537
+ } else if (currentEle.id.indexOf('_bubble_Group') > -1) {
538
+ let childElement: HTMLElement;
539
+ for (let k: number = 0; k < currentEle.childElementCount; k++) {
540
+ childElement = currentEle.childNodes[k] as HTMLElement;
541
+ const bubbleTransform: string = childElement.getAttribute('transform');
542
+ layerIndex = parseFloat(childElement.id.split('_LayerIndex_')[1].split('_')[0]);
543
+ const bubleIndex: number = parseFloat(childElement.id.split('_BubbleIndex_')[1].split('_')[0]);
544
+ const dataIndex: number = parseFloat(childElement.id.split('_BubbleIndex_')[1].split('_')[2]);
545
+ for (let l: number = 0; l < maps.bubbleModule.bubbleCollection.length; l++) {
546
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
547
+ const bubbleCollection: any = maps.bubbleModule.bubbleCollection[l];
548
+ if (bubbleCollection['LayerIndex'] === layerIndex && bubbleCollection['BubbleIndex'] === bubleIndex &&
549
+ bubbleCollection['DataIndex'] === dataIndex) {
550
+ const centerX: number = bubbleCollection['center']['x'];
551
+ const centerY: number = bubbleCollection['center']['y'];
552
+ const currentX: number = ((centerX + x) * scale);
553
+ const currentY: number = ((centerY + y) * scale);
554
+ const duration: number = this.currentLayer.animationDuration;
555
+ if (!animate || duration === 0) {
556
+ childElement.setAttribute('transform', 'translate( ' + currentX + ' ' + currentY + ' )');
557
+ } else {
558
+ smoothTranslate(childElement, 0, duration, new MapLocation(currentX, currentY));
559
+ }
560
+ break;
561
+ }
562
+ }
563
+ }
564
+ } else if (currentEle.id.indexOf('_dataLableIndex_Group') > -1 && !isNullOrUndefined(maps.layers[this.index])) {
565
+ this.intersect = []; maps.zoomLabelPositions = [];
566
+ maps.zoomLabelPositions = maps.dataLabelModule.dataLabelCollections;
567
+ let labelAnimate: boolean = !maps.isTileMap && animate;
568
+ for (let k: number = 0; k < currentEle.childElementCount; k++) {
569
+ if (currentEle.childNodes[k]['id'].indexOf('_LabelIndex_') > -1) {
570
+ const labelIndex: number = parseFloat(currentEle.childNodes[k]['id'].split('_LabelIndex_')[1].split('_')[0]);
571
+ this.zoomshapewidth = (currentEle.childNodes[k] as Element).getBoundingClientRect();
572
+ maps.zoomShapeCollection.push(this.zoomshapewidth);
573
+ this.dataLabelTranslate(<Element>currentEle.childNodes[k], factor, x, y, scale, 'DataLabel', labelAnimate);
574
+ const dataLabel: DataLabelSettingsModel = maps.layers[this.index].dataLabelSettings;
575
+ const border: BorderModel = dataLabel.border;
576
+ if (k > 0 && border['width'] > 1) {
577
+ if (currentEle.childNodes[k - 1]['id'].indexOf('_rectIndex_') > -1 && !isNullOrUndefined(maps.zoomLabelPositions[labelIndex])) {
578
+ const labelX: number = ((maps.zoomLabelPositions[labelIndex]['location']['x'] + x) * scale);
579
+ const labelY: number = ((maps.zoomLabelPositions[labelIndex]['location']['y'] + y) * scale);
580
+ const zoomtext: string = currentEle.childNodes[k]['innerHTML'];
581
+ const style: FontModel = maps.layers[this.index].dataLabelSettings.textStyle;
582
+ const zoomtextSize: Size = measureText(zoomtext, style);
583
+ const padding: number = 5;
584
+ const rectElement: ChildNode = currentEle.childNodes[k - 1];
585
+ const rectX: number = labelX - zoomtextSize['width'] / 2;
586
+ const rectY: number = labelY - zoomtextSize['height'] / 2 - padding;
587
+ rectElement['setAttribute']('x', rectX);
588
+ rectElement['setAttribute']('y', rectY);
589
+ }
590
+ }
591
+ }
592
+ }
593
+ }
594
+ }
595
+ }
596
+ maps.arrangeTemplate();
597
+ }
598
+ if (!isNullOrUndefined(this.currentLayer)) {
599
+ if (!animate || this.currentLayer.animationDuration === 0 || maps.isTileMap) {
600
+ this.processTemplate(x, y, scale, maps);
601
+ }
602
+ }
603
+ }
604
+ }
605
+
606
+ private markerTranslates(
607
+ element: Element | HTMLElement, factor: number, x: number, y: number, scale: number, type: string, layerElement: Element, animate: boolean = false
608
+ ): void {
609
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
610
+ let templateFn: any;
611
+ let nullCount: number = 0;
612
+ let markerCounts: number = 0;
613
+ let markerTemplateCounts : number = 0;
614
+ const layerIndex: number = parseInt((element ? element : layerElement).id.split('_LayerIndex_')[1].split('_')[0], 10);
615
+ const markerSVGObject: Element = this.maps.renderer.createGroup({
616
+ id: this.maps.element.id + '_Markers_Group',
617
+ class: 'GroupElement',
618
+ style: 'pointer-events: auto;'
619
+ });
620
+ if (document.getElementById(markerSVGObject.id)) {
621
+ removeElement(markerSVGObject.id);
622
+ }
623
+ const mapsAreaRect: Rect = this.maps.mapAreaRect;
624
+ const markerTemplateElements: HTMLElement = createElement('div', {
625
+ id: this.maps.element.id + '_LayerIndex_' + layerIndex + '_Markers_Template_Group',
626
+ className: 'template',
627
+ styles: 'overflow: hidden; position: absolute;pointer-events: none;' +
628
+ 'top:' + mapsAreaRect.y + 'px;' +
629
+ 'left:' + mapsAreaRect.x + 'px;' +
630
+ 'height:' + mapsAreaRect.height + 'px;' +
631
+ 'width:' + mapsAreaRect.width + 'px;'
632
+ });
633
+ if (document.getElementById(markerTemplateElements.id)) {
634
+ removeElement(markerTemplateElements.id);
635
+ }
636
+ const currentLayers: LayerSettings = <LayerSettings>this.maps.layersCollection[layerIndex];
637
+ currentLayers.markerSettings.map((markerSettings: MarkerSettings, markerIndex: number) => {
638
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
639
+ const markerDatas: any[] = <any[]>markerSettings.dataSource;
640
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
641
+ Array.prototype.forEach.call(markerDatas, (data: any, dataIndex: number) => {
642
+ this.maps.markerNullCount = markerIndex >= 0 && dataIndex === 0 ? 0 : this.maps.markerNullCount;
643
+ let eventArgs: IMarkerRenderingEventArgs = {
644
+ template: markerSettings.template, data: data, maps: this.maps, marker: markerSettings,
645
+ cancel: false, name: markerRendering, fill: markerSettings.fill, colorValuePath: markerSettings.colorValuePath,
646
+ shapeValuePath: markerSettings.shapeValuePath, height: markerSettings.height,
647
+ width: markerSettings.width, imageUrl: markerSettings.imageUrl, imageUrlValuePath: markerSettings.imageUrlValuePath, shape: markerSettings.shape,
648
+ border: markerSettings.border
649
+ };
650
+ eventArgs = markerShapeChoose(eventArgs, data);
651
+ eventArgs = markerColorChoose(eventArgs, data);
652
+ this.maps.trigger('markerRendering', eventArgs, (MarkerArgs: IMarkerRenderingEventArgs) => {
653
+ if (markerSettings.shapeValuePath !== eventArgs.shapeValuePath ) {
654
+ eventArgs = markerShapeChoose(eventArgs, data);
655
+ }
656
+ if (markerSettings.colorValuePath !== eventArgs.colorValuePath ) {
657
+ eventArgs = markerColorChoose(eventArgs, data);
658
+ }
659
+ const lati: number = (!isNullOrUndefined(markerSettings.latitudeValuePath)) ?
660
+ Number(getValueFromObject(data, markerSettings.latitudeValuePath)) : !isNullOrUndefined(data['latitude']) ?
661
+ parseFloat(data['latitude']) : !isNullOrUndefined(data['Latitude']) ? data['Latitude'] : null;
662
+ const long: number = (!isNullOrUndefined(markerSettings.longitudeValuePath)) ?
663
+ Number(getValueFromObject(data, markerSettings.longitudeValuePath)) : !isNullOrUndefined(data['longitude']) ?
664
+ parseFloat(data['longitude']) : !isNullOrUndefined(data['Longitude']) ? data['Longitude'] : null;
665
+ const offset: Point = markerSettings.offset;
666
+ if (!eventArgs.cancel && markerSettings.visible && !isNullOrUndefined(long) && !isNullOrUndefined(lati)) {
667
+ const markerID: string = this.maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_'
668
+ + markerIndex + '_dataIndex_' + dataIndex;
669
+ const location: Point = (this.maps.isTileMap) ? convertTileLatLongToPoint(
670
+ new MapLocation(long, lati), this.maps.tileZoomLevel, this.maps.tileTranslatePoint, true
671
+ ) : convertGeoToPoint(lati, long, factor, currentLayers, this.maps);
672
+ const animate: boolean = currentLayers.animationDuration !== 0 || isNullOrUndefined(this.maps.zoomModule);
673
+ const transPoint: Point = {x: x, y: y};
674
+ if (eventArgs.template && (!isNaN(location.x) && !isNaN(location.y))) {
675
+ markerTemplateCounts++;
676
+ markerTemplate(eventArgs, templateFn, markerID, data, markerIndex, markerTemplateElements, location, transPoint,
677
+ scale, offset, this.maps);
678
+ } else if (!eventArgs.template && (!isNaN(location.x) && !isNaN(location.y))) {
679
+ markerCounts++;
680
+ marker(eventArgs, markerSettings, markerDatas, dataIndex, location, transPoint,
681
+ markerID, offset, scale, this.maps, markerSVGObject);
682
+ }
683
+ }
684
+ nullCount += (!isNaN(lati) && !isNaN(long)) ? 0 : 1;
685
+ markerTemplateCounts += (eventArgs.cancel) ? 1 : 0;
686
+ markerCounts += (eventArgs.cancel) ? 1 : 0;
687
+ this.maps.markerNullCount = (isNullOrUndefined(lati) || isNullOrUndefined(long))
688
+ ? this.maps.markerNullCount + 1 : this.maps.markerNullCount;
689
+ const markerDataLength: number = markerDatas.length - this.maps.markerNullCount;
690
+ if (markerSVGObject.childElementCount === (markerDataLength - markerTemplateCounts - nullCount) && (type !== 'Template')) {
691
+ layerElement.appendChild(markerSVGObject);
692
+ if (currentLayers.markerClusterSettings.allowClustering) {
693
+ this.maps.svgObject.appendChild(markerSVGObject);
694
+ this.maps.element.appendChild(this.maps.svgObject);
695
+ clusterTemplate(currentLayers, markerSVGObject, this.maps, layerIndex, markerSVGObject, layerElement, true, true);
696
+ }
697
+ }
698
+ if (markerTemplateElements.childElementCount === (markerDataLength - markerCounts - nullCount) && getElementByID(this.maps.element.id + '_Secondary_Element')) {
699
+ getElementByID(this.maps.element.id + '_Secondary_Element').appendChild(markerTemplateElements);
700
+ if (scale >= 1) {
701
+ if (currentLayers.markerClusterSettings.allowClustering) {
702
+ clusterTemplate(currentLayers, markerTemplateElements, this.maps, layerIndex, markerSVGObject, layerElement, false, true) ;
703
+ }
704
+ }
705
+ }
706
+ });
707
+ });
708
+ });
709
+ }
710
+ /**
711
+ * To translate the layer template elements
712
+ *
713
+ * @param {number} x - Specifies the x value
714
+ * @param {number} y - Specifies the y value
715
+ * @param {number} scale - Specifies the scale value
716
+ * @param {Maps} maps - Specifies the maps value
717
+ * @returns {void}
718
+ * @private
719
+ */
720
+ public processTemplate(x: number, y: number, scale: number, maps: Maps): void {
721
+ for (let i: number = 0; i < this.templateCount; i++) {
722
+ const factor: number = maps.mapLayerPanel.calculateFactor(this.currentLayer);
723
+ const markerTemplateElement: HTMLElement = <HTMLElement>getElementByID(maps.element.id + '_LayerIndex_' +
724
+ i + '_Markers_Template_Group');
725
+ const datalabelTemplateElemement: HTMLElement = <HTMLElement>getElementByID(maps.element.id + '_LayerIndex_'
726
+ + i + '_Label_Template_Group');
727
+ if ((!isNullOrUndefined(markerTemplateElement)) && markerTemplateElement.childElementCount > 0) {
728
+ for (let k: number = 0; k < markerTemplateElement.childElementCount; k++) {
729
+ this.markerTranslate(<HTMLElement>markerTemplateElement.childNodes[k], factor, x, y, scale, 'Template');
730
+ }
731
+ }
732
+ if ((!isNullOrUndefined(datalabelTemplateElemement)) && datalabelTemplateElemement.childElementCount > 0) {
733
+ for (let k: number = 0; k < datalabelTemplateElemement.childElementCount; k++) {
734
+ this.dataLabelTranslate(<HTMLElement>datalabelTemplateElemement.childNodes[k], factor, x, y, scale, 'Template');
735
+ }
736
+ }
737
+ }
738
+ }
739
+
740
+ private dataLabelTranslate(element: Element | HTMLElement, factor: number, x: number, y: number, scale: number, type: string, animate: boolean = false): void {
741
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
742
+ const labelCollection: any[] = this.maps.dataLabelModule.dataLabelCollections;
743
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
744
+ const zoomelement: any = element.getBoundingClientRect();
745
+ let text: string; let trimmedLable: string;
746
+ const style: FontModel = this.maps.layers[this.index].dataLabelSettings.textStyle;
747
+ let zoomtext: string; let zoomtextSize: Size; let zoomtrimLabel: string;
748
+ const labelPath: string = this.maps.layers[this.index].dataLabelSettings.labelPath;
749
+ const layerIndex: number = parseFloat(element.id.split('_LayerIndex_')[1].split('_')[0]);
750
+ const shapeIndex: number = parseFloat(element.id.split('_shapeIndex_')[1].split('_')[0]);
751
+ let labelIndex: number;
752
+ if (element.id.indexOf('_LabelIndex_') > -1) {
753
+ labelIndex = parseFloat(element.id.split('_LabelIndex_')[1].split('_')[0]);
754
+ }
755
+ const duration: number = this.currentLayer.animationDuration;
756
+ for (let l: number = 0; l < labelCollection.length; l++) {
757
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
758
+ const label: any = labelCollection[l];
759
+ if (label['layerIndex'] === layerIndex && label['shapeIndex'] === shapeIndex
760
+ && label['labelIndex'] === labelIndex) {
761
+ let labelX: number = label['location']['x'];
762
+ let labelY: number = label['location']['y'];
763
+ if (type === 'Template') {
764
+ const layerEle: Element = getElementByID(this.maps.element.id + '_Layer_Collections');
765
+ labelX = ((Math.abs(this.maps.baseMapRectBounds['min']['x'] - labelX)) * scale);
766
+ labelY = ((Math.abs(this.maps.baseMapRectBounds['min']['y'] - labelY)) * scale);
767
+ const templateOffset: ClientRect = element.getBoundingClientRect();
768
+ const layerOffset: ClientRect = layerEle.getBoundingClientRect();
769
+ const elementOffset: ClientRect = element.parentElement.getBoundingClientRect();
770
+ const x: number = ((labelX) + (layerOffset.left - elementOffset.left) - (templateOffset.width / 2));
771
+ const y: number = ((labelY) + (layerOffset.top - elementOffset.top) - (templateOffset.height / 2));
772
+ (<HTMLElement>element).style.left = x + 'px';
773
+ (<HTMLElement>element).style.top = y + 'px';
774
+ } else {
775
+ labelX = ((labelX + x) * scale); labelY = ((labelY + y) * scale);
776
+ zoomtext = label['dataLabelText'];
777
+ zoomtextSize = measureText(zoomtext, style);
778
+ const start: number = labelY - zoomtextSize['height'] / 4;
779
+ const end: number = labelY + zoomtextSize['height'] / 4;
780
+ const xpositionEnds: number = labelX + zoomtextSize['width'] / 2;
781
+ const xpositionStart: number = labelX - zoomtextSize['width'] / 2;
782
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
783
+ const textLocations: any = { rightWidth: xpositionEnds, leftWidth: xpositionStart, heightTop: start, heightBottom: end };
784
+ if (!animate || duration === 0) {
785
+ element.setAttribute('transform', 'translate( ' + labelX + ' ' + labelY + ' )');
786
+ }
787
+ if (this.maps.layers[this.index].dataLabelSettings.smartLabelMode === 'Hide') {
788
+ if (scale > 1) {
789
+ text = ((this.maps.dataLabelShape[l] * scale) >= zoomtextSize['width']) ? zoomtext : '';
790
+ element.innerHTML = text;
791
+ } else {
792
+ text = (this.maps.dataLabelShape[l] >= zoomtextSize['width']) ? zoomtext : '';
793
+ element.innerHTML = text;
794
+ }
795
+ }
796
+ if (this.maps.layers[this.index].dataLabelSettings.smartLabelMode === 'Trim') {
797
+ if (scale > 1) {
798
+ zoomtrimLabel = textTrim((this.maps.dataLabelShape[l] * scale), zoomtext, style);
799
+ text = zoomtrimLabel; element.innerHTML = text;
800
+ } else {
801
+ zoomtrimLabel = textTrim(this.maps.dataLabelShape[l], zoomtext, style);
802
+ text = zoomtrimLabel; element.innerHTML = text;
803
+ }
804
+ }
805
+ if (this.maps.layers[this.index].dataLabelSettings.intersectionAction === 'Hide') {
806
+ for (let m: number = 0; m < this.intersect.length; m++) {
807
+ if (!isNullOrUndefined(this.intersect[m])) {
808
+ if (textLocations['leftWidth'] > this.intersect[m]['rightWidth']
809
+ || textLocations['rightWidth'] < this.intersect[m]['leftWidth']
810
+ || textLocations['heightTop'] > this.intersect[m]['heightBottom']
811
+ || textLocations['heightBottom'] < this.intersect[m]['heightTop']) {
812
+ text = !isNullOrUndefined(text) ? text : zoomtext;
813
+ element.innerHTML = text;
814
+ } else {
815
+ text = ''; element.innerHTML = text;
816
+ break;
817
+ }
818
+ }
819
+ }
820
+ this.intersect.push(textLocations);
821
+ }
822
+ if (this.maps.layers[this.index].dataLabelSettings.intersectionAction === 'Trim') {
823
+ for (let j: number = 0; j < this.intersect.length; j++) {
824
+ if (!isNullOrUndefined(this.intersect[j])) {
825
+ if (textLocations['rightWidth'] < this.intersect[j]['leftWidth']
826
+ || textLocations['leftWidth'] > this.intersect[j]['rightWidth']
827
+ || textLocations['heightBottom'] < this.intersect[j]['heightTop']
828
+ || textLocations['heightTop'] > this.intersect[j]['heightBottom']) {
829
+ trimmedLable = !isNullOrUndefined(text) ? text : zoomtext;
830
+ if (scale > 1) {
831
+ trimmedLable = textTrim((this.maps.dataLabelShape[l] * scale), trimmedLable, style);
832
+ }
833
+ element.innerHTML = trimmedLable;
834
+ } else {
835
+ if (textLocations['leftWidth'] > this.intersect[j]['leftWidth']) {
836
+ const width: number = this.intersect[j]['rightWidth'] - textLocations['leftWidth'];
837
+ const difference: number = width - (textLocations['rightWidth'] - textLocations['leftWidth']);
838
+ text = !isNullOrUndefined(text) ? text : zoomtext;
839
+ trimmedLable = textTrim(difference, text, style);
840
+ element.innerHTML = trimmedLable;
841
+ break;
842
+ }
843
+ if (textLocations['leftWidth'] < this.intersect[j]['leftWidth']) {
844
+ const width: number = textLocations['rightWidth'] - this.intersect[j]['leftWidth'];
845
+ const difference: number = Math.abs(width - (textLocations['rightWidth'] - textLocations['leftWidth']));
846
+ text = !isNullOrUndefined(text) ? text : zoomtext;
847
+ trimmedLable = textTrim(difference, text, style);
848
+ element.innerHTML = trimmedLable;
849
+ break;
850
+ }
851
+ }
852
+ }
853
+ }
854
+ this.intersect.push(textLocations);
855
+ if (isNullOrUndefined(trimmedLable)) {
856
+ trimmedLable = textTrim((this.maps.dataLabelShape[l] * scale), zoomtext, style);
857
+ element.innerHTML = trimmedLable;
858
+ }
859
+ }
860
+ if (animate || duration > 0) {
861
+ smoothTranslate(element, 0, duration, new MapLocation(labelX, labelY));
862
+ }
863
+ }
864
+ }
865
+ }
866
+ }
867
+
868
+ private markerTranslate(
869
+ element: Element | HTMLElement, factor: number, x: number, y: number, scale: number, type: string, animate: boolean = false
870
+ ): void {
871
+ const layerIndex: number = parseInt(element.id.split('_LayerIndex_')[1].split('_')[0], 10);
872
+ const markerIndex: number = parseInt(element.id.split('_MarkerIndex_')[1].split('_')[0], 10);
873
+ const dataIndex: number = parseInt(element.id.split('_dataIndex_')[1].split('_')[0], 10);
874
+ const layer: LayerSettings = <LayerSettings>this.maps.layersCollection[layerIndex];
875
+ const marker: MarkerSettings = <MarkerSettings>layer.markerSettings[markerIndex];
876
+ if (!isNullOrUndefined(marker) && !isNullOrUndefined(marker.dataSource) && !isNullOrUndefined(marker.dataSource[dataIndex])) {
877
+ const lng: number = (!isNullOrUndefined(marker.longitudeValuePath)) ?
878
+ Number(getValueFromObject(marker.dataSource[dataIndex], marker.longitudeValuePath)) :
879
+ !isNullOrUndefined(marker.dataSource[dataIndex]['longitude']) ? parseFloat(marker.dataSource[dataIndex]['longitude']) :
880
+ !isNullOrUndefined(marker.dataSource[dataIndex]['Latitude']) ? parseFloat(marker.dataSource[dataIndex]['Latitude']) : 0;
881
+ const lat: number = (!isNullOrUndefined(marker.latitudeValuePath)) ?
882
+ Number(getValueFromObject(marker.dataSource[dataIndex], marker.latitudeValuePath)) :
883
+ !isNullOrUndefined(marker.dataSource[dataIndex]['latitude']) ? parseFloat(marker.dataSource[dataIndex]['latitude']) :
884
+ !isNullOrUndefined(marker.dataSource[dataIndex]['Latitude']) ? parseFloat(marker.dataSource[dataIndex]['Latitude']) : 0;
885
+ const duration: number = this.currentLayer.animationDuration;
886
+ const location: Point = (this.maps.isTileMap) ? convertTileLatLongToPoint(
887
+ new Point(lng, lat), this.maps.tileZoomLevel, this.maps.tileTranslatePoint, true
888
+ ) : convertGeoToPoint(lat, lng, factor, layer, this.maps);
889
+ if (this.maps.isTileMap) {
890
+ if (type === 'Template') {
891
+ const templateOffset: ClientRect = element.getBoundingClientRect();
892
+ (<HTMLElement>element).style.left = ((location.x - (templateOffset.width / 2)) + marker.offset.x) + 'px';
893
+ (<HTMLElement>element).style.top = ((location.y - (templateOffset.height / 2)) + marker.offset.y) + 'px';
894
+ if (this.maps.layers[this.maps.baseLayerIndex].layerType === 'GoogleStaticMap') {
895
+ const staticMapOffset : ClientRect = getElementByID(this.maps.element.id + '_StaticGoogleMap').getBoundingClientRect();
896
+ const staticMapOffsetWidth : number = 640;
897
+ if (element['style']['display'] !== 'none') {
898
+ if ((staticMapOffset['x'] > templateOffset['x'] || staticMapOffset['x'] + staticMapOffsetWidth < templateOffset['x'] + templateOffset['width'])
899
+ && (staticMapOffset['y'] > templateOffset['y'] || staticMapOffset['y'] + staticMapOffset['height'] < templateOffset['y'] + templateOffset['height'])
900
+ ) {
901
+ element['style']['display'] = 'none';
902
+ } else if ((staticMapOffset['x'] > templateOffset['x'] || staticMapOffset['x'] + staticMapOffsetWidth < templateOffset['x'] + templateOffset['width'])) {
903
+ element['style']['display'] = 'none';
904
+ }
905
+ }
906
+ }
907
+
908
+ } else {
909
+ location.x += marker.offset.x;
910
+ location.y += marker.offset.y;
911
+ element.setAttribute('transform', 'translate( ' + location.x + ' ' + location.y + ' )');
912
+ }
913
+ } else {
914
+ if (type === 'Template') {
915
+ if (duration > 0) {
916
+ location.x = ((Math.abs(this.maps.baseMapRectBounds['min']['x'] - location.x)) * scale);
917
+ location.y = ((Math.abs(this.maps.baseMapRectBounds['min']['y'] - location.y)) * scale);
918
+ const layerOffset: ClientRect = getElementByID(this.maps.element.id + '_Layer_Collections').getBoundingClientRect();
919
+ const elementOffset: ClientRect = element.parentElement.getBoundingClientRect();
920
+ (<HTMLElement>element).style.left = (((location.x) + (layerOffset.left - elementOffset.left)) + marker.offset.x) + 'px';
921
+ (<HTMLElement>element).style.top = (((location.y) + (layerOffset.top - elementOffset.top)) + marker.offset.y) + 'px';
922
+ (<HTMLElement>element).style.transform = 'translate(-50%, -50%)';
923
+ } else {
924
+ const elementOffset: ClientRect = element.getBoundingClientRect();
925
+ (<HTMLElement>element).style.left = ((location.x + x) * scale) + marker.offset.x - this.maps.mapAreaRect.x - (elementOffset.width / 2) + 'px';
926
+ (<HTMLElement>element).style.top = ((location.y + y) * scale) + marker.offset.y - this.maps.mapAreaRect.y - (elementOffset.height / 2) + 'px';
927
+ }
928
+ } else {
929
+ location.x = (((location.x + x) * scale) + marker.offset.x);
930
+ location.y = (((location.y + y) * scale) + marker.offset.y);
931
+ if (!animate || duration === 0) {
932
+ element.setAttribute('transform', 'translate( ' + location.x + ' ' + location.y + ' )');
933
+ } else {
934
+ smoothTranslate(element, 0, duration, location);
935
+ }
936
+ }
937
+ }
938
+ }
939
+ }
940
+ private markerLineAnimation(map: Maps): void {
941
+ if (map.isTileMap) {
942
+ for (let i: number = 0; i < map.layersCollection.length; i++) {
943
+ const markerTemplateElement: HTMLElement = <HTMLElement>getElementByID(this.maps.element.id + '_LayerIndex_' + i + '_Markers_Template_Group');
944
+ const lineElement: HTMLElement = <HTMLElement>getElementByID(this.maps.element.id + '_LayerIndex_' + i + '_line_Group');
945
+ if (!isNullOrUndefined(markerTemplateElement)) {
946
+ markerTemplateElement.style.visibility = 'hidden';
947
+ }
948
+ if (!isNullOrUndefined(lineElement)) {
949
+ lineElement.style.visibility = 'hidden';
950
+ }
951
+ }
952
+ }
953
+ }
954
+ /**
955
+ * @private
956
+ */
957
+ public panning(direction: PanDirection, xDifference: number, yDifference: number, mouseLocation?: PointerEvent | TouchEvent | KeyboardEvent): void {
958
+ const map: Maps = this.maps; let panArgs: IMapPanEventArgs;
959
+ const down: Point = this.mouseDownPoints;
960
+ const move: Point = this.mouseMovePoints;
961
+ const scale: number = map.scale;
962
+ map.markerZoomedState = false;
963
+ map.zoomPersistence = map.enablePersistence;
964
+ map.defaultState = false;
965
+ map.initialCheck = false;
966
+ const translatePoint: Point = map.translatePoint;
967
+ const prevTilePoint: Point = map.tileTranslatePoint;
968
+ let x: number; let y: number;
969
+ xDifference = !isNullOrUndefined(xDifference) ? xDifference : (down.x - move.x);
970
+ yDifference = !isNullOrUndefined(yDifference) ? yDifference : (down.y - move.y);
971
+ this.maps.mergeCluster();
972
+ if (!map.isTileMap) {
973
+ const legendElement: HTMLElement = document.getElementById(map.element.id + '_Legend_Group');
974
+ const legendHeight: number = !isNullOrUndefined(legendElement) ? legendElement.getClientRects()[0].height : 0;
975
+ x = translatePoint.x - xDifference / scale;
976
+ y = translatePoint.y - yDifference / scale;
977
+ const layerRect: ClientRect = getElementByID(map.element.id + '_Layer_Collections').getBoundingClientRect();
978
+ const elementRect: ClientRect = getElementByID(map.element.id + '_svg').getBoundingClientRect();
979
+ const panningXDirection: boolean = ((xDifference < 0 ? layerRect.left <= (elementRect.left + map.mapAreaRect.x) :
980
+ ((layerRect.left + layerRect.width + map.mapAreaRect.x) >= (elementRect.width))));
981
+ const panningYDirection: boolean = ((yDifference < 0 ? layerRect.top <= (elementRect.top + map.mapAreaRect.y) :
982
+ ((layerRect.top + layerRect.height + legendHeight + map.margin.top) >= (elementRect.top + elementRect.height))));
983
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
984
+ const location: any = this.maps.getGeoLocation(this.maps.layersCollection.length - 1, mouseLocation['layerX'], mouseLocation['layerY']);
985
+ panArgs = {
986
+ cancel: false, name: pan, maps: map,
987
+ tileTranslatePoint: {}, translatePoint: { previous: translatePoint, current: new Point(x, y) },
988
+ scale: map.scale, tileZoomLevel: map.tileZoomLevel, latitude: location['latitude'], longitude: location['longitude']
989
+ };
990
+ map.trigger(pan, panArgs);
991
+ if (!panArgs.cancel) {
992
+ if (panningXDirection && panningYDirection) {
993
+ map.translatePoint = new Point(x, y);
994
+ this.applyTransform(map);
995
+ } else if (panningXDirection) {
996
+ map.translatePoint = new Point(x, map.translatePoint.y);
997
+ this.applyTransform(map);
998
+ } else if (panningYDirection) {
999
+ map.translatePoint = new Point(map.translatePoint.x, y);
1000
+ this.applyTransform(map);
1001
+ }
1002
+ }
1003
+ this.maps.zoomNotApplied = false;
1004
+ } else if (this.maps.tileZoomLevel > 1) {
1005
+ x = map.tileTranslatePoint.x - xDifference;
1006
+ y = map.tileTranslatePoint.y - yDifference;
1007
+ this.distanceX = x - map.tileTranslatePoint.x;
1008
+ this.distanceY = y - map.tileTranslatePoint.y;
1009
+ map.tileTranslatePoint.x = x;
1010
+ map.tileTranslatePoint.y = y;
1011
+ if ((map.tileTranslatePoint.y > -10 && yDifference < 0) || ((map.tileTranslatePoint.y < -((Math.pow(2, this.maps.tileZoomLevel) - 2) * 256) && yDifference > 0))) {
1012
+ map.tileTranslatePoint.x = x + xDifference;
1013
+ map.tileTranslatePoint.y = y + yDifference;
1014
+ }
1015
+ map.translatePoint.x = (map.tileTranslatePoint.x - xDifference) / map.scale;
1016
+ map.translatePoint.y = (map.tileTranslatePoint.y - yDifference) / map.scale;
1017
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1018
+ const location: any = this.maps.getTileGeoLocation(mouseLocation['layerX'], mouseLocation['layerY']);
1019
+ panArgs = {
1020
+ cancel: false, name: pan, maps: map,
1021
+ tileTranslatePoint: { previous: prevTilePoint, current: map.tileTranslatePoint },
1022
+ translatePoint: { previous: translatePoint, current: map.translatePoint }, scale: map.scale,
1023
+ tileZoomLevel: map.tileZoomLevel, latitude: location['latitude'], longitude: location['longitude']
1024
+ };
1025
+ map.trigger(pan, panArgs);
1026
+ map.mapLayerPanel.generateTiles(map.tileZoomLevel, map.tileTranslatePoint, 'Pan');
1027
+ this.applyTransform(map);
1028
+ }
1029
+ map.zoomTranslatePoint = map.translatePoint;
1030
+ this.mouseDownPoints = this.mouseMovePoints;
1031
+ this.maps.zoomNotApplied = false;
1032
+ this.isSingleClick = false;
1033
+ }
1034
+
1035
+ private toAlignSublayer(): void {
1036
+ this.maps.translatePoint.x = !isNullOrUndefined(this.distanceX) ? (this.maps.translatePoint.x -
1037
+ (this.distanceX / this.maps.scale)) : this.maps.translatePoint.x;
1038
+ this.maps.translatePoint.y = !isNullOrUndefined(this.distanceY) ? this.maps.translatePoint.y -
1039
+ (this.distanceY / this.maps.scale) : this.maps.translatePoint.y;
1040
+ this.applyTransform(this.maps, false);
1041
+ }
1042
+
1043
+ public toolBarZooming(zoomFactor: number, type: string): void {
1044
+ const map: Maps = this.maps;
1045
+ map.initialCheck = false;
1046
+ map.defaultState = ((type === 'Reset' && zoomFactor === 1 && !(map.zoomSettings.resetToInitial && map.applyZoomReset))
1047
+ || (type === 'ZoomOut' && zoomFactor === 1));
1048
+ const prevLevel: number = map.tileZoomLevel;
1049
+ const scale: number = map.previousScale = map.scale;
1050
+ map.markerZoomedState = false;
1051
+ map.zoomPersistence = map.enablePersistence;
1052
+ map.mapScaleValue = zoomFactor;
1053
+ const maxZoom: number = map.zoomSettings.maxZoom;
1054
+ const minZoom: number = map.zoomSettings.minZoom;
1055
+ const size: Rect = map.mapAreaRect;
1056
+ const translatePoint: Point = map.previousPoint = map.translatePoint;
1057
+ const prevTilePoint: Point = map.tileTranslatePoint;
1058
+ map.previousProjection = map.projectionType;
1059
+ zoomFactor = (type === 'ZoomOut') ? (Math.round(zoomFactor) === 1 ? 1 : zoomFactor) : zoomFactor;
1060
+ zoomFactor = (type === 'Reset') ? 1 : (Math.round(zoomFactor) === 0) ? 1 : zoomFactor;
1061
+ zoomFactor = (minZoom > zoomFactor && type === 'ZoomIn') ? minZoom + 1 : zoomFactor;
1062
+ let zoomArgs: IMapZoomEventArgs;
1063
+ if ((!map.isTileMap) && (type === 'ZoomIn' ? zoomFactor >= minZoom && zoomFactor <= maxZoom : zoomFactor >= minZoom
1064
+ || map.isReset)) {
1065
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1066
+ const min: any = map.baseMapRectBounds['min'] as any;
1067
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1068
+ const max: any = map.baseMapRectBounds['max'] as any;
1069
+ let mapWidth: number = Math.abs(max['x'] - min['x']);
1070
+ let mapHeight: number = Math.abs(min['y'] - max['y']);
1071
+ let translatePointX: number;
1072
+ let translatePointY: number;
1073
+ if (zoomFactor < 1.2 && map.projectionType !== 'Eckert5') {
1074
+ if (mapHeight === 0 || mapWidth === 0 || mapHeight === mapWidth) {
1075
+ mapWidth = size.width / 2;
1076
+ mapHeight = size.height;
1077
+ }
1078
+ zoomFactor = parseFloat(Math.min(size.width / mapWidth, size.height / mapHeight).toFixed(2));
1079
+ zoomFactor = zoomFactor > 1.05 ? 1 : zoomFactor;
1080
+ map.translatePoint = this.calculateInitalZoomTranslatePoint(zoomFactor, mapWidth, mapHeight, size, min, map);
1081
+ } else {
1082
+ translatePointX = translatePoint.x - (((size.width / scale) - (size.width / zoomFactor)) / 2);
1083
+ translatePointY = translatePoint.y - (((size.height / scale) - (size.height / zoomFactor)) / 2);
1084
+ const currentHeight: number = Math.abs(map.baseMapRectBounds['max']['y'] - map.baseMapRectBounds['min']['y']) * zoomFactor;
1085
+ translatePointX = (currentHeight < map.mapAreaRect.height) ? (size.x + ((-(min['x'])) + ((size.width / 2) - (mapWidth / 2))))
1086
+ : translatePointX;
1087
+ translatePointY = (currentHeight < map.mapAreaRect.height) ? (size.y + ((-(min['y'])) + ((size.height / 2) - (mapHeight / 2))))
1088
+ : translatePointY;
1089
+ map.translatePoint = new Point(translatePointX, translatePointY);
1090
+ }
1091
+ map.zoomTranslatePoint = map.translatePoint;
1092
+ map.scale = zoomFactor;
1093
+ if (this.triggerZoomEvent(prevTilePoint, prevLevel, type)) {
1094
+ map.translatePoint = map.zoomTranslatePoint = map.previousPoint;
1095
+ map.scale = map.previousScale;
1096
+ } else {
1097
+ this.applyTransform(map, true);
1098
+ }
1099
+ } else if ((map.isTileMap) && ((zoomFactor >= minZoom && zoomFactor <= maxZoom) || map.isReset)) {
1100
+ let tileZoomFactor: number = prevLevel < minZoom && !map.isReset ? minZoom : zoomFactor;
1101
+ map.scale = Math.pow(2, tileZoomFactor - 1);
1102
+ map.tileZoomLevel = tileZoomFactor;
1103
+ if (map.previousScale !== map.scale || map.isReset) {
1104
+ map.zoomSettings.zoomFactor = zoomFactor;
1105
+ const position: Point = { x: map.availableSize.width / 2, y: map.availableSize.height / 2 };
1106
+ this.getTileTranslatePosition(prevLevel, tileZoomFactor, position, type);
1107
+ if (map.zoomSettings.resetToInitial && map.applyZoomReset && type === 'Reset' || (type === 'ZoomOut' && map.zoomSettings.resetToInitial && map.applyZoomReset && tileZoomFactor <= map.initialZoomLevel)) {
1108
+ map.initialCheck = true;
1109
+ map.zoomPersistence = false;
1110
+ map.tileTranslatePoint.x = map.initialTileTranslate.x;
1111
+ map.tileTranslatePoint.y = map.initialTileTranslate.y;
1112
+ tileZoomFactor = map.tileZoomLevel = map.mapScaleValue = map.initialZoomLevel;
1113
+ }
1114
+ if (this.triggerZoomEvent(prevTilePoint, prevLevel, type)) {
1115
+ map.translatePoint = map.tileTranslatePoint = new Point(0, 0);
1116
+ map.scale = map.previousScale;
1117
+ map.tileZoomLevel = prevLevel;
1118
+ map.zoomSettings.zoomFactor = map.previousScale;
1119
+ } else {
1120
+ map.translatePoint.y = (map.tileTranslatePoint.y - (0.01 * map.mapScaleValue)) / map.scale;
1121
+ map.translatePoint.x = (map.tileTranslatePoint.x - (0.01 * map.mapScaleValue)) / map.scale;
1122
+ if (document.getElementById(this.maps.element.id + '_LayerIndex_1')) {
1123
+ document.getElementById(this.maps.element.id + '_LayerIndex_1').style.display = 'none';
1124
+ }
1125
+ if (document.querySelector('.GroupElement')) {
1126
+ (document.querySelector('.GroupElement') as HTMLElement).style.display = 'none';
1127
+ }
1128
+ this.markerLineAnimation(map);
1129
+ map.mapLayerPanel.generateTiles(tileZoomFactor, map.tileTranslatePoint, type);
1130
+ const element1: HTMLElement = document.getElementById(this.maps.element.id + '_tiles');
1131
+ const animationDuration: number = this.maps.layersCollection[0].animationDuration;
1132
+ setTimeout(() => {
1133
+ if (type === 'ZoomOut' || type === 'Reset') {
1134
+ // element1.removeChild(element1.children[element1.childElementCount - 1]);
1135
+ // element1.childElementCount ? element1.removeChild(element1.children[element1.childElementCount - 1]) : element1;
1136
+ }
1137
+ this.applyTransform(this.maps, true);
1138
+ if (document.getElementById(this.maps.element.id + '_LayerIndex_1')) {
1139
+ document.getElementById(this.maps.element.id + '_LayerIndex_1').style.display = 'block';
1140
+ }
1141
+ this.maps.isAddLayer = false;
1142
+ }, animationDuration);
1143
+ }
1144
+ }
1145
+ this.maps.zoomNotApplied = false;
1146
+ }
1147
+ }
1148
+
1149
+ public createZoomingToolbars(): void {
1150
+ const map: Maps = this.maps;
1151
+ let zoomInElements: Element;
1152
+ let zoomOutElements: Element;
1153
+ this.toolBarGroup = map.renderer.createGroup({
1154
+ id: map.element.id + '_Zooming_KitCollection',
1155
+ opacity: map.theme.toLowerCase() === 'fluentdark' ? 0.6 : 0.3
1156
+ });
1157
+ const kitHeight: number = 16; const kitWidth: number = 16;
1158
+ let xSpacing: number = 15; let ySpacing: number = 15;
1159
+ const padding: number = 20;
1160
+ const orientation: Orientation = map.zoomSettings.toolBarOrientation;
1161
+ const toolbarsCollection: string[] = map.zoomSettings.toolbars;
1162
+ let shadowElement: string = '<filter id="chart_shadow" height="130%"><feGaussianBlur in="SourceAlpha" stdDeviation="5"/>';
1163
+ shadowElement += '<feOffset dx="-3" dy="4" result="offsetblur"/><feComponentTransfer><feFuncA type="linear" slope="1"/>';
1164
+ shadowElement += '</feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge></filter>';
1165
+ const toolBarLength: number = map.zoomSettings.toolbars.length;
1166
+ const toolWidth: number = (map.zoomSettings.toolBarOrientation === 'Horizontal') ? (toolBarLength * kitWidth) + (toolBarLength * padding) : (kitWidth * 2);
1167
+ const toolHeight: number = (map.zoomSettings.toolBarOrientation === 'Horizontal') ? (kitHeight * 2) : (toolBarLength * kitHeight) + (toolBarLength * padding);
1168
+ const defElement: Element = map.renderer.createDefs();
1169
+ defElement.innerHTML = shadowElement;
1170
+ this.toolBarGroup.appendChild(defElement);
1171
+ const outerElement: Element = map.renderer.drawRectangle(new RectOption(
1172
+ map.element.id + '_Zooming_Rect', 'transparent', { color: 'transparent', width: 1 },
1173
+ 0.1, new Rect(0, 0, toolWidth, toolHeight), 0, 0
1174
+ ));
1175
+ outerElement.setAttribute('filter', 'url(#chart_shadow)');
1176
+ this.toolBarGroup.appendChild(outerElement);
1177
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1178
+ let performFunction: any;
1179
+ for (let i: number = 0; i < toolbarsCollection.length; i++) {
1180
+ const toolbar: string = toolbarsCollection[i];
1181
+ let pathOptions: PathOption; let polyOptions: PolygonOption;
1182
+ this.currentToolbarEle = map.renderer.createGroup({
1183
+ id: map.element.id + '_Zooming_ToolBar_' + toolbar + '_Group',
1184
+ transform: 'translate( ' + xSpacing + ' ' + ySpacing + ' ) '
1185
+ });
1186
+ this.currentToolbarEle.setAttribute('class', 'e-maps-toolbar');
1187
+ const fillColor: string = '';
1188
+ const fill: string = 'transparent';
1189
+ let direction: string = ''; const polygonDirection: string = '';
1190
+ this.selectionColor = this.maps.zoomSettings.selectionColor || this.maps.themeStyle.zoomSelectionColor;
1191
+ switch (toolbar.toLowerCase()) {
1192
+ case 'zoom': {
1193
+ let fillColor: string;
1194
+ let strokeColor: string;
1195
+ direction = 'M0.001,14.629L1.372,16l4.571-4.571v-0.685l0.228-0.274c1.051,0.868,2.423,1.417,3.885,1.417c3.291,0,';
1196
+ direction += '5.943-2.651,5.943-5.943S13.395,0,10.103,0S4.16,2.651,4.16,5.943c0,1.508,0.503,2.834,1.417,3.885l-0.274,0.228H4.571';
1197
+ direction = direction + 'L0.001,14.629L0.001,14.629z M5.943,5.943c0-2.285,1.828-4.114,4.114-4.114s4.114,1.828,4.114,';
1198
+ if (this.maps.zoomSettings.enablePanning && !this.maps.zoomSettings.enableSelectionZooming) {
1199
+ fillColor = fill;
1200
+ strokeColor = this.maps.themeStyle.zoomFillColor;
1201
+ } else if (this.maps.zoomSettings.enablePanning && this.maps.zoomSettings.enableSelectionZooming){
1202
+ fillColor = fill;
1203
+ strokeColor = this.maps.themeStyle.zoomFillColor;
1204
+ } else if (!this.maps.zoomSettings.enablePanning && !this.maps.zoomSettings.enableSelectionZooming) {
1205
+ fillColor = fill;
1206
+ strokeColor = this.maps.themeStyle.zoomFillColor;
1207
+ } else {
1208
+ fillColor = this.selectionColor;
1209
+ strokeColor = this.selectionColor;
1210
+ }
1211
+ this.currentToolbarEle.appendChild(map.renderer.drawPath(new PathOption(
1212
+ map.element.id + '_Zooming_ToolBar_' + toolbar, fillColor, 1, strokeColor, 1, 1, null,
1213
+ direction + '4.114s-1.828,4.114-4.114,4.114S5.943,8.229,5.943,5.943z')
1214
+ ) as SVGPathElement);
1215
+ this.zoomElements = this.currentToolbarEle;
1216
+ this.wireEvents(this.currentToolbarEle, this.performToolBarAction);
1217
+ break;
1218
+ }
1219
+ case 'zoomin':
1220
+ direction = 'M 8, 0 L 8, 16 M 0, 8 L 16, 8';
1221
+ this.currentToolbarEle.appendChild(map.renderer.drawPath(new PathOption(
1222
+ map.element.id + '_Zooming_ToolBar_' + toolbar + '_Path', fill, 3, this.maps.themeStyle.zoomFillColor, 1, 1, null, direction)
1223
+ ) as SVGPathElement);
1224
+ zoomInElements = this.currentToolbarEle;
1225
+ this.wireEvents(this.currentToolbarEle, this.performToolBarAction);
1226
+ break;
1227
+ case 'zoomout':
1228
+ direction = 'M 0, 8 L 16, 8';
1229
+ this.currentToolbarEle.appendChild(map.renderer.drawPath(new PathOption(
1230
+ map.element.id + '_Zooming_ToolBar_' + toolbar, fill, 3, this.maps.themeStyle.zoomFillColor, 1, 1, null, direction)
1231
+ ) as SVGPathElement);
1232
+ zoomOutElements = this.currentToolbarEle;
1233
+ this.wireEvents(this.currentToolbarEle, this.performToolBarAction);
1234
+ break;
1235
+ case 'pan': {
1236
+ let color: string;
1237
+ direction = 'M5,3h2.3L7.275,5.875h1.4L8.65,3H11L8,0L5,3z M3,11V8.7l2.875,0.025v-1.4L3,7.35V5L0,8L3,';
1238
+ direction += '11z M11,13H8.7l0.025-2.875h-1.4L7.35,13H5l3,3L11,13z M13,5v2.3l-2.875-0.025v1.4L13,8.65V11l3-3L13,5z';
1239
+ if (this.maps.zoomSettings.enablePanning && this.maps.zoomModule.isDragZoom) {
1240
+ color = '#737373';
1241
+ } else if (!this.maps.zoomSettings.enablePanning) {
1242
+ color = '#737373';
1243
+ this.currentToolbarEle.setAttribute('class', '');
1244
+ } else {
1245
+ color = this.selectionColor;
1246
+ }
1247
+ this.currentToolbarEle.appendChild(map.renderer.drawPath(new PathOption(
1248
+ map.element.id + '_Zooming_ToolBar_' + toolbar, color, 1, color, 1, 1, null,
1249
+ direction)
1250
+ ) as SVGPathElement);
1251
+ this.panColor = color;
1252
+ this.panElements = this.currentToolbarEle;
1253
+ this.wireEvents(this.currentToolbarEle, this.performToolBarAction);
1254
+ break;
1255
+ }
1256
+ case 'reset':
1257
+ direction = 'M12.364,8h-2.182l2.909,3.25L16,8h-2.182c0-3.575-2.618-6.5-5.818-6.5c-1.128,0-2.218,0.366-3.091,';
1258
+ direction += '1.016l1.055,1.178C6.581,3.328,7.272,3.125,8,3.125C10.4,3.125,12.363,5.319,12.364,8L12.364,8z M11.091,';
1259
+ direction += '13.484l-1.055-1.178C9.419,12.672,8.728,12.875,8,12.875c-2.4,0-4.364-2.194-4.364-4.875h2.182L2.909,4.75L0,8h2.182c0,';
1260
+ this.currentToolbarEle.appendChild(map.renderer.drawPath(new PathOption(
1261
+ map.element.id + '_Zooming_ToolBar_' + toolbar, this.fillColor, null, this.maps.themeStyle.zoomFillColor,
1262
+ 1, 1, null, direction + '3.575,2.618,6.5,5.818,6.5C9.128,14.5,10.219,14.134,11.091,13.484L11.091,13.484z')
1263
+ ) as HTMLElement);
1264
+ this.wireEvents(this.currentToolbarEle, this.performToolBarAction);
1265
+ break;
1266
+ }
1267
+ this.currentToolbarEle.appendChild(map.renderer.drawCircle(
1268
+ new CircleOption(map.element.id + '_Zooming_ToolBar_' + toolbar + '_Rect', fill, { color: this.maps.themeStyle.zoomFillColor, width: 1 }, 1, 8, 8, 16, '')
1269
+ ) as SVGRectElement);
1270
+ xSpacing = (orientation === 'Horizontal') ? (xSpacing + (kitWidth + padding)) : xSpacing;
1271
+ ySpacing = (orientation === 'Horizontal') ? ySpacing : (ySpacing + (kitHeight + padding));
1272
+ this.toolBarGroup.appendChild(this.currentToolbarEle);
1273
+ }
1274
+ }
1275
+
1276
+ public performToolBarAction(e: PointerEvent): void {
1277
+ const target: Element = <Element>e.target;
1278
+ e.stopImmediatePropagation();
1279
+ const isTouch: boolean = e.pointerType === 'touch' || e.pointerType === '2' || (e.type.indexOf('touch') > -1);
1280
+ const toolbar: string = target.id.split('_Zooming_ToolBar_')[1].split('_')[0];
1281
+ if (isTouch) {
1282
+ this.handled = true;
1283
+ this.performZoomingByToolBar(toolbar);
1284
+ } else if ((e.type === 'mousedown' || e.type === 'pointerdown') && !this.handled) {
1285
+ this.handled = false;
1286
+ this.performZoomingByToolBar(toolbar);
1287
+ } else {
1288
+ this.handled = false;
1289
+ }
1290
+ }
1291
+
1292
+ /**
1293
+ * @param {string} type - Specifies the type.
1294
+ * @returns {void}
1295
+ * @private
1296
+ */
1297
+ public performZoomingByToolBar(type: string): void {
1298
+ const map: Maps = this.maps;
1299
+ map.isReset = false;
1300
+ switch (type.toLowerCase()) {
1301
+ case 'zoom':
1302
+ this.panColor = this.fillColor;
1303
+ this.zoomColor = this.selectionColor;
1304
+ this.applySelection(this.zoomElements, this.selectionColor);
1305
+ this.applySelection(this.panElements, this.fillColor);
1306
+ break;
1307
+ case 'pan':
1308
+ if (!this.maps.zoomSettings.enablePanning) {
1309
+ this.panColor = '#737373';
1310
+ } else {
1311
+ this.panColor = this.selectionColor;
1312
+ }
1313
+ this.zoomColor = this.fillColor;
1314
+ if (!this.maps.zoomSettings.enablePanning) {
1315
+ this.applySelection(this.zoomElements, this.selectionColor);
1316
+ this.applySelection(this.panElements, this.panColor);
1317
+ } else {
1318
+ this.applySelection(this.zoomElements, this.fillColor);
1319
+ this.applySelection(this.panElements, this.panColor);
1320
+ }
1321
+ break;
1322
+ case 'zoomin':
1323
+ map.staticMapZoom = map.tileZoomLevel;
1324
+ if (map.staticMapZoom > 0 && map.staticMapZoom < 22) {
1325
+ map.staticMapZoom += 1;
1326
+ }
1327
+ this.toolBarZooming((map.isTileMap ? map.tileZoomLevel : map.scale) + 1, 'ZoomIn');
1328
+ break;
1329
+ case 'zoomout':
1330
+ map.staticMapZoom = map.tileZoomLevel;
1331
+ map.markerCenterLatitude = null;
1332
+ map.markerCenterLongitude = null;
1333
+ this.toolBarZooming((map.isTileMap ? map.tileZoomLevel : map.scale) - 1, 'ZoomOut');
1334
+ break;
1335
+ case 'reset':
1336
+ map.staticMapZoom = map.zoomSettings.enable ? map.zoomSettings.zoomFactor : 0;
1337
+ map.markerCenterLatitude = null;
1338
+ map.markerCenterLongitude = null;
1339
+ this.toolBarZooming(1, 'Reset');
1340
+ if (!this.maps.zoomSettings.enablePanning) {
1341
+ this.applySelection(this.zoomElements, this.selectionColor);
1342
+ this.applySelection(this.panElements, '#737373');
1343
+ } else {
1344
+ this.applySelection(this.zoomElements, this.fillColor);
1345
+ this.applySelection(this.panElements, this.selectionColor);
1346
+ }
1347
+ }
1348
+ this.panningStyle(type.toLowerCase());
1349
+ }
1350
+
1351
+ private panningStyle(toolbar: string): void {
1352
+ const svg: Element = getElementByID(this.maps.element.id + '_svg');
1353
+ if (toolbar === 'pan' || this.isPanning) {
1354
+ svg.setAttribute('class', 'e-maps-panning');
1355
+ } else {
1356
+ svg.setAttribute('class', '');
1357
+ }
1358
+ }
1359
+ private applySelection(elements: Element, color: string): void {
1360
+ if (!elements) {
1361
+ return;
1362
+ }
1363
+ let childElement: HTMLElement;
1364
+ for (let i: number = 0; i < elements.childElementCount; i++) {
1365
+ childElement = elements.childNodes[i] as HTMLElement;
1366
+ if (childElement.tagName !== 'circle') {
1367
+ childElement.setAttribute('fill', color);
1368
+ childElement.setAttribute('stroke', color);
1369
+ }
1370
+ }
1371
+ }
1372
+
1373
+ public showTooltip(e: PointerEvent): void {
1374
+ const text: string = (<Element>e.target).id.split('_Zooming_ToolBar_')[1].split('_')[0];
1375
+ if (!this.isTouch) {
1376
+ createTooltip('EJ2_Map_Toolbar_Tip', this.maps.getLocalizedLabel(text), (e.pageY + 10), (e.pageX + 10), '10px');
1377
+ }
1378
+ }
1379
+
1380
+ public removeTooltip(): void {
1381
+ if (getElementByID('EJ2_Map_Toolbar_Tip')) {
1382
+ remove(getElementByID('EJ2_Map_Toolbar_Tip'));
1383
+ }
1384
+ }
1385
+ public alignToolBar(): void {
1386
+ const map: Maps = this.maps;
1387
+ const padding: number = 10;
1388
+ const element: HTMLElement = createElement('div', { id: map.element.id + '_ToolBar', styles: 'position:absolute;z-index:2' });
1389
+ const rectSVGObject: Element = map.renderer.createSvg({
1390
+ id: map.element.id + '_Zooming_ToolBar', width: 10, height: 10
1391
+ });
1392
+ rectSVGObject.appendChild(this.toolBarGroup);
1393
+ element.appendChild(rectSVGObject);
1394
+ if (getElementByID(map.element.id + '_Secondary_Element')) {
1395
+ getElementByID(map.element.id + '_Secondary_Element').appendChild(element);
1396
+ }
1397
+ const toolBarSize: ClientRect = this.toolBarGroup.getBoundingClientRect();
1398
+ rectSVGObject.setAttribute('height', (toolBarSize.height + padding / 2).toString());
1399
+ rectSVGObject.setAttribute('width', (toolBarSize.width + padding / 2).toString());
1400
+ const size: Rect = !isNullOrUndefined(map.totalRect) ? map.totalRect : map.mapAreaRect;
1401
+ let x: number = 0; let y: number = 0;
1402
+ switch (map.zoomSettings.verticalAlignment) {
1403
+ case 'Near':
1404
+ y = size.y;
1405
+ break;
1406
+ case 'Center':
1407
+ y = (size.height / 2) - (toolBarSize.height / 2);
1408
+ break;
1409
+ case 'Far':
1410
+ y = (size.height - toolBarSize.height) - padding;
1411
+ break;
1412
+ }
1413
+ switch (map.zoomSettings.horizontalAlignment) {
1414
+ case 'Near':
1415
+ x = size.x;
1416
+ break;
1417
+ case 'Center':
1418
+ x = (size.width / 2) - (toolBarSize.width / 2);
1419
+ break;
1420
+ case 'Far':
1421
+ if (!isNullOrUndefined(map.legendModule) && map.legendSettings.position === 'Left') {
1422
+ x = size.width + size.x - toolBarSize.width - padding;
1423
+ } else {
1424
+ x = (size.width - toolBarSize.width) - padding;
1425
+ }
1426
+ break;
1427
+ }
1428
+ let extraPosition: Point = map.getExtraPosition();
1429
+ element.style.left = x + extraPosition.x + 'px';
1430
+ element.style.top = y + extraPosition.y + 'px';
1431
+ const color: string = this.maps.zoomSettings.highlightColor || this.maps.themeStyle.zoomSelectionColor;
1432
+ const css: string = ' .e-maps-toolbar:hover > circle { stroke:' + color + '; } .e-maps-toolbar:hover > path { fill: ' + color + ' ; stroke: ' + color + '; }' +
1433
+ '.e-maps-toolbar:hover { cursor: pointer; } .e-maps-cursor-disable:hover { cursor: not-allowed; } .e-maps-panning:hover { cursor: pointer; } ' +
1434
+ '.e-maps-popup-close { display: block; opacity: 0; }';
1435
+ const style: HTMLStyleElement = document.createElement('style');
1436
+ style.appendChild(document.createTextNode(css));
1437
+ element.appendChild(style);
1438
+ }
1439
+
1440
+ /**
1441
+ * To bind events.
1442
+ *
1443
+ * @param {Element} element - Specifies the element.
1444
+ * @param {any} process - Specifies the process.
1445
+ * @returns {void}
1446
+ * @private
1447
+ */
1448
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1449
+ public wireEvents(element: Element, process: any): void {
1450
+ EventHandler.add(element, Browser.touchStartEvent, process, this);
1451
+ EventHandler.add(element, 'mouseover', this.showTooltip, this);
1452
+ EventHandler.add(element, 'mouseout', this.removeTooltip, this);
1453
+ }
1454
+
1455
+ public mapMouseWheel(e: WheelEvent): void {
1456
+ if (this.maps.zoomSettings.enable && this.maps.zoomSettings.mouseWheelZoom) {
1457
+ const map: Maps = this.maps;
1458
+ const size: Size = map.availableSize;
1459
+ map.markerZoomedState = false;
1460
+ map.zoomPersistence = map.enablePersistence;
1461
+ const position: Point = this.getMousePosition(e.pageX, e.pageY);
1462
+ const prevLevel: number = map.tileZoomLevel;
1463
+ const prevScale: number = map.scale;
1464
+ const delta: number = 1;
1465
+ const staticMaxZoomLevel : number = 22; // google map maximum zoom level value
1466
+ const value: number = (map.isTileMap) ? prevLevel : prevScale;
1467
+ if (((position.x > map.mapAreaRect.x) && (position.x < (map.mapAreaRect.x + map.mapAreaRect.width))) &&
1468
+ (position.y > map.mapAreaRect.y) && position.y < (map.mapAreaRect.y + map.mapAreaRect.height)) {
1469
+ e.preventDefault();
1470
+ const direction: string = (this.browserName === 'mozilla' && !this.isPointer) ?
1471
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1472
+ -(e.detail) / 3 > 0 ? 'ZoomIn' : 'ZoomOut' : ((e as any).wheelDelta / 120) > 0 ? 'ZoomIn' : 'ZoomOut';
1473
+ if (direction === 'ZoomIn') {
1474
+ map.mapScaleValue = value + delta;
1475
+ map.staticMapZoom = map.tileZoomLevel;
1476
+ if (map.staticMapZoom > 0 && map.staticMapZoom < staticMaxZoomLevel) {
1477
+ map.staticMapZoom += 1;
1478
+ }
1479
+ this.performZooming(position, (value + delta), direction);
1480
+ } else {
1481
+ map.mapScaleValue = value - delta;
1482
+ map.isReset = (map.mapScaleValue < 1) ? true : false;
1483
+ map.staticMapZoom = map.tileZoomLevel;
1484
+ if (map.mapScaleValue === 1) {
1485
+ map.markerCenterLatitude = null;
1486
+ map.markerCenterLongitude = null;
1487
+ }
1488
+ if (map.staticMapZoom > 1 && map.staticMapZoom < staticMaxZoomLevel) {
1489
+ map.staticMapZoom -= 1;
1490
+ }
1491
+ this.performZooming(position, (value - delta), direction);
1492
+ }
1493
+ }
1494
+ }
1495
+ }
1496
+
1497
+ public doubleClick(e: PointerEvent): void {
1498
+ const pageX: number = e.pageX;
1499
+ const pageY: number = e.pageY;
1500
+ const target: Element = <Element>(<PointerEvent>e).target;
1501
+ if (this.maps.zoomSettings.enable && this.maps.zoomSettings.doubleClickZoom
1502
+ && !(e.target['id'].indexOf('_Zooming_') > -1)) {
1503
+ const position: Point = this.getMousePosition(pageX, pageY);
1504
+ const map: Maps = this.maps;
1505
+ const size: Size = map.availableSize;
1506
+ const prevLevel: number = map.tileZoomLevel;
1507
+ const prevScale: number = map.scale;
1508
+ map.mapScaleValue = map.mapScaleValue + 1;
1509
+ const value: number = (map.isTileMap) ? prevLevel : prevScale;
1510
+ if (((position.x > map.mapAreaRect.x) && (position.x < (map.mapAreaRect.x + map.mapAreaRect.width))) &&
1511
+ (position.y > map.mapAreaRect.y) && position.y < (map.mapAreaRect.y + map.mapAreaRect.height)) {
1512
+ this.performZooming(position, (value + 1), 'ZoomIn');
1513
+ }
1514
+ }
1515
+ }
1516
+
1517
+ public mouseDownHandler(e: PointerEvent | TouchEvent): void {
1518
+ let pageX: number;
1519
+ let pageY: number;
1520
+ let target: Element;
1521
+ let touches: TouchList = null;
1522
+ const element: Element = <Element>e.target;
1523
+ if (e.type === 'touchstart') {
1524
+ this.isTouch = true;
1525
+ touches = (<TouchEvent & PointerEvent>e).touches;
1526
+ target = <Element>(<TouchEvent & PointerEvent>e).target;
1527
+ pageX = touches[0].clientX;
1528
+ pageY = touches[0].clientY;
1529
+ } else {
1530
+ pageX = (<PointerEvent>e).pageX;
1531
+ pageY = (<PointerEvent>e).pageY;
1532
+ target = <Element>e.target;
1533
+ }
1534
+ if (!this.maps.zoomSettings.enablePanning) {
1535
+ this.isPanning = this.panColor !== this.selectionColor ? this.maps.zoomSettings.enablePanning
1536
+ : this.zoomColor === this.selectionColor;
1537
+ } else {
1538
+ this.isPanning = this.panColor === this.selectionColor ? this.maps.zoomSettings.enablePanning
1539
+ : this.zoomColor !== this.selectionColor;
1540
+ }
1541
+ this.mouseDownLatLong = { x: pageX, y: pageY };
1542
+ this.rectZoomingStart = ((!this.isPanning) && this.maps.zoomSettings.enable);
1543
+ this.mouseDownPoints = this.getMousePosition(pageX, pageY);
1544
+ if (this.isTouch) {
1545
+ this.firstMove = true;
1546
+ this.pinchFactor = this.maps.scale;
1547
+ this.fingers = touches.length;
1548
+ }
1549
+ this.isSingleClick = true;
1550
+ }
1551
+
1552
+ public mouseMoveHandler(e: PointerEvent | TouchEvent): void {
1553
+ let pageX: number;
1554
+ let pageY: number;
1555
+ const map: Maps = this.maps;
1556
+ let touchArg: TouchEvent;
1557
+ let target: Element;
1558
+ let touches: TouchList = null;
1559
+ const zoom: ZoomSettings = <ZoomSettings>this.maps.zoomSettings;
1560
+ if (e.type === 'touchmove') {
1561
+ this.isTouch = true;
1562
+ target = <Element>(<TouchEvent & PointerEvent>e).target;
1563
+ touches = (<TouchEvent & PointerEvent>e).touches;
1564
+ pageX = touches[0].clientX;
1565
+ pageY = touches[0].clientY;
1566
+ } else {
1567
+ pageX = (<PointerEvent>e).pageX;
1568
+ pageY = (<PointerEvent>e).pageY;
1569
+ target = <Element>e.target;
1570
+ }
1571
+ if (getElementByID(map.element.id + '_Zooming_KitCollection')) {
1572
+ if (target.id.indexOf('_Zooming_') > -1) {
1573
+ getElementByID(map.element.id + '_Zooming_KitCollection').setAttribute('opacity', '1');
1574
+ if (document.getElementById(map.element.id + '_Zooming_ToolBar_Pan_Group')) {
1575
+ if (!this.maps.zoomSettings.enablePanning) {
1576
+ if (target.id.indexOf('_Zooming_ToolBar') > -1 || target.id.indexOf('_Zooming_Rect') > -1) {
1577
+ getElementByID(map.element.id + '_Zooming_ToolBar_Pan_Rect').setAttribute('opacity', map.theme.toLowerCase() === 'fluentdark' ? '0.6' : '0.3');
1578
+ getElementByID(map.element.id + '_Zooming_ToolBar_Pan').setAttribute('opacity', map.theme.toLowerCase() === 'fluentdark' ? '0.6' : '0.3');
1579
+ }
1580
+ }
1581
+ }
1582
+ }
1583
+ else {
1584
+ getElementByID(map.element.id + '_Zooming_KitCollection').setAttribute('opacity', map.theme.toLowerCase() === 'fluentdark' ? '0.6' : '0.3');
1585
+ if (!this.maps.zoomSettings.enablePanning && document.getElementById(map.element.id + '_Zooming_ToolBar_Pan_Group')) {
1586
+ getElementByID(map.element.id + '_Zooming_ToolBar_Pan_Rect').setAttribute('opacity', '1');
1587
+ getElementByID(map.element.id + '_Zooming_ToolBar_Pan').setAttribute('opacity', '1');
1588
+ }
1589
+ }
1590
+ }
1591
+ if (this.isTouch) {
1592
+ if (this.maps.zoomSettings.pinchZooming) {
1593
+ if (this.firstMove && touches.length === 2) {
1594
+ this.rectZoomingStart = false;
1595
+ this.updateInteraction();
1596
+ this.touchStartList = targetTouches(e);
1597
+ } else if (touches.length === 2 && this.touchStartList.length === 2) {
1598
+ this.touchMoveList = targetTouches(e);
1599
+ e.preventDefault();
1600
+ this.rectZoomingStart = false;
1601
+ this.performPinchZooming(<PointerEvent>e);
1602
+ }
1603
+ this.firstMove = false;
1604
+ }
1605
+ }
1606
+ this.mouseMovePoints = this.getMousePosition(pageX, pageY);
1607
+ const targetId: string = e.target['id'];
1608
+ const targetEle: Element = <Element>e.target;
1609
+ if (zoom.enable && this.isPanning && ((Browser.isDevice && touches.length >= 1) || !Browser.isDevice)) {
1610
+ e.preventDefault();
1611
+ this.maps.element.style.cursor = 'pointer';
1612
+ this.mouseMoveLatLong = { x: pageX, y: pageY };
1613
+ if ((this.mouseDownLatLong['x'] !== this.mouseMoveLatLong['x']) && (this.mouseDownLatLong['y'] !== this.mouseMoveLatLong['y'])) {
1614
+ if (this.maps.zoomSettings.enablePanning) {
1615
+ this.panning('None', null, null, e);
1616
+ }
1617
+ this.mouseDownLatLong['x'] = pageX;
1618
+ this.mouseDownLatLong['y'] = pageY;
1619
+ }
1620
+ }
1621
+ if (this.isTouch ? (touches.length === 1 && this.rectZoomingStart) : this.rectZoomingStart) {
1622
+ e.preventDefault();
1623
+ if (this.maps.zoomSettings.enableSelectionZooming) {
1624
+ this.drawZoomRectangle();
1625
+ }
1626
+ }
1627
+ }
1628
+
1629
+ public mouseUpHandler(e: PointerEvent | TouchEvent): void {
1630
+ let isDragZoom: boolean;
1631
+ const map: Maps = this.maps;
1632
+ this.rectZoomingStart = false;
1633
+ this.isPanning = false;
1634
+ this.isSingleClick = this.isSingleClick ? true : false;
1635
+ this.isTouch = false;
1636
+ this.touchStartList = [];
1637
+ this.touchMoveList = [];
1638
+ this.lastScale = 1;
1639
+ this.maps.element.style.cursor = 'auto';
1640
+ if ((!isNullOrUndefined(this.distanceX) || !isNullOrUndefined(this.distanceY)) && (!isNullOrUndefined(this.currentLayer) && this.currentLayer.type === 'SubLayer')) {
1641
+ this.toAlignSublayer();
1642
+ this.distanceX = this.distanceY = null;
1643
+ }
1644
+ const zoomRectElement: HTMLElement = <HTMLElement>getElementByID(this.maps.element.id + '_Selection_Rect_Zooming');
1645
+ if (zoomRectElement && this.maps.zoomSettings.enable && this.maps.zoomSettings.enableSelectionZooming) {
1646
+ isDragZoom = true;
1647
+ remove(zoomRectElement);
1648
+ this.performRectZooming();
1649
+ }
1650
+ this.mouseMoveLatLong = { x: 0, y: 0 };
1651
+ this.mouseDownLatLong = { x: 0, y: 0 };
1652
+ }
1653
+
1654
+ public mouseCancelHandler(e: PointerEvent): void {
1655
+ this.isPanning = false;
1656
+ this.isTouch = false;
1657
+ this.rectZoomingStart = false;
1658
+ const zoomRectElement: HTMLElement = <HTMLElement>getElementByID(this.maps.element.id + '_Selection_Rect_Zooming');
1659
+ if (zoomRectElement && this.maps.zoomSettings.enable) {
1660
+ remove(zoomRectElement);
1661
+ this.performRectZooming();
1662
+ }
1663
+ }
1664
+ /**
1665
+ * To handle the click event for maps.
1666
+ *
1667
+ * @param {PointerEvent} e - Specifies the pointer event.
1668
+ * @returns {void}
1669
+ */
1670
+ public click(e: PointerEvent): void {
1671
+ const map: Maps = this.maps;
1672
+ if ((map.markerModule && map.markerModule.sameMarkerData.length > 0) ||
1673
+ (e.target['id'].indexOf('MarkerIndex') > -1 && e.target['id'].indexOf('cluster') === -1)) {
1674
+ return null;
1675
+ }
1676
+ if (this.isSingleClick && map.zoomSettings.zoomOnClick && !(e.target['id'].indexOf('_Zooming_') > -1) && !map.zoomSettings.doubleClickZoom
1677
+ && (this.zoomColor !== this.selectionColor)) {
1678
+ const pageX: number = e.pageX;
1679
+ const pageY: number = e.pageY;
1680
+ const position: Point = this.getMousePosition(pageX, pageY);
1681
+ const prevLevel: number = map.tileZoomLevel;
1682
+ const prevScale: number = map.scale;
1683
+ map.mapScaleValue = map.mapScaleValue + 1;
1684
+ const value: number = (map.isTileMap) ? prevLevel : prevScale;
1685
+ if (((position.x > map.mapAreaRect.x) && (position.x < (map.mapAreaRect.x + map.mapAreaRect.width))) &&
1686
+ (position.y > map.mapAreaRect.y) && position.y < (map.mapAreaRect.y + map.mapAreaRect.height)) {
1687
+ this.performZooming(position, (value + 1), 'ZoomIn');
1688
+ }
1689
+ }
1690
+ }
1691
+
1692
+ public getMousePosition(pageX: number, pageY: number): Point {
1693
+ const map: Maps = this.maps;
1694
+ const elementRect: ClientRect = map.element.getBoundingClientRect();
1695
+ const pageXOffset: number = map.element.ownerDocument.defaultView.pageXOffset;
1696
+ const pageYOffset: number = map.element.ownerDocument.defaultView.pageYOffset;
1697
+ const clientTop: number = map.element.ownerDocument.documentElement.clientTop;
1698
+ const clientLeft: number = map.element.ownerDocument.documentElement.clientLeft;
1699
+ const positionX: number = elementRect.left + pageXOffset - clientLeft;
1700
+ const positionY: number = elementRect.top + pageYOffset - clientTop;
1701
+ return new Point(Math.abs(pageX - positionX), Math.abs(pageY - positionY));
1702
+ }
1703
+
1704
+ public addEventListener(): void {
1705
+ if (this.maps.isDestroyed) {
1706
+ return;
1707
+ }
1708
+ EventHandler.add(this.maps.element, this.wheelEvent, this.mapMouseWheel, this);
1709
+ EventHandler.add(this.maps.element, 'click', this.click, this);
1710
+ EventHandler.add(this.maps.element, 'dblclick', this.doubleClick, this);
1711
+ this.maps.on(Browser.touchMoveEvent, this.mouseMoveHandler, this);
1712
+ this.maps.on(Browser.touchStartEvent, this.mouseDownHandler, this);
1713
+ this.maps.on(Browser.touchEndEvent, this.mouseUpHandler, this);
1714
+ EventHandler.add(this.maps.element, this.cancelEvent, this.mouseCancelHandler, this);
1715
+ }
1716
+
1717
+ public removeEventListener(): void {
1718
+ if (this.maps.isDestroyed) {
1719
+ return;
1720
+ }
1721
+ EventHandler.remove(this.maps.element, this.wheelEvent, this.mapMouseWheel);
1722
+ EventHandler.remove(this.maps.element, 'click', this.click);
1723
+ EventHandler.remove(this.maps.element, 'dblclick', this.doubleClick);
1724
+ this.maps.off(Browser.touchMoveEvent, this.mouseMoveHandler);
1725
+ this.maps.off(Browser.touchStartEvent, this.mouseDownHandler);
1726
+ this.maps.off(Browser.touchEndEvent, this.mouseUpHandler);
1727
+ this.maps.off(this.cancelEvent, this.mouseCancelHandler);
1728
+ }
1729
+
1730
+ /**
1731
+ * Get module name.
1732
+ *
1733
+ * @returns {string} - Returns the module name.
1734
+ */
1735
+ protected getModuleName(): string {
1736
+ return 'Zoom';
1737
+ }
1738
+
1739
+ /**
1740
+ * To destroy the zoom.
1741
+ *
1742
+ * @returns {void}
1743
+ * @private
1744
+ */
1745
+ public destroy(): void {
1746
+ this.toolBarGroup = null;
1747
+ this.currentToolbarEle = null;
1748
+ this.zoomingRect = null;
1749
+ this.zoomElements = null;
1750
+ this.panElements = null;
1751
+ this.baseTranslatePoint = null;
1752
+ this.touchStartList = null;
1753
+ this.touchMoveList = null;
1754
+ this.previousTouchMoveList = null;
1755
+ this.mouseDownPoints = null;
1756
+ this.mouseMovePoints = null;
1757
+ this.startTouches = [];
1758
+ this.zoomshapewidth = null;
1759
+ this.intersect = [];
1760
+ this.mouseDownLatLong = null;
1761
+ this.mouseMoveLatLong = null;
1762
+ this.removeEventListener();
1763
+ //TODO: Calling the below code throws spec issue.
1764
+ //this.maps = null;
1765
+ this.currentLayer = null;
1766
+ }
1767
+ }