UNPKG

@syncfusion/ej2-maps

Version:

The Maps component is used to visualize the geographical data and represent the statistical data of a particular geographical area on earth with user interactivity, and provides various customizing options

1,348 lines (1,296 loc) 154 kB
/** * Maps Component file */ import { Component, NotifyPropertyChanges, INotifyPropertyChanged, Property, Fetch } from '@syncfusion/ej2-base'; import { EventHandler, Browser, EmitType, isNullOrUndefined, createElement, setValue, extend } from '@syncfusion/ej2-base'; import { Event, remove, L10n, Collection, Internationalization, Complex } from '@syncfusion/ej2-base'; import { ModuleDeclaration } from '@syncfusion/ej2-base'; import { SvgRenderer } from '@syncfusion/ej2-svg-base'; import { Size, createSvg, Point, removeElement, triggerShapeEvent, showTooltip, checkShapeDataFields, MapLocation, getMousePosition, calculateSize } from './utils/helper'; import { getElement, removeClass, getTranslate, triggerItemSelectionEvent, mergeSeparateCluster, customizeStyle, querySelector } from './utils/helper'; import { createStyle, getProcessedMarginValue } from './utils/helper'; import { ZoomSettings, LegendSettings } from './model/base'; import { LayerSettings, TitleSettings, Border, Margin, MapsAreaSettings, Annotation, CenterPosition } from './model/base'; import { ZoomSettingsModel, LegendSettingsModel, LayerSettingsModel, BubbleSettingsModel, PolygonSettingsModel } from './model/base-model'; import { MarkerSettingsModel, SelectionSettingsModel, InitialMarkerSelectionSettingsModel } from './model/base-model'; import { TitleSettingsModel, BorderModel, MarginModel, CenterPositionModel, InitialShapeSelectionSettingsModel } from './model/base-model'; import { MapsAreaSettingsModel, AnnotationModel } from './model/base-model'; import { Bubble } from './layers/bubble'; import { Legend } from './layers/legend'; import { Marker } from './layers/marker'; import { Highlight } from './user-interaction/highlight'; import { Selection } from './user-interaction/selection'; import { MapsTooltip } from './user-interaction/tooltip'; import { Zoom } from './user-interaction/zoom'; import { load, click, onclick, rightClick, doubleClick, resize, shapeSelected, zoomIn, mouseMove } from './model/constants'; import { ProjectionType, MapsTheme, PanDirection, TooltipGesture } from './utils/enum'; import { MapsModel } from './maps-model'; import { getThemeStyle, Theme } from './model/theme'; import { ILoadEventArgs, ILoadedEventArgs, IMinMaxLatitudeLongitude, IMouseEventArgs, IMouseMoveEventArgs, IResizeEventArgs, ITooltipRenderEventArgs } from './model/interface'; import { GeoPosition, ITooltipRenderCompleteEventArgs, ILegendRenderingEventArgs } from './model/interface'; import { ILayerRenderingEventArgs, IShapeRenderingEventArgs, IMarkerRenderingEventArgs, IMarkerClickEventArgs } from './model/interface'; import { IMarkerMoveEventArgs, ILabelRenderingEventArgs, IBubbleMoveEventArgs, IBubbleClickEventArgs } from './model/interface'; import { IMarkerClusterClickEventArgs, IMarkerClusterMoveEventArgs, IMarkerClusterRenderingEventArgs } from './model/interface'; import { ISelectionEventArgs, IShapeSelectedEventArgs, IMapPanEventArgs, IMapZoomEventArgs } from './model/interface'; import { IBubbleRenderingEventArgs, IAnimationCompleteEventArgs, IPrintEventArgs, IThemeStyle } from './model/interface'; import { LayerPanel } from './layers/layer-panel'; import { GeoLocation, Rect, RectOption, measureText, getElementByID, MapAjax, processResult, getElementsByClassName } from '../maps/utils/helper'; import { findPosition, textTrim, TextOption, renderTextElement, calculateZoomLevel, convertTileLatLongToPoint, convertGeoToPoint} from '../maps/utils/helper'; import { Annotations } from '../maps/user-interaction/annotation'; import { FontModel, DataLabel, MarkerSettings, IAnnotationRenderingEventArgs, IMarkerDragEventArgs, BingMap } from './index'; import { NavigationLineSettingsModel, changeBorderWidth } from './index'; import { NavigationLine } from './layers/navigation-selected-line'; import { Polygon } from './layers/polygon'; import { DataManager, Query } from '@syncfusion/ej2-data'; import { ExportType } from '../maps/utils/enum'; import { PdfPageOrientation } from '@syncfusion/ej2-pdf-export'; import { Print } from './model/print'; import { PdfExport } from './model/export-pdf'; import { ImageExport } from './model/export-image'; /** * Represents the maps control. It is ideal for rendering maps from GeoJSON data or other map providers like OpenStreetMap, Google Maps, Bing Maps, etc that * has rich feature set that includes markers, labels, bubbles and much more. * ```html * <div id="maps"/> * <script> * var maps = new Maps(); * maps.appendTo("#maps"); * </script> * ``` */ @NotifyPropertyChanges export class Maps extends Component<HTMLElement> implements INotifyPropertyChanged { //Module Declaration of Maps. /** * Gets or sets the module to add bubbles in the maps. * * @private */ public bubbleModule: Bubble; /** * Sets and get the module to add the marker in the maps. * * @private */ public markerModule: Marker; /** * Gets or sets the module to add the data-label in the maps. * * @private */ public dataLabelModule: DataLabel; /** * Gets or sets the module to highlight the element when mouse has hovered on it in maps. * * @private */ public highlightModule: Highlight; /** * Gets or sets the module to add the navigation lines in the maps. * * @private */ public navigationLineModule: NavigationLine; /** * Gets or sets the module to add the polygon shapes over the maps. * * @private */ public polygonModule: Polygon; /** * Gets or sets the module to add the legend in maps. * * @private */ public legendModule: Legend; /** * Gets or sets the module to select the geometric shapes when clicking in maps. * * @private */ public selectionModule: Selection; /** * Gets or sets the module to add the tooltip when mouse has hovered on an element in maps. * * @private */ public mapsTooltipModule: MapsTooltip; /** * Gets or sets the module to add the zooming operations in maps. * * @private */ public zoomModule: Zoom; /** * Gets or sets the module to add annotation elements in maps. * * @private */ public annotationsModule: Annotations; /** * This module enables the print functionality in maps. * * @private */ public printModule: Print; /** * This module enables the export to PDF functionality in maps. * * @private */ public pdfExportModule: PdfExport; /** * This module enables the export to image functionality in maps. * * @private */ public imageExportModule: ImageExport; /** * This module enables the bing map functionality in maps. * * @private */ public bingMap: BingMap; // Maps pblic API Declaration /** * Gets or sets the background color of the maps container. * * @default null */ @Property(null) public background: string; /** * Enables or disables the visibility state of the separator for grouping. * * @default false */ @Property(false) public useGroupingSeparator: boolean; /** * Gets or sets the format to apply internationalization for the text in the maps. * * @default null */ @Property(null) public format: string; /** * Gets or sets the width in which the maps is to be rendered. * * @default null */ @Property(null) public width: string; /** * Gets or sets the height in which the maps is to be rendered. * * @default null */ @Property(null) public height: string; /** * Gets or sets the mode in which the tooltip is to be displayed. * The tooltip can be rendered on mouse move, click or double clicking on the * element on the map. * * @default 'MouseMove' */ @Property('MouseMove') public tooltipDisplayMode: TooltipGesture; /** * Enables or disables the print functionality in maps. * * @default false */ @Property(false) public allowPrint: boolean; /** * Enables or disables the export to image functionality in maps. * * @default false */ @Property(false) public allowImageExport: boolean; /** * Enables or disables the export to PDF functionality in maps. * * @default false */ @Property(false) public allowPdfExport: boolean; /** * Gets or sets the options to customize the title of the maps. */ @Complex<TitleSettingsModel>({}, TitleSettings) public titleSettings: TitleSettingsModel; /** * Gets or sets the options to customize the zooming operations in maps. */ @Complex<ZoomSettingsModel>({}, ZoomSettings) public zoomSettings: ZoomSettingsModel; /** * Gets or sets the options to customize the legend of the maps. */ @Complex<LegendSettingsModel>({}, LegendSettings) public legendSettings: LegendSettingsModel; /** * Gets or sets the options to customize the layers of the maps. */ @Collection<LayerSettingsModel>([], LayerSettings) public layers: LayerSettingsModel[]; /** * Gets or sets the options for customizing the annotations in the maps. */ @Collection<AnnotationModel>([], Annotation) public annotations: AnnotationModel[]; /** * Gets or sets the options to customize the margin of the maps. */ @Complex<MarginModel>({}, Margin) public margin: MarginModel; /** * Gets or sets the options for customizing the style properties of the maps border. */ @Complex<BorderModel>({ color: '#DDDDDD', width: 0 }, Border) public border: BorderModel; /** * Gets or sets the theme styles supported for maps. When the theme is set, the styles associated with the theme will be set in the maps. * * @default Material */ @Property('Material') public theme: MapsTheme; /** * Gets or sets the projection with which the maps will be rendered to show the two-dimensional curved surface of a globe on a plane. * * @default Mercator */ @Property('Mercator') public projectionType: ProjectionType; /** * Gets or sets the index of the layer of maps which will be the base layer. It provides the option to select which layer to be visible in the maps. * * @default 0 */ @Property(0) public baseLayerIndex: number; /** * Gets or sets the description of the maps for assistive technology. * * @default null */ @Property(null) public description: string; /** * Gets or sets the tab index value for the maps. * * @default 0 */ @Property(0) public tabIndex: number; /** * Gets or sets the center position of the maps. */ @Complex<CenterPositionModel>({ latitude: null, longitude: null }, CenterPosition) public centerPosition: CenterPositionModel; /** * Gets or sets the options to customize the area around the map. */ @Complex<MapsAreaSettingsModel>({}, MapsAreaSettings) public mapsArea: MapsAreaSettingsModel; /** * Triggers before the maps gets rendered. * * @event load */ @Event() public load: EmitType<ILoadEventArgs>; /** * Triggers before the print gets started. * * @event beforePrint */ @Event() public beforePrint: EmitType<IPrintEventArgs>; /** * Triggers after the maps gets rendered. * * @event loaded */ @Event() public loaded: EmitType<ILoadedEventArgs>; /** * Triggers when a user clicks on an element in Maps. * * @event click * @deprecated */ @Event() public click: EmitType<IMouseEventArgs>; /** * Triggers when a user clicks on an element in Maps. * * @event onclick */ @Event() public onclick: EmitType<IMouseEventArgs>; /** * Triggers when performing the double click operation on an element in maps. * * @event doubleClick */ @Event() public doubleClick: EmitType<IMouseEventArgs>; /** * Triggers when performing the right click operation on an element in maps. * * @event rightClick */ @Event() public rightClick: EmitType<IMouseEventArgs>; /** * Triggers to notify the resize of the maps when the window is resized. * * @event resize */ @Event() public resize: EmitType<IResizeEventArgs>; /** * Triggers before the maps tooltip gets rendered. * * @event tooltipRender */ @Event() public tooltipRender: EmitType<ITooltipRenderEventArgs>; /** * Triggers before the legend gets rendered. * * @event legendRendering * @deprecated */ @Event() public legendRendering: EmitType<ILegendRenderingEventArgs>; /** * Triggers after the maps tooltip gets rendered. * * @deprecated * @event tooltipRenderComplete */ @Event() public tooltipRenderComplete: EmitType<ITooltipRenderCompleteEventArgs>; /** * Triggers when a shape is selected in the maps. * * @event shapeSelected */ @Event() public shapeSelected: EmitType<IShapeSelectedEventArgs>; /** * Triggers before the shape, bubble or marker gets selected. * * @event itemSelection */ @Event() public itemSelection: EmitType<ISelectionEventArgs>; /** * Trigger before the shape, bubble or marker gets highlighted. * * @event itemHighlight */ @Event() public itemHighlight: EmitType<ISelectionEventArgs>; /** * Triggers before the shape gets highlighted. * * @event shapeHighlight */ @Event() public shapeHighlight: EmitType<IShapeSelectedEventArgs>; /** * Triggers before the maps layer gets rendered. * * @event layerRendering */ @Event() public layerRendering: EmitType<ILayerRenderingEventArgs>; /** * Triggers before the maps shape gets rendered. * * @event shapeRendering */ @Event() public shapeRendering: EmitType<IShapeRenderingEventArgs>; /** * Triggers before the maps marker gets rendered. * * @event markerRendering */ @Event() public markerRendering: EmitType<IMarkerRenderingEventArgs>; /** * Triggers before the maps marker cluster gets rendered. * * @event markerClusterRendering */ @Event() public markerClusterRendering: EmitType<IMarkerClusterRenderingEventArgs>; /** * Triggers when clicking on a marker element. * * @event markerClick */ @Event() public markerClick: EmitType<IMarkerClickEventArgs>; /** * When the marker begins to drag on the map, this event is triggered. * * @event markerDragStart */ @Event() public markerDragStart: EmitType<IMarkerDragEventArgs>; /** * When the marker has stopped dragging on the map, this event is triggered. * * @event markerDragEnd */ @Event() public markerDragEnd: EmitType<IMarkerDragEventArgs>; /** * Triggers when clicking the marker cluster in maps. * * @event markerClusterClick */ @Event() public markerClusterClick: EmitType<IMarkerClusterClickEventArgs>; /** * Triggers when moving the mouse over the marker cluster element in maps. * * @event markerClusterMouseMove */ @Event() public markerClusterMouseMove: EmitType<IMarkerClusterMoveEventArgs>; /** * Triggers when moving the mouse over the marker element in maps. * * @event markerMouseMove */ @Event() public markerMouseMove: EmitType<IMarkerMoveEventArgs>; /** * This event is triggered when the mouse pointer moves over the map. * * @event mouseMove */ @Event() public mouseMove: EmitType<IMouseMoveEventArgs>; /** * Triggers before the data-label gets rendered. * * @event dataLabelRendering */ @Event() public dataLabelRendering: EmitType<ILabelRenderingEventArgs>; /** * Triggers before the bubble element gets rendered on the map. * * @event bubbleRendering */ @Event() public bubbleRendering: EmitType<IBubbleRenderingEventArgs>; /** * Triggers when performing the click operation on the bubble element in maps. * * @event bubbleClick */ @Event() public bubbleClick: EmitType<IBubbleClickEventArgs>; /** * Triggers when hovering the mouse on the bubble element in maps. * * @event bubbleMouseMove */ @Event() public bubbleMouseMove: EmitType<IBubbleMoveEventArgs>; /** * Triggers after the animation is completed in the maps. * * @event animationComplete */ @Event() public animationComplete: EmitType<IAnimationCompleteEventArgs>; /** * Triggers before rendering an annotation in the maps. * * @event annotationRendering */ @Event() public annotationRendering: EmitType<IAnnotationRenderingEventArgs>; /** * Triggers before the zoom operations such as zoom in and zoom out in the maps. * * @event zoom */ @Event() public zoom: EmitType<IMapZoomEventArgs>; /** * Triggers before performing the panning operation. * * @event pan */ @Event() public pan: EmitType<IMapPanEventArgs>; /** * This event is triggered after performing the panning action. * * @event panComplete */ @Event() public panComplete: EmitType<IMapPanEventArgs>; /** * This event is triggered after the zooming operation is completed. * * @event zoomComplete */ @Event() public zoomComplete: EmitType<IMapPanEventArgs>; // Internal properties declaration area. /** * Specifies the function to format the text contents in the maps. * * @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public formatFunction: any; /** * Specifies the svg renderer object. * * @private */ public renderer: SvgRenderer; /** * Specifies the svg element's object of maps. * * @private */ public svgObject: Element; /** @public */ public mapScaleValue: number; /** * Specifies the available height and width of maps. * * @private */ public availableSize: Size; /** * whether it is layer add or not. * * @private */ public isAddLayer: boolean; /** * Specifies the localization object. * * @private */ public localeObject: L10n; /** * Specifies the default values of localization values. */ // eslint-disable-next-line @typescript-eslint/no-explicit-any private defaultLocalConstants: any; /** * Internal use of internationalization instance. * * @private */ public intl: Internationalization; /** * Check layer whether is geometry or tile. * * @private */ public isTileMap: boolean = false; /** * Resize the map */ private resizeTo: number; /** * Resize the map * * @private */ public isResize: boolean = false; /** * @private */ public mapAreaRect: Rect; /** * @private */ public layersCollection: LayerSettings[]; /** * @private */ public isExportInitialTileMap: boolean; /** * @private * @hidden */ public mapLayerPanel: LayerPanel; /** * @private * @hidden */ /** * @private */ public themeStyle: IThemeStyle; /** * @private */ public isReset: boolean = false; /** * @private */ public totalRect: Rect; /** * * Specifies whether the shape is selected in the maps or not. * * @returns {boolean} - Returns a boolean value to specify whether the shape is selected in the maps or not. */ public get isShapeSelected(): boolean { return this.mapSelect; } public dataLabel: DataLabel; /** @private */ public isTouch: boolean; /** @private */ public baseSize: Size = new Size(0, 0); /** @private */ public scale: number; /** @private */ public baseScale: number; /** @private */ public mapSelect: boolean; /** @private */ public baseMapBounds: GeoLocation; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public baseMapRectBounds: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any private resizeEvent: any; /** @public */ public translatePoint: Point = new Point(0, 0); /** @private */ public baseTranslatePoint: Point = new Point(0, 0); /** @public */ public zoomTranslatePoint: Point = new Point(0, 0); /** @private */ public markerZoomFactor: number; /** @private */ public markerZoomCenterPoint: CenterPositionModel; /** @private */ public markerZoomedState: boolean = true; /** @private */ public zoomPersistence: boolean = false; /** @private */ public defaultState: boolean = true; /** @private */ public currentTiles: HTMLElement; /** @private */ public markerCenterLatitude: number; /** @private */ public markerCenterLongitude: number; /** @private */ public previousCenterLatitude: number; /** @private */ public previousCenterLongitude: number; /** @private */ public centerPositionChanged: boolean = false; /** @private */ public previousZoomFactor: number; /** @private */ public shouldZoomCurrentFactor: number; /** @private */ public shouldZoomPreviousFactor: number; /** @private */ public markerNullCount: number = 0; /** @private */ public translateType: string; /** @public */ // eslint-disable-next-line @typescript-eslint/ban-types public previousProjection: String; /** @private */ public currentShapeDataLength: number; /** @private */ public tileTranslatePoint: Point = new Point(0, 0); /** @private */ public baseTileTranslatePoint: Point = new Point(0, 0); /** @private */ // eslint-disable-next-line @typescript-eslint/ban-types public isDevice: Boolean = false; /** @private */ public tileZoomLevel: number; /** @private */ public isZoomByPosition: boolean; /** @private */ public tileZoomScale: number; /** @private */ public staticMapZoom: number = this.zoomSettings.enable ? this.zoomSettings.zoomFactor : 0; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public serverProcess: any; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public toolbarProperties: any; /** @private */ public previousScale: number; /** @private */ public previousPoint: Point; /** @private */ public centerLatOfGivenLocation: number; /** @private */ public centerLongOfGivenLocation: number; /** @private */ public minLatOfGivenLocation: number; /** @private */ public minLongOfGivenLocation: number; /** @private */ public maxLatOfGivenLocation: number; /** @private */ public maxLongOfGivenLocation: number; /** @private */ public scaleOfGivenLocation: number; /** @private */ public zoomNotApplied: boolean = false; /** @public */ public dataLabelShape: number[] = []; public zoomShapeCollection: string[] = []; public zoomLabelPositions: object[] = []; public mouseDownEvent: Object = { x: null, y: null }; public mouseClickEvent: Object = { x: null, y: null }; /** @private */ public shapeSelectionClass: Element; /** @private */ public selectedElementId: string[] = []; /** @private */ public markerSelectionClass: Element; /** @private */ public selectedMarkerElementId: string[] = []; /** @private */ public bubbleSelectionClass: Element; /** @private */ public selectedBubbleElementId: string[] = []; /** @private */ public navigationSelectionClass: Element; /** @private */ public selectedNavigationElementId: string[] = []; /** @private */ public polygonSelectionClass: Element; /** @private */ public selectedPolygonElementId: string[] = []; /** @private */ public legendSelectionClass: SelectionSettingsModel; /** @private */ public selectedLegendElementId: number[] = []; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public legendSelectionCollection: any[] = []; /** @private */ public shapeSelections: boolean = true; /** @private */ public legendSelection: boolean = true; /** @private */ public toggledLegendId: number[] = []; /** @private */ public toggledElementId: string[] = []; /** @private */ public checkInitialRender: boolean = true; /** @private */ public widthBeforeRefresh: number; /** @private */ public heightBeforeRefresh: number; /** @private */ public previousTranslate: Point; /** @private */ public initialTileTranslate: Point = new Point(0, 0); /** @private */ public previousTileWidth: number; /** @private */ public isMarkerZoomCompleted: boolean = false; /** @private */ public markerDragId: string = ''; /** @private */ public previousTileHeight: number; /** @private */ public initialZoomLevel: number; /** @private */ public initialCheck: boolean = true; /** @private */ public applyZoomReset: boolean = false; /** @private */ public markerClusterExpandCheck: boolean = false; /** @private */ public markerClusterExpand: boolean = false; /** @private */ public mouseMoveId: string = ''; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public shapeSelectionItem: any[] = []; /** @private */ // eslint-disable-next-line @typescript-eslint/no-explicit-any public markerDragArgument: any = null; /** * Constructor for creating the widget. * * @param {MapsModel} options Specifies the options * @param {string | HTMLElement} element Specifies the element */ constructor(options?: MapsModel, element?: string | HTMLElement) { super(options, <HTMLElement | string>element); setValue('mergePersistData', this.mergePersistMapsData, this); } /** * To manage persist maps data. * * @returns {void} */ private mergePersistMapsData(): void { let data: string; // eslint-disable-next-line @typescript-eslint/no-explicit-any let windowData: any; try { windowData = window.localStorage; } catch (e) { windowData = null; } if (!isNullOrUndefined(windowData)) { data = window.localStorage.getItem(this.getModuleName() + this.element.id); } if (!(isNullOrUndefined(data) || (data === ''))) { const dataObj: Maps = JSON.parse(data); const keys: string[] = Object.keys(dataObj); this.isProtectedOnChange = true; for (const key of keys) { if ((typeof this[key as string] === 'object') && !isNullOrUndefined(this[key as string])) { extend(this[key as string], dataObj[key as string]); } else { this[key as string] = dataObj[key as string]; } } this.isProtectedOnChange = false; } } /** * Gets the localized label by locale keyword. * * @param {string} key - Specifies the key * @returns {string} - Returns the string value * @private */ public getLocalizedLabel(key: string): string { return this.localeObject.getConstant(key); } /** * Initializing pre-required values. * * @returns {void} */ protected preRender(): void { this.isDevice = Browser.isDevice; this.initPrivateVariable(); this.allowServerDataBinding = false; this.unWireEVents(); this.wireEVents(); this.setCulture(); } private renderElements(): void { if (!this.isDestroyed) { this.trigger(load, { maps: this }); this.createSVG(); this.findBaseAndSubLayers(); if (!isNullOrUndefined(this.markerModule) && this.markerModule.getMapsInstance()) { this.markerModule.initializeMarkerClusterList(); } this.createSecondaryElement(); this.addTabIndex(); this.themeStyle = getThemeStyle(this.theme); this.renderBorder(); this.renderTitle(this.titleSettings, 'title', null, null); this.renderArea(); this.processRequestJsonData(); this.renderComplete(); this.isAddLayer = !this.isTileMap ? false : this.isAddLayer; } } /** * To Initialize the control rendering. * * @returns {void} */ protected render(): void { this.renderElements(); } protected processRequestJsonData(): void { const length: number = this.layersCollection.length - 1; this.serverProcess = { request: 0, response: 0 }; let queryModule: Query; let dataModule: DataManager; Array.prototype.forEach.call(this.layersCollection, (layer: LayerSettings, layerIndex: number) => { if (layer.shapeData instanceof DataManager) { this.serverProcess['request']++; dataModule = layer.shapeData; queryModule = layer.query instanceof Query ? layer.query : new Query(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const dataManager: Promise<any> = dataModule.executeQuery(queryModule); // eslint-disable-next-line @typescript-eslint/no-explicit-any dataManager.then((e: any) => { this.processResponseJsonData('DataManager', e, layer, 'ShapeData'); }); } else if (layer.shapeData instanceof MapAjax || layer.shapeData) { if (!isNullOrUndefined(layer.shapeData['dataOptions'])) { this.processAjaxRequest(layer, layer.shapeData, 'ShapeData'); } } if (layer.dataSource instanceof DataManager) { this.serverProcess['request']++; dataModule = layer.dataSource as DataManager; queryModule = layer.query instanceof Query ? layer.query : new Query(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const dataManager: Promise<any> = dataModule.executeQuery(queryModule); // eslint-disable-next-line @typescript-eslint/no-explicit-any dataManager.then((e: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any layer.dataSource = processResult(e) as any[]; }); } if (layer.markerSettings.length > 0) { for (let i: number = 0; i < layer.markerSettings.length; i++) { if (layer.markerSettings[i as number].dataSource instanceof DataManager) { this.serverProcess['request']++; dataModule = layer.markerSettings[i as number].dataSource as DataManager; queryModule = layer.markerSettings[i as number].query instanceof Query ? layer.markerSettings[i as number].query : new Query(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const dataManager: Promise<any> = dataModule.executeQuery(queryModule); // eslint-disable-next-line @typescript-eslint/no-explicit-any dataManager.then((e: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any layer.markerSettings[i as number].dataSource = processResult(e) as any[]; }); } } } if (layer.bubbleSettings.length > 0) { for (let i: number = 0; i < layer.bubbleSettings.length; i++) { if (layer.bubbleSettings[i as number].dataSource instanceof DataManager) { this.serverProcess['request']++; dataModule = layer.bubbleSettings[i as number].dataSource as DataManager; queryModule = layer.bubbleSettings[i as number].query instanceof Query ? layer.bubbleSettings[i as number].query : new Query(); // eslint-disable-next-line @typescript-eslint/no-explicit-any const dataManager: Promise<any> = dataModule.executeQuery(queryModule); // eslint-disable-next-line @typescript-eslint/no-explicit-any dataManager.then((e: any) => { // eslint-disable-next-line @typescript-eslint/no-explicit-any layer.bubbleSettings[i as number].dataSource = processResult(e) as any[]; }); } } } if (layer.dataSource instanceof MapAjax || (!isNullOrUndefined(layer.dataSource) && !isNullOrUndefined(layer.dataSource['dataOptions']))) { this.processAjaxRequest(layer, layer.dataSource, 'DataSource'); } if (this.serverProcess['request'] === this.serverProcess['response'] && length === layerIndex) { this.processResponseJsonData(null); } }); } // eslint-disable-next-line @typescript-eslint/no-explicit-any private processAjaxRequest(layer: LayerSettings, localAjax: MapAjax | any, type: string): void { this.serverProcess['request']++; const fetchApiModule: Fetch = new Fetch(localAjax.dataOptions, localAjax.type, localAjax.contentType); // eslint-disable-next-line @typescript-eslint/no-explicit-any fetchApiModule.onSuccess = (args: any) => { if (!isNullOrUndefined(args.type) && args.type === 'application/octet-stream') { const reader: FileReader = new FileReader(); //eslint-disable-next-line @typescript-eslint/no-this-alias const map: Maps = this; // eslint-disable-next-line @typescript-eslint/tslint/config reader.onload = function () { args = JSON.parse(reader.result.toString()); map.processResponseJsonData('Fetch', args, layer, type); }; reader.readAsText(args); } else { this.processResponseJsonData('Fetch', args, layer, type); } }; fetchApiModule.send(localAjax.sendData); } /** * This method is used to process the JSON data to render the maps. * * @param {string} processType - Specifies the process type in maps. * @param {any | string} data - Specifies the data for maps. * @param {LayerSettings} layer - Specifies the layer for the maps. * @param {string} dataType - Specifies the data type for maps. * @returns {void} * @private */ public processResponseJsonData(processType: string, // eslint-disable-next-line @typescript-eslint/no-explicit-any data?: any | string, layer?: LayerSettings, dataType?: string): void { this.serverProcess['response']++; if (processType) { if (dataType === 'ShapeData') { // eslint-disable-next-line @typescript-eslint/no-explicit-any layer.shapeData = (processType === 'DataManager') ? processResult((data as any)) : data; } else { // eslint-disable-next-line @typescript-eslint/no-explicit-any layer.dataSource = (processType === 'DataManager') ? processResult((data as any)) : data; } } if (!isNullOrUndefined(processType) && this.serverProcess['request'] === this.serverProcess['response']) { const collection: LayerSettings[] = this.layersCollection; this.layersCollection = []; for (let i: number = 0; i < collection.length; i++) { if (collection[i as number].isBaseLayer) { this.layersCollection.push(collection[i as number]); } } for (let j: number = 0; j < collection.length; j++) { if (!collection[j as number].isBaseLayer) { this.layersCollection.push(collection[j as number]); } } this.renderMap(); } else if (isNullOrUndefined(processType)) { this.renderMap(); } } private renderMap(): void { if (this.legendModule && this.legendSettings.visible) { this.legendModule.renderLegend(); } this.createTile(); if (this.zoomSettings.enable && this.zoomModule) { this.zoomModule.createZoomingToolbars(); } if (!isNullOrUndefined(this.dataLabelModule)) { this.dataLabelModule.dataLabelCollections = []; } this.mapLayerPanel.measureLayerPanel(); if (!isNullOrUndefined(this.svgObject)) { this.element.appendChild(this.svgObject); } this.setSecondaryElementPosition(); for (let i: number = 0; i < this.layers.length; i++) { if (this.layers[i as number].selectionSettings && this.layers[i as number].selectionSettings.enable && this.layers[i as number].initialShapeSelection.length > 0 && this.checkInitialRender) { const checkSelection: boolean = this.layers[i as number].selectionSettings.enableMultiSelect; this.layers[i as number].selectionSettings.enableMultiSelect = checkSelection ? checkSelection : true; const shapeSelection: InitialShapeSelectionSettingsModel[] = this.layers[i as number].initialShapeSelection; for (let j: number = 0; j < this.layers[i as number].initialShapeSelection.length; j++) { this.shapeSelection(i, shapeSelection[j as number].shapePath, shapeSelection[j as number].shapeValue, true); } this.layers[i as number].selectionSettings.enableMultiSelect = checkSelection; if (i === this.layers.length - 1) { this.checkInitialRender = false; } } if (!this.isResize) { for (let k: number = 0; k < this.layers[i as number].markerSettings.length; k++) { // eslint-disable-next-line max-len if (this.layers[i as number].markerSettings[k as number].selectionSettings && this.layers[i as number].markerSettings[k as number].selectionSettings.enable && this.layers[i as number].markerSettings[k as number].initialMarkerSelection.length > 0) { const markerSelectionValues: InitialMarkerSelectionSettingsModel[] = this.layers[i as number].markerSettings[k as number].initialMarkerSelection; for (let j: number = 0; j < markerSelectionValues.length; j++) { this.markerInitialSelection(i, k, this.layers[i as number].markerSettings[k as number], markerSelectionValues[j as number].latitude, markerSelectionValues[j as number].longitude); } } } } } if (!isNullOrUndefined(document.getElementById(this.element.id + '_tile_parent'))) { const svg: ClientRect = this.svgObject.getBoundingClientRect(); const element: HTMLElement = document.getElementById(this.element.id); const tileElement: HTMLElement = document.getElementById(this.element.id + '_tile_parent'); const tileElement1: HTMLElement = document.getElementById(this.element.id + '_tiles'); const tile: ClientRect = tileElement.getBoundingClientRect(); let top: number; let left: number; left = parseFloat(tileElement.style.left); const bottom: number = svg.bottom - tile.bottom - element.offsetTop; top = parseFloat(tileElement.style.top); top = (bottom <= 11) ? top : (!isNullOrUndefined(this.legendModule) && this.legendSettings.position === 'Bottom') ? this.mapAreaRect.y : (top * 2); left = (bottom <= 11) ? left : !isNullOrUndefined(this.legendModule) ? left : (left * 2); tileElement.style.top = top + 'px'; tileElement.style.left = left + 'px'; tileElement1.style.top = top + 'px'; tileElement1.style.left = left + 'px'; if (!isNullOrUndefined(this.legendModule) && this.legendModule.totalPages.length > 0) { tileElement.style.height = tileElement1.style.height = this.legendModule.legendTotalRect.height + 'px'; tileElement.style.width = tileElement1.style.width = this.legendModule.legendTotalRect.width + 'px'; } } this.arrangeTemplate(); if (this.annotationsModule) { if (this.width !== '0px' && this.height !== '0px' && this.width !== '0%' && this.height !== '0%') { this.annotationsModule.renderAnnotationElements(); } } this.element.style.outline = 'none'; this.element.style.position = 'relative'; for (let i: number = 0; i < document.getElementsByTagName('path').length - 1; i++) { if (document.getElementsByTagName('path')[i as number].id.indexOf('shapeIndex') > -1) { document.getElementsByTagName('path')[i as number].style.outline = 'none'; } } this.zoomingChange(); if (this.zoomModule && this.isDevice) { this.zoomModule.removeToolbarOpacity(this.isTileMap ? Math.round(this.tileZoomLevel) : this.mapScaleValue, this.element.id + '_Zooming_'); } if (!this.isZoomByPosition && !this.zoomNotApplied) { this.triggerZoomEvent(); } this.isResize = false; } private triggerZoomEvent(): void { let loadedArgs: ILoadedEventArgs; const minMaxLatitudeLongitude: IMinMaxLatitudeLongitude = this.getMinMaxLatitudeLongitude(); // eslint-disable-next-line prefer-const loadedArgs = { maps: this, isResized: this.isResize, minLatitude: minMaxLatitudeLongitude.minLatitude, maxLatitude: minMaxLatitudeLongitude.maxLatitude, minLongitude: minMaxLatitudeLongitude.minLongitude, maxLongitude: minMaxLatitudeLongitude.maxLongitude, cancel: false, name: 'Loaded' }; this.trigger('loaded', loadedArgs); //eslint-enable @typescript-eslint/prefer-const } /** * To apply color to the initial selected marker. * * @param {SelectionSettingsModel} selectionSettings - Specifies the selection settings * @param {Maps} map - Specifies the instance of the maps * @param {Element} targetElement - Specifies the target element * @param {object} data - Specifies the data * @returns {void} * @private */ public markerSelection( selectionSettings: SelectionSettingsModel, map: Maps, targetElement: Element, data: object ): void { const border: BorderModel = { color: selectionSettings.border.color, width: selectionSettings.border.width / map.scale, opacity: selectionSettings.border.opacity }; const markerSelectionProperties: object = { opacity: selectionSettings.opacity, fill: selectionSettings.fill, border: border, target: targetElement.id, cancel: false, data: data, maps: map }; if (!getElement('MarkerselectionMap')) { document.body.appendChild(createStyle('MarkerselectionMap', 'MarkerselectionMapStyle', markerSelectionProperties)); } else { customizeStyle('MarkerselectionMap', 'MarkerselectionMapStyle', markerSelectionProperties); } if (this.selectedMarkerElementId.length === 0 || selectionSettings.enableMultiSelect) { if (targetElement.tagName === 'g') { targetElement.children[0].setAttribute('class', 'MarkerselectionMapStyle'); this.selectedMarkerElementId.push(targetElement.children[0].id); } else { targetElement.setAttribute('class', 'MarkerselectionMapStyle'); this.selectedMarkerElementId.push(targetElement.id); } } } /** * initial selection of marker. * * @param {number} layerIndex - Specifies the layer index * @param {number} markerIndex - Specifies the marker index * @param {MarkerSettingsModel} markerSettings - Specifies the marker settings * @param {number} latitude - Specifies hte latitude * @param {number} longitude - Specifies the longitude * @returns {void} * @private */ public markerInitialSelection( layerIndex: number, markerIndex: number, markerSettings: MarkerSettingsModel, latitude: number, longitude: number ): void { const selectionSettings: SelectionSettingsModel = markerSettings.selectionSettings; if (selectionSettings.enable) { for (let i: number = 0; i < markerSettings.dataSource['length']; i++) { // eslint-disable-next-line @typescript-eslint/no-explicit-any const data: any = markerSettings.dataSource[i as number]; if (data['latitude'] === latitude && data['longitude'] === longitude) { const targetId: string = this.element.id + '_' + 'LayerIndex_' + layerIndex + '_MarkerIndex_' + markerIndex + '_dataIndex_' + i; this.markerSelection(selectionSettings, this, getElement(targetId), data); } } } } /** * Render the map area border. * * @returns {void} */ private renderArea(): void { const width: number = this.mapsArea.border.width; const background: string = this.mapsArea.background; if (width > 0 || (background || this.themeStyle.areaBackgroundColor)) { const mapBorder: BorderModel = { opacity: isNullOrUndefined(this.mapsArea.border.opacity) ? 1 : this.mapsArea.border.opacity, color: this.mapsArea.border.color, width: this.mapsArea.border.width }; const rect: RectOption = new RectOption( this.element.id + '_MapAreaBorder', background || this.themeStyle.areaBackgroundColor, mapBorder, 1, this.mapAreaRect ); this.svgObject.appendChild(this.renderer.drawRectangle(rect) as SVGRectElement); } } /** * To add tab index for map element. * * @returns {void} */ private addTabIndex(): void { this.element.setAttribute('aria-label', this.description || 'Maps Element'); this.element.setAttribute('role', 'region'); this.element.tabIndex = this.tabIndex; } private setSecondaryElementPosition(): void { const element: HTMLDivElement = getElementByID(this.element.id + '_Secondary_Element') as HTMLDivElement; const rect: ClientRect = this.element.getBoundingClientRect(); const svgElement: Element = getElementByID(this.element.id + '_svg'); if (!isNullOrUndefined(svgElement)) { const svgRect: ClientRect = svgElement.getBoundingClientRect(); element.style.left = Math.max(svgRect.left - rect.left, 0) + 'px'; element.style.top = Math.max(svgRect.top - rect.top, 0) + 'px'; } } private zoomingChange(): void { let left: number; let top: number; if (getElementByID(this.element.id + '_Layer_Collections') && this.zoomModule) { this.zoomModule.layerCollectionEle = getElementByID(this.element.id + '_Layer_Collections'); } if (this.isTileMap && getElementByID(this.element.id + '_Tile_SVG') && getElementByID(this.element.id + '_tile_parent')) { const tileElement: Element = getElementByID(this.element.id + '_tile_parent'); const tileSvgElement: Element = getElementByID(this.element.id + '_Tile_SVG'); const tileSvgParentElement: Element = getElementByID(this.element.id + '_Tile_SVG_Parent'); const tileRect: ClientRect = tileElement.getBoundingClientRect(); const tileSvgRect: ClientRect = tileSvgElement.getBoundingClientRect(); left = (tileRect.left - tileSvgRect.left); top = (tileRect.top - tileSvgRect.top); (tileSvgParentElement as HTMLElement).style.left = left + 'px'; (tileSvgParentElement as HTMLElement).style.top = top + 'px'; if (!isNullOrUndefined(this.le