/// <summary> /// Create a LinkedGeoPolygon describing the outline(s) of a set of hexagons. /// Polygon outlines will follow GeoJSON MultiPolygon order: Each polygon will /// have one outer loop, which is first in the list, followed by any holes. /// /// It is expected that all hexagons in the set have the same resolution and /// that the set contains no duplicates. Behavior is undefined if duplicates /// or multiple resolutions are present, and the algorithm may produce unexpected /// or invalid output. /// </summary> /// <param name="h3Set">Set of hexagons</param> /// <param name="numHexes">NUmber of hexagons in set</param> /// <param name="out_polygons">output polygon</param> /// <!-- Based off 3.1.1 --> public static void h3SetToLinkedGeo(ref List <H3Index> h3Set, int numHexes, ref LinkedGeo.LinkedGeoPolygon out_polygons) { VertexGraph graph = new VertexGraph(0, 0); h3SetToVertexGraph(ref h3Set, numHexes, ref graph); _vertexGraphToLinkedGeo(ref graph, ref out_polygons); // TODO: The return value, possibly indicating an error, is discarded here - // we should use this when we update the API to return a value LinkedGeo.normalizeMultiPolygon(ref out_polygons); VertexGraph.destroyVertexGraph(ref graph); }
/// <summary> /// Internal: Create a LinkedGeoPolygon from a vertex graph. It is the /// responsibility of the caller to call destroyLinkedPolygon on the /// populated linked geo structure, or the memory for that structure /// will not be freed. /// </summary> /// <param name="graph">input graph</param> /// <param name="out_polygon">output polygon</param> /// <!-- Based off 3.1.1 --> internal static void _vertexGraphToLinkedGeo(ref VertexGraph graph, ref LinkedGeo.LinkedGeoPolygon out_polygon) { out_polygon = new LinkedGeo.LinkedGeoPolygon(); VertexGraph.VertexNode edge; // Find the next unused entry point while ((edge = VertexGraph.firstVertexNode(ref graph)) != null) { var loop = LinkedGeo.addNewLinkedLoop(ref out_polygon); // Walk the graph to get the outline do { var addLinkedCoord = LinkedGeo.addLinkedCoord(ref loop, ref edge.from); var nextVertex = edge.to; // Remove frees the node, so we can't use edge after this VertexGraph.removeVertexNode(ref graph, ref edge); edge = VertexGraph.findNodeForVertex(ref graph, ref nextVertex); } while (edge != null); } }