diff --git a/Infrastructure/Utils/ShapeUtil.cs b/Infrastructure/Utils/ShapeUtil.cs
index 906e0fc..aff39db 100644
--- a/Infrastructure/Utils/ShapeUtil.cs
+++ b/Infrastructure/Utils/ShapeUtil.cs
@@ -119,6 +119,11 @@ public class ShapeUtil
// return NetTopologySuite.IO.Esri.Shapefile.ReadAllGeometries(shpPath);
}
+ public static bool CheckTextByUtf8()
+ {
+ return false;
+ }
+
///
/// 判断是否乱码
///
diff --git a/OpenAuth.App/ServiceApp/LayerManagerApp/DataTableAttr.cs b/OpenAuth.App/ServiceApp/LayerManagerApp/DataTableAttr.cs
new file mode 100644
index 0000000..79d8517
--- /dev/null
+++ b/OpenAuth.App/ServiceApp/LayerManagerApp/DataTableAttr.cs
@@ -0,0 +1,27 @@
+using NetTopologySuite.IO;
+
+namespace OpenAuth.Repository.Domain;
+
+public class DataTableAttr
+{
+ // 字段名称
+ public string Name { get; set; }
+
+ // 字段类型
+ public string Type { get; set; }
+
+ // 字段长度
+ public int Length { get; set; }
+
+ ///
+ /// 对应数据库列名
+ ///
+ public string RefName { get; set; }
+
+ ///
+ /// 可能是中文描述
+ ///
+ public string InitName { get; set; }
+
+
+}
\ No newline at end of file
diff --git a/OpenAuth.App/ServiceApp/LayerManagerApp/LayerApp.cs b/OpenAuth.App/ServiceApp/LayerManagerApp/LayerApp.cs
new file mode 100644
index 0000000..5e266a0
--- /dev/null
+++ b/OpenAuth.App/ServiceApp/LayerManagerApp/LayerApp.cs
@@ -0,0 +1,260 @@
+using System.Data;
+using Infrastructure;
+using Infrastructure.Utils;
+using Microsoft.Extensions.Options;
+using NetTopologySuite;
+using NetTopologySuite.Geometries;
+using NPOI.HSSF.UserModel;
+using NPOI.SS.UserModel;
+using NPOI.XSSF.UserModel;
+using OpenAuth.App.BaseApp.Base;
+using OpenAuth.App.Interface;
+using OpenAuth.App.ServiceApp.LayerManagerApp.Request;
+using OpenAuth.Repository;
+using OpenAuth.Repository.Domain;
+using SqlSugar;
+
+namespace OpenAuth.App.ServiceApp.LayerManagerApp;
+
+public class LayerApp : SqlSugarBaseApp
+{
+ private readonly string _filePath;
+ private readonly ISqlSugarClient _client;
+
+ public LayerApp(ISugarUnitOfWork unitWork,
+ ISimpleClient repository, IAuth auth,
+ IOptions setOptions, ISqlSugarClient client) : base(unitWork, repository, auth)
+ {
+ _client = client;
+ _filePath = setOptions.Value.UploadPath;
+ if (string.IsNullOrEmpty(_filePath))
+ {
+ _filePath = AppContext.BaseDirectory;
+ }
+ }
+
+ public async Task> UploadExcel(LayerReq req)
+ {
+ using var db = Repository.AsSugarClient();
+ var excelPath = Path.Combine(_filePath, req.FilePath);
+ // excel名称
+ var excelFileName = Path.GetFileNameWithoutExtension(excelPath);
+ // 使用NPOI读取Excel文件
+ using (var fileStream = new FileStream(excelPath, FileMode.Open, FileAccess.Read))
+ {
+ IWorkbook workbook;
+ if (Path.GetExtension(excelPath).Equals(".xls"))
+ {
+ workbook = new HSSFWorkbook(fileStream);
+ }
+ else
+ {
+ workbook = new XSSFWorkbook(fileStream);
+ }
+
+ //
+ var sheet = workbook.GetSheetAt(0);
+ // 获取总行数
+ var rowCount = sheet.LastRowNum;
+ if (rowCount < 3)
+ {
+ throw new Exception("只有两行表头");
+ }
+
+ // 获取总列数
+ var columnCount = sheet.GetRow(0).LastCellNum;
+ var headers = new List();
+ // 遍历表头
+ var chineseRow = sheet.GetRow(0);
+ var englishRow = sheet.GetRow(1);
+
+ for (var j = 0; j < columnCount; j++)
+ {
+ var header = new DataTableAttr
+ {
+ InitName = chineseRow.GetCell(j).ToString(), // 中文表头
+ RefName = englishRow.GetCell(j).ToString()?.ToLower(), // 英文表头
+ // 字段类型
+ Type = "string",
+ // 原始字段名称
+ Name = englishRow.GetCell(j).ToString(),
+ // 字段长度
+ Length = 64
+ };
+ headers.Add(header);
+ }
+
+ var keys = headers.Select(a => a.RefName).ToList();
+ if (!keys.Contains("lng") || !keys.Contains("lat"))
+ {
+ throw new Exception("缺少经纬度字段");
+ }
+
+ var typeBuilder = db.DynamicBuilder().CreateClass(req.DataTable,
+ new SugarTable() { TableName = req.DataTable, TableDescription = req.ServerName + "图斑" });
+ //添加主键
+ typeBuilder.CreateProperty("id", typeof(string), new SugarColumn()
+ {
+ IsPrimaryKey = true,
+ IsIdentity = false,
+ ColumnDataType = "varchar",
+ Length = 36,
+ ColumnDescription = "主键",
+ });
+ //添加主键
+ typeBuilder.CreateProperty("geometry", typeof(string), new SugarColumn()
+ {
+ IsPrimaryKey = false,
+ IsIdentity = false,
+ // ColumnDataType = "geometry(GEOMETRY)",
+ ColumnDataType = string.Concat("geometry(GEOMETRY,",
+ req.SpatialRef.AsSpan(req.SpatialRef.LastIndexOf(":", StringComparison.Ordinal) + 1),
+ ")"),
+ ColumnDescription = "图斑",
+ });
+
+ headers.ForEach(u =>
+ {
+ if (!u.RefName.Equals("lng") && !u.RefName.Equals("lat"))
+ {
+ typeBuilder.CreateProperty(u.RefName, typeof(string), new SugarColumn()
+ {
+ IsPrimaryKey = false,
+ IsIdentity = false,
+ IsNullable = true,
+ Length = u.Length,
+ ColumnDescription = u.InitName,
+ });
+ }
+ });
+ // 开启事务
+ await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted);
+ // 创建表
+ //db.CodeFirst.InitTables(typeBuilder.BuilderType());
+
+ var cols = new string[headers.Count];
+ for (var i = 0; i < headers.Count; i++)
+ {
+ if (headers[i].RefName.Equals("lng"))
+ {
+ cols[i] = "geometry";
+ }
+ else if (headers[i].RefName.Equals("lat"))
+ {
+ cols[i] = "id";
+ }
+ else
+ {
+ cols[i] = headers[i].RefName;
+ }
+ }
+
+ var objs = new List>(1001);
+ var num = 0;
+ // 遍历数据行
+ for (var i = 2; i < rowCount; i++)
+ {
+ var row = sheet.GetRow(i);
+ if (row == null)
+ {
+ continue;
+ }
+
+ var data = new Dictionary();
+ // 遍历列
+ string lat = null, lng = null;
+ for (var j = 0; j < columnCount; j++)
+ {
+ var cell = row.GetCell(j);
+ if (cell == null)
+ {
+ continue;
+ }
+
+ var cellValue = cell.ToString();
+ switch (headers[j].RefName)
+ {
+ case "lat":
+ lat = cellValue;
+ continue;
+ case "lng":
+ lng = cellValue;
+ continue;
+ default:
+ data[headers[j].RefName] = cellValue;
+ break;
+ }
+ }
+
+ if (lat != null && lng != null)
+ {
+ var geography =
+ NtsGeometryServices.Instance.CreateGeometryFactory(
+ int.Parse(req.SpatialRef.Substring(
+ req.SpatialRef.IndexOf(":", StringComparison.Ordinal) + 1)));
+ var point = geography.CreatePoint(new Coordinate(double.Parse(lng), double.Parse(lat)));
+ data["geometry"] = point.AsText();
+ }
+
+ data["id"] = Guid.NewGuid().ToString();
+ objs.Add(data);
+ if (num++ == 999)
+ {
+ await db.Insertable(objs)
+ .AS(req.DataTable) // 指定目标表名
+ .InsertColumns(cols) // 指定要插入的列
+ .ExecuteCommandAsync();
+ num = 0;
+ objs.Clear();
+ }
+ }
+
+ await db.Insertable(objs)
+ .AS(req.DataTable) // 指定目标表名
+ .InsertColumns(cols) // 指定要插入的列
+ .ExecuteCommandAsync();
+ await db.Ado.CommitTranAsync();
+ workbook.Close();
+ // 关于图层发布失败后,如何处理?
+ // excel 矢量点发布图层
+ var response = await GeoUtil.CreateStoreAndLayer("", req.SpatialRef, req.DataTable, "");
+ // todo 保存图层信息
+ var dmLayer = new DmLayer()
+ {
+ Id = Guid.NewGuid().ToString(),
+ SeverName = req.ServerName,
+ SpatialRef = req.SpatialRef,
+ SeverType = req.SeverType, // 服务类型
+ StoreType = "", //存储类型
+ DataSourceType = req.DataSourceType,
+ TableRef = req.DataTable,
+ ShapeType = req.ShapeType,
+ StyleName = req.StyleName, // 样式名称
+ Description = req.Description, // 描述
+ Screenshot = req.Screenshot // 截图
+ };
+ await Repository.AsSugarClient().Insertable(dmLayer).ExecuteCommandAsync();
+ }
+
+ return new Response
+ {
+ Result = true
+ };
+ }
+
+ public async Task> UploadShape(LayerReq req)
+ {
+ try
+ {
+ }
+ catch (Exception ex)
+ {
+ throw new CommonException(ex.Message, 500);
+ }
+
+ return new Response
+ {
+ Result = true
+ };
+ }
+}
\ No newline at end of file
diff --git a/OpenAuth.App/ServiceApp/LayerManagerApp/Request/LayerReq.cs b/OpenAuth.App/ServiceApp/LayerManagerApp/Request/LayerReq.cs
new file mode 100644
index 0000000..51e7b2a
--- /dev/null
+++ b/OpenAuth.App/ServiceApp/LayerManagerApp/Request/LayerReq.cs
@@ -0,0 +1,64 @@
+using OpenAuth.Repository.Domain;
+
+namespace OpenAuth.App.ServiceApp.LayerManagerApp.Request
+{
+ public class LayerReq
+ {
+ public LayerReq()
+ {
+ }
+
+ ///
+ /// Desc:
+ /// Default:
+ /// Nullable:False
+ ///
+ public string Id { get; set; }
+
+ ///
+ /// Desc:服务名称
+ /// Default:
+ /// Nullable:True
+ ///
+ public string ServerName { get; set; }
+
+
+ ///
+ /// 空间参考
+ ///
+ public string SpatialRef { get; set; }
+
+ public string SeverType { get; set; }
+
+ ///
+ /// 数据源类型
+ ///
+ public string DataSourceType { get; set; }
+
+ ///
+ /// 数据表名
+ ///
+ public string DataTable { get; set; }
+
+ ///
+ /// 文件路径
+ ///
+ public string FilePath { get; set; }
+
+ ///
+ /// 点线面
+ ///
+ public string ShapeType { get; set; }
+
+ // 头部信息,目前为空
+ public List Headers { get; set; }
+
+ public string Style { get; set; }
+
+ public string StyleName { get; set; }
+
+ public string Description { get; set; }
+
+ public string Screenshot { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/OpenAuth.Repository/Domain/DmLayer.cs b/OpenAuth.Repository/Domain/DmLayer.cs
new file mode 100644
index 0000000..19cf823
--- /dev/null
+++ b/OpenAuth.Repository/Domain/DmLayer.cs
@@ -0,0 +1,57 @@
+namespace OpenAuth.Repository.Domain;
+
+public class DmLayer
+{
+ ///
+ /// 主键
+ ///
+ public string Id { get; set; }
+ ///
+ /// 服务名
+ ///
+ public string SeverName { get; set; }
+ ///
+ /// 空间参考
+ ///
+ public string SpatialRef { get; set; }
+ ///
+ /// 服务类型 矢量 倾斜摄影 栅格
+ ///
+ public string SeverType { get; set; }
+ ///
+ /// 存储类型
+ ///
+ public string StoreType { get; set; }
+ ///
+ /// 数据源类型
+ ///
+ public string DataSourceType { get; set; }
+ ///
+ /// 创建时间
+ ///
+ public DateTime? CreateTime { get; set; }
+ ///
+ /// 数据表名
+ ///
+ public string TableRef { get; set; }
+ ///
+ /// 是否发布
+ ///
+ public bool IsDisplay { get; set; }
+ ///
+ /// 矢量类型 点线面
+ ///
+ public string ShapeType { get; set; }
+ ///
+ /// 样式名称
+ ///
+ public string StyleName { get; set; }
+ ///
+ /// 描述
+ ///
+ public string Description { get; set; }
+ ///
+ /// 截图
+ ///
+ public string Screenshot { get; set; }
+}
\ No newline at end of file
diff --git a/OpenAuth.WebApi/Controllers/ServiceController/LayerController.cs b/OpenAuth.WebApi/Controllers/ServiceController/LayerController.cs
new file mode 100644
index 0000000..f53090f
--- /dev/null
+++ b/OpenAuth.WebApi/Controllers/ServiceController/LayerController.cs
@@ -0,0 +1,43 @@
+using Infrastructure;
+using Microsoft.AspNetCore.Mvc;
+using OpenAuth.App.ServiceApp.LayerManagerApp;
+using OpenAuth.App.ServiceApp.LayerManagerApp.Request;
+
+namespace OpenAuth.WebApi.Controllers.ServiceController;
+
+///
+/// 图层
+///
+[Route("api/[controller]/[action]")]
+[ApiController]
+public class LayerController : ControllerBase
+{
+ private readonly LayerApp _app;
+
+ public LayerController(LayerApp layerApp)
+ {
+ _app = layerApp;
+ }
+
+ ///
+ /// excel 上传
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> UploadExcel(LayerReq req)
+ {
+ return await _app.UploadExcel(req);
+ }
+
+ ///
+ /// shape文件上传
+ ///
+ ///
+ ///
+ [HttpPost]
+ public async Task> UploadShape(LayerReq req)
+ {
+ return await _app.UploadShape(req);
+ }
+}
\ No newline at end of file