@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.
- package/.eslintrc.json +18 -3
- package/.github/PULL_REQUEST_TEMPLATE/Bug.md +72 -72
- package/.github/PULL_REQUEST_TEMPLATE/Feature.md +49 -49
- package/CHANGELOG.md +441 -430
- package/README.md +73 -73
- package/dist/ej2-maps.umd.min.js +1 -10
- package/dist/ej2-maps.umd.min.js.map +1 -1
- package/dist/es6/ej2-maps.es2015.js +1205 -644
- package/dist/es6/ej2-maps.es2015.js.map +1 -1
- package/dist/es6/ej2-maps.es5.js +1243 -683
- package/dist/es6/ej2-maps.es5.js.map +1 -1
- package/dist/global/ej2-maps.min.js +1 -10
- package/dist/global/ej2-maps.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/maps/layers/bing-map.ts +50 -0
- package/dist/ts/maps/layers/bubble.ts +290 -0
- package/dist/ts/maps/layers/color-mapping.ts +226 -0
- package/dist/ts/maps/layers/data-label.ts +418 -0
- package/dist/ts/maps/layers/layer-panel.ts +1480 -0
- package/dist/ts/maps/layers/legend.ts +2236 -0
- package/dist/ts/maps/layers/marker.ts +453 -0
- package/dist/ts/maps/layers/navigation-selected-line.ts +167 -0
- package/dist/ts/maps/maps.ts +2886 -0
- package/dist/ts/maps/model/base.ts +1843 -0
- package/dist/ts/maps/model/constants.ts +200 -0
- package/dist/ts/maps/model/export-image.ts +178 -0
- package/dist/ts/maps/model/export-pdf.ts +170 -0
- package/dist/ts/maps/model/interface.ts +823 -0
- package/dist/ts/maps/model/print.ts +104 -0
- package/dist/ts/maps/model/theme.ts +554 -0
- package/dist/ts/maps/user-interaction/annotation.ts +127 -0
- package/dist/ts/maps/user-interaction/highlight.ts +233 -0
- package/dist/ts/maps/user-interaction/selection.ts +321 -0
- package/dist/ts/maps/user-interaction/tooltip.ts +387 -0
- package/dist/ts/maps/user-interaction/zoom.ts +1767 -0
- package/dist/ts/maps/utils/enum.ts +368 -0
- package/dist/ts/maps/utils/helper.ts +3421 -0
- package/helper/e2e/index.js +3 -3
- package/helper/e2e/maps-helper.js +13 -13
- package/license +9 -9
- package/package.json +85 -85
- package/src/maps/layers/bing-map.d.ts +4 -0
- package/src/maps/layers/bing-map.js +16 -3
- package/src/maps/layers/bubble.d.ts +1 -2
- package/src/maps/layers/bubble.js +7 -12
- package/src/maps/layers/data-label.d.ts +1 -4
- package/src/maps/layers/data-label.js +32 -35
- package/src/maps/layers/layer-panel.d.ts +18 -1
- package/src/maps/layers/layer-panel.js +226 -72
- package/src/maps/layers/legend.d.ts +5 -2
- package/src/maps/layers/legend.js +170 -61
- package/src/maps/layers/marker.d.ts +2 -4
- package/src/maps/layers/marker.js +49 -48
- package/src/maps/layers/navigation-selected-line.d.ts +1 -2
- package/src/maps/layers/navigation-selected-line.js +7 -13
- package/src/maps/maps-model.d.ts +259 -251
- package/src/maps/maps.d.ts +24 -3
- package/src/maps/maps.js +164 -97
- package/src/maps/model/base-model.d.ts +1025 -1021
- package/src/maps/model/base.d.ts +5 -1
- package/src/maps/model/base.js +24 -24
- package/src/maps/model/constants.d.ts +6 -0
- package/src/maps/model/constants.js +6 -0
- package/src/maps/model/export-image.d.ts +2 -4
- package/src/maps/model/export-image.js +34 -33
- package/src/maps/model/export-pdf.d.ts +4 -6
- package/src/maps/model/export-pdf.js +31 -32
- package/src/maps/model/interface.d.ts +34 -26
- package/src/maps/model/print.d.ts +2 -5
- package/src/maps/model/print.js +32 -18
- package/src/maps/model/theme.js +7 -4
- package/src/maps/user-interaction/annotation.d.ts +1 -2
- package/src/maps/user-interaction/annotation.js +3 -4
- package/src/maps/user-interaction/highlight.d.ts +1 -2
- package/src/maps/user-interaction/highlight.js +11 -10
- package/src/maps/user-interaction/selection.d.ts +1 -2
- package/src/maps/user-interaction/selection.js +42 -19
- package/src/maps/user-interaction/tooltip.d.ts +3 -5
- package/src/maps/user-interaction/tooltip.js +27 -14
- package/src/maps/user-interaction/zoom.d.ts +3 -8
- package/src/maps/user-interaction/zoom.js +282 -162
- package/src/maps/utils/enum.d.ts +5 -1
- package/src/maps/utils/helper.d.ts +9 -1
- package/src/maps/utils/helper.js +82 -33
|
@@ -0,0 +1,3421 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
+
/* eslint-disable max-len */
|
|
4
|
+
/**
|
|
5
|
+
* Helper functions for maps control
|
|
6
|
+
*/
|
|
7
|
+
import { createElement, isNullOrUndefined, remove, compile as templateComplier, merge } from '@syncfusion/ej2-base';
|
|
8
|
+
import { AnimationOptions, Animation } from '@syncfusion/ej2-base';
|
|
9
|
+
import { SvgRenderer } from '@syncfusion/ej2-svg-base';
|
|
10
|
+
import { Maps, FontModel, BorderModel, LayerSettings, ProjectionType, ISelectionEventArgs, itemSelection } from '../../index';
|
|
11
|
+
import { animationComplete, IAnimationCompleteEventArgs, Alignment, LayerSettingsModel } from '../index';
|
|
12
|
+
import {
|
|
13
|
+
MarkerType, IShapeSelectedEventArgs, ITouches, IShapes, SelectionSettingsModel,
|
|
14
|
+
MarkerClusterSettingsModel, IMarkerRenderingEventArgs, MarkerSettings, markerClusterRendering,
|
|
15
|
+
IMarkerClusterRenderingEventArgs, MarkerClusterData
|
|
16
|
+
} from '../index';
|
|
17
|
+
import { CenterPositionModel, ConnectorLineSettingsModel, MarkerSettingsModel } from '../model/base-model';
|
|
18
|
+
import { ExportType } from '../utils/enum';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Maps internal use of `Size` type
|
|
22
|
+
*/
|
|
23
|
+
export class Size {
|
|
24
|
+
/**
|
|
25
|
+
* height value for size
|
|
26
|
+
*/
|
|
27
|
+
public height: number;
|
|
28
|
+
/**
|
|
29
|
+
* width value for size
|
|
30
|
+
*/
|
|
31
|
+
public width: number;
|
|
32
|
+
|
|
33
|
+
constructor(width: number, height: number) {
|
|
34
|
+
this.width = width;
|
|
35
|
+
this.height = height;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* To find number from string
|
|
40
|
+
*
|
|
41
|
+
* @param {string} value Specifies the value
|
|
42
|
+
* @param {number} containerSize Specifies the container size
|
|
43
|
+
* @returns {number} Returns the number
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
export function stringToNumber(value: string, containerSize: number): number {
|
|
47
|
+
if (value !== null && value !== undefined) {
|
|
48
|
+
return value.indexOf('%') !== -1 ? (containerSize / 100) * parseInt(value, 10) : parseInt(value, 10);
|
|
49
|
+
}
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Method to calculate the width and height of the maps
|
|
54
|
+
*
|
|
55
|
+
* @param {Maps} maps Specifies the maps instance
|
|
56
|
+
* @returns {void}
|
|
57
|
+
*/
|
|
58
|
+
export function calculateSize(maps: Maps): Size {
|
|
59
|
+
maps.element.style.height = !isNullOrUndefined(maps.height) ? maps.height : 'auto';
|
|
60
|
+
maps.element.style.width = !isNullOrUndefined(maps.width) ? maps.width : 'auto';
|
|
61
|
+
const containerWidth: number = maps.element.clientWidth;
|
|
62
|
+
const containerHeight: number = maps.element.clientHeight;
|
|
63
|
+
const containerElementWidth: number = stringToNumber(maps.element.style.width, containerWidth);
|
|
64
|
+
const containerElementHeight: number = stringToNumber(maps.element.style.height, containerHeight);
|
|
65
|
+
let availableSize: Size = new Size(0,0);
|
|
66
|
+
if (maps.width === '0px' || maps.width === '0%' || maps.height === '0%' || maps.height === '0px') {
|
|
67
|
+
availableSize = new Size(0, 0);
|
|
68
|
+
} else {
|
|
69
|
+
availableSize = new Size(
|
|
70
|
+
stringToNumber(maps.width, containerWidth) || containerWidth || containerElementWidth || 600,
|
|
71
|
+
stringToNumber(maps.height, containerHeight) || containerHeight || containerElementHeight || (maps.isDevice ?
|
|
72
|
+
Math.min(window.innerWidth, window.innerHeight) : 450)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return availableSize;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Method to create svg for maps.
|
|
79
|
+
*
|
|
80
|
+
* @param {Maps} maps Specifies the map instance
|
|
81
|
+
* @returns {void}
|
|
82
|
+
*/
|
|
83
|
+
export function createSvg(maps: Maps): void {
|
|
84
|
+
maps.renderer = new SvgRenderer(maps.element.id);
|
|
85
|
+
maps.availableSize = calculateSize(maps);
|
|
86
|
+
maps.svgObject = maps.renderer.createSvg({
|
|
87
|
+
id: maps.element.id + '_svg',
|
|
88
|
+
width: maps.availableSize.width,
|
|
89
|
+
height: maps.availableSize.height
|
|
90
|
+
});
|
|
91
|
+
if (maps.width === '0px' || maps.width === '0%' || maps.height === '0%' || maps.height === '0px') {
|
|
92
|
+
maps.svgObject.setAttribute('height', '0');
|
|
93
|
+
maps.svgObject.setAttribute('width', '0');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Method to get the mouse position
|
|
98
|
+
*
|
|
99
|
+
* @param {number} pageX - Specifies the pageX.
|
|
100
|
+
* @param {number} pageY - Specifies the pageY.
|
|
101
|
+
* @param {Element} element - Specifies the element.
|
|
102
|
+
* @returns {MapLocation} - Returns the location.
|
|
103
|
+
*/
|
|
104
|
+
export function getMousePosition(pageX: number, pageY: number, element: Element): MapLocation {
|
|
105
|
+
const elementRect: ClientRect = element.getBoundingClientRect();
|
|
106
|
+
const pageXOffset: number = element.ownerDocument.defaultView.pageXOffset;
|
|
107
|
+
const pageYOffset: number = element.ownerDocument.defaultView.pageYOffset;
|
|
108
|
+
const clientTop: number = element.ownerDocument.documentElement.clientTop;
|
|
109
|
+
const clientLeft: number = element.ownerDocument.documentElement.clientLeft;
|
|
110
|
+
const positionX: number = elementRect.left + pageXOffset - clientLeft;
|
|
111
|
+
const positionY: number = elementRect.top + pageYOffset - clientTop;
|
|
112
|
+
return new MapLocation((pageX - positionX), (pageY - positionY));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Method to convert degrees to radians
|
|
116
|
+
*
|
|
117
|
+
* @param {number} deg Specifies the degree value
|
|
118
|
+
* @returns {number} Returns the number
|
|
119
|
+
*/
|
|
120
|
+
export function degreesToRadians(deg: number): number {
|
|
121
|
+
return deg * (Math.PI / 180);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Convert radians to degrees method
|
|
126
|
+
*
|
|
127
|
+
* @param {number} radian Specifies the radian value
|
|
128
|
+
* @returns {number} Returns the number
|
|
129
|
+
*/
|
|
130
|
+
export function radiansToDegrees(radian: number): number {
|
|
131
|
+
return radian * (180 / Math.PI);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Method for converting from latitude and longitude values to points
|
|
137
|
+
*
|
|
138
|
+
* @param {number} latitude - Specifies the latitude.
|
|
139
|
+
* @param {number} longitude - Specifies the longitude.
|
|
140
|
+
* @param {number} factor - Specifies the factor.
|
|
141
|
+
* @param {LayerSettings} layer - Specifies the layer settings.
|
|
142
|
+
* @param {Maps} mapModel - Specifies the maps.
|
|
143
|
+
* @returns {Point} - Returns the point values.
|
|
144
|
+
*/
|
|
145
|
+
export function convertGeoToPoint(latitude: number, longitude: number, factor: number, layer: LayerSettings, mapModel: Maps): Point {
|
|
146
|
+
const mapSize: Size = new Size(mapModel.mapAreaRect.width, mapModel.mapAreaRect.height);
|
|
147
|
+
let x: number; let y: number; let value: Point;
|
|
148
|
+
let lat: number; let lng: number; let temp: number;
|
|
149
|
+
const longitudeMinMax: MinMax = mapModel.baseMapBounds.longitude;
|
|
150
|
+
const latitudeMinMax: MinMax = mapModel.baseMapBounds.latitude;
|
|
151
|
+
let latRadian: number = degreesToRadians(latitude);
|
|
152
|
+
const lngRadian: number = degreesToRadians(longitude);
|
|
153
|
+
const type: ProjectionType = mapModel.projectionType;
|
|
154
|
+
const size: number = (mapModel.isTileMap) ? Math.pow(2, 1) * 256 : (isNullOrUndefined(factor)) ?
|
|
155
|
+
Math.min(mapSize.width, mapSize.height) : (Math.min(mapSize.width, mapSize.height) * factor);
|
|
156
|
+
if (layer.geometryType === 'Normal') {
|
|
157
|
+
x = isNullOrUndefined(factor) ? longitude : Math.abs((longitude - longitudeMinMax.min) * factor);
|
|
158
|
+
y = isNullOrUndefined(factor) ? latitude : Math.abs((latitudeMinMax.max - latitude) * factor);
|
|
159
|
+
} else if (layer.geometryType === 'Geographic') {
|
|
160
|
+
switch (type) {
|
|
161
|
+
case 'Mercator': {
|
|
162
|
+
const pixelOrigin: Point = new Point(size / 2, size / 2);
|
|
163
|
+
x = pixelOrigin.x + longitude * (size / 360);
|
|
164
|
+
const sinY: number = calculateBound(Math.sin(degreesToRadians(latitude)), -0.9999, 0.9999);
|
|
165
|
+
y = pixelOrigin.y + 0.5 * (Math.log((1 + sinY) / (1 - sinY))) * (-(size / (2 * Math.PI)));
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case 'Winkel3':
|
|
169
|
+
value = aitoff(lngRadian, latRadian);
|
|
170
|
+
lng = (value.x + lngRadian / (Math.PI / 2)) / 2;
|
|
171
|
+
lat = (value.y + latRadian) / 2;
|
|
172
|
+
break;
|
|
173
|
+
case 'Miller':
|
|
174
|
+
lng = lngRadian;
|
|
175
|
+
lat = (1.25 * Math.log(Math.tan((Math.PI / 4) + (.4 * latRadian))));
|
|
176
|
+
break;
|
|
177
|
+
case 'Eckert3':
|
|
178
|
+
temp = Math.sqrt(Math.PI * (4 + Math.PI));
|
|
179
|
+
lng = 2 / temp * lngRadian * (1 + Math.sqrt(1 - 4 * latRadian * latRadian / (Math.PI * Math.PI)));
|
|
180
|
+
lat = 4 / temp * latRadian;
|
|
181
|
+
break;
|
|
182
|
+
case 'AitOff':
|
|
183
|
+
value = aitoff(lngRadian, latRadian);
|
|
184
|
+
lng = value.x;
|
|
185
|
+
lat = value.y;
|
|
186
|
+
break;
|
|
187
|
+
case 'Eckert5':
|
|
188
|
+
lng = lngRadian * (1 + Math.cos(latRadian)) / Math.sqrt(2 + Math.PI);
|
|
189
|
+
lat = 2 * latRadian / Math.sqrt(2 + Math.PI);
|
|
190
|
+
break;
|
|
191
|
+
case 'Equirectangular':
|
|
192
|
+
lng = lngRadian;
|
|
193
|
+
lat = latRadian;
|
|
194
|
+
break;
|
|
195
|
+
case 'Eckert6': {
|
|
196
|
+
const epsilon: number = 1e-6;
|
|
197
|
+
temp = (1 + (Math.PI / 2)) * Math.sin(latRadian);
|
|
198
|
+
let delta: number = Infinity;
|
|
199
|
+
for (let i: number = 0; i < 10 && Math.abs(delta) > epsilon; i++) {
|
|
200
|
+
delta = (latRadian + (Math.sin(latRadian)) - temp) / (1 + Math.cos(latRadian));
|
|
201
|
+
latRadian = latRadian - delta;
|
|
202
|
+
}
|
|
203
|
+
temp = Math.sqrt(2 + Math.PI);
|
|
204
|
+
lng = lngRadian * (1 + Math.cos(latRadian)) / temp;
|
|
205
|
+
lat = 2 * latRadian / temp;
|
|
206
|
+
break;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
x = (type === 'Mercator') ? x : roundTo(xToCoordinate(mapModel, radiansToDegrees(lng)), 3);
|
|
210
|
+
y = (type === 'Mercator') ? y : (-(roundTo(yToCoordinate(mapModel, radiansToDegrees(lat)), 3)));
|
|
211
|
+
}
|
|
212
|
+
return new Point(x, y);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Converting tile latitude and longitude to point
|
|
216
|
+
*
|
|
217
|
+
* @param {MapLocation} center Specifies the map center location
|
|
218
|
+
* @param {number} zoomLevel Specifies the zoom level
|
|
219
|
+
* @param {MapLocation} tileTranslatePoint Specifies the tile translate point
|
|
220
|
+
* @param {boolean} isMapCoordinates Specifies the boolean value
|
|
221
|
+
* @returns {MapLocation} Returns the location value
|
|
222
|
+
*/
|
|
223
|
+
export function convertTileLatLongToPoint(
|
|
224
|
+
center: MapLocation, zoomLevel: number, tileTranslatePoint: MapLocation, isMapCoordinates: boolean): MapLocation {
|
|
225
|
+
const size: number = Math.pow(2, zoomLevel) * 256;
|
|
226
|
+
const x: number = (center.x + 180) / 360;
|
|
227
|
+
const sinLatitude: number = Math.sin(center.y * Math.PI / 180);
|
|
228
|
+
const y: number = 0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (4 * Math.PI);
|
|
229
|
+
let pixelX: number = center.x;
|
|
230
|
+
let pixelY: number = center.y;
|
|
231
|
+
if (isMapCoordinates) {
|
|
232
|
+
pixelX = (x * size + 0.5) + tileTranslatePoint.x;
|
|
233
|
+
pixelY = (y * size + 0.5) + tileTranslatePoint.y;
|
|
234
|
+
}
|
|
235
|
+
return { x: pixelX, y: pixelY };
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Method for calculate x point
|
|
239
|
+
*
|
|
240
|
+
* @param {Maps} mapObject - Specifies the maps.
|
|
241
|
+
* @param {number} val - Specifies the value.
|
|
242
|
+
* @returns {number} - Returns the number.
|
|
243
|
+
*/
|
|
244
|
+
export function xToCoordinate(mapObject: Maps, val: number): number {
|
|
245
|
+
const longitudeMinMax: MinMax = mapObject.baseMapBounds.longitude;
|
|
246
|
+
const totalSize: number = isNullOrUndefined(mapObject.baseSize) ? mapObject.mapAreaRect.width : mapObject.mapAreaRect.width +
|
|
247
|
+
(Math.abs(mapObject.baseSize.width - mapObject.mapAreaRect.width) / 2);
|
|
248
|
+
return Math.round(totalSize * (val - longitudeMinMax.min) / (longitudeMinMax.max - longitudeMinMax.min) * 100) / 100;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Method for calculate y point
|
|
253
|
+
*
|
|
254
|
+
* @param {Maps} mapObject - Specifies the maps.
|
|
255
|
+
* @param {number} val - Specifies the value.
|
|
256
|
+
* @returns {number} - Returns the number.
|
|
257
|
+
*/
|
|
258
|
+
export function yToCoordinate(mapObject: Maps, val: number): number {
|
|
259
|
+
const latitudeMinMax: MinMax = mapObject.baseMapBounds.latitude;
|
|
260
|
+
return Math.round(mapObject.mapAreaRect.height * (val - latitudeMinMax.min) / (latitudeMinMax.max - latitudeMinMax.min) * 100) / 100;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Method for calculate aitoff projection
|
|
265
|
+
*
|
|
266
|
+
* @param {number} x - Specifies the x value.
|
|
267
|
+
* @param {number} y - Specifies the y value.
|
|
268
|
+
* @returns {Point} - Returns the point value.
|
|
269
|
+
*/
|
|
270
|
+
export function aitoff(x: number, y: number): Point {
|
|
271
|
+
const cosy: number = Math.cos(y);
|
|
272
|
+
const sincia: number = sinci(acos(cosy * Math.cos(x /= 2)));
|
|
273
|
+
return new Point(2 * cosy * Math.sin(x) * sincia, Math.sin(y) * sincia);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Method to round the number
|
|
279
|
+
*
|
|
280
|
+
* @param {number} a - Specifies the a value
|
|
281
|
+
* @param {number} b - Specifies the b value
|
|
282
|
+
* @returns {number} - Returns the number
|
|
283
|
+
*/
|
|
284
|
+
export function roundTo(a: number, b: number): number {
|
|
285
|
+
const c: number = Math.pow(10, b);
|
|
286
|
+
return (Math.round(a * c) / c);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
*
|
|
291
|
+
* @param {number} x - Specifies the x value
|
|
292
|
+
* @returns {number} - Returns the number
|
|
293
|
+
*/
|
|
294
|
+
export function sinci(x: number): number {
|
|
295
|
+
return x / Math.sin(x);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
*
|
|
300
|
+
* @param {number} a - Specifies the a value
|
|
301
|
+
* @returns {number} - Returns the number
|
|
302
|
+
*/
|
|
303
|
+
export function acos(a: number): number {
|
|
304
|
+
return Math.acos(a);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Method to calculate bound
|
|
309
|
+
*
|
|
310
|
+
* @param {number} value Specifies the value
|
|
311
|
+
* @param {number} min Specifies the minimum value
|
|
312
|
+
* @param {number} max Specifies the maximum value
|
|
313
|
+
* @returns {number} Returns the value
|
|
314
|
+
*/
|
|
315
|
+
export function calculateBound(value: number, min: number, max: number): number {
|
|
316
|
+
if (!isNullOrUndefined(min)) {
|
|
317
|
+
value = Math.max(value, min);
|
|
318
|
+
}
|
|
319
|
+
if (!(isNullOrUndefined(max))) {
|
|
320
|
+
value = Math.min(value, max);
|
|
321
|
+
}
|
|
322
|
+
return value;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* To trigger the download element
|
|
327
|
+
*
|
|
328
|
+
* @param {string} fileName Specifies the file name
|
|
329
|
+
* @param {ExportType} type Specifies the type
|
|
330
|
+
* @param {string} url Specifies the url
|
|
331
|
+
* @param {boolean} isDownload Specifies whether download a file.
|
|
332
|
+
* @returns {void}
|
|
333
|
+
*/
|
|
334
|
+
export function triggerDownload(fileName: string, type: ExportType, url: string, isDownload: boolean): void {
|
|
335
|
+
createElement('a', {
|
|
336
|
+
attrs: {
|
|
337
|
+
'download': fileName + '.' + (type as string).toLocaleLowerCase(),
|
|
338
|
+
'href': url
|
|
339
|
+
}
|
|
340
|
+
}).dispatchEvent(new MouseEvent(isDownload ? 'click' : 'move', {
|
|
341
|
+
view: window,
|
|
342
|
+
bubbles: false,
|
|
343
|
+
cancelable: true
|
|
344
|
+
}));
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Map internal class for point
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
export class Point {
|
|
351
|
+
/**
|
|
352
|
+
* Point x value
|
|
353
|
+
*/
|
|
354
|
+
public x: number;
|
|
355
|
+
/**
|
|
356
|
+
* Point Y value
|
|
357
|
+
*/
|
|
358
|
+
public y: number;
|
|
359
|
+
constructor(x: number, y: number) {
|
|
360
|
+
this.x = x;
|
|
361
|
+
this.y = y;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Map internal class for min and max
|
|
367
|
+
*
|
|
368
|
+
*/
|
|
369
|
+
|
|
370
|
+
export class MinMax {
|
|
371
|
+
public min: number;
|
|
372
|
+
public max: number;
|
|
373
|
+
constructor(min: number, max: number) {
|
|
374
|
+
this.min = min;
|
|
375
|
+
this.max = max;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Map internal class locations
|
|
381
|
+
*/
|
|
382
|
+
|
|
383
|
+
export class GeoLocation {
|
|
384
|
+
public latitude: MinMax;
|
|
385
|
+
public longitude: MinMax;
|
|
386
|
+
constructor(latitude: MinMax, longitude: MinMax) {
|
|
387
|
+
this.latitude = new MinMax(latitude.min, latitude.max);
|
|
388
|
+
this.longitude = new MinMax(longitude.min, longitude.max);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Function to measure the height and width of the text.
|
|
394
|
+
*
|
|
395
|
+
* @param {string} text Specifies the text
|
|
396
|
+
* @param {FontModel} font Specifies the font
|
|
397
|
+
* @returns {Size} Returns the size
|
|
398
|
+
* @private
|
|
399
|
+
*/
|
|
400
|
+
export function measureText(text: string, font: FontModel): Size {
|
|
401
|
+
let measureObject: HTMLElement = document.getElementById('mapsmeasuretext');
|
|
402
|
+
|
|
403
|
+
if (measureObject === null) {
|
|
404
|
+
measureObject = createElement('text', { id: 'mapsmeasuretext' });
|
|
405
|
+
document.body.appendChild(measureObject);
|
|
406
|
+
}
|
|
407
|
+
measureObject.innerHTML = text;
|
|
408
|
+
measureObject.style.position = 'absolute';
|
|
409
|
+
if (typeof (font.size) === 'number') {
|
|
410
|
+
measureObject.style.fontSize = (font.size) + 'px';
|
|
411
|
+
} else {
|
|
412
|
+
measureObject.style.fontSize = font.size;
|
|
413
|
+
}
|
|
414
|
+
measureObject.style.fontWeight = font.fontWeight;
|
|
415
|
+
measureObject.style.fontStyle = font.fontStyle;
|
|
416
|
+
measureObject.style.fontFamily = font.fontFamily;
|
|
417
|
+
measureObject.style.visibility = 'hidden';
|
|
418
|
+
measureObject.style.top = '-100';
|
|
419
|
+
measureObject.style.left = '0';
|
|
420
|
+
measureObject.style.whiteSpace = 'nowrap';
|
|
421
|
+
// For bootstrap line height issue
|
|
422
|
+
measureObject.style.lineHeight = 'normal';
|
|
423
|
+
return new Size(measureObject.clientWidth, measureObject.clientHeight);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Internal use of text options
|
|
428
|
+
*
|
|
429
|
+
* @private
|
|
430
|
+
*/
|
|
431
|
+
export class TextOption {
|
|
432
|
+
public anchor: string;
|
|
433
|
+
public id: string;
|
|
434
|
+
public transform: string = '';
|
|
435
|
+
public x: number;
|
|
436
|
+
public y: number;
|
|
437
|
+
public text: string | string[];
|
|
438
|
+
public baseLine: string = 'auto';
|
|
439
|
+
|
|
440
|
+
constructor(id?: string, x?: number, y?: number, anchor?: string, text?: string | string[], transform: string = '', baseLine?: string) {
|
|
441
|
+
this.id = id;
|
|
442
|
+
this.text = text;
|
|
443
|
+
this.transform = transform;
|
|
444
|
+
this.anchor = anchor;
|
|
445
|
+
this.x = x;
|
|
446
|
+
this.y = y;
|
|
447
|
+
this.baseLine = baseLine;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Internal use of path options
|
|
452
|
+
*
|
|
453
|
+
* @private
|
|
454
|
+
*/
|
|
455
|
+
export class PathOption {
|
|
456
|
+
public id: string;
|
|
457
|
+
public fill: string;
|
|
458
|
+
public stroke: string;
|
|
459
|
+
public ['stroke-width']: number;
|
|
460
|
+
public ['stroke-dasharray']: string;
|
|
461
|
+
public ['stroke-opacity']: number;
|
|
462
|
+
public ['fill-opacity']: number;
|
|
463
|
+
public d: string;
|
|
464
|
+
constructor(
|
|
465
|
+
id: string, fill: string, width: number, color: string, fillOpacity?: number, strokeOpacity?: number,
|
|
466
|
+
dashArray?: string, d?: string
|
|
467
|
+
) {
|
|
468
|
+
this.id = id;
|
|
469
|
+
this['fill-opacity'] = fillOpacity;
|
|
470
|
+
this['stroke-opacity'] = strokeOpacity;
|
|
471
|
+
this.fill = fill;
|
|
472
|
+
this.stroke = color;
|
|
473
|
+
this['stroke-width'] = width;
|
|
474
|
+
this['stroke-dasharray'] = dashArray;
|
|
475
|
+
this.d = d;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/** @private */
|
|
479
|
+
export class ColorValue {
|
|
480
|
+
public r: number;
|
|
481
|
+
public g: number;
|
|
482
|
+
public b: number;
|
|
483
|
+
constructor(r?: number, g?: number, b?: number) {
|
|
484
|
+
this.r = r;
|
|
485
|
+
this.g = g;
|
|
486
|
+
this.b = b;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Internal use of rectangle options
|
|
491
|
+
*
|
|
492
|
+
* @private
|
|
493
|
+
*/
|
|
494
|
+
export class RectOption extends PathOption {
|
|
495
|
+
|
|
496
|
+
public x: number;
|
|
497
|
+
public y: number;
|
|
498
|
+
public height: number;
|
|
499
|
+
public width: number;
|
|
500
|
+
public rx: number;
|
|
501
|
+
public ry: number;
|
|
502
|
+
public transform: string;
|
|
503
|
+
public ['stroke-dasharray']: string;
|
|
504
|
+
constructor(
|
|
505
|
+
id: string, fill: string, border: BorderModel, fillOpacity: number,
|
|
506
|
+
rect: Rect, rx?: number, ry?: number, transform?: string, dashArray?: string
|
|
507
|
+
) {
|
|
508
|
+
super(id, fill, border.width, border.color, fillOpacity, border.opacity);
|
|
509
|
+
this.y = rect.y;
|
|
510
|
+
this.x = rect.x;
|
|
511
|
+
this.height = rect.height;
|
|
512
|
+
this.width = rect.width;
|
|
513
|
+
this.rx = rx ? rx : 0;
|
|
514
|
+
this.ry = ry ? ry : 0;
|
|
515
|
+
this.transform = transform ? transform : '';
|
|
516
|
+
this['stroke-dasharray'] = dashArray;
|
|
517
|
+
this['fill-opacity'] = fillOpacity;
|
|
518
|
+
this['stroke-opacity'] = border.opacity;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Internal use of circle options
|
|
523
|
+
*
|
|
524
|
+
* @private
|
|
525
|
+
*/
|
|
526
|
+
export class CircleOption extends PathOption {
|
|
527
|
+
public cy: number;
|
|
528
|
+
public cx: number;
|
|
529
|
+
public r: number;
|
|
530
|
+
public ['stroke-dasharray']: string;
|
|
531
|
+
constructor(id: string, fill: string, border: BorderModel, fillOpacity: number,
|
|
532
|
+
cx: number, cy: number, r: number, dashArray: string) {
|
|
533
|
+
super(id, fill, border.width, border.color, fillOpacity, border.opacity, dashArray);
|
|
534
|
+
this.cy = cy;
|
|
535
|
+
this.cx = cx;
|
|
536
|
+
this.r = r;
|
|
537
|
+
this['stroke-dasharray'] = dashArray;
|
|
538
|
+
this['fill-opacity'] = fillOpacity;
|
|
539
|
+
this['stroke-opacity'] = border.opacity;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Internal use of polygon options
|
|
545
|
+
*
|
|
546
|
+
* @private
|
|
547
|
+
*/
|
|
548
|
+
export class PolygonOption extends PathOption {
|
|
549
|
+
public points: string;
|
|
550
|
+
constructor(id: string, points: string, fill: string, width: number, color: string, fillOpacity: number = 1,
|
|
551
|
+
strokeOpacity: number = 1, dashArray: string = ''
|
|
552
|
+
) {
|
|
553
|
+
super(id, fill, width, color, fillOpacity, strokeOpacity, dashArray);
|
|
554
|
+
this.points = points;
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Internal use of polyline options
|
|
559
|
+
*
|
|
560
|
+
* @private
|
|
561
|
+
*/
|
|
562
|
+
export class PolylineOption extends PolygonOption {
|
|
563
|
+
constructor(id: string, points: string, fill: string, width: number, color: string,
|
|
564
|
+
fillOpacity: number = 1, strokeOpacity: number = 1, dashArray: string = '') {
|
|
565
|
+
super(id, points, fill, width, color, fillOpacity, strokeOpacity, dashArray);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Internal use of line options
|
|
570
|
+
*
|
|
571
|
+
* @private
|
|
572
|
+
*/
|
|
573
|
+
export class LineOption extends PathOption {
|
|
574
|
+
public x1: number;
|
|
575
|
+
public y1: number;
|
|
576
|
+
public x2: number;
|
|
577
|
+
public y2: number;
|
|
578
|
+
constructor(id: string, line: Line, fill: string, width: number, color: string,
|
|
579
|
+
fillOpacity: number = 1, strokeOpacity: number = 1, dashArray: string = ''
|
|
580
|
+
) {
|
|
581
|
+
super(id, fill, width, color, fillOpacity, strokeOpacity, dashArray);
|
|
582
|
+
this.x1 = line.x1;
|
|
583
|
+
this.y1 = line.y1;
|
|
584
|
+
this.x2 = line.x2;
|
|
585
|
+
this.y2 = line.y2;
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
/**
|
|
589
|
+
* Internal use of line
|
|
590
|
+
*
|
|
591
|
+
* @property {number} Line - Specifies the line class
|
|
592
|
+
*/
|
|
593
|
+
export class Line {
|
|
594
|
+
public x1: number;
|
|
595
|
+
public y1: number;
|
|
596
|
+
public x2: number;
|
|
597
|
+
public y2: number;
|
|
598
|
+
constructor(x1: number, y1: number, x2: number, y2: number) {
|
|
599
|
+
this.x1 = x1;
|
|
600
|
+
this.y1 = y1;
|
|
601
|
+
this.x2 = x2;
|
|
602
|
+
this.y2 = y2;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* Internal use of map location type
|
|
607
|
+
*
|
|
608
|
+
*/
|
|
609
|
+
export class MapLocation {
|
|
610
|
+
/**
|
|
611
|
+
* To specify x value
|
|
612
|
+
*/
|
|
613
|
+
public x: number;
|
|
614
|
+
/**
|
|
615
|
+
* To specify y value
|
|
616
|
+
*/
|
|
617
|
+
public y: number;
|
|
618
|
+
constructor(x: number, y: number) {
|
|
619
|
+
this.x = x;
|
|
620
|
+
this.y = y;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
/**
|
|
624
|
+
* Internal use of type rect
|
|
625
|
+
*
|
|
626
|
+
* @private
|
|
627
|
+
*/
|
|
628
|
+
export class Rect {
|
|
629
|
+
|
|
630
|
+
public x: number;
|
|
631
|
+
public y: number;
|
|
632
|
+
public height: number;
|
|
633
|
+
public width: number;
|
|
634
|
+
|
|
635
|
+
constructor(x: number, y: number, width: number, height: number) {
|
|
636
|
+
this.x = x;
|
|
637
|
+
this.y = y;
|
|
638
|
+
this.width = width;
|
|
639
|
+
this.height = height;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Defines the pattern unit types for drawing the patterns in maps.
|
|
644
|
+
*/
|
|
645
|
+
export type patternUnits =
|
|
646
|
+
/** Specifies the user space for maps. */
|
|
647
|
+
'userSpaceOnUse' |
|
|
648
|
+
/** Specifies the bounding box for the object. */
|
|
649
|
+
'objectBoundingBox';
|
|
650
|
+
/**
|
|
651
|
+
* Internal use for pattern creation.
|
|
652
|
+
*
|
|
653
|
+
* @property {PatternOptions} PatternOptions - Specifies the pattern option class.
|
|
654
|
+
*/
|
|
655
|
+
export class PatternOptions {
|
|
656
|
+
public id: string;
|
|
657
|
+
public patternUnits: patternUnits;
|
|
658
|
+
public patternContentUnits: patternUnits;
|
|
659
|
+
public patternTransform: string;
|
|
660
|
+
public x: number;
|
|
661
|
+
public y: number;
|
|
662
|
+
public width: number;
|
|
663
|
+
public height: number;
|
|
664
|
+
public href: string;
|
|
665
|
+
constructor(
|
|
666
|
+
id: string, x: number, y: number, width: number, height: number, patternUnits: patternUnits = 'userSpaceOnUse',
|
|
667
|
+
patternContentUnits: patternUnits = 'userSpaceOnUse', patternTransform: string = '', href: string = '') {
|
|
668
|
+
this.id = id;
|
|
669
|
+
this.x = x;
|
|
670
|
+
this.y = y;
|
|
671
|
+
this.width = width;
|
|
672
|
+
this.height = height;
|
|
673
|
+
this.patternUnits = patternUnits;
|
|
674
|
+
this.patternContentUnits = patternContentUnits;
|
|
675
|
+
this.patternTransform = patternTransform;
|
|
676
|
+
this.href = href;
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Internal rendering of text
|
|
681
|
+
*
|
|
682
|
+
* @param {TextOption} option Specifies the text option
|
|
683
|
+
* @param {FontModel} style Specifies the style
|
|
684
|
+
* @param {string} color Specifies the color
|
|
685
|
+
* @param {HTMLElement | Element} parent Specifies the parent element
|
|
686
|
+
* @param {boolean} isMinus Specifies the boolean value
|
|
687
|
+
* @returns {Element} Returns the html object
|
|
688
|
+
* @private
|
|
689
|
+
*/
|
|
690
|
+
export function renderTextElement(
|
|
691
|
+
option: TextOption, style: FontModel, color: string, parent: HTMLElement | Element, isMinus: boolean = false
|
|
692
|
+
): Element {
|
|
693
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
694
|
+
const renderOptions: any = {
|
|
695
|
+
'id': option.id,
|
|
696
|
+
'x': option.x,
|
|
697
|
+
'y': option.y,
|
|
698
|
+
'fill': color,
|
|
699
|
+
'font-size': style.size,
|
|
700
|
+
'font-style': style.fontStyle,
|
|
701
|
+
'font-family': style.fontFamily,
|
|
702
|
+
'font-weight': style.fontWeight,
|
|
703
|
+
'text-anchor': option.anchor,
|
|
704
|
+
'transform': option.transform,
|
|
705
|
+
'opacity': style.opacity,
|
|
706
|
+
'dominant-baseline': option.baseLine
|
|
707
|
+
};
|
|
708
|
+
const text: string = typeof option.text === 'string' || typeof option.text === 'number' ? option.text : isMinus ? option.text[option.text.length - 1] : option.text[0];
|
|
709
|
+
let tspanElement: Element;
|
|
710
|
+
const renderer: SvgRenderer = new SvgRenderer('');
|
|
711
|
+
let height: number;
|
|
712
|
+
const htmlObject: HTMLElement = <HTMLElement>renderer.createText(renderOptions, text);
|
|
713
|
+
htmlObject.style['user-select'] = 'none';
|
|
714
|
+
htmlObject.style['font-family'] = style.fontFamily;
|
|
715
|
+
htmlObject.style['font-size'] = style.size;
|
|
716
|
+
htmlObject.style['font-weight'] = style.fontWeight;
|
|
717
|
+
htmlObject.style['font-color'] = style.color;
|
|
718
|
+
htmlObject.style['-moz-user-select'] = 'none';
|
|
719
|
+
htmlObject.style['-webkit-touch-callout'] = 'none';
|
|
720
|
+
htmlObject.style['-webkit-user-select'] = 'none';
|
|
721
|
+
htmlObject.style['-khtml-user-select'] = 'none';
|
|
722
|
+
htmlObject.style['-ms-user-select'] = 'none';
|
|
723
|
+
htmlObject.style['-o-user-select'] = 'none';
|
|
724
|
+
if (typeof option.text !== 'string' && option.text.length > 1) {
|
|
725
|
+
for (let i: number = 1, len: number = option.text.length; i < len; i++) {
|
|
726
|
+
height = (measureText(option.text[i], style).height);
|
|
727
|
+
tspanElement = renderer.createTSpan(
|
|
728
|
+
{
|
|
729
|
+
'x': option.x, 'id': option.id,
|
|
730
|
+
'y': (option.y) + ((isMinus) ? -(i * height) : (i * height))
|
|
731
|
+
},
|
|
732
|
+
isMinus ? option.text[option.text.length - (i + 1)] : option.text[i]
|
|
733
|
+
);
|
|
734
|
+
htmlObject.appendChild(tspanElement);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
parent.appendChild(htmlObject);
|
|
738
|
+
return htmlObject;
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
/**
|
|
742
|
+
* @param {HTMLCollection} element Specifies the html collection
|
|
743
|
+
* @param {string} markerId Specifies the marker id
|
|
744
|
+
* @param {any} data Specifies the data
|
|
745
|
+
* @param {number} index Specifies the index
|
|
746
|
+
* @param {Maps} mapObj Specifies the map object
|
|
747
|
+
* @returns {HTMLCollection} Returns the html collection
|
|
748
|
+
* @private
|
|
749
|
+
*/
|
|
750
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
751
|
+
export function convertElement(element: HTMLCollection, markerId: string, data: any, index: number, mapObj: Maps): HTMLElement {
|
|
752
|
+
const childElement: HTMLElement = createElement('div', {
|
|
753
|
+
id: markerId,
|
|
754
|
+
styles: 'position: absolute;pointer-events: auto;'
|
|
755
|
+
});
|
|
756
|
+
let elementLength: number = element.length;
|
|
757
|
+
while (elementLength > 0) {
|
|
758
|
+
childElement.appendChild(element[0]);
|
|
759
|
+
elementLength--;
|
|
760
|
+
}
|
|
761
|
+
let templateHtml: string = childElement.innerHTML;
|
|
762
|
+
let templateSplitValue: string;
|
|
763
|
+
const properties: string[] = Object.keys(data);
|
|
764
|
+
for (let i: number = 0; i < properties.length; i++) {
|
|
765
|
+
if (typeof data[properties[i]] === 'object') {
|
|
766
|
+
templateHtml = convertStringToValue(templateHtml, '', data, mapObj);
|
|
767
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
768
|
+
} else if ((<String>properties[i]).toLowerCase() !== 'latitude' && (<string>properties[i]).toLowerCase() !== 'longitude') {
|
|
769
|
+
templateHtml = templateHtml.replace(new RegExp('{{:' + <string>properties[i] + '}}', 'g'), data[properties[i].toString()]);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
childElement.innerHTML = templateHtml;
|
|
773
|
+
return childElement;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
*
|
|
778
|
+
* @param {string} value - Specifies the value
|
|
779
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
780
|
+
* @returns {string} - Returns the string value
|
|
781
|
+
*/
|
|
782
|
+
export function formatValue(value: string, maps: Maps): string {
|
|
783
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
784
|
+
let formatValue: string; let formatFunction: any;
|
|
785
|
+
if (maps.format && !isNaN(Number(value))) {
|
|
786
|
+
formatFunction = maps.intl.getNumberFormat(
|
|
787
|
+
{ format: maps.format, useGrouping: maps.useGroupingSeparator });
|
|
788
|
+
formatValue = formatFunction(Number(value));
|
|
789
|
+
} else {
|
|
790
|
+
formatValue = value;
|
|
791
|
+
}
|
|
792
|
+
return formatValue;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
*
|
|
797
|
+
* @param {string} stringTemplate - Specifies the template
|
|
798
|
+
* @param {string} format - Specifies the format
|
|
799
|
+
* @param {any} data - Specifies the data
|
|
800
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
801
|
+
* @returns {string} - Returns the string value
|
|
802
|
+
*/
|
|
803
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
804
|
+
export function convertStringToValue(stringTemplate: string, format: string, data: any, maps: Maps): string {
|
|
805
|
+
let templateHtml: string = (stringTemplate === '') ? format : stringTemplate;
|
|
806
|
+
const templateValue: string[] = (stringTemplate === '') ? templateHtml.split('${') : templateHtml.split('{{:');
|
|
807
|
+
for (let i: number = 0; i < templateValue.length; i++) {
|
|
808
|
+
if ((templateValue[i].indexOf('}}') > -1 && templateValue[i].indexOf('.') > -1) ||
|
|
809
|
+
(templateValue[i].indexOf('}') > -1 && templateValue[i].search('.') > -1)) {
|
|
810
|
+
const split: string[] = (stringTemplate === '') ? templateValue[i].split('}') : templateValue[i].split('}}');
|
|
811
|
+
for (let j: number = 0; j < split.length; j++) {
|
|
812
|
+
if (split[j].indexOf('.') > -1) {
|
|
813
|
+
const templateSplitValue: string = (getValueFromObject(data, split[j])).toString();
|
|
814
|
+
templateHtml = (stringTemplate === '') ?
|
|
815
|
+
templateHtml.split('${' + split[j] + '}').join(formatValue(templateSplitValue, maps)) :
|
|
816
|
+
templateHtml.replace(new RegExp('{{:' + split[j] + '}}', 'g'), templateSplitValue);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
return templateHtml;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
/**
|
|
825
|
+
*
|
|
826
|
+
* @param {Element} element - Specifies the element
|
|
827
|
+
* @param {string} labelId - Specifies the label id
|
|
828
|
+
* @param {any} data - Specifies the data
|
|
829
|
+
* @param {number} index - Specifies the index
|
|
830
|
+
* @param {Maps} mapObj - Specifies the map object
|
|
831
|
+
* @returns {HTMLElement} - Returns the html element
|
|
832
|
+
*/
|
|
833
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
834
|
+
export function convertElementFromLabel(element: Element, labelId: string, data: any, index: number, mapObj: Maps): HTMLElement {
|
|
835
|
+
const labelEle: Element = isNullOrUndefined(element.childElementCount) ? element[0] : element;
|
|
836
|
+
let templateHtml: string = labelEle.outerHTML;
|
|
837
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
838
|
+
const properties: any[] = Object.keys(data);
|
|
839
|
+
for (let i: number = 0; i < properties.length; i++) {
|
|
840
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
841
|
+
templateHtml = templateHtml.replace(new RegExp('{{:' + <String>properties[i] + '}}', 'g'), data[properties[i].toString()]);
|
|
842
|
+
}
|
|
843
|
+
return createElement('div', {
|
|
844
|
+
id: labelId,
|
|
845
|
+
innerHTML: templateHtml,
|
|
846
|
+
styles: 'position: absolute'
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
/**
|
|
851
|
+
*
|
|
852
|
+
* @param {MarkerType} shape - Specifies the shape
|
|
853
|
+
* @param {string} imageUrl - Specifies the image url
|
|
854
|
+
* @param {Point} location - Specifies the location
|
|
855
|
+
* @param {string} markerID - Specifies the marker id
|
|
856
|
+
* @param {any} shapeCustom - Specifies the shape custom
|
|
857
|
+
* @param {Element} markerCollection - Specifies the marker collection
|
|
858
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
859
|
+
* @returns {Element} - Returns the element
|
|
860
|
+
*/
|
|
861
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
862
|
+
export function drawSymbols(shape: MarkerType, imageUrl: string, location: Point, markerID: string, shapeCustom: any, markerCollection: Element, maps: Maps): Element {
|
|
863
|
+
let markerEle: Element; let x: number; let y: number;
|
|
864
|
+
const size: Size = <Size>shapeCustom['size'];
|
|
865
|
+
const borderColor: string = shapeCustom['borderColor'];
|
|
866
|
+
const borderWidth: number = parseFloat(shapeCustom['borderWidth']);
|
|
867
|
+
const borderOpacity: number = parseFloat(shapeCustom['borderOpacity']);
|
|
868
|
+
const fill: string = shapeCustom['fill'];
|
|
869
|
+
const dashArray: string = shapeCustom['dashArray'];
|
|
870
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
871
|
+
const border: any = { color: borderColor, width: borderWidth, opacity: borderOpacity };
|
|
872
|
+
const opacity: number = shapeCustom['opacity']; const padding: number = 5;
|
|
873
|
+
let rectOptions: RectOption;
|
|
874
|
+
const pathOptions: PathOption = new PathOption(markerID, fill, borderWidth, borderColor, opacity, borderOpacity, dashArray, '');
|
|
875
|
+
size.width = typeof(size.width) === 'string' ? parseInt(size.width, 10) : size.width;
|
|
876
|
+
size.height = typeof(size.height) === 'string' ? parseInt(size.height, 10) : size.height;
|
|
877
|
+
if (shape === 'Circle') {
|
|
878
|
+
const radius: number = (size.width + size.height) / 4;
|
|
879
|
+
const circleOptions: CircleOption = new CircleOption(markerID, fill, border, opacity,
|
|
880
|
+
location.x, location.y, radius, dashArray);
|
|
881
|
+
markerEle = maps.renderer.drawCircle(circleOptions) as SVGCircleElement;
|
|
882
|
+
} else if (shape === 'Rectangle') {
|
|
883
|
+
x = location.x - (size.width / 2);
|
|
884
|
+
y = location.y - (size.height / 2);
|
|
885
|
+
rectOptions = new RectOption(
|
|
886
|
+
markerID, fill, border, opacity, new Rect(x, y, size.width, size.height), null, null, '', dashArray
|
|
887
|
+
);
|
|
888
|
+
markerEle = maps.renderer.drawRectangle(rectOptions) as SVGRectElement;
|
|
889
|
+
} else if (shape === 'Image') {
|
|
890
|
+
x = location.x - (size.width / 2);
|
|
891
|
+
y = location.y - size.height;
|
|
892
|
+
merge(pathOptions, { 'href': imageUrl, 'height': size.height, 'width': size.width, x: x, y: y });
|
|
893
|
+
markerEle = maps.renderer.drawImage(pathOptions) as SVGImageElement;
|
|
894
|
+
} else {
|
|
895
|
+
markerEle = calculateShapes(maps, shape, pathOptions, size, location, markerCollection);
|
|
896
|
+
}
|
|
897
|
+
return markerEle;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
*
|
|
902
|
+
* @param {any} data - Specifies the data
|
|
903
|
+
* @param {string} value - Specifies the value
|
|
904
|
+
* @returns {any} - Returns the data
|
|
905
|
+
*/
|
|
906
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
907
|
+
export function getValueFromObject(data: any, value: string): any {
|
|
908
|
+
if (!isNullOrUndefined(data) && !isNullOrUndefined(value)) {
|
|
909
|
+
const splits: string[] = value.replace(/\[/g, '.').replace(/\]/g, '').split('.');
|
|
910
|
+
if (splits.length === 1) {
|
|
911
|
+
data = data[splits[0]];
|
|
912
|
+
}
|
|
913
|
+
else {
|
|
914
|
+
for (let i: number = 0; i < splits.length && !isNullOrUndefined(data); i++) {
|
|
915
|
+
data = data[splits[i]];
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return data;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
/**
|
|
923
|
+
*
|
|
924
|
+
* @param {IMarkerRenderingEventArgs} eventArgs - Specifies the event arguments
|
|
925
|
+
* @param {any} data - Specifies the data
|
|
926
|
+
* @returns {IMarkerRenderingEventArgs} - Returns the arguments
|
|
927
|
+
*/
|
|
928
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
929
|
+
export function markerColorChoose(eventArgs: IMarkerRenderingEventArgs, data: any): IMarkerRenderingEventArgs {
|
|
930
|
+
const color: string = (!isNullOrUndefined(eventArgs.colorValuePath)) ? ((eventArgs.colorValuePath.indexOf('.') > -1) ? (getValueFromObject(data, eventArgs.colorValuePath)).toString() :
|
|
931
|
+
data[eventArgs.colorValuePath]) : data[eventArgs.colorValuePath];
|
|
932
|
+
eventArgs.fill = (!isNullOrUndefined(eventArgs.colorValuePath) &&
|
|
933
|
+
!isNullOrUndefined(color)) ?
|
|
934
|
+
((eventArgs.colorValuePath.indexOf('.') > -1) ? (getValueFromObject(data, eventArgs.colorValuePath)).toString() :
|
|
935
|
+
data[eventArgs.colorValuePath]) : eventArgs.fill;
|
|
936
|
+
return eventArgs;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
*
|
|
941
|
+
* @param {IMarkerRenderingEventArgs} eventArgs - Specifies the event arguments
|
|
942
|
+
* @param {any} data - Specifies the data
|
|
943
|
+
* @returns {IMarkerRenderingEventArgs} - Returns the arguments
|
|
944
|
+
*/
|
|
945
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
946
|
+
export function markerShapeChoose(eventArgs: IMarkerRenderingEventArgs, data: any): IMarkerRenderingEventArgs {
|
|
947
|
+
if (!isNullOrUndefined(eventArgs.shapeValuePath) && !isNullOrUndefined(data[eventArgs.shapeValuePath])) {
|
|
948
|
+
const shape: MarkerType = ((eventArgs.shapeValuePath.indexOf('.') > -1) ?
|
|
949
|
+
(getValueFromObject(data, eventArgs.shapeValuePath).toString()) as MarkerType :
|
|
950
|
+
data[eventArgs.shapeValuePath]);
|
|
951
|
+
eventArgs.shape = (shape.toString() !== "") ? shape : eventArgs.shape;
|
|
952
|
+
if (data[eventArgs.shapeValuePath] === 'Image') {
|
|
953
|
+
eventArgs.imageUrl = (!isNullOrUndefined(eventArgs.imageUrlValuePath)) ?
|
|
954
|
+
((eventArgs.imageUrlValuePath.indexOf('.') > -1) ? getValueFromObject(data, eventArgs.imageUrlValuePath).toString() : (!isNullOrUndefined(data[eventArgs.imageUrlValuePath]) ?
|
|
955
|
+
data[eventArgs.imageUrlValuePath] : eventArgs.imageUrl)) : eventArgs.imageUrl;
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
else {
|
|
959
|
+
const shapes: MarkerType = (!isNullOrUndefined(eventArgs.shapeValuePath)) ? ((eventArgs.shapeValuePath.indexOf('.') > -1) ? (getValueFromObject(data, eventArgs.shapeValuePath).toString() as MarkerType) : eventArgs.shape) : eventArgs.shape;
|
|
960
|
+
eventArgs.shape = (shapes.toString() !== "") ? shapes : eventArgs.shape;
|
|
961
|
+
const shapeImage: string = (!isNullOrUndefined(eventArgs.imageUrlValuePath)) ?
|
|
962
|
+
((eventArgs.imageUrlValuePath.indexOf('.') > -1) ? getValueFromObject(data, eventArgs.imageUrlValuePath).toString() as MarkerType : (!isNullOrUndefined(data[eventArgs.imageUrlValuePath]) ?
|
|
963
|
+
data[eventArgs.imageUrlValuePath] : eventArgs.imageUrl)) : eventArgs.imageUrl;
|
|
964
|
+
eventArgs.imageUrl = shapeImage;
|
|
965
|
+
}
|
|
966
|
+
return eventArgs;
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
*
|
|
971
|
+
* @param {LayerSettings} currentLayer - Specifies the current layer
|
|
972
|
+
* @param {HTMLElement | Element} markerTemplate - Specifies the marker template
|
|
973
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
974
|
+
* @param {number} layerIndex - Specifies the layer index
|
|
975
|
+
* @param {Element} markerCollection - Specifies the marker collection
|
|
976
|
+
* @param {Element} layerElement - Specifies the layer element
|
|
977
|
+
* @param {boolean} check - Specifies the boolean value
|
|
978
|
+
* @param {boolean} zoomCheck - Specifies the boolean value
|
|
979
|
+
* @returns {void}
|
|
980
|
+
*/
|
|
981
|
+
export function clusterTemplate(currentLayer: LayerSettings, markerTemplate: HTMLElement | Element, maps: Maps, layerIndex: number, markerCollection: Element,
|
|
982
|
+
layerElement: Element, check: boolean, zoomCheck: boolean): void {
|
|
983
|
+
let bounds1: DOMRect;
|
|
984
|
+
let bounds2: DOMRect;
|
|
985
|
+
let colloideBounds: DOMRect[] = [];
|
|
986
|
+
let clusterColloideBounds: Element[] = [];
|
|
987
|
+
let tempX: number = 0;
|
|
988
|
+
let tempY: number = 0;
|
|
989
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
990
|
+
let data: any;
|
|
991
|
+
const style: FontModel = currentLayer.markerClusterSettings.labelStyle;
|
|
992
|
+
let options: TextOption;
|
|
993
|
+
let textElement: Element;
|
|
994
|
+
let tempElement1: Element;
|
|
995
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
996
|
+
let shapeCustom: any;
|
|
997
|
+
let tempElement: Element;
|
|
998
|
+
const postionY: number = (15 / 4);
|
|
999
|
+
let m: number = 0;
|
|
1000
|
+
let indexCollection: number[] = [];
|
|
1001
|
+
const clusters: MarkerClusterSettingsModel = currentLayer.markerClusterSettings;
|
|
1002
|
+
const clusterGroup: Element = maps.renderer.createGroup({ id: maps.element.id + '_LayerIndex_' + layerIndex + '_markerCluster' });
|
|
1003
|
+
const eventArg: IMarkerClusterRenderingEventArgs = {
|
|
1004
|
+
cancel: false, name: markerClusterRendering, fill: clusters.fill, height: clusters.height,
|
|
1005
|
+
width: clusters.width, imageUrl: clusters.imageUrl, shape: clusters.shape,
|
|
1006
|
+
data: data, maps: maps, cluster: clusters, border: clusters.border
|
|
1007
|
+
};
|
|
1008
|
+
maps.trigger('markerClusterRendering', eventArg, (clusterargs: IMarkerClusterRenderingEventArgs) => {
|
|
1009
|
+
for (let o: number = 0; o < markerTemplate.childElementCount; o++) {
|
|
1010
|
+
indexCollection = [];
|
|
1011
|
+
if (markerTemplate.childNodes[o]['style']['visibility'] !== 'hidden') {
|
|
1012
|
+
tempElement = markerTemplate.childNodes[o] as Element;
|
|
1013
|
+
bounds1 = tempElement.getBoundingClientRect() as DOMRect;
|
|
1014
|
+
indexCollection.push(o as number);
|
|
1015
|
+
if (!isNullOrUndefined(bounds1)) {
|
|
1016
|
+
for (let p: number = o + 1; p < markerTemplate.childElementCount; p++) {
|
|
1017
|
+
if (markerTemplate.childNodes[p]['style']['visibility'] !== 'hidden') {
|
|
1018
|
+
tempElement = markerTemplate.childNodes[p] as Element;
|
|
1019
|
+
bounds2 = tempElement.getBoundingClientRect() as DOMRect;
|
|
1020
|
+
if (!isNullOrUndefined(bounds2)) {
|
|
1021
|
+
if (!(bounds1.left > bounds2.right || bounds1.right < bounds2.left
|
|
1022
|
+
|| bounds1.top > bounds2.bottom || bounds1.bottom < bounds2.top)) {
|
|
1023
|
+
colloideBounds.push(bounds2);
|
|
1024
|
+
markerTemplate.childNodes[p]['style']['visibility'] = 'hidden';
|
|
1025
|
+
indexCollection.push(p as number);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
tempX = bounds1.left + bounds1.width / 2;
|
|
1031
|
+
tempY = bounds1.top + bounds1.height;
|
|
1032
|
+
if (colloideBounds.length > 0) {
|
|
1033
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1034
|
+
indexCollection = indexCollection.filter((item: any, index: any, value: any) => value.indexOf(item) === index);
|
|
1035
|
+
const container: ClientRect = maps.element.getBoundingClientRect();
|
|
1036
|
+
tempX = tempX - container['left'];
|
|
1037
|
+
tempY = (tempY - ((maps.availableSize.height <= container['height']) ?
|
|
1038
|
+
container['top'] : (container['bottom'] - container['top'])));
|
|
1039
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1040
|
+
const translate: any = (maps.isTileMap) ? new Object() : getTranslate(maps, currentLayer, false);
|
|
1041
|
+
const transPoint: Point = (maps.isTileMap) ? { x: 0, y: 0 } : (maps.translatePoint.x !== 0) ?
|
|
1042
|
+
maps.translatePoint : translate['location'];
|
|
1043
|
+
const dataIndex: number = parseInt(markerTemplate.childNodes[o]['id'].split('_dataIndex_')[1].split('_')[0], 10);
|
|
1044
|
+
const markerIndex: number = parseInt(markerTemplate.childNodes[o]['id'].split('_MarkerIndex_')[1].split('_')[0], 10);
|
|
1045
|
+
const markerSetting: MarkerSettingsModel = currentLayer.markerSettings[markerIndex];
|
|
1046
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1047
|
+
const markerData: any = markerSetting.dataSource[dataIndex];
|
|
1048
|
+
let factor: number; let location: Point;
|
|
1049
|
+
const longitude: number = (!isNullOrUndefined(markerSetting.longitudeValuePath)) ?
|
|
1050
|
+
Number(getValueFromObject(markerData, markerSetting.longitudeValuePath)) :
|
|
1051
|
+
!isNullOrUndefined(markerData['longitude']) ? parseFloat(markerData['longitude']) :
|
|
1052
|
+
!isNullOrUndefined(markerData['Latitude']) ? parseFloat(markerData['Latitude']) : 0;
|
|
1053
|
+
const latitude: number = (!isNullOrUndefined(markerSetting.latitudeValuePath)) ?
|
|
1054
|
+
Number(getValueFromObject(markerData, markerSetting.latitudeValuePath)) :
|
|
1055
|
+
!isNullOrUndefined(markerData['latitude']) ? parseFloat(markerData['latitude']) :
|
|
1056
|
+
!isNullOrUndefined(markerData['Latitude']) ? parseFloat(markerData['Latitude']) : 0;
|
|
1057
|
+
if (!maps.isTileMap) {
|
|
1058
|
+
factor = maps.mapLayerPanel.calculateFactor(currentLayer);
|
|
1059
|
+
location = convertGeoToPoint(latitude, longitude, factor, currentLayer, maps);
|
|
1060
|
+
} else if (maps.isTileMap && !maps.zoomSettings.enable) {
|
|
1061
|
+
location = convertTileLatLongToPoint(new Point(longitude, latitude), maps.tileZoomLevel, maps.tileTranslatePoint, true);
|
|
1062
|
+
}
|
|
1063
|
+
markerTemplate.childNodes[o]['style']['visibility'] = 'hidden';
|
|
1064
|
+
const clusters: MarkerClusterSettingsModel = currentLayer.markerClusterSettings;
|
|
1065
|
+
if (eventArg.cancel) {
|
|
1066
|
+
shapeCustom = {
|
|
1067
|
+
size: new Size(clusters.width, clusters.height),
|
|
1068
|
+
fill: clusters.fill, borderColor: clusters.border.color,
|
|
1069
|
+
borderWidth: clusters.border.width, opacity: clusters.opacity,
|
|
1070
|
+
dashArray: clusters.dashArray
|
|
1071
|
+
};
|
|
1072
|
+
shapeCustom['fill'] = clusters.fill;
|
|
1073
|
+
shapeCustom['size']['width'] = clusters.width;
|
|
1074
|
+
shapeCustom['size']['height'] = clusters.height;
|
|
1075
|
+
shapeCustom['imageUrl'] = clusters.imageUrl;
|
|
1076
|
+
shapeCustom['shape'] = clusters.shape;
|
|
1077
|
+
shapeCustom['borderColor'] = clusters.border.color;
|
|
1078
|
+
shapeCustom['borderWidth'] = clusters.border.width;
|
|
1079
|
+
shapeCustom['borderOpacity'] = isNullOrUndefined(clusters.border.opacity) ? clusters.opacity : clusters.border.opacity;
|
|
1080
|
+
} else {
|
|
1081
|
+
shapeCustom = {
|
|
1082
|
+
size: new Size(clusters.width, clusters.height),
|
|
1083
|
+
fill: clusters.fill, borderColor: clusters.border.color,
|
|
1084
|
+
borderWidth: clusters.border.width, opacity: clusters.opacity,
|
|
1085
|
+
dashArray: clusters.dashArray
|
|
1086
|
+
};
|
|
1087
|
+
shapeCustom['fill'] = eventArg.fill;
|
|
1088
|
+
shapeCustom['size']['width'] = eventArg.width;
|
|
1089
|
+
shapeCustom['size']['height'] = eventArg.height;
|
|
1090
|
+
shapeCustom['imageUrl'] = eventArg.imageUrl;
|
|
1091
|
+
shapeCustom['shape'] = eventArg.shape;
|
|
1092
|
+
shapeCustom['borderColor'] = eventArg.border.color;
|
|
1093
|
+
shapeCustom['borderWidth'] = eventArg.border.width;
|
|
1094
|
+
shapeCustom['borderOpacity'] = isNullOrUndefined(eventArg.border.opacity) ? clusters.opacity : eventArg.border.opacity;
|
|
1095
|
+
}
|
|
1096
|
+
tempX = (maps.isTileMap) ? tempX : (markerTemplate.id.indexOf('_Markers_Group') > -1) ? tempX : tempX + postionY - (eventArg.width / 2);
|
|
1097
|
+
tempY = (maps.isTileMap) ? tempY : (markerTemplate.id.indexOf('_Markers_Group') > -1) ? tempY : tempY - (eventArg.height / 2);
|
|
1098
|
+
if (maps.isTileMap && !maps.zoomSettings.enable) {
|
|
1099
|
+
tempX = location.x;
|
|
1100
|
+
tempY = location.y;
|
|
1101
|
+
}
|
|
1102
|
+
const clusterID: string = maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_dataIndex_' + dataIndex + '_cluster_' + (m);
|
|
1103
|
+
const labelID: string = maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_dataIndex_' + dataIndex + '_cluster_' + (m) + '_datalabel_' + m;
|
|
1104
|
+
m++;
|
|
1105
|
+
const imageShapeY: number = shapeCustom['shape'] === 'Image' ? shapeCustom['size']['height'] / 2 : 0;
|
|
1106
|
+
const ele: Element = drawSymbols(
|
|
1107
|
+
shapeCustom['shape'], shapeCustom['imageUrl'], { x: 0, y: imageShapeY },
|
|
1108
|
+
clusterID, shapeCustom, markerCollection, maps
|
|
1109
|
+
);
|
|
1110
|
+
ele.setAttribute('transform', 'translate( ' + tempX + ' ' + tempY + ' )');
|
|
1111
|
+
if (eventArg.shape === 'Balloon') {
|
|
1112
|
+
ele.children[0].innerHTML = indexCollection.toString();
|
|
1113
|
+
} else {
|
|
1114
|
+
ele.innerHTML = indexCollection.toString();
|
|
1115
|
+
}
|
|
1116
|
+
options = new TextOption(labelID, (0), postionY, 'middle', (colloideBounds.length + 1).toString(), '', '');
|
|
1117
|
+
textElement = renderTextElement(options, style, style.color, markerCollection);
|
|
1118
|
+
textElement.setAttribute('transform', 'translate( ' + tempX + ' ' + tempY + ' )');
|
|
1119
|
+
clusterGroup.appendChild(textElement);
|
|
1120
|
+
clusterGroup.appendChild(ele);
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
colloideBounds = [];
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
layerElement.appendChild(clusterGroup);
|
|
1127
|
+
maps.svgObject.appendChild(layerElement) as Element;
|
|
1128
|
+
maps.element.appendChild(maps.svgObject) as Element;
|
|
1129
|
+
for (let o: number = 0; o < clusterGroup.childElementCount; o++) {
|
|
1130
|
+
if (clusterGroup.childNodes[o]['style']['visibility'] !== 'hidden') {
|
|
1131
|
+
tempElement = clusterGroup.childNodes[o] as Element;
|
|
1132
|
+
bounds1 = tempElement.getBoundingClientRect() as DOMRect;
|
|
1133
|
+
if (!isNullOrUndefined(bounds1) && !(tempElement.id.indexOf('_datalabel_') > -1)) {
|
|
1134
|
+
for (let p: number = o + 1; p < clusterGroup.childElementCount; p++) {
|
|
1135
|
+
if (clusterGroup.childNodes[p]['style']['visibility'] !== 'hidden') {
|
|
1136
|
+
tempElement1 = clusterGroup.childNodes[p] as Element;
|
|
1137
|
+
bounds2 = tempElement1.getBoundingClientRect() as DOMRect;
|
|
1138
|
+
if (!isNullOrUndefined(bounds2) && !(tempElement1.id.indexOf('_datalabel_') > -1)) {
|
|
1139
|
+
if (!(bounds1.left > bounds2.right || bounds1.right < bounds2.left
|
|
1140
|
+
|| bounds1.top > bounds2.bottom || bounds1.bottom < bounds2.top)) {
|
|
1141
|
+
clusterColloideBounds.push(tempElement1);
|
|
1142
|
+
clusterColloideBounds.push(clusterGroup.childNodes[p - 1] as Element);
|
|
1143
|
+
clusterGroup.childNodes[p]['style']['visibility'] = 'hidden';
|
|
1144
|
+
clusterGroup.childNodes[p - 1]['style']['visibility'] = 'hidden';
|
|
1145
|
+
indexCollection.push(p as number);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
if (clusterColloideBounds.length > 0) {
|
|
1151
|
+
tempElement = clusterGroup.childNodes[o] as Element;
|
|
1152
|
+
for (let i: number = 0; i < clusterColloideBounds.length; i++) {
|
|
1153
|
+
if (tempElement.tagName === 'g') {
|
|
1154
|
+
tempElement.childNodes[0].textContent = tempElement.childNodes[0].textContent + ',' +
|
|
1155
|
+
clusterColloideBounds[i].textContent;
|
|
1156
|
+
} else {
|
|
1157
|
+
tempElement.textContent = tempElement.textContent + ',' + clusterColloideBounds[i].textContent;
|
|
1158
|
+
}
|
|
1159
|
+
clusterGroup.childNodes[o - 1].textContent = ((+(clusterGroup.childNodes[o - 1].textContent)) + (+(clusterColloideBounds[i + 1].textContent))).toString();
|
|
1160
|
+
i++;
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
clusterColloideBounds = [];
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
while (0 < clusterGroup.childNodes.length) {
|
|
1168
|
+
markerCollection.insertBefore(clusterGroup.childNodes[0], markerCollection.firstChild);
|
|
1169
|
+
}
|
|
1170
|
+
if (check) {
|
|
1171
|
+
layerElement.appendChild(markerCollection);
|
|
1172
|
+
} else {
|
|
1173
|
+
getElementByID(maps.element.id + '_Secondary_Element').appendChild(markerCollection);
|
|
1174
|
+
layerElement.appendChild(markerCollection);
|
|
1175
|
+
}
|
|
1176
|
+
const markerCluster: HTMLElement = document.getElementById(maps.element.id + '_LayerIndex_' + layerIndex +'_markerCluster');
|
|
1177
|
+
if (!isNullOrUndefined(markerCluster)) {
|
|
1178
|
+
markerCluster.remove();
|
|
1179
|
+
}
|
|
1180
|
+
if (zoomCheck) {
|
|
1181
|
+
let layerGroupElement: HTMLElement = document.getElementById(maps.element.id + '_Layer_Collections');
|
|
1182
|
+
if (!isNullOrUndefined(layerGroupElement)) {
|
|
1183
|
+
layerGroupElement.appendChild(layerElement);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
1188
|
+
|
|
1189
|
+
/**
|
|
1190
|
+
*
|
|
1191
|
+
* @param {MarkerClusterData[]} sameMarkerData - Specifies the marker data
|
|
1192
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1193
|
+
* @param {Element | HTMLElement} markerElement - Specifies the marker element
|
|
1194
|
+
* @returns {void}
|
|
1195
|
+
*/
|
|
1196
|
+
export function mergeSeparateCluster(sameMarkerData: MarkerClusterData[], maps: Maps, markerElement: Element | HTMLElement): void {
|
|
1197
|
+
const layerIndex: number = sameMarkerData[0].layerIndex;
|
|
1198
|
+
const clusterIndex: number = sameMarkerData[0].targetClusterIndex;
|
|
1199
|
+
const markerIndex: number = sameMarkerData[0].markerIndex;
|
|
1200
|
+
const dataIndex: number = sameMarkerData[0].dataIndex;
|
|
1201
|
+
const markerId: string = maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex;
|
|
1202
|
+
const marker: MarkerSettingsModel = maps.layers[layerIndex].markerSettings[markerIndex];
|
|
1203
|
+
const clusterId: string = markerId + '_dataIndex_' + dataIndex + '_cluster_' + clusterIndex;
|
|
1204
|
+
const clusterEle: Element = maps.layers[layerIndex].markerClusterSettings.shape === 'Balloon' ? getElement(clusterId + '_Group') : getElement(clusterId);
|
|
1205
|
+
const clusterEleLabel: Element = getElement(clusterId + '_datalabel_' + clusterIndex);
|
|
1206
|
+
clusterEle.setAttribute('visibility', 'visible');
|
|
1207
|
+
clusterEleLabel.setAttribute('visibility', 'visible');
|
|
1208
|
+
let markerEle: Element;
|
|
1209
|
+
const markerDataLength: number = sameMarkerData[0].data.length;
|
|
1210
|
+
for (let i: number = 0; i < markerDataLength; i++) {
|
|
1211
|
+
markerEle = marker.shape === 'Balloon' ? getElement(markerId + '_dataIndex_' + sameMarkerData[0].data[i]['index'] + '_Group') : getElement(markerId + '_dataIndex_' + sameMarkerData[0].data[i]['index']);
|
|
1212
|
+
markerEle['style']['visibility'] = 'hidden';
|
|
1213
|
+
}
|
|
1214
|
+
removeElement(maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_markerClusterConnectorLine');
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
/**
|
|
1218
|
+
*
|
|
1219
|
+
* @param {MarkerClusterData[]} sameMarkerData - Specifies the marker data
|
|
1220
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1221
|
+
* @param {Element | HTMLElement} markerElement - Specifies the marker element
|
|
1222
|
+
* @param {boolean} isDom - Specifies the boolean value
|
|
1223
|
+
* @returns {void}
|
|
1224
|
+
*/
|
|
1225
|
+
export function clusterSeparate(sameMarkerData: MarkerClusterData[], maps: Maps, markerElement: Element | HTMLElement, isDom?: boolean): void {
|
|
1226
|
+
const layerIndex: number = sameMarkerData[0].layerIndex;
|
|
1227
|
+
const markerIndex: number = sameMarkerData[0].markerIndex;
|
|
1228
|
+
const clusterIndex: number = sameMarkerData[0].targetClusterIndex;
|
|
1229
|
+
const dataIndex: number = sameMarkerData[0].dataIndex;
|
|
1230
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1231
|
+
const getElementFunction: any = isDom ? getElement : markerElement.querySelector.bind(markerElement);
|
|
1232
|
+
const getQueryConnect: string = isDom ? '' : '#';
|
|
1233
|
+
const markerId: string = maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex;
|
|
1234
|
+
const marker: MarkerSettingsModel = maps.layers[layerIndex].markerSettings[markerIndex];
|
|
1235
|
+
const clusterId: string = markerId + '_dataIndex_' + dataIndex + '_cluster_' + clusterIndex;
|
|
1236
|
+
const clusterEle: Element = maps.layers[layerIndex].markerClusterSettings.shape === 'Balloon' ? getElementFunction(getQueryConnect + '' + clusterId + '_Group') : getElementFunction(getQueryConnect + '' + clusterId);
|
|
1237
|
+
const clusterEleLabel: Element = getElementFunction(getQueryConnect + '' + clusterId + '_datalabel_' + clusterIndex);
|
|
1238
|
+
clusterEle.setAttribute('visibility', 'hidden');
|
|
1239
|
+
clusterEleLabel.setAttribute('visibility', 'hidden');
|
|
1240
|
+
let markerEle: Element = marker.shape === 'Balloon' ? getElementFunction(getQueryConnect + '' + markerId + '_dataIndex_' + dataIndex + '_Group') : getElementFunction(getQueryConnect + '' + markerId + '_dataIndex_' + dataIndex);
|
|
1241
|
+
const height: number = markerEle.parentElement.id.indexOf('Template_Group') > -1 ? markerEle.getBoundingClientRect().height : marker.height;
|
|
1242
|
+
const width: number = markerEle.parentElement.id.indexOf('Template_Group') > -1 ? markerEle.getBoundingClientRect().width : marker.width;
|
|
1243
|
+
const centerX: number = +clusterEle.getAttribute('transform').split('translate(')[1].trim().split(' ')[0];
|
|
1244
|
+
const centerY: number = +clusterEle.getAttribute('transform').split('translate(')[1].trim().split(' ')[1].split(')')[0].trim();
|
|
1245
|
+
|
|
1246
|
+
let radius: number = width + 5;
|
|
1247
|
+
let area: number = 2 * 3.14 * radius;
|
|
1248
|
+
let totalMarker: number = 0;
|
|
1249
|
+
let numberOfMarker: number = Math.round(area / width);
|
|
1250
|
+
totalMarker += numberOfMarker;
|
|
1251
|
+
const markerDataLength: number = sameMarkerData[0].data.length;
|
|
1252
|
+
let percent: number = Math.round((height / area) * 100);
|
|
1253
|
+
percent = markerDataLength < numberOfMarker ? 100 / markerDataLength : percent;
|
|
1254
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1255
|
+
let angle: any = (percent / 100) * 360;
|
|
1256
|
+
let newAngle: number = markerDataLength < numberOfMarker ? 45 : 0;
|
|
1257
|
+
let count: number = 1;
|
|
1258
|
+
const start: string = 'M ' + centerX + ' ' + centerY + ' ';
|
|
1259
|
+
let path: string = '';
|
|
1260
|
+
for (let i: number = 0; i < markerDataLength; i++) {
|
|
1261
|
+
if (totalMarker === i || Math.round(newAngle) >= 360) {
|
|
1262
|
+
count++;
|
|
1263
|
+
radius = (width + 5) * count;
|
|
1264
|
+
newAngle = 0;
|
|
1265
|
+
area = 2 * 3.14 * radius;
|
|
1266
|
+
numberOfMarker = Math.round(area / height);
|
|
1267
|
+
percent = Math.round((height / area) * 100);
|
|
1268
|
+
while (percent * numberOfMarker < 100) {
|
|
1269
|
+
numberOfMarker++;
|
|
1270
|
+
}
|
|
1271
|
+
angle = ((percent / 100) * 360);
|
|
1272
|
+
totalMarker += numberOfMarker;
|
|
1273
|
+
}
|
|
1274
|
+
const x1: number = centerX + radius * Math.sin((Math.PI * 2 * newAngle) / 360);
|
|
1275
|
+
const y1: number = centerY + radius * Math.cos((Math.PI * 2 * newAngle) / 360);
|
|
1276
|
+
path += start + 'L ' + (x1) + ' ' + y1 + ' ';
|
|
1277
|
+
markerEle = marker.shape === 'Balloon' ? getElementFunction(getQueryConnect + '' + markerId + '_dataIndex_' + sameMarkerData[0].data[i]['index'] + '_Group') : getElementFunction(getQueryConnect + '' + markerId + '_dataIndex_' + sameMarkerData[0].data[i]['index']);
|
|
1278
|
+
if (markerEle.parentElement.id.indexOf('Template_Group') > -1) {
|
|
1279
|
+
markerEle['style']['transform'] = '';
|
|
1280
|
+
markerEle['style']['left'] = maps.isTileMap ? x1 - (width / 2) + 'px' : (x1 - (width / 2) - 10) + 'px';
|
|
1281
|
+
markerEle['style']['top'] = maps.isTileMap ? y1 - (height / 2) + 'px' : (y1 - (height / 2) - 10) + 'px';
|
|
1282
|
+
markerEle.setAttribute('transform', 'translate( ' + x1 + ' ' + y1 + ')');
|
|
1283
|
+
} else {
|
|
1284
|
+
markerEle.setAttribute('transform', 'translate( ' + x1 + ' ' + y1 + ')');
|
|
1285
|
+
}
|
|
1286
|
+
markerEle['style']['visibility'] = 'visible';
|
|
1287
|
+
newAngle += angle;
|
|
1288
|
+
}
|
|
1289
|
+
const connectorLine: ConnectorLineSettingsModel = maps.layers[layerIndex].markerClusterSettings.connectorLineSettings;
|
|
1290
|
+
const options: PathOption = {
|
|
1291
|
+
d: path, id: maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_dataIndex_' + dataIndex + '_markerClusterConnectorLine', stroke: connectorLine.color,
|
|
1292
|
+
'fill-opacity': connectorLine.opacity, 'stroke-opacity': connectorLine.opacity, 'stroke-width': connectorLine.width
|
|
1293
|
+
} as PathOption;
|
|
1294
|
+
markerElement = isDom ? getElementFunction(maps.element.id + '_Markers_Group') : markerElement;
|
|
1295
|
+
const groupEle: Element = maps.renderer.createGroup({ id: maps.element.id + '_LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_markerClusterConnectorLine' });
|
|
1296
|
+
groupEle.appendChild(maps.renderer.drawPath(options));
|
|
1297
|
+
if (marker.shape === 'Balloon') {
|
|
1298
|
+
markerElement.insertBefore(groupEle, markerElement.querySelector('#' + markerId + '_dataIndex_0_Group'));
|
|
1299
|
+
} else {
|
|
1300
|
+
markerElement.insertBefore(groupEle, markerElement.querySelector('#' + markerId + '_dataIndex_0'));
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
*
|
|
1306
|
+
* @param {IMarkerRenderingEventArgs} eventArgs - Specifies the arguments
|
|
1307
|
+
* @param {MarkerSettings} markerSettings - Specifies the marker settings
|
|
1308
|
+
* @param {any[]} markerData - Specifies the marker data
|
|
1309
|
+
* @param {number} dataIndex - Specifies the data index
|
|
1310
|
+
* @param {Point} location - Specifies the location
|
|
1311
|
+
* @param {Point} transPoint - Specifies the translate point
|
|
1312
|
+
* @param {string} markerID - Specifies the marker id
|
|
1313
|
+
* @param {Point} offset - Specifies the offset value
|
|
1314
|
+
* @param {number} scale - Specifies the scale value
|
|
1315
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1316
|
+
* @param {Element} markerCollection - Specifies the marker collection
|
|
1317
|
+
* @returns {Element} - Returns the element
|
|
1318
|
+
*/
|
|
1319
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1320
|
+
export function marker(eventArgs: IMarkerRenderingEventArgs, markerSettings: MarkerSettings, markerData: any[], dataIndex: number,
|
|
1321
|
+
location: Point, transPoint: Point, markerID: string, offset: Point, scale: number, maps: Maps,
|
|
1322
|
+
markerCollection: Element): Element {
|
|
1323
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1324
|
+
const shapeCustom: any = {
|
|
1325
|
+
size: new Size(eventArgs.width, eventArgs.height),
|
|
1326
|
+
fill: eventArgs.fill, borderColor: eventArgs.border.color,
|
|
1327
|
+
borderWidth: eventArgs.border.width, opacity: markerSettings.opacity,
|
|
1328
|
+
dashArray: markerSettings.dashArray, borderOpacity: isNullOrUndefined(eventArgs.border.opacity) ? markerSettings.opacity :
|
|
1329
|
+
eventArgs.border.opacity
|
|
1330
|
+
};
|
|
1331
|
+
removeElement(markerID);
|
|
1332
|
+
const ele: Element = drawSymbols(eventArgs.shape, eventArgs.imageUrl, { x: 0, y: 0 }, markerID, shapeCustom, markerCollection, maps);
|
|
1333
|
+
const x: number = (maps.isTileMap ? location.x : (location.x + transPoint.x) * scale) + offset.x;
|
|
1334
|
+
const y: number = (maps.isTileMap ? location.y : (location.y + transPoint.y) * scale) + offset.y;
|
|
1335
|
+
ele.setAttribute('transform', 'translate( ' + x + ' ' + y + ' )');
|
|
1336
|
+
maintainSelection(maps.selectedMarkerElementId, maps.markerSelectionClass, ele, 'MarkerselectionMapStyle');
|
|
1337
|
+
markerCollection.appendChild(ele);
|
|
1338
|
+
const element: string = (markerData.length - 1) === dataIndex ? 'marker' : null;
|
|
1339
|
+
const markerPoint: Point = new Point(x, y);
|
|
1340
|
+
if (markerSettings.animationDuration > 0) {
|
|
1341
|
+
elementAnimate(
|
|
1342
|
+
ele, markerSettings.animationDelay, markerSettings.animationDuration, markerPoint, maps, element
|
|
1343
|
+
);
|
|
1344
|
+
}
|
|
1345
|
+
return markerCollection;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
/**
|
|
1349
|
+
*
|
|
1350
|
+
* @param {IMarkerRenderingEventArgs} eventArgs - Specifies the arguments
|
|
1351
|
+
* @param {any} templateFn - Specifies the template function
|
|
1352
|
+
* @param {string} markerID - Specifies the marker id
|
|
1353
|
+
* @param {any} data - Specifies the data
|
|
1354
|
+
* @param {number} markerIndex - Specifies the marker index
|
|
1355
|
+
* @param {HTMLElement} markerTemplate - Specifies the marker template element
|
|
1356
|
+
* @param {Point} location - Specifies the location
|
|
1357
|
+
* @param {Point} transPoint - Specifies the translate point.
|
|
1358
|
+
* @param {number} scale - Specifies the scale value
|
|
1359
|
+
* @param {Point} offset - Specifies the offset value
|
|
1360
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1361
|
+
* @returns {HTMLElement} - Returns the html element
|
|
1362
|
+
*/
|
|
1363
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1364
|
+
export function markerTemplate(eventArgs: IMarkerRenderingEventArgs, templateFn: any, markerID: string, data: any,
|
|
1365
|
+
markerIndex: number, markerTemplate: HTMLElement, location: Point, transPoint: Point, scale: number, offset: Point, maps: Maps): HTMLElement {
|
|
1366
|
+
templateFn = getTemplateFunction(eventArgs.template, maps);
|
|
1367
|
+
if (templateFn && (templateFn(data, maps, eventArgs.template, maps.element.id + '_MarkerTemplate' + markerIndex, false).length)) {
|
|
1368
|
+
const templateElement: HTMLCollection = templateFn(data, maps, eventArgs.template, maps.element.id + '_MarkerTemplate' + markerIndex, false);
|
|
1369
|
+
const markerElement: HTMLElement = <HTMLElement>convertElement(
|
|
1370
|
+
templateElement, markerID, data, markerIndex, maps
|
|
1371
|
+
);
|
|
1372
|
+
for (let i: number = 0; i < markerElement.children.length; i++) {
|
|
1373
|
+
(<HTMLElement>markerElement.children[i]).style.pointerEvents = 'none';
|
|
1374
|
+
}
|
|
1375
|
+
markerElement.style.left = (maps.isTileMap ? location.x : (location.x + transPoint.x) * scale) + offset.x - maps.mapAreaRect.x + 'px';
|
|
1376
|
+
markerElement.style.top = (maps.isTileMap ? location.y : (location.y + transPoint.y) * scale) + offset.y - maps.mapAreaRect.y + 'px';
|
|
1377
|
+
markerTemplate.appendChild(markerElement);
|
|
1378
|
+
if (maps.layers[maps.baseLayerIndex].layerType === 'GoogleStaticMap') {
|
|
1379
|
+
const staticMapOffset: ClientRect = getElementByID(maps.element.id + '_StaticGoogleMap').getBoundingClientRect();
|
|
1380
|
+
const markerElementOffset: ClientRect = markerElement.getBoundingClientRect();
|
|
1381
|
+
const staticMapOffsetWidth: number = 640;
|
|
1382
|
+
if ((staticMapOffset['x'] > markerElementOffset['x'] || staticMapOffset['x'] + staticMapOffsetWidth < markerElementOffset['x'] + markerElementOffset['width'])
|
|
1383
|
+
&& (staticMapOffset['y'] > markerElementOffset['y'] || staticMapOffset['y'] + staticMapOffset['height'] < markerElementOffset['y'] + markerElementOffset['height'])
|
|
1384
|
+
) {
|
|
1385
|
+
markerElement.style.display = 'none';
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
}
|
|
1390
|
+
return markerTemplate;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1393
|
+
/**
|
|
1394
|
+
* To maintain selection during page resize
|
|
1395
|
+
*
|
|
1396
|
+
* @param {string[]} elementId - Specifies the element id
|
|
1397
|
+
* @param {Element} elementClass - Specifies the element class
|
|
1398
|
+
* @param {Element} element - Specifies the element
|
|
1399
|
+
* @param {string} className - Specifies the class name
|
|
1400
|
+
* @returns {void}
|
|
1401
|
+
* @private
|
|
1402
|
+
*/
|
|
1403
|
+
export function maintainSelection(elementId: string[], elementClass: Element, element: Element, className: string): void {
|
|
1404
|
+
if (elementId) {
|
|
1405
|
+
for (let index: number = 0; index < elementId.length; index++) {
|
|
1406
|
+
if (element.getAttribute('id') === elementId[index]) {
|
|
1407
|
+
if (index === 0 || element.tagName === 'g') {
|
|
1408
|
+
if (!isNullOrUndefined(elementClass) && !isNullOrUndefined(elementClass.id)) {
|
|
1409
|
+
document.body.appendChild(elementClass);
|
|
1410
|
+
}
|
|
1411
|
+
if (element.id.indexOf('_MarkerIndex_') > -1 && element.childElementCount > 0) {
|
|
1412
|
+
element.children[0].setAttribute('class', className);
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
element.setAttribute('class', className);
|
|
1416
|
+
}
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1421
|
+
/**
|
|
1422
|
+
* To maintain selection style class
|
|
1423
|
+
*
|
|
1424
|
+
* @param {string} id - Specifies the id
|
|
1425
|
+
* @param {string} idClass - Specifies the class id
|
|
1426
|
+
* @param {string} fill - Specifies the fill
|
|
1427
|
+
* @param {string} opacity - Specifies the opactiy
|
|
1428
|
+
* @param {string} borderColor - Specifies the border color
|
|
1429
|
+
* @param {string} borderWidth - Specifies the border width
|
|
1430
|
+
* @param {Maps} maps - Specifies the maps
|
|
1431
|
+
* @returns {void}
|
|
1432
|
+
* @private
|
|
1433
|
+
*/
|
|
1434
|
+
export function maintainStyleClass(id: string, idClass: string, fill: string, opacity: string, borderColor: string,
|
|
1435
|
+
borderWidth: string, maps: Maps): void {
|
|
1436
|
+
if (!getElement(id)) {
|
|
1437
|
+
const styleClass: Element = createElement('style', {
|
|
1438
|
+
id: id, innerHTML: '.' + idClass + '{fill:'
|
|
1439
|
+
+ fill + ';' + 'opacity:' + opacity + ';' +
|
|
1440
|
+
'stroke-width:' + borderWidth + ';' +
|
|
1441
|
+
'stroke:' + borderColor + ';' + '}'
|
|
1442
|
+
});
|
|
1443
|
+
maps.shapeSelectionClass = styleClass;
|
|
1444
|
+
document.body.appendChild(styleClass);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
/**
|
|
1449
|
+
* Internal use of append shape element
|
|
1450
|
+
*
|
|
1451
|
+
* @param {Element} shape - Specifies the shape
|
|
1452
|
+
* @param {Element} element - Specifies the element
|
|
1453
|
+
* @returns {Element} - Returns the element
|
|
1454
|
+
* @private
|
|
1455
|
+
*/
|
|
1456
|
+
export function appendShape(shape: Element, element: Element): Element {
|
|
1457
|
+
if (element) { element.appendChild(shape); }
|
|
1458
|
+
return shape;
|
|
1459
|
+
}
|
|
1460
|
+
/**
|
|
1461
|
+
* Internal rendering of Circle
|
|
1462
|
+
*
|
|
1463
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1464
|
+
* @param {CircleOption} options - Specifies the circle options
|
|
1465
|
+
* @param {Element} element - Specifies the element
|
|
1466
|
+
* @returns {Element} - Returns the element
|
|
1467
|
+
* @private
|
|
1468
|
+
*/
|
|
1469
|
+
export function drawCircle(maps: Maps, options: CircleOption, element?: Element): Element {
|
|
1470
|
+
return appendShape(maps.renderer.drawCircle(options), element);
|
|
1471
|
+
}
|
|
1472
|
+
/**
|
|
1473
|
+
* Internal rendering of Rectangle
|
|
1474
|
+
*
|
|
1475
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1476
|
+
* @param {RectOption} options - Specifies the rect options
|
|
1477
|
+
* @param {Element} element - Specifies the element
|
|
1478
|
+
* @returns {Element} - Returns the element
|
|
1479
|
+
* @private
|
|
1480
|
+
*/
|
|
1481
|
+
export function drawRectangle(maps: Maps, options: RectOption, element?: Element): Element {
|
|
1482
|
+
return appendShape(maps.renderer.drawRectangle(options), element);
|
|
1483
|
+
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Internal rendering of Path
|
|
1486
|
+
*
|
|
1487
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1488
|
+
* @param {PathOption} options - Specifies the polygon options
|
|
1489
|
+
* @param {Element} element - Specifies the element
|
|
1490
|
+
* @returns {Element} - Returns the element
|
|
1491
|
+
* @private
|
|
1492
|
+
*/
|
|
1493
|
+
export function drawPath(maps: Maps, options: PathOption, element?: Element): Element {
|
|
1494
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1495
|
+
}
|
|
1496
|
+
/**
|
|
1497
|
+
* Internal rendering of Polygon
|
|
1498
|
+
*
|
|
1499
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1500
|
+
* @param {PolygonOption} options - Specifies the polygon options
|
|
1501
|
+
* @param {Element} element - Specifies the element
|
|
1502
|
+
* @returns {Element} - Returns the element
|
|
1503
|
+
* @private
|
|
1504
|
+
*/
|
|
1505
|
+
export function drawPolygon(maps: Maps, options: PolygonOption, element?: Element): Element {
|
|
1506
|
+
return appendShape(maps.renderer.drawPolygon(options), element);
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Internal rendering of Polyline
|
|
1510
|
+
*
|
|
1511
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1512
|
+
* @param {PolylineOption} options - Specifies the poly line options
|
|
1513
|
+
* @param {Element} element - Specifies the element
|
|
1514
|
+
* @returns {Element} - Returns the element
|
|
1515
|
+
* @private
|
|
1516
|
+
*/
|
|
1517
|
+
export function drawPolyline(maps: Maps, options: PolylineOption, element?: Element): Element {
|
|
1518
|
+
return appendShape(maps.renderer.drawPolyline(options), element);
|
|
1519
|
+
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Internal rendering of Line
|
|
1522
|
+
*
|
|
1523
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1524
|
+
* @param {LineOption} options - Specifies the line options
|
|
1525
|
+
* @param {Element} element - Specifies the element
|
|
1526
|
+
* @returns {Element} - Returns the element
|
|
1527
|
+
* @private
|
|
1528
|
+
*/
|
|
1529
|
+
export function drawLine(maps: Maps, options: LineOption, element?: Element): Element {
|
|
1530
|
+
return appendShape(maps.renderer.drawLine(options), element);
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* Calculate marker shapes
|
|
1535
|
+
*
|
|
1536
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1537
|
+
* @param {MarkerType} shape - Specifies the marker type
|
|
1538
|
+
* @param {PathOption} options - Specifies the path options
|
|
1539
|
+
* @param {Size} size - Specifies the size
|
|
1540
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1541
|
+
* @param {Element} markerEle - Specifies the element
|
|
1542
|
+
* @returns {Element} - Returns the element
|
|
1543
|
+
* @private
|
|
1544
|
+
*/
|
|
1545
|
+
export function calculateShapes(
|
|
1546
|
+
maps: Maps, shape: MarkerType, options: PathOption, size: Size, location: MapLocation, markerEle: Element
|
|
1547
|
+
): Element {
|
|
1548
|
+
let tempGroup: Element;
|
|
1549
|
+
switch (shape) {
|
|
1550
|
+
case 'Balloon':
|
|
1551
|
+
tempGroup = drawBalloon(maps, options, size, location, 'Marker', markerEle);
|
|
1552
|
+
break;
|
|
1553
|
+
case 'Cross':
|
|
1554
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' + (location.y + size.height
|
|
1555
|
+
/ 2) + ' M ' + (location.x - size.width / 2) + ' ' + location.y + ' L ' + (location.x + size.width / 2) + ' ' + location.y;
|
|
1556
|
+
break;
|
|
1557
|
+
case 'Diamond':
|
|
1558
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + (location.x + size.width / 2) + ' '
|
|
1559
|
+
+ location.y + ' L ' + location.x + ' ' + (location.y + size.height / 2) + ' L ' + (location.x - size.width / 2)
|
|
1560
|
+
+ ' ' + location.y + ' Z';
|
|
1561
|
+
break;
|
|
1562
|
+
case 'Star':
|
|
1563
|
+
options.d = 'M ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + (location.x - size.width / 2)
|
|
1564
|
+
+ ' ' + (location.y + size.height / 6) + ' L ' + (location.x + size.width / 2) + ' ' + (location.y + size.height / 6)
|
|
1565
|
+
+ ' L ' + (location.x - size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' +
|
|
1566
|
+
(location.y + size.height / 2) + ' L ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' Z';
|
|
1567
|
+
break;
|
|
1568
|
+
case 'Triangle':
|
|
1569
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + (location.x + size.width / 2) + ' ' +
|
|
1570
|
+
(location.y + size.height / 2) + ' L ' + (location.x - size.width / 2) + ' ' + (location.y + size.height / 2) + ' Z';
|
|
1571
|
+
break;
|
|
1572
|
+
case 'HorizontalLine':
|
|
1573
|
+
options.d = ' M ' + (location.x - size.width / 2) + ' ' + location.y + ' L ' + (location.x + size.width / 2) + ' '
|
|
1574
|
+
+ location.y;
|
|
1575
|
+
break;
|
|
1576
|
+
case 'VerticalLine':
|
|
1577
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' +
|
|
1578
|
+
(location.y + size.height / 2);
|
|
1579
|
+
break;
|
|
1580
|
+
case 'InvertedTriangle':
|
|
1581
|
+
options.d = 'M ' + (location.x - size.width / 2) + ' ' + (location.y - size.height / 2) + ' L ' + (location.x + size.width / 2) + ' ' +
|
|
1582
|
+
(location.y - size.height / 2) + ' L ' + (location.x) + ' ' + (location.y + size.height / 2) + ' Z';
|
|
1583
|
+
break;
|
|
1584
|
+
case 'Pentagon':
|
|
1585
|
+
// eslint-disable-next-line no-case-declarations
|
|
1586
|
+
const eq: number = 72; let xValue: number; let yValue: number;
|
|
1587
|
+
for (let i: number = 0; i < 5; i++) {
|
|
1588
|
+
xValue = (size.width / 2) * Math.cos((Math.PI / 180) * (i * eq));
|
|
1589
|
+
yValue = (size.height / 2) * Math.sin((Math.PI / 180) * (i * eq));
|
|
1590
|
+
options.d += (i === 0 ? 'M ' : 'L ') + (location.x + xValue) + ' ' + (location.y + yValue);
|
|
1591
|
+
}
|
|
1592
|
+
options.d += ' Z';
|
|
1593
|
+
break;
|
|
1594
|
+
}
|
|
1595
|
+
if (shape === 'Cross' || shape === 'HorizontalLine' || shape === 'VerticalLine') {
|
|
1596
|
+
options['stroke'] = (options['stroke'] === 'transparent') ? options['fill'] : options['stroke'];
|
|
1597
|
+
}
|
|
1598
|
+
return shape === 'Balloon' ? tempGroup : maps.renderer.drawPath(options);
|
|
1599
|
+
}
|
|
1600
|
+
|
|
1601
|
+
|
|
1602
|
+
/**
|
|
1603
|
+
* Internal rendering of Diamond
|
|
1604
|
+
*
|
|
1605
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1606
|
+
* @param {PathOption} options - Specifies the path options
|
|
1607
|
+
* @param {Size} size - Specifies the size
|
|
1608
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1609
|
+
* @param {Element} element - Specifies the element
|
|
1610
|
+
* @returns {Element} - Returns the element
|
|
1611
|
+
* @private
|
|
1612
|
+
*/
|
|
1613
|
+
export function drawDiamond(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1614
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + (location.x + size.width / 2) + ' ' + location.y +
|
|
1615
|
+
' L ' + location.x + ' ' + (location.y + size.height / 2) + ' L ' + (location.x - size.width / 2) + ' ' + location.y + ' Z';
|
|
1616
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1617
|
+
}
|
|
1618
|
+
/**
|
|
1619
|
+
* Internal rendering of Triangle
|
|
1620
|
+
*
|
|
1621
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1622
|
+
* @param {PathOption} options - Specifies the path options
|
|
1623
|
+
* @param {Size} size - Specifies the size
|
|
1624
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1625
|
+
* @param {Element} element - Specifies the element
|
|
1626
|
+
* @returns {Element} - Returns the element
|
|
1627
|
+
* @private
|
|
1628
|
+
*/
|
|
1629
|
+
export function drawTriangle(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1630
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + (location.x + size.width / 2) + ' ' +
|
|
1631
|
+
(location.y + size.height / 2) + ' L ' + (location.x - size.width / 2) + ' ' + (location.y + size.height / 2) + ' Z';
|
|
1632
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1633
|
+
}
|
|
1634
|
+
/**
|
|
1635
|
+
* Internal rendering of Cross
|
|
1636
|
+
*
|
|
1637
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1638
|
+
* @param {PathOption} options - Specifies the path options
|
|
1639
|
+
* @param {Size} size - Specifies the size
|
|
1640
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1641
|
+
* @param {Element} element - Specifies the element
|
|
1642
|
+
* @returns {Element} - Returns the element
|
|
1643
|
+
* @private
|
|
1644
|
+
*/
|
|
1645
|
+
export function drawCross(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1646
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' + (location.y + size.height / 2) +
|
|
1647
|
+
' M ' + (location.x - size.width / 2) + ' ' + location.y + ' L ' + (location.x + size.width / 2) + ' ' + location.y;
|
|
1648
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1649
|
+
}
|
|
1650
|
+
/**
|
|
1651
|
+
* Internal rendering of HorizontalLine
|
|
1652
|
+
*
|
|
1653
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1654
|
+
* @param {PathOption} options - Specifies the path options
|
|
1655
|
+
* @param {Size} size - Specifies the size
|
|
1656
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1657
|
+
* @param {Element} element - Specifies the element
|
|
1658
|
+
* @returns {Element} - Returns the element
|
|
1659
|
+
* @private
|
|
1660
|
+
*/
|
|
1661
|
+
export function drawHorizontalLine(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1662
|
+
options.d = ' M ' + (location.x - size.width / 2) + ' ' + location.y + ' L ' + (location.x + size.width / 2) + ' ' + location.y;
|
|
1663
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1664
|
+
}
|
|
1665
|
+
/**
|
|
1666
|
+
* Internal rendering of VerticalLine
|
|
1667
|
+
*
|
|
1668
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1669
|
+
* @param {PathOption} options - Specifies the path options
|
|
1670
|
+
* @param {Size} size - Specifies the size
|
|
1671
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1672
|
+
* @param {Element} element - Specifies the element
|
|
1673
|
+
* @returns {Element} - Returns the element
|
|
1674
|
+
* @private
|
|
1675
|
+
*/
|
|
1676
|
+
export function drawVerticalLine(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1677
|
+
options.d = 'M ' + location.x + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' + (location.y + size.height / 2);
|
|
1678
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1679
|
+
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Internal rendering of Star
|
|
1682
|
+
*
|
|
1683
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1684
|
+
* @param {PathOption} options - Specifies the path options
|
|
1685
|
+
* @param {Size} size - Specifies the size
|
|
1686
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1687
|
+
* @param {Element} element - Specifies the element
|
|
1688
|
+
* @returns {Element} - Returns the element
|
|
1689
|
+
* @private
|
|
1690
|
+
*/
|
|
1691
|
+
export function drawStar(maps: Maps, options: PathOption, size: Size, location: MapLocation, element?: Element): Element {
|
|
1692
|
+
options.d = 'M ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + (location.x - size.width / 2)
|
|
1693
|
+
+ ' ' + (location.y + size.height / 6) + ' L ' + (location.x + size.width / 2) + ' ' + (location.y + size.height / 6) + ' L '
|
|
1694
|
+
+ (location.x - size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' + (location.y + size.height / 2)
|
|
1695
|
+
+ ' L ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' Z';
|
|
1696
|
+
return appendShape(maps.renderer.drawPath(options), element);
|
|
1697
|
+
}
|
|
1698
|
+
/**
|
|
1699
|
+
* Internal rendering of Balloon
|
|
1700
|
+
*
|
|
1701
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1702
|
+
* @param {PathOption} options - Specifies the path options
|
|
1703
|
+
* @param {Size} size - Specifies the size
|
|
1704
|
+
* @param {MapLocation} location - Specifies the map location
|
|
1705
|
+
* @param {Element} element - Specifies the element
|
|
1706
|
+
* @returns {Element} - Returns the element
|
|
1707
|
+
* @private
|
|
1708
|
+
*/
|
|
1709
|
+
export function drawBalloon(maps: Maps, options: PathOption, size: Size, location: MapLocation, type: string, element?: Element): Element {
|
|
1710
|
+
const width: number = size.width;
|
|
1711
|
+
const height: number = size.height;
|
|
1712
|
+
let pathElement: Element;
|
|
1713
|
+
location.x -= width / 2;
|
|
1714
|
+
location.y -= height;
|
|
1715
|
+
options.d = 'M15,0C8.8,0,3.8,5,3.8,11.2C3.8,17.5,9.4,24.4,15,30c5.6-5.6,11.2-12.5,11.2-18.8C26.2,5,21.2,0,15,0z M15,16' +
|
|
1716
|
+
'c-2.8,0-5-2.2-5-5s2.2-5,5-5s5,2.2,5,5S17.8,16,15,16z';
|
|
1717
|
+
const balloon: Element = maps.renderer.drawPath(options);
|
|
1718
|
+
const x: number = size.width / 30;
|
|
1719
|
+
const y: number = size.height / 30;
|
|
1720
|
+
balloon.setAttribute('transform', 'translate(' + location.x + ', ' + location.y + ') scale(' + x + ', ' + y + ')');
|
|
1721
|
+
if (type === 'Marker') {
|
|
1722
|
+
const g: Element = maps.renderer.createGroup({ id: options.id + '_Group' });
|
|
1723
|
+
appendShape(balloon, g);
|
|
1724
|
+
pathElement = appendShape(g, element);
|
|
1725
|
+
}
|
|
1726
|
+
else {
|
|
1727
|
+
pathElement = balloon;
|
|
1728
|
+
}
|
|
1729
|
+
return pathElement;
|
|
1730
|
+
}
|
|
1731
|
+
/**
|
|
1732
|
+
* Internal rendering of Pattern
|
|
1733
|
+
*
|
|
1734
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
1735
|
+
* @param {PatternOptions} options - Specifies the pattern options
|
|
1736
|
+
* @param {Element[]} elements - Specifies the elements
|
|
1737
|
+
* @param {Element} element - Specifies the element
|
|
1738
|
+
* @returns {Element} - Returns the element
|
|
1739
|
+
* @private
|
|
1740
|
+
*/
|
|
1741
|
+
export function drawPattern(maps: Maps, options: PatternOptions, elements: Element[], element?: Element): Element {
|
|
1742
|
+
const pattern: Element = maps.renderer.createPattern(options, 'pattern');
|
|
1743
|
+
for (const ele of elements) {
|
|
1744
|
+
appendShape(ele, pattern);
|
|
1745
|
+
}
|
|
1746
|
+
return appendShape(pattern, element);
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* Method to get specific field and vaues from data.
|
|
1750
|
+
*
|
|
1751
|
+
* @param {any[]} dataSource - Specifies the data source
|
|
1752
|
+
* @param {string[]} fields - Specifies the fields
|
|
1753
|
+
* @returns {any[]} - Returns the object
|
|
1754
|
+
* @private
|
|
1755
|
+
*/
|
|
1756
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1757
|
+
export function getFieldData(dataSource: any[], fields: string[]): any[] {
|
|
1758
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1759
|
+
const newData: any[] = [];
|
|
1760
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1761
|
+
let data: { [key: string]: any };
|
|
1762
|
+
for (const temp of dataSource) {
|
|
1763
|
+
data = {};
|
|
1764
|
+
for (const field of fields) {
|
|
1765
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1766
|
+
if ((<any>temp)[field]) {
|
|
1767
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1768
|
+
data[field] = (<any>temp)[field];
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
newData.push(data);
|
|
1772
|
+
}
|
|
1773
|
+
return newData;
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* To find the index of dataSource from shape properties
|
|
1777
|
+
*
|
|
1778
|
+
* @param {any[]} dataSource - Specifies the data source
|
|
1779
|
+
* @param {any} properties - Specifies the properties
|
|
1780
|
+
* @param {string} dataPath - Specifies the data path
|
|
1781
|
+
* @param {string | string[]} propertyPath - Specifies the property path
|
|
1782
|
+
* @param {LayerSettingsModel} layer - Specifies the layer settings
|
|
1783
|
+
* @returns {number} - Returns the number
|
|
1784
|
+
*/
|
|
1785
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1786
|
+
export function checkShapeDataFields(dataSource: any[], properties: any, dataPath: string, propertyPath: string | string[],
|
|
1787
|
+
layer: LayerSettingsModel): number {
|
|
1788
|
+
if (!(isNullOrUndefined(properties))) {
|
|
1789
|
+
for (let i: number = 0; i < dataSource.length; i++) {
|
|
1790
|
+
const shapeDataPath: string = ((dataPath.indexOf('.') > -1) ? getValueFromObject(dataSource[i], dataPath) :
|
|
1791
|
+
dataSource[i][dataPath]);
|
|
1792
|
+
const shapePath: string = checkPropertyPath(shapeDataPath, propertyPath, properties);
|
|
1793
|
+
const shapeDataPathValue: string = !isNullOrUndefined(shapeDataPath) && isNaN(properties[shapePath])
|
|
1794
|
+
? shapeDataPath.toLowerCase() : shapeDataPath;
|
|
1795
|
+
const propertiesShapePathValue: string = !isNullOrUndefined(properties[shapePath]) && isNaN(properties[shapePath])
|
|
1796
|
+
? properties[shapePath].toLowerCase() : properties[shapePath];
|
|
1797
|
+
if (shapeDataPathValue === propertiesShapePathValue) {
|
|
1798
|
+
return i;
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
return null;
|
|
1803
|
+
}
|
|
1804
|
+
/**
|
|
1805
|
+
*
|
|
1806
|
+
* @param {string} shapeData - Specifies the shape data
|
|
1807
|
+
* @param {string | string[]} shapePropertyPath - Specifies the shape property path
|
|
1808
|
+
* @param {any} shape - Specifies the shape
|
|
1809
|
+
* @returns {string} - Returns the string value
|
|
1810
|
+
*/
|
|
1811
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1812
|
+
export function checkPropertyPath(shapeData: string, shapePropertyPath: string | string[], shape: any): string {
|
|
1813
|
+
if (!isNullOrUndefined(shapeData) && !isNullOrUndefined(shape)) {
|
|
1814
|
+
if (!isNullOrUndefined(shapePropertyPath)) {
|
|
1815
|
+
let length: number;
|
|
1816
|
+
const properties: string[] = (Object.prototype.toString.call(shapePropertyPath) === '[object Array]' ?
|
|
1817
|
+
shapePropertyPath : [shapePropertyPath]) as string[];
|
|
1818
|
+
for (let i: number = 0; i < properties.length; i++) {
|
|
1819
|
+
const shapeDataValue: string = !isNullOrUndefined(shapeData) ? shapeData.toLowerCase() : shapeData;
|
|
1820
|
+
const shapePropertiesValue: string = !isNullOrUndefined(shape[properties[i]])
|
|
1821
|
+
&& isNaN(shape[properties[i]])
|
|
1822
|
+
? shape[properties[i]].toLowerCase() : shape[properties[i]];
|
|
1823
|
+
if (shapeDataValue === shapePropertiesValue) {
|
|
1824
|
+
return properties[i];
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
return null;
|
|
1830
|
+
}
|
|
1831
|
+
|
|
1832
|
+
/**
|
|
1833
|
+
*
|
|
1834
|
+
* @param {MapLocation[]} points - Specifies the location
|
|
1835
|
+
* @param {number} start - Specifies the start value
|
|
1836
|
+
* @param {number} end - Specifies the end value
|
|
1837
|
+
* @returns {MapLocation[]} - Returns the location
|
|
1838
|
+
*/
|
|
1839
|
+
export function filter(points: MapLocation[], start: number, end: number): MapLocation[] {
|
|
1840
|
+
const pointObject: MapLocation[] = [];
|
|
1841
|
+
for (let i: number = 0; i < points.length; i++) {
|
|
1842
|
+
const point: MapLocation = points[i];
|
|
1843
|
+
if (start <= point.y && end >= point.y) {
|
|
1844
|
+
pointObject.push(point);
|
|
1845
|
+
}
|
|
1846
|
+
}
|
|
1847
|
+
return pointObject;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
/**
|
|
1851
|
+
*
|
|
1852
|
+
* @param {number} min - Specifies the min value
|
|
1853
|
+
* @param {number} max - Specifies the max value
|
|
1854
|
+
* @param {number} value - Specifies the value
|
|
1855
|
+
* @param {number} minValue - Specifies the minValue
|
|
1856
|
+
* @param {number} maxValue -Specifies the maxValue
|
|
1857
|
+
* @returns {number} - Returns the number
|
|
1858
|
+
*/
|
|
1859
|
+
export function getRatioOfBubble(min: number, max: number, value: number, minValue: number, maxValue: number): number {
|
|
1860
|
+
const percent: number = (100 / (maxValue - minValue)) * (value - minValue);
|
|
1861
|
+
let bubbleRadius: number = (((max - min) / 100) * percent) + min;
|
|
1862
|
+
if (maxValue === minValue) {
|
|
1863
|
+
bubbleRadius = (((max - min) / 100)) + min;
|
|
1864
|
+
}
|
|
1865
|
+
return bubbleRadius;
|
|
1866
|
+
}
|
|
1867
|
+
/**
|
|
1868
|
+
* To find the midpoint of the polygon from points
|
|
1869
|
+
*
|
|
1870
|
+
* @param {MapLocation[]} points - Specifies the points
|
|
1871
|
+
* @param {string} type - Specifies the type
|
|
1872
|
+
* @param {string} geometryType - Specified the type of the geometry
|
|
1873
|
+
* @returns {any} - Specifies the object
|
|
1874
|
+
*/
|
|
1875
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1876
|
+
export function findMidPointOfPolygon(points: MapLocation[], type: string, geometryType?: string): any {
|
|
1877
|
+
if (!points.length) {
|
|
1878
|
+
return null;
|
|
1879
|
+
}
|
|
1880
|
+
const min: number = 0;
|
|
1881
|
+
const max: number = points.length;
|
|
1882
|
+
let startX: number;
|
|
1883
|
+
let startY: number;
|
|
1884
|
+
let startX1: number;
|
|
1885
|
+
let startY1: number;
|
|
1886
|
+
let sum: number = 0;
|
|
1887
|
+
let xSum: number = 0;
|
|
1888
|
+
let ySum: number = 0;
|
|
1889
|
+
|
|
1890
|
+
for (let i: number = min; i <= max - 1; i++) {
|
|
1891
|
+
startX = points[i].x;
|
|
1892
|
+
startY = type === 'Mercator' || geometryType === 'Normal' ? points[i].y : -(points[i].y);
|
|
1893
|
+
if (i === max - 1) {
|
|
1894
|
+
startX1 = points[0].x;
|
|
1895
|
+
startY1 = type === 'Mercator' || geometryType === 'Normal' ? points[0].y : -(points[0].y);
|
|
1896
|
+
} else {
|
|
1897
|
+
startX1 = points[i + 1].x;
|
|
1898
|
+
startY1 = type === 'Mercator' || geometryType === 'Normal' ? points[i + 1].y : -(points[i + 1].y);
|
|
1899
|
+
}
|
|
1900
|
+
sum = sum + Math.abs(((startX * startY1)) - (startX1 * startY));
|
|
1901
|
+
xSum = xSum + Math.abs(((startX + startX1) * (((startX * startY1) - (startX1 * startY)))));
|
|
1902
|
+
ySum = ySum + Math.abs(((startY + startY1) * (((startX * startY1) - (startX1 * startY)))));
|
|
1903
|
+
}
|
|
1904
|
+
sum = 0.5 * sum;
|
|
1905
|
+
xSum = (1 / (4 * sum)) * xSum;
|
|
1906
|
+
ySum = (1 / (4 * sum)) * ySum;
|
|
1907
|
+
|
|
1908
|
+
/* Code for finding nearest points in polygon related to midPoint*/
|
|
1909
|
+
let rightMinPoint: MapLocation = { x: 0, y: 0 };
|
|
1910
|
+
let rightMaxPoint: MapLocation = { x: 0, y: 0 };
|
|
1911
|
+
let leftMinPoint: MapLocation = { x: 0, y: 0 };
|
|
1912
|
+
let leftMaxPoint: MapLocation = { x: 0, y: 0 };
|
|
1913
|
+
let bottomMinPoint: MapLocation = { x: 0, y: 0 };
|
|
1914
|
+
let bottomMaxPoint: MapLocation = { x: 0, y: 0 };
|
|
1915
|
+
let topMinPoint: MapLocation = { x: 0, y: 0 };
|
|
1916
|
+
let topMaxPoint: MapLocation = { x: 0, y: 0 };
|
|
1917
|
+
let height: number = 0;
|
|
1918
|
+
for (let i: number = min; i <= max - 1; i++) {
|
|
1919
|
+
const point: MapLocation = points[i];
|
|
1920
|
+
point.y = type === 'Mercator' || geometryType === 'Normal' ? point.y : -(point.y);
|
|
1921
|
+
if (point.y > ySum) {
|
|
1922
|
+
if (point.x < xSum && xSum - point.x < xSum - bottomMinPoint.x) {
|
|
1923
|
+
bottomMinPoint = { x: point.x, y: point.y };
|
|
1924
|
+
} else if (point.x > xSum && (bottomMaxPoint.x === 0 || point.x - xSum < bottomMaxPoint.x - xSum)) {
|
|
1925
|
+
bottomMaxPoint = { x: point.x, y: point.y };
|
|
1926
|
+
}
|
|
1927
|
+
} else {
|
|
1928
|
+
if (point.x < xSum && xSum - point.x < xSum - topMinPoint.x) {
|
|
1929
|
+
topMinPoint = { x: point.x, y: point.y };
|
|
1930
|
+
} else if (point.x > xSum && (topMaxPoint.x === 0 || point.x - xSum < topMaxPoint.x - xSum)) {
|
|
1931
|
+
topMaxPoint = { x: point.x, y: point.y };
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
height = (bottomMaxPoint.y - topMaxPoint.y) + ((bottomMaxPoint.y - topMaxPoint.y) / 4);
|
|
1935
|
+
if (point.x > xSum) {
|
|
1936
|
+
if (point.y < ySum && ySum - point.y < ySum - rightMinPoint.y) {
|
|
1937
|
+
rightMinPoint = { x: point.x, y: point.y };
|
|
1938
|
+
} else if (point.y > ySum && (rightMaxPoint.y === 0 || point.y - ySum < rightMaxPoint.y - ySum)) {
|
|
1939
|
+
rightMaxPoint = { x: point.x, y: point.y };
|
|
1940
|
+
}
|
|
1941
|
+
} else {
|
|
1942
|
+
if (point.y < ySum && ySum - point.y < ySum - leftMinPoint.y) {
|
|
1943
|
+
leftMinPoint = { x: point.x, y: point.y };
|
|
1944
|
+
} else if (point.y > ySum && (leftMaxPoint.y === 0 || point.y - ySum < leftMaxPoint.y - ySum)) {
|
|
1945
|
+
leftMaxPoint = { x: point.x, y: point.y };
|
|
1946
|
+
}
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
return {
|
|
1951
|
+
x: xSum, y: ySum, rightMin: rightMinPoint, rightMax: rightMaxPoint,
|
|
1952
|
+
leftMin: leftMinPoint, leftMax: leftMaxPoint, points: points, topMax: topMaxPoint, topMin: topMinPoint,
|
|
1953
|
+
bottomMax: bottomMaxPoint, bottomMin: bottomMinPoint, height: height
|
|
1954
|
+
};
|
|
1955
|
+
}
|
|
1956
|
+
/**
|
|
1957
|
+
* Check custom path
|
|
1958
|
+
*
|
|
1959
|
+
* @param {any[]} layerData - Specifies the layer data
|
|
1960
|
+
* @returns {boolean} - Returns the boolean vlue
|
|
1961
|
+
* @private
|
|
1962
|
+
*/
|
|
1963
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1964
|
+
export function isCustomPath(layerData: any[]): boolean {
|
|
1965
|
+
let customPath: boolean = false;
|
|
1966
|
+
if (Object.prototype.toString.call(layerData) === '[object Array]') {
|
|
1967
|
+
Array.prototype.forEach.call(layerData, (layer: LayerSettings, index: number) => {
|
|
1968
|
+
if (!isNullOrUndefined(layer['geometry']) && layer['geometry']['type'] === 'Path') {
|
|
1969
|
+
customPath = true;
|
|
1970
|
+
}
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
return customPath;
|
|
1974
|
+
}
|
|
1975
|
+
|
|
1976
|
+
/**
|
|
1977
|
+
* Trim the title text
|
|
1978
|
+
*
|
|
1979
|
+
* @param {number} maxWidth - Specifies the maximum width
|
|
1980
|
+
* @param {string} text - Specifies the text
|
|
1981
|
+
* @param {FontModel} font - Specifies the font
|
|
1982
|
+
* @returns {string} - Returns the string
|
|
1983
|
+
* @private
|
|
1984
|
+
*/
|
|
1985
|
+
export function textTrim(maxWidth: number, text: string, font: FontModel): string {
|
|
1986
|
+
let label: string = text;
|
|
1987
|
+
let size: number = measureText(text, font).width;
|
|
1988
|
+
if (size > maxWidth) {
|
|
1989
|
+
const textLength: number = text.length;
|
|
1990
|
+
for (let i: number = textLength - 1; i >= 0; --i) {
|
|
1991
|
+
label = text.substring(0, i) + '...';
|
|
1992
|
+
size = measureText(label, font).width;
|
|
1993
|
+
if (size <= maxWidth || label.length < 4) {
|
|
1994
|
+
if (label.length < 4) {
|
|
1995
|
+
label = ' ';
|
|
1996
|
+
}
|
|
1997
|
+
return label;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
return label;
|
|
2002
|
+
}
|
|
2003
|
+
|
|
2004
|
+
/**
|
|
2005
|
+
* Method to calculate x position of title
|
|
2006
|
+
*
|
|
2007
|
+
* @param {Rect} location - Specifies the location
|
|
2008
|
+
* @param {Alignment} alignment - Specifies the alignment
|
|
2009
|
+
* @param {Size} textSize - Specifies the text size
|
|
2010
|
+
* @param {string} type - Specifies the type
|
|
2011
|
+
* @returns {Point} - Returns the point values
|
|
2012
|
+
*/
|
|
2013
|
+
export function findPosition(location: Rect, alignment: Alignment, textSize: Size, type: string): Point {
|
|
2014
|
+
let x: number;
|
|
2015
|
+
switch (alignment) {
|
|
2016
|
+
case 'Near':
|
|
2017
|
+
x = location.x;
|
|
2018
|
+
break;
|
|
2019
|
+
case 'Center':
|
|
2020
|
+
x = (type === 'title') ? (location.width / 2 - textSize.width / 2) :
|
|
2021
|
+
((location.x + (location.width / 2)) - textSize.width / 2);
|
|
2022
|
+
break;
|
|
2023
|
+
case 'Far':
|
|
2024
|
+
x = (type === 'title') ? (location.width - location.y - textSize.width) :
|
|
2025
|
+
((location.x + location.width) - textSize.width);
|
|
2026
|
+
break;
|
|
2027
|
+
}
|
|
2028
|
+
const y: number = (type === 'title') ? location.y + (textSize.height / 2) : ((location.y + location.height / 2) + textSize.height / 2);
|
|
2029
|
+
return new Point(x, y);
|
|
2030
|
+
}
|
|
2031
|
+
/**
|
|
2032
|
+
* To remove element by id
|
|
2033
|
+
*
|
|
2034
|
+
* @param {string} id - Specifies the id
|
|
2035
|
+
* @returns {void}
|
|
2036
|
+
*/
|
|
2037
|
+
export function removeElement(id: string): void {
|
|
2038
|
+
const element: Element = document.getElementById(id);
|
|
2039
|
+
return element ? remove(element) : null;
|
|
2040
|
+
}
|
|
2041
|
+
|
|
2042
|
+
/**
|
|
2043
|
+
* To calculate map center position from pixel values
|
|
2044
|
+
*
|
|
2045
|
+
* @param {Maps} mapObject - Specifies the map object
|
|
2046
|
+
* @param {LayerSettings} layer - Specifies the layer settings
|
|
2047
|
+
* @returns {Point} - Returns the x and y points
|
|
2048
|
+
*/
|
|
2049
|
+
export function calculateCenterFromPixel(mapObject: Maps, layer: LayerSettings): Point {
|
|
2050
|
+
const point1: Point = convertGeoToPoint(
|
|
2051
|
+
mapObject.minLatOfGivenLocation, mapObject.minLongOfGivenLocation, mapObject.mapLayerPanel.calculateFactor(layer), layer, mapObject);
|
|
2052
|
+
const point2: Point = convertGeoToPoint(
|
|
2053
|
+
mapObject.maxLatOfGivenLocation, mapObject.maxLongOfGivenLocation, mapObject.mapLayerPanel.calculateFactor(layer), layer, mapObject);
|
|
2054
|
+
const x: number = (point1.x + point2.x) / 2;
|
|
2055
|
+
const y: number = (point1.y + point2.y) / 2;
|
|
2056
|
+
return new Point(x, y);
|
|
2057
|
+
}
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* @param {Maps} mapObject - Specifies the map object
|
|
2061
|
+
* @param {LayerSettings} layer - Specifies the layer settings
|
|
2062
|
+
* @param {boolean} animate - Specifies the boolean value
|
|
2063
|
+
* @returns {any} - Returns the object
|
|
2064
|
+
* @private
|
|
2065
|
+
*/
|
|
2066
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2067
|
+
export function getTranslate(mapObject: Maps, layer: LayerSettings, animate?: boolean): any {
|
|
2068
|
+
let zoomFactorValue: number = mapObject.zoomSettings.zoomFactor; let scaleFactor: number;
|
|
2069
|
+
let center: CenterPositionModel = mapObject.centerPosition;
|
|
2070
|
+
let centerLatitude: number = center.latitude;
|
|
2071
|
+
let centerLongitude: number = center.longitude;
|
|
2072
|
+
const checkMethodeZoom: boolean = !isNullOrUndefined(mapObject.centerLatOfGivenLocation) &&
|
|
2073
|
+
!isNullOrUndefined(mapObject.centerLongOfGivenLocation) && mapObject.zoomNotApplied;
|
|
2074
|
+
if (isNullOrUndefined(mapObject.mapScaleValue)) {
|
|
2075
|
+
mapObject.mapScaleValue = zoomFactorValue;
|
|
2076
|
+
}
|
|
2077
|
+
if (mapObject.zoomSettings.shouldZoomInitially && mapObject.zoomSettings.enable) {
|
|
2078
|
+
mapObject.mapScaleValue = scaleFactor = zoomFactorValue = ((mapObject.zoomSettings.shouldZoomInitially || mapObject.enablePersistence) && mapObject.scale === 1)
|
|
2079
|
+
? mapObject.scale : (isNullOrUndefined(mapObject.markerZoomFactor)) ? 1 : mapObject.markerZoomFactor;
|
|
2080
|
+
if (mapObject.mapScaleValue !== mapObject.markerZoomFactor && !mapObject.enablePersistence) {
|
|
2081
|
+
mapObject.mapScaleValue = zoomFactorValue = mapObject.markerZoomFactor;
|
|
2082
|
+
}
|
|
2083
|
+
if (!isNullOrUndefined(mapObject.markerCenterLatitude) && !isNullOrUndefined(mapObject.markerCenterLongitude)) {
|
|
2084
|
+
centerLatitude = mapObject.markerCenterLatitude;
|
|
2085
|
+
centerLongitude = mapObject.markerCenterLongitude;
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
if (checkMethodeZoom) {
|
|
2089
|
+
mapObject.mapScaleValue = scaleFactor = zoomFactorValue = mapObject.scaleOfGivenLocation;
|
|
2090
|
+
}
|
|
2091
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2092
|
+
const min: any = !isNullOrUndefined(mapObject.baseMapRectBounds) ? mapObject.baseMapRectBounds['min'] as any : null;
|
|
2093
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2094
|
+
const max: any = !isNullOrUndefined(mapObject.baseMapRectBounds) ? mapObject.baseMapRectBounds['max'] as any : null;
|
|
2095
|
+
const zoomFactor: number = animate ? 1 : mapObject.mapScaleValue;
|
|
2096
|
+
if (isNullOrUndefined(mapObject.currentShapeDataLength)) {
|
|
2097
|
+
mapObject.currentShapeDataLength = !isNullOrUndefined(layer.shapeData['features'])
|
|
2098
|
+
? layer.shapeData['features'].length : layer.shapeData['geometries'].length;
|
|
2099
|
+
}
|
|
2100
|
+
const size: Rect = (mapObject.totalRect && mapObject.legendSettings.visible) ? mapObject.totalRect : mapObject.mapAreaRect;
|
|
2101
|
+
const availSize: Size = mapObject.availableSize;
|
|
2102
|
+
let x: number; let y: number;
|
|
2103
|
+
if (!isNullOrUndefined(min) && !isNullOrUndefined(max)) {
|
|
2104
|
+
let mapWidth: number = Math.abs(max['x'] - min['x']);
|
|
2105
|
+
let mapHeight: number = Math.abs(min['y'] - max['y']);
|
|
2106
|
+
const factor: number = animate ? 1 : mapObject.markerZoomFactor === 1 ? mapObject.mapScaleValue : zoomFactorValue;
|
|
2107
|
+
center = mapObject.zoomSettings.shouldZoomInitially
|
|
2108
|
+
&& mapObject.markerZoomedState && !mapObject.zoomPersistence ? mapObject.markerZoomCenterPoint :
|
|
2109
|
+
mapObject.centerPosition;
|
|
2110
|
+
if ((!isNullOrUndefined(centerLongitude) && !isNullOrUndefined(centerLatitude)) || checkMethodeZoom) {
|
|
2111
|
+
const leftPosition: number = (((mapWidth + Math.abs(mapObject.mapAreaRect.width - mapWidth)) / 2) + mapObject.mapAreaRect.x) / factor;
|
|
2112
|
+
const topPosition: number = (((mapHeight + Math.abs(mapObject.mapAreaRect.height - mapHeight)) / 2) + mapObject.mapAreaRect.y) / factor;
|
|
2113
|
+
const point: Point = checkMethodeZoom ? calculateCenterFromPixel(mapObject, layer) :
|
|
2114
|
+
convertGeoToPoint(
|
|
2115
|
+
centerLatitude, centerLongitude, mapObject.mapLayerPanel.calculateFactor(layer), layer, mapObject);
|
|
2116
|
+
if (isNullOrUndefined(mapObject.previousProjection) || mapObject.previousProjection !== mapObject.projectionType) {
|
|
2117
|
+
x = -point.x + leftPosition;
|
|
2118
|
+
y = -point.y + topPosition;
|
|
2119
|
+
scaleFactor = zoomFactor;
|
|
2120
|
+
} else {
|
|
2121
|
+
if (Math.floor(mapObject.scale) !== 1 && mapObject.zoomSettings.shouldZoomInitially || (mapObject.zoomNotApplied)) {
|
|
2122
|
+
x = -point.x + leftPosition;
|
|
2123
|
+
y = -point.y + topPosition;
|
|
2124
|
+
} else {
|
|
2125
|
+
if (mapObject.zoomSettings.shouldZoomInitially || mapObject.zoomNotApplied) {
|
|
2126
|
+
x = -point.x + leftPosition;
|
|
2127
|
+
y = -point.y + topPosition;
|
|
2128
|
+
scaleFactor = zoomFactor;
|
|
2129
|
+
} else {
|
|
2130
|
+
x = mapObject.zoomTranslatePoint.x;
|
|
2131
|
+
y = mapObject.zoomTranslatePoint.y;
|
|
2132
|
+
}
|
|
2133
|
+
}
|
|
2134
|
+
scaleFactor = mapObject.mapScaleValue;
|
|
2135
|
+
}
|
|
2136
|
+
} else {
|
|
2137
|
+
if (isNullOrUndefined(mapObject.previousProjection) || mapObject.previousProjection !== mapObject.projectionType) {
|
|
2138
|
+
if (mapHeight === 0 || mapWidth === 0 || mapHeight === mapWidth) {
|
|
2139
|
+
mapWidth = size.width / 2;
|
|
2140
|
+
mapHeight = size.height;
|
|
2141
|
+
}
|
|
2142
|
+
scaleFactor = parseFloat(Math.min(size.width / mapWidth, size.height / mapHeight).toFixed(2));
|
|
2143
|
+
scaleFactor = scaleFactor > 1.05 ? 1 : scaleFactor;
|
|
2144
|
+
mapWidth *= scaleFactor;
|
|
2145
|
+
mapHeight *= scaleFactor;
|
|
2146
|
+
const widthDiff: number = min['x'] !== 0 && mapObject.translateType === 'layers' ? availSize.width - size.width : 0;
|
|
2147
|
+
x = size.x + ((-(min['x'])) + ((size.width / 2) - (mapWidth / 2))) - widthDiff;
|
|
2148
|
+
y = size.y + ((-(min['y'])) + ((size.height / 2) - (mapHeight / 2)));
|
|
2149
|
+
mapObject.previousTranslate = new Point(x, y);
|
|
2150
|
+
} else {
|
|
2151
|
+
if (!mapObject.zoomSettings.shouldZoomInitially && mapObject.markerZoomFactor === 1 && mapObject.mapScaleValue === 1) {
|
|
2152
|
+
scaleFactor = parseFloat(Math.min(size.width / mapWidth, size.height / mapHeight).toFixed(2));
|
|
2153
|
+
mapHeight *= scaleFactor; mapWidth *= scaleFactor;
|
|
2154
|
+
y = size.y + ((-(min['y'])) + ((size.height / 2) - (mapHeight / 2)));
|
|
2155
|
+
x = size.x + ((-(min['x'])) + ((size.width / 2) - (mapWidth / 2)));
|
|
2156
|
+
} else {
|
|
2157
|
+
scaleFactor = mapObject.mapScaleValue < 1 ? mapObject.mapScaleValue + 1 : mapObject.mapScaleValue;
|
|
2158
|
+
mapObject.mapScaleValue = mapObject.zoomSettings.enable && mapObject.mapScaleValue !== 1 ? mapObject.mapScaleValue : 1;
|
|
2159
|
+
if ((mapObject.currentShapeDataLength !== (!isNullOrUndefined(layer.shapeData['features'])
|
|
2160
|
+
? layer.shapeData['features'].length : layer.shapeData['geometries'].length)) && layer.type !== 'SubLayer') {
|
|
2161
|
+
const scale: number = parseFloat(Math.min(size.height / mapHeight, size.width / mapWidth).toFixed(2));
|
|
2162
|
+
mapHeight *= scale; mapWidth *= scale;
|
|
2163
|
+
y = size.y + ((-(min['y'])) + ((size.height / 2)
|
|
2164
|
+
- (mapHeight / 2)));
|
|
2165
|
+
scaleFactor = scale;
|
|
2166
|
+
x = size.x + ((-(min['x']))
|
|
2167
|
+
+ ((size.width / 2) - (mapWidth / 2)));
|
|
2168
|
+
} else if (mapObject.availableSize.height !== mapObject.heightBeforeRefresh || mapObject.widthBeforeRefresh !== mapObject.availableSize.width) {
|
|
2169
|
+
const cscaleFactor: number = parseFloat(Math.min(size.width / mapWidth, size.height / mapHeight).toFixed(2));
|
|
2170
|
+
let cmapWidth: number = mapWidth; cmapWidth *= cscaleFactor;
|
|
2171
|
+
let cmapHeight: number = mapHeight; cmapHeight *= cscaleFactor;
|
|
2172
|
+
const x1: number = size.x + ((-(min['x'])) + ((size.width / 2) - (cmapWidth / 2)));
|
|
2173
|
+
const y1: number = size.y + ((-(min['y'])) + ((size.height / 2) - (cmapHeight / 2)));
|
|
2174
|
+
const xdiff: number = (mapObject.translatePoint.x - mapObject.previousTranslate.x) / (mapObject.widthBeforeRefresh);
|
|
2175
|
+
const ydiff: number = (mapObject.translatePoint.y - mapObject.previousTranslate.y) / (mapObject.heightBeforeRefresh);
|
|
2176
|
+
const actxdiff: number = xdiff * (mapObject.availableSize.width);
|
|
2177
|
+
const actydiff: number = ydiff * (mapObject.availableSize.height);
|
|
2178
|
+
x = x1 + actxdiff;
|
|
2179
|
+
y = y1 + actydiff;
|
|
2180
|
+
mapObject.previousTranslate = new Point(x1, y1);
|
|
2181
|
+
mapObject.zoomTranslatePoint.x = x;
|
|
2182
|
+
mapObject.zoomTranslatePoint.y = y;
|
|
2183
|
+
} else {
|
|
2184
|
+
if (!isNullOrUndefined(mapObject.previousProjection) && (mapObject.mapScaleValue === 1 || mapObject.mapScaleValue <= 1.05) && !mapObject.zoomModule.isDragZoom) {
|
|
2185
|
+
scaleFactor = parseFloat(Math.min(size.width / mapWidth, size.height / mapHeight).toFixed(2));
|
|
2186
|
+
scaleFactor = scaleFactor > 1.05 ? 1: scaleFactor;
|
|
2187
|
+
mapWidth *= scaleFactor;
|
|
2188
|
+
x = size.x + ((-(min['x'])) + ((size.width / 2) - (mapWidth / 2)));
|
|
2189
|
+
mapHeight *= scaleFactor;
|
|
2190
|
+
y = size.y + ((-(min['y'])) + ((size.height / 2) - (mapHeight / 2)));
|
|
2191
|
+
} else {
|
|
2192
|
+
x = mapObject.zoomTranslatePoint.x;
|
|
2193
|
+
y = mapObject.zoomTranslatePoint.y;
|
|
2194
|
+
scaleFactor = mapObject.scale;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
}
|
|
2200
|
+
if (!isNullOrUndefined(mapObject.translatePoint)) {
|
|
2201
|
+
x = (mapObject.enablePersistence && mapObject.translatePoint.x !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.x : x;
|
|
2202
|
+
y = (mapObject.enablePersistence && mapObject.translatePoint.y !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.y : y;
|
|
2203
|
+
}
|
|
2204
|
+
}
|
|
2205
|
+
scaleFactor = (mapObject.enablePersistence) ? ((mapObject.mapScaleValue >= 1) ? mapObject.mapScaleValue : 1) : scaleFactor;
|
|
2206
|
+
mapObject.widthBeforeRefresh = mapObject.availableSize.width;
|
|
2207
|
+
mapObject.heightBeforeRefresh = mapObject.availableSize.height;
|
|
2208
|
+
return { scale: scaleFactor, location: new Point(x, y) };
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
/**
|
|
2212
|
+
* @param {Maps} mapObject - Specifies the map object
|
|
2213
|
+
* @param {LayerSettings} layer - Specifies the layer
|
|
2214
|
+
* @param {boolean} animate - Specifies the boolean value
|
|
2215
|
+
* @returns {any} - Returns the object.
|
|
2216
|
+
* @private
|
|
2217
|
+
*/
|
|
2218
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2219
|
+
export function getZoomTranslate(mapObject: Maps, layer: LayerSettings, animate?: boolean): any {
|
|
2220
|
+
let zoomFactorValue: number = mapObject.zoomSettings.zoomFactor;
|
|
2221
|
+
let scaleFactor: number;
|
|
2222
|
+
const center: CenterPositionModel = mapObject.centerPosition;
|
|
2223
|
+
let latitude: number = center.latitude;
|
|
2224
|
+
let longitude: number = center.longitude;
|
|
2225
|
+
const checkZoomMethod: boolean = !isNullOrUndefined(mapObject.centerLongOfGivenLocation) &&
|
|
2226
|
+
!isNullOrUndefined(mapObject.centerLatOfGivenLocation) && mapObject.zoomNotApplied;
|
|
2227
|
+
if (isNullOrUndefined(mapObject.previousCenterLatitude) &&
|
|
2228
|
+
isNullOrUndefined(mapObject.previousCenterLongitude)) {
|
|
2229
|
+
mapObject.previousCenterLatitude = mapObject.centerPosition.latitude;
|
|
2230
|
+
mapObject.previousCenterLongitude = mapObject.centerPosition.longitude;
|
|
2231
|
+
}
|
|
2232
|
+
else if (mapObject.previousCenterLatitude !==
|
|
2233
|
+
mapObject.centerPosition.latitude && mapObject.previousCenterLongitude !==
|
|
2234
|
+
mapObject.centerPosition.longitude) {
|
|
2235
|
+
mapObject.centerPositionChanged = true;
|
|
2236
|
+
mapObject.previousCenterLatitude = mapObject.centerPosition.latitude;
|
|
2237
|
+
mapObject.previousCenterLongitude = mapObject.centerPosition.longitude;
|
|
2238
|
+
}
|
|
2239
|
+
else {
|
|
2240
|
+
mapObject.centerPositionChanged = false;
|
|
2241
|
+
}
|
|
2242
|
+
if (isNullOrUndefined(mapObject.mapScaleValue) || (zoomFactorValue > mapObject.mapScaleValue)) {
|
|
2243
|
+
if (mapObject.isReset && mapObject.mapScaleValue === 1) {
|
|
2244
|
+
// eslint-disable-next-line no-self-assign
|
|
2245
|
+
mapObject.mapScaleValue = mapObject.mapScaleValue;
|
|
2246
|
+
} else {
|
|
2247
|
+
mapObject.mapScaleValue = zoomFactorValue;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
mapObject.mapScaleValue = mapObject.zoomSettings.zoomFactor !== 1 &&
|
|
2251
|
+
mapObject.zoomSettings.zoomFactor ===
|
|
2252
|
+
mapObject.mapScaleValue ? mapObject.zoomSettings.zoomFactor :
|
|
2253
|
+
mapObject.zoomSettings.zoomFactor !== mapObject.mapScaleValue && !mapObject.centerPositionChanged ? mapObject.mapScaleValue : mapObject.zoomSettings.zoomFactor;
|
|
2254
|
+
if (mapObject.zoomSettings.shouldZoomInitially) {
|
|
2255
|
+
mapObject.mapScaleValue = zoomFactorValue = scaleFactor = ((mapObject.enablePersistence || mapObject.zoomSettings.shouldZoomInitially) && mapObject.scale === 1)
|
|
2256
|
+
? mapObject.scale : (isNullOrUndefined(mapObject.markerZoomFactor)) ? mapObject.mapScaleValue : mapObject.markerZoomFactor;
|
|
2257
|
+
zoomFactorValue = mapObject.mapScaleValue;
|
|
2258
|
+
if (!isNullOrUndefined(mapObject.markerCenterLatitude) && !isNullOrUndefined(mapObject.markerCenterLongitude)) {
|
|
2259
|
+
latitude = mapObject.markerCenterLatitude;
|
|
2260
|
+
longitude = mapObject.markerCenterLongitude;
|
|
2261
|
+
}
|
|
2262
|
+
}
|
|
2263
|
+
if (checkZoomMethod) {
|
|
2264
|
+
mapObject.mapScaleValue = scaleFactor = zoomFactorValue = mapObject.scaleOfGivenLocation;
|
|
2265
|
+
}
|
|
2266
|
+
const zoomFactor: number = animate ? 1 : mapObject.mapScaleValue;
|
|
2267
|
+
const size: Rect = mapObject.mapAreaRect; let x: number; let y: number;
|
|
2268
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2269
|
+
const min: any = mapObject.baseMapRectBounds['min'] as any;
|
|
2270
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2271
|
+
const max: any = mapObject.baseMapRectBounds['max'] as any;
|
|
2272
|
+
const factor: number = animate ? 1 : mapObject.mapScaleValue;
|
|
2273
|
+
const mapWidth: number = Math.abs(max['x'] - min['x']); const mapHeight: number = Math.abs(min['y'] - max['y']);
|
|
2274
|
+
if ((!isNullOrUndefined(longitude) && !isNullOrUndefined(latitude)) || checkZoomMethod) {
|
|
2275
|
+
const topPosition: number = ((mapHeight + Math.abs(mapObject.mapAreaRect.height - mapHeight)) / 2) / factor;
|
|
2276
|
+
const leftPosition: number = ((mapWidth + Math.abs(mapObject.mapAreaRect.width - mapWidth)) / 2) / factor;
|
|
2277
|
+
const point: Point = checkZoomMethod ? calculateCenterFromPixel(mapObject, layer) :
|
|
2278
|
+
convertGeoToPoint(
|
|
2279
|
+
latitude, longitude, mapObject.mapLayerPanel.calculateFactor(layer), layer, mapObject);
|
|
2280
|
+
if ((!isNullOrUndefined(mapObject.zoomTranslatePoint) || !isNullOrUndefined(mapObject.previousProjection)) && !mapObject.zoomNotApplied) {
|
|
2281
|
+
if (mapObject.previousProjection !== mapObject.projectionType) {
|
|
2282
|
+
x = -point.x + leftPosition;
|
|
2283
|
+
y = -point.y + topPosition;
|
|
2284
|
+
} else {
|
|
2285
|
+
x = mapObject.zoomTranslatePoint.x;
|
|
2286
|
+
y = mapObject.zoomTranslatePoint.y;
|
|
2287
|
+
zoomFactorValue = zoomFactor;
|
|
2288
|
+
}
|
|
2289
|
+
} else {
|
|
2290
|
+
x = -point.x + leftPosition + mapObject.mapAreaRect.x / zoomFactor;
|
|
2291
|
+
y = -point.y + topPosition + mapObject.mapAreaRect.y / zoomFactor;
|
|
2292
|
+
}
|
|
2293
|
+
if (!isNullOrUndefined(mapObject.translatePoint)) {
|
|
2294
|
+
y = (mapObject.enablePersistence && mapObject.translatePoint.y !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.y : y;
|
|
2295
|
+
x = (mapObject.enablePersistence && mapObject.translatePoint.x !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.x : x;
|
|
2296
|
+
}
|
|
2297
|
+
scaleFactor = zoomFactorValue !== 0 ? zoomFactorValue : 1;
|
|
2298
|
+
} else {
|
|
2299
|
+
let zoomFact: number = mapObject.zoomSettings.zoomFactor === 0 ? 1 : mapObject.zoomSettings.zoomFactor;
|
|
2300
|
+
const maxZoomFact: number = mapObject.zoomSettings.maxZoom;
|
|
2301
|
+
zoomFact = zoomFact > maxZoomFact ? maxZoomFact : zoomFact;
|
|
2302
|
+
scaleFactor = zoomFact;
|
|
2303
|
+
const mapScale: number = mapObject.mapScaleValue === 0 ? 1 : mapObject.mapScaleValue > maxZoomFact
|
|
2304
|
+
? maxZoomFact : mapObject.mapScaleValue;
|
|
2305
|
+
let leftPosition: number = (size.x + ((-(min['x'])) + ((size.width / 2) - (mapWidth / 2))));
|
|
2306
|
+
let topPosition: number = (size.y + ((-(min['y'])) + ((size.height / 2) - (mapHeight / 2))));
|
|
2307
|
+
if (!isNullOrUndefined(mapObject.zoomTranslatePoint) || !isNullOrUndefined(mapObject.previousProjection)) {
|
|
2308
|
+
if (mapObject.previousProjection !== mapObject.projectionType) {
|
|
2309
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2310
|
+
const previousPositions: any[] = [];
|
|
2311
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2312
|
+
let previousPoints: any = { x: leftPosition, y: topPosition };
|
|
2313
|
+
previousPositions.push(previousPoints);
|
|
2314
|
+
for (let i: number = 1; i < maxZoomFact; i++) {
|
|
2315
|
+
const translatePointX: number = previousPositions[i - 1]['x'] - (((size.width / (i)) - (size.width / (i + 1))) / 2);
|
|
2316
|
+
const translatePointY: number = previousPositions[i - 1]['y'] - (((size.height / (i)) - (size.height / (i + 1))) / 2);
|
|
2317
|
+
previousPoints = { x: translatePointX, y: translatePointY };
|
|
2318
|
+
previousPositions.push(previousPoints);
|
|
2319
|
+
}
|
|
2320
|
+
leftPosition = previousPositions[zoomFact - 1]['x'];
|
|
2321
|
+
topPosition = previousPositions[zoomFact - 1]['y'];
|
|
2322
|
+
} else {
|
|
2323
|
+
leftPosition = mapObject.zoomTranslatePoint.x;
|
|
2324
|
+
topPosition = mapObject.zoomTranslatePoint.y;
|
|
2325
|
+
if (zoomFact !== mapScale) {
|
|
2326
|
+
scaleFactor = mapScale;
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
if (!isNullOrUndefined(mapObject.translatePoint)) {
|
|
2331
|
+
x = (mapObject.enablePersistence && mapObject.translatePoint.x !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.x : leftPosition;
|
|
2332
|
+
y = (mapObject.enablePersistence && mapObject.translatePoint.y !== 0 && !mapObject.zoomNotApplied) ? mapObject.translatePoint.y : topPosition;
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
scaleFactor = (mapObject.enablePersistence) ? (mapObject.mapScaleValue === 0 ? 1 : mapObject.mapScaleValue) : scaleFactor;
|
|
2336
|
+
mapObject.widthBeforeRefresh = mapObject.availableSize.width;
|
|
2337
|
+
mapObject.heightBeforeRefresh = mapObject.availableSize.height;
|
|
2338
|
+
return { scale: animate ? 1 : scaleFactor, location: new Point(x, y) };
|
|
2339
|
+
}
|
|
2340
|
+
|
|
2341
|
+
/**
|
|
2342
|
+
* To get the html element by specified id
|
|
2343
|
+
*
|
|
2344
|
+
* @param {Maps} map - Specifies the instance of the maps
|
|
2345
|
+
* @returns {void}
|
|
2346
|
+
*/
|
|
2347
|
+
export function fixInitialScaleForTile(map: Maps): void {
|
|
2348
|
+
map.tileZoomScale = map.tileZoomLevel = Math.floor(map.availableSize.height / 512) + 1;
|
|
2349
|
+
const padding: number = map.layers[map.baseLayerIndex].layerType !== 'GoogleStaticMap' ?
|
|
2350
|
+
20 : 0;
|
|
2351
|
+
const totalSize: number = Math.pow(2, map.tileZoomLevel) * 256;
|
|
2352
|
+
map.tileTranslatePoint.x = (map.availableSize.width / 2) - (totalSize / 2);
|
|
2353
|
+
map.tileTranslatePoint.y = (map.availableSize.height / 2) - (totalSize / 2) + padding;
|
|
2354
|
+
map.previousTileWidth = map.availableSize.width;
|
|
2355
|
+
map.previousTileHeight = map.availableSize.height;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
/**
|
|
2359
|
+
* To get the html element by specified id
|
|
2360
|
+
*
|
|
2361
|
+
* @param {string} id - Specifies the id
|
|
2362
|
+
* @returns {Element} - Returns the element
|
|
2363
|
+
*/
|
|
2364
|
+
export function getElementByID(id: string): Element {
|
|
2365
|
+
return document.getElementById(id);
|
|
2366
|
+
}
|
|
2367
|
+
/**
|
|
2368
|
+
* Function to get clientElement from id.
|
|
2369
|
+
*
|
|
2370
|
+
* @param {string} id - Specifies the id
|
|
2371
|
+
* @returns {Element} - Returns the element
|
|
2372
|
+
* @private
|
|
2373
|
+
*/
|
|
2374
|
+
export function getClientElement(id: string): ClientRect {
|
|
2375
|
+
const element: HTMLElement = document.getElementById(id);
|
|
2376
|
+
if (!isNullOrUndefined(element)) {
|
|
2377
|
+
return element.getClientRects()[0];
|
|
2378
|
+
} else {
|
|
2379
|
+
return null;
|
|
2380
|
+
}
|
|
2381
|
+
}
|
|
2382
|
+
/**
|
|
2383
|
+
* To apply internalization
|
|
2384
|
+
*
|
|
2385
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
2386
|
+
* @param {number} value - Specifies the value
|
|
2387
|
+
* @returns {string} - Returns the string
|
|
2388
|
+
*/
|
|
2389
|
+
export function Internalize(maps: Maps, value: number): string {
|
|
2390
|
+
maps.formatFunction =
|
|
2391
|
+
maps.intl.getNumberFormat({ format: maps.format, useGrouping: maps.useGroupingSeparator });
|
|
2392
|
+
return maps.formatFunction(value);
|
|
2393
|
+
}
|
|
2394
|
+
|
|
2395
|
+
/**
|
|
2396
|
+
* Function to compile the template function for maps.
|
|
2397
|
+
*
|
|
2398
|
+
* @param {string} template - Specifies the template
|
|
2399
|
+
* @returns {Function} - Returns the function
|
|
2400
|
+
* @private
|
|
2401
|
+
*/
|
|
2402
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2403
|
+
export function getTemplateFunction(template: string, maps: Maps): any {
|
|
2404
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2405
|
+
let templateFn: any = null;
|
|
2406
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2407
|
+
let e: any;
|
|
2408
|
+
try {
|
|
2409
|
+
if (document.querySelectorAll(template).length) {
|
|
2410
|
+
templateFn = templateComplier(document.querySelector(template).innerHTML.trim());
|
|
2411
|
+
} else if ((maps as any).isVue || (maps as any).isVue3) {
|
|
2412
|
+
templateFn = templateComplier(template);
|
|
2413
|
+
}
|
|
2414
|
+
} catch (e) {
|
|
2415
|
+
templateFn = templateComplier(template);
|
|
2416
|
+
}
|
|
2417
|
+
return templateFn;
|
|
2418
|
+
}
|
|
2419
|
+
/**
|
|
2420
|
+
* Function to get element from id.
|
|
2421
|
+
*
|
|
2422
|
+
* @param {string} id - Specifies the id
|
|
2423
|
+
* @returns {Element} - Returns the element
|
|
2424
|
+
* @private
|
|
2425
|
+
*/
|
|
2426
|
+
export function getElement(id: string): Element {
|
|
2427
|
+
return document.getElementById(id);
|
|
2428
|
+
}
|
|
2429
|
+
|
|
2430
|
+
/**
|
|
2431
|
+
* Function to get shape data using target id
|
|
2432
|
+
*
|
|
2433
|
+
* @param {string} targetId - Specifies the target id
|
|
2434
|
+
* @param {Maps} map - Specifies the instance of the maps
|
|
2435
|
+
* @returns {any} - Returns the object
|
|
2436
|
+
*/
|
|
2437
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2438
|
+
export function getShapeData(targetId: string, map: Maps): { shapeData: any, data: any } {
|
|
2439
|
+
const layerIndex: number = parseInt(targetId.split('_LayerIndex_')[1].split('_')[0], 10);
|
|
2440
|
+
const shapeIndex: number = parseInt(targetId.split('_shapeIndex_')[1].split('_')[0], 10);
|
|
2441
|
+
const layer: LayerSettings = map.layersCollection[layerIndex] as LayerSettings;
|
|
2442
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2443
|
+
const shapeData: any = layer.layerData[shapeIndex]['property'];
|
|
2444
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2445
|
+
let data: any;
|
|
2446
|
+
if (layer.dataSource) {
|
|
2447
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2448
|
+
data = layer.dataSource[checkShapeDataFields(<any[]>layer.dataSource, shapeData, layer.shapeDataPath, layer.shapePropertyPath,
|
|
2449
|
+
layer)];
|
|
2450
|
+
}
|
|
2451
|
+
return { shapeData: shapeData, data: data };
|
|
2452
|
+
}
|
|
2453
|
+
/**
|
|
2454
|
+
* Function to trigger shapeSelected event
|
|
2455
|
+
*
|
|
2456
|
+
* @param {string} targetId - Specifies the target id
|
|
2457
|
+
* @param {SelectionSettingsModel} selection - Specifies the selection
|
|
2458
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
2459
|
+
* @param {string} eventName - Specifies the event name
|
|
2460
|
+
* @returns {IShapeSelectedEventArgs} - Returns the event args
|
|
2461
|
+
* @private
|
|
2462
|
+
*/
|
|
2463
|
+
export function triggerShapeEvent(
|
|
2464
|
+
targetId: string, selection: SelectionSettingsModel, maps: Maps, eventName: string
|
|
2465
|
+
): IShapeSelectedEventArgs {
|
|
2466
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2467
|
+
const shape: { shapeData: any, data: any } = getShapeData(targetId, maps);
|
|
2468
|
+
const border: BorderModel = {
|
|
2469
|
+
color: selection.border.color, opacity: selection.border.opacity,
|
|
2470
|
+
width: selection.border.width
|
|
2471
|
+
};
|
|
2472
|
+
const eventArgs: IShapeSelectedEventArgs = (selection.enableMultiSelect) ? {
|
|
2473
|
+
cancel: false,
|
|
2474
|
+
name: eventName,
|
|
2475
|
+
fill: selection.fill,
|
|
2476
|
+
opacity: selection.opacity,
|
|
2477
|
+
border: border,
|
|
2478
|
+
shapeData: shape.shapeData,
|
|
2479
|
+
data: shape.data,
|
|
2480
|
+
target: targetId,
|
|
2481
|
+
maps: maps,
|
|
2482
|
+
shapeDataCollection: maps.shapeSelectionItem
|
|
2483
|
+
} : {
|
|
2484
|
+
cancel: false,
|
|
2485
|
+
name: eventName,
|
|
2486
|
+
fill: selection.fill,
|
|
2487
|
+
opacity: selection.opacity,
|
|
2488
|
+
border: border,
|
|
2489
|
+
shapeData: shape.shapeData,
|
|
2490
|
+
data: shape.data,
|
|
2491
|
+
target: targetId,
|
|
2492
|
+
maps: maps
|
|
2493
|
+
};
|
|
2494
|
+
maps.trigger(eventName, eventArgs, (observedArgs: IShapeSelectedEventArgs) => {
|
|
2495
|
+
eventArgs.border.opacity = isNullOrUndefined(eventArgs.border.opacity) ? eventArgs.opacity : eventArgs.border.opacity;
|
|
2496
|
+
});
|
|
2497
|
+
return eventArgs;
|
|
2498
|
+
}
|
|
2499
|
+
|
|
2500
|
+
/**
|
|
2501
|
+
* Function to get elements using class name
|
|
2502
|
+
*
|
|
2503
|
+
* @param {string} className - Specifies the class name
|
|
2504
|
+
* @returns {HTMLCollectionOf<Element>} - Returns the collection
|
|
2505
|
+
*/
|
|
2506
|
+
export function getElementsByClassName(className: string): HTMLCollectionOf<Element> {
|
|
2507
|
+
return document.getElementsByClassName(className);
|
|
2508
|
+
}
|
|
2509
|
+
/**
|
|
2510
|
+
* Function to get elements using querySelectorAll
|
|
2511
|
+
*/
|
|
2512
|
+
// export function querySelectorAll(args: string, element: Element): ArrayOf<Element> {
|
|
2513
|
+
// return element.querySelectorAll('.' + args);
|
|
2514
|
+
// }
|
|
2515
|
+
/**
|
|
2516
|
+
* Function to get elements using querySelector
|
|
2517
|
+
*
|
|
2518
|
+
* @param {string} args - Specifies the args
|
|
2519
|
+
* @param {string} elementSelector - Specifies the element selector
|
|
2520
|
+
* @returns {Element} - Returns the element
|
|
2521
|
+
*/
|
|
2522
|
+
export function querySelector(args: string, elementSelector: string): Element {
|
|
2523
|
+
let targetEle: Element = null;
|
|
2524
|
+
if (document.getElementById(elementSelector)) {
|
|
2525
|
+
targetEle = document.getElementById(elementSelector).querySelector('#' + args);
|
|
2526
|
+
}
|
|
2527
|
+
return targetEle;
|
|
2528
|
+
}
|
|
2529
|
+
/**
|
|
2530
|
+
* Function to get the element for selection and highlight using public method
|
|
2531
|
+
*
|
|
2532
|
+
* @param {number} layerIndex - Specifies the layer index
|
|
2533
|
+
* @param {string} name - Specifies the layer name
|
|
2534
|
+
* @param {boolean} enable - Specifies the boolean value
|
|
2535
|
+
* @param {Maps} map - Specifies the instance of the maps
|
|
2536
|
+
* @returns {Element} - Returns the element
|
|
2537
|
+
*/
|
|
2538
|
+
export function getTargetElement(layerIndex: number, name: string, enable: boolean, map: Maps): Element {
|
|
2539
|
+
let shapeIndex: number;
|
|
2540
|
+
let targetId: string;
|
|
2541
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2542
|
+
const shapeData: any[] = <any[]>map.layers[layerIndex].shapeData['features'];
|
|
2543
|
+
for (let i: number = 0; i < shapeData.length; i++) {
|
|
2544
|
+
if (shapeData[i]['properties'].name === name) {
|
|
2545
|
+
targetId = map.element.id + '_' + 'LayerIndex_' + layerIndex + '_shapeIndex_' + i + '_dataIndex_undefined';
|
|
2546
|
+
break;
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
const targetEle: Element = getElement(targetId);
|
|
2550
|
+
return targetEle;
|
|
2551
|
+
}
|
|
2552
|
+
/**
|
|
2553
|
+
* Function to create style element for highlight and selection
|
|
2554
|
+
*
|
|
2555
|
+
* @param {string} id - Specifies the id
|
|
2556
|
+
* @param {string} className - Specifies the class name
|
|
2557
|
+
* @param {IShapeSelectedEventArgs | any} eventArgs - Specifies the event args
|
|
2558
|
+
* @returns {Element} - Returns the element
|
|
2559
|
+
*/
|
|
2560
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2561
|
+
export function createStyle(id: string, className: string, eventArgs: IShapeSelectedEventArgs | any): Element {
|
|
2562
|
+
return createElement('style', {
|
|
2563
|
+
id: id, innerHTML: '.' + className + '{fill:'
|
|
2564
|
+
+ eventArgs['fill'] + ';' + 'fill-opacity:' + (eventArgs['opacity']).toString() + ';' +
|
|
2565
|
+
'stroke-opacity:' + (eventArgs['border']['opacity']).toString() + ';' +
|
|
2566
|
+
'stroke-width:' + (eventArgs['border']['width']).toString() + ';' +
|
|
2567
|
+
'stroke:' + eventArgs['border']['color'] + ';' + '}'
|
|
2568
|
+
});
|
|
2569
|
+
}
|
|
2570
|
+
/**
|
|
2571
|
+
* Function to customize the style for highlight and selection
|
|
2572
|
+
*
|
|
2573
|
+
* @param {string} id - Specifies the id
|
|
2574
|
+
* @param {string} className - Specifies the class name
|
|
2575
|
+
* @param {IShapeSelectedEventArgs | any} eventArgs - Specifies the event args
|
|
2576
|
+
* @returns {void}
|
|
2577
|
+
*/
|
|
2578
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2579
|
+
export function customizeStyle(id: string, className: string, eventArgs: IShapeSelectedEventArgs | any): void {
|
|
2580
|
+
const styleEle: Element = getElement(id);
|
|
2581
|
+
if (!isNullOrUndefined(styleEle)) {
|
|
2582
|
+
styleEle.innerHTML = '.' + className + '{fill:'
|
|
2583
|
+
+ eventArgs['fill'] + ';' + 'fill-opacity:' + (eventArgs['opacity']).toString() + ';' +
|
|
2584
|
+
'stroke-width:' + (eventArgs['border']['width']).toString() + ';' +
|
|
2585
|
+
'stroke-opacity:' + (eventArgs['border']['opacity']).toString() + ';' +
|
|
2586
|
+
'stroke:' + eventArgs['border']['color'] + '}';
|
|
2587
|
+
}
|
|
2588
|
+
}
|
|
2589
|
+
|
|
2590
|
+
/**
|
|
2591
|
+
* Function to trigger itemSelection event for legend selection and public method
|
|
2592
|
+
*
|
|
2593
|
+
* @param {SelectionSettingsModel} selectionSettings - Specifies the selection settings
|
|
2594
|
+
* @param {Maps} map - Specifies the instance of the maps
|
|
2595
|
+
* @param {Element} targetElement - Specifies the target element
|
|
2596
|
+
* @param {any} shapeData - Specifies the shape data
|
|
2597
|
+
* @param {any} data - Specifies the data
|
|
2598
|
+
* @returns {void}
|
|
2599
|
+
*/
|
|
2600
|
+
export function triggerItemSelectionEvent(selectionSettings: SelectionSettingsModel, map: Maps, targetElement: Element,
|
|
2601
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2602
|
+
shapeData: any, data: any): void {
|
|
2603
|
+
const border: BorderModel = {
|
|
2604
|
+
color: selectionSettings.border.color,
|
|
2605
|
+
width: selectionSettings.border.width / map.scale,
|
|
2606
|
+
opacity: selectionSettings.border.opacity
|
|
2607
|
+
};
|
|
2608
|
+
const eventArgs: ISelectionEventArgs = {
|
|
2609
|
+
opacity: selectionSettings.opacity,
|
|
2610
|
+
fill: selectionSettings.fill,
|
|
2611
|
+
border: border,
|
|
2612
|
+
name: itemSelection,
|
|
2613
|
+
target: targetElement.id,
|
|
2614
|
+
cancel: false,
|
|
2615
|
+
shapeData: shapeData,
|
|
2616
|
+
data: data,
|
|
2617
|
+
maps: map
|
|
2618
|
+
};
|
|
2619
|
+
map.trigger('itemSelection', eventArgs, (observedArgs: ISelectionEventArgs) => {
|
|
2620
|
+
eventArgs.border.opacity = isNullOrUndefined(selectionSettings.border.opacity) ? selectionSettings.opacity : selectionSettings.border.opacity;
|
|
2621
|
+
map.shapeSelectionItem.push(eventArgs.shapeData);
|
|
2622
|
+
if (!getElement('ShapeselectionMap')) {
|
|
2623
|
+
document.body.appendChild(createStyle('ShapeselectionMap',
|
|
2624
|
+
'ShapeselectionMapStyle', eventArgs));
|
|
2625
|
+
} else {
|
|
2626
|
+
customizeStyle('ShapeselectionMap', 'ShapeselectionMapStyle', eventArgs);
|
|
2627
|
+
}
|
|
2628
|
+
});
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
/**
|
|
2632
|
+
* Function to remove class from element
|
|
2633
|
+
*
|
|
2634
|
+
* @param {Element} element - Specifies the element
|
|
2635
|
+
* @returns {void}
|
|
2636
|
+
*/
|
|
2637
|
+
export function removeClass(element: Element): void {
|
|
2638
|
+
element.removeAttribute('class');
|
|
2639
|
+
}
|
|
2640
|
+
/**
|
|
2641
|
+
* Animation Effect Calculation End
|
|
2642
|
+
*
|
|
2643
|
+
* @param {Element} element - Specifies the element
|
|
2644
|
+
* @param {number} delay - Specifies the delay
|
|
2645
|
+
* @param {number} duration - Specifies the duration
|
|
2646
|
+
* @param {MapLocation} point - Specifies the location
|
|
2647
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
2648
|
+
* @param {string} ele - Specifies the element
|
|
2649
|
+
* @param {number} radius - Specifies the radius
|
|
2650
|
+
* @returns {void}
|
|
2651
|
+
* @private
|
|
2652
|
+
*/
|
|
2653
|
+
export function elementAnimate(
|
|
2654
|
+
element: Element, delay: number, duration: number, point: MapLocation, maps: Maps,
|
|
2655
|
+
ele?: string, radius: number = 0
|
|
2656
|
+
): void {
|
|
2657
|
+
const centerX: number = point.x;
|
|
2658
|
+
const centerY: number = point.y;
|
|
2659
|
+
let height: number = 0;
|
|
2660
|
+
const transform: string = element.getAttribute('transform') || '';
|
|
2661
|
+
new Animation({}).animate(<HTMLElement>element, {
|
|
2662
|
+
duration: duration,
|
|
2663
|
+
delay: delay,
|
|
2664
|
+
progress: (args: AnimationOptions): void => {
|
|
2665
|
+
if (args.timeStamp > args.delay) {
|
|
2666
|
+
if (maps.isTileMap && height === 0) {
|
|
2667
|
+
const layerGroupElement: HTMLElement = document.querySelector('.GroupElement') as HTMLElement;
|
|
2668
|
+
if (!isNullOrUndefined(layerGroupElement)) {
|
|
2669
|
+
layerGroupElement.style.display = 'block';
|
|
2670
|
+
}
|
|
2671
|
+
}
|
|
2672
|
+
height = ((args.timeStamp - args.delay) / args.duration);
|
|
2673
|
+
element.setAttribute('transform', 'translate( ' + (centerX - (radius * height)) + ' ' + (centerY - (radius * height)) +
|
|
2674
|
+
' ) scale(' + height + ')');
|
|
2675
|
+
}
|
|
2676
|
+
},
|
|
2677
|
+
end: (model: AnimationOptions) => {
|
|
2678
|
+
|
|
2679
|
+
element.setAttribute('transform', transform);
|
|
2680
|
+
if (!ele) {
|
|
2681
|
+
return;
|
|
2682
|
+
}
|
|
2683
|
+
const event: IAnimationCompleteEventArgs = {
|
|
2684
|
+
cancel: false, name: animationComplete, element: ele, maps: maps
|
|
2685
|
+
};
|
|
2686
|
+
maps.trigger(animationComplete, event);
|
|
2687
|
+
}
|
|
2688
|
+
});
|
|
2689
|
+
}
|
|
2690
|
+
|
|
2691
|
+
/**
|
|
2692
|
+
* @param {string} id - Specifies the id
|
|
2693
|
+
* @returns {void}
|
|
2694
|
+
*/
|
|
2695
|
+
export function timeout(id: string): void {
|
|
2696
|
+
removeElement(id);
|
|
2697
|
+
}
|
|
2698
|
+
|
|
2699
|
+
/**
|
|
2700
|
+
* @param {string} text - Specifies the text
|
|
2701
|
+
* @param {string} size - Specifies the size
|
|
2702
|
+
* @param {number} x - Specifies the x value
|
|
2703
|
+
* @param {number} y - Specifies the y value
|
|
2704
|
+
* @param {number} areaWidth - Specifies the area width
|
|
2705
|
+
* @param {number} areaHeight - Specifies the area height
|
|
2706
|
+
* @param {string} id - Specifies the id
|
|
2707
|
+
* @param {Element} element - Specifies the element
|
|
2708
|
+
* @param {boolean} isTouch - Specifies the boolean value
|
|
2709
|
+
* @returns {void}
|
|
2710
|
+
*/
|
|
2711
|
+
export function showTooltip(
|
|
2712
|
+
text: string, size: string, x: number, y: number, areaWidth: number, areaHeight: number, id: string, element: Element,
|
|
2713
|
+
isTouch?: boolean
|
|
2714
|
+
): void {
|
|
2715
|
+
const location: MapLocation = getMousePosition(x, y, element);
|
|
2716
|
+
if (!isNullOrUndefined(location)) {
|
|
2717
|
+
x = location.x;
|
|
2718
|
+
y = location.y;
|
|
2719
|
+
}
|
|
2720
|
+
let tooltip: HTMLElement = document.getElementById(id);
|
|
2721
|
+
let width: number = measureText(text, {
|
|
2722
|
+
fontFamily: 'Segoe UI', size: '8px',
|
|
2723
|
+
fontStyle: 'Normal', fontWeight: 'Regular'
|
|
2724
|
+
}).width;
|
|
2725
|
+
const str: string[] = text.split(' ');
|
|
2726
|
+
let demo: number = str[0].length;
|
|
2727
|
+
for (let i: number = 1; i < str.length; i++) {
|
|
2728
|
+
if (demo < str[i].length) {
|
|
2729
|
+
demo = str[i].length;
|
|
2730
|
+
}
|
|
2731
|
+
}
|
|
2732
|
+
if (!tooltip) {
|
|
2733
|
+
tooltip = createElement('div', {
|
|
2734
|
+
id: id,
|
|
2735
|
+
styles: 'background-color: rgb(255, 255, 255) !important; color:black !important; ' +
|
|
2736
|
+
'position:absolute;border:1px solid rgb(0, 0, 0); padding-left:5px;' +
|
|
2737
|
+
'font-size:12px; font-family: "Segoe UI"; text-align:center'
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
if (x < (areaWidth - width)) {
|
|
2741
|
+
// eslint-disable-next-line no-self-assign
|
|
2742
|
+
x = x;
|
|
2743
|
+
} else if (x > (areaWidth - width) && x < areaWidth - (demo * 8)) {
|
|
2744
|
+
width = (areaWidth - x);
|
|
2745
|
+
} else if (x >= areaWidth - demo * 8) {
|
|
2746
|
+
if (x > width) {
|
|
2747
|
+
x = x - width;
|
|
2748
|
+
} else {
|
|
2749
|
+
width = x;
|
|
2750
|
+
x = 0;
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
const size1: string[] = size.split('px');
|
|
2754
|
+
wordWrap(tooltip, text, x, y, size1, width, areaWidth, element);
|
|
2755
|
+
const height: number = tooltip.clientHeight;
|
|
2756
|
+
if ((height + parseInt(size1[0], 10) * 2) > areaHeight) {
|
|
2757
|
+
width = x;
|
|
2758
|
+
x = 0;
|
|
2759
|
+
}
|
|
2760
|
+
wordWrap(tooltip, text, x, y, size1, width, areaWidth, element);
|
|
2761
|
+
if (isTouch) {
|
|
2762
|
+
setTimeout(timeout, 5000, id);
|
|
2763
|
+
}
|
|
2764
|
+
}
|
|
2765
|
+
|
|
2766
|
+
/**
|
|
2767
|
+
* @param {HTMLElement} tooltip - Specifies the tooltip element
|
|
2768
|
+
* @param {string} text - Specifies the text
|
|
2769
|
+
* @param {number} x - Specifies the x value
|
|
2770
|
+
* @param {number} y - Specifies the y value
|
|
2771
|
+
* @param {string[]} size1 - Specifies the size
|
|
2772
|
+
* @param {number} width - Specifies the width
|
|
2773
|
+
* @param {number} areaWidth - Specifies the area width
|
|
2774
|
+
* @param {Element} element - Specifies the element
|
|
2775
|
+
* @returns {void}
|
|
2776
|
+
*/
|
|
2777
|
+
export function wordWrap(
|
|
2778
|
+
tooltip: HTMLElement, text: string, x: number, y: number, size1: string[], width: number,
|
|
2779
|
+
areaWidth: number, element: Element
|
|
2780
|
+
): void {
|
|
2781
|
+
tooltip.innerHTML = text;
|
|
2782
|
+
tooltip.style.top = tooltip.id.indexOf('_Legend') !== -1 ?
|
|
2783
|
+
(parseInt(size1[0], 10) + y).toString() + 'px' : (parseInt(size1[0], 10) * 2).toString() + 'px';
|
|
2784
|
+
tooltip.style.left = (x).toString() + 'px';
|
|
2785
|
+
tooltip.style.width = width.toString() + 'px';
|
|
2786
|
+
tooltip.style.maxWidth = (areaWidth).toString() + 'px';
|
|
2787
|
+
tooltip.style.wordWrap = 'break-word';
|
|
2788
|
+
element.appendChild(tooltip);
|
|
2789
|
+
}
|
|
2790
|
+
// /**
|
|
2791
|
+
// *
|
|
2792
|
+
// * @param touchList
|
|
2793
|
+
// * @param e
|
|
2794
|
+
// * @param touches
|
|
2795
|
+
// */
|
|
2796
|
+
// export function addTouchPointer(touchList: ITouches[], e: PointerEvent, touches: TouchList): ITouches[] {
|
|
2797
|
+
// if (touches) {
|
|
2798
|
+
// touchList = [];
|
|
2799
|
+
// for (let i: number = 0, length: number = touches.length; i < length; i++) {
|
|
2800
|
+
// touchList.push({ pageX: touches[i].clientX, pageY: touches[i].clientY, pointerId: null });
|
|
2801
|
+
// }
|
|
2802
|
+
// } else {
|
|
2803
|
+
// touchList = touchList ? touchList : [];
|
|
2804
|
+
// if (touchList.length === 0) {
|
|
2805
|
+
// touchList.push({ pageX: e.clientX, pageY: e.clientY, pointerId: e.pointerId });
|
|
2806
|
+
// } else {
|
|
2807
|
+
// for (let i: number = 0, length: number = touchList.length; i < length; i++) {
|
|
2808
|
+
// if (touchList[i].pointerId === e.pointerId) {
|
|
2809
|
+
// touchList[i] = { pageX: e.clientX, pageY: e.clientY, pointerId: e.pointerId };
|
|
2810
|
+
// } else {
|
|
2811
|
+
// touchList.push({ pageX: e.clientX, pageY: e.clientY, pointerId: e.pointerId });
|
|
2812
|
+
// }
|
|
2813
|
+
// }
|
|
2814
|
+
// }
|
|
2815
|
+
// }
|
|
2816
|
+
// return touchList;
|
|
2817
|
+
// }
|
|
2818
|
+
|
|
2819
|
+
/**
|
|
2820
|
+
* @param {string} id - Specifies the id
|
|
2821
|
+
* @param {string} text - Specifies the text
|
|
2822
|
+
* @param {string} top - Specifies the top
|
|
2823
|
+
* @param {string} left - Specifies the left
|
|
2824
|
+
* @param {string} fontSize - Specifies the fontSize
|
|
2825
|
+
* @returns {void}
|
|
2826
|
+
* @private
|
|
2827
|
+
*/
|
|
2828
|
+
export function createTooltip(id: string, text: string, top: number, left: number, fontSize: string): void {
|
|
2829
|
+
let tooltip: HTMLElement = getElement(id) as HTMLElement;
|
|
2830
|
+
const style: string = 'top:' + top.toString() + 'px;' +
|
|
2831
|
+
'left:' + left.toString() + 'px;' +
|
|
2832
|
+
'color: #000000; ' +
|
|
2833
|
+
'background:' + '#FFFFFF' + ';' +
|
|
2834
|
+
'z-index: 2;' +
|
|
2835
|
+
'position:absolute;border:1px solid #707070;font-size:' + fontSize + ';border-radius:2px;';
|
|
2836
|
+
if (!tooltip) {
|
|
2837
|
+
tooltip = createElement('div', {
|
|
2838
|
+
id: id, innerHTML: ' ' + text + ' ', styles: style
|
|
2839
|
+
});
|
|
2840
|
+
document.body.appendChild(tooltip);
|
|
2841
|
+
} else {
|
|
2842
|
+
tooltip.setAttribute('innerHTML', ' ' + text + ' ');
|
|
2843
|
+
tooltip.setAttribute('styles', style);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
|
|
2847
|
+
/**
|
|
2848
|
+
* @param {Point} location - Specifies the location
|
|
2849
|
+
* @param {string} shape - Specifies the shape
|
|
2850
|
+
* @param {Size} size - Specifies the size
|
|
2851
|
+
* @param {string} url - Specifies the url
|
|
2852
|
+
* @param {PathOption} options - Specifies the options
|
|
2853
|
+
* @returns {Element} - Returns the element
|
|
2854
|
+
* @private
|
|
2855
|
+
*/
|
|
2856
|
+
export function drawSymbol(location: Point, shape: string, size: Size, url: string, options: PathOption): Element {
|
|
2857
|
+
const functionName: string = 'Path';
|
|
2858
|
+
const renderer: SvgRenderer = new SvgRenderer('');
|
|
2859
|
+
const temp: IShapes = renderLegendShape(location, size, shape, options, url);
|
|
2860
|
+
const htmlObject: Element = renderer['draw' + temp.functionName](temp.renderOption);
|
|
2861
|
+
return htmlObject;
|
|
2862
|
+
}
|
|
2863
|
+
|
|
2864
|
+
|
|
2865
|
+
/**
|
|
2866
|
+
* @param {MapLocation} location - Specifies the location
|
|
2867
|
+
* @param {Size} size - Specifies the size
|
|
2868
|
+
* @param {string} shape - Specifies the shape
|
|
2869
|
+
* @param {PathOption} options - Specifies the path options
|
|
2870
|
+
* @param {string} url - Specifies the url
|
|
2871
|
+
* @returns {IShapes} - Returns the shapes
|
|
2872
|
+
* @private
|
|
2873
|
+
*/
|
|
2874
|
+
export function renderLegendShape(location: MapLocation, size: Size, shape: string, options: PathOption, url: string): IShapes {
|
|
2875
|
+
let renderPath: string;
|
|
2876
|
+
let functionName: string = 'Path';
|
|
2877
|
+
const shapeWidth: number = size.width;
|
|
2878
|
+
const shapeHeight: number = size.height;
|
|
2879
|
+
const shapeX: number = location.x;
|
|
2880
|
+
const shapeY: number = location.y;
|
|
2881
|
+
const x: number = location.x + (-shapeWidth / 2);
|
|
2882
|
+
const y: number = location.y + (-shapeHeight / 2);
|
|
2883
|
+
options['stroke'] = (shape === 'HorizontalLine' || shape === 'VerticalLine' || shape === 'Cross') ? options['fill'] : options['stroke'];
|
|
2884
|
+
options['stroke-width'] = (options['stroke-width'] === 0 && (shape === 'HorizontalLine' || shape === 'VerticalLine' || shape === 'Cross')) ? 1: options['stroke-width'];
|
|
2885
|
+
switch (shape) {
|
|
2886
|
+
case 'Circle':
|
|
2887
|
+
case 'Bubble':
|
|
2888
|
+
functionName = 'Ellipse';
|
|
2889
|
+
merge(options, { 'rx': shapeWidth / 2, 'ry': shapeHeight / 2, 'cx': shapeX, 'cy': shapeY });
|
|
2890
|
+
break;
|
|
2891
|
+
case 'VerticalLine':
|
|
2892
|
+
renderPath = 'M' + ' ' + shapeX + ' ' + (shapeY + (shapeHeight / 2)) + ' ' + 'L' + ' ' + shapeX + ' '
|
|
2893
|
+
+ (shapeY + (-shapeHeight / 2));
|
|
2894
|
+
merge(options, { 'd': renderPath });
|
|
2895
|
+
break;
|
|
2896
|
+
case 'HorizontalLine':
|
|
2897
|
+
renderPath = 'M' + ' ' + shapeX + ' ' + shapeY + ' ' + 'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' '
|
|
2898
|
+
+ shapeY;
|
|
2899
|
+
merge(options, { 'd': renderPath });
|
|
2900
|
+
break;
|
|
2901
|
+
case 'Diamond':
|
|
2902
|
+
renderPath = 'M' + ' ' + x + ' ' + shapeY + ' ' +
|
|
2903
|
+
'L' + ' ' + shapeX + ' ' + (shapeY + (-shapeHeight / 2)) + ' ' +
|
|
2904
|
+
'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + shapeY + ' ' +
|
|
2905
|
+
'L' + ' ' + shapeX + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2906
|
+
'L' + ' ' + x + ' ' + shapeY + ' z';
|
|
2907
|
+
merge(options, { 'd': renderPath });
|
|
2908
|
+
break;
|
|
2909
|
+
case 'Rectangle':
|
|
2910
|
+
renderPath = 'M' + ' ' + x + ' ' + (shapeY + (-shapeHeight / 2)) + ' ' +
|
|
2911
|
+
'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + (shapeY + (-shapeHeight / 2)) + ' ' +
|
|
2912
|
+
'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2913
|
+
'L' + ' ' + x + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2914
|
+
'L' + ' ' + x + ' ' + (shapeY + (-shapeHeight / 2)) + ' z';
|
|
2915
|
+
merge(options, { 'd': renderPath });
|
|
2916
|
+
break;
|
|
2917
|
+
case 'Triangle':
|
|
2918
|
+
renderPath = 'M' + ' ' + x + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2919
|
+
'L' + ' ' + shapeX + ' ' + (shapeY + (-shapeHeight / 2)) + ' ' +
|
|
2920
|
+
'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2921
|
+
'L' + ' ' + x + ' ' + (shapeY + (shapeHeight / 2)) + ' z';
|
|
2922
|
+
merge(options, { 'd': renderPath });
|
|
2923
|
+
break;
|
|
2924
|
+
case 'InvertedTriangle':
|
|
2925
|
+
renderPath = 'M' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + (shapeY - (shapeHeight / 2)) + ' ' +
|
|
2926
|
+
'L' + ' ' + shapeX + ' ' + (shapeY + (shapeHeight / 2)) + ' ' +
|
|
2927
|
+
'L' + ' ' + (shapeX - (shapeWidth / 2)) + ' ' + (shapeY - (shapeHeight / 2)) + ' ' +
|
|
2928
|
+
'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + (shapeY - (shapeHeight / 2)) + ' z';
|
|
2929
|
+
merge(options, { 'd': renderPath });
|
|
2930
|
+
break;
|
|
2931
|
+
case 'Pentagon':
|
|
2932
|
+
// eslint-disable-next-line no-case-declarations
|
|
2933
|
+
const eq: number = 72; let xValue: number; let yValue: number;
|
|
2934
|
+
for (let i: number = 0; i <= 5; i++) {
|
|
2935
|
+
xValue = (shapeWidth / 2) * Math.cos((Math.PI / 180) * (i * eq));
|
|
2936
|
+
yValue = (shapeWidth / 2) * Math.sin((Math.PI / 180) * (i * eq));
|
|
2937
|
+
if (i === 0) {
|
|
2938
|
+
renderPath = 'M' + ' ' + (shapeX + xValue) + ' ' + (shapeY + yValue) + ' ';
|
|
2939
|
+
} else {
|
|
2940
|
+
renderPath = renderPath.concat('L' + ' ' + (shapeX + xValue) + ' ' + (shapeY + yValue) + ' ');
|
|
2941
|
+
}
|
|
2942
|
+
}
|
|
2943
|
+
renderPath = renderPath.concat('Z');
|
|
2944
|
+
merge(options, { 'd': renderPath });
|
|
2945
|
+
break;
|
|
2946
|
+
case 'Star':
|
|
2947
|
+
renderPath = 'M ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + (location.x - size.width / 2)
|
|
2948
|
+
+ ' ' + (location.y + size.height / 6) + ' L ' + (location.x + size.width / 2) + ' ' + (location.y + size.height / 6)
|
|
2949
|
+
+ ' L ' + (location.x - size.width / 3) + ' ' + (location.y - size.height / 2) + ' L ' + location.x + ' ' +
|
|
2950
|
+
(location.y + size.height / 2) + ' L ' + (location.x + size.width / 3) + ' ' + (location.y - size.height / 2) + ' Z';
|
|
2951
|
+
merge(options, { 'd': renderPath });
|
|
2952
|
+
break;
|
|
2953
|
+
case 'Cross':
|
|
2954
|
+
renderPath = 'M' + ' ' + x + ' ' + shapeY + ' ' + 'L' + ' ' + (shapeX + (shapeWidth / 2)) + ' ' + shapeY + ' ' +
|
|
2955
|
+
'M' + ' ' + shapeX + ' ' + (shapeY + (shapeHeight / 2)) + ' ' + 'L' + ' ' + shapeX + ' ' +
|
|
2956
|
+
(shapeY + (-shapeHeight / 2));
|
|
2957
|
+
merge(options, { 'd': renderPath });
|
|
2958
|
+
break;
|
|
2959
|
+
case 'Image':
|
|
2960
|
+
functionName = 'Image';
|
|
2961
|
+
merge(options, { 'href': url, 'height': shapeHeight, 'width': shapeWidth, x: x, y: y });
|
|
2962
|
+
break;
|
|
2963
|
+
}
|
|
2964
|
+
return { renderOption: options, functionName: functionName };
|
|
2965
|
+
}
|
|
2966
|
+
/**
|
|
2967
|
+
* Animation Effect Calculation End
|
|
2968
|
+
*
|
|
2969
|
+
* @private
|
|
2970
|
+
*/
|
|
2971
|
+
|
|
2972
|
+
// export function markerTemplateAnimate(element: Element, delay: number, duration: number, point: MapLocation): void {
|
|
2973
|
+
// let delta: number = 0;
|
|
2974
|
+
// let top: string = (element as HTMLElement).style.top;
|
|
2975
|
+
// let y: number = parseInt(top, 10);
|
|
2976
|
+
// new Animation({}).animate(<HTMLElement>element, {
|
|
2977
|
+
// duration: duration,
|
|
2978
|
+
// delay: delay,
|
|
2979
|
+
// progress: (args: AnimationOptions): void => {
|
|
2980
|
+
// if (args.timeStamp > args.delay) {
|
|
2981
|
+
// delta = ((args.timeStamp - args.delay) / args.duration);
|
|
2982
|
+
// (element as HTMLElement).style.top = y - 100 + (delta * 100) + 'px';
|
|
2983
|
+
// }
|
|
2984
|
+
// },
|
|
2985
|
+
// end: (model: AnimationOptions) => {
|
|
2986
|
+
// (element as HTMLElement).style.top = top;
|
|
2987
|
+
// }
|
|
2988
|
+
// });
|
|
2989
|
+
// }
|
|
2990
|
+
|
|
2991
|
+
/**
|
|
2992
|
+
* @param {HTMLElement} childElement - Specifies the child element
|
|
2993
|
+
* @param {HTMLElement} parentElement - Specifies the parent element
|
|
2994
|
+
* @returns {Size} - Returns the size
|
|
2995
|
+
* @private
|
|
2996
|
+
*/
|
|
2997
|
+
export function getElementOffset(childElement: HTMLElement, parentElement: HTMLElement): Size {
|
|
2998
|
+
parentElement.appendChild(childElement);
|
|
2999
|
+
const width: number = childElement.offsetWidth;
|
|
3000
|
+
const height: number = childElement.offsetHeight;
|
|
3001
|
+
parentElement.removeChild(childElement);
|
|
3002
|
+
return new Size(width, height);
|
|
3003
|
+
}
|
|
3004
|
+
|
|
3005
|
+
/**
|
|
3006
|
+
* @param {Element} element - Specifies the element
|
|
3007
|
+
* @param {number} index - Specifies the element
|
|
3008
|
+
* @param {number} scale - Specifies the scale
|
|
3009
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
3010
|
+
* @returns {void}
|
|
3011
|
+
* @private
|
|
3012
|
+
*/
|
|
3013
|
+
export function changeBorderWidth(element: Element, index: number, scale: number, maps: Maps): void {
|
|
3014
|
+
let childNode: HTMLElement;
|
|
3015
|
+
for (let l: number = 0; l < element.childElementCount; l++) {
|
|
3016
|
+
childNode = element.childNodes[l] as HTMLElement;
|
|
3017
|
+
if (childNode.id.indexOf('_NavigationGroup') > -1) {
|
|
3018
|
+
changeNavaigationLineWidth(childNode, index, scale, maps);
|
|
3019
|
+
} else {
|
|
3020
|
+
let currentStroke: number;
|
|
3021
|
+
let value: number = 0;
|
|
3022
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3023
|
+
const borderWidthValue: any = maps.layersCollection[index].shapeSettings.borderWidthValuePath;
|
|
3024
|
+
const borderWidth: number = (<LayerSettingsModel>maps.layersCollection[index]).shapeSettings.border.width;
|
|
3025
|
+
const circleRadius: number = (<LayerSettingsModel>maps.layersCollection[index]).shapeSettings.circleRadius;
|
|
3026
|
+
if (maps.layersCollection[index].shapeSettings.borderWidthValuePath) {
|
|
3027
|
+
value = checkShapeDataFields(
|
|
3028
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3029
|
+
<any[]>maps.layersCollection[index].dataSource, maps.layersCollection[index].layerData[l]['property'],
|
|
3030
|
+
maps.layersCollection[index].shapeDataPath, maps.layersCollection[index].shapePropertyPath, maps.layersCollection[index]
|
|
3031
|
+
);
|
|
3032
|
+
if (value !== null) {
|
|
3033
|
+
if (maps.layersCollection[index].dataSource[value][borderWidthValue]) {
|
|
3034
|
+
currentStroke = maps.layersCollection[index].dataSource[value][borderWidthValue];
|
|
3035
|
+
} else {
|
|
3036
|
+
currentStroke = (isNullOrUndefined(borderWidth) ? 0 : borderWidth);
|
|
3037
|
+
}
|
|
3038
|
+
} else {
|
|
3039
|
+
currentStroke = (isNullOrUndefined(borderWidth) ? 0 : borderWidth);
|
|
3040
|
+
}
|
|
3041
|
+
} else {
|
|
3042
|
+
currentStroke = (isNullOrUndefined(borderWidth) ? 0 : borderWidth);
|
|
3043
|
+
}
|
|
3044
|
+
childNode.setAttribute('stroke-width', (currentStroke / scale).toString());
|
|
3045
|
+
if (element.id.indexOf('_Point') > -1 || element.id.indexOf('_MultiPoint') > -1) {
|
|
3046
|
+
childNode.setAttribute('r', (circleRadius / scale).toString());
|
|
3047
|
+
}
|
|
3048
|
+
}
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
/**
|
|
3053
|
+
* @param {Element} element - Specifies the element
|
|
3054
|
+
* @param {number} index - Specifies the element
|
|
3055
|
+
* @param {number} scale - Specifies the scale
|
|
3056
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
3057
|
+
* @returns {void}
|
|
3058
|
+
* @private
|
|
3059
|
+
*/
|
|
3060
|
+
export function changeNavaigationLineWidth(element: Element, index: number, scale: number, maps: Maps): void {
|
|
3061
|
+
let node: HTMLElement;
|
|
3062
|
+
for (let m: number = 0; m < element.childElementCount; m++) {
|
|
3063
|
+
node = element.childNodes[m] as HTMLElement;
|
|
3064
|
+
if (node.tagName === 'path') {
|
|
3065
|
+
const currentStroke: number = ((<LayerSettingsModel>maps.layersCollection[index])
|
|
3066
|
+
.navigationLineSettings[parseFloat(node.id.split('_NavigationIndex_')[1].split('_')[0])].width);
|
|
3067
|
+
node.setAttribute('stroke-width', (currentStroke / scale).toString());
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
|
|
3072
|
+
// /** Pinch zoom helper methods */
|
|
3073
|
+
|
|
3074
|
+
/**
|
|
3075
|
+
* @param {PointerEvent | TouchEvent} event - Specifies the pointer or touch event
|
|
3076
|
+
* @returns {ITouches[]} - Returns the target
|
|
3077
|
+
* @private */
|
|
3078
|
+
export function targetTouches(event: PointerEvent | TouchEvent): ITouches[] {
|
|
3079
|
+
const targetTouches: ITouches[] = [];
|
|
3080
|
+
const touches: TouchList = (<TouchEvent & PointerEvent>event).touches;
|
|
3081
|
+
for (let i: number = 0; i < touches.length; i++) {
|
|
3082
|
+
targetTouches.push({ pageX: touches[i].pageX, pageY: touches[i].pageY });
|
|
3083
|
+
}
|
|
3084
|
+
return targetTouches;
|
|
3085
|
+
}
|
|
3086
|
+
|
|
3087
|
+
/**
|
|
3088
|
+
* @param {ITouches[]} startTouches - Specifies the start touches
|
|
3089
|
+
* @param {ITouches[]} endTouches - Specifies the end touches
|
|
3090
|
+
* @returns {number} - Returns the number
|
|
3091
|
+
* @private
|
|
3092
|
+
*/
|
|
3093
|
+
export function calculateScale(startTouches: ITouches[], endTouches: ITouches[]): number {
|
|
3094
|
+
const startDistance: number = getDistance(startTouches[0], startTouches[1]);
|
|
3095
|
+
const endDistance: number = getDistance(endTouches[0], endTouches[1]);
|
|
3096
|
+
return (endDistance / startDistance);
|
|
3097
|
+
}
|
|
3098
|
+
|
|
3099
|
+
/**
|
|
3100
|
+
* @param {ITouches} a - Specifies the a value
|
|
3101
|
+
* @param {ITouches} b - Specifies the b value
|
|
3102
|
+
* @returns {number} - Returns the number
|
|
3103
|
+
* @private */
|
|
3104
|
+
export function getDistance(a: ITouches, b: ITouches): number {
|
|
3105
|
+
const x: number = a.pageX - b.pageX;
|
|
3106
|
+
const y: number = a.pageY - b.pageY;
|
|
3107
|
+
return Math.sqrt(x * x + y * y);
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
/**
|
|
3111
|
+
* @param {ITouches[]} touches - Specifies the touches
|
|
3112
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
3113
|
+
* @returns {any[]} - Returns the object
|
|
3114
|
+
* @private
|
|
3115
|
+
*/
|
|
3116
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3117
|
+
export function getTouches(touches: ITouches[], maps: Maps): any[] {
|
|
3118
|
+
const rect: ClientRect = maps.element.getBoundingClientRect();
|
|
3119
|
+
const posTop: number = rect.top + document.defaultView.pageXOffset;
|
|
3120
|
+
const posLeft: number = rect.left + document.defaultView.pageYOffset;
|
|
3121
|
+
return Array.prototype.slice.call(touches).map((touch: ITouches) => {
|
|
3122
|
+
return {
|
|
3123
|
+
x: touch.pageX - posLeft,
|
|
3124
|
+
y: touch.pageY - posTop
|
|
3125
|
+
};
|
|
3126
|
+
});
|
|
3127
|
+
}
|
|
3128
|
+
|
|
3129
|
+
/**
|
|
3130
|
+
* @param {any[]} touches - Specifies the touches
|
|
3131
|
+
* @returns {Point} - Returns the point
|
|
3132
|
+
* @private
|
|
3133
|
+
*/
|
|
3134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3135
|
+
export function getTouchCenter(touches: any[]): Point {
|
|
3136
|
+
return {
|
|
3137
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3138
|
+
x: touches.map((e: any) => { return e['x']; }).reduce(sum) / touches.length,
|
|
3139
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3140
|
+
y: touches.map((e: any) => { return e['y']; }).reduce(sum) / touches.length
|
|
3141
|
+
};
|
|
3142
|
+
}
|
|
3143
|
+
|
|
3144
|
+
/**
|
|
3145
|
+
* @param {number} a - Specifies a value
|
|
3146
|
+
* @param {number} b - Specifies b value
|
|
3147
|
+
* @returns {number} - Returns the sum of a and b
|
|
3148
|
+
* @private
|
|
3149
|
+
*/
|
|
3150
|
+
export function sum(a: number, b: number): number {
|
|
3151
|
+
return a + b;
|
|
3152
|
+
}
|
|
3153
|
+
|
|
3154
|
+
/**
|
|
3155
|
+
* Animation Effect Calculation End
|
|
3156
|
+
*
|
|
3157
|
+
* @param {Element} element - Specifies the element.
|
|
3158
|
+
* @param {number} delay - Specifies the delay.
|
|
3159
|
+
* @param {number} duration - Specifies the duration.
|
|
3160
|
+
* @param {MapLocation} point - Specifies the location.
|
|
3161
|
+
* @param {number} scale - Specifies the scale value.
|
|
3162
|
+
* @param {Size} size - Specifies the size.
|
|
3163
|
+
* @param {Maps} maps - Specifies the maps.
|
|
3164
|
+
* @returns {void}
|
|
3165
|
+
* @private
|
|
3166
|
+
*/
|
|
3167
|
+
export function zoomAnimate(
|
|
3168
|
+
element: Element, delay: number, duration: number, point: MapLocation, scale: number, size: Size,
|
|
3169
|
+
maps: Maps
|
|
3170
|
+
): void {
|
|
3171
|
+
let delta: number = 0;
|
|
3172
|
+
const previousLocation: MapLocation = maps.previousPoint;
|
|
3173
|
+
const preScale: number = maps.previousScale;
|
|
3174
|
+
const diffScale: number = scale - preScale;
|
|
3175
|
+
const currentLocation: MapLocation = new MapLocation(0, 0);
|
|
3176
|
+
let currentScale: number = 1;
|
|
3177
|
+
if (scale === preScale) {
|
|
3178
|
+
element.setAttribute('transform', 'scale( ' + (scale) + ' ) translate( ' + point.x + ' ' + point.y + ' )');
|
|
3179
|
+
return;
|
|
3180
|
+
}
|
|
3181
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3182
|
+
const slope: any = (previousLocation: MapLocation, point: MapLocation): number => {
|
|
3183
|
+
if (previousLocation.x === point.x) {
|
|
3184
|
+
return null;
|
|
3185
|
+
}
|
|
3186
|
+
return (point.y - previousLocation.y) / (point.x - previousLocation.x);
|
|
3187
|
+
};
|
|
3188
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3189
|
+
const intercept: any = (point: MapLocation, slopeValue: number): number => {
|
|
3190
|
+
if (slopeValue === null) {
|
|
3191
|
+
return point.x;
|
|
3192
|
+
}
|
|
3193
|
+
return point.y - slopeValue * point.x;
|
|
3194
|
+
};
|
|
3195
|
+
const slopeFactor: number = slope(previousLocation, point);
|
|
3196
|
+
const slopeIntersection: number = intercept(previousLocation, slopeFactor);
|
|
3197
|
+
const horizontalDifference: number = point.x - previousLocation.x;
|
|
3198
|
+
const verticalDifference: number = point.y - previousLocation.y;
|
|
3199
|
+
animate(
|
|
3200
|
+
<HTMLElement>element, delay, duration,
|
|
3201
|
+
(args: AnimationOptions): void => {
|
|
3202
|
+
if (args.timeStamp > args.delay) {
|
|
3203
|
+
delta = ((args.timeStamp - args.delay) / args.duration);
|
|
3204
|
+
currentScale = preScale + (delta * diffScale);
|
|
3205
|
+
currentLocation.x = previousLocation.x + (delta * horizontalDifference) / (currentScale / scale);
|
|
3206
|
+
if (slopeFactor == null) {
|
|
3207
|
+
currentLocation.y = previousLocation.y + (delta * verticalDifference);
|
|
3208
|
+
} else {
|
|
3209
|
+
currentLocation.y = ((slopeFactor * currentLocation.x) + slopeIntersection);
|
|
3210
|
+
}
|
|
3211
|
+
args.element.setAttribute('transform', 'scale( ' + currentScale + ' ) ' +
|
|
3212
|
+
'translate( ' + currentLocation.x + ' ' + currentLocation.y + ' )');
|
|
3213
|
+
maps.translatePoint = currentLocation;
|
|
3214
|
+
maps.scale = currentScale;
|
|
3215
|
+
maps.zoomModule.processTemplate(point.x, point.y, currentScale, maps);
|
|
3216
|
+
}
|
|
3217
|
+
},
|
|
3218
|
+
() => {
|
|
3219
|
+
maps.translatePoint = point;
|
|
3220
|
+
maps.scale = scale;
|
|
3221
|
+
element.setAttribute('transform', 'scale( ' + (scale) + ' ) translate( ' + point.x + ' ' + point.y + ' )');
|
|
3222
|
+
maps.zoomModule.processTemplate(point.x, point.y, scale, maps);
|
|
3223
|
+
}
|
|
3224
|
+
);
|
|
3225
|
+
}
|
|
3226
|
+
/**
|
|
3227
|
+
* To process custom animation
|
|
3228
|
+
*
|
|
3229
|
+
* @param {Element} element - Specifies the element
|
|
3230
|
+
* @param {number} delay - Specifies the delay
|
|
3231
|
+
* @param {number} duration - Specifies the duration
|
|
3232
|
+
* @param {Function} process - Specifies the process
|
|
3233
|
+
* @param {Function} end - Specifies the end
|
|
3234
|
+
* @returns {void}
|
|
3235
|
+
*/
|
|
3236
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3237
|
+
export function animate(element: Element, delay: number, duration: number, process: any, end: any): void {
|
|
3238
|
+
let start: number = null;
|
|
3239
|
+
// eslint-disable-next-line prefer-const
|
|
3240
|
+
let clearAnimation: number;
|
|
3241
|
+
const markerStyle: string = 'visibility:visible';
|
|
3242
|
+
const startAnimation: FrameRequestCallback = (timestamp: number) => {
|
|
3243
|
+
if (!start) { start = timestamp; }
|
|
3244
|
+
const progress: number = timestamp - start;
|
|
3245
|
+
if (progress < duration) {
|
|
3246
|
+
process.call(this, { element: element, delay: 0, timeStamp: progress, duration: duration });
|
|
3247
|
+
window.requestAnimationFrame(startAnimation);
|
|
3248
|
+
} else {
|
|
3249
|
+
window.cancelAnimationFrame(clearAnimation);
|
|
3250
|
+
end.call(this, { element: element });
|
|
3251
|
+
if (element.id.indexOf('Marker') > -1) {
|
|
3252
|
+
let markerElement: Element = getElementByID(element.id.split('_Layer')[0] + '_Markers_Group');
|
|
3253
|
+
markerElement.setAttribute('style', markerStyle);
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
};
|
|
3257
|
+
clearAnimation = window.requestAnimationFrame(startAnimation);
|
|
3258
|
+
}
|
|
3259
|
+
/**
|
|
3260
|
+
* To get shape data file using Ajax.
|
|
3261
|
+
*/
|
|
3262
|
+
export class MapAjax {
|
|
3263
|
+
/**
|
|
3264
|
+
* MapAjax data options
|
|
3265
|
+
*/
|
|
3266
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3267
|
+
public dataOptions: string | any;
|
|
3268
|
+
/**
|
|
3269
|
+
* MapAjax type value
|
|
3270
|
+
*/
|
|
3271
|
+
public type: string;
|
|
3272
|
+
/**
|
|
3273
|
+
* MapAjax async value
|
|
3274
|
+
*/
|
|
3275
|
+
public async: boolean;
|
|
3276
|
+
/**
|
|
3277
|
+
* MapAjax contentType value
|
|
3278
|
+
*/
|
|
3279
|
+
public contentType: string;
|
|
3280
|
+
/**
|
|
3281
|
+
* MapAjax sendData value
|
|
3282
|
+
*/
|
|
3283
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3284
|
+
public sendData: string | any;
|
|
3285
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3286
|
+
constructor(options: string | any, type?: string, async?: boolean, contentType?: string, sendData?: string | any) {
|
|
3287
|
+
this.dataOptions = options;
|
|
3288
|
+
this.type = type || 'GET';
|
|
3289
|
+
this.async = async || true;
|
|
3290
|
+
this.contentType = contentType;
|
|
3291
|
+
this.sendData = sendData;
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3295
|
+
/**
|
|
3296
|
+
* Animation Translate
|
|
3297
|
+
*
|
|
3298
|
+
* @param {Element} element - Specifies the element
|
|
3299
|
+
* @param {number} delay - Specifies the delay
|
|
3300
|
+
* @param {number} duration - Specifies the duration
|
|
3301
|
+
* @param {MapLocation} point - Specifies the location
|
|
3302
|
+
* @returns {void}
|
|
3303
|
+
* @private
|
|
3304
|
+
*/
|
|
3305
|
+
export function smoothTranslate(element: Element, delay: number, duration: number, point: MapLocation): void {
|
|
3306
|
+
let delta: number = 0;
|
|
3307
|
+
const transform: string[] = element.getAttribute('transform').split(' ');
|
|
3308
|
+
if (transform.length === 2) { transform[2] = transform[1].split(')')[0]; transform[1] = transform[0].split('(')[1]; }
|
|
3309
|
+
const previousLocation: MapLocation = new MapLocation(parseInt(transform[1], 10), parseInt(transform[2], 10));
|
|
3310
|
+
const diffx: number = point.x - previousLocation.x;
|
|
3311
|
+
const diffy: number = point.y - previousLocation.y;
|
|
3312
|
+
const currentLocation: MapLocation = new MapLocation(0, 0);
|
|
3313
|
+
animate(
|
|
3314
|
+
<HTMLElement>element, delay, duration, (args: AnimationOptions): void => {
|
|
3315
|
+
if (args.timeStamp > args.delay) {
|
|
3316
|
+
delta = ((args.timeStamp - args.delay) / args.duration);
|
|
3317
|
+
currentLocation.x = previousLocation.x + (delta * diffx);
|
|
3318
|
+
currentLocation.y = previousLocation.y + (delta * diffy);
|
|
3319
|
+
args.element.setAttribute('transform', 'translate( ' + currentLocation.x + ' ' + currentLocation.y + ' )');
|
|
3320
|
+
}
|
|
3321
|
+
},
|
|
3322
|
+
() => {
|
|
3323
|
+
element.setAttribute('transform', 'translate( ' + point.x + ' ' + point.y + ' )');
|
|
3324
|
+
}
|
|
3325
|
+
);
|
|
3326
|
+
}
|
|
3327
|
+
/**
|
|
3328
|
+
* To find compare should zoom factor with previous factor and current factor
|
|
3329
|
+
*
|
|
3330
|
+
* @param {number} scaleFactor - Specifies the scale factor
|
|
3331
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
3332
|
+
* @returns {void}
|
|
3333
|
+
*/
|
|
3334
|
+
export function compareZoomFactor(scaleFactor: number, maps: Maps): void {
|
|
3335
|
+
const previous: number = isNullOrUndefined(maps.shouldZoomPreviousFactor) ?
|
|
3336
|
+
null : maps.shouldZoomPreviousFactor;
|
|
3337
|
+
const current: number = isNullOrUndefined(maps.shouldZoomCurrentFactor) ?
|
|
3338
|
+
null : maps.shouldZoomCurrentFactor;
|
|
3339
|
+
if (!isNullOrUndefined(current)) {
|
|
3340
|
+
maps.shouldZoomCurrentFactor = null;
|
|
3341
|
+
maps.shouldZoomPreviousFactor = null;
|
|
3342
|
+
} else if (!isNullOrUndefined(previous)
|
|
3343
|
+
&& isNullOrUndefined(current)
|
|
3344
|
+
&& maps.shouldZoomPreviousFactor !== scaleFactor) {
|
|
3345
|
+
maps.shouldZoomCurrentFactor = scaleFactor;
|
|
3346
|
+
} else {
|
|
3347
|
+
maps.shouldZoomPreviousFactor = scaleFactor;
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
/**
|
|
3351
|
+
* To find zoom level for the min and max latitude values
|
|
3352
|
+
*
|
|
3353
|
+
* @param {number} minLat - Specifies the minimum latitude
|
|
3354
|
+
* @param {number} maxLat - Specifies the maximum latitude
|
|
3355
|
+
* @param {number} minLong - Specifies the minimum longitude
|
|
3356
|
+
* @param {number} maxLong - Specifies the maximum longitude
|
|
3357
|
+
* @param {number} mapWidth - Specifies the width of the maps
|
|
3358
|
+
* @param {number} mapHeight - Specifies the height of the maps
|
|
3359
|
+
* @param {Maps} maps - Specifies the instance of the maps
|
|
3360
|
+
* @returns {number} - Returns the scale factor
|
|
3361
|
+
*/
|
|
3362
|
+
export function calculateZoomLevel(minLat: number, maxLat: number, minLong: number, maxLong: number,
|
|
3363
|
+
mapWidth: number, mapHeight: number, maps: Maps): number {
|
|
3364
|
+
let scaleFactor: number;
|
|
3365
|
+
const maxZoomFact: number = maps.zoomSettings.maxZoom;
|
|
3366
|
+
let applyMethodeZoom: number;
|
|
3367
|
+
const maxLatSin: number = Math.sin(maxLat * Math.PI / 180);
|
|
3368
|
+
const maxLatRad: number = Math.log((1 + maxLatSin) / (1 - maxLatSin)) / 2;
|
|
3369
|
+
const maxLatValue: number = Math.max(Math.min(maxLatRad, Math.PI), -Math.PI) / 2;
|
|
3370
|
+
const minLatSin: number = Math.sin(minLat * Math.PI / 180);
|
|
3371
|
+
const minLatRad: number = Math.log((1 + minLatSin) / (1 - minLatSin)) / 2;
|
|
3372
|
+
const minLatValue: number = Math.max(Math.min(minLatRad, Math.PI), -Math.PI) / 2;
|
|
3373
|
+
|
|
3374
|
+
if (maps.zoomNotApplied && !maps.isTileMap) {
|
|
3375
|
+
const latiRatio: number = Math.abs((maps.baseMapBounds.latitude.max - maps.baseMapBounds.latitude.min) / (maxLat - minLat));
|
|
3376
|
+
const longiRatio: number = Math.abs((maps.baseMapBounds.longitude.max - maps.baseMapBounds.longitude.min) / (maxLong - minLong));
|
|
3377
|
+
applyMethodeZoom = Math.min(latiRatio, longiRatio);
|
|
3378
|
+
|
|
3379
|
+
|
|
3380
|
+
const minLocation: Point = convertGeoToPoint(minLat, minLong, 1, maps.layersCollection[0], maps);
|
|
3381
|
+
const maxLocation: Point = convertGeoToPoint(maxLat, maxLong, 1, maps.layersCollection[0], maps);
|
|
3382
|
+
}
|
|
3383
|
+
|
|
3384
|
+
const latRatio: number = (maxLatValue - minLatValue) / Math.PI;
|
|
3385
|
+
const lngDiff: number = maxLong - minLong;
|
|
3386
|
+
const lngRatio: number = ((lngDiff < 0) ? (lngDiff + 360) : lngDiff) / 360;
|
|
3387
|
+
const WORLD_PX_HEIGHT: number = 256;
|
|
3388
|
+
const WORLD_PX_WIDTH: number = 256;
|
|
3389
|
+
const latZoom: number = (Math.log(mapHeight / WORLD_PX_HEIGHT / latRatio) / Math.LN2);
|
|
3390
|
+
const lngZoom: number = (Math.log(mapWidth / WORLD_PX_WIDTH / lngRatio) / Math.LN2);
|
|
3391
|
+
const result: number = (maps.zoomNotApplied && !maps.isTileMap) ? applyMethodeZoom : Math.min(latZoom, lngZoom);
|
|
3392
|
+
scaleFactor = Math.min(result, maxZoomFact);
|
|
3393
|
+
scaleFactor = maps.isTileMap || !maps.zoomNotApplied ? Math.floor(scaleFactor) : scaleFactor;
|
|
3394
|
+
if (!maps.isTileMap) {
|
|
3395
|
+
compareZoomFactor(scaleFactor, maps);
|
|
3396
|
+
}
|
|
3397
|
+
return scaleFactor;
|
|
3398
|
+
}
|
|
3399
|
+
|
|
3400
|
+
/**
|
|
3401
|
+
* Method to get the result
|
|
3402
|
+
*
|
|
3403
|
+
* @param {any} e - Specifies the any type value
|
|
3404
|
+
* @returns {any} - Returns the data value
|
|
3405
|
+
*/
|
|
3406
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3407
|
+
export function processResult(e: any): any {
|
|
3408
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3409
|
+
let dataValue: any;
|
|
3410
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3411
|
+
const resultValue: any = !isNullOrUndefined(e['result']) ? e['result'] : e['actual'];
|
|
3412
|
+
if (isNullOrUndefined(resultValue.length)) {
|
|
3413
|
+
if (!isNullOrUndefined(resultValue['Items'])) {
|
|
3414
|
+
dataValue = resultValue['Items'];
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
else {
|
|
3418
|
+
dataValue = resultValue;
|
|
3419
|
+
}
|
|
3420
|
+
return dataValue;
|
|
3421
|
+
}
|