@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,2886 @@
1
+ /* eslint-disable @typescript-eslint/explicit-module-boundary-types */
2
+ /* eslint-disable @typescript-eslint/no-unused-vars */
3
+ /* eslint-disable radix */
4
+ /* eslint-disable max-len */
5
+ /* eslint-disable valid-jsdoc */
6
+ /**
7
+ * Maps Component file
8
+ */
9
+ import { Component, NotifyPropertyChanges, INotifyPropertyChanged, Property, Ajax } from '@syncfusion/ej2-base';
10
+ import { EventHandler, Browser, EmitType, isNullOrUndefined, createElement, setValue, extend } from '@syncfusion/ej2-base';
11
+ import { Event, remove, L10n, Collection, Internationalization, Complex } from '@syncfusion/ej2-base';
12
+ import { ModuleDeclaration } from '@syncfusion/ej2-base';
13
+ import { SvgRenderer } from '@syncfusion/ej2-svg-base';
14
+ import { Size, createSvg, Point, removeElement, triggerShapeEvent, showTooltip, checkShapeDataFields, MapLocation, getMousePosition, calculateSize } from './utils/helper';
15
+ import { getElement, removeClass, getTranslate, triggerItemSelectionEvent, mergeSeparateCluster, customizeStyle, querySelector } from './utils/helper';
16
+ import { createStyle } from './utils/helper';
17
+ import { ZoomSettings, LegendSettings, Tile } from './model/base';
18
+ import { LayerSettings, TitleSettings, Border, Margin, MapsAreaSettings, Annotation, CenterPosition } from './model/base';
19
+ import { ZoomSettingsModel, LegendSettingsModel, LayerSettingsModel, BubbleSettingsModel } from './model/base-model';
20
+ import { MarkerSettingsModel, SelectionSettingsModel , InitialMarkerSelectionSettingsModel} from './model/base-model';
21
+ import { TitleSettingsModel, BorderModel, MarginModel, CenterPositionModel, InitialShapeSelectionSettingsModel } from './model/base-model';
22
+ import { MapsAreaSettingsModel, AnnotationModel } from './model/base-model';
23
+ import { Bubble } from './layers/bubble';
24
+ import { Legend } from './layers/legend';
25
+ import { Marker } from './layers/marker';
26
+ import { Highlight } from './user-interaction/highlight';
27
+ import { Selection } from './user-interaction/selection';
28
+ import { MapsTooltip } from './user-interaction/tooltip';
29
+ import { Zoom } from './user-interaction/zoom';
30
+ import { load, click, onclick, rightClick, loaded, doubleClick, resize, shapeSelected, itemSelection, zoomIn } from './model/constants';
31
+ import { ProjectionType, MapsTheme, PanDirection, TooltipGesture } from './utils/enum';
32
+ import { MapsModel } from './maps-model';
33
+ import { getThemeStyle, Theme } from './model/theme';
34
+ import { BingMap } from './layers/bing-map';
35
+ import { ILoadEventArgs, ILoadedEventArgs, IMouseEventArgs, IResizeEventArgs, ITooltipRenderEventArgs } from './model/interface';
36
+ import { GeoPosition, ITooltipRenderCompleteEventArgs, ILegendRenderingEventArgs } from './model/interface';
37
+ import { ILayerRenderingEventArgs, IShapeRenderingEventArgs, IMarkerRenderingEventArgs, IMarkerClickEventArgs } from './model/interface';
38
+ import { IMarkerMoveEventArgs, ILabelRenderingEventArgs, IBubbleMoveEventArgs, IBubbleClickEventArgs } from './model/interface';
39
+ import { IMarkerClusterClickEventArgs, IMarkerClusterMoveEventArgs, IMarkerClusterRenderingEventArgs } from './model/interface';
40
+ import { ISelectionEventArgs, IShapeSelectedEventArgs, IMapPanEventArgs, IMapZoomEventArgs } from './model/interface';
41
+ import { IBubbleRenderingEventArgs, IAnimationCompleteEventArgs, IPrintEventArgs, IThemeStyle } from './model/interface';
42
+ import { LayerPanel } from './layers/layer-panel';
43
+ import { GeoLocation, Rect, RectOption, measureText, getElementByID, MapAjax, processResult, getElementsByClassName } from '../maps/utils/helper';
44
+ import { findPosition, textTrim, TextOption, renderTextElement, convertGeoToPoint, calculateZoomLevel } from '../maps/utils/helper';
45
+ import { Annotations } from '../maps/user-interaction/annotation';
46
+ import { FontModel, DataLabel, MarkerSettings, IAnnotationRenderingEventArgs } from './index';
47
+ import { NavigationLineSettingsModel, changeBorderWidth } from './index';
48
+ import { NavigationLine } from './layers/navigation-selected-line';
49
+ import { DataManager, Query } from '@syncfusion/ej2-data';
50
+ import { ExportType } from '../maps/utils/enum';
51
+ import { PdfPageOrientation } from '@syncfusion/ej2-pdf-export';
52
+ import { Print } from './model/print';
53
+ import { PdfExport } from './model/export-pdf';
54
+ import { ImageExport } from './model/export-image';
55
+
56
+ /**
57
+ * Represents the Maps control.
58
+ * ```html
59
+ * <div id="maps"/>
60
+ * <script>
61
+ * var maps = new Maps();
62
+ * maps.appendTo("#maps");
63
+ * </script>
64
+ * ```
65
+ */
66
+ @NotifyPropertyChanges
67
+ export class Maps extends Component<HTMLElement> implements INotifyPropertyChanged {
68
+
69
+ //Module Declaration of Maps.
70
+ /**
71
+ * Sets and gets the module to add bubbles in the maps component.
72
+ */
73
+ public bubbleModule: Bubble;
74
+ /**
75
+ * Sets and get the module to add the marker in the maps component.
76
+ */
77
+ public markerModule: Marker;
78
+ /**
79
+ * Sets and gets the module to add the data-label in the maps component.
80
+ */
81
+ public dataLabelModule: DataLabel;
82
+ /**
83
+ * Sets and gets the module to highlight the element when mouse has hovered on it in maps.
84
+ */
85
+ public highlightModule: Highlight;
86
+ /**
87
+ * Sets and gets the module to add the navigation lines in the maps component.
88
+ */
89
+ public navigationLineModule: NavigationLine;
90
+ /**
91
+ * Sets and gets the module to add the legend in maps.
92
+ */
93
+ public legendModule: Legend;
94
+ /**
95
+ * Sets and gets the module to select the geometric shapes when clicking in maps.
96
+ */
97
+ public selectionModule: Selection;
98
+ /**
99
+ * Sets and gets the module to add the tooltip when mouse has hovered on an element in maps.
100
+ */
101
+ public mapsTooltipModule: MapsTooltip;
102
+ /**
103
+ * Sets and gets the module to add the zooming operations in maps.
104
+ */
105
+ public zoomModule: Zoom;
106
+ /**
107
+ * Sets and gets the module to add annotation elements in maps.
108
+ */
109
+ public annotationsModule: Annotations;
110
+ /**
111
+ * This module enables the print functionality in Maps control.
112
+ *
113
+ * @private
114
+ */
115
+ public printModule: Print;
116
+ /**
117
+ * This module enables the export to PDF functionality in Maps control.
118
+ *
119
+ * @private
120
+ */
121
+ public pdfExportModule: PdfExport;
122
+ /**
123
+ * This module enables the export to image functionality in Maps control.
124
+ *
125
+ * @private
126
+ */
127
+ public imageExportModule: ImageExport;
128
+
129
+
130
+ // Maps pblic API Declaration
131
+
132
+ /**
133
+ * Sets and gets the background color of the maps container.
134
+ *
135
+ * @default null
136
+ */
137
+ @Property(null)
138
+ public background: string;
139
+ /**
140
+ * Enables or disables the visibility state of the separator for grouping.
141
+ *
142
+ * @default false
143
+ */
144
+ @Property(false)
145
+ public useGroupingSeparator: boolean;
146
+ /**
147
+ * Sets and gets the format in which the text in the maps are to be rendered.
148
+ *
149
+ * @default null
150
+ */
151
+ @Property(null)
152
+ public format: string;
153
+ /**
154
+ * Sets and gets the width in which the maps is to be rendered.
155
+ *
156
+ * @default null
157
+ */
158
+ @Property(null)
159
+ public width: string;
160
+ /**
161
+ * Sets and gets the height in which the maps is to be rendered.
162
+ *
163
+ * @default null
164
+ */
165
+ @Property(null)
166
+ public height: string;
167
+ /**
168
+ * Sets and gets the mode in which the tooltip is to be displayed.
169
+ * The tooltip can be rendered on mouse move, click or double clicking on the
170
+ * element on the map.
171
+ *
172
+ * @default 'MouseMove'
173
+ */
174
+ @Property('MouseMove')
175
+ public tooltipDisplayMode: TooltipGesture;
176
+ /**
177
+ * Enables or disables the print functionality in map.
178
+ *
179
+ * @default false
180
+ */
181
+ @Property(false)
182
+ public allowPrint: boolean;
183
+ /**
184
+ * Enables or disables the export to image functionality in map.
185
+ *
186
+ * @default false
187
+ */
188
+ @Property(false)
189
+ public allowImageExport: boolean;
190
+ /**
191
+ * Enables or disables the export to PDF functionality in map.
192
+ *
193
+ * @default false
194
+ */
195
+ @Property(false)
196
+ public allowPdfExport: boolean;
197
+ /**
198
+ * Sets and gets the title to be displayed for maps.
199
+ */
200
+ @Complex<TitleSettingsModel>({}, TitleSettings)
201
+ public titleSettings: TitleSettingsModel;
202
+ /**
203
+ * Sets and gets the options to customize the zooming operations in maps.
204
+ */
205
+ @Complex<ZoomSettingsModel>({}, ZoomSettings)
206
+ public zoomSettings: ZoomSettingsModel;
207
+ /**
208
+ * Sets and gets the options to customize the legend of the maps.
209
+ */
210
+ @Complex<LegendSettingsModel>({}, LegendSettings)
211
+ public legendSettings: LegendSettingsModel;
212
+ /**
213
+ * Sets and gets the options to customize the layers of the maps.
214
+ */
215
+ @Collection<LayerSettingsModel>([], LayerSettings)
216
+ public layers: LayerSettingsModel[];
217
+ /**
218
+ * Sets and gets the options for customizing the annotation of maps.
219
+ */
220
+ @Collection<AnnotationModel>([], Annotation)
221
+ public annotations: AnnotationModel[];
222
+
223
+ /**
224
+ * Sets and gets the options to customize the margins of the maps.
225
+ */
226
+ @Complex<MarginModel>({}, Margin)
227
+ public margin: MarginModel;
228
+
229
+ /**
230
+ * Sets and gets the options for customizing the color and width of the maps border.
231
+ */
232
+ @Complex<BorderModel>({ color: '#DDDDDD', width: 0 }, Border)
233
+ public border: BorderModel;
234
+
235
+ /**
236
+ * Set and gets the theme supported for the maps.
237
+ *
238
+ * @default Material
239
+ */
240
+ @Property('Material')
241
+ public theme: MapsTheme;
242
+ /**
243
+ * Sets and gets the projection type for the maps.
244
+ *
245
+ * @default Mercator
246
+ */
247
+ @Property('Mercator')
248
+ public projectionType: ProjectionType;
249
+ /**
250
+ * Sets and gets the base map index of maps. It provides the option to select which layer to be visible in the maps.
251
+ *
252
+ * @default 0
253
+ */
254
+ @Property(0)
255
+ public baseLayerIndex: number;
256
+
257
+ /**
258
+ * Sets and gets the description for maps.
259
+ *
260
+ * @default null
261
+ */
262
+ @Property(null)
263
+ public description: string;
264
+
265
+ /**
266
+ * Sets and gets the tab index value for the maps.
267
+ *
268
+ * @default 1
269
+ */
270
+ @Property(1)
271
+ public tabIndex: number;
272
+ /**
273
+ * Sets and gets the center position of the maps.
274
+ */
275
+ @Complex<CenterPositionModel>({ latitude: null, longitude: null }, CenterPosition)
276
+ public centerPosition: CenterPositionModel;
277
+ /**
278
+ * Sets and gets the options to customize the area around the map.
279
+ */
280
+ @Complex<MapsAreaSettingsModel>({}, MapsAreaSettings)
281
+ public mapsArea: MapsAreaSettingsModel;
282
+ /**
283
+ * Triggers when the map is on load.
284
+ *
285
+ * @event load
286
+ */
287
+ @Event()
288
+ public load: EmitType<ILoadEventArgs>;
289
+ /**
290
+ * Triggers before the print gets started.
291
+ *
292
+ * @event beforePrint
293
+ */
294
+ @Event()
295
+ public beforePrint: EmitType<IPrintEventArgs>;
296
+ /**
297
+ * Triggers after the maps gets rendered.
298
+ *
299
+ * @event loaded
300
+ */
301
+ @Event()
302
+ public loaded: EmitType<ILoadedEventArgs>;
303
+ /**
304
+ * Triggers when a user clicks on an element in Maps.
305
+ *
306
+ * @event click
307
+ * @deprecated
308
+ */
309
+ @Event()
310
+ public click: EmitType<IMouseEventArgs>;
311
+ /**
312
+ * Triggers when a user clicks on an element in Maps.
313
+ *
314
+ * @event onclick
315
+ */
316
+ @Event()
317
+ public onclick: EmitType<IMouseEventArgs>;
318
+ /**
319
+ * Triggers when performing the double click operation on an element in maps.
320
+ *
321
+ * @event doubleClick
322
+ */
323
+ @Event()
324
+ public doubleClick: EmitType<IMouseEventArgs>;
325
+ /**
326
+ * Triggers when performing the right click operation on an element in maps.
327
+ *
328
+ * @event rightClick
329
+ */
330
+ @Event()
331
+ public rightClick: EmitType<IMouseEventArgs>;
332
+ /**
333
+ * Triggers when resizing the maps.
334
+ *
335
+ * @event resize
336
+ */
337
+ @Event()
338
+ public resize: EmitType<IResizeEventArgs>;
339
+ /**
340
+ * Triggers before the maps tooltip gets rendered.
341
+ *
342
+ * @event tooltipRender
343
+ */
344
+ @Event()
345
+ public tooltipRender: EmitType<ITooltipRenderEventArgs>;
346
+ /**
347
+ * Triggers before the legend gets rendered.
348
+ *
349
+ * @event legendRendering
350
+ * @deprecated
351
+ */
352
+ @Event()
353
+ public legendRendering: EmitType<ILegendRenderingEventArgs>;
354
+ /**
355
+ * Triggers after the maps tooltip gets rendered.
356
+ *
357
+ * @deprecated
358
+ * @event tooltipRenderComplete
359
+ */
360
+ @Event()
361
+ public tooltipRenderComplete: EmitType<ITooltipRenderCompleteEventArgs>;
362
+ /**
363
+ * Triggers when clicking a shape in maps.
364
+ *
365
+ * @event shapeSelected
366
+ */
367
+ @Event()
368
+ public shapeSelected: EmitType<IShapeSelectedEventArgs>;
369
+ /**
370
+ * Triggers when clicking the shape on maps and before the selection is applied.
371
+ *
372
+ * @event itemSelection
373
+ */
374
+ @Event()
375
+ public itemSelection: EmitType<ISelectionEventArgs>;
376
+ /**
377
+ * Trigger when mouse move on the shape in maps and before the shape gets highlighted.
378
+ *
379
+ * @event itemHighlight
380
+ */
381
+ @Event()
382
+ public itemHighlight: EmitType<ISelectionEventArgs>;
383
+ /**
384
+ * Triggers when mouse move on the shape in maps and before the shape gets highlighted.
385
+ *
386
+ * @event shapeHighlight
387
+ */
388
+ @Event()
389
+ public shapeHighlight: EmitType<IShapeSelectedEventArgs>;
390
+ /**
391
+ * Triggers before the maps layer gets rendered.
392
+ *
393
+ * @event layerRendering
394
+ */
395
+ @Event()
396
+ public layerRendering: EmitType<ILayerRenderingEventArgs>;
397
+
398
+ /**
399
+ * Triggers before the maps shape gets rendered.
400
+ *
401
+ * @event shapeRendering
402
+ */
403
+ @Event()
404
+ public shapeRendering: EmitType<IShapeRenderingEventArgs>;
405
+
406
+ /**
407
+ * Triggers before the maps marker gets rendered.
408
+ *
409
+ * @event markerRendering
410
+ */
411
+ @Event()
412
+ public markerRendering: EmitType<IMarkerRenderingEventArgs>;
413
+ /**
414
+ * Triggers before the maps marker cluster gets rendered.
415
+ *
416
+ * @event markerClusterRendering
417
+ */
418
+ @Event()
419
+ public markerClusterRendering: EmitType<IMarkerClusterRenderingEventArgs>;
420
+
421
+ /**
422
+ * Triggers when clicking on the maps marker element.
423
+ *
424
+ * @event markerClick
425
+ */
426
+ @Event()
427
+ public markerClick: EmitType<IMarkerClickEventArgs>;
428
+
429
+ /**
430
+ * Triggers when clicking the marker cluster in maps.
431
+ *
432
+ * @event markerClusterClick
433
+ */
434
+ @Event()
435
+ public markerClusterClick: EmitType<IMarkerClusterClickEventArgs>;
436
+
437
+ /**
438
+ * Triggers when moving the mouse over the marker cluster element in maps.
439
+ *
440
+ * @event markerClusterMouseMove
441
+ */
442
+ @Event()
443
+ public markerClusterMouseMove: EmitType<IMarkerClusterMoveEventArgs>;
444
+
445
+ /**
446
+ * Triggers when moving the mouse over the marker element in maps.
447
+ *
448
+ * @event markerMouseMove
449
+ */
450
+ @Event()
451
+ public markerMouseMove: EmitType<IMarkerMoveEventArgs>;
452
+
453
+ /**
454
+ * Triggers before the data-label gets rendered.
455
+ *
456
+ * @event dataLabelRendering
457
+ */
458
+ @Event()
459
+ public dataLabelRendering: EmitType<ILabelRenderingEventArgs>;
460
+
461
+ /**
462
+ * Triggers before the bubble element gets rendered on the map.
463
+ *
464
+ * @event bubbleRendering
465
+ */
466
+ @Event()
467
+ public bubbleRendering: EmitType<IBubbleRenderingEventArgs>;
468
+
469
+ /**
470
+ * Triggers when performing the click operation on the bubble element in maps.
471
+ *
472
+ * @event bubbleClick
473
+ */
474
+ @Event()
475
+ public bubbleClick: EmitType<IBubbleClickEventArgs>;
476
+
477
+ /**
478
+ * Triggers when hovering the mouse on the bubble element in maps.
479
+ *
480
+ * @event bubbleMouseMove
481
+ */
482
+ @Event()
483
+ public bubbleMouseMove: EmitType<IBubbleMoveEventArgs>;
484
+
485
+ /**
486
+ * Triggers after the animation completed in the maps component.
487
+ *
488
+ * @event animationComplete
489
+ */
490
+ @Event()
491
+ public animationComplete: EmitType<IAnimationCompleteEventArgs>;
492
+
493
+ /**
494
+ * Triggers before rendering the annotation in maps.
495
+ *
496
+ * @event annotationRendering
497
+ */
498
+ @Event()
499
+ public annotationRendering: EmitType<IAnnotationRenderingEventArgs>;
500
+
501
+ /**
502
+ * Triggers before the zoom operations in the maps such as zoom in and zoom out.
503
+ *
504
+ * @event zoom
505
+ */
506
+ @Event()
507
+ public zoom: EmitType<IMapZoomEventArgs>;
508
+
509
+ /**
510
+ * Triggers before performing the panning operation.
511
+ *
512
+ * @event pan
513
+ */
514
+ @Event()
515
+ public pan: EmitType<IMapPanEventArgs>;
516
+
517
+ // Internal properties declaration area.
518
+ /**
519
+ * Specifies the function to format the text contents in the maps.
520
+ *
521
+ * @private
522
+ */
523
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
524
+ public formatFunction: any;
525
+ /**
526
+ * Specifies the svg renderer object.
527
+ *
528
+ * @private
529
+ */
530
+ public renderer: SvgRenderer;
531
+ /**
532
+ * Specifies the svg element's object of maps.
533
+ *
534
+ * @private
535
+ */
536
+ public svgObject: Element;
537
+ /** @public */
538
+ public mapScaleValue: number;
539
+ /**
540
+ * Specifies the available height and width of maps.
541
+ *
542
+ * @private
543
+ */
544
+ public availableSize: Size;
545
+
546
+ /**
547
+ * whether it is layer add or not.
548
+ *
549
+ * @private
550
+ */
551
+ public isAddLayer: boolean;
552
+
553
+ /**
554
+ * Specifies the localization object.
555
+ *
556
+ * @private
557
+ */
558
+ public localeObject: L10n;
559
+ /**
560
+ * Specifies the default values of localization values.
561
+ */
562
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
563
+ private defaultLocalConstants: any;
564
+
565
+ /**
566
+ * Internal use of internationalization instance.
567
+ *
568
+ * @private
569
+ */
570
+ public intl: Internationalization;
571
+
572
+ /**
573
+ * Check layer whether is geometry or tile
574
+ *
575
+ * @private
576
+ */
577
+ public isTileMap: boolean = false;
578
+
579
+ /**
580
+ * Resize the map
581
+ */
582
+ private resizeTo: number;
583
+
584
+ /**
585
+ * Resize the map
586
+ */
587
+ private isResize: boolean = false;
588
+
589
+ /**
590
+ * @private
591
+ */
592
+
593
+ public mapAreaRect: Rect;
594
+
595
+ /**
596
+ * @private
597
+ */
598
+ public layersCollection: LayerSettings[];
599
+
600
+ /**
601
+ * @private
602
+ * @hidden
603
+ */
604
+ public mapLayerPanel: LayerPanel;
605
+ /**
606
+ * @private
607
+ * @hidden
608
+ */
609
+ /**
610
+ * @private
611
+ */
612
+ public themeStyle: IThemeStyle;
613
+ /**
614
+ * @private
615
+ */
616
+ public isReset: boolean = false;
617
+ /**
618
+ * @private
619
+ */
620
+ public totalRect: Rect;
621
+ /**
622
+ *
623
+ * Specifies whether the shape is selected in the maps or not.
624
+ *
625
+ * @returns {boolean} - Returns the boolean value.
626
+ */
627
+ public get isShapeSelected(): boolean {
628
+ return this.mapSelect;
629
+ }
630
+ public dataLabel: DataLabel;
631
+ /** @private */
632
+ public isTouch: boolean;
633
+ /** @private */
634
+ public baseSize: Size = new Size(0, 0);
635
+ /** @private */
636
+ public scale: number;
637
+ /** @private */
638
+ public baseScale: number;
639
+ /** @private */
640
+ public mapSelect: boolean;
641
+ /** @private */
642
+ public baseMapBounds: GeoLocation;
643
+ /** @private */
644
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
645
+ public baseMapRectBounds: any;
646
+ /** @public */
647
+ public translatePoint: Point = new Point(0, 0);
648
+ /** @private */
649
+ public baseTranslatePoint: Point = new Point(0, 0);
650
+ /** @public */
651
+ public zoomTranslatePoint: Point = new Point(0, 0);
652
+ /** @private */
653
+ public markerZoomFactor: number;
654
+ /** @private */
655
+ public markerZoomCenterPoint: CenterPositionModel;
656
+ /** @private */
657
+ public markerZoomedState: boolean = true;
658
+ /** @private */
659
+ public zoomPersistence: boolean = false;
660
+ /** @private */
661
+ public defaultState: boolean = true;
662
+ /** @private */
663
+ public markerCenterLatitude: number;
664
+ /** @private */
665
+ public markerCenterLongitude: number;
666
+ /** @private */
667
+ public previousCenterLatitude: number;
668
+ /** @private */
669
+ public previousCenterLongitude: number;
670
+ /** @private */
671
+ public centerPositionChanged: boolean = false;
672
+ /** @private */
673
+ public previousZoomFactor: number;
674
+ /** @private */
675
+ public isTileMapSubLayer: boolean = false;
676
+ /** @private */
677
+ public shouldZoomCurrentFactor: number;
678
+ /** @private */
679
+ public shouldZoomPreviousFactor: number;
680
+ /** @private */
681
+ public markerNullCount: number = 0;
682
+ /** @private */
683
+ public translateType: string;
684
+ /** @public */
685
+ // eslint-disable-next-line @typescript-eslint/ban-types
686
+ public previousProjection: String;
687
+ /** @private */
688
+ public currentShapeDataLength: number;
689
+ /** @private */
690
+ public tileTranslatePoint: Point = new Point(0, 0);
691
+ /** @private */
692
+ public baseTileTranslatePoint: Point = new Point(0, 0);
693
+ /** @private */
694
+ // eslint-disable-next-line @typescript-eslint/ban-types
695
+ public isDevice: Boolean = false;
696
+ /** @private */
697
+ public tileZoomLevel: number;
698
+ /** @private */
699
+ public tileZoomScale: number;
700
+ /** @private */
701
+ public staticMapZoom: number = this.zoomSettings.enable ? this.zoomSettings.zoomFactor : 0;
702
+ /** @private */
703
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
704
+ public serverProcess: any;
705
+ /** @private */
706
+ public previousScale: number;
707
+ /** @private */
708
+ public previousPoint: Point;
709
+ /** @private */
710
+ public centerLatOfGivenLocation: number;
711
+ /** @private */
712
+ public centerLongOfGivenLocation: number;
713
+ /** @private */
714
+ public minLatOfGivenLocation: number;
715
+ /** @private */
716
+ public minLongOfGivenLocation: number;
717
+ /** @private */
718
+ public maxLatOfGivenLocation: number;
719
+ /** @private */
720
+ public maxLongOfGivenLocation: number;
721
+ /** @private */
722
+ public scaleOfGivenLocation: number;
723
+ /** @private */
724
+ public zoomNotApplied: boolean = false;
725
+ /** @public */
726
+ public dataLabelShape: number[] = [];
727
+ public zoomShapeCollection: object[] = [];
728
+ public zoomLabelPositions: object[] = [];
729
+ public mouseDownEvent: Object = { x: null, y: null };
730
+ public mouseClickEvent: Object = { x: null, y: null };
731
+
732
+ /** @private */
733
+ public shapeSelectionClass: Element;
734
+ /** @private */
735
+ public selectedElementId: string[] = [];
736
+ /** @private */
737
+ public markerSelectionClass: Element;
738
+ /** @private */
739
+ public selectedMarkerElementId: string[] = [];
740
+ /** @private */
741
+ public bubbleSelectionClass: Element;
742
+ /** @private */
743
+ public selectedBubbleElementId: string[] = [];
744
+ /** @private */
745
+ public navigationSelectionClass: Element;
746
+ /** @private */
747
+ public selectedNavigationElementId: string[] = [];
748
+ /** @private */
749
+ public legendSelectionClass: SelectionSettingsModel;
750
+ /** @private */
751
+ public selectedLegendElementId: number[] = [];
752
+ /** @private */
753
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
754
+ public legendSelectionCollection: any[] = [];
755
+ /** @private */
756
+ public shapeSelections: boolean = true;
757
+ /** @private */
758
+ public legendSelection: boolean = true;
759
+ /** @private */
760
+ public toggledLegendId: number[] = [];
761
+ /** @private */
762
+ public toggledShapeElementId: string[] = [];
763
+ /** @private */
764
+ public checkInitialRender: boolean = true;
765
+ /** @private */
766
+ public widthBeforeRefresh: number;
767
+ /** @private */
768
+ public heightBeforeRefresh: number;
769
+ /** @private */
770
+ public previousTranslate: Point;
771
+ /** @private */
772
+ public initialTileTranslate: Point = new Point(0, 0);
773
+ /** @private */
774
+ public previousTileWidth: number;
775
+ /** @private */
776
+ public previousTileHeight: number;
777
+ /** @private */
778
+ public initialZoomLevel: number;
779
+ /** @private */
780
+ public initialCheck: boolean = true;
781
+ /** @private */
782
+ public applyZoomReset: boolean = false;
783
+ /** @private */
784
+ public markerClusterExpandCheck: boolean = false;
785
+ /** @private */
786
+ public markerClusterExpand: boolean = false;
787
+ /** @private */
788
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
789
+ public shapeSelectionItem: any[] = [];
790
+
791
+ /**
792
+ * Constructor for creating the widget
793
+ *
794
+ * @param {MapsModel} options Specifies the options
795
+ * @param {string | HTMLElement} element Specifies the element
796
+ */
797
+ constructor(options?: MapsModel, element?: string | HTMLElement) {
798
+ super(options, <HTMLElement | string>element);
799
+ setValue('mergePersistData', this.mergePersistMapsData, this);
800
+ }
801
+ /**
802
+ * To manage persist maps data
803
+ *
804
+ * @returns {void}
805
+ */
806
+ private mergePersistMapsData(): void {
807
+ let data: string;
808
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
809
+ let windowData: any;
810
+ try {
811
+ windowData = window.localStorage;
812
+ } catch (e) {
813
+ windowData = null;
814
+ }
815
+ if (!isNullOrUndefined(windowData)) {
816
+ data = window.localStorage.getItem(this.getModuleName() + this.element.id);
817
+ }
818
+ if (!(isNullOrUndefined(data) || (data === ''))) {
819
+ const dataObj: Maps = JSON.parse(data);
820
+ const keys: string[] = Object.keys(dataObj);
821
+ this.isProtectedOnChange = true;
822
+ for (const key of keys) {
823
+ if ((typeof this[key] === 'object') && !isNullOrUndefined(this[key])) {
824
+ extend(this[key], dataObj[key]);
825
+ } else {
826
+ this[key] = dataObj[key];
827
+ }
828
+ }
829
+ this.isProtectedOnChange = false;
830
+ }
831
+
832
+ }
833
+ /**
834
+ * Gets the localized label by locale keyword.
835
+ *
836
+ * @param {string} key - Specifies the key
837
+ * @returns {string} - Returns the string value
838
+ */
839
+ public getLocalizedLabel(key: string): string {
840
+ return this.localeObject.getConstant(key);
841
+ }
842
+ /**
843
+ * Initializing pre-required values.
844
+ *
845
+ * @returns {void}
846
+ */
847
+ protected preRender(): void {
848
+ this.isDevice = Browser.isDevice;
849
+ this.initPrivateVariable();
850
+ this.allowServerDataBinding = false;
851
+ this.unWireEVents();
852
+ this.wireEVents();
853
+ this.setCulture();
854
+ }
855
+ private renderElements(): void {
856
+ this.trigger(load, { maps: this });
857
+ this.createSVG();
858
+ this.findBaseAndSubLayers();
859
+ this.createSecondaryElement();
860
+ this.addTabIndex();
861
+ this.themeStyle = getThemeStyle(this.theme);
862
+ this.renderBorder();
863
+ this.renderTitle(this.titleSettings, 'title', null, null);
864
+ this.renderArea();
865
+ this.processRequestJsonData();
866
+ this.renderComplete();
867
+ this.isAddLayer = !this.isTileMap ? false : this.isAddLayer;
868
+ }
869
+ /**
870
+ * To Initialize the control rendering.
871
+ *
872
+ * @returns {void}
873
+ */
874
+ protected render(): void {
875
+ this.renderElements();
876
+ }
877
+
878
+ protected processRequestJsonData(): void {
879
+ const length: number = this.layersCollection.length - 1;
880
+ this.serverProcess = { request: 0, response: 0 }; let queryModule: Query;
881
+ let localAjax: MapAjax; let ajaxModule: Ajax; let dataModule: DataManager;
882
+ Array.prototype.forEach.call(this.layersCollection, (layer: LayerSettings, layerIndex: number) => {
883
+ if (layer.shapeData instanceof DataManager) {
884
+ this.serverProcess['request']++;
885
+ dataModule = layer.shapeData;
886
+ queryModule = layer.query instanceof Query ? layer.query : new Query();
887
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
888
+ const dataManager: Promise<any> = dataModule.executeQuery(queryModule);
889
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
890
+ dataManager.then((e: any) => {
891
+ this.processResponseJsonData('DataManager', e, layer, 'ShapeData');
892
+ });
893
+ } else if (layer.shapeData instanceof MapAjax || layer.shapeData) {
894
+ if (!isNullOrUndefined(layer.shapeData['dataOptions'])) {
895
+ this.processAjaxRequest(layer, layer.shapeData, 'ShapeData');
896
+ }
897
+ }
898
+ if (layer.dataSource instanceof DataManager) {
899
+ this.serverProcess['request']++;
900
+ dataModule = layer.dataSource as DataManager;
901
+ queryModule = layer.query instanceof Query ? layer.query : new Query();
902
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
903
+ const dataManager: Promise<any> = dataModule.executeQuery(queryModule);
904
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
905
+ dataManager.then((e: any) => {
906
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
907
+ layer.dataSource = processResult(e) as any[];
908
+ });
909
+ }
910
+ if (layer.markerSettings.length > 0) {
911
+ for (let i: number = 0; i < layer.markerSettings.length; i++) {
912
+ if (layer.markerSettings[i].dataSource instanceof DataManager) {
913
+ this.serverProcess['request']++;
914
+ dataModule = layer.markerSettings[i].dataSource as DataManager;
915
+ queryModule = layer.markerSettings[i].query instanceof Query ? layer.markerSettings[i].query : new Query();
916
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
917
+ const dataManager: Promise<any> = dataModule.executeQuery(queryModule);
918
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
919
+ dataManager.then((e: any) => {
920
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
921
+ layer.markerSettings[i].dataSource = processResult(e) as any[];
922
+ });
923
+ }
924
+ }
925
+ }
926
+ if (layer.bubbleSettings.length > 0) {
927
+ for (let i: number = 0; i < layer.bubbleSettings.length; i++) {
928
+ if (layer.bubbleSettings[i].dataSource instanceof DataManager) {
929
+ this.serverProcess['request']++;
930
+ dataModule = layer.bubbleSettings[i].dataSource as DataManager;
931
+ queryModule = layer.bubbleSettings[i].query instanceof Query ? layer.bubbleSettings[i].query : new Query();
932
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
933
+ const dataManager: Promise<any> = dataModule.executeQuery(queryModule);
934
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
935
+ dataManager.then((e: any) => {
936
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
937
+ layer.bubbleSettings[i].dataSource = processResult(e) as any[];
938
+ });
939
+ }
940
+ }
941
+ }
942
+ if (layer.dataSource instanceof MapAjax || !isNullOrUndefined(layer.dataSource['dataOptions'])) {
943
+ this.processAjaxRequest(layer, layer.dataSource, 'DataSource');
944
+ }
945
+ if (this.serverProcess['request'] === this.serverProcess['response'] && length === layerIndex) {
946
+ this.processResponseJsonData(null);
947
+ }
948
+ });
949
+ }
950
+ /* eslint-disable @typescript-eslint/no-explicit-any */
951
+ private processAjaxRequest(layer: LayerSettings, localAjax: MapAjax | any, type: string): void {
952
+ this.serverProcess['request']++;
953
+ const ajaxModule: Ajax = new Ajax(localAjax.dataOptions, localAjax.type, localAjax.async, localAjax.contentType);
954
+ ajaxModule.onSuccess = (args: string) => {
955
+ this.processResponseJsonData('Ajax', args, layer, type);
956
+ };
957
+ ajaxModule.send(localAjax.sendData);
958
+ }
959
+ /**
960
+ * This method is used to process the JSON data to render the maps.
961
+ *
962
+ * @param {string} processType - Specifies the process type in maps.
963
+ * @param {any | string} data - Specifies the data for maps.
964
+ * @param {LayerSettings} layer - Specifies the layer for the maps.
965
+ * @param {string} dataType - Specifies the data type for maps.
966
+ * @returns {void}
967
+ */
968
+ public processResponseJsonData(processType: string, data?: any | string, layer?: LayerSettings, dataType?: string): void {
969
+ this.serverProcess['response']++;
970
+ if (processType) {
971
+ if (dataType === 'ShapeData') {
972
+ layer.shapeData = (processType === 'DataManager') ? processResult((data as any)) : JSON.parse(data as string);
973
+ } else {
974
+ layer.dataSource = (processType === 'DataManager') ? processResult((data as any)) : JSON.parse('[' + data + ']')[0];
975
+ }
976
+ }
977
+ if (!isNullOrUndefined(processType) && this.serverProcess['request'] === this.serverProcess['response']) {
978
+ const collection: LayerSettings[] = this.layersCollection;
979
+ this.layersCollection = [];
980
+ for (let i: number = 0; i < collection.length; i++) {
981
+ if (collection[i].isBaseLayer) {
982
+ this.layersCollection.push(collection[i]);
983
+ }
984
+ }
985
+ for (let j: number = 0; j < collection.length; j++) {
986
+ if (!collection[j].isBaseLayer) {
987
+ this.layersCollection.push(collection[j]);
988
+ }
989
+ }
990
+ this.renderMap();
991
+ } else if (isNullOrUndefined(processType)) {
992
+ this.renderMap();
993
+ }
994
+ }
995
+
996
+ private renderMap(): void {
997
+ if (this.legendModule && this.legendSettings.visible) {
998
+ this.legendModule.renderLegend();
999
+ }
1000
+ this.createTile();
1001
+ if (this.zoomSettings.enable && this.zoomModule) {
1002
+ this.zoomModule.createZoomingToolbars();
1003
+ }
1004
+ if (!isNullOrUndefined(this.dataLabelModule)) {
1005
+ this.dataLabelModule.dataLabelCollections = [];
1006
+ this.dataLabelShape = [];
1007
+ }
1008
+ this.mapLayerPanel.measureLayerPanel();
1009
+ if (!isNullOrUndefined(this.svgObject)) {
1010
+ this.element.appendChild(this.svgObject);
1011
+ }
1012
+ const position: Point = this.getExtraPosition();
1013
+ for (let i: number = 0; i < this.layers.length; i++) {
1014
+ if (position.x !== 0 || position.y !== 0) {
1015
+ let markerTemplate: HTMLElement = document.getElementById(this.element.id + '_LayerIndex_' + i + '_Markers_Template_Group');
1016
+ if (!isNullOrUndefined(markerTemplate)) {
1017
+ markerTemplate.style.top = this.mapAreaRect.y + position.y + 'px';
1018
+ markerTemplate.style.left = this.mapAreaRect.x + position.x + 'px';
1019
+ }
1020
+ }
1021
+ if (this.layers[i].selectionSettings && this.layers[i].selectionSettings.enable &&
1022
+ this.layers[i].initialShapeSelection.length > 0 && this.checkInitialRender) {
1023
+ const checkSelection: boolean = this.layers[i].selectionSettings.enableMultiSelect;
1024
+ this.layers[i].selectionSettings.enableMultiSelect = checkSelection ? checkSelection : true;
1025
+ const shapeSelection: InitialShapeSelectionSettingsModel[] = this.layers[i].initialShapeSelection;
1026
+ for (let j: number = 0; j < this.layers[i].initialShapeSelection.length; j++) {
1027
+ this.shapeSelection(i, shapeSelection[j].shapePath, shapeSelection[j].shapeValue, true);
1028
+ }
1029
+ this.layers[i].selectionSettings.enableMultiSelect = checkSelection;
1030
+ if (i === this.layers.length - 1) { this.checkInitialRender = false; }
1031
+ }
1032
+ if (!this.isResize) {
1033
+ for (let k : number = 0; k < this.layers[i].markerSettings.length; k++) {
1034
+ if (this.layers[i].markerSettings[k].selectionSettings && this.layers[i].markerSettings[k].selectionSettings.enable
1035
+ && this.layers[i].markerSettings[k].initialMarkerSelection.length > 0) {
1036
+ const markerSelectionValues : InitialMarkerSelectionSettingsModel[] =
1037
+ this.layers[i].markerSettings[k].initialMarkerSelection;
1038
+ for (let j : number = 0; j < markerSelectionValues.length; j++) {
1039
+ this.markerInitialSelection(i, k, this.layers[i].markerSettings[k], markerSelectionValues[j].latitude,
1040
+ markerSelectionValues[j].longitude);
1041
+ }
1042
+ }
1043
+ }
1044
+ }
1045
+ }
1046
+ if (!isNullOrUndefined(document.getElementById(this.element.id + '_tile_parent'))) {
1047
+ const svg: ClientRect = this.svgObject.getBoundingClientRect();
1048
+ const element: HTMLElement = document.getElementById(this.element.id);
1049
+ const tileElement: HTMLElement = document.getElementById(this.element.id + '_tile_parent');
1050
+ const tileElement1: HTMLElement = document.getElementById(this.element.id + '_tiles');
1051
+ const tile: ClientRect = tileElement.getBoundingClientRect();
1052
+ let bottom: number; let top: number; let left: number;
1053
+ left = parseFloat(tileElement.style.left) + element.offsetLeft;
1054
+ const titleTextSize: Size = measureText(
1055
+ this.titleSettings.text,
1056
+ this.titleSettings.textStyle
1057
+ );
1058
+ const subTitleTextSize: Size = measureText(
1059
+ this.titleSettings.subtitleSettings.text,
1060
+ this.titleSettings.subtitleSettings.textStyle
1061
+ );
1062
+ if (this.isTileMap && this.isTileMapSubLayer && this.legendSettings.position === 'Bottom' && this.legendSettings.visible) {
1063
+ if (this.legendSettings.mode !== 'Default') {
1064
+ if (titleTextSize.width !== 0 && titleTextSize.height !== 0) {
1065
+ top = parseFloat(tileElement.style.top) + element.offsetTop + (subTitleTextSize.height / 2)
1066
+ - (this.legendModule.legendBorderRect.height / 2);
1067
+ } else {
1068
+ top = parseFloat(tileElement.style.top) + element.offsetTop - this.mapAreaRect.y;
1069
+ }
1070
+ } else {
1071
+ left = this.legendModule.legendBorderRect.x;
1072
+ if (titleTextSize.width !== 0 && titleTextSize.height !== 0) {
1073
+ top = parseFloat(tileElement.style.top) + element.offsetTop + (subTitleTextSize['height'] / 2)
1074
+ - this.legendModule.legendBorderRect.y;
1075
+ } else {
1076
+ top = parseFloat(tileElement.style.top) + element.offsetTop + (subTitleTextSize['height'] / 2);
1077
+ }
1078
+ }
1079
+ } else {
1080
+ bottom = svg.bottom - tile.bottom - element.offsetTop;
1081
+ top = parseFloat(tileElement.style.top) + element.offsetTop;
1082
+ }
1083
+ top = (bottom <= 11) ? top : (!isNullOrUndefined(this.legendModule) && this.legendSettings.position === 'Bottom') ? this.mapAreaRect.y : (top * 2);
1084
+ left = (bottom <= 11) ? left : !isNullOrUndefined(this.legendModule) ? left : (left * 2);
1085
+ tileElement.style.top = top + 'px';
1086
+ tileElement.style.left = left + 'px';
1087
+ tileElement1.style.top = top + 'px';
1088
+ tileElement1.style.left = left + 'px';
1089
+ if (!isNullOrUndefined(this.legendModule) && this.legendModule.totalPages.length > 0) {
1090
+ tileElement.style.height = tileElement1.style.height = this.legendModule.legendTotalRect.height + 'px';
1091
+ tileElement.style.width = tileElement1.style.width = this.legendModule.legendTotalRect.width + 'px';
1092
+ }
1093
+ }
1094
+
1095
+ this.arrangeTemplate();
1096
+
1097
+ if (this.annotationsModule) {
1098
+ if (this.width !== '0px' && this.height !== '0px' && this.width !== '0%' && this.height !== '0%') {
1099
+ this.annotationsModule.renderAnnotationElements();
1100
+ }
1101
+ }
1102
+ this.element.style.outline = 'none';
1103
+ for (let i: number = 0; i < document.getElementsByTagName('path').length - 1; i++) {
1104
+ if (document.getElementsByTagName('path')[i].id.indexOf('shapeIndex') > -1) {
1105
+ document.getElementsByTagName('path')[i].style.outline = 'none';
1106
+ }
1107
+ }
1108
+ this.zoomingChange();
1109
+ this.trigger(loaded, { maps: this, isResized: this.isResize });
1110
+ this.isResize = false;
1111
+ }
1112
+
1113
+ /**
1114
+ * To apply color to the initial selected marker
1115
+ *
1116
+ * @param {SelectionSettingsModel} selectionSettings - Specifies the selection settings
1117
+ * @param {Maps} map - Specifies the instance of the maps
1118
+ * @param {Element} targetElement - Specifies the target element
1119
+ * @param {any} data - Specifies the data
1120
+ * @returns {void}
1121
+ * @private
1122
+ */
1123
+ public markerSelection(
1124
+ selectionSettings : SelectionSettingsModel, map : Maps, targetElement : Element,
1125
+ data : any
1126
+ ) : void {
1127
+ const border : BorderModel = {
1128
+ color: selectionSettings.border.color,
1129
+ width: selectionSettings.border.width / map.scale,
1130
+ opacity: selectionSettings.border.opacity
1131
+ };
1132
+ const markerSelectionProperties : any = {
1133
+ opacity: selectionSettings.opacity,
1134
+ fill: selectionSettings.fill,
1135
+ border: border,
1136
+ target: targetElement.id,
1137
+ cancel: false,
1138
+ data: data,
1139
+ maps: map
1140
+ };
1141
+
1142
+ if (!getElement('MarkerselectionMap')) {
1143
+ document.body.appendChild(createStyle('MarkerselectionMap', 'MarkerselectionMapStyle', markerSelectionProperties));
1144
+ } else {
1145
+ customizeStyle('MarkerselectionMap', 'MarkerselectionMapStyle', markerSelectionProperties);
1146
+ }
1147
+ if (this.selectedMarkerElementId.length === 0 || selectionSettings.enableMultiSelect) {
1148
+ if (targetElement.tagName === 'g') {
1149
+ targetElement.children[0].setAttribute('class', 'MarkerselectionMapStyle');
1150
+ this.selectedMarkerElementId.push(targetElement.children[0].id);
1151
+ } else {
1152
+ targetElement.setAttribute('class', 'MarkerselectionMapStyle');
1153
+ this.selectedMarkerElementId.push(targetElement.id);
1154
+ }
1155
+ }
1156
+ }
1157
+ /**
1158
+ * initial selection of marker
1159
+ *
1160
+ * @param {number} layerIndex - Specifies the layer index
1161
+ * @param {number} markerIndex - Specifies the marker index
1162
+ * @param {MarkerSettingsModel} markerSettings - Specifies the marker settings
1163
+ * @param {number} latitude - Specifies hte latitude
1164
+ * @param {number} longitude - Specifies the longitude
1165
+ * @returns {void}
1166
+ * @private
1167
+ */
1168
+ public markerInitialSelection(
1169
+ layerIndex : number, markerIndex : number, markerSettings : MarkerSettingsModel,
1170
+ latitude : number, longitude : number
1171
+ ): void {
1172
+ const selectionSettings : SelectionSettingsModel = markerSettings.selectionSettings;
1173
+ if (selectionSettings.enable) {
1174
+ for (let i : number = 0; i < markerSettings.dataSource['length']; i++) {
1175
+ const data: any = markerSettings.dataSource[i];
1176
+ if (data['latitude'] === latitude && data['longitude'] === longitude) {
1177
+ const targetId : string = this.element.id + '_' + 'LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex +
1178
+ '_dataIndex_' + i;
1179
+ this.markerSelection(selectionSettings, this, getElement(targetId), data);
1180
+ }
1181
+ }
1182
+ }
1183
+ }
1184
+
1185
+ /**
1186
+ * Render the map area border
1187
+ *
1188
+ * @returns {void}
1189
+ */
1190
+ private renderArea(): void {
1191
+ const width: number = this.mapsArea.border.width;
1192
+ const background: string = this.mapsArea.background;
1193
+ if (width > 0 || (background || this.themeStyle.areaBackgroundColor)) {
1194
+ const mapBorder: BorderModel = {
1195
+ opacity: isNullOrUndefined(this.mapsArea.border.opacity) ? 1 : this.mapsArea.border.opacity,
1196
+ color: this.mapsArea.border.color, width: this.mapsArea.border.width
1197
+ };
1198
+ const rect: RectOption = new RectOption(
1199
+ this.element.id + '_MapAreaBorder', background || this.themeStyle.areaBackgroundColor,
1200
+ mapBorder, 1, this.mapAreaRect
1201
+ );
1202
+ this.svgObject.appendChild(this.renderer.drawRectangle(rect) as SVGRectElement);
1203
+ }
1204
+ }
1205
+ /**
1206
+ * To add tab index for map element
1207
+ *
1208
+ * @returns {void}
1209
+ */
1210
+ private addTabIndex(): void {
1211
+ this.element.setAttribute('aria-label', this.description || 'Maps Element');
1212
+ this.element.setAttribute('role', '');
1213
+ this.element.setAttribute('tabindex', this.tabIndex.toString());
1214
+ }
1215
+
1216
+ // private setSecondaryElementPosition(): void {
1217
+ // if (!this.isTileMap) {
1218
+ // let element: HTMLDivElement = getElementByID(this.element.id + '_Secondary_Element') as HTMLDivElement;
1219
+ // let rect: ClientRect = this.element.getBoundingClientRect();
1220
+ // let svgRect: ClientRect = getElementByID(this.element.id + '_svg').getBoundingClientRect();
1221
+ // element.style.marginLeft = Math.max(svgRect.left - rect.left, 0) + 'px';
1222
+ // element.style.marginTop = Math.max(svgRect.top - rect.top, 0) + 'px';
1223
+ // }
1224
+ // }
1225
+
1226
+ private zoomingChange(): void {
1227
+ let left: number; let top: number;
1228
+ if (getElementByID(this.element.id + '_Layer_Collections') && this.zoomModule) {
1229
+ this.zoomModule.layerCollectionEle = getElementByID(this.element.id + '_Layer_Collections');
1230
+ }
1231
+ if (this.isTileMap && getElementByID(this.element.id + '_Tile_SVG') && getElementByID(this.element.id + '_tile_parent')) {
1232
+ let tileElement: Element = getElementByID(this.element.id + '_tile_parent');
1233
+ let tileSvgElement: Element = getElementByID(this.element.id + '_Tile_SVG');
1234
+ const tileSvgParentElement: Element = getElementByID(this.element.id + '_Tile_SVG_Parent');
1235
+ const tileRect: ClientRect = tileElement.getBoundingClientRect();
1236
+ const tileSvgRect: ClientRect = tileSvgElement.getBoundingClientRect();
1237
+ left = (tileRect.left - tileSvgRect.left);
1238
+ top = (tileRect.top - tileSvgRect.top);
1239
+ (tileSvgParentElement as HTMLElement).style.left = left + 'px';
1240
+ (tileSvgParentElement as HTMLElement).style.top = top + 'px';
1241
+ if (!isNullOrUndefined(this.legendModule) && this.legendModule.totalPages.length > 0) {
1242
+ (tileElement as HTMLElement).style.width = (tileSvgElement as HTMLElement).style.width = this.legendModule.legendTotalRect.width.toString();
1243
+ (tileElement as HTMLElement).style.height = (tileSvgElement as HTMLElement).style.height = this.legendModule.legendTotalRect.height.toString();
1244
+ (tileSvgParentElement as HTMLElement).style.width = this.legendModule.legendTotalRect.width + 'px';
1245
+ (tileSvgParentElement as HTMLElement).style.height = this.legendModule.legendTotalRect.height + 'px';
1246
+ }
1247
+ const markerTemplateElements: HTMLCollectionOf<Element> = document.getElementsByClassName('template');
1248
+ if (!isNullOrUndefined(markerTemplateElements) && markerTemplateElements.length > 0) {
1249
+ for (let i: number = 0; i < markerTemplateElements.length; i++) {
1250
+ const templateGroupEle: HTMLElement = markerTemplateElements[i] as HTMLElement;
1251
+ templateGroupEle.style.left = left + 'px';
1252
+ templateGroupEle.style.top = top + 'px';
1253
+ }
1254
+ }
1255
+ }
1256
+ if (this.zoomSettings.zoomFactor >= 0) {
1257
+ if (this.zoomModule && this.zoomModule.toolBarGroup && this.zoomSettings.enable) {
1258
+ this.zoomModule.alignToolBar();
1259
+ }
1260
+ const elements: Element = document.getElementById(this.element.id + '_Layer_Collections');
1261
+ if (!isNullOrUndefined(elements) && elements.childElementCount > 0) {
1262
+ for (let i: number = 0; i < elements.childNodes.length; i++) {
1263
+ const childElement: SVGAElement = elements.childNodes[i] as SVGAElement;
1264
+ if (childElement.tagName === 'g' && childElement.id.indexOf('_Legend_Group') == -1) {
1265
+ const layerIndex: number = parseFloat(childElement.id.split('_LayerIndex_')[1].split('_')[0]);
1266
+ for (let j: number = 0; j < childElement.childNodes.length; j++) {
1267
+ const childNode: Element = <Element>childElement.childNodes[j];
1268
+ if (!(childNode.id.indexOf('_Markers_Group') > -1) &&
1269
+ (!(childNode.id.indexOf('_bubble_Group') > -1)) &&
1270
+ (!(childNode.id.indexOf('_dataLableIndex_Group') > -1))) {
1271
+ changeBorderWidth(childNode, layerIndex, this.scale, this);
1272
+ }
1273
+ }
1274
+ }
1275
+ }
1276
+ }
1277
+ if (this.zoomModule && (this.previousScale !== this.scale)) {
1278
+ this.zoomModule.applyTransform(this, true);
1279
+ }
1280
+ }
1281
+ }
1282
+
1283
+ private createSecondaryElement(): void {
1284
+ if (isNullOrUndefined(document.getElementById(this.element.id + '_Secondary_Element'))) {
1285
+ const secondaryElement: Element = createElement('div', {
1286
+ id: this.element.id + '_Secondary_Element',
1287
+ styles: 'position: absolute;z-index:2;'
1288
+ });
1289
+ this.element.appendChild(secondaryElement);
1290
+ }
1291
+ }
1292
+
1293
+ /**
1294
+ * @returns {void}
1295
+ * @private
1296
+ */
1297
+ public arrangeTemplate(): void {
1298
+ if (document.getElementById(this.element.id + '_Legend_Border')) {
1299
+ document.getElementById(this.element.id + '_Legend_Border').style.pointerEvents = 'none';
1300
+ }
1301
+ const templateElements: HTMLCollectionOf<Element> = document.getElementsByClassName(this.element.id + '_template');
1302
+ if (!isNullOrUndefined(templateElements) && templateElements.length > 0 &&
1303
+ getElementByID(this.element.id + '_Layer_Collections') && !this.isTileMap) {
1304
+ for (let i: number = 0; i < templateElements.length; i++) {
1305
+ let offSetLetValue: number = 0;
1306
+ let offSetTopValue: number = 0;
1307
+ const templateGroupEle: Element = templateElements[i] as Element;
1308
+ if (!isNullOrUndefined(templateGroupEle) && templateGroupEle.childElementCount > 0) {
1309
+ const layerOffset: ClientRect = getElementByID(this.element.id + '_Layer_Collections').getBoundingClientRect();
1310
+ const elementOffset: ClientRect = getElementByID(templateGroupEle.id).getBoundingClientRect();
1311
+ if (templateGroupEle.id.indexOf('Marker') === -1) {
1312
+ offSetLetValue = this.isTileMap ? 0 : (layerOffset.left < elementOffset.left) ?
1313
+ -(Math.abs(elementOffset.left - layerOffset.left)) : (Math.abs(elementOffset.left - layerOffset.left));
1314
+ offSetTopValue = this.isTileMap ? 0 : (layerOffset.top < elementOffset.top) ?
1315
+ - (Math.abs(elementOffset.top - layerOffset.top)) : Math.abs(elementOffset.top - layerOffset.top);
1316
+ }
1317
+ for (let j: number = 0; j < templateGroupEle.childElementCount; j++) {
1318
+ const currentTemplate: HTMLElement = <HTMLElement>templateGroupEle.childNodes[j];
1319
+ if (currentTemplate.id.indexOf('Marker') !== -1) {
1320
+ const elementOffset: ClientRect = getElementByID(currentTemplate.id).getBoundingClientRect();
1321
+ currentTemplate.style.left = parseFloat(currentTemplate.style.left) - (this.isTileMap ? 0 : elementOffset.width / 2) + 'px';
1322
+ currentTemplate.style.top = parseFloat(currentTemplate.style.top) - (this.isTileMap ? 0 : elementOffset.height / 2) + 'px';
1323
+ } else {
1324
+ currentTemplate.style.left = parseFloat(currentTemplate.style.left) + offSetLetValue + 'px';
1325
+ currentTemplate.style.top = parseFloat(currentTemplate.style.top) + offSetTopValue + 'px';
1326
+ currentTemplate.style.transform = 'translate(-50%, -50%)';
1327
+ }
1328
+ }
1329
+ }
1330
+ }
1331
+ }
1332
+ }
1333
+
1334
+ private createTile(): void {
1335
+ const mainLayer: LayerSettings = this.layersCollection[0];
1336
+ const padding: number = 0;
1337
+ if (mainLayer.isBaseLayer && (mainLayer.layerType === 'OSM' || mainLayer.layerType === 'Bing' ||
1338
+ mainLayer.layerType === 'GoogleStaticMap' || mainLayer.layerType === 'Google' || (!isNullOrUndefined(mainLayer.urlTemplate) && mainLayer.urlTemplate !== ''))) {
1339
+ removeElement(this.element.id + '_tile_parent');
1340
+ removeElement(this.element.id + '_tiles');
1341
+ removeElement('animated_tiles');
1342
+ const ele: Element = createElement('div', {
1343
+ id: this.element.id + '_tile_parent', styles: 'position: absolute; left: ' +
1344
+ (this.mapAreaRect.x) + 'px; right: ' + (this.margin.right) + 'px; top: '
1345
+ + (this.mapAreaRect.y + padding) + 'px; height: ' +
1346
+ (this.mapAreaRect.height) + 'px; width: '
1347
+ + (this.mapAreaRect.width) + 'px; overflow: hidden;'
1348
+ });
1349
+ const ele1: Element = createElement('div', {
1350
+ id: this.element.id + '_tiles', styles: 'position: absolute; left: ' +
1351
+ (this.mapAreaRect.x) + 'px; right: ' + (this.margin.right) + 'px; top: '
1352
+ + (this.mapAreaRect.y + padding) + 'px; height: ' + (this.mapAreaRect.height) + 'px; width: '
1353
+ + (this.mapAreaRect.width) + 'px; overflow: hidden;'
1354
+ });
1355
+ this.element.appendChild(ele);
1356
+ this.element.appendChild(ele1);
1357
+ }
1358
+ }
1359
+
1360
+
1361
+ /**
1362
+ * To initilize the private varibales of maps.
1363
+ *
1364
+ * @returns {void}
1365
+ */
1366
+ private initPrivateVariable(): void {
1367
+ if (this.element.id === '') {
1368
+ const collection: number = document.getElementsByClassName('e-maps').length;
1369
+ this.element.id = 'maps_control_' + collection;
1370
+ }
1371
+ this.renderer = new SvgRenderer(this.element.id);
1372
+ this.mapLayerPanel = new LayerPanel(this);
1373
+ }
1374
+
1375
+ private findBaseAndSubLayers(): void {
1376
+ const baseIndex: number = this.baseLayerIndex;
1377
+ const mainLayers: any[] = []; const subLayers: any[] = [];
1378
+ this.layersCollection = [];
1379
+ Array.prototype.forEach.call(this.layers, (layer: LayerSettingsModel) => {
1380
+ // eslint-disable-next-line @typescript-eslint/no-unused-expressions
1381
+ (layer.type === 'Layer') ? mainLayers.push(layer) : subLayers.push(layer);
1382
+ });
1383
+ for (let i: number = 0; i < mainLayers.length; i++) {
1384
+ const baseLayer: LayerSettings = <LayerSettings>mainLayers[i];
1385
+ if (baseLayer.visible && baseIndex === i) {
1386
+ baseLayer.isBaseLayer = true;
1387
+ this.isTileMap = (baseLayer.layerType === 'Geometry' && !isNullOrUndefined(baseLayer.shapeData)) ? false : true;
1388
+ this.layersCollection.push(baseLayer);
1389
+ break;
1390
+ } else if (i === mainLayers.length - 1) {
1391
+ this.layersCollection.push(<LayerSettings>mainLayers[0]);
1392
+ break;
1393
+ }
1394
+ }
1395
+ subLayers.map((subLayer: LayerSettings, subLayerIndex: number) => {
1396
+ if (subLayer.visible) {
1397
+ this.layersCollection.push(subLayer);
1398
+ }
1399
+ });
1400
+ }
1401
+
1402
+ /**
1403
+ * Render the map border
1404
+ *
1405
+ * @private
1406
+ * @returns {void}
1407
+ */
1408
+ private renderBorder(): void {
1409
+ const width: number = this.border.width;
1410
+ const borderElement: Element = this.svgObject.querySelector('#' + this.element.id + '_MapBorder');
1411
+ if ((width > 0 || (this.background || this.themeStyle.backgroundColor)) && isNullOrUndefined(borderElement)) {
1412
+ const border: BorderModel = {
1413
+ opacity: isNullOrUndefined(this.border.opacity) ? 1 : this.border.opacity,
1414
+ color: this.border.color, width: this.border.width
1415
+ };
1416
+ const borderRect: RectOption = new RectOption(
1417
+ this.element.id + '_MapBorder', this.background || this.themeStyle.backgroundColor, border, 1,
1418
+ new Rect(width / 2, width / 2, this.availableSize.width - width, this.availableSize.height - width));
1419
+ this.svgObject.appendChild(this.renderer.drawRectangle(borderRect) as SVGRectElement);
1420
+ } else {
1421
+ borderElement.setAttribute('fill', this.background || this.themeStyle.backgroundColor);
1422
+ }
1423
+ }
1424
+
1425
+ /**
1426
+ * Render the title and subtitle
1427
+ *
1428
+ * @param {TitleSettingsModel} title - Specifies the title
1429
+ * @param {string} type - Specifies the type
1430
+ * @param {Rect} bounds - Specifies the bounds
1431
+ * @param {Element} groupEle - Specifies the group element
1432
+ * @returns {void}
1433
+ * @private
1434
+ */
1435
+ private renderTitle(title: TitleSettingsModel, type: string, bounds: Rect, groupEle: Element): void {
1436
+ const style: FontModel = {
1437
+ size: title.textStyle.size,
1438
+ color: title.textStyle.color,
1439
+ fontFamily: title.textStyle.fontFamily,
1440
+ fontWeight: title.textStyle.fontWeight,
1441
+ fontStyle: title.textStyle.fontStyle,
1442
+ opacity: title.textStyle.opacity
1443
+ };
1444
+ let height: number;
1445
+ const width: number = Math.abs((this.margin.left + this.margin.right) - this.availableSize.width);
1446
+ style.fontFamily = !isNullOrUndefined(style.fontFamily) ? style.fontFamily : this.themeStyle.fontFamily;
1447
+ style.fontWeight = style.fontWeight || this.themeStyle.titleFontWeight;
1448
+ style.size = type === 'title' ? (style.size || this.themeStyle.titleFontSize) : (style.size || Theme.mapsSubTitleFont.size);
1449
+ if (title.text) {
1450
+ if (isNullOrUndefined(groupEle)) {
1451
+ groupEle = this.renderer.createGroup({ id: this.element.id + '_Title_Group' });
1452
+ }
1453
+ const trimmedTitle: string = textTrim(width, title.text, style);
1454
+ const elementSize: Size = measureText(trimmedTitle, style);
1455
+ const rect: Rect = (isNullOrUndefined(bounds)) ? new Rect(
1456
+ this.margin.left, this.margin.top, this.availableSize.width, this.availableSize.height) : bounds;
1457
+ const location: Point = findPosition(rect, title.alignment, elementSize, type);
1458
+ const options: TextOption = new TextOption(
1459
+ this.element.id + '_Map_' + type, location.x, location.y, 'start', trimmedTitle
1460
+ );
1461
+ const titleBounds: Rect = new Rect(location.x, location.y, elementSize.width, elementSize.height);
1462
+ const element: Element = renderTextElement(
1463
+ options, style, style.color || (type === 'title' ? this.themeStyle.titleFontColor : this.themeStyle.subTitleFontColor),
1464
+ groupEle
1465
+ );
1466
+ element.setAttribute('aria-label', this.description || title.text);
1467
+ element.setAttribute('role', '');
1468
+ if ((type === 'title' && !title.subtitleSettings.text) || (type === 'subtitle')) {
1469
+ height = Math.abs((titleBounds.y + this.margin.bottom) - this.availableSize.height);
1470
+ this.mapAreaRect = new Rect(this.margin.left, titleBounds.y + 10, width, height - 10);
1471
+ }
1472
+ if (type !== 'subtitle' && title.subtitleSettings.text) {
1473
+ this.renderTitle(title.subtitleSettings, 'subtitle', titleBounds, groupEle);
1474
+ } else {
1475
+ this.svgObject.appendChild(groupEle);
1476
+ }
1477
+ } else {
1478
+ height = Math.abs((this.margin.top + this.margin.bottom) - this.availableSize.height);
1479
+ this.mapAreaRect = new Rect(this.margin.left, this.margin.top, width, height);
1480
+ }
1481
+ }
1482
+
1483
+ /**
1484
+ * To create svg element for maps
1485
+ *
1486
+ * @returns {void}
1487
+ */
1488
+ private createSVG(): void {
1489
+ this.removeSvg();
1490
+ createSvg(this);
1491
+ }
1492
+ /**
1493
+ * To Remove the SVG
1494
+ *
1495
+ * @returns {void}
1496
+ */
1497
+ private removeSvg(): void {
1498
+ removeElement(this.element.id + '_Secondary_Element');
1499
+ removeElement(this.element.id + '_tile_parent');
1500
+ removeElement(this.element.id + '_tiles');
1501
+ if (this.svgObject) {
1502
+ while (this.svgObject.childNodes.length > 0) {
1503
+ this.svgObject.removeChild(this.svgObject.firstChild);
1504
+ }
1505
+ if (!this.svgObject.hasChildNodes() && this.svgObject.parentNode) {
1506
+ remove(this.svgObject);
1507
+ }
1508
+ }
1509
+ this.clearTemplate();
1510
+ }
1511
+ /**
1512
+ * To bind event handlers for maps.
1513
+ *
1514
+ * @returns {void}
1515
+ */
1516
+ private wireEVents(): void {
1517
+ //let cancelEvent: string = Browser.isPointer ? 'pointerleave' : 'mouseleave';
1518
+ EventHandler.add(this.element, 'click', this.mapsOnClick, this);
1519
+ // EventHandler.add(this.element, 'contextmenu', this.mapsOnRightClick, this);
1520
+ EventHandler.add(this.element, 'dblclick', this.mapsOnDoubleClick, this);
1521
+ EventHandler.add(this.element, Browser.touchStartEvent, this.mouseDownOnMap, this);
1522
+ EventHandler.add(this.element, Browser.touchMoveEvent, this.mouseMoveOnMap, this);
1523
+ EventHandler.add(this.element, Browser.touchEndEvent, this.mouseEndOnMap, this);
1524
+ EventHandler.add(this.element, 'pointerleave mouseleave', this.mouseLeaveOnMap, this);
1525
+ EventHandler.add(this.element, 'keydown', this.keyDownHandler, this);
1526
+ EventHandler.add(this.element, 'keyup', this.keyUpHandler, this);
1527
+ // EventHandler.add(this.element, cancelEvent, this.mouseLeaveOnMap, this);
1528
+ window.addEventListener(
1529
+ (Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize',
1530
+ this.mapsOnResize.bind(this)
1531
+ );
1532
+
1533
+ }
1534
+
1535
+ /**
1536
+ * To unbind event handlers from maps.
1537
+ *
1538
+ * @returns {void}
1539
+ */
1540
+ private unWireEVents(): void {
1541
+ //let cancelEvent: string = Browser.isPointer ? 'pointerleave' : 'mouseleave';
1542
+ EventHandler.remove(this.element, 'click', this.mapsOnClick);
1543
+ // EventHandler.remove(this.element, 'contextmenu', this.mapsOnRightClick);
1544
+ EventHandler.remove(this.element, 'dblclick', this.mapsOnDoubleClick);
1545
+ EventHandler.remove(this.element, Browser.touchStartEvent, this.mouseDownOnMap);
1546
+ EventHandler.remove(this.element, Browser.touchMoveEvent, this.mouseMoveOnMap);
1547
+ EventHandler.remove(this.element, Browser.touchEndEvent, this.mouseEndOnMap);
1548
+ EventHandler.remove(this.element, 'pointerleave mouseleave', this.mouseLeaveOnMap);
1549
+ EventHandler.remove(this.element, 'keydown', this.keyDownHandler);
1550
+ EventHandler.remove(this.element, 'keyup', this.keyUpHandler);
1551
+ //EventHandler.remove(this.element, cancelEvent, this.mouseLeaveOnMap);
1552
+ window.removeEventListener(
1553
+ (Browser.isTouch && ('orientation' in window && 'onorientationchange' in window)) ? 'orientationchange' : 'resize',
1554
+ this.mapsOnResize
1555
+ );
1556
+ }
1557
+ /**
1558
+ * This method is used to perform operations when mouse pointer leave from maps.
1559
+ *
1560
+ * @param {PointerEvent} e - Specifies the pointer event on maps.
1561
+ * @returns {void}
1562
+ */
1563
+ public mouseLeaveOnMap(e: PointerEvent): void {
1564
+ if (document.getElementsByClassName('highlightMapStyle').length > 0 && this.legendModule) {
1565
+ this.legendModule.removeShapeHighlightCollection();
1566
+ removeClass(document.getElementsByClassName('highlightMapStyle')[0]);
1567
+ }
1568
+ }
1569
+ private keyUpHandler(event: KeyboardEvent): void {
1570
+ const id: string = event.target['id'];
1571
+ if (event.code === 'Tab' && id.indexOf('_LayerIndex_') > -1 && id.indexOf('shapeIndex') > -1) {
1572
+ this.keyboardHighlightSelection(id, event.type);
1573
+ } else if (id.indexOf('_LayerIndex_') === -1 && id.indexOf('shapeIndex') === -1 &&
1574
+ getElementsByClassName('highlightMapStyle').length > 0) {
1575
+ removeClass(<Element>getElementsByClassName('highlightMapStyle')[0]);
1576
+ if (this.legendSettings.visible && this.legendModule) {
1577
+ this.legendModule.removeShapeHighlightCollection();
1578
+ }
1579
+ }
1580
+ }
1581
+
1582
+ private keyboardHighlightSelection(id: string, key: string): void {
1583
+ const layerIndex: number = parseInt(id.split('_LayerIndex_')[1].split('_')[0], 10);
1584
+ const shapeIndex: number = parseInt(id.split('_shapeIndex_')[1].split('_')[0], 10);
1585
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1586
+ const shapeData: any = this.layers[layerIndex].shapeData['features']['length'] > shapeIndex ?
1587
+ this.layers[layerIndex].shapeData['features'][shapeIndex]['properties'] : null;
1588
+ const dataIndex: number = parseInt(id.split('_dataIndex_')[1].split('_')[0], 10);
1589
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1590
+ const data: any = isNullOrUndefined(dataIndex) ? null : this.layers[layerIndex].dataSource[dataIndex];
1591
+ if (this.layers[layerIndex].selectionSettings.enable && key === 'keydown' && this.selectionModule) {
1592
+ this.selectionModule.selectionsettings = this.layers[layerIndex].selectionSettings;
1593
+ this.selectionModule.selectionType = 'Shape';
1594
+ this.selectionModule.selectElement(<Element>event.target, layerIndex, data, shapeData);
1595
+ } else if (this.highlightModule && (this.layers[layerIndex].highlightSettings.enable && key === 'keyup' &&
1596
+ !(event.target as HTMLElement).classList.contains('ShapeselectionMapStyle'))) {
1597
+ this.highlightModule.highlightSettings = this.layers[layerIndex].highlightSettings;
1598
+ this.highlightModule.handleHighlight(<Element>event.target, layerIndex, data, shapeData);
1599
+ }
1600
+ }
1601
+
1602
+ private keyDownHandler(event: KeyboardEvent): void {
1603
+ const zoom: Zoom = this.zoomModule;
1604
+ if ((event.key === '+' || event.code === 'Equal') && zoom) {
1605
+ zoom.performZoomingByToolBar('zoomin');
1606
+ } else if ((event.key === '-' || event.code === 'Minus') && zoom) {
1607
+ zoom.performZoomingByToolBar('zoomout');
1608
+ } else if (event['keyCode'] === 82 && zoom) {
1609
+ zoom.performZoomingByToolBar('reset');
1610
+ } else if ((event.code === 'ArrowUp' || event.code === 'ArrowDown') && zoom) {
1611
+ event.preventDefault();
1612
+ zoom.mouseDownLatLong['x'] = 0;
1613
+ zoom.mouseMoveLatLong['y'] = this.mapAreaRect.height / 7;
1614
+ zoom.panning('None', zoom.mouseDownLatLong['x'], event.code === 'ArrowUp' ? -(zoom.mouseMoveLatLong['y']) :
1615
+ zoom.mouseMoveLatLong['y'], event);
1616
+ zoom.mouseDownLatLong['y'] = zoom.mouseMoveLatLong['y'];
1617
+ } else if ((event.code === 'ArrowLeft' || event.code === 'ArrowRight') && zoom) {
1618
+ event.preventDefault();
1619
+ zoom.mouseDownLatLong['y'] = 0;
1620
+ zoom.mouseMoveLatLong['x'] = this.mapAreaRect.width / 7;
1621
+ zoom.panning('None', event.code === 'ArrowLeft' ? -(zoom.mouseMoveLatLong['x']) : zoom.mouseMoveLatLong['x'],
1622
+ zoom.mouseDownLatLong['y'], event);
1623
+ zoom.mouseDownLatLong['x'] = zoom.mouseMoveLatLong['x'];
1624
+ } else if (event.code === 'Enter') {
1625
+ const id: string = event.target['id'];
1626
+ event.preventDefault();
1627
+ if (this.legendModule && (id.indexOf('_Left_Page_Rect') > -1 || id.indexOf('_Right_Page_Rect') > -1)) {
1628
+ this.mapAreaRect = this.legendModule.initialMapAreaRect;
1629
+ this.legendModule.currentPage = (id.indexOf('_Left_Page_') > -1) ? (this.legendModule.currentPage - 1) :
1630
+ (this.legendModule.currentPage + 1);
1631
+ this.legendModule.legendGroup = this.renderer.createGroup({ id: this.element.id + '_Legend_Group' });
1632
+ this.legendModule.drawLegendItem(this.legendModule.currentPage);
1633
+ const textContent: string = (document.getElementById(this.element.id + '_Paging_Text')).textContent;
1634
+ const text: number[] = textContent.split('/').map(Number);
1635
+ if (id.indexOf('_Left_Page_Rect') > -1) {
1636
+ if (text[0] !== 1) {
1637
+ (event.target as HTMLElement).focus();
1638
+ }
1639
+ (event.target as HTMLElement).style.outlineColor = text[0] - 1 !== text[1] ? '' : 'transparent';
1640
+ } else if (id.indexOf('_Right_Page_Rect') > -1) {
1641
+ if (text[0] !== text[1]) {
1642
+ (event.target as HTMLElement).focus();
1643
+ }
1644
+ (event.target as HTMLElement).style.outlineColor = text[0] !== text[1] + 1 ? '' : 'transparent';
1645
+ }
1646
+ if (querySelector(this.element.id + '_Legend_Border', this.element.id)) {
1647
+ (<HTMLElement>querySelector(this.element.id + '_Legend_Border', this.element.id)).style.pointerEvents = 'none';
1648
+ }
1649
+ }
1650
+ if (id.indexOf('shapeIndex') > -1) {
1651
+ this.keyboardHighlightSelection(id, event.type);
1652
+ }
1653
+ }
1654
+ }
1655
+
1656
+ /**
1657
+ * Gets the selected element to be maintained or not.
1658
+ *
1659
+ * @param {Element} targetEle - Specifies the target element
1660
+ * @returns {boolean} - Returns the boolean value
1661
+ * @private
1662
+ */
1663
+ public SelectedElement(targetEle : Element) : boolean {
1664
+ let isSelect : boolean = false;
1665
+ if (targetEle.getAttribute('class') === 'ShapeselectionMapStyle') {
1666
+ isSelect = true;
1667
+ }
1668
+ return isSelect;
1669
+ }
1670
+
1671
+ /**
1672
+ * This method is used to perform the operations when a click operation is performed on maps.
1673
+ *
1674
+ * @param {PointerEvent} e - Specifies the pointer event on maps.
1675
+ */
1676
+ public mapsOnClick(e: PointerEvent): void {
1677
+ const targetEle: Element = <Element>e.target;
1678
+ const targetId: string = targetEle.id;
1679
+ let latitude: number = null;
1680
+ let longitude: number = null;
1681
+ this.mouseClickEvent = { x: e.x, y: e.y };
1682
+ if (targetEle.id.indexOf('_ToolBar') === -1) {
1683
+ const latLongValue: GeoPosition = this.getClickLocation(targetId, e.pageX, e.pageY, (targetEle as HTMLElement), e['layerX'], e['layerY']);
1684
+ if (!isNullOrUndefined(latLongValue)) {
1685
+ latitude = latLongValue.latitude;
1686
+ longitude = latLongValue.longitude;
1687
+ }
1688
+ const eventArgs: IMouseEventArgs = {
1689
+ cancel: false, name: click, target: targetId, x: e.clientX, y: e.clientY,
1690
+ latitude: latitude, longitude: longitude,
1691
+ isShapeSelected : this.SelectedElement(targetEle)
1692
+ };
1693
+ if (this.onclick) {
1694
+ eventArgs.name = onclick;
1695
+ this.trigger('onclick', eventArgs, (mouseArgs: IMouseEventArgs) => {
1696
+ this.clickHandler(e, eventArgs, targetEle);
1697
+ });
1698
+ } else {
1699
+ this.trigger('click', eventArgs, (mouseArgs: IMouseEventArgs) => {
1700
+ this.clickHandler(e, eventArgs, targetEle);
1701
+ });
1702
+ }
1703
+ }
1704
+ }
1705
+
1706
+ private clickHandler(e : PointerEvent, eventArgs : IMouseEventArgs, targetEle: Element) : void {
1707
+ if (targetEle.id.indexOf('shapeIndex') > -1) {
1708
+ this.mergeCluster();
1709
+ if (getElement(this.element.id + '_mapsTooltip') &&
1710
+ this.mapsTooltipModule.tooltipTargetID.indexOf('_MarkerIndex_') > -1) {
1711
+ removeElement(this.element.id + '_mapsTooltip');
1712
+ }
1713
+ }
1714
+ if (this.markerModule) {
1715
+ this.markerModule.markerClusterClick(e);
1716
+ }
1717
+ if (!eventArgs.cancel) {
1718
+ this.notify(click, targetEle);
1719
+ }
1720
+ if (!eventArgs.cancel && targetEle.id.indexOf('shapeIndex') !== -1) {
1721
+ this.triggerShapeSelection(targetEle);
1722
+ }
1723
+ }
1724
+
1725
+ private triggerShapeSelection(targetEle: Element) {
1726
+ const layerIndex: number = parseInt(targetEle.id.split('_LayerIndex_')[1].split('_')[0], 10);
1727
+ const shapeSelectedEventArgs : IShapeSelectedEventArgs = triggerShapeEvent(
1728
+ targetEle.id, this.layers[layerIndex].selectionSettings, this, shapeSelected
1729
+ );
1730
+ if (!shapeSelectedEventArgs.cancel && this.selectionModule && !isNullOrUndefined(this.shapeSelected)) {
1731
+ customizeStyle(this.selectionModule.selectionType + 'selectionMap',
1732
+ this.selectionModule.selectionType + 'selectionMapStyle', shapeSelectedEventArgs);
1733
+ } else if (shapeSelectedEventArgs.cancel && this.selectionModule
1734
+ && isNullOrUndefined(shapeSelectedEventArgs['data'])) {
1735
+ removeClass(targetEle);
1736
+ this.selectionModule.removedSelectionList(targetEle);
1737
+ }
1738
+ }
1739
+ private getClickLocation(targetId: string, pageX: number, pageY: number, targetElement: HTMLElement, x: number, y: number): GeoPosition {
1740
+ let layerIndex: number = 0;
1741
+ let latLongValue: any;
1742
+ if (targetId.indexOf('_LayerIndex_') !== -1 && !this.isTileMap && (parseInt(this.mouseDownEvent['x']) === parseInt(this.mouseClickEvent['x']))
1743
+ && (parseInt(this.mouseDownEvent['y']) === parseInt(this.mouseClickEvent['y']))) {
1744
+ layerIndex = parseFloat(targetId.split('_LayerIndex_')[1].split('_')[0]);
1745
+ if (this.layers[layerIndex].geometryType === 'Normal') {
1746
+ if (targetId.indexOf('_shapeIndex_') > -1) {
1747
+ const location: MapLocation = getMousePosition(pageX, pageY, (targetElement as any).parentElement);
1748
+ const minLongitude: number = Math.abs((-this.baseMapBounds.longitude.min) * this.mapLayerPanel.currentFactor);
1749
+ const minLatitude: number = Math.abs(this.baseMapBounds.latitude.max * this.mapLayerPanel.currentFactor);
1750
+ latLongValue = {
1751
+ latitude: Math.abs(this.baseMapBounds.latitude.max - (location.y / this.mapLayerPanel.currentFactor)),
1752
+ longitude: Math.abs((location.x / this.mapLayerPanel.currentFactor) + this.baseMapBounds.longitude.min)
1753
+ };
1754
+ if (this.baseMapBounds.longitude.min < 0 && minLongitude > location.x) {
1755
+ (latLongValue as any).longitude = -(latLongValue as any).longitude;
1756
+ }
1757
+ if (this.baseMapBounds.latitude.min < 0 && minLatitude > location.y) {
1758
+ (latLongValue as any).latitude = - (latLongValue as any).latitude;
1759
+ }
1760
+ } else if (targetId.indexOf('_MarkerIndex_') > -1 && this.markerModule) {
1761
+ const markerIndex: number = parseInt(targetId.split('_MarkerIndex_')[1].split('_')[0], 10);
1762
+ const dataIndex: number = parseInt(targetId.split('_dataIndex_')[1].split('_')[0], 10);
1763
+ if (!isNaN(markerIndex) && !isNaN(dataIndex)) {
1764
+ const dataObject: any = this.layers[layerIndex].markerSettings[markerIndex].dataSource[dataIndex];
1765
+ latLongValue = { latitude: dataObject['latitude'], longitude: dataObject.longitude };
1766
+ } else {
1767
+ latLongValue = { latitude: null, longitude: null };
1768
+ }
1769
+ } else { latLongValue = { latitude: null, longitude: null }; }
1770
+ } else {
1771
+ latLongValue = this.getGeoLocation(layerIndex, x, y);
1772
+ }
1773
+ } else if (this.isTileMap && (parseInt(this.mouseDownEvent['x']) === parseInt(this.mouseClickEvent['x']))
1774
+ && (parseInt(this.mouseDownEvent['y']) === parseInt(this.mouseClickEvent['y']))) {
1775
+ latLongValue = this.getTileGeoLocation(x, y);
1776
+ }
1777
+ return latLongValue;
1778
+ }
1779
+
1780
+ /**
1781
+ * This method is used to perform operations when mouse click on maps.
1782
+ *
1783
+ * @param {PointerEvent} e - Specifies the pointer event on maps.
1784
+ * @returns {boolean} - Returns the boolean value
1785
+ */
1786
+ public mouseEndOnMap(e: PointerEvent): boolean {
1787
+ const targetEle: Element = <Element>e.target;
1788
+ const targetId: string = targetEle.id;
1789
+ let pageX: number;
1790
+ let latitude: number = null;
1791
+ let longitude: number = null;
1792
+ let pageY: number;
1793
+ let target: Element;
1794
+ let touchArg: TouchEvent;
1795
+ const rect: ClientRect = this.element.getBoundingClientRect();
1796
+ const element: Element = <Element>e.target;
1797
+ if (e.type.indexOf('touch') !== - 1) {
1798
+ this.isTouch = true;
1799
+ touchArg = <TouchEvent & PointerEvent>e;
1800
+ pageX = touchArg.changedTouches[0].pageX;
1801
+ pageY = touchArg.changedTouches[0].pageY;
1802
+ target = <Element>touchArg.target;
1803
+ this.mouseClickEvent = { x: pageX, y: pageY };
1804
+ } else {
1805
+ this.isTouch = e.pointerType === 'touch';
1806
+ pageX = e.pageX;
1807
+ pageY = e.pageY;
1808
+ target = <Element>e.target;
1809
+ }
1810
+ if (this.isTouch) {
1811
+ if (targetEle.id.indexOf('_ToolBar') === -1) {
1812
+ const latLongValue: GeoPosition = this.getClickLocation(targetId, pageX, pageY, (targetEle as HTMLElement), pageX, pageY);
1813
+ if (!isNullOrUndefined(latLongValue)) {
1814
+ latitude = latLongValue.latitude;
1815
+ longitude = latLongValue.longitude;
1816
+ }
1817
+ }
1818
+ this.titleTooltip(e, pageX, pageY, true);
1819
+ if (!isNullOrUndefined(this.legendModule)) {
1820
+ this.legendTooltip(e, e.pageX, e.pageY, true);
1821
+ }
1822
+ }
1823
+ this.notify(Browser.touchEndEvent, e);
1824
+ if (e.cancelable && !this.isTouch) {
1825
+ e.preventDefault();
1826
+ }
1827
+ return false;
1828
+ }
1829
+ /**
1830
+ * This method is used to perform operations when mouse is clicked down on maps.
1831
+ *
1832
+ * @param {PointerEvent} e - Specifies the pointer event on maps
1833
+ * @returns {void}
1834
+ */
1835
+ public mouseDownOnMap(e: PointerEvent): void {
1836
+ let pageX: number;
1837
+ let pageY: number;
1838
+ let target: Element;
1839
+ let touchArg: TouchEvent;
1840
+ this.mouseDownEvent = { x: e.x, y: e.y };
1841
+ if (e.type.indexOf('touch') !== - 1 && (e as any).changedTouches) {
1842
+ this.mouseDownEvent = { x: (e as any).changedTouches[0].pageX, y: (e as any).changedTouches[0].pageY };
1843
+ }
1844
+ const rect: ClientRect = this.element.getBoundingClientRect();
1845
+ const element: Element = <Element>e.target;
1846
+ if (element.id.indexOf('_ToolBar') === -1) {
1847
+ const markerModule: Marker = this.markerModule;
1848
+ if (element.id.indexOf('shapeIndex') > -1 || element.id.indexOf('Tile') > -1) {
1849
+ this.mergeCluster();
1850
+ if (element.id.indexOf('shapeIndex') > -1) {
1851
+ this.triggerShapeSelection(element);
1852
+ }
1853
+ }
1854
+ if (markerModule) {
1855
+ markerModule.markerClick(e);
1856
+ markerModule.markerClusterClick(e);
1857
+ }
1858
+ if (this.bubbleModule) {
1859
+ this.bubbleModule.bubbleClick(e);
1860
+ }
1861
+ }
1862
+ this.notify(Browser.touchStartEvent, e);
1863
+ }
1864
+
1865
+ /**
1866
+ * Merges the marker clusters.
1867
+ *
1868
+ * @returns {void}
1869
+ * @private
1870
+ */
1871
+ public mergeCluster(): void {
1872
+ if (this.markerModule && (this.markerModule.sameMarkerData.length > 0) &&
1873
+ (this.zoomModule ? this.zoomModule.isSingleClick : true)) {
1874
+ mergeSeparateCluster(this.markerModule.sameMarkerData, this, getElement(this.element.id + '_Markers_Group'));
1875
+ this.markerModule.sameMarkerData = [];
1876
+ }
1877
+ }
1878
+
1879
+ /**
1880
+ * This method is used to perform operations when performing the double click operation on maps.
1881
+ *
1882
+ * @param {PointerEvent} e - Specifies the pointer event.
1883
+ */
1884
+ public mapsOnDoubleClick(e: PointerEvent): void {
1885
+ this.notify('dblclick', e);
1886
+ const targetElement: Element = <Element>e.target;
1887
+ const targetId: string = targetElement.id;
1888
+ let layerIndex: number = 0;
1889
+ let latLongValue: any;
1890
+ let latitude: number = null; let longitude: number = null;
1891
+ if (targetElement.id.indexOf('_ToolBar') === -1) {
1892
+ if (targetElement.id.indexOf('_LayerIndex_') !== -1 && !this.isTileMap && (this.mouseDownEvent['x'] === e.clientX)
1893
+ && (this.mouseDownEvent['y'] === e.clientY)) {
1894
+ layerIndex = parseFloat(targetElement.id.split('_LayerIndex_')[1].split('_')[0]);
1895
+ latLongValue = this.getGeoLocation(layerIndex, e['layerX'], e['layerY']);
1896
+ latitude = latLongValue['latitude']; longitude = latLongValue['longitude'];
1897
+ } else if (this.isTileMap && (this.mouseDownEvent['x'] === e.clientX)
1898
+ && (this.mouseDownEvent['y'] === e.clientY)) {
1899
+ latLongValue = this.getTileGeoLocation(e['layerX'], e['layerY']);
1900
+ latitude = latLongValue['latitude']; longitude = latLongValue['longitude'];
1901
+ }
1902
+ const doubleClickArgs: IMouseEventArgs = { cancel: false, name: doubleClick, x: e.clientX, y: e.clientY,
1903
+ target : targetId, latitude: latitude, longitude: longitude, isShapeSelected : null };
1904
+ this.trigger('doubleClick', doubleClickArgs);
1905
+ }
1906
+ }
1907
+
1908
+ /**
1909
+ * This method is used to perform operations while performing mouse over on maps.
1910
+ *
1911
+ * @param {PointerEvent} e - Specifies the pointer event on maps.
1912
+ * @returns {void}
1913
+ */
1914
+ public mouseMoveOnMap(e: PointerEvent): void {
1915
+ let pageX: number;
1916
+ let pageY: number;
1917
+ let touchArg: TouchEvent;
1918
+ let target: Element;
1919
+ const touches: TouchList = null;
1920
+ target = (e.type === 'touchmove') ? <Element>(<TouchEvent & PointerEvent>e).target :
1921
+ target = <Element>e.target;
1922
+ // if (target.id.indexOf('shapeIndex') !== -1 && !this.highlightSettings.enable) {
1923
+ // triggerShapeEvent(target.id, this.highlightSettings, this, shapeHighlight);
1924
+ // }
1925
+ if (this.markerModule) {
1926
+ this.markerModule.markerMove(e);
1927
+ this.markerModule.markerClusterMouseMove(e);
1928
+ }
1929
+ if (this.bubbleModule) {
1930
+ this.bubbleModule.bubbleMove(e);
1931
+ }
1932
+ this.onMouseMove(e);
1933
+ this.notify(Browser.touchMoveEvent, e);
1934
+ }
1935
+ /**
1936
+ * This method is used to perform operations when mouse move event is performed on maps.
1937
+ *
1938
+ * @param {PointerEvent} e - Specifies the pointer event on maps.
1939
+ * @returns {void}
1940
+ */
1941
+ public onMouseMove(e: PointerEvent): boolean {
1942
+ const element: Element = <Element>e.target;
1943
+ let pageX: number;
1944
+ let pageY: number;
1945
+ let target: Element;
1946
+ let touchArg: TouchEvent;
1947
+ if (!this.isTouch) {
1948
+ this.titleTooltip(e, e.pageX, e.pageY);
1949
+ if (!isNullOrUndefined(this.legendModule)) {
1950
+ this.legendTooltip(e, e.pageX, e.pageY, true);
1951
+ }
1952
+ }
1953
+ return false;
1954
+ }
1955
+
1956
+ private legendTooltip(event: Event, x: number, y: number, isTouch?: boolean): void {
1957
+ let targetId: string = (<HTMLElement>event.target).id;
1958
+ let legendText : string; let page : number = this.legendModule.currentPage;
1959
+ let legendIndex : string = (<HTMLElement>event.target).id.split('_Index_')[1];
1960
+ let collection : any;
1961
+ page = this.legendModule.totalPages.length <= this.legendModule.currentPage
1962
+ ? this.legendModule.totalPages.length - 1 : this.legendModule.currentPage < 0 ?
1963
+ 0 : this.legendModule.currentPage;
1964
+ const count : number = this.legendModule.totalPages.length !== 0 ?
1965
+ this.legendModule.totalPages[page]['Collection'].length : this.legendModule.totalPages.length;
1966
+ for (let i : number = 0; i < count; i++) {
1967
+ collection = this.legendModule.totalPages[page]['Collection'][i];
1968
+ legendText = collection['DisplayText'];
1969
+ targetId = event.target['id'];
1970
+ legendIndex = event.target['id'].split('_Index_')[1];
1971
+ if ((targetId === (this.element.id + '_Legend_Text_Index_' + legendIndex)) &&
1972
+ ((<HTMLElement>event.target).textContent.indexOf('...') > -1) && collection['idIndex'] === parseInt(legendIndex, 10)) {
1973
+ showTooltip(
1974
+ legendText, this.legendSettings.textStyle.size, x, y, this.element.offsetWidth, this.element.offsetHeight,
1975
+ this.element.id + '_EJ2_Legend_Text_Tooltip', getElement(this.element.id + '_Secondary_Element'), isTouch
1976
+ );
1977
+ }
1978
+ }
1979
+ if ((targetId !== (this.element.id + '_Legend_Text_Index_' + legendIndex))) {
1980
+ removeElement(this.element.id + '_EJ2_Legend_Text_Tooltip');
1981
+ }
1982
+ }
1983
+
1984
+ private titleTooltip(event: Event, x: number, y: number, isTouch?: boolean): void {
1985
+ const targetId: string = (<HTMLElement>event.target).id;
1986
+ if (targetId === (this.element.id + '_LegendTitle') && ((<HTMLElement>event.target).textContent.indexOf('...') > -1)) {
1987
+ showTooltip(
1988
+ this.legendSettings.title.text, this.legendSettings.titleStyle.size, x, y, this.element.offsetWidth,
1989
+ this.element.offsetHeight, this.element.id + '_EJ2_LegendTitle_Tooltip',
1990
+ getElement(this.element.id + '_Secondary_Element'), isTouch
1991
+ );
1992
+ } else {
1993
+ removeElement(this.element.id + '_EJ2_LegendTitle_Tooltip');
1994
+ }
1995
+ if ((targetId === (this.element.id + '_Map_title')) && ((<HTMLElement>event.target).textContent.indexOf('...') > -1)) {
1996
+ showTooltip(
1997
+ this.titleSettings.text, this.titleSettings.textStyle.size || this.themeStyle.titleFontSize, x, y, this.element.offsetWidth, this.element.offsetHeight,
1998
+ this.element.id + '_EJ2_Title_Tooltip', getElement(this.element.id + '_Secondary_Element'), isTouch
1999
+ );
2000
+ } else {
2001
+ removeElement(this.element.id + '_EJ2_Title_Tooltip');
2002
+ }
2003
+ }
2004
+ /*
2005
+
2006
+ /**
2007
+ * This method is used to perform operations while resizing the window.
2008
+ *
2009
+ * @param e - Specifies the arguments of window resize event.
2010
+ */
2011
+ public mapsOnResize(e: Event): boolean {
2012
+ this.isResize = this.isReset = true;
2013
+ const args: IResizeEventArgs = {
2014
+ cancel: false,
2015
+ name: resize,
2016
+ previousSize: this.availableSize,
2017
+ currentSize: calculateSize(this),
2018
+ maps: this
2019
+ };
2020
+ this.trigger(resize, args);
2021
+ if (!args.cancel) {
2022
+ if (this.resizeTo) {
2023
+ clearTimeout(this.resizeTo);
2024
+ }
2025
+ if (!isNullOrUndefined(this.element) && this.element.classList.contains('e-maps')) {
2026
+ this.resizeTo = setTimeout(
2027
+ (): void => {
2028
+ this.unWireEVents();
2029
+ this.createSVG();
2030
+ this.refreshing = true;
2031
+ this.wireEVents();
2032
+ this.render();
2033
+ this.refreshing = false;
2034
+ },
2035
+ 500);
2036
+ }
2037
+ }
2038
+ return false;
2039
+ }
2040
+
2041
+ /**
2042
+ * This method is used to zoom the map by specifying the center position.
2043
+ *
2044
+ * @param {number} centerPosition - Specifies the center position
2045
+ * @param {number} centerPosition.latitude - Specifies the latitude value for the center position
2046
+ * @param {number} centerPosition.longitude - Specifies the longitude value for the center position
2047
+ * @param {number} zoomFactor - Specifies the zoom factor for maps.
2048
+ * @returns {void}
2049
+ */
2050
+ public zoomByPosition(centerPosition: { latitude: number, longitude: number }, zoomFactor: number): void {
2051
+ const factor: number = this.mapLayerPanel.calculateFactor(this.layersCollection[0]);
2052
+ let position: Point;
2053
+ const size: Rect = this.mapAreaRect;
2054
+ if (!this.isTileMap && this.zoomModule) {
2055
+ if (!isNullOrUndefined(centerPosition)) {
2056
+ position = convertGeoToPoint(
2057
+ centerPosition.latitude, centerPosition.longitude, factor, this.layersCollection[0], this);
2058
+ const mapRect: ClientRect = document.getElementById(this.element.id + '_Layer_Collections').getBoundingClientRect();
2059
+ const svgRect: ClientRect = this.svgObject.getBoundingClientRect();
2060
+ const xDiff: number = Math.abs(mapRect.left - svgRect.left) / this.scale;
2061
+ const yDiff: number = Math.abs(mapRect.top - svgRect.top) / this.scale;
2062
+ const x: number = this.translatePoint.x + xDiff;
2063
+ const y: number = this.translatePoint.y + yDiff;
2064
+ this.scale = zoomFactor;
2065
+ this.translatePoint.x = ((mapRect.left < svgRect.left ? x : 0) + (size.width / 2) - (position.x * zoomFactor)) / zoomFactor;
2066
+ this.translatePoint.y = ((mapRect.top < svgRect.top ? y : 0) + (size.height / 2) - (position.y * zoomFactor)) / zoomFactor;
2067
+ this.zoomModule.applyTransform(this);
2068
+ } else {
2069
+ position = { x: size.width / 2, y: size.height / 2 };
2070
+ this.zoomModule.performZooming(position, zoomFactor, zoomFactor > this.scale ? 'ZoomIn' : 'ZoomOut');
2071
+ }
2072
+ } else if (this.zoomModule) {
2073
+ this.tileZoomLevel = zoomFactor;
2074
+ this.tileTranslatePoint = this.mapLayerPanel['panTileMap'](
2075
+ this.availableSize.width, this.availableSize.height,
2076
+ { x: centerPosition.longitude, y: centerPosition.latitude }
2077
+ );
2078
+ this.mapLayerPanel.generateTiles(zoomFactor, this.tileTranslatePoint, null, new BingMap(this));
2079
+ }
2080
+ }
2081
+
2082
+ /**
2083
+ * This method is used to perform panning by specifying the direction.
2084
+ *
2085
+ * @param {PanDirection} direction - Specifies the direction in which the panning is performed.
2086
+ * @param {PointerEvent | TouchEvent} mouseLocation - Specifies the location of the mouse pointer in maps.
2087
+ */
2088
+ public panByDirection(direction: PanDirection, mouseLocation?: PointerEvent | TouchEvent): void {
2089
+ let xDiff: number = 0; let yDiff: number = 0;
2090
+ switch (direction) {
2091
+ case 'Left':
2092
+ xDiff = -(this.mapAreaRect.width / 7);
2093
+ break;
2094
+ case 'Right':
2095
+ xDiff = (this.mapAreaRect.width / 7);
2096
+ break;
2097
+ case 'Top':
2098
+ yDiff = -(this.mapAreaRect.height / 7);
2099
+ break;
2100
+ case 'Bottom':
2101
+ yDiff = (this.mapAreaRect.height / 7);
2102
+ break;
2103
+ }
2104
+ if (this.zoomModule) {
2105
+ this.zoomModule.panning(direction, xDiff, yDiff, mouseLocation);
2106
+ }
2107
+ }
2108
+
2109
+ /**
2110
+ * This method is used to add the layers dynamically to the maps.
2111
+ *
2112
+ * @param {Object} layer - Specifies the layer for the maps.
2113
+ */
2114
+ public addLayer(layer: Object): void {
2115
+ let mapsLayer: LayerSettingsModel[] = this.layers;
2116
+ mapsLayer.push(layer);
2117
+ this.isAddLayer = true;
2118
+ this.layers = mapsLayer;
2119
+ }
2120
+ /**
2121
+ * This method is used to remove a layer from map.
2122
+ *
2123
+ * @param {number} index - Specifies the index number of the layer to be removed.
2124
+ * @returns {void}
2125
+ */
2126
+ public removeLayer(index: number): void {
2127
+ let mapsLayer: LayerSettingsModel[] = this.layers;
2128
+ mapsLayer.splice(index, 1);
2129
+ this.layers = mapsLayer;
2130
+ }
2131
+ /**
2132
+ * This method is used to add markers dynamically in the maps.
2133
+ * If we provide the index value of the layer in which the marker to be added and the coordinates
2134
+ * of the marker as parameters, the marker will be added in the location.
2135
+ *
2136
+ * @param {number} layerIndex - Specifies the index number of the layer.
2137
+ * @param {MarkerSettingsModel[]} markerCollection - Specifies the settings of the marker to be added.
2138
+ * @returns {void}
2139
+ */
2140
+ public addMarker(layerIndex: number, markerCollection: MarkerSettingsModel[]): void {
2141
+ const layerEle: Element = document.getElementById(this.element.id + '_LayerIndex_' + layerIndex);
2142
+ if (markerCollection.length > 0 && layerEle) {
2143
+ for (const newMarker of markerCollection) {
2144
+ this.layersCollection[layerIndex].markerSettings.push(new MarkerSettings(this, 'markerSettings', newMarker));
2145
+ }
2146
+ const markerModule: Marker = new Marker(this);
2147
+ markerModule.markerRender(this, layerEle, layerIndex, this.mapLayerPanel['currentFactor'], 'AddMarker');
2148
+ this.arrangeTemplate();
2149
+ }
2150
+ }
2151
+ /**
2152
+ * This method is used to select the geometric shape element in the maps component.
2153
+ *
2154
+ * @param {number} layerIndex - Specifies the index of the layer in maps.
2155
+ * @param {string | string[]} propertyName - Specifies the property name from the data source.
2156
+ * @param {string} name - Specifies the name of the shape that is selected.
2157
+ * @param {boolean} enable - Specifies the shape selection to be enabled.
2158
+ * @returns {void}
2159
+ */
2160
+ public shapeSelection(layerIndex: number, propertyName: string | string[], name: string, enable?: boolean): void {
2161
+ let targetEle: Element;
2162
+ let subLayerIndex: number;
2163
+ const popertyNameArray: string[] = Array.isArray(propertyName) ? propertyName : Array(propertyName);
2164
+ if (isNullOrUndefined(enable)) {
2165
+ enable = true;
2166
+ }
2167
+ const selectionsettings: SelectionSettingsModel = this.layers[layerIndex].selectionSettings;
2168
+ if (!selectionsettings.enableMultiSelect && this.legendSelection && enable) {
2169
+ this.removeShapeSelection();
2170
+ }
2171
+ if (this.layers[layerIndex].type === 'SubLayer') {
2172
+ for (let i: number = 0; i < this.layersCollection.length; i++) {
2173
+ if ((this.layersCollection[i].shapeData === this.layers[layerIndex].shapeData)) {
2174
+ subLayerIndex = i;
2175
+ break;
2176
+ }
2177
+ }
2178
+ }
2179
+ if (selectionsettings.enable) {
2180
+ let targetId: string;
2181
+ let dataIndex: number;
2182
+ let shapeIndex: number;
2183
+ let indexValue: number;
2184
+ let shapeDataValue: any;
2185
+ let data: any;
2186
+ const shapeData: any[] = <any[]>this.layers[layerIndex].shapeData['features'];
2187
+ for (let i: number = 0; i < shapeData.length; i++) {
2188
+ for (let j: number = 0; j < (<string[]>popertyNameArray).length; j++) {
2189
+ const propertyName : string = !isNullOrUndefined(shapeData[i]['properties'][popertyNameArray[j]])
2190
+ && isNaN(shapeData[i]['properties'][popertyNameArray[j]]) ?
2191
+ shapeData[i]['properties'][popertyNameArray[j]].toLowerCase() : shapeData[i]['properties'][popertyNameArray[j]];
2192
+ const shapeName : string = !isNullOrUndefined(name) ? name.toLowerCase() : name;
2193
+ let k: number;
2194
+ if (propertyName === shapeName) {
2195
+ if (!isNullOrUndefined(this.layers[layerIndex].shapeSettings.colorValuePath)) {
2196
+ k = checkShapeDataFields(
2197
+ <any[]>this.layers[layerIndex].dataSource, shapeData[i]['properties'],
2198
+ this.layers[layerIndex].shapeDataPath, this.layers[layerIndex].shapePropertyPath,
2199
+ this.layers[layerIndex]);
2200
+ }
2201
+ const baseLayer: LayerSettings = <LayerSettings>this.layers[layerIndex];
2202
+ if (this.baseLayerIndex >= 0 && baseLayer.isBaseLayer) {
2203
+ indexValue = 0;
2204
+ } else if (this.layers[layerIndex].type === 'SubLayer') {
2205
+ indexValue = subLayerIndex;
2206
+ }
2207
+ targetId = this.element.id + '_' + 'LayerIndex_' + indexValue + '_shapeIndex_' + i + '_dataIndex_' + k;
2208
+ targetEle = getElement(targetId);
2209
+ if (isNullOrUndefined(k) && isNullOrUndefined(targetEle)) {
2210
+ targetId = this.element.id + '_' + 'LayerIndex_' + layerIndex + '_shapeIndex_' + i + '_dataIndex_null';
2211
+ targetEle = getElement(targetId);
2212
+ }
2213
+ shapeIndex = parseInt(targetEle.id.split('_shapeIndex_')[1].split('_')[0], 10);
2214
+ shapeDataValue = this.layers[layerIndex].shapeData['features']['length'] > shapeIndex ?
2215
+ this.layers[layerIndex].shapeData['features'][shapeIndex]['properties'] : null;
2216
+ dataIndex = parseInt(targetEle.id.split('_dataIndex_')[1].split('_')[0], 10);
2217
+ data = isNullOrUndefined(dataIndex) ? null : this.layers[layerIndex].dataSource[dataIndex];
2218
+ if (enable) {
2219
+ triggerItemSelectionEvent(selectionsettings, this, targetEle, shapeDataValue, data);
2220
+ this.shapeSelectionClass = getElement('ShapeselectionMap');
2221
+ if (this.legendSettings.visible && targetEle.id.indexOf('_MarkerIndex_') === -1) {
2222
+ this.legendModule.shapeHighLightAndSelection(
2223
+ targetEle, data, selectionsettings, 'selection', layerIndex);
2224
+ }
2225
+ const shapeToggled: boolean = this.legendSettings.visible ? this.legendModule.shapeToggled : true;
2226
+ if (shapeToggled) {
2227
+ targetEle.setAttribute('class', 'ShapeselectionMapStyle');
2228
+ if (this.selectedElementId.indexOf(targetEle.getAttribute('id')) === -1) {
2229
+ this.selectedElementId.push(targetEle.getAttribute('id'));
2230
+ }
2231
+ if (!selectionsettings.enableMultiSelect) { return; }
2232
+ }
2233
+ } else {
2234
+ this.legendSelection = (!selectionsettings.enableMultiSelect && !this.legendSelection) ?
2235
+ true : this.legendSelection;
2236
+ if (this.legendSettings.visible && targetEle.id.indexOf('_MarkerIndex_') === -1 &&
2237
+ targetEle.getAttribute('class') === 'ShapeselectionMapStyle') {
2238
+ this.legendModule.shapeHighLightAndSelection(
2239
+ targetEle, data, selectionsettings, 'selection', layerIndex);
2240
+ }
2241
+ const shapeToggled: boolean = this.legendSettings.visible ? this.legendModule.shapeToggled : true;
2242
+ if (shapeToggled) {
2243
+ removeClass(targetEle);
2244
+ const selectedElementIdIndex: number = this.selectedElementId.indexOf(targetEle.getAttribute('id'));
2245
+ if (selectedElementIdIndex !== -1) {
2246
+ this.selectedElementId.splice(selectedElementIdIndex, 1);
2247
+ if (!selectionsettings.enableMultiSelect && this.legendSelection && this.selectedElementId.length > 0) {
2248
+ this.removeShapeSelection();
2249
+ }
2250
+ }
2251
+ }
2252
+ }
2253
+ }
2254
+ }
2255
+ }
2256
+ }
2257
+ }
2258
+
2259
+ /**
2260
+ * This method is used to zoom the maps component based on the provided coordinates.
2261
+ *
2262
+ * @param {number} minLatitude - Specifies the minimum latitude to be zoomed.
2263
+ * @param {number} minLongitude - Specifies the minimum latitude to be zoomed.
2264
+ * @param {number} maxLatitude - Specifies the maximum latitude to be zoomed.
2265
+ * @param {number} maxLongitude - Specifies the maximum longitude to be zoomed.
2266
+ * @returns {void}
2267
+ */
2268
+ public zoomToCoordinates(minLatitude: number, minLongitude: number, maxLatitude: number, maxLongitude: number): void {
2269
+ let centerLatitude: number;
2270
+ let centerLongtitude: number;
2271
+ let isTwoCoordinates: boolean = false;
2272
+ if (isNullOrUndefined(maxLatitude) && isNullOrUndefined(maxLongitude)
2273
+ || isNullOrUndefined(minLatitude) && isNullOrUndefined(minLongitude)) {
2274
+ minLatitude = isNullOrUndefined(minLatitude) ? 0 : minLatitude;
2275
+ minLongitude = isNullOrUndefined(minLatitude) ? 0 : minLongitude;
2276
+ maxLatitude = isNullOrUndefined(maxLatitude) ? minLatitude : maxLatitude;
2277
+ maxLongitude = isNullOrUndefined(maxLongitude) ? minLongitude : maxLongitude;
2278
+ isTwoCoordinates = true;
2279
+ }
2280
+ if (minLatitude > maxLatitude) {
2281
+ [minLatitude, maxLatitude] = [maxLatitude, minLatitude];
2282
+ }
2283
+ if (minLongitude > maxLongitude) {
2284
+ [minLongitude, maxLongitude] = [maxLongitude, minLongitude];
2285
+ }
2286
+ if (!isTwoCoordinates) {
2287
+ centerLatitude = (minLatitude + maxLatitude) / 2;
2288
+ centerLongtitude = (minLongitude + maxLongitude) / 2;
2289
+ } else {
2290
+ centerLatitude = (minLatitude + maxLatitude);
2291
+ centerLongtitude = (minLongitude + maxLongitude);
2292
+ }
2293
+ this.centerLatOfGivenLocation = centerLatitude;
2294
+ this.centerLongOfGivenLocation = centerLongtitude;
2295
+ this.minLatOfGivenLocation = minLatitude;
2296
+ this.minLongOfGivenLocation = minLongitude;
2297
+ this.maxLatOfGivenLocation = maxLatitude;
2298
+ this.maxLongOfGivenLocation = maxLongitude;
2299
+ this.zoomNotApplied = true;
2300
+ this.scaleOfGivenLocation = calculateZoomLevel(minLatitude, maxLatitude, minLongitude, maxLongitude,
2301
+ this.mapAreaRect.width, this.mapAreaRect.height, this);
2302
+ const zoomArgs: IMapZoomEventArgs = {
2303
+ cancel: false, name: 'zoom', type: zoomIn, maps: this,
2304
+ tileTranslatePoint: {}, translatePoint: {},
2305
+ tileZoomLevel: this.isTileMap ? { previous: this.tileZoomLevel, current: this.scaleOfGivenLocation } : {},
2306
+ scale: !this.isTileMap ? { previous: this.scale, current: this.scaleOfGivenLocation } :
2307
+ { previous: this.tileZoomLevel, current: this.scaleOfGivenLocation}
2308
+ };
2309
+ this.trigger('zoom', zoomArgs);
2310
+ this.refresh();
2311
+ }
2312
+
2313
+ /**
2314
+ * This method is used to remove multiple selected shapes in the maps.
2315
+ *
2316
+ * @returns {void}
2317
+ */
2318
+ private removeShapeSelection(): void {
2319
+ const selectedElements: number = this.selectedElementId.length;
2320
+ for (let i: number = 0; i < selectedElements; i++) {
2321
+ removeClass(getElementByID(this.selectedElementId[0]));
2322
+ this.selectedElementId.splice(0, 1);
2323
+ }
2324
+ if (this.legendSettings.visible) {
2325
+ const legendSelectedElements: number = this.legendSelectionCollection.length;
2326
+ for (let i: number = 0; i < legendSelectedElements; i++) {
2327
+ removeClass(getElementByID(this.legendSelectionCollection[i]['legendElement']['id']));
2328
+ this.selectedLegendElementId.splice(0, 1);
2329
+ }
2330
+ }
2331
+ this.shapeSelectionItem = [];
2332
+ this.legendSelectionCollection = [];
2333
+
2334
+ }
2335
+
2336
+ /**
2337
+ * This method is used to set culture for maps component.
2338
+ *
2339
+ * @returns {void}
2340
+ */
2341
+ private setCulture(): void {
2342
+ this.intl = new Internationalization();
2343
+ this.setLocaleConstants();
2344
+ this.localeObject = new L10n(this.getModuleName(), this.defaultLocalConstants, this.locale);
2345
+ }
2346
+
2347
+ /**
2348
+ * This method to set locale constants to the maps component.
2349
+ *
2350
+ * @returns {void}
2351
+ */
2352
+ private setLocaleConstants(): void {
2353
+ // Need to modify after the api confirm
2354
+ this.defaultLocalConstants = {
2355
+ ZoomIn: 'Zoom in',
2356
+ Zoom: 'Zoom',
2357
+ ZoomOut: 'Zoom out',
2358
+ Pan: 'Pan',
2359
+ Reset: 'Reset',
2360
+ ImageNotFound: 'Image Not Found'
2361
+ };
2362
+ }
2363
+
2364
+ /**
2365
+ * This method disposes the maps component.
2366
+ */
2367
+ public destroy(): void {
2368
+ this.unWireEVents();
2369
+ super.destroy();
2370
+ this.shapeSelectionItem = [];
2371
+ this.toggledShapeElementId = [];
2372
+ this.toggledLegendId = [];
2373
+ this.legendSelectionCollection = [];
2374
+ this.selectedLegendElementId = [];
2375
+ this.selectedNavigationElementId = [];
2376
+ this.selectedBubbleElementId = [];
2377
+ this.selectedMarkerElementId = [];
2378
+ this.selectedElementId = [];
2379
+ this.dataLabelShape = [];
2380
+ this.zoomShapeCollection = [];
2381
+ this.zoomLabelPositions = [];
2382
+ this.mouseDownEvent = { x: null, y: null };
2383
+ this.mouseClickEvent = { x: null, y: null };
2384
+ this.formatFunction = null;
2385
+ //TODO: Calling the below code throws spec issue.
2386
+ //this.renderer = null;
2387
+ this.availableSize = new Size(0, 0);
2388
+ if (document.getElementById('mapsmeasuretext')) {
2389
+ document.getElementById('mapsmeasuretext').remove();
2390
+ }
2391
+ this.removeSvg();
2392
+ }
2393
+
2394
+ /**
2395
+ * Gets component name
2396
+ *
2397
+ * @returns {string} - Returns the string value
2398
+ */
2399
+ public getModuleName(): string {
2400
+ return 'maps';
2401
+ }
2402
+
2403
+ /**
2404
+ * Gets the properties to be maintained in the persisted state.
2405
+ *
2406
+ * @returns {string} - Returns the string value
2407
+ * @private
2408
+ */
2409
+ public getPersistData(): string {
2410
+ const keyEntity: string[] = ['translatePoint', 'zoomSettings', 'mapScaleValue', 'tileTranslatePoint', 'baseTranslatePoint',
2411
+ 'scale', 'zoomPersistence', 'defaultState', 'markerZoomedState', 'initialCheck', 'initialZoomLevel', 'initialTileTranslate',
2412
+ 'applyZoomReset', 'markerZoomFactor'];
2413
+ return this.addOnPersist(keyEntity);
2414
+ }
2415
+
2416
+ /**
2417
+ * Called internally if any of the property value changed.
2418
+ *
2419
+ * @param {MapsModel} newProp - Specifies the new property
2420
+ * @param {MapsModel} oldProp - Specifies the old property
2421
+ * @returns {void}
2422
+ * @private
2423
+ */
2424
+ public onPropertyChanged(newProp: MapsModel, oldProp: MapsModel): void {
2425
+ let render: boolean = false; let isMarker: boolean = false; let isLayer: boolean = false;
2426
+ let isStaticMapType: boolean = false;
2427
+ let layerEle: Element;
2428
+ if (newProp['layers']) {
2429
+ const newLayerLength: number = Object.keys(newProp['layers']).length;
2430
+ layerEle = document.getElementById(this.element.id + '_LayerIndex_' + (newLayerLength - 1));
2431
+ }
2432
+ for (const prop of Object.keys(newProp)) {
2433
+ switch (prop) {
2434
+ case 'background':
2435
+ this.renderBorder();
2436
+ break;
2437
+ case 'height':
2438
+ case 'width':
2439
+ case 'layers':
2440
+ case 'projectionType':
2441
+ case 'centerPosition':
2442
+ case 'legendSettings':
2443
+ case 'baseLayerIndex':
2444
+ if (prop === 'layers') {
2445
+ isLayer = true;
2446
+ const layerPropLength: number = Object.keys(newProp.layers).length;
2447
+ for (let x: number = 0; x < layerPropLength; x++) {
2448
+ if (!isNullOrUndefined(newProp.layers[x])) {
2449
+ const collection: string[] = Object.keys(newProp.layers[x]);
2450
+ for (const collectionProp of collection) {
2451
+ if ((collectionProp === 'layerType' && newProp.layers[x].layerType !== 'Geometry') || (isNullOrUndefined(this.layers[x].shapeData)
2452
+ && !isNullOrUndefined(this.layers[x].urlTemplate) && this.layers[x].urlTemplate !== '')) {
2453
+ this.isReset = true;
2454
+ } else if (collectionProp === 'markerSettings') {
2455
+ isMarker = true;
2456
+ } else if (collectionProp === 'staticMapType') {
2457
+ isStaticMapType = true;
2458
+ }
2459
+ }
2460
+ }
2461
+ }
2462
+ }
2463
+ render = true;
2464
+ break;
2465
+ case 'zoomSettings':
2466
+ if (!isNullOrUndefined(oldProp.zoomSettings)) {
2467
+ if (newProp.zoomSettings.zoomFactor !== oldProp.zoomSettings.zoomFactor && !isLayer) {
2468
+ render = false;
2469
+ }
2470
+ else if (newProp.zoomSettings.shouldZoomInitially !== oldProp.zoomSettings.shouldZoomInitially) {
2471
+ this.zoomSettings.zoomFactor = 1;
2472
+ render = true;
2473
+ } else if (newProp.zoomSettings.enable !== oldProp.zoomSettings.enable) {
2474
+ this.zoomSettings.zoomFactor = 1;
2475
+ render = true;
2476
+ }
2477
+ else {
2478
+ render = true;
2479
+ }
2480
+ }
2481
+ break;
2482
+ case 'locale':
2483
+ case 'currencyCode':
2484
+ super.refresh(); break;
2485
+ }
2486
+ }
2487
+ if (render) {
2488
+ if (newProp.layers && isMarker) {
2489
+ removeElement(this.element.id + '_Markers_Group');
2490
+ if (this.isTileMap) {
2491
+ this.mapLayerPanel.renderTileLayer(this.mapLayerPanel, this.layers['currentFactor'], (this.layers.length - 1));
2492
+ }
2493
+ else {
2494
+ this.render();
2495
+ }
2496
+ } else if (newProp.layers && isStaticMapType) {
2497
+ this.mapLayerPanel.renderGoogleMap(this.layers[this.layers.length - 1].key, this.staticMapZoom);
2498
+ } else {
2499
+ this.createSVG();
2500
+ this.renderElements();
2501
+ }
2502
+ }
2503
+ }
2504
+ /**
2505
+ * To provide the array of modules needed for maps rendering
2506
+ *
2507
+ * @returns {ModuleDeclaration[]} - Returns the modules
2508
+ * @private
2509
+ */
2510
+ public requiredModules(): ModuleDeclaration[] {
2511
+ const modules: ModuleDeclaration[] = [];
2512
+ const isVisible: { layer: boolean, bubble: boolean, tooltip: boolean, selection: boolean, highlight: boolean } =
2513
+ this.findVisibleLayers(this.layers);
2514
+ let annotationEnable: boolean = false;
2515
+ this.annotations.map((annotation: Annotation, index: number) => {
2516
+ annotationEnable = annotation.content != null;
2517
+ });
2518
+
2519
+ if (this.isBubbleVisible()) {
2520
+ modules.push({
2521
+ member: 'Bubble',
2522
+ args: [this]
2523
+ });
2524
+ }
2525
+ if (isVisible.highlight) {
2526
+ modules.push({
2527
+ member: 'Highlight',
2528
+ args: [this]
2529
+ });
2530
+ }
2531
+ if (isVisible.selection) {
2532
+ modules.push({
2533
+ member: 'Selection',
2534
+ args: [this]
2535
+ });
2536
+ }
2537
+ if (this.legendSettings.visible) {
2538
+ modules.push({
2539
+ member: 'Legend',
2540
+ args: [this]
2541
+ });
2542
+ }
2543
+ if (this.zoomSettings.enable || this.zoomSettings.zoomFactor > this.zoomSettings.minZoom) {
2544
+ modules.push({
2545
+ member: 'Zoom',
2546
+ args: [this]
2547
+ });
2548
+ }
2549
+
2550
+ if (this.isMarkersVisible()) {
2551
+ modules.push({
2552
+ member: 'Marker',
2553
+ args: [this]
2554
+ });
2555
+ }
2556
+
2557
+
2558
+ if (this.isDataLabelVisible()) {
2559
+ modules.push({
2560
+ member: 'DataLabel',
2561
+ args: [this]
2562
+ });
2563
+ }
2564
+
2565
+ if (this.isNavigationVisible()) {
2566
+ modules.push({
2567
+ member: 'NavigationLine',
2568
+ args: [this]
2569
+ });
2570
+ }
2571
+
2572
+ if (isVisible.tooltip) {
2573
+ modules.push({
2574
+ member: 'MapsTooltip',
2575
+ args: [this]
2576
+ });
2577
+ }
2578
+ if (annotationEnable) {
2579
+ modules.push({
2580
+ member: 'Annotations',
2581
+ args: [this, Annotations]
2582
+ });
2583
+ }
2584
+ if (this.allowPrint) {
2585
+ modules.push({
2586
+ member: 'Print',
2587
+ args: [this]
2588
+ });
2589
+ }
2590
+ if (this.allowImageExport) {
2591
+ modules.push({
2592
+ member: 'ImageExport',
2593
+ args: [this]
2594
+ });
2595
+ }
2596
+ if (this.allowPdfExport) {
2597
+ modules.push({
2598
+ member: 'PdfExport',
2599
+ args: [this]
2600
+ });
2601
+ }
2602
+
2603
+ return modules;
2604
+ }
2605
+
2606
+ /**
2607
+ * To find marker visibility
2608
+ */
2609
+
2610
+ private isMarkersVisible(): boolean {
2611
+ let isVisible: boolean = false;
2612
+ Array.prototype.forEach.call(this.layers, (layer: LayerSettings, layerIndex: number) => {
2613
+ for (let i: number = 0; i < layer.markerSettings.length; i++) {
2614
+ if (layer.markerSettings[i].visible) {
2615
+ isVisible = true;
2616
+ break;
2617
+ }
2618
+ }
2619
+ });
2620
+ return isVisible;
2621
+ }
2622
+
2623
+ /**
2624
+ * To find DataLabel visibility
2625
+ */
2626
+
2627
+ private isDataLabelVisible(): boolean {
2628
+ let isVisible: boolean = false;
2629
+ for (let i: number = 0; i < this.layers.length; i++) {
2630
+ if (this.layers[i].dataLabelSettings.visible) {
2631
+ isVisible = true;
2632
+ break;
2633
+ }
2634
+ }
2635
+ return isVisible;
2636
+ }
2637
+
2638
+ /**
2639
+ * To find navigation line visibility
2640
+ */
2641
+
2642
+ private isNavigationVisible(): boolean {
2643
+ let isVisible: boolean = false;
2644
+ Array.prototype.forEach.call(this.layers, (layer: LayerSettings, layerIndex: number) => {
2645
+ for (let i: number = 0; i < layer.navigationLineSettings.length; i++) {
2646
+ if (layer.navigationLineSettings[i].visible) {
2647
+ isVisible = true;
2648
+ break;
2649
+ }
2650
+ }
2651
+ });
2652
+ return isVisible;
2653
+ }
2654
+
2655
+ /**
2656
+ * To find space between the secondary element and svg element.
2657
+ * @private
2658
+ */
2659
+ public getExtraPosition(): Point {
2660
+ let top: number = 0;
2661
+ let left: number = 0;
2662
+ const svgElement: Element = getElement(this.element.id + '_svg');
2663
+ if (!isNullOrUndefined(svgElement)) {
2664
+ const svgClientRects: DOMRectList = svgElement.getClientRects() as DOMRectList;
2665
+ const mapsClientRects: DOMRectList = (getElement(this.element.id + '_Secondary_Element')).getClientRects() as DOMRectList;
2666
+ if (svgClientRects.length !== 0 && mapsClientRects.length !== 0) {
2667
+ const svgClientRect: ClientRect = svgClientRects[0];
2668
+ const mapsClientRect: ClientRect = mapsClientRects[0];
2669
+ top = svgClientRect.top - mapsClientRect.top;
2670
+ left = svgClientRect.left - mapsClientRect.left;
2671
+ }
2672
+ }
2673
+ return new Point(left, top);
2674
+ }
2675
+
2676
+ /**
2677
+ * To find marker visibility
2678
+ */
2679
+
2680
+ private isBubbleVisible(): boolean {
2681
+ let isVisible: boolean = false;
2682
+ for (const layer of this.layers) {
2683
+ if (this.getBubbleVisible(layer)) {
2684
+ isVisible = true;
2685
+ break;
2686
+ }
2687
+ }
2688
+ return isVisible;
2689
+ }
2690
+ /**
2691
+ * To find the bubble visibility from layer
2692
+ *
2693
+ * @param {LayerSettingsModel} layer - Spcifies the layer settings model
2694
+ * @returns {boolean} - Returns the boolean value
2695
+ * @private
2696
+ */
2697
+ public getBubbleVisible(layer: LayerSettingsModel): boolean {
2698
+ let isVisible: boolean = false;
2699
+ for (const bubble of layer.bubbleSettings) {
2700
+ if (bubble.visible) {
2701
+ isVisible = true;
2702
+ break;
2703
+ }
2704
+ }
2705
+ return isVisible;
2706
+ }
2707
+ /**
2708
+ * This method handles the printing functionality for the maps component.
2709
+ *
2710
+ * @param {string[] | string | Element} id - Specifies the element to be printed.
2711
+ * @returns {void}
2712
+ */
2713
+ public print(id?: string[] | string | Element): void {
2714
+ if ((this.allowPrint) && (this.printModule)) {
2715
+ this.printModule.print(this, id);
2716
+ }
2717
+ }
2718
+ /**
2719
+ * This method handles the export functionality for the maps component.
2720
+ *
2721
+ * @param {ExportType} type - Specifies the type of the exported file.
2722
+ * @param {string} fileName - Specifies the name of the file with which the rendered maps need to be exported.
2723
+ * @param {PdfPageOrientation} orientation - Specifies the orientation of the pdf document in exporting.
2724
+ * @param {boolean} allowDownload - Specifies whether to download as a file or get as base64 string for the file
2725
+ * @returns {Promise<string>} - Returns the string value.
2726
+ */
2727
+ public export(type: ExportType, fileName: string, orientation?: PdfPageOrientation, allowDownload?: boolean): Promise<string> {
2728
+ if (isNullOrUndefined(allowDownload)) {
2729
+ allowDownload = true;
2730
+ }
2731
+ if ((type !== 'PDF') && (this.allowImageExport) && (this.imageExportModule)) {
2732
+ return new Promise((resolve: any, reject: any) => {
2733
+ resolve(this.imageExportModule.export(this, type, fileName, allowDownload));
2734
+ });
2735
+ } else if ((this.allowPdfExport) && (this.pdfExportModule)) {
2736
+ return new Promise((resolve: any, reject: any) => {
2737
+ resolve(this.pdfExportModule.export(this, type, fileName, allowDownload, orientation));
2738
+ });
2739
+ }
2740
+ return null;
2741
+ }
2742
+
2743
+ /**
2744
+ * This method is used to get the Bing maps URL.
2745
+ *
2746
+ * @param {string} url - Specifies the URL of the maps.
2747
+ * @returns {Promise<string>} - Returns the processed Bing URL as Promise.
2748
+ */
2749
+ public getBingUrlTemplate(url: string): Promise<string> {
2750
+ const promise: Promise<string> = new Promise((resolve: any, reject: any) => {
2751
+ const ajax: Ajax = new Ajax({
2752
+ url: url
2753
+ });
2754
+ ajax.onSuccess = (json: string) => {
2755
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2756
+ const jsonObject: any = JSON.parse(json);
2757
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2758
+ const resource: any = jsonObject['resourceSets'][0]['resources'][0];
2759
+ resolve(<string>resource['imageUrl']);
2760
+ }
2761
+ ajax.send();
2762
+ });
2763
+ return promise;
2764
+ }
2765
+
2766
+ /**
2767
+ * To find visibility of layers and markers for required modules load.
2768
+ *
2769
+ * @param {LayerSettingsModel[]} layers - Specifies the layers.
2770
+ * @param {boolean} isLayerVisible - Specifies whether the layer is visible or not.
2771
+ * @param {boolean} isBubblevisible - Specifies whether the bubble is visible or not.
2772
+ * @param {boolean} istooltipVisible - Specifies whether the tooltip is visible or not.
2773
+ * @param {boolean} isSelection - Specifies whether the shape is selectd or not.
2774
+ * @param {boolean} isHighlight - Specfies whether the shape is highlighted or not.
2775
+ * @returns {boolean} - Returns the boolean value
2776
+ */
2777
+ private findVisibleLayers(
2778
+ layers: LayerSettingsModel[], isLayerVisible: boolean = false,
2779
+ isBubblevisible: boolean = false, istooltipVisible: boolean = false, isSelection: boolean = false,
2780
+ isHighlight: boolean = false
2781
+ ): { layer: boolean, bubble: boolean, tooltip: boolean, selection: boolean, highlight: boolean } {
2782
+ let bubbles: BubbleSettingsModel[];
2783
+ let markers: MarkerSettingsModel[];
2784
+ let navigationLine: NavigationLineSettingsModel[];
2785
+ for (const layer of layers) {
2786
+ isLayerVisible = layer.visible || isLayerVisible;
2787
+ if (layer.visible) {
2788
+ bubbles = layer.bubbleSettings;
2789
+ markers = layer.markerSettings;
2790
+ navigationLine = layer.navigationLineSettings;
2791
+ for (const navigation of navigationLine) {
2792
+ if (navigation.visible) {
2793
+ isSelection = navigation.highlightSettings.enable || isSelection;
2794
+ isHighlight = navigation.selectionSettings.enable || isHighlight;
2795
+ }
2796
+ }
2797
+ for (const marker of markers) {
2798
+ if (marker.visible) {
2799
+ istooltipVisible = marker.tooltipSettings.visible || istooltipVisible;
2800
+ isSelection = marker.selectionSettings.enable || isSelection;
2801
+ isHighlight = marker.highlightSettings.enable || isHighlight;
2802
+ }
2803
+ if (istooltipVisible) { break; }
2804
+ }
2805
+ for (const bubble of bubbles) {
2806
+ if (bubble.visible) {
2807
+ istooltipVisible = bubble.tooltipSettings.visible || istooltipVisible;
2808
+ isSelection = bubble.selectionSettings.enable || isSelection;
2809
+ isHighlight = bubble.highlightSettings.enable || isHighlight;
2810
+ }
2811
+ if (istooltipVisible) { break; }
2812
+ }
2813
+ istooltipVisible = layer.tooltipSettings.visible || istooltipVisible;
2814
+ isSelection = layer.selectionSettings.enable || isSelection;
2815
+ isHighlight = layer.highlightSettings.enable || isHighlight;
2816
+ }
2817
+ if (isLayerVisible && isBubblevisible && istooltipVisible) { break; }
2818
+ }
2819
+ return {
2820
+ layer: isLayerVisible, bubble: isBubblevisible, tooltip: istooltipVisible,
2821
+ selection: isSelection, highlight: isHighlight
2822
+ };
2823
+ }
2824
+ /**
2825
+ * This method is used to get the geo location points.
2826
+ *
2827
+ * @param {number} layerIndex - Specifies the index number of the layer of the map.
2828
+ * @param {number} x - Specifies the x value.
2829
+ * @param {number} y - Specifies the y value.
2830
+ * @returns {GeoPosition}- Returns the geo position
2831
+ */
2832
+ public getGeoLocation(layerIndex: number, x: number, y: number): GeoPosition {
2833
+ const container: HTMLElement = document.getElementById(this.element.id);
2834
+ const pageX: number = x - container.offsetLeft;
2835
+ const pageY: number = y - container.offsetTop;
2836
+ const currentLayer: LayerSettings = <LayerSettings>this.layersCollection[layerIndex];
2837
+ const translate: any = getTranslate(this, currentLayer, false);
2838
+ const translatePoint: Point = translate['location'] as Point;
2839
+ const translatePointX: number = translatePoint.x * this.scale;
2840
+ const translatePointY: number = translatePoint.y * this.scale;
2841
+ const mapSize: number = (Math.min(this.mapAreaRect.height, this.mapAreaRect.width)
2842
+ * this.mapLayerPanel['currentFactor']) * this.scale;
2843
+ const xx: number = (this.clip(pageX - translatePointX, 0, mapSize - 1) / mapSize) - 0.5;
2844
+ const yy: number = 0.5 - (this.clip(pageY - translatePointY, 0, mapSize - 1) / mapSize);
2845
+ const lat: number = 90 - 360 * Math.atan(Math.exp(-yy * 2 * Math.PI)) / Math.PI;
2846
+ const long: number = 360 * xx;
2847
+ return { latitude: lat, longitude: long };
2848
+ }
2849
+
2850
+ private clip(value: number, minVal: number, maxVal: number): number {
2851
+ return Math.min(Math.max(value, minVal), maxVal);
2852
+ }
2853
+
2854
+ /**
2855
+ * This method is used to get the geo location points when tile maps is rendered in the maps component.
2856
+ *
2857
+ * @param {number} x - Specifies the x value
2858
+ * @param {number} y - Specifies the y value
2859
+ * @returns {GeoPosition} - Returns the position
2860
+ */
2861
+ public getTileGeoLocation(x: number, y: number): GeoPosition {
2862
+ const container: HTMLElement = document.getElementById(this.element.id);
2863
+ const ele: HTMLElement = document.getElementById(this.element.id + '_tile_parent');
2864
+ const latLong: any = this.pointToLatLong(
2865
+ x + this.mapAreaRect.x - (ele.offsetLeft - container.offsetLeft),
2866
+ y + this.mapAreaRect.y - (ele.offsetTop - container.offsetTop));
2867
+ return { latitude: latLong['latitude'], longitude: latLong['longitude'] };
2868
+ }
2869
+ /**
2870
+ * This method is used to convert the point to latitude and longitude in maps.
2871
+ *
2872
+ * @param {number} pageX - Specifies the x value for the page.
2873
+ * @param {number} pageY - Specifies the y value for the page.
2874
+ * @returns {Object} - Returns the object.
2875
+ */
2876
+ public pointToLatLong(pageX: number, pageY: number): Object {
2877
+ const padding: number = this.layers[this.layers.length - 1].layerType === 'GoogleStaticMap' ? 0 : 10;
2878
+ pageY = (this.zoomSettings.enable) ? pageY + padding : pageY;
2879
+ const mapSize: number = 256 * Math.pow(2, this.tileZoomLevel);
2880
+ const x1: number = (this.clip(pageX - (this.translatePoint.x * this.scale), 0, mapSize - 1) / mapSize) - 0.5;
2881
+ const y1: number = 0.5 - (this.clip(pageY - (this.translatePoint.y * this.scale), 0, mapSize - 1) / mapSize);
2882
+ const lat: number = 90 - 360 * Math.atan(Math.exp(-y1 * 2 * Math.PI)) / Math.PI;
2883
+ const long: number = 360 * x1;
2884
+ return { latitude: lat, longitude: long };
2885
+ }
2886
+ }