Ejemplo n.º 1
0
        /// <summary>
        /// Internal: Create a vertex graph from a set of hexagons. It is the
        /// responsibility of the caller to call destroyVertexGraph on the populated
        /// graph, otherwise the memory in the graph nodes will not be freed.
        /// </summary>
        ///
        /// <param name="h3Set">Set of hexagons</param>
        /// <param name="numHexes">Number of hexagons in the set</param>
        /// <param name="graph">Output graph</param>
        /// <!-- Based off 3.1.1 -->
        public static void h3SetToVertexGraph(ref List <H3Index> h3Set, int numHexes,
                                              ref VertexGraph graph)
        {
            GeoBoundary vertices   = new GeoBoundary();
            GeoCoord    fromVertex = new GeoCoord();
            GeoCoord    toVertex   = new GeoCoord();

            VertexGraph.VertexNode edge;
            if (numHexes < 1)
            {
                // We still need to init the graph, or calls to destroyVertexGraph will
                // fail
                graph = new VertexGraph(0, 0);
                return;
            }

            int       res        = H3Index.H3_GET_RESOLUTION(h3Set[0]);
            const int minBuckets = 6;
            // TODO: Better way to calculate/guess?
            int numBuckets = numHexes > minBuckets ? numHexes : minBuckets;

            graph = new VertexGraph(numBuckets, res);

            // Iterate through every hexagon
            for (int i = 0; i < numHexes; i++)
            {
                H3Index.h3ToGeoBoundary(h3Set[i], ref vertices);
                // iterate through every edge
                for (int j = 0; j < vertices.numVerts; j++)
                {
                    fromVertex = new GeoCoord(vertices.verts[j].lat, vertices.verts[j].lon);
                    //fromVtx = vertices.verts[j];
                    int idx = (j + 1) % vertices.numVerts;
                    toVertex = new GeoCoord(vertices.verts[idx].lat, vertices.verts[idx].lon);
                    //toVtx = vertices.verts[(j + 1) % vertices.numVerts];
                    // If we've seen this edge already, it will be reversed
                    edge = VertexGraph.findNodeForEdge(ref graph, toVertex, fromVertex);
                    if (edge != null)
                    {
                        // If we've seen it, drop it. No edge is shared by more than 2
                        // hexagons, so we'll never see it again.
                        VertexGraph.removeVertexNode(ref graph, ref edge);
                    }
                    else
                    {
                        // Add a new node for this edge
                        VertexGraph.addVertexNode(ref graph, fromVertex, toVertex);
                    }
                }
            }
        }
Ejemplo n.º 2
0
 /// <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);
     }
 }