feixian_weifajianguan/OpenAuth.App/ServiceApp/ShpGeo/Utils/ShapeUtil.cs

158 lines
5.4 KiB
C#
Raw 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.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
{
/// <summary>
///
/// </summary>
/// <param name="shpPath"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
public static List<Dictionary<string, object>> getRows(string shpPath)
{
throw new NotImplementedException();
}
/// <summary>
/// 支持
/// </summary>
/// <param name="shpPath"></param>
/// <returns></returns>
public static List<Dictionary<string, object>> 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<Dictionary<string, object>> 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<Dictionary<string, object>> rows = new List<Dictionary<string, object>>();
while (dataReader.Read())
{
Dictionary<string, object> row = new Dictionary<string, object>();
// 读取列
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; // 其他异常,可能表示存在乱码
}
}
}