@syncfusion/ej2-maps 33.1.44 → 34.1.29

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 (67) hide show
  1. package/.gitleaksignore +8 -8
  2. package/dist/ej2-maps.min.js +2 -2
  3. package/dist/ej2-maps.umd.min.js +2 -2
  4. package/dist/ej2-maps.umd.min.js.map +1 -1
  5. package/dist/es6/ej2-maps.es2015.js +1 -1
  6. package/dist/es6/ej2-maps.es2015.js.map +1 -1
  7. package/dist/es6/ej2-maps.es5.js +1 -1
  8. package/dist/es6/ej2-maps.es5.js.map +1 -1
  9. package/dist/global/ej2-maps.min.js +2 -2
  10. package/dist/global/ej2-maps.min.js.map +1 -1
  11. package/dist/global/index.d.ts +1 -1
  12. package/dist/ts/index.d.ts +4 -0
  13. package/dist/ts/index.ts +4 -0
  14. package/dist/ts/maps/index.d.ts +28 -0
  15. package/dist/ts/maps/index.ts +28 -0
  16. package/dist/ts/maps/layers/bing-map.d.ts +21 -0
  17. package/dist/ts/maps/layers/bing-map.ts +51 -0
  18. package/dist/ts/maps/layers/bubble.d.ts +77 -0
  19. package/dist/ts/maps/layers/bubble.ts +304 -0
  20. package/dist/ts/maps/layers/color-mapping.d.ts +36 -0
  21. package/dist/ts/maps/layers/color-mapping.ts +230 -0
  22. package/dist/ts/maps/layers/data-label.d.ts +45 -0
  23. package/dist/ts/maps/layers/data-label.ts +457 -0
  24. package/dist/ts/maps/layers/layer-panel.d.ts +144 -0
  25. package/dist/ts/maps/layers/layer-panel.ts +1495 -0
  26. package/dist/ts/maps/layers/legend.d.ts +173 -0
  27. package/dist/ts/maps/layers/legend.ts +2473 -0
  28. package/dist/ts/maps/layers/marker.d.ts +105 -0
  29. package/dist/ts/maps/layers/marker.ts +632 -0
  30. package/dist/ts/maps/layers/navigation-selected-line.d.ts +33 -0
  31. package/dist/ts/maps/layers/navigation-selected-line.ts +171 -0
  32. package/dist/ts/maps/layers/polygon.d.ts +30 -0
  33. package/dist/ts/maps/layers/polygon.ts +68 -0
  34. package/dist/ts/maps/maps-model.d.ts +409 -0
  35. package/dist/ts/maps/maps.d.ts +1247 -0
  36. package/dist/ts/maps/maps.ts +3416 -0
  37. package/dist/ts/maps/model/base-model.d.ts +2107 -0
  38. package/dist/ts/maps/model/base.d.ts +1840 -0
  39. package/dist/ts/maps/model/base.ts +2257 -0
  40. package/dist/ts/maps/model/constants.d.ts +225 -0
  41. package/dist/ts/maps/model/constants.ts +226 -0
  42. package/dist/ts/maps/model/export-image.d.ts +39 -0
  43. package/dist/ts/maps/model/export-image.ts +194 -0
  44. package/dist/ts/maps/model/export-pdf.d.ts +40 -0
  45. package/dist/ts/maps/model/export-pdf.ts +183 -0
  46. package/dist/ts/maps/model/interface.d.ts +892 -0
  47. package/dist/ts/maps/model/interface.ts +929 -0
  48. package/dist/ts/maps/model/print.d.ts +45 -0
  49. package/dist/ts/maps/model/print.ts +125 -0
  50. package/dist/ts/maps/model/theme.d.ts +98 -0
  51. package/dist/ts/maps/model/theme.ts +919 -0
  52. package/dist/ts/maps/user-interaction/annotation.d.ts +27 -0
  53. package/dist/ts/maps/user-interaction/annotation.ts +133 -0
  54. package/dist/ts/maps/user-interaction/highlight.d.ts +63 -0
  55. package/dist/ts/maps/user-interaction/highlight.ts +272 -0
  56. package/dist/ts/maps/user-interaction/selection.d.ts +85 -0
  57. package/dist/ts/maps/user-interaction/selection.ts +342 -0
  58. package/dist/ts/maps/user-interaction/tooltip.d.ts +78 -0
  59. package/dist/ts/maps/user-interaction/tooltip.ts +500 -0
  60. package/dist/ts/maps/user-interaction/zoom.d.ts +334 -0
  61. package/dist/ts/maps/user-interaction/zoom.ts +2523 -0
  62. package/dist/ts/maps/utils/enum.d.ts +328 -0
  63. package/dist/ts/maps/utils/enum.ts +343 -0
  64. package/dist/ts/maps/utils/helper.d.ts +1318 -0
  65. package/dist/ts/maps/utils/helper.ts +3811 -0
  66. package/package.json +8 -8
  67. package/src/maps/layers/layer-panel.js +1 -1
@@ -0,0 +1,1495 @@
1
+ /* eslint-disable no-case-declarations */
2
+ import { isNullOrUndefined, extend, createElement, Fetch, animationMode } from '@syncfusion/ej2-base';
3
+ import { Maps } from '../../maps/maps';
4
+ import { getShapeColor } from '../model/theme';
5
+ import { GeoLocation, isCustomPath, convertGeoToPoint, Point, PathOption, Size, removeElement, maintainToggleSelection } from '../utils/helper';
6
+ import { getElementByID, maintainSelection, getValueFromObject } from '../utils/helper';
7
+ import { MapLocation, RectOption, getTranslate, convertTileLatLongToPoint, checkShapeDataFields, CircleOption } from '../utils/helper';
8
+ import { getZoomTranslate, fixInitialScaleForTile } from '../utils/helper';
9
+ import { LayerSettings, ShapeSettings, Tile} from '../model/base';
10
+ import { BorderModel, LayerSettingsModel } from '../model/base-model';
11
+ import { BingMap } from './bing-map';
12
+ import { ColorMapping } from './color-mapping';
13
+ import { layerRendering, ILayerRenderingEventArgs, shapeRendering, IShapeRenderingEventArgs, BubbleSettingsModel, Rect } from '../index';
14
+ /**
15
+ * To calculate and render the shape layer
16
+ */
17
+
18
+ export class LayerPanel {
19
+ private mapObject: Maps;
20
+ public currentFactor: number;
21
+ private groupElements: Element[];
22
+ private layerObject: Element;
23
+ private currentLayer: LayerSettings;
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ private rectBounds: any;
26
+ public tiles: Tile[];
27
+ private clipRectElement: Element;
28
+ private urlTemplate: string;
29
+ private isMapCoordinates: boolean = true;
30
+ private tileSvgObject: Element;
31
+ private ajaxModule: Fetch;
32
+ private ajaxResponse: LayerSettings[];
33
+ private bing: BingMap;
34
+ private animateToZoomX : number;
35
+ private animateToZoomY : number;
36
+ public horizontalPan: boolean = false;
37
+ public horizontalPanXCount: number = 0;
38
+ public layerGroup: Element;
39
+ constructor(map: Maps) {
40
+ this.mapObject = map;
41
+ this.ajaxModule = new Fetch();
42
+ this.ajaxResponse = [];
43
+ }
44
+
45
+ public measureLayerPanel(): void {
46
+ const layerCollection: LayerSettings[] = <LayerSettings[]>this.mapObject.layersCollection;
47
+ const areaRect: Rect = this.mapObject.mapAreaRect;
48
+ const secondaryEle: HTMLElement = <HTMLElement>getElementByID(this.mapObject.element.id + '_Secondary_Element');
49
+ if (this.mapObject.isTileMap && secondaryEle) {
50
+ this.tileSvgObject = this.mapObject.renderer.createSvg({
51
+ id: this.mapObject.element.id + '_Tile_SVG', width: areaRect.width,
52
+ height: areaRect.height
53
+ });
54
+ const parentElement: Element = createElement('div', {
55
+ id: this.mapObject.element.id + '_Tile_SVG_Parent'
56
+ });
57
+ (parentElement as HTMLElement).style.cssText = 'position: absolute; height: ' + (areaRect.height) + 'px; width: ' +
58
+ (areaRect.width) + 'px;';
59
+ parentElement.appendChild(this.tileSvgObject);
60
+ secondaryEle.appendChild(parentElement);
61
+ }
62
+ this.layerGroup = (this.mapObject.renderer.createGroup({
63
+ id: this.mapObject.element.id + '_Layer_Collections',
64
+ 'clip-path': 'url(#' + this.mapObject.element.id + '_MapArea_ClipRect)'
65
+ }));
66
+ this.clipRectElement = this.mapObject.renderer.drawClipPath(new RectOption(
67
+ this.mapObject.element.id + '_MapArea_ClipRect',
68
+ 'transparent', { width: 1, color: 'Gray' }, 1,
69
+ {
70
+ x: this.mapObject.isTileMap ? 0 : areaRect.x, y: this.mapObject.isTileMap ? 0 : areaRect.y,
71
+ width: areaRect.width, height: areaRect.height
72
+ }));
73
+
74
+ this.layerGroup.appendChild(this.clipRectElement);
75
+ this.mapObject.baseMapBounds = null;
76
+ this.mapObject.baseMapRectBounds = null;
77
+ this.mapObject.baseSize = null;
78
+ Array.prototype.forEach.call(layerCollection, (layer: LayerSettings, index: number) => {
79
+ this.currentLayer = <LayerSettings>layer;
80
+ this.processLayers(layer, index);
81
+ });
82
+ if (!isNullOrUndefined(this.mapObject.legendModule) && this.mapObject.legendSettings.position === 'Float') {
83
+ if (this.mapObject.isTileMap) {
84
+ this.layerGroup.appendChild(this.mapObject.legendModule.legendGroup);
85
+ } else {
86
+ this.mapObject.svgObject.appendChild(this.mapObject.legendModule.legendGroup);
87
+ }
88
+ }
89
+ }
90
+ /**
91
+ * Tile rendering
92
+ *
93
+ * @param {LayerPanel} panel - Specifies the layer panel.
94
+ * @param {LayerSettings} layer - Specifies the layer settings.
95
+ * @param {number} layerIndex - Specifies the layer index.
96
+ * @param {BingMap} bing - Specifies the bing map.
97
+ * @returns {void}
98
+ * @private
99
+ */
100
+ public renderTileLayer(panel: LayerPanel, layer: LayerSettings, layerIndex: number, bing?: BingMap): void {
101
+ panel.currentFactor = panel.calculateFactor(layer);
102
+ panel.mapObject.defaultState = ((panel.mapObject.zoomSettings.zoomFactor !== 1) &&
103
+ (!isNullOrUndefined(panel.mapObject.tileZoomLevel) && panel.mapObject.tileZoomLevel !== 1 )) ?
104
+ false : true;
105
+ if (isNullOrUndefined(panel.mapObject.previousCenterLatitude) &&
106
+ isNullOrUndefined(panel.mapObject.previousCenterLongitude) && !panel.mapObject.isZoomByPosition) {
107
+ panel.mapObject.previousCenterLatitude = panel.mapObject.centerPosition.latitude;
108
+ panel.mapObject.previousCenterLongitude = panel.mapObject.centerPosition.longitude;
109
+ } else if ((panel.mapObject.previousCenterLatitude !==
110
+ panel.mapObject.centerPosition.latitude && panel.mapObject.previousCenterLongitude !==
111
+ panel.mapObject.centerPosition.longitude) || panel.mapObject.isZoomByPosition) {
112
+ panel.mapObject.centerPositionChanged = true;
113
+ panel.mapObject.previousCenterLatitude = panel.mapObject.centerPosition.latitude;
114
+ panel.mapObject.previousCenterLongitude = panel.mapObject.centerPosition.longitude;
115
+ } else {
116
+ panel.mapObject.centerPositionChanged = false;
117
+ }
118
+ let center: Point = new Point(panel.mapObject.centerPosition.longitude, panel.mapObject.centerPosition.latitude);
119
+ let centerTileMap : Point = center;
120
+ if ((this.mapObject.isTileMap && panel.mapObject.markerModule) && panel.mapObject.zoomSettings.enable) {
121
+ panel.mapObject.markerModule.calculateZoomCenterPositionAndFactor(this.mapObject.layersCollection);
122
+ if (!isNullOrUndefined(this.mapObject.markerCenterLatitude) && !isNullOrUndefined(this.mapObject.markerCenterLongitude)
123
+ && !panel.mapObject.isZoomByPosition) {
124
+ centerTileMap = new Point(panel.mapObject.markerCenterLongitude, panel.mapObject.markerCenterLatitude);
125
+ }
126
+ }
127
+ if (!panel.mapObject.zoomSettings.shouldZoomInitially && panel.mapObject.centerPosition.longitude
128
+ && panel.mapObject.centerPosition.latitude && !panel.mapObject.zoomPersistence && panel.mapObject.defaultState) {
129
+ center = new Point(panel.mapObject.centerPosition.longitude, panel.mapObject.centerPosition.latitude);
130
+ } else if (panel.mapObject.zoomSettings.shouldZoomInitially
131
+ && panel.mapObject.markerZoomedState && !panel.mapObject.zoomPersistence
132
+ && !isNullOrUndefined(panel.mapObject.markerZoomCenterPoint)) {
133
+ center = new Point(panel.mapObject.markerZoomCenterPoint.longitude, panel.mapObject.markerZoomCenterPoint.latitude);
134
+ } else {
135
+ center = { x: null, y: null };
136
+ }
137
+ let zoomFactorValue: number = (panel.mapObject.zoomSettings.shouldZoomInitially && !panel.mapObject.isZoomByPosition) ?
138
+ isNullOrUndefined(panel.mapObject.markerZoomFactor) ? 1 :
139
+ panel.mapObject.markerZoomFactor : panel.mapObject.zoomSettings.zoomFactor;
140
+ zoomFactorValue = (panel.mapObject.enablePersistence) ? ((isNullOrUndefined(panel.mapObject.mapScaleValue))
141
+ ? (isNullOrUndefined(panel.mapObject.markerZoomFactor) ? panel.mapObject.zoomSettings.zoomFactor :
142
+ panel.mapObject.markerZoomFactor) : panel.mapObject.mapScaleValue) : zoomFactorValue;
143
+ zoomFactorValue = panel.mapObject.zoomSettings.enable ? zoomFactorValue : panel.mapObject.zoomSettings.zoomFactor;
144
+ zoomFactorValue = zoomFactorValue > 0 ? zoomFactorValue : 1;
145
+ panel.mapObject.defaultState = zoomFactorValue !== 1 ? false : true;
146
+ if (!panel.mapObject.markerZoomedState && panel.mapObject.zoomSettings.shouldZoomInitially &&
147
+ panel.mapObject.zoomSettings.zoomFactor === 1) {
148
+ panel.mapObject.defaultState = true;
149
+ }
150
+ if (isNullOrUndefined(panel.mapObject.tileZoomLevel)) {
151
+ panel.mapObject.tileZoomLevel = zoomFactorValue;
152
+ panel.mapObject.previousZoomFactor = zoomFactorValue;
153
+ } else if (this.mapObject.isReset && panel.mapObject.tileZoomLevel === 1 && !panel.mapObject.zoomSettings.shouldZoomInitially) {
154
+ const zoomLevel: number = panel.mapObject.tileZoomLevel;
155
+ panel.mapObject.tileZoomLevel = zoomLevel;
156
+ } else if (panel.mapObject.zoomSettings.zoomFactor !== 1 || panel.mapObject.zoomSettings.shouldZoomInitially) {
157
+ panel.mapObject.previousZoomFactor = panel.mapObject.tileZoomLevel;
158
+ panel.mapObject.tileZoomLevel = panel.mapObject.defaultState && panel.mapObject.zoomSettings.enable ?
159
+ panel.mapObject.tileZoomLevel : !panel.mapObject.zoomSettings.shouldZoomInitially
160
+ && !panel.mapObject.centerPositionChanged ?
161
+ panel.mapObject.previousZoomFactor !== panel.mapObject.zoomSettings.zoomFactor ?
162
+ panel.mapObject.zoomSettings.zoomFactor : panel.mapObject.tileZoomLevel : zoomFactorValue;
163
+ panel.mapObject.tileZoomLevel = zoomFactorValue === 1 && panel.mapObject.zoomSettings.zoomFactor === 0 ?
164
+ zoomFactorValue : panel.mapObject.tileZoomLevel;
165
+ if (!isNullOrUndefined(panel.mapObject.tileTranslatePoint) &&
166
+ (panel.mapObject.markerZoomFactor !== panel.mapObject.mapScaleValue
167
+ || (isNullOrUndefined(panel.mapObject.markerZoomFactor)
168
+ && isNullOrUndefined(panel.mapObject.mapScaleValue)))
169
+ && (panel.mapObject.zoomSettings.zoomFactor <= 1 || panel.mapObject.previousZoomFactor !==
170
+ panel.mapObject.zoomSettings.zoomFactor)) {
171
+ panel.mapObject.tileTranslatePoint.x = 0;
172
+ panel.mapObject.tileTranslatePoint.y = 0;
173
+ }
174
+ } else if (panel.mapObject.defaultState) {
175
+ panel.mapObject.previousZoomFactor = panel.mapObject.tileZoomLevel;
176
+ panel.mapObject.tileZoomLevel = zoomFactorValue;
177
+ if (!isNullOrUndefined(panel.mapObject.tileTranslatePoint)) {
178
+ panel.mapObject.tileTranslatePoint.x = 0;
179
+ panel.mapObject.tileTranslatePoint.y = 0;
180
+ }
181
+ }
182
+ if ( zoomFactorValue <= 1 && !isNullOrUndefined(panel.mapObject.height) && !panel.mapObject.zoomSettings.shouldZoomInitially
183
+ && (panel.mapObject.tileZoomLevel === panel.mapObject.tileZoomScale) && this.mapObject.initialCheck ) {
184
+ fixInitialScaleForTile(this.mapObject);
185
+ }
186
+ if (!isNullOrUndefined(panel.mapObject.centerLatOfGivenLocation) && !isNullOrUndefined(panel.mapObject.centerLongOfGivenLocation) &&
187
+ panel.mapObject.zoomNotApplied) {
188
+ if (!isNullOrUndefined(centerTileMap)) {
189
+ centerTileMap.y = panel.mapObject.centerLatOfGivenLocation;
190
+ centerTileMap.x = panel.mapObject.centerLongOfGivenLocation;
191
+ }
192
+ panel.mapObject.tileZoomLevel = panel.mapObject.mapScaleValue = panel.mapObject.scaleOfGivenLocation;
193
+ }
194
+ panel.mapObject.tileTranslatePoint = panel.panTileMap(
195
+ panel.mapObject.availableSize.width, panel.mapObject.availableSize.height, centerTileMap
196
+ );
197
+ if (this.mapObject.zoomSettings.resetToInitial && this.mapObject.initialCheck && !isNullOrUndefined(panel.mapObject.height)
198
+ && this.mapObject.availableSize.height > 512) {
199
+ this.mapObject.applyZoomReset = true;
200
+ this.mapObject.initialZoomLevel = Math.floor(this.mapObject.availableSize.height / 512);
201
+ const padding : number = 20;
202
+ const totalSize : number = Math.pow(2, this.mapObject.initialZoomLevel) * 256;
203
+ if (!isNullOrUndefined(this.mapObject.initialTileTranslate)) {
204
+ this.mapObject.initialTileTranslate.x = (this.mapObject.availableSize.width / 2) - (totalSize / 2);
205
+ this.mapObject.initialTileTranslate.y = (this.mapObject.availableSize.height / 2) - (totalSize / 2) + padding;
206
+ }
207
+ }
208
+ panel.generateTiles(panel.mapObject.tileZoomLevel, panel.mapObject.tileTranslatePoint, null, bing);
209
+ if (!isNullOrUndefined(panel.mapObject.previousZoomFactor)
210
+ && panel.mapObject.previousZoomFactor !== panel.mapObject.zoomSettings.zoomFactor) {
211
+ panel.mapObject.previousZoomFactor = panel.mapObject.zoomSettings.zoomFactor;
212
+ }
213
+ if (panel.mapObject.polygonModule) {
214
+ const polygonElement: Element =
215
+ panel.mapObject.polygonModule.polygonRender(this.mapObject, layerIndex, panel.mapObject.tileZoomLevel);
216
+ if (!isNullOrUndefined(polygonElement)) {
217
+ panel.layerObject.appendChild(polygonElement);
218
+ }
219
+ }
220
+ if (panel.mapObject.navigationLineModule) {
221
+ const navigationLineElement: Element =
222
+ panel.mapObject.navigationLineModule.renderNavigation(panel.currentLayer, panel.mapObject.tileZoomLevel, layerIndex);
223
+ if (!isNullOrUndefined(navigationLineElement)) {
224
+ panel.layerObject.appendChild(navigationLineElement);
225
+ }
226
+ }
227
+ if (panel.mapObject.markerModule) {
228
+ panel.mapObject.markerModule.markerRender(this.mapObject, panel.layerObject, layerIndex, panel.mapObject.tileZoomLevel, null);
229
+ }
230
+ panel.translateLayerElements(panel.layerObject);
231
+ panel.layerGroup.appendChild(panel.layerObject);
232
+ }
233
+
234
+
235
+ protected processLayers(layer: LayerSettings, layerIndex: number): void {
236
+ this.layerObject = (this.mapObject.renderer.createGroup({
237
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex
238
+ }));
239
+ if (!this.mapObject.enablePersistence) {
240
+ const itemName: string = this.mapObject.getModuleName() + this.mapObject.element.id;
241
+ if (navigator.userAgent.indexOf('Edge') === -1) {
242
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
243
+ let data: any;
244
+ try {
245
+ data = window.localStorage;
246
+ } catch (e) {
247
+ data = null;
248
+ }
249
+ if (!isNullOrUndefined(data) && window.localStorage.getItem(itemName)) {
250
+ window.localStorage.removeItem(itemName);
251
+ }
252
+ }
253
+ }
254
+ const eventArgs: ILayerRenderingEventArgs = {
255
+ cancel: false, name: layerRendering, index: layerIndex,
256
+ layer: layer, maps: this.mapObject, visible: layer.visible
257
+ };
258
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
259
+ this.mapObject.trigger('layerRendering', eventArgs, (observedArgs: ILayerRenderingEventArgs) => {
260
+ if (!eventArgs.cancel && eventArgs.visible) {
261
+ if ((isNullOrUndefined(layer.shapeData) && !isNullOrUndefined(layer.urlTemplate) && layer.urlTemplate !== '')) {
262
+ if (!isNullOrUndefined(layer.urlTemplate) && layer.urlTemplate.indexOf('quadkey') > -1) {
263
+ const bing: BingMap = new BingMap(this.mapObject);
264
+ this.bingMapCalculation(layer, layerIndex, this, bing);
265
+ } else {
266
+ this.renderTileLayer(this, layer, layerIndex);
267
+ }
268
+ } else {
269
+ if (!isNullOrUndefined(layer.shapeData) && (!isNullOrUndefined(layer.shapeData['geometries']) ||
270
+ !isNullOrUndefined(layer.shapeData['features']))) {
271
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
272
+ const featureData: any[] = (!isNullOrUndefined(layer.shapeData['geometries']) &&
273
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
+ (<any[]>layer.shapeData['geometries']).length > 0 ? layer.shapeData['geometries'] :
275
+ layer.shapeData['features']);
276
+ layer.layerData = [];
277
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
278
+ const bbox: any = layer.shapeData['bbox'];
279
+ if (!isNullOrUndefined(bbox) && layer.isBaseLayer) {
280
+ this.mapObject.baseMapBounds = new GeoLocation(
281
+ { min: bbox[0][1], max: bbox[1][1] },
282
+ { min: bbox[0][0], max: bbox[1][0] }
283
+ );
284
+ } else if (isNullOrUndefined(this.mapObject.baseMapBounds) && !isCustomPath(featureData)) {
285
+ this.calculateRectBounds(featureData);
286
+ }
287
+ this.calculatePathCollection(layerIndex, featureData);
288
+ }
289
+ }
290
+ }
291
+ });
292
+ if (!this.mapObject.isTileMap) {
293
+ this.mapObject.svgObject.appendChild(this.layerGroup);
294
+ } else if (this.tileSvgObject) {
295
+ this.tileSvgObject.appendChild(this.layerGroup);
296
+ this.mapObject.baseMapBounds = null;
297
+ }
298
+ }
299
+
300
+ private bingMapCalculation(layer: LayerSettings, layerIndex: number, proxy: LayerPanel, bing: BingMap): void {
301
+ bing.imageUrl = layer.urlTemplate;
302
+ bing.subDomains = ['t0', 't1', 't2', 't3'];
303
+ bing.maxZoom = '21';
304
+ proxy.mapObject.bingMap = bing;
305
+ proxy.renderTileLayer(proxy, layer, layerIndex, bing);
306
+ this.mapObject.arrangeTemplate();
307
+ if (this.mapObject.zoomModule && (this.mapObject.previousScale !== this.mapObject.scale)) {
308
+ this.mapObject.zoomModule.applyTransform(this.mapObject, false, true);
309
+ }
310
+ }
311
+
312
+ private bubbleCalculation(bubbleSettings: BubbleSettingsModel, range: { min: number, max: number }): void {
313
+ if (bubbleSettings.dataSource != null && bubbleSettings != null) {
314
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
315
+ const bubbleDataSource: any[] = bubbleSettings.dataSource as any[];
316
+ for (let i: number = 0; i < bubbleDataSource.length; i++) {
317
+ const bubbledata: number = (!isNullOrUndefined(bubbleSettings.valuePath)) ? ((bubbleSettings.valuePath.indexOf('.') > -1) ?
318
+ Number(getValueFromObject(bubbleSettings.dataSource[i as number], bubbleSettings.valuePath)) :
319
+ parseFloat(bubbleSettings.dataSource[i as number][bubbleSettings.valuePath])) :
320
+ parseFloat(bubbleSettings.dataSource[i as number][bubbleSettings.valuePath]);
321
+ if (!isNaN(bubbledata)) {
322
+ if (i !== 0) {
323
+ if (bubbledata > range.max) {
324
+ range.max = bubbledata;
325
+ } else if (bubbledata < range.min) {
326
+ range.min = bubbledata;
327
+ }
328
+ } else {
329
+ range.max = range.min = bubbledata;
330
+ }
331
+ }
332
+ }
333
+ }
334
+ }
335
+
336
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
337
+ public calculatePathCollection(layerIndex: number, renderData: any[]): void {
338
+ this.groupElements = [];
339
+ if ((!isCustomPath(renderData))) {
340
+ this.currentFactor = this.calculateFactor(this.currentLayer);
341
+ }
342
+ this.rectBounds = null;
343
+ const shapeSettings: ShapeSettings = <ShapeSettings>this.currentLayer.shapeSettings;
344
+ for (let r: number = 0; r < renderData.length; r++) {
345
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
346
+ const geometryData: any = renderData[r as number];
347
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
348
+ const geom: any = geometryData['geometry'];
349
+ const hasGeom: boolean = !isNullOrUndefined(geom);
350
+ const hasCoords: boolean = !isNullOrUndefined(geometryData['coordinates']);
351
+ if (hasGeom || hasCoords) {
352
+ const type: string = hasGeom ? geom['type'] : geometryData['type'];
353
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
354
+ const coords: any[] = hasGeom ? geom['coordinates'] : geometryData['coordinates'];
355
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
356
+ const data: any = geom;
357
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
358
+ const properties: any = geometryData['properties'];
359
+ this.generatePoints(type, coords, data, properties);
360
+ }
361
+ }
362
+ this.currentLayer.rectBounds = this.rectBounds;
363
+ if (isNullOrUndefined(this.mapObject.baseMapRectBounds) && this.currentLayer.isBaseLayer) {
364
+ this.mapObject.baseMapRectBounds = this.rectBounds;
365
+ }
366
+ const colors: string[] = (!isNullOrUndefined(shapeSettings.palette) && shapeSettings.palette.length > 1) ?
367
+ shapeSettings.palette : getShapeColor(this.mapObject.theme);
368
+ const areaRect: Rect = this.mapObject.mapAreaRect;
369
+ const labelTemplateEle: HTMLElement = createElement('div', {
370
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_Label_Template_Group',
371
+ className: this.mapObject.element.id + '_template'
372
+ });
373
+ labelTemplateEle.style.cssText = 'pointer-events: none; overflow: hidden; position: absolute;' +
374
+ 'top:' + areaRect.y + 'px;' +
375
+ 'left:' + areaRect.x + 'px;' +
376
+ 'height:' + areaRect.height + 'px;' +
377
+ 'width:' + areaRect.width + 'px;';
378
+ if (this.currentLayer.layerData.length !== 0) {
379
+ for (let i: number = 0; i < this.currentLayer.layerData.length; i++) {
380
+ let k: number;
381
+ const borderValue: BorderModel = {
382
+ color: shapeSettings.border.color || this.mapObject.themeStyle.shapeBorderColor,
383
+ width: shapeSettings.border.width,
384
+ opacity: shapeSettings.border.opacity
385
+ };
386
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
387
+ const currentShapeData: any[] = <any[]>this.currentLayer.layerData[i as number];
388
+ let pathOptions: PathOption;
389
+ let circleOptions: CircleOption; let groupElement: Element;
390
+ let path: string = '';
391
+ let fill: string = (shapeSettings.autofill) ? colors[i % colors.length] :
392
+ (shapeSettings.fill || this.mapObject.themeStyle.shapeFill);
393
+ if (shapeSettings.colorValuePath !== null && !isNullOrUndefined(currentShapeData['property'])) {
394
+ k = checkShapeDataFields(
395
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
396
+ <any[]>this.currentLayer.dataSource, currentShapeData['property'],
397
+ this.currentLayer.shapeDataPath, this.currentLayer.shapePropertyPath, this.currentLayer
398
+ );
399
+ if (k !== null && shapeSettings.colorMapping.length === 0) {
400
+ fill = ((this.currentLayer.shapeSettings.colorValuePath.indexOf('.') > -1) ?
401
+ (getValueFromObject(this.currentLayer.dataSource[k as number], shapeSettings.colorValuePath)) :
402
+ this.currentLayer.dataSource[k as number][shapeSettings.colorValuePath]);
403
+ } else if (currentShapeData['property'][shapeSettings.colorValuePath] &&
404
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
405
+ (<any[]>this.currentLayer.dataSource).length === 0 && shapeSettings.colorMapping.length === 0) {
406
+ fill = ((this.currentLayer.shapeSettings.colorValuePath.indexOf('.') > -1) ?
407
+ (getValueFromObject(currentShapeData['property'], shapeSettings.colorValuePath)) :
408
+ currentShapeData['property'][shapeSettings.colorValuePath]);
409
+ }
410
+ fill = !isNullOrUndefined(fill) ? fill : (shapeSettings.fill || this.mapObject.themeStyle.shapeFill);
411
+ }
412
+ const shapeID: string = this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_shapeIndex_' + i + '_dataIndex_' + k;
413
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
414
+ const getShapeColor: any = this.getShapeColorMapping(this.currentLayer, currentShapeData['property'], fill);
415
+ fill = Object.prototype.toString.call(getShapeColor) === '[object Object]' && !isNullOrUndefined(getShapeColor['fill'])
416
+ ? getShapeColor['fill'] : fill;
417
+ if (this.currentLayer.shapeSettings.borderColorValuePath || this.currentLayer.shapeSettings.borderWidthValuePath) {
418
+ k = checkShapeDataFields(
419
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
420
+ <any[]>this.currentLayer.dataSource, currentShapeData['property'],
421
+ this.currentLayer.shapeDataPath, this.currentLayer.shapePropertyPath, this.currentLayer
422
+ );
423
+ if (k !== null) {
424
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
425
+ const currentDataSource: any = this.currentLayer.dataSource[k as number];
426
+ if (currentDataSource[shapeSettings.borderColorValuePath]) {
427
+ borderValue.color = currentDataSource[shapeSettings.borderColorValuePath];
428
+ }
429
+ if (currentDataSource[shapeSettings.borderWidthValuePath]) {
430
+ borderValue.width = currentDataSource[shapeSettings.borderWidthValuePath];
431
+ }
432
+ }
433
+ }
434
+ const opacity: number = (Object.prototype.toString.call(getShapeColor) === '[object Object]'
435
+ && !isNullOrUndefined(getShapeColor['opacity'])) ? getShapeColor['opacity'] : shapeSettings.opacity;
436
+ const eventArgs: IShapeRenderingEventArgs = {
437
+ cancel: false, name: shapeRendering, index: i,
438
+ data: this.currentLayer.dataSource ? this.currentLayer.dataSource[k as number] : null,
439
+ maps: this.mapObject,
440
+ shape: shapeSettings, fill: fill,
441
+ border: { width: borderValue.width, color: borderValue.color, opacity: borderValue.opacity}
442
+ };
443
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
444
+ const shapeRenderingSuccess: any = (eventArgs: IShapeRenderingEventArgs) => {
445
+ let drawingType: string = !isNullOrUndefined(currentShapeData['_isMultiPolygon'])
446
+ ? 'MultiPolygon' : isNullOrUndefined(currentShapeData['type']) ? currentShapeData[0]['type'] : currentShapeData['type'];
447
+ drawingType = (drawingType === 'Polygon' || drawingType === 'MultiPolygon') ? 'Polygon' : drawingType;
448
+ if (!eventArgs.cancel) {
449
+ eventArgs.fill = eventArgs.fill === '#A6A6A6' ? eventArgs.shape.fill ||
450
+ this.mapObject.themeStyle.shapeFill : eventArgs.fill;
451
+ eventArgs.border.color = eventArgs.border.color === 'transparent' ?
452
+ eventArgs.shape.border.color : eventArgs.border.color;
453
+ eventArgs.border.width = eventArgs.border.width === 0 ? eventArgs.shape.border.width : eventArgs.border.width;
454
+ if (isNullOrUndefined(shapeSettings.borderColorValuePath)) {
455
+ borderValue.color = eventArgs.border.color;
456
+ }
457
+ if (isNullOrUndefined(shapeSettings.borderWidthValuePath)) {
458
+ borderValue.width = eventArgs.border.width;
459
+ }
460
+ } else {
461
+ eventArgs.fill = fill;
462
+ eventArgs.border.color = shapeSettings.border.color || this.mapObject.themeStyle.shapeBorderColor;
463
+ eventArgs.border.width = shapeSettings.border.width;
464
+ }
465
+ eventArgs.border.opacity = isNullOrUndefined(eventArgs.border.opacity) ? opacity : eventArgs.border.opacity;
466
+ if (this.groupElements.length < 1) {
467
+ groupElement = this.mapObject.renderer.createGroup({
468
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_' + drawingType + '_Group', transform: ''
469
+ });
470
+ this.groupElements.push(groupElement);
471
+ } else {
472
+ for (let i: number = 0; i < this.groupElements.length; i++) {
473
+ const ele: Element = this.groupElements[i as number];
474
+ if (ele.id.indexOf(drawingType) > -1) {
475
+ groupElement = ele;
476
+ break;
477
+ } else if (i >= this.groupElements.length - 1) {
478
+ groupElement = this.mapObject.renderer.createGroup({
479
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_' + drawingType + '_Group'
480
+ });
481
+ this.groupElements.push(groupElement);
482
+ break;
483
+ }
484
+ }
485
+ }
486
+ let pathEle: Element;
487
+ switch (drawingType) {
488
+ case 'Polygon':
489
+ if (!currentShapeData['_isMultiPolygon']) {
490
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
491
+ const shapeData: any[] = currentShapeData as any[];
492
+ if (shapeData.length > 0) {
493
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
494
+ const firstPoint: any = shapeData[0]['point'];
495
+ const pathSegments: string[] = ['M', String(firstPoint['x']), String(firstPoint['y'])];
496
+ for (let index: number = 0; index < shapeData.length; index++) {
497
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
498
+ const point: any = shapeData[index as number]['point'];
499
+ pathSegments.push('L', String(point['x']), String(point['y']));
500
+ }
501
+ pathSegments.push('z');
502
+ path = pathSegments.join(' ');
503
+ }
504
+ } else {
505
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
506
+ path = this.generateMultiPolygonPath(<any[]>currentShapeData);
507
+ path += ' z ';
508
+ }
509
+ if (path.length > 3) {
510
+ pathOptions = new PathOption(
511
+ shapeID, eventArgs.fill, eventArgs.border.width, eventArgs.border.color,
512
+ opacity, eventArgs.border.opacity, shapeSettings.dashArray, path);
513
+ pathEle = this.mapObject.renderer.drawPath(pathOptions) as SVGPathElement;
514
+ }
515
+ break;
516
+ case 'LineString':
517
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
518
+ currentShapeData.map((lineData: any, index: number) => {
519
+ if (index === 0) {
520
+ path += 'M ' + (lineData['point']['x']) + ' ' + (lineData['point']['y']);
521
+ } else {
522
+ path += 'L' + (lineData['point']['x']) + ' , ' + (lineData['point']['y']) + ' ';
523
+ }
524
+ });
525
+ if (path.length > 3) {
526
+ pathOptions = new PathOption(
527
+ shapeID, 'transparent', !isNullOrUndefined(eventArgs.border.width) ? eventArgs.border.width : 1, !isNullOrUndefined(eventArgs.fill) ? eventArgs.fill :
528
+ eventArgs.border.color,
529
+ opacity, eventArgs.border.opacity, shapeSettings.dashArray, path);
530
+ pathEle = this.mapObject.renderer.drawPath(pathOptions) as SVGPathElement;
531
+ }
532
+ break;
533
+ case 'MultiLineString':
534
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
535
+ currentShapeData.map((multilineData: any) => {
536
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
537
+ multilineData.map((lineData: any, index: number) => {
538
+ if (index === 0) {
539
+ path += 'M ' + (lineData['point']['x']) + ' ' + (lineData['point']['y']);
540
+ } else {
541
+ path += 'L' + (lineData['point']['x']) + ' , ' + (lineData['point']['y']) + ' ';
542
+ }
543
+ });
544
+ });
545
+ if (path.length > 3) {
546
+ pathOptions = new PathOption(
547
+ shapeID, 'transparent', !isNullOrUndefined(eventArgs.border.width) ? eventArgs.border.width : 1, !isNullOrUndefined(eventArgs.fill) ? eventArgs.fill :
548
+ eventArgs.border.color,
549
+ opacity, eventArgs.border.opacity, shapeSettings.dashArray, path);
550
+ pathEle = this.mapObject.renderer.drawPath(pathOptions) as SVGPathElement;
551
+ }
552
+ break;
553
+ case 'Point':
554
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
555
+ const pointData: any = <any>currentShapeData['point'];
556
+ const circleRadius: number = (this.mapObject.layers[layerIndex as number].type !== 'SubLayer') ?
557
+ shapeSettings.circleRadius : shapeSettings.circleRadius / (this.mapObject.isTileMap ?
558
+ this.mapObject.scale : this.currentFactor);
559
+ circleOptions = new CircleOption(
560
+ shapeID, eventArgs.fill, eventArgs.border, opacity,
561
+ pointData['x'], pointData['y'], circleRadius, shapeSettings.dashArray);
562
+ pathEle = this.mapObject.renderer.drawCircle(circleOptions) as SVGCircleElement;
563
+ break;
564
+ case 'MultiPoint':
565
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
566
+ currentShapeData.map((multiPointData: any, index: number) => {
567
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
568
+ const pointData: any = multiPointData['point'];
569
+ const circleRadius: number = (this.mapObject.layers[layerIndex as number].type !== 'SubLayer') ? shapeSettings.circleRadius : shapeSettings.circleRadius / (this.mapObject.isTileMap ? this.mapObject.scale : this.currentFactor);
570
+ circleOptions = new CircleOption(
571
+ (shapeID + '_multiLine_' + index), eventArgs.fill, eventArgs.border, opacity,
572
+ pointData['x'], pointData['y'], circleRadius, shapeSettings.dashArray);
573
+ pathEle = this.mapObject.renderer.drawCircle(circleOptions) as SVGCircleElement;
574
+ this.pathAttributeCalculate(groupElement, pathEle, drawingType, currentShapeData);
575
+ });
576
+ break;
577
+ case 'Path':
578
+ path = <string>currentShapeData['point'];
579
+ pathOptions = new PathOption(
580
+ shapeID, eventArgs.fill, eventArgs.border.width, eventArgs.border.color,
581
+ opacity, eventArgs.border.opacity, shapeSettings.dashArray, path);
582
+ pathEle = this.mapObject.renderer.drawPath(pathOptions) as SVGPathElement;
583
+ break;
584
+ }
585
+ if (!isNullOrUndefined(pathEle) && drawingType !== 'MultiPoint') {
586
+ this.pathAttributeCalculate(groupElement, pathEle, drawingType, currentShapeData);
587
+ }
588
+ if (i === this.currentLayer.layerData.length - 1) {
589
+ this.layerFeatures(layerIndex, colors, renderData, labelTemplateEle);
590
+ }
591
+ };
592
+ shapeRenderingSuccess.bind(this);
593
+ this.mapObject.trigger('shapeRendering', eventArgs, shapeRenderingSuccess);
594
+ }
595
+ } else {
596
+ this.layerFeatures(layerIndex, colors, renderData, labelTemplateEle);
597
+ }
598
+ }
599
+ /**
600
+ * layer features as bubble, marker, datalabel, navigation line.
601
+ *
602
+ * @param {Element} groupElement - Specifies the element to append the group.
603
+ * @param {Element} pathEle - Specifies the svg element.
604
+ * @param {string} drawingType - Specifies the data type.
605
+ * @param {any} currentShapeData - Specifies the layer of shapedata.
606
+ * @returns {void}
607
+ */
608
+ private pathAttributeCalculate(groupElement: Element, pathEle: Element, drawingType: string,
609
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
610
+ currentShapeData: any): void {
611
+ const property: string[] = (Object.prototype.toString.call(this.currentLayer.shapePropertyPath) === '[object Array]' ?
612
+ this.currentLayer.shapePropertyPath : [this.currentLayer.shapePropertyPath]) as string[];
613
+ let properties: string;
614
+ for (let j: number = 0; j < property.length; j++) {
615
+ if (!isNullOrUndefined(currentShapeData['property'])) {
616
+ properties = property[j as number];
617
+ break;
618
+ }
619
+ }
620
+ pathEle.setAttribute('aria-label', ((!isNullOrUndefined(currentShapeData['property'])) ?
621
+ (currentShapeData['property'][properties as string]) : ''));
622
+ if (this.currentLayer.selectionSettings.enable || this.currentLayer.highlightSettings.enable) {
623
+ (pathEle as HTMLElement).tabIndex = this.mapObject.tabIndex;
624
+ pathEle.setAttribute('role', 'button');
625
+ (pathEle as HTMLElement).style.cursor = this.currentLayer.highlightSettings.enable && !this.currentLayer.selectionSettings.enable ? 'default' : 'pointer';
626
+ }
627
+ else {
628
+ pathEle.setAttribute('role', 'region');
629
+ }
630
+ if (drawingType === 'LineString' || drawingType === 'MultiLineString') {
631
+ (pathEle as HTMLElement).style.cssText = 'outline:none';
632
+ }
633
+ maintainSelection(this.mapObject.selectedElementId, this.mapObject.shapeSelectionClass, pathEle,
634
+ 'ShapeselectionMapStyle');
635
+ if (this.mapObject.legendSettings.toggleLegendSettings.enable && this.mapObject.legendSettings.type === 'Layers') {
636
+ maintainToggleSelection(this.mapObject.toggledElementId, pathEle,
637
+ this.mapObject.legendSettings.toggleLegendSettings.applyShapeSettings ? this.currentLayer.shapeSettings
638
+ : this.mapObject.legendSettings.toggleLegendSettings);
639
+ }
640
+ groupElement.appendChild(pathEle);
641
+ }
642
+ /**
643
+ * layer features as bubble, marker, datalabel, navigation line.
644
+ *
645
+ * @param {number} layerIndex - Specifies the layer index
646
+ * @param {string[]} colors - Specifies the colors
647
+ * @param {any[]} renderData - Specifies the render data
648
+ * @param {HTMLElement} labelTemplateEle - Specifies the label template element
649
+ * @returns {void}
650
+ */
651
+ private layerFeatures(
652
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
653
+ layerIndex: number, colors: string[], renderData: any[],
654
+ labelTemplateEle: HTMLElement
655
+ ): void {
656
+ let bubbleG: Element;
657
+ if (this.mapObject.polygonModule) {
658
+ this.groupElements.push(
659
+ this.mapObject.polygonModule.polygonRender(this.mapObject, layerIndex,
660
+ (this.mapObject.isTileMap ? Math.floor(this.currentFactor)
661
+ : this.currentFactor)));
662
+ }
663
+ if (this.currentLayer.bubbleSettings.length && this.mapObject.bubbleModule) {
664
+ const length: number = this.currentLayer.bubbleSettings.length;
665
+ let bubble: BubbleSettingsModel;
666
+ for (let j: number = 0; j < length; j++) {
667
+ bubble = this.currentLayer.bubbleSettings[j as number];
668
+ bubbleG = this.mapObject.renderer.createGroup({
669
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_bubble_Group_' + j
670
+ });
671
+ const range: {
672
+ min: number;
673
+ max: number;
674
+ } = { min: 0, max: 0 };
675
+ this.bubbleCalculation(bubble, range);
676
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
677
+ const bubbleDataSource: any[] = bubble.dataSource as any[];
678
+ this.mapObject.bubbleModule.bubbleCollection = [];
679
+ if (!isNullOrUndefined(bubbleDataSource) && bubbleDataSource.length > 0) {
680
+ bubbleDataSource.map((bubbleData: object, i: number) => {
681
+ this.renderBubble(
682
+ this.currentLayer, bubbleData, colors[i % colors.length], range, j, i, bubbleG, layerIndex, bubble);
683
+ });
684
+ this.groupElements.push(bubbleG);
685
+ }
686
+ }
687
+ }
688
+ if ((this.mapObject.markerModule && !this.mapObject.isTileMap) && this.mapObject.zoomSettings.enable) {
689
+ this.mapObject.markerModule.calculateZoomCenterPositionAndFactor(this.mapObject.layersCollection);
690
+ }
691
+ const group: Element = (this.mapObject.renderer.createGroup({
692
+ id: this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_dataLableIndex_Group'
693
+ }));
694
+ (group as HTMLElement).style.pointerEvents = 'none';
695
+ if (this.mapObject.dataLabelModule && this.currentLayer.dataLabelSettings.visible) {
696
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
697
+ const intersect: any[] = [];
698
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
699
+ Array.prototype.forEach.call(renderData, (currentShapeData: any[], i: number) => {
700
+ this.renderLabel(this.currentLayer, layerIndex, currentShapeData, group, i, labelTemplateEle, intersect);
701
+ });
702
+ this.groupElements.push(group);
703
+ }
704
+ if (this.mapObject.navigationLineModule) {
705
+ this.groupElements.push(
706
+ this.mapObject.navigationLineModule.renderNavigation(this.currentLayer, this.currentFactor, layerIndex)
707
+ );
708
+ }
709
+ if (!isNullOrUndefined(this.groupElements) && !isNullOrUndefined(this.layerObject)) {
710
+ this.groupElements.map((element: Element) => {
711
+ if (!isNullOrUndefined(element)) {
712
+ this.layerObject.appendChild(element);
713
+ }
714
+ });
715
+ }
716
+ if (this.mapObject.markerModule) {
717
+ this.mapObject.markerModule.markerRender(this.mapObject, this.layerObject, layerIndex,
718
+ (this.mapObject.isTileMap ? Math.floor(this.currentFactor) :
719
+ this.currentFactor), null);
720
+ }
721
+ this.translateLayerElements(this.layerObject);
722
+ this.layerGroup.appendChild(this.layerObject);
723
+ }
724
+
725
+ /**
726
+ * render datalabel.
727
+ *
728
+ * @param {LayerSettings} layer - Specifies the layer
729
+ * @param {number} layerIndex - Specifies the layer index
730
+ * @param {any[]} shape - Specifies the shape
731
+ * @param {Element} group - Specifies the group
732
+ * @param {number} shapeIndex - Specifies the shape index
733
+ * @param {HTMLElement} labelTemplateEle - Specifies the label template element
734
+ * @param {any[]} intersect - Specifies the intersect
735
+ * @returns {void}
736
+ */
737
+ private renderLabel(
738
+ layer: LayerSettings, layerIndex: number,
739
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
740
+ shape: any[], group: Element, shapeIndex: number, labelTemplateEle: HTMLElement, intersect: any[]
741
+ ): void {
742
+ this.mapObject.dataLabelModule.renderLabel(
743
+ layer, layerIndex, shape, layer.layerData, group, labelTemplateEle, shapeIndex, intersect
744
+ );
745
+ }
746
+ /**
747
+ * To render path for multipolygon.
748
+ *
749
+ * @param {any[]} currentShapeData Specifies the current shape data
750
+ * @returns {string} Returns the path
751
+ */
752
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
753
+ private generateMultiPolygonPath(currentShapeData: any[]): string {
754
+ const parts: string[] = [];
755
+ for (const shape of currentShapeData) {
756
+ if (!shape || shape.length === 0) { continue; }
757
+ const startX: number = shape[0].point.x;
758
+ const startY: number = shape[0].point.y;
759
+ parts.push(`M${startX} ${startY}`);
760
+ for (let i: number = 1; i < shape.length; i++) {
761
+ const x: number = shape[i as number].point.x;
762
+ const y: number = shape[i as number].point.y;
763
+ parts.push(` L ${x} ${y}`);
764
+ }
765
+ }
766
+ return parts.join(' ');
767
+ }
768
+ /**
769
+ * To render bubble.
770
+ *
771
+ * @param {LayerSettings} layer - Specifies the layer
772
+ * @param {object} bubbleData - Specifies the bubble data
773
+ * @param {string} color - Specifies the color
774
+ * @param {number} range - Specifies the range
775
+ * @param {number} range.min - Specifies the minimum range
776
+ * @param {number} range.max - Specifies the maximum range
777
+ * @param {number} bubbleIndex - Specifies the bubble index
778
+ * @param {number} dataIndex - Specifies the data index
779
+ * @param {number} group - Specifies the group
780
+ * @param {number} layerIndex - Specifies the layer index
781
+ * @param {BubbleSettingsModel} bubbleSettings - Specifies the bubble settings
782
+ * @returns {void}
783
+ */
784
+ private renderBubble(
785
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
786
+ layer: LayerSettings, bubbleData: any, color: string, range: { min: number, max: number },
787
+ bubbleIndex: number, dataIndex: number, group: Element, layerIndex: number, bubbleSettings: BubbleSettingsModel
788
+ ): void {
789
+ if (isNullOrUndefined(this.mapObject.bubbleModule) || !bubbleSettings.visible) {
790
+ return null;
791
+ }
792
+ color = bubbleSettings.fill ? bubbleSettings.fill : color;
793
+ this.mapObject.bubbleModule.id = this.mapObject.element.id + '_LayerIndex_' + layerIndex + '_BubbleIndex_' +
794
+ bubbleIndex + '_dataIndex_' + dataIndex;
795
+ this.mapObject.bubbleModule.renderBubble(
796
+ bubbleSettings, bubbleData, color, range, bubbleIndex, dataIndex, layerIndex, layer, group, this.mapObject.bubbleModule.id);
797
+ }
798
+ /**
799
+ * To get the shape color from color mapping module.
800
+ *
801
+ * @param {LayerSettingsModel} layer - Specifies the layer
802
+ * @param {any} shape - Specifies the shape
803
+ * @param {string} color - Specifies the color
804
+ * @returns {any} - Returns the object
805
+ */
806
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
807
+ private getShapeColorMapping(layer: LayerSettingsModel, shape: any, color: string): any {
808
+ color = color ? color : layer.shapeSettings.fill;
809
+ if (layer.shapeSettings.colorMapping.length === 0 && isNullOrUndefined(layer.dataSource)) {
810
+ return color;
811
+ }
812
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
813
+ const index: number = checkShapeDataFields(<any[]>layer.dataSource, shape, layer.shapeDataPath, layer.shapePropertyPath, layer);
814
+ const colorMapping: ColorMapping = new ColorMapping(this.mapObject);
815
+ if (isNullOrUndefined(layer.dataSource) || isNullOrUndefined(layer.dataSource[index as number])) {
816
+ return color;
817
+ }
818
+ return colorMapping.getShapeColorMapping(layer.shapeSettings, layer.dataSource[index as number], color);
819
+ }
820
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
821
+ public generatePoints(type: string, coordinates: any[], data: object, properties: object): void {
822
+ let latitude: number; let longitude: number;
823
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
824
+ let newData: any[] = [];
825
+ switch (type.toLowerCase()) {
826
+ case 'polygon':
827
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
828
+ newData = <any[]>this.calculatePolygonBox(<any[]>coordinates[0]);
829
+ if (newData.length > 0) {
830
+ newData['property'] = properties;
831
+ newData['type'] = type;
832
+ newData['_isMultiPolygon'] = false;
833
+ this.currentLayer.layerData.push(newData);
834
+ }
835
+ break;
836
+ case 'multipolygon':
837
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
838
+ const multiPolygonDatas: any[] = [];
839
+ for (let i: number = 0; i < coordinates.length; i++) {
840
+ for (let j: number = 0; j < coordinates[i as number].length; j++) {
841
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
842
+ newData = <any[]>this.calculatePolygonBox(<any[]>coordinates[i as number][j as number]);
843
+ if (newData.length > 0) {
844
+ multiPolygonDatas.push(newData);
845
+ }
846
+ }
847
+ }
848
+ multiPolygonDatas['property'] = properties;
849
+ multiPolygonDatas['type'] = type;
850
+ multiPolygonDatas['_isMultiPolygon'] = true;
851
+ this.currentLayer.layerData.push(multiPolygonDatas);
852
+ break;
853
+ case 'linestring':
854
+ const lineExtraSpace: number = !isNullOrUndefined(this.currentLayer.shapeSettings.border.width) ?
855
+ (typeof(this.currentLayer.shapeSettings.border.width) === 'string' ?
856
+ parseInt(this.currentLayer.shapeSettings.border.width, 10) : this.currentLayer.shapeSettings.border.width) : 1;
857
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
858
+ coordinates.map((points: any) => {
859
+ latitude = <number>points[1];
860
+ longitude = <number>points[0];
861
+ const point: Point = convertGeoToPoint(
862
+ latitude, longitude, this.currentFactor, this.currentLayer, this.mapObject);
863
+ this.calculateBox(point, lineExtraSpace);
864
+ newData.push({
865
+ point: point, lat: latitude, lng: longitude
866
+ });
867
+ });
868
+ newData['property'] = properties;
869
+ newData['type'] = type;
870
+ this.currentLayer.layerData.push(newData);
871
+ break;
872
+ case 'multilinestring':
873
+ const extraSpaces: number = !isNullOrUndefined(this.currentLayer.shapeSettings.border.width) ?
874
+ (typeof(this.currentLayer.shapeSettings.border.width) === 'string' ?
875
+ parseInt(this.currentLayer.shapeSettings.border.width, 10) : this.currentLayer.shapeSettings.border.width) : 1;
876
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
877
+ const multiLineData: any[] = [];
878
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
879
+ coordinates.map((multiPoints: any) => {
880
+ newData = [];
881
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
882
+ multiPoints.map((points: any) => {
883
+ latitude = <number>points[1];
884
+ longitude = <number>points[0];
885
+ const point: Point = convertGeoToPoint(
886
+ latitude, longitude, this.currentFactor, this.currentLayer, this.mapObject);
887
+ this.calculateBox(point, extraSpaces);
888
+ newData.push({
889
+ point: point, lat: latitude, lng: longitude
890
+ });
891
+ });
892
+ multiLineData.push(newData);
893
+ });
894
+ multiLineData['property'] = properties;
895
+ multiLineData['type'] = type;
896
+ this.currentLayer.layerData.push(multiLineData);
897
+ break;
898
+ case 'point':
899
+ const pointExtraSpace: number = (!isNullOrUndefined(this.currentLayer.shapeSettings.border.width) ?
900
+ (typeof(this.currentLayer.shapeSettings.border.width) === 'string' ?
901
+ parseInt(this.currentLayer.shapeSettings.border.width, 10) : this.currentLayer.shapeSettings.border.width) : 1) +
902
+ (this.currentLayer.shapeSettings.circleRadius * 2);
903
+ latitude = <number>coordinates[1];
904
+ longitude = <number>coordinates[0];
905
+ const point: Point = convertGeoToPoint(latitude, longitude, this.currentFactor, this.currentLayer, this.mapObject);
906
+ this.calculateBox(point, pointExtraSpace);
907
+ this.currentLayer.layerData.push({
908
+ point: point, type: type, lat: latitude, lng: longitude, property: properties
909
+ });
910
+ break;
911
+ case 'multipoint':
912
+ const extraSpace: number = (!isNullOrUndefined(this.currentLayer.shapeSettings.border.width) ?
913
+ (typeof(this.currentLayer.shapeSettings.border.width) === 'string' ?
914
+ parseInt(this.currentLayer.shapeSettings.border.width, 10) : this.currentLayer.shapeSettings.border.width) : 1) +
915
+ (this.currentLayer.shapeSettings.circleRadius * 2);
916
+ newData = [];
917
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
918
+ coordinates.map((points: any) => {
919
+ latitude = points[1];
920
+ longitude = points[0];
921
+ const point: Point = convertGeoToPoint(latitude, longitude, this.currentFactor, this.currentLayer, this.mapObject);
922
+ this.calculateBox(point, extraSpace);
923
+ newData.push({
924
+ point: point, lat: latitude, lng: longitude
925
+ });
926
+ });
927
+ newData['property'] = properties;
928
+ newData['type'] = type;
929
+ this.currentLayer.layerData.push(newData);
930
+ break;
931
+ case 'path':
932
+ this.currentLayer.layerData.push({
933
+ point: data['d'], type: type, property: properties
934
+ });
935
+ break;
936
+ }
937
+ }
938
+
939
+ public calculateBox(point: Point, extraSpace: number): void {
940
+ if (isNullOrUndefined(this.rectBounds)) {
941
+ this.rectBounds = { min: { x: point.x - extraSpace, y: point.y - extraSpace }, max: { x: point.x + extraSpace,
942
+ y: point.y + extraSpace } };
943
+ } else {
944
+ this.rectBounds['min']['x'] = Math.min(this.rectBounds['min']['x'], point.x - extraSpace);
945
+ this.rectBounds['min']['y'] = Math.min(this.rectBounds['min']['y'], point.y - extraSpace);
946
+ this.rectBounds['max']['x'] = Math.max(this.rectBounds['max']['x'], point.x + extraSpace);
947
+ this.rectBounds['max']['y'] = Math.max(this.rectBounds['max']['y'], point.y + extraSpace);
948
+ }
949
+ }
950
+
951
+ public calculateFactor(layer: LayerSettings): number {
952
+ let horFactor: number; let verFactor: number = 1;
953
+ const divide: number = 10;
954
+ const exp: string = 'e+1';
955
+ const bounds: GeoLocation = this.mapObject.baseMapBounds;
956
+ const mapSize: Size = new Size(this.mapObject.mapAreaRect.width, this.mapObject.mapAreaRect.height - 5);
957
+ let mapHeight: number; let mapWidth: number;
958
+ if (bounds) {
959
+ const start: Point = convertGeoToPoint(
960
+ bounds.latitude.min, bounds.longitude.min, null, layer, this.mapObject);
961
+ const end: Point = convertGeoToPoint(
962
+ bounds.latitude.max, bounds.longitude.max, null, layer, this.mapObject);
963
+ mapHeight = end.y - start.y;
964
+ mapWidth = end.x - start.x;
965
+ if (mapHeight === 0 || mapWidth === 0) {
966
+ mapWidth = mapSize.width / 2;
967
+ mapHeight = mapSize.height;
968
+ }
969
+ } else {
970
+ mapHeight = mapWidth = 500;
971
+ }
972
+ if (mapHeight < mapSize.height) {
973
+ horFactor = parseFloat(Math.abs(Number(mapSize.height / Number(mapHeight.toString() + exp)) * 100).toString().split('.')[0])
974
+ / divide;
975
+ } else {
976
+ horFactor = mapSize.height / mapHeight;
977
+ }
978
+ if (mapWidth < mapSize.width) {
979
+ verFactor = parseFloat(Math.abs(Number(mapSize.width / Number(mapWidth.toString() + exp)) * 100).toString().split('.')[0])
980
+ / divide;
981
+ } else {
982
+ verFactor = mapSize.width / mapWidth;
983
+ }
984
+ return (Math.min(verFactor, horFactor));
985
+ }
986
+
987
+ public translateLayerElements(layerElement: Element): void {
988
+ let childNode: HTMLElement;
989
+ this.mapObject.translateType = 'layer';
990
+ if (!isNullOrUndefined(this.mapObject.baseMapRectBounds)) {
991
+ const duration: number = animationMode === 'Disable' ? 0 : (this.currentLayer.animationDuration === 0 && animationMode === 'Enable') ?
992
+ 1000 : this.currentLayer.animationDuration;
993
+ const animate: boolean = duration !== 0 || isNullOrUndefined(this.mapObject.zoomModule);
994
+ this.mapObject.baseTranslatePoint = this.mapObject.zoomTranslatePoint;
995
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
996
+ let translate: any;
997
+ if (this.mapObject.zoomSettings.zoomFactor > 1 && !isNullOrUndefined(this.mapObject.zoomModule)) {
998
+ translate = getZoomTranslate(this.mapObject, this.currentLayer, animate);
999
+ } else {
1000
+ translate = getTranslate(this.mapObject, this.currentLayer, animate);
1001
+ }
1002
+ const scale: number = this.mapObject.previousScale = translate['scale'];
1003
+ const location: Point = this.mapObject.previousPoint = translate['location'] as Point;
1004
+ this.mapObject.baseTranslatePoint = this.mapObject.translatePoint = location;
1005
+ this.mapObject.baseScale = this.mapObject.scale = scale;
1006
+ for (let i: number = 0; i < layerElement.childElementCount; i++) {
1007
+ childNode = layerElement.childNodes[i as number] as HTMLElement;
1008
+ if (!(childNode.id.indexOf('_Markers_Group') > -1) &&
1009
+ (!(childNode.id.indexOf('_bubble_Group') > -1)) &&
1010
+ (!(childNode.id.indexOf('_dataLableIndex_Group') > -1))
1011
+ ) {
1012
+ const transform: string = 'scale( ' + scale + ' ) '
1013
+ + 'translate( ' + location.x + ' ' + location.y + ' ) ';
1014
+ childNode.setAttribute('transform', transform);
1015
+ if (duration > 0 && !isNullOrUndefined(this.mapObject.zoomModule)) {
1016
+ if (this.mapObject.zoomSettings.zoomFactor > 1) {
1017
+ translate = getZoomTranslate(this.mapObject, this.currentLayer);
1018
+ } else {
1019
+ translate = getTranslate(this.mapObject, this.currentLayer);
1020
+ }
1021
+ this.mapObject.scale = translate['scale'];
1022
+ this.mapObject.zoomTranslatePoint = this.mapObject.translatePoint = translate['location'] as Point;
1023
+ }
1024
+ }
1025
+ }
1026
+ } else if (this.mapObject.isTileMap && !isNullOrUndefined(this.mapObject.scale)) {
1027
+ for (let j: number = 0; j < layerElement.childElementCount; j++) {
1028
+ childNode = layerElement.childNodes[j as number] as HTMLElement;
1029
+ if (!(childNode.id.indexOf('_Markers_Group') > -1) &&
1030
+ (!(childNode.id.indexOf('_bubble_Group') > -1)) &&
1031
+ (!(childNode.id.indexOf('_dataLableIndex_Group') > -1)) &&
1032
+ (!(childNode.id.indexOf('_line_Group') > -1))) {
1033
+ if (childNode.id.indexOf('_Polygons_Group') === -1) {
1034
+ const transform: string = 'scale( ' + this.mapObject.scale + ' ) ' + 'translate( ' + this.mapObject.translatePoint.x
1035
+ + ' ' + this.mapObject.translatePoint.y + ' ) ';
1036
+ childNode.setAttribute('transform', transform);
1037
+ }
1038
+ }
1039
+ }
1040
+ }
1041
+ }
1042
+
1043
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1044
+ public calculateRectBounds(layerData: any[]): void {
1045
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1046
+ Array.prototype.forEach.call(layerData, (obj: any) => {
1047
+ if (!isNullOrUndefined(obj['geometry']) || !isNullOrUndefined(obj['coordinates'])) {
1048
+ const type: string = !isNullOrUndefined(obj['geometry']) ? obj['geometry']['type'] : obj['type'];
1049
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1050
+ const coordinates: any[] = !isNullOrUndefined(obj['geometry']) ? obj['geometry']['coordinates'] : obj['coordinates'];
1051
+ switch (type.toLowerCase()) {
1052
+ case 'polygon':
1053
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1054
+ this.calculateRectBox(<any[]>coordinates[0]);
1055
+ break;
1056
+ case 'multipolygon':
1057
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1058
+ coordinates.map((point: any) => {
1059
+ this.calculateRectBox(point[0]);
1060
+ });
1061
+ break;
1062
+ case 'multilinestring':
1063
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1064
+ coordinates.map((multiPoint: any) => {
1065
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1066
+ multiPoint.map((point: any, index: number) => {
1067
+ this.calculateRectBox(point, 'multilinestring', index === 0 ? true : false);
1068
+ });
1069
+ });
1070
+ break;
1071
+ case 'linestring':
1072
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1073
+ coordinates.map((point: any, index: number) => {
1074
+ this.calculateRectBox(point, 'linestring', index === 0 ? true : false);
1075
+ });
1076
+ break;
1077
+ case 'point':
1078
+ this.calculateRectBox(coordinates, 'point');
1079
+ break;
1080
+ case 'multipoint':
1081
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1082
+ coordinates.map((point: any, index: number) => {
1083
+ this.calculateRectBox(point, 'multipoint', index === 0 ? true : false);
1084
+ });
1085
+ break;
1086
+ }
1087
+ }
1088
+ });
1089
+ }
1090
+
1091
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1092
+ public calculatePolygonBox(coordinates: any[]): any {
1093
+ // Use a simple for-loop, cache frequent lookups, and update rectBounds once
1094
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1095
+ const newData: any[] = [];
1096
+ const bounds: GeoLocation = this.mapObject.baseMapBounds;
1097
+ const lonMin: number = bounds.longitude.min;
1098
+ const lonMax: number = bounds.longitude.max;
1099
+ const latMin: number = bounds.latitude.min;
1100
+ const latMax: number = bounds.latitude.max;
1101
+
1102
+ let minX: number | undefined;
1103
+ let minY: number | undefined;
1104
+ let maxX: number | undefined;
1105
+ let maxY: number | undefined;
1106
+
1107
+ for (let i: number = 0; i < coordinates.length; i++) {
1108
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1109
+ const currentPoint: any = coordinates[i as number];
1110
+ const latitude: number = currentPoint[1];
1111
+ const longitude: number = currentPoint[0];
1112
+
1113
+ if (longitude >= lonMin && longitude <= lonMax && latitude >= latMin && latitude <= latMax) {
1114
+ const point: Point = convertGeoToPoint(
1115
+ latitude, longitude, this.currentFactor, this.currentLayer, this.mapObject
1116
+ );
1117
+
1118
+ if (minX === undefined) {
1119
+ minX = maxX = point.x;
1120
+ minY = maxY = point.y;
1121
+ } else {
1122
+ // Update local bounds only
1123
+ minX = Math.min(minX as number, point.x);
1124
+ minY = Math.min(minY as number, point.y);
1125
+ maxX = Math.max(maxX as number, point.x);
1126
+ maxY = Math.max(maxY as number, point.y);
1127
+ }
1128
+
1129
+ newData.push({ point: point, lat: latitude, lng: longitude });
1130
+ }
1131
+ }
1132
+
1133
+ // Apply the accumulated bounds once to reduce repeated property access
1134
+ if (newData.length) {
1135
+ if (isNullOrUndefined(this.rectBounds)) {
1136
+ this.rectBounds = { min: { x: minX as number, y: minY as number }, max: { x: maxX as number, y: maxY as number } };
1137
+ } else {
1138
+ this.rectBounds.min.x = Math.min(this.rectBounds.min.x, minX as number);
1139
+ this.rectBounds.min.y = Math.min(this.rectBounds.min.y, minY as number);
1140
+ this.rectBounds.max.x = Math.max(this.rectBounds.max.x, maxX as number);
1141
+ this.rectBounds.max.y = Math.max(this.rectBounds.max.y, maxY as number);
1142
+ }
1143
+ }
1144
+
1145
+ return newData;
1146
+ }
1147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1148
+ public calculateRectBox(coordinates: any[], type?: string, isFirstItem?: boolean): void {
1149
+ if ((type !== 'linestring' && type !== 'multilinestring') && (type !== 'point' && type !== 'multipoint')) {
1150
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1151
+ Array.prototype.forEach.call(coordinates, (currentCoords: any) => {
1152
+ if (isNullOrUndefined(this.mapObject.baseMapBounds)) {
1153
+ this.mapObject.baseMapBounds = new GeoLocation(
1154
+ { min: currentCoords[1], max: currentCoords[1] },
1155
+ { min: currentCoords[0], max: currentCoords[0] });
1156
+ } else {
1157
+ this.mapObject.baseMapBounds.latitude.min = Math.min(this.mapObject.baseMapBounds.latitude.min, currentCoords[1]);
1158
+ this.mapObject.baseMapBounds.latitude.max = Math.max(this.mapObject.baseMapBounds.latitude.max, currentCoords[1]);
1159
+ this.mapObject.baseMapBounds.longitude.min = Math.min(this.mapObject.baseMapBounds.longitude.min, currentCoords[0]);
1160
+ this.mapObject.baseMapBounds.longitude.max = Math.max(this.mapObject.baseMapBounds.longitude.max, currentCoords[0]);
1161
+ }
1162
+ });
1163
+ } else {
1164
+ if ((isFirstItem || type === 'point') && isNullOrUndefined(this.mapObject.baseMapBounds)) {
1165
+ this.mapObject.baseMapBounds = new GeoLocation(
1166
+ { min: coordinates[1], max: coordinates[1] },
1167
+ { min: coordinates[0], max: coordinates[0] });
1168
+ } else {
1169
+ this.mapObject.baseMapBounds.latitude.min = Math.min(this.mapObject.baseMapBounds.latitude.min, coordinates[1]);
1170
+ this.mapObject.baseMapBounds.latitude.max = Math.max(this.mapObject.baseMapBounds.latitude.max, coordinates[1]);
1171
+ this.mapObject.baseMapBounds.longitude.min = Math.min(this.mapObject.baseMapBounds.longitude.min, coordinates[0]);
1172
+ this.mapObject.baseMapBounds.longitude.max = Math.max(this.mapObject.baseMapBounds.longitude.max, coordinates[0]);
1173
+ }
1174
+ }
1175
+ }
1176
+ public generateTiles(zoomLevel: number, tileTranslatePoint: Point, zoomType?: string, bing?: BingMap, position?: Point,
1177
+ isPinch?: boolean): void {
1178
+ const userLang: string = this.mapObject.locale;
1179
+ const size: Size = this.mapObject.availableSize;
1180
+ this.tiles = [];
1181
+ let xcount: number;
1182
+ let ycount: number;
1183
+ xcount = ycount = Math.pow(2, zoomLevel);
1184
+ let xLeft: number = 0; let xRight: number = 0;
1185
+ if ((tileTranslatePoint.x + (xcount * 256)) < size.width) {
1186
+ xLeft = tileTranslatePoint.x > 0 ? Math.ceil(tileTranslatePoint.x / 256) : 0;
1187
+ xRight = ((tileTranslatePoint.x + xcount * 256) < size.width) ?
1188
+ Math.ceil((size.width - (tileTranslatePoint.x + xcount * 256)) / 256) : 0;
1189
+ }
1190
+ xcount += xLeft + xRight;
1191
+ if (zoomType === 'Pan') {
1192
+ xcount = (this.horizontalPanXCount >= xcount) ? this.horizontalPanXCount : xcount;
1193
+ this.horizontalPan = false;
1194
+ } else {
1195
+ this.horizontalPanXCount = xcount;
1196
+ this.horizontalPan = true;
1197
+ }
1198
+ const baseLayer: LayerSettingsModel = this.mapObject.layers[this.mapObject.baseLayerIndex];
1199
+ this.urlTemplate = baseLayer.urlTemplate;
1200
+ const endY: number = Math.min(ycount, ((-tileTranslatePoint.y + size.height) / 256) + 1);
1201
+ const endX: number = Math.min(xcount, ((-tileTranslatePoint.x + size.width + (xRight * 256)) / 256) + 1);
1202
+ const startX: number = (-((tileTranslatePoint.x + (xLeft * 256)) + 256) / 256);
1203
+ const startY: number = (-(tileTranslatePoint.y + 256) / 256);
1204
+ bing = bing || this.bing || this.mapObject.bingMap;
1205
+ for (let i: number = Math.round(startX); i < Math.round(endX); i++) {
1206
+ for (let j: number = Math.round(startY); j < Math.round(endY); j++) {
1207
+ const x: number = 256 * i + tileTranslatePoint.x;
1208
+ const y: number = 256 * j + tileTranslatePoint.y;
1209
+ if (x > -256 && x <= size.width && y > -256 && y < size.height) {
1210
+ if (j >= 0) {
1211
+ let tileI: number = i;
1212
+ if (i < 0) {
1213
+ tileI = (tileI % ycount) + ycount;
1214
+ }
1215
+ const tile: Tile = new Tile(tileI % ycount, j);
1216
+ tile.left = Math.round(x);
1217
+ tile.top = Math.round(y);
1218
+ if ((bing && !isNullOrUndefined(baseLayer.urlTemplate) && baseLayer.urlTemplate !== '' && baseLayer.urlTemplate.indexOf('quadkey') > -1)) {
1219
+ tile.src = bing.getBingMap(tile, '', '', userLang, bing.imageUrl, bing.subDomains);
1220
+ } else {
1221
+ bing = null;
1222
+ tile.src = this.urlTemplate.replace('level', zoomLevel.toString()).replace('tileX', tile.x.toString())
1223
+ .replace('tileY', tile.y.toString());
1224
+ }
1225
+ this.tiles.push(tile);
1226
+ }
1227
+ }
1228
+ }
1229
+ }
1230
+ if (!isNullOrUndefined(zoomType)) {
1231
+ if (zoomType.indexOf('wheel') > 1) {
1232
+ this.animateToZoomX = (this.mapObject.availableSize.width / 2) - position.x - 10;
1233
+ this.animateToZoomY = -position.y;
1234
+ } else {
1235
+ this.animateToZoomX = -10;
1236
+ this.animateToZoomY = -(this.mapObject.availableSize.height / 2 + 11.5) + 10;
1237
+ }
1238
+ }
1239
+ const proxTiles: Tile[] = extend([], this.tiles, [], true) as Tile[];
1240
+ for (const layer of this.mapObject.layers) {
1241
+ if (!(layer.type === 'SubLayer' && layer.visible)) {
1242
+ continue;
1243
+ }
1244
+ if (isNullOrUndefined(layer.shapeData) && !isNullOrUndefined(layer.urlTemplate) && layer.urlTemplate !== '') {
1245
+ for (const baseTile of proxTiles) {
1246
+ const subtile: Tile = extend({}, baseTile, {}, true) as Tile;
1247
+ if (layer.urlTemplate.indexOf('quadkey')) {
1248
+ bing = new BingMap(this.mapObject);
1249
+ subtile.src = bing.getBingMap(subtile, '', '', userLang, bing.imageUrl, bing.subDomains);
1250
+ } else {
1251
+ subtile.src = layer.urlTemplate.replace('level', zoomLevel.toString()).replace('tileX', baseTile.x.toString())
1252
+ .replace('tileY', baseTile.y.toString());
1253
+ }
1254
+ this.tiles.push(subtile);
1255
+ }
1256
+ }
1257
+ }
1258
+ if (this.mapObject.previousScale !== this.mapObject.scale || this.mapObject.isReset || this.mapObject.isZoomByPosition
1259
+ || this.mapObject.zoomNotApplied || (this.mapObject.previousScale === 1 && this.mapObject.scale === 1)) {
1260
+ this.arrangeTiles(zoomType, this.animateToZoomX, this.animateToZoomY, isPinch);
1261
+ }
1262
+ }
1263
+
1264
+ public arrangeTiles(type: string, x: number, y: number, isPinch: boolean = false): void {
1265
+ const element: HTMLElement = document.getElementById(this.mapObject.element.id + '_tile_parent');
1266
+ const element1: HTMLElement = document.getElementById(this.mapObject.element.id + '_tiles');
1267
+ if (!isPinch) {
1268
+ let timeOut: number;
1269
+ if (!isNullOrUndefined(type) && type !== 'Pan') {
1270
+ this.tileAnimation(type, x, y);
1271
+ timeOut = animationMode === 'Disable' ? 0 : (this.mapObject.layersCollection[0].animationDuration === 0 &&
1272
+ animationMode === 'Enable') ? 1000 : this.mapObject.layersCollection[0].animationDuration;
1273
+ } else {
1274
+ timeOut = 0;
1275
+ }
1276
+ setTimeout(() => {
1277
+ if (element) {
1278
+ element.style.zIndex = '1';
1279
+ }
1280
+ if (element1) {
1281
+ element1.style.zIndex = '0';
1282
+ }
1283
+ let animateElement: HTMLElement;
1284
+ if (!document.getElementById(this.mapObject.element.id + '_animated_tiles') && element) {
1285
+ animateElement = createElement('div', { id: this.mapObject.element.id + '_animated_tiles' });
1286
+ element.appendChild(animateElement);
1287
+ } else {
1288
+ if (type !== 'Pan' && element1 && element) {
1289
+ element1.appendChild(element.children[0]);
1290
+ if (!this.mapObject.isAddLayer && !isNullOrUndefined(document.getElementById(this.mapObject.element.id + '_animated_tiles'))) {
1291
+ document.getElementById(this.mapObject.element.id + '_animated_tiles').id =
1292
+ this.mapObject.element.id + '_animated_tiles_old';
1293
+ }
1294
+ animateElement = createElement('div', { id: this.mapObject.element.id + '_animated_tiles' });
1295
+ element.appendChild(animateElement);
1296
+ } else {
1297
+ animateElement = element ? element.children[0] as HTMLElement : null;
1298
+ }
1299
+ }
1300
+ this.tileProcess(type, animateElement, isPinch);
1301
+ if (!isNullOrUndefined(this.mapObject.currentTiles)) {
1302
+ for (let l: number = this.tiles.length; l < animateElement.childElementCount; l++) {
1303
+ let isExistingElement: boolean = false;
1304
+ for (let a: number = 0; a < this.mapObject.currentTiles.childElementCount; a++) {
1305
+ if (!isExistingElement &&
1306
+ this.mapObject.currentTiles.children[a as number].id === animateElement.children[l as number].id) {
1307
+ isExistingElement = true;
1308
+ }
1309
+ }
1310
+ if (isExistingElement) {
1311
+ (animateElement.children[l as number] as HTMLElement).style.display = 'none';
1312
+ } else {
1313
+ animateElement.removeChild(animateElement.children[l as number]);
1314
+ }
1315
+ }
1316
+ }
1317
+ }, timeOut);
1318
+ } else {
1319
+ let animateElement: HTMLElement = document.getElementById(this.mapObject.element.id + '_animates_tiles');
1320
+ if (isNullOrUndefined(animateElement)) {
1321
+ animateElement = createElement('div', { id: this.mapObject.element.id + '_animates_tiles' });
1322
+ }
1323
+ this.tileProcess(type, animateElement, isPinch);
1324
+ element1.appendChild(animateElement);
1325
+ }
1326
+ }
1327
+
1328
+ private tileProcess(type: string, animateElement: HTMLElement, isPinch?: boolean): void{
1329
+ for (let id: number = 0; id < this.tiles.length; id++) {
1330
+ const tile: Tile = this.tiles[id as number];
1331
+ let imgElement: HTMLImageElement = null;
1332
+ const mapId: string = this.mapObject.element.id;
1333
+ if (type === 'Pan') {
1334
+ let child: HTMLElement = document.getElementById(mapId + '_tile_' + id);
1335
+ let isNewTile: boolean = false;
1336
+ if (isNullOrUndefined(child)) {
1337
+ isNewTile = true;
1338
+ child = createElement('div', { id: mapId + '_tile_' + id });
1339
+ imgElement = createElement('img') as HTMLImageElement;
1340
+ } else {
1341
+ child.style.removeProperty('display');
1342
+ imgElement = <HTMLImageElement>child.children[0];
1343
+ }
1344
+ if (!isNewTile && imgElement && imgElement.src !== tile.src) {
1345
+ imgElement.src = tile.src;
1346
+ }
1347
+ child.style.position = 'absolute';
1348
+ child.style.left = tile.left + 'px';
1349
+ child.style.top = tile.top + 'px';
1350
+ child.style.height = tile.height + 'px';
1351
+ child.style.width = tile.width + 'px';
1352
+ if (isNewTile) {
1353
+ imgElement.setAttribute('height', '256px');
1354
+ imgElement.setAttribute('width', '256px');
1355
+ imgElement.setAttribute('src', tile.src);
1356
+ imgElement.setAttribute('alt', this.mapObject.getLocalizedLabel('ImageNotFound'));
1357
+ imgElement.style.setProperty('user-select', 'none');
1358
+ child.appendChild(imgElement);
1359
+ animateElement.appendChild(child);
1360
+ }
1361
+ } else {
1362
+ imgElement = createElement('img') as HTMLImageElement;
1363
+ imgElement.setAttribute('height', '256px');
1364
+ imgElement.setAttribute('width', '256px');
1365
+ imgElement.setAttribute('src', tile.src);
1366
+ imgElement.style.setProperty('user-select', 'none');
1367
+ imgElement.setAttribute('alt', this.mapObject.getLocalizedLabel('ImageNotFound'));
1368
+ const child: HTMLElement = createElement('div', { id: mapId + '_tile_' + id });
1369
+ child.style.position = 'absolute';
1370
+ child.style.left = tile.left + 'px';
1371
+ child.style.top = tile.top + 'px';
1372
+ child.style.height = tile.height + 'px';
1373
+ child.style.width = tile.width + 'px';
1374
+ child.appendChild(imgElement);
1375
+ if (animateElement) {
1376
+ animateElement.appendChild(child);
1377
+ }
1378
+ }
1379
+ if (!isPinch && id === (this.tiles.length - 1) && document.getElementById(this.mapObject.element.id + '_animated_tiles_old')) {
1380
+ removeElement(this.mapObject.element.id + '_animated_tiles_old');
1381
+ }
1382
+ }
1383
+ }
1384
+
1385
+ /**
1386
+ * Animation for tile layers and hide the group element until the tile layer rendering.
1387
+ *
1388
+ * @param {string} zoomType - Specifies the zoom type
1389
+ * @param {number} translateX - Specifies the x translate point
1390
+ * @param {number} translateY - Specifies the y translate point
1391
+ * @returns {void}
1392
+ */
1393
+ private tileAnimation(zoomType: string, translateX: number, translateY: number): void {
1394
+ const tileParent: HTMLElement = document.getElementById(this.mapObject.element.id + '_tile_parent');
1395
+ const animatedTiles: HTMLElement = document.getElementById(this.mapObject.element.id + '_animated_tiles');
1396
+ const tileElement: HTMLElement = document.getElementById(this.mapObject.element.id + '_tiles');
1397
+ let scaleValue: string = '2';
1398
+ if (zoomType.indexOf('ZoomOut') === 0 || zoomType === 'Reset') {
1399
+ tileElement.style.zIndex = '1';
1400
+ tileParent.style.zIndex = '0';
1401
+ while (tileElement.childElementCount >= 1) {
1402
+ tileElement.removeChild(tileElement.children[0]);
1403
+ }
1404
+ translateX = 0;
1405
+ translateY = document.getElementById(this.mapObject.element.id + '_tile_parent').getClientRects()[0].height / 4;
1406
+ scaleValue = zoomType.indexOf('ZoomOut') === 0 ? '0.5' : '0.2';
1407
+ }
1408
+ if (!isNullOrUndefined(animatedTiles)) {
1409
+ animatedTiles.style.transition = animationMode === 'Disable' ? '0ms' : (this.mapObject.layersCollection[0].animationDuration === 0
1410
+ && animationMode === 'Enable') ? '1000ms' : this.mapObject.layersCollection[0].animationDuration + 'ms';
1411
+ animatedTiles.style.transform = 'translate(' + translateX + 'px, ' + translateY + 'px) scale(' + scaleValue + ')';
1412
+ }
1413
+ }
1414
+
1415
+ /**
1416
+ * To find the tile translate point.
1417
+ *
1418
+ * @param {number} factorX - Specifies the x factor
1419
+ * @param {number} factorY - Specifies the x factor
1420
+ * @param {MapLocation} centerPosition - Specifies the map location
1421
+ * @returns {Point} - Returns point values
1422
+ */
1423
+ private panTileMap(factorX: number, factorY: number, centerPosition: MapLocation): Point {
1424
+ if (this.mapObject.tileZoomLevel <= this.mapObject.tileZoomScale && this.mapObject.initialCheck) {
1425
+ this.mapObject.tileZoomLevel = this.mapObject.tileZoomScale;
1426
+ }
1427
+ const level: number = this.mapObject.tileZoomLevel;
1428
+ let padding: number = 20;
1429
+ let x: number; let y: number;
1430
+ const totalSize: number = Math.pow(2, level) * 256;
1431
+ x = (factorX / 2) - (totalSize / 2);
1432
+ y = (factorY / 2) - (totalSize / 2);
1433
+ const position: MapLocation = convertTileLatLongToPoint(
1434
+ centerPosition, level, { x: x, y: y }, this.isMapCoordinates);
1435
+ padding = this.mapObject.zoomNotApplied ? 0 : padding;
1436
+ x -= position.x - (factorX / 2);
1437
+ y = (y - (position.y - (factorY / 2))) + padding;
1438
+ this.mapObject.scale = Math.pow(2, level - 1);
1439
+ if ((isNullOrUndefined(this.mapObject.tileTranslatePoint) || (this.mapObject.tileTranslatePoint.y === 0 &&
1440
+ this.mapObject.tileTranslatePoint.x === 0)) || (isNullOrUndefined(this.mapObject.previousTileWidth) ||
1441
+ isNullOrUndefined(this.mapObject.previousTileHeight))) {
1442
+ this.mapObject.previousTileWidth = factorX;
1443
+ this.mapObject.previousTileHeight = factorY;
1444
+ }
1445
+ if (!isNullOrUndefined(this.mapObject.tileTranslatePoint) && (isNullOrUndefined(centerPosition.x)) &&
1446
+ (this.mapObject.zoomSettings.zoomFactor === 1 ||
1447
+ this.mapObject.zoomSettings.zoomFactor !== level || !this.mapObject.defaultState)) {
1448
+ if ((factorX !== this.mapObject.previousTileWidth || factorY !== this.mapObject.previousTileHeight) ) {
1449
+ const xdiff: number = x - ((this.mapObject.previousTileWidth / 2) - (totalSize / 2));
1450
+ const ydiff: number = y - ((this.mapObject.previousTileHeight / 2) - (totalSize / 2) + padding);
1451
+ this.mapObject.tileTranslatePoint.x = this.mapObject.tileTranslatePoint.x + xdiff;
1452
+ this.mapObject.tileTranslatePoint.y = this.mapObject.tileTranslatePoint.y + ydiff;
1453
+ }
1454
+ }
1455
+ if (!isNullOrUndefined(this.mapObject.tileTranslatePoint) && !this.mapObject.zoomNotApplied) {
1456
+ if (this.mapObject.tileTranslatePoint.x !== 0 && this.mapObject.tileTranslatePoint.x !== x
1457
+ && !this.mapObject.centerPositionChanged) {
1458
+ x = this.mapObject.tileTranslatePoint.x;
1459
+ }
1460
+ if (this.mapObject.tileTranslatePoint.y !== 0 && this.mapObject.tileTranslatePoint.y !== y
1461
+ && !this.mapObject.centerPositionChanged) {
1462
+ y = this.mapObject.tileTranslatePoint.y;
1463
+ }
1464
+ }
1465
+ this.mapObject.translatePoint = new Point(
1466
+ (x - (0.01 * this.mapObject.zoomSettings.zoomFactor)) / this.mapObject.scale,
1467
+ (y - (0.01 * this.mapObject.zoomSettings.zoomFactor)) / this.mapObject.scale
1468
+ );
1469
+ this.mapObject.previousTileWidth = factorX;
1470
+ this.mapObject.previousTileHeight = factorY;
1471
+ return new Point(x, y);
1472
+ }
1473
+
1474
+ /**
1475
+ * @returns {void}
1476
+ * @private
1477
+ */
1478
+ public destroy(): void {
1479
+ this.mapObject = null;
1480
+ this.groupElements = [];
1481
+ this.layerObject = null;
1482
+ this.currentLayer = null;
1483
+ this.rectBounds = null;
1484
+ this.tiles = [];
1485
+ this.clipRectElement = null;
1486
+ this.tileSvgObject = null;
1487
+ this.ajaxModule = null;
1488
+ this.ajaxResponse = [];
1489
+ this.layerGroup = null;
1490
+ if (!isNullOrUndefined(this.bing)) {
1491
+ this.bing.destroy();
1492
+ }
1493
+ this.bing = null;
1494
+ }
1495
+ }