Skip to content
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

v4: convert edge from h3fake2 #253

Merged
merged 6 commits into from
Jun 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/h3/_cy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
experimental_local_ij_to_h3,
)

# from .edges import (
from h3fake2._cy import (
from .edges import (
are_neighbors,
edge,
is_edge,
Expand Down
20 changes: 10 additions & 10 deletions src/h3/_cy/edges.pxd
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# from .h3lib cimport bool, H3int
from .h3lib cimport bool, H3int

# cpdef bool are_neighbors(H3int h1, H3int h2)
# cpdef H3int edge(H3int origin, H3int destination) except 1
# cpdef bool is_edge(H3int e)
# cpdef H3int edge_origin(H3int e) except 1
# cpdef H3int edge_destination(H3int e) except 1
# cpdef (H3int, H3int) edge_cells(H3int e) except *
# cpdef H3int[:] edges_from_cell(H3int origin)
# cpdef double mean_edge_length(int resolution, unit=*) except -1
# cpdef double edge_length(H3int e, unit=*) except -1
cpdef bool are_neighbors(H3int h1, H3int h2)
cpdef H3int edge(H3int origin, H3int destination) except *
cpdef bool is_edge(H3int e)
cpdef H3int edge_origin(H3int e) except 1
cpdef H3int edge_destination(H3int e) except 1
cpdef (H3int, H3int) edge_cells(H3int e) except *
cpdef H3int[:] edges_from_cell(H3int origin)
cpdef double mean_edge_length(int resolution, unit=*) except -1
cpdef double edge_length(H3int e, unit=*) except -1
165 changes: 95 additions & 70 deletions src/h3/_cy/edges.pyx
Original file line number Diff line number Diff line change
@@ -1,100 +1,125 @@
# cimport h3lib
# from .h3lib cimport bool, H3int
cimport h3lib
from .h3lib cimport bool, H3int

# from .util cimport (
# check_cell,
# check_edge,
# check_res,
# create_ptr,
# create_mv,
# )
from .util cimport (
check_cell,
check_edge,
check_res,
create_ptr,
create_mv,
)

# from .util import H3ValueError
from .util import H3ValueError

# cpdef bool are_neighbors(H3int h1, H3int h2):
# check_cell(h1)
# check_cell(h2)
cpdef bool are_neighbors(H3int h1, H3int h2):
cdef:
int out

# return h3lib.h3IndexesAreNeighbors(h1, h2) == 1
check_cell(h1)
check_cell(h2)

error = h3lib.areNeighborCells(h1, h2, &out)
if error != 0:
return False
return out == 1

# cpdef H3int edge(H3int origin, H3int destination) except 1:
# check_cell(origin)
# check_cell(destination)

# if h3lib.h3IndexesAreNeighbors(origin, destination) != 1:
# s = 'Cells are not neighbors: {} and {}'
# s = s.format(hex(origin), hex(destination))
# raise H3ValueError(s)
cpdef H3int edge(H3int origin, H3int destination) except *:
cdef:
int neighbor_out
H3int out

# return h3lib.getH3UnidirectionalEdge(origin, destination)
check_cell(origin)
check_cell(destination)

error = h3lib.areNeighborCells(origin, destination, &neighbor_out)
if error != 0 or neighbor_out != 1:
s = 'Cells are not neighbors: {} and {}'
s = s.format(hex(origin), hex(destination))
raise H3ValueError(s)

# cpdef bool is_edge(H3int e):
# return h3lib.h3UnidirectionalEdgeIsValid(e) == 1
h3lib.cellsToDirectedEdge(origin, destination, &out)
return out

# cpdef H3int edge_origin(H3int e) except 1:
# # without the check, with an invalid input, the function will just return 0
# check_edge(e)

# return h3lib.getOriginH3IndexFromUnidirectionalEdge(e)
cpdef bool is_edge(H3int e):
return h3lib.isValidDirectedEdge(e) == 1

# cpdef H3int edge_destination(H3int e) except 1:
# check_edge(e)
cpdef H3int edge_origin(H3int e) except 1:
cdef:
H3int out

# return h3lib.getDestinationH3IndexFromUnidirectionalEdge(e)
# without the check, with an invalid input, the function will just return 0
check_edge(e)

# cpdef (H3int, H3int) edge_cells(H3int e) except *:
# check_edge(e)
h3lib.getDirectedEdgeOrigin(e, &out)
return out

# return edge_origin(e), edge_destination(e)
cpdef H3int edge_destination(H3int e) except 1:
cdef:
H3int out

# cpdef H3int[:] edges_from_cell(H3int origin):
# """ Returns the 6 (or 5 for pentagons) directed edges
# for the given origin cell
# """
# check_cell(origin)
check_edge(e)

# ptr = create_ptr(6)
# h3lib.getH3UnidirectionalEdgesFromHexagon(origin, ptr)
# mv = create_mv(ptr, 6)
h3lib.getDirectedEdgeDestination(e, &out)
return out

# return mv
cpdef (H3int, H3int) edge_cells(H3int e) except *:
check_edge(e)

return edge_origin(e), edge_destination(e)

# cpdef double mean_edge_length(int resolution, unit='km') except -1:
# check_res(resolution)
cpdef H3int[:] edges_from_cell(H3int origin):
""" Returns the 6 (or 5 for pentagons) directed edges
for the given origin cell
"""
check_cell(origin)

# length = h3lib.edgeLengthKm(resolution)
ptr = create_ptr(6)
h3lib.originToDirectedEdges(origin, ptr)
mv = create_mv(ptr, 6)

# # todo: multiple units
# convert = {
# 'km': 1.0,
# 'm': 1000.0
# }
return mv

# try:
# length *= convert[unit]
# except:
# raise H3ValueError('Unknown unit: {}'.format(unit))

# return length
cpdef double mean_edge_length(int resolution, unit='km') except -1:
cdef:
double length

check_res(resolution)

# cpdef double edge_length(H3int e, unit='km') except -1:
# check_edge(e)
h3lib.getHexagonEdgeLengthAvgKm(resolution, &length)

# # todo: maybe kick this logic up to the python level
# # it might be a little cleaner, because we can do the "switch statement"
# # with a dict, but would require exposing more C functions
# todo: multiple units
convert = {
'km': 1.0,
'm': 1000.0
}

# if unit == 'rads':
# length = h3lib.exactEdgeLengthRads(e)
# elif unit == 'km':
# length = h3lib.exactEdgeLengthKm(e)
# elif unit == 'm':
# length = h3lib.exactEdgeLengthM(e)
# else:
# raise H3ValueError('Unknown unit: {}'.format(unit))
try:
length *= convert[unit]
except:
raise H3ValueError('Unknown unit: {}'.format(unit))

# return length
return length


cpdef double edge_length(H3int e, unit='km') except -1:
cdef:
double length
check_edge(e)

# todo: maybe kick this logic up to the python level
# it might be a little cleaner, because we can do the "switch statement"
# with a dict, but would require exposing more C functions

if unit == 'rads':
h3lib.exactEdgeLengthRads(e, &length)
elif unit == 'km':
h3lib.exactEdgeLengthKm(e, &length)
elif unit == 'm':
h3lib.exactEdgeLengthM(e, &length)
else:
raise H3ValueError('Unknown unit: {}'.format(unit))

return length
31 changes: 13 additions & 18 deletions src/h3/_cy/h3lib.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,20 @@ cdef extern from "h3api.h":
H3Error gridDiskDistances(H3Index origin, int k, H3Index *out, int *distances) nogil
H3Error gridRingUnsafe(H3Index origin, int k, H3Index *out) nogil

H3Error cellToBoundary(H3Index h3, CellBoundary *gp) nogil
H3Error areNeighborCells(H3Index origin, H3Index destination, int *out) nogil
H3Error cellsToDirectedEdge(H3Index origin, H3Index destination, H3Index *out) nogil
H3Error getDirectedEdgeOrigin(H3Index edge, H3Index *out) nogil
H3Error getDirectedEdgeDestination(H3Index edge, H3Index *out) nogil
H3Error originToDirectedEdges(H3Index origin, H3Index *edges) nogil

H3Error getHexagonEdgeLengthAvgKm(int res, double *out) nogil
H3Error getHexagonEdgeLengthAvgM(int res, double *out) nogil

H3Error exactEdgeLengthRads(H3Index edge, double *out) nogil
H3Error exactEdgeLengthKm(H3Index edge, double *out) nogil
H3Error exactEdgeLengthM(H3Index edge, double *out) nogil

H3Error cellToBoundary(H3Index h3, CellBoundary *gp) nogil
H3Error directedEdgeToBoundary(H3Index edge, CellBoundary *gb) nogil

double distanceRads(const LatLng *a, const LatLng *b) nogil
Expand Down Expand Up @@ -148,21 +160,4 @@ cdef extern from "h3api.h":

# void h3ToString(H3Index h, char *str, size_t sz)

# int h3IndexesAreNeighbors(H3Index origin, H3Index destination)

# H3Index getH3UnidirectionalEdge(H3Index origin, H3Index destination)

# H3Index getOriginH3IndexFromUnidirectionalEdge(H3Index edge)

# H3Index getDestinationH3IndexFromUnidirectionalEdge(H3Index edge)

# void getH3IndexesFromUnidirectionalEdge(H3Index edge, H3Index *originDestination)

# void getH3UnidirectionalEdgesFromHexagon(H3Index origin, H3Index *edges)

# double edgeLengthKm(int res) nogil
# double edgeLengthM(int res) nogil

# double exactEdgeLengthRads(H3Index edge) nogil
# double exactEdgeLengthKm(H3Index edge) nogil
# double exactEdgeLengthM(H3Index edge) nogil