sync
This commit is contained in:
		| @@ -3,13 +3,156 @@ using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Data; | ||||
| using System.IO; | ||||
| using System.IO.Compression; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Xml; | ||||
|  | ||||
| namespace IronIntel.Contractor.Shape | ||||
| { | ||||
|     public static class ShapeFileParser | ||||
|     { | ||||
|         /// <summary> | ||||
|         /// 解析.shp文件 | ||||
|         /// </summary> | ||||
|         /// <param name="fileName"></param> | ||||
|         public static void ParseFromShapeFile(string fileName, Shape shape) | ||||
|         { | ||||
|             using (FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||||
|             { | ||||
|                 ParseFromShapeFile(fileStream, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         ///  解析.shp文件 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">.shp文件数据</param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromShapeFile(byte[] buffer, Shape shape) | ||||
|         { | ||||
|             using (MemoryStream ms = new MemoryStream(buffer, false)) | ||||
|             { | ||||
|                 ParseFromShapeFile(ms, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 解析.shp文件 | ||||
|         /// </summary> | ||||
|         /// <param name="fs">装载.shp文件数据的流</param> | ||||
|         public static void ParseFromShapeFile(Stream fs, Shape shape) | ||||
|         { | ||||
|             fs.Seek(0, SeekOrigin.Begin); | ||||
|             using (BinaryReader binaryReader = new BinaryReader(fs)) | ||||
|             { | ||||
|                 binaryReader.ReadBytes(24); | ||||
|  | ||||
|                 int FileLength = binaryReader.ReadInt32();//<0代表数据长度未知 | ||||
|                 int FileBanben = binaryReader.ReadInt32(); | ||||
|                 int ShapeType = binaryReader.ReadInt32(); | ||||
|  | ||||
|                 double xmin = binaryReader.ReadDouble(); | ||||
|                 double ymax = -1 * binaryReader.ReadDouble(); | ||||
|                 double xmax = binaryReader.ReadDouble(); | ||||
|                 double ymin = -1 * binaryReader.ReadDouble(); | ||||
|                 double width = xmax - xmin; | ||||
|                 double height = ymax - ymin; | ||||
|  | ||||
|                 binaryReader.ReadBytes(32); | ||||
|  | ||||
|                 switch (ShapeType) | ||||
|                 { | ||||
|                     case 1://Point | ||||
|                     case 11://PointZ | ||||
|                     case 21://PointM | ||||
|                         MapPoints points = new MapPoints(); | ||||
|                         shape.Points.Add(points); | ||||
|                         ParsePoints(binaryReader, points); | ||||
|                         break; | ||||
|                     case 3://PolyLine | ||||
|                     case 13://PolyLineZ | ||||
|                     case 23://PolyLineM | ||||
|                         ParsePolylines(binaryReader, shape.Polylines); | ||||
|                         break; | ||||
|                     case 5://Polygon | ||||
|                     case 15://PolygonZ | ||||
|                     case 25://PolygonM | ||||
|                         ParsePolygons(binaryReader, shape.Polygons); | ||||
|                         break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从zip文件当中解析.shp | ||||
|         /// </summary> | ||||
|         /// <param name="stream">装载.zip文件内容的流</param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(Stream stream, Shape shape) | ||||
|         { | ||||
|             const string EXT = ".shp"; | ||||
|             //using (ZipInputStream s = new ZipInputStream(stream)) | ||||
|             //{ | ||||
|             //    ZipEntry zipentry = s.GetNextEntry(); | ||||
|             //    while (zipentry != null) | ||||
|             //    { | ||||
|             //        if (zipentry.IsDirectory) | ||||
|             //        { | ||||
|             //            zipentry = s.GetNextEntry(); | ||||
|             //            continue; | ||||
|             //        } | ||||
|             //        string ext = Path.GetExtension(zipentry.FileName); | ||||
|             //        if (string.Compare(ext, EXT, true) == 0) | ||||
|             //        { | ||||
|             //            Stream shpStream = new MemoryStream(); | ||||
|             //            int size = 0; | ||||
|             //            byte[] data = new byte[2048]; | ||||
|             //            while (true) | ||||
|             //            { | ||||
|             //                size = s.Read(data, 0, data.Length); | ||||
|             //                if (size > 0) | ||||
|             //                { | ||||
|             //                    shpStream.Write(data, 0, size); | ||||
|             //                } | ||||
|             //                else | ||||
|             //                { | ||||
|             //                    break; | ||||
|             //                } | ||||
|             //            } | ||||
|             //            ParseFromShapeFile(shpStream, shape); | ||||
|             //        } | ||||
|             //        zipentry = s.GetNextEntry(); | ||||
|             //    }//while | ||||
|             //} | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从.zip文件当中解析.shp | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">.zip文件数据</param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(byte[] buffer, Shape shape) | ||||
|         { | ||||
|             using (MemoryStream ms = new MemoryStream(buffer, false)) | ||||
|             { | ||||
|                 ParseFromZipFile(ms, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从.zip文件当中解析.shp | ||||
|         /// </summary> | ||||
|         /// <param name="filename"></param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(string filename, Shape shape) | ||||
|         { | ||||
|             using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||||
|             { | ||||
|                 ParseFromZipFile(fs, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static void ParsePoints(BinaryReader binaryReader, MapPoints points) | ||||
|         { | ||||
|             while (binaryReader.PeekChar() != -1) | ||||
| @@ -177,148 +320,189 @@ namespace IronIntel.Contractor.Shape | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 解析.shp文件 | ||||
|         /// </summary> | ||||
|         /// <param name="fileName"></param> | ||||
|         public static void ParseFromShapeFile(string fileName, Shape shape) | ||||
|         { | ||||
|             using (FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||||
|             { | ||||
|                 ParseFromShapeFile(fileStream, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|  | ||||
|  | ||||
|         #region kmz/kml | ||||
|  | ||||
|         /// <summary> | ||||
|         ///  解析.shp文件 | ||||
|         /// 从kmz文件当中解析.kml,再解析kml | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">.shp文件数据</param> | ||||
|         /// <param name="stream"></param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromShapeFile(byte[] buffer, Shape shape) | ||||
|         public static void ParseFromKMZFile(byte[] buffer, Shape shape) | ||||
|         { | ||||
|             using (MemoryStream ms = new MemoryStream(buffer, false)) | ||||
|             { | ||||
|                 ParseFromShapeFile(ms, shape); | ||||
|                 ParseFromKMZFile(ms, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 解析.shp文件 | ||||
|         /// 从kmz文件当中解析.kml,再解析kml | ||||
|         /// </summary> | ||||
|         /// <param name="fs">装载.shp文件数据的流</param> | ||||
|         public static void ParseFromShapeFile(Stream fs, Shape shape) | ||||
|         /// <param name="stream"></param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromKMZFile(Stream stream, Shape shape) | ||||
|         { | ||||
|             fs.Seek(0, SeekOrigin.Begin); | ||||
|             using (BinaryReader binaryReader = new BinaryReader(fs)) | ||||
|             const string EXT = ".kml"; | ||||
|             using (ZipArchive archive = new ZipArchive(stream)) | ||||
|             { | ||||
|                 binaryReader.ReadBytes(24); | ||||
|  | ||||
|                 int FileLength = binaryReader.ReadInt32();//<0代表数据长度未知 | ||||
|                 int FileBanben = binaryReader.ReadInt32(); | ||||
|                 int ShapeType = binaryReader.ReadInt32(); | ||||
|  | ||||
|                 double xmin = binaryReader.ReadDouble(); | ||||
|                 double ymax = -1 * binaryReader.ReadDouble(); | ||||
|                 double xmax = binaryReader.ReadDouble(); | ||||
|                 double ymin = -1 * binaryReader.ReadDouble(); | ||||
|                 double width = xmax - xmin; | ||||
|                 double height = ymax - ymin; | ||||
|  | ||||
|                 binaryReader.ReadBytes(32); | ||||
|  | ||||
|                 switch (ShapeType) | ||||
|                 foreach (var e in archive.Entries) | ||||
|                 { | ||||
|                     case 1://Point | ||||
|                     case 11://PointZ | ||||
|                     case 21://PointM | ||||
|                         MapPoints points = new MapPoints(); | ||||
|                         shape.Points.Add(points); | ||||
|                         ParsePoints(binaryReader, points); | ||||
|                         break; | ||||
|                     case 3://PolyLine | ||||
|                     case 13://PolyLineZ | ||||
|                     case 23://PolyLineM | ||||
|                         ParsePolylines(binaryReader, shape.Polylines); | ||||
|                         break; | ||||
|                     case 5://Polygon | ||||
|                     case 15://PolygonZ | ||||
|                     case 25://PolygonM | ||||
|                         ParsePolygons(binaryReader, shape.Polygons); | ||||
|                         break; | ||||
|                     string ext = Path.GetExtension(e.Name); | ||||
|                     if (string.Compare(ext, EXT, true) == 0) | ||||
|                     { | ||||
|                         using (StreamReader reader = new StreamReader(e.Open())) | ||||
|                         { | ||||
|                             using (MemoryStream fstream = new MemoryStream()) | ||||
|                             { | ||||
|                                 e.Open().CopyTo(fstream); | ||||
|                                 ParseFromKMLFile(fstream, shape); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从zip文件当中解析.shp | ||||
|         /// 解析.kml文件 | ||||
|         /// </summary> | ||||
|         /// <param name="stream">装载.zip文件内容的流</param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(Stream stream, Shape shape) | ||||
|         /// <param name="fileName"></param> | ||||
|         public static void ParseFromKMLFile(string fileName, Shape shape) | ||||
|         { | ||||
|             const string EXT = ".shp"; | ||||
|             //using (ZipInputStream s = new ZipInputStream(stream)) | ||||
|             //{ | ||||
|             //    ZipEntry zipentry = s.GetNextEntry(); | ||||
|             //    while (zipentry != null) | ||||
|             //    { | ||||
|             //        if (zipentry.IsDirectory) | ||||
|             //        { | ||||
|             //            zipentry = s.GetNextEntry(); | ||||
|             //            continue; | ||||
|             //        } | ||||
|             //        string ext = Path.GetExtension(zipentry.FileName); | ||||
|             //        if (string.Compare(ext, EXT, true) == 0) | ||||
|             //        { | ||||
|             //            Stream shpStream = new MemoryStream(); | ||||
|             //            int size = 0; | ||||
|             //            byte[] data = new byte[2048]; | ||||
|             //            while (true) | ||||
|             //            { | ||||
|             //                size = s.Read(data, 0, data.Length); | ||||
|             //                if (size > 0) | ||||
|             //                { | ||||
|             //                    shpStream.Write(data, 0, size); | ||||
|             //                } | ||||
|             //                else | ||||
|             //                { | ||||
|             //                    break; | ||||
|             //                } | ||||
|             //            } | ||||
|             //            ParseFromShapeFile(shpStream, shape); | ||||
|             //        } | ||||
|             //        zipentry = s.GetNextEntry(); | ||||
|             //    }//while | ||||
|             //} | ||||
|             using (FileStream fileStream = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||||
|             { | ||||
|                 ParseFromKMLFile(fileStream, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从.zip文件当中解析.shp | ||||
|         ///  解析.kml文件 | ||||
|         /// </summary> | ||||
|         /// <param name="buffer">.zip文件数据</param> | ||||
|         /// <param name="buffer">.kml文件数据</param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(byte[] buffer, Shape shape) | ||||
|         public static void ParseFromKMLFile(byte[] buffer, Shape shape) | ||||
|         { | ||||
|             using (MemoryStream ms = new MemoryStream(buffer, false)) | ||||
|             { | ||||
|                 ParseFromZipFile(ms, shape); | ||||
|                 ParseFromKMLFile(ms, shape); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         /// <summary> | ||||
|         /// 从.zip文件当中解析.shp | ||||
|         /// 解析.kml文件 | ||||
|         /// </summary> | ||||
|         /// <param name="filename"></param> | ||||
|         /// <param name="shape"></param> | ||||
|         public static void ParseFromZipFile(string filename, Shape shape) | ||||
|         /// <param name="fs">装载.kml文件数据的流</param> | ||||
|         public static void ParseFromKMLFile(Stream fs, Shape shape) | ||||
|         { | ||||
|             using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||||
|             //fs.Seek(0, SeekOrigin.Begin); | ||||
|             //StreamReader sr = new StreamReader(fs); | ||||
|             //string content = sr.ReadToEnd(); | ||||
|             fs.Seek(0, SeekOrigin.Begin); | ||||
|             XmlDocument xmldoc = new XmlDocument(); | ||||
|             xmldoc.Load(fs); | ||||
|             XmlElement root = xmldoc.DocumentElement; | ||||
|  | ||||
|             XmlNodeList pointNodes = root.GetElementsByTagName("Point"); | ||||
|             foreach (XmlElement pe in pointNodes) | ||||
|             { | ||||
|                 ParseFromZipFile(fs, shape); | ||||
|                 ParseKMLPoints(pe, shape.Points); | ||||
|             } | ||||
|  | ||||
|             XmlNodeList lineNodes = root.GetElementsByTagName("LineString"); | ||||
|             foreach (XmlElement le in lineNodes) | ||||
|             { | ||||
|                 ParseKMLLines(le, shape.Polylines); | ||||
|             } | ||||
|  | ||||
|             XmlNodeList polygonNodes = root.GetElementsByTagName("Polygon"); | ||||
|             foreach (XmlElement pe in polygonNodes) | ||||
|             { | ||||
|                 ParseKMLPolygons(pe, shape.Polygons); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|         private static void ParseKMLPoints(XmlElement node, List<MapPoints> ls) | ||||
|         { | ||||
|             if (node == null) return; | ||||
|             var coordinates = node["coordinates"]; | ||||
|             if (coordinates == null) return; | ||||
|  | ||||
|             MapPoints points = new MapPoints(); | ||||
|             ls.Add(points); | ||||
|  | ||||
|             string coordinatesstr = coordinates.InnerText.Trim(); | ||||
|             string[] temps = coordinatesstr.Split(',');//Longitude,Latitude,Z | ||||
|             MapPoint mp = new MapPoint(); | ||||
|             double d = 0; | ||||
|             if (double.TryParse(temps[0], out d)) | ||||
|                 mp.Longitude = d; | ||||
|             if (double.TryParse(temps[1], out d)) | ||||
|                 mp.Latitude = d; | ||||
|             points.Points.Add(mp); | ||||
|         } | ||||
|  | ||||
|         private static void ParseKMLLines(XmlElement node, List<Polyline> ls) | ||||
|         { | ||||
|             if (node == null) return; | ||||
|             var coordinates = node["coordinates"]; | ||||
|             if (coordinates == null) return; | ||||
|  | ||||
|             Polyline l = new Polyline(); | ||||
|             ls.Add(l); | ||||
|  | ||||
|             MapPoints line = new MapPoints(); | ||||
|             l.Parts.Add(line); | ||||
|  | ||||
|             string coordinatesstr = coordinates.InnerText.Trim(); | ||||
|             string[] cs = coordinatesstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             double d = 0; | ||||
|             foreach (string c in cs) | ||||
|             { | ||||
|                 string[] temps = c.Split(',');//Longitude,Latitude,Z | ||||
|                 MapPoint mp = new MapPoint(); | ||||
|                 if (double.TryParse(temps[0], out d)) | ||||
|                     mp.Longitude = d; | ||||
|                 if (double.TryParse(temps[1], out d)) | ||||
|                     mp.Latitude = d; | ||||
|                 line.Points.Add(mp); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         private static void ParseKMLPolygons(XmlElement node, List<Polygon> ls) | ||||
|         { | ||||
|             if (node == null) return; | ||||
|             var outer = node["outerBoundaryIs"]; | ||||
|             if (outer == null) return; | ||||
|             var linearRing = outer["LinearRing"]; | ||||
|             if (linearRing == null) return; | ||||
|             var coordinates = linearRing["coordinates"]; | ||||
|             if (coordinates == null) return; | ||||
|  | ||||
|             Polygon p = new Polygon(); | ||||
|             ls.Add(p); | ||||
|  | ||||
|             MapPoints ring = new MapPoints(); | ||||
|             p.Rings.Add(ring); | ||||
|  | ||||
|             string coordinatesstr = coordinates.InnerText.Trim(); | ||||
|             string[] cs = coordinatesstr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); | ||||
|             double d = 0; | ||||
|             foreach (string c in cs) | ||||
|             { | ||||
|                 string[] temps = c.Split(',');//Longitude,Latitude,Z | ||||
|                 MapPoint mp = new MapPoint(); | ||||
|                 if (double.TryParse(temps[0], out d)) | ||||
|                     mp.Longitude = d; | ||||
|                 if (double.TryParse(temps[1], out d)) | ||||
|                     mp.Latitude = d; | ||||
|                 ring.Points.Add(mp); | ||||
|             } | ||||
|         } | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user