From 4529e45a7a7bc438dd4fabbf177f74cb2c0aa5b5 Mon Sep 17 00:00:00 2001
From: surprise <15810472099@163.com>
Date: 星期二, 09 一月 2024 16:10:14 +0800
Subject: [PATCH] 代码更新

---
 /dev/null                                     |  160 --------------------
 src/components/left/layerTree/messageInfo.vue |   32 ++-
 src/assets/js/Layer/mapViewer.js              |    8 
 src/assets/js/Layer/mapGeo.js                 |   42 ----
 src/components/left/layerTree/meuGrid.vue     |   21 +-
 src/components/left/leftmenu.vue              |    4 
 src/assets/js/Layer/drawGrid.js               |  159 +++++++++++++++++++
 static/layers.json                            |   12 
 src/components/menu/menulist.vue              |    9 
 9 files changed, 209 insertions(+), 238 deletions(-)

diff --git a/src/assets/js/Layer/drawGrid.js b/src/assets/js/Layer/drawGrid.js
new file mode 100644
index 0000000..3d65258
--- /dev/null
+++ b/src/assets/js/Layer/drawGrid.js
@@ -0,0 +1,159 @@
+import * as turf from '@turf/turf';
+import store from '../../../store';
+var drawGrid = {
+    id: "Rectangle",
+    drawRect: function () {
+        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
+        var points = [];
+        var shape = this.renderRect(points);
+        var step = 0;
+        var $this = this;
+
+        this.handler.setInputAction(function (e) {
+            var cartesian = viewer.scene.pickPosition(e.position);
+            if (!Cesium.defined(cartesian)) {
+                var ray = viewer.camera.getPickRay(e.position);
+                cartesian = viewer.scene.globe.pick(ray, viewer.scene);
+            }
+            points[step] = cartesian;
+            step++;
+            if (step === 3) {
+                $this.handler.destroy();
+                store.state.isshowGrid= true
+            }
+        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
+        this.handler.setInputAction(function (e) {
+            var cartesian = viewer.scene.pickPosition(e.startPosition);
+            if (!Cesium.defined(cartesian)) {
+                var ray = viewer.camera.getPickRay(e.startPosition);
+                cartesian = viewer.scene.globe.pick(ray, viewer.scene);
+            }
+            points[2] = cartesian;
+        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+    },
+    renderRect: function (points) {
+        var shape = viewer.entities.add({
+            id: this.id,
+            polygon: {
+                hierarchy: new Cesium.CallbackProperty(function () {
+                    if (points[0] && points[1] && points[2]) {
+                        var r0 = Cesium.Cartographic.fromCartesian(points[0]);
+                        var r1 = Cesium.Cartographic.fromCartesian(points[1]); // 杈呭姪鐐�
+                        var r2 = Cesium.Cartographic.fromCartesian(points[2]);
+
+                        var p0 = turf.point([
+                          (r0.longitude * 180) / Math.PI,
+                          (r0.latitude * 180) / Math.PI
+                        ]);
+                        var p1 = turf.point([
+                          (r1.longitude * 180) / Math.PI,
+                          (r1.latitude * 180) / Math.PI
+                        ]);
+                        var p2 = turf.point([
+                          (r2.longitude * 180) / Math.PI,
+                          (r2.latitude * 180) / Math.PI
+                        ]);
+
+                        this.rectanglePoint = p1;
+                        var bearing1 = turf.rhumbBearing(p0, p1);
+                        var bearing2 = turf.rhumbBearing(p0, p2);
+                        var angle1 = bearing2 - bearing1;
+
+                        // 瀵硅闀垮害
+                        var length = turf.distance(p0, p2, { units: "meters" });
+
+                        var len1 = Math.cos((angle1 / 180) * Math.PI) * length;
+                        var dest1 = turf.destination(p0, len1, bearing1, { units: "meters" });
+
+                        var angle2 = 90 - angle1;
+                        var len2 = Math.cos((angle2 / 180) * Math.PI) * length;
+                        var dest2 = turf.destination(p0, len2, 90 + bearing1, {
+                            units: "meters",
+                        });
+
+                        var coordinates = [
+                          points[0],
+                          Cesium.Cartesian3.fromDegrees(dest1.geometry.coordinates[0], dest1.geometry.coordinates[1]),
+                          points[2],
+                          Cesium.Cartesian3.fromDegrees(dest2.geometry.coordinates[0], dest2.geometry.coordinates[1])
+                        ];
+                        return new Cesium.PolygonHierarchy(coordinates);
+                    }
+                }, false),
+                material: Cesium.Color.CYAN.withAlpha(0.5),
+                outline: true,
+                outlineColor: Cesium.Color.BLACK,
+            },
+        });
+ 
+        return shape;
+    },
+    drawPoint: function ( res) {
+        var rect = viewer.entities.getById(this.id);
+        if (!rect) return;
+
+        var points = rect.polygon.hierarchy.getValue().positions;
+        //var r0 = Cesium.Cartographic.fromCartesian(points[0]);
+        //var r1 = Cesium.Cartographic.fromCartesian(points[1]);
+        //var r2 = Cesium.Cartographic.fromCartesian(points[2]);
+        
+        var r0 = Cesium.Cartographic.fromCartesian(points[0]);
+        var r1 = Cesium.Cartographic.fromCartesian(points[1]);
+        var r2 = Cesium.Cartographic.fromCartesian(points[2]);
+
+        var p0 = turf.point([(r0.longitude * 180) / Math.PI, (r0.latitude * 180) / Math.PI]);
+        var p1 = turf.point([(r1.longitude * 180) / Math.PI, (r1.latitude * 180) / Math.PI]);
+        var p2 = turf.point([(r2.longitude * 180) / Math.PI, (r2.latitude * 180) / Math.PI]);
+
+        // 鍋氭垚 3 * 4 鐨勭綉鏍�
+        var wCount =res.col, hCount = res.row;
+   
+        var wStep = turf.distance(p0, p1, { units: "meters" }) / (wCount - 1);
+        var hStep = turf.distance(p1, p2, { units: "meters" }) / (hCount - 1);
+
+        var wAngle = turf.bearing(p0, p1);
+        var hAngle = turf.bearing(p1, p2);
+        var op = { units: "meters", };
+
+        var arr = [p0.geometry.coordinates];
+  
+        // for (var i = 1; i < wCount; i++) {
+        //     var dest = turf.destination(p0, wStep * i, wAngle, op);
+        //     arr.push(dest.geometry.coordinates);
+        // }
+ 
+        // for (var i = 0; i < wCount; i++) {
+        //     var p = arr[i];
+        //     for (var j = 1; j < hCount; j++) {
+        //         var dest = turf.destination(p, hStep * j, hAngle, op);
+        //         arr.push(dest.geometry.coordinates);
+        //     }
+        // }
+ 
+        // 鏄剧ず鐐�
+        // for (var i = 0; i < arr.length; i++) {
+        //     var p = arr[i];
+        //     console.log(arr[i])
+        //     viewer.entities.add({
+        //         name: "鐐�",
+        //         show: true,
+        //         position: Cesium.Cartesian3.fromDegrees(p[0], p[1], 0),
+        //         point: {
+        //             color: Cesium.Color.RED,
+        //             pixelSize: 5,
+        //             heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
+        //             // 鏃犺濡備綍缂╂斁锛屾爣璁扮偣涓嶈鍦板舰閬尅
+        //             disableDepthTestDistance: Number.POSITIVE_INFINITY
+        //         }
+        //     });
+        // }
+    },
+    setGridRowCol:function(res){
+     
+        store.state.isshowGrid= false;  
+
+        this.drawPoint(res);
+
+    },
+};
+export default drawGrid
diff --git a/src/assets/js/Layer/mapGeo.js b/src/assets/js/Layer/mapGeo.js
index 59a2856..4bc8b4c 100644
--- a/src/assets/js/Layer/mapGeo.js
+++ b/src/assets/js/Layer/mapGeo.js
@@ -49,21 +49,16 @@
         if (this.type && this.type == res) {
             this.type = null
         }
-        if (res.type == "zhaiHai") {
-            Viewer.dataSources.remove(Viewer.dataSources.getByName("zhaiHai2")[0])
-            Viewer.dataSources.remove(Viewer.dataSources.getByName("zhaiHai1")[0])
-            Viewer.dataSources.remove(Viewer.dataSources.getByName("zhaiHai3")[0])
-        } else {
+      
             if (!res.type) return;
             Viewer.dataSources.remove(Viewer.dataSources.getByName(res.type)[0])
-        }
+      
 
     },
 
     addzhaiHaiGeoJson(res) {
-        var url1 = layerData.config.Model_URL + res.urls[0];
-        var url2 = layerData.config.Model_URL + res.urls[1];
-        var url3 = layerData.config.Model_URL + res.urls[2];
+        var url1 = layerData.config.Model_URL + res.urls ;
+     
         var color = Cesium.Color.fromCssColorString("rgb(255,0,255)")
         var data1 = Cesium.GeoJsonDataSource.load(url1, //瑕佸姞杞界殑 url銆丟eoJSON 瀵硅薄鎴� TopoJSON 瀵硅薄銆�
             {
@@ -73,38 +68,13 @@
             }
         )
         data1.then((dataSource) => {
-            dataSource.name = "zhaiHai1"
+            dataSource.name = res.type
             Viewer.dataSources.add(
                 dataSource
             );
         })
 
-        var data2 = Cesium.GeoJsonDataSource.load(url2, //瑕佸姞杞界殑 url銆丟eoJSON 瀵硅薄鎴� TopoJSON 瀵硅薄銆�
-            {
-                stroke: color, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ら鑹层��
-                fill: Cesium.Color.WHITE.withAlpha(0.2), //澶氳竟褰㈠唴閮ㄧ殑榛樿棰滆壊銆�
-                strokeWidth: 3, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ゅ搴︺��
-            }
-        )
-        data2.then((dataSource) => {
-            dataSource.name = "zhaiHai2"
-            Viewer.dataSources.add(
-                dataSource
-            );
-        })
-        var data3 = Cesium.GeoJsonDataSource.load(url3, //瑕佸姞杞界殑 url銆丟eoJSON 瀵硅薄鎴� TopoJSON 瀵硅薄銆�
-            {
-                stroke: color, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ら鑹层��
-                fill: Cesium.Color.WHITE.withAlpha(0.2), //澶氳竟褰㈠唴閮ㄧ殑榛樿棰滆壊銆�
-                strokeWidth: 3, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ゅ搴︺��
-            }
-        )
-        data3.then((dataSource) => {
-            dataSource.name = "zhaiHai3"
-            Viewer.dataSources.add(
-                dataSource
-            );
-        })
+       
     },
 
     addZhongQuXianGeoJson(res) {
diff --git a/src/assets/js/Layer/mapViewer.js b/src/assets/js/Layer/mapViewer.js
index 85b57f6..8fb0cc8 100644
--- a/src/assets/js/Layer/mapViewer.js
+++ b/src/assets/js/Layer/mapViewer.js
@@ -37,12 +37,12 @@
                 store.state.isShowMeasureCoord= true;
             }
             if (Cesium.defined(nPickFeature)) {
-             
                 if(nPickFeature.id && nPickFeature.id.properties){
-                    console.log(nPickFeature)
                     mapInfo.setGeoJsonInfo(nPickFeature.id.properties)
-                }else if(nPickFeature && nPickFeature.getProperty("name") == "DLJQT0007"){
-                    store.state.isShowVideo= true;
+                }else if(nPickFeature && nPickFeature.getProperty("name")){
+                    if(nPickFeature.getProperty("name") == "DLJQT0007"){
+                        store.state.isShowVideo= true;
+                    }
                 }
             }
             if(store.state.isQueryFalag){
diff --git a/src/assets/js/Layer/menuGrid.js b/src/assets/js/Layer/menuGrid.js
deleted file mode 100644
index 2bfa1de..0000000
--- a/src/assets/js/Layer/menuGrid.js
+++ /dev/null
@@ -1,160 +0,0 @@
-import parse from "qs/lib/parse";
-import store from "../../../store";
-import * as turf from '@turf/turf';
-const menuGrid = {
-    geom: [],
-    init() {
-        var that = this;
-        var grid = sgworld.Creator.createSimpleGraphic(
-            "point",
-            {
-                // clampToGround: false
-            }, (entity) => {
-                var val = that.setCartesianToEightFour(entity.position.getValue())
-                that.geom.push([parseFloat(val.lng), parseFloat(val.lat)])
-                sgworld.Creator.SimpleGraphic.remove(entity.id);
-                if (this.geom.length < 2) {
-                    that.init();
-                } else {
-                    store.state.isshowGrid = true;
-                }
-            })
-    },
-    setTurfGrid(res, geom) {
-
-        var box = [parseFloat(geom[0][0]), parseFloat(geom[0][1]), parseFloat(geom[1][0]), parseFloat(geom[1][1])]
-        this.geom = [];
-        var options = { units: "meters" };
-        var squareGrid = turf.squareGrid(box, res.cellSide, options);
-        var features = [];
-        for (var i = 0; i < squareGrid.features.length; i++) {
-            var coord = squareGrid.features[i].geometry.coordinates[0];
-            var coordinates = [];
-            for (var j in coord) {
-                coordinates.push([coord[j][0], coord[j][1], 18])
-            }
-            features.push({
-                "type": "Feature", "properties": {
-                    "NAME": '鏂板缓鏍肩綉' + (i + 1),
-                    "bak": ''
-                },
-                "geometry": {
-                    "type": "Polygon", "coordinates": [
-                        coordinates
-                    ]
-                }
-            })
-        }
-        var obj = {
-            "type": "FeatureCollection",
-            "name": "鏂板缓鏍肩綉",
-            "crs": {
-                "type": "name",
-                "properties": {
-                    "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
-                }
-            },
-            "features": features
-        }
-        this.adddDataSource(obj)
-    },
-
-    adddDataSource(res) {
-        var data = Cesium.GeoJsonDataSource.load(res, //瑕佸姞杞界殑 url銆丟eoJSON 瀵硅薄鎴� TopoJSON 瀵硅薄銆�
-            {
-                stroke: Cesium.Color.RED, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ら鑹层��
-                fill: Cesium.Color.WHITE.withAlpha(0.2), //澶氳竟褰㈠唴閮ㄧ殑榛樿棰滆壊銆�
-                strokeWidth: 3, //鎶樼嚎鍜屽杈瑰舰杞粨鐨勯粯璁ゅ搴︺��
-            }
-        )
-        data.then((dataSource) => {
-            Viewer.dataSources.add(
-                dataSource
-            );
-        })
-    },
-
-    setOtherGrid(res, geom) {
-        var maxlon, minlon, maxlat, minlat;
-        console.log(geom)
-        if (parseFloat(geom[0][0]) > parseFloat(geom[1][0])) {
-            maxlon = parseFloat(geom[0][0]);
-            minlon = parseFloat(geom[1][0]);
-        } else {
-            maxlon = parseFloat(geom[1][0]);
-            minlon = parseFloat(geom[0][0]);
-        }
-        if (parseFloat(geom[0][1]) > parseFloat(geom[1][1])) {
-            maxlat = geom[0][1];
-            minlat = geom[1][1];
-        } else {
-            maxlat = geom[1][1];
-            minlat = geom[0][1];
-        }
-        var row = 3;
-        var col = 3;
-        var lon_dis = (parseFloat(maxlon) - parseFloat(minlon)) / 3;
-        var lat_dis = (parseFloat(maxlat) - parseFloat(minlat)) / 3;
-        console.log(lon_dis, minlon)
-        for (var i = 0; i < col; i++) {
-            for (var j = 0; j < row; j++) {
-                var startlon = parseFloat(minlon + (j * lon_dis)) 
-                var startlat = parseFloat(minlat + (i * lat_dis)) 
-                var endlon = parseFloat(minlon + ((j + 1) * lon_dis)) 
-                var endlat = parseFloat(minlat + ((i + 1) * lat_dis)) 
-                var positions = [
-                    parseFloat(startlon), parseFloat(startlat),  parseFloat(endlon), parseFloat(startlat),  
-                    parseFloat(endlon), parseFloat(endlat),  parseFloat(startlon), parseFloat(endlat),   parseFloat(startlon), parseFloat(startlat) 
-                ]
-            
-                   
-                Viewer.entities.add({
-                    name: "polygon_height",
-                    polygon: {
-                        show: true,
-                        hierarchy: new Cesium.Cartesian3.fromDegreesArray(positions),
-                        height: 18,
-                        material: Cesium.Color.CYAN.withAlpha(0.5),
-                        outline: true,
-                        outlineColor: Cesium.Color.BLACK,
-                    }
-                })
-          
-
-
-            }
-        }
-    },
-
-
-    setGridRowCol(res) {
-        store.state.isshowGrid = false;
-        var geom = this.geom;
-        // this.setTurfGrid(res,geom)
-        this.setOtherGrid(res, geom);
-
-    },
-    toFixed(res) {
-        return parseFloat(res).toFixed(6)
-    },
-    setdistance(start, end) {
-        var from = turf.point(start);
-        var to = turf.point(end);
-        var distance = turf.distance(from, to, {
-            units: 'meters'
-        });
-        return distance
-    },
-
-
-    setCartesianToEightFour(res) {
-        var std = {};
-        let ellipsoid = window.Viewer.scene.globe.ellipsoid;
-        let cartographic = ellipsoid.cartesianToCartographic(res);
-        std.lat = Cesium.Math.toDegrees(cartographic.latitude);
-        std.lng = Cesium.Math.toDegrees(cartographic.longitude);
-        std.alt = cartographic.height;
-        return std;
-    }
-}
-export default menuGrid;
\ No newline at end of file
diff --git a/src/components/left/layerTree/messageInfo.vue b/src/components/left/layerTree/messageInfo.vue
index 11fe5e2..06bb843 100644
--- a/src/components/left/layerTree/messageInfo.vue
+++ b/src/components/left/layerTree/messageInfo.vue
@@ -61,26 +61,30 @@
       }
       var flag = false;
       var id=null;
-      for(var i in data){
-        if(data[i].name == '绫诲瀷' && data[i].value =='缃戞牸'){
-          flag = true;
-        }
-        if(data[i].name =='ID'){
-          id=data[i].value;
-        }
-      }
-      if(flag){
-        this.getInfoMessage(id)
-      }else{
-        this.setInfoMesgData(data);
-      }
+      // for(var i in data){
+      //   if(data[i].name == '绫诲瀷' && data[i].value =='缃戞牸'){
+      //     flag = true;
+      //   }
+      //   if(data[i].name =='ID'){
+      //     id=data[i].value;
+      //   }
+      // }
+      // if(flag){
+      //   this.getInfoMessage(id)
+      // }else{
+      //   this.setInfoMesgData(data);
+      // }
+
+      this.setInfoMesgData(data);
     },
     setInfoMesgData(res) {
       this.modelOption = res
     },
    async getInfoMessage(res){
       const data = await Grid_SelectById(res);
-      console.log(data)
+       if(data.status == 200){
+
+       }
     }
   }
 };
diff --git a/src/components/left/layerTree/meuGrid.vue b/src/components/left/layerTree/meuGrid.vue
index 4e0af29..90e9caa 100644
--- a/src/components/left/layerTree/meuGrid.vue
+++ b/src/components/left/layerTree/meuGrid.vue
@@ -1,5 +1,5 @@
 <template>
-  <div id="mapInfo" class="modelBox" v-drag>
+  <div id="mapInfo" class="modelBox">
     <div>
       <div class="modleTitle ">
         <div>鏍肩綉</div>
@@ -9,8 +9,11 @@
     <div class="modelContent">
 
       <el-form :model="modelOption" style="width: 100%;">
-        <el-form-item label="缃戞牸澶у皬(鍗曚綅绫�)">
-          <el-input-number  v-model="cellSide "></el-input-number>
+        <el-form-item label="琛屾暟">
+          <el-input-number  v-model="row "></el-input-number>
+        </el-form-item>
+        <el-form-item label="鍒楁暟">
+          <el-input-number  v-model="col "></el-input-number>
         </el-form-item>
         <el-form-item >
           <el-button @click="setMenuRowsCols" size="mall">鎻愪氦</el-button>
@@ -24,12 +27,7 @@
 </template>
 
 <script>
-import menuGrid from '../../../assets/js/Layer/menuGrid';
-
-
-
-
-
+import drawGrid from '../../../assets/js/Layer/drawGrid';
 export default {
   name: "modelEdit",
   components: {
@@ -42,7 +40,8 @@
        
       },
        
-      cellSide: 3,
+      row: 3,
+      col: 3,
     };
   },
   mounted() {
@@ -57,7 +56,7 @@
       this.modelOption = mapInfo.mssageInfo;
     },
     setMenuRowsCols(){
-        menuGrid.setGridRowCol({cellSide:this.cellSide});
+        drawGrid.setGridRowCol({row:this.row,col:this.col});
     }
   }
 };
diff --git a/src/components/left/leftmenu.vue b/src/components/left/leftmenu.vue
index 1e3af49..7402fd2 100644
--- a/src/components/left/leftmenu.vue
+++ b/src/components/left/leftmenu.vue
@@ -2412,8 +2412,8 @@
             "0",
             true
           );
-          layer._primitive.cullingDistance = 100
-          layer._primitive.cameraHeightRange = new Cesium.Cartesian3(0, 1000)
+          // layer._primitive.cullingDistance = 100
+          // layer._primitive.cameraHeightRange = new Cesium.Cartesian3(0, 1000)
 
 
           break;
diff --git a/src/components/menu/menulist.vue b/src/components/menu/menulist.vue
index 70c345c..db9dd57 100644
--- a/src/components/menu/menulist.vue
+++ b/src/components/menu/menulist.vue
@@ -24,10 +24,10 @@
           <span>妯″瀷</span>
         </div>
 
-        <!-- <div class="menubtn" @click="setMenuGrid()">
+        <div class="menubtn" @click="setMenuGrid()">
           <img class="bhImg" title="鏍肩綉" src="@/assets/img/right/cx-s.png" />
           <span>鏍肩綉</span>
-        </div> -->
+        </div>  
         <div class="menubtn" @click="setMenuQuery()">
           <img class="bhImg" title="鏌ヨ" src="@/assets/img/right/queyr.png" />
           <span>鏌ヨ</span>
@@ -208,9 +208,10 @@
 import zt from "@/assets/img/left/specialanalyse4.png";
 import fx from "@/assets/img/right/cx-s.png";
 import tx from "@/assets/img/left/leftnav2.png";
-import menuGrid from '@/assets/js/Layer/menuGrid'
+ 
 import { Img_Upload } from '@/api/api.js'
 import Bus from "../tools/Bus";
+import drawGrid from "../../assets/js/Layer/drawGrid";
 export default {
   name: "menulist",
   components: {
@@ -268,7 +269,7 @@
       this.$store.commit("setMenuQuery", true)
     },
     setMenuGrid() {
-      menuGrid.init();
+      drawGrid.drawRect();
     },
     setImgUpDate() {
       // this.$store.commit("setImgUpdate",true)
diff --git a/static/layers.json b/static/layers.json
index 5dd5eed..9aedd7e 100644
--- a/static/layers.json
+++ b/static/layers.json
@@ -39,7 +39,8 @@
                     "zIndex": 4,
                     "checked": false,
                     "rename": false
-                },      {
+                },
+                {
                     "id": "A349C2B3",
                     "sourceType": "GEOJSON",
                     "type": "ZhongPo",
@@ -66,11 +67,7 @@
                     "sourceType": "GEOJSON",
                     "type": "zhaiHai",
                     "name": "鐏惧",
-                    "urls": [
-                        "/Data/json/zhaiHai1.geojson",
-                        "/Data/json/zhaiHai2.geojson",
-                        "/Data/json/zhaiHai3.geojson"
-                    ],
+                    "urls": "/Data/json/zhaiHai.geojson",
                     "alpha": 1,
                     "zIndex": 4,
                     "checked": false,
@@ -124,7 +121,8 @@
                     "rename": false,
                     "zIndex": 2,
                     "effectsMaxHeight": 0
-                },{
+                },
+                {
                     "id": "482040AD4",
                     "sourceType": "b3dm",
                     "name": "鍘嬪姏娴嬭瘯妯″瀷",

--
Gitblit v1.9.3