From 3d8b1de723044ce5fdf7a618a6e8753537030bdc Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 16:54:07 -0500 Subject: [PATCH 01/37] areNeighborCells --- src/apps/filters/h3.c | 34 ++++++++++++++++++++++++++++++++++ tests/cli/areNeighborCells.txt | 3 +++ 2 files changed, 37 insertions(+) create mode 100644 tests/cli/areNeighborCells.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 3f061a093..b3f5c4593 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1632,6 +1632,37 @@ SUBCOMMAND(cellsToMultiPolygon, return E_SUCCESS; } +/// Directed edge subcommands + +SUBCOMMAND(areNeighborCells, + "Determines if the provided H3 cells are neighbors (have a shared " + "border)") { + H3Index origin, destination; + Arg originCellArg = {.names = {"-o", "--origin"}, + .required = true, + .scanFormat = "%" PRIx64, + .valueName = "CELL", + .value = &origin, + .helpText = "Origin H3 Cell"}; + Arg destinationCellArg = {.names = {"-d", "--destination"}, + .required = true, + .scanFormat = "%" PRIx64, + .valueName = "CELL", + .value = &destination, + .helpText = "Destination H3 Cell"}; + Arg *args[] = {&areNeighborCellsArg, &originCellArg, &destinationCellArg, + &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + int areNeighbors = 0; + H3Error err = + H3_EXPORT(areNeighborCells)(origin, destination, &areNeighbors); + if (err != E_SUCCESS) { + return err; + } + printf(areNeighbors ? "true\n" : "false\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1674,6 +1705,9 @@ SUBCOMMAND_INDEX(polygonToCells) SUBCOMMAND_INDEX(maxPolygonToCellsSize) SUBCOMMAND_INDEX(cellsToMultiPolygon) +/// Directed Edge subcommands +SUBCOMMAND_INDEX(areNeighborCells) + END_SUBCOMMANDS_INDEX int main(int argc, char *argv[]) { diff --git a/tests/cli/areNeighborCells.txt b/tests/cli/areNeighborCells.txt new file mode 100644 index 000000000..368aecbec --- /dev/null +++ b/tests/cli/areNeighborCells.txt @@ -0,0 +1,3 @@ +add_h3_cli_test(testCliAreNeighborCells "areNeighborCells -o 85283473fffffff -d 85283477fffffff" "true") +add_h3_cli_test(testCliAreNotNeighborCells "areNeighborCells -o 85283473fffffff -d 85283472fffffff" "false") +add_h3_cli_test(testCliAreNeighborNotCells "areNeighborCells -o 85283473fffffff -d 852834727fffffff 2>&1" "Error 5: Cell argument was not valid") From 18b2719ebfb77eb465b1956957f51fb73312f42c Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:14:20 -0500 Subject: [PATCH 02/37] cellsToDirectedEdge --- src/apps/filters/h3.c | 29 +++++++++++++++++++++++++++++ tests/cli/cellsToDirectedEdge.txt | 2 ++ 2 files changed, 31 insertions(+) create mode 100644 tests/cli/cellsToDirectedEdge.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index b3f5c4593..5470b43b9 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1663,6 +1663,34 @@ SUBCOMMAND(areNeighborCells, return E_SUCCESS; } +SUBCOMMAND(cellsToDirectedEdge, + "Converts neighboring cells into a directed edge index (or errors " + "if they are not neighbors)") { + H3Index origin, destination; + Arg originCellArg = {.names = {"-o", "--origin"}, + .required = true, + .scanFormat = "%" PRIx64, + .valueName = "CELL", + .value = &origin, + .helpText = "Origin H3 Cell"}; + Arg destinationCellArg = {.names = {"-d", "--destination"}, + .required = true, + .scanFormat = "%" PRIx64, + .valueName = "CELL", + .value = &destination, + .helpText = "Destination H3 Cell"}; + Arg *args[] = {&cellsToDirectedEdgeArg, &originCellArg, &destinationCellArg, + &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out = 0; + H3Error err = H3_EXPORT(cellsToDirectedEdge)(origin, destination, &out); + if (err != E_SUCCESS) { + return err; + } + printf("%" PRIx64 "\n", out); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1707,6 +1735,7 @@ SUBCOMMAND_INDEX(cellsToMultiPolygon) /// Directed Edge subcommands SUBCOMMAND_INDEX(areNeighborCells) +SUBCOMMAND_INDEX(cellsToDirectedEdge) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/cellsToDirectedEdge.txt b/tests/cli/cellsToDirectedEdge.txt new file mode 100644 index 000000000..9e0c8656b --- /dev/null +++ b/tests/cli/cellsToDirectedEdge.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellsToDirectedEdge "cellsToDirectedEdge -o 85283473fffffff -d 85283477fffffff" "115283473fffffff") +add_h3_cli_test(testCliCellsNotToDirectedEdge "cellsToDirectedEdge -o 85283473fffffff -d 85283472fffffff 2>&1" "Error 11: Cell arguments were not neighbors") From 702ca3b7642ce61fbf04eb6193068e3bedcdba07 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:22:28 -0500 Subject: [PATCH 03/37] isValidDirectedEdge --- src/apps/filters/h3.c | 11 +++++++++++ tests/cli/isValidDirectedEdge.txt | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 tests/cli/isValidDirectedEdge.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 5470b43b9..80b16bde5 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1691,6 +1691,16 @@ SUBCOMMAND(cellsToDirectedEdge, return E_SUCCESS; } +SUBCOMMAND(isValidDirectedEdge, + "Checks if the provided H3 directed edge is actually valid") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&isValidDirectedEdgeArg, &helpArg, &cellArg}; + PARSE_SUBCOMMAND(argc, argv, args); + bool isValid = H3_EXPORT(isValidDirectedEdge)(cell); + printf("%s", isValid ? "true\n" : "false\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1736,6 +1746,7 @@ SUBCOMMAND_INDEX(cellsToMultiPolygon) /// Directed Edge subcommands SUBCOMMAND_INDEX(areNeighborCells) SUBCOMMAND_INDEX(cellsToDirectedEdge) +SUBCOMMAND_INDEX(isValidDirectedEdge) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/isValidDirectedEdge.txt b/tests/cli/isValidDirectedEdge.txt new file mode 100644 index 000000000..76fdaee9f --- /dev/null +++ b/tests/cli/isValidDirectedEdge.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliIsValidDirectedEdge "isValidDirectedEdge -c 115283473fffffff" "true") +add_h3_cli_test(testCliIsNotValidDirectedEdge "isValidDirectedEdge -c 85283473fffffff" "false") From 6eec8d0f71ce529c8bd6aa4c0e7c0a875fc9e9cd Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:29:39 -0500 Subject: [PATCH 04/37] getDirectedEdgeOrigin --- src/apps/filters/h3.c | 15 +++++++++++++++ tests/cli/getDirectedEdgeOrigin.txt | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 tests/cli/getDirectedEdgeOrigin.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 80b16bde5..f084ea3f3 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1701,6 +1701,20 @@ SUBCOMMAND(isValidDirectedEdge, return E_SUCCESS; } +SUBCOMMAND(getDirectedEdgeOrigin, + "Returns the origin cell from the directed edge") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&getDirectedEdgeOriginArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out = 0; + H3Error err = H3_EXPORT(getDirectedEdgeOrigin)(cell, &out); + if (err != E_SUCCESS) { + return err; + } + printf("%" PRIx64 "\n", out); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1747,6 +1761,7 @@ SUBCOMMAND_INDEX(cellsToMultiPolygon) SUBCOMMAND_INDEX(areNeighborCells) SUBCOMMAND_INDEX(cellsToDirectedEdge) SUBCOMMAND_INDEX(isValidDirectedEdge) +SUBCOMMAND_INDEX(getDirectedEdgeOrigin) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getDirectedEdgeOrigin.txt b/tests/cli/getDirectedEdgeOrigin.txt new file mode 100644 index 000000000..770d26264 --- /dev/null +++ b/tests/cli/getDirectedEdgeOrigin.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetDirectedEdgeOrigin "getDirectedEdgeOrigin -c 115283473fffffff" "85283473fffffff") +add_h3_cli_test(testCliDoNotGetDirectedEdgeOrigin "getDirectedEdgeOrigin -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From b2c44f25165768aa371c2a7d77c91260f1b031b2 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:36:15 -0500 Subject: [PATCH 05/37] getDirectedEdgeDestination --- src/apps/filters/h3.c | 15 +++++++++++++++ tests/cli/getDirectedEdgeDestination.txt | 2 ++ 2 files changed, 17 insertions(+) create mode 100644 tests/cli/getDirectedEdgeDestination.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index f084ea3f3..ee23cb4a5 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1715,6 +1715,20 @@ SUBCOMMAND(getDirectedEdgeOrigin, return E_SUCCESS; } +SUBCOMMAND(getDirectedEdgeDestination, + "Returns the destination cell from the directed edge") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&getDirectedEdgeDestinationArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out = 0; + H3Error err = H3_EXPORT(getDirectedEdgeDestination)(cell, &out); + if (err != E_SUCCESS) { + return err; + } + printf("%" PRIx64 "\n", out); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1762,6 +1776,7 @@ SUBCOMMAND_INDEX(areNeighborCells) SUBCOMMAND_INDEX(cellsToDirectedEdge) SUBCOMMAND_INDEX(isValidDirectedEdge) SUBCOMMAND_INDEX(getDirectedEdgeOrigin) +SUBCOMMAND_INDEX(getDirectedEdgeDestination) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getDirectedEdgeDestination.txt b/tests/cli/getDirectedEdgeDestination.txt new file mode 100644 index 000000000..7a67f2a0b --- /dev/null +++ b/tests/cli/getDirectedEdgeDestination.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetDirectedEdgeDestination "getDirectedEdgeDestination -c 115283473fffffff" "85283477fffffff") +add_h3_cli_test(testCliDoNotGetDirectedEdgeDestination "getDirectedEdgeDestination -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From 024d4e2c546324c6a4ebed230b2fa761d20e3e66 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:47:33 -0500 Subject: [PATCH 06/37] directedEdgeToCells --- src/apps/filters/h3.c | 16 ++++++++++++++++ tests/cli/directedEdgeToCells.txt | 2 ++ 2 files changed, 18 insertions(+) create mode 100644 tests/cli/directedEdgeToCells.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index ee23cb4a5..de0a80b57 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1729,6 +1729,21 @@ SUBCOMMAND(getDirectedEdgeDestination, return E_SUCCESS; } +SUBCOMMAND( + directedEdgeToCells, + "Returns the origin, destination pair of cells from the directed edge") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&directedEdgeToCellsArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out[2] = {0}; + H3Error err = H3_EXPORT(directedEdgeToCells)(cell, &out[0]); + if (err != E_SUCCESS) { + return err; + } + printf("[%" PRIx64 ", %" PRIx64 "]\n", out[0], out[1]); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1777,6 +1792,7 @@ SUBCOMMAND_INDEX(cellsToDirectedEdge) SUBCOMMAND_INDEX(isValidDirectedEdge) SUBCOMMAND_INDEX(getDirectedEdgeOrigin) SUBCOMMAND_INDEX(getDirectedEdgeDestination) +SUBCOMMAND_INDEX(directedEdgeToCells) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/directedEdgeToCells.txt b/tests/cli/directedEdgeToCells.txt new file mode 100644 index 000000000..c5f23c695 --- /dev/null +++ b/tests/cli/directedEdgeToCells.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliDirectedEdgeToCells "directedEdgeToCells -c 115283473fffffff" "[85283473fffffff, 85283477fffffff]") +add_h3_cli_test(testCliNotDirectedEdgeToCells "directedEdgeToCells -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From bbc5e7f9252b78a4b7a0c0744d0b62787944e653 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 17:59:27 -0500 Subject: [PATCH 07/37] originToDirectedEdges --- src/apps/filters/h3.c | 32 +++++++++++++++++++++++++++++ tests/cli/originToDirectedEdges.txt | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 tests/cli/originToDirectedEdges.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index de0a80b57..c1578b991 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1744,6 +1744,37 @@ SUBCOMMAND( return E_SUCCESS; } +SUBCOMMAND(originToDirectedEdges, + "Returns all of the directed edges from the specified origin cell") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&originToDirectedEdgesArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out[6] = {0}; + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + H3Error err = H3_EXPORT(originToDirectedEdges)(cell, &out[0]); + if (err != E_SUCCESS) { + return err; + } + printf("["); + bool hasPrinted = false; + for (int i = 0; i < 6; i++) { + if (out[i] > 0) { + if (hasPrinted) { + printf(", "); + } + printf("%" PRIx64, out[i]); + hasPrinted = true; + } + } + printf("]\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1793,6 +1824,7 @@ SUBCOMMAND_INDEX(isValidDirectedEdge) SUBCOMMAND_INDEX(getDirectedEdgeOrigin) SUBCOMMAND_INDEX(getDirectedEdgeDestination) SUBCOMMAND_INDEX(directedEdgeToCells) +SUBCOMMAND_INDEX(originToDirectedEdges) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/originToDirectedEdges.txt b/tests/cli/originToDirectedEdges.txt new file mode 100644 index 000000000..8c7c95e4b --- /dev/null +++ b/tests/cli/originToDirectedEdges.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliOriginToDirectedEdges "originToDirectedEdges -c 85283473fffffff" "[115283473fffffff, 125283473fffffff, 135283473fffffff, 145283473fffffff, 155283473fffffff, 165283473fffffff]") +add_h3_cli_test(testCliNotOriginToDirectedEdges "originToDirectedEdges -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From ca48447f02a5fedc2d975ec83694c97f881de6b2 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:05:50 -0500 Subject: [PATCH 08/37] directedEdgeToBoundary --- src/apps/filters/h3.c | 25 +++++++++++++++++++++++++ tests/cli/directedEdgeToBoundary.txt | 2 ++ 2 files changed, 27 insertions(+) create mode 100644 tests/cli/directedEdgeToBoundary.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index c1578b991..132b1c789 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1775,6 +1775,30 @@ SUBCOMMAND(originToDirectedEdges, return E_SUCCESS; } +SUBCOMMAND(directedEdgeToBoundary, + "Provides the coordinates defining the directed edge") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&directedEdgeToBoundaryArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + CellBoundary cb = {0}; + H3Error err = H3_EXPORT(directedEdgeToBoundary)(cell, &cb); + if (err) { + return err; + } + // Using WKT formatting for the output. TODO: Add support for JSON + // formatting + printf("POLYGON(("); + for (int i = 0; i < cb.numVerts; i++) { + LatLng *ll = &cb.verts[i]; + printf("%.10lf %.10lf, ", H3_EXPORT(radsToDegs)(ll->lng), + H3_EXPORT(radsToDegs)(ll->lat)); + } + // WKT has the first and last points match, so re-print the first one + printf("%.10lf %.10lf))\n", H3_EXPORT(radsToDegs)(cb.verts[0].lng), + H3_EXPORT(radsToDegs)(cb.verts[0].lat)); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1825,6 +1849,7 @@ SUBCOMMAND_INDEX(getDirectedEdgeOrigin) SUBCOMMAND_INDEX(getDirectedEdgeDestination) SUBCOMMAND_INDEX(directedEdgeToCells) SUBCOMMAND_INDEX(originToDirectedEdges) +SUBCOMMAND_INDEX(directedEdgeToBoundary) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/directedEdgeToBoundary.txt b/tests/cli/directedEdgeToBoundary.txt new file mode 100644 index 000000000..537f75927 --- /dev/null +++ b/tests/cli/directedEdgeToBoundary.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliDirectedEdgeToBoundary "directedEdgeToBoundary -c 115283473fffffff" "POLYGON((-122.0377349643 37.4201286777, -122.0904289290 37.3375560844, -122.0377349643 37.4201286777))") +add_h3_cli_test(testCliNotDirectedEdgeToBoundary "directedEdgeToBoundary -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From c4a8bebf605e2ae590871c4a6fbd595651185079 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:17:00 -0500 Subject: [PATCH 09/37] cellToVertex --- src/apps/filters/h3.c | 33 +++++++++++++++++++++++++++++++++ tests/cli/cellToVertex.txt | 2 ++ 2 files changed, 35 insertions(+) create mode 100644 tests/cli/cellToVertex.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 132b1c789..b278deb90 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1799,6 +1799,36 @@ SUBCOMMAND(directedEdgeToBoundary, return E_SUCCESS; } +/// Vertex subcommands + +SUBCOMMAND(cellToVertex, + "Returns the vertex for the specified cell and vertex index. Must " + "be 0-5 for hexagons, 0-4 for pentagons") { + DEFINE_CELL_ARG(cell, cellArg); + int vertIndex = 0; + Arg vertIndexArg = { + .names = {"-v", "--vertex"}, + .required = true, + .scanFormat = "%d", + .valueName = "INDEX", + .value = &vertIndex, + .helpText = "Vertex index number. 0-5 for hexagons, 0-4 for pentagons"}; + Arg *args[] = {&cellToVertexArg, &cellArg, &vertIndexArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This function also doesn't sanitize its inputs correctly + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + H3Index out = 0; + H3Error err = H3_EXPORT(cellToVertex)(cell, vertIndex, &out); + if (err) { + return err; + } + printf("%" PRIx64 "\n", out); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1851,6 +1881,9 @@ SUBCOMMAND_INDEX(directedEdgeToCells) SUBCOMMAND_INDEX(originToDirectedEdges) SUBCOMMAND_INDEX(directedEdgeToBoundary) +/// Vertex subcommands +SUBCOMMAND_INDEX(cellToVertex) + END_SUBCOMMANDS_INDEX int main(int argc, char *argv[]) { diff --git a/tests/cli/cellToVertex.txt b/tests/cli/cellToVertex.txt new file mode 100644 index 000000000..3efa6d2fd --- /dev/null +++ b/tests/cli/cellToVertex.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellToVertex "cellToVertex -c 85283473fffffff -v 0" "22528340bfffffff") +add_h3_cli_test(testCliNotCellToVertex "cellToVertex -c 115283473fffffff -v 0 2>&1" "Error 5: Cell argument was not valid") From d0159f09ace1de52c53b346d437f359fa898763b Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:23:00 -0500 Subject: [PATCH 10/37] cellToVertexes --- src/apps/filters/h3.c | 32 ++++++++++++++++++++++++++++++++ tests/cli/cellToVertexes.txt | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 tests/cli/cellToVertexes.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index b278deb90..18f1939b7 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1829,6 +1829,37 @@ SUBCOMMAND(cellToVertex, return E_SUCCESS; } +SUBCOMMAND(cellToVertexes, + "Returns all of the vertexes from the specified cell") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&cellToVertexesArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index out[6] = {0}; + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + H3Error err = H3_EXPORT(cellToVertexes)(cell, &out[0]); + if (err != E_SUCCESS) { + return err; + } + printf("["); + bool hasPrinted = false; + for (int i = 0; i < 6; i++) { + if (out[i] > 0) { + if (hasPrinted) { + printf(", "); + } + printf("%" PRIx64, out[i]); + hasPrinted = true; + } + } + printf("]\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1883,6 +1914,7 @@ SUBCOMMAND_INDEX(directedEdgeToBoundary) /// Vertex subcommands SUBCOMMAND_INDEX(cellToVertex) +SUBCOMMAND_INDEX(cellToVertexes) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/cellToVertexes.txt b/tests/cli/cellToVertexes.txt new file mode 100644 index 000000000..52f24bb79 --- /dev/null +++ b/tests/cli/cellToVertexes.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellToVertexes "cellToVertexes -c 85283473fffffff" "[22528340bfffffff, 235283447fffffff, 205283463fffffff, 255283463fffffff, 22528340ffffffff, 23528340bfffffff]") +add_h3_cli_test(testCliNotCellToVertexes "cellToVertexes -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From 4dffda1ec5b8b633d1c4dbaa9af760f69c2b0f2a Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:30:12 -0500 Subject: [PATCH 11/37] vertexToLatLng --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/vertexToLatLng.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/vertexToLatLng.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 18f1939b7..10d79c6cd 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1860,6 +1860,26 @@ SUBCOMMAND(cellToVertexes, return E_SUCCESS; } +SUBCOMMAND(vertexToLatLng, "Returns the lat, lng pair for the given vertex") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&vertexToLatLngArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + bool isValid = H3_EXPORT(isValidVertex)(cell); + if (!isValid) { + return E_VERTEX_INVALID; + } + LatLng ll; + H3Error err = H3_EXPORT(vertexToLatLng)(cell, &ll); + if (err) { + return err; + } + // Using WKT formatting for the output. TODO: Add support for JSON + // formatting + printf("POINT(%.10lf %.10lf)\n", H3_EXPORT(radsToDegs)(ll.lng), + H3_EXPORT(radsToDegs)(ll.lat)); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1915,6 +1935,7 @@ SUBCOMMAND_INDEX(directedEdgeToBoundary) /// Vertex subcommands SUBCOMMAND_INDEX(cellToVertex) SUBCOMMAND_INDEX(cellToVertexes) +SUBCOMMAND_INDEX(vertexToLatLng) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/vertexToLatLng.txt b/tests/cli/vertexToLatLng.txt new file mode 100644 index 000000000..7204b3d1c --- /dev/null +++ b/tests/cli/vertexToLatLng.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliVertexToLatLng "vertexToLatLng -c 22528340bfffffff" "POINT(-121.9150803271 37.2713558667)") +add_h3_cli_test(testCliNotVertexToLatLng "vertexToLatLng -c 85283473fffffff 2>&1" "Error 8: Vertex argument was not valid") From 729d95f292f77b4977783dc3749d9a4dd5de3792 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:34:11 -0500 Subject: [PATCH 12/37] isValidVertex --- src/apps/filters/h3.c | 11 +++++++++++ tests/cli/isValidVertex.txt | 2 ++ 2 files changed, 13 insertions(+) create mode 100644 tests/cli/isValidVertex.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 10d79c6cd..a2d8c4c01 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1880,6 +1880,16 @@ SUBCOMMAND(vertexToLatLng, "Returns the lat, lng pair for the given vertex") { return E_SUCCESS; } +SUBCOMMAND(isValidVertex, + "Checks if the provided H3 vertex is actually valid") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&isValidVertexArg, &helpArg, &cellArg}; + PARSE_SUBCOMMAND(argc, argv, args); + bool isValid = H3_EXPORT(isValidVertex)(cell); + printf("%s", isValid ? "true\n" : "false\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1936,6 +1946,7 @@ SUBCOMMAND_INDEX(directedEdgeToBoundary) SUBCOMMAND_INDEX(cellToVertex) SUBCOMMAND_INDEX(cellToVertexes) SUBCOMMAND_INDEX(vertexToLatLng) +SUBCOMMAND_INDEX(isValidVertex) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/isValidVertex.txt b/tests/cli/isValidVertex.txt new file mode 100644 index 000000000..d52d98a89 --- /dev/null +++ b/tests/cli/isValidVertex.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliIsValidVertex "isValidVertex -c 22528340bfffffff" "true") +add_h3_cli_test(testCliIsNotValidVertex "isValidVertex -c 85283473fffffff" "false") From 35188b829d28cabb7ed7a1cd0c73adba2ff2f18b Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 18:58:50 -0500 Subject: [PATCH 13/37] degsToRads radsToDegs --- src/apps/filters/h3.c | 34 ++++++++++++++++++++++++++++++++++ tests/cli/degsToRads.txt | 1 + tests/cli/radsToDegs.txt | 1 + 3 files changed, 36 insertions(+) create mode 100644 tests/cli/degsToRads.txt create mode 100644 tests/cli/radsToDegs.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index a2d8c4c01..095532573 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1890,6 +1890,36 @@ SUBCOMMAND(isValidVertex, return E_SUCCESS; } +/// Miscellaneous subcommands + +SUBCOMMAND(degsToRads, "Converts degrees to radians") { + double deg = 0; + Arg degArg = {.names = {"-d", "--degree"}, + .required = true, + .scanFormat = "%lf", + .valueName = "DEG", + .value = °, + .helpText = "Angle in degrees"}; + Arg *args[] = {°sToRadsArg, °Arg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + printf("%.10lf\n", H3_EXPORT(degsToRads)(deg)); + return E_SUCCESS; +} + +SUBCOMMAND(radsToDegs, "Converts radians to degrees") { + double rad = 0; + Arg radArg = {.names = {"-r", "--radian"}, + .required = true, + .scanFormat = "%lf", + .valueName = "RAD", + .value = &rad, + .helpText = "Angle in radians"}; + Arg *args[] = {&radsToDegsArg, &radArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + printf("%.10lf\n", H3_EXPORT(radsToDegs)(rad)); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1948,6 +1978,10 @@ SUBCOMMAND_INDEX(cellToVertexes) SUBCOMMAND_INDEX(vertexToLatLng) SUBCOMMAND_INDEX(isValidVertex) +/// Miscellaneous subcommands +SUBCOMMAND_INDEX(degsToRads) +SUBCOMMAND_INDEX(radsToDegs) + END_SUBCOMMANDS_INDEX int main(int argc, char *argv[]) { diff --git a/tests/cli/degsToRads.txt b/tests/cli/degsToRads.txt new file mode 100644 index 000000000..a59b5299e --- /dev/null +++ b/tests/cli/degsToRads.txt @@ -0,0 +1 @@ +add_h3_cli_test(testCliDegsToRads "degsToRads -d 180" "3.1415926536") diff --git a/tests/cli/radsToDegs.txt b/tests/cli/radsToDegs.txt new file mode 100644 index 000000000..d864100e6 --- /dev/null +++ b/tests/cli/radsToDegs.txt @@ -0,0 +1 @@ +add_h3_cli_test(testCliRadsToDegs "radsToDegs -r 3.1415926536" "180.0000000006") From a1ba8e1d3e5288720d9cfba9f3db0436ea7fa221 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:08:22 -0500 Subject: [PATCH 14/37] getHexagonAreaAvgKm2 --- src/apps/filters/h3.c | 22 ++++++++++++++++++++++ tests/cli/getHexagonAreaAvgKm2.txt | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 tests/cli/getHexagonAreaAvgKm2.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 095532573..445c5e51e 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1920,6 +1920,27 @@ SUBCOMMAND(radsToDegs, "Converts radians to degrees") { return E_SUCCESS; } +SUBCOMMAND(getHexagonAreaAvgKm2, + "The average area in square kilometers for a hexagon of a given " + "resolution (excludes pentagons)") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getHexagonAreaAvgKm2Arg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + double area = 0; + H3Error err = H3_EXPORT(getHexagonAreaAvgKm2)(res, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -1981,6 +2002,7 @@ SUBCOMMAND_INDEX(isValidVertex) /// Miscellaneous subcommands SUBCOMMAND_INDEX(degsToRads) SUBCOMMAND_INDEX(radsToDegs) +SUBCOMMAND_INDEX(getHexagonAreaAvgKm2) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getHexagonAreaAvgKm2.txt b/tests/cli/getHexagonAreaAvgKm2.txt new file mode 100644 index 000000000..c1a4c6946 --- /dev/null +++ b/tests/cli/getHexagonAreaAvgKm2.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetHexagonAreaAvgKm2 "getHexagonAreaAvgKm2 -r 0" "4357449.4160783831") +add_h3_cli_test(testCliDontGetHexagonAreaAvgKm2 "getHexagonAreaAvgKm2 -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From d6685fa0826828100c87391dc3d7ca0e6d367cf8 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:13:39 -0500 Subject: [PATCH 15/37] getHexagonAreaAvgM2 --- src/apps/filters/h3.c | 22 ++++++++++++++++++++++ tests/cli/getHexagonAreaAvgM2.txt | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 tests/cli/getHexagonAreaAvgM2.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 445c5e51e..126f1d1b5 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1941,6 +1941,27 @@ SUBCOMMAND(getHexagonAreaAvgKm2, return E_SUCCESS; } +SUBCOMMAND(getHexagonAreaAvgM2, + "The average area in square meters for a hexagon of a given " + "resolution (excludes pentagons)") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getHexagonAreaAvgM2Arg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + double area = 0; + H3Error err = H3_EXPORT(getHexagonAreaAvgM2)(res, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2003,6 +2024,7 @@ SUBCOMMAND_INDEX(isValidVertex) SUBCOMMAND_INDEX(degsToRads) SUBCOMMAND_INDEX(radsToDegs) SUBCOMMAND_INDEX(getHexagonAreaAvgKm2) +SUBCOMMAND_INDEX(getHexagonAreaAvgM2) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getHexagonAreaAvgM2.txt b/tests/cli/getHexagonAreaAvgM2.txt new file mode 100644 index 000000000..ecd48074d --- /dev/null +++ b/tests/cli/getHexagonAreaAvgM2.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetHexagonAreaAvgM2 "getHexagonAreaAvgM2 -r 0" "4357449416078.3901367188") +add_h3_cli_test(testCliDontGetHexagonAreaAvgM2 "getHexagonAreaAvgM2 -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From b44fb684051f1bc69302ac80d930dbc5ca08d34b Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:25:57 -0500 Subject: [PATCH 16/37] cellAreaRads2 --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/cellAreaRads2.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/cellAreaRads2.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 126f1d1b5..2dfdf9dbf 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1962,6 +1962,26 @@ SUBCOMMAND(getHexagonAreaAvgM2, return E_SUCCESS; } +SUBCOMMAND(cellAreaRads2, + "The exact area of a specific cell in square radians") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&cellAreaRads2Arg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + double area = 0; + H3Error err = H3_EXPORT(cellAreaRads2)(cell, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2025,6 +2045,7 @@ SUBCOMMAND_INDEX(degsToRads) SUBCOMMAND_INDEX(radsToDegs) SUBCOMMAND_INDEX(getHexagonAreaAvgKm2) SUBCOMMAND_INDEX(getHexagonAreaAvgM2) +SUBCOMMAND_INDEX(cellAreaRads2) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/cellAreaRads2.txt b/tests/cli/cellAreaRads2.txt new file mode 100644 index 000000000..20f865805 --- /dev/null +++ b/tests/cli/cellAreaRads2.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellAreaRads2 "cellAreaRads2 -c 85283473fffffff" "0.0000065310") +add_h3_cli_test(testCliNotCellAreaRads2 "cellAreaRads2 -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From e435c8a5b0050e968c50e42750628852b519358b Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:31:44 -0500 Subject: [PATCH 17/37] cellAreaKm2 --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/cellAreaKm2.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/cellAreaKm2.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 2dfdf9dbf..5395dcc93 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -1982,6 +1982,26 @@ SUBCOMMAND(cellAreaRads2, return E_SUCCESS; } +SUBCOMMAND(cellAreaKm2, + "The exact area of a specific cell in square kilometers") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&cellAreaKm2Arg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + double area = 0; + H3Error err = H3_EXPORT(cellAreaKm2)(cell, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2046,6 +2066,7 @@ SUBCOMMAND_INDEX(radsToDegs) SUBCOMMAND_INDEX(getHexagonAreaAvgKm2) SUBCOMMAND_INDEX(getHexagonAreaAvgM2) SUBCOMMAND_INDEX(cellAreaRads2) +SUBCOMMAND_INDEX(cellAreaKm2) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/cellAreaKm2.txt b/tests/cli/cellAreaKm2.txt new file mode 100644 index 000000000..4e976f3ad --- /dev/null +++ b/tests/cli/cellAreaKm2.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellAreaKm2 "cellAreaKm2 -c 85283473fffffff" "265.0925581283") +add_h3_cli_test(testCliNotCellAreaKm2 "cellAreaKm2 -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From a6fb01c42958c53b3203cc6eea72dbb34544a4f5 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:35:47 -0500 Subject: [PATCH 18/37] cellAreaM2 --- src/apps/filters/h3.c | 20 ++++++++++++++++++++ tests/cli/cellAreaM2.txt | 2 ++ 2 files changed, 22 insertions(+) create mode 100644 tests/cli/cellAreaM2.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 5395dcc93..cbefcafa6 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2002,6 +2002,25 @@ SUBCOMMAND(cellAreaKm2, return E_SUCCESS; } +SUBCOMMAND(cellAreaM2, "The exact area of a specific cell in square meters") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&cellAreaM2Arg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidCell)(cell); + if (!isValid) { + return E_CELL_INVALID; + } + double area = 0; + H3Error err = H3_EXPORT(cellAreaM2)(cell, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2067,6 +2086,7 @@ SUBCOMMAND_INDEX(getHexagonAreaAvgKm2) SUBCOMMAND_INDEX(getHexagonAreaAvgM2) SUBCOMMAND_INDEX(cellAreaRads2) SUBCOMMAND_INDEX(cellAreaKm2) +SUBCOMMAND_INDEX(cellAreaM2) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/cellAreaM2.txt b/tests/cli/cellAreaM2.txt new file mode 100644 index 000000000..5ec15f5fb --- /dev/null +++ b/tests/cli/cellAreaM2.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliCellAreaM2 "cellAreaM2 -c 85283473fffffff" "265092558.1282823086") +add_h3_cli_test(testCliNotCellAreaM2 "cellAreaM2 -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From b401b5b680c1ff66c08cd9a7d89b70c18d516ac7 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 19:48:43 -0500 Subject: [PATCH 19/37] getHexagonEdgeLengthAvgKm --- src/apps/filters/h3.c | 22 ++++++++++++++++++++++ tests/cli/getHexagonEdgeLengthAvgKm.txt | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 tests/cli/getHexagonEdgeLengthAvgKm.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index cbefcafa6..51080c00b 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2021,6 +2021,27 @@ SUBCOMMAND(cellAreaM2, "The exact area of a specific cell in square meters") { return E_SUCCESS; } +SUBCOMMAND(getHexagonEdgeLengthAvgKm, + "The average hexagon edge length in kilometers of a given " + "resolution (excludes pentagons)") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getHexagonEdgeLengthAvgKmArg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + double area = 0; + H3Error err = H3_EXPORT(getHexagonEdgeLengthAvgKm)(res, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2087,6 +2108,7 @@ SUBCOMMAND_INDEX(getHexagonAreaAvgM2) SUBCOMMAND_INDEX(cellAreaRads2) SUBCOMMAND_INDEX(cellAreaKm2) SUBCOMMAND_INDEX(cellAreaM2) +SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgKm) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getHexagonEdgeLengthAvgKm.txt b/tests/cli/getHexagonEdgeLengthAvgKm.txt new file mode 100644 index 000000000..44b9f0c47 --- /dev/null +++ b/tests/cli/getHexagonEdgeLengthAvgKm.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetHexagonEdgeLengthAvgKm "getHexagonEdgeLengthAvgKm -r 0" "1281.2560110000") +add_h3_cli_test(testCliDontGetHexagonEdgeLengthAvgKm "getHexagonEdgeLengthAvgKm -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From 82d1bc35669a3983c4790fce48c4aa1620a1c7a8 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:08:39 -0500 Subject: [PATCH 20/37] getHexagonEdgeLengthAvgM --- src/apps/filters/h3.c | 22 ++++++++++++++++++++++ tests/cli/getHexagonEdgeLengthAvgM.txt | 2 ++ 2 files changed, 24 insertions(+) create mode 100644 tests/cli/getHexagonEdgeLengthAvgM.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 51080c00b..75bf916a3 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2042,6 +2042,27 @@ SUBCOMMAND(getHexagonEdgeLengthAvgKm, return E_SUCCESS; } +SUBCOMMAND(getHexagonEdgeLengthAvgM, + "The average hexagon edge length in meters of a given " + "resolution (excludes pentagons)") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getHexagonEdgeLengthAvgMArg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + double area = 0; + H3Error err = H3_EXPORT(getHexagonEdgeLengthAvgM)(res, &area); + if (err) { + return err; + } + printf("%.10lf\n", area); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2109,6 +2130,7 @@ SUBCOMMAND_INDEX(cellAreaRads2) SUBCOMMAND_INDEX(cellAreaKm2) SUBCOMMAND_INDEX(cellAreaM2) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgKm) +SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgM) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getHexagonEdgeLengthAvgM.txt b/tests/cli/getHexagonEdgeLengthAvgM.txt new file mode 100644 index 000000000..022103101 --- /dev/null +++ b/tests/cli/getHexagonEdgeLengthAvgM.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetHexagonEdgeLengthAvgM "getHexagonEdgeLengthAvgM -r 0" "1281256.0109999999") +add_h3_cli_test(testCliDontGetHexagonEdgeLengthAvgM "getHexagonEdgeLengthAvgM -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From 8d180d57d22229c2361153244bd44d67b2c47446 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:33:48 -0500 Subject: [PATCH 21/37] edgeLengthKm --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/edgeLengthKm.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/edgeLengthKm.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 75bf916a3..a3dcb9c62 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2063,6 +2063,26 @@ SUBCOMMAND(getHexagonEdgeLengthAvgM, return E_SUCCESS; } +SUBCOMMAND(edgeLengthKm, + "The exact edge length of a specific directed edge in kilometers") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&edgeLengthKmArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidDirectedEdge)(cell); + if (!isValid) { + return E_DIR_EDGE_INVALID; + } + double length = 0; + H3Error err = H3_EXPORT(edgeLengthKm)(cell, &length); + if (err) { + return err; + } + printf("%.10lf\n", length); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2131,6 +2151,7 @@ SUBCOMMAND_INDEX(cellAreaKm2) SUBCOMMAND_INDEX(cellAreaM2) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgKm) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgM) +SUBCOMMAND_INDEX(edgeLengthKm) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/edgeLengthKm.txt b/tests/cli/edgeLengthKm.txt new file mode 100644 index 000000000..3c0cc8b4d --- /dev/null +++ b/tests/cli/edgeLengthKm.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliEdgeLengthKm "edgeLengthKm -c 115283473fffffff" "10.2947360862") +add_h3_cli_test(testCliNotEdgeLengthKm "edgeLengthKm -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From 20c2b58ad8e65d9cd527780f51ef413129e204c7 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:37:08 -0500 Subject: [PATCH 22/37] edgeLengthM --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/edgeLengthM.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/edgeLengthM.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index a3dcb9c62..fecb6e281 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2083,6 +2083,26 @@ SUBCOMMAND(edgeLengthKm, return E_SUCCESS; } +SUBCOMMAND(edgeLengthM, + "The exact edge length of a specific directed edge in meters") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&edgeLengthMArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidDirectedEdge)(cell); + if (!isValid) { + return E_DIR_EDGE_INVALID; + } + double length = 0; + H3Error err = H3_EXPORT(edgeLengthM)(cell, &length); + if (err) { + return err; + } + printf("%.10lf\n", length); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2152,6 +2172,7 @@ SUBCOMMAND_INDEX(cellAreaM2) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgKm) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgM) SUBCOMMAND_INDEX(edgeLengthKm) +SUBCOMMAND_INDEX(edgeLengthM) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/edgeLengthM.txt b/tests/cli/edgeLengthM.txt new file mode 100644 index 000000000..173cbe0f9 --- /dev/null +++ b/tests/cli/edgeLengthM.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliEdgeLengthM "edgeLengthM -c 115283473fffffff" "10294.7360861995") +add_h3_cli_test(testCliNotEdgeLengthM "edgeLengthM -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From 8faef796d51d54f7d9de6353ff985e37a5377b69 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:41:31 -0500 Subject: [PATCH 23/37] edgeLengthRads --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/edgeLengthRads.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/edgeLengthRads.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index fecb6e281..49863bf54 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2063,6 +2063,26 @@ SUBCOMMAND(getHexagonEdgeLengthAvgM, return E_SUCCESS; } +SUBCOMMAND(edgeLengthRads, + "The exact edge length of a specific directed edge in radians") { + DEFINE_CELL_ARG(cell, cellArg); + Arg *args[] = {&edgeLengthRadsArg, &cellArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + // This one is pretty loose about the inputs it accepts, so let's validate + // for it + bool isValid = H3_EXPORT(isValidDirectedEdge)(cell); + if (!isValid) { + return E_DIR_EDGE_INVALID; + } + double length = 0; + H3Error err = H3_EXPORT(edgeLengthRads)(cell, &length); + if (err) { + return err; + } + printf("%.10lf\n", length); + return E_SUCCESS; +} + SUBCOMMAND(edgeLengthKm, "The exact edge length of a specific directed edge in kilometers") { DEFINE_CELL_ARG(cell, cellArg); @@ -2171,6 +2191,7 @@ SUBCOMMAND_INDEX(cellAreaKm2) SUBCOMMAND_INDEX(cellAreaM2) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgKm) SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgM) +SUBCOMMAND_INDEX(edgeLengthRads) SUBCOMMAND_INDEX(edgeLengthKm) SUBCOMMAND_INDEX(edgeLengthM) diff --git a/tests/cli/edgeLengthRads.txt b/tests/cli/edgeLengthRads.txt new file mode 100644 index 000000000..8e3fbffb8 --- /dev/null +++ b/tests/cli/edgeLengthRads.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliEdgeLengthRads "edgeLengthRads -c 115283473fffffff" "0.0016158726") +add_h3_cli_test(testCliNotEdgeLengthRads "edgeLengthRads -c 85283473fffffff 2>&1" "Error 6: Directed edge argument was not valid") From aadc792524a53cd9b3fcf3decea6e15d237de23a Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:51:06 -0500 Subject: [PATCH 24/37] getNumCells --- src/apps/filters/h3.c | 21 +++++++++++++++++++++ tests/cli/getNumCells.txt | 2 ++ 2 files changed, 23 insertions(+) create mode 100644 tests/cli/getNumCells.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 49863bf54..305817983 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2123,6 +2123,26 @@ SUBCOMMAND(edgeLengthM, return E_SUCCESS; } +SUBCOMMAND(getNumCells, + "The number of unique H3 cells for a specified resolution") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getNumCellsArg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + int64_t numCells = 0; + H3Error err = H3_EXPORT(getNumCells)(res, &numCells); + if (err) { + return err; + } + printf("%" PRIu64 "\n", numCells); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2194,6 +2214,7 @@ SUBCOMMAND_INDEX(getHexagonEdgeLengthAvgM) SUBCOMMAND_INDEX(edgeLengthRads) SUBCOMMAND_INDEX(edgeLengthKm) SUBCOMMAND_INDEX(edgeLengthM) +SUBCOMMAND_INDEX(getNumCells) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getNumCells.txt b/tests/cli/getNumCells.txt new file mode 100644 index 000000000..de5e0cdda --- /dev/null +++ b/tests/cli/getNumCells.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetNumCells "getNumCells -r 0" "122") +add_h3_cli_test(testCliDontGetNumCells "getNumCells -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From 64cffa1dfa6700b53412a12560f50ab822948616 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 20:56:47 -0500 Subject: [PATCH 25/37] getRes0Cells --- src/apps/filters/h3.c | 24 ++++++++++++++++++++++++ tests/cli/getRes0Cells.txt | 1 + 2 files changed, 25 insertions(+) create mode 100644 tests/cli/getRes0Cells.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 305817983..777d347d3 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2143,6 +2143,29 @@ SUBCOMMAND(getNumCells, return E_SUCCESS; } +SUBCOMMAND(getRes0Cells, "Returns all of the resolution 0 cells") { + Arg *args[] = {&getRes0CellsArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index *out = calloc(122, sizeof(H3Index)); + H3Error err = H3_EXPORT(getRes0Cells)(out); + if (err != E_SUCCESS) { + return err; + } + printf("["); + bool hasPrinted = false; + for (int i = 0; i < 122; i++) { + if (out[i] > 0) { + if (hasPrinted) { + printf(", "); + } + printf("%" PRIx64, out[i]); + hasPrinted = true; + } + } + printf("]\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2215,6 +2238,7 @@ SUBCOMMAND_INDEX(edgeLengthRads) SUBCOMMAND_INDEX(edgeLengthKm) SUBCOMMAND_INDEX(edgeLengthM) SUBCOMMAND_INDEX(getNumCells) +SUBCOMMAND_INDEX(getRes0Cells) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getRes0Cells.txt b/tests/cli/getRes0Cells.txt new file mode 100644 index 000000000..437c9fc1a --- /dev/null +++ b/tests/cli/getRes0Cells.txt @@ -0,0 +1 @@ +add_h3_cli_test(testCliGetRes0Cells "getRes0Cells" "[8001fffffffffff, 8003fffffffffff, 8005fffffffffff, 8007fffffffffff, 8009fffffffffff, 800bfffffffffff, 800dfffffffffff, 800ffffffffffff, 8011fffffffffff, 8013fffffffffff, 8015fffffffffff, 8017fffffffffff, 8019fffffffffff, 801bfffffffffff, 801dfffffffffff, 801ffffffffffff, 8021fffffffffff, 8023fffffffffff, 8025fffffffffff, 8027fffffffffff, 8029fffffffffff, 802bfffffffffff, 802dfffffffffff, 802ffffffffffff, 8031fffffffffff, 8033fffffffffff, 8035fffffffffff, 8037fffffffffff, 8039fffffffffff, 803bfffffffffff, 803dfffffffffff, 803ffffffffffff, 8041fffffffffff, 8043fffffffffff, 8045fffffffffff, 8047fffffffffff, 8049fffffffffff, 804bfffffffffff, 804dfffffffffff, 804ffffffffffff, 8051fffffffffff, 8053fffffffffff, 8055fffffffffff, 8057fffffffffff, 8059fffffffffff, 805bfffffffffff, 805dfffffffffff, 805ffffffffffff, 8061fffffffffff, 8063fffffffffff, 8065fffffffffff, 8067fffffffffff, 8069fffffffffff, 806bfffffffffff, 806dfffffffffff, 806ffffffffffff, 8071fffffffffff, 8073fffffffffff, 8075fffffffffff, 8077fffffffffff, 8079fffffffffff, 807bfffffffffff, 807dfffffffffff, 807ffffffffffff, 8081fffffffffff, 8083fffffffffff, 8085fffffffffff, 8087fffffffffff, 8089fffffffffff, 808bfffffffffff, 808dfffffffffff, 808ffffffffffff, 8091fffffffffff, 8093fffffffffff, 8095fffffffffff, 8097fffffffffff, 8099fffffffffff, 809bfffffffffff, 809dfffffffffff, 809ffffffffffff, 80a1fffffffffff, 80a3fffffffffff, 80a5fffffffffff, 80a7fffffffffff, 80a9fffffffffff, 80abfffffffffff, 80adfffffffffff, 80affffffffffff, 80b1fffffffffff, 80b3fffffffffff, 80b5fffffffffff, 80b7fffffffffff, 80b9fffffffffff, 80bbfffffffffff, 80bdfffffffffff, 80bffffffffffff, 80c1fffffffffff, 80c3fffffffffff, 80c5fffffffffff, 80c7fffffffffff, 80c9fffffffffff, 80cbfffffffffff, 80cdfffffffffff, 80cffffffffffff, 80d1fffffffffff, 80d3fffffffffff, 80d5fffffffffff, 80d7fffffffffff, 80d9fffffffffff, 80dbfffffffffff, 80ddfffffffffff, 80dffffffffffff, 80e1fffffffffff, 80e3fffffffffff, 80e5fffffffffff, 80e7fffffffffff, 80e9fffffffffff, 80ebfffffffffff, 80edfffffffffff, 80effffffffffff, 80f1fffffffffff, 80f3fffffffffff]") From 7ebe10d4c8d21d9b2cbe5ee307eb8430a27fa1b7 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:01:38 -0500 Subject: [PATCH 26/37] getPentagons --- src/apps/filters/h3.c | 32 ++++++++++++++++++++++++++++++++ tests/cli/getPentagons.txt | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 tests/cli/getPentagons.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 777d347d3..7a8b2b4de 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2166,6 +2166,37 @@ SUBCOMMAND(getRes0Cells, "Returns all of the resolution 0 cells") { return E_SUCCESS; } +SUBCOMMAND(getPentagons, + "Returns all of the pentagons at the specified resolution") { + int res = 0; + Arg resArg = {.names = {"-r", "--resolution"}, + .required = true, + .scanFormat = "%d", + .valueName = "res", + .value = &res, + .helpText = "Resolution, 0-15 inclusive."}; + Arg *args[] = {&getPentagonsArg, &resArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + H3Index *out = calloc(12, sizeof(H3Index)); + H3Error err = H3_EXPORT(getPentagons)(res, out); + if (err != E_SUCCESS) { + return err; + } + printf("["); + bool hasPrinted = false; + for (int i = 0; i < 12; i++) { + if (out[i] > 0) { + if (hasPrinted) { + printf(", "); + } + printf("%" PRIx64, out[i]); + hasPrinted = true; + } + } + printf("]\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2239,6 +2270,7 @@ SUBCOMMAND_INDEX(edgeLengthKm) SUBCOMMAND_INDEX(edgeLengthM) SUBCOMMAND_INDEX(getNumCells) SUBCOMMAND_INDEX(getRes0Cells) +SUBCOMMAND_INDEX(getPentagons) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/getPentagons.txt b/tests/cli/getPentagons.txt new file mode 100644 index 000000000..60f3abe41 --- /dev/null +++ b/tests/cli/getPentagons.txt @@ -0,0 +1,2 @@ +add_h3_cli_test(testCliGetPentagons "getPentagons -r 0" "[8009fffffffffff, 801dfffffffffff, 8031fffffffffff, 804dfffffffffff, 8063fffffffffff, 8075fffffffffff, 807ffffffffffff, 8091fffffffffff, 80a7fffffffffff, 80c3fffffffffff, 80d7fffffffffff, 80ebfffffffffff]") +add_h3_cli_test(testCliDontGetPentagons "getPentagons -r 20 2>&1" "Error 4: Resolution argument was outside of acceptable range") From 3a5690e40e7f2539b1b12be8b35128c6c23056a6 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:06:26 -0500 Subject: [PATCH 27/37] pentagonCount --- src/apps/filters/h3.c | 8 ++++++++ tests/cli/pentagonCount.txt | 1 + 2 files changed, 9 insertions(+) create mode 100644 tests/cli/pentagonCount.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 7a8b2b4de..d0bb7ed35 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2197,6 +2197,13 @@ SUBCOMMAND(getPentagons, return E_SUCCESS; } +SUBCOMMAND(pentagonCount, "Returns 12") { + Arg *args[] = {&pentagonCountArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + printf("12\n"); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2271,6 +2278,7 @@ SUBCOMMAND_INDEX(edgeLengthM) SUBCOMMAND_INDEX(getNumCells) SUBCOMMAND_INDEX(getRes0Cells) SUBCOMMAND_INDEX(getPentagons) +SUBCOMMAND_INDEX(pentagonCount) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/pentagonCount.txt b/tests/cli/pentagonCount.txt new file mode 100644 index 000000000..bc79f391a --- /dev/null +++ b/tests/cli/pentagonCount.txt @@ -0,0 +1 @@ +add_h3_cli_test(testCliPentagonCount "pentagonCount" "12") From 0d226b525764c31d4c1609d348155d6417b47d53 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:23:51 -0500 Subject: [PATCH 28/37] greatCircleDistanceKm --- src/apps/filters/h3.c | 67 ++++++++++++++++++++++ tests/cli/greatCircleDistanceKm.txt | 4 ++ tests/inputfiles/great_circle_distance.txt | 1 + 3 files changed, 72 insertions(+) create mode 100644 tests/cli/greatCircleDistanceKm.txt create mode 100644 tests/inputfiles/great_circle_distance.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index d0bb7ed35..afb33b090 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2204,6 +2204,72 @@ SUBCOMMAND(pentagonCount, "Returns 12") { return E_SUCCESS; } +SUBCOMMAND(greatCircleDistanceKm, + "Calculates the 'great circle' or 'haversine' distance between two " + "lat, lng points, in kilometers") { + char filename[1024] = {0}; // More than Windows, lol + Arg filenameArg = {.names = {"-f", "--file"}, + .scanFormat = "%1023c", + .valueName = "FILENAME", + .value = &filename, + .helpText = + "The file to load the coordinates from. Use -- to " + "read from stdin."}; + char coordinateStr[1501] = {0}; + Arg coordinateStrArg = { + .names = {"-c", "--coordinates"}, + .scanFormat = "%1500c", + .valueName = "ARRAY", + .value = &coordinateStr, + .helpText = + "The array of coordinates to convert. Up to 1500 characters."}; + Arg *args[] = {&greatCircleDistanceKmArg, &filenameArg, &coordinateStrArg, + &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + if (!filenameArg.found && !coordinateStrArg.found) { + fprintf( + stderr, + "You must provide either a file to read from or a coordinate array " + "to use greatCircleDistanceKm"); + exit(1); + } + FILE *fp = 0; + bool isStdin = false; + if (filenameArg.found) { + if (strcmp(filename, "--") == 0) { + fp = stdin; + isStdin = true; + } else { + fp = fopen(filename, "r"); + } + if (fp == 0) { + fprintf(stderr, "The specified file does not exist."); + exit(1); + } + // Do the initial population of data from the file + if (fread(coordinateStr, 1, 1500, fp) == 0) { + fprintf(stderr, "The specified file is empty."); + exit(1); + } + } + GeoPolygon polygon = {0}; + H3Error err = polygonStringToGeoPolygon(fp, coordinateStr, &polygon); + if (fp != 0 && !isStdin) { + fclose(fp); + } + if (err != E_SUCCESS) { + return err; + } + if (polygon.numHoles > 0 || polygon.geoloop.numVerts != 2) { + fprintf(stderr, "Only two pairs of coordinates should be provided."); + exit(1); + } + double distance = H3_EXPORT(greatCircleDistanceKm)( + &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); + printf("%.10lf\n", distance); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2279,6 +2345,7 @@ SUBCOMMAND_INDEX(getNumCells) SUBCOMMAND_INDEX(getRes0Cells) SUBCOMMAND_INDEX(getPentagons) SUBCOMMAND_INDEX(pentagonCount) +SUBCOMMAND_INDEX(greatCircleDistanceKm) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/greatCircleDistanceKm.txt b/tests/cli/greatCircleDistanceKm.txt new file mode 100644 index 000000000..b75391b1f --- /dev/null +++ b/tests/cli/greatCircleDistanceKm.txt @@ -0,0 +1,4 @@ +add_h3_cli_test(testCliGreatCircleDistanceKmArg "greatCircleDistanceKm -c '[[0, 1], [1, 2]]'" "157.2495585118") +add_h3_cli_test(testCliGreatCircleDistanceKmFile "greatCircleDistanceKm -f ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "157.2495585118") +add_h3_cli_test(testCliGreatCircleDistanceKmStdin "greatCircleDistanceKm -f -- < ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "157.2495585118") +add_h3_cli_test(testCliGreatCircleDistanceKmBadArg "greatCircleDistanceKm -c '[[0, 1]]' 2>&1" "Only two pairs of coordinates should be provided.") diff --git a/tests/inputfiles/great_circle_distance.txt b/tests/inputfiles/great_circle_distance.txt new file mode 100644 index 000000000..0b812a23d --- /dev/null +++ b/tests/inputfiles/great_circle_distance.txt @@ -0,0 +1 @@ +[[0, 1], [1, 2]] From 4dd179f322811b7c3d6d1063dc84fa99bdf24358 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:28:08 -0500 Subject: [PATCH 29/37] greatCircleDistanceM --- src/apps/filters/h3.c | 67 ++++++++++++++++++++++++++++++ tests/cli/greatCircleDistanceM.txt | 4 ++ 2 files changed, 71 insertions(+) create mode 100644 tests/cli/greatCircleDistanceM.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index afb33b090..b9bacfbc1 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2270,6 +2270,72 @@ SUBCOMMAND(greatCircleDistanceKm, return E_SUCCESS; } +SUBCOMMAND(greatCircleDistanceM, + "Calculates the 'great circle' or 'haversine' distance between two " + "lat, lng points, in meters") { + char filename[1024] = {0}; // More than Windows, lol + Arg filenameArg = {.names = {"-f", "--file"}, + .scanFormat = "%1023c", + .valueName = "FILENAME", + .value = &filename, + .helpText = + "The file to load the coordinates from. Use -- to " + "read from stdin."}; + char coordinateStr[1501] = {0}; + Arg coordinateStrArg = { + .names = {"-c", "--coordinates"}, + .scanFormat = "%1500c", + .valueName = "ARRAY", + .value = &coordinateStr, + .helpText = + "The array of coordinates to convert. Up to 1500 characters."}; + Arg *args[] = {&greatCircleDistanceMArg, &filenameArg, &coordinateStrArg, + &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + if (!filenameArg.found && !coordinateStrArg.found) { + fprintf( + stderr, + "You must provide either a file to read from or a coordinate array " + "to use greatCircleDistanceM"); + exit(1); + } + FILE *fp = 0; + bool isStdin = false; + if (filenameArg.found) { + if (strcmp(filename, "--") == 0) { + fp = stdin; + isStdin = true; + } else { + fp = fopen(filename, "r"); + } + if (fp == 0) { + fprintf(stderr, "The specified file does not exist."); + exit(1); + } + // Do the initial population of data from the file + if (fread(coordinateStr, 1, 1500, fp) == 0) { + fprintf(stderr, "The specified file is empty."); + exit(1); + } + } + GeoPolygon polygon = {0}; + H3Error err = polygonStringToGeoPolygon(fp, coordinateStr, &polygon); + if (fp != 0 && !isStdin) { + fclose(fp); + } + if (err != E_SUCCESS) { + return err; + } + if (polygon.numHoles > 0 || polygon.geoloop.numVerts != 2) { + fprintf(stderr, "Only two pairs of coordinates should be provided."); + exit(1); + } + double distance = H3_EXPORT(greatCircleDistanceM)( + &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); + printf("%.10lf\n", distance); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2346,6 +2412,7 @@ SUBCOMMAND_INDEX(getRes0Cells) SUBCOMMAND_INDEX(getPentagons) SUBCOMMAND_INDEX(pentagonCount) SUBCOMMAND_INDEX(greatCircleDistanceKm) +SUBCOMMAND_INDEX(greatCircleDistanceM) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/greatCircleDistanceM.txt b/tests/cli/greatCircleDistanceM.txt new file mode 100644 index 000000000..2e0bbfea5 --- /dev/null +++ b/tests/cli/greatCircleDistanceM.txt @@ -0,0 +1,4 @@ +add_h3_cli_test(testCliGreatCircleDistanceMArg "greatCircleDistanceM -c '[[0, 1], [1, 2]]'" "157249.5585117787") +add_h3_cli_test(testCliGreatCircleDistanceMFile "greatCircleDistanceM -f ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "157249.5585117787") +add_h3_cli_test(testCliGreatCircleDistanceMStdin "greatCircleDistanceM -f -- < ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "157249.5585117787") +add_h3_cli_test(testCliGreatCircleDistanceMBadArg "greatCircleDistanceM -c '[[0, 1]]' 2>&1" "Only two pairs of coordinates should be provided.") From 64e4041e90871aa945d1414c9f63573fe6cbf839 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:32:38 -0500 Subject: [PATCH 30/37] greatCircleDistanceRads --- src/apps/filters/h3.c | 67 +++++++++++++++++++++++++++ tests/cli/greatCircleDistanceRads.txt | 4 ++ 2 files changed, 71 insertions(+) create mode 100644 tests/cli/greatCircleDistanceRads.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index b9bacfbc1..aa578b636 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2204,6 +2204,72 @@ SUBCOMMAND(pentagonCount, "Returns 12") { return E_SUCCESS; } +SUBCOMMAND(greatCircleDistanceRads, + "Calculates the 'great circle' or 'haversine' distance between two " + "lat, lng points, in radians") { + char filename[1024] = {0}; // More than Windows, lol + Arg filenameArg = {.names = {"-f", "--file"}, + .scanFormat = "%1023c", + .valueName = "FILENAME", + .value = &filename, + .helpText = + "The file to load the coordinates from. Use -- to " + "read from stdin."}; + char coordinateStr[1501] = {0}; + Arg coordinateStrArg = { + .names = {"-c", "--coordinates"}, + .scanFormat = "%1500c", + .valueName = "ARRAY", + .value = &coordinateStr, + .helpText = + "The array of coordinates to convert. Up to 1500 characters."}; + Arg *args[] = {&greatCircleDistanceRadsArg, &filenameArg, &coordinateStrArg, + &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + if (!filenameArg.found && !coordinateStrArg.found) { + fprintf( + stderr, + "You must provide either a file to read from or a coordinate array " + "to use greatCircleDistanceRads"); + exit(1); + } + FILE *fp = 0; + bool isStdin = false; + if (filenameArg.found) { + if (strcmp(filename, "--") == 0) { + fp = stdin; + isStdin = true; + } else { + fp = fopen(filename, "r"); + } + if (fp == 0) { + fprintf(stderr, "The specified file does not exist."); + exit(1); + } + // Do the initial population of data from the file + if (fread(coordinateStr, 1, 1500, fp) == 0) { + fprintf(stderr, "The specified file is empty."); + exit(1); + } + } + GeoPolygon polygon = {0}; + H3Error err = polygonStringToGeoPolygon(fp, coordinateStr, &polygon); + if (fp != 0 && !isStdin) { + fclose(fp); + } + if (err != E_SUCCESS) { + return err; + } + if (polygon.numHoles > 0 || polygon.geoloop.numVerts != 2) { + fprintf(stderr, "Only two pairs of coordinates should be provided."); + exit(1); + } + double distance = H3_EXPORT(greatCircleDistanceRads)( + &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); + printf("%.10lf\n", distance); + return E_SUCCESS; +} + SUBCOMMAND(greatCircleDistanceKm, "Calculates the 'great circle' or 'haversine' distance between two " "lat, lng points, in kilometers") { @@ -2411,6 +2477,7 @@ SUBCOMMAND_INDEX(getNumCells) SUBCOMMAND_INDEX(getRes0Cells) SUBCOMMAND_INDEX(getPentagons) SUBCOMMAND_INDEX(pentagonCount) +SUBCOMMAND_INDEX(greatCircleDistanceRads) SUBCOMMAND_INDEX(greatCircleDistanceKm) SUBCOMMAND_INDEX(greatCircleDistanceM) diff --git a/tests/cli/greatCircleDistanceRads.txt b/tests/cli/greatCircleDistanceRads.txt new file mode 100644 index 000000000..af4d2b499 --- /dev/null +++ b/tests/cli/greatCircleDistanceRads.txt @@ -0,0 +1,4 @@ +add_h3_cli_test(testCliGreatCircleDistanceRadsArg "greatCircleDistanceRads -c '[[0, 1], [1, 2]]'" "0.0246820564") +add_h3_cli_test(testCliGreatCircleDistanceRadsFile "greatCircleDistanceRads -f ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "0.0246820564") +add_h3_cli_test(testCliGreatCircleDistanceRadsStdin "greatCircleDistanceRads -f -- < ${PROJECT_SOURCE_DIR}/tests/inputfiles/great_circle_distance.txt" "0.0246820564") +add_h3_cli_test(testCliGreatCircleDistanceRadsBadArg "greatCircleDistanceRads -c '[[0, 1]]' 2>&1" "Only two pairs of coordinates should be provided.") From 0e9017891c351516bf0a1b222af50113c9356409 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:42:49 -0500 Subject: [PATCH 31/37] describeH3Error --- src/apps/filters/h3.c | 17 +++++++++++++++++ tests/cli/describeH3Error.txt | 4 ++++ 2 files changed, 21 insertions(+) create mode 100644 tests/cli/describeH3Error.txt diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index aa578b636..2eaf4ad9d 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2402,6 +2402,22 @@ SUBCOMMAND(greatCircleDistanceM, return E_SUCCESS; } +SUBCOMMAND(describeH3Error, + "Returns a description of the provided H3 error code number, or " + "indicates the number is itself invalid.") { + H3Error err = E_SUCCESS; + Arg errArg = {.names = {"-e", "--error"}, + .required = true, + .scanFormat = "%d", + .valueName = "CODE", + .value = &err, + .helpText = "H3 Error code to describe"}; + Arg *args[] = {&describeH3ErrorArg, &errArg, &helpArg}; + PARSE_SUBCOMMAND(argc, argv, args); + printf("%s\n", H3_EXPORT(describeH3Error)(err)); + return E_SUCCESS; +} + // TODO: Is there any way to avoid this particular piece of duplication? SUBCOMMANDS_INDEX @@ -2480,6 +2496,7 @@ SUBCOMMAND_INDEX(pentagonCount) SUBCOMMAND_INDEX(greatCircleDistanceRads) SUBCOMMAND_INDEX(greatCircleDistanceKm) SUBCOMMAND_INDEX(greatCircleDistanceM) +SUBCOMMAND_INDEX(describeH3Error) END_SUBCOMMANDS_INDEX diff --git a/tests/cli/describeH3Error.txt b/tests/cli/describeH3Error.txt new file mode 100644 index 000000000..fcc55b990 --- /dev/null +++ b/tests/cli/describeH3Error.txt @@ -0,0 +1,4 @@ +add_h3_cli_test(testCliDescribeH3Error0 "describeH3Error -e 0" "Success") +add_h3_cli_test(testCliDescribeH3Error10 "describeH3Error -e 10" "Duplicate input") +add_h3_cli_test(testCliDescribeH3Error13 "describeH3Error -e 13" "Memory allocation failed") +add_h3_cli_test(testCliDescribeH3Error100 "describeH3Error -e 100" "Invalid error code") From adb66d239d6b67368834f471e31ea629a58517cc Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 21:54:14 -0500 Subject: [PATCH 32/37] Add some forgotten free() calls --- src/apps/filters/h3.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 2eaf4ad9d..76554e110 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2163,6 +2163,7 @@ SUBCOMMAND(getRes0Cells, "Returns all of the resolution 0 cells") { } } printf("]\n"); + free(out); return E_SUCCESS; } @@ -2194,6 +2195,7 @@ SUBCOMMAND(getPentagons, } } printf("]\n"); + free(out); return E_SUCCESS; } @@ -2267,6 +2269,11 @@ SUBCOMMAND(greatCircleDistanceRads, double distance = H3_EXPORT(greatCircleDistanceRads)( &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); printf("%.10lf\n", distance); + for (int i = 0; i < polygon.numHoles; i++) { + free(polygon.holes[i].verts); + } + free(polygon.holes); + free(polygon.geoloop.verts); return E_SUCCESS; } @@ -2333,6 +2340,11 @@ SUBCOMMAND(greatCircleDistanceKm, double distance = H3_EXPORT(greatCircleDistanceKm)( &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); printf("%.10lf\n", distance); + for (int i = 0; i < polygon.numHoles; i++) { + free(polygon.holes[i].verts); + } + free(polygon.holes); + free(polygon.geoloop.verts); return E_SUCCESS; } @@ -2399,6 +2411,11 @@ SUBCOMMAND(greatCircleDistanceM, double distance = H3_EXPORT(greatCircleDistanceM)( &polygon.geoloop.verts[0], &polygon.geoloop.verts[1]); printf("%.10lf\n", distance); + for (int i = 0; i < polygon.numHoles; i++) { + free(polygon.holes[i].verts); + } + free(polygon.holes); + free(polygon.geoloop.verts); return E_SUCCESS; } From 8f2d3159592ca70a3cd00a0a74af4edb0cb6bfa4 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 22:04:38 -0500 Subject: [PATCH 33/37] Fix missing free()s in error paths --- src/apps/filters/h3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 76554e110..5788aa338 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2149,6 +2149,7 @@ SUBCOMMAND(getRes0Cells, "Returns all of the resolution 0 cells") { H3Index *out = calloc(122, sizeof(H3Index)); H3Error err = H3_EXPORT(getRes0Cells)(out); if (err != E_SUCCESS) { + free(out); return err; } printf("["); @@ -2181,6 +2182,7 @@ SUBCOMMAND(getPentagons, H3Index *out = calloc(12, sizeof(H3Index)); H3Error err = H3_EXPORT(getPentagons)(res, out); if (err != E_SUCCESS) { + free(out); return err; } printf("["); From e2ab2ad38ca083089a23f345daf39817086fde2a Mon Sep 17 00:00:00 2001 From: David Ellis Date: Wed, 9 Oct 2024 22:18:25 -0500 Subject: [PATCH 34/37] Add some rounding to a test that's failing on MacOS on ARM --- tests/cli/cellAreaM2.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cli/cellAreaM2.txt b/tests/cli/cellAreaM2.txt index 5ec15f5fb..004b7c7cb 100644 --- a/tests/cli/cellAreaM2.txt +++ b/tests/cli/cellAreaM2.txt @@ -1,2 +1,2 @@ -add_h3_cli_test(testCliCellAreaM2 "cellAreaM2 -c 85283473fffffff" "265092558.1282823086") +add_h3_cli_test(testCliCellAreaM2 "cellAreaM2 -c 85283473fffffff | xargs printf '%.3f'" "265092558.128") add_h3_cli_test(testCliNotCellAreaM2 "cellAreaM2 -c 115283473fffffff 2>&1" "Error 5: Cell argument was not valid") From 671d9473c5c037f202ddf0789aba7a46b2f63422 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Sun, 13 Oct 2024 15:23:53 -0500 Subject: [PATCH 35/37] Update src/apps/filters/h3.c Co-authored-by: Isaac Brodsky --- src/apps/filters/h3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 5788aa338..4a103ae5d 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2139,7 +2139,7 @@ SUBCOMMAND(getNumCells, if (err) { return err; } - printf("%" PRIu64 "\n", numCells); + printf("%" PRId64 "\n", numCells); return E_SUCCESS; } From d6a22f6d86e0c345bc1b5f654de9c2bafb421182 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Sun, 13 Oct 2024 19:58:06 -0500 Subject: [PATCH 36/37] Apply suggestions from code review Co-authored-by: Isaac Brodsky --- src/apps/filters/h3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 4a103ae5d..50b1b18ee 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2230,7 +2230,7 @@ SUBCOMMAND(greatCircleDistanceRads, Arg *args[] = {&greatCircleDistanceRadsArg, &filenameArg, &coordinateStrArg, &helpArg}; PARSE_SUBCOMMAND(argc, argv, args); - if (!filenameArg.found && !coordinateStrArg.found) { + if (filenameArg.found == coordinateStrArg.found) { fprintf( stderr, "You must provide either a file to read from or a coordinate array " @@ -2301,7 +2301,7 @@ SUBCOMMAND(greatCircleDistanceKm, Arg *args[] = {&greatCircleDistanceKmArg, &filenameArg, &coordinateStrArg, &helpArg}; PARSE_SUBCOMMAND(argc, argv, args); - if (!filenameArg.found && !coordinateStrArg.found) { + if (filenameArg.found == coordinateStrArg.found) { fprintf( stderr, "You must provide either a file to read from or a coordinate array " @@ -2372,7 +2372,7 @@ SUBCOMMAND(greatCircleDistanceM, Arg *args[] = {&greatCircleDistanceMArg, &filenameArg, &coordinateStrArg, &helpArg}; PARSE_SUBCOMMAND(argc, argv, args); - if (!filenameArg.found && !coordinateStrArg.found) { + if (filenameArg.found == coordinateStrArg.found) { fprintf( stderr, "You must provide either a file to read from or a coordinate array " From d63accfd1d5c164b339fb38d5643f16d1d171295 Mon Sep 17 00:00:00 2001 From: David Ellis Date: Mon, 14 Oct 2024 15:06:01 -0500 Subject: [PATCH 37/37] BUFFER_SIZE for a few more constants --- src/apps/filters/h3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/filters/h3.c b/src/apps/filters/h3.c index 50b1b18ee..5a76b1213 100644 --- a/src/apps/filters/h3.c +++ b/src/apps/filters/h3.c @@ -2251,7 +2251,7 @@ SUBCOMMAND(greatCircleDistanceRads, exit(1); } // Do the initial population of data from the file - if (fread(coordinateStr, 1, 1500, fp) == 0) { + if (fread(coordinateStr, 1, BUFFER_SIZE, fp) == 0) { fprintf(stderr, "The specified file is empty."); exit(1); } @@ -2322,7 +2322,7 @@ SUBCOMMAND(greatCircleDistanceKm, exit(1); } // Do the initial population of data from the file - if (fread(coordinateStr, 1, 1500, fp) == 0) { + if (fread(coordinateStr, 1, BUFFER_SIZE, fp) == 0) { fprintf(stderr, "The specified file is empty."); exit(1); } @@ -2393,7 +2393,7 @@ SUBCOMMAND(greatCircleDistanceM, exit(1); } // Do the initial population of data from the file - if (fread(coordinateStr, 1, 1500, fp) == 0) { + if (fread(coordinateStr, 1, BUFFER_SIZE, fp) == 0) { fprintf(stderr, "The specified file is empty."); exit(1); }