Skip to content

Commit 1ac484a

Browse files
authored
h3shape_to_cells_experimental takes string containment modes (#436)
* polygon to cells just takes string arguments * don't need enum * docstrings * have tests use h3shape_to_cells_experimental * clean up tests * don't repeat tests * experimental warning * Being experimental, try `contain` instead of `containment` in params * try typing with literal * add polygon_to_cells_experimental. Contains coverage and lint errors -- just checking that they raise in CI * ruff fix * docs and changelog * add test_polygon_to_cells_experimental for full coverage * test notes
1 parent 1dc5e51 commit 1ac484a

File tree

9 files changed

+125
-105
lines changed

9 files changed

+125
-105
lines changed

.github/workflows/lint_and_coverage.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ jobs:
2828

2929
- name: Coverage Requirement - Library
3030
run: |
31-
pytest --cov=tests/test_lib --cov-fail-under=100
31+
pytest tests/test_lib --cov=h3 --cov=tests/test_lib --cov-fail-under=100
3232
3333
- name: Coverage - Cython
3434
run: |
3535
pip install cython
3636
cythonize tests/test_cython/cython_example.pyx
37-
pytest --cov=tests/test_cython
37+
pytest tests/test_cython --cov=tests/test_cython

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ avoid adding features or APIs which do not map onto the
1717
## Unreleased
1818

1919
- Update to v4.2.0. (#432)
20+
- Add `h3shape_to_cells_experimental` (#436)
21+
- Add `polygon_to_cells_experimental` alias
2022

2123
## [4.1.2] - 2024-10-26
2224

docs/api_quick.md

+11
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ Note that this is reversed from [``__geo_interface__``](https://gist.github.com/
161161
cells_to_geo
162162
```
163163

164+
#### Additional functions
165+
166+
```{eval-rst}
167+
.. currentmodule:: h3
168+
169+
.. autosummary::
170+
polygon_to_cells
171+
polygon_to_cells_experimental
172+
h3shape_to_cells_experimental
173+
```
174+
164175

165176
## Specialized functions
166177

makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ purge: clear
3535
-@rm -rf env
3636

3737
test:
38-
./env/bin/pytest --cov=tests/test_lib --cov-fail-under=100
38+
./env/bin/pytest tests/test_lib --cov=h3 --cov=tests/test_lib --cov-fail-under=100
3939

4040
./env/bin/pip install cython
4141
./env/bin/cythonize tests/test_cython/cython_example.pyx
42-
./env/bin/pytest --cov=tests/test_cython
42+
./env/bin/pytest tests/test_cython --cov=tests/test_cython
4343

4444
lint:
4545
./env/bin/ruff check

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ all = [
6363
]
6464

6565
[tool.pytest.ini_options]
66-
addopts = "--cov=h3 --cov-report=term-missing --durations=10"
66+
addopts = "--cov-report=term-missing --durations=10"
6767

6868
[tool.coverage.run]
6969
omit = [

src/h3/_cy/latlng.pyx

+7-7
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def polygons_to_cells(polygons, int res):
196196
return hmm.to_mv()
197197

198198

199-
def polygon_to_cells_experimental(outer, int res, int flags, holes=None):
199+
def polygon_to_cells_experimental(outer, int res, int flag, holes=None):
200200
""" Get the set of cells whose center is contained in a polygon.
201201
202202
The polygon is defined similarity to the GeoJson standard, with an exterior
@@ -221,8 +221,8 @@ def polygon_to_cells_experimental(outer, int res, int flags, holes=None):
221221
A ring given by a sequence of lat/lng pairs.
222222
res : int
223223
The resolution of the output hexagons
224-
flags : int
225-
Polygon to cells flags, such as containment mode.
224+
flag : int
225+
Polygon to cells flag, such as containment mode.
226226
holes : list or tuple
227227
A collection of rings, each given by a sequence of lat/lng pairs.
228228
These describe any the "holes" in the polygon.
@@ -238,21 +238,21 @@ def polygon_to_cells_experimental(outer, int res, int flags, holes=None):
238238
gp = GeoPolygon(outer, holes=holes)
239239

240240
check_for_error(
241-
h3lib.maxPolygonToCellsSizeExperimental(&gp.gp, res, flags, &n)
241+
h3lib.maxPolygonToCellsSizeExperimental(&gp.gp, res, flag, &n)
242242
)
243243

244244
hmm = H3MemoryManager(n)
245245
check_for_error(
246-
h3lib.polygonToCellsExperimental(&gp.gp, res, flags, n, hmm.ptr)
246+
h3lib.polygonToCellsExperimental(&gp.gp, res, flag, n, hmm.ptr)
247247
)
248248
mv = hmm.to_mv()
249249

250250
return mv
251251

252252

253-
def polygons_to_cells_experimental(polygons, int res, int flags):
253+
def polygons_to_cells_experimental(polygons, int res, int flag):
254254
mvs = [
255-
polygon_to_cells_experimental(outer=poly.outer, res=res, holes=poly.holes, flags=flags)
255+
polygon_to_cells_experimental(outer=poly.outer, res=res, holes=poly.holes, flag=flag)
256256
for poly in polygons
257257
]
258258

src/h3/_h3shape.py

-11
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
11
from abc import ABCMeta, abstractmethod
2-
from enum import Enum
3-
4-
5-
class ContainmentMode(int, Enum):
6-
"""
7-
Containment modes for use with ``polygon_to_cells_experimental``.
8-
"""
9-
containment_center = 0
10-
containment_full = 1
11-
containment_overlapping = 2
12-
containment_overlapping_bbox = 3
132

143

154
class H3Shape(metaclass=ABCMeta):

src/h3/api/basic_int/__init__.py

+50-32
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# This file is **symlinked** across the APIs to ensure they are exactly the same.
2+
from typing import Literal
23

34
from ... import _cy
45
from ..._h3shape import (
5-
ContainmentMode,
66
H3Shape,
77
LatLngPoly,
88
LatLngMultiPoly,
@@ -468,6 +468,13 @@ def uncompact_cells(cells, res):
468468
return _out_collection(hu)
469469

470470

471+
def polygon_to_cells(h3shape, res):
472+
"""
473+
Alias for ``h3shape_to_cells``.
474+
"""
475+
return h3shape_to_cells(h3shape, res)
476+
477+
471478
def h3shape_to_cells(h3shape, res):
472479
"""
473480
Return the collection of H3 cells at a given resolution whose center points
@@ -519,25 +526,46 @@ def h3shape_to_cells(h3shape, res):
519526
return _out_collection(mv)
520527

521528

522-
def polygon_to_cells(h3shape, res):
529+
def polygon_to_cells_experimental(
530+
h3shape: H3Shape,
531+
res: int,
532+
contain: Literal['center', 'full', 'overlap', 'bbox_overlap'] = 'center',
533+
):
523534
"""
524-
Alias for ``h3shape_to_cells``.
535+
Alias for ``h3shape_to_cells_experimental``.
525536
"""
526-
return h3shape_to_cells(h3shape, res)
537+
return h3shape_to_cells_experimental(h3shape, res, contain)
527538

528539

529-
def h3shape_to_cells_experimental(h3shape, res, flags=0):
540+
def h3shape_to_cells_experimental(
541+
h3shape: H3Shape,
542+
res: int,
543+
contain: Literal['center', 'full', 'overlap', 'bbox_overlap'] = 'center',
544+
):
530545
"""
531-
Return the collection of H3 cells at a given resolution whose center points
532-
are contained within an ``LatLngPoly`` or ``LatLngMultiPoly``.
546+
Experimental function similar to ``h3shape_to_cells``, but with support for
547+
multiple cell containment modes.
548+
549+
Using ``contain='center'`` should give identical behavior as
550+
``h3shape_to_cells``.
551+
552+
Note that this function is **experimental** and has no API stability gaurantees
553+
across versions, so it may change in the future.
554+
533555
534556
Parameters
535557
----------
536558
h3shape : ``H3Shape``
537559
res : int
538560
Resolution of the output cells
539-
flags : ``ContainmentMode``, int, or string
540-
Containment mode flags
561+
contain : {'center', 'full', 'overlap', 'bbox_overlap'}, optional
562+
Specifies the containment condition.
563+
- 'center': Cell center is contained in shape
564+
- 'full': Cell is fully contained in shape
565+
- 'overlap': Cell is partially contained in shape
566+
- 'bbox_overlap': Cell bounding box is partially contained in shape
567+
568+
Default is 'center'.
541569
542570
Returns
543571
-------
@@ -550,7 +578,7 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0):
550578
... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34),
551579
... (37.82, -122.54)],
552580
... )
553-
>>> h3.h3shape_to_cells_experimental(poly, 6, h3.ContainmentMode.containment_center)
581+
>>> h3.h3shape_to_cells_experimental(poly, 6, 'center')
554582
['862830807ffffff',
555583
'862830827ffffff',
556584
'86283082fffffff',
@@ -564,30 +592,27 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0):
564592
There is currently no guaranteed order of the output cells.
565593
"""
566594

567-
if isinstance(flags, str):
568-
try:
569-
flags = ContainmentMode[flags]
570-
except KeyError as e:
571-
raise ValueError('Unrecognized flags: ' + flags) from e
572-
if isinstance(flags, ContainmentMode):
573-
flags = int(flags)
574-
if not isinstance(flags, int):
575-
raise ValueError(
576-
'Flags should be ContainmentMode, str, or int, but got: ' + str(type(flags))
577-
)
595+
contain_modes = {
596+
'center': 0,
597+
'full': 1,
598+
'overlap': 2,
599+
'bbox_overlap': 3,
600+
}
601+
602+
flag = contain_modes[contain]
578603

579604
# todo: not sure if i want this dispatch logic here. maybe in the objects?
580605
if isinstance(h3shape, LatLngPoly):
581606
poly = h3shape
582607
mv = _cy.polygon_to_cells_experimental(
583608
poly.outer,
584-
res=res,
585-
holes=poly.holes,
586-
flags=flags
609+
res = res,
610+
holes = poly.holes,
611+
flag = flag,
587612
)
588613
elif isinstance(h3shape, LatLngMultiPoly):
589614
mpoly = h3shape
590-
mv = _cy.polygons_to_cells_experimental(mpoly.polys, res=res, flags=flags)
615+
mv = _cy.polygons_to_cells_experimental(mpoly.polys, res=res, flag=flag)
591616
elif isinstance(h3shape, H3Shape):
592617
raise ValueError('Unrecognized H3Shape: ' + str(h3shape))
593618
else:
@@ -596,13 +621,6 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0):
596621
return _out_collection(mv)
597622

598623

599-
def polygon_to_cells_experimental(h3shape, res, flags=0):
600-
"""
601-
Alias for ``h3shape_to_cells_experimental``.
602-
"""
603-
return h3shape_to_cells_experimental(h3shape, res, flags=flags)
604-
605-
606624
def cells_to_h3shape(cells, *, tight=True):
607625
"""
608626
Return an ``H3Shape`` describing the area covered by a collection of H3 cells.

0 commit comments

Comments
 (0)