Metadata-Version: 2.4
Name: catsmoothing
Version: 0.5.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Programming Language :: Python :: 3.15
Classifier: Programming Language :: Rust
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Typing :: Typed
Requires-Dist: numpy>=2
Requires-Dist: shapely>=2
License-File: LICENSE
License-File: AUTHORS.md
Summary: Smoothing Shapely geometries using Catmull-Rom spline
Home-Page: https://github.com/cheginit/catsmoothing
Author-email: Taher Chegini <cheginit@gmail.com>
License: MIT
Requires-Python: >=3.13
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: CI, https://github.com/cheginit/catsmoothing/actions
Project-URL: Changelog, https://github.com/cheginit/catsmoothing/blob/main/CHANGELOG.md
Project-URL: Documentation, https://cheginit.github.io/catsmoothing/
Project-URL: Homepage, https://github.com/cheginit/catsmoothing
Project-URL: Issues, https://github.com/cheginit/catsmoothing/issues

![CatSmoothing](https://raw.githubusercontent.com/cheginit/catsmoothing/refs/heads/main/docs/assets/logo_small.png)

# CatSmoothing: Smoothing Shapely Geometries with Catmull-Rom Splines

[![PyPI](https://img.shields.io/pypi/v/catsmoothing)](https://pypi.org/project/catsmoothing/)
[![Conda](https://img.shields.io/conda/vn/conda-forge/catsmoothing)](https://anaconda.org/conda-forge/catsmoothing)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/cheginit/catsmoothing/HEAD?labpath=docs%2Fexamples)
[![Downloads](https://img.shields.io/conda/dn/conda-forge/catsmoothing.svg)](https://anaconda.org/conda-forge/catsmoothing)

[![codecov](https://codecov.io/gh/cheginit/catsmoothing/graph/badge.svg?token=U2638J9WKM)](https://codecov.io/gh/cheginit/catsmoothing)
[![CI](https://github.com/cheginit/catsmoothing/actions/workflows/test.yml/badge.svg)](https://github.com/cheginit/catsmoothing/actions/workflows/test.yml)
[![Docs](https://github.com/cheginit/catsmoothing/actions/workflows/docs.yml/badge.svg)](https://cheginit.github.io/catsmoothing/)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![CodSpeed Badge](https://img.shields.io/endpoint?url=https://codspeed.io/badge.json)](https://codspeed.io/cheginit/catsmoothing)

## Overview

**CatSmoothing** smooths [Shapely](https://shapely.readthedocs.io) geometries,
`LineString` and `(Multi)Polygon`, using the Catmull-Rom spline algorithm and can
compute tangent angles at each vertex of a list of lines. The implementation is based on
the [Splines](https://github.com/AudioSceneDescriptionFormat/splines) library, but
offers performance improvements and additional features.

You can try CatSmoothing directly in your browser by clicking the Binder badge above.

## Key Features

- Written in Rust for performance and runs in parallel using Rayon
- Creating splines from 2D vertices of a line that allows computing n-th derivatives
- Smoothing geometries with Centripetal Catmull-Rom splines with **uniform spacing**
    (points are spaced by equal arc length, computed with Gauss-Legendre quadrature)
- Computing tangent vectors at each vertex of a line
- Optional vertex pre-smoothing to reduce noise before fitting: a Gaussian filter with
    sigma in vertices or in length along the line, or Taubin smoothing that keeps the
    size of well-sampled shapes
- Optional curvature continuity (G2 or C2) through continuity-enhancing splits

## Installation

Install CatSmoothing via `pip` or `micromamba`:

Using `pip`:

```bash
pip install catsmoothing
```

Using `micromamba` (or `conda`/`mamba`):

```bash
micromamba install -c conda-forge catsmoothing
```

## Quick Start

CatSmoothing provide one class called `CatmullRom` that is general purpose, Catmull-Rom
spline interpolation class. You can tweak the `alpha` parameter of the class to
interpolate with different versions of the Catmull-Rom spline from 2D vertices of a line
and compute n-th derivatives. For smoothing geometries, CatSmoothing uses the
centripetal Catmull-Rom spline algorithm, i.e., `alpha=0.5`. There are two functions
that can be used for smoothing geometries: `smooth_linestrings` and `smooth_polygon`.
There is also a function for computing tangent angles (in radians) at each vertex of a
line.

### Basic Usage

For fitting a Catmull-Rom spline to a line, we can use the following code:

```python
from catsmoothing import CatmullRom


verts = [(0, 0), (0, 0.5), (1.5, 1.5), (1.6, 1.5), (3, 0.2), (3, 0)]
n_pts = 15
smoothed = {}
for alpha in (0, 0.5, 1):
    s = CatmullRom(verts, alpha=alpha, bc_type="closed")
    dots = int((s.grid[-1] - s.grid[0]) * n_pts) + 1
    distances = s.grid[0] + np.arange(dots) / n_pts
    smoothed[alpha] = s.evaluate(distances)
```

![Catmull-Rom Splines](https://raw.githubusercontent.com/cheginit/catsmoothing/main/docs/examples/images/alpha.png)

For smoothing a geometry, we can use the following code:

```python
from shapely import Polygon
import catsmoothing as cs


poly = Polygon(verts)
ploy_smoothed = cs.smooth_polygon(poly, n_pts=50)
```

![Polygon Smoothing](https://raw.githubusercontent.com/cheginit/catsmoothing/main/docs/examples/images/poly.png)

For smoothing a noisy line, we can use the following code:

```python
import numpy as np
from shapely import LineString
import catsmoothing as cs


rng = np.random.default_rng(123)
x = np.linspace(-3, 2.5, 50)
y = np.exp(-(x**2)) + 0.1 * rng.standard_normal(50)
line = LineString(np.c_[x, y])
line_smoothed = cs.smooth_linestrings(line, n_pts=30, gaussian_sigmas=2)
```

![Line Smoothing](https://raw.githubusercontent.com/cheginit/catsmoothing/main/docs/examples/images/line.png)

We can then compute the tangent angles in radians at each vertex of the smoothed line:

```python
tangents = cs.linestrings_tangent_angles(line_smoothed)
```

![Tangent Angles](https://raw.githubusercontent.com/cheginit/catsmoothing/main/docs/examples/images/tangents.png)

### Pre-smoothing and continuity options

The smoothing functions and `CatmullRom` accept keyword-only options:

- `sigma_units="length"` measures the Gaussian sigma in coordinate units along the line,
    so unevenly spaced vertices are smoothed evenly.
- `taubin_iterations=n` applies Taubin smoothing, which damps jitter and keeps the size
    of curves drawn with more than about a dozen vertices per turn (Gaussian smoothing
    shrinks closed rings).
- `continuity="g2"` makes curvature continuous, and `continuity="c2"` also makes the
    second derivative continuous; vertices and their tangents are unchanged.

```python
line_smoothed = cs.smooth_linestrings(
    line, distances=0.1, gaussian_sigmas=0.3, sigma_units="length", continuity="g2"
)
```

For more examples, visit the [documentation](https://cheginit.github.io/catsmoothing/).

## Contributing

We welcome contributions! For guidelines, please refer to the
[contributing guide](https://cheginit.github.io/catsmoothing/contributing/) and
[CODE_OF_CONDUCT.md](https://github.com/cheginit/catsmoothing/blob/main/CODE_OF_CONDUCT.md).

## License

CatSmoothing is licensed under the MIT License. See the
[LICENSE](https://github.com/cheginit/catsmoothing/blob/main/LICENSE) file for details.

