From a579efb9fc66cfd01dd1d1b29b89467a9a3e7d70 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 17:51:11 -0800 Subject: [PATCH 1/9] polygon to cells just takes string arguments --- src/h3/_cy/latlng.pyx | 14 +++++------ src/h3/_h3shape.py | 10 -------- src/h3/api/basic_int/__init__.py | 40 ++++++++++++++---------------- tests/test_lib/polyfill/test_h3.py | 36 +++++++++++---------------- 4 files changed, 40 insertions(+), 60 deletions(-) diff --git a/src/h3/_cy/latlng.pyx b/src/h3/_cy/latlng.pyx index 60b9053f..d83a9d3d 100644 --- a/src/h3/_cy/latlng.pyx +++ b/src/h3/_cy/latlng.pyx @@ -196,7 +196,7 @@ def polygons_to_cells(polygons, int res): return hmm.to_mv() -def polygon_to_cells_experimental(outer, int res, int flags, holes=None): +def polygon_to_cells_experimental(outer, int res, int flag, holes=None): """ Get the set of cells whose center is contained in a polygon. 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): A ring given by a sequence of lat/lng pairs. res : int The resolution of the output hexagons - flags : int - Polygon to cells flags, such as containment mode. + flag : int + Polygon to cells flag, such as containment mode. holes : list or tuple A collection of rings, each given by a sequence of lat/lng pairs. These describe any the "holes" in the polygon. @@ -238,21 +238,21 @@ def polygon_to_cells_experimental(outer, int res, int flags, holes=None): gp = GeoPolygon(outer, holes=holes) check_for_error( - h3lib.maxPolygonToCellsSizeExperimental(&gp.gp, res, flags, &n) + h3lib.maxPolygonToCellsSizeExperimental(&gp.gp, res, flag, &n) ) hmm = H3MemoryManager(n) check_for_error( - h3lib.polygonToCellsExperimental(&gp.gp, res, flags, n, hmm.ptr) + h3lib.polygonToCellsExperimental(&gp.gp, res, flag, n, hmm.ptr) ) mv = hmm.to_mv() return mv -def polygons_to_cells_experimental(polygons, int res, int flags): +def polygons_to_cells_experimental(polygons, int res, int flag): mvs = [ - polygon_to_cells_experimental(outer=poly.outer, res=res, holes=poly.holes, flags=flags) + polygon_to_cells_experimental(outer=poly.outer, res=res, holes=poly.holes, flag=flag) for poly in polygons ] diff --git a/src/h3/_h3shape.py b/src/h3/_h3shape.py index 261dfa92..bfaed54d 100644 --- a/src/h3/_h3shape.py +++ b/src/h3/_h3shape.py @@ -2,16 +2,6 @@ from enum import Enum -class ContainmentMode(int, Enum): - """ - Containment modes for use with ``polygon_to_cells_experimental``. - """ - containment_center = 0 - containment_full = 1 - containment_overlapping = 2 - containment_overlapping_bbox = 3 - - class H3Shape(metaclass=ABCMeta): """ Abstract parent class of ``LatLngPoly`` and ``LatLngMultiPoly``. diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index cf450c89..55b014c2 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -2,7 +2,6 @@ from ... import _cy from ..._h3shape import ( - ContainmentMode, H3Shape, LatLngPoly, LatLngMultiPoly, @@ -526,7 +525,7 @@ def polygon_to_cells(h3shape, res): return h3shape_to_cells(h3shape, res) -def h3shape_to_cells_experimental(h3shape, res, flags=0): +def h3shape_to_cells_experimental(h3shape, res, containment='center'): """ Return the collection of H3 cells at a given resolution whose center points are contained within an ``LatLngPoly`` or ``LatLngMultiPoly``. @@ -536,8 +535,8 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0): h3shape : ``H3Shape`` res : int Resolution of the output cells - flags : ``ContainmentMode``, int, or string - Containment mode flags + containment: str + 'center', 'full', 'overlap', 'bbox_overlap' Returns ------- @@ -550,7 +549,7 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0): ... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34), ... (37.82, -122.54)], ... ) - >>> h3.h3shape_to_cells_experimental(poly, 6, h3.ContainmentMode.containment_center) + >>> h3.h3shape_to_cells_experimental(poly, 6, 'center') ['862830807ffffff', '862830827ffffff', '86283082fffffff', @@ -564,30 +563,27 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0): There is currently no guaranteed order of the output cells. """ - if isinstance(flags, str): - try: - flags = ContainmentMode[flags] - except KeyError as e: - raise ValueError('Unrecognized flags: ' + flags) from e - if isinstance(flags, ContainmentMode): - flags = int(flags) - if not isinstance(flags, int): - raise ValueError( - 'Flags should be ContainmentMode, str, or int, but got: ' + str(type(flags)) - ) + containment_modes = { + 'center': 0, + 'full': 1, + 'overlap': 2, + 'bbox_overlap': 3, + } + + flag = containment_modes[containment] # todo: not sure if i want this dispatch logic here. maybe in the objects? if isinstance(h3shape, LatLngPoly): poly = h3shape mv = _cy.polygon_to_cells_experimental( poly.outer, - res=res, - holes=poly.holes, - flags=flags + res = res, + holes = poly.holes, + flag = flag, ) elif isinstance(h3shape, LatLngMultiPoly): mpoly = h3shape - mv = _cy.polygons_to_cells_experimental(mpoly.polys, res=res, flags=flags) + mv = _cy.polygons_to_cells_experimental(mpoly.polys, res=res, flag=flag) elif isinstance(h3shape, H3Shape): raise ValueError('Unrecognized H3Shape: ' + str(h3shape)) else: @@ -596,11 +592,11 @@ def h3shape_to_cells_experimental(h3shape, res, flags=0): return _out_collection(mv) -def polygon_to_cells_experimental(h3shape, res, flags=0): +def polygon_to_cells_experimental(h3shape, res, containment='center'): """ Alias for ``h3shape_to_cells_experimental``. """ - return h3shape_to_cells_experimental(h3shape, res, flags=flags) + return h3shape_to_cells_experimental(h3shape, res, containment=containment) def cells_to_h3shape(cells, *, tight=True): diff --git a/tests/test_lib/polyfill/test_h3.py b/tests/test_lib/polyfill/test_h3.py index 933f404c..3b38fb68 100644 --- a/tests/test_lib/polyfill/test_h3.py +++ b/tests/test_lib/polyfill/test_h3.py @@ -119,9 +119,9 @@ def test_polygon_to_cells(): def test_polygon_to_cells_experimental(): poly = h3.LatLngPoly(sf_7x7) - for flags in [0, 'containment_center', h3.ContainmentMode.containment_center]: + for flags in ['center']: # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, flags=flags) + out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1253 assert '89283080527ffff' in out @@ -130,9 +130,9 @@ def test_polygon_to_cells_experimental(): def test_polygon_to_cells_experimental_full(): poly = h3.LatLngPoly(sf_7x7) - for flags in [1, 'containment_full', h3.ContainmentMode.containment_full]: + for flags in ['full']: # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, flags=flags) + out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1175 assert '89283082a1bffff' in out @@ -142,13 +142,9 @@ def test_polygon_to_cells_experimental_full(): def test_polygon_to_cells_experimental_overlapping(): poly = h3.LatLngPoly(sf_7x7) - for flags in [ - 2, - 'containment_overlapping', - h3.ContainmentMode.containment_overlapping - ]: + for flags in ['overlap']: # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, flags=flags) + out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1334 assert '89283080527ffff' in out @@ -158,12 +154,10 @@ def test_polygon_to_cells_experimental_overlapping(): def test_polygon_to_cells_experimental_overlapping_bbox(): poly = h3.LatLngPoly(sf_7x7) for flags in [ - 3, - 'containment_overlapping_bbox', - h3.ContainmentMode.containment_overlapping_bbox + 'bbox_overlap' ]: # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, flags=flags) + out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1416 assert '89283080527ffff' in out @@ -172,10 +166,10 @@ def test_polygon_to_cells_experimental_overlapping_bbox(): def test_polygon_to_cells_experimental_invalid_mode(): poly = h3.LatLngPoly(sf_7x7) - for flags in [1.0, 'containment_overlapping_bbox_abc', None]: - with pytest.raises(ValueError): + for flags in ['containment_overlapping_bbox_abc']: + with pytest.raises(KeyError): # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - h3.polygon_to_cells_experimental(poly, res=9, flags=flags) + h3.polygon_to_cells_experimental(poly, res=9, containment=flags) def test_poly_to_cells_experimental_mpoly(): @@ -187,7 +181,7 @@ def test_poly_to_cells_experimental_mpoly(): assert ( set(h3.polygon_to_cells_experimental(mpoly, res=9)) == - set(h3.polygon_to_cells_experimental(mpoly, res=9, flags='containment_center')) + set(h3.polygon_to_cells_experimental(mpoly, res=9, containment='center')) ) assert ( @@ -196,14 +190,14 @@ def test_poly_to_cells_experimental_mpoly(): set(h3.polygon_to_cells_experimental( mpoly, res=9, - flags='containment_overlapping' + containment='overlap' )) ) assert 120 == len(h3.polygon_to_cells_experimental( mpoly, - res=9, - flags='containment_overlapping' + res = 9, + containment = 'overlap' )) From fb2cf65ae70d4cd630b2896fb8f7fc581ddb2e1c Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 17:53:07 -0800 Subject: [PATCH 2/9] don't need enum --- src/h3/_h3shape.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/h3/_h3shape.py b/src/h3/_h3shape.py index bfaed54d..5c362951 100644 --- a/src/h3/_h3shape.py +++ b/src/h3/_h3shape.py @@ -1,5 +1,4 @@ from abc import ABCMeta, abstractmethod -from enum import Enum class H3Shape(metaclass=ABCMeta): From c5a5d65986cad68038d22389943f350ffa7b4d0c Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 18:24:30 -0800 Subject: [PATCH 3/9] docstrings --- docs/api_quick.md | 10 ++++++++++ src/h3/api/basic_int/__init__.py | 9 +++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/docs/api_quick.md b/docs/api_quick.md index 5503baef..33b37b8f 100644 --- a/docs/api_quick.md +++ b/docs/api_quick.md @@ -161,6 +161,16 @@ Note that this is reversed from [``__geo_interface__``](https://gist.github.com/ cells_to_geo ``` +#### Additional functions + +```{eval-rst} +.. currentmodule:: h3 + +.. autosummary:: + polygon_to_cells + h3shape_to_cells_experimental +``` + ## Specialized functions diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index 55b014c2..10c1946a 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -535,8 +535,13 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): h3shape : ``H3Shape`` res : int Resolution of the output cells - containment: str - 'center', 'full', 'overlap', 'bbox_overlap' + containment : {'center', 'full', 'overlap', 'bbox_overlap'} + Specifies the containment condition. + - 'center': Cell center is contained in shape + - 'full': Cell is fully contained in shape + - 'overlap': Cell is partially contained in shape + - 'bbox_overlap': Cell bounding box is partially contained in shape + Returns ------- From c627dcae12fda1367ececeed90511cf0c4fc3b54 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 18:32:28 -0800 Subject: [PATCH 4/9] have tests use h3shape_to_cells_experimental --- src/h3/api/basic_int/__init__.py | 8 +------ tests/test_lib/polyfill/test_h3.py | 36 +++++++++++++----------------- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index 10c1946a..953ffc54 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -525,6 +525,7 @@ def polygon_to_cells(h3shape, res): return h3shape_to_cells(h3shape, res) +# TODO: better docstring explaining experimental options def h3shape_to_cells_experimental(h3shape, res, containment='center'): """ Return the collection of H3 cells at a given resolution whose center points @@ -597,13 +598,6 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): return _out_collection(mv) -def polygon_to_cells_experimental(h3shape, res, containment='center'): - """ - Alias for ``h3shape_to_cells_experimental``. - """ - return h3shape_to_cells_experimental(h3shape, res, containment=containment) - - def cells_to_h3shape(cells, *, tight=True): """ Return an ``H3Shape`` describing the area covered by a collection of H3 cells. diff --git a/tests/test_lib/polyfill/test_h3.py b/tests/test_lib/polyfill/test_h3.py index 3b38fb68..7fe507ac 100644 --- a/tests/test_lib/polyfill/test_h3.py +++ b/tests/test_lib/polyfill/test_h3.py @@ -117,22 +117,20 @@ def test_polygon_to_cells(): assert '89283095edbffff' in out -def test_polygon_to_cells_experimental(): +def test_h3shape_to_cells_experimental(): poly = h3.LatLngPoly(sf_7x7) for flags in ['center']: - # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) + out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1253 assert '89283080527ffff' in out assert '89283095edbffff' in out -def test_polygon_to_cells_experimental_full(): +def test_h3shape_to_cells_experimental_full(): poly = h3.LatLngPoly(sf_7x7) for flags in ['full']: - # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) + out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1175 assert '89283082a1bffff' in out @@ -140,36 +138,34 @@ def test_polygon_to_cells_experimental_full(): assert '89283095edbffff' in out -def test_polygon_to_cells_experimental_overlapping(): +def test_h3shape_to_cells_experimental_overlapping(): poly = h3.LatLngPoly(sf_7x7) for flags in ['overlap']: - # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) + out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1334 assert '89283080527ffff' in out assert '89283095edbffff' in out -def test_polygon_to_cells_experimental_overlapping_bbox(): +# TODO: fix these for flags loops +def test_h3shape_to_cells_experimental_overlapping_bbox(): poly = h3.LatLngPoly(sf_7x7) for flags in [ 'bbox_overlap' ]: - # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - out = h3.polygon_to_cells_experimental(poly, res=9, containment=flags) + out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) assert len(out) == 1416 assert '89283080527ffff' in out assert '89283095edbffff' in out -def test_polygon_to_cells_experimental_invalid_mode(): +def test_h3shape_to_cells_experimental_invalid_mode(): poly = h3.LatLngPoly(sf_7x7) for flags in ['containment_overlapping_bbox_abc']: with pytest.raises(KeyError): - # Note that `polygon_to_cells` is an alias for `h3shape_to_cells` - h3.polygon_to_cells_experimental(poly, res=9, containment=flags) + h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) def test_poly_to_cells_experimental_mpoly(): @@ -179,22 +175,22 @@ def test_poly_to_cells_experimental_mpoly(): ) assert ( - set(h3.polygon_to_cells_experimental(mpoly, res=9)) + set(h3.h3shape_to_cells_experimental(mpoly, res=9)) == - set(h3.polygon_to_cells_experimental(mpoly, res=9, containment='center')) + set(h3.h3shape_to_cells_experimental(mpoly, res=9, containment='center')) ) assert ( - set(h3.polygon_to_cells_experimental(mpoly, res=9)) + set(h3.h3shape_to_cells_experimental(mpoly, res=9)) < - set(h3.polygon_to_cells_experimental( + set(h3.h3shape_to_cells_experimental( mpoly, res=9, containment='overlap' )) ) - assert 120 == len(h3.polygon_to_cells_experimental( + assert 120 == len(h3.h3shape_to_cells_experimental( mpoly, res = 9, containment = 'overlap' From 0a5eac02a5706be015f4806f35813816539dc5e8 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 20:40:37 -0800 Subject: [PATCH 5/9] clean up tests --- src/h3/api/basic_int/__init__.py | 9 ++--- tests/test_lib/polyfill/test_h3.py | 57 +++++++++++++++--------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index 953ffc54..57ef64c5 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -525,11 +525,13 @@ def polygon_to_cells(h3shape, res): return h3shape_to_cells(h3shape, res) -# TODO: better docstring explaining experimental options def h3shape_to_cells_experimental(h3shape, res, containment='center'): """ - Return the collection of H3 cells at a given resolution whose center points - are contained within an ``LatLngPoly`` or ``LatLngMultiPoly``. + Experimental function similar to ``h3shape_to_cells``, but with support for + multiple cell containment modes. + + Using ``containment='center'`` should give identical behavior as + ``h3shape_to_cells``. Parameters ---------- @@ -543,7 +545,6 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): - 'overlap': Cell is partially contained in shape - 'bbox_overlap': Cell bounding box is partially contained in shape - Returns ------- list of H3Cell diff --git a/tests/test_lib/polyfill/test_h3.py b/tests/test_lib/polyfill/test_h3.py index 7fe507ac..72ed86ff 100644 --- a/tests/test_lib/polyfill/test_h3.py +++ b/tests/test_lib/polyfill/test_h3.py @@ -119,53 +119,52 @@ def test_polygon_to_cells(): def test_h3shape_to_cells_experimental(): poly = h3.LatLngPoly(sf_7x7) - for flags in ['center']: - out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) - assert len(out) == 1253 - assert '89283080527ffff' in out - assert '89283095edbffff' in out + out = h3.h3shape_to_cells_experimental(poly, res=9, containment='center') + + assert len(out) == 1253 + assert '89283080527ffff' in out + assert '89283095edbffff' in out def test_h3shape_to_cells_experimental_full(): poly = h3.LatLngPoly(sf_7x7) - for flags in ['full']: - out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) - assert len(out) == 1175 - assert '89283082a1bffff' in out - assert '89283080527ffff' not in out - assert '89283095edbffff' in out + out = h3.h3shape_to_cells_experimental(poly, res=9, containment='full') + + assert len(out) == 1175 + assert '89283082a1bffff' in out + assert '89283080527ffff' not in out + assert '89283095edbffff' in out def test_h3shape_to_cells_experimental_overlapping(): poly = h3.LatLngPoly(sf_7x7) - for flags in ['overlap']: - out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) - assert len(out) == 1334 - assert '89283080527ffff' in out - assert '89283095edbffff' in out + out = h3.h3shape_to_cells_experimental(poly, res=9, containment='overlap') + + assert len(out) == 1334 + assert '89283080527ffff' in out + assert '89283095edbffff' in out -# TODO: fix these for flags loops def test_h3shape_to_cells_experimental_overlapping_bbox(): poly = h3.LatLngPoly(sf_7x7) - for flags in [ - 'bbox_overlap' - ]: - out = h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) + out = h3.h3shape_to_cells_experimental(poly, res=9, containment='bbox_overlap') - assert len(out) == 1416 - assert '89283080527ffff' in out - assert '89283095edbffff' in out + assert len(out) == 1416 + assert '89283080527ffff' in out + assert '89283095edbffff' in out def test_h3shape_to_cells_experimental_invalid_mode(): poly = h3.LatLngPoly(sf_7x7) - for flags in ['containment_overlapping_bbox_abc']: - with pytest.raises(KeyError): - h3.h3shape_to_cells_experimental(poly, res=9, containment=flags) + with pytest.raises(KeyError): + h3.h3shape_to_cells_experimental( + poly, + res = 9, + containment = 'containment_overlapping_bbox_abc', + ) def test_poly_to_cells_experimental_mpoly(): @@ -185,8 +184,8 @@ def test_poly_to_cells_experimental_mpoly(): < set(h3.h3shape_to_cells_experimental( mpoly, - res=9, - containment='overlap' + res = 9, + containment = 'overlap' )) ) From 81a96e2b436d63c4472da3e9ae22f4ed70b635a4 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 21:11:39 -0800 Subject: [PATCH 6/9] don't repeat tests --- .github/workflows/lint_and_coverage.yml | 4 ++-- makefile | 4 ++-- pyproject.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint_and_coverage.yml b/.github/workflows/lint_and_coverage.yml index ab23b27c..723677cc 100644 --- a/.github/workflows/lint_and_coverage.yml +++ b/.github/workflows/lint_and_coverage.yml @@ -28,10 +28,10 @@ jobs: - name: Coverage Requirement - Library run: | - pytest --cov=tests/test_lib --cov-fail-under=100 + pytest tests/test_lib --cov=h3 --cov=tests/test_lib --cov-fail-under=100 - name: Coverage - Cython run: | pip install cython cythonize tests/test_cython/cython_example.pyx - pytest --cov=tests/test_cython + pytest tests/test_cython --cov=tests/test_cython diff --git a/makefile b/makefile index e6b02837..df39c8f4 100644 --- a/makefile +++ b/makefile @@ -35,11 +35,11 @@ purge: clear -@rm -rf env test: - ./env/bin/pytest --cov=tests/test_lib --cov-fail-under=100 + ./env/bin/pytest tests/test_lib --cov=h3 --cov=tests/test_lib --cov-fail-under=100 ./env/bin/pip install cython ./env/bin/cythonize tests/test_cython/cython_example.pyx - ./env/bin/pytest --cov=tests/test_cython + ./env/bin/pytest tests/test_cython --cov=tests/test_cython lint: ./env/bin/ruff check diff --git a/pyproject.toml b/pyproject.toml index e1cc0ba9..06ce0e3b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -63,7 +63,7 @@ all = [ ] [tool.pytest.ini_options] -addopts = "--cov=h3 --cov-report=term-missing --durations=10" +addopts = "--cov-report=term-missing --durations=10" [tool.coverage.run] omit = [ From 022de273a8385612e0e443e74181a3d7dfe7e7bd Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 21:25:53 -0800 Subject: [PATCH 7/9] experimental warning --- src/h3/api/basic_int/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index 57ef64c5..de776919 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -533,6 +533,10 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): Using ``containment='center'`` should give identical behavior as ``h3shape_to_cells``. + Note that this function is **experimental** and has no API stability gaurantees + across versions, so it may change in the future. + + Parameters ---------- h3shape : ``H3Shape`` From 49dbf59ff4e35cb94dec0fd13daa75036b7f7269 Mon Sep 17 00:00:00 2001 From: ajfriend Date: Mon, 30 Dec 2024 21:50:46 -0800 Subject: [PATCH 8/9] Being experimental, try `contain` instead of `containment` in params --- src/h3/api/basic_int/__init__.py | 10 +++++----- tests/test_lib/polyfill/test_h3.py | 16 ++++++++-------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index de776919..c898ada6 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -525,12 +525,12 @@ def polygon_to_cells(h3shape, res): return h3shape_to_cells(h3shape, res) -def h3shape_to_cells_experimental(h3shape, res, containment='center'): +def h3shape_to_cells_experimental(h3shape, res, contain='center'): """ Experimental function similar to ``h3shape_to_cells``, but with support for multiple cell containment modes. - Using ``containment='center'`` should give identical behavior as + Using ``contain='center'`` should give identical behavior as ``h3shape_to_cells``. Note that this function is **experimental** and has no API stability gaurantees @@ -542,7 +542,7 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): h3shape : ``H3Shape`` res : int Resolution of the output cells - containment : {'center', 'full', 'overlap', 'bbox_overlap'} + contain : {'center', 'full', 'overlap', 'bbox_overlap'} Specifies the containment condition. - 'center': Cell center is contained in shape - 'full': Cell is fully contained in shape @@ -574,14 +574,14 @@ def h3shape_to_cells_experimental(h3shape, res, containment='center'): There is currently no guaranteed order of the output cells. """ - containment_modes = { + contain_modes = { 'center': 0, 'full': 1, 'overlap': 2, 'bbox_overlap': 3, } - flag = containment_modes[containment] + flag = contain_modes[contain] # todo: not sure if i want this dispatch logic here. maybe in the objects? if isinstance(h3shape, LatLngPoly): diff --git a/tests/test_lib/polyfill/test_h3.py b/tests/test_lib/polyfill/test_h3.py index 72ed86ff..cb26fdd4 100644 --- a/tests/test_lib/polyfill/test_h3.py +++ b/tests/test_lib/polyfill/test_h3.py @@ -120,7 +120,7 @@ def test_polygon_to_cells(): def test_h3shape_to_cells_experimental(): poly = h3.LatLngPoly(sf_7x7) - out = h3.h3shape_to_cells_experimental(poly, res=9, containment='center') + out = h3.h3shape_to_cells_experimental(poly, res=9, contain='center') assert len(out) == 1253 assert '89283080527ffff' in out @@ -130,7 +130,7 @@ def test_h3shape_to_cells_experimental(): def test_h3shape_to_cells_experimental_full(): poly = h3.LatLngPoly(sf_7x7) - out = h3.h3shape_to_cells_experimental(poly, res=9, containment='full') + out = h3.h3shape_to_cells_experimental(poly, res=9, contain='full') assert len(out) == 1175 assert '89283082a1bffff' in out @@ -141,7 +141,7 @@ def test_h3shape_to_cells_experimental_full(): def test_h3shape_to_cells_experimental_overlapping(): poly = h3.LatLngPoly(sf_7x7) - out = h3.h3shape_to_cells_experimental(poly, res=9, containment='overlap') + out = h3.h3shape_to_cells_experimental(poly, res=9, contain='overlap') assert len(out) == 1334 assert '89283080527ffff' in out @@ -150,7 +150,7 @@ def test_h3shape_to_cells_experimental_overlapping(): def test_h3shape_to_cells_experimental_overlapping_bbox(): poly = h3.LatLngPoly(sf_7x7) - out = h3.h3shape_to_cells_experimental(poly, res=9, containment='bbox_overlap') + out = h3.h3shape_to_cells_experimental(poly, res=9, contain='bbox_overlap') assert len(out) == 1416 assert '89283080527ffff' in out @@ -163,7 +163,7 @@ def test_h3shape_to_cells_experimental_invalid_mode(): h3.h3shape_to_cells_experimental( poly, res = 9, - containment = 'containment_overlapping_bbox_abc', + contain = 'contain_overlapping_bbox_abc', ) @@ -176,7 +176,7 @@ def test_poly_to_cells_experimental_mpoly(): assert ( set(h3.h3shape_to_cells_experimental(mpoly, res=9)) == - set(h3.h3shape_to_cells_experimental(mpoly, res=9, containment='center')) + set(h3.h3shape_to_cells_experimental(mpoly, res=9, contain='center')) ) assert ( @@ -185,14 +185,14 @@ def test_poly_to_cells_experimental_mpoly(): set(h3.h3shape_to_cells_experimental( mpoly, res = 9, - containment = 'overlap' + contain = 'overlap' )) ) assert 120 == len(h3.h3shape_to_cells_experimental( mpoly, res = 9, - containment = 'overlap' + contain = 'overlap' )) From 4b805bf1bb748a85cdd937783ed3e94a4540bb8d Mon Sep 17 00:00:00 2001 From: ajfriend Date: Thu, 2 Jan 2025 12:27:12 -0800 Subject: [PATCH 9/9] try typing with literal --- src/h3/api/basic_int/__init__.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index c898ada6..46579107 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -1,4 +1,5 @@ # This file is **symlinked** across the APIs to ensure they are exactly the same. +from typing import Literal from ... import _cy from ..._h3shape import ( @@ -525,7 +526,11 @@ def polygon_to_cells(h3shape, res): return h3shape_to_cells(h3shape, res) -def h3shape_to_cells_experimental(h3shape, res, contain='center'): +def h3shape_to_cells_experimental( + h3shape: H3Shape, + res: int, + contain: Literal['center', 'full', 'overlap', 'bbox_overlap'] = 'center', +): """ Experimental function similar to ``h3shape_to_cells``, but with support for multiple cell containment modes. @@ -542,13 +547,15 @@ def h3shape_to_cells_experimental(h3shape, res, contain='center'): h3shape : ``H3Shape`` res : int Resolution of the output cells - contain : {'center', 'full', 'overlap', 'bbox_overlap'} + contain : {'center', 'full', 'overlap', 'bbox_overlap'}, optional Specifies the containment condition. - 'center': Cell center is contained in shape - 'full': Cell is fully contained in shape - 'overlap': Cell is partially contained in shape - 'bbox_overlap': Cell bounding box is partially contained in shape + Default is 'center'. + Returns ------- list of H3Cell