Skip to main content

High performance rasterization tool for Python built in Rust

Project description


High performance rasterization tool for Python built in Rust, inspired by the fasterize package with lots of useful improvements (see API).

rusterize is designed to work on all shapely geometries, even when they are nested inside complex geometry collections. Functionally, it supports four input types:

  • geopandas GeoDataFrame and GeoSeries
  • polars-st GeoDataFrame
  • Python list of geometries in shapely.Geometry, WKB, or WKT format
  • Numpy array of geometries in shapely.Geometry, WKB, or WKT format

It returns a xarray, a numpy, or a sparse array in COOrdinate format.

Installation

rusterize comes with numpy as the only required dependency and is distributed in different flavors. A core library that performs the rasterization and returns a bare numpy array, a xarray flavor that returns a georeferenced xarray (requires xarray and rioxarray and is the recommended flavor), or an all flavor with dependencies for all supported inputs.

Install the current version with pip:

# core library
pip install rusterize

# xarray capabilities
pip install 'rusterize[xarray]'

# support all input types
pip install 'rusterize[all]'

Contributing

Any contribution is welcome! You can install rusterize directly from this repo using maturin as an editable package. For this to work, you’ll need to have Rust and cargo installed. To run the tests you need to have gdal installed as well as the rusterize[all] flavor.

# clone repo
git clone https://github.com/<username>/rusterize.git
cd rusterize

# install Rust nightly toolchain
rustup toolchain install nightly-2026-01-09

# install maturin
pip install maturin

# install editable version with optmized code
maturin develop --profile dist-release

# test the new contribution
pytest

API

rusterize has a simple API consisting of a single function rusterize():

from rusterize import rusterize

rusterize(
    data,
    like=None,
    res=(30, 30),
    out_shape=(10, 10),
    extent=(0, 10, 10, 20),
    field="field",
    by="by",
    burn=None,
    fun="sum",
    background=0,
    encoding="xarray",
    all_touched=False,
    tap=False,
    dtype="uint8"
)
  • data : geopandas.GeoDataFrame, geopandas.GeoSeries, polars.DataFrame, list, numpy.ndarray
    Input data to rasterize.

    • If polars.DataFrame, it must be have a "geometry" column with geometries stored in WKB or WKT format.
    • If list or numpy.ndarray, geometries must be in WKT, WKB, or shapely formats (EPSG is not inferred and defaults to None).
  • like : xarray.DataArray or xarray.Dataset (default: None)
    Template array used as a spatial blueprint (resolution, shape, extent). Mutually exclusive with res, out_shape, and extent. Requires xarray and rioxarray.

  • res : tuple or list (default: None)
    Pixel resolution defined as (xres, yres).

  • out_shape : tuple or list (default: None)
    Output raster dimensions defined as (nrows, ncols).

  • extent : tuple or list (default: None)
    Spatial bounding box defined as (xmin, ymin, xmax, ymax).

  • field : str (default: None)
    Column name to use for pixel values. Mutually exclusive with burn. Not considered when input is list or numpy.ndarray.

  • by : str (default: None)
    Column used for grouping. Each group is rasterized into a distinct band in the output. Not considered when input is list or numpy.ndarray.

  • burn : int, float, or numpy.ndarray (default: None)
    A static value or a list of values to apply to each geometries. If a numpy.ndarray, it must match the length of the geometry data. Mutually exclusive with field. If burn is a numpy.ndarray, its dtype should match the output dtype, otherwise it is internally casted. If data is a geopandas.GeoSeries, its index is used as burn value, unless otherwise specified.

  • fun : str (default: "last")
    Pixel function to use when burning geometries. Available options: sum, first, last, min, max, count, or any.

  • background : int or float (default: numpy.nan)
    Value assigned to pixels not covered by any geometry.

  • encoding : str (default: "xarray")
    The format of the returned object: "xarray", "numpy", or "sparse".

  • all_touched : bool (default: False)
    If True, every pixel touched by a geometry is burned.

  • tap : bool (default: False)
    Target Aligned Pixel: aligns the extent to the pixel resolution.

  • dtype : str (default: "float64")
    Output data type (e.g., uint8, int32, float32).

Note that control over the desired extent is not as strict as for resolution and shape. That is, when resolution, output shape, and extent are specified, priority is given to resolution and shape. So, extent is not guaranteed, but resolution and shape are. If extent is not given, it is taken from the polygons and is not modified, unless you specify a resolution value. If you only specify an output shape, the extent is maintained. This mimics the logics of gdal_rasterize.

Encoding

rusterize offers three encoding options for the rasterization output. You can return a xarray/numpy with the rasterized geometries, or a new SparseArray structure. This SparseArray structure stores the band/row/column triplets of where the geometries should be burned onto the final raster, as well as their corresponding values before applying any pixel function. This can be used as an intermediate output to avoid allocating memory before materializing the final raster, or as a final product. SparseArray has three convenience functions: to_xarray(), to_numpy(), and to_frame(). The first two return the final xarray/numpy with the appropriate pixel function, the last returns a polars dataframe with only the coordinates and values of the rasterized geometries. Note that SparseArray avoids allocating memory for the array during rasterization until it's actually needed (e.g. calling to_xarray()). See below for an example.

Usage

from rusterize import rusterize
import geopandas as gpd
from shapely import wkt
import matplotlib.pyplot as plt

# construct geometries
geoms = [
    "POLYGON ((-180 -20, -140 55, 10 0, -140 -60, -180 -20), (-150 -20, -100 -10, -110 20, -150 -20))",
    "POLYGON ((-10 0, 140 60, 160 0, 140 -55, -10 0))",
    "POLYGON ((-125 0, 0 60, 40 5, 15 -45, -125 0))",
    "MULTILINESTRING ((-180 -70, -140 -50), (-140 -50, -100 -70), (-100 -70, -60 -50), (-60 -50, -20 -70), (-20 -70, 20 -50), (20 -50, 60 -70), (60 -70, 100 -50), (100 -50, 140 -70), (140 -70, 180 -50))",
    "GEOMETRYCOLLECTION (POINT (50 -40), POLYGON ((75 -40, 75 -30, 100 -30, 100 -40, 75 -40)), LINESTRING (60 -40, 80 0), GEOMETRYCOLLECTION (POLYGON ((100 20, 100 30, 110 30, 110 20, 100 20))))"
]

# create a GeoDataFrame with shapely geometries from WKT
gdf = gpd.GeoDataFrame({'value': range(1, len(geoms) + 1)}, geometry=wkt.loads(geoms), crs='EPSG:32619')

# or pass values directly to rusterize
# rusterize to "xarray" -> returns a xarray with the burned geometries and spatial reference when available (default)
# will raise a ModuleNotFoundError if xarray and rioxarray are not found
output = rusterize(
    geoms,
    res=(1, 1),
    fun="sum",
    burn=np.arange(1, len(geoms) + 1)
).squeeze()

output = rusterize(
    gdf,
    res=(1, 1),
    field="value",
    fun="sum",
).squeeze()

# plot it
fig, ax = plt.subplots(figsize=(12, 6))
output.plot.imshow(ax=ax)
plt.show()

# rusterize to "sparse" -> custom structure storing the coordinates and values of the rasterized geometries
output = rusterize(
    gdf,
    res=(1, 1),
    field="value",
    fun="sum",
    encoding="sparse"
)
output
# SparseArray:
# - Shape: (131, 361)
# - Extent: (-180.5, -70.5, 180.5, 60.5)
# - Resolution: (1.0, 1.0)
# - EPSG: 32619
# - Estimated size: 378.33 KB

# materialize into xarray or numpy
array = output.to_xarray()
array = output.to_numpy()

# get only coordinates and values
output.to_frame()
# shape: (29_340, 3)
# ┌─────┬─────┬──────┐
# │ row ┆ col ┆ data │
# │ --- ┆ --- ┆ ---  │
# │ u32 ┆ u32 ┆ f64  │
# ╞═════╪═════╪══════╡
# │ 6   ┆ 40  ┆ 1.0  │
# │ 6   ┆ 41  ┆ 1.0  │
# │ 6   ┆ 42  ┆ 1.0  │
# │ 7   ┆ 39  ┆ 1.0  │
# │ 7   ┆ 40  ┆ 1.0  │
# │ …   ┆ …   ┆ …    │
# │ 64  ┆ 258 ┆ 1.0  │
# │ 63  ┆ 259 ┆ 1.0  │
# │ 62  ┆ 259 ┆ 1.0  │
# │ 61  ┆ 260 ┆ 1.0  │
# │ 60  ┆ 260 ┆ 1.0  │
# └─────┴─────┴──────┘

Benchmarks

rusterize is fast! Let’s try it on small and large datasets in comparison to GDAL (benchmark_rusterize.py). You can run this with pytest and pytest-benchmark:

pytest <python file> --benchmark-min-rounds=10 --benchmark-time-unit='s'

--------------------------------------------- benchmark: 8 tests -------------------------------------------------
Name (time in s)               Min     Max    Mean  StdDev  Median     IQR  Outliers       OPS  Rounds  Iterations
------------------------------------------------------------------------------------------------------------------
test_water_small_f64_numpy  0.0038  0.0045  0.0040  0.0001  0.0040  0.0002      56;3  248.7981     181           1
test_water_small_f64        0.0048  0.0057  0.0050  0.0001  0.0050  0.0001      21;9  198.8759     158           1
test_water_small_gdal_f64   0.0053  0.0057  0.0054  0.0001  0.0054  0.0001     28;14  184.3595     160           1
test_water_large_f64_numpy  1.2628  1.3610  1.3133  0.0314  1.3193  0.0498       5;0    0.7614      10           1
test_water_large_f64        1.2762  1.4723  1.3342  0.0628  1.3149  0.0165       2;4    0.7495      10           1
test_water_large_gdal_f64   1.4128  1.4229  1.4178  0.0029  1.4180  0.0040       3;0    0.7053      10           1
test_roads_uint8            3.3184  3.5184  3.4021  0.0578  3.3849  0.0527       3;1    0.2939      10           1
test_roads_gdal_uint8       9.0672  9.1040  9.0901  0.0109  9.0920  0.0125       2;0    0.1100      10           1
------------------------------------------------------------------------------------------------------------------

And fasterize (benchmark_fasterize.r). Note that it doesn't support custom dtype so the returning raster is float64.

Unit: seconds
            expr              min           lq        mean       median          uq         max neval
 fasterize_small_f64   0.05764281   0.06274373   0.1286875   0.06520358   0.1128432   0.6000182    10
 fasterize_large_f64  36.91321005  37.71877265  41.0140303  40.81343803  43.9201820  46.5596799    10

Comparison with other tools

While rusterize is fast, there are other fast alternatives out there, including rasterio and geocube. However, rusterize allows for a seamless, Rust-native processing with similar or lower memory footprint that does not require you to install GDAL and returns the geoinformation you need for downstream processing with ample control over resolution, shape, extent, and data type.

The following is a time comparison of 10 runs (median) on the same large water bodies dataset used earlier (dtype is float64) (run_others.py).

rusterize: 1.3 sec
rasterio:  14.5 sec
geocube:   124.9 sec

Integrations

rusterize is integrated into the following libraries:


Disclaimer: Logo originally generated with Nano Banana Pro

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rusterize-0.8.1.tar.gz (741.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rusterize-0.8.1-cp311-abi3-win_amd64.whl (18.3 MB view details)

Uploaded CPython 3.11+Windows x86-64

rusterize-0.8.1-cp311-abi3-musllinux_1_2_x86_64.whl (18.1 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ x86-64

rusterize-0.8.1-cp311-abi3-musllinux_1_2_armv7l.whl (18.2 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARMv7l

rusterize-0.8.1-cp311-abi3-musllinux_1_2_aarch64.whl (17.1 MB view details)

Uploaded CPython 3.11+musllinux: musl 1.2+ ARM64

rusterize-0.8.1-cp311-abi3-manylinux_2_28_x86_64.whl (18.1 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ x86-64

rusterize-0.8.1-cp311-abi3-manylinux_2_28_ppc64le.whl (19.4 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ppc64le

rusterize-0.8.1-cp311-abi3-manylinux_2_28_armv7l.whl (17.9 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARMv7l

rusterize-0.8.1-cp311-abi3-manylinux_2_28_aarch64.whl (16.9 MB view details)

Uploaded CPython 3.11+manylinux: glibc 2.28+ ARM64

rusterize-0.8.1-cp311-abi3-macosx_11_0_arm64.whl (16.2 MB view details)

Uploaded CPython 3.11+macOS 11.0+ ARM64

rusterize-0.8.1-cp311-abi3-macosx_10_12_x86_64.whl (17.5 MB view details)

Uploaded CPython 3.11+macOS 10.12+ x86-64

File details

Details for the file rusterize-0.8.1.tar.gz.

File metadata

  • Download URL: rusterize-0.8.1.tar.gz
  • Upload date:
  • Size: 741.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rusterize-0.8.1.tar.gz
Algorithm Hash digest
SHA256 2376de4e40a2c305bf760c45e31a6d9af0adb15a2475aa06606608efe2c75a0e
MD5 8697a379deaeb2aef5d728f13052abf2
BLAKE2b-256 5c050b824a53b651e84a39e31481674f3ca9db0f6df64fd476af474ce688fbaa

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1.tar.gz:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-win_amd64.whl.

File metadata

  • Download URL: rusterize-0.8.1-cp311-abi3-win_amd64.whl
  • Upload date:
  • Size: 18.3 MB
  • Tags: CPython 3.11+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 15486ea102717ce6abdda70406a4890fe8ddb5b9c1e7bb2babd967fdacaf0d10
MD5 8488cb62adf9472e0dec281485e6621f
BLAKE2b-256 e522e7e224de6fb60b669f5cfe4cd1a195c78f0212af901194bf40bf9855b57d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-win_amd64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 133aba0ae22ae49a1c2ae0b9914f4281944e15d6d585891a7b292e824ec97a32
MD5 e2e0f12a446c5e375e21dab3513b7745
BLAKE2b-256 628b65172015e0c458e1a428d03db66844430a1347aae2dfafba3f986d034ad2

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-musllinux_1_2_x86_64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-musllinux_1_2_armv7l.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-musllinux_1_2_armv7l.whl
Algorithm Hash digest
SHA256 4d8c5e9aac4eef3e618bc2b02d7093bce3d48b941b8d7dd3ea62f8b1d61c9159
MD5 d76bd3c65c7139e542816dcb5e098c84
BLAKE2b-256 6b727f7708243fa737fa13f65796d9463ff21b714d74a8804c6b128133603672

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-musllinux_1_2_armv7l.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 7d9946f9b582f85cfb171d22d60c284a5b14ad0715c9ef8842098b1b44fe0231
MD5 be70a36ecf229b7f6fb6fdc87959df44
BLAKE2b-256 b405f95a32ac798cf72f5dedbbfea488062684bfae227773c1ee2ce2142ca4cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-musllinux_1_2_aarch64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e736ac9c551577b5cb19aaded84d1840c95c6b0a6ee6c29501ec6c5a81e09fb8
MD5 0724197c0e72e5c19ff7c872e514c276
BLAKE2b-256 729d0a13858df84014f80e707548034011a355646e4680fea74d530e047ce83c

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-manylinux_2_28_x86_64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-manylinux_2_28_ppc64le.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-manylinux_2_28_ppc64le.whl
Algorithm Hash digest
SHA256 1f9cdbb4927da467971081b0be309d375644a4cae9133897c23bdcfccf22491a
MD5 d858c634468cbb7c91231e87fc884750
BLAKE2b-256 15e0182c98c0f708bdb47c977d24e3f13d71a4eddfd895665c5b848d5bc3d412

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-manylinux_2_28_ppc64le.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-manylinux_2_28_armv7l.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-manylinux_2_28_armv7l.whl
Algorithm Hash digest
SHA256 801f20d0633b0522b70a74121a78399412c992ddac3f984980a5b9df2f5fe7b6
MD5 d5f4620d30615041c4283a2c74fe1506
BLAKE2b-256 f05e6c0a4ddc5a8deafc00769f3696cf70908363b4dab4105a69bacf7b377272

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-manylinux_2_28_armv7l.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 62df7cb82d5b327e3b02e3299a109b71418563dcfc8776d93c343a9c416fe9a0
MD5 84006c7674d12051fddabac3d046b6d4
BLAKE2b-256 5375066a433e900de0951c23ef13dfd2947b0930325e4a436732253f2e67af0a

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-manylinux_2_28_aarch64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 8eb65a05865a9e4a7ae74fce1d24602110ef32d740c3ff2cfb9dfecda1bbaea2
MD5 78b9ff0d0ba6ba4a8004a965ac5d07df
BLAKE2b-256 c9c86857f47997db5a5f600fbbc062f542577611cfa54c237a8d608ab580cece

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-macosx_11_0_arm64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rusterize-0.8.1-cp311-abi3-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for rusterize-0.8.1-cp311-abi3-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 038cfb9a97cb6502c9c94a0750cb38986030bb92737b34e1632704a257351241
MD5 66f1c8d4b9a60aa5a42a061fe9d4862f
BLAKE2b-256 27624ba4ef3c59f69392234e2a1e2165af735b9e8654d12d2cf227245e5358c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for rusterize-0.8.1-cp311-abi3-macosx_10_12_x86_64.whl:

Publisher: CI.yml on ttrotto/rusterize

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page