<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: '', coordinateY: 39.9, coordinateX: 116.4, radius: '0' } } }, 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] } }, valves: { // 阀门原始数据 type: Array, default: () => [] }, closeAreas: { // 关阀影响区域原始数据 type: Array, default: () => { return [] } } }, data() { return { affectCicle: null, // 影响区域 mapLayers: null, // 地图图层 wellOverlay: null, // 井overlay affectAreaOverlay: [], // 影响区域overlay valvesOverlays: [], // 阀门overlay列表 closeAreaOverlays: [] // 关阀影响区域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) }, wellObj(val) { if (val == null) { this.removeOverlays() } else { this.renderAffectAP() } }, valves(val) { console.log('renderValves') this.renderValves() }, closeAreas(val) { console.log('renderValves') this.renderCloseArea() } }, 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() { const { mapLayers } = this if (!mapLayers) { return } this.removeOverlays() // 清除所有overlay // 渲染井 if (this.wellObj != null) { this.affectCircle = { lat: this.wellObj.coordinateY, lng: this.wellObj.coordinateX, radius: parseFloat(this.wellObj.radius) } this.renderWell() // 当影响区域不为空的时候显示影响区域 if (this.affectCircle != null) { this.renderAffectArea() } } }, // 移除影响区域 removeAffectAP() { // 移除影响区域 if (this.affectArea != null) { this.removeAffectArea() } }, // 渲染影响区域 renderAffectArea() { const { mapLayers, affectCircle } = this // 绘制影响区域 const opts = { color: '#boacfc', weight: 0, opacity: 0.9, fill: true, fillColor: '#32d3eb', fillOpacity: 0.5 } 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: [15, 30] } const cmapIcon = createIcon(options) const opts = { icon: cmapIcon, title: wellObj.wellCode, draggable: false } this.wellOverlay = new CMarker(new CLatLng(wellObj.coordinateY, wellObj.coordinateX), opts) mapLayers.addOverlay(this.wellOverlay) mapLayers.setZoom(17) mapLayers.setCenter(new CLatLng(wellObj.coordinateY, wellObj.coordinateX)) }, // 移除井 removeWell() { const { mapLayers } = this if (!this.wellOverlay) { mapLayers.removeOverlay(this.wellOverlay) this.wellOverlay = null } }, // 渲染阀门 renderValves() { const { mapLayers, size, valves } = this for (const valve of valves) { const options = { url: './static/images/map_images/valve1.png', size: [20, 20], anchor: [10, 10] } const cmapIcon = createIcon(options) const opts = { icon: cmapIcon, title: valve.valveCode, draggable: false } const valveOverlay = new CMarker(new CLatLng(valve.coordinateY, valve.coordinateX), opts) mapLayers.addOverlay(valveOverlay) this.valvesOverlays.push(valveOverlay) mapLayers.setZoom(16) } }, // 移除影响管线 removeValves() { const { mapLayers } = this for (const overlay of this.valves) { mapLayers.removeOverlay(overlay) } this.valves = [] }, // 渲染关阀影响区域 renderCloseArea() { const { mapLayers, closeAreas } = this this.removeCloseArea() // 绘制影响区域 for (const valveArea of closeAreas) { const opts = { color: '#e7944f', weight: 1, opacity: 0.9, fill: true, fillColor: '#e7944f', fillOpacity: 0.4 } const polygon = mapLayers.drawPolygon(valveArea.position, opts) this.closeAreaOverlays.push(polygon) } }, // 移除关阀影响区域 removeCloseArea() { const { mapLayers } = this if (this.closeAreaOverlays) { mapLayers.removeOverlay(this.closeAreaOverlays) this.closeAreaOverlays = [] } }, // 清除所有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>