public void h3IsResClassIII() { //GeoCoord coord = { 0, 0 }; var coord = new GeoCoord(0, 0); for (int i = 0; i <= MAX_H3_RES; i++) { //H3Index h = H3_EXPORT(geoToH3)(&coord, i); var h = coord.ToH3Index(i); //t_assert(H3_EXPORT(h3IsResClassIII)(h) == isResClassIII(i), "matches existing definition"); Assert.IsTrue(h.IsResClassIII() == H3Index.isResClassIII(i), "matches existing definition"); } }
/// <summary> /// Test that the local coordinates for an index map to itself. /// </summary> private void LocalIjToH3IdentityAssertions(H3Index h3) { int status; CoordIj ij; (status, ij) = h3.ToLocalIjExperimental(h3); Assert.AreEqual(0, status); H3Index retrieved; (status, retrieved) = ij.ToH3Experimental(h3); Assert.AreEqual(0, status); Assert.AreEqual(h3, retrieved); }
public void h3IsValidBaseCellInvalid() { //H3Index hWrongBaseCell = H3_INIT; var hWrongBaseCell = new H3Index(H3Index.H3_INIT); //H3_SET_MODE(hWrongBaseCell, H3_HEXAGON_MODE); hWrongBaseCell.Mode = H3_HEXAGON_MODE; //H3_SET_BASE_CELL(hWrongBaseCell, NUM_BASE_CELLS); hWrongBaseCell.BaseCell = NUM_BASE_CELLS; //t_assert(!H3_EXPORT(h3IsValid)(hWrongBaseCell), "h3IsValid failed on invalid base cell"); Assert.IsFalse(hWrongBaseCell.IsValid(), "h3IsValid failed on invalid base cell"); }
public void faceIjkToH3ExtremeCoordinates() { FaceIJK fijk0I = new FaceIJK { face = 0, coord = new CoordIJK(3, 0, 0) }; Assert.True(H3Index._faceIjkToH3(ref fijk0I, 0) == 0, "i out of bounds at res 0"); FaceIJK fijk0J = new FaceIJK { face = 1, coord = new CoordIJK(0, 4, 0) }; Assert.True(H3Index._faceIjkToH3(ref fijk0J, 0) == 0, "j out of bounds at res 0"); FaceIJK fijk0K = new FaceIJK { face = 2, coord = new CoordIJK(2, 0, 5) }; Assert.True(H3Index._faceIjkToH3(ref fijk0K, 0) == 0, "k out of bounds at res 0"); FaceIJK fijk1I = new FaceIJK { face = 3, coord = new CoordIJK(6, 0, 0) }; Assert.True(H3Index._faceIjkToH3(ref fijk1I, 1) == 0, "i out of bounds at res 1"); FaceIJK fijk1J = new FaceIJK { face = 4, coord = new CoordIJK(0, 7, 1) }; Assert.True(H3Index._faceIjkToH3(ref fijk1J, 1) == 0, "j out of bounds at res 1"); FaceIJK fijk1K = new FaceIJK { face = 5, coord = new CoordIJK(2, 0, 8) }; Assert.True(H3Index._faceIjkToH3(ref fijk1K, 1) == 0, "k out of bounds at res 1"); FaceIJK fijk2I = new FaceIJK { face = 6, coord = new CoordIJK(18, 0, 0) }; Assert.True(H3Index._faceIjkToH3(ref fijk2I, 2) == 0, "i out of bounds at res 2"); FaceIJK fijk2J = new FaceIJK { face = 7, coord = new CoordIJK(0, 19, 1) }; Assert.True(H3Index._faceIjkToH3(ref fijk2J, 2) == 0, "j out of bounds at res 2"); FaceIJK fijk2K = new FaceIJK { face = 8, coord = new CoordIJK(2, 0, 20) }; Assert.True(H3Index._faceIjkToH3(ref fijk2K, 2) == 0, "k out of bounds at res 2"); }
public void ancestorsForEachRes() { for (int res = 1; res < 15; res++) { for (int step = 0; step < res; step++) { var child = H3Index.geoToH3(ref sf, res); var parent = H3Index.h3ToParent(child, res - step); var comparisonParent = H3Index.geoToH3(ref sf, res - step); Assert.True(parent == comparisonParent, "Got expected parent"); } } }
public void VertexNumForDirectionBadDirections() { H3Index origin = 0x823007fffffffff; Assert.AreEqual (origin.VertexNumForDirection(Direction.CENTER_DIGIT), H3Lib.Constants.Vertex.INVALID_VERTEX_NUM); Assert.AreEqual (origin.VertexNumForDirection(Direction.INVALID_DIGIT), H3Lib.Constants.Vertex.INVALID_VERTEX_NUM); H3Index pentagon = 0x823007fffffffff; Assert.AreEqual (pentagon.VertexNumForDirection(Direction.K_AXES_DIGIT), H3Lib.Constants.Vertex.INVALID_VERTEX_NUM); }
public void h3BadDigitInvalid() { //H3Index h = H3_INIT; var h = new H3Index(H3Index.H3_INIT); //H3_SET_MODE(h, H3_HEXAGON_MODE); h.Mode = H3_HEXAGON_MODE; //H3_SET_RESOLUTION(h, 1); h.Resolution = 1; //t_assert(!H3_EXPORT(h3IsValid)(h), "h3IsValid failed on too large digit"); Assert.IsFalse(h.IsValid(), "h3IsValid failed on too large digit"); }
private static void ProcessArguments(HexRangeArguments argParser) { var origin = new H3Index(argParser.Origin); var ij = new CoordIj(argParser.I, argParser.J); var(status, cell) = ij.ToH3Experimental(origin); Console.WriteLine ( status != 0 ? "NA" : cell.ToString() ); }
/// Generates all pentagons at the specified resolution /// /// <param name="res">The resolution to produce pentagons at.</param> /// <returns>Output List.</returns> /// <!-- /// h3Index.c /// void H3_EXPORT(getPentagonIndexes) /// --> public static List <H3Index> GetPentagonIndexes(this int res) { var results = new List <H3Index>(); for (int bc = 0; bc < Constants.H3.NUM_BASE_CELLS; bc++) { if (bc.IsBaseCellPentagon()) { H3Index pentagon = new H3Index().SetIndex(res, bc, 0); results.Add(pentagon); } } return(results); }
public void onPentagon() { int err; H3Index nearPentagon = 0; H3Index.setH3Index(ref nearPentagon, 0, 4, 0); List <H3Index> kp2 = new List <H3Index> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; err = Algos.hexRing(nearPentagon, 2, ref kp2); Assert.True(err != 0, "Should return an error when starting at a pentagon"); }
public void pentagonChildren() { H3Index pentagon = 0; H3Index.setH3Index(ref pentagon, 1, 4, 0); const int expectedCount = (5 * 7) + 6; int paddedCount = H3Index.maxH3ToChildrenSize(pentagon, 3); var children = new ulong[paddedCount].Select(child => new H3Index(child)).ToList(); H3Index.h3ToChildren(sfHex8, 10, ref children); H3Index.h3ToChildren(pentagon, 3, ref children); verifyCountAndUniqueness(children, paddedCount, expectedCount); }
public void StringToH3() { // NOTE: This one was skipped in implementation. // However, it's not impossible to work around. if (ulong.TryParse("", out ulong result1)) { H3Index h = result1; Assert.AreEqual(0, h.Value); } if (ulong.TryParse("**", out ulong result2)) { H3Index h = result2; Assert.AreEqual(0, h.Value); } }
void t_assertBoundary(H3Index h3, GeoBoundary b1) { // Generate cell boundary for the h3 index GeoBoundary b2 = new GeoBoundary(); H3Index.h3ToGeoBoundary(h3, ref b2); Assert.True(b1.numVerts == b2.numVerts, "expected cell boundary count"); for (int v = 0; v < b1.numVerts; v++) { Assert.True ( GeoCoord.geoAlmostEqual(b1.verts[v], b2.verts[v]), "got expected vertex" ); } }
public void H3IsValidWithMode() { for (var i = 0; i <= 15; i++) { H3Index h = H3Lib.Constants.H3Index.H3_INIT; h = h.SetMode((H3Mode)i); if (i == (int)H3Mode.Hexagon) { Assert.IsTrue(h.IsValid()); } else { Assert.IsFalse(h.IsValid()); } } }
public void h3IsResClassIII() { GeoCoord coord = new GeoCoord(0, 0); for (int i = 0; i <= Constants.MAX_H3_RES; i++) { H3Index h = H3Index.geoToH3(ref coord, i); Assert.True ( H3Index.h3IsResClassIII(h) == (H3Index.isResClassIII(i) ? 1 : 0), "matches existing definition" ); } }
public void h3IsValidWithMode() { for (int i = 0; i <= 0xf; i++) { //H3Index h = H3_INIT; var h = new H3Index(H3Index.H3_INIT); //H3_SET_MODE(h, i); h.Mode = i; //char failureMessage[BUFF_SIZE]; //sprintf(failureMessage, "h3IsValid failed on mode %d", i); //t_assert(!H3_EXPORT(h3IsValid)(h) || i == 1, failureMessage); Assert.IsTrue(!h.IsValid() || i == 1, $"h3IsValid failed on mode {i}"); } }
public void getH3UnidirectionalEdgeBoundaryPentagonClassII() { H3Index pentagon = 0; GeoBoundary boundary = new GeoBoundary(); GeoBoundary edgeBoundary = new GeoBoundary(); var edges = new ulong[6].Select(cell => new H3Index(cell)).ToList(); int[,] expectedVertices = { { -1, -1 }, { 1, 2 }, { 2, 3 }, { 4, 0 }, { 3, 4 }, { 0, 1 } }; // TODO: The current implementation relies on lat/lon comparison and fails // on resolutions finer than 12 for (int res = 0; res < 12; res += 2) { H3Index.setH3Index(ref pentagon, res, 24, 0); H3Index.h3ToGeoBoundary(pentagon, ref boundary); H3UniEdge.getH3UnidirectionalEdgesFromHexagon(pentagon, edges); int missingEdgeCount = 0; for (int i = 0; i < 6; i++) { if (edges[i] == 0) { missingEdgeCount++; } else { H3UniEdge.getH3UnidirectionalEdgeBoundary(edges[i], ref edgeBoundary); Assert.True( edgeBoundary.numVerts == 2, "Got the expected number of vertices back for a Class II pentagon"); for (int j = 0; j < edgeBoundary.numVerts; j++) { Assert.True( GeoCoord.geoAlmostEqual(edgeBoundary.verts[j], boundary.verts[expectedVertices[i, j]]), "Got expected vertex"); } } } Assert.True(missingEdgeCount == 1, "Only one edge was deleted for the pentagon"); } }
public void assertExpected(H3Index h1, ref GeoCoord g1) { const double epsilon = 0.0001 * Constants.M_PI_180; // convert H3 to lat/lon and verify GeoCoord g2 = new GeoCoord(); H3Index.h3ToGeo(h1, ref g2); Assert.True(GeoCoord.geoAlmostEqualThreshold(g2, g1, epsilon), "got expected h3ToGeo output"); // Convert back to H3 to verify int res = H3Index.h3GetResolution(h1); H3Index h2 = H3Index.geoToH3(ref g2, res); Debug.WriteLine($"{res}\t{h1.value}\t=>{h2.value}"); Assert.True(h1 == h2, "got expected geoToH3 output"); }
void assertExpected(H3Index h1, GeoCoord g1) { double epsilon = 0.000001 * M_PI_180; // convert H3 to lat/lon and verify // H3_EXPORT(h3ToGeo)(h1, &g2); GeoCoord g2 = h1.ToGeoCoord(); Assert.IsTrue(GeoCoord.AlmostEqualThreshold(g2, g1, epsilon), "got expected h3ToGeo output"); // Convert back to H3 to verify //int res = H3_EXPORT(h3GetResolution)(h1); //H3Index h2 = H3_EXPORT(geoToH3)(&g2, res); var h2 = g2.ToH3Index(h1.Resolution); Assert.AreEqual(h1, h2, "got expected geoToH3 output"); }
public void h3DistanceEdge() { H3Index origin = 0x832830fffffffffL; H3Index dest = 0x832834fffffffffL; H3Index edge = H3UniEdge.getH3UnidirectionalEdge(origin, dest); Assert.True(0 != edge, "test edge is valid"); Assert.True(LocalIJ.h3Distance(edge, origin) == 0, "edge has zero distance to origin"); Assert.True(LocalIJ.h3Distance(origin, edge) == 0, "origin has zero distance to edge"); Assert.True(LocalIJ.h3Distance(edge, dest) == 1, "edge has distance to destination"); Assert.True(LocalIJ.h3Distance(edge, dest) == 1, "destination has distance to edge"); }
public void H3IsValidReservedBits() { for (int i = 0; i < 8; i++) { H3Index h = H3Lib.Constants.H3Index.H3_INIT; h = h.SetMode(H3Mode.Hexagon).SetReservedBits(i); if (i == 0) { Assert.IsTrue(h.IsValid()); } else { Assert.IsFalse(h.IsValid()); } } }
public void stringToH3() { //t_assert(H3_EXPORT(stringToH3)("") == 0, "got an index from nothing"); var h1 = new H3Index(""); Assert.IsTrue(h1 == 0, "got an index from nothing"); //t_assert(H3_EXPORT(stringToH3)("**") == 0, "got an index from junk"); var h2 = new H3Index("**"); Assert.IsTrue(h1 == 0, "got an index from junk"); //t_assert(H3_EXPORT(stringToH3)("ffffffffffffffff") == 0xffffffffffffffff, "failed on large input"); var h3 = new H3Index("ffffffffffffffff"); Assert.IsTrue(h1 == 0, "failed on large input"); }
public void roundtrip() { int k = 9; int hexCount = Algos.maxKringSize(k); int expectedCompactCount = 73; // Generate a set of hexagons to compact List <H3Index> sunnyvaleExpanded = new ulong[hexCount].Select(cell => new H3Index(cell)).ToList(); Algos.kRing(sunnyvale, k, ref sunnyvaleExpanded); List <H3Index> compressed = new List <H3Index>(hexCount); int err = H3Index.compact(ref sunnyvaleExpanded, ref compressed, hexCount); Assert.True(err == 0); int count = 0; for (int i = 0; i < compressed.Count; i++) { if (compressed[i] != 0) { count++; } } Assert.True(count == expectedCompactCount); int size = H3Index.maxUncompactSize(ref compressed, count, 9); List <H3Index> decompressed = new List <H3Index>(size); int err2 = H3Index.uncompact(ref compressed, count, ref decompressed, hexCount, 9); Assert.True(err2 == 0); int count2 = 0; for (int i = 0; i < hexCount; i++) { if (decompressed[i] != 0) { count2++; } } Assert.True(count2 == hexCount); }
public void kRing0_polarPentagon() { H3Index polar = 0; H3Index.setH3Index(ref polar, 0, 4, 0); var k2 = new List <H3Index> { 0, 0, 0, 0, 0, 0, 0 }; var k2Dist = new List <int> { 0, 0, 0, 0, 0, 0, 0 }; var expectedK2 = new List <H3Index> { 0x8009fffffffffff, 0x8007fffffffffff, 0x8001fffffffffff, 0x8011fffffffffff, 0x801ffffffffffff, 0x8019fffffffffff, 0 }; Algos.kRingDistances(polar, 1, ref k2, ref k2Dist); int k2present = 0; for (int i = 0; i < 7; i++) { if (k2[i] != 0) { k2present++; int inList = 0; for (int j = 0; j < 7; j++) { if (k2[i] == expectedK2[j]) { Assert.True(k2Dist[i] == (k2[i] == polar ? 0 : 1), "distance is as expected"); inList++; } } Assert.True(inList == 1, "index found in expected set"); } } Assert.True(k2present == 6, "pentagon has 5 neighbors"); }
public void OneResStep() { const int expectedCount = 7; //const int paddedCount = 10; var sfHex9s = sfHex8.ToChildren(9); var center = sfHex8.ToGeoCoord(); var sfHex9_0 = center.ToH3Index(9); int numFound = 0; // Find the center for (int i = 0; i < sfHex9s.Count; i++) { if (sfHex9_0 == sfHex9s[i]) { numFound++; } } Assert.AreEqual(1, numFound); // Get the neighbor hexagons by averaging the center point and outer // points then query for those independently GeoBoundary outside = sfHex8.ToGeoBoundary(); for (int i = 0; i < outside.NumVerts; i++) { GeoCoord avg = new GeoCoord ( (outside.Verts[i].Latitude + center.Latitude) / 2, (outside.Verts[i].Longitude + center.Longitude) / 2 ); H3Index avgHex9 = avg.ToH3Index(9); for (int j = 0; j < expectedCount; j++) { if (avgHex9 == sfHex9s[j]) { numFound++; } } } Assert.AreEqual(expectedCount, numFound); }
private void kRing_equals_kRingInternal_assertions(H3Index h3) { for (int k = 0; k < 3; k++) { int kSz = Algos.maxKringSize(k); var neighbors = new H3Index[kSz].Select(c => (H3Index)0).ToList(); var distances = new int[kSz].Select(c => 0).ToList(); Algos.kRingDistances(h3, k, ref neighbors, ref distances); var internalNeighbors = new H3Index[kSz].Select(c => (H3Index)0).ToList(); var internalDistances = new int[kSz].Select(c => 0).ToList(); Algos._kRingInternal(h3, k, ref internalNeighbors, ref internalDistances, kSz, 0); int found = 0; int internalFound = 0; for (int iNeighbor = 0; iNeighbor < kSz; iNeighbor++) { if (neighbors[iNeighbor] != 0) { found++; for (int iInternal = 0; iInternal < kSz; iInternal++) { if (internalNeighbors[iInternal] == neighbors[iNeighbor]) { internalFound++; Assert.True(distances[iNeighbor] == internalDistances[iInternal], "External and internal agree on distance"); break; } } Assert.True(found == internalFound, "External and internal implementations produce same output"); } } } }
public void pentagonChildren() { var pentagon = new H3Index(); pentagon.SetH3Index(1, 4, 0); int expectedCount = (5 * 7) + 6; int paddedCount = pentagon.maxH3ToChildrenSize(3); //H3Index* children = calloc(paddedCount, sizeof(H3Index)); //H3_EXPORT(h3ToChildren)(sfHex8, 10, children); //H3_EXPORT(h3ToChildren)(pentagon, 3, children); var children = new List <H3Index>(); children.AddRange(sfHex8.ToChildren(10)); children.AddRange(pentagon.ToChildren(3)); verifyCountAndUniqueness(children, paddedCount, expectedCount); }
private static void H3UniEdgeCorrectnessAssertions(H3Index h3) { bool isPentagon = h3.IsPentagon(); var edges = h3.GetUniEdgesFromCell(); for (var i = 0; i < 6; i++) { if (isPentagon && i == 0) { Assert.AreEqual(Constants.H3Index.H3_NULL, edges[i]); continue; } Assert.IsTrue(edges[i].IsValidUniEdge()); Assert.AreEqual(h3, edges[i].OriginFromUniDirectionalEdge()); var destination = edges[i].DestinationFromUniDirectionalEdge(); Assert.IsTrue(h3.IsNeighborTo(destination)); } }
public void TestIndexDistance() { var bc = new H3Index(1, 17, 0); var p = new H3Index(1, 14, 0); var p2 = new H3Index(1, 14, 2); var p3 = new H3Index(1, 14, 3); var p4 = new H3Index(1, 14, 4); var p5 = new H3Index(1, 14, 5); var p6 = new H3Index(1, 14, 6); Assert.AreEqual(3, bc.DistanceTo(p)); Assert.AreEqual(2, bc.DistanceTo(p2)); Assert.AreEqual(3, bc.DistanceTo(p3)); // TODO works correctly but is rejected due to possible pentagon // distortion. // t_assert(H3_EXPORT(h3Distance)(bc, p4) == 3, "distance onto p4"); // t_assert(H3_EXPORT(h3Distance)(bc, p5) == 4, "distance onto p5"); Assert.AreEqual(2, bc.DistanceTo(p6)); }
public void compact_duplicates() { int numHex = 3; List <H3Index> someHexagons = new List <H3Index> { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }.ToList(); for (int i = 0; i < numHex; i++) { H3Index hp = someHexagons[i]; H3Index.setH3Index(ref hp, 5, 0, (Direction)2); someHexagons[i] = hp; } List <H3Index> compressed = new List <H3Index>(); int err = H3Index.compact(ref someHexagons, ref compressed, numHex); Assert.True(err != 0); }