static private PointD GetClosePoint(PointD point, MultiPolyLine multiPolyline, double tolerance) { if (multiPolyline == null) { return(null); } RectangleD smbr = multiPolyline.MBR; RectangleD sRect = new RectangleD(smbr.MinX - tolerance, smbr.MaxX + tolerance, smbr.MinY - tolerance, smbr.MaxY + tolerance); if (!IsPointInRect(point, sRect)) { return(null); } foreach (PolyLine sPolyline in multiPolyline.PolyLines) { foreach (PointD sPoint in sPolyline.Points) { if (IsPointOnPoint(point, sPoint, tolerance)) { return(sPoint); } } } return(null); }
//读取线状目标数据 private static void ReadShpPolyline(BinaryReader br, ref Layer layer) { Int32 RecordNum; //记录号 Int32 ContentLength; //坐标记录长度 while (true) //逐个记录进行读取,直到文件末尾 { try { RecordNum = OnChangeByteOrder(br.ReadInt32()); } catch (EndOfStreamException) { break; } ContentLength = OnChangeByteOrder(br.ReadInt32()); Int32 ShapeType = br.ReadInt32(); //记录的几何类型,线状目标为3 if (ShapeType == 0) //null shape { layer.Records.Rows.Add(RecordNum, null, null); //将该记录添加到layer中 continue; } //读取外包矩形数据 Double MinX = br.ReadDouble(); Double MinY = br.ReadDouble(); Double MaxX = br.ReadDouble(); Double MaxY = br.ReadDouble(); RectangleD MBR = new RectangleD(MinX, MaxX, MinY, MaxY); Int32 NumParts = br.ReadInt32(); //构成当前线目标的子线段个数 Int32 NumPoints = br.ReadInt32(); //构成当前线目标的坐标点个数 Int32[] Parts = new Int32[NumParts + 1]; //记录每个子线段的点坐标信息在所有点坐标信息中的起始位置,为计算方便在末尾加入坐标点总个数 for (int i = 0; i < NumParts; i++) { Parts[i] = br.ReadInt32(); } Parts[NumParts] = NumPoints; //读取所有点的坐标信息,记录在各个子线段中 List <PolyLine> mPolyLine = new List <PolyLine>(NumParts); for (int i = 0; i < NumParts; i++) //对各个子线段的点坐标进行读取 { int PointNum = Parts[i + 1] - Parts[i]; //当前子线段的点个数 PointD[] Points = new PointD[PointNum]; for (int j = 0; j < PointNum; j++) { Double x = br.ReadDouble(); //x坐标 Double y = br.ReadDouble(); //y坐标 Points[j] = new PointD(x, y); } mPolyLine.Add(new PolyLine(Points)); } MultiPolyLine mMultiPolyLine = new MultiPolyLine(mPolyLine, MBR); //生成读取的MultiPolyLine对象 layer.Records.Rows.Add(RecordNum, mMultiPolyLine, null); //将该记录添加到layer中 } }
static void ReadTest1Shp(string shpPath) { IFeatureSet fs = FeatureSet.Open(shpPath); Console.WriteLine("FeatureType:" + fs.FeatureType); Console.WriteLine(); var dataTable = fs.AttrTable; Console.WriteLine("属性表字段:"); foreach (DataColumn col in dataTable.Columns) { Console.Write(col.ColumnName + "\t"); } Console.WriteLine(); Console.WriteLine(new string('=', 50)); Console.WriteLine(); foreach (var fe in fs.Features) { Console.WriteLine(); Console.WriteLine("GeometryType:" + fe.GeometryType); if (fe.GeometryType == GeometryType.MultiPolyLine) { MultiPolyLine multiPolyLine = fe.Geometry.BasicGeometry as MultiPolyLine; if (multiPolyLine != null) { Console.WriteLine("PartsNum:" + multiPolyLine.PartsNum); } Console.WriteLine("起始点:"); if (multiPolyLine != null) { foreach (var line in multiPolyLine.PolyLines) { Console.WriteLine(line[0]); } } } Console.WriteLine("\r\n所有点信息:"); foreach (var point in fe.Geometry.Coordinates) { Console.Write($"{point.X},{point.Y}\t"); } Console.WriteLine("\r\n属性信息:"); var datarow = fe.DataRow.ItemArray; foreach (var o in datarow) { Console.Write(o + "\t"); } Console.WriteLine(); Console.WriteLine(new string('-', 20)); Console.WriteLine(); } }
MultiPolyLine lonLat2WebMercator(MultiPolyLine multiPolyline) { List <PolyLine> lines = new List <PolyLine>(); foreach (PolyLine polyline in multiPolyline.PolyLines) { lines.Add(new PolyLine(lonLat2WebMercator(polyline.Points))); } return(new MultiPolyLine(lines)); }
internal MultiPolyLine ToProjCo(MultiPolyLine geoMulline) { if (_ProjectedSystem == ProjectedSystem.WebMercator) { return(lonLat2WebMercator(geoMulline)); } else { return(geoMulline.Clone()); } }
internal MultiPolyLine ToLngLat(MultiPolyLine prjMulline) { if (_ProjectedSystem == ProjectedSystem.WebMercator) { return(WebMercator2lonLat(prjMulline)); } else { return(prjMulline.Clone()); } }
private static int GetCodeLength(MultiPolyLine multiPolyline) { int n = multiPolyline.Count; int length = 0; for (int i = 0; i < n; i++) { length += multiPolyline.PolyLines[i].Count * 8;//每个点坐标信息占8个长度 } return(22 + 2 * n + length); }
public static IGeometry CreatePolyLine(byte[] buffer) { if (buffer.Length >= 60) { var lines = GetMultiPolyLineParts(buffer); IBasicGeometry polygon = new MultiPolyLine(lines); IGeometry geometry = new Geometry(polygon); return(geometry); } else { throw new ArgumentException($"Byte数组大小无效,不能创建线要素。数组大小为{buffer.Length}"); } }
/// <summary> /// 判断点是否在MultiPolyline上(点选是否选中线) /// </summary> /// <param name="point"></param> /// <param name="multiPolyline"></param> /// <param name="tolerance"></param> /// <returns></returns> static public bool IsPointOnMulPolyline(PointD point, MultiPolyLine multiPolyline, double tolerance) { //先将点与外包矩形对比 if (IsPointInRect(point, multiPolyline.MBR) == false) { return(false); } foreach (PolyLine sLine in multiPolyline.PolyLines) { if (IsPointOnPolyline(point, sLine, tolerance)) { return(true); } } return(false); }
/// <summary> /// 判断线是否位于矩形盒内(框选是否选中线) /// </summary> /// <param name="multiPolyline"></param> /// <param name="rect"></param> /// <returns></returns> static public bool IsRectInterMultiPolyline(MultiPolyLine multiPolyline, RectangleD rect) { //先对外包矩形判断 if (IsMBRInterRect(multiPolyline.MBR, rect) == false) { return(false); } foreach (PolyLine line in multiPolyline.PolyLines) { if (IsRectInterPolyline(line, rect)) { return(true); } } return(false); }
//保存线状目标数据 private static void SavePolyline(BinaryWriter bw, ref Layer layer) { int RecordNum = layer.Records.Rows.Count; for (int i = 0; i < RecordNum; i++) { bw.Write(OnChangeByteOrder(i + 1)); //ID if (Convert.IsDBNull(layer.Records.Rows[i][1])) //null shape { bw.Write(OnChangeByteOrder(2)); bw.Write(0);//几何类型 continue; } MultiPolyLine mMultiPolyLine = (MultiPolyLine)layer.Records.Rows[i][1]; bw.Write(OnChangeByteOrder(GetCodeLength(mMultiPolyLine))); //坐标记录长度 bw.Write(3); //写入几何类型 //MBR数据 bw.Write(mMultiPolyLine.MBR.MinX); bw.Write(mMultiPolyLine.MBR.MinY); bw.Write(mMultiPolyLine.MBR.MaxX); bw.Write(mMultiPolyLine.MBR.MaxY); Int32 NumParts = mMultiPolyLine.Count; bw.Write(NumParts); //子线段个数 Int32 NumPoints = (GetCodeLength(mMultiPolyLine) - 22 - 2 * NumParts) / 8; bw.Write(NumPoints); //点个数 Int32 parts = 0; bw.Write(parts); //每个子线段的点坐标信息在所有点坐标信息中的起始位置,第一个为0 for (int j = 0; j < NumParts - 1; j++) { parts += mMultiPolyLine.PolyLines[j].Count; bw.Write(parts); } //点坐标信息 for (int j = 0; j < NumParts; j++) { for (int k = 0; k < mMultiPolyLine.PolyLines[j].Count; k++) { bw.Write(mMultiPolyLine.PolyLines[j].Points[k].X); bw.Write(mMultiPolyLine.PolyLines[j].Points[k].Y); } } } }
public static RectangleD GetLayerGeoMBR(Layer layer) { RectangleD sRec = RectangleD.EmptyMBR; if (layer.GeoType == typeof(MultiPolygon)) { for (int i = 0; i < layer.GeoCount; ++i) { MultiPolygon mu = layer.Records.Rows[i].Field <MultiPolygon>(2); if (mu != null) { sRec += mu.MBR; } } } if (layer.GeoType == typeof(MultiPolyLine)) { for (int i = 0; i < layer.GeoCount; ++i) { MultiPolyLine mu = layer.Records.Rows[i].Field <MultiPolyLine>(2); if (mu != null) { sRec += mu.MBR; } } } if (layer.GeoType == typeof(PointD)) { for (int i = 0; i < layer.GeoCount; ++i) { PointD mu = layer.Records.Rows[i].Field <PointD>(2); sRec = new RectangleD(Math.Min(sRec.MinX, mu.X), Math.Max(sRec.MaxX, mu.X) , Math.Min(sRec.MinY, mu.Y), Math.Max(sRec.MaxY, mu.Y)); } } if (sRec.Width < 0 || sRec.Height < 0) { sRec = new RectangleD(); } return(sRec); }
TcsGeometry(this MultiLineString multiLineString) { var lines = new List <CoreSpatial.BasicGeometrys.PolyLine>(); foreach (var lineGeom in multiLineString) { var lineNum = lineGeom.NumGeometries; for (int i = 0; i < lineNum; i++) { var line = lineGeom.GetGeometryN(i).Coordinates .Select(TcsGeometry).ToList(); var polyLine = new PolyLine(line); lines.Add(polyLine); } } MultiPolyLine res = new MultiPolyLine(lines); return(res); }
/// <summary> /// 获取整个地图的最小外包矩形 /// </summary> /// <param name="layer"></param> /// <returns></returns> private RectangleD RectMain(Layer layer) { RectangleD sRec = new RectangleD(); if (layer.GeoType == typeof(MultiPolygon)) { for (int i = 0; i < layer.GeoCount; ++i) { MultiPolygon mu = layer.Records.Rows[i].Field <MultiPolygon>(2); if (mu != null) { sRec += mu.MBR; } } } if (layer.GeoType == typeof(MultiPolyLine)) { for (int i = 0; i < layer.GeoCount; ++i) { MultiPolyLine mu = layer.Records.Rows[i].Field <MultiPolyLine>(2); if (mu != null) { sRec += mu.MBR; } } } if (layer.GeoType == typeof(PointD)) { for (int i = 0; i < layer.GeoCount; ++i) { PointD mu = layer.Records.Rows[i].Field <PointD>(2); sRec = new RectangleD(Math.Min(sRec.MinX, mu.X), Math.Max(sRec.MaxX, mu.X) , Math.Min(sRec.MinY, mu.Y), Math.Max(sRec.MaxY, mu.Y)); } } return(sRec); }
/// <summary> /// 辅助添加操作函数(分123级添加) /// </summary> /// <param name="layer"></param> /// <param name="dataRow"></param> /// <param name="Div"></param> private void AddRecord123(DataRow dataRow, int Div) { double sWidth = mMBR.Width / Div; double sHeight = mMBR.Height / Div; for (int i = 0; i < Div; i++) { double sWidthCount = mMBR.MinX + i * sWidth; for (int j = 0; j < Div; j++) { double sHeightCount = mMBR.MinY + j * sHeight; if (mLayer.GeoType == typeof(MultiPolygon)) { MultiPolygon mu = dataRow.Field <MultiPolygon>(2); if (mu.MBR.MinX > (sWidthCount + sWidth) || mu.MBR.MaxX < sWidthCount || mu.MBR.MinY > (sHeightCount + sHeight) || mu.MBR.MaxY < sHeightCount) { } else { if (Div == 2) { sets1[i][j].Add(dataRow); } if (Div == 4) { sets2[i][j].Add(dataRow); } if (Div == 8) { sets3[i][j].Add(dataRow); } } } if (mLayer.GeoType == typeof(MultiPolyLine)) { { MultiPolyLine mu = dataRow.Field <MultiPolyLine>(2); if (mu.MBR.MinX > (sWidthCount + sWidth) || mu.MBR.MaxX < sWidthCount || mu.MBR.MinY > (sHeightCount + sHeight) || mu.MBR.MaxY < sHeightCount) { } else { if (Div == 2) { sets1[i][j].Add(dataRow); } if (Div == 4) { sets2[i][j].Add(dataRow); } if (Div == 8) { sets3[i][j].Add(dataRow); } } } } if (mLayer.GeoType == typeof(PointD)) { { PointD mu = dataRow.Field <PointD>(2); if (mu.X > (sWidthCount + sWidth) || mu.X < sWidthCount || mu.Y > (sHeightCount + sHeight) || mu.Y < sHeightCount) { } else { if (Div == 2) { sets1[i][j].Add(dataRow); } if (Div == 4) { sets2[i][j].Add(dataRow); } if (Div == 8) { sets3[i][j].Add(dataRow); } } } } } } }
/// <summary> /// 初始化索引函数(分123级分割方式) /// </summary> /// <param name="layer">图层编号</param> /// <param name="Div">分割数</param> private HashSet <DataRow>[][] GeoIndexf(int Div) { HashSet <DataRow>[][] sSet; if (Div == 2) { sSet = sets1; } else if (Div == 4) { sSet = sets2; } else { sSet = sets3; } for (int k = 0; k < Div; k++) { sSet[k] = new HashSet <DataRow> [Div]; for (int s = 0; s < Div; s++) { sSet[k][s] = new HashSet <DataRow>(); } } double sWidth = mMBR.Width / Div; double sHeight = mMBR.Height / Div; for (int i = 0; i < Div; i++) { double sWidthCount = mMBR.MinX + i * sWidth; for (int j = 0; j < Div; j++) { double sHeightCount = mMBR.MinY + j * sHeight; if (mLayer.GeoType == typeof(MultiPolygon)) { for (int k = 0; k < mLayer.GeoCount; ++k) { MultiPolygon mu = mLayer.Records.Rows[k].Field <MultiPolygon>(2); if (mu != null) { if (mu.MBR.MinX > (sWidthCount + sWidth) || mu.MBR.MaxX < sWidthCount || mu.MBR.MinY > (sHeightCount + sHeight) || mu.MBR.MaxY < sHeightCount) { } else { sSet[i][j].Add(mLayer.Records.Rows[k]); } } } } if (mLayer.GeoType == typeof(MultiPolyLine)) { for (int k = 0; k < mLayer.GeoCount; ++k) { MultiPolyLine mu = mLayer.Records.Rows[k].Field <MultiPolyLine>(2); if (mu.MBR.MinX > (sWidthCount + sWidth) || mu.MBR.MaxX < sWidthCount || mu.MBR.MinY > (sHeightCount + sHeight) || mu.MBR.MaxY < sHeightCount) { } else { sSet[i][j].Add(mLayer.Records.Rows[k]); } } } if (mLayer.GeoType == typeof(PointD)) { for (int k = 0; k < mLayer.GeoCount; ++k) { PointD mu = mLayer.Records.Rows[k].Field <PointD>(2); if (mu.X > (sWidthCount + sWidth) || mu.X < sWidthCount || mu.Y > (sHeightCount + sHeight) || mu.Y < sHeightCount) { } else { sSet[i][j].Add(mLayer.Records.Rows[k]); } } } } } return(sSet); }
public static void CreateNew() { void CreatePoint() { IFeatureSet fs = new FeatureSet(FeatureType.Point); var point1 = new GeoPoint(133, 30); var point2 = new GeoPoint(133, 32); var point3 = new GeoPoint(134, 30); var feature1 = new Feature(new Geometry(point1)); var feature2 = new Feature(new Geometry(point2)); var feature3 = new Feature(new Geometry(point3)); fs.Features.Add(feature1); fs.Features.Add(feature2); fs.Features.Add(feature3); fs.Crs = Crs.Wgs84Gcs; var dataTable = new DataTable(); dataTable.Columns.Add("名称", typeof(string)); dataTable.Columns.Add("id", typeof(int)); var row1 = dataTable.NewRow(); var row2 = dataTable.NewRow(); var row3 = dataTable.NewRow(); row1[0] = "点1"; row1[1] = 1; row2[0] = "点2"; row2[1] = 2; row3[0] = "点3"; row3[1] = 3; dataTable.Rows.Add(row1); dataTable.Rows.Add(row2); dataTable.Rows.Add(row3); fs.AttrTable = dataTable; fs.Save("../createNew/point.shp"); } void CreateMultiPoint() { IFeatureSet fs = new FeatureSet(FeatureType.MultiPoint); var point1 = new GeoPoint(133, 30); var point2 = new GeoPoint(133, 32); var point3 = new GeoPoint(134, 30); var point4 = new GeoPoint(134, 34); var point5 = new GeoPoint(135, 35); var multiPoint1 = new MultiPoint(new List <GeoPoint>() { point1, point2, point3 }); var multiPoint2 = new MultiPoint(); multiPoint2.Points.Add(point4); multiPoint2.Points.Add(point5); var feature1 = new Feature(new Geometry(multiPoint1)); var feature2 = new Feature(new Geometry(multiPoint2)); fs.Features.Add(feature1); fs.Features.Add(feature2); fs.Crs = Crs.Wgs84Gcs; var dataTable = new DataTable(); dataTable.Columns.Add("名称", typeof(string)); dataTable.Columns.Add("id", typeof(int)); var row1 = dataTable.NewRow(); var row2 = dataTable.NewRow(); row1[0] = "多点1"; row1[1] = 1; row2[0] = "多点2"; row2[1] = 2; dataTable.Rows.Add(row1); dataTable.Rows.Add(row2); fs.AttrTable = dataTable; fs.Save("../createNew/multipoint.shp"); } void CreatePolyLine() { IFeatureSet fs = new FeatureSet(FeatureType.PolyLine); var point1 = new GeoPoint(133, 30); var point2 = new GeoPoint(133, 32); var point3 = new GeoPoint(134, 30); var point4 = new GeoPoint(134, 34); var point5 = new GeoPoint(135, 35); //line ring var polyLine1 = new PolyLine(new List <GeoPoint>() { point1, point2, point3, point1 }); var isLineRing = polyLine1.IsLineRing; var polyLine2 = new PolyLine(new List <GeoPoint>() { point4, point5 }); var feature1 = new Feature(new Geometry(polyLine1)); var feature2 = new Feature(new Geometry(polyLine2)); fs.Features.Add(feature1); fs.Features.Add(feature2); fs.Crs = Crs.Wgs84Gcs; var dataTable = new DataTable(); dataTable.Columns.Add("名称", typeof(string)); dataTable.Columns.Add("id", typeof(int)); var row1 = dataTable.NewRow(); var row2 = dataTable.NewRow(); row1[0] = "线1"; row1[1] = 1; row2[0] = "线2"; row2[1] = 2; dataTable.Rows.Add(row1); dataTable.Rows.Add(row2); fs.AttrTable = dataTable; fs.Save("../createNew/polyline.shp"); } void CreateMultiPolyLine() { IFeatureSet fs = new FeatureSet(FeatureType.PolyLine); var point1 = new GeoPoint(132, 30); var point2 = new GeoPoint(136, 30); var point3 = new GeoPoint(134, 28); var point4 = new GeoPoint(134, 32); var polyLine1 = new PolyLine(new List <GeoPoint>() { point1, point2 }); var polyLine2 = new PolyLine(new List <GeoPoint>() { point3, point4 }); var multiPolyLine1 = new MultiPolyLine(new List <PolyLine>() { polyLine1, polyLine2 }); var feature1 = new Feature(new Geometry(multiPolyLine1)); fs.Features.Add(feature1); fs.Crs = Crs.Wgs84Gcs; var dataTable = new DataTable(); dataTable.Columns.Add("名称", typeof(string)); dataTable.Columns.Add("id", typeof(int)); var row1 = dataTable.NewRow(); row1[0] = "十字多线"; row1[1] = 1; dataTable.Rows.Add(row1); fs.AttrTable = dataTable; fs.Save("../createNew/multiPolyLine.shp"); } void CreatePolygon() { IFeatureSet fs = new FeatureSet(FeatureType.Polygon); var point1 = new GeoPoint(132, 30); var point2 = new GeoPoint(136, 30); var point3 = new GeoPoint(132, 35); var edge = new PolyLine(new List <GeoPoint>() { point1, point2, point3, point1 }); var polygon = new Polygon(edge); //edge,Clockwise var point4 = new GeoPoint(140, 30); var point5 = new GeoPoint(140, 35); var point6 = new GeoPoint(150, 35); var point7 = new GeoPoint(150, 30); var edge2 = new PolyLine(new List <GeoPoint>() { point4, point5, point6, point7, point4 }); //points sketch // .(point9) // // .(point8) .(point10) // var point8 = new GeoPoint(142, 31); var point9 = new GeoPoint(145, 33); var point10 = new GeoPoint(148, 31); //hole, need Counterclockwise, //if Counterclockwise, sequence should be: //point8, point10, point9 //It will be handled inside the library. //It will be a line ring inside the library too var hole = new PolyLine(new List <GeoPoint>() { point8, point9, point10 }); var polygon2 = new Polygon(edge2, hole); var feature1 = new Feature(new Geometry(polygon)); var feature2 = new Feature(new Geometry(polygon2)); fs.Features.Set(new List <IFeature>() { feature1, feature2 }); fs.Crs = Crs.Wgs84Gcs; var dataTable = new DataTable(); dataTable.Columns.Add("名称", typeof(string)); dataTable.Columns.Add("id", typeof(int)); var row1 = dataTable.NewRow(); var row2 = dataTable.NewRow(); row1[0] = "简单面"; row1[1] = 1; row2[0] = "带洞面"; row2[1] = 2; dataTable.Rows.Add(row1); dataTable.Rows.Add(row2); fs.AttrTable = dataTable; fs.Save("../createNew/polygon.shp"); } CreatePoint(); CreateMultiPoint(); CreatePolyLine(); CreateMultiPolyLine(); CreatePolygon(); }
static void ReadFromStream(string shpPath) { var shx = Path.ChangeExtension(shpPath, ".shx"); var dbf = Path.ChangeExtension(shpPath, ".dbf"); var shpStream = new FileStream(shpPath, FileMode.Open, FileAccess.Read, FileShare.Read); var shxStream = new FileStream(shx, FileMode.Open, FileAccess.Read, FileShare.Read); var dbfStream = new FileStream(dbf, FileMode.Open, FileAccess.Read, FileShare.Read); IFeatureSet fs = FeatureSet.Open(shpStream, shxStream, dbfStream); Console.WriteLine("FeatureType:" + fs.FeatureType); Console.WriteLine(); var dataTable = fs.AttrTable; Console.WriteLine("属性表字段:"); foreach (DataColumn col in dataTable.Columns) { Console.Write(col.ColumnName + "\t"); } Console.WriteLine(); Console.WriteLine(new string('=', 50)); Console.WriteLine(); foreach (var fe in fs.Features) { Console.WriteLine(); Console.WriteLine("GeometryType:" + fe.GeometryType); if (fe.GeometryType == GeometryType.MultiPolyLine) { MultiPolyLine multiPolyLine = fe.Geometry.BasicGeometry as MultiPolyLine; if (multiPolyLine != null) { Console.WriteLine("PartsNum:" + multiPolyLine.PartsNum); } Console.WriteLine("起始点:"); if (multiPolyLine != null) { foreach (var line in multiPolyLine.PolyLines) { Console.WriteLine(line[0]); } } } Console.WriteLine("\r\n所有点信息:"); foreach (var point in fe.Geometry.Coordinates) { Console.Write($"{point.X},{point.Y}\t"); } Console.WriteLine("\r\n属性信息:"); var datarow = fe.DataRow.ItemArray; foreach (var o in datarow) { Console.Write(o + "\t"); } Console.WriteLine(); Console.WriteLine(new string('-', 20)); Console.WriteLine(); } }
//将图层信息保存到shp文件中 public static void SaveShp(Layer layer, string fileName) { FileStream fs = new FileStream(fileName, FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); //写文件头 bw.Write(OnChangeByteOrder(9994)); for (int i = 0; i < 5; i++) { bw.Write(0); } Type GeoType = layer.GeoType; //获取图层记录的要素类型 Int32 TypeCode; //要素类型对应的编码 Int32 FileLength = 50; //文件长度,初值为头文件长度50 Int32 RecondNum = layer.Records.Rows.Count; //要素个数 //计算要素类型对应的编码和文件长度 if (GeoType == typeof(PointD)) { TypeCode = 1; for (int i = 0; i < RecondNum; i++) { if (Convert.IsDBNull(layer.Records.Rows[i][1])) { FileLength += 6; } else { FileLength += 14; } } } else if (GeoType == typeof(MultiPolyLine)) { TypeCode = 3; for (int i = 0; i < RecondNum; i++) { if (Convert.IsDBNull(layer.Records.Rows[i][1])) { FileLength += 6; } else { MultiPolyLine mMultiPolyLine = (MultiPolyLine)layer.Records.Rows[i][1]; FileLength += (4 + GetCodeLength(mMultiPolyLine)); } } } else if (GeoType == typeof(MultiPolygon)) { TypeCode = 5; for (int i = 0; i < RecondNum; i++) { if (Convert.IsDBNull(layer.Records.Rows[i][1])) { FileLength += 6; } else { MultiPolygon mMultiPolygon = (MultiPolygon)layer.Records.Rows[i][1]; FileLength += (4 + GetCodeLength(mMultiPolygon)); } } } else { throw new Exception("不支持的数据类型"); } bw.Write(OnChangeByteOrder(FileLength)); //写入文件长度 bw.Write(1000); //写入版本号 bw.Write(TypeCode); //写入几何类型 //写入MBR数据 bw.Write(layer.MBR.MinX); bw.Write(layer.MBR.MinY); bw.Write(layer.MBR.MaxX); bw.Write(layer.MBR.MaxY); //最大、最小Z值、M值为0 for (int i = 0; i < 4; i++) { bw.Write((double)0); } //写空间数据 switch (TypeCode) { case 1: //空间数据几何类型为点 SavePoint(bw, ref layer); break; case 3: //空间数据几何类型为线 SavePolyline(bw, ref layer); break; case 5: //空间数据几何类型为多边形 SavePolygon(bw, ref layer); break; default: throw new FileLoadException("不支持的数据类型"); } bw.Dispose(); fs.Dispose(); SaveDbf(ref layer, fileName); SaveShx(ref layer, fileName); }
//保存shx文件 private static void SaveShx(ref Layer layer, string fileName) { int sIndex = fileName.LastIndexOf("\\"); string sName = fileName.Substring(0, fileName.Length - 4) + ".shx"; FileStream fs = new FileStream(sName, FileMode.Create); BinaryWriter bw = new BinaryWriter(fs); //(1)写文件头 bw.Write(OnChangeByteOrder(9994)); for (int i = 0; i < 5; i++) { bw.Write(0); } Type GeoType = layer.GeoType; //获取图层记录的要素类型 Int32 RecondNum = layer.Records.Rows.Count; //要素个数 Int32 FileLength = 50 + RecondNum * 4; //文件长度 bw.Write(OnChangeByteOrder(FileLength)); //写入文件长度 bw.Write(1000); //写入版本号 //写入几何类型 if (GeoType == typeof(PointD)) { bw.Write(1); } else if (GeoType == typeof(MultiPolyLine)) { bw.Write(3); } else if (GeoType == typeof(MultiPolygon)) { bw.Write(5); } else { throw new Exception("不支持的数据类型"); } //写入MBR数据 bw.Write(layer.MBR.MinX); bw.Write(layer.MBR.MinY); bw.Write(layer.MBR.MaxX); bw.Write(layer.MBR.MaxY); //最大、最小Z值、M值为0 for (int i = 0; i < 4; i++) { bw.Write((double)0); } //(2)写实体信息部分 Int32 Offset = 50; //坐标文件中对应记录的起始位置相对文件起始位置的偏移量,第一条记录为50 Int32 ContentLength = 0; //坐标文件中对应记录的长度 for (int i = 0; i < RecondNum; i++) { bw.Write(OnChangeByteOrder(Offset)); //写入偏移量 //获取对应记录的长度 if (Convert.IsDBNull(layer.Records.Rows[i][1])) //null shape { ContentLength = 2; } else { if (GeoType == typeof(PointD)) { ContentLength = 10; } else if (GeoType == typeof(MultiPolyLine)) { MultiPolyLine mMultiPolyLine = (MultiPolyLine)layer.Records.Rows[i][1]; ContentLength = GetCodeLength(mMultiPolyLine); } else { MultiPolygon mMultiPolygon = (MultiPolygon)layer.Records.Rows[i][1]; ContentLength = GetCodeLength(mMultiPolygon); } } bw.Write(OnChangeByteOrder(ContentLength)); //写入记录长度 Offset += (ContentLength + 4); //更新偏移量 } bw.Dispose(); fs.Dispose(); }
//计算标注位置 public static PointD GetCenterPoint(Geometry geo) { if (geo.GetType() == typeof(PointD)) { return(((PointD)geo).Clone()); } else if (geo.GetType() == typeof(MultiPolyLine)) { MultiPolyLine mMultiPolyLine = (MultiPolyLine)geo; if (mMultiPolyLine.Count == 0) { return(null); } int MaxPolyLineIndex = 0; if (mMultiPolyLine.Count != 1) { for (int i = 1; i < mMultiPolyLine.Count; i++) { if (mMultiPolyLine.PolyLines[i].Count > mMultiPolyLine.PolyLines[MaxPolyLineIndex].Count) { MaxPolyLineIndex = i; } } } int n = mMultiPolyLine.PolyLines[MaxPolyLineIndex].Count; if (n == 0) { return(null); } return(mMultiPolyLine.PolyLines[MaxPolyLineIndex].Points[n / 2].Clone()); } else { MultiPolygon mMultiPolygon = (MultiPolygon)geo; if (mMultiPolygon.Count == 0) { return(null); } int MaxPolygonIndex = 0; if (mMultiPolygon.Count != 1) { for (int i = 1; i < mMultiPolygon.Count; i++) { if (mMultiPolygon.Polygons[i].Count > mMultiPolygon.Polygons[MaxPolygonIndex].Count) { MaxPolygonIndex = i; } } } Polygon mPolygon = mMultiPolygon.Polygons[MaxPolygonIndex]; if (mPolygon.Count == 0) { return(null); } RectangleD mMBR = mPolygon.MBR; PointD Center = new PointD(); PointD p1 = new PointD(mMBR.MinX, (mMBR.MaxY + mMBR.MinY) / 2); PointD p2 = new PointD(mMBR.MaxX, (mMBR.MaxY + mMBR.MinY) / 2); List <double> InsectX = new List <double>(); for (int i = 0; i < mPolygon.Count - 1; i++) { PointD sP1 = mPolygon.GetPoint(i); PointD sP2 = mPolygon.GetPoint(i + 1); if (IsRayInterLine(p1, sP1, sP2)) { InsectX.Add(mPolygon.Points[i].X); } } int MaxLengthIndex = 0; double MaxLength = 0; InsectX.Sort(); if (InsectX.Count < 2) { return(mPolygon.Points[0]); } else { MaxLength = InsectX[1] - InsectX[0]; for (int i = 1; i < InsectX.Count / 2; i++) { if (InsectX[2 * i + 1] - InsectX[2 * i] > MaxLength) { MaxLength = InsectX[2 * i + 1] - InsectX[2 * i]; MaxLengthIndex = i; } } } Center.X = (InsectX[2 * MaxLengthIndex] + InsectX[2 * MaxLengthIndex + 1]) / 2; Center.Y = (mMBR.MaxY + mMBR.MinY) / 2; return(Center); } }