flagwind-map
Version:
flagwind map library
1,230 lines (1,229 loc) • 361 kB
JavaScript
/*!
* 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.