import Feature from 'ol/Feature' import Overlay from 'ol/Overlay' import Observable from 'ol/Observable' import PlotDraw from './PlotDraw' import PlotEdit from './PlotEdit' import FeatureEvent from './events/FeatureEvent' import FeatureOperatorEvent from './events/FeatureOperatorEvent' import DrawEvent from './events/DrawEvent' import FeatureOperator from './core/FeatureOperator' import PlotFactory from './PlotFactory' import Constants from './Constants' import { combineOpts, deepcopy } from '../util/core' import * as ArrTools from '../util/array' import VectorLayer from 'ol/layer/Vector'; import VectorSource from 'ol/source/Vector'; // import Ajax from '../util/seieajax'; class PlottingLayer extends Observable { /** * @classdesc 标绘主图层封装。后续可以有多个对象。目前就中心而言应该就一个对象 * 与SEIE标绘服务进行对接,加载标绘服务,编辑标绘图元,保存标绘属性。是暴露出的唯一一个类。 * @author daiyujie * @extends {Observable} * @constructs * @param {ol.Map} map 地图对象 * @param {Object} opts 初始化选项 * @example <caption>加载标绘,绘制标绘,保存标绘</caption> * //创建TrackingLay的工作可以由SEOL完成。逻辑也可在SEOL中封装 * const plottingLayer = new PlottingLayer(map); * //--从服务器加载标绘 * plottingLayer.loadFromService('1735'); * //--绘制标绘 * plottingLayer.addFeature('polygon'); * //--监听绘制事件,从中取到FeatureOperator对象。进行一些操作 * plottingLayer.on('activate_feature', function (e) { * window.fo = e.feature_operator; * //--TODO * }) * plottingLayer.on('deactivate_feature', function (e) { * window.fo = null; * //--TODO * }) * //--设置选中图元样式 * fo.setStyle({"fill":{"color":"rgba(0,255,0,0.4)"},"stroke":{"color":"#FF0000","width":2}}) * //--设置属性 * fo.setAttribute('hellow','i am free'); * //--其余操作参考FeatureOperator类 * * //--设置层级等关联操作通过PlottingLayer对象完成 * //--上移图元 * plottingLayer.moveDown(fo); * //--其余操作参照api * //--保存所有图元至服务器 * plottingLayer.saveToService('1735'); */ constructor(map, opts) { super(); /** * map对象 * @type {ol.Map} */ this.map = map; /** * 默认配置 * @ignore * @type {Object} */ this.defaults = { } /** * 合并配置 * @ignore * @type {Object} */ this.opts = {}; /** * 当前图层的所有图元操作对象 * @type {Array<FeatureOperator>} */ this.feature_operators = []; /** * 主显示图层 * @type {Layer.SourceLayer} */ this.showLayer = null; /** * 编辑工具类对象 * @type {PlotEdit} */ this.plotEdit = null; /** * 绘制工具类对象 * @type {PlotDraw} */ this.plotDraw = null; /** * 绘制提示图层 * @type {ol.Overlay} */ this.help_overlay = null; /** * 绘制提示图层元素。用以设置提示内容 * @type {Element} */ this.help_overlay_ele = null; /** * map绑定的事件钩子 * @ignore * @type {Function} */ this._ls_mapclick = null; //--合并地图选项 combineOpts(this.opts, this.defaults, opts) //--创建layer this.showLayer = this._createShowLayer(); //--创建编辑对象 this.plotEdit = new PlotEdit(map); //--创建绘制对象 this.plotDraw = new PlotDraw(map); //--绑定地图事件 this._bindListener(); } /** * @ignore * 绑定地图事件 */ _bindListener() { this.plotDraw.on(FeatureEvent.DRAW_END, (e) => { this._onDrawEnd(e) }) //--试用移动端手势点击 this.plotDraw.on(DrawEvent.ADD_CONTROL_POINT, (e) => { if (!this.help_overlay) { this._createHelpOverlay(); } this._setHelpOverlayState(e.drawstate); }) //--试用pc端 this.plotDraw.on(DrawEvent.ADDING_MOUSE_MOVE, (e) => { if (!this.help_overlay) { this._createHelpOverlay(); } this._setHelpOverlayState(e.drawstate); }) this.plotEdit.on(FeatureEvent.ACTIVATE, (e) => { this.dispatchEvent(new FeatureOperatorEvent(FeatureOperatorEvent.ACTIVATE, this._getFeatureOperator(e.feature, this.showLayer))); }) this.plotEdit.on(FeatureEvent.DEACTIVATE, (e) => { this.dispatchEvent(new FeatureOperatorEvent(FeatureOperatorEvent.DEACTIVATE, this._getFeatureOperator(e.feature, this.showLayer))); }) this._ls_mapclick = this.map.on('click', (e) => { if (!this.plotDraw || this.plotDraw.isDrawing()) { return; } const feature = this.map.forEachFeatureAtPixel(e.pixel, (feature, layer) => { return feature; }); if (feature && !feature.get(Constants.SE_DISABLED)) { // 开始编辑 this.plotEdit.activate(feature); } else { // 结束编辑 this.plotEdit.deactivate(); } }).listener } /** * @ignore * 移除地图绑定事件 */ _unbindListener() { this.plotDraw.un([DrawEvent.ADD_CONTROL_POINT, DrawEvent.ADDING_MOUSE_MOVE, FeatureEvent.DRAW_END]) this.plotEdit.un([FeatureEvent.ACTIVATE, FeatureEvent.DEACTIVATE]) if (this._ls_mapclick) { this.map.un('click', this._ls_mapclick) this._ls_mapclick = null; } } /** * @ignore * 创建绘制提示图层 */ _createHelpOverlay() { if (this.help_overlay_ele) { this.help_overlay_ele.parentNode.removeChild(this.help_overlay_ele); } this.help_overlay_ele = document.createElement('div'); this.help_overlay_ele.className = 'tooltip hidden se-tooltip'; this.help_overlay = new Overlay({ element: this.help_overlay_ele, offset: [15, 0], positioning: 'center-left' }); this.map.addOverlay(this.help_overlay); } /** * @ignore * 移除绘制提示图层 */ _removeHelpOverlay() { if (this.help_overlay_ele) { this.help_overlay_ele.parentNode.removeChild(this.help_overlay_ele); this.help_overlay_ele = null; } if (this.help_overlay) { this.map.removeOverlay(this.help_overlay); this.help_overlay = null; } } /** * @ignore * 创建layer */ _createShowLayer() { const showlayer = new VectorLayer({ source: new VectorSource() }); // showlayer.setStyle(drawStyle); showlayer.setMap(this.map); return showlayer } /** * @ignore */ _onDrawEnd(event) { const feature = event.feature; this._removeHelpOverlay(); this._addFeature(feature); // 开始编辑 this.plotEdit.activate(feature); } _setHelpOverlayState(drawstate) { if (!this.help_overlay_ele) return; const freehandmsg = '当前随意绘制。单击结束'; const msg1 = !drawstate.total ? '当前图元控制点无限制,' : `图元共${drawstate.total}个控制点,` const msg2 = `当前是第${drawstate.current}个,`; const msg3 = !drawstate.total ? '双击结束绘制' : '点击继续绘制。'; this.help_overlay_ele.innerHTML = drawstate.freehand ? freehandmsg : msg1 + msg2 + msg3; this.help_overlay.setPosition(drawstate.position) } /** * @ignore * 添加图元 */ _addFeature(feature, zindex) { const fo = this._getFeatureOperator(feature, this.showLayer, zindex || this.feature_operators.length + 1); this.feature_operators.push(fo) return fo; } /** * @ignore * 按照zindex排序图元操作对象数组 */ _sortByZindex() { this.feature_operators.sort((a, b) => { return a.feature.getStyle().zIndex - b.feature.getStyle().zIndex; }) } /** * @ignore * 获取某个人图元操作对象位置 */ _getFeatureOperatorIndex(feature_operator) { for (let i = 0; i < this.feature_operators.length; i++) { if (feature_operator.guid == this.feature_operators[i].guid) { return i; } } } /** * @ignore * 重新计算图元index */ _resetZIndex() { this.feature_operators.map((f, i) => { const style = f.feature.getStyle().clone(); style.setZIndex(i + 1); f.feature.setStyle(style); }) } /** * @ignore * 获取已有图元操作对象或者新建一个 */ _getFeatureOperator(feature, vectorlayer, zindex) { for (let i = 0; i < this.feature_operators.length; i++) { const fo = this.feature_operators[i]; if (fo.feature == feature) return fo; } return new FeatureOperator(feature, vectorlayer, zindex); } /** * @param {Number} service_id 需要加载的标绘服务id * @param {Function} callback 加载成功的回调 * @param {Function} error 加载失败的回调 * 从服务器加载一个标绘服务 */ loadFromService(service_id, callback, error) { if (!service_id) { error(); return; } //--清除所有图元 // this.clearFeatures(); // Ajax.getPlottingService(service_id, null, (res_service) => { // const query_params = { // service_id: service_id, // projection: res_service.projection // } // Ajax.queryPlottingData(query_params, (res) => { // if (!res.item_list || !res.item_list.length) // return; // res.item_list.map((item) => { // if (!item.config.cresda_flag) { // console.error('不支持非中心sdk标绘(openlayer)之外的标绘图元。') // return undefined; // } // const plot = PlotFactory.createPlot(item.plotting_type, item.geo_data.coordinates); // const feature = new Feature(plot); // const fo = this._addFeature(feature, item.config.z_index); // fo.attrs = deepcopy(item.ext_attr); // fo.setStyle(item.style); // }) // if (callback && typeof callback == 'function') // callback(); // }, error) // }, (e) => { // console.error('加载标绘服务失败!') // error(); // }) } /** * @param {Number} service_id 需要保存的标绘服务id * @param {Function} callback 保存成功的回调 * @param {Function} error 保存失败的回调 * 保存标绘服务到服务器 */ saveToService(service_id, callback, error) { if (!service_id) { error(); return; } // Ajax.clearPlottingServiceData(service_id, () => { // const promises = []; // this.feature_operators.map((fo) => { // const d = fo.serialize(); // d.service_id = service_id; // promises.push(new Promise((resove, reject) => { // Ajax.createPlottingData(d, (r) => { // resove(); // }, () => { // reject('保存图元' + fo.getName() + '失败!') // }) // })) // }) // Promise.all(promises).then(() => { // if (callback && typeof callback == 'function') // callback(service_id); // }).catch(e => { // if (error && typeof error == 'function') // error(e); // }) // }) } /** * @param {Number} type 类型 * 添加一个标绘绘制图元 */ addFeature(type) { this.plotDraw.activate(type); } /** * @param {FeatureOperator} feature_operator 对象 * 移除一个图元操作对象 */ removeFeature(feature_operator) { this.showLayer.getSource().removeFeature(feature_operator.feature); this.plotEdit.deactivate(); const curIndex = this._getFeatureOperatorIndex(feature_operator); feature_operator.destory(); this.feature_operators.splice(curIndex, 1); this._sortByZindex(); this._resetZIndex(); } /** * 清空图元 */ clearFeatures(callback) { this.plotEdit.deactivate(); this.feature_operators.map((fo) => { this.showLayer.getSource().removeFeature(fo.feature); fo.destory(); }, this) this.feature_operators.splice(0, this.feature_operators.length); return this; } /** * @param {FeatureOperator} feature_operator 对象 * 上移一个图元 */ moveUp(feature_operator) { this._sortByZindex(); const curIndex = this._getFeatureOperatorIndex(feature_operator); ArrTools.moveUp(this.feature_operators, curIndex); this._resetZIndex(); } /** * @param {FeatureOperator} feature_operator 对象 * 下移一个图元 */ moveDown(feature_operator) { this._sortByZindex(); const curIndex = this._getFeatureOperatorIndex(feature_operator); ArrTools.moveDown(this.feature_operators, curIndex); this._resetZIndex(); } /** * @param {FeatureOperator} feature_operator 对象 * 置顶一个图元 */ setToTop(feature_operator) { this._sortByZindex(); const curIndex = this._getFeatureOperatorIndex(feature_operator); ArrTools.moveToTop(this.feature_operators, curIndex); this._resetZIndex(); } /** * @param {FeatureOperator} feature_operator 对象 * 置底一个图元 */ setToBottom(feature_operator) { this._sortByZindex(); const curIndex = this._getFeatureOperatorIndex(feature_operator); ArrTools.moveToBottom(this.feature_operators, curIndex); this._resetZIndex(); } destory() { //--清空图元 this.clearFeatures(); //--移除map this.showLayer.setMap(null); this.showLayer = null; //--解绑事件 this._unbindListener(); //--移除编辑工具对象 this.plotEdit.deactivate(); this.plotEdit = null; //--移除绘制工具对象 this.plotDraw.deactivate(); this.plotEdit = null; //--移除帮助overlay this.map.removeOverlay(this.help_overlay); this.help_overlay = null; this.help_overlay_ele = null; this.map = null; } } export default PlottingLayer;