using System.IO.Compression; using System.Resources; using System.Text; using Flurl.Http; using NetTopologySuite.Geometries; using NetTopologySuite.IO; namespace OpenAuth.App.ServiceApp.ShpGeo.Utils; public class ShapeUtil { /// /// /// /// /// /// public static List> getRows(string shpPath) { throw new NotImplementedException(); } /// /// 支持 /// /// /// public static List> ReadAllGeometry(string shpPath) { // 取得后缀,如果是zip,则解压 var fileExtension = Path.GetExtension(shpPath); if (!fileExtension.Equals(".shp") && !fileExtension.Equals(".zip")) { throw new Exception("不支持的文件格式"); } // 设置字符编码 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); var gbk = Encoding.GetEncoding("gbk"); if (fileExtension == ".zip") { var extractPath = Path.GetDirectoryName(shpPath) + "\\temp"; Directory.CreateDirectory(extractPath); using (var archive = ZipFile.OpenRead(shpPath)) { // 列举ZIP文件中的条目 foreach (var entry in archive.Entries) { Console.WriteLine("zip 包含文件:"); var fileName = gbk.GetString(Encoding.Default.GetBytes(entry.FullName)); Console.WriteLine(fileName); } // 提取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("文件解压失败"); } // 查找 var dirInfo = new DirectoryInfo(extractPath); // zip 压缩包中只有一个shp文件 shpPath = dirInfo.GetFiles("*.shp", SearchOption.AllDirectories)[0].FullName; } var data = ParseShape(shpPath, null); var tifPath = data.First()["Image"].ToString(); if (CheckForGarbledText(tifPath)) { // 乱码,需要解码 data = ParseShape(shpPath, gbk); } return data; } private static List> ParseShape(string shpPath, Encoding code) { using var dataReader = code == null ? new ShapefileDataReader(shpPath, GeometryFactory.Default) : new ShapefileDataReader(shpPath, GeometryFactory.Default, code); Console.WriteLine("记录数" + dataReader.RecordCount); List> rows = new List>(); while (dataReader.Read()) { Dictionary row = new Dictionary(); // 读取列 for (int i = 0, j = 0; i < dataReader.FieldCount; i++) { var colName = dataReader.GetName(i); var value = dataReader.GetValue(i); row.Add(colName, value); } rows.Add(row); } return rows; // return NetTopologySuite.IO.Esri.Shapefile.ReadAllGeometries(shpPath); } private static bool CheckForGarbledText(string content) { try { // 检查是否有不可打印的字符 foreach (char c in content) { if (char.IsControl(c) && !char.IsWhiteSpace(c)) { return true; // 发现不可打印的控制字符 } } // 检查是否有不常见的字符 foreach (char c in content) { if (c > 0x7F && !char.IsLetterOrDigit(c) && !char.IsPunctuation(c) && !char.IsSymbol(c) && !char.IsWhiteSpace(c)) { return true; // 发现不常见的字符 } } return false; // 没有发现乱码 } catch (DecoderFallbackException) { return true; // 解码失败,存在乱码 } catch (Exception ex) { return true; // 其他异常,可能表示存在乱码 } } }