rusterize 0.1.0__cp310-abi3-musllinux_1_2_x86_64.whl → 0.1.1__cp310-abi3-musllinux_1_2_x86_64.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.

Potentially problematic release.


This version of rusterize might be problematic. Click here for more details.

rusterize/core.py CHANGED
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ from types import NoneType
3
4
  from typing import Any, Dict, Optional, Tuple, Union
4
5
 
5
6
  import polars as pl
@@ -10,7 +11,9 @@ from .rusterize import _rusterize
10
11
 
11
12
 
12
13
  def rusterize(gdf: DataFrame,
13
- res: Union[Tuple[int, ...], Tuple[float, ...]],
14
+ res: Optional[Union[Tuple[int, ...], Tuple[float, ...]]] = None,
15
+ out_shape: Optional[Union[Tuple[int, ...]]] = None,
16
+ extent: Optional[Union[Tuple[int, ...], Tuple[float, ...]]] = None,
14
17
  field: Optional[str] = None,
15
18
  by: Optional[str] = None,
16
19
  fun: str = "last",
@@ -20,47 +23,71 @@ def rusterize(gdf: DataFrame,
20
23
  Fast geopandas rasterization into xarray.DataArray
21
24
 
22
25
  Args:
23
- :param gdf: geopandas dataframe to rasterize.
24
- :param res: tuple of (xres, yres) for rasterized data.
25
- :param field: field to rasterize. Default is None.
26
- :param by: column to rasterize, assigns each unique value to a layer in the stack based on field. Default is None.
27
- :param fun: pixel function to use, see fasterize for options. Default is `last`.
28
- :param background: background value in final raster. Default is None.
26
+ :param gdf: geopandas dataframe to rasterize.
27
+ :param res: tuple of (xres, yres) for rasterized data.
28
+ :param out_shape: tuple of (nrows, ncols) for regularized output shape.
29
+ :param extent: tuple of (xmin, xmax, ymin, ymax) for regularized extent.
30
+ :param field: field to rasterize. Default is None.
31
+ :param by: column to rasterize, assigns each unique value to a layer in the stack based on field. Default is None.
32
+ :param fun: pixel function to use, see fasterize for options. Default is `last`.
33
+ :param background: background value in final raster. Default is None.
29
34
 
30
35
  Returns:
31
- Dictionary containing rasterized geometries and spatial attributes to build a xarray.DataArray.
36
+ Rasterized xarray.DataArray.
37
+
38
+ Note:
39
+ When any of `res`, `out_shape`, or `extent` is not provided, it is inferred from the other arguments when applicable.
40
+ Unless `extent` is specified, a half-pixel buffer is applied to avoid missing points on the border.
41
+ The logics dictating the final spatial properties of the rasterized geometries follow those of GDAL.
32
42
  """
33
43
  # type checks
34
44
  if not isinstance(gdf, DataFrame):
35
45
  raise TypeError("Must pass a valid geopandas dataframe.")
36
- if not isinstance(field, (str, type(None))):
46
+ if not isinstance(res, (tuple, NoneType)):
47
+ raise TypeError("Must pass a valid resolution tuple (x, y).")
48
+ if not isinstance(out_shape, (tuple, NoneType)):
49
+ raise TypeError("Must pass a valid output shape tuple (nrows, ncols).")
50
+ if not isinstance(extent, (tuple, NoneType)):
51
+ raise TypeError("Must pass a valid extent tuple (xmin, ymin, xmax, ymax).")
52
+ if not isinstance(field, (str, NoneType)):
37
53
  raise TypeError("Must pass a valid string to field.")
38
- if not isinstance(by, (str, type(None))):
54
+ if not isinstance(by, (str, NoneType)):
39
55
  raise TypeError("Must pass a valid string to by.")
40
- if not isinstance(res, tuple):
41
- raise TypeError("Must pass a valid resolution tuple (x, y).")
42
56
  if not isinstance(fun, str):
43
57
  raise TypeError("Must pass a valid string to pixel_fn. Select only of sum, first, last, min, max, count, or any.")
44
- if not isinstance(background, (int, float, type(None))):
58
+ if not isinstance(background, (int, float, NoneType)):
45
59
  raise TypeError("Must pass a valid background type.")
46
60
 
47
61
  # value check
62
+ if not res and not out_shape and not extent:
63
+ raise ValueError("One of `res`, `out_shape`, or `extent` must be provided.")
64
+ if extent and not res and not out_shape:
65
+ raise ValueError("Must also specify `res` or `out_shape` with extent.")
66
+ if res and (len(res) != 2 or any(r <= 0 for r in res) or any(not isinstance(r, (int, float)) for r in res)):
67
+ raise ValueError("Resolution must be 2 positive numbers.")
68
+ if out_shape and (len(out_shape) != 2 or any(s <= 0 for s in out_shape) or any(not isinstance(s, int) for s in out_shape)):
69
+ raise ValueError("Output shape must be 2 positive integers.")
70
+ if extent and len(extent) != 4:
71
+ raise ValueError("Extent must be 4 numbers (xmin, ymin, xmax, ymax).")
48
72
  if by and not field:
49
73
  raise ValueError("If by is specified, field must also be specified.")
50
- if len(res) != 2 or any((res[0], res[1])) <= 0 or not isinstance(res[0], type(res[1])):
51
- raise ValueError("Must pass valid resolution tuple of values of consistent dtype.")
74
+
75
+ # defaults
76
+ _res = res if res else (0, 0)
77
+ _shape = out_shape if out_shape else (0, 0)
78
+ (_bounds, has_extent) = (extent, True) if extent else (gdf.total_bounds, False)
52
79
 
53
80
  # RasterInfo
54
- bounds = gdf.total_bounds
55
81
  raster_info = {
56
- "xmin": bounds[0],
57
- "ymin": bounds[1],
58
- "xmax": bounds[2],
59
- "ymax": bounds[3],
60
- "xres": res[0],
61
- "yres": res[1],
62
- "nrows": 0,
63
- "ncols": 0
82
+ "xmin": _bounds[0],
83
+ "ymin": _bounds[1],
84
+ "xmax": _bounds[2],
85
+ "ymax": _bounds[3],
86
+ "xres": _res[0],
87
+ "yres": _res[1],
88
+ "nrows": _shape[0],
89
+ "ncols": _shape[1],
90
+ "has_extent": has_extent
64
91
  }
65
92
 
66
93
  # extract columns of interest and convert to polars
Binary file
@@ -1,19 +1,19 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rusterize
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Classifier: License :: OSI Approved :: MIT License
5
5
  Classifier: Operating System :: OS Independent
6
6
  Classifier: Programming Language :: Rust
7
7
  Classifier: Programming Language :: Python :: Implementation :: CPython
8
8
  Classifier: Programming Language :: Python :: Implementation :: PyPy
9
- Requires-Dist: geopandas >=1.0.1
10
- Requires-Dist: pandas >=2.2.3
11
- Requires-Dist: pyarrow >=18.1.0
12
- Requires-Dist: polars >=1.19.0
13
- Requires-Dist: xarray >=2025.1.1
14
- Requires-Dist: rioxarray >=0.18.2
9
+ Requires-Dist: geopandas>=1.0.1
10
+ Requires-Dist: pandas>=2.2.3
11
+ Requires-Dist: pyarrow>=18.1.0
12
+ Requires-Dist: polars>=1.19.0
13
+ Requires-Dist: xarray>=2025.1.1
14
+ Requires-Dist: rioxarray>=0.18.2
15
15
  License-File: LICENSE
16
- Summary: High performance rasterization tool for Python build in Rust
16
+ Summary: High performance rasterization tool for Python built in Rust
17
17
  Keywords: fast,raster
18
18
  Requires-Python: >=3.10
19
19
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
@@ -21,9 +21,9 @@ Project-URL: repository, https://github.com/ttrotto/rusterize
21
21
 
22
22
  # rusterize
23
23
 
24
- High performance rasterization tool for python built in Rust. This
25
- repository is heavily based on the [**fasterize**](https://github.com/ecohealthalliance/fasterize.git) package built in C++
26
- for R. This version ports it to Python with a Rust backend.
24
+ High performance rasterization tool for Python built in Rust. This
25
+ repository is heavily based on the [fasterize](https://github.com/ecohealthalliance/fasterize.git) package built in C++
26
+ for R. This version ports it to Python with a Rust backend, with some useful improvements.
27
27
 
28
28
  Functionally, it takes an input [geopandas](https://geopandas.org/en/stable/)
29
29
  dataframes and returns a [xarray](https://docs.xarray.dev/en/stable/). It
@@ -34,7 +34,7 @@ tighly mirrors the processing routine of fasterize, so it works only on
34
34
 
35
35
  Install the current version with pip:
36
36
 
37
- ``` {shell}
37
+ ``` shell
38
38
  pip install rusterize
39
39
  ```
40
40
 
@@ -46,7 +46,7 @@ package. For this to work, you’ll need to have [Rust](https://www.rust-lang.or
46
46
  [cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html)
47
47
  installed.
48
48
 
49
- ``` {shell}
49
+ ``` shell
50
50
  # Clone repo
51
51
  git clone https://github.com/<username>/rusterize.git
52
52
  cd rusterize
@@ -65,22 +65,26 @@ maturin develop --profile dist-release
65
65
 
66
66
  This function has a simple API:
67
67
 
68
- ``` {shell}
68
+ ``` python
69
69
  from rusterize.core import rusterize
70
70
 
71
71
  # gdf = <import datasets as needed>
72
72
 
73
73
  # rusterize
74
74
  rusterize(gdf,
75
- (30, 30),
76
- "field",
77
- "by",
78
- "sum",
79
- 0)
75
+ res=(30, 30),
76
+ out_shape=(10, 10)
77
+ extent=(0, 300, 0, 300)
78
+ field="field",
79
+ by="by",
80
+ fun="sum",
81
+ background=0)
80
82
  ```
81
83
 
82
84
  - `gdf`: geopandas dataframe to rasterize
83
- - `res`: tuple of (xres, yres) for final resolution
85
+ - `res`: tuple of (xres, yres) for desired resolution
86
+ - `out_shape`: tuple of (nrows, ncols) for desired output shape
87
+ - `extent`: tuple of (xmin, ymin, xmax, ymax) for desired output extent
84
88
  - `field`: field to rasterize. Default is None (a value of `1` is rasterized).
85
89
  - `by`: column to rasterize. Assigns each group to a band in the
86
90
  stack. Values are taken from `field`. Default is None
@@ -88,10 +92,16 @@ rusterize(gdf,
88
92
  `last`. Available options are `sum`, `first`, `last`, `min`, `max`, `count`, or `any`
89
93
  - `background`: background value in final raster. Default is None (NaN)
90
94
 
95
+ Note that control over the desired extent is not as strict as for resolution and shape. That is,
96
+ when resolution, output shape, and extent are specified, priority is given to resolution and shape.
97
+ So, extent is not guaranteed, but resolution and shape are. If extent is not given, it is taken
98
+ from the polygons and is not modified, unless you specify a resolution value. If you only specify an output
99
+ shape, the extent is maintained. This mimics the logics of `gdal_rasterize`.
100
+
91
101
  # Usage
92
102
 
93
103
  **rusterize** consists of a single function `rusterize()`. The Rust implementation
94
- returns an array that is then converted to a xarray on the Python side
104
+ returns an array that is converted to a xarray on the Python side
95
105
  for simpliicty.
96
106
 
97
107
  ``` python
@@ -127,12 +137,11 @@ output.plot.imshow(ax=ax)
127
137
  plt.show()
128
138
  ```
129
139
 
130
- ![](README_files/figure-commonmark/cell-2-output-1.png)
140
+ ![](img/plot.png)
131
141
 
132
142
  # Benchmarks
133
143
 
134
- **fasterize** is fast and so is **rusterize**! Let’s try it on small and large
135
- datasets.
144
+ **rusterize** is fast! Let’s try it on small and large datasets.
136
145
 
137
146
  ``` python
138
147
  from rusterize.core import rusterize
@@ -167,7 +176,7 @@ Then you can run it with [pytest](https://docs.pytest.org/en/stable/)
167
176
  and
168
177
  [pytest-benchmark](https://pytest-benchmark.readthedocs.io/en/stable/):
169
178
 
170
- ``` {shell}
179
+ ```
171
180
  pytest <python file> --benchmark-min-rounds=20 --benchmark-time-unit='s'
172
181
 
173
182
  --------------------------------------------- benchmark: 1 tests --------------------------------------------
@@ -180,7 +189,7 @@ test_small 0.5083 0.6416 0.5265 0.0393 0.5120 0.0108 2;
180
189
 
181
190
  And fasterize:
182
191
 
183
- ``` {r}
192
+ ``` r
184
193
  large <- st_read("Mammals_Terrestrial/Mammals_Terrestrial.shp", quiet = TRUE)
185
194
  small <- large[1:1000, ]
186
195
  fn <- function(v) {
@@ -195,7 +204,7 @@ microbenchmark(
195
204
  )
196
205
  ```
197
206
 
198
- ``` {shell}
207
+ ```
199
208
  Unit: seconds
200
209
  expr min lq mean median uq max neval
201
210
  fasterize_large 9.565781 9.815375 10.02838 9.984965 10.18532 10.66656 20
@@ -207,7 +216,7 @@ And on even
207
216
  datasets? This is a benchmark with 350K+ geometries rasterized at 30
208
217
  meters (20 rounds) with no field value and pixel function `sum`.
209
218
 
210
- ``` {shell}
219
+ ```
211
220
  # rusterize
212
221
  --------------------------------------------- benchmark: 1 tests --------------------------------------------
213
222
  Name (time in s) Min Max Mean StdDev Median IQR Outliers OPS Rounds Iterations
@@ -223,7 +232,7 @@ Unit: seconds
223
232
 
224
233
  # Comparison with other tools
225
234
 
226
- While `rusterize` is fast, there are other very fast solutions out there, including
235
+ While `rusterize` is fast, there are other very fast solutions out there, including:
227
236
  - `GDAL`
228
237
  - `rasterio`
229
238
  - `geocube`
@@ -0,0 +1,8 @@
1
+ rusterize-0.1.1.dist-info/METADATA,sha256=82TdiZEs_ruMJ_uAl_Spc_yKByUCVbK6f8BWSEJPMgU,8570
2
+ rusterize-0.1.1.dist-info/WHEEL,sha256=el9cc43wermkDCrN642yvtxBbpmdymUuzyya8P1Eb_0,106
3
+ rusterize-0.1.1.dist-info/licenses/LICENSE,sha256=v-2DqBji_azGEWFDxBhw-CNIRu8450vBbloLx6UNqLU,1108
4
+ rusterize.libs/libgcc_s-1e52349c.so.1,sha256=Ani0u_W_tB8ESsFePO4D2mn2lrgWLhyFdw6RETxBTYM,437537
5
+ rusterize/__init__.py,sha256=OymrFdgWCN3VMuSM3oXoGKeagAd-5ayPsYyXnQ_HsDE,101
6
+ rusterize/core.py,sha256=9nsqL-v5Bw5DezS_kpnDx1eQHooJr6zK1TpWSKxJT94,4574
7
+ rusterize/rusterize.abi3.so,sha256=bJ7ukAvSnu5PjajyH_KDYyAcsJo6bHPR7m9ATaY-1e8,35619001
8
+ rusterize-0.1.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: maturin (1.8.1)
2
+ Generator: maturin (1.8.2)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp310-abi3-musllinux_1_2_x86_64
@@ -1,8 +0,0 @@
1
- rusterize-0.1.0.dist-info/METADATA,sha256=pS1UlizVrXEDCis4_jefaIP1bDrZH5lJGquhtWwM69g,7938
2
- rusterize-0.1.0.dist-info/WHEEL,sha256=mUAOKVF4E29A5oud-Hdyi-U210B5mh3h4Z9sZAEXcHA,106
3
- rusterize-0.1.0.dist-info/licenses/LICENSE,sha256=v-2DqBji_azGEWFDxBhw-CNIRu8450vBbloLx6UNqLU,1108
4
- rusterize.libs/libgcc_s-1e52349c.so.1,sha256=Ani0u_W_tB8ESsFePO4D2mn2lrgWLhyFdw6RETxBTYM,437537
5
- rusterize/__init__.py,sha256=OymrFdgWCN3VMuSM3oXoGKeagAd-5ayPsYyXnQ_HsDE,101
6
- rusterize/core.py,sha256=eSBSQMebf3vELR6FHvmL7j-66mnWcRDXiow-flG5H8M,2861
7
- rusterize/rusterize.abi3.so,sha256=QbeGUWs-adE5EkwW7_ztgiyOzZNv6k2zsSWOuJkz5nw,35573913
8
- rusterize-0.1.0.dist-info/RECORD,,