Browse Source

新渲染方式加载

zhiyuan-007 4 months ago
parent
commit
b0d81bd578

BIN
src/assets/view.png


+ 157 - 27
src/components/mapJK.vue

@@ -316,18 +316,144 @@ export default {
           m_handles.add(addScaleEvent.scaleHandle,scale_handle_id);
         }
       }
+      function getEyeExtent(){
+        const screenWidth = m_view.width;
+        const screenHeight = m_view.height;
+        // 四个角的像素坐标
+        const screenCorners = [
+          { x: 0, y: 0 }, // 左上角
+          { x: screenWidth, y: 0 }, // 右上角
+          { x: screenWidth, y: screenHeight }, // 右下角
+          { x: 0, y: screenHeight }, // 左下角
+        ];
+
+        const mapPoints = screenCorners.map((screenPoint) => {
+          return m_view.toMap(screenPoint);
+        });
+
+        // 获取最小和最大坐标值
+        const xmin = Math.min(...mapPoints.map((p) => p.x));
+        const ymin = Math.min(...mapPoints.map((p) => p.y));
+        const xmax = Math.max(...mapPoints.map((p) => p.x));
+        const ymax = Math.max(...mapPoints.map((p) => p.y));
+
+        const screenExtent = {
+          xmin: xmin,
+          ymin: ymin,
+          xmax: xmax,
+          ymax: ymax,
+          spatialReference: m_view.spatialReference,
+        };
+        console.log(screenExtent);
+        return screenExtent
+      }
+
+
       function showLayersWithScaleEventsReturn(scaleValue){
-        let layer = m_map.layers.find(item => item.id === "WhiteMold");
+        let eyeExtent = getEyeExtent();
+        let height = m_view.camera.position.z;
+        console.log("height",height,"scale",m_view.scale)
+        debugger
         if(scaleValue > 50000){
-          if(layer){
-            layer.visible = false;
+          if(addThreeGridEvent){
+            addThreeGridEvent.extent = {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax};
+            addThreeGridEvent.height = 1200;
+            addThreeGridEvent.size = 2000;
+            addThreeGridEvent.layerHeight = 400;
+            addThreeGridEvent.start();
+          }else{
+            addThreeGridEvent = new AddThreeGridEvent({
+              view:m_view,
+              extent:{minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax},
+              height:height>1200?1200:height,
+              size:2000,
+              layerHeight:400,
+            })
+            addThreeGridEvent.start();
           }
-        }else{
-          if(layer){
-            layer.visible = true;
+        }else if(scaleValue > 25000 && scaleValue <= 50000){
+          if(addThreeGridEvent){
+            addThreeGridEvent.extent = {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax};
+            addThreeGridEvent.height = height>1200?1200:height;
+            addThreeGridEvent.size = 400;
+            addThreeGridEvent.layerHeight = 400;
+            addThreeGridEvent.start();
+          }else{
+            addThreeGridEvent = new AddThreeGridEvent({
+              view:m_view,
+              extent: {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax},
+              height:height>1200?1200:height,
+              size:400,
+              layerHeight:400,
+            })
+            addThreeGridEvent.start();
+          }
+        }else if(scaleValue > 8000 && scaleValue <= 25000){
+          if(addThreeGridEvent){
+            addThreeGridEvent.extent = {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax};
+            addThreeGridEvent.height = height>1200?1200:height;
+            addThreeGridEvent.size = 123;
+            addThreeGridEvent.layerHeight = 123;
+            addThreeGridEvent.start();
+          }else{
+            addThreeGridEvent = new AddThreeGridEvent({
+              view:m_view,
+              extent: {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax},
+              height:height>1200?1200:height,
+              size:123,
+              layerHeight:123,
+            })
+            addThreeGridEvent.start();
+          }
+        }else if(scaleValue > 800 && scaleValue <= 8000){
+          if(addThreeGridEvent){
+            addThreeGridEvent.extent = {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax};
+            addThreeGridEvent.height = height>1200?1200:height;
+            addThreeGridEvent.size = 60;
+            addThreeGridEvent.layerHeight = 60;
+            addThreeGridEvent.start();
+          }else{
+            addThreeGridEvent = new AddThreeGridEvent({
+              view:m_view,
+              extent: {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax},
+              height:height>1200?1200:height,
+              size:60,
+              layerHeight:60,
+            })
+            addThreeGridEvent.start();
+          }
+        }else if(scaleValue <= 800){
+          if(addThreeGridEvent){
+            addThreeGridEvent.extent = {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax};
+            addThreeGridEvent.height = height>1200?1200:height;
+            addThreeGridEvent.size = 5;
+            addThreeGridEvent.layerHeight = 5;
+            addThreeGridEvent.start();
+          }else{
+            addThreeGridEvent = new AddThreeGridEvent({
+              view:m_view,
+              extent: {minX:eyeExtent.xmin,maxX:eyeExtent.xmax,minY:eyeExtent.ymin,maxY:eyeExtent.ymax},
+              height:height>1200?1200:height,
+              size:8,
+              layerHeight:8,
+            })
+            addThreeGridEvent.start();
           }
         }
+
       }
+      // function showLayersWithScaleEventsReturn(scaleValue){
+      //   let layer = m_map.layers.find(item => item.id === "WhiteMold");
+      //   if(scaleValue > 50000){
+      //     if(layer){
+      //       layer.visible = false;
+      //     }
+      //   }else{
+      //     if(layer){
+      //       layer.visible = true;
+      //     }
+      //   }
+      // }
       function viewshedAnalysis(params){
         let status = params.status;
         if(status === "hide"){
@@ -371,7 +497,11 @@ export default {
           return
         }
         addThreeGridEvent = new AddThreeGridEvent({
-          view:m_view
+          view:m_view,
+          extent : {minX:-60000,maxX:60000,minY:-60000,maxY:60000},
+          height : 1200,
+          size : 200,
+          layerHeight : 400
         })
         addThreeGridEvent.start();
       }
@@ -390,28 +520,28 @@ export default {
           map:m_map,
           layerId:"WhiteMold",
           rings:
-            [
-              [
-                2425.570123891455,
-                802.4959489723367
-              ],
-              [
-                3983.7870548734795,
-                796.6284491105638
-              ],
-              [
-                3953.6447199613026,
-                -126.47813961693197
-              ],
-              [
-                2399.753338035622,
-                -50.34620065126925
-              ],
               [
-                2425.570123891455,
-                802.4959489723367
+                [
+                  3593.510727444371,
+                  1477.9873809879282,
+                  0
+                ],
+                [
+                  2059.624729191924,
+                  657.1274997157789,
+                  0
+                ],
+                [
+                  2612.404454918337,
+                  -89.310007207348,
+                  0
+                ],
+                [
+                  3269.0228638724784,
+                  474.83225384561496,
+                  0
+                ]
               ]
-            ]
         });
         limitHeightAnalysisEvent.start()
       }

+ 1 - 1
src/config/basicTool.json

@@ -42,7 +42,7 @@
             "title":"WhiteMold",
             "visible": true,
             "opacity": 1,
-            "url": "https://cimweb.zjw.sh.cegn.cn:2008/MapServiceProxy/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzE5OTg2MDQsImtleSI6IjA1MTk1NDE4Iiwic2VydmljZU5vIjoiRDkwMDMwMDA2MjAyMzA4MDEiLCJ1c2VybmFtZSI6InB0Z2wifQ.cxIPV-WaKXH9Jkwbhlhco7WJN5Jh09JtTHQnSMKLLHM",
+            "url": "https://cimweb.zjw.sh.cegn.cn:2008/MapServiceProxy/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MzIyNTkzNTgsImtleSI6IjA1MTk1NDE4Iiwic2VydmljZU5vIjoiRDkwMDMwMDA2MjAyMzA4MDEiLCJ1c2VybmFtZSI6InB0Z2wifQ.p3Zfmz8gf0h02fq3dCyrPc6kL3vq4flTANziTglR9zM",
             "token": ""
           }
         }

+ 18 - 4
src/units/map/addThreeGridEvent.js

@@ -6,24 +6,38 @@ class AddThreeGridEvent{
     constructor(options){
         this.view = options.view;
         this.addThreeGridEvent = null;
+        this.extent = options.extent;
+        this.height = options.height;
+        this.size = options.size;
+        this.layerHeight = options.layerHeight;
+        this.layerColors = options.layerColors;
     }
     start(){
         let that = this;
         if(this.addThreeGridEvent){
-            clear();
+            this.clear();
         }
         let subRenderClass = RenderNode.createSubclass(ThreeGridClass);
         this.view.when(()=>{
             that.addThreeGridEvent = new subRenderClass({
                 view:that.view,
-                webgl
+                webgl,
+                extent: {
+                    minX: that.extent.minX < -60000?-60000:that.extent.minX,
+                    minY: that.extent.minY < -60000?-60000:that.extent.minY,
+                    maxX: that.extent.maxX > 60000?60000:that.extent.maxX,
+                    maxY: that.extent.maxY > 70000?70000:that.extent.maxY,
+                },
+                height:that.height,
+                size:that.size,
+                layerHeight:that.layerHeight,
             })
         })
     }
     clear(){
         if(this.addThreeGridEvent){
-            this.addLightBallEvent.destroy();
-            this.addLightBallEvent = null;
+            this.addThreeGridEvent.destroy();
+            this.addThreeGridEvent = null;
         }
     }
 }

+ 2 - 1
src/units/threejs/limitHeight.js

@@ -153,6 +153,7 @@ export const LimitHeightClass = {
     // 根据多边形点创建裁切面
     createClipPlane() {
         let clipPanels = [];
+        this.drawVertices.push(this.drawVertices[0])
         for (let k = 0; k < this.drawVertices.length - 1; k++) {
             let point1 = this.drawVertices[k];
             let point2 = this.drawVertices[k + 1];
@@ -161,7 +162,7 @@ export const LimitHeightClass = {
             let top1 = [];
             this.webgl.toRenderCoordinates(this.view, [point1[0], point1[1], 0], 0, this.view.spatialReference, base1, 0, 1);
             this.webgl.toRenderCoordinates(this.view, [point2[0], point2[1], 0], 0, this.view.spatialReference, base2, 0, 1);
-            this.webgl.toRenderCoordinates(this.view, [point1[0], point1[1], 1000], 0, this.view.spatialReference, top1, 0, 1);
+            this.webgl.toRenderCoordinates(this.view, [point1[0], point1[1], point1[2] + 1000], 0, this.view.spatialReference, top1, 0, 1);
 
             let plane = new THREE.Plane();
             let p1_1 = new THREE.Vector3(base1[0], base1[1], base1[2]);

+ 91 - 43
src/units/threejs/threeGrid.js

@@ -5,13 +5,17 @@ export const ThreeGridClass = {
         this.webgl = options.webgl;
         this.view = options.view;
         this.extent = options.extent||{minX:-5000,maxX:5000,minY:-5000,maxY:5000}; // {minX, maxX, minY, maxY}
-        this.height = options.height ||1000; // 网格总高度
-        this.size = options.size ||50; // 单个立方体的尺寸
+        this.height = options.height ||1200; // 网格总高度
+        this.size = options.size ||200; // 单个立方体的尺寸
+        this.layerHeight = this.layerHeight || 400, // 每层的高度
+        this.layerColors = this.layerColors || [new THREE.Color(0xff0000), new THREE.Color(0x00ff00), new THREE.Color(0x0000ff)] // 自定义每层颜色
         this.mesh = null;
         this._camera = null;
     },
 
+
     initialize() {
+        this.layerColors = [new THREE.Color(0xff0000), new THREE.Color(0x00ff00), new THREE.Color(0x0000ff)];
         this.renderer = new THREE.WebGLRenderer({
             context: this.gl,
             premultipliedAlpha: false,
@@ -63,98 +67,141 @@ export const ThreeGridClass = {
     },
 
     createInstancedMesh() {
-        const geometry = new THREE.BoxGeometry(this.size, this.size, this.size);
-    
+        const geometry = new THREE.BoxGeometry(this.layerHeight, this.size, this.size);
+
         const material = new THREE.MeshPhongMaterial({
             transparent: true,
-            opacity: 0.8,
+            opacity: 0.5,
         });
-    
+
         // 修改材质支持 instanceColor
         material.onBeforeCompile = (shader) => {
             shader.vertexShader = `
-                attribute vec3 instanceColor;
-                varying vec3 vColor;
-            ` + shader.vertexShader;
-    
+            attribute vec3 instanceColor;
+            varying vec3 vColor;
+        ` + shader.vertexShader;
+
             shader.vertexShader = shader.vertexShader.replace(
                 `#include <begin_vertex>`,
                 `
-                #include <begin_vertex>
-                vColor = instanceColor;
-                `
+            #include <begin_vertex>
+            vColor = instanceColor;
+            `
             );
-    
+
             shader.fragmentShader = `
-                varying vec3 vColor;
-            ` + shader.fragmentShader;
-    
+            varying vec3 vColor;
+        ` + shader.fragmentShader;
+
             shader.fragmentShader = shader.fragmentShader.replace(
                 `#include <dithering_fragment>`,
                 `
-                #include <dithering_fragment>
-                gl_FragColor.rgb = vColor;
-                `
+            #include <dithering_fragment>
+            gl_FragColor.rgb = vColor;
+            `
             );
         };
-    
+
         const xCount = Math.floor((this.extent.maxX - this.extent.minX) / this.size);
         const yCount = Math.floor((this.extent.maxY - this.extent.minY) / this.size);
-        const zCount = Math.floor(this.height / this.size);
+        const zCount = Math.floor(this.height / this.layerHeight);
         const count = xCount * yCount * zCount;
-    
+
         this.mesh = new THREE.InstancedMesh(geometry, material, count);
-    
+
         // 为实例添加颜色属性
         const instanceColors = new Float32Array(count * 3);
         const dummy = new THREE.Object3D();
         const color = new THREE.Color();
         let index = 0;
-    
+
+        // 存储合并后的线段
+        const mergedLines = [];
+
+        // 创建边框线的几何体 (LineSegments)
+        const edges = new THREE.EdgesGeometry(geometry);
+        const edgeMaterial = new THREE.LineBasicMaterial({
+            color: 0xffffff,
+            opacity: 0.8,
+            linewidth:8,
+            transparent: true
+        });
+
+        // 按照网格的格子来合并线段
         for (let i = 0; i < xCount; i++) {
             for (let j = 0; j < yCount; j++) {
                 for (let k = 0; k < zCount; k++) {
                     const worldX = this.extent.minX + i * this.size + this.size / 2;
                     const worldY = this.extent.minY + j * this.size + this.size / 2;
-                    const worldZ = k * this.size + this.size / 2;
-    
+                    const worldZ = k * this.layerHeight + this.layerHeight / 2;
+
                     let renderPos = [];
                     this.webgl.toRenderCoordinates(this.view, [worldX, worldY, worldZ], 0, this.view.spatialReference, renderPos, 0, 1);
-    
+
                     dummy.position.set(renderPos[0], renderPos[1], renderPos[2]);
                     dummy.updateMatrix();
                     this.mesh.setMatrixAt(index, dummy.matrix);
-    
-                    // 设置随机颜色
-                    color.setHSL(Math.random(), 0.8, 0.5);
+
+                    // 分配颜色:由层数计算从红到绿的渐变
+                    const layerFraction = k / (zCount - 1); // 当前层在总层数中的比例
+                    color.setHSL(layerFraction * 0.33, 1, 0.5); // HSL中的H从0(红)到0.33(绿)
+
                     instanceColors[index * 3] = color.r;
                     instanceColors[index * 3 + 1] = color.g;
                     instanceColors[index * 3 + 2] = color.b;
-    
+
+                    // 将当前格子的边框添加到合并的线段列表中
+                    const edgesArr = edges.attributes.position.array;
+                    const startIndex = index * edgesArr.length;
+
+                    for (let i = 0; i < edgesArr.length; i++) {
+                        mergedLines.push(edgesArr[i] + dummy.position.toArray()[i % 3]);
+                    }
+
                     index++;
                 }
             }
         }
-    
+
+        // 为实例化的网格设置颜色
         geometry.setAttribute('instanceColor', new THREE.InstancedBufferAttribute(instanceColors, 3));
         geometry.attributes.instanceColor.needsUpdate = true;
         this.mesh.instanceMatrix.needsUpdate = true;
+
+        // 创建合并后的线段几何体
+        const mergedLineGeometry = new THREE.BufferGeometry();
+        mergedLineGeometry.setAttribute('position', new THREE.Float32BufferAttribute(mergedLines, 3));
+        const mergedLineMesh = new THREE.LineSegments(mergedLineGeometry, edgeMaterial);
+
+        // 将网格和边框分别添加到场景中
+        this.scene.add(this.mesh);
+        this.scene.add(mergedLineMesh);  // 添加边框线
+
+        // 网格的光照
+        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
+        this.scene.add(ambientLight);
+
+        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
+        directionalLight.position.set(10, 10, 10);
+        this.scene.add(directionalLight);
     },
 
+
+
     updateColors() {
         const instanceColors = this.mesh.geometry.attributes.instanceColor.array;
         const color = new THREE.Color();
-    
-        for (let i = 0; i < this.mesh.count; i++) {
-            color.setHSL(Math.random(), 0.8, 0.5);
-            instanceColors[i * 3] = color.r;
-            instanceColors[i * 3 + 1] = color.g;
-            instanceColors[i * 3 + 2] = color.b;
-        }
-    
+
+        // for (let i = 0; i < this.mesh.count; i++) {
+        //     color.setHSL(Math.random(), 0.8, 0.5);
+        //     instanceColors[i * 3] = color.r;
+        //     instanceColors[i * 3 + 1] = color.g;
+        //     instanceColors[i * 3 + 2] = color.b;
+        // }
+
         // 标记颜色属性需要更新
         this.mesh.geometry.attributes.instanceColor.needsUpdate = true;
-    
+
         // 触发重新渲染
         this.requestRender();
     },
@@ -177,5 +224,6 @@ export const ThreeGridClass = {
 
         // cleanup
         this.resetWebGLState();
-    }
+    },
+
 }