2023-08-18 08:55:52 +08:00
|
|
|
|
<template>
|
2023-08-26 14:07:11 +08:00
|
|
|
|
<div
|
|
|
|
|
|
:id="`mars3d-container${mapKey}`"
|
|
|
|
|
|
:class="[
|
|
|
|
|
|
'mars3d-container',
|
|
|
|
|
|
customClass,
|
|
|
|
|
|
{ 'mars3d-container-compare-rh': compare },
|
|
|
|
|
|
]"
|
|
|
|
|
|
></div>
|
2023-08-18 08:55:52 +08:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2023-08-26 14:07:11 +08:00
|
|
|
|
import Vue from "vue";
|
|
|
|
|
|
import axios from "axios";
|
|
|
|
|
|
import AppInfo from "../../../public/config/app.json";
|
2024-05-14 15:40:21 +08:00
|
|
|
|
let GEOSERVER_BASE_API = process.env.VUE_APP_GEOSERVER_URL;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
// 为了方便使用,绑定到原型链,在其他vue文件,直接 this.mars3d 来使用
|
2023-08-26 14:07:11 +08:00
|
|
|
|
Vue.prototype.mars3d = window.mars3d;
|
|
|
|
|
|
Vue.prototype.Cesium = mars3d.Cesium;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
export default {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
name: "mars3dViewer",
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
props: {
|
|
|
|
|
|
// 初始化配置参数
|
|
|
|
|
|
url: String,
|
|
|
|
|
|
widgetUrl: String,
|
|
|
|
|
|
|
|
|
|
|
|
// 地图唯一性标识
|
|
|
|
|
|
mapKey: {
|
|
|
|
|
|
type: String,
|
2023-08-26 14:07:11 +08:00
|
|
|
|
default: "",
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 自定义参数
|
|
|
|
|
|
options: Object,
|
|
|
|
|
|
|
|
|
|
|
|
// 是否分屏显示
|
|
|
|
|
|
compare: {
|
|
|
|
|
|
type: Boolean,
|
2023-08-26 14:07:11 +08:00
|
|
|
|
default: false,
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 是否插入到body元素上
|
|
|
|
|
|
appendToBody: {
|
|
|
|
|
|
type: Boolean,
|
2023-08-26 14:07:11 +08:00
|
|
|
|
default: false,
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
// 自定义css类名
|
|
|
|
|
|
customClass: {
|
|
|
|
|
|
type: String,
|
2023-08-26 14:07:11 +08:00
|
|
|
|
default: "",
|
|
|
|
|
|
},
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
mounted() {
|
|
|
|
|
|
if (this.appendToBody) {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
document.body.appendChild(this.$el);
|
2023-08-18 08:55:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this.mapKey) {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this.initMars3d(this.options);
|
2023-08-18 08:55:52 +08:00
|
|
|
|
} else {
|
|
|
|
|
|
mars3d.Resource.fetchJson({ url: this.url }).then((data) => {
|
2023-09-04 15:46:49 +08:00
|
|
|
|
// 根据沂水县平邑登录获取对应的图层
|
2023-09-06 16:44:09 +08:00
|
|
|
|
try{
|
|
|
|
|
|
axios({
|
|
|
|
|
|
method: "get",
|
|
|
|
|
|
url: AppInfo[localStorage.getItem("areaName")].layerurl,
|
|
|
|
|
|
}).then((res) => {
|
|
|
|
|
|
let configLayers = [];
|
|
|
|
|
|
res.data.data.forEach((item, index) => {
|
|
|
|
|
|
let group = null;
|
|
|
|
|
|
group = {
|
|
|
|
|
|
id: parseInt(Math.random() * 10000000),
|
|
|
|
|
|
name: item.serverName,
|
|
|
|
|
|
type: "group",
|
|
|
|
|
|
};
|
2023-09-12 13:32:00 +08:00
|
|
|
|
configLayers.unshift(group);
|
2024-10-23 09:22:04 +08:00
|
|
|
|
|
2023-09-06 16:44:09 +08:00
|
|
|
|
if (item.children && item.children.length > 0) {
|
|
|
|
|
|
item.children.forEach((it, idx) => {
|
2024-11-05 16:52:54 +08:00
|
|
|
|
|
2023-09-06 16:44:09 +08:00
|
|
|
|
let attribute = JSON.parse(it.attribute);
|
|
|
|
|
|
attribute.pid = group.id;
|
2024-10-25 14:32:39 +08:00
|
|
|
|
delete attribute.highlight;
|
2024-05-14 15:40:21 +08:00
|
|
|
|
|
|
|
|
|
|
if(attribute.type == "geojson"){
|
|
|
|
|
|
delete attribute.symbol.styleOptions.opacity
|
|
|
|
|
|
delete attribute.symbol.styleOptions.color
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-10-23 09:22:04 +08:00
|
|
|
|
if(attribute && attribute.symbol && attribute.symbol.styleField && attribute.symbol.styleFieldOptions && Object.keys(attribute.symbol.styleFieldOptions).length>0){
|
|
|
|
|
|
attribute.type = 'geojson';
|
|
|
|
|
|
|
|
|
|
|
|
if(attribute.layers){
|
|
|
|
|
|
attribute.url = "geoserver/ksp/ows?service=WFS&version=1.0.0&request=GetFeature&typeName="+attribute.layers+"&maxFeatures=1000000&outputFormat=application%2Fjson";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
delete attribute.layers;
|
|
|
|
|
|
// delete attribute.symbol.styleOptions.color;
|
|
|
|
|
|
delete attribute.parameters;
|
|
|
|
|
|
delete attribute.highlight;
|
|
|
|
|
|
|
|
|
|
|
|
// if(!attribute.symbol.styleOptions){
|
|
|
|
|
|
attribute.symbol.styleOptions = {
|
|
|
|
|
|
"opacity": 0.8,
|
|
|
|
|
|
"color": "",
|
|
|
|
|
|
"width": 2,
|
|
|
|
|
|
"clampToGround": true
|
|
|
|
|
|
}
|
|
|
|
|
|
// }
|
|
|
|
|
|
attribute.zIndex = 10000000000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-05-14 15:40:21 +08:00
|
|
|
|
let ipinfo = this.matchHttpIpPort(attribute.url);
|
|
|
|
|
|
if(ipinfo){ // 如果匹配得到则替换为配置文件中的
|
|
|
|
|
|
attribute.url = attribute.url.replace(ipinfo[0],GEOSERVER_BASE_API);
|
|
|
|
|
|
}else{ //如果没有匹配到则直接拼接
|
|
|
|
|
|
attribute.url = GEOSERVER_BASE_API+attribute.url
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2023-09-12 13:32:00 +08:00
|
|
|
|
configLayers.unshift(attribute);
|
2023-09-06 16:44:09 +08:00
|
|
|
|
});
|
|
|
|
|
|
}
|
2024-05-14 15:40:21 +08:00
|
|
|
|
|
2023-09-06 16:44:09 +08:00
|
|
|
|
});
|
2023-09-08 08:42:38 +08:00
|
|
|
|
data.map3d.layers = configLayers;
|
|
|
|
|
|
this.initMars3d(data.map3d);
|
2023-08-26 14:07:11 +08:00
|
|
|
|
});
|
2023-09-08 08:42:38 +08:00
|
|
|
|
|
2023-09-06 16:44:09 +08:00
|
|
|
|
}catch(e){
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this.initMars3d(data.map3d);
|
2023-09-08 08:42:38 +08:00
|
|
|
|
}finally{
|
|
|
|
|
|
|
2023-09-06 16:44:09 +08:00
|
|
|
|
}
|
2024-05-14 15:40:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
2023-08-18 08:55:52 +08:00
|
|
|
|
// this.initMars3d(data.map3d)// 构建地图
|
2023-08-26 14:07:11 +08:00
|
|
|
|
});
|
2023-08-18 08:55:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
destroy() {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this[`map${this.mapKey}`].destroy();
|
|
|
|
|
|
delete this[`map${this.mapKey}`];
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
methods: {
|
2024-05-14 15:40:21 +08:00
|
|
|
|
matchHttpIpPort(url) { // 匹配“ http://ip:port ”
|
|
|
|
|
|
const ipRegex = /^http\:\/\/\b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b\:\b[0-9]{1,5}\//;
|
|
|
|
|
|
const match = url.match(ipRegex);
|
|
|
|
|
|
if (match) {
|
|
|
|
|
|
return match;
|
|
|
|
|
|
}
|
|
|
|
|
|
return null;
|
|
|
|
|
|
},
|
2023-08-26 14:07:11 +08:00
|
|
|
|
getLayers() {},
|
2023-08-18 08:55:52 +08:00
|
|
|
|
initMars3d(options) {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
if (this[`map${this.mapKey}`]) return;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
const mapOptions = {
|
|
|
|
|
|
...options,
|
2023-08-26 14:07:11 +08:00
|
|
|
|
...this.options,
|
|
|
|
|
|
};
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
// 创建三维地球场景
|
2023-08-26 14:07:11 +08:00
|
|
|
|
var map = new mars3d.Map(`mars3d-container${this.mapKey}`, mapOptions);
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this[`map${this.mapKey}`] = map;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
// 挂载到全局对象下,所有组件通过 this.map 访问
|
|
|
|
|
|
// Vue.prototype[`map${this.mapKey}`] = map
|
|
|
|
|
|
|
|
|
|
|
|
// 绑定对alert的处理,右键弹出信息更美观。
|
2023-08-26 14:07:11 +08:00
|
|
|
|
window.haoutil = window.haoutil || {};
|
2023-08-18 08:55:52 +08:00
|
|
|
|
window.haoutil.msg = (msg) => {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this.$message.success(msg);
|
|
|
|
|
|
};
|
2023-08-18 08:55:52 +08:00
|
|
|
|
window.haoutil.alert = (msg) => {
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this.$message.success(msg);
|
|
|
|
|
|
};
|
|
|
|
|
|
//widget处理
|
|
|
|
|
|
if (
|
|
|
|
|
|
!(
|
|
|
|
|
|
typeof this.widgetUrl == "undefined" ||
|
|
|
|
|
|
this.widgetUrl == null ||
|
|
|
|
|
|
this.widgetUrl == ""
|
|
|
|
|
|
)
|
|
|
|
|
|
)
|
|
|
|
|
|
mars3d.Resource.fetchJson({ url: this.widgetUrl }).then((data) => {
|
|
|
|
|
|
this.initStaticWidget(map, data);
|
|
|
|
|
|
});
|
2023-08-18 08:55:52 +08:00
|
|
|
|
|
|
|
|
|
|
// 抛出事件
|
2023-08-26 14:07:11 +08:00
|
|
|
|
this.$emit("onload", map);
|
2023-08-18 08:55:52 +08:00
|
|
|
|
//开场动画
|
2023-08-27 10:57:18 +08:00
|
|
|
|
// map.openFlyAnimation({
|
|
|
|
|
|
// // duration1:4,
|
|
|
|
|
|
// // easingFunction1: Cesium.EasingFunction.QUINTIC_IN_OUT,
|
|
|
|
|
|
// callback: function () {
|
|
|
|
|
|
// //动画播放完成后回调
|
|
|
|
|
|
// },
|
|
|
|
|
|
// });
|
2023-08-18 08:55:52 +08:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
//初始化外部静态widget功能(兼容使用传统模式开发的一些widget)
|
2023-08-26 14:07:11 +08:00
|
|
|
|
initStaticWidget(map, widget) {
|
|
|
|
|
|
mars3d.widget.init(map, widget, "/");
|
|
|
|
|
|
},
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
2023-08-18 08:55:52 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
2023-08-26 14:07:11 +08:00
|
|
|
|
<style>
|
2023-08-18 08:55:52 +08:00
|
|
|
|
.mars3d-container {
|
|
|
|
|
|
height: 100%;
|
2023-08-26 14:07:11 +08:00
|
|
|
|
height: 100vh;
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 0px;
|
|
|
|
|
|
left: 0px;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 重写Cesium的css */
|
|
|
|
|
|
|
|
|
|
|
|
/**cesium按钮背景色*/
|
|
|
|
|
|
.cesium-button {
|
2023-08-21 17:32:19 +08:00
|
|
|
|
background-color: #062020;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
color: #e6e6e6;
|
|
|
|
|
|
fill: #e6e6e6;
|
|
|
|
|
|
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;
|
2024-10-24 13:46:10 +08:00
|
|
|
|
/** right: 460px; **/
|
2023-08-23 09:43:13 +08:00
|
|
|
|
bottom: 150px;
|
2023-08-18 08:55:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.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>
|