vector2dggs 0.5.4__py3-none-any.whl → 0.6.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
vector2dggs/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__: str = "0.5.4"
1
+ __version__: str = "0.6.1"
vector2dggs/h3.py CHANGED
@@ -11,8 +11,6 @@ from typing import Union
11
11
  from urllib.parse import urlparse
12
12
  import warnings
13
13
 
14
- os.environ["USE_PYGEOS"] = "0"
15
-
16
14
  import click
17
15
  import click_log
18
16
  import dask.dataframe as dd
@@ -69,18 +67,40 @@ def polyfill(
69
67
  output_directory: str,
70
68
  ) -> None:
71
69
  """
72
- Reads a geoparquet, performs H3 polyfilling,
73
- and writes out to parquet.
70
+ Reads a geoparquet, performs H3 polyfilling (for Polygon),
71
+ linetracing (for LineString), and writes out to parquet.
74
72
  """
75
73
  df = gpd.read_parquet(pq_in).reset_index().drop(columns=[spatial_sort_col])
76
74
  if len(df.index) == 0:
77
75
  # Input is empty, nothing to polyfill
78
76
  return None
79
- df = df.h3.polyfill_resample(resolution, return_geometry=False)
77
+
78
+ df_polygon = df[df.geom_type == "Polygon"]
79
+ if len(df_polygon.index) > 0:
80
+ df_polygon = df_polygon.h3.polyfill_resample(
81
+ resolution, return_geometry=False
82
+ ).drop(columns=["index"])
83
+
84
+ df_linestring = df[df.geom_type == "LineString"]
85
+ if len(df_linestring.index) > 0:
86
+ df_linestring = (
87
+ df_linestring.h3.linetrace(resolution)
88
+ .explode("h3_linetrace")
89
+ .set_index("h3_linetrace")
90
+ )
91
+ df_linestring = df_linestring[~df_linestring.index.duplicated(keep="first")]
92
+
93
+ df = pd.concat(
94
+ map(
95
+ lambda _df: pd.DataFrame(_df.drop(columns=[_df.geometry.name])),
96
+ [df_polygon, df_linestring],
97
+ )
98
+ )
99
+
80
100
  if len(df.index) == 0:
81
101
  # Polyfill resulted in empty output (e.g. large cell, small feature)
82
102
  return None
83
- df = pd.DataFrame(df).drop(columns=["index", "geometry"])
103
+
84
104
  df.index.rename(f"h3_{resolution:02}", inplace=True)
85
105
  parent_res: int = _get_parent_res(parent_res, resolution)
86
106
  # Secondary (parent) H3 index, used later for partitioning
@@ -193,7 +213,7 @@ def _index(
193
213
  # Remove all attributes except the geometry
194
214
  df = df.loc[:, ["geometry"]]
195
215
 
196
- LOGGER.info("Watch out for ninjas! (Cutting polygons)")
216
+ LOGGER.info("Cutting large geometries")
197
217
  with tqdm(total=df.shape[0]) as pbar:
198
218
  for index, row in df.iterrows():
199
219
  df.loc[index, "geometry"] = GeometryCollection(
@@ -218,8 +238,9 @@ def _index(
218
238
  {
219
239
  "index": lambda frame: frame[
220
240
  (frame.geometry.geom_type != "Polygon")
221
- ], # NB currently points and lines are lost; in principle, these could be indexed
222
- "message": "Dropping non-polygonal geometries",
241
+ & (frame.geometry.geom_type != "LineString")
242
+ ], # NB currently points and other types are lost; in principle, these could be indexed
243
+ "message": "Dropping unsupported geometries",
223
244
  },
224
245
  ]
225
246
  for condition in drop_conditions:
@@ -319,7 +340,7 @@ def _index(
319
340
  required=False,
320
341
  default=None,
321
342
  type=int,
322
- help="Set the coordinate reference system (CRS) used for cutting large polygons (see `--cur-threshold`). Defaults to the same CRS as the input. Should be a valid EPSG code.",
343
+ help="Set the coordinate reference system (CRS) used for cutting large geometries (see `--cur-threshold`). Defaults to the same CRS as the input. Should be a valid EPSG code.",
323
344
  nargs=1,
324
345
  )
325
346
  @click.option(
@@ -328,7 +349,7 @@ def _index(
328
349
  required=True,
329
350
  default=5000,
330
351
  type=int,
331
- help="Cutting up large polygons into smaller pieces based on a target length. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS.",
352
+ help="Cutting up large geometries into smaller geometries based on a target length. Units are assumed to match the input CRS units unless the `--cut_crs` is also given, in which case units match the units of the supplied CRS.",
332
353
  nargs=1,
333
354
  )
334
355
  @click.option(
vector2dggs/katana.py CHANGED
@@ -11,13 +11,20 @@ Redistribution and use in source and binary forms, with or without modification,
11
11
  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12
12
  """
13
13
 
14
- from shapely.geometry import box, Polygon, MultiPolygon, GeometryCollection
14
+ from shapely.geometry import (
15
+ box,
16
+ Polygon,
17
+ MultiPolygon,
18
+ LineString,
19
+ MultiLineString,
20
+ GeometryCollection,
21
+ )
15
22
  from shapely.validation import explain_validity, make_valid
16
23
 
17
24
 
18
25
  def katana(geometry, threshold, count=0) -> GeometryCollection:
19
26
  """
20
- Split a polygon into two parts across it's shortest dimension.
27
+ Split a geometry into two parts across its shortest dimension.
21
28
  Invalid input `geometry` will silently be made valid (if possible).
22
29
  """
23
30
  if geometry is None:
@@ -53,7 +60,7 @@ def katana(geometry, threshold, count=0) -> GeometryCollection:
53
60
  if not isinstance(c, GeometryCollection):
54
61
  c = GeometryCollection([c])
55
62
  for e in c.geoms:
56
- if isinstance(e, (Polygon, MultiPolygon)):
63
+ if isinstance(e, (Polygon, MultiPolygon, LineString, MultiLineString)):
57
64
  result.extend(katana(e, threshold, count + 1))
58
65
  if count > 0:
59
66
  return result
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: vector2dggs
3
- Version: 0.5.4
3
+ Version: 0.6.1
4
4
  Summary: CLI DGGS indexer for vector geospatial data
5
5
  Home-page: https://github.com/manaakiwhenua/vector2dggs
6
6
  License: LGPL-3.0-or-later
@@ -9,27 +9,27 @@ Author: James Ardo
9
9
  Author-email: ardoj@landcareresearch.co.nz
10
10
  Maintainer: Richard Law
11
11
  Maintainer-email: lawr@landcareresearch.co.nz
12
- Requires-Python: >=3.10,<4.0
12
+ Requires-Python: >=3.11,<4.0
13
13
  Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.10
16
15
  Classifier: Programming Language :: Python :: 3.11
17
16
  Classifier: Topic :: Scientific/Engineering
18
17
  Classifier: Topic :: Scientific/Engineering :: GIS
19
18
  Classifier: Topic :: Scientific/Engineering :: Information Analysis
20
- Requires-Dist: click (>=8.1.3,<9.0.0)
19
+ Requires-Dist: click (>=8.1.7,<9.0.0)
21
20
  Requires-Dist: click-log (>=0.4.0,<0.5.0)
22
- Requires-Dist: dask (>=2023.3.0,<2024.0.0)
23
- Requires-Dist: dask-geopandas (>=0.3.0,<0.4.0)
24
- Requires-Dist: gdal (>=3.6.4,<4.0.0)
25
- Requires-Dist: geopandas (>=0.12.2,<0.13.0)
26
- Requires-Dist: h3pandas (>=0.2.3,<0.3.0)
27
- Requires-Dist: psycopg2 (>=2.9.6,<3.0.0)
28
- Requires-Dist: pyarrow (>=11.0.0,<12.0.0)
29
- Requires-Dist: pygeos (>=0.14,<0.15)
30
- Requires-Dist: pyproj (>=3.5.0,<4.0.0)
31
- Requires-Dist: sqlalchemy (>=2.0.10,<3.0.0)
32
- Requires-Dist: tqdm (>=4.65.0,<5.0.0)
21
+ Requires-Dist: dask (>=2024.8.0,<2025.0.0)
22
+ Requires-Dist: dask-geopandas (>=0.4.1,<0.5.0)
23
+ Requires-Dist: gdal (==3.8.4)
24
+ Requires-Dist: geopandas (>=1.0.1,<2.0.0)
25
+ Requires-Dist: h3pandas (>=0.2.6,<0.3.0)
26
+ Requires-Dist: numpy (<2)
27
+ Requires-Dist: psycopg2 (>=2.9.9,<3.0.0)
28
+ Requires-Dist: pyarrow (>=17.0.0,<18.0.0)
29
+ Requires-Dist: pyproj (>=3.6.1,<4.0.0)
30
+ Requires-Dist: shapely (>=2.0.5,<3.0.0)
31
+ Requires-Dist: sqlalchemy (>=2.0.32,<3.0.0)
32
+ Requires-Dist: tqdm (>=4.66.5,<5.0.0)
33
33
  Project-URL: Repository, https://github.com/manaakiwhenua/vector2dggs
34
34
  Description-Content-Type: text/markdown
35
35
 
@@ -159,6 +159,8 @@ In brief, to get started:
159
159
 
160
160
  If you run `poetry install`, the CLI tool will be aliased so you can simply use `vector2dggs` rather than `poetry run vector2dggs`, which is the alternative if you do not `poetry install`.
161
161
 
162
+ Alternaively, it is also possible to isntall using pip with `pip install -e .`, and bypass Poetry.
163
+
162
164
  #### Code formatting
163
165
 
164
166
  [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
@@ -187,14 +189,14 @@ vector2dggs h3 -v DEBUG -id ogc_fid -r 9 -p 5 -t 4 --overwrite -tbl topo50_lake
187
189
  title={{vector2dggs}},
188
190
  author={Ardo, James and Law, Richard},
189
191
  url={https://github.com/manaakiwhenua/vector2dggs},
190
- version={0.5.4},
192
+ version={0.6.1},
191
193
  date={2023-04-20}
192
194
  }
193
195
  ```
194
196
 
195
197
  APA/Harvard
196
198
 
197
- > Ardo, J., & Law, R. (2023). vector2dggs (0.5.4) [Computer software]. https://github.com/manaakiwhenua/vector2dggs
199
+ > Ardo, J., & Law, R. (2023). vector2dggs (0.6.1) [Computer software]. https://github.com/manaakiwhenua/vector2dggs
198
200
 
199
201
  [![manaakiwhenua-standards](https://github.com/manaakiwhenua/vector2dggs/workflows/manaakiwhenua-standards/badge.svg)](https://github.com/manaakiwhenua/manaakiwhenua-standards)
200
202
 
@@ -0,0 +1,10 @@
1
+ vector2dggs/__init__.py,sha256=8sqy-gBl8LCgOL8GSQBSJg6UWO0eWPpvb3gdHmGQvbg,27
2
+ vector2dggs/cli.py,sha256=tL4NJ99uQsqoVinwYadna1a4ko5v2sdZaFaeDAj6QNE,599
3
+ vector2dggs/h3.py,sha256=AMH9VdspvKu26VhFmuWf48xm4VEDKxmNuvOeb_I2nmI,14310
4
+ vector2dggs/katana.py,sha256=pgVWy032NkT5yilUO0d0IKH4NUvY7DJLjmfsxhBiF08,3407
5
+ vector2dggs-0.6.1.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
+ vector2dggs-0.6.1.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
7
+ vector2dggs-0.6.1.dist-info/METADATA,sha256=djCsEsjEqHZp2iTyMhBaTVOs0VtNAORURR7s9N8cs0U,9846
8
+ vector2dggs-0.6.1.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
9
+ vector2dggs-0.6.1.dist-info/entry_points.txt,sha256=5h8LB9L2oOE5u_N7FRGtu4JDwa553iPs4u0XhcLeLZU,52
10
+ vector2dggs-0.6.1.dist-info/RECORD,,
@@ -1,10 +0,0 @@
1
- vector2dggs/__init__.py,sha256=k2mVhGfDpsy8Z1zpD4DDxkUDrEoNwp3wetuIS9B8ioQ,27
2
- vector2dggs/cli.py,sha256=tL4NJ99uQsqoVinwYadna1a4ko5v2sdZaFaeDAj6QNE,599
3
- vector2dggs/h3.py,sha256=Ye9YS9G1HEnoSm9pnXVTUZClC5FpGaUGmIXtZWvk7bw,13646
4
- vector2dggs/katana.py,sha256=xx5R9lDuraWLK5bfGkiDQDC2r2naj_sKZlYeB52_xwc,3320
5
- vector2dggs-0.5.4.dist-info/COPYING,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
6
- vector2dggs-0.5.4.dist-info/COPYING.LESSER,sha256=46mU2C5kSwOnkqkw9XQAJlhBL2JAf1_uCD8lVcXyMRg,7652
7
- vector2dggs-0.5.4.dist-info/METADATA,sha256=X7yb_cHG7RUx_hCh4VwuUL5wlcQeGvxxmz2w3URXiKE,9777
8
- vector2dggs-0.5.4.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
9
- vector2dggs-0.5.4.dist-info/entry_points.txt,sha256=5h8LB9L2oOE5u_N7FRGtu4JDwa553iPs4u0XhcLeLZU,52
10
- vector2dggs-0.5.4.dist-info/RECORD,,