<!--Mars 3D地图--> <template> <div ref="map" :id="`mars3d-container${mapKey}`" :class="['mars3d-container', customClass, { 'mars3d-container-compare-rh' : compare }]"> <slot/> </div> </template> <script> // import * as mapv from 'mapv' import 'mars3d-mapv' import axios from 'axios' export default { name: 'MarsMap', props: { // 初始化配置参数 url: { type: String, required: true }, // 地图唯一性标识 mapKey: { type: String, default: '' }, deep: { type: Number, default: 1000 }, // 地图厚度 // 自定义参数 options: { type: Object, default: () => { return {} } }, labelShow: { type: Boolean, default: true }, // 地块上文字是否显示 // 是否分屏显示 compare: { type: Boolean, default: false }, // 是否插入到body元素上 appendToBody: { type: Boolean, default: false }, // 自定义css类名 customClass: { type: String, default: '' }, colorful: { type: Boolean, default: false }, colorList: { type: Array, default: () => { return ['#2F50F3', '#417EE0', '#1D2EB7', '#2E5EA8', '#386ADE', '#2D5BA7', '#4991DB', '#4991DB', '#4C96E6', '#2F50F3', '#0385BD', '#4A94DC'] } }// 地块使用的颜色列表 }, data() { return { map: null, lastEntity: null } }, mounted() { const { mars3d } = this if (this.appendToBody) { document.body.appendChild(this.$el) } if (this.mapKey) { this.initMars3d(this.options) } else { mars3d.Resource.fetchJson({ url: this.url }).then((data) => { this.initMars3d(data.map3d)// 构建地图 }) } }, destroy() { this[`map${this.mapKey}`].destroy() delete this[`map${this.mapKey}`] }, methods: { initMars3d(options) { const { mars3d } = this if (this[`map${this.mapKey}`]) return const mapOptions = { ...options, ...this.options } // 创建三维地球场景 var map = new mars3d.Map(`mars3d-container${this.mapKey}`, mapOptions) this.map = map this[`map${this.mapKey}`] = map console.log('>>>>> 地图创建成功 >>>>', map) // 挂载到全局对象下,所有组件通过 this.map 访问 // Vue.prototype[`map${this.mapKey}`] = map // 绑定对alert的处理,右键弹出信息更美观。 window.haoutil = window.haoutil || {} window.haoutil.msg = (msg) => { this.$message.success(msg) } window.haoutil.alert = (msg) => { this.$message.success(msg) } // // 背景透明 map._viewer.scene.backgroundColor = new mars3d.Cesium.Color(0.0, 0.0, 0.0, 0.0) map._viewer.scene.globe.baseColor = new mars3d.Cesium.Color(0.0, 0.0, 0.0, 0.0) map._viewer.scene.globe.baseColor.alpha = 0 // 添加各市地块 this.addProvincePolygon() this.map.fixedLight = true // 抛出事件 this.$emit('onload', map) }, // 显示城市边界线数据 addLine() { const { mars3d } = this const geoJsonLayer = new mars3d.layer.CzmGeoJsonLayer({ name: '省界线', url: 'static/geojson/140000.json', symbol: { styleOptions: { lineType: 'glow', glowPower: 0.9, opacity: 0.3, // 透明度 color: '#87ffff', outline: true, // 边框 outlineColor: '#87ffff', // 边框颜色 outlineWidth: 3, // 边框宽度 fill: false, // 是否填充 width: 5, // 宽度 height: 20000, clampToGround: false } }, flyTo: true }) this.map.addLayer(geoJsonLayer) }, // 管线 addPipe() { console.log('addPipe') const { mars3d } = this // geojson图层 var geoJsonLayer1 = new mars3d.layer.GeoJsonLayer({ type: 'geojson', url: 'static/geojson/pipe.json', symbol: { styleOptions: { materialType: 'PolylineGlow', // materialType: 'LineFlowColor', // alpha: 0.5, // percent: 0.1, // width: 5, // 线宽 glowPower: 0.04, // 发光强度 width: 10, // 线宽 color: '#4ff8ff', opacity: 0.9, clampToGround: false } }, show: true }) this.map.addLayer(geoJsonLayer1) }, // 添加省地块 addProvincePolygon() { const { mars3d, colorful, colorList } = this var graphicLayer = new mars3d.layer.DivLayer() this.polygonLayer = graphicLayer this.map.addLayer(graphicLayer) axios.get('static/geojson/140000.json').then((res) => { if (res.status === 200) { const features = res.data.features for (let i = 0; i < features.length; i++) { const coordinates = (features[i].geometry.coordinates[0][0]).map(item => { return [item[0], item[1], 0] }) const color = colorful ? colorList[i] : '#3a77da' const graphic = new mars3d.graphic.PolygonEntity({ name: features[i].properties.name, positions: coordinates, style: { height: -10000, // heightReference: mars3d.Cesium.HeightReference.RELATIVE_TO_GROUND, hasShadows: true, diffHeight: 10000.0, color: color, opacity: 1, outline: !colorful, outlineColor: '#4764c9', outlineWidth: 3, outlineOpacity: 1, arcType: mars3d.Cesium.ArcType.GEODESIC, label: { // 面中心点,显示文字的配置 text: this.labelShow ? features[i].properties.name : '', // 对应的属性名称 opacity: 1, font_size: 20, color: '#ffffff', font_family: '微软雅黑', background: false, backgroundColor: '#000000', backgroundOpacity: 0.1, font_weight: 'normal', font_style: 'normal', scaleByDistance: true, scaleByDistance_far: 20000000, scaleByDistance_farValue: 0.1, scaleByDistance_near: 1000, scaleByDistance_nearValue: 1, clampToGround: false, distanceDisplayCondition: false, distanceDisplayCondition_far: 10000, distanceDisplayCondition_near: 0, visibleDepth: false } } }) graphicLayer.addGraphic(graphic) } graphicLayer.on(mars3d.EventType.mouseOver, event => { console.log('鼠标移入图层', event) console.log(event) this.$emit('mouseIn', event) // var entity = event.czmObject // if (entity && entity.polygon) { // this.highlightedEntity(entity) // } }) graphicLayer.on(mars3d.EventType.mouseOut, event => { console.log('鼠标移出图层', event) this.$emit('mouseOut', event) // var entity = event.czmObject // if (entity && entity.polygon) { // this.clearLastHighlightedEntity() // } }) } }) }, // 高亮 highlightedEntity(entity) { if (!entity || !entity.polygon) { return } const color = entity.polygon.material.color const outline = entity.polygon.outlineColor const nclr = this.mars3d.Cesium.Color.fromCssColorString('#1ff5ff') color.setValue(nclr) outline.setValue(nclr) this.lastEntity = entity }, // 清除高亮 clearLastHighlightedEntity() { const { lastEntity } = this if (lastEntity == null) { return } var color = lastEntity.polygon.material.color const outline = lastEntity.polygon.outlineColor const nclr = this.mars3d.Cesium.Color.fromCssColorString('#3a77da') color.setValue(nclr) outline.setValue(nclr) this.lastEntity = null } } } </script> <!-- Add "scoped" attribute to limit CSS to this component only --> <style > .mars3d-container { height: 100%; overflow: hidden; } /* 重写Cesium的css */ /**cesium按钮背景色*/ .cesium-button { background-color: #3f4854; color: #e6e6e6; fill: #e6e6e6; box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); line-height: 32px; } .cesium-viewer-geocoderContainer .cesium-geocoder-input { background-color: rgba(63, 72, 84, 0.7); } .cesium-viewer-geocoderContainer .cesium-geocoder-input:focus { background-color: rgba(63, 72, 84, 0.9); } .cesium-viewer-geocoderContainer .search-results { background-color: #3f4854; } .cesium-geocoder-searchButton { background-color: #3f4854; } .cesium-infoBox-title { background-color: #3f4854; } .cesium-infoBox { background: rgba(63, 72, 84, 0.9); } .cesium-toolbar-button img { height: 100%; } .cesium-performanceDisplay-defaultContainer { top: auto; bottom: 35px; right: 50px; } .cesium-performanceDisplay-ms, .cesium-performanceDisplay-fps { color: #fff; } /**cesium工具栏位置*/ .cesium-viewer-toolbar { top: auto; left: auto; right: 12px; bottom: 35px; } .cesium-viewer-toolbar > .cesium-toolbar-button, .cesium-navigationHelpButton-wrapper, .cesium-viewer-geocoderContainer { margin-bottom: 5px; float: right; clear: both; text-align: center; } .cesium-baseLayerPicker-dropDown { bottom: 0; right: 40px; max-height: 700px; margin-bottom: 5px; } .cesium-navigation-help { top: auto; bottom: 0; right: 40px; transform-origin: right bottom; } .cesium-sceneModePicker-wrapper { width: auto; } .cesium-sceneModePicker-wrapper .cesium-sceneModePicker-dropDown-icon { float: left; margin: 0 3px; } .cesium-viewer-geocoderContainer .search-results { left: 0; right: 40px; width: auto; z-index: 9999; } .cesium-infoBox-title { background-color: #3f4854; } .cesium-infoBox { top: 50px; background: rgba(63, 72, 84, 0.9); } /**左下工具栏菜单*/ .toolbar-dropdown-menu-div { background: rgba(43, 44, 47, 0.8); border: 1px solid #2b2c2f; z-index: 991; position: absolute; right: 60px; bottom: 40px; display: none; } .toolbar-dropdown-menu { min-width: 110px; padding: 0; } .toolbar-dropdown-menu > li { padding: 0 3px; margin: 2px 0; } .toolbar-dropdown-menu > li > a { color: #edffff; display: block; padding: 4px 10px; clear: both; font-weight: normal; line-height: 1.6; white-space: nowrap; text-decoration: none; } .toolbar-dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { color: #fff; background-color: #444d59; } .toolbar-dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #fff; background-color: #444d59; } .toolbar-dropdown-menu i { padding-right: 5px; } </style>