import WfsLayerService from './WfsLayerService' import { clone, pulseEffect } from '../../../utils/utils' import { logicMapper, SERVICE_TYPE } from '../../../conf/Constants' import WmsLayerService from './WmsLayerService' /** * init 只初始化一次 * start 每次调用图层显示show()时,都会调用 * destory 每次调用图层隐藏hide()时,都会调用 * */ class LayerFactory { constructor (options) { this.L = options.L this.map = window.map this.layers = {} this.layersLogic = {} this.minZoomLayers = {} this.wmsLayers = [] this.wmsLayerService = null // todo 待优化,wmslayerservice调用,放这里不合适 this.clickSwitch = true // 图层点击弹窗开关 this.hightlightLayer = options.L.featureGroup({}).addTo(window.map) } init (layerConfig) { // wms服务只需要初始化一次 this.wmsLayerService = new WmsLayerService() this.wmsLayerService.init() this.initConfig(layerConfig) } initConfig (layerConfig) { // 1. 遍历layer config if (layerConfig) { for (var i = 0; i < layerConfig.length; i++) { var config = layerConfig[i] var layers = config.layers var childLayer = config.childLayer var checked = config.checked /* if (config.groupName) { const wmsGroupLayerService = new WmsLayerGroupService(config) wmsGroupLayerService.init() continue } */ layers && this.initConfig(config.layers) childLayer && this.initConfig(config.childLayer) this.initMinZoom(config) this.loadLogic(config) checked && this.show(config) } } } initMinZoom (config) { const minZoom = parseInt(config.minZoom) if (minZoom) { var configs = this.minZoomLayers[minZoom] if (configs) { configs[configs.length] = config } else { configs = [config] } this.minZoomLayers[minZoom] = configs } } loadLogic (config) { var code = config.code var type = config.type const file = logicMapper[code] var logic = this.layersLogic[code] if (!logic) { if (file) { var BusiLayer = require('../logic/' + file) logic = new BusiLayer() } else if (type === SERVICE_TYPE.WFS) { logic = new WfsLayerService(config) } } this.layersLogic[code] = logic return logic } /** * 1. 先调用处理逻辑的 initLayer ,如果没有 就创建一个 featureGroup * 2. 如果存在事件逻辑的话,绑定tooltip,click事件 * 3. 将layer添加到map * 4. 返回layer * @param config * @returns layer */ addLayer (config) { var code = config.code var logic = this.loadLogic(config) var layer = (logic && logic.initLayer && logic.initLayer((this.L))) || this.L.featureGroup({}) if (logic.bindTooltip) { // 全局tips位置 layer.bindTooltip(logic.bindTooltip, { direction: 'top', offset: [0, -15], sticky: false }) } // 调用click事件 if (logic.clickListener) { layer.on('click', logic.clickListener) } layer.addTo(this.map) this.layers[code] = layer return layer } /** * 如果 存在已经加载了的对象,就直接加到map * 如果 不存在则 调用 addLayer 及 逻辑类的init 进行初始化操作 * 如果 存在start函数,则调用 * @param config */ show (config) { var index = config.index var layer = this.layers[config.code] var logic = this.loadLogic(config) if (layer) { if (!this.map.hasLayer(layer)) { index && layer.setZIndex(index) layer.addTo(this.map) } } else { logic && logic.init(this.addLayer(config), this.L) } logic && logic.start && logic.start() this.wmsLayerService && this.wmsLayerService.add(config) } hide (config) { const code = config.code const layer = this.layers[code] layer && this.map.removeLayer(layer) const logic = this.loadLogic(config) logic && logic.destory && logic.destory() this.wmsLayerService && this.wmsLayerService.remove(config) } /** * 控制显示的级别 * @param layerConfig */ initEvent (layerConfig) { // this.map.on('zoomend ', () => this.toggleByZoom()) } toggleByZoom () { const zoom = this.map.getZoom() for (var k in this.minZoomLayers) { const configs = this.minZoomLayers[k] for (var j in configs) { const config = configs[j] const checked = config.checked // console.log(zoom) // console.log(k) if (checked && zoom > k) { this.show(config) } else if (checked && zoom < k) { this.hide(config) } } } } /** * * 根据传的 feature对象定位, * @param code * @param feature */ flyByFeature (feature, code) { this.clearHighlight() const type = feature.geometry.type var point = [] switch (type) { case 'Point': point = feature.geometry.coordinates break case 'MultiLineString': var coordinates = feature.geometry.coordinates var coordinate = coordinates[parseInt(coordinates.length / 2)][0] if (coordinate.length > 2) { point = [coordinate[0], coordinate[1]] } break case 'LineString': var lineString = feature.geometry.coordinates point = lineString[parseInt(lineString.length / 2)][0] break } if (point.length > 2) { point.splice(2, 1) } this.highlight(feature) window.map.setView(clone(point).reverse(), 17) code && this.openPopup(code, feature.id) } clearHighlight () { this.hightlightLayer.clearLayers() } highlight (feature) { const type = feature.geometry.type if (type === 'MultiLineString') { this.L.geoJSON(feature, { style: function () { return { fillColor: 'red', color: 'red' } } }).addTo(this.hightlightLayer) } else if (type === 'Point') { let point = clone(feature.geometry.coordinates) if (point.length > 2) { point = [point[0], point[1]] } pulseEffect(point.reverse()) /* var myIcon = this.L.divIcon({ className: 'my-div-icon' }) this.L.marker(feature.geometry.coordinates.reverse(), { icon: myIcon }).addTo(this.hightlightLayer) */ } else if (type === 'LineString') { this.L.polyline(this.reversePolyLine(feature), { color: 'red' }).addTo(this.hightlightLayer) } } reverseMultiLine (feature) { const coordinates = feature.geometry.coordinates var latlng = [] for (var j = 0; j < coordinates.length; j++) { const coordinate = coordinates[j] var xy = [] for (var k = 0; k < coordinate.length; k++) { const coor = coordinate[k] xy.push(coor.reverse()) } latlng.push(xy) } return latlng } reversePolyLine (feature) { const coordinates = feature.geometry.coordinates var latlng = [] for (var j = 0; j < coordinates.length; j++) { const coordinate = coordinates[j] latlng.push(coordinate.reverse()) } return latlng } openPopup (layerId, id) { const layer = this.layers[layerId] if (layer) { layer.eachLayer(function (layer) { const layers = layer.getLayers() for (var i = 0; i < layers.length; i++) { const lay = layers[i] const feature = lay.feature lay.closePopup() if (feature.id === id) { lay.openPopup() break } } }) } /* for (var k in this.layers) { var layerGroup = this.layers[k] layerGroup.eachLayer(function (layer) { console.log(layer) console.log(layer.getAttribution()) }) var layers = layerGroup.getLayers() if (layers) { for (var m = 0; m < layers.length; m++) { var layer = layers[m] console.log(layer) console.log(layer.getLayerId(val.id)) /!* var feature = layer.feature if (feature.id === layerId) { this.map.flyToBounds(bound) return layer } *!/ } } } */ return null } findLayerById (layer, id) { const layers = layer.getLayers if (layers) { this.findLayerById(layer.getLayers(), id) } else { layer.eachLayer(function (layer) { // console.log(layer) }) } } } export default LayerFactory