From 676892f591be011d2e41f309d7e3ee809f412f0d Mon Sep 17 00:00:00 2001
From: 13693261870 <252740454@qq.com>
Date: 星期一, 07 八月 2023 17:26:55 +0800
Subject: [PATCH] 1

---
 ExportMap/Sources/xyz2.py                  |  149 +++++++++++++++++++++
 ExportMap/cs/Tools.cs                      |    4 
 ExportMap/cs/PyLasUtils.cs                 |  110 +++++++++++++++
 ExportMap/Controllers/ConvertController.cs |   30 ++++
 ExportMap/ExportMap.csproj                 |    1 
 ExportMap/cs/TerraUtils.cs                 |    5 
 ExportMap/Sources/xyz.py                   |   74 +++------
 ExportMap/export.html                      |   12 +
 ExportMap/Web.config                       |    2 
 9 files changed, 334 insertions(+), 53 deletions(-)

diff --git a/ExportMap/Controllers/ConvertController.cs b/ExportMap/Controllers/ConvertController.cs
index 48c8390..c4ea621 100644
--- a/ExportMap/Controllers/ConvertController.cs
+++ b/ExportMap/Controllers/ConvertController.cs
@@ -219,6 +219,36 @@
         }
 
         /// <summary>
+        /// Py杞崲LAS
+        /// </summary>
+        [HttpPost]
+        public ResponseMsg<string> ToLasByPy([FromBody]XYZArgs args)
+        {
+            try
+            {
+                ResponseMsg<string> msg = checkArgs(args);
+                if (null != msg) return msg;
+
+                //if (args.srids.Count != args.ids.Count) return ResponseMsg<string>.fail("鍧愭爣绯籌D闆嗗悎涓庡厓鏁版嵁ID闆嗗悎闀垮害涓嶄竴鑷�");
+                //if (args.zs.Count != args.ids.Count) return ResponseMsg<string>.fail("楂樺害鍋忕Щ閲忛泦鍚堜笌鍏冩暟鎹甀D闆嗗悎闀垮害涓嶄竴鑷�");
+
+                string err = null;
+                List<int> rs = PyLasUtils.Generate(args, ref err);
+                if (null == rs || rs.Count == 0)
+                {
+                    return ResponseMsg<string>.fail(null == err ? "澶辫触" : err);
+                }
+
+                return ResponseMsg<string>.success("鎴愬姛", string.Join(",", rs), rs.Count);
+            }
+            catch (Exception ex)
+            {
+                LogOut.Error(ex.Message + "\r\n" + ex.StackTrace);
+                return ResponseMsg<string>.fail(ex.Message);
+            }
+        }
+
+        /// <summary>
         /// 鍒犻櫎鏂囦欢
         /// </summary>
         [HttpPost]
diff --git a/ExportMap/ExportMap.csproj b/ExportMap/ExportMap.csproj
index 7ecfc3f..ecc67bd 100644
--- a/ExportMap/ExportMap.csproj
+++ b/ExportMap/ExportMap.csproj
@@ -153,6 +153,7 @@
     <Compile Include="cs\LogOut.cs" />
     <Compile Include="cs\NoBufferPolicySelector.cs" />
     <Compile Include="cs\OsgbUtils.cs" />
+    <Compile Include="cs\PyLasUtils.cs" />
     <Compile Include="cs\SGUtils.cs" />
     <Compile Include="cs\TBUtils.cs" />
     <Compile Include="cs\TerraUtils.cs" />
diff --git a/ExportMap/Sources/xyz.py b/ExportMap/Sources/xyz.py
index acb3e18..0fd93f1 100644
--- a/ExportMap/Sources/xyz.py
+++ b/ExportMap/Sources/xyz.py
@@ -28,18 +28,18 @@
     parser = argparse.ArgumentParser(description='ArgUtils')
     parser.add_argument("-src", type=str, default=get_full_path(), required=False)
     parser.add_argument("-qgz", type=str, default=r"xyz.qgz", required=False)
-    parser.add_argument("-file", type=str, default=r"D:\xyz\domtt\tif.txt", required=False)
-    parser.add_argument("-out", type=str, default=r"D:\xyz\domtt\png", required=False)
+    parser.add_argument("-file", type=str, default=r"D:\xyz\dom0.2m\tif.txt", required=False)
+    parser.add_argument("-out", type=str, default=r"D:\xyz\dom0.2m\png", required=False)
     parser.add_argument("-min", type=int, default=12, required=False)
-    parser.add_argument("-max", type=int, default=18, required=False)
+    parser.add_argument("-max", type=int, default=15, required=False)
     parser.add_argument("-noData", type=int, default=0, required=False)
 
     return parser.parse_args()
 
 
 # 璇诲彇鏂囨湰鏂囦欢
-def readTxt(filePath):
-    f = open(filePath, encoding="utf-8")
+def read_txt(path):
+    f = open(path, encoding="utf-8")
     lines = f.readlines()
     f.close()
 
@@ -50,12 +50,12 @@
 
 
 # 鍔犺浇鍥惧眰
-def loadLayers(prj, args):
+def load_layers(prj, args):
     for layer in prj.mapLayers().values():
         prj.removeMapLayer(layer)
 
-    args.authid = None
-    lines = readTxt(args.file)
+    args.crs = None
+    lines = read_txt(args.file)
     for i in range(0, len(lines)):
         if len(lines[i]) == 0:
             continue
@@ -67,8 +67,8 @@
             continue
 
         if len(prj.mapLayers()) == 0:
-            args.authid = layer.crs().authid()
-            print("authid: " + args.authid)
+            args.crs = layer.crs()
+            print("authid: " + args.crs.authid())
             prj.setCrs(layer.crs())
 
         for j in range(1, layer.bandCount() + 1):
@@ -88,33 +88,36 @@
         self.ymin = ymin
         self.ymax = ymax
 
+
 # 鑾峰彇杈圭晫
-def getExtent(prj, args):
+def get_extent(prj, args):
     ex = None
     for layer in prj.mapLayers().values():
         rect = layer.extent()
         if ex is None:
+            # print(layer.extent().asWktCoordinates()); geo = QgsGeometry.fromWkt(layer.extent().asWktPolygon())
             ex = Rectangle(rect.xMinimum(), rect.xMaximum(), rect.yMinimum(), rect.yMaximum())
             continue
 
-        if args.authid != layer.crs().authid():
-            transform = QgsCoordinateTransform(QgsCoordinateReferenceSystem(layer.crs().authid()), QgsCoordinateReferenceSystem(args.authid), prj)
+        if args.crs.authid() != layer.crs().authid():
+            transform = QgsCoordinateTransform(layer.crs(),  args.crs, prj)
             min = QgsPoint(rect.xMinimum(), rect.yMinimum())
             max = QgsPoint(rect.xMaximum(), rect.yMaximum())
             min.transform(transform)
             max.transform(transform)
 
-            setRectBound(ex, min.x(), min.y(), max.x(), max.y())
+            set_rect_bound(ex, min.x(), min.y(), max.x(), max.y())
 
         else:
-            setRectBound(ex, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum())
+            set_rect_bound(ex, rect.xMinimum(), rect.yMinimum(), rect.xMaximum(), rect.yMaximum())
 
     # 123543.6722,2730986.0671,2732253.9315,3552923.0518 [EPSG:32643]
     # return '38400309.1314,38403253.7083,3559920.4768,3561690.3144 [CGCS2000 / 3-degree Gauss-Kruger zone 38]'
-    return str(ex.xmin) + "," + str(ex.xmax) + "," + str(ex.ymin) + "," + str(ex.ymax) + ' [' + args.authid + "]"
+    return str(ex.xmin) + "," + str(ex.xmax) + "," + str(ex.ymin) + "," + str(ex.ymax) + ' [' + args.crs.authid() + "]"
+
 
 # 璁剧疆鐭╁舰杈圭晫
-def setRectBound(ex, xmin, ymin, xmax, ymax):
+def set_rect_bound(ex, xmin, ymin, xmax, ymax):
     if xmin < ex.xmin:
         ex.xmin = xmin
     if ymin < ex.ymin:
@@ -125,33 +128,8 @@
         ex.ymax = ymax
 
 
-def getExtent2(prj, args):
-    ex = None
-    for layer in prj.mapLayers().values():
-        rect = layer.extent()
-        print(layer.name() + ", " + rect.toString() + ", " + layer.crs().authid())
-
-        if ex is None:
-            ex = Rectangle(rect.xMinimum(), rect.xMaximum(), rect.yMinimum(), rect.yMaximum())
-            # print(layer.extent().asWktCoordinates())
-            geo = QgsGeometry.fromWkt(layer.extent().asWktPolygon())
-            continue
-
-        if rect.xMinimum() < ex.xmin:
-            ex.xmin = rect.xMinimum()
-        if rect.yMinimum() < ex.ymin:
-            ex.ymin = rect.yMinimum()
-        if rect.xMaximum() > ex.xmax:
-            ex.xmax = rect.xMaximum()
-        if rect.yMaximum() > ex.ymax:
-            ex.ymax = rect.yMaximum()
-
-    # '-3640.3675,1734588.1947,2434663.1477,3677421.7047 [EPSG:32643]'
-    return str(ex.xmin) + "," + str(ex.xmax) + "," + str(ex.ymin) + "," + str(ex.ymax) + ' [' + args.authid + "]"
-
-
 # 鑾峰彇XYZ鍙傛暟
-def getXYZOps(args):
+def get_xyz_ops(args):
     ops = {
         'BACKGROUND_COLOR': QColor(0, 0, 0, 0),
         'DPI': 96,
@@ -174,10 +152,10 @@
 
 
 # 鍒涘缓XYZ鐡︾墖
-def createXYZ(args):
+def create_xyz(args):
     import processing
 
-    ops = getXYZOps(args)
+    ops = get_xyz_ops(args)
     processing.run("qgis:tilesxyzdirectory", ops)
 
 
@@ -194,11 +172,11 @@
     # prj.read(args.qgz)
     print("FileName: " + prj.fileName())
 
-    loadLayers(prj, args)
+    load_layers(prj, args)
     # prj.write(args.file.replace(".txt", ".qgz"))
 
-    args.ext = getExtent(prj, args)
-    createXYZ(args)
+    args.ext = get_extent(prj, args)
+    create_xyz(args)
 
     qgs.exitQgis()
 
diff --git a/ExportMap/Sources/xyz2.py b/ExportMap/Sources/xyz2.py
new file mode 100644
index 0000000..6bae100
--- /dev/null
+++ b/ExportMap/Sources/xyz2.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env
+# -*- coding: utf-8 -*-
+
+
+import os
+import sys
+import time
+
+sys.path.append(r"C:\Program Files\QGIS 3.16\apps\qgis-ltr\python\plugins")
+import math
+import argparse
+from qgis.core import *
+from qgis.gui import *
+from qgis.PyQt.QtGui import *
+from qgis.PyQt.QtCore import *
+from qgis.PyQt.QtWidgets import *
+from processing.core.Processing import Processing
+
+
+# 鑾峰彇瀹屾暣璺緞
+def get_full_path():
+    return os.path.split(sys.argv[0])[0]
+
+
+# 鑾峰彇鍙傛暟
+def get_args():
+    print("argv = ", sys.argv[1:])
+    parser = argparse.ArgumentParser(description='ArgUtils')
+    parser.add_argument("-src", type=str, default=get_full_path(), required=False)
+    parser.add_argument("-qgz", type=str, default=r"xyz.qgz", required=False)
+    parser.add_argument("-file", type=str, default=r"D:\xyz\dom0.2m\tif.txt", required=False)
+    parser.add_argument("-out", type=str, default=r"D:\xyz\dom0.2m\png2", required=False)
+    parser.add_argument("-min", type=int, default=12, required=False)
+    parser.add_argument("-max", type=int, default=15, required=False)
+    parser.add_argument("-noData", type=int, default=0, required=False)
+    parser.add_argument("-authid", type=int, default=4490, required=False)
+
+    return parser.parse_args()
+
+
+# 璇诲彇鏂囨湰鏂囦欢
+def readTxt(filePath):
+    f = open(filePath, encoding="utf-8")
+    lines = f.readlines()
+    f.close()
+
+    for i in range(0, len(lines)):
+        lines[i] = lines[i].replace('\n', '')
+
+    return lines
+
+
+# 鍔犺浇鍥惧眰
+def loadLayers(prj, args):
+    for layer in prj.mapLayers().values():
+        prj.removeMapLayer(layer)
+
+    lines = readTxt(args.file)
+    for i in range(0, len(lines)):
+        if len(lines[i]) == 0:
+            continue
+
+        print("layer_" + str(i) + ": " + lines[i])
+        layer = QgsRasterLayer(lines[i], "layer_" + str(i))
+        if not layer.isValid() or layer.crs() is None:
+            print("layer_" + str(i) + ": failed to load!")
+            continue
+
+        for j in range(1, layer.bandCount() + 1):
+            try:
+                layer.dataProvider().setNoDataValue(j, args.noData)
+            except Exception as e:
+                print(e)
+
+        prj.addMapLayer(layer)
+
+
+# 杈圭晫绫�
+class Rectangle:
+    def __init__(self, xmin, xmax, ymin, ymax):
+        self.xmin = xmin
+        self.xmax = xmax
+        self.ymin = ymin
+        self.ymax = ymax
+
+
+# 鑾峰彇XYZ鍙傛暟
+def getXYZOps(args):
+    ops = {
+        'BACKGROUND_COLOR': QColor(0, 0, 0, 0),
+        'DPI': 96,
+        'EXTENT': args.ext,
+        'METATILESIZE': 4,
+        'OUTPUT_DIRECTORY': args.out,
+        # 'OUTPUT_HTML': 'TEMPORARY_OUTPUT',
+        'OUTPUT_HTML': args.out + "\\view.html",
+        'QUALITY': 100,
+        'TILE_FORMAT': 0,
+        'TILE_HEIGHT': 256,
+        'TILE_WIDTH': 256,
+        'TMS_CONVENTION': False,
+        'ZOOM_MAX': args.max,
+        'ZOOM_MIN': args.min
+    }
+    print(ops)
+
+    return ops
+
+
+# 鍒涘缓XYZ鐡︾墖
+def createXYZ(prj, args):
+    import processing
+
+    for layer in prj.mapLayers().values():
+        e = layer.extent()
+        prj.setCrs(layer.crs())
+        epsg = '' if layer.crs() is None else ' [' + layer.crs().authid() + ']'
+        args.ext = str(e.xMinimum()) + "," + str(e.xMaximum()) + "," + str(e.yMinimum()) + "," + str(e.yMaximum()) + epsg
+        ops = getXYZOps(args)
+        processing.run("qgis:tilesxyzdirectory", ops)
+
+
+# 鍒濆鍖�
+def init():
+    # QgsApplication.setPrefixPath("C:\Program Files\QGIS 3.16", True)
+    qgs = QgsApplication([], False)
+    qgs.initQgis()
+    Processing.initialize()
+
+    args = get_args()
+    prj = QgsProject.instance()
+    prj.read(os.path.join(args.src, args.qgz))
+    # prj.read(args.qgz)
+    print("FileName: " + prj.fileName())
+
+    loadLayers(prj, args)
+    # prj.write(args.file.replace(".txt", ".qgz"))
+
+    # args.ext = getExtent(prj, args)
+    createXYZ(prj, args)
+
+    qgs.exitQgis()
+
+
+# main
+if __name__ == '__main__':
+    timer = time.time()
+    init()
+    print(f'鑰楁椂:{time.time() - timer:.2f}s')
diff --git a/ExportMap/Web.config b/ExportMap/Web.config
index cc5aba4..b68576c 100644
--- a/ExportMap/Web.config
+++ b/ExportMap/Web.config
@@ -11,6 +11,8 @@
     <add key="uploadFolder" value="D:\LF\upload"/>
     <!-- 涓嬭浇鐩綍 -->
     <add key="downloadFolder" value="D:\LF\download"/>
+    <!-- Python鐩綍 -->
+    <add key="pythonFolder" value="C:\Python310"/>
     <!-- 寤婂潑鏁版嵁鐩綍 -->
     <add key="lfData" value="E:\data\99.public\soft\LFData"/>
     <!-- SG鐨凞B搴� -->
diff --git a/ExportMap/cs/PyLasUtils.cs b/ExportMap/cs/PyLasUtils.cs
new file mode 100644
index 0000000..c34060b
--- /dev/null
+++ b/ExportMap/cs/PyLasUtils.cs
@@ -0,0 +1,110 @@
+锘縰sing ExportMap.db;
+using ExportMap.Models;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Web;
+
+namespace ExportMap.cs
+{
+    public class PyLasUtils
+    {
+        /// <summary>
+        /// 鑾峰彇璺緞
+        /// </summary>
+        public static string GetPath(int id)
+        {
+            return Path.Combine(SGUtils.LFData, "3d\\3dtiles\\las", id.ToString());
+        }
+
+        /// <summary>
+        /// 鑾峰彇鍙戝竷鍦板潃
+        /// </summary>
+        public static string GetReleaseUrl(string path)
+        {
+            return "http://{host}/LFData/" + path.Replace("\\", "/");
+        }
+
+        /// <summary>
+        /// 鐢熸垚
+        /// </summary>
+        /// <param name="args">XYZ鍙傛暟</param>
+        /// <param name="err">閿欒淇℃伅</param>
+        /// <returns>鏁版嵁鍙戝竷ID闆嗗悎</returns>
+        public static List<int> Generate(XYZArgs args, ref string err)
+        {
+            try
+            {
+                List<SysMeta> list = XYZUtils.SelectMetas(args.ids, "and type in ('las', 'laz')");
+                if (null == list || list.Count == 0) return null;
+
+                string pyPath = Tools.GetSetting("pythonFolder");
+                string tilerPath = Tools.GetSetting("tilerPath");
+                string uploadFolder = Tools.GetSetting("uploadFolder");
+
+                List<int> ids = new List<int>();
+                foreach (SysMeta meta in list)
+                {
+                    string lasPath = Path.Combine(uploadFolder, meta.path);
+                    if (!File.Exists(lasPath)) continue;
+
+                    string outPath = GetPath(meta.id);
+                    if (Directory.Exists(outPath)) Tools.DelPath(outPath);
+                    if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
+
+                    //int idx = args.ids.IndexOf(meta.id); // args.srids[idx], args.zs[idx])
+                    List<string> cmds = new List<string>();
+                    cmds.Add(string.Format("set PYTHONHOME={0}", pyPath));
+                    cmds.Add(string.Format("{0}\\Scripts\\py3dtiles.exe convert --overwrite {1} --out {2}", pyPath, lasPath, outPath));
+
+                    SysTask task = TaskDBHelper.CreateTask(args, meta, "LAS", "鐐逛簯鏁版嵁(LAS)");
+                    err = Tools.ExecCmd(task, cmds, false);
+                    err = null;
+
+                    string jsonFile = Path.Combine(outPath, "tileset.json");
+                    if (File.Exists(jsonFile))
+                    {
+                        string path = jsonFile.Replace(Tools.GetSetting("lfData") + "\\", "");
+                        int pubid = InsertToDB(meta, args, path);
+                        if (pubid > 0) ids.Add(pubid);
+                    }
+                }
+
+                return ids;
+            }
+            catch (Exception ex)
+            {
+                LogOut.Error(ex.Message + "\r\n" + ex.StackTrace);
+                err = ex.Message;
+                return null;
+            }
+        }
+
+        /// <summary>
+        /// 鎻掑叆鏁版嵁搴�
+        /// </summary>
+        private static int InsertToDB(SysMeta meta, XYZArgs args, string path)
+        {
+            //if (PubDBHelper.IsPublish(meta.id)) return 1;
+            int pubid = PubDBHelper.GetPushlishId(meta.id);
+            if (pubid > 0)
+            {
+                PubDBHelper.UpdatePublish(pubid, meta.name, args.userId, null);
+                return pubid;
+            }
+
+            SysPublish sys = Tools.NewPublish(meta, args, GetReleaseUrl(path), path);
+
+            pubid = PubDBHelper.InsertPublish(sys);
+            if (pubid > 0)
+            {
+                sys.id = pubid;
+                PubDBHelper.InsertLayer(sys, meta);
+                PubDBHelper.InsertMetaPub(meta.id, pubid, args.userId);
+            }
+
+            return pubid;
+        }
+    }
+}
diff --git a/ExportMap/cs/TerraUtils.cs b/ExportMap/cs/TerraUtils.cs
index affe3bc..3c0f599 100644
--- a/ExportMap/cs/TerraUtils.cs
+++ b/ExportMap/cs/TerraUtils.cs
@@ -169,8 +169,9 @@
                 }
                 else
                 {
-                    if (File.Exists(tifFile)) File.Delete(tifFile);
-                    WriteText(txtFile, metas, null);
+                    //if (File.Exists(tifFile)) File.Delete(tifFile);
+                    //WriteText(txtFile, metas, null);
+                    if (File.Exists(tifFile)) return tifFile;
                 }
 
                 string cmd = string.Format("python \"{0}\" -qgz {1} -file \"{2}\" -out \"{3}\"", PyFile, Qgz, txtFile, tifFile);
diff --git a/ExportMap/cs/Tools.cs b/ExportMap/cs/Tools.cs
index 42effbc..e7257b0 100644
--- a/ExportMap/cs/Tools.cs
+++ b/ExportMap/cs/Tools.cs
@@ -206,7 +206,7 @@
                 p.StartInfo.CreateNoWindow = true;
                 //p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                 p.StartInfo.RedirectStandardInput = true;
-                p.StartInfo.RedirectStandardOutput = true;
+                p.StartInfo.RedirectStandardOutput = isOut;
                 p.StartInfo.RedirectStandardError = true;
                 p.Start();
 
@@ -239,8 +239,8 @@
                     TaskDBHelper.Update(task);
                 }
 
+                if (null != so) so.Close();
                 se.Close();
-                //so.Close();
                 si.Close();
                 p.Close();
             }
diff --git a/ExportMap/export.html b/ExportMap/export.html
index ee355a9..513e498 100644
--- a/ExportMap/export.html
+++ b/ExportMap/export.html
@@ -10,7 +10,7 @@
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
   <script src="js/jquery.1.12.4.js"></script>
   <script>
-    var token = "2befc513-49b6-45e9-8c22-4909e08c7e44";
+    var token = "ddcfdd6d-4b81-49d6-a2a1-733332b8092a";
 
     $(function () {
       $("#token").html(token);
@@ -147,6 +147,15 @@
       });
     }
 
+    // LasByPy
+    function toLasByPy() {
+      var data = { token: token, ids: [10481], depcode: "00", dircode: "0C", userId: 1, name: "HL_point_cloud_part_1.las", srids: [4548], zs: [0] };
+      ajax("Convert/ToLasByPy", "POST", JSON.stringify(data), null, null, function (rs) {
+        alert("code = " + rs.code + ", msg = " + rs.msg + ", result = " + rs.result);
+        console.log(rs);
+      });
+    }
+
     // 娴嬭瘯Las
     function toLas() {
       var data = { token: token, ids: [10481], depcode: "00", dircode: "0C", userId: 1, name: "HL_point_cloud_part_1.las", srids: [4548], zs: [0] };
@@ -212,6 +221,7 @@
   <input type="button" value="娴嬭瘯SG" onclick="toSG();" />
   <input type="button" value="娴嬭瘯Terra" onclick="toTerra();" />
   <input type="button" value="娴嬭瘯OSGB" onclick="toOsgb();" />
+  <input type="button" value="LasByPy" onclick="toLasByPy();" />
   <input type="button" value="娴嬭瘯Las" onclick="toLas();" />
   <input type="button" value="娴嬭瘯Laz" onclick="toLaz();" />
   <input type="button" value="鐢熸垚Mpt" onclick="createMpt();" />

--
Gitblit v1.9.3