using System.Data; using System.IO.Compression; using System.Text; using Infrastructure; using Infrastructure.Extensions; using Microsoft.Extensions.Options; using NetTopologySuite; using NetTopologySuite.Geometries; using NetTopologySuite.IO; using NetTopologySuite.IO.Esri; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using OpenAuth.App.BaseApp.Base; using OpenAuth.App.BasicQueryService; using OpenAuth.App.FormScheme; using OpenAuth.App.FormScheme.FormHelpers; using OpenAuth.App.Interface; using OpenAuth.App.Request; using OpenAuth.App.Response; using OpenAuth.App.ServiceApp.ShpGeo.Request; using OpenAuth.App.ServiceApp.ShpGeo.Utils; using OpenAuth.Repository; using OpenAuth.Repository.Domain; using SqlSugar; using Shapefile = NetTopologySuite.IO.Esri.Shapefile; namespace OpenAuth.App.ServiceApp.ShpGeo; public class ShpGeoLayerApp : SqlSugarBaseApp { private readonly string _filePath; private readonly ISqlSugarClient _client; CommonDataManager _commonDataManager; public ShpGeoLayerApp(ISugarUnitOfWork unitWork, ISimpleClient repository, IAuth auth, FormSchemeApp formSchemeApp, IOptions setOptions, ISqlSugarClient client, CommonDataManager commonDataManager) : base(unitWork, repository, auth) { _client = client; _filePath = setOptions.Value.UploadPath; if (string.IsNullOrEmpty(_filePath)) { _filePath = AppContext.BaseDirectory; } _commonDataManager = commonDataManager; } /// /// 添加geo图层 /// /// /// /// public async Task> Add(ShpGeoLayerShpReq obj) { var record = obj.MapTo(); record.CreateTime = DateTime.Now; record.UpdateTime = DateTime.Now; record.Id = Guid.NewGuid().ToString(); using var db = Repository.AsSugarClient(); if (db.DbMaintenance.IsAnyTable(obj.DataTable, false)) { throw new Exception(obj.DataTable + "数据表已存在"); } var layer = await Repository.AsQueryable().Where(a => a.DataTable.Equals(obj.DataTable)).FirstAsync(); if (layer != null) { throw new Exception($"图层记录数据表名{obj.DataTable}已存在"); } // 发布图层 if (record.DataSourceType.Equals("shp")) { /* // 相对路径 var sldFile = record.AppendPath; // 取得全路径 var sldPath = Path.Combine(_filePath, sldFile); // 处理SLD var isSuccess = await GeoUtil.PublishSldStyle(sldPath, obj.DataTable); if (!isSuccess) { throw new Exception("SLD样式发布失败"); }*/ var response = await CreateDataTable(obj); if (!response.Result) { throw new Exception("创建shp数据表失败"); } // 配置存储仓库及发布图层 //var sldName = Path.GetFileName(sldFile); //var sldName = Path.GetFileNameWithoutExtension(sldFile); var result = await GeoUtil.CreateStoreAndLayer("", obj.SpatialRef, obj.DataTable, obj.StyleName); if (!result) { db.DbMaintenance.DropTable(obj.DataTable); throw new Exception("发布图层失败"); } } else // excel { var excelPath = Path.Combine(_filePath, obj.ShpPath); var excelFileName = Path.GetFileNameWithoutExtension(excelPath); // xls xlsx // 使用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(obj.DataTable, new SugarTable() { TableName = obj.DataTable, TableDescription = obj.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,", obj.SpatialRef.AsSpan(obj.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; } } // 遍历数据行 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(obj.SpatialRef.Substring( obj.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(); await db.Insertable(data) .AS(obj.DataTable) // 指定目标表名 .InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync(); } await db.Ado.CommitTranAsync(); // 关于图层发布失败后,如何处理? // excel 矢量点发布图层 var response = await GeoUtil.CreateStoreAndLayer("", obj.SpatialRef, obj.DataTable, ""); if (!response) { // 如果图层发布失败 删除数据表 db.DbMaintenance.DropTable(obj.DataTable); } workbook.Close(); } } var geoserver = GeoUtil.GeoserverUrl; var workspace = GeoUtil.Workspace; var storeName = GeoUtil.DbStoreName; var getBboxResponse = await GeoUtil.GetDBLayerBBox(workspace, storeName, obj.DataTable); if (getBboxResponse.Code == 200) { var bbox = getBboxResponse.Result; var serverUrl = $"{geoserver}/{workspace}/wms" + $"?service=WMS" + $"&version=1.1.0" + $"&request=GetMap" + $"&layers={workspace}:{obj.DataTable}" + $"&bbox=" + bbox + $"&width=768&height=619" + $"&srs=" + obj.SpatialRef + "&styles=" + /*$"&styles=" + (obj.DataSourceType.Equals("shp") ? Path.GetFileName(obj.AppendPath)?.Replace(".sld", "") : "") +*/ $"&format=application/openlayers"; record.ServerUrl = serverUrl; var pbfUrl = $"{geoserver}/gwc/service/tms/1.0.0/{workspace}:{obj.DataTable}@{obj.SpatialRef}@pbf"; record.PbfUrl = pbfUrl; } var settingResponse = await GeoUtil.SettingLayerReturnFormat("", obj.DataTable); if (!settingResponse.Result) { // 设置返回格式失败 } var flag = await Repository.InsertAsync(record); return new Response { Result = flag, Message = flag && getBboxResponse.Code == 200 ? "success" : flag ? "成功但获取serverurl失败" : "error" }; } public async Task>>> LoadPage(ShpGeoLayerReq req) { RefAsync totalCount = 0; var sources = await base.Repository.AsQueryable() .WhereIF(!string.IsNullOrEmpty(req.SererName), a => a.ServerName.Contains(req.SererName)) .WhereIF(!string.IsNullOrEmpty(req.startTime) && !string.IsNullOrEmpty(req.endTime), a => SqlFunc.Between(a.CreateTime, Convert.ToDateTime(req.startTime), Convert.ToDateTime(req.endTime))) // 时间段查询 .ToPageListAsync(req.page, req.limit, totalCount); return new Response>> { Result = new PageInfo> { Items = sources, Total = totalCount } }; } public ShpGeoLayer Get(string id) { return Repository.GetById(id); } private static async Task UnZip(string zipFilePath, string extractPath) { await Task.Run(() => { Directory.CreateDirectory(extractPath); // 设置字符编码 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var gbk = Encoding.GetEncoding("utf-8"); using (var archive = ZipFile.OpenRead(zipFilePath)) { // 列举ZIP文件中的条目 foreach (var entry in archive.Entries) { var xxx = gbk.GetString(Encoding.Default.GetBytes(entry.FullName)); Console.WriteLine(xxx); } // 提取ZIP文件中的所有文件到指定目录 foreach (var entry in archive.Entries) { if (entry.Name != string.Empty) { // 确保完整路径存在 entry.FullName 是否可以编码 var fixedEntryName = entry.FullName.Replace("/", ""); var destinationPath = Path.GetFullPath(Path.Combine(extractPath, fixedEntryName)); Console.WriteLine("解压文件路径:" + destinationPath); if (!destinationPath.StartsWith(Path.GetFullPath(extractPath) + Path.DirectorySeparatorChar)) { throw new UnauthorizedAccessException("试图提取的文件超出了目标文件夹的路径边界。"); } // 提取条目到目标路径 entry.ExtractToFile(destinationPath, overwrite: true); } } } // 遍历解压目录,是否有shp后缀的文件 if (!Directory.Exists(extractPath)) { throw new Exception("文件解压失败"); } }); } private static void DeleteFile(string extractPath) { try { // 递归删除目录和其内容 Directory.Delete(extractPath, true); Console.WriteLine("解压目录删除成功"); } catch (IOException ex) { Console.WriteLine("解压目录不能删除: " + ex.Message); } catch (UnauthorizedAccessException ex) { Console.WriteLine("没有权限删除解压目录: " + ex.Message); } } private static string MapDbaseTypeToPostgresString(char dbaseType) { return dbaseType switch { 'C' => "varchar", 'N' => "numeric", 'L' => "boolean", 'D' => "date", 'M' => "text", _ => "varchar" }; } public async Task> Test(string tableName, string serverName, string srid, string shpPath) { using var db = Repository.AsSugarClient(); // 校验 表是否存在 var isExists = db.DbMaintenance.IsAnyTable(tableName, false); if (isExists) { //throw new Exception(tableName + "该数据库表已存在"); db.DbMaintenance.DropTable(tableName); } var shpGeoLayer = await db.Queryable() .Where(c => c.ServerName.Equals(serverName)) .FirstAsync(); if (!shpGeoLayer.IsNullOrEmpty()) { throw new Exception("服务名已存在"); } // 插入图斑数据 shpPath = Path.Combine(_filePath, shpPath); var extractPath = shpPath.Substring(0, shpPath.LastIndexOf(".", StringComparison.Ordinal)) + "extract"; await UnZip(shpPath, extractPath); var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名 var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories); if (fileName.IsEmpty()) { throw new Exception("未找到shp文件"); } string shpFileName = fileName[0]; // shpFile 文件路径 string shpFile = Path.Combine(extractPath, shpFileName); var rows = new List>(); using (var dataReader = new ShapefileDataReader(shpFile, GeometryFactory.Default)) { var headers = new List(); for (var i = 0; i < dataReader.DbaseHeader.NumFields; i++) { var colAttr = new DataTableAttr(); //colAttr.DataType = dataReader.DbaseHeader.Fields[i].Type; colAttr.RefName = dataReader.DbaseHeader.Fields[i].Name; colAttr.InitName = dataReader.DbaseHeader.Fields[i].Name; colAttr.Length = dataReader.DbaseHeader.Fields[i].Length; headers.Add(colAttr); } // 创建数据表 var typeBuilder = db.DynamicBuilder().CreateClass(tableName, new SugarTable() { TableName = tableName, TableDescription = 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 = string.Concat("geometry(GEOMETRY, ", srid.AsSpan(srid.LastIndexOf(":", StringComparison.Ordinal) + 1), ")"), ColumnDescription = "图斑", }); headers.ForEach(u => { typeBuilder.CreateProperty(u.RefName, typeof(string), new SugarColumn() { IsPrimaryKey = false, IsIdentity = false, //ColumnDataType = u.Type, IsNullable = true, Length = u.Length, ColumnDescription = u.InitName, }); }); // 开启事务 await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted); // 创建表 db.CodeFirst.InitTables(typeBuilder.BuilderType()); var x = 0; List cols = new List(); // 读取一下行数据 while (dataReader.Read() && x++ < 20) { // 增加 id 及 // var cols = new string[dataReader.DbaseHeader.NumFields + 2]; var insertObj = new Dictionary { { "id", Guid.NewGuid().ToString() } }; Console.Write("类型: " + dataReader.Geometry.GeometryType); // 读取一行数据 for (int i = 0, j = 0; i < dataReader.FieldCount; i++) { cols.Add(dataReader.GetName(i)); if (dataReader.GetName(i).ToLower().Equals("geometry")) { var geom = dataReader.GetValue(i) as Geometry; //var srid = geom.SRID; insertObj.Add(dataReader.GetName(i), geom.AsText()); } else { insertObj.Add(dataReader.GetName(i), dataReader.GetValue(i)); } } rows.Add(insertObj); } /*await db.Insertable(rows) .AS(tableName) // 指定目标表名 //.InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync();*/ var sql = "INSERT INTO \"public\".\"" + tableName + "\" ("; // to do var colsStr = ""; foreach (var key in rows.First().Keys) { colsStr += "\"" + key + "\","; } colsStr = colsStr.Substring(0, colsStr.Length - 1); sql += colsStr + ") VALUES ("; var values = ""; foreach (var dictionary in rows) { // todo 如何处理 geometry 类型 foreach (var value in dictionary.Values) { values += "'" + value + "',"; } } await db.Ado.ExecuteCommandAsync(sql); await db.Ado.CommitTranAsync(); } return new Response() { Result = true, Message = "ok" }; } /// /// 图层更新 /// /// /// public async Task> UpdateLayer(UpdateGeoLayerShpReq updateLayerReq) { var db = Repository.AsSugarClient(); await db.Ado.BeginTranAsync(); var layer = await Repository.GetByIdAsync(updateLayerReq.Id); //var styleName = layer.StyleName; // 前面使用表名作为样式名称 var newStyleName = updateLayerReq.StyleName; var result = await GeoUtil.UpdateStyle(GeoContext.Instance.Workspace, layer.DataTable, newStyleName); /* if (!string.IsNullOrEmpty(updateLayerReq.sldPath)) { // 更新样式 // 取得全路径 // var sldPath = Path.Combine(_filePath, updateLayerReq.sldPath); var response = await GeoUtil.UpdateSldStyle(sldPath, styleName); if (!response) { throw new Exception("样式更新失败"); } }*/ if (!result.Result) { throw new Exception("更换样式失败"); } var record = updateLayerReq.MapTo(); await db.Updateable(record).IgnoreNullColumns().ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); return new Response() { Result = true, Message = "更新成功" }; } /// /// 删除图层 /// /// /// public async Task> Delete(string id) { var db = Repository.AsSugarClient(); await db.Ado.BeginTranAsync(); var shp = await Repository.GetByIdAsync(id); var dataTable = shp.DataTable; db.DbMaintenance.DropTable(dataTable); // todo 删除对应图层 await db.Deleteable().Where(c => c.Id.Equals(id)).ExecuteCommandAsync(); await db.Ado.CommitTranAsync(); return new Response() { Result = true, Message = "删除成功" }; } public async Task> ParseShpInfo(string zipFilePath, string tableName, string srid) { using var db = Repository.AsSugarClient(); // 开启事务 if (db.DbMaintenance.IsAnyTable(tableName)) { throw new Exception("表名已存在"); } // 取得文件完全路径 zipFilePath = Path.Combine(_filePath, zipFilePath); // 确保ZIP文件存在 if (!File.Exists(zipFilePath)) { throw new FileNotFoundException("ZIP文件未找到。"); } var exist = await db.Queryable() .Where(c => c.DataType.Equals(tableName)) .CountAsync(); if (exist > 0) { throw new Exception(tableName + "表名已存在"); } // 打开ZIP存档 取除后缀之前的字符串 var extractPath = zipFilePath.Substring(0, zipFilePath.LastIndexOf(".", StringComparison.Ordinal)) + "extract"; // 解压文件 await UnZip(zipFilePath, extractPath); var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名 var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories); if (fileName.IsEmpty()) { throw new Exception("压缩文件中无shp文件"); } var shpFileName = fileName[0]; var shpFile = Path.Combine(extractPath, shpFileName); var shapeType = Shapefile.GetShapeType(shpFile); var shpInfo = new ShpInfo(); switch (shapeType) { case ShapeType.Point: shpInfo.DataType = "点"; break; case ShapeType.Polygon: shpInfo.DataType = "面"; break; case ShapeType.PolyLine: shpInfo.DataType = "线"; break; default: throw new Exception("不支持的shp类型: " + shapeType); } var attrs = new List(); // 添加自定义字段 var geom = new DataTableAttr { Name = "Geometry", Type = string.Concat("geometry(GEOMETRY,", srid.AsSpan(srid.LastIndexOf(":", StringComparison.Ordinal) + 1), ")") }; attrs.Add(geom); using (var reader = new ShapefileDataReader(shpFile, GeometryFactory.Default)) { // 获取DbfDataReader,用于读取属性信息 var dbfReader = reader.DbaseHeader; foreach (var dbaseFieldDescriptor in dbfReader.Fields) { DataTableAttr attr = new DataTableAttr(); attr.Name = dbaseFieldDescriptor.Name; attr.Length = dbaseFieldDescriptor.Length; attr.Type = MapDbaseTypeToPostgresString(dbaseFieldDescriptor.DbaseType); attrs.Add(attr); } } shpInfo.Headers = attrs; shpInfo.TableName = tableName; return new Response() { Result = shpInfo, Message = "ok" }; } // todo 拆分,主方法中完成数据库操作, public async Task> CreateDataTable(ShpGeoLayerShpReq shpInfo) { using var db = Repository.AsSugarClient(); var tableName = shpInfo.DataTable; // 校验 表是否存在 var exist = await db.Queryable() .Where(c => c.DataTable.Equals(tableName)) .CountAsync(); if (exist > 0) { throw new Exception(tableName + "库表名称已存在"); } var shpGeoLayer = await db.Queryable() .Where(c => c.ServerName.Equals(shpInfo.ServerName)) .FirstAsync(); if (!shpGeoLayer.IsNullOrEmpty()) { throw new Exception("未执行shp解析"); } // 创建数据表 var typeBuilder = db.DynamicBuilder().CreateClass(tableName, new SugarTable() { TableName = tableName, TableDescription = shpInfo.ServerName + "图斑" }); //添加主键 typeBuilder.CreateProperty("id", typeof(string), new SugarColumn() { IsPrimaryKey = true, IsIdentity = false, ColumnDataType = "varchar", Length = 36, ColumnDescription = "主键", }); shpInfo.Headers.ForEach(u => { typeBuilder.CreateProperty(u.RefName, typeof(string), new SugarColumn() { IsPrimaryKey = false, IsIdentity = false, ColumnDataType = u.Type, IsNullable = true, Length = u.Length, ColumnDescription = u.InitName, }); }); // 开启事务 await db.Ado.BeginTranAsync(IsolationLevel.ReadCommitted); // 创建表 db.CodeFirst.InitTables(typeBuilder.BuilderType()); // 插入图斑数据 var shpPath = Path.Combine(_filePath, shpInfo.ShpPath); var extractPath = shpPath.Substring(0, shpPath.LastIndexOf(".", StringComparison.Ordinal)) + "extract"; var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名 var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories); if (fileName.IsEmpty()) { throw new Exception("未找到shp文件"); } var shpFileName = fileName[0]; // shpFile 文件路径 var shpFile = Path.Combine(extractPath, shpFileName); shpInfo.Headers.Add(new DataTableAttr { RefName = "", InitName = "", Name = "" }); // 批量插入 var cols = new string[shpInfo.Headers.Count]; for (var i = 0; i < shpInfo.Headers.Count - 1; i++) { cols[i] = shpInfo.Headers[i].RefName; } cols[^1] = "id"; using (var dataReader = new ShapefileDataReader(shpFile, GeometryFactory.Default)) { Console.WriteLine("记录数" + dataReader.RecordCount); //throw new Exception("失败"); var objs = new List>(1001); var num = 0; int count = 0; while (dataReader.Read()) { count++; Console.WriteLine("记录行:" + count); var insertObj = new Dictionary { { "id", Guid.NewGuid().ToString() } }; // 读取列 for (int i = 0, j = 0; i < dataReader.FieldCount; i++) { var colName = dataReader.GetName(i); var header = shpInfo.Headers[j]; if (header.Name.Equals(colName)) { if (colName.ToLower().Equals("geometry")) { var geometry = (Geometry)dataReader.GetValue(i); var srid = shpInfo.SpatialRef.Substring( shpInfo.SpatialRef.IndexOf(":", StringComparison.Ordinal) + 1); var geometryForWgs84 = GeometryFactory.Default.WithSRID(int.Parse(srid)) .CreateGeometry(geometry); insertObj.Add(shpInfo.Headers[j++].RefName, geometryForWgs84.AsText()); } else { insertObj.Add(shpInfo.Headers[j++].RefName, dataReader.GetValue(i)); } } } objs.Add(insertObj); if (num++ == 999) { await db.Insertable(objs) .AS(tableName) // 指定目标表名 .InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync(); num = 0; objs.Clear(); } } // 读取末尾 await db.Insertable(objs) .AS(tableName) // 指定目标表名 .InsertColumns(cols) // 指定要插入的列 .ExecuteCommandAsync(); } await db.Ado.CommitTranAsync(); // 删文件 //DeleteFile(extractPath); return new Response() { Result = true, Message = "ok" }; } public async Task> Test1(string tableName, string serverName, string srid, string shpPath) { var db = Repository.AsSugarClient(); // 输出目 /*var db = Repository.AsSugarClient(); shpPath = Path.Combine(_filePath, shpPath); var extractPath = shpPath.Substring(0, shpPath.LastIndexOf(".", StringComparison.Ordinal)) + "extract"; var searchPattern = "*.shp"; // 设置你想要遍历的文件后缀名 var fileName = Directory.GetFiles(extractPath, searchPattern, SearchOption.AllDirectories); if (fileName.IsEmpty()) { throw new Exception("未找到shp文件"); } var shpFileName = fileName[0]; // shpFile 文件路径 var shpFile = Path.Combine(extractPath, shpFileName); await db.Ado.BeginTranAsync(); var rows = new List>(); using (var dataReader = new ShapefileDataReader(shpFile, GeometryFactory.Default)) { while (dataReader.Read()) { var insertObj = new Dictionary { { "id", Guid.NewGuid().ToString() }, { "geometry", dataReader.Geometry.AsBinary() }, }; rows.Add(insertObj); } } int insertCount = await db.Insertable(rows) .AS(tableName) // 指定目标表名 .InsertColumns("id", "geometry") // 指定要插入的列 .ExecuteCommandAsync(); /* foreach (var geometry in Shapefile.ReadAllGeometries(shpFile)) { var insertObj = new Dictionary { { "id", Guid.NewGuid().ToString() }, { "geometry", geometry.AsBinary() }, }; int insertCount = await db.Insertable(insertObj) .AS(tableName) // 指定目标表名 .InsertColumns("id", "geometry") // 指定要插入的列 .ExecuteCommandAsync(); } #1# await db.Ado.CommitTranAsync();*/ return new Response { Result = true }; } /// /// 获取图层中心点 /// /// /// public async Task> GetGeomData(string tableName) { var sql = "select ST_AsText(ST_Centroid(ST_Extent(geometry))) from \"public\".\"" + tableName + "\""; var db = Repository.AsSugarClient(); var result = await db.Ado.SqlQuerySingleAsync(sql); return new Response { Result = result, Message = "ok" }; } public byte[] QueryVectorTileByTable(QueryVectorTileByTableReq req) { VectorTileSearchModel searchModel = new VectorTileSearchModel { x = req.x, y = req.y, z = req.z, //field = req.field, table = req.table, filter = req.filter, }; var fieldArray = req.field.TrimEnd(',').Split(","); //req fields var fields = ""; var cols = _client.DbMaintenance.GetColumnInfosByTableName(req.table); foreach (var dbColumnInfo in cols) { if (dbColumnInfo.DbColumnName.Equals("geometry")) { continue; } fields += dbColumnInfo.DbColumnName + ","; } fields = fields.TrimEnd(','); var fieldArrayTemp = fields.Split(","); // 取两个数组的交集 fields = string.Join(",", fieldArrayTemp.Intersect(fieldArray)) + ","; searchModel.field = fields; var result = _commonDataManager.VectorTile1(searchModel); return result; } public dynamic GetDataTableRecord(string dataTable, string id) { using var db = Repository.AsSugarClient(); var list = db.DbMaintenance.GetColumnInfosByTableName(dataTable); var fields = string.Join(",", list.Where(x => x.DbColumnName != "geometry").Select(x => x.DbColumnName)); return db.Ado.SqlQuery("select " + fields + " from " + dataTable + " where id='" + id + "'").First(); } }