| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- <template>
- <div class="mapBox">
- <div id="cesiumContainer" style="width: 100%; height: 100vh"></div>
- <div class="menuBox" :class="allyShow ? '' : 'switch'">
- <el-button type="primary" size="small" @click="resetViewport">初始化视角</el-button>
- <el-button type="primary" size="small" @click="switchLayer">返回</el-button>
- <el-tooltip
- class="box-item"
- effect="dark"
- :content="`点击${allyShow ? '隐藏' : '常显'}菜单栏`"
- placement="bottom-end"
- >
- <el-icon
- style="margin-left: 20px"
- size="20px"
- :color="allyShow ? '#1890ff' : '#f25656'"
- @click="allyShow = !allyShow"
- >
- <House
- :style="`transform: rotate(${
- allyShow ? -45 : 45
- }deg); transition: 0.2s; cursor: pointer;`"
- />
- </el-icon>
- </el-tooltip>
- </div>
- <comModelDialog :showcomModelDia="showcomModelDia" :modelVal="modelVal" @showDia="showComDia" />
- </div>
- </template>
- <script>
- import * as Cesium from "../../Cesium";
- import "../../Cesium/Widgets/widgets.css";
- import fjLonLatJson from "./fjLonLat.json";
- import comModelDialog from "@/components/comModelDialog.vue"
- export default {
- components: {
- comModelDialog
- },
- data() {
- return {
- allyShow: true,
- viewer: null,
- showcomModelDia: false,
- modelVal: null
- }
- },
- mounted() {
- this.initCesium();
- },
- methods: {
- async initCesium() {
- // Cesium.Ion.defaultAccessToken =
- // "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwYTQwNDk3MC05YTZkLTQ2ZTEtODc0MS1lZTFkYjFlOTFmNmQiLCJpZCI6MTcyNDQ1LCJpYXQiOjE3NTQ4ODA4MzF9.KnhENYiHxNwTkhTWRA-lHqG59coLVT2FsIyOru2TV3E";
- const box = document.getElementById('cesiumContainer')
- const viewer = new Cesium.Viewer(box, {
- animation: false,//是否创建动画小器件,左下角仪表
- baseLayerPicker: false,//是否显示图层选择器,右上角图层选择按钮
- baseLayer: false, // 不显示默认图层
- fullscreenButton: false,//是否显示全屏按钮,右下角全屏选择按钮
- timeline: false,//是否显示时间轴
- infoBox: false,//是否显示信息框
- sceneModePicker: false,//是否显示场景模式切换按钮
- vrButton: false,
- geocoder: false,//是否显示地理编码按钮
- homeButton: false,//是否显示地图导航按钮
- selectionIndicator: false,
- navigationHelpButton: false,
- shouldAnimate: true,
- imageryProvider: false, //控制默认底图的显示
- showGroundAtmosphere: false,
- depthTestAgainstTerrain: true,
- dynamicAtmosphereLightingFromSun: false,
- })
- const url = 'https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'
- const layer = Cesium.ImageryLayer.fromProviderAsync(
- Cesium.ArcGisMapServerImageryProvider.fromUrl(url)
- )
- viewer.imageryLayers.add(layer)
- viewer._cesiumWidget._creditContainer.style.display = "none";
- viewer.scene.globe.enableLighting = false;
- viewer.scene.sun.show = false;
- viewer.scene.moon.show = false;
- viewer.shadows = false;
- viewer.scene.skyAtmosphere.show = true;
- viewer._cesiumWidget._creditContainer.style.display = "none";
- viewer.terrainProvider = await Cesium.createWorldTerrainAsync({
- requestWaterMask: true,
- requestVertexNormals: true,
- });
- // this.csceneElliposid(viewer)
- viewer.camera.flyTo({
- // destination: Cesium.Cartesian3.fromDegrees(106.44, 37.27, 2000),// 场站位置
- destination: Cesium.Cartesian3.fromDegrees(106.712885, 37.413269, 8000),
- orientation: {
- heading: 0.9,
- pitch: -0.5,
- roll: 0,
- },
- duration: 3,
- });
- // 添加一些3D风机模型
- fjLonLatJson.data.forEach(e => {
- this.addModel(
- viewer,
- "./static/model/fjSolo/model.glb",
- "风机",
- e.longitude,
- e.latitude,
- 0.5,
- e
- );
- });
- //添加3D光伏模型
- this.addModel(
- viewer,
- "./static/model/SolarPowerPlant/model.glb",
- "光伏",
- 106.797343,
- 37.546013,
- 20,
- null
- );
- // 创建一个方向光
- const directionalLight = new Cesium.DirectionalLight({
- direction: Cesium.Cartesian3.normalize(
- new Cesium.Cartesian3(0, 0, 1), // 光照方向(从左前上方来)
- new Cesium.Cartesian3()
- ),
- color: Cesium.Color.WHITE, // 光源颜色
- intensity: 10.0 // 强度(默认 1.0,可调高)
- });
- // 替换默认光源
- viewer.scene.light = directionalLight;
- this.viewer = viewer
-
- },
- addModel(viewer, uri, name, lon, lat, scale, val) {
- const hpRoll = new Cesium.HeadingPitchRoll(90.0, 0.0, 0.0);
- const position = Cesium.Cartesian3.fromDegrees(lon, lat);
- const orientation = Cesium.Transforms.headingPitchRollQuaternion(
- position,
- hpRoll
- );
- const entity = viewer.entities.add({
- name, // 模型名称
- position, // 模型位置
- orientation, // 模型朝向
- model: {
- uri,
- scale,
- // 模型贴地
- heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
- },
- //添加标签
- label: {
- text: val ? val.name : name, // 标签文字
- font: '14px sans-serif', // 字体
- fillColor: Cesium.Color.YELLOW, // 填充颜色
- outlineColor: Cesium.Color.BLACK, // 描边颜色
- outlineWidth: 2, // 描边宽度
- style: Cesium.LabelStyle.FILL_AND_OUTLINE, // 填充+描边
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 文本在模型上方
- horizontalOrigin: Cesium.HorizontalOrigin.CENTER, // 水平居中
- eyeOffset: new Cesium.Cartesian3(50, 1150, 5), // 向上 15 米
- translucencyByDistance: new Cesium.NearFarScalar(1.0e6, 1.0, 6.0e6, 0.0)
- }
- });
- let that = this
- // 创建事件处理器
- const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
- handler.setInputAction(function(click) {
- const picked = viewer.scene.pick(click.position);
- if (picked && picked.id === entity) {
- console.log('你点击了标签或模型!', entity);
- console.log('标签或模型数据!', val);
- // alert('你点击了: ' + entity.label.text.getValue());
- // this.$refs.comModelDialog.init(val)
- if (name !== '光伏') {
- that.showcomModelDia = true
- that.modelVal = val
- }
- }
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- },
- showComDia(val) {
- this.showcomModelDia = val
- this.modelVal = null
- },
- csceneElliposid(viewer) {
- let that = this
- // 获取 scene 和 ellipsoid
- var scene = viewer.scene;
- var labels = viewer.scene.primitives.add(new Cesium.LabelCollection());
- // 创建 ScreenSpaceEventHandler
- var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
- // 监听左键点击事件
- handler.setInputAction(async(click) => {
- // 获取点击位置的笛卡尔坐标
- var position = click.position;
- if (!position) return;
- // 使用 globe.pick 获取包含地形高度的坐标
- var ray = viewer.camera.getPickRay(position);
- var cartesian = viewer.scene.globe.pick(ray, viewer.scene);
-
- if (cartesian) {
- // 转换为地理坐标
- var cartographic = Cesium.Cartographic.fromCartesian(cartesian);
- var longitude = Cesium.Math.toDegrees(cartographic.longitude);
- var latitude = Cesium.Math.toDegrees(cartographic.latitude);
- var height = cartographic.height;
- // 格式化坐标
- var text = `经度: ${longitude.toFixed(6)}°\n纬度: ${latitude.toFixed(6)}°`;
- // 创建一个标签
- var label = labels.add({
- position: cartesian,
- text: text,
- font: '14px monospace',
- fillColor: Cesium.Color.fromCssColorString('#1d70df'),
- // style: Cesium.LabelStyle.FILL_AND_OUTLINE,
- // outlineColor: Cesium.Color.BLACK,
- outlineWidth: 2,
- verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 标签在点的上方
- pixelOffset: new Cesium.Cartesian2(0, -20), // 向上偏移一点
- disableDepthTest: true, // 让标签始终可见(即使在地球背面)
- scale: 0.8
- });
- // 5秒后移除标签
- setTimeout(function() {
- labels.remove(label);
- }, 5000);
- console.log(`点击坐标: ${longitude.toFixed(6)}, ${latitude.toFixed(6)}, ${height.toFixed(2)}m`);
- }
- }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
- },
- // 重置视角
- resetViewport() {
- // 设置初始视图为宁夏
- this.viewer.camera.flyTo({
- destination: Cesium.Cartesian3.fromDegrees(106.712885, 37.413269, 8000),
- orientation: {
- heading: 0.9,
- pitch: -0.5,
- roll: 0,
- },
- duration: 3,
- });
- },
- switchLayer() {
- this.$router.push({
- path: '/'
- })
- }
- }
- }
- </script>
- <style lang="less" scoped>
- .mapBox {
- width: 100%;
- height: 100%;
- position: relative;
- box-sizing: content-box;
- .menuBox {
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- background: #fff;
- opacity: 0.8;
- display: flex;
- justify-content: flex-end;
- align-items: center;
- padding: 10px;
- &.switch {
- opacity: 0;
- transition: 0.2s;
- &:hover {
- opacity: 1;
- transition: 0.2s;
- }
- }
- }
- }
- </style>
|