feixian_weifajianguan/OpenAuth.App/ServiceApp/ShpGeo/ShpGeoLayerApp.cs

1028 lines
37 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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<ShpGeoLayer, SugarDbContext>
{
private readonly string _filePath;
private readonly ISqlSugarClient _client;
CommonDataManager _commonDataManager;
public ShpGeoLayerApp(ISugarUnitOfWork<SugarDbContext> unitWork,
ISimpleClient<ShpGeoLayer> repository, IAuth auth, FormSchemeApp formSchemeApp,
IOptions<AppSetting> setOptions, ISqlSugarClient client, CommonDataManager commonDataManager) : base(unitWork, repository, auth)
{
_client = client;
_filePath = setOptions.Value.UploadPath;
if (string.IsNullOrEmpty(_filePath))
{
_filePath = AppContext.BaseDirectory;
}
_commonDataManager = commonDataManager;
}
/// <summary>
/// 添加geo图层
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<Response<bool>> Add(ShpGeoLayerShpReq obj)
{
var record = obj.MapTo<ShpGeoLayer>();
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<DataTableAttr>();
// 遍历表头
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, object>();
// 遍历列
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<bool>
{
Result = flag,
Message = flag && getBboxResponse.Code == 200 ? "success" : flag ? "成功但获取serverurl失败" : "error"
};
}
public async Task<Response<PageInfo<List<ShpGeoLayer>>>> LoadPage(ShpGeoLayerReq req)
{
RefAsync<int> 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<PageInfo<List<ShpGeoLayer>>>
{
Result = new PageInfo<List<ShpGeoLayer>>
{
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<Response<bool>> 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<ShpGeoLayer>()
.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<Dictionary<string, object>>();
using (var dataReader = new ShapefileDataReader(shpFile, GeometryFactory.Default))
{
var headers = new List<DataTableAttr>();
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<string> cols = new List<string>();
// 读取一下行数据
while (dataReader.Read() && x++ < 20)
{
// 增加 id 及
// var cols = new string[dataReader.DbaseHeader.NumFields + 2];
var insertObj = new Dictionary<string, object>
{
{ "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<bool>()
{
Result = true,
Message = "ok"
};
}
/// <summary>
/// 图层更新
/// </summary>
/// <param name="updateLayerReq"></param>
/// <returns></returns>
public async Task<Response<bool>> 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<ShpGeoLayer>();
await db.Updateable(record).IgnoreNullColumns().ExecuteCommandAsync();
await db.Ado.CommitTranAsync();
return new Response<bool>()
{
Result = true,
Message = "更新成功"
};
}
/// <summary>
/// 删除图层
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<Response<bool>> 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<ShpGeoLayer>().Where(c => c.Id.Equals(id)).ExecuteCommandAsync();
await db.Ado.CommitTranAsync();
return new Response<bool>()
{
Result = true,
Message = "删除成功"
};
}
public async Task<Response<ShpInfo>> 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<ShpGeoLayer>()
.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<DataTableAttr>();
// 添加自定义字段
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<ShpInfo>()
{
Result = shpInfo,
Message = "ok"
};
}
// todo 拆分,主方法中完成数据库操作,
public async Task<Response<bool>> CreateDataTable(ShpGeoLayerShpReq shpInfo)
{
using var db = Repository.AsSugarClient();
var tableName = shpInfo.DataTable;
// 校验 表是否存在
var exist = await db.Queryable<ShpGeoLayer>()
.Where(c => c.DataTable.Equals(tableName))
.CountAsync();
if (exist > 0)
{
throw new Exception(tableName + "库表名称已存在");
}
var shpGeoLayer = await db.Queryable<ShpGeoLayer>()
.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<Dictionary<string, object>>(1001);
var num = 0;
int count = 0;
while (dataReader.Read())
{
count++;
Console.WriteLine("记录行:" + count);
var insertObj = new Dictionary<string, object>
{
{ "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<bool>()
{
Result = true,
Message = "ok"
};
}
public async Task<Response<bool>> 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<Dictionary<string, object>>();
using (var dataReader = new ShapefileDataReader(shpFile, GeometryFactory.Default))
{
while (dataReader.Read())
{
var insertObj = new Dictionary<string, object>
{
{ "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<string, object>
{
{ "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<bool>
{
Result = true
};
}
/// <summary>
/// 获取图层中心点
/// </summary>
/// <param name="tableName"></param>
/// <returns></returns>
public async Task<Response<string>> 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<string>(sql);
return new Response<string>
{
Result = result,
Message = "ok"
};
}
public byte[] QueryVectorTileByTable1(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;
}
#region 获取矢量切片
/// <summary>
/// 根据表名获取矢量切片
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
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 result = new CommonDataManager(base.UnitWork.CreateContext().Db).VectorTile(searchModel);
return result;
}
#endregion
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<dynamic>("select " + fields + " from " + dataTable + " where id='" + id + "'").First();
}
}