private Polygon CreateKmlPolygon(IPolygon polygon) { var kmlPolygon = new Polygon(); var ring = new LinearRing { Coordinates = new CoordinateCollection() }; kmlPolygon.OuterBoundary = new OuterBoundary { LinearRing = ring }; foreach (var coordinate in polygon.ExteriorRing.Coordinates) { ring.Coordinates.Add(new Vector(coordinate.Y, coordinate.X)); } foreach (var interiorRing in polygon.InteriorRings) { var innerBoundary = new InnerBoundary(); kmlPolygon.AddInnerBoundary(innerBoundary); ring = new LinearRing { Coordinates = new CoordinateCollection() }; innerBoundary.LinearRing = ring; foreach (var coordinate in interiorRing.Coordinates) { ring.Coordinates.Add(new Vector(coordinate.Y, coordinate.X)); } } return(kmlPolygon); }
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); }
/// <summary> /// Adds a vertex to current triangulation using incremental algorithm Bowyer-Watson /// algorithm if vertex is completely inside triangulation otherwise /// creates triangles on visible boundary and restores delaunay property. /// </summary> /// <param name="vertexIndex">Vertex index.</param> private bool AddVertex(int vertexIndex) { // First: locate the given vertex. // Determine whether it's in the specific triangle or // lies outside of triangulation. var vertex = InnerVertices[vertexIndex].Pos; var result = LocateClosestTriangle(vertex, out var halfEdge); // Check special cases: // Same vertex already exists: if (result == LocationResult.SameVertex) { // Shouldn't insert vertex int sameVertexIndex = -1; for (int i = 0; i < Vertices.Count; i++) { if (i != vertexIndex && Vertices[i].Pos == vertex) { sameVertexIndex = i; break; } } if (sameVertexIndex >= 0) { return(false); } // otherwise it can be bounding figure vertex. if (!BelongsToBoundingFigure(vertex, out var bfvi) || halfEdge.Origin != -bfvi) { return(false); } foreach (var incidentEdge in IncidentEdges(halfEdge)) { incidentEdge.Origin = vertexIndex; } } else if (result == LocationResult.OnEdge) { // Should split edge var prev = halfEdge.Origin; var next = halfEdge.Next.Origin; SplitEdge(vertexIndex, halfEdge); if (InnerBoundary.Contains(prev) && InnerBoundary.Next(prev) == next) { // Then we splitted boundary edge. InnerBoundary.Insert(prev, vertexIndex); } else if (InnerBoundary.Contains(next) && InnerBoundary.Next(next) == prev) { InnerBoundary.Insert(next, vertexIndex); } } else if (result == LocationResult.InsideTriangle) { // Boywer-Watson algorithm Root = BowyerWatson(vertexIndex, halfEdge); } else { // Find boundary of triangulation that is visible from given vertex. // Build triangles on the sides of the visible boundary. // Use flip algorithm to restore delaunay property. var visibleBoundary = GetVisibleBoundary(vertexIndex, halfEdge); // Should probably triangulate only leftmost\rightmost\closest chain // of visible edges (for better UE). var edgesToCheck = new List <HalfEdge>(visibleBoundary[0].Count * 2); HalfEdge lastConstructedTriangle = null; foreach (var edge in visibleBoundary[0]) { var twin = new HalfEdge(edge.Next.Origin) { Next = new HalfEdge(edge.Origin) { Next = new HalfEdge(vertexIndex), } }; twin.Prev.Next = twin; edge.TwinWith(twin); lastConstructedTriangle?.Prev.TwinWith(twin.Next); lastConstructedTriangle = twin; edgesToCheck.Add(edge); edgesToCheck.Add(twin.Next); } RestoreDelaunayProperty(edgesToCheck); } return(true); }