-
Notifications
You must be signed in to change notification settings - Fork 132
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
Added Bindings for Vertex-Related Functions #388
Changes from 12 commits
3d07598
87f749e
ec1d546
91c837c
291b02d
469ac00
b202241
08d2621
f69b46d
0a06d75
a788a2b
792700c
681a241
de57f68
863123a
a7fa37f
f367655
d1a2031
7d46922
06e271b
06f96e8
b894274
149ee2c
dd272ca
b8ecc81
e15f34a
b73d6ab
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,11 @@ | ||
from .h3lib cimport H3int | ||
from .h3lib cimport bool, H3int | ||
|
||
cpdef H3int latlng_to_cell(double lat, double lng, int res) except 1 | ||
cpdef (double, double) cell_to_latlng(H3int h) except * | ||
cpdef double great_circle_distance( | ||
double lat1, double lng1, | ||
double lat2, double lng2, unit=*) except -1 | ||
cpdef H3int cell_to_vertex(H3int h, int vertex_num) except 1 | ||
cpdef H3int[:] cell_to_vertexes(H3int h) | ||
cpdef (double, double) vertex_to_latlng(H3int v) except * | ||
cpdef bool is_valid_vertex(H3int v) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,10 @@ from h3lib cimport bool, H3int | |
from .util cimport ( | ||
check_cell, | ||
check_edge, | ||
check_vertex, | ||
check_res, | ||
deg2coord, | ||
coord2deg, | ||
coord2deg | ||
) | ||
|
||
from .error_system cimport check_for_error | ||
|
@@ -245,3 +246,46 @@ cpdef double great_circle_distance( | |
raise ValueError('Unknown unit: {}'.format(unit)) | ||
|
||
return d | ||
|
||
# todo: one might want to move the following to a separate vertex.pyx file | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm supportive of moving this to a separate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah but I thought that would be a larger change of structure... I wrote this comment in case there would be more vertex-related functions in the future. IMHO the current structure is good enough, but I can move it to a separate file as well if it's very beneficial :-) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I appreciate you asking! I think your suggestion to move the vertex code to its own file is a good one. :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok I'd do so. |
||
|
||
cpdef H3int cell_to_vertex(H3int h, int vertex_num) except 1: | ||
cdef: | ||
H3int out | ||
|
||
check_cell(h) | ||
|
||
check_for_error( | ||
h3lib.cellToVertex(h, vertex_num, &out) | ||
) | ||
|
||
return out | ||
|
||
cpdef H3int[:] cell_to_vertexes(H3int h): | ||
cdef: | ||
H3int out | ||
|
||
check_cell(h) | ||
|
||
hmm = H3MemoryManager(6) | ||
check_for_error( | ||
h3lib.cellToVertexes(h, hmm.ptr) | ||
) | ||
mv = hmm.to_mv() | ||
|
||
return mv | ||
|
||
cpdef (double, double) vertex_to_latlng(H3int v) except *: | ||
cdef: | ||
h3lib.LatLng c | ||
|
||
check_vertex(v) | ||
|
||
check_for_error( | ||
h3lib.vertexToLatLng(v, &c) | ||
) | ||
|
||
return coord2deg(c) | ||
|
||
cpdef bool is_valid_vertex(H3int v): | ||
return h3lib.isValidVertex(v) == 1 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -996,3 +996,70 @@ def great_circle_distance(latlng1, latlng2, unit='km'): | |
lat2, lng2, | ||
unit = unit | ||
) | ||
|
||
|
||
def cell_to_vertex(h, vertex_num): | ||
""" | ||
Return a (specified) vertex of an H3 cell. | ||
|
||
Parameters | ||
---------- | ||
h : H3Cell | ||
vertex_num : int | ||
Vertex number (0-5) | ||
|
||
Returns | ||
------- | ||
The vertex | ||
""" | ||
return _cy.cell_to_vertex(_in_scalar(h), vertex_num) | ||
|
||
|
||
def cell_to_vertexes(h): | ||
""" | ||
Return a list of vertices of an H3 cell. The list will always be of length 6. | ||
If a pentagon is entered, the last element will be 0. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the Python world, I'd rather have us dynamically size the array: a hex should return an array of length 6, and a pentagon should return an array of length 5. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I fixed array length to 6 only to align with the official docs... I'll change this. |
||
|
||
Parameters | ||
---------- | ||
h : H3Cell | ||
|
||
Returns | ||
------- | ||
A list of vertices | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I think we should have used "vertices" in H3, we decided to go with "vertexes". As a result, I think we should try to be consistent in the code and docs and only use "vertexes". There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK! :-) |
||
""" | ||
mv = _cy.cell_to_vertexes(_in_scalar(h)) | ||
arr = [str_to_int(a) for a in _out_collection(mv)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for making adjustments, but this will still return
To do that, the last operation should be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this line still needed? It looks as if you can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I have rewritten in my newest commit (yesterday) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Github is still showing this comment as up-to-date, could you double check your commit has been pushed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I see, thank you! Fixed. |
||
return arr if len(arr) == 6 else arr + [0] | ||
|
||
|
||
def vertex_to_latlng(v): | ||
""" | ||
Return latitude and longitude of a vertex. | ||
|
||
Returns | ||
------- | ||
lat : float | ||
Latitude | ||
lng : float | ||
Longitude | ||
""" | ||
if isinstance(v, str): | ||
v = str_to_int(v) | ||
return _cy.vertex_to_latlng(v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You need to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK! |
||
|
||
|
||
def is_valid_vertex(v): | ||
""" | ||
Validates an H3 vertex. | ||
|
||
Returns | ||
------- | ||
bool | ||
""" | ||
try: | ||
if isinstance(v, str): | ||
v = str_to_int(v) | ||
return _cy.is_valid_vertex(v) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK! |
||
except (ValueError, TypeError): | ||
return False |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -387,3 +387,62 @@ def test_grid_path_cells(): | |
|
||
with pytest.raises(h3.H3ResMismatchError): | ||
h3.grid_path_cells(h1, '8001fffffffffff') | ||
|
||
|
||
def test_cell_to_vertex(): | ||
# pentagon | ||
assert h3.cell_to_vertex('814c3ffffffffff', 0) == 2311688013026951167 | ||
assert h3.cell_to_vertex('814c3ffffffffff', 1) == 2383745607064879103 | ||
assert h3.cell_to_vertex('814c3ffffffffff', 2) == 2455803201102807039 | ||
assert h3.cell_to_vertex('814c3ffffffffff', 3) == 2527860795140734975 | ||
assert h3.cell_to_vertex('814c3ffffffffff', 4) == 2599918389178662911 | ||
try: | ||
h3.cell_to_vertex('814c3ffffffffff', 5) | ||
except h3._cy.error_system.H3DomainError: | ||
pass | ||
else: | ||
assert False | ||
|
||
# hexagon | ||
assert h3.cell_to_vertex('814d7ffffffffff', 0) == 2311710003259506687 | ||
assert h3.cell_to_vertex('814d7ffffffffff', 1) == 2455495337847029759 | ||
assert h3.cell_to_vertex('814d7ffffffffff', 2) == 2383437743809101823 | ||
assert h3.cell_to_vertex('814d7ffffffffff', 3) == 2599918389178662911 | ||
assert h3.cell_to_vertex('814d7ffffffffff', 4) == 2527860795140734975 | ||
assert h3.cell_to_vertex('814d7ffffffffff', 5) == 2599931583318196223 | ||
|
||
|
||
def test_cell_to_vertexes(): | ||
# pentagon | ||
assert h3.cell_to_vertexes('814c3ffffffffff') == [ | ||
2311688013026951167, | ||
2383745607064879103, | ||
2455803201102807039, | ||
2527860795140734975, | ||
2599918389178662911, | ||
0 | ||
] | ||
|
||
# hexagon | ||
assert h3.cell_to_vertexes('814d7ffffffffff') == [ | ||
2311710003259506687, | ||
2455495337847029759, | ||
2383437743809101823, | ||
2599918389178662911, | ||
2527860795140734975, | ||
2599931583318196223, | ||
] | ||
|
||
|
||
def test_vertex_to_latlng(): | ||
latlng = h3.vertex_to_latlng('2114c3ffffffffff') | ||
assert latlng == approx((24.945215618732814, -70.33904370008679)) | ||
latlng = h3.vertex_to_latlng(2455495337847029759) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We don't expect any single API to be able to handle both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see, I'll just leave the string tests, then. |
||
assert latlng == approx((21.8146389946083, -57.23011196400803)) | ||
|
||
|
||
def test_is_valid_vertex(): | ||
assert h3.is_valid_vertex('2114c3ffffffffff') | ||
assert h3.is_valid_vertex(2455495337847029759) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should expect this to fail for the (default) string API because a string is expected. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK! |
||
assert not h3.is_valid_vertex('foobar') | ||
assert not h3.is_valid_vertex(42) |
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.
Let's just put this under
## Unreleased
for now, since we'll publish as a separate step.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.
OK!