You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

397 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="map-container">
<div class="input-search" ref="targetElement">
<div class="search-box">
<input type="text" placeholder="请输入路线或者临时任务名称" />
<div class="search-btn" @click="show = !show">搜索</div>
</div>
<el-collapse-transition>
<div v-show="show" class="search-list">
<div class="list-item" v-for="(item, index) in 5" :key="index">
002号线_01_维护_守押085_苏E
</div>
</div>
</el-collapse-transition>
</div>
<mars-map @mapLoad="mapLoad" :options="options"></mars-map>
<div class="multiple">
<div
@click="toggleSelection(item)"
:class="{ checkbox: true, checked: isSelected(item) }"
v-for="(item, index) in multipleList"
:key="index"
>
<img
:src="
isSelected(item)
? require(`../assets/images/${item}-active.png`)
: require(`../assets/images/${item}.png`)
"
alt=""
class="btn-icon"
/>
{{ item }}
</div>
</div>
<!-- <div class="video-list" v-show="showVideo">
<grids></grids>
</div> -->
</div>
</template>
<script>
import { getCarLocation } from "@/api/static/index.js";
import MarsMap from "@/components/mars-map";
// import grids from "@/components/grids.vue";
export default {
data() {
const basePathUrl = window.basePathUrl || "";
return {
multipleList: ["营运线路", "维护线路", "临时任务"],
selectedItems: [],
graphicLayer: null,
baseUrl: basePathUrl + "lib/geoJson/tileset.json",
map: null,
options: {
scene: {
center: {
lat: 31.212805,
lng: 120.607156,
alt: 5096.4,
heading: 357.9,
pitch: -31.5,
},
},
basemaps: [
{
name: "mapbox影像图",
icon: "img/basemaps/mapboxSatellite.png",
type: "mapbox",
username: "sharealex",
styleId: "cly5i21fn00e901prgq643t4r",
token:
"pk.eyJ1Ijoic2hhcmVhbGV4IiwiYSI6ImNsaXNhZmRjbTFhbnczZmxib3h1OW05YXYifQ.PhlKv60ar3K359d8x2yBPw",
tilesize: 256,
scaleFactor: false,
show: true,
},
],
},
show: false,
showVideo: true,
};
},
components: { MarsMap },
beforeDestroy() {
clearInterval(this.timer);
// 在组件销毁之前移除事件监听,防止内存泄漏
document.removeEventListener("click", this.handleClickOutside);
},
mounted() {
// 在mounted钩子中添加全局点击事件监听
document.addEventListener("click", this.handleClickOutside);
},
methods: {
// 获取车辆信息
getCarLocation() {
getCarLocation().then((res) => {
this.createCar(res.list);
});
},
/**
* 创建车辆图标
*/
createCar(list) {
list.map((item, index) => {
const graphic = new mars3d.graphic.ModelEntity({
id: `car${item.carId}`,
position: [parseFloat(item.lng), parseFloat(item.lat)],
style: {
heading: parseInt(item.drct),
url: "//data.mars3d.cn/gltf/imap/ce2fddca7bac436d8d318bcd4fdf2d69/gltf/gltf2.gltf",
scale: 0.5,
minimumPixelSize: 35,
silhouette: true,
silhouetteColor: "#025CC1",
silhouetteSize: 2,
// 高亮时的样式默认为鼠标移入也可以指定type:'click'单击高亮构造后也可以openHighlight、closeHighlight方法来手动调用
highlight: {
type: mars3d.EventType.click,
silhouette: true,
silhouetteColor: "#FAAC51",
silhouetteSize: 2,
label: {
outlineColor: "#FAAC51",
},
},
label: {
// 不需要文字时去掉label配置即可
text: item.carName,
font_size: 14,
color: "#ffffff",
outline: true,
outlineColor: "#000000",
pixelOffsetY: -30,
distanceDisplayCondition: true,
distanceDisplayCondition_far: 50000,
distanceDisplayCondition_near: 0,
},
clampToGround: true,
},
// forwardExtrapolationType: Cesium.ExtrapolationType.NONE,
attr: { index: index, remark: "Model示例" },
});
this.graphicLayer.addGraphic(graphic);
});
},
/**
* 生成车辆实时点位
*/
// createCar(list) {
// let _this = this;
// console.log(list);
// for (let i = 0; i < list.length; i++) {
// let item = list[i];
// const graphic = new mars3d.graphic.DivGraphic({
// id: "car" + i,
// position: [parseFloat(item.lng), parseFloat(item.lat)],
// style: {
// className: `carIcon`,
// html: `<div>
// <div class="car-name">${item.carName}</div>
// </div>`,
// color: "#fff",
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER, //
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
// distanceDisplayCondition: false,
// clampToGround: true,
// highlight: {
// type: "click",
// className: `carIconActive`,
// },
// },
// attr: {
// index: i,
// id: "car" + i,
// },
// });
// graphic.on(mars3d.EventType.highlightOpen, function (event) {
// _this.$router.push("/carInfo");
// });
// this.graphicLayer.addGraphic(graphic);
// }
// // this.changePosition(0);
// // setInterval
// // const interval = 30;
// // this.changePosition(interval);
// // this.timer = setInterval(() => {
// // _this.changePosition(interval);
// // }, interval * 1000);
// },
handleClickOutside(event) {
// 判断点击的元素是否在目标元素外部
if (this.show && !this.$refs.targetElement.contains(event.target)) {
this.show = false;
}
},
toggleSelection(item) {
// 切换选中状态
if (this.isSelected(item)) {
this.selectedItems = this.selectedItems.filter(
(selectedItem) => selectedItem !== item
);
} else {
this.selectedItems.push(item);
}
},
isSelected(item) {
// 检查某个项是否被选中
return this.selectedItems.includes(item);
},
mapLoad(map) {
this.map = map;
this.graphicLayer = new mars3d.layer.GraphicLayer();
map.addLayer(this.graphicLayer);
this.initTilesetLayer();
},
// 改变位置
changePosition(time) {
let _this = this;
this.graphicLayer.eachGraphic((graphic) => {
if (graphic.isPrivate) {
return;
}
graphic.addDynamicPosition(_this.randomPoint(), time); // 按time秒运动至指定位置
});
},
// 取区域内的随机点
randomPoint() {
const jd = this.random(120.5265 * 1000, 120.7177 * 1000) / 1000;
const wd = this.random(31.2783 * 1000, 31.4647 * 1000) / 1000;
return Cesium.Cartesian3.fromDegrees(jd, wd);
},
random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
},
/**
* 加载姑苏区三维图层
*/
initTilesetLayer() {
let _this = this;
// 添加参考三维模型;
const tiles3dLayer = new mars3d.layer.TilesetLayer({
name: "姑苏区建筑物",
url: "https://www.jichuanglanhai.com:88/3dtiles/yunkun/tileset.json",
maximumScreenSpaceError: 1,
style: {
color: {
conditions: [["true", `color("rgba(42, 160, 224, 1)")`]],
},
},
});
this.map.addLayer(tiles3dLayer);
if (process.env.NODE_ENV === "production") this.chkShadows(true);
tiles3dLayer.on(mars3d.EventType.load, function (event) {
_this.getCarLocation();
});
},
chkShadows(val) {
let _this = this;
this.map.viewer.shadows = val;
if (val) {
setTimeout(function () {
// 光照沿着相机方向
_this.map.scene.shadowMap._lightCamera = _this.map.scene.camera;
}, 1500);
}
},
},
};
</script>
<style lang="scss" scoped>
.input-search {
position: absolute;
top: 23px;
left: 50%;
transform: translateX(-50%);
z-index: 100;
.search-box {
display: flex;
align-items: center;
height: 32px;
}
.search-btn {
cursor: pointer;
line-height: 32px;
background: #0084ff;
color: #ffffff;
font-size: 14px;
padding: 0 10px;
height: 100%;
border-radius: 0 3px 3px 0;
}
input {
font-size: 14px;
width: 280px;
height: 100%;
border: 1px solid #0084ff;
border-right: 0;
background: #032b57;
padding-left: 6px;
color: #ffffff;
}
input::placeholder {
color: #7c91a8;
}
input:focus-visible {
outline: none;
}
.search-list {
width: 280px;
background: #032b57;
color: #fff;
border: 1px solid #0084ff;
border-top: 0;
& > div {
font-size: 14px;
padding: 10px;
}
& > div:hover {
background: #0084ff;
}
}
}
.video-list {
position: absolute;
bottom: 25px;
left: 50%;
transform: translateX(-50%);
z-index: 50;
padding: 10px;
display: flex;
align-items: center;
border: 1px solid #415367;
border-radius: 10px;
background: rgba(28, 31, 34, 0.6);
}
.multiple {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
z-index: 50;
width: 880px;
height: 80px;
display: flex;
align-items: center;
justify-content: space-between;
background: url("../assets/images/multipleList.png");
background-size: 100% 100%;
padding: 0 230px;
.checkbox {
cursor: pointer;
width: 112px;
height: 32px;
line-height: 32px;
text-align: center;
font-size: 14px;
color: #ffffff;
background: linear-gradient(180deg, #072853 0%, #0079ff 100%);
// border-radius: 16px;
border: 1px solid #0084ff;
border-radius: 16px;
display: flex;
align-items: center;
justify-content: center;
}
.checked {
background: #fd873f;
color: #612500;
border: 0;
font-weight: bold;
border: 1px solid #f7c75d;
}
.btn-icon {
width: 15px;
height: 16px;
margin-right: 10px;
}
}
</style>