2019-07-08 09:38:39 +08:00
|
|
|
import * as zrUtil from 'zrender/src/core/util';
|
2019-07-09 19:04:45 +08:00
|
|
|
import zrender from 'zrender';
|
2019-07-03 14:29:09 +08:00
|
|
|
import Painter from './painter';
|
2019-07-10 12:02:02 +08:00
|
|
|
import Options from './options';
|
2019-07-09 19:04:45 +08:00
|
|
|
import MouseController from './mouseController';
|
2019-07-16 13:34:03 +08:00
|
|
|
import deviceState from './constant/deviceState';
|
2019-07-15 09:38:35 +08:00
|
|
|
import { selectSkinStyle } from './config/deviceStyle';
|
2019-07-16 13:34:03 +08:00
|
|
|
import deviceType from './constant/deviceType';
|
2019-07-25 10:32:29 +08:00
|
|
|
import { parser, deviceFactory, createBoundingRect, calculateDCenter } from './utils/parser';
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
const renderer = 'canvas';
|
2019-07-22 15:43:42 +08:00
|
|
|
const devicePixelRatio = 1;
|
2019-07-09 19:04:45 +08:00
|
|
|
|
2019-07-25 10:32:29 +08:00
|
|
|
class Jlmap {
|
2019-07-04 10:59:40 +08:00
|
|
|
constructor(opts) {
|
2019-07-09 09:24:54 +08:00
|
|
|
// 回调事件
|
|
|
|
this.methods = opts.methods;
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
// 鼠标事件
|
2019-07-25 18:25:04 +08:00
|
|
|
this.events = { __Pan: 'pan', __Zoom: 'zoom', Selected: 'selected', Contextmenu: 'contextmenu', DataZoom: 'dataZoom'};
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 原始数据
|
|
|
|
this.data = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 皮肤参数
|
|
|
|
this.skinStyle = '';
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 皮肤风格
|
|
|
|
this.styleDict = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 设备数据
|
|
|
|
this.mapDevice = {};
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
// 默认状态
|
|
|
|
this.defaultStateDict = this.loadDefaultState();
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
this.initMapInstance(opts);
|
|
|
|
}
|
|
|
|
|
2019-07-11 17:58:58 +08:00
|
|
|
// 初始化属性有鼠标事件 缩放等
|
2019-07-10 12:02:02 +08:00
|
|
|
initMapInstance(opts) {
|
2019-07-11 17:58:58 +08:00
|
|
|
const width = opts.dom.clientWidth;
|
|
|
|
const height = opts.dom.clientHeight;
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$zr = zrender.init(opts.dom, Object.assign({ renderer, devicePixelRatio, width, height }, opts.config));
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
this.$options = new Options(Object.assign({ scaleRate: 1, offsetX: 0, offsetY: 0 }, opts.options || {}), (dataZoom) => { this.$mouseController.trigger(this.events.DataZoom, dataZoom); }); // 缩放
|
2019-07-19 11:11:34 +08:00
|
|
|
this.$painter = new Painter(this);
|
2019-07-19 18:01:42 +08:00
|
|
|
this.$painter.updateZrSize({width: this.$zr.getWidth(), height: this.$zr.getHeight()});
|
2019-07-19 11:11:34 +08:00
|
|
|
this.$painter.updateTransform(this.$options);
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
this.optionsHandler = this.setOptions.bind(this);
|
2019-07-19 13:54:23 +08:00
|
|
|
|
2019-07-10 13:17:12 +08:00
|
|
|
this.$mouseController = new MouseController(this);
|
|
|
|
this.$mouseController.enable();
|
2019-07-10 12:02:02 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
this.$mouseController.on(this.events.__Pan, this.optionsHandler);
|
|
|
|
this.$mouseController.on(this.events.__Zoom, this.optionsHandler);
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
2019-07-03 14:29:09 +08:00
|
|
|
|
2019-07-25 14:03:26 +08:00
|
|
|
loadStyle(skinStyle) {
|
|
|
|
return selectSkinStyle(skinStyle);
|
|
|
|
}
|
|
|
|
|
|
|
|
loadDefaultState() {
|
|
|
|
const defaultStateDict = {};
|
|
|
|
|
|
|
|
zrUtil.each(Object.keys(deviceState), (type) => {
|
|
|
|
defaultStateDict[type] = {};
|
|
|
|
zrUtil.each(Object.keys(deviceState[type] || {}), (state) => {
|
|
|
|
defaultStateDict[type][state] = deviceState[type][state].Default;
|
|
|
|
}, this);
|
|
|
|
}, this);
|
|
|
|
|
|
|
|
return defaultStateDict;
|
|
|
|
}
|
|
|
|
|
2019-07-25 10:32:29 +08:00
|
|
|
setMap(map) {
|
2019-07-09 19:04:45 +08:00
|
|
|
// 保存皮肤类型
|
2019-07-25 18:25:04 +08:00
|
|
|
if (map.skinVO) {
|
|
|
|
this.skinStyle = map.skinVO.code;
|
|
|
|
}
|
2019-07-09 19:04:45 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 保存原始数据
|
2019-07-25 10:32:29 +08:00
|
|
|
this.data = map;
|
2019-07-04 10:59:40 +08:00
|
|
|
|
2019-07-18 18:25:57 +08:00
|
|
|
// 加载对应皮肤
|
2019-07-10 13:24:03 +08:00
|
|
|
this.styleDict = this.loadStyle(this.skinStyle);
|
2019-07-04 11:00:52 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 解析地图数据
|
2019-07-25 10:32:29 +08:00
|
|
|
this.mapDevice = parser(map, this);
|
2019-07-04 10:59:40 +08:00
|
|
|
|
2019-07-18 18:25:57 +08:00
|
|
|
// 数据加载完成 回调
|
2019-07-25 18:25:04 +08:00
|
|
|
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(this.mapDevice); }
|
2019-07-08 09:38:39 +08:00
|
|
|
|
2019-07-04 10:59:40 +08:00
|
|
|
// 初次渲染视图
|
2019-07-18 18:25:57 +08:00
|
|
|
this.$painter.repaint(this.mapDevice);
|
2019-07-08 09:38:39 +08:00
|
|
|
|
2019-07-18 18:25:57 +08:00
|
|
|
// 视图加载完成 回调
|
2019-07-25 18:25:04 +08:00
|
|
|
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(this.mapDevice); }
|
2019-07-26 10:38:57 +08:00
|
|
|
|
2019-07-04 11:00:52 +08:00
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
setDefaultState() {
|
2019-07-11 17:58:58 +08:00
|
|
|
const list = [];
|
2019-07-09 19:04:45 +08:00
|
|
|
|
|
|
|
Object.values(this.mapDevice).forEach(elem => {
|
2019-07-11 17:58:58 +08:00
|
|
|
const code = elem._code;
|
|
|
|
const type = elem._type;
|
2019-07-09 19:04:45 +08:00
|
|
|
list.push(Object.assign({ code, type }, this.defaultStateDict[type]));
|
2019-07-11 17:58:58 +08:00
|
|
|
});
|
2019-07-09 19:04:45 +08:00
|
|
|
|
|
|
|
this.update(list);
|
2019-07-10 16:04:17 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
if (this.methods.stateLoaded instanceof Function) { this.methods.stateLoaded(list); }
|
2019-07-09 19:04:45 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
setOptions(opts) {
|
2019-07-19 15:17:58 +08:00
|
|
|
const options = this.pullBack(opts);
|
|
|
|
this.$options.update(options);
|
2019-07-19 11:11:34 +08:00
|
|
|
this.$painter.updateTransform(this.$options);
|
2019-07-19 15:15:51 +08:00
|
|
|
|
2019-07-19 13:54:23 +08:00
|
|
|
if (this.$options.disabled == true) {
|
|
|
|
this.$mouseController.disable();
|
|
|
|
} else {
|
|
|
|
this.$mouseController.enable(opts);
|
|
|
|
}
|
2019-07-19 15:15:51 +08:00
|
|
|
|
2019-07-25 13:24:40 +08:00
|
|
|
if (this.methods.optionsUpdate instanceof Function) { this.methods.optionsUpdate(this.$options); }
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 10:32:29 +08:00
|
|
|
setCenter(deviceCode) {
|
|
|
|
const device = this.mapDevice[deviceCode];
|
|
|
|
if (device && device.instance) {
|
|
|
|
var rect = createBoundingRect(device.instance);
|
2019-07-26 15:52:50 +08:00
|
|
|
var dcenter = calculateDCenter(rect, { width: this.$zr.getWidth(), height: this.$zr.getHeight() });
|
|
|
|
this.setOptions(dcenter);
|
2019-07-25 10:32:29 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-25 15:44:23 +08:00
|
|
|
setLayerVisible(layer) {
|
|
|
|
this.$painter.setLayerVisible(layer);
|
|
|
|
}
|
|
|
|
|
2019-07-19 09:40:22 +08:00
|
|
|
setLevelVisible(list, show) {
|
|
|
|
this.$painter.setLevelVisible(list, show);
|
2019-07-15 14:14:44 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 18:39:30 +08:00
|
|
|
render(list) {
|
|
|
|
(list || []).forEach(elem => {
|
2019-07-11 17:58:58 +08:00
|
|
|
const type = elem.type;
|
|
|
|
const code = elem.code;
|
2019-07-18 17:21:18 +08:00
|
|
|
const oDevice = this.mapDevice[code] || deviceFactory(type, this.styleDict[type], elem);
|
|
|
|
const model = Object.assign(oDevice.model || {}, elem);
|
2019-07-18 18:24:40 +08:00
|
|
|
this.dataSync(model, model._dispose, !this.mapDevice[code]);
|
2019-07-18 17:21:18 +08:00
|
|
|
this.$painter.delete(oDevice);
|
2019-07-04 18:39:30 +08:00
|
|
|
if (!elem._dispose) {
|
2019-07-18 17:21:18 +08:00
|
|
|
const nDevice = Object.assign(oDevice, { model });
|
|
|
|
this.mapDevice[code] = nDevice;
|
|
|
|
this.$painter.add(nDevice);
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
2019-07-11 17:58:58 +08:00
|
|
|
});
|
2019-07-10 16:04:17 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
if (this.methods.viewUpdate instanceof Function) { this.methods.viewUpdate(list); }
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
update(list) {
|
|
|
|
(list || []).forEach(elem => {
|
2019-07-11 17:58:58 +08:00
|
|
|
const code = elem.code;
|
2019-07-18 18:25:57 +08:00
|
|
|
const oDevice = this.mapDevice[code] || {};
|
2019-07-04 18:39:30 +08:00
|
|
|
if (elem._dispose) {
|
2019-07-18 18:25:57 +08:00
|
|
|
this.$painter.delete(oDevice);
|
2019-07-04 18:39:30 +08:00
|
|
|
} else {
|
2019-07-18 17:21:18 +08:00
|
|
|
const state = Object.assign(oDevice.state || {}, elem);
|
|
|
|
const nDevice = Object.assign(oDevice, { state });
|
|
|
|
this.$painter.update(nDevice);
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
2019-07-11 17:58:58 +08:00
|
|
|
});
|
2019-07-10 16:04:17 +08:00
|
|
|
|
2019-07-25 18:25:04 +08:00
|
|
|
if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(list); }
|
2019-07-10 16:04:17 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 15:44:23 +08:00
|
|
|
pullBack(payload) {
|
|
|
|
if (payload.type === 'zoom') {
|
|
|
|
const zrWidth = this.$zr.getWidth();
|
|
|
|
const zrHeight = this.$zr.getHeight();
|
|
|
|
const originX = payload.originX || zrWidth / 2;
|
|
|
|
const originY = payload.originY || zrHeight / 2;
|
|
|
|
const x = (this.$options.offsetX + originX) / this.$options.scaleRate;
|
|
|
|
const y = (this.$options.offsetY + originY) / this.$options.scaleRate;
|
|
|
|
const newScaleRate = this.$options.getScaleRate(payload.scale);
|
|
|
|
const dx = originX - (x * newScaleRate - this.$options.offsetX);
|
|
|
|
const dy = originY - (y * newScaleRate - this.$options.offsetY);
|
|
|
|
payload.dx = dx;
|
|
|
|
payload.dy = dy;
|
|
|
|
}
|
|
|
|
|
|
|
|
return payload || {};
|
|
|
|
}
|
|
|
|
|
2019-07-18 18:24:40 +08:00
|
|
|
dataSync(model, isDel, isAdd) {
|
2019-07-11 17:58:58 +08:00
|
|
|
const code = model.code;
|
|
|
|
const type = model.type;
|
2019-07-10 16:04:17 +08:00
|
|
|
|
|
|
|
let prop = null;
|
|
|
|
switch (type) {
|
2019-07-11 17:58:58 +08:00
|
|
|
case deviceType.Link: prop = 'linkList'; break;
|
2019-07-15 10:07:04 +08:00
|
|
|
case deviceType.Sction: prop = 'sectionList'; break;
|
2019-07-16 09:44:31 +08:00
|
|
|
case deviceType.Switch: prop = 'switchList'; break;
|
|
|
|
case deviceType.Signal: prop = 'signalList'; break;
|
2019-07-15 15:25:49 +08:00
|
|
|
case deviceType.Station: prop = 'stationList'; break;
|
2019-07-16 09:44:31 +08:00
|
|
|
case deviceType.StationStand: prop = 'stationStandList'; break;
|
2019-07-15 15:25:49 +08:00
|
|
|
case deviceType.StationControl: prop = 'stationControlList'; break;
|
2019-07-16 09:44:31 +08:00
|
|
|
case deviceType.StationCounter: prop = 'stationCounterList'; break;
|
|
|
|
case deviceType.ZcControl: prop = 'zcControlList'; break;
|
|
|
|
case deviceType.StationDelayUnlock: prop = 'stationDelayUnlockList'; break;
|
|
|
|
case deviceType.LcControl: prop = 'lcControlList'; break;
|
2019-07-15 15:25:49 +08:00
|
|
|
case deviceType.LimitControl: prop = 'tempSpeedLimitList'; break;
|
2019-07-16 09:44:31 +08:00
|
|
|
case deviceType.ImageControl: prop = 'imageControl'; break;
|
|
|
|
case deviceType.Train: prop = 'trainList'; break;
|
|
|
|
case deviceType.TrainWindow: prop = 'trainWindowList'; break;
|
|
|
|
case deviceType.Line: prop = 'lineList'; break;
|
|
|
|
case deviceType.Text: prop = 'textList'; break;
|
2019-07-10 16:04:17 +08:00
|
|
|
}
|
|
|
|
|
2019-07-11 17:58:58 +08:00
|
|
|
const list = this.data[prop];
|
2019-07-10 16:04:17 +08:00
|
|
|
if (list) {
|
2019-07-18 18:24:40 +08:00
|
|
|
if (isAdd) {
|
2019-07-10 16:04:17 +08:00
|
|
|
list.push(model);
|
|
|
|
}
|
2019-07-18 18:24:40 +08:00
|
|
|
if (isDel) {
|
|
|
|
const idex = list.findIndex(elem => { return elem.code == code; });
|
|
|
|
if (idex >= 0) {
|
|
|
|
list.splice(idex, 1);
|
|
|
|
}
|
|
|
|
}
|
2019-07-10 16:04:17 +08:00
|
|
|
}
|
2019-07-04 18:39:30 +08:00
|
|
|
}
|
|
|
|
|
2019-07-09 19:04:45 +08:00
|
|
|
getZr() {
|
2019-07-10 13:17:12 +08:00
|
|
|
return this.$zr;
|
2019-07-09 19:04:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
getEvents() {
|
2019-07-15 09:38:35 +08:00
|
|
|
return this.events;
|
2019-07-04 10:59:40 +08:00
|
|
|
}
|
|
|
|
|
2019-07-04 18:39:30 +08:00
|
|
|
getSkinStyle() {
|
|
|
|
return this.skinStyle;
|
|
|
|
}
|
|
|
|
|
2019-07-15 09:38:35 +08:00
|
|
|
getStyleDict() {
|
2019-07-04 18:39:30 +08:00
|
|
|
return this.styleDict;
|
|
|
|
}
|
|
|
|
|
|
|
|
getDefaultStateDict() {
|
|
|
|
return this.defaultStateDict;
|
|
|
|
}
|
|
|
|
|
2019-07-15 14:01:57 +08:00
|
|
|
getDeviceByCode(code) {
|
|
|
|
return this.mapDevice[code];
|
|
|
|
}
|
|
|
|
|
2019-07-19 11:11:34 +08:00
|
|
|
resize(opt) {
|
|
|
|
this.$zr.resize(opt);
|
2019-07-25 10:30:30 +08:00
|
|
|
this.$painter.updateZrSize(opt);
|
2019-07-19 11:11:34 +08:00
|
|
|
}
|
|
|
|
|
2019-07-10 16:04:17 +08:00
|
|
|
refresh() {
|
|
|
|
this.$painter.refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
clear() {
|
|
|
|
this.$painter.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
dispose() {
|
2019-07-15 09:38:35 +08:00
|
|
|
this.off(this.events.Pan, this.optionsHandler);
|
|
|
|
this.off(this.events.Zoom, this.optionsHandler);
|
2019-07-10 16:04:17 +08:00
|
|
|
|
|
|
|
this.skinStyle = '';
|
|
|
|
this.styleDict = {};
|
|
|
|
this.mapDevice = {};
|
|
|
|
|
2019-07-15 09:38:35 +08:00
|
|
|
this.$mouseController.dispose();
|
2019-07-10 16:04:17 +08:00
|
|
|
this.$zr && zrender.dispose(this.$zr);
|
|
|
|
this.$painter.dispose();
|
|
|
|
}
|
|
|
|
|
2019-07-10 12:02:02 +08:00
|
|
|
on(eventname, cb, context) {
|
2019-07-15 09:38:35 +08:00
|
|
|
const idx = Object.values(this.events).indexOf(eventname);
|
2019-07-10 12:02:02 +08:00
|
|
|
if (idx >= 0) {
|
|
|
|
switch (eventname) {
|
2019-07-25 10:32:29 +08:00
|
|
|
case this.events.Selected:
|
2019-07-15 10:58:31 +08:00
|
|
|
this.$mouseController.on(this.events.Selected, cb, context);
|
2019-07-11 17:58:58 +08:00
|
|
|
break;
|
2019-07-25 10:32:29 +08:00
|
|
|
case this.events.Contextmenu:
|
2019-07-15 10:58:31 +08:00
|
|
|
this.$mouseController.on(this.events.Contextmenu, cb, context);
|
2019-07-11 17:58:58 +08:00
|
|
|
break;
|
2019-07-25 18:25:04 +08:00
|
|
|
case this.events.DataZoom:
|
|
|
|
this.$mouseController.on(this.events.DataZoom, cb, context);
|
|
|
|
break;
|
2019-07-10 12:02:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
off(eventname, cb) {
|
2019-07-15 09:38:35 +08:00
|
|
|
const idx = Object.values(this.events).indexOf(eventname);
|
2019-07-10 12:02:02 +08:00
|
|
|
if (idx >= 0) {
|
|
|
|
switch (eventname) {
|
2019-07-25 10:32:29 +08:00
|
|
|
case this.events.Selected:
|
2019-07-15 10:58:31 +08:00
|
|
|
this.$mouseController.off(this.events.Selected, cb);
|
2019-07-11 17:58:58 +08:00
|
|
|
break;
|
2019-07-25 10:32:29 +08:00
|
|
|
case this.events.Contextmenu:
|
2019-07-15 10:58:31 +08:00
|
|
|
this.$mouseController.off(this.events.Contextmenu, cb);
|
2019-07-11 17:58:58 +08:00
|
|
|
break;
|
2019-07-25 18:25:04 +08:00
|
|
|
case this.events.DataZoom:
|
|
|
|
this.$mouseController.off(this.events.DataZoom, cb);
|
|
|
|
break;
|
2019-07-10 12:02:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-26 15:45:30 +08:00
|
|
|
clearTrainView() {
|
|
|
|
for (const code in this.mapDevice) {
|
|
|
|
if (this.mapDevice[code]._type === deviceType.Train) {
|
|
|
|
this.$painter.delete(this.mapDevice[code]);
|
|
|
|
delete this.mapDevice[code];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-07-03 14:29:09 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 10:32:29 +08:00
|
|
|
export default Jlmap;
|