623 lines
27 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}