| | |
| | | using ExportMap.Models; |
| | | using ExportMap.db; |
| | | using ExportMap.Models; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.IO; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Web; |
| | | |
| | | namespace ExportMap.cs |
| | |
| | | public class TerrainUtils |
| | | { |
| | | private static int terrainMaxLevel = 0; |
| | | |
| | | private const string EPSG4326 = "EPSG:4326"; |
| | | |
| | | /// <summary> |
| | | /// 地形最大级别 |
| | |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 默认最大文件大小:5GB |
| | | /// </summary> |
| | | public static long DEFAULT_MAX_SIZE = 5L * 1024 * 1024 * 1024; |
| | | |
| | | /// <summary> |
| | | /// 获取发布地址 |
| | | /// </summary> |
| | | public static string GetReleaseUrl(string dircode) |
| | | { |
| | | return "http://{host}/LFData/3d/terrain/" + dircode; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取地形路径 |
| | | /// </summary> |
| | | public static string GetTerrainPath(string dircode) |
| | | { |
| | | return Path.Combine(SGUtils.LFData, "3d\\terrain", dircode); |
| | | } |
| | | |
| | | /// <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> metas = XYZUtils.SelectMetas(args.ids, "and type in ('tif', 'tiff', 'dem')"); |
| | | if (null == metas || metas.Count == 0) return PrintInfo("找不到元数据"); |
| | | |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | //if (Directory.Exists(dirPath)) Tools.DelPath(dirPath); // 已存在的,删除 |
| | | if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); |
| | | string subPath = Path.Combine(dirPath, "subs"); |
| | | if (!Directory.Exists(subPath)) Directory.CreateDirectory(subPath); |
| | | |
| | | int pubid = PubDBHelper.GetPushlishId(args.dircode, "DEM"); |
| | | List<int> metsIds = PubDBHelper.GetPublishMetaId(pubid); |
| | | |
| | | List<string> files = new List<string>(); |
| | | string uploadFolder = Tools.GetSetting("uploadFolder"); |
| | | foreach (SysMeta meta in metas) |
| | | { |
| | | if (metsIds.Contains(meta.id)) |
| | | { |
| | | PrintInfo("元数据[" + meta.id + "] 已发布。"); |
| | | continue; |
| | | } |
| | | string sourceFile = Path.Combine(uploadFolder, meta.path); |
| | | if (!File.Exists(sourceFile)) |
| | | { |
| | | PrintInfo("元数据[" + meta.id + "] 不存在。"); |
| | | continue; |
| | | } |
| | | |
| | | string targetFile = Path.Combine(subPath, meta.path.Split(new string[] { "\\", "//" }, StringSplitOptions.None)[1]); |
| | | ConvertRaster(sourceFile, targetFile); |
| | | if (File.Exists(targetFile)) |
| | | { |
| | | files.Add(targetFile); |
| | | CreateTerrain(args, targetFile, ref err); |
| | | } |
| | | } |
| | | |
| | | CreateLayerJson(args, files, ref err); |
| | | string json = Path.Combine(dirPath, "layer.json"); |
| | | if (!File.Exists(json)) return PrintInfo("找不到layer.json文件"); |
| | | |
| | | Complement(args); |
| | | pubid = InsertToDB(metas, args); |
| | | |
| | | return new List<int> { pubid }; |
| | | } |
| | | catch (Exception ex) |
| | | { |
| | | LogOut.Error(ex.Message + "\r\n" + ex.StackTrace); |
| | | err = ex.Message; |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 打印信息 |
| | | /// </summary> |
| | | private static List<int> PrintInfo(string info) |
| | | { |
| | | LogOut.Info("TerrainUtils:" + info); |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 转换栅格文件 |
| | | /// </summary> |
| | | private static void ConvertRaster(string sourceFile, string targetFile) |
| | | { |
| | | if (File.Exists(targetFile)) return; |
| | | |
| | | string epsg = Tools.GetEPSG(sourceFile); |
| | | if (epsg == EPSG4326) |
| | | { |
| | | File.Copy(sourceFile, targetFile); |
| | | return; |
| | | } |
| | | |
| | | Reproject(sourceFile, targetFile, epsg, EPSG4326); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建高程切片 |
| | | /// </summary> |
| | | private static void CreateTerrain(XYZArgs args, string tifFile, ref string err) |
| | | { |
| | | string ctbPath = Tools.GetSetting("ctbJL"); |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | //int maxLevel = GetTerrainMaxLevel(args, tifFile); |
| | | |
| | | string gdal_data = string.Format("set GDAL_DATA={0}\\data", ctbPath); |
| | | // -N 顶点法线, -C 强制创建缺失根瓦片, -R 不覆盖现有文件,-f Mesh |
| | | string createMesh = string.Format("{0}\\ctb-tile.exe -s {1} -o \"{2}\" \"{3}\"", ctbPath, TERRAIN_MAX_LEVEL, dirPath, tifFile); |
| | | |
| | | List<string> list = new List<string>() { gdal_data, createMesh }; |
| | | SysTask task = TaskDBHelper.CreateTask(args, "DEM", "高程数据(DEM)"); |
| | | err = Tools.ExecCmd(task, list); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建layer.json |
| | | /// </summary> |
| | | private static string CreateLayerJson(XYZArgs args, List<string> files, ref string err) |
| | | { |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | string vrt = Path.Combine(dirPath, "subs", "dem.vrt"); |
| | | CreateVrt(files, vrt); |
| | | if (!File.Exists(vrt)) return null; |
| | | |
| | | string ctbPath = Tools.GetSetting("ctbJL"); |
| | | string gdal_data = string.Format("set GDAL_DATA={0}\\data", ctbPath); |
| | | string createLayer = string.Format("{0}\\ctb-tile.exe -l -s {1} -o \"{2}\" \"{3}\"", ctbPath, TERRAIN_MAX_LEVEL, dirPath, vrt); |
| | | Tools.ExecCmd(new List<string>() { gdal_data, createLayer }); |
| | | |
| | | return vrt; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 创建VRT |
| | | /// </summary> |
| | | private static void CreateVrt(List<string> files, string vrt) |
| | | { |
| | | string str = string.Join("\r\n", files); |
| | | string filelist = vrt.Replace("dem.vrt", "list.txt"); |
| | | File.WriteAllText(filelist, str); |
| | | |
| | | string gdalPath = Tools.GetSetting("gdalPath"); |
| | | string cmd = string.Format("\"{0}\\gdalbuildvrt.exe\" -input_file_list \"{1}\" \"{2}\" -overwrite", gdalPath, filelist, vrt); |
| | | Tools.ExecCmd(new List<string> { cmd }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取地形最大级别 |
| | | /// </summary> |
| | | private static int GetTerrainMaxLevel(XYZArgs args, string tifFile) |
| | | { |
| | | FileInfo fi = new FileInfo(tifFile); |
| | | if (fi.Length > DEFAULT_MAX_SIZE) return TERRAIN_MAX_LEVEL; |
| | | |
| | | string ctbPath = Tools.GetSetting("ctbJL"); |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | string subPath = Path.Combine(dirPath, "subs"); |
| | | |
| | | string gdal_data = string.Format("set GDAL_DATA={0}\\data", ctbPath); |
| | | string createLayer = string.Format("{0}\\ctb-tile.exe -l -o \"{1}\" \"{2}\"", ctbPath, subPath, tifFile); |
| | | |
| | | Tools.ExecCmd(new List<string>() { gdal_data, createLayer }); |
| | | |
| | | string layerJson = Path.Combine(subPath, "layer.json"); |
| | | if (!File.Exists(layerJson)) return TERRAIN_MAX_LEVEL; |
| | | |
| | | string[] lines = File.ReadAllLines(layerJson, Encoding.UTF8); |
| | | |
| | | int level = -1; |
| | | foreach (string line in lines) |
| | | { |
| | | if (line.IndexOf("startX") > -1) level++; |
| | | } |
| | | if (File.Exists(layerJson)) File.Delete(layerJson); |
| | | |
| | | return level > TERRAIN_MAX_LEVEL ? TERRAIN_MAX_LEVEL : level; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 补充文件 |
| | | /// </summary> |
| | | private static void Complement(XYZArgs args) |
| | | { |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | string p_0_0 = Path.Combine(dirPath, "0", "0"); |
| | | if (!Directory.Exists(p_0_0)) Directory.CreateDirectory(p_0_0); |
| | | |
| | | string p_0_1 = Path.Combine(dirPath, "0", "1"); |
| | | if (!Directory.Exists(p_0_1)) Directory.CreateDirectory(p_0_1); |
| | | |
| | | string s_0_0_0 = Path.Combine(SGUtils.LFData, "dem", "0", "0", "0.terrain"); |
| | | string d_0_0_0 = Path.Combine(dirPath, "0", "0", "0.terrain"); |
| | | if (!File.Exists(d_0_0_0)) File.Copy(s_0_0_0, d_0_0_0, true); |
| | | |
| | | string s_0_1_0 = Path.Combine(SGUtils.LFData, "dem", "0", "1", "0.terrain"); |
| | | string d_0_1_0 = Path.Combine(dirPath, "0", "1", "0.terrain"); |
| | | if (!File.Exists(d_0_1_0)) File.Copy(s_0_1_0, d_0_1_0, true); |
| | | |
| | | string layerJson = Path.Combine(dirPath, "layer.json"); |
| | | string[] lines = File.ReadAllLines(layerJson, Encoding.UTF8); |
| | | //lines[12] = " [ { \"startX\": 0, \"startY\": 0, \"endX\": 1, \"endY\": 0 } ]"; |
| | | for (int i = 0, c = lines.Length; i < c; i++) |
| | | { |
| | | if (lines[i].IndexOf("startX") > -1) |
| | | { |
| | | lines[i] = " [ { \"startX\": 0, \"startY\": 0, \"endX\": 1, \"endY\": 0 } ]"; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | File.WriteAllLines(layerJson, lines, Encoding.UTF8); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 插入数据库 |
| | | /// </summary> |
| | | private static int InsertToDB(List<SysMeta> metas, XYZArgs args) |
| | | { |
| | | //if (PubDBHelper.IsPublish(args.dircode, "DEM")) return 1; |
| | | int pubid = PubDBHelper.GetPushlishId(args.dircode, "DEM"); |
| | | if (pubid > 0) // 更新发布 |
| | | { |
| | | List<int> ids = PubDBHelper.GetPublishMetaId(pubid); |
| | | foreach (SysMeta m in metas) |
| | | { |
| | | if (!ids.Contains(m.id)) PubDBHelper.InsertMetaPub(m.id, pubid, args.userId); |
| | | } |
| | | string geom = GetPointZ(args); |
| | | int rows = PubDBHelper.UpdatePublish(pubid, args.name, args.userId, geom); |
| | | |
| | | return pubid; |
| | | } |
| | | |
| | | SysMeta meta = metas[0]; |
| | | meta.type = "DEM"; |
| | | meta.name = args.name; |
| | | meta.dircode = args.dircode; |
| | | |
| | | SysPublish sys = Tools.NewPublish(meta, args, GetReleaseUrl(args.dircode), "3d\\terrain\\" + args.dircode); |
| | | sys.geom = GetPointZ(args); |
| | | |
| | | pubid = PubDBHelper.InsertPublish(sys); |
| | | if (pubid > 0) |
| | | { |
| | | sys.id = pubid; |
| | | PubDBHelper.InsertLayer(sys, new SysMeta() |
| | | { |
| | | name = args.name, |
| | | type = meta.type, |
| | | dirname = meta.dirname |
| | | }); |
| | | foreach (SysMeta m in metas) |
| | | { |
| | | PubDBHelper.InsertMetaPub(m.id, pubid, args.userId); |
| | | } |
| | | } |
| | | |
| | | return pubid; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取中心点 |
| | | /// </summary> |
| | | public static string GetPointZ(XYZArgs args) |
| | | { |
| | | string dirPath = GetTerrainPath(args.dircode); |
| | | string vrt = Path.Combine(dirPath, "subs", "dem.vrt"); |
| | | if (!File.Exists(vrt)) return null; |
| | | |
| | | string gdalPath = Tools.GetSetting("gdalPath"); |
| | | string cmd = string.Format("\"{0}\\gdalinfo.exe\" \"{1}\"", gdalPath, vrt); |
| | | |
| | | string rs = null; |
| | | Tools.ExecCmd(new List<string> { cmd }, ref rs); |
| | | string center = GetCenter(rs); |
| | | if (string.IsNullOrEmpty(rs)) return null; |
| | | |
| | | string[] strs = center.Split(new string[] { "," }, StringSplitOptions.None); |
| | | double x = double.Parse(strs[0]); |
| | | double y = double.Parse(strs[1]); |
| | | |
| | | return string.Format("ST_GeomFromText('POINT Z ({0} {1} {2})')", x, y, 12); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 获取中心坐标 |
| | | /// </summary> |
| | | private static string GetCenter(string rs) |
| | | { |
| | | if (string.IsNullOrEmpty(rs)) return null; |
| | | |
| | | string[] strs = rs.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); |
| | | foreach (string str in strs) |
| | | { |
| | | if (str.StartsWith("Center ")) |
| | | { |
| | | int start = str.IndexOf("("); |
| | | int end = str.IndexOf(")"); |
| | | |
| | | return str.Substring(start + 1, end - start - 1).Replace(" ", ""); |
| | | } |
| | | } |
| | | |
| | | return null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 重投影 |
| | | /// </summary> |
| | | public static void Reproject(string sourceFile, string targetFile, string sourceSrs, string targetSrs) |
| | | { |
| | | string gdalPath = Tools.GetSetting("gdalPath"); |
| | | string cmd = string.Format("{0}\\gdalwarp.exe -s_srs {1} -t_srs {2} -r near -of GTiff {3} {4}", gdalPath, sourceSrs, targetSrs, sourceFile, targetFile); |
| | | string cmd = string.Format("\"{0}\\gdalwarp.exe\" -s_srs {1} -t_srs {2} -r near -of GTiff \"{3}\" \"{4}\"", gdalPath, sourceSrs, targetSrs, sourceFile, targetFile); |
| | | |
| | | Tools.ExecCmd(new List<string> { cmd }); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 指定投影 |
| | | /// 指定投影 * |
| | | /// </summary> |
| | | public static void Project(string sourceFile, string targetSrs) |
| | | { |