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