-
Notifications
You must be signed in to change notification settings - Fork 468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement the cellToBoundary command for the h3 binary #818
Conversation
So... I don't see any tests for the |
Co-authored-by: Isaac Brodsky <[email protected]>
…T where applicable, and eliminate hardwired constants in favor of sizeof trick @sahrk mentioned
I finally found the tests near the bottom of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please change lat, lng ordering for compatibility with existing WKT implementations
printf("%.10lf %.10lf))\n", H3_EXPORT(radsToDegs)(cb.verts[0].lng), | ||
H3_EXPORT(radsToDegs)(cb.verts[0].lat)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit/note if this function gets reused, that it depends on numVerts > 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible for it to be zero and not produce an H3Error value that short-circuits it, though?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know it should always have vertices if the return code is success
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good - most of my comments are non-blocking questions about input/output and some of the existing structure of these commands
return false; | ||
} | ||
// Using WKT formatting for the output. TODO: Add support for JSON | ||
// formatting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious about plans for output and input formats here. I assume for output we'd want a -f
or --format
param similar to ogr2ogr
. It would be easy to go overboard here, but I think at a minimum:
csv
:37.5012466151,-122.5003039349
wkt
:POINT(-122.5003039349 37.5012466151)
geojson
:{"type": "Point", "coordinates": [-122.5003039349 37.5012466151]}
We might also support json-array
([-122.5003039349 37.5012466151]
) or json-object
({"lat":-122.5003039349, "lng": 37.5012466151}
) and maybe an --ordering
param specifying latlng
or lnglat
?
The parallel question is what inputs we support - accepting these formats as inputs is nicely symmetrical, but more painful than --lat=x --lng=y
or bare arguments.
Not saying we should do any of this, but it might be nice to know where we plan to draw the line. I think a good yardstick should be how easy it is to pipe data from a tool like ogr2ogr
to and from these CLI commands.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this can definitely become a rabbit hole, here. There are other things to consider, for instance: should the csv
output type include a headers row for the first one with lat,lng
?
But also, how much of this can we generalize across these functions, and how much has to be hand-written per sub-command? The more of the latter the less I want to support everything under the sun and just suggest users to do things like h3 cellToLatLng -c 8928342e20fffff --geojson | jq .coordinates
if they want other formats.
That's part of why I was thinking of going with a JSON-based output by default, because of the possibility of mangling the format more easily than any other, but went with WKT since that's what @isaacbrodsky suggested as an expected output.
I'm not personally familiar with ogr2ogr
, though, so that's part of my bias towards a JSON-based format.
H3_EXPORT(radsToDegs)(ll.lng)); | ||
H3Error err = H3_EXPORT(cellToLatLng)(cell, &ll); | ||
if (err) { | ||
return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For my info, why return true
/false
from these functions? Wouldn't we just want to return the error code, so callers would get a 0
exit code on success and a meaningful non-zero code on failure?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, I think we started work on this binary before H3Error
was a thing and it was doing h3IsValid
checks on the inputs/outputs to determine if it should exit with an error or not.
Then the conversion of that was done this way because it was the most straightforward. Bubbling up the H3Error
does make sense to me. If you don't mind, I'll keep that refactor for when I add in the next sub-command.
@@ -102,6 +107,7 @@ bool latLngToCellCmd(int argc, char *argv[]) { | |||
H3Index c; | |||
H3Error e = H3_EXPORT(latLngToCell)(&ll, res, &c); | |||
|
|||
// TODO: Add support for JSON formatting |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does JSON formatting mean "8928342e20fffff"
in this case? Also, does h3Println
make piping harder than h3Print
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That or {"cell": "8928342e20fffff"}
. I'm not sure which would be a better idea.
src/apps/filters/h3.c
Outdated
Arg *args[] = {&cellToBoundaryArg, &helpArg, &cellArg}; | ||
if (parseArgs(argc, argv, sizeof(args) / sizeof(Arg *), args, &helpArg, | ||
"Convert an H3 cell to an array of latitude/longitude " | ||
"coordinates defining its boundary")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Is it possible to reuse cellToBoundaryArg.helpText
here instead of repeating it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really want to DRY this stuff up, but I think I need to rework or add some macros to do so in a way that maintains its legibility. I left it here for now because I found it easier to read the code this way, but I will do a bigger refactor in a follow-up PR that's focused just on DRYing the code so we can debate that without holding up progress on implementing a sub-command.
.helpText = | ||
"Convert an H3 cell to an array of latitude/longitude coordinates " | ||
"defining its boundary", | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Is it possible to define this a top-level static const
so that we can reuse it instead of repeating it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my prior comment. Leaving DRY-ing it to another PR focused solely on that so we can better debate the merits/long-term maintenance.
@@ -140,6 +190,9 @@ int main(int argc, char *argv[]) { | |||
if (has("latLngToCell", 1, argv) && latLngToCellCmd(argc, argv)) { | |||
return 0; | |||
} | |||
if (has("cellToBoundary", 1, argv) && cellToBoundaryCmd(argc, argv)) { | |||
return 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above, I would have gone with return cellToBoundaryCmd(argc, argv)
and have each command return H3_ERROR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with you, but would like that to also be a separate PR.
Just this one command at first as I remember how we had structured the arg parsing API. Tested for correctness manually, I will see if/how testing this binary was set up shortly.