diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 45f007fb..ee175036 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -14,7 +14,7 @@ jobs: strategy: matrix: os: [macos-latest, windows-latest, ubuntu-22.04] - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', '3.12'] + python-version: ['3.8', '3.9', '3.10', '3.11', '3.12'] steps: - uses: actions/checkout@v4.1.1 diff --git a/docs/api_quick.md b/docs/api_quick.md index 731f8a98..d73f1144 100644 --- a/docs/api_quick.md +++ b/docs/api_quick.md @@ -110,7 +110,7 @@ Functions relating H3 objects to geographic (lat/lng) coordinates. ## Polygon interface -The ``H3Poly`` and ``H3MultiPoly`` objects and their related functions allow users to represent (multi)polygons of lat/lng points and convert back and forth between H3 cells. +The ``LatLngPoly`` and ``LatLngMultiPoly`` objects and their related functions allow users to represent (multi)polygons of lat/lng points and convert back and forth between H3 cells. The objects and functions also compatible with the popular [``__geo_interface__`` protocol](https://gist.github.com/sgillies/2217756), which is used by Python geospatial libraries like [GeoPandas](https://geopandas.org/en/stable/docs/reference/api/geopandas.GeoDataFrame.__geo_interface__.html) and many plotting libraries. @@ -128,8 +128,8 @@ Note that this is reversed from [``__geo_interface__``](https://gist.github.com/ .. autosummary:: H3Shape - H3Poly - H3MultiPoly + LatLngPoly + LatLngMultiPoly ``` ### Conversion functions diff --git a/docs/polygon_tutorial.ipynb b/docs/polygon_tutorial.ipynb index c5efd91e..7e0a1e93 100644 --- a/docs/polygon_tutorial.ipynb +++ b/docs/polygon_tutorial.ipynb @@ -9,15 +9,15 @@ "\n", "`h3-py` can convert between sets of cells and GeoJSON-like polygon and multipolygon shapes.\n", "\n", - "We use the abstract base class `H3Shape` and its concrete child classes `H3Poly` and `H3MultiPoly`\n", + "We use the abstract base class `H3Shape` and its concrete child classes `LatLngPoly` and `LatLngMultiPoly`\n", "to represent these shapes. \n", - "Any references or function names that use \"H3Shape\" will apply to both `H3Poly` and `H3MultiPoly` objects.\n", + "Any references or function names that use \"H3Shape\" will apply to both `LatLngPoly` and `LatLngMultiPoly` objects.\n", "\n", "`h3-py` is also compatible with Python objects that implement `__geo_interface__` (https://gist.github.com/sgillies/2217756),\n", "making it easy to interface with other Python geospatial libraries.\n", "We'll refer to any such object as a \"geo\" or \"geo object\".\n", "\n", - "`H3Poly` and `H3MultiPoly` both implement `__geo_interface__` (making them geo objects themselves),\n", + "`LatLngPoly` and `LatLngMultiPoly` both implement `__geo_interface__` (making them geo objects themselves),\n", "and can be created from other geo objects, like Shapely's `Polygon` or `MultiPolygon` objects that occur\n", "when using `geopandas`.\n", "\n", @@ -79,9 +79,9 @@ "id": "c5a41e2b-0c9e-45f5-8005-51af2ef8af32", "metadata": {}, "source": [ - "# H3Poly\n", + "# LatLngPoly\n", "\n", - "We can create a simple `H3Poly` object by providing a list of the **latitude/longitude pairs** that describe its exterior.\n", + "We can create a simple `LatLngPoly` object by providing a list of the **latitude/longitude pairs** that describe its exterior.\n", "Optionally, holes can be added to the polygon by appending additional lat/lng lists do describe them." ] }, @@ -98,7 +98,7 @@ " (37.733, -122.501)\n", "]\n", "\n", - "poly = h3.H3Poly(outer)\n", + "poly = h3.LatLngPoly(outer)\n", "print(poly)\n", "plot_shape(poly)" ] @@ -116,7 +116,7 @@ " (37.788, -122.454),\n", "]\n", "\n", - "poly = h3.H3Poly(outer, hole1)\n", + "poly = h3.LatLngPoly(outer, hole1)\n", "print(poly)\n", "plot_shape(poly)" ] @@ -135,7 +135,7 @@ " (37.769, -122.496),\n", "]\n", "\n", - "poly = h3.H3Poly(outer, hole1, hole2)\n", + "poly = h3.LatLngPoly(outer, hole1, hole2)\n", "print(poly)\n", "plot_shape(poly)" ] @@ -147,13 +147,13 @@ "source": [ "## String representation and attributes\n", "\n", - "The `H3Poly` string representation given by its `__repr__` shows the number of vertices in the outer loop of the polygon, followed\n", + "The `LatLngPoly` string representation given by its `__repr__` shows the number of vertices in the outer loop of the polygon, followed\n", "by the number of vertices in each hole.\n", "\n", "A representation like\n", "\n", "```\n", - "\n", + "\n", "```\n", "\n", "denotes a polygon whose outer boundary consists of 3 vertices and which has 2 holes,\n", @@ -161,8 +161,8 @@ "\n", "We can access the coordinates describing the polygon through the attributes:\n", "\n", - "- `H3Poly.outer` gives the list of lat/lng points making up the outer loop of the polygon.\n", - "- `H3Poly.holes` gives each of the lists of lat/lng points making up the holes of the polygon." + "- `LatLngPoly.outer` gives the list of lat/lng points making up the outer loop of the polygon.\n", + "- `LatLngPoly.holes` gives each of the lists of lat/lng points making up the holes of the polygon." ] }, { @@ -172,7 +172,7 @@ "metadata": {}, "outputs": [], "source": [ - "poly = h3.H3Poly(outer, hole1, hole2)\n", + "poly = h3.LatLngPoly(outer, hole1, hole2)\n", "poly" ] }, @@ -203,9 +203,9 @@ "source": [ "## `__geo_interface__`\n", "\n", - "`H3Poly.__geo_interface__` gives a GeoJSON representation of the polygon as described in https://gist.github.com/sgillies/2217756\n", + "`LatLngPoly.__geo_interface__` gives a GeoJSON representation of the polygon as described in https://gist.github.com/sgillies/2217756\n", "\n", - "**Note the differences in this representation**: Points are given in **lng/lat** order (but the `H3Poly` constructor expects **lat/lng** order), and the last vertex repeats the first." + "**Note the differences in this representation**: Points are given in **lng/lat** order (but the `LatLngPoly` constructor expects **lat/lng** order), and the last vertex repeats the first." ] }, { @@ -235,7 +235,7 @@ "id": "8f567fae-9f4e-472f-afcd-bd6f7bb32cba", "metadata": {}, "source": [ - "We can create an `H3Poly` object from a GeoJSON-like dictionary or an object that implements `__geo_interface__` using `h3.geo_to_h3shape()`." + "We can create an `LatLngPoly` object from a GeoJSON-like dictionary or an object that implements `__geo_interface__` using `h3.geo_to_h3shape()`." ] }, { @@ -272,7 +272,7 @@ "id": "0ab82119-9d9e-465d-94b5-61083e9d9df3", "metadata": {}, "source": [ - "Also note that `H3Poly.__geo_interface__` is equivalent to calling `h3.h3shape_to_geo()` on an `H3Poly` object." + "Also note that `LatLngPoly.__geo_interface__` is equivalent to calling `h3.h3shape_to_geo()` on an `LatLngPoly` object." ] }, { @@ -292,7 +292,7 @@ "source": [ "## Polygon to cells\n", "\n", - "We can get all the H3 cells whose centroids fall within an `H3Poly` by using `h3.h3shape_to_cells()` and specifying the resolution." + "We can get all the H3 cells whose centroids fall within an `LatLngPoly` by using `h3.h3shape_to_cells()` and specifying the resolution." ] }, { @@ -350,15 +350,15 @@ "source": [ "## H3 Polygons don't need to follow the right-hand rule\n", "\n", - "`H3Poly` objects do not need to follow the \"right-hand rule\", unlike GeoJSON Polygons. \n", + "`LatLngPoly` objects do not need to follow the \"right-hand rule\", unlike GeoJSON Polygons. \n", "The right-hand rule requires that vertices in outer loops are listed in counterclockwise\n", "order and holes are listed in clockwise order.\n", "`h3-py` accepts loops in any order and will usually interpret them as the user intended, for example,\n", "converting to sets of cells. However, `h3-py` won't re-order your loops to\n", "conform to the right-hand rule, so be careful if you're using `__geo_interface__` to plot them.\n", "\n", - "Obeying the right-hand rule is only a concern when creating `H3Poly` objects from external input; `H3Poly` or `H3MultiPoly`\n", - "objects created through `h3.cells_to_shape()` **will respect the right-hand rule**.\n", + "Obeying the right-hand rule is only a concern when creating `LatLngPoly` objects from external input; `LatLngPoly` or `LatLngMultiPoly`\n", + "objects created through `h3.cells_to_h3shape()` **will respect the right-hand rule**.\n", "\n", "For example, if we reverse the order of one of the holes in our example polygon above,\n", "the hole won't be rendered correctly, but the conversion to cells will remain unchanged." @@ -372,7 +372,7 @@ "outputs": [], "source": [ "# Respects right-hand rule\n", - "poly = h3.H3Poly(outer, hole1, hole2)\n", + "poly = h3.LatLngPoly(outer, hole1, hole2)\n", "plot_shape_and_cells(poly, res=10)" ] }, @@ -385,7 +385,7 @@ "source": [ "# Does not respect right-hand-rule; second hole is reversed\n", "# Conversion to cells still works, tho!\n", - "poly = h3.H3Poly(outer, hole1[::-1], hole2)\n", + "poly = h3.LatLngPoly(outer, hole1[::-1], hole2)\n", "plot_shape_and_cells(poly, res=10)" ] }, @@ -398,7 +398,7 @@ "source": [ "# Does not respect right-hand-rule; outer loop and second hole are both reversed\n", "# Conversion to cells still works, tho!\n", - "poly = h3.H3Poly(outer[::-1], hole1[::-1], hole2)\n", + "poly = h3.LatLngPoly(outer[::-1], hole1[::-1], hole2)\n", "plot_shape_and_cells(poly, res=10)" ] }, @@ -407,13 +407,13 @@ "id": "b0b13d4a-a376-4a8f-b314-898d9cf94c59", "metadata": {}, "source": [ - "# H3MultiPoly\n", + "# LatLngMultiPoly\n", "\n", - "An `H3MultiPoly` can be created from `H3Poly` objects. The string representation of the `H3MultiPoly`\n", - "gives the number of vertices in the outer loop of each `H3Poly`, along with the number of vertices\n", + "An `LatLngMultiPoly` can be created from `LatLngPoly` objects. The string representation of the `LatLngMultiPoly`\n", + "gives the number of vertices in the outer loop of each `LatLngPoly`, along with the number of vertices\n", "in each hole (if there are any).\n", "\n", - "For example `` represents an `H3MultiPoly` consisting of two `H3Poly` polygons:\n", + "For example `` represents an `LatLngMultiPoly` consisting of two `LatLngPoly` polygons:\n", "\n", "- the first polygon has 3 outer vertices and no holes\n", "- the second polygon has 4 outer vertices and 1 hole with 5 vertices" @@ -426,12 +426,12 @@ "metadata": {}, "outputs": [], "source": [ - "poly1 = h3.H3Poly([(37.804, -122.412), (37.778, -122.507), (37.733, -122.501)])\n", - "poly2 = h3.H3Poly(\n", + "poly1 = h3.LatLngPoly([(37.804, -122.412), (37.778, -122.507), (37.733, -122.501)])\n", + "poly2 = h3.LatLngPoly(\n", " [(37.803, -122.408), (37.736, -122.491), (37.738, -122.380), (37.787, -122.39)],\n", " [(37.760, -122.441), (37.772, -122.427), (37.773, -122.404), (37.758, -122.401), (37.745, -122.428)]\n", ")\n", - "mpoly = h3.H3MultiPoly(poly1, poly2)\n", + "mpoly = h3.LatLngMultiPoly(poly1, poly2)\n", "\n", "print(poly1)\n", "print(poly2)\n", @@ -455,7 +455,7 @@ "source": [ "## MultiPolygon to cells\n", "\n", - "`h3.h3shape_to_cells()` works on both `H3MultiPoly` and `H3Poly` objects (both are subclasses of `H3Shape`)." + "`h3.h3shape_to_cells()` works on both `LatLngMultiPoly` and `LatLngPoly` objects (both are subclasses of `H3Shape`)." ] }, { @@ -474,10 +474,10 @@ "id": "f3712d99-cbe2-4f42-80e3-0acf3fcb8e25", "metadata": {}, "source": [ - "## H3MultiPoly affordances\n", + "## LatLngMultiPoly affordances\n", "\n", - "- Calling `len()` on an `H3MultiPoly` gives the number of polygons\n", - "- You can iterate through a `H3MultiPoly`, with the elements being the underlying `H3Poly`s" + "- Calling `len()` on an `LatLngMultiPoly` gives the number of polygons\n", + "- You can iterate through a `LatLngMultiPoly`, with the elements being the underlying `LatLngPoly`s" ] }, { @@ -518,7 +518,7 @@ "source": [ "## `__geo_interface__`\n", "\n", - "`H3MultiPoly` implements `__geo_interface__`, and `H3MultiPoly` objects can also be created through `h3.geo_to_h3shape()`." + "`LatLngMultiPoly` implements `__geo_interface__`, and `LatLngMultiPoly` objects can also be created through `h3.geo_to_h3shape()`." ] }, { @@ -548,9 +548,9 @@ "id": "a2b71ee2-deed-4336-8b2c-2ab740555188", "metadata": {}, "source": [ - "# Cells to H3Poly or H3MultiPoly\n", + "# Cells to LatLngPoly or LatLngMultiPoly\n", "\n", - "If you have a set of H3 cells that you would like to visualize, you may want to convert them to `H3Poly` or `H3MultiPoly` objects using `h3.cells_to_h3shape()` and then use `__geo_interface__` to get their GeoJSON representation. Or you could\n", + "If you have a set of H3 cells that you would like to visualize, you may want to convert them to `LatLngPoly` or `LatLngMultiPoly` objects using `h3.cells_to_h3shape()` and then use `__geo_interface__` to get their GeoJSON representation. Or you could\n", "use `h3.cells_to_geo()` to get the GeoJSON dictionary directly." ] }, @@ -610,7 +610,7 @@ "\"Geo objects\" are any Python object that implements `__geo_interface__`. This is a widely used\n", "standard in geospatial Python and is used by libraries like `geopandas` and Shapely.\n", "\n", - "`H3Shape` is an abstract class implemented by `H3Poly` and `H3MultiPoly`, each of which\n", + "`H3Shape` is an abstract class implemented by `LatLngPoly` and `LatLngMultiPoly`, each of which\n", "implement `__geo_interface__` and can be created from external \"Geo objects\":\n", "\n", "- `geo_to_h3shape()`\n", @@ -810,7 +810,7 @@ "If we assign `df.geometry = cell_column` we'll get an error because the `geometry` column of a `geopandas.GeoDataFrame` must contain valid geometry objects.\n", "We can obtain compatible objects by converting the cells to `H3Shape` by applying `h3.cells_to_h3shape()`.\n", "\n", - "(Note that, unfortunately, Pandas has some logic to identify iterable members of a series and then renders a tuple of the elements, rather than our preferred `H3MultiPoly.__repr__` representation.)" + "(Note that, unfortunately, Pandas has some logic to identify iterable members of a series and then renders a tuple of the elements, rather than our preferred `LatLngMultiPoly.__repr__` representation.)" ] }, { @@ -829,7 +829,7 @@ "id": "1965d53f-2bba-4840-a627-1bbf55405be3", "metadata": {}, "source": [ - "Note that the column now consists of `H3Poly` and `H3MultiPoly` objects." + "Note that the column now consists of `LatLngPoly` and `LatLngMultiPoly` objects." ] }, { diff --git a/src/h3/_h3shape.py b/src/h3/_h3shape.py index 974a91ad..a9f1ebb0 100644 --- a/src/h3/_h3shape.py +++ b/src/h3/_h3shape.py @@ -3,7 +3,7 @@ class H3Shape(metaclass=ABCMeta): """ - Abstract parent class of ``H3Poly`` and ``H3MultiPoly``. + Abstract parent class of ``LatLngPoly`` and ``LatLngMultiPoly``. """ @property @abstractmethod @@ -11,7 +11,7 @@ def __geo_interface__(self): """ https://github.com/pytest-dev/pytest-cov/issues/428 """ -class H3Poly(H3Shape): +class LatLngPoly(H3Shape): """ Container for loops of lat/lng points describing a polygon, possibly with holes. @@ -28,34 +28,34 @@ class H3Poly(H3Shape): A polygon with a single outer ring consisting of 4 points, having no holes: - >>> H3Poly( + >>> LatLngPoly( ... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34), (37.82, -122.54)], ... ) - + The same polygon, but with one hole consisting of 3 points: - >>> H3Poly( + >>> LatLngPoly( ... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34), (37.82, -122.54)], ... [(37.76, -122.51), (37.76, -122.44), (37.81, -122.51)], ... ) - + The same as above, but with one additional hole, made up of 5 points: - >>> H3Poly( + >>> LatLngPoly( ... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34), (37.82, -122.54)], ... [(37.76, -122.51), (37.76, -122.44), (37.81, -122.51)], ... [(37.71, -122.43), (37.71, -122.37), (37.73, -122.37), (37.75, -122.41), ... (37.73, -122.43)], ... ) - + """ def __init__(self, outer, *holes): loops = [outer] + list(holes) for loop in loops: if len(loop) in (1, 2): - raise ValueError('Non-empty H3Poly loops need at least 3 points.') + raise ValueError('Non-empty LatLngPoly loops need at least 3 points.') self.outer = tuple(_open_ring(outer)) self.holes = tuple( @@ -64,14 +64,14 @@ def __init__(self, outer, *holes): ) def __repr__(self): - return ''.format(self.loopcode) + return ''.format(self.loopcode) def __len__(self): """ Should this be the number of points in the outer loop, the number of holes (or +1 for the outer loop)? """ - raise NotImplementedError('No clear definition of length for H3Poly.') + raise NotImplementedError('No clear definition of length for LatLngPoly.') @property def loopcode(self): @@ -102,26 +102,26 @@ def __geo_interface__(self): return gj_dict -class H3MultiPoly(H3Shape): +class LatLngMultiPoly(H3Shape): """ - Container for multiple ``H3Poly`` polygons. + Container for multiple ``LatLngPoly`` polygons. Attributes ---------- - polys : list[H3Poly] + polys : list[LatLngPoly] List of lat/lng points describing the outer loop of the polygon """ def __init__(self, *polys): self.polys = tuple(polys) for p in self.polys: - if not isinstance(p, H3Poly): - raise ValueError('H3MultiPoly requires each input to be an H3Poly object, instead got: ' + str(p)) # noqa + if not isinstance(p, LatLngPoly): + raise ValueError('LatLngMultiPoly requires each input to be an LatLngPoly object, instead got: ' + str(p)) # noqa def __repr__(self): out = [p.loopcode for p in self.polys] out = ', '.join(out) - out = ''.format(out) + out = ''.format(out) return out def __iter__(self): @@ -135,24 +135,25 @@ def __len__(self): TODO: Pandas series or dataframe representation changes depending on if __len__ is defined. - I'd prefer the one that states `H3MultiPoly`. It seems like Pandas is assuming - an iterable is best-described by its elements when choosing the representation. + I'd prefer the one that states `LatLngMultiPoly`. + It seems like Pandas is assuming an iterable is best-described + by its elements when choosing the representation. when __len__ *IS NOT* defined: - 0 - 1 + 1 , , ) - 1 (, , , , , , <... + 0 (, , ) + 1 (, , , , , , <... """ return len(self.polys) @@ -203,13 +204,13 @@ def _LL3_to_mpoly(ll3): for ll2 in ll3 ] - mpoly = H3MultiPoly(*polys) + mpoly = LatLngMultiPoly(*polys) return mpoly -def _polygon_to_LL2(h3poly): - ll2 = [h3poly.outer] + list(h3poly.holes) +def _polygon_to_LL2(LatLngPoly): + ll2 = [LatLngPoly.outer] + list(LatLngPoly.holes) ll2 = tuple( _close_ring(_swap_latlng(ll1)) for ll1 in ll2 @@ -223,7 +224,7 @@ def _LL2_to_polygon(ll2): _swap_latlng(ll1) for ll1 in ll2 ] - h3poly = H3Poly(*ll2) + h3poly = LatLngPoly(*ll2) return h3poly @@ -284,7 +285,7 @@ def geo_to_h3shape(geo): H3Shape """ - # geo can be dict, a __geo_interface__, a string, H3Poly or H3MultiPoly + # geo can be dict, a __geo_interface__, a string, LatLngPoly or LatLngMultiPoly if isinstance(geo, H3Shape): return geo @@ -299,21 +300,21 @@ def geo_to_h3shape(geo): if t == 'Polygon': ll2 = coord - h3shape = _LL2_to_polygon(ll2) + shape = _LL2_to_polygon(ll2) elif t == 'MultiPolygon': ll3 = coord - h3shape = _LL3_to_mpoly(ll3) + shape = _LL3_to_mpoly(ll3) else: raise ValueError('Unrecognized type: ' + str(t)) - return h3shape + return shape def h3shape_to_geo(h3shape): """ Translate from an ``H3Shape`` to a ``__geo_interface__`` dict. - ``h3shape`` should be either ``H3Poly`` or ``H3MultiPoly`` + ``h3shape`` should be either ``LatLngPoly`` or ``LatLngMultiPoly`` Returns ------- diff --git a/src/h3/api/basic_int/__init__.py b/src/h3/api/basic_int/__init__.py index 4106f3b9..d1122d83 100644 --- a/src/h3/api/basic_int/__init__.py +++ b/src/h3/api/basic_int/__init__.py @@ -3,8 +3,8 @@ from ... import _cy from ..._h3shape import ( H3Shape, - H3Poly, - H3MultiPoly, + LatLngPoly, + LatLngMultiPoly, geo_to_h3shape, h3shape_to_geo, ) @@ -398,11 +398,11 @@ def uncompact_cells(cells, res): def h3shape_to_cells(h3shape, res): """ Return the collection of H3 cells at a given resolution whose center points - are contained within an ``H3Poly`` or ``H3MultiPoly``. + are contained within an ``LatLngPoly`` or ``LatLngMultiPoly``. Parameters ---------- - h3shape : ``H3shape`` + h3shape : ``H3Shape`` res : int Resolution of the output cells @@ -413,7 +413,7 @@ def h3shape_to_cells(h3shape, res): Examples -------- - >>> poly = H3Poly( + >>> poly = LatLngPoly( ... [(37.68, -122.54), (37.68, -122.34), (37.82, -122.34), ... (37.82, -122.54)], ... ) @@ -432,10 +432,10 @@ def h3shape_to_cells(h3shape, res): """ # todo: not sure if i want this dispatch logic here. maybe in the objects? - if isinstance(h3shape, H3Poly): + if isinstance(h3shape, LatLngPoly): poly = h3shape mv = _cy.polygon_to_cells(poly.outer, res, holes=poly.holes) - elif isinstance(h3shape, H3MultiPoly): + elif isinstance(h3shape, LatLngMultiPoly): mpoly = h3shape mv = _cy.polygons_to_cells(mpoly.polys, res) elif isinstance(h3shape, H3Shape): @@ -446,35 +446,36 @@ def h3shape_to_cells(h3shape, res): return _out_collection(mv) -def cells_to_h3shape(cells, tight=True): +def cells_to_h3shape(cells, *, tight=True): """ Return an ``H3Shape`` describing the area covered by a collection of H3 cells. - Will return ``H3Poly`` or ``H3MultiPoly``. + Will return ``LatLngPoly`` or ``LatLngMultiPoly``. Parameters ---------- cells : iterable of H3 cells tight : bool - If True, return ``H3Poly`` if possible. If False, always return ``H3MultiPoly``. + If True, return ``LatLngPoly`` if possible. + If False, always return ``LatLngMultiPoly``. Returns ------- - H3Poly | H3MultiPoly + LatLngPoly | LatLngMultiPoly Examples -------- >>> cells = ['8428309ffffffff', '842830dffffffff'] >>> h3.cells_to_h3shape(cells, tight=True) - + >>> h3.cells_to_h3shape(cells, tight=False) - + """ cells = _in_collection(cells) mpoly = _cy.cells_to_multi_polygon(cells) - polys = [H3Poly(*poly) for poly in mpoly] - out = H3MultiPoly(*polys) + polys = [LatLngPoly(*poly) for poly in mpoly] + out = LatLngMultiPoly(*polys) if tight and len(out) == 1: out = out[0] @@ -488,7 +489,7 @@ def geo_to_cells(geo, res): Parameters ---------- geo : an object implementing ``__geo_interface__`` or a dictionary in that format. - Both ``H3Poly`` and ``H3MultiPoly`` implement the interface. + Both ``LatLngPoly`` and ``LatLngMultiPoly`` implement the interface. res : int Resolution of desired output cells. @@ -508,8 +509,8 @@ def cells_to_geo(cells, tight=True): ---------- cells : iterable of H3 Cells tight : bool - When ``True``, returns an ``H3Poly`` when possible. - When ``False``, always returns an ``H3MultiPoly``. + When ``True``, returns an ``LatLngPoly`` when possible. + When ``False``, always returns an ``LatLngMultiPoly``. Returns ------- diff --git a/tests/polyfill/test_h3.py b/tests/polyfill/test_h3.py index 78d32238..dbed67b6 100644 --- a/tests/polyfill/test_h3.py +++ b/tests/polyfill/test_h3.py @@ -74,8 +74,8 @@ def get_mocked(loop): def test_geo_interface(): - poly = h3.H3Poly(sf_hole1) - mpoly = h3.H3MultiPoly(poly) + poly = h3.LatLngPoly(sf_hole1) + mpoly = h3.LatLngMultiPoly(poly) assert poly.__geo_interface__['type'] == 'Polygon' assert mpoly.__geo_interface__['type'] == 'MultiPolygon' @@ -88,18 +88,18 @@ def test_geo_interface(): def test_shape_repr(): - poly = h3.H3Poly(sf_hole1) - mpoly = h3.H3MultiPoly(poly) + poly = h3.LatLngPoly(sf_hole1) + mpoly = h3.LatLngMultiPoly(poly) assert ( - '' + '' == str(mpoly) == repr(mpoly) ) def test_polyfill(): - poly = h3.H3Poly(sf_7x7) + poly = h3.LatLngPoly(sf_7x7) out = h3.h3shape_to_cells(poly, res=9) assert len(out) == 1253 @@ -108,12 +108,12 @@ def test_polyfill(): def test_polyfill_with_hole(): - poly = h3.H3Poly(sf_7x7, sf_hole1) + poly = h3.LatLngPoly(sf_7x7, sf_hole1) out = h3.h3shape_to_cells(poly, res=9) assert len(out) == 1214 - foo = lambda x: set(h3.h3shape_to_cells(h3.H3Poly(x), 9)) + foo = lambda x: set(h3.h3shape_to_cells(h3.LatLngPoly(x), 9)) assert u.same_set( out, @@ -123,11 +123,11 @@ def test_polyfill_with_hole(): def test_polyfill_with_two_holes(): - poly = h3.H3Poly(sf_7x7, sf_hole1, sf_hole2) + poly = h3.LatLngPoly(sf_7x7, sf_hole1, sf_hole2) out = h3.h3shape_to_cells(poly, 9) assert len(out) == 1172 - foo = lambda x: set(h3.h3shape_to_cells(h3.H3Poly(x), 9)) + foo = lambda x: set(h3.h3shape_to_cells(h3.LatLngPoly(x), 9)) assert u.same_set( out, foo(sf_7x7) - (foo(sf_hole1) | foo(sf_hole2)) @@ -148,21 +148,21 @@ def test_polyfill_geo_interface_compliant(): def test_poly_opens_loop(): loop = lnglat_closed() - poly = h3.H3Poly(loop) + poly = h3.LatLngPoly(loop) assert loop[0] == loop[-1] assert len(poly.outer) == len(loop) - 1 def test_geo_to_h3shape(): - h3shapes = [ + shapes = [ h3.geo_to_h3shape(get_mocked(lnglat_open())), h3.geo_to_h3shape(get_mocked(lnglat_closed())), - h3.H3Poly(latlng_open()), - h3.H3Poly(latlng_closed()), + h3.LatLngPoly(latlng_open()), + h3.LatLngPoly(latlng_closed()), ] - for s in h3shapes: + for s in shapes: assert len(h3.h3shape_to_cells(s, 8)) == 48 expected = { @@ -175,10 +175,10 @@ def test_geo_to_h3shape(): ),) } - for shape in h3shapes: + for shape in shapes: assert shape.__geo_interface__ == expected - mpolys = map(h3.H3MultiPoly, h3shapes) + mpolys = map(h3.LatLngMultiPoly, shapes) multi_expected = { 'type': 'MultiPolygon', @@ -195,8 +195,8 @@ def test_geo_to_h3shape(): def test_geo_to_h3shape_passthrough(): - poly = h3.H3Poly(latlng_open()) - mpoly = h3.H3MultiPoly(poly) + poly = h3.LatLngPoly(latlng_open()) + mpoly = h3.LatLngMultiPoly(poly) for shape in [poly, mpoly]: assert h3.geo_to_h3shape(shape) is shape @@ -237,7 +237,7 @@ def test_polyfill_down_under(): (-33.8556, 151.1979), ] - poly = h3.H3Poly(sydney) + poly = h3.LatLngPoly(sydney) out = h3.h3shape_to_cells(poly, 9) assert len(out) == 92 assert '89be0e34207ffff' in out @@ -253,7 +253,7 @@ def test_polyfill_far_east(): (41.925781, 142.864838), ] - poly = h3.H3Poly(geo) + poly = h3.LatLngPoly(geo) out = h3.h3shape_to_cells(poly, 9) assert len(out) == 18507 assert '892e18d16c3ffff' in out @@ -269,7 +269,7 @@ def test_polyfill_southern_tip(): (-55.416544, -67.642822), ] - poly = h3.H3Poly(geo) + poly = h3.LatLngPoly(geo) out = h3.h3shape_to_cells(poly, 9) assert len(out) == 223247 assert '89df4000003ffff' in out @@ -285,7 +285,7 @@ def test_polyfill_null_island(): (-3, -3), ] - poly = h3.H3Poly(geo) + poly = h3.LatLngPoly(geo) out = h3.h3shape_to_cells(poly, 4) assert len(out) == 345 assert '847421bffffffff' in out @@ -306,7 +306,7 @@ def test_cells_to_h3shape_single(): poly = mpoly[0] vertices = h3.cell_to_boundary(h) - expected_poly = h3.H3Poly(vertices) + expected_poly = h3.LatLngPoly(vertices) assert set(poly.outer) == set(expected_poly.outer) assert poly.holes == expected_poly.holes == () @@ -378,10 +378,10 @@ def test_cells_to_h3shape_2grid_disk(): def test_multipoly_checks(): with pytest.raises(ValueError): - h3.H3MultiPoly('foo') + h3.LatLngMultiPoly('foo') with pytest.raises(ValueError): - h3.H3MultiPoly(1) + h3.LatLngMultiPoly(1) with pytest.raises(ValueError): - h3.H3MultiPoly([[(1, 2), (3, 4)]]) + h3.LatLngMultiPoly([[(1, 2), (3, 4)]]) diff --git a/tests/polyfill/test_polyfill.py b/tests/polyfill/test_polyfill.py index 541c453b..b78e8751 100644 --- a/tests/polyfill/test_polyfill.py +++ b/tests/polyfill/test_polyfill.py @@ -71,7 +71,7 @@ def test_h3shape_to_cells(): '832badfffffffff' } - poly = h3.H3Poly(maine) + poly = h3.LatLngPoly(maine) out = h3.h3shape_to_cells(poly, 3) assert u.same_set(out, expected) @@ -80,7 +80,7 @@ def test_h3shape_to_cells(): def test_h3shape_to_cells2(): lnglat, _, _ = get_us_box_coords() - poly = h3.H3Poly(lnglat) + poly = h3.LatLngPoly(lnglat) out = h3.h3shape_to_cells(poly, 5) assert len(out) == 7063 @@ -97,15 +97,16 @@ def test_h3shape_to_cells_holes(): outer, hole1, hole2 = get_us_box_coords() assert 7063 == len( - h3.h3shape_to_cells(h3.H3Poly(outer), 5) + h3.h3shape_to_cells(h3.LatLngPoly(outer), 5) ) for res in 1, 2, 3, 4, 5: - cells_all = h3.h3shape_to_cells(h3.H3Poly(outer), res) - cells_holes = set(h3.h3shape_to_cells(h3.H3Poly(outer, hole1, hole2), res=res)) + cells_all = h3.h3shape_to_cells(h3.LatLngPoly(outer), res) + poly = h3.LatLngPoly(outer, hole1, hole2) + cells_holes = set(h3.h3shape_to_cells(poly, res=res)) - cells_1 = set(h3.h3shape_to_cells(h3.H3Poly(hole1), res)) - cells_2 = set(h3.h3shape_to_cells(h3.H3Poly(hole2), res)) + cells_1 = set(h3.h3shape_to_cells(h3.LatLngPoly(hole1), res)) + cells_2 = set(h3.h3shape_to_cells(h3.LatLngPoly(hole2), res)) assert len(cells_all) == len(cells_holes) + len(cells_1) + len(cells_2) assert u.same_set( @@ -115,7 +116,7 @@ def test_h3shape_to_cells_holes(): def test_resolution(): - poly = h3.H3Poly([]) + poly = h3.LatLngPoly([]) assert h3.h3shape_to_cells(poly, 0) == [] assert h3.h3shape_to_cells(poly, 15) == [] @@ -134,11 +135,11 @@ def test_invalid_polygon(): some `cdef` functions. """ with pytest.raises(TypeError): - poly = h3.H3Poly([1, 2, 3]) + poly = h3.LatLngPoly([1, 2, 3]) h3.h3shape_to_cells(poly, 4) with pytest.raises(ValueError): - poly = h3.H3Poly([[1, 2, 3]]) + poly = h3.LatLngPoly([[1, 2, 3]]) h3.h3shape_to_cells(poly, 4) diff --git a/tests/polyfill/test_polyfill_ordering.py b/tests/polyfill/test_polyfill_ordering.py index 0206138b..e0e43d8f 100644 --- a/tests/polyfill/test_polyfill_ordering.py +++ b/tests/polyfill/test_polyfill_ordering.py @@ -44,7 +44,7 @@ def input_permutations(geo, res=5): g = chain_toggle_map(reverse, g) for p in g: - poly = h3.H3Poly(*p) + poly = h3.LatLngPoly(*p) cells = h3.h3shape_to_cells(poly, res=res) yield cells diff --git a/tests/polyfill/test_polygon_class.py b/tests/polyfill/test_polygon_class.py index 4ed7faa3..c38505dc 100644 --- a/tests/polyfill/test_polygon_class.py +++ b/tests/polyfill/test_polygon_class.py @@ -17,18 +17,18 @@ def test_repr(): mpoly2 = sorted(map(str, mpoly2)) assert mpoly1 == [ - '', - '', + '', + '', ] assert mpoly2 == [ - '', - '', - '', + '', + '', + '', ] -def test_h3poly_len(): +def test_LatLngPoly_len(): cells = {'8928308280fffff'} poly = h3.cells_to_h3shape(cells, tight=True) diff --git a/tests/polyfill/test_to_multipoly.py b/tests/polyfill/test_to_multipoly.py index 1207da2a..61f77f63 100644 --- a/tests/polyfill/test_to_multipoly.py +++ b/tests/polyfill/test_to_multipoly.py @@ -11,7 +11,7 @@ def test_cells_to_h3shape(): mpoly = h3.cells_to_h3shape(cells, tight=False) poly = mpoly[0] - poly2 = h3.H3Poly(poly.outer, *poly.holes) + poly2 = h3.LatLngPoly(poly.outer, *poly.holes) out = h3.h3shape_to_cells(poly2, 9) assert u.same_set(out, cells) @@ -22,7 +22,7 @@ def test_cells_to_h3shape_tight(): cells = h3.grid_disk(h, 1) poly = h3.cells_to_h3shape(cells, tight=True) - poly2 = h3.H3Poly(poly.outer, *poly.holes) + poly2 = h3.LatLngPoly(poly.outer, *poly.holes) out = h3.h3shape_to_cells(poly2, 9) assert u.same_set(out, cells) diff --git a/tests/test_cells_and_edges.py b/tests/test_cells_and_edges.py index 1e4c5d75..d23ff4d6 100644 --- a/tests/test_cells_and_edges.py +++ b/tests/test_cells_and_edges.py @@ -208,7 +208,7 @@ def test_distance_error(): def get_maine_cells(): # lat/lngs for State of Maine - poly = h3.H3Poly([ + poly = h3.LatLngPoly([ (45.137451890638886, -67.13734351262877), (44.8097, -66.96466), (44.3252, -68.03252), diff --git a/tests/test_h3.py b/tests/test_h3.py index a7fc4150..186145fa 100644 --- a/tests/test_h3.py +++ b/tests/test_h3.py @@ -201,7 +201,7 @@ def test_compact_and_uncompact_cells(): (37.8151571999998453, -122.4798767000009008), ] - poly = h3.H3Poly(sf_7x7) + poly = h3.LatLngPoly(sf_7x7) cells = h3.h3shape_to_cells(poly, 9) compact_cells = h3.compact_cells(cells)