Skip to content

Commit

Permalink
greatCircleDistanceRads
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis committed Oct 10, 2024
1 parent 295a094 commit f2131c0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/apps/filters/h3.c
Original file line number Diff line number Diff line change
Expand Up @@ -2188,6 +2188,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") {
Expand Down Expand Up @@ -2395,6 +2461,7 @@ SUBCOMMAND_INDEX(getNumCells)
SUBCOMMAND_INDEX(getRes0Cells)
SUBCOMMAND_INDEX(getPentagons)
SUBCOMMAND_INDEX(pentagonCount)
SUBCOMMAND_INDEX(greatCircleDistanceRads)
SUBCOMMAND_INDEX(greatCircleDistanceKm)
SUBCOMMAND_INDEX(greatCircleDistanceM)

Expand Down
4 changes: 4 additions & 0 deletions tests/cli/greatCircleDistanceRads.txt
Original file line number Diff line number Diff line change
@@ -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.")

0 comments on commit f2131c0

Please sign in to comment.