<!--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 {} } }, // 是否分屏显示 compare: { type: Boolean, default: false }, // 是否插入到body元素上 appendToBody: { type: Boolean, default: false }, // 自定义css类名 customClass: { type: String, default: '' } }, 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.addLine() this.addPipe() // this.addPipe2() 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 // label: { // // 面中心点,显示文字的配置 // text: '{name}', // 对应的属性名称 // opacity: 1, // font_size: 20, // color: '#ffffff', // // font_family: '楷体', // outline: true, // outlineColor: '#ffffff', // outlineWidth: 1, // // 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, // // distanceDisplayCondition: false, // distanceDisplayCondition_far: 10000, // distanceDisplayCondition_near: 0, // visibleDepth: 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) }, // 材质线的管线 addPipe2() { const { mars3d } = this var graphicLayer = new mars3d.layer.GraphicLayer() this.map.addLayer(graphicLayer) axios.get('static/geojson/pipe.json').then((res) => { if (res.status === 200) { const features = res.data.features for (const feature of features) { this.addMaterialLine(graphicLayer, feature.geometry.coordinates) } } }) }, // 添加线方法 addMaterialLine(graphicLayer, arr, options) { const { mars3d, Cesium } = this const positionsArr = arr.map(item => { return Cesium.Cartesian3.fromDegrees(item[0], item[1], item[2]) }) console.log(positionsArr) var primitive = new mars3d.graphic.PolylinePrimitive({ positions: positionsArr, style: { width: 10, material: mars3d.MaterialUtil.createMaterial(mars3d.MaterialType.LineFlow, { image: 'static/images/map/LinkPulse.png', color: '#ff0000', repeat: new Cesium.Cartesian2(10.0, 1.0), speed: 2 }) } }) graphicLayer.addGraphic(primitive) }, // 添加mapV管线 addPipe3() { axios.get('static/geojson/pipe.json').then((res) => { if (res.status === 200) { const features = res.data.features for (const feature of features) { this.addMapvLine(feature.geometry.coordinates) } } }) // var graphicLayer = new mars3d.layer.GraphicLayer() // this.map.addLayer(graphicLayer) }, addMapvLine(arr, options) { const { mars3d } = this const timeData = arr.map((item, index) => { return { geometry: { type: 'Point', coordinates: [item[0], item[1]] }, count: 1, time: index } }) var options2 = { fillStyle: 'rgba(51,255,255, 0.2)', globalCompositeOperation: 'lighter', size: 3, animation: { stepsRange: { start: 0, end: 100 }, trails: 3, duration: 5 }, draw: 'simple', depthTest: false } var dataSet2 = new mapv.DataSet(timeData) var mapVLayer2 = new mars3d.layer.MapVLayer(options2, dataSet2) this.map.addLayer(mapVLayer2) }, // 添加省地块 addProvincePolygon() { const { mars3d } = 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 graphic = new mars3d.graphic.PolygonEntity({ positions: coordinates, style: { height: -10000, // heightReference: mars3d.Cesium.HeightReference.RELATIVE_TO_GROUND, hasShadows: true, diffHeight: 10000.0, color: '#3a77da', opacity: 1, outline: true, outlineColor: '#4764c9', outlineWidth: 3, outlineOpacity: 1, arcType: mars3d.Cesium.ArcType.GEODESIC, label: { // 面中心点,显示文字的配置 text: 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) // var entity = event.czmObject // if (entity && entity.polygon) { // this.highlightedEntity(entity) // } // }) // graphicLayer.on(mars3d.EventType.mouseOut, event => { // console.log('鼠标移出图层', 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>