623 lines
27 KiB
C#
623 lines
27 KiB
C#
using ICSharpCode.SharpZipLib.Zip;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Xml;
|
||
|
||
namespace Learun.Application.Web.Common
|
||
{
|
||
/// <summary>
|
||
/// KML实体
|
||
/// </summary>
|
||
public class Placemark
|
||
{
|
||
public string name { get; set; }
|
||
public string typeStr { get; set; }
|
||
public List<double> points { get; set; }
|
||
public object style { get; set; }
|
||
public List<Coordinates> coordinates { get; set; }
|
||
}
|
||
/// <summary>
|
||
/// 坐标
|
||
/// </summary>
|
||
public class Coordinates
|
||
{
|
||
public double X { get; set; }
|
||
public double Y { get; set; }
|
||
public double Z { get; set; }
|
||
}
|
||
|
||
public class KmlUtility
|
||
{
|
||
|
||
/// <summary>
|
||
/// 解压缩文件(压缩文件中含有子目录)
|
||
/// </summary>
|
||
/// <param name="zipfilepath">待解压缩的文件路径</param>
|
||
/// <param name="unzippath">解压缩到指定目录</param>
|
||
/// <returns>解压后的文件列表</returns>
|
||
public static List<string> UnZip(string zipfilepath, string unzippath)
|
||
{
|
||
if (!File.Exists(zipfilepath))
|
||
{
|
||
return new List<string>();
|
||
}
|
||
//解压出来的文件列表
|
||
List<string> unzipFiles = new List<string>();
|
||
|
||
//检查输出目录是否以“\\”结尾
|
||
List<string> kmlfile = new List<string>();
|
||
if (unzippath.EndsWith("\\") == false || unzippath.EndsWith(":\\") == false)
|
||
{
|
||
unzippath += "\\";
|
||
}
|
||
ZipInputStream s = new ZipInputStream(File.OpenRead(zipfilepath));
|
||
ZipEntry theEntry;
|
||
while ((theEntry = s.GetNextEntry()) != null)
|
||
{
|
||
if (Path.GetExtension(theEntry.Name).ToLower() == ".kml")
|
||
{
|
||
string directoryName = Path.GetDirectoryName(unzippath);
|
||
string fileName = Path.GetFileName(theEntry.Name);
|
||
|
||
//生成解压目录【用户解压到硬盘根目录时,不需要创建】
|
||
if (!string.IsNullOrEmpty(directoryName))
|
||
{
|
||
Directory.CreateDirectory(directoryName);
|
||
}
|
||
if (fileName != String.Empty)
|
||
{
|
||
//如果文件的压缩后大小为0那么说明这个文件是空的,因此不需要进行读出写入
|
||
if (theEntry.CompressedSize == 0)
|
||
continue;
|
||
//解压文件到指定的目录
|
||
directoryName = Path.GetDirectoryName(unzippath + theEntry.Name);
|
||
//建立下面的目录和子目录
|
||
Directory.CreateDirectory(directoryName);
|
||
|
||
kmlfile.Add(unzippath + theEntry.Name);
|
||
//记录导出的文件
|
||
unzipFiles.Add(unzippath + theEntry.Name);
|
||
|
||
FileStream streamWriter = File.Create(unzippath + theEntry.Name);
|
||
|
||
int size = 2048;
|
||
byte[] data = new byte[2048];
|
||
while (true)
|
||
{
|
||
size = s.Read(data, 0, data.Length);
|
||
if (size > 0)
|
||
{
|
||
streamWriter.Write(data, 0, size);
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
streamWriter.Close();
|
||
}
|
||
}
|
||
|
||
}
|
||
s.Close();
|
||
GC.Collect();
|
||
return kmlfile;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取kml对象
|
||
/// </summary>
|
||
/// <param name="kmlPath"></param>
|
||
/// <returns></returns>
|
||
public static List<Placemark> readKml(string kmlPath, bool isAPP = false)
|
||
{
|
||
List<string> list = new List<string>();
|
||
List<Placemark> retMarks = new List<Placemark>();
|
||
if (!File.Exists(kmlPath))
|
||
{
|
||
return new List<Placemark>();
|
||
}
|
||
if (Path.GetExtension(kmlPath).ToLower() == ".kmz")
|
||
{
|
||
list = UnZip(kmlPath, Path.GetDirectoryName(kmlPath));
|
||
}
|
||
else
|
||
{
|
||
list.Add(kmlPath);
|
||
}
|
||
foreach (var path in list)
|
||
{
|
||
XmlDocument xmldoc = new XmlDocument();
|
||
xmldoc.Load(path);
|
||
//申明xml命名空间管理对象
|
||
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmldoc.NameTable);
|
||
XmlElement root = xmldoc.DocumentElement;
|
||
//添加命名空间
|
||
nsmanager.AddNamespace("XX", "" + root.NamespaceURI + "");
|
||
/////规范命名空间
|
||
XmlNode t = root.GetElementsByTagName("Kml")[0];
|
||
XmlNode _document = root.GetElementsByTagName("Document")[0];
|
||
// XmlNodeList xmlmark = root.GetElementsByTagName("Placemark");
|
||
XmlNodeList xmlmark = xmldoc.SelectNodes("//XX:Placemark", nsmanager);
|
||
int tpid = 0;//踏勘点序号
|
||
foreach (XmlElement element in xmlmark)
|
||
{
|
||
Placemark mark = new Placemark();
|
||
mark.points = new List<double>();
|
||
tpid = tpid + 1;
|
||
string note = "";
|
||
var nameNode = element.GetElementsByTagName("name");
|
||
if (nameNode != null && nameNode.Count > 0)
|
||
{
|
||
string nmNode = nameNode[0].InnerText;
|
||
note = nmNode.Trim();
|
||
}
|
||
mark.name = note;
|
||
XmlElement cNode = null;
|
||
var pointNode = element.GetElementsByTagName("Point");
|
||
if (pointNode != null && pointNode.Count > 0)
|
||
{
|
||
mark.typeStr = "point";
|
||
cNode = (XmlElement)pointNode[0];
|
||
}
|
||
else
|
||
{
|
||
var lineNode = element.GetElementsByTagName("LineString");
|
||
if (lineNode != null && lineNode.Count > 0)
|
||
{
|
||
mark.typeStr = "line";
|
||
cNode = (XmlElement)lineNode[0];
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText;
|
||
var points = pointstr.Split(new char[] { '\n', ' ' });
|
||
var pointsCount = points.Length;
|
||
int pIndex = -1;
|
||
foreach (var item in points)
|
||
{
|
||
pIndex++;
|
||
if (pointsCount > 50)
|
||
{
|
||
if (isAPP && pIndex != 0 && pIndex != pointsCount - 1)
|
||
{
|
||
var yu = pIndex % 4;
|
||
if (yu != 0)
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
}
|
||
var pointStr = item.Trim();
|
||
if (string.IsNullOrEmpty(pointStr))
|
||
{
|
||
continue;
|
||
}
|
||
var point = pointStr.Split(',');
|
||
if (point.Length < 3)
|
||
{
|
||
continue;
|
||
}
|
||
double X = Convert.ToDouble(point[0].Trim());
|
||
double Y = Convert.ToDouble(point[1].Trim());
|
||
mark.points.Add(X);
|
||
mark.points.Add(Y);
|
||
}
|
||
}
|
||
//线必须大于两个点
|
||
if (mark.points.Count < 4 && (mark.points.Count % 2) != 0 && mark.typeStr == "line")
|
||
{
|
||
continue;
|
||
}
|
||
if (mark.points.Count > 0)
|
||
{
|
||
retMarks.Add(mark);
|
||
}
|
||
}
|
||
}
|
||
|
||
return retMarks;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取kml对象
|
||
/// </summary>
|
||
/// <param name="kmlPath"></param>
|
||
/// <returns></returns>
|
||
public static List<Placemark> readzKml(string kmlPath, bool isAPP = false)
|
||
{
|
||
List<string> list = new List<string>();
|
||
List<Placemark> retMarks = new List<Placemark>();
|
||
if (!File.Exists(kmlPath))
|
||
{
|
||
return new List<Placemark>();
|
||
}
|
||
if (Path.GetExtension(kmlPath).ToLower() == ".kmz")
|
||
{
|
||
list = UnZip(kmlPath, Path.GetDirectoryName(kmlPath));
|
||
}
|
||
else
|
||
{
|
||
list.Add(kmlPath);
|
||
}
|
||
foreach (var path in list)
|
||
{
|
||
XmlDocument xmldoc = new XmlDocument();
|
||
xmldoc.Load(path);
|
||
//申明xml命名空间管理对象
|
||
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmldoc.NameTable);
|
||
XmlElement root = xmldoc.DocumentElement;
|
||
//添加命名空间
|
||
nsmanager.AddNamespace("XX", "" + root.NamespaceURI + "");
|
||
/////规范命名空间
|
||
XmlNode t = root.GetElementsByTagName("Kml")[0];
|
||
XmlNode _document = root.GetElementsByTagName("Document")[0];
|
||
// XmlNodeList xmlmark = root.GetElementsByTagName("Placemark");
|
||
XmlNodeList xmlmark = xmldoc.SelectNodes("//XX:Placemark", nsmanager);
|
||
int tpid = 0;//踏勘点序号
|
||
foreach (XmlElement element in xmlmark)
|
||
{
|
||
Placemark mark = new Placemark();
|
||
mark.points = new List<double>();
|
||
tpid = tpid + 1;
|
||
string note = "";
|
||
var nameNode = element.GetElementsByTagName("name");
|
||
if (nameNode != null && nameNode.Count > 0)
|
||
{
|
||
string nmNode = nameNode[0].InnerText;
|
||
note = nmNode.Trim();
|
||
}
|
||
mark.name = note;
|
||
XmlElement cNode = null;
|
||
var pointNode = element.GetElementsByTagName("Point");
|
||
var lineString = element.GetElementsByTagName("LineString");
|
||
var linearRing = element.GetElementsByTagName("LinearRing");
|
||
if (pointNode != null && pointNode.Count > 0)
|
||
{
|
||
mark.typeStr = "point";
|
||
cNode = (XmlElement)pointNode[0];
|
||
}
|
||
else if (lineString != null && lineString.Count > 0)
|
||
{
|
||
|
||
mark.typeStr = "line";
|
||
cNode = (XmlElement)lineString[0];
|
||
|
||
}
|
||
else if (linearRing != null && linearRing.Count > 0)
|
||
{
|
||
mark.typeStr = "ring";
|
||
cNode = (XmlElement)linearRing[0];
|
||
}
|
||
else
|
||
{
|
||
continue;
|
||
}
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText;
|
||
var points = pointstr.Split(new char[] { '\n', ' ' });
|
||
var pointsCount = points.Length;
|
||
int pIndex = -1;
|
||
foreach (var item in points)
|
||
{
|
||
pIndex++;
|
||
var pointStr = item.Trim();
|
||
if (string.IsNullOrEmpty(pointStr))
|
||
{
|
||
continue;
|
||
}
|
||
var point = pointStr.Split(',');
|
||
if (point.Length < 3)
|
||
{
|
||
continue;
|
||
}
|
||
double X = Convert.ToDouble(point[0].Trim());
|
||
double Y = Convert.ToDouble(point[1].Trim());
|
||
double Z = Convert.ToDouble(point[2].Trim());
|
||
if (mark.typeStr == "line")
|
||
{
|
||
Z += 100;
|
||
}
|
||
mark.points.Add(X);
|
||
mark.points.Add(Y);
|
||
mark.points.Add(Z);
|
||
}
|
||
}
|
||
//线必须大于两个点
|
||
if (mark.points.Count < 6 && (mark.points.Count % 3) != 0 && mark.typeStr == "line")
|
||
{
|
||
continue;
|
||
}
|
||
if (mark.points.Count > 0)
|
||
{
|
||
retMarks.Add(mark);
|
||
}
|
||
}
|
||
}
|
||
return retMarks;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取kml对象
|
||
/// </summary>
|
||
/// <param name="kmlPath"></param>
|
||
/// <returns></returns>
|
||
public static List<Placemark> readzKml(string kmlPath)
|
||
{
|
||
List<string> list = new List<string>();
|
||
List<Placemark> retMarks = new List<Placemark>();
|
||
if (!File.Exists(kmlPath))
|
||
{
|
||
return new List<Placemark>();
|
||
}
|
||
if (Path.GetExtension(kmlPath).ToLower() == ".kmz")
|
||
{
|
||
list = UnZip(kmlPath, Path.GetDirectoryName(kmlPath));
|
||
}
|
||
else
|
||
{
|
||
list.Add(kmlPath);
|
||
}
|
||
foreach (var path in list)
|
||
{
|
||
XmlDocument xmldoc = new XmlDocument();
|
||
xmldoc.Load(path);
|
||
//申明xml命名空间管理对象
|
||
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmldoc.NameTable);
|
||
XmlElement root = xmldoc.DocumentElement;
|
||
//添加命名空间
|
||
nsmanager.AddNamespace("XX", "" + root.NamespaceURI + "");
|
||
/////规范命名空间
|
||
XmlNode t = root.GetElementsByTagName("Kml")[0];
|
||
XmlNode _document = root.GetElementsByTagName("Document")[0];
|
||
XmlNodeList xmlmark = xmldoc.SelectNodes("//XX:Placemark", nsmanager);
|
||
foreach (XmlElement element in xmlmark)
|
||
{
|
||
Placemark mark = new Placemark();
|
||
mark.coordinates = new List<Coordinates>();
|
||
string note = "";
|
||
var nameNode = element.GetElementsByTagName("name");
|
||
if (nameNode != null && nameNode.Count > 0)
|
||
{
|
||
string nmNode = nameNode[0].InnerText;
|
||
note = nmNode.Trim();
|
||
}
|
||
mark.name = note;
|
||
string IconStyleColor = "";
|
||
string LabelStyleColor = "";
|
||
string LineStyleColor = "";
|
||
string LineStyleWidth = "";
|
||
var styleNode = element.GetElementsByTagName("Style");
|
||
if (styleNode != null && styleNode.Count > 0)
|
||
{
|
||
XmlElement tempStyleNode = (XmlElement)styleNode[0];
|
||
//图标样式
|
||
var iconStyle = tempStyleNode.GetElementsByTagName("IconStyle");
|
||
if (iconStyle != null && iconStyle.Count > 0)
|
||
{
|
||
XmlElement iconStyleNode = (XmlElement)iconStyle[0];
|
||
var color = iconStyleNode.GetElementsByTagName("color");
|
||
IconStyleColor = color[0].InnerText.Trim();
|
||
}
|
||
//标签样式
|
||
var labelStyle = tempStyleNode.GetElementsByTagName("LabelStyle");
|
||
if (iconStyle != null && iconStyle.Count > 0)
|
||
{
|
||
XmlElement labelStyleNode = (XmlElement)labelStyle[0];
|
||
var color = labelStyleNode.GetElementsByTagName("color");
|
||
LabelStyleColor = color[0].InnerText.Trim();
|
||
}
|
||
//线样式
|
||
var lineStyle = tempStyleNode.GetElementsByTagName("LineStyle");
|
||
if (lineStyle != null && lineStyle.Count > 0)
|
||
{
|
||
XmlElement lineStyleNode = (XmlElement)lineStyle[0];
|
||
var lineStyleColor = lineStyleNode.GetElementsByTagName("color");
|
||
LineStyleColor = lineStyleColor[0].InnerText.Trim();
|
||
var width = lineStyleNode.GetElementsByTagName("width");
|
||
LineStyleWidth = width[0].InnerText.Trim();
|
||
}
|
||
}
|
||
XmlElement cNode = null;
|
||
var pointNode = element.GetElementsByTagName("Point");
|
||
var lineString = element.GetElementsByTagName("LineString");
|
||
var linearRing = element.GetElementsByTagName("LinearRing");
|
||
if (pointNode != null && pointNode.Count > 0)
|
||
{
|
||
mark.typeStr = "point";
|
||
foreach (var p in pointNode)
|
||
{
|
||
cNode = (XmlElement)p;
|
||
//点的样式
|
||
mark.style = new { IconStyleColor, LabelStyleColor };
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText;
|
||
var points = pointstr.Split(new char[] { '\n', ' ' });
|
||
var pointsCount = points.Length;
|
||
foreach (var item in points)
|
||
{
|
||
var coordinates = new Coordinates();
|
||
var pointStr = item.Trim();
|
||
if (string.IsNullOrEmpty(pointStr))
|
||
{
|
||
continue;
|
||
}
|
||
var point = pointStr.Split(',');
|
||
double X = Convert.ToDouble(point[0].Trim());
|
||
double Y = Convert.ToDouble(point[1].Trim());
|
||
coordinates.X = X;
|
||
coordinates.Y = Y;
|
||
coordinates.Z = 0;
|
||
mark.coordinates.Add(coordinates);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (lineString != null && lineString.Count > 0)
|
||
{
|
||
mark.typeStr = "line";
|
||
foreach (var p in lineString)
|
||
{
|
||
cNode = (XmlElement)p;
|
||
//线的样式
|
||
mark.style = new { LineStyleColor, LineStyleWidth };
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText;
|
||
var points = pointstr.Split(new char[] { '\n', ' ' });
|
||
var pointsCount = points.Length;
|
||
foreach (var item in points)
|
||
{
|
||
var coordinates = new Coordinates();
|
||
var pointStr = item.Trim();
|
||
if (string.IsNullOrEmpty(pointStr))
|
||
{
|
||
continue;
|
||
}
|
||
var point = pointStr.Split(',');
|
||
double X = Convert.ToDouble(point[0].Trim());
|
||
double Y = Convert.ToDouble(point[1].Trim());
|
||
coordinates.X = X;
|
||
coordinates.Y = Y;
|
||
coordinates.Z = 0;
|
||
mark.coordinates.Add(coordinates);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
if (linearRing != null && linearRing.Count > 0)
|
||
{
|
||
mark.typeStr = "ring";
|
||
foreach (var p in linearRing)
|
||
{
|
||
cNode = (XmlElement)p;
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText;
|
||
var points = pointstr.Split(new char[] { '\n', ' ' });
|
||
var pointsCount = points.Length;
|
||
foreach (var item in points)
|
||
{
|
||
var coordinates = new Coordinates();
|
||
var pointStr = item.Trim();
|
||
if (string.IsNullOrEmpty(pointStr))
|
||
{
|
||
continue;
|
||
}
|
||
var point = pointStr.Split(',');
|
||
|
||
double X = Convert.ToDouble(point[0].Trim());
|
||
double Y = Convert.ToDouble(point[1].Trim());
|
||
coordinates.X = X;
|
||
coordinates.Y = Y;
|
||
coordinates.Z = 0;
|
||
mark.coordinates.Add(coordinates);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
retMarks.Add(mark);
|
||
}
|
||
}
|
||
return retMarks;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取KML桩号坐标集合
|
||
/// </summary>
|
||
/// <param name="filePath">路径</param>
|
||
/// <returns></returns>
|
||
public static List<Placemark> GetStakeCoordinate(string filePath)
|
||
{
|
||
List<string> list = new List<string>();
|
||
List<Placemark> retMarks = new List<Placemark>();
|
||
if (!File.Exists(filePath))
|
||
{
|
||
return new List<Placemark>();
|
||
}
|
||
if (Path.GetExtension(filePath).ToLower() == ".kmz")
|
||
{
|
||
list = UnZip(filePath, Path.GetDirectoryName(filePath));
|
||
}
|
||
else
|
||
{
|
||
list.Add(filePath);
|
||
}
|
||
foreach (var path in list)
|
||
{
|
||
XmlDocument xmldoc = new XmlDocument();
|
||
xmldoc.Load(path);
|
||
//申明xml命名空间管理对象
|
||
XmlNamespaceManager nsmanager = new XmlNamespaceManager(xmldoc.NameTable);
|
||
XmlElement root = xmldoc.DocumentElement;
|
||
//添加命名空间
|
||
nsmanager.AddNamespace("XX", "" + root.NamespaceURI + "");
|
||
/////规范命名空间
|
||
XmlNode t = root.GetElementsByTagName("Kml")[0];
|
||
XmlNode _document = root.GetElementsByTagName("Document")[0];
|
||
XmlNodeList xmlmark = xmldoc.SelectNodes("//XX:Placemark", nsmanager);
|
||
//var isselect = false;
|
||
foreach (XmlElement element in xmlmark)
|
||
{
|
||
Placemark mark = new Placemark();
|
||
mark.points = new List<double>();
|
||
string note = string.Empty;
|
||
var nameNode = element.GetElementsByTagName("name");
|
||
if (nameNode != null && nameNode.Count > 0)
|
||
{
|
||
//string nmNode = nameNode[0].InnerText.Trim();
|
||
//note = Regex.Replace(nmNode, "[ \\[ \\] \\^ \\-_*×――(^)|'$%~!@#$…&%¥—+=<>《》!!???::•`·、。,;,.;\"‘’“”-]", "").ToUpper();
|
||
note = nameNode[0].InnerText.Trim();
|
||
}
|
||
mark.name = note;
|
||
// if (name.Contains(mark.name) || isselect)
|
||
//{
|
||
//if (!isselect)
|
||
//{
|
||
// mark.name = name;
|
||
//}
|
||
XmlElement cNode = null;
|
||
var pointNode = element.GetElementsByTagName("Point");
|
||
if (pointNode != null && pointNode.Count > 0)
|
||
{
|
||
mark.typeStr = "point";
|
||
cNode = (XmlElement)pointNode[0];
|
||
}
|
||
if (cNode != null)
|
||
{
|
||
var coordinatesNode = cNode.GetElementsByTagName("coordinates");
|
||
if (coordinatesNode != null && coordinatesNode.Count > 0)
|
||
{
|
||
string pointstr = coordinatesNode[0].InnerText.Trim();
|
||
var points = pointstr.Split(',');
|
||
double X = Convert.ToDouble(points[0].Trim());
|
||
double Y = Convert.ToDouble(points[1].Trim());
|
||
mark.points.Add(X);
|
||
mark.points.Add(Y);
|
||
mark.points.Add(0);
|
||
retMarks.Add(mark);
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|
||
return retMarks;
|
||
}
|
||
|
||
}
|
||
} |