@syncfusion/ej2-maps 19.4.56 → 19.4.57-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 -439
  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 +1161 -638
  9. package/dist/es6/ej2-maps.es2015.js.map +1 -1
  10. package/dist/es6/ej2-maps.es5.js +1200 -678
  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 +152 -90
  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 +26 -32
  66. package/src/maps/model/export-pdf.d.ts +4 -6
  67. package/src/maps/model/export-pdf.js +27 -35
  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 +33 -21
  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 +1 -1
  84. package/src/maps/utils/helper.js +62 -31
@@ -0,0 +1,453 @@
1
+ /* eslint-disable valid-jsdoc */
2
+ /* eslint-disable jsdoc/require-param */
3
+ /* eslint-disable @typescript-eslint/no-unused-vars */
4
+ /* eslint-disable max-len */
5
+ import { Maps } from '../../index';
6
+ import {
7
+ LayerSettings, MarkerSettings, IMarkerRenderingEventArgs, markerRendering,
8
+ convertTileLatLongToPoint, MapLocation, MarkerClusterData
9
+ } from '../index';
10
+ import {
11
+ IMarkerClickEventArgs, markerClick, IMarkerMoveEventArgs, markerMouseMove,
12
+ IMarkerClusterClickEventArgs, IMarkerClusterMoveEventArgs, markerClusterClick, markerClusterMouseMove,
13
+ MarkerSettingsModel
14
+ } from '../index';
15
+ import { isNullOrUndefined, createElement } from '@syncfusion/ej2-base';
16
+ import { Point, getTranslate, convertGeoToPoint, clusterTemplate, marker, markerTemplate, getZoomTranslate } from '../utils/helper';
17
+ import {
18
+ getElementByID, mergeSeparateCluster, clusterSeparate, removeElement, getElement,
19
+ markerColorChoose, markerShapeChoose, calculateZoomLevel, compareZoomFactor, getValueFromObject
20
+ } from '../utils/helper';
21
+
22
+ /**
23
+ * Marker class
24
+ */
25
+ export class Marker {
26
+ private maps: Maps;
27
+ private isMarkerExplode: number;
28
+ private trackElements: Element[];
29
+ private markerSVGObject: Element;
30
+ /**
31
+ * @private
32
+ */
33
+ public sameMarkerData: MarkerClusterData[];
34
+ constructor(maps: Maps) {
35
+ this.maps = maps;
36
+ this.trackElements = [];
37
+ this.sameMarkerData = [];
38
+ }
39
+
40
+ public markerRender(maps: Maps, layerElement: Element, layerIndex: number, factor: number, type: string): void {
41
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
+ let templateFn: any;
43
+ let markerCount: number = 0;
44
+ let nullCount: number = 0;
45
+ let markerTemplateCount: number = 0; maps.translateType = 'marker';
46
+ const currentLayer: LayerSettings = <LayerSettings>maps.layersCollection[layerIndex];
47
+ this.markerSVGObject = maps.renderer.createGroup({
48
+ id: maps.element.id + '_Markers_Group',
49
+ class: 'GroupElement',
50
+ style: 'pointer-events: auto;'
51
+ });
52
+ const markerTemplateEle: HTMLElement = createElement('div', {
53
+ id: maps.element.id + '_LayerIndex_' + layerIndex + '_Markers_Template_Group',
54
+ className: maps.element.id + '_template',
55
+ styles: 'overflow: hidden; position: absolute;pointer-events: none;' +
56
+ 'top:' + maps.mapAreaRect.y + 'px;' +
57
+ 'left:' + maps.mapAreaRect.x + 'px;' +
58
+ 'height:' + maps.mapAreaRect.height + 'px;' +
59
+ 'width:' + maps.mapAreaRect.width + 'px;'
60
+ });
61
+ currentLayer.markerSettings.map((markerSettings: MarkerSettings, markerIndex: number) => {
62
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
63
+ const markerData: any[] = <any[]>markerSettings.dataSource;
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ Array.prototype.forEach.call(markerData, (data: any, dataIndex: number) => {
66
+ maps.markerNullCount = markerIndex > 0 && dataIndex === 0 ? 0 : maps.markerNullCount;
67
+ let eventArgs: IMarkerRenderingEventArgs = {
68
+ cancel: false, name: markerRendering, fill: markerSettings.fill, height: markerSettings.height,
69
+ width: markerSettings.width, imageUrl: markerSettings.imageUrl, shape: markerSettings.shape,
70
+ template: markerSettings.template, data: data, maps: maps, marker: markerSettings,
71
+ border: markerSettings.border, colorValuePath: markerSettings.colorValuePath,
72
+ shapeValuePath: markerSettings.shapeValuePath, imageUrlValuePath: markerSettings.imageUrlValuePath
73
+ };
74
+ maps.trigger('markerRendering', eventArgs, (MarkerArgs: IMarkerRenderingEventArgs) => {
75
+ eventArgs = markerColorChoose(eventArgs, data);
76
+ eventArgs = markerShapeChoose(eventArgs, data);
77
+ const lng: number = (!isNullOrUndefined(markerSettings.longitudeValuePath)) ?
78
+ Number(getValueFromObject(data, markerSettings.longitudeValuePath)) : !isNullOrUndefined(data['longitude']) ?
79
+ parseFloat(data['longitude']) : !isNullOrUndefined(data['Longitude']) ? parseFloat(data['Longitude']) : null;
80
+ const lat: number = (!isNullOrUndefined(markerSettings.latitudeValuePath)) ?
81
+ Number(getValueFromObject(data, markerSettings.latitudeValuePath)) : !isNullOrUndefined(data['latitude']) ?
82
+ parseFloat(data['latitude']) : !isNullOrUndefined(data['Latitude']) ? parseFloat(data['Latitude']) : null;
83
+ const offset: Point = markerSettings.offset;
84
+ if (!eventArgs.cancel && markerSettings.visible && !isNullOrUndefined(lng) && !isNullOrUndefined(lat)) {
85
+ const markerID: string = maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_'
86
+ + markerIndex + '_dataIndex_' + dataIndex;
87
+ let location: Point = (maps.isTileMap) ? convertTileLatLongToPoint(
88
+ new MapLocation(lng, lat), factor, maps.tileTranslatePoint, true
89
+ ) : convertGeoToPoint(lat, lng, factor, currentLayer, maps);
90
+ const animate: boolean = currentLayer.animationDuration !== 0 || isNullOrUndefined(maps.zoomModule);
91
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
92
+ const translate: any = (maps.isTileMap) ? (currentLayer.type === 'SubLayer' && isNullOrUndefined(maps.zoomModule)) ? location = convertTileLatLongToPoint(
93
+ new MapLocation(lng, lat), maps.tileZoomLevel, maps.tileTranslatePoint, true
94
+ ) : new Object() :
95
+ !isNullOrUndefined(maps.zoomModule) && maps.zoomSettings.zoomFactor > 1 ?
96
+ getZoomTranslate(maps, currentLayer, animate) :
97
+ getTranslate(maps, currentLayer, animate);
98
+ const scale: number = type === 'AddMarker' ? maps.scale : translate['scale'];
99
+ const transPoint: Point = type === 'AddMarker' ? maps.translatePoint : translate['location'] as Point;
100
+ if (eventArgs.template && (!isNaN(location.x) && !isNaN(location.y))) {
101
+ markerTemplateCount++;
102
+ markerTemplate(eventArgs, templateFn, markerID, data, markerIndex, markerTemplateEle, location, transPoint,
103
+ scale, offset, maps);
104
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
+ (maps as any).renderReactTemplates();
106
+ } else if (!eventArgs.template && (!isNaN(location.x) && !isNaN(location.y))) {
107
+ markerCount++;
108
+ marker(eventArgs, markerSettings, markerData, dataIndex,
109
+ location, transPoint, markerID, offset, scale, maps, this.markerSVGObject);
110
+ }
111
+ }
112
+ nullCount += (!isNaN(lat) && !isNaN(lng)) ? 0 : 1;
113
+ markerTemplateCount += (eventArgs.cancel) ? 1 : 0;
114
+ markerCount += (eventArgs.cancel) ? 1 : 0;
115
+ maps.markerNullCount = (isNullOrUndefined(lng) || isNullOrUndefined(lat)) ? maps.markerNullCount + 1 : maps.markerNullCount;
116
+ const markerDataLength: number = markerData.length - maps.markerNullCount;
117
+ if (this.markerSVGObject.childElementCount === (markerDataLength - markerTemplateCount - nullCount) && (type !== 'Template')) {
118
+ layerElement.appendChild(this.markerSVGObject);
119
+ if (currentLayer.markerClusterSettings.allowClustering) {
120
+ maps.svgObject.appendChild(this.markerSVGObject);
121
+ maps.element.appendChild(maps.svgObject);
122
+ if ((currentLayer.layerType === 'OSM' || (currentLayer.urlTemplate.indexOf('openstreetmap') !== -1 && isNullOrUndefined(currentLayer.shapeData)))
123
+ && maps.zoomSettings.enable) {
124
+ layerElement.appendChild(this.markerSVGObject);
125
+ } else {
126
+ clusterTemplate(currentLayer, this.markerSVGObject,
127
+ maps, layerIndex, this.markerSVGObject, layerElement, true, false);
128
+ }
129
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
130
+ (maps as any).renderReactTemplates();
131
+ }
132
+ }
133
+ if (markerTemplateEle.childElementCount === (markerDataLength - markerCount - nullCount) && getElementByID(maps.element.id + '_Secondary_Element')) {
134
+ getElementByID(maps.element.id + '_Secondary_Element').appendChild(markerTemplateEle);
135
+ if (maps.checkInitialRender) {
136
+ if (currentLayer.markerClusterSettings.allowClustering) {
137
+ clusterTemplate(currentLayer, markerTemplateEle, maps,
138
+ layerIndex, this.markerSVGObject, layerElement, false, false);
139
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
140
+ (maps as any).renderReactTemplates();
141
+ }
142
+ }
143
+ }
144
+ });
145
+ });
146
+ });
147
+ }
148
+ /**
149
+ * To find zoom level for individual layers like India, USA.
150
+ *
151
+ * @param {number} mapWidth - Specifies the width of the maps
152
+ * @param {number} mapHeight - Specifies the height of the maps
153
+ * @param {number} maxZoomFact - Specifies the maximum zoom factor
154
+ * @returns {number} - Returns the scale factor
155
+ */
156
+ private calculateIndividualLayerMarkerZoomLevel(mapWidth : number, mapHeight : number,
157
+ maxZoomFact : number): number {
158
+ let latZoom: number; let lngZoom : number;
159
+ const height : number = Math.abs(this.maps.baseMapBounds.latitude.max - this.maps.baseMapBounds.latitude.min);
160
+ const width : number = Math.abs(this.maps.baseMapBounds.longitude.max - this.maps.baseMapBounds.longitude.min);
161
+ latZoom = Math.floor(Math.log(mapHeight / height));
162
+ latZoom = (latZoom > maxZoomFact) ? maxZoomFact : latZoom;
163
+ lngZoom = Math.floor(Math.log(mapWidth / width));
164
+ lngZoom = (lngZoom > maxZoomFact) ? maxZoomFact : lngZoom;
165
+ const result: number = Math.min(latZoom, lngZoom);
166
+ const scaleFactor: number = Math.min(result, maxZoomFact - 1);
167
+ if (!this.maps.isTileMap) {
168
+ compareZoomFactor(scaleFactor, this.maps);
169
+ }
170
+ return scaleFactor;
171
+ }
172
+ /**
173
+ * To calculate center position and factor value dynamically
174
+ */
175
+ public calculateZoomCenterPositionAndFactor(layersCollection: LayerSettings[]): void {
176
+ if (this.maps.zoomSettings.shouldZoomInitially && this.maps.markerModule) {
177
+ let minLong: number; let maxLat: number; let minLat: number; let maxLong: number;
178
+ let latZoom: number; let lngZoom : number; let result: number; let zoomLevel : number;
179
+ let centerLat: number; let centerLong: number; const maxZoomFact: number = this.maps.zoomSettings.maxZoom;
180
+ const mapWidth: number = this.maps.mapAreaRect.width;
181
+ const mapHeight: number = this.maps.mapAreaRect.height;
182
+ this.maps.markerZoomedState = this.maps.markerZoomedState ? this.maps.markerZoomedState : isNullOrUndefined(this.maps.markerZoomFactor) ?
183
+ !this.maps.markerZoomedState : this.maps.markerZoomFactor > 1 ? this.maps.markerZoomedState : !this.maps.markerZoomedState;
184
+ this.maps.defaultState = this.maps.markerZoomedState ? !this.maps.markerZoomedState : this.maps.defaultState;
185
+ Array.prototype.forEach.call(layersCollection, (currentLayer: LayerSettings, layerIndex: number) => {
186
+ const isMarker: boolean = currentLayer.markerSettings.length !== 0;
187
+ if (isMarker) {
188
+ Array.prototype.forEach.call(currentLayer.markerSettings, (markerSetting: MarkerSettingsModel, markerIndex: number) => {
189
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
190
+ const markerData: any[] = <any[]>markerSetting.dataSource;
191
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
192
+ Array.prototype.forEach.call(markerData, (data: any, dataIndex: number) => {
193
+ const latitude: number = !isNullOrUndefined(data['latitude']) ? parseFloat(data['latitude']) :
194
+ !isNullOrUndefined(data['Latitude']) ? parseFloat(data['Latitude']) : null;
195
+ const longitude: number = !isNullOrUndefined(data['longitude']) ? parseFloat(data['longitude']) :
196
+ !isNullOrUndefined(data['Longitude']) ? parseFloat(data['Longitude']) : null;
197
+ minLong = isNullOrUndefined(minLong) && dataIndex === 0 ?
198
+ longitude : minLong;
199
+ maxLat = isNullOrUndefined(maxLat) && dataIndex === 0 ?
200
+ latitude : maxLat;
201
+ minLat = isNullOrUndefined(minLat) && dataIndex === 0 ?
202
+ latitude : minLat;
203
+ maxLong = isNullOrUndefined(maxLong) && dataIndex === 0 ?
204
+ longitude : maxLong;
205
+ if (minLong > longitude) {
206
+ minLong = longitude;
207
+ }
208
+ if (minLat > latitude) {
209
+ minLat = latitude;
210
+ }
211
+ if (maxLong < longitude) {
212
+ maxLong = longitude;
213
+ }
214
+ if (maxLat < latitude) {
215
+ maxLat = latitude;
216
+ }
217
+ });
218
+ });
219
+ }
220
+ });
221
+ if (!isNullOrUndefined(minLat) && !isNullOrUndefined(minLong) &&
222
+ !isNullOrUndefined(maxLong) && !isNullOrUndefined(maxLat)) {
223
+ // To find the center position
224
+ centerLat = (minLat + maxLat) / 2;
225
+ centerLong = (minLong + maxLong) / 2;
226
+ this.maps.markerCenterLatitude = centerLat;
227
+ this.maps.markerCenterLongitude = centerLong;
228
+ if (isNullOrUndefined(this.maps.markerZoomCenterPoint) || this.maps.markerZoomedState) {
229
+ this.maps.markerZoomCenterPoint = {
230
+ latitude: centerLat,
231
+ longitude: centerLong
232
+ };
233
+ }
234
+ let markerFactor: number;
235
+ if (this.maps.isTileMap || this.maps.baseMapRectBounds['min']['x'] === 0) {
236
+ zoomLevel = calculateZoomLevel(minLat, maxLat, minLong, maxLong, mapWidth, mapHeight, this.maps);
237
+ if (this.maps.isTileMap) {
238
+ markerFactor = isNullOrUndefined(this.maps.markerZoomFactor) ?
239
+ zoomLevel : isNullOrUndefined(this.maps.mapScaleValue) ?
240
+ zoomLevel : this.maps.mapScaleValue > 1 && this.maps.markerZoomFactor !== 1 ?
241
+ this.maps.mapScaleValue : zoomLevel;
242
+ } else {
243
+ markerFactor = isNullOrUndefined(this.maps.mapScaleValue) ? zoomLevel :
244
+ (Math.floor(this.maps.scale) !== 1 &&
245
+ this.maps.mapScaleValue !== zoomLevel)
246
+ &&
247
+ (isNullOrUndefined(this.maps.shouldZoomCurrentFactor))
248
+ ? this.maps.mapScaleValue : zoomLevel;
249
+ if (((markerFactor === this.maps.mapScaleValue &&
250
+ (this.maps.markerZoomFactor === 1 || this.maps.mapScaleValue === 1))
251
+ && (!this.maps.enablePersistence))) {
252
+ markerFactor = zoomLevel;
253
+ }
254
+ }
255
+ } else {
256
+ zoomLevel = this.calculateIndividualLayerMarkerZoomLevel(mapWidth, mapHeight, maxZoomFact);
257
+ markerFactor = isNullOrUndefined(this.maps.mapScaleValue) ? zoomLevel :
258
+ (this.maps.mapScaleValue !== zoomLevel)
259
+ ? this.maps.mapScaleValue : zoomLevel;
260
+ }
261
+ this.maps.markerZoomFactor = markerFactor;
262
+ }
263
+ } else {
264
+ this.maps.markerZoomedState = false;
265
+ if (this.maps.markerZoomFactor > 1) {
266
+ this.maps.markerCenterLatitude = null;
267
+ this.maps.markerCenterLongitude = null;
268
+ this.maps.markerZoomFactor = 1;
269
+ if (!this.maps.enablePersistence){
270
+ this.maps.mapScaleValue = 1;
271
+ }
272
+ }
273
+ if (this.maps.isTileMap && !this.maps.enablePersistence
274
+ && this.maps.mapScaleValue <= 1) {
275
+ this.maps.tileZoomLevel = this.maps.mapScaleValue === 0 ? 1 : this.maps.mapScaleValue;
276
+ if (this.maps.mapScaleValue === 1 && this.maps.markerZoomFactor === 1) {
277
+ this.maps.tileTranslatePoint.x = 0;
278
+ this.maps.tileTranslatePoint.y = 0;
279
+ }
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * To check and trigger marker click event
285
+ */
286
+ public markerClick(e: PointerEvent): void {
287
+ const target: string = (e.target as Element).id;
288
+ if (target.indexOf('_LayerIndex_') === -1 || target.indexOf('_cluster_') > 0) {
289
+ return;
290
+ }
291
+ const options: { marker: MarkerSettingsModel, data: object } = this.getMarker(target);
292
+ if (isNullOrUndefined(options)) {
293
+ return;
294
+ }
295
+ const eventArgs: IMarkerClickEventArgs = {
296
+ cancel: false, name: markerClick, data: options.data, maps: this.maps,
297
+ marker: options.marker, target: target, x: e.clientX, y: e.clientY,
298
+ latitude: options.data['latitude'] || options.data['Latitude'],
299
+ longitude: options.data['longitude'] || options.data['Longitude'],
300
+ value: options.data['name']
301
+ };
302
+ this.maps.trigger(markerClick, eventArgs);
303
+ }
304
+ /**
305
+ * To check and trigger Cluster click event
306
+ */
307
+ public markerClusterClick(e: PointerEvent): void {
308
+ const target: string = (e.target as Element).id;
309
+ if (target.indexOf('_LayerIndex_') === -1 || target.indexOf('_cluster_') === -1) {
310
+ return;
311
+ }
312
+ const options: { marker: MarkerSettingsModel, data: object, clusterCollection: MarkerClusterData[], markCollection: object[] } = this.getMarker(target);
313
+ if (isNullOrUndefined(options)) {
314
+ return;
315
+ }
316
+ if ((options.clusterCollection.length > 0 && this.maps.markerClusterExpand)) {
317
+ if (getElement(this.maps.element.id + '_mapsTooltip') &&
318
+ this.maps.mapsTooltipModule.tooltipTargetID.indexOf('_MarkerIndex_') > -1) {
319
+ removeElement(this.maps.element.id + '_mapsTooltip');
320
+ }
321
+ if (this.sameMarkerData.length > 0 && !this.maps.markerClusterExpandCheck) {
322
+ this.maps.markerClusterExpandCheck = true;
323
+ mergeSeparateCluster(this.sameMarkerData, this.maps, this.markerSVGObject);
324
+ } else {
325
+ this.sameMarkerData = options.clusterCollection;
326
+ this.maps.markerClusterExpandCheck = false;
327
+ clusterSeparate(this.sameMarkerData, this.maps, this.markerSVGObject, true);
328
+ }
329
+ }
330
+ const eventArgs: IMarkerClusterClickEventArgs = {
331
+ cancel: false, name: markerClusterClick, data: options, maps: this.maps,
332
+ target: target, x: e.clientX, y: e.clientY,
333
+ latitude: options.data['latitude'] || options.data['Latitude'], longitude: options.data['longitude'] || options.data['Longitude'],
334
+ markerClusterCollection: options['markCollection']
335
+ };
336
+ this.maps.trigger(markerClusterClick, eventArgs);
337
+ }
338
+ /**
339
+ * To get marker from target id
340
+ *
341
+ * @param {string} target - Specifies the target
342
+ * @returns {string} - Returns the string
343
+ */
344
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
345
+ private getMarker(target: string): { marker: MarkerSettingsModel, data: any, clusterCollection: MarkerClusterData[], markCollection: any[] } {
346
+ const id: string[] = target.split('_LayerIndex_');
347
+ const index: number = parseInt(id[1].split('_')[0], 10);
348
+ const layer: LayerSettings = <LayerSettings>this.maps.layers[index];
349
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
350
+ let data: any;
351
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
352
+ const markCollection: any[] = [];
353
+ const clusterCollection: MarkerClusterData[] = [];
354
+ let marker: MarkerSettingsModel;
355
+ this.maps.markerClusterExpand = layer.markerClusterSettings.allowClusterExpand;
356
+ if (target.indexOf('_MarkerIndex_') > -1) {
357
+ const markerIndex: number = parseInt(id[1].split('_MarkerIndex_')[1].split('_')[0], 10);
358
+ const dataIndex: number = parseInt(id[1].split('_dataIndex_')[1].split('_')[0], 10);
359
+ marker = layer.markerSettings[markerIndex];
360
+ if (!isNaN(markerIndex)) {
361
+ data = marker.dataSource[dataIndex];
362
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
363
+ let collection: any[] = [];
364
+ if (!marker.template && (target.indexOf('_cluster_') > -1) && (this.maps.layers[index].markerClusterSettings.allowClusterExpand)) {
365
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
366
+ Array.prototype.forEach.call(marker.dataSource, (location: any, index: number) => {
367
+ if (location['latitude'] === data['latitude'] && location['longitude'] === data['longitude']) {
368
+ collection.push({ data: data, index: index });
369
+ }
370
+ });
371
+ }
372
+ if ((target.indexOf('_cluster_') > -1)) {
373
+ let isClusterSame: boolean = false;
374
+ const clusterElement: HTMLElement = document.getElementById(target.indexOf('_datalabel_') > -1 ? layer.markerClusterSettings.shape === 'Balloon' ? target.split('_datalabel_')[0] + '_Group' : target.split('_datalabel_')[0] : layer.markerClusterSettings.shape === 'Balloon' ? target + '_Group': target);
375
+ const indexes: number[] = layer.markerClusterSettings.shape === 'Balloon' ? clusterElement.children[0].innerHTML.split(',').map(Number) : clusterElement.innerHTML.split(',').map(Number);
376
+ collection = [];
377
+ for (const i of indexes) {
378
+ collection.push({ data: marker.dataSource[i], index: i });
379
+ markCollection.push(marker.dataSource[i]);
380
+ }
381
+ isClusterSame = false;
382
+ clusterCollection.push(<MarkerClusterData>{
383
+ data: collection, layerIndex: index, markerIndex: markerIndex, dataIndex: dataIndex,
384
+ targetClusterIndex: +(target.split('_cluster_')[1].indexOf('_datalabel_') > -1 ? target.split('_cluster_')[1].split('_datalabel_')[0] : target.split('_cluster_')[1]),
385
+ isClusterSame: isClusterSame
386
+ });
387
+ }
388
+ return { marker: marker, data: data, clusterCollection: clusterCollection, markCollection: markCollection };
389
+ }
390
+ }
391
+ return null;
392
+ }
393
+ /**
394
+ * To check and trigger marker move event
395
+ */
396
+ public markerMove(e: PointerEvent): void {
397
+ const targetId: string = (e.target as Element).id;
398
+ if (targetId.indexOf('_LayerIndex_') === -1 || targetId.indexOf('_cluster_') > 0) {
399
+ return;
400
+ }
401
+ const options: { marker: MarkerSettingsModel, data: object } = this.getMarker(targetId);
402
+ if (isNullOrUndefined(options)) {
403
+ return;
404
+ }
405
+ const eventArgs: IMarkerMoveEventArgs = {
406
+ cancel: false, name: markerMouseMove, data: options.data,
407
+ maps: this.maps, target: targetId, x: e.clientX, y: e.clientY
408
+ };
409
+ this.maps.trigger(markerMouseMove, eventArgs);
410
+ }
411
+ /**
412
+ * To check and trigger cluster move event
413
+ */
414
+ public markerClusterMouseMove(e: PointerEvent): void {
415
+ const targetId: string = (e.target as Element).id;
416
+ if (targetId.indexOf('_LayerIndex_') === -1 || targetId.indexOf('_cluster_') === -1) {
417
+ return;
418
+ }
419
+ const options: { marker: MarkerSettingsModel, data: object, clusterCollection: MarkerClusterData[] } = this.getMarker(targetId);
420
+ if (this.maps.markerClusterExpand) {
421
+ (e.target as Element).setAttribute('style', 'cursor: pointer');
422
+ }
423
+ if (isNullOrUndefined(options)) {
424
+ return;
425
+ }
426
+ const eventArgs: IMarkerClusterMoveEventArgs = {
427
+ cancel: false, name: markerClusterMouseMove, data: options.data, maps: this.maps,
428
+ target: targetId, x: e.clientX, y: e.clientY
429
+ };
430
+ this.maps.trigger(markerClusterMouseMove, eventArgs);
431
+ }
432
+ /**
433
+ * Get module name.
434
+ *
435
+ * @returns {string} - Returns the module name
436
+ */
437
+ protected getModuleName(): string {
438
+ return 'Marker';
439
+ }
440
+
441
+ /**
442
+ * To destroy the layers.
443
+ *
444
+ * @returns {void}
445
+ * @private
446
+ */
447
+ public destroy(): void {
448
+ this.maps = null;
449
+ this.trackElements = [];
450
+ this.markerSVGObject = null;
451
+ this.sameMarkerData = [];
452
+ }
453
+ }
@@ -0,0 +1,167 @@
1
+ /* eslint-disable jsdoc/require-param */
2
+ /* eslint-disable jsdoc/require-returns */
3
+ /* eslint-disable @typescript-eslint/no-unused-vars */
4
+ import { Maps } from '../../index';
5
+ import { LayerSettings, convertTileLatLongToPoint } from '../index';
6
+ import { convertGeoToPoint, Point, PathOption, maintainSelection } from '../utils/helper';
7
+ import { isNullOrUndefined } from '@syncfusion/ej2-base';
8
+ /**
9
+ * navigation-selected-line
10
+ */
11
+ export class NavigationLine {
12
+ private maps: Maps;
13
+ constructor(maps: Maps) {
14
+ this.maps = maps;
15
+ }
16
+ // eslint-disable-next-line valid-jsdoc
17
+ /**
18
+ * To render navigation line for maps
19
+ */
20
+ public renderNavigation(layer: LayerSettings, factor: number, layerIndex: number): Element {
21
+ let navigationEle: Element;
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ const navigation: any[] = layer.navigationLineSettings;
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ let longitude: any;
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ let point: any[] = [];
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ let latitude: any;
30
+ let visible: boolean;
31
+ let angle: number;
32
+ let width: number;
33
+ let color: string;
34
+ let dashArray: string;
35
+ let pathOption: PathOption;
36
+ let direction: number;
37
+ let showArrow: boolean;
38
+ let arrowColor: string;
39
+ let arrowSize: number;
40
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
41
+ let arrowSettings: any;
42
+ let arrowPosition: string;
43
+ let startArrow: string;
44
+ let endArrow: string;
45
+ let offSet: number;
46
+ let offSetValue: number;
47
+ let navigationGroup: Element;
48
+ let d: string;
49
+ const group: Element = (this.maps.renderer.createGroup({
50
+ id: this.maps.element.id + '_LayerIndex_' + layerIndex + '_line_Group'
51
+ }));
52
+ for (let i: number = 0; i < navigation.length; i++) {
53
+ latitude = navigation[i]['properties']['latitude'];
54
+ longitude = navigation[i]['properties']['longitude'];
55
+ visible = navigation[i]['properties']['visible'];
56
+ angle = navigation[i]['angle'];
57
+ width = navigation[i]['width'] || 1;
58
+ color = navigation[i]['color'];
59
+ dashArray = navigation[i]['properties']['dashArray'];
60
+ arrowSettings = navigation[i]['properties']['arrowSettings'];
61
+ showArrow = (isNullOrUndefined(arrowSettings)) ? false : arrowSettings['properties']['showArrow'];
62
+ if (longitude['length'] === latitude['length'] && visible) {
63
+ for (let i: number = 0; i < longitude['length']; i++) {
64
+ const location: Point = (this.maps.isTileMap) ? convertTileLatLongToPoint(
65
+ new Point(longitude[i], latitude[i]), factor, this.maps.tileTranslatePoint, true
66
+ ) : convertGeoToPoint(latitude[i], longitude[i], factor, layer, this.maps);
67
+ point.push(location);
68
+ }
69
+ }
70
+ navigationGroup = (this.maps.renderer.createGroup({
71
+ id: this.maps.element.id + '_LayerIndex_' + layerIndex + '_NavigationGroup' + i + ''
72
+ }));
73
+ for (let j: number = 0; j < point['length'] - 1; j++) {
74
+ angle = (-1 > angle) ? -1 : angle;
75
+ angle = (1 < angle) ? 1 : angle;
76
+ const arcId: string = this.maps.element.id + '_LayerIndex_' + layerIndex + '_NavigationIndex_' + i + '_Line' + j + '';
77
+ const radius: number = this.convertRadius(point[j], point[j + 1]);
78
+ if (angle <= 1 && angle > 0) {
79
+ direction = 0;
80
+ if (point[j]['x'] > point[j + 1]['x']) {
81
+ direction = 1;
82
+ }
83
+ }
84
+ if (angle >= -1 && angle < 0) {
85
+ direction = 1;
86
+ if (point[j]['x'] > point[j + 1]['x']) {
87
+ direction = 0;
88
+ }
89
+ }
90
+ if (point[j]['x'] !== point[j + 1]['x']) {
91
+ if (showArrow) {
92
+ arrowColor = arrowSettings['properties']['color'];
93
+ arrowSize = arrowSettings['properties']['size'];
94
+ offSetValue = (arrowSettings['properties']['offSet'] === undefined) ? 0 : arrowSettings['properties']['offSet'];
95
+ const divide: number = (Math.round(arrowSize / 2));
96
+ arrowPosition = arrowSettings['properties']['position'];
97
+ startArrow = (arrowPosition === 'Start') ? 'url(#triangle' + i + ')' : null;
98
+ endArrow = (arrowPosition === 'End') ? 'url(#triangle' + i + ')' : null;
99
+ if (offSet !== 0 && angle === 0) {
100
+ offSet = (arrowPosition === 'Start') ? offSetValue : -(offSetValue);
101
+ }
102
+ offSet = (isNullOrUndefined(offSet)) ? 0 : offSet;
103
+ const triId: string = this.maps.element.id + '_triangle';
104
+ const defElement: Element = this.maps.renderer.createDefs();
105
+ defElement.innerHTML += '<marker id="' + 'triangle' + i + '"></marker>';
106
+ const markerEle: Element = defElement.querySelector('#' + 'triangle' + i);
107
+ markerEle.setAttribute('markerWidth', (arrowSize.toString()));
108
+ markerEle.setAttribute('markerHeight', (arrowSize.toString()));
109
+ markerEle.setAttribute('refX', (divide - offSet).toString());
110
+ markerEle.setAttribute('refY', divide.toString());
111
+ markerEle.setAttribute('orient', 'auto');
112
+ const d2: string = 'M 0,0 L 0,' + arrowSize + ' L ' + divide + ', ' + divide + ' Z';
113
+ pathOption = new PathOption(triId, arrowColor, width, color, 1, 1, dashArray, d2);
114
+ navigationEle = this.maps.renderer.drawPath(pathOption);
115
+ markerEle.appendChild(navigationEle);
116
+ defElement.appendChild(markerEle);
117
+ navigationGroup.appendChild(defElement);
118
+ }
119
+ angle = Math.abs(angle);
120
+ d = (angle === 0) ? 'M ' + point[j]['x'] + ',' + point[j]['y'] + 'L ' + point[j + 1]['x']
121
+ + ',' + point[j + 1]['y'] + ' ' :
122
+ 'M ' + point[j]['x'] + ',' + point[j]['y'] + ' A ' + (radius / 2 + (1 - angle) * radius / (angle * 10)) +
123
+ ' ' + (radius / 2 + (1 - angle) * radius / (angle * 10)) + ' ' + 0 + ',' + 0 + ','
124
+ + direction + ' , ' + point[j + 1]['x'] + ',' + point[j + 1]['y'] + ' ';
125
+ pathOption = new PathOption(arcId, 'none', width, color, 1, 1, dashArray, d);
126
+ navigationEle = this.maps.renderer.drawPath(pathOption) as SVGLineElement;
127
+ if (!isNullOrUndefined(arrowPosition)) {
128
+ const position: void = (arrowPosition === 'Start') ? navigationEle.setAttribute('marker-start', startArrow)
129
+ : navigationEle.setAttribute('marker-end', endArrow);
130
+ }
131
+ maintainSelection(this.maps.selectedNavigationElementId, this.maps.navigationSelectionClass, navigationEle,
132
+ 'navigationlineselectionMapStyle');
133
+ navigationGroup.appendChild(navigationEle);
134
+ group.appendChild(navigationGroup);
135
+ }
136
+ }
137
+ point = [];
138
+ }
139
+ return group;
140
+ }
141
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
142
+ private convertRadius(point1: any, point2: any): number {
143
+ const value1: number = point2['x'] - point1['x'];
144
+ const value2: number = point2['y'] - point1['y'];
145
+ const value: number = Math.sqrt((Math.pow(value1, 2) + Math.pow(value2, 2)));
146
+ return value;
147
+ }
148
+
149
+ /**
150
+ * Get module name.
151
+ *
152
+ * @returns {string} - Returns the module name
153
+ */
154
+ protected getModuleName(): string {
155
+ return 'NavigationLine';
156
+ }
157
+
158
+ /**
159
+ * To destroy the layers.
160
+ *
161
+ * @returns {void}
162
+ * @private
163
+ */
164
+ public destroy(): void {
165
+ this.maps = null;
166
+ }
167
+ }