using ICSharpCode.SharpZipLib.Zip; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Xml; namespace Learun.Application.Web.Common { /// /// KML实体 /// public class Placemark { public string name { get; set; } public string typeStr { get; set; } public List points { get; set; } public object style { get; set; } public List coordinates { get; set; } } /// /// 坐标 /// public class Coordinates { public double X { get; set; } public double Y { get; set; } public double Z { get; set; } } public class KmlUtility { /// /// 解压缩文件(压缩文件中含有子目录) /// /// 待解压缩的文件路径 /// 解压缩到指定目录 /// 解压后的文件列表 public static List UnZip(string zipfilepath, string unzippath) { if (!File.Exists(zipfilepath)) { return new List(); } //解压出来的文件列表 List unzipFiles = new List(); //检查输出目录是否以“\\”结尾 List kmlfile = new List(); 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; } /// /// 获取kml对象 /// /// /// public static List readKml(string kmlPath, bool isAPP = false) { List list = new List(); List retMarks = new List(); if (!File.Exists(kmlPath)) { return new List(); } 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(); 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; } /// /// 获取kml对象 /// /// /// public static List readzKml(string kmlPath, bool isAPP = false) { List list = new List(); List retMarks = new List(); if (!File.Exists(kmlPath)) { return new List(); } 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(); 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; } /// /// 获取kml对象 /// /// /// public static List readzKml(string kmlPath) { List list = new List(); List retMarks = new List(); if (!File.Exists(kmlPath)) { return new List(); } 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(); 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; } /// /// 获取KML桩号坐标集合 /// /// 路径 /// public static List GetStakeCoordinate(string filePath) { List list = new List(); List retMarks = new List(); if (!File.Exists(filePath)) { return new List(); } 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(); 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; } } }