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