管道基础大数据平台系统开发-【CS】-ExportMap
1
13693261870
2023-08-07 676892f591be011d2e41f309d7e3ee809f412f0d
1
已添加2个文件
已修改7个文件
387 ■■■■ 文件已修改
ExportMap/Controllers/ConvertController.cs 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/ExportMap.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/Sources/xyz.py 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/Sources/xyz2.py 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/Web.config 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/cs/PyLasUtils.cs 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/cs/TerraUtils.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/cs/Tools.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ExportMap/export.html 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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("坐标系ID集合与元数据ID集合长度不一致");
                //if (args.zs.Count != args.ids.Count) return ResponseMsg<string>.fail("高度偏移量集合与元数据ID集合长度不一致");
                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]
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" />
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()
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')
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的DB库 -->
ExportMap/cs/PyLasUtils.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,110 @@
using 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;
        }
    }
}
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);
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();
            }
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();" />