UNPKG

flagwind-map

Version:
1,230 lines (1,229 loc) 361 kB
/*! * flagwind-map v1.0.40 * * Authors: * chendebao <hbchendb1985@gmail.com> * * Licensed under the MIT License. * Copyright (C) 2018-2019 Flagwind Inc. All rights reserved. */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.flagwind = {}))); }(this, (function (exports) { 'use strict'; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; var flagwind; (function (flagwind) { var DataManager = /** @class */ (function () { function DataManager() { this.rawData = []; } /** * 客户端聚合 * @param clusterRatio 聚合比率 * @param maxSingleFlareCount 最大的单个聚合点包含成员数 * @param areaDisplayMode 是否显示聚合区域 * @param map 地图对象 */ DataManager.prototype.clientSideClustering = function (clusterRatio, // 聚合比率 maxSingleFlareCount, // 最大的单个聚合点包含成员数 areaDisplayMode, map) { // let itcount = 0; console.time("fake-server-side-cluster"); var webExtent = map.extent; // set up a grid system to do the clustering // get the total amount of grid spaces based on the height and width of the map (divide it by clusterRatio) - then get the degrees for x and y var xCount = Math.round(map.width / clusterRatio); var yCount = Math.round(map.height / clusterRatio); var xw = (webExtent.xmax - webExtent.xmin) / xCount; var yh = (webExtent.ymax - webExtent.ymin) / yCount; var gsxmin, gsxmax, gsymin, gsymax; var dataLength = this.rawData.length; // create an array of clusters that is a grid over the visible extent. Each cluster contains the extent (in web merc) that bounds the grid space for it. var clusters = []; for (var i = 0; i < xCount; i++) { gsxmin = webExtent.xmin + xw * i; gsxmax = gsxmin + xw; for (var j = 0; j < yCount; j++) { gsymin = webExtent.ymin + yh * j; gsymax = gsymin + yh; var ext = new esri.geometry.Extent({ xmin: gsxmin, xmax: gsxmax, ymin: gsymin, ymax: gsymax }); ext.setSpatialReference(new esri.SpatialReference({ wkid: 4326 })); clusters.push({ extent: ext, clusterCount: 0, subTypeCounts: [], singles: [], points: [] }); } } var web, obj; for (var i = 0; i < dataLength; i++) { obj = this.rawData[i]; web = esri.geometry.lngLatToXY(obj.x, obj.y); if (web[0] < webExtent.xmin || web[0] > webExtent.xmax || web[1] < webExtent.ymin || web[1] > webExtent.ymax) { continue; } // let foundCluster = false; // loop cluster grid to see if it should be added to one for (var j = 0, jLen = clusters.length; j < jLen; j++) { var cl = clusters[j]; if (web[0] < cl.extent.xmin || web[0] > cl.extent.xmax || web[1] < cl.extent.ymin || web[1] > cl.extent.ymax) { continue; // not here so carry on } // recalc the x and y of the cluster by averaging the points again cl.x = cl.clusterCount > 0 ? (obj.x + cl.x * cl.clusterCount) / (cl.clusterCount + 1) : obj.x; cl.y = cl.clusterCount > 0 ? (obj.y + cl.y * cl.clusterCount) / (cl.clusterCount + 1) : obj.y; if (areaDisplayMode) { cl.points.push([obj.x, obj.y]); } cl.clusterCount++; var subTypeExists = false; for (var s = 0, sLen = cl.subTypeCounts.length; s < sLen; s++) { if (cl.subTypeCounts[s].name === obj.facilityType) { cl.subTypeCounts[s].count++; subTypeExists = true; break; } } if (!subTypeExists) { cl.subTypeCounts.push({ name: obj.facilityType, count: 1 }); } cl.singles.push(obj); } } var results = []; for (var i = 0, len = clusters.length; i < len; i++) { if (clusters[i].clusterCount === 1) { results.push(clusters[i].singles[0]); } else if (clusters[i].clusterCount > 0) { if (clusters[i].singles.length > maxSingleFlareCount) { clusters[i].singles = []; } results.push(clusters[i]); } } console.timeEnd("fake-server-side-cluster"); return results; }; DataManager.prototype.getData = function () { return this.rawData; }; DataManager.prototype.setData = function (data) { this.rawData = data; }; return DataManager; }()); flagwind.DataManager = DataManager; })(flagwind || (flagwind = {})); var flagwind; (function (flagwind) { /** * 表示一个事件项。 * @internal * @class * @version 1.0.0 */ var EventEntry = /** @class */ (function () { /** * 初始化事件项的新实例。 * @param {string} type 事件类型。 * @param {Function} listener 侦听函数。 * @param {any} scope 侦听函数中的 this 对象。 * @param {boolean} scope 是否为仅回掉一次。 */ function EventEntry(type, listener, scope, once) { this.type = type; this.listener = listener; this.scope = scope; this.once = once; } return EventEntry; }()); /** * 事件提供程序类。 * @description 用于添加或删除事件侦听器的方法,检查是否已注册特定类型的事件侦听器,并调度事件。 * @class * @version 1.0.0 */ var EventProvider = /** @class */ (function () { /** * 初始化事件提供程序的新实例。 * @param {any} source? 事件源实例。 */ function EventProvider(source) { // 保存事件源对象 this._source = source || this; // 初始化事件字典 this._events = new flagwind.Map(); } /** * 为指定的事件类型注册一个侦听器,以使侦听器能够接收事件通知。 * @summary 如果不再需要某个事件侦听器,可调用 removeListener() 删除它,否则会产生内存问题。 * 由于垃圾回收器不会删除仍包含引用的对象,因此不会从内存中自动删除使用已注册事件侦听器的对象。 * @param {string} type 事件类型。 * @param {Function} 处理事件的侦听器函数。 * @param {any} scope? 侦听函数绑定的 this 对象。 * @param {boolean} once? 是否添加仅回调一次的事件侦听器,如果此参数设为 true 则在第一次回调时就自动移除监听。 * @returns void */ EventProvider.prototype.addListener = function (type, listener, scope, once) { if (scope === void 0) { scope = this; } if (once === void 0) { once = false; } if (!type || !listener) { throw new flagwind.ArgumentException(); } var entries = this._events.get(type); if (!entries) { entries = new Array(); this._events.set(type, entries); } for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { var entry = entries_1[_i]; // 防止添加重复的侦听函数 if (entry.listener === listener && entry.scope === scope) { return; } } entries.push(new EventEntry(type, listener, scope, once)); }; /** * 移除侦听器。如果没有注册任何匹配的侦听器,则对此方法的调用没有任何效果。 * @param {string} type 事件类型。 * @param {Function} listener 处理事件的侦听器函数。 * @param {any} scope? 侦听函数绑定的 this 对象。 * @returns void */ EventProvider.prototype.removeListener = function (type, listener, scope) { if (scope === void 0) { scope = this; } if (!type || !listener) { throw new flagwind.ArgumentException(); } var entries = this._events.get(type); if (!entries) { return; } for (var i = 0, len = entries.length; i < len; i++) { var entry = entries[i]; if (entry.listener === listener && entry.scope === scope) { entries.splice(i, 1); break; } } // 如果事件项为空,则需要释放资源 if (entries.length === 0) { this._events.delete(type); } }; /** * 检查是否为特定事件类型注册了侦听器。 * @param {string} type 事件类型。 * @returns boolean 如果指定类型的侦听器已注册,则值为 true;否则,值为 false。 */ EventProvider.prototype.hasListener = function (type) { var entries = this._events.get(type); return !!entries && entries.length > 0; }; EventProvider.prototype.dispatchEvent = function () { var params = arguments, args; switch (params.length) { // 重载匹配: // dispatchEvent(args: EventArgs): void; // dispatchEvent(type: string): void; case 1: { if (params[0] instanceof flagwind.EventArgs) { // 参数匹配: args: EventArgs args = params[0]; } else if (flagwind.Type.isString(params[0])) { // 参数匹配: type: string args = new flagwind.EventArgs(params[0]); } break; } // 重载匹配: // dispatchEvent(type: string, data: any): void; case 2: { // 参数匹配: type: string, data: any args = new flagwind.EventArgs(params[0], params[1]); break; } } // 设置事件源 args.source = this._source; // 根据事件类型获取所有事件项 var entries = this._events.get(args.type); if (!entries || entries.length === 0) { return; } // 临时数组用于保存只回掉一次的事件项 var onces = new Array(); for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { var entry = entries_2[_i]; entry.listener.call(entry.scope, args); if (entry.once) { onces.push(entry); } } // 清除所有只回调一次的事件项 while (onces.length) { var entry = onces.pop(); this.removeListener(entry.type, entry.listener, entry.scope); } }; return EventProvider; }()); flagwind.EventProvider = EventProvider; })(flagwind || (flagwind = {})); /// <reference path="../events/EventProvider.ts" /> var flagwind; (function (flagwind) { /** * 功能图层包装类 * * @export * @class FlagwindFeatureLayer */ var FlagwindFeatureLayer = /** @class */ (function (_super) { __extends(FlagwindFeatureLayer, _super); function FlagwindFeatureLayer(id, title) { var _this = _super.call(this) || this; _this.id = id; _this.title = title; _this.isShow = true; _this.id = id; return _this; } Object.defineProperty(FlagwindFeatureLayer.prototype, "graphics", { get: function () { return this.layer.graphics; }, enumerable: true, configurable: true }); Object.defineProperty(FlagwindFeatureLayer.prototype, "items", { get: function () { return this.graphics.map(function (g) { return g.attributes; }); }, enumerable: true, configurable: true }); Object.defineProperty(FlagwindFeatureLayer.prototype, "count", { get: function () { if (this.layer) { return this.graphics.length; } return 0; }, enumerable: true, configurable: true }); FlagwindFeatureLayer.prototype.appendTo = function (map) { this.layer.addToMap(map); }; FlagwindFeatureLayer.prototype.removeLayer = function (map) { this.layer.removeFromMap(map); }; FlagwindFeatureLayer.prototype.clear = function () { this.layer.clear(); }; FlagwindFeatureLayer.prototype.show = function () { this.isShow = true; this.layer.show(); }; FlagwindFeatureLayer.prototype.hide = function () { this.isShow = false; this.layer.hide(); }; /** * 获取指定id的地图要素对象 */ FlagwindFeatureLayer.prototype.getGraphicById = function (id) { var graphics = this.graphics; for (var i = 0; i < graphics.length; i++) { var attrs = graphics[i].attributes; if (attrs.id === id) { return graphics[i]; } } return null; }; /** * 删除指定id的地图要素对象 */ FlagwindFeatureLayer.prototype.removeGraphicById = function (id) { var graphic = this.getGraphicById(id); if (graphic != null) { this.layer.remove(graphic); } }; /** * 为指定的事件类型注册一个侦听器,以使侦听器能够接收事件通知。 * @summary 如果不再需要某个事件侦听器,可调用 removeListener() 删除它,否则会产生内存问题。 * 由于垃圾回收器不会删除仍包含引用的对象,因此不会从内存中自动删除使用已注册事件侦听器的对象。 * @param {string} type 事件类型。 * @param {Function} 处理事件的侦听器函数。 * @param {any} scope? 侦听函数绑定的 this 对象。 * @param {boolean} once? 是否添加仅回调一次的事件侦听器,如果此参数设为 true 则在第一次回调时就自动移除监听。 * @returns void */ FlagwindFeatureLayer.prototype.on = function (type, listener, scope, once) { if (scope === void 0) { scope = this; } if (once === void 0) { once = false; } this.addListener(type, listener, scope, once); }; /** * 移除侦听器。如果没有注册任何匹配的侦听器,则对此方法的调用没有任何效果。 * @param {string} type 事件类型。 * @param {Function} listener 处理事件的侦听器函数。 * @param {any} scope? 侦听函数绑定的 this 对象。 * @returns void */ FlagwindFeatureLayer.prototype.off = function (type, listener, scope) { if (scope === void 0) { scope = this; } this.removeListener(type, listener, scope); }; FlagwindFeatureLayer.prototype.add = function (graphic) { this.layer.add(graphic); }; FlagwindFeatureLayer.prototype.remove = function (graphic) { this.layer.remove(graphic); }; return FlagwindFeatureLayer; }(flagwind.EventProvider)); flagwind.FlagwindFeatureLayer = FlagwindFeatureLayer; })(flagwind || (flagwind = {})); /// <reference path="./flagwind-feature.layer.ts" />import { resolve } from "dns"; /* tslint:disable:member-ordering */ var flagwind; (function (flagwind) { flagwind.BUSINESS_LAYER_OPTIONS = { onLayerClick: function (evt) { console.log("onLayerClick"); }, onMapLoad: function () { console.log("onMapLoad"); }, onEvent: function (eventName, evt) { console.log("onEvent"); }, onCheckChanged: function (evt) { console.log("onCheckChanged"); }, onPositionChanged: function (currentPoint, originPoint, item) { console.log("onPositionChanged"); }, onVisibleChanged: function (isShow) { console.log("onVisibleChanged"); }, changeStandardModel: function (model) { return model; }, getInfoWindowContext: function (mode) { return { title: "详细信息", content: "没有定制详细信息" }; }, /** * 获取图层 */ getDataList: function () { return new Promise(function (resolve, reject) { resolve([]); }); }, /** * 获取最新图层数据状态 */ getLastStatus: function () { return new Promise(function (resolve, reject) { resolve([]); }); }, showInfoWindowCompleted: null, timeout: 3000, autoInit: true, enableEdit: true, selectMode: 0, showTooltip: false, showInfoWindow: false, symbol: null, dataType: "point" }; /** * 业务图层 */ var FlagwindBusinessLayer = /** @class */ (function (_super) { __extends(FlagwindBusinessLayer, _super); function FlagwindBusinessLayer(flagwindMap, id, options) { var _this = _super.call(this, id, options.title || "设备图层") || this; _this.flagwindMap = flagwindMap; _this.id = id; _this.layerType = flagwind.LayerType.point; // point polyline polygon _this.isLoading = false; _this.options = __assign({}, flagwind.BUSINESS_LAYER_OPTIONS, options); _this.layer = _this.onCreateGraphicsLayer({ id: _this.id }); _this.layerType = options.layerType; _this.flagwindMap = flagwindMap; if (_this.options.autoInit) { _this.onInit(); } return _this; } Object.defineProperty(FlagwindBusinessLayer.prototype, "map", { // #region 属性 /** * 地图原生对象 */ get: function () { return this.flagwindMap.map; }, enumerable: true, configurable: true }); Object.defineProperty(FlagwindBusinessLayer.prototype, "spatial", { /** * 空间坐标系 */ get: function () { return this.flagwindMap.spatial; }, enumerable: true, configurable: true }); // #endregion // #region graphic操作 /** * 根据对象集合构造要素集合(无则新增,有则修改) * @param dataList 对象集合 */ FlagwindBusinessLayer.prototype.saveGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { this.saveGraphicByModel(dataList[i]); } }; /** * 根据对象集合修改要素集合(无则忽略) * @param dataList 对象集合 */ FlagwindBusinessLayer.prototype.updateGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { this.updateGraphicByModel(dataList[i]); } }; /** * 根据对象集合新增要素集合 * @param dataList 对象集合 */ FlagwindBusinessLayer.prototype.addGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { var graphic = this.getGraphicById(dataList[i].id); if (graphic) { console.warn("已存在id:" + dataList[i].id + "要素点"); continue; } this.addGraphicByModel(dataList[i]); } }; /** * 保存要素(有则修改,无则增加) * @param item 原始要素模型 */ FlagwindBusinessLayer.prototype.saveGraphicByModel = function (item) { item = this.onChangeStandardModel(item); if (!item || !item.id) return; var graphic = this.getGraphicById(item.id); if (graphic) { return this.updateGraphicByModel(item, graphic); } else { return this.addGraphicByModel(item); } }; /** * 创建并增加要素 */ FlagwindBusinessLayer.prototype.addGraphicByModel = function (item) { var graphic = this.creatGraphicByModel(item); if (graphic) { this.add(graphic); } }; /** * 创建要素(未添加至图层中),请方法在flagwind包下可见 */ FlagwindBusinessLayer.prototype.creatGraphicByModel = function (item) { item = this.onChangeStandardModel(item); if (!this.onValidModel(item)) { console.warn("无效的要素:" + item); return null; } // select属性为true表示当前选中,false表示未选中 if (item.selected === undefined) { item.selected = false; } var graphic = this.onCreatGraphicByModel(item); return graphic; }; /** * 修改要素 */ FlagwindBusinessLayer.prototype.updateGraphicByModel = function (item, graphic) { if (graphic === void 0) { graphic = null; } item = this.onChangeStandardModel(item); if (!this.onValidModel(item)) { return; } if (!graphic) { graphic = this.getGraphicById(item.id); } if (graphic == null) { return; } item = __assign({}, graphic.attributes, item); this.onUpdateGraphicByModel(item); }; // #endregion // #region 状态管理 /** * 清除选择状态 */ FlagwindBusinessLayer.prototype.clearSelectStatus = function () { var graphics = this.graphics; for (var i = 0; i < graphics.length; i++) { if (graphics[i].attributes.selected || typeof graphics[i].attributes.selected !== "boolean") { this.setSelectStatus(graphics[i].attributes, false); } } this.options.onCheckChanged({ target: graphics ? graphics.map(function (v) { return v.attributes; }) : [], check: false, selectedItems: this.getSelectedGraphics().map(function (g) { return g.attributes; }) }); }; /** * 设置选择状态 * @param dataList 要素模型集合 * @param refresh 是否刷新(为true是时,把所有的要素还原再设置;否则,之前的状态保留,然后再追加) */ FlagwindBusinessLayer.prototype.setSelectStatusByModels = function (dataList, refresh) { if (refresh) { this.clearSelectStatus(); } for (var i = 0; i < dataList.length; i++) { var model = this.onChangeStandardModel(dataList[i]); var graphic = this.getGraphicById(model.id); if (graphic) { this.setSelectStatus(graphic.attributes, true); } } this.options.onCheckChanged({ target: dataList, check: true, selectedItems: this.getSelectedGraphics().map(function (g) { return g.attributes; }) }); }; /** * 获取所有选中的要素 */ FlagwindBusinessLayer.prototype.getSelectedGraphics = function () { return this.graphics.filter(function (g) { return g.attributes && g.attributes.selected; }); }; /** * 设置选中状态 * @param item 要素原型 * @param selected 是否选中 */ FlagwindBusinessLayer.prototype.setSelectStatus = function (item, selected) { item.selected = selected; this.onUpdateGraphicByModel(item); }; // #endregion // #region 坐标转换 /** * 创建点要素(把业务数据的坐标转换成地图上的点) */ FlagwindBusinessLayer.prototype.getPoint = function (item) { return this.flagwindMap.getPoint(item); }; /** * 把地图上的点转换成业务的坐标 * @param {*} point */ FlagwindBusinessLayer.prototype.formPoint = function (point) { return this.flagwindMap.onFormPoint(point); }; // #endregion // #region 常规操作 /** * 在指定id的graphic上打开InfoWindow * @param id grahpic的唯一标识 * @param context 内容 * @param options 参数 */ FlagwindBusinessLayer.prototype.openInfoWindow = function (id, context, options) { var graphic = this.getGraphicById(id); if (!graphic) { console.warn("该条数据不在图层内!id:", id); return; } if (context) { this.flagwindMap.onShowInfoWindow({ graphic: graphic, context: context, options: options || {} }); } else { this.showInfoWindow({ graphic: graphic }); } }; /** * 关闭信息窗口 */ FlagwindBusinessLayer.prototype.closeInfoWindow = function () { this.flagwindMap.closeInfoWindow(); }; /** * 定位至指定id的点 * @param id */ FlagwindBusinessLayer.prototype.gotoCenterById = function (id) { var graphic = this.getGraphicById(id); if (!graphic) { console.trace("-----该条数据不在图层内!id:", id); return; } var pt = this.getPoint(graphic.attributes); this.flagwindMap.centerAt(pt.x, pt.y); }; /** * 增加到地图上 */ FlagwindBusinessLayer.prototype.addToMap = function () { this.onAddLayerBefor(); this.flagwindMap.addFeatureLayer(this); this.onAddLayerAfter(); }; /** * 从地图移除 */ FlagwindBusinessLayer.prototype.removeFromMap = function () { this.flagwindMap.removeFeatureLayer(this.id); }; /** * 显示InfoWindow(在flagwind包下可用,对外不要调用此方法) * @param args */ FlagwindBusinessLayer.prototype.showInfoWindow = function (evt) { var context = this.onGetInfoWindowContext(evt.graphic.attributes); this.flagwindMap.onShowInfoWindow({ graphic: evt.graphic, context: { type: "html", title: context.title, content: context.content }, options: {} }); if (this.options.showInfoWindowCompleted) { this.options.showInfoWindowCompleted(evt.graphic.attributes); } }; // #endregion // #region 数据加载 /** * 加载并显示设备点位 * */ FlagwindBusinessLayer.prototype.showDataList = function () { var _this = this; this.isLoading = true; this.fireEvent("showDataList", { action: "start" }); return this.options.getDataList() .then(function (dataList) { _this.isLoading = false; _this.saveGraphicList(dataList); _this.fireEvent("showDataList", { action: "end", attributes: dataList }); }) .catch(function (error) { _this.isLoading = false; console.log("加载图层数据时发生了错误:", error); _this.fireEvent("showDataList", { action: "error", attributes: error }); }); }; /** * 开启定时器 */ FlagwindBusinessLayer.prototype.start = function () { var _this = this; this.timer = setInterval(function () { _this.updateStatus(); }, this.options.timeout || 20000); }; /** * 关闭定时器 */ FlagwindBusinessLayer.prototype.stop = function () { if (this.timer) { clearInterval(this.timer); } }; /** * 更新设备状态 */ FlagwindBusinessLayer.prototype.updateStatus = function () { var _this = this; this.isLoading = true; this.fireEvent("updateStatus", { action: "start" }); this.options.getLastStatus().then(function (dataList) { _this.isLoading = false; _this.saveGraphicList(dataList); _this.fireEvent("updateStatus", { action: "end", attributes: dataList }); }).catch(function (error) { _this.isLoading = false; console.log("加载卡口状态时发生了错误:", error); _this.fireEvent("updateStatus", { action: "error", attributes: error }); }); }; // #endregion // #region 内部方法 FlagwindBusinessLayer.prototype.onGetInfoWindowContext = function (item) { return this.options.getInfoWindowContext(item); }; FlagwindBusinessLayer.prototype.onInit = function () { var _this = this; this.addToMap(); if (this.flagwindMap.loaded) { this.onLoad(); } else { this.flagwindMap.on("onLoad", function () { return _this.onLoad(); }); } }; FlagwindBusinessLayer.prototype.onAddLayerBefor = function () { // console.log("onAddLayerBefor"); }; FlagwindBusinessLayer.prototype.onAddLayerAfter = function () { // console.log("onAddLayerAfter"); }; FlagwindBusinessLayer.prototype.onLoad = function () { try { if (!this.layer._map) { this.layer._map = this.flagwindMap.innerMap; } this.registerEvent(); this.onMapLoad(); } catch (error) { console.error(error); } }; FlagwindBusinessLayer.prototype.onMapLoad = function () { this.options.onMapLoad(); }; FlagwindBusinessLayer.prototype.registerEvent = function () { var _this = this; this.on("onClick", function (evt) { _this.onLayerClick(_this, evt.data); }); // 如果开启鼠标hover开关 this.on("onMouseOver", function (evt) { if (_this.options.showTooltip) { _this.flagwindMap.onShowTooltip(evt.data.graphic); } _this.fireEvent("onMouseOver", evt.data); }); this.on("onMouseOut", function (evt) { if (_this.options.showTooltip) { _this.flagwindMap.onHideTooltip(); } _this.fireEvent("onMouseOut", evt.data); }); }; FlagwindBusinessLayer.prototype.onLayerClick = function (deviceLayer, evt) { if (deviceLayer.options.onLayerClick) { deviceLayer.options.onLayerClick(evt); } if (deviceLayer.options.showInfoWindow) { evt.graphic.attributes.eventName = ""; deviceLayer.showInfoWindow(evt); } if (deviceLayer.options.selectMode) { if (deviceLayer.options.selectMode === flagwind.SelectMode.multiple) { var item = evt.graphic.attributes; if (evt.graphic.attributes.selected) { deviceLayer.setSelectStatus(item, false); } else { deviceLayer.setSelectStatus(item, true); } } else { deviceLayer.clearSelectStatus(); var item = evt.graphic.attributes; deviceLayer.setSelectStatus(item, true); } deviceLayer.options.onCheckChanged({ target: [evt.graphic.attributes], check: evt.graphic.attributes.selected, selectedItems: deviceLayer.getSelectedGraphics() }); } }; FlagwindBusinessLayer.prototype.fireEvent = function (eventName, event) { this.options.onEvent(eventName, event); }; FlagwindBusinessLayer.prototype.onValidModel = function (item) { switch (this.layerType) { case flagwind.LayerType.point: return item.id && item.longitude && item.latitude; case flagwind.LayerType.polyline: return item.id && item.polyline; case flagwind.LayerType.polygon: return item.id && item.polygon; default: return item.id && item.longitude && item.latitude; } }; /** * 变换成标准实体 * * @protected * @param {*} item * @returns {{ id: String, name: String, longitude: number, latitude: number }} * @memberof FlagwindBusinessLayer */ FlagwindBusinessLayer.prototype.onChangeStandardModel = function (item) { return this.options.changeStandardModel(item); }; return FlagwindBusinessLayer; }(flagwind.FlagwindFeatureLayer)); flagwind.FlagwindBusinessLayer = FlagwindBusinessLayer; })(flagwind || (flagwind = {})); /// <reference path="../base/flagwind-business.layer.ts" />; var flagwind; (function (flagwind) { flagwind.ESRI_CLUSTER_LAYER_OPTIONS = { onEvent: function (eventName, evt) { switch (eventName) { case "onMouseOver": if (evt.graphic.getNode()) evt.graphic.getNode().classList.add("marker-scale"); break; case "onMouseOut": if (evt.graphic.getNode()) evt.graphic.getNode().classList.remove("marker-scale"); break; } }, symbol: { width: 32, height: 32 }, enableCluster: true, cluster: { font: { color: "#FF0000", outline: null, size: 6 }, singleFlareAtCount: 10, flareShowMode: "mouse", preClustered: false, ratio: 75, areaDisplay: false, levels: { xl: { start: 1001, end: Infinity, size: 32, color: { line: [200, 52, 59, 0.8], fill: [250, 65, 74, 0.8] } }, lg: { start: 151, end: 1000, size: 28, color: { line: [41, 163, 41, 0.8], fill: [51, 204, 51, 0.8] } }, md: { start: 20, end: 150, size: 24, color: { line: [82, 163, 204, 0.8], fill: [102, 204, 255, 0.8] } }, sm: { start: 0, end: 19, size: 22, color: { line: [230, 184, 92, 0.8], fill: [255, 204, 102, 0.8] } } }, clusteringBegin: function () { console.log("clustering begin"); }, clusteringComplete: function () { console.log("clustering complete"); } }, layerType: "point" }; /** * 点图层 */ var EsriClusterLayer = /** @class */ (function (_super) { __extends(EsriClusterLayer, _super); function EsriClusterLayer(flagwindMap, id, options) { var _this = _super.call(this, flagwindMap, id, __assign({}, flagwind.ESRI_CLUSTER_LAYER_OPTIONS, options)) || this; if (_this.options.enableCluster) { _this.dataManager = new flagwind.DataManager(); } return _this; } EsriClusterLayer.prototype.onCreateGraphicsLayer = function (args) { var _this = this; var layer; if (this.enableCluster) { layer = this.createClusterLayer(this.options.cluster); } else { layer = new esri.layers.GraphicsLayer(args); } layer.on("mouse-over", function (evt) { return _this.dispatchEvent("onMouseOver", evt); }); layer.on("mouse-out", function (evt) { return _this.dispatchEvent("onMouseOut", evt); }); layer.on("mouse-up", function (evt) { return _this.dispatchEvent("onMouseUp", evt); }); layer.on("mouse-down", function (evt) { return _this.dispatchEvent("onMouseDown", evt); }); layer.on("click", function (evt) { return _this.dispatchEvent("onClick", evt); }); layer.on("dbl-click", function (evt) { return _this.dispatchEvent("onDblClick", evt); }); layer.addToMap = function (map) { map.addLayer(this); }; layer.removeFromMap = function (map) { try { if (!this._map) { this._map = map; } map.removeLayer(this); } catch (error) { console.warn(error); } }; return layer; }; EsriClusterLayer.prototype.createClusterLayer = function (options) { // init the layer, more options are available and explained in the cluster layer constructor var layer = new esri.layers.ClusterLayer(__assign({ id: this.id, spatialReference: this.flagwindMap.spatial, xPropertyName: "longitude", yPropertyName: "latitude", subTypeFlareProperty: "kind", singleFlareTooltipProperty: "" }, options)); // set up a class breaks renderer to render different symbols based on the cluster count. Use the required clusterCount property to break on. var defaultSym = new esri.symbol.SimpleMarkerSymbol().setSize(6).setColor(options.font.color).setOutline(options.font.outline); var renderer = new esri.renderer.ClassBreaksRenderer(defaultSym, "clusterCount"); var xlSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, options.levels.xl.size, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.xl.color.line), 1), new dojo.Color(options.levels.xl.color.fill)); var lgSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, options.levels.lg.size, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.lg.color.line), 1), new dojo.Color(options.levels.lg.color.fill)); var mdSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, options.levels.md.size, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.md.color.line), 1), new dojo.Color(options.levels.md.color.fill)); var smSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, options.levels.sm.size, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.sm.color.line), 1), new dojo.Color(options.levels.sm.color.fill)); renderer.addBreak(options.levels.sm.start, options.levels.sm.end, smSymbol); renderer.addBreak(options.levels.md.start, options.levels.md.end, mdSymbol); renderer.addBreak(options.levels.lg.start, options.levels.lg.end, lgSymbol); renderer.addBreak(options.levels.xl.start, options.levels.xl.end, xlSymbol); if (options.areaDisplay) { // if area display mode is set. Create a renderer to display cluster areas. Use SimpleFillSymbols as the areas are polygons var defaultAreaSym = new esri.symbol.SimpleFillSymbol().setStyle(esri.symbol.SimpleFillSymbol.STYLE_SOLID).setColor(new dojo.Color([0, 0, 0, 0.2])).setOutline(new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0, 0.3]), 1)); var areaRenderer = new esri.renderer.ClassBreaksRenderer(defaultAreaSym, "clusterCount"); var xlAreaSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.xl.color.line), 1), new dojo.Color(options.levels.xl.color.fill)); var lgAreaSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.lg.color.line), 1), new dojo.Color(options.levels.lg.color.fill)); var mdAreaSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.md.color.line), 1), new dojo.Color(options.levels.md.color.fill)); var smAreaSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color(options.levels.sm.color.line), 1), new dojo.Color(options.levels.sm.color.fill)); areaRenderer.addBreak(options.levels.sm.start, options.levels.sm.end, smAreaSymbol); areaRenderer.addBreak(options.levels.md.start, options.levels.md.end, mdAreaSymbol); areaRenderer.addBreak(options.levels.lg.start, options.levels.lg.end, lgAreaSymbol); areaRenderer.addBreak(options.levels.xl.start, options.levels.xl.end, xlAreaSymbol); // use the custom overload of setRenderer to include the renderer for areas. layer.setRenderer(renderer, areaRenderer); } else { layer.setRenderer(renderer); // use standard setRenderer. } // 初始化数据仓库 layer.allData = []; // 创建graphic仓库 layer._graphics = []; return layer; }; EsriClusterLayer.prototype.addClusters = function () { var datas = this.graphics.map(function (g) { return g.attributes; }); this.layer.clear(); this.dataManager.setData(datas); if (this.options.cluster.preClustered) { this.getPreClusteredGraphics(); } else { var list = this.dataManager.getData(); this.layer.addData(list); } }; EsriClusterLayer.prototype.getPreClusteredGraphics = function () { var clusterOptions = this.options; var maxSingleFlareCount = clusterOptions.displaySingleFlaresAtCount; var clusterRatio = clusterOptions.ratio; var clusteredData = this.dataManager.clientSideClustering(clusterRatio, maxSingleFlareCount, clusterOptions.areaDisplay, this.flagwindMap.map); this.layer.addPreClusteredData(clusteredData); }; EsriClusterLayer.prototype.getImageUrl = function (item) { var imageUrl = this.options.symbol.imageUrl; if (typeof imageUrl === "string" && imageUrl) { var key = "imageUrl" + (item.status || "") + (item.selected ? "checked" : ""); var statusImageUrl = this.options[key] || this.options.symbol[key] || imageUrl; var suffixIndex = statusImageUrl.lastIndexOf("."); var path = statusImageUrl.substring(0, suffixIndex); var suffix = statusImageUrl.substring(suffixIndex + 1); if (item.selected) { return path + "_checked." + suffix; } else { return path + "." + suffix; } } else { var status_1 = item.status; if (status_1 === undefined || status_1 === null) { status_1 = ""; } var key = "image" + status_1 + (item.selected ? "checked" : ""); return (this.options[key] || this.options.symbol[key] || this.options.image); } }; Object.defineProperty(EsriClusterLayer.prototype, "enableCluster", { get: function () { return (this.options.enableCluster); }, enumerable: true, configurable: true }); Object.defineProperty(EsriClusterLayer.prototype, "singles", { get: function () { return this.layer.singles || []; }, enumerable: true, configurable: true }); Object.defineProperty(EsriClusterLayer.prototype, "clusters", { get: function () { return this.layer.clusters || []; }, enumerable: true, configurable: true }); Object.defineProperty(EsriClusterLayer.prototype, "graphics", { get: function () { if (this.enableCluster) { return this.layer._graphics; } else { return this.layer.graphics; } }, enumerable: true, configurable: true }); EsriClusterLayer.prototype.saveGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { this.saveGraphicByModel(dataList[i]); } if (this.enableCluster) { this.addClusters(); } }; EsriClusterLayer.prototype.addGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { this.addGraphicByModel(dataList[i]); } if (this.enableCluster) { this.addClusters(); } }; /** * 根据对象集合修改要素集合(无则忽略) * @param dataList 对象集合 */ EsriClusterLayer.prototype.updateGraphicList = function (dataList) { for (var i = 0; i < dataList.length; i++) { this.updateGraphicByModel(dataList[i]); } if (this.enableCluster) { this.addClusters(); } }; /** * 创建要素方法 * @param item 实体信息 */ EsriClusterLayer.prototype.onCreatGraphicByModel = function (item) { var iconUrl = this.getImageUrl(item); var pt = this.getPoint(item); var width = this.