Esempio n. 1
0
        /// <summary>
        /// Returns the origin hexagon from the unidirectional edge H3Index
        /// </summary>
        /// <param name="edge">The edge H3 index</param>
        /// <returns>The origin H3 hexagon index</returns>
        /// <!-- Based off 3.1.1 -->
        public static H3Index getOriginH3IndexFromUnidirectionalEdge(H3Index edge)
        {
            if (H3Index.H3_GET_MODE(ref edge) != Constants.H3_UNIEDGE_MODE)
            {
                return(H3Index.H3_INVALID_INDEX);
            }
            H3Index origin = edge.value;

            H3Index.H3_SET_MODE(ref origin, Constants.H3_HEXAGON_MODE);
            H3Index.H3_SET_RESERVED_BITS(ref origin, 0);
            return(origin);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the destination hexagon from the unidirectional edge H3Index
        /// </summary>
        /// <param name="edge">The edge H3 index</param>
        /// <returns>The destination H3 hexagon index</returns>
        /// <!-- Based off 3.1.1 -->
        public static H3Index getDestinationH3IndexFromUnidirectionalEdge(H3Index edge)
        {
            if (H3Index.H3_GET_MODE(ref edge) != Constants.H3_UNIEDGE_MODE)
            {
                return(H3Index.H3_INVALID_INDEX);
            }
            Direction direction   = (Direction)H3Index.H3_GET_RESERVED_BITS(edge);
            int       rotations   = 0;
            H3Index   destination = Algos
                                    .h3NeighborRotations
                                    (
                getOriginH3IndexFromUnidirectionalEdge(edge),
                direction,
                ref rotations
                                    );

            return(destination);
        }
Esempio n. 3
0
        /// <summary>
        /// Determines if the provided H3Index is a valid unidirectional edge index
        /// </summary>
        /// <param name="edge">The unidirectional edge H3Index</param>
        /// <returns>1 if it is a unidirectional edge H3Index, otherwise 0.</returns>
        /// <!-- Based off 3.1.1 -->
        public static int h3UnidirectionalEdgeIsValid(H3Index edge)
        {
            if (H3Index.H3_GET_MODE(ref edge) != Constants.H3_UNIEDGE_MODE)
            {
                return(0);
            }

            Direction neighborDirection = (Direction)H3Index.H3_GET_RESERVED_BITS(edge);

            if (neighborDirection <= Direction.CENTER_DIGIT ||
                neighborDirection >= Direction.NUM_DIGITS)
            {
                return(0);
            }

            H3Index origin = getOriginH3IndexFromUnidirectionalEdge(edge);

            if (H3Index.h3IsPentagon(origin) != 0 && neighborDirection == Direction.K_AXES_DIGIT)
            {
                return(0);
            }

            return(H3Index.h3IsValid(origin));
        }
Esempio n. 4
0
        /// <summary>
        /// Returns whether or not the provided H3Indexes are neighbors.
        /// </summary>
        /// <param name="origin">The origin H3 index</param>
        /// <param name="destination">The destination H3 index</param>
        /// <returns>1 if the indexes are neighbors, 0 otherwise</returns>
        /// <!-- Based off 3.1.1 -->
        public static int h3IndexesAreNeighbors(H3Index origin, H3Index destination)
        {
            // Make sure they're hexagon indexes
            if (H3Index.H3_GET_MODE(ref origin) != Constants.H3_HEXAGON_MODE ||
                H3Index.H3_GET_MODE(ref destination) != Constants.H3_HEXAGON_MODE)
            {
                return(0);
            }

            // Hexagons cannot be neighbors with themselves
            if (origin == destination)
            {
                return(0);
            }

            // Only hexagons in the same resolution can be neighbors
            if (H3Index.H3_GET_RESOLUTION(origin) != H3Index.H3_GET_RESOLUTION(destination))
            {
                return(0);
            }

            // H3 Indexes that share the same parent are very likely to be neighbors
            // Child 0 is neighbor with all of its parent's 'offspring', the other
            // children are neighbors with 3 of the 7 children. So a simple comparison
            // of origin and destination parents and then a lookup table of the children
            // is a super-cheap way to possibly determine they are neighbors.
            int parentRes = H3Index.H3_GET_RESOLUTION(origin) - 1;

            if (parentRes > 0 && (H3Index.h3ToParent(origin, parentRes) ==
                                  H3Index.h3ToParent(destination, parentRes)))
            {
                Direction originResDigit      = H3Index.H3_GET_INDEX_DIGIT(origin, parentRes + 1);
                Direction destinationResDigit =
                    H3Index.H3_GET_INDEX_DIGIT(destination, parentRes + 1);
                if (originResDigit == Direction.CENTER_DIGIT ||
                    destinationResDigit == Direction.CENTER_DIGIT)
                {
                    return(1);
                }

                // These sets are the relevant neighbors in the clockwise
                // and counter-clockwise
                Direction[] neighborSetClockwise =
                {
                    Direction.CENTER_DIGIT, Direction.JK_AXES_DIGIT, Direction.IJ_AXES_DIGIT,
                    Direction.J_AXES_DIGIT, Direction.IK_AXES_DIGIT, Direction.K_AXES_DIGIT,
                    Direction.I_AXES_DIGIT
                };
                Direction[] neighborSetCounterclockwise =
                {
                    Direction.CENTER_DIGIT, Direction.IK_AXES_DIGIT, Direction.JK_AXES_DIGIT,
                    Direction.K_AXES_DIGIT, Direction.IJ_AXES_DIGIT, Direction.I_AXES_DIGIT,
                    Direction.J_AXES_DIGIT
                };
                if (
                    neighborSetClockwise[(int)originResDigit] == destinationResDigit ||
                    neighborSetCounterclockwise[(int)originResDigit] == destinationResDigit)
                {
                    return(1);
                }
            }

            // Otherwise, we have to determine the neighbor relationship the "hard" way.
            var neighborRing = new ulong[7].Select(cell => new H3Index(cell)).ToList();

            Algos.kRing(origin, 1, ref neighborRing);
            for (int i = 0; i < 7; i++)
            {
                if (neighborRing[i] == destination)
                {
                    return(1);
                }
            }

            // Made it here, they definitely aren't neighbors
            return(0);
        }