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.

333 lines
7.5 KiB

<template>
<mars-map :options="options" @onload="mapLoad"></mars-map>
</template>
<script setup>
import marsMap from "@/components/marsMap";
import PointJson from "./point.json";
let options = {
scene: {
center: {
lat: 31.035216,
lng: 120.656763,
alt: 652.5,
heading: 6.3,
pitch: -23,
},
showSun: false,
showMoon: false,
3 weeks ago
showSkyBox: true,
showSkyAtmosphere: true,
fog: false,
clock: {
currentTime: "2023-11-01 12:00:00", // 固定光照时间
},
cameraController: {
zoomFactor: 1.5,
minimumZoomDistance: 0.1,
maximumZoomDistance: 200000,
enableCollisionDetection: false, // 允许进入地下
},
},
terrain: {
show: false,
},
basemaps: [
{
id: 2021,
pid: 10,
name: "天地图影像",
icon: "https://data.mars3d.cn/img/thumbnail/basemap/tdt_img.png",
type: "group",
layers: [
{
name: "底图",
type: "tdt",
layer: "img_d",
},
{
name: "注记",
type: "tdt",
layer: "img_z",
},
],
show: true,
},
],
};
3 weeks ago
const params = reactive({
lat: 31.162232,
lng: 120.734077,
altitude: 3000,
heading: 0, //当前朝向
pitch: 0, //保当前俯仰角
roll: 0, //当前翻滚角
correction: 1,
speed: 800,
});
const EARTH_RADIUS = 6371000;
let isUav = true
const DIRECTION = {
UP: "w",
DOWN: "s",
LEFT: "a",
RIGHT: "d",
SPEED_UP: "q",
SPEED_DOWN: "e",
};
3 weeks ago
const keyboardMap = {
[DIRECTION.UP]: false,
[DIRECTION.DOWN]: false,
[DIRECTION.LEFT]: false,
[DIRECTION.RIGHT]: false,
[DIRECTION.SPEED_UP]: false,
[DIRECTION.SPEED_DOWN]: false,
};
let map = null;
3 weeks ago
let list = [];
let uav = null
const mapLayer = {};
const mapLoad = (mapInstance) => {
map = mapInstance;
//创建marker图层
mapLayer.markerLayer = new mars3d.layer.GraphicLayer({
allowDrillPick: true, // 如果存在坐标完全相同的图标点可以打开该属性click事件通过graphics判断
});
map.addLayer(mapLayer.markerLayer);
//创建无人机固定巡航
3 weeks ago
// initUav()
// // 绘制停机场矩形
// initRectangle();
// initMarker();
boostrapUav()
};
const boostrapUav = () => {
initUav()
onAddKeyboardListener()
const renderer = () => {
onAdjustParams();
onAdjustAttitude();
requestAnimationFrame(renderer);
};
renderer();
3 weeks ago
}
//开启按键监听
const onAddKeyboardListener = () => {
document.addEventListener("keydown", (e) => {
if (Object.keys(keyboardMap).includes(e.key)) {
keyboardMap[e.key] = true;
}
});
document.addEventListener("keyup", (e) => {
if (Object.keys(keyboardMap).includes(e.key)) {
keyboardMap[e.key] = false;
}
});
};
//开启飞行参数调整
const onAdjustParams = () => {
if (keyboardMap[DIRECTION.SPEED_UP]) {
params.speed += 100;
}
if (keyboardMap[DIRECTION.SPEED_DOWN]) {
if (params.speed >= 500) {
params.speed -= 100;
}
}
//机体爬升
if (keyboardMap[DIRECTION.UP] && params.pitch <= 0.3) {
params.pitch += 0.005;
if (params.pitch > 0) {
const { speed, pitch } = params;
const temp = (params.speed / 60 / 60 / 60) * 110;
//1经纬度约等于110km
params.altitude += temp * Math.sin(pitch);
}
}
//机体俯冲
if (keyboardMap[DIRECTION.DOWN] && params.pitch >= -0.3) {
params.pitch -= 0.006;
if (params.pitch < 0) {
const { speed, pitch } = params;
//1经纬度约等于110km
const temp = (params.speed / 60 / 60 / 60) * 110;
params.altitude += temp * Math.sin(pitch);
}
}
//机体左转
if (keyboardMap[DIRECTION.LEFT]) {
params.heading -= 0.115;
if (params.roll > -10) {
params.roll -= 0.115;
}
}
//机体右转
if (keyboardMap[DIRECTION.RIGHT]) {
params.heading += 0.115;
if (params.roll < 10) {
params.roll += 0.115;
}
}
const { heading, pitch, roll } = params;
const { abs, cos } = Math;
params.correction = abs(cos(heading) * cos(pitch));
if (abs(heading) < 0.001) params.heading = 0;
if (abs(roll) < 0.001) params.roll = 0;
if (abs(pitch) < 0.001) params.pitch = 0;
//方向自动回正
// if (params.heading > 0) params.heading -= 0.0025
// if (params.heading < 0) params.heading += 0.0025
if (params.roll > 0) params.roll -= 0.003;
if (params.roll < 0) params.roll += 0.003;
if (params.pitch < 0) params.pitch += 0.005;
if (params.pitch > 0) params.pitch -= 0.003;
};
// 开启飞行姿态调整/
const onAdjustAttitude = () => {
const temp = params.speed / 60 / 60 / 60 / 110;
params.lng += temp * Math.cos(Cesium.Math.toRadians(params.heading));
params.lat -= temp * Math.sin(Cesium.Math.toRadians(params.heading));
3 weeks ago
const { lng, lat, altitude, heading, pitch, roll } = params;
params.altitude += temp * Math.sin(pitch) * 110 * 1000 * 10;
const position = Cesium.Cartesian3.fromDegrees(lng, lat, altitude);
uav.model.setStyle({
heading,
pitch,
roll
});
uav.addTimePosition(position);
};
3 weeks ago
const initUav = () => {
if (list.length == 0) {
PointJson.map((item) => {
list.push(item.wz.split(",").map(Number));
});
}
uav = new mars3d.graphic.Route({
id: "uav",
name: "无人机模型",
position: {
3 weeks ago
type: "time", // 时序动态坐标
speed: 100,
list: list,
},
model: {
url: "https://data.mars3d.cn/gltf/mars/wrj.glb",
scale: 0.1,
minimumPixelSize: 0.1,
runAnimations: true,
// mergeOrientation: true,
3 weeks ago
},
3 weeks ago
camera: {
type: "gs",
3 weeks ago
},
});
mapLayer.markerLayer.addGraphic(uav);
3 weeks ago
};
const initRectangle = () => {
const graphic = new mars3d.graphic.RectanglePrimitive({
positions: [
[120.657821, 31.048952],
[120.657318, 31.047691],
[120.658122, 31.047505],
[120.658591, 31.04872],
],
style: {
color: "#22E8AE",
opacity: 0.4,
outline: true,
outlineColor: "#22E8AE",
},
});
mapLayer.markerLayer.addGraphic(graphic);
};
/**
* 渲染所有点位
*/
const initMarker = () => {
PointJson.map((item, index) => {
item.point = item.wz.split(",").map(Number);
// 绘制水波浪圆
circlePoint(item, index);
//绘制名字图标
lablePoint(item, index);
});
};
/**
*文字图标
*/
const lablePoint = (item, index) => {
const markerDiv = new mars3d.graphic.DivGraphic({
position: item.wz.split(",").map(Number),
id: `marker${index}`,
name: item.name,
style: {
html: `
<div class="div-marker">
<div class="marker-name">${item.name}</div>
<div class="marker-icon"></div>
</div>
`,
offsetY: -73,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
distanceDisplayCondition: true, // 按视距距离显示
},
});
mapLayer.markerLayer.addGraphic(markerDiv);
};
/**
* 点位底部圆特效
* @param item
* @param index
*/
const circlePoint = (item, index) => {
const graphic = new mars3d.graphic.CircleEntity({
position: item.point,
style: {
radius: 50,
height: 0,
materialType: mars3d.MaterialType.CircleWave,
materialOptions: {
color: "#59F9FF",
count: 2,
speed: 6,
},
distanceDisplayCondition: true, // 按视距距离显示
},
});
mapLayer.markerLayer.addGraphic(graphic);
};
</script>
<style scoped>
.mars3d-container {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
}
</style>