private Geometry GetKml(TPolygon polygon) { if (polygon.Rings.Count == 0) { return(null); } var outher = polygon.GetOuterBoundary(); if (outher == null) { return(GetKml(polygon.AsCollection())); } var outherKml = new OuterBoundary { LinearRing = GetRingKml(outher) }; var kml = new Polygon { OuterBoundary = outherKml }; foreach (var ring in polygon.Rings) { if (ring == outher) { continue; } var inner = new InnerBoundary() { LinearRing = GetRingKml(ring) }; var _ = kml.InnerBoundary.Append(inner); } return(kml); }
[TestCategoryAttribute("Geometry"), TestMethod] //TestCategoryAttribute("RuleManager"), public void TestMTPolygonToShortWKT2D() { TLineString ls1 = new TLineString(new List <MyPoint>() { new MyPoint(0, 0), new MyPoint(1, 0), new MyPoint(1, 1), new MyPoint(0, 1) }); TLineString ls2 = new TLineString(new List <MyPoint>() { new MyPoint(0.25, 0.25), new MyPoint(0.75, 0.25), new MyPoint(0.75, 0.75), new MyPoint(0.25, 0.75) }); TPolygon poly = new TPolygon(new List <TLineString>() { ls1, ls2 }); string test1 = poly.ToShortWKT2D(); string test2 = poly.ToWKT2D(); string tp = poly.GetType().ToString(); Assert.IsTrue(true, "good"); }
/// <summary> /// 读取要素数据,存入数据到TProjInfo实例中 /// </summary> /// <param name="features"></param> /// <returns></returns> public static TProjInfo GetProjInfoFromFeatures(Feature[] features) { var txtInfo = new TProjInfo(); GetAttrDescriptPart(features, txtInfo); //获取“属性描述” for (int i = 0; i < features.Length; i++) //获取“地块坐标” { var feature = features[i]; var geometry = feature.GetGeometryRef(); if (geometry == null || geometry.IsEmpty()) { throw new Exception("几何图形为空!"); } TPolygon tPolygon = GetBlockInfoHeader(feature, i + 1); //地块头部属性信息 tPolygon.Rings.AddRange(GetRingInfo(geometry)); //地块各个环的点信息 if (tPolygon.AttributeValues[0] == "0") { tPolygon.AttributeValues[0] = tPolygon.Rings.Sum(v => v.XyPair.Count).ToString(); } txtInfo.Polygons.Add(tPolygon); } return(txtInfo); }
// вхождение точки в полигон public static bool PointInPolygon(TPoint point, TPolygon polygon, double EPS) { int count, up; count = 0; for (int i = 0; i < polygon.Dots.Length - 1; i++) { up = CRS(point, polygon.Dots[i], polygon.Dots[i + 1], EPS); if (up >= 0) { count += up; } else { break; } } ; up = CRS(point, polygon.Dots[polygon.Dots.Length - 1], polygon.Dots[0], EPS); if (up >= 0) { return(Convert.ToBoolean((count + up) & 1)); } else { return(false); } }
/// <summary> /// 获取地块信息(界址点数,地块面积,地块编号,地块名称,几何类型(点、线、面),图幅号,地块用途,地类编码) /// </summary> /// <param name="feature">地块要素</param> /// <param name="xh">地块序号</param> /// <returns></returns> private static TPolygon GetBlockInfoHeader(Feature feature, int xh) { var tPolygon = new TPolygon(); var polygon = feature.GetGeometryRef(); var blockFields = CfgRedlineTxt.BlockFields; var ptCount = polygon.GetPointCount().ToString(); var area = polygon.GetArea().ToString("0.00"); tPolygon.AttributeValues.AddRange(new[] { ptCount, area, xh.ToString(), "", "面", "", "", "" }); for (int j = 0; j < blockFields.Count; j++) { if (tPolygon.AttributeValues[j] == string.Empty) { var index = feature.GetFieldIndex(blockFields[j].FieldName); if (index > -1) { tPolygon.AttributeValues[j] = feature.GetFieldAsString(index); } } } return(tPolygon); }
// вхождение точки в треугольник public static bool PointInTriangle(TPoint point, TTriangle triangle, double EPS) { TPolygon poly = new TPolygon(3); poly.Dots[0].X = triangle.APoint.X; poly.Dots[0].Y = triangle.APoint.Y; poly.Dots[1].X = triangle.BPoint.X; poly.Dots[1].Y = triangle.BPoint.Y; poly.Dots[2].X = triangle.CPoint.X; poly.Dots[2].Y = triangle.CPoint.Y; return(PointInPolygon(point, poly, EPS)); }
public HalfEdge(Vertex V) { idx = num; num++; liftingForce = 0.0f; bindingForce = 70.0f; curvature = 0.0f; vert = V; pair = null; next = null; prev = null; face = null; connected = true; }
// попадание точки в линию public static bool PointInLine(TPoint point, TPolygon line, int deltaX, double zoom) { for (int i = 1; i < line.Dots.Length; i++) { double dx = (line.Dots[i].Y - line.Dots[i - 1].Y) / (line.Dots[i].X - line.Dots[i - 1].X); if (Math.Abs((point.X - line.Dots[i - 1].X) * dx - (point.Y - line.Dots[i - 1].Y)) < ((5 + deltaX) * zoom)) { return(true); } } ; return(false); }
public static bool PointInOtrezok(TPoint point, TPolygon line) { if (PointInLine(point, line)) { return ((((line.Dots[0].X <= point.X) && (line.Dots[1].X >= point.X)) || ((line.Dots[0].X >= point.X) && (line.Dots[1].X <= point.X))) && (((line.Dots[0].Y <= point.Y) && (line.Dots[1].Y >= point.Y)) || ((line.Dots[0].Y >= point.Y) && (line.Dots[1].Y <= point.Y)))); } ; return(false); }
private static AnalyticsObject GetRectangle() { AnalyticsObject aObject; TPolygon tPolygon; TColor tColor; aObject = new AnalyticsObject(); aObject.Name = "SuspectArea"; aObject.AlarmTrigger = true; aObject.Value = "A suspect item"; aObject.Confidence = 0.9; aObject.Description = "Object description"; tPolygon = new TPolygon(); aObject.Polygon = tPolygon; tColor = new TColor(); tColor.A = 255; tColor.R = 255; tColor.G = 255; tColor.B = 0; tPolygon.Color = tColor; PointList pointList = new PointList(); TPoint tPoint; tPoint = new TPoint(); tPoint.X = 0.3D; tPoint.Y = 0.3D; pointList.Add(tPoint); tPoint = new TPoint(); tPoint.X = 0.6D; tPoint.Y = 0.3D; pointList.Add(tPoint); tPoint = new TPoint(); tPoint.X = 0.6D; tPoint.Y = 0.6D; pointList.Add(tPoint); tPoint = new TPoint(); tPoint.X = 0.3D; tPoint.Y = 0.6D; pointList.Add(tPoint); tPoint = new TPoint(); tPoint.X = 0.3D; tPoint.Y = 0.3D; pointList.Add(tPoint); tPolygon.PointList = pointList; return(aObject); }
/// <summary> /// 读取txt坐标文件,存入数据到TProjInfo实例中 /// </summary> /// <param name="txtPath">txt文件路径</param> /// <param name="isAddProjZone">是否在Y坐标值上添加投影分带带号</param> /// <returns></returns> public static TProjInfo GetProjInfoFromTxt(string txtPath, bool isAddProjZone = false) { var txtInfo = new TProjInfo(); var lines = File.ReadAllLines(txtPath, FileEncode.GetEncoding(txtPath)); var txtFlag = ETxtContent.NoDefine; TPolygon polygon = null; for (int i = 0; i < lines.Length; i++) { try { var line = lines[i]; if (SetStrFlag(line, ref txtFlag)) { continue; } if (txtFlag == ETxtContent.Project) { txtInfo.AddProjectDict(line); } else if (txtFlag == ETxtContent.Property) { txtInfo.AddPropertyDict(line); } else if (txtFlag == ETxtContent.Coordinate) { string[] strArray = line.Split(','); if (line.Contains("@")) { polygon = new TPolygon(); polygon.AddAttribute(strArray); txtInfo.Polygons.Add(polygon); } else if (strArray.Length == 4) { var strY = isAddProjZone ? txtInfo.ProjZone + strArray[3] : strArray[3]; polygon.AddXY(Convert.ToInt32(strArray[1]), Convert.ToDouble(strArray[2]), Convert.ToDouble(strY)); } } } catch (Exception ex) { throw new Exception($"读取坐标文件第{i}行发生错误:{ex.Message}"); } } CheckRepairPolygon(txtInfo); return(txtInfo); }
public static double Area(TPolygon poly) { int highI = poly.Count - 1; if (highI < 2) { return(0); } double result = 0; for (int i = 0; i < highI; ++i) { result += (poly[i].X + poly[i + 1].X) * (poly[i].Y - poly[i + 1].Y); } result += (poly[highI].X + poly[0].X) * (poly[highI].Y - poly[0].Y); result = result / 2; return(result); }
// пересечение полигонов public static bool PolygonInPolygon(TPolygon pol1, TPolygon pol2) { for (int i = 0; i < pol1.Dots.Length; i++) { if (PointInPolygon(pol1.Dots[i], pol2)) { return(true); } } for (int i = 0; i < pol2.Dots.Length; i++) { if (PointInPolygon(pol2.Dots[i], pol1)) { return(true); } } return(false); }
/// <summary>Получить полигон</summary> /// <param name="polygon"></param> /// <param name="projection"></param> /// <returns></returns> public static Polygon GetKml(this TPolygon polygon, ProjectionInfo projection) { if (projection == null) { return(null); } if (polygon.Rings.Count == 0) { return(null); } var outher = new OuterBoundary { LinearRing = polygon.Rings[0].GetRingKml(projection) }; var kml = new Polygon { OuterBoundary = outher }; return(kml); }
//------------------------------------------------------------------------------ private static TPolygon BuildArc(TDoublePoint pt, double a1, double a2, double r) { int steps = (int)Math.Max(6, Math.Sqrt(Math.Abs(r)) * Math.Abs(a2 - a1)); TPolygon result = new TPolygon(); result.Capacity = steps; int n = steps - 1; double da = (a2 - a1) / n; double a = a1; for (int i = 0; i <= n; ++i) { double dy = Math.Sin(a) * r; double dx = Math.Cos(a) * r; result.Add(new TDoublePoint(pt.X + dx, pt.Y + dy)); a = a + da; } return(result); }
private List <List <Vertex> > GetParts(TGeometry geom) { List <List <Vertex> > res = new List <List <Vertex> >(); List <Vertex> plist; switch (geom.GetGeometryType()) { case GeometryType.Point: TPoint p = geom as TPoint; res.Add(new List <Vertex>() { new Vertex(p.Coord.X, p.Coord.Y) }); break; case GeometryType.LineString: TLineString ls = geom as TLineString; plist = new List <Vertex>(); foreach (MyPoint np in ls.Coords) { plist.Add(new Vertex(np.X, np.Y)); } res.Add(plist); break; case GeometryType.Polygon: TPolygon poly = geom as TPolygon; foreach (TLineString ring in poly.Rings) { plist = new List <Vertex>(); foreach (MyPoint np in ring.Coords) { plist.Add(new Vertex(np.X, np.Y)); } res.Add(plist); } break; case GeometryType.MultiPolygon: TMultiPolygon mpoly = geom as TMultiPolygon; TPolygon spoly; foreach (TGeometry sg in mpoly.Geometries) { spoly = sg as TPolygon; foreach (TLineString ring in spoly.Rings) { plist = new List <Vertex>(); foreach (MyPoint np in ring.Coords) { plist.Add(new Vertex(np.X, np.Y)); } res.Add(plist); } } break; case GeometryType.No: break; case GeometryType.GeometryCollection: break; default: throw new ArgumentOutOfRangeException(); } return(res); }
// вхождение в составные зоны - Исключающий полигон в эллипсе public static bool PointInDoubleZone(TPoint point, TEllipse in_parent_zone, TPolygon not_in_childzone) { return(PointInEllipse(point, in_parent_zone, MaxError) & (!PointInPolygon(point, not_in_childzone, MaxError))); }
// вхождение в составные зоны - Исключающий эллипс в полигоне public static bool PointInDoubleZone(TPoint point, TPolygon in_parent_zone, TEllipse not_in_childzone, double EPS) { return(PointInPolygon(point, in_parent_zone, EPS) & (!PointInEllipse(point, not_in_childzone, EPS))); }
// попадание точки в линию public static bool PointInLine(TPoint point, TPolygon line) { return(PointInLine(point, line, 3, 1)); }
// вхождение точки в полигон public static bool PointInPolygon(TPoint point, TPolygon polygon) { return(PointInPolygon(point, polygon, MaxError)); }
//------------------------------------------------------------------------------ public static TPolyPolygon OffsetPolygons(TPolyPolygon pts, double delta) { //A positive delta will offset each polygon edge towards its left, so //polygons orientated clockwise (ie outer polygons) will expand but //inner polyons (holes) will shrink. Conversely, negative deltas will //offset polygon edges towards their right so outer polygons will shrink //and inner polygons will expand. double deltaSq = delta * delta; TPolyPolygon result = new TPolyPolygon(pts.Count); for (int j = 0; j < pts.Count; ++j) { int highI = pts[j].Count - 1; TPolygon pg = new TPolygon(highI * 2 + 2); result.Add(pg); //to minimize artefacts, strip out those polygons where //it's shrinking and where its area < Sqr(delta) ... double area = Area(pts[j]); if (delta < 0) { if (area > 0 && area < deltaSq) { highI = 0; } } else if (area < 0 && -area < deltaSq) { highI = 0; //nb: a hole if area < 0 } if (highI < 2) { continue; } TPolygon normals = new TPolygon(highI + 1); normals.Add(TClipper.GetUnitNormal(pts[j][highI], pts[j][0])); for (int i = 1; i <= highI; ++i) { normals.Add(TClipper.GetUnitNormal(pts[j][i - 1], pts[j][i])); } for (int i = 0; i < highI; ++i) { pg.Add(new TDoublePoint(pts[j][i].X + delta * normals[i].X, pts[j][i].Y + delta * normals[i].Y)); pg.Add(new TDoublePoint(pts[j][i].X + delta * normals[i + 1].X, pts[j][i].Y + delta * normals[i + 1].Y)); } pg.Add(new TDoublePoint(pts[j][highI].X + delta * normals[highI].X, pts[j][highI].Y + delta * normals[highI].Y)); pg.Add(new TDoublePoint(pts[j][highI].X + delta * normals[0].X, pts[j][highI].Y + delta * normals[0].Y)); //round off reflex angles (ie > 180 deg) unless it's almost flat (ie < 10deg angle) ... //cross product normals < 0 . reflex angle; dot product normals == 1 . no angle if ((normals[highI].X * normals[0].Y - normals[0].X * normals[highI].Y) * delta > 0 && (normals[0].X * normals[highI].X + normals[0].Y * normals[highI].Y) < 0.985) { double a1 = Math.Atan2(normals[highI].Y, normals[highI].X); double a2 = Math.Atan2(normals[0].Y, normals[0].X); if (delta > 0 && a2 < a1) { a2 = a2 + Math.PI * 2; } else if (delta < 0 && a2 > a1) { a2 = a2 - Math.PI * 2; } TPolygon arc = BuildArc(pts[j][highI], a1, a2, delta); pg.InsertRange(highI * 2 + 1, arc); } for (int i = highI; i > 0; --i) { if ((normals[i - 1].X * normals[i].Y - normals[i].X * normals[i - 1].Y) * delta > 0 && (normals[i].X * normals[i - 1].X + normals[i].Y * normals[i - 1].Y) < 0.985) { double a1 = Math.Atan2(normals[i - 1].Y, normals[i - 1].X); double a2 = Math.Atan2(normals[i].Y, normals[i].X); if (delta > 0 && a2 < a1) { a2 = a2 + Math.PI * 2; } else if (delta < 0 && a2 > a1) { a2 = a2 - Math.PI * 2; } TPolygon arc = BuildArc(pts[j][i - 1], a1, a2, delta); pg.InsertRange((i - 1) * 2 + 1, arc); } } } //finally, clean up untidy corners ... TClipper c = new TClipper(); c.AddPolyPolygon(result, TPolyType.ptSubject); if (delta > 0) { if (!c.Execute(TClipType.ctUnion, result, TPolyFillType.pftNonZero, TPolyFillType.pftNonZero)) { result.Clear(); } } else { TDoubleRect r = c.GetBounds(); TPolygon outer = new TPolygon(4); outer.Add(new TDoublePoint(r.left - 10, r.bottom + 10)); outer.Add(new TDoublePoint(r.right + 10, r.bottom + 10)); outer.Add(new TDoublePoint(r.right + 10, r.top - 10)); outer.Add(new TDoublePoint(r.left - 10, r.top - 10)); c.AddPolygon(outer, TPolyType.ptSubject); if (c.Execute(TClipType.ctUnion, result, TPolyFillType.pftNonZero, TPolyFillType.pftNonZero)) { result.RemoveAt(0); } else { result.Clear(); } } return(result); }