195 lines
5.7 KiB
Vue
195 lines
5.7 KiB
Vue
<template>
|
|
<vc-entity
|
|
:show="pintype == 'landmark' ? landshow : show"
|
|
:position="position"
|
|
@click="clickPin"
|
|
@ready="ready"
|
|
>
|
|
<vc-graphics-billboard
|
|
:image="image"
|
|
:verticalOrigin="1"
|
|
:scale="pintype == 'landmark' ? jump : 1"
|
|
:color="pintype == 'landmark' ? jumpColor : 'none'"
|
|
/>
|
|
</vc-entity>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { LandMarkWindowStore } from '/@/stores/LandMarkWindow';
|
|
import { LandMarkShowStore } from '/@/stores/LandMarkShow';
|
|
import { ref, computed, watch } from "vue";
|
|
import { VcEntity, VcGraphicsBillboard } from "vue-cesium";
|
|
import { isLnglat } from "/@/api/util";
|
|
import { landmarkArr } from "/@/information/landmark";
|
|
import pin from "/@/assets/pin.png";
|
|
|
|
const LandMarkWindow = LandMarkWindowStore();
|
|
const LandMarkShow = LandMarkShowStore();
|
|
|
|
const props = defineProps({
|
|
position: {
|
|
type: Object,
|
|
default: { lng: NaN, lat: NaN },
|
|
},
|
|
image: {
|
|
type: String,
|
|
default: pin,
|
|
},
|
|
pintype: {
|
|
type: String,
|
|
default: "ordinary",
|
|
},
|
|
});
|
|
|
|
const show = computed(() => isLnglat(props.position));
|
|
|
|
const landshow = ref(false);
|
|
|
|
const jump = ref(1);
|
|
const jumpSwitch = ref(true);
|
|
const jumpColor = ref("none");
|
|
|
|
let Cesium = null,
|
|
viewer = null,
|
|
handler = null;
|
|
|
|
//标点动画
|
|
const animetion = () => {
|
|
setInterval(() => {
|
|
if (0.5 <= jump.value < 1.1 && jumpSwitch.value) {
|
|
jump.value = Math.round(jump.value * 100) / 100 + 0.05;
|
|
jumpColor.value = "none";
|
|
if (jump.value == 1.1) {
|
|
jumpSwitch.value = false;
|
|
jumpColor.value = "rgba(0,255,255,0.5)";
|
|
}
|
|
} else if (0.5 < jump.value <= 1.1) {
|
|
jump.value = Math.round(jump.value * 100) / 100 - 0.05;
|
|
jumpColor.value = "none";
|
|
if (jump.value == 0.5) {
|
|
jumpSwitch.value = true;
|
|
jumpColor.value = "rgba(0,255,255,0.5)";
|
|
}
|
|
}
|
|
}, 100);
|
|
};
|
|
|
|
const ready = (readyObj) => {
|
|
Cesium = readyObj.Cesium;
|
|
viewer = readyObj.viewer;
|
|
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
viewer.scene.postRender.addEventListener(() => {
|
|
if (viewer.camera.positionCartographic.height < 100000) {
|
|
landshow.value = true;
|
|
} else {
|
|
landshow.value = false;
|
|
}
|
|
});
|
|
if (props.pintype == "landmark") {
|
|
animetion();
|
|
}
|
|
};
|
|
|
|
let landTitle, landDescribes, landImgUrl, landPosition, landImgCount;
|
|
|
|
const insetLand = () => {
|
|
landmarkArr.forEach((element) => {
|
|
if (
|
|
element.position.lng == props.position.lng &&
|
|
element.position.lat == props.position.lat
|
|
) {
|
|
landTitle = element.landmark;
|
|
landDescribes = element.describes;
|
|
landImgUrl = element.imgUrl;
|
|
landPosition = element.position;
|
|
landImgCount = element.imgCount;
|
|
}
|
|
});
|
|
}
|
|
|
|
//清除事件监听
|
|
const clearDiv = (id) => {
|
|
viewer.scene.postRender.removeEventListener(addDynamicLabel);
|
|
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
};
|
|
|
|
const addDynamicLabel = (data) => {
|
|
insetLand();
|
|
LandMarkWindow.information.landTitle = landTitle;
|
|
LandMarkWindow.information.landDescribes = landDescribes;
|
|
LandMarkWindow.information.landImgUrl = landImgUrl;
|
|
LandMarkWindow.information.landPosition = landPosition;
|
|
LandMarkWindow.information.landImgCount = landImgCount;
|
|
LandMarkWindow.windowShow = true;
|
|
LandMarkWindow.hiddenWindow = false;
|
|
let gisPosition = data.position._value;
|
|
//cesium 渲染事件监听
|
|
viewer.scene.postRender.addEventListener(() => {
|
|
const canvasHeight = viewer.scene.canvas.height;
|
|
const windowPosition = new Cesium.Cartesian2();
|
|
Cesium.SceneTransforms.wgs84ToWindowCoordinates(
|
|
viewer.scene,
|
|
gisPosition,
|
|
windowPosition
|
|
);
|
|
//组件 LandMarkWindow 宽度
|
|
const elWidth = 300;
|
|
let showBottom = canvasHeight - windowPosition.y + 240 + "px";
|
|
let showLeft = windowPosition.x - elWidth / 2 + "px";
|
|
//使弹窗跟随标点移动
|
|
LandMarkWindow.windowPosition.bottom = showBottom;
|
|
LandMarkWindow.windowPosition.left = showLeft;
|
|
const camerPosition = viewer.camera.position;
|
|
let height = viewer.scene.globe.ellipsoid.cartesianToCartographic(camerPosition).height;
|
|
height += viewer.scene.globe.ellipsoid.maximumRadius;
|
|
if (viewer.camera.positionCartographic.height < 2400) {
|
|
LandMarkWindow.buttonText = true;
|
|
} else {
|
|
LandMarkWindow.buttonText = false;
|
|
}
|
|
if (viewer.camera.positionCartographic.height > 100000) {
|
|
LandMarkWindow.windowShow = false;
|
|
}else{
|
|
if(!LandMarkWindow.hiddenWindow){
|
|
LandMarkWindow.windowShow = true;
|
|
}
|
|
}
|
|
});
|
|
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
handler.setInputAction(function (movement) {
|
|
//点击空白处触发
|
|
LandMarkWindow.windowShow = false;
|
|
LandMarkWindow.hiddenWindow = true;
|
|
clearDiv();
|
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
};
|
|
|
|
watch(() => LandMarkWindow.flyToLand, (newValue, oldValue) => {
|
|
if(LandMarkWindow.flyToLand){
|
|
viewer.camera.flyTo({
|
|
destination: Cesium.Cartesian3.fromDegrees(
|
|
LandMarkWindow.information.landPosition.lng,
|
|
LandMarkWindow.information.landPosition.lat,
|
|
2000.0
|
|
),
|
|
});
|
|
LandMarkWindow.flyToLand = false;
|
|
}
|
|
})
|
|
|
|
const clickPin = () => {
|
|
if (props.pintype == "landmark") {
|
|
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
//cesium 监听鼠标事件
|
|
handler.setInputAction(function (movement) {
|
|
let pick = viewer.scene.pick(movement.position);
|
|
//点击标点时触发
|
|
if (Cesium.defined(pick) && pick.id.id) {
|
|
let id = pick.id.id;
|
|
let entiy = viewer.entities.getById(id);
|
|
addDynamicLabel(entiy);
|
|
}
|
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
}
|
|
};
|
|
</script> |