<template> <div> <div id="map" ref="map" class="mapDiv"/> <slot/> </div> </template> <script> import bindEvents from './../base/bindEvents' import { createIcon } from '../base/factory.js' export default { name: 'Cmap', props: { center: { // 地图中心 type: Object, default: function() { return { lat: 39.9, lng: 116.4 } } }, wellObj: { // 井对象 type: Object, default: function() { return { wellCode: '', id: '', lat: 39.9, lng: 116.4, radius: 10 } } }, valves: { // 阀门 type: Array, default: () => [] }, zoom: { // 缩放层级 type: Number, default: 12 }, minZoom: { // 最小缩放层级 type: Number, default: 9 }, maxZoom: { // 最大缩放层级 type: Number, default: 21 }, autoResize: { // 自动重绘 type: Boolean, default: true }, size: { // marker大小 type: Array, default: function() { return [30, 30] } }, anchor: { // 位移 type: Array, default: function() { return [15, 30] } }, // 图标位移 popupTemplate: { // 弹窗html内容 type: String, default: '<div>hello</div>' }, popupAnchor: { // 弹窗位移 type: Array, default: function() { return [0, -15] } } }, data() { return { // wellObj: null, affectCicle: null, // 影响区域 affectPipes: null, // 影响管线 closeCircle: null, // 关阀影响区域 closePipes: null, // 影响管线 mapLayers: null, // 地图图层 wellOverlay: null, // 井overlay affectAreaOverlay: null, // 影响区域overlay affectLineOverlays: [], // 影响管线overlay valvesOverlays: [], // 阀门overlay列表 closeAreaOverlay: null, // 关阀影响区域overlay closeLineOverlays: [] // 关阀影响区域overlay } }, watch: { center(val, oldVal) { const { mapLayers, zoom } = this if (mapLayers != null && val !== oldVal) { mapLayers.setCenter(new CLatLng(val.lat, val.lng)) } }, 'center.lng'(val, oldVal) { const { mapLayers, zoom, center } = this if (mapLayers != null && val !== oldVal) { mapLayers.setCenter(new CLatLng(center.lat, val)) } }, 'center.lat'(val, oldVal) { const { mapLayers, zoom, center } = this if (mapLayers != null && val !== oldVal) { mapLayers.setCenter(new CLatLng(val, center.lng)) } }, zoom(val, oldVal) { const { mapLayers } = this mapLayers.setZoom(val) }, minZoom(val, oldVal) { const { mapLayers } = this mapLayers.setMinZoom(val) }, maxZoom(val, oldVal) { const { mapLayers } = this mapLayers.setMaxZoom(val) }, alarmMarkers(val) { console.log('alarmMarkers') this.renderMarkers() } }, mounted() { console.log('map mounted') this.reset() }, activated() { console.log('map activated') this.init() }, methods: { // 初始化地图 init() { if (this.mapLayers) { return } const $el = this.$refs.map // 影像和矢量地图 // const sateLayer = new CTileLayer(2, 18, 'sate', null, null)// 影像 // const sateLabelLayer = new CTileLayer(2, 18, 'satelabel', null, null)// 影像注记 // const mapLayer = new CTileLayer(2, 18, 'map', null, null)// 矢量 // const mapLabelLayer = new CTileLayer(2, 18, 'maplabel', null, null)// 矢量注记 var tianditusateLayer = new CTileLayer({ zbound: [2, 18], tileName: 'sate', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], url: 'http://t{s}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00' }) var tianditusateLabelLayer = new CTileLayer({ zbound: [2, 18], tileName: 'satelabel', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], url: 'http://t{s}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00' }) var tianditumapLayer = new CTileLayer({ zbound: [2, 18], tileName: 'map', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], url: 'http://t{s}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00' }) const tianditumapLabelLayer = new CTileLayer({ zbound: [2, 18], tileName: 'maplabel', subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'], url: 'http://t{s}.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=80310778300778a15b36e70a6da5af00' }) const TianDiTuBASEMAP = new CMapType([tianditumapLayer], '矢量') const TianDiTuVECTORMAP = new CMapType([tianditumapLayer, tianditumapLabelLayer], '矢量') const TianDiTuSATEMAP = new CMapType([tianditusateLayer, tianditusateLabelLayer], '影像') const VECTORMAP = new CMapType([tianditumapLayer, tianditumapLabelLayer], '矢量') const SATEMAP = new CMapType([tianditusateLayer, tianditusateLabelLayer], '影像') // const VECTORMAP = new CMapType([mapLayer, mapLabelLayer], '矢量') // const SATEMAP = new CMapType([sateLayer, sateLabelLayer], '影像') const { getCenterPoint, zoom } = this // 初始化配置 const opts = { mapTypes: [VECTORMAP], center: getCenterPoint(), zoom: zoom } // 加载图层 this.mapLayers = new CMapLayers($el, opts) this.mapLayers.addMapTypeControl() bindEvents.call(this, this.mapLayers) // 此处强行初始化一次地图 回避一个由于错误的 center 字符串导致初始化失败抛出的错误 // this.mapLayers.reset() this.reset() this.mapLayers.setCenter(getCenterPoint(), zoom) this.$emit('ready', { mapLayers: this.mapLayers }) // this.renderMarkers() }, renderAffectAP(wellObj) { // this.wellObj = wellObj const { mapLayers } = this if (!mapLayers) { return } this.removeOverlays() // 清除所有overlay // 渲染井 if (this.wellObj != null) { this.affectCircle = { lat: this.wellObj.lat, lng: this.wellObj.lng, radius: this.wellObj.radius } if (this.wellObj.affectPipes) { this.affectPipes = this.wellObj.affectPipes } this.renderWell() } // 当影响区域不为空的时候显示影响区域 if (this.affectCircle != null) { this.renderAffectArea() } // 渲染管线 if (this.affectPipes && this.affectPipes.length > 0) { this.renderAffectPipes() } }, removeAffectAP() { // 移除井 // if (this.wellObj != null) { // this.removeWell() // } // 移除影响区域 if (this.affectArea != null) { this.removeAffectArea() } // 移除管线 if (this.affectPipes.length > 0) { this.removeAffectPipes() } }, // 渲染影响区域 renderAffectArea() { const { mapLayers, affectCircle } = this // 绘制影响区域 const opts = { color: '#c45366', weight: 2, opacity: 0.9, fill: true, fillColor: '#009900', fillOpacity: 0.4 } this.affectAreaOverlay = mapLayers.drawCircle(new CLatLng(affectCircle.lat, affectCircle.lng), affectCircle.radius, opts) }, // 移除影响区域 removeAffectArea() { const { mapLayers } = this if (this.affectAreaOverlay) { mapLayers.removeOverlay(this.affectAreaOverlay) this.affectAreaOverlay = null } }, // 渲染井 renderWell() { const { mapLayers, size, anchor, wellObj } = this const options = { url: './static/images/map_images/alarm-well1.png', size: size, anchor: anchor } const cmapIcon = createIcon(options) const opts = { icon: cmapIcon, title: wellObj.wellCode, draggable: false } this.wellOverlay = new CMarker(new CLatLng(wellObj.lat, wellObj.lng), opts) mapLayers.addOverlay(this.wellOverlay) mapLayers.setZoom(17) mapLayers.setCenter(new CLatLng(wellObj.lat, wellObj.lng)) }, // 移除井 removeWell() { const { mapLayers } = this if (!this.wellOverlay) { mapLayers.removeOverlay(this.wellOverlay) this.wellOverlay = null } }, // 渲染问题影响管线 renderAffectPipes() { // TODO: 渲染管线 }, // 移除影响管线 removeAffectPipes() { const { mapLayers } = this for (const overlay of this.affectLineOverlays) { mapLayers.removeOverlay(overlay) } this.affectLineOverlays = [] }, // 渲染关阀影响区域 renderCloseArea() { const { mapLayers, closeCircle } = this // 绘制影响区域 const opts = { color: '#c45366', weight: 2, opacity: 0.9, fill: true, fillColor: '#009900', fillOpacity: 0.4 } this.closeAreaOverlay = mapLayers.drawCircle(new CLatLng(closeCircle.lat, closeCircle.lng), closeCircle.radius, opts) }, // 移除关阀影响区域 removeCloseArea() { const { mapLayers } = this if (this.closeAreaOverlay) { mapLayers.removeOverlay(this.closeAreaOverlay) this.closeAreaOverlay = null } }, // 渲染关阀影响管线 renderClosePipes() { // TODO: 渲染管线 }, // 移除关阀影响管线 removeClosePipes() { const { mapLayers } = this for (const overlay of this.closeLineOverlays) { mapLayers.removeOverlay(overlay) } this.closeLineOverlays = [] }, // 清除所有overlay removeOverlays() { const { mapLayers } = this mapLayers.clearOverlays() }, // 获取中点 getCenterPoint() { const { center } = this console.log('getCenterPoint:' + center.lat + ',' + center.lng) return new CLatLng(center.lat, center.lng) }, initMap(CMapLayers) { this.CMapLayers = CMapLayers this.init(CMapLayers) }, getMapScript() { // 动态获取cmap的脚本 // const TMapURL = 'http://satellite.casm.ac.cn:8020/geowinmap/api?version=tapi&map=map&utils=mapcase' const TMapURL = 'http://119.3.228.125:8080/geowinmap/api?version=tapi&map=map&utils=mapcase,mapv' return new Promise((resolve, reject) => { console.log(window.CMapLayers) // 如果已加载直接返回 if (typeof window.CMapLayers !== 'undefined') { console.log('地图脚本初始化成功1111...') resolve(window.CMapLayers) // return true } else { // 插入script脚本 const scriptNode = document.createElement('script') scriptNode.setAttribute('type', 'text/javascript') scriptNode.setAttribute('src', TMapURL) if (scriptNode.readyState) { // IE scriptNode.onreadystatechange = function() { if (scriptNode.readyState === 'loaded' || scriptNode.readyState === 'complete') { scriptNode.onreadystatechange = null console.log('地图脚本初始化成功2...') // eslint-disable-next-line resolve(window.CMapLayers) } } } else { // 其他浏览器 scriptNode.onload = function() { console.log('地图脚本初始化成功3...') resolve(window.CMapLayers) } } document.body.appendChild(scriptNode) console.log(scriptNode) } }) }, reset() { console.log('map reset') const { initMap, getMapScript } = this getMapScript() .then(initMap) } } } </script> <style rel="stylesheet/scss" lang="scss"> .mapDiv{ width:100%; height: calc(100vh - 84px); } /*.alarm-window{*/ /*max-width: 250px;*/ /*!*background-color: #ffeaf1;*!*/ /*.alarm-header {*/ /*padding: 10px 10px 5px 10px;*/ /*line-height: 30px;*/ /*color: red;*/ /*font-weight: bold;*/ /*!*background-color: #ffecec;*!*/ /*}*/ /*.alarm-body{*/ /*padding: 5px 10px 10px 10px;*/ /*line-height: 23px;*/ /*font-size: 14px;*/ /*.alarm-red{*/ /*color: #ff0000;*/ /*}*/ /*}*/ /*}*/ </style>