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; // 其他异常,可能表示存在乱码
}
}
}