This commit is contained in:
2023-04-28 12:21:24 +08:00
parent 156d145a48
commit 88e0a25ecd
162 changed files with 26324 additions and 7519 deletions

View File

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