Fast Linestring Simplification
The `simplification` library provides highly optimized linestring (polyline) simplification using either the Ramer-Douglas-Peucker (RDP) or Visvalingam-Whyatt algorithms. It achieves high performance by leveraging a Rust binary through Python's Foreign Function Interface (FFI). The library is currently at version 0.7.14 and appears to be actively maintained with frequent minor releases.
Common errors
-
ModuleNotFoundError: No module named 'simplification.cutil'
cause The `simplification` library's core functions are implemented in Rust and exposed via a `cutil` module. This error usually means the C/Rust extension module failed to compile or was not properly installed.fixEnsure `pip install simplification` completes without errors. If installing in a non-standard environment or from source, you may need a Rust toolchain installed (e.g., `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh`) and potentially development headers for Python. -
AttributeError: module 'simplification' has no attribute 'simplify_coords'
cause Attempting to import simplification functions directly from the top-level `simplification` package instead of its `cutil` submodule.fixCorrect the import statement to specifically target `simplification.cutil`: `from simplification.cutil import simplify_coords` (or other relevant functions). -
ValueError: input is not a valid sequence of coordinates
cause The input `coords` argument to `simplify_coords` or `simplify_coords_vw` is not in the expected format (e.g., not a list of lists/tuples of numbers, or a 2D NumPy array).fixEnsure your input coordinates are a sequence of sequences (e.g., `[[x1, y1], [x2, y2]]`) or a 2D NumPy array with shape `(N, 2)` or `(N, 3)` where N is the number of points and 2/3 are the dimensions.
Warnings
- gotcha The library primarily exposes functions through `simplification.cutil`, which is a Cython/Rust FFI module. Direct imports from `simplification` (e.g., `from simplification import simplify`) will fail as the main simplification functions are not exposed at the top-level package.
- gotcha The library's documentation explicitly states that 'Error-checking is non-existent at this point.' This means invalid inputs (e.g., non-numeric coordinates, malformed lists) might lead to crashes or unexpected behavior rather than clear Python exceptions.
- gotcha When using Visvalingam-Whyatt, the `simplify_coords_vwp` function offers a topology-preserving variant. While it produces geometries less prone to self-intersections, it is generally slower than `simplify_coords_vw`. Choose based on your application's need for speed versus geometric validity.
- gotcha The `simplification` library relies on a compiled Rust binary. While `pip install` typically handles pre-built wheels, local development or unusual environments might require a Rust toolchain for compilation, which can be a dependency hurdle.
Install
-
pip install simplification
Imports
- simplify_coords
from simplification.cutil import simplify_coords
- simplify_coords_vw
from simplification.cutil import simplify_coords_vw
- simplify_coords_vwp
from simplification.cutil import simplify_coords_vwp
Quickstart
import numpy as np
from simplification.cutil import simplify_coords, simplify_coords_vw
# Example coordinates (list of lists or NumPy array)
coords_list = [
[0.0, 0.0],
[5.0, 4.0],
[11.0, 5.5],
[17.3, 3.2],
[27.8, 0.1]
]
coords_np = np.array(coords_list)
# --- Ramer-Douglas-Peucker (RDP) Simplification ---
# Epsilon: maximum distance between an original point and the simplified line segment
epsilon_rdp = 1.0
simplified_rdp = simplify_coords(coords_list, epsilon_rdp)
print(f"RDP Simplified (epsilon={epsilon_rdp}): {simplified_rdp}")
# --- Visvalingam-Whyatt (VW) Simplification ---
# Threshold: minimum effective area of a triangle formed by a point and its neighbors
threshold_vw = 30.0
simplified_vw = simplify_coords_vw(coords_np, threshold_vw)
print(f"VW Simplified (threshold={threshold_vw}): {simplified_vw}")