rt-sim-training-client/src/jmap/map.js

283 lines
6.5 KiB
JavaScript
Raw Normal View History

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-03 14:29:09 +08:00
import ProxyHandle from './proxyHandle';
2019-07-09 19:04:45 +08:00
import MouseController from './mouseController';
2019-07-03 18:41:00 +08:00
import deviceState from './config/deviceState';
2019-07-15 09:38:35 +08:00
import { selectSkinStyle } from './config/deviceStyle';
2019-07-04 18:39:30 +08:00
import deviceType from './config/deviceType';
import { parser, deviceFactory } from './utils/parser';
2019-07-03 14:29:09 +08:00
2019-07-09 19:04:45 +08:00
const renderer = 'canvas';
const devicePixelRatio = 2;
2019-07-03 14:29:09 +08:00
class Jmap {
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-15 09:38:35 +08:00
this.events = { Pan: 'pan', Zoom: 'zoom', Selected: 'selected', Contextmenu: 'contextmenu' };
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-09 19:04:45 +08:00
// 代理数据
2019-07-04 10:59:40 +08:00
this.proxyData = {};
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-13 23:45:49 +08:00
this.optionsHandler = this.setOptions.bind(this);
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-11 17:58:58 +08:00
this.$options = new Options(Object.assign({ scaleRate: 1, offsetX: 0, offsetY: 0 }, opts.options || {})); // 缩放
2019-07-09 19:04:45 +08:00
2019-07-11 17:58:58 +08:00
this.$painter = new Painter(this); // 绘画层
2019-07-10 13:17:12 +08:00
this.$painter.updateZoomTransform(this.$options);
2019-07-10 12:02:02 +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-15 09:38:35 +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-10 13:24:03 +08:00
loadData(data) {
2019-07-09 19:04:45 +08:00
// 保存皮肤类型
2019-07-15 08:58:54 +08:00
this.skinStyle = data.skinVO.code;
2019-07-09 19:04:45 +08:00
2019-07-04 10:59:40 +08:00
// 保存原始数据
this.data = data;
// 加载皮肤
2019-07-10 13:24:03 +08:00
this.styleDict = this.loadStyle(this.skinStyle);
2019-07-04 10:59:40 +08:00
// 解析地图数据
2019-07-15 13:01:03 +08:00
this.mapDevice = parser(data, this);
2019-07-04 10:59:40 +08:00
// 生成代理对象
2019-07-10 13:17:12 +08:00
this.proxyData = new Proxy(this.mapDevice, new ProxyHandle(this.$painter));
2019-07-04 10:59:40 +08:00
2019-07-10 16:04:17 +08:00
// 数据加载完成
if (this.methods.dataLoaded instanceof Function) { this.methods.dataLoaded(); }
2019-07-08 09:38:39 +08:00
2019-07-04 10:59:40 +08:00
// 初次渲染视图
2019-07-10 13:17:12 +08:00
this.$painter.repaint(this.mapDevice, this.styleDict);
2019-07-08 09:38:39 +08:00
2019-07-10 16:04:17 +08:00
// 视图加载完成
if (this.methods.viewLoaded instanceof Function) { this.methods.viewLoaded(); }
}
loadStyle(skinStyle) {
2019-07-15 09:38:35 +08:00
return selectSkinStyle(skinStyle);
2019-07-04 10:59:40 +08:00
}
2019-07-09 19:04:45 +08:00
loadDefaultState() {
2019-07-04 10:59:40 +08:00
const defaultStateDict = {};
2019-07-08 09:38:39 +08:00
zrUtil.each(Object.keys(deviceState), (type) => {
2019-07-04 10:59:40 +08:00
defaultStateDict[type] = {};
2019-07-08 09:38:39 +08:00
zrUtil.each(Object.keys(deviceState[type] || {}), (state) => {
2019-07-04 10:59:40 +08:00
defaultStateDict[type][state] = deviceState[type][state].Default;
2019-07-11 17:58:58 +08:00
});
});
2019-07-04 10:59:40 +08:00
return defaultStateDict;
}
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
if (this.methods.stateLoaded instanceof Function) { this.methods.stateLoaded(); }
2019-07-09 19:04:45 +08:00
}
2019-07-10 13:24:03 +08:00
setOptions(zoom) {
2019-07-11 17:58:58 +08:00
this.$options.update(zoom); // 更新信息
2019-07-10 13:24:03 +08:00
this.$painter.updateZoomTransform(this.$options);
2019-07-10 16:04:17 +08:00
if (this.methods.optionsUpdate instanceof Function) { this.methods.optionsUpdate(); }
2019-07-04 18:39:30 +08:00
}
2019-07-15 14:14:44 +08:00
setLevelInvisible(list) {
this.$painter.setLevelInvisible(list);
}
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;
const device = this.proxyData[code] || deviceFactory(type, this.styleDict[type], elem);
const model = Object.assign(device.model || {}, elem);
2019-07-04 18:39:30 +08:00
delete this.proxyData[code];
if (!elem._dispose) {
2019-07-10 16:04:17 +08:00
this.proxyData[code] = Object.assign(device, { model });
2019-07-04 18:39:30 +08:00
}
2019-07-10 16:04:17 +08:00
this.dataSync(model);
2019-07-11 17:58:58 +08:00
});
2019-07-10 16:04:17 +08:00
if (this.methods.viewUpdate instanceof Function) { this.methods.viewUpdate(); }
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-04 18:39:30 +08:00
if (elem._dispose) {
delete this.proxyData[code];
} else {
2019-07-11 17:58:58 +08:00
const device = this.proxyData[code] || {};
const state = Object.assign(device.state || {}, elem);
2019-07-04 18:39:30 +08:00
this.proxyData[code] = Object.assign(device, { state });
}
2019-07-11 17:58:58 +08:00
});
2019-07-10 16:04:17 +08:00
if (this.methods.stateUpdate instanceof Function) { this.methods.stateUpdate(); }
}
dataSync(model) {
2019-07-11 17:58:58 +08:00
const code = model.code;
const type = model.type;
const dispose = model._dispose;
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;
case deviceType.Sction: prop = 'sectionList'; break;
2019-07-15 15:25:49 +08:00
case deviceType.Station: prop = 'stationList'; break;
case deviceType.StationControl: prop = 'stationControlList'; break;
case deviceType.LcControl: prop = 'LcControlList'; break;
case deviceType.LimitControl: prop = 'tempSpeedLimitList'; 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-11 17:58:58 +08:00
const idex = list.findIndex(elem => { return elem.code == code; });
2019-07-10 16:04:17 +08:00
if (idex >= 0) {
dispose && list.splice(idex, 1);
} else {
list.push(model);
}
}
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
}
2019-07-04 10:59:40 +08:00
getPainter() {
2019-07-10 13:17:12 +08:00
return this.$painter;
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;
}
getMapDevice() {
return this.mapDevice;
}
2019-07-15 14:01:57 +08:00
getDeviceByCode(code) {
return this.mapDevice[code];
}
getViewInstanceByCode(code) {
return this.$painter.getViewInstanceByCode(code);
}
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 = {};
this.proxyData = {};
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) {
case this.events.Selected: {
this.$mouseController.on(this.events.Selected, cb, context);
2019-07-11 17:58:58 +08:00
break;
}
case this.events.Contextmenu: {
this.$mouseController.on(this.events.Contextmenu, cb, context);
2019-07-11 17:58:58 +08:00
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) {
case this.events.Selected: {
this.$mouseController.off(this.events.Selected, cb);
2019-07-11 17:58:58 +08:00
break;
}
case this.events.Contextmenu: {
this.$mouseController.off(this.events.Contextmenu, cb);
2019-07-11 17:58:58 +08:00
break;
}
2019-07-10 12:02:02 +08:00
}
}
}
2019-07-03 14:29:09 +08:00
}
2019-07-04 10:59:40 +08:00
export default Jmap;