maxiaoxiao hai 5 meses
pai
achega
701ec418d0

BIN=BIN
src/assets/video.mp4


+ 204 - 0
src/components/3DAnalysis/ClippingPlanes/index1.vue

@@ -0,0 +1,204 @@
+<template>
+  <div>
+    <div id="cesiumViewer"></div>
+    <div class="action">
+      <div>
+        <span>轴:</span>
+        <div>
+          <button
+            v-for="axis in axisArr"
+            :key="axis"
+            :class="{ active: actionData.axis === axis }"
+            @click="changeAxis(axis)"
+          >
+            {{ axis }}
+          </button>
+        </div>
+      </div>
+      <div>
+        <span>方向:</span>
+        <div>
+          <button
+            v-for="direction in directionArr"
+            :key="direction"
+            :class="{ active: actionData.direction === direction }"
+            @click="changeDirection(direction)"
+          >
+            {{ direction }}
+          </button>
+        </div>
+      </div>
+      <div>
+        <span>离原点距离:</span>
+        <div>
+          <a-slider
+            v-model:value="actionData.distance"
+            :max="10"
+            :min="-10"
+            :step="0.01"
+            :tooltip-open="true"
+          />
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+ 
+<script setup>
+import * as Cesium from "cesium";
+import { onBeforeUnmount, onMounted, reactive } from "vue";
+let viewer,
+  modelEntity,
+  planeEntity = null;
+onMounted(() => {
+  addModal();
+});
+
+/****************** 初始化 *********************/
+
+/****************** 控制面板 *********************/
+let axisArr = ["x", "y", "z"];
+let directionArr = [1, -1];
+
+const actionData = reactive({
+  axis: "",
+  direction: 1,
+  distance: 0,
+});
+
+// 设置剖切面板的轴和方向
+const setClippingPlane = () => {
+  let axisVal = { x: 0, y: 0, z: 0 };
+  if (actionData.axis in axisVal) {
+    axisVal[actionData.axis] = actionData.direction;
+  }
+  return new Cesium.ClippingPlane(
+    new Cesium.Cartesian3(axisVal.x, axisVal.y, axisVal.z),
+    actionData.distance
+  );
+};
+
+// 轴改变
+const changeAxis = (axis) => {
+  clearPlanes();
+  if (actionData.axis === axis) {
+    actionData.axis = "";
+    return;
+  }
+  actionData.axis = axis;
+  let clippingPlane = setClippingPlane();
+  modelEntity.model.clippingPlanes._value.add(clippingPlane);
+  addSlice();
+};
+
+// 方向改变
+const changeDirection = (direction) => {
+  actionData.direction = direction;
+  clearPlanes();
+  let clippingPlane = setClippingPlane();
+  modelEntity.model.clippingPlanes._value.add(clippingPlane);
+  addSlice();
+};
+
+//清空
+const clearPlanes = () => {
+  modelEntity.model.clippingPlanes._value.removeAll();
+  planeEntity && viewer.entities.remove(planeEntity);
+  planeEntity = null;
+};
+
+/****************** 加载模型 *********************/
+const position = new Cesium.Cartesian3(
+  -2489625.0836225147,
+  -4393941.44443024,
+  3890535.9454173897
+);
+
+let clippingPlanes = new Cesium.ClippingPlaneCollection({
+  planes: [],
+  edgeWidth: 1.0,
+});
+
+const addModal = () => {
+  modelEntity = viewer.entities.add({
+    name: "model",
+    position,
+    model: {
+      uri: "/public/modals/haimianbaobao.glb",
+      minimumPixelSize: 500, // 最小的模型像素
+      maximumScale: 500, // 最大的模型像素
+      runAnimations: false, // 关闭动画
+      show: true,
+      clippingPlanes,
+    },
+  });
+  // 聚焦模型
+  viewer.trackedEntity = modelEntity;
+};
+
+// 添加剖切面
+const addSlice = () => {
+  for (let i = 0; i < clippingPlanes.length; ++i) {
+    const plane = clippingPlanes.get(i);
+    planeEntity = viewer.entities.add({
+      position,
+      plane: {
+        dimensions: new Cesium.Cartesian2(10, 10),
+        material: Cesium.Color.WHITE.withAlpha(0.1),
+        plane: new Cesium.CallbackProperty(
+          createPlaneUpdateFunction(plane),
+          false
+        ),
+        outline: true,
+        outlineColor: Cesium.Color.WHITE,
+      },
+    });
+  }
+};
+
+const createPlaneUpdateFunction = (plane) => {
+  return function () {
+    plane.distance = actionData.distance;
+    return plane;
+  };
+};
+
+onBeforeUnmount(() => {});
+</script>
+ 
+<style lang="less" scoped>
+#cesiumViewer {
+  width: 100%;
+  height: 100%;
+}
+.action {
+  width: 300px;
+  position: absolute;
+  right: 10px;
+  top: 10px;
+  background-color: #fff;
+  padding: 20px;
+  > div {
+    display: flex;
+    align-items: center;
+    margin-top: 20px;
+    &:first-of-type {
+      margin-top: 0;
+    }
+    button {
+      cursor: pointer;
+    }
+    > span {
+      flex-shrink: 0;
+      width: 100px;
+    }
+    > div {
+      flex: 1;
+    }
+  }
+  .active {
+    color: #fff;
+    background-color: cadetblue;
+  }
+}
+</style>

+ 175 - 0
src/components/3DAnalysis/Projection/index.vue

@@ -0,0 +1,175 @@
+<template>
+  <div class="sm-function-module-content">
+    <video
+      id="trailer"
+      WE
+      style="
+        visibility: hidden;
+        position: absolute;
+        top: 0px;
+        left: 0px;
+        width: 200px;
+        height: 200px;
+      "
+      autoplay
+      loop
+      crossorigin
+      controls
+    >
+      <source src="@/assets/video.mp4" type="video/mp4" />
+    </video>
+    <el-form :model="proform" ref="ruleForm" label-width="100px">
+      <el-form-item label="宽度:" prop="horizontal">
+        <el-slider
+          class="inputwidth"
+          :min="1"
+          :max="50"
+          :step="1"
+          v-model="proform.horizontal"
+          @input="chageHor"
+        ></el-slider>
+      </el-form-item>
+      <el-form-item label="高度:" prop="vertical">
+        <el-slider
+          class="inputwidth"
+          :min="1"
+          :max="50"
+          :step="1"
+          v-model="proform.vertical"
+          @input="chageVert"
+        ></el-slider>
+      </el-form-item>
+      <el-form-item label="距离:" prop="distance">
+        <el-slider
+          class="distance"
+          :min="100"
+          :max="1000"
+          :step="1"
+          v-model="proform.distance"
+          @input="chageDist"
+        ></el-slider>
+      </el-form-item>
+    </el-form>
+    <el-checkbox v-model="proform.visibleLine" @change="chageLineVisible">
+      显示视频投放线
+    </el-checkbox>
+    <div class="boxchild">
+      <el-button type="primary" size="mini" @click="active">
+        视频投放
+      </el-button>
+      <!-- <button type="button" id="cilpRegion" class="button black">
+      绘制裁剪面
+    </button> -->
+      <el-button type="primary" size="mini" @click="clear">清除</el-button>
+    </div>
+
+    <div id="toolbar" class="param-container tool-bar">
+      <!-- <div class="param-item">
+      <b>宽度:</b>
+      <input
+        type="range"
+        id="horizontal"
+        min="1"
+        max="50"
+        step="1"
+        value="20"
+      />
+    </div>
+    <div class="param-item">
+      <b>高度:</b>
+      <input type="range" id="vertical" min="1" max="50" step="1" value="10" />
+    </div>
+    <div class="param-item">
+      <b>距离:</b>
+      <input
+        type="range"
+        id="distance"
+        min="100"
+        max="1000"
+        step="1"
+        value="200"
+      />
+    </div>
+    <div class="param-item">
+      <b>裁剪模式:</b>
+      <select id="clip-mode" class="supermap3d-button">
+        <option value="clip-outside">保留区域外</option>
+        <option value="clip-inside">保留区域内</option>
+      </select>
+    </div>
+    <div>
+      <label>
+        <input
+          type="checkbox"
+          id="visibleLine"
+          style="display: inline-block; vertical-align: middle"
+          checked
+        />
+        <span style="display: inline-block; vertical-align: middle"
+          >显示视频投放线</span
+        >
+      </label>
+    </div> -->
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  proInit,
+  clearAndActive,
+  handler,
+  chageHor,
+  chageVert,
+  chageDist,
+  chageLineVisible,
+  centerPoint,
+} from "./projectionImage.js";
+export default {
+  data() {
+    return {
+      videoElement: "",
+      proform: {
+        horizontal: 2,
+        vertical: 1,
+        distance: 200,
+        visibleLine: true,
+      },
+    };
+  },
+  mounted() {
+    // if (this.analysisShow && this.skylineComb) {
+    // }
+    this.$nextTick(() => {
+      proInit();
+      this.videoElement = document.getElementById("trailer");
+    });
+  },
+  methods: {
+    active() {
+      clearAndActive(this.videoElement, 20, 10);
+      handler.activate();
+    },
+    clear() {
+      clearAndActive(this.videoElement, 20, 10);
+      handler.clear();
+      viewer.entities.remove(centerPoint);
+    },
+    chageHor(v) {
+      chageHor(v);
+    },
+    chageVert(v) {
+      chageVert(v);
+    },
+    chageDist(v) {
+      chageDist(v);
+    },
+    chageLineVisible(v) {
+      chageLineVisible(v);
+    },
+  },
+};
+</script>
+
+<style>
+</style>

+ 116 - 0
src/components/3DAnalysis/Projection/projectionImage.js

@@ -0,0 +1,116 @@
+
+export let projectionImage, handler, centerPoint
+export function proInit(pdistance = 300) {
+    viewer.resolutionScale = window.devicePixelRatio;
+    let scene = viewer.scene
+    // viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({
+    //     url: 'https://dev.virtualearth.net',
+    //     mapStyle: Cesium.BingMapsStyle.AERIAL,
+    //     key: URL_CONFIG.BING_MAP_KEY
+    // }));
+
+    // var scene = viewer.scene;
+    // scene.shadowMap.darkness = 1.275; //设置第二重烘焙纹理的效果(明暗程度)
+    // scene.debugShowFramesPerSecond = false;
+    // scene.hdrEnabled = false;
+    // scene.sun.show = true;
+
+    if (!scene.pickPositionSupported) {
+        alert('不支持深度纹理,视频投放功能无法使用!');
+    }
+    //图层加载完成,设置相机位置
+    scene.camera.setView({
+        destination: Cesium.Cartesian3.fromDegrees(109.5151, 18.3185, 100),
+        orientation: {
+            heading: 3.179304500963121,
+            pitch: -0.46239072362282485,
+            roll: 6.283185307179583
+        }
+    });
+
+    projectionImage = new Cesium.ProjectionImage(scene);
+    centerPoint = viewer.entities.add({
+        id: 'cameraCenter',
+        position: Cesium.Cartesian3.ZERO, // 初始位置设为当前视角中心,稍后更新
+        point: {
+            pixelSize: 10,
+            color: Cesium.Color.YELLOW,
+            outlineColor: Cesium.Color.BLACK,
+            outlineWidth: 2
+        }
+    });
+    handler = new Cesium.DrawHandler(viewer, Cesium.DrawMode.Point);
+
+    handler.movingEvt.addEventListener(function (windowPosition) {
+        // viewer.scene.pickPositionAsync(windowPosition).then((last) => {
+        // let geom = `POINT (${item.lzb_x} ${item.bzb_y}${gcHight ? ' ' + gcHight : ''})`
+        // loadGeoJSON(geom, "#facd91", { isfly: false, point: 'landslide' }, (data) => {
+        //     geoSources[item.bsm] = data;
+        //     data.name = "dzzh";
+        // });
+        let last = scene.pickPosition(windowPosition);
+
+        //计算该点与视口位置点坐标的距离
+        var distance = Cesium.Cartesian3.distance(scene.camera.position, last);
+        if (distance > 0) {
+            //将鼠标当前点坐标转化成经纬度
+            var cartographic = Cesium.Cartographic.fromCartesian(last);
+            var longitude = Cesium.Math.toDegrees(cartographic.longitude);
+            var latitude = Cesium.Math.toDegrees(cartographic.latitude);
+            var height = cartographic.height;
+            //通过该点设置视频投放对象的距离及方向
+            projectionImage.setDistDirByPoint([longitude, latitude, height]);
+            projectionImage.distance = pdistance;
+            centerPoint.position = Cesium.Cartesian3.fromDegrees(longitude, latitude, 0)
+
+        }
+        // })
+    });
+}
+export function clearAndActive(videoElement, horizontal = 20, verticalFov = 10,) {
+    // videoElement = videoElement// document.getElementById('trailer');
+    projectionImage.distance = 0.1;
+    var wgsPosition = viewer.scene.camera.positionCartographic;
+    var longitude = Cesium.Math.toDegrees(wgsPosition.longitude);
+    var latitude = Cesium.Math.toDegrees(wgsPosition.latitude);
+    var height = wgsPosition.height;
+    projectionImage.viewPosition = [longitude, latitude, height];
+    projectionImage.horizontalFov = horizontal;
+    projectionImage.verticalFov = verticalFov;
+    projectionImage.setImage({
+        video: videoElement
+    });
+    videoElement.play();
+    projectionImage.removeAllClipRegion();
+    projectionImage.build();
+
+}
+
+
+export function chageHor(value) {
+    if (projectionImage) projectionImage.horizontalFov = value;
+}
+export function chageVert(value) {
+    if (projectionImage) projectionImage.verticalFov = value;
+}
+export function chageDist(value) {
+    if (projectionImage) projectionImage.distance = value;
+}
+export function chageLineVisible(checked) {
+    if (projectionImage) projectionImage.hintLineVisible = checked;
+}
+export function chagecilpRegion(e) {
+    // handlerPolygon.deactivate();
+    // handlerPolygon.activate();
+}
+export function chageclipmode() {
+    let clipMode = $(this).val() === 'clip-inside' ? SuperMap3D.ModifyRegionMode.CLIP_INSIDE : SuperMap3D.ModifyRegionMode.CLIP_OUTSIDE;
+    if (projectionImage) projectionImage.setClipMode(clipMode);
+}
+
+// $('#loadingbar').remove();
+// $('#toolbar').show();
+// if (typeof Cesium !== 'undefined') {
+//     window.startupCalled = true;
+//     onload(Cesium);
+// }

+ 18 - 10
src/components/Combinations/analysisCombination/analysisCombination.vue

@@ -1,8 +1,7 @@
 <template>
   <div id="3DAnalysis" class="sm-panel analysis" v-show="analysisShow" v-drag>
     <div class="sm-content">
-      <div class="sm-panel-header">
-        <!-- headertwo -->
+      <div class="sm-panel-header headertwo">
         <span :class="{ titleColor: sightlineShow }" class="title-txt" @click="choose(0)">{{ Resource.sightline
           }}</span>
         <span :class="{ titleColor: viewshedShow }" class="title-txt" @click="choose(1)">{{ Resource.viewShed }}</span>
@@ -12,6 +11,7 @@
         <span :class="{ titleColor: skylineShow }" class="title-txt" @click="choose(4)">{{ Resource.skyline }}</span>
         <span :class="{ titleColor: smashingShow }" class="title-txt" @click="choose(5)">{{ Resource.smashing }}</span>
         <span :class="{ titleColor: clipPlaneShow }" class="title-txt" @click="choose(6)">模型剖切</span>
+        <span :class="{ titleColor: projectionShow }" class="title-txt" @click="choose(7)">视频融合</span>
         <span class="closeBtn" @click="toggleVisibility">&times;</span>
       </div>
       <!-- 调用子组件 -->
@@ -22,15 +22,17 @@
       <sm3d-skyline></sm3d-skyline>
       <sm3d-smashing></sm3d-smashing>
       <ClippingPlanes v-if="clipPlaneShow"></ClippingPlanes>
+      <Projection v-if="projectionShow"></Projection>
     </div>
   </div>
 </template>
 
 <script>
-import ClippingPlanes from "../../3DAnalysis/ClippingPlanes/index.vue";
+import ClippingPlanes from "@/components/3DAnalysis/ClippingPlanes/index.vue";
+import Projection from "@/components/3DAnalysis/Projection/index.vue";
 export default {
   name: "Sm3dAnalysis",
-  components: { ClippingPlanes },
+  components: { ClippingPlanes, Projection },
   props: {},
   data() {
     return {
@@ -62,6 +64,9 @@ export default {
     clipPlaneShow: function () {
       return this.sharedState.analysis[6];
     },
+    projectionShow: function () {
+      return this.sharedState.analysis[7];
+    },
     analysisShow: function () {
       return this.sharedState.toolBar[6];
     },
@@ -82,22 +87,25 @@ export default {
       }
       switch (i) {
         case 0:
-          store.setAnalysisAction([1, 0, 0, 0, 0, 0]);
+          store.setAnalysisAction([1, 0, 0, 0, 0, 0, 0]);
           break;
         case 1:
-          store.setAnalysisAction([0, 1, 0, 0, 0, 0, 0]);
+          store.setAnalysisAction([0, 1, 0, 0, 0, 0, 0, 0]);
           break;
         case 2:
-          store.setAnalysisAction([0, 0, 1, 0, 0, 0, 0]);
+          store.setAnalysisAction([0, 0, 1, 0, 0, 0, 0, 0]);
           break;
         case 3:
-          store.setAnalysisAction([0, 0, 0, 1, 0, 0, 0]);
+          store.setAnalysisAction([0, 0, 0, 1, 0, 0, 0, 0]);
           break;
         case 5:
-          store.setAnalysisAction([0, 0, 0, 0, 0, 1, 0]);
+          store.setAnalysisAction([0, 0, 0, 0, 0, 1, 0, 0]);
           break;
         case 6:
-          store.setAnalysisAction([0, 0, 0, 0, 0, 0, 1]);
+          store.setAnalysisAction([0, 0, 0, 0, 0, 0, 1, 0]);
+          break;
+          case 7:
+          store.setAnalysisAction([0, 0, 0, 0, 0, 0, 0,1]);
           break;
         default:
           store.setAnalysisAction([0, 0, 0, 0, 1, 0]);

+ 1 - 1
src/store/store.js

@@ -11,7 +11,7 @@ var store2 = {
         sceneAtttribute: [1, 0, 0, 0, 0],
         terrain: [0, 0, 0, 0, 1],
         clip: [1, 0, 0, 0],
-        analysis: [1, 0, 0, 0, 0, 0],
+        analysis: [1, 0, 0, 0, 0, 0, 0],
         cityPlan: [1, 0, 0, 0, 0],
         onlineEdit: [1, 0, 0],
         specialEffects: [0, 0, 0], //特效