Skip to content

Available Capabilities

Capabilities are the unit operations GISPulse can apply to spatial datasets. They are invoked inside JSON rules via the capability field.

bash
# List all capabilities
gispulse capabilities

Each rule calls a capability and passes it a config block. The parameters below are the keys of that block.

json
{
  "capability": "<name>",
  "ref_layer": "<optional>",
  "config": { "...": "..." }
}

Source of truth

The code is authoritative. For the exact schema of a capability (parameters, types, defaults):

python
from capabilities.registry import REGISTRY
REGISTRY.get("buffer")().get_schema()

Total registered capabilities: 117 — across 18 categories.


Vector — selection & join (Community)

Available in every tier. Capabilities tagged DuckDB / PostGIS go through the multi-backend Strategy pattern (dispatch by input size).

buffer

Metric buffer around geometries. Automatically reprojects to a metric CRS when needed.

Engines: Python (GeoPandas), DuckDB (ST_Buffer, > 50,000 features), PostGIS (server-side).

json
{
  "capability": "buffer",
  "config": { "distance": 100, "crs_meters": "EPSG:3857" }
}
ParameterTypeDefaultDescription
distancefloat0.0Distance in meters
crs_metersstringEPSG:3857Intermediate metric projection
cap_stylestringroundround, flat, square
join_stylestringroundround, mitre, bevel

filter

Filters features by attribute expression and/or spatial predicate. Supports cross-layer references.

Engines: Python (gdf.query + Shapely), DuckDB (SQL), PostGIS.

json
{
  "capability": "filter",
  "config": {
    "expression": "surface > 500 and usage == 'residential'",
    "spatial_predicate": "intersects",
    "ref_layer": "flood_zones",
    "buffer_distance": 50
  }
}
ParameterTypeDescription
expressionstringPython expression evaluated against columns
spatial_predicatestringintersects, within, contains, crosses, overlaps, touches, dwithin
ref_layerstringReference layer for the spatial predicate
ref_wkt / ref_geojsonstring / objectExplicit WKT or GeoJSON reference geometry
buffer_distancefloatBuffer (meters) applied to the reference geometry

intersects

Keeps features intersecting a reference geometry or layer (shortcut for a spatial filter).

json
{ "capability": "intersects", "config": { "ref_layer": "flood_zones" } }

clip

Clips features to the extent of a reference layer.

json
{ "capability": "clip", "config": { "ref_layer": "study_area" } }

spatial_join

Spatial join between the processed layer and a reference layer. Attaches reference attributes to matching features.

json
{
  "capability": "spatial_join",
  "config": { "ref_layer": "municipalities", "how": "left", "op": "intersects" }
}
ParameterTypeDefaultDescription
ref_layerstringrequiredReference layer
howstringleftleft, inner, right
opstringintersectsintersects, contains, within

nearest_neighbor

Joins attributes from the k nearest features of a reference layer, with optional max_distance.

json
{
  "capability": "nearest_neighbor",
  "config": { "ref_layer": "schools", "k": 1, "max_distance": 2000, "distance_col": "dist_school_m" }
}
ParameterTypeDefaultDescription
ref_layerstringrequiredReference layer
kint1Number of neighbours
max_distancefloatnoneMax distance in meters
distance_colstringdistanceName of the emitted distance column

spatial_aggregate

Aggregates values from a reference layer via a spatial predicate (count, sum, mean, min, max).

json
{
  "capability": "spatial_aggregate",
  "config": {
    "ref_layer": "households",
    "aggregations": { "population": "sum" },
    "predicate": "contains"
  }
}

reproject

Reproject to a target CRS.

json
{ "capability": "reproject", "config": { "target_crs": "EPSG:2154" } }

Vector — overlay & combine (Community)

Combine multiple layers into one — either geometrically (FME / QGIS-style overlay) or by concatenation.

CapabilityDescriptionKey parameters
overlay_intersectionGeometric intersection of two layers — attributes inherited from both sides.ref_layer, keep_geom_type, suffix_left, suffix_right
overlay_unionGeometric union — keeps A-only, B-only and A∩B fragments.ref_layer, keep_geom_type, suffix_left, suffix_right
eraseGeometric difference — removes from A whatever is covered by B (A attributes preserved).ref_layer, keep_geom_type
merge_layersConcatenates the primary layer with a list of ref_layers.ref_layers (array)
classify_by_ringClassifies every feature by the smallest containing ring (concentric isochrones / buffers) — emits value / class / color.ref_layers, ring_field, outside_value, palette
json
{
  "capability": "overlay_intersection",
  "config": { "ref_layer": "zoning_plu", "suffix_right": "_plu" }
}
json
{
  "capability": "classify_by_ring",
  "config": {
    "ref_layers": ["iso_500", "iso_1000", "iso_1500"],
    "ring_field": "cost_budget",
    "palette": "YlGnBu"
  }
}

Vector — derived geometry (Community)

CapabilityDescriptionKey parameters
centroidReplaces each geometry with its centroid.
envelopeAxis-aligned bounding box.
oriented_bboxMinimum rotated rectangle (buildings, parcels).
min_bounding_circleMinimum bounding circle (Shapely ≥ 2.1).
convex_hullConvex hull. Supports by_group / dissolve.by_group, dissolve
concave_hullk-nearest concave hull.k, ratio
alpha_shapeAlpha-shape (generalised concave hull).alpha
delaunay_triangulationDelaunay triangulation of vertices.
voronoi_polygonsVoronoi tessellation of input points.bounds
polygonizeBuilds polygons from a noded line network.snap_tolerance
json
{ "capability": "convex_hull", "config": { "by_group": "municipality" } }

Vector — editing & metrology (Community)

CapabilityDescriptionKey parameters
area_lengthAdds area_m2 / length_m columns.area_column, length_column
calculateEvaluates an expression to build a new column (sum, avg, min, max, median, std, ...).expression, output_field
dissolveDissolves features by attribute (GROUP BY + ST_Union).by
unionMerges every feature into a single geometry.
symmetric_differenceXOR between each feature and the union of a reference layer.ref_layer
vector_diffCompares two layers by id and flags added / removed / modified / unchanged.ref_layer, id_col, geometry_tolerance
make_validRepairs invalid geometries (self-intersections, duplicate rings).
simplifySimplification (Douglas-Peucker, Visvalingam-Whyatt, topology-preserving).tolerance, algorithm
chaikin_smoothIterative corner-cutting smoother.iterations
densify_verticesInserts vertices at a target spacing.max_distance, n_segments
snap_to_gridSnaps vertex coordinates onto a grid.grid_size
offset_curveParallel line at a signed distance.distance
line_mergeMerges touching line segments.
line_substringLine substring between two measures.start_measure, end_measure
line_locate_pointProjects points onto the nearest reference line + computes the measure.ref_layer
extract_verticesEmits one Point per vertex with indices.
extract_segmentsSplits each line / polygon boundary into 2-point segments.
json
{ "capability": "simplify", "config": { "tolerance": 5.0, "algorithm": "vw" } }
json
{
  "capability": "calculate",
  "config": { "output_field": "price_m2", "expression": "price / surface_m2" }
}

Vector — attribute manipulation (Community)

Non-spatial schema operations — add, drop, rename, join, lookup table, null fallback.

CapabilityDescriptionKey parameters
add_fieldAdds one or more columns with a default value.fields, overwrite
drop_fieldDrops columns (geometry is protected).fields, ignore_missing
select_columnsKeeps only the listed columns (geometry always preserved).fields
rename_fieldRenames columns via {old: new} mapping.mapping, ignore_missing
cast_fieldCasts columns to a target dtype.casts, errors
attribute_joinNon-spatial join on a key column (left / right / inner / outer).ref_layer, left_on, right_on, how, columns, prefix, suffix
lookup_tableMaps a column through a dict with default fallback.source_col, target_col, mapping, default
coalesce_fieldsFirst non-null value across a list of columns.sources, target_col
case_whenSQL-style conditional column.target_col, cases, else_
describeSchema introspection report (dtype, nulls, unique, geom_type, bounds) — stored under gdf.attrs["__schema_describe__"], layer returned unchanged.sample_size, include_geometry
json
{
  "capability": "case_when",
  "config": {
    "target_col": "tier",
    "cases": [
      { "when": "population > 100000", "value": "A" },
      { "when": "population > 10000", "value": "B" }
    ],
    "else_": "C"
  }
}
json
{
  "capability": "attribute_join",
  "config": { "ref_layer": "communes_insee", "left_on": "code_insee", "how": "left" }
}

Vector — pivot / unpivot (Community)

Long ↔ wide reshape (pandas semantics), geometry preserved.

CapabilityDescriptionKey parameters
pivotLong → wide: columns becomes new columns, values populates the cells.index, columns, values, aggfunc, fill_value, geom_strategy
unpivotWide → long: emits (variable, value) pairs from value_vars.id_vars, value_vars, var_name, value_name
json
{
  "capability": "pivot",
  "config": {
    "index": "municipality_id",
    "columns": "year",
    "values": "population",
    "aggfunc": "sum",
    "geom_strategy": "first"
  }
}

geom_strategy (first, union, centroid) controls how geometries collapse when several rows in the same group carry different geometries.


Vector — ordered selection & sampling (Community)

Sort, deduplicate, random sample, top-N — purely attribute operations.

CapabilityDescriptionKey parameters
sortOrders by one or more columns.by, ascending, na_position
deduplicateDrops duplicates by attribute key (compare with duplicate_geometry which dedupes on geometry).keys, keep, order_by, ascending
random_sampleRandom sample (n or fraction, reproducible via seed).n, fraction, seed, replace
top_nKeeps the top-N features ordered by a column.n, by, ascending
json
{ "capability": "top_n", "config": { "n": 100, "by": "rdm_m2", "ascending": false } }

Vector — multipart & Z/M dimensions (Community)

Multipart ↔ singlepart conversion and Z (elevation) / M (measure) dimension management.

CapabilityDescriptionKey parameters
multipart_to_singlepartsExplodes Multi* features — one row per part, attributes duplicated.reset_index, drop_empty
singleparts_to_multipartCollects single-parts into Multi*, optionally grouped by attributes.by, agg
add_zAdds a Z dimension (constant or from_column).z, from_column
drop_zStrips the Z dimension → 2D layer.
add_mAdds an M dimension (constant or column).m, from_column
drop_mStrips the M dimension.
json
{ "capability": "add_z", "config": { "from_column": "ground_elevation" } }

Vector — geometric transforms (Community)

Affine transforms, axis swap, line reversal — fast operations that don't touch the CRS.

CapabilityDescriptionKey parameters
affine_transformTranslate / rotate / scale / skew (declared order, configurable origin).translate, rotate, scale, skew, origin
swap_xySwaps X and Y on every vertex (rescue mis-exported lat/lon files).
reverse_linesReverses vertex order for LineString / MultiLineString.ignore_non_lines
json
{
  "capability": "affine_transform",
  "config": { "rotate": 30, "origin": "centroid" }
}

Vector — boundary & projection (Community)

Boundary extraction, hole handling, geometry-type coercion, CRS declaration without transform.

CapabilityDescriptionKey parameters
boundaryTopological boundary of every geometry.drop_empty
extract_holesExtracts interior rings (holes) as polygon features.parent_id_col, hole_index_col
force_geometry_typeCoerces to a target type (Multi → single via explode, etc.).target, on_multi, on_invalid
assign_projectionSets the layer CRS without reprojecting (use reproject to transform).crs, allow_override
json
{ "capability": "force_geometry_type", "config": { "target": "Polygon", "on_multi": "explode" } }

assign_projectionreproject

assign_projection only changes the CRS metadata — it does not touch the coordinates. Use it to fix a layer with a wrong or missing CRS.


Temporal (Community)

Filters and joins on datetime columns.

CapabilityDescriptionKey parameters
temporal_filterFilters by a [start, end] window on a datetime column. Inversion supported.time_col, start, end, include_start, include_end, invert
temporal_joinExact or as-of join (backward / forward / nearest) with tolerance.ref_layer, left_on, right_on, strategy, by, tolerance, columns
json
{
  "capability": "temporal_join",
  "config": {
    "ref_layer": "weather_hourly",
    "left_on": "ts_observation",
    "strategy": "nearest",
    "tolerance": "30min",
    "by": "station_id"
  }
}

Validation (Community)

Data quality controls. Validation capabilities return a violations layer (one row per issue detected).

CapabilityDescription
topology_checkInvalid geometries, self-intersections, overlapping polygons.
duplicate_geometryExact or tolerance-based duplicate detection.
attribute_validationTypes, nullability, value ranges, regex, uniqueness.
completeness_checkNull ratio per column, spatial coverage relative to a reference extent.
json
{
  "capability": "topology_check",
  "config": { "check_overlaps": true, "check_self_intersections": true }
}
json
{
  "capability": "attribute_validation",
  "config": {
    "schema": [
      { "field": "population", "type": "integer", "min": 0 },
      { "field": "code_insee", "unique": true, "pattern": "^[0-9]{5}$" }
    ]
  }
}

Classification & styling (Community)

Prepares data for thematic cartography: bucketing, colour ramps, style generation.

CapabilityDescriptionKey parameters
classifyBuckets a numeric column into N classes (quantile / equal_interval / manual / jenks / pretty / std_dev).column, method, k, palette
classify_categoricalClassification by unique values with optional other bucket.column, palette, other_threshold
head_tail_breaksHead/Tail breaks (Jiang 2013) — number of classes driven by the distribution.column
normalizeNormalisation (minmax / zscore / log / log1p / rank / percent).column, method, denom
continuous_rampContinuous colour gradient (no classification).column, palette
graduated_sizeProportional symbol size driven by a numeric column.column, min_size, max_size
choroplethClassification + LayerStyleDef + legend (QML/SLD export).column, method, k, palette
bivariate_choroplethBivariate choropleth (two columns × palette grid).column_x, column_y, n, palette
json
{
  "capability": "choropleth",
  "config": {
    "column": "pop_density",
    "method": "jenks",
    "k": 5,
    "palette": "YlOrRd"
  }
}

Spatial statistics (Community)

Cluster detection, autocorrelation, hot / cold spot analysis.

CapabilityDescriptionKey parameters
spatial_weightsBuilds spatial weights (queen / rook / k-NN / distance band) and adds n_neighbours.method, k, threshold
morans_iGlobal Moran's I with permutation-based pseudo p-value. Returns a summary row.column, weights, n_permutations
getis_ord_gGetis-Ord Gi* z-score per feature (hot / cold spots).column, weights
json
{
  "capability": "morans_i",
  "config": { "column": "price_m2", "weights": { "method": "queen" }, "n_permutations": 999 }
}

Density & tessellation (Community)

Grid builders and density surfaces.

CapabilityDescriptionKey parameters
grid_createRegular square fishnet over a ref_layer or explicit bounds.cell_size, bounds, ref_layer
hexgrid_createFlat-top hexagonal grid.cell_size, bounds, ref_layer
kde_heatmapKDE sampled on a regular grid → points with density.bandwidth, cell_size, bounds
json
{
  "capability": "hexgrid_create",
  "config": { "cell_size": 500, "ref_layer": "study_area" }
}

Clustering (Community — optional scikit-learn)

Install via pip install "gispulse[cluster]". Each capability adds a cluster column (-1 = noise for DBSCAN / HDBSCAN).

CapabilityDescriptionKey parameters
cluster_kmeansK-Means on geometry centroids.k, random_state
cluster_dbscanDensity-based DBSCAN.eps, min_samples
cluster_hdbscanHierarchical HDBSCAN, varying densities.min_cluster_size, min_samples
json
{ "capability": "cluster_dbscan", "config": { "eps": 200, "min_samples": 5 } }

Line-network topology (Community)

Cleans a line network before running network analysis.

CapabilityDescriptionKey parameters
network_snap_endpointsSnaps near-coincident endpoints together.tolerance
network_extend_danglesExtends dangling endpoints to the closest line.tolerance
network_node_linesSplits each line at every intersection → planar graph.
network_remove_duplicatesDrops geometric duplicates (direction-agnostic).tolerance
network_remove_pseudo_nodesMerges segments meeting at degree-2 nodes.
json
{ "capability": "network_snap_endpoints", "config": { "tolerance": 0.5 } }

Polygon topology (Community)

Repairs a polygon coverage (gaps, overlaps, slivers).

CapabilityDescriptionKey parameters
polygon_fix_gapsDetects gaps below max_area and merges them into the neighbour with the longest shared border.max_area
polygon_fix_overlapsRemoves overlaps following a rule (smallest, largest, first).rule
polygon_remove_sliversRemoves long / thin polygons (min_area or max_shape_index).min_area, max_shape_index
polygon_snap_bordersSnaps vertices onto a grid → adjacent borders land on the same coordinates.grid_size
json
{ "capability": "polygon_fix_gaps", "config": { "max_area": 10.0 } }

3D Pointcloud (Community — pip install "gispulse[pointcloud]")

Loading and processing of LAS / LAZ pointclouds (ASPRS). Requires laspy (and lazrs for LAZ).

CapabilityDescriptionKey parameters
pointcloud_load_lasLoads a .las / .laz file into a GeoDataFrame of Point Z.path, crs, max_points, classifications
pointcloud_filter_classificationFilters points by ASPRS classification codes (keep / drop).keep, drop, col
pointcloud_zonal_heightPer-polygon Z statistics (building heights, canopy).ref_layer, stats, prefix, ground_col
pointcloud_grid_summaryBins Z values into a regular grid → polygons with per-cell stats.cell_size, stats, drop_empty
json
{
  "capability": "pointcloud_load_las",
  "config": {
    "path": "data/lidar/tile_1234.laz",
    "crs": "EPSG:2154",
    "classifications": [2, 6]
  }
}
json
{
  "capability": "pointcloud_zonal_height",
  "config": {
    "ref_layer": "lidar_points",
    "stats": ["max", "mean", "p95"],
    "ground_col": "ground_elevation",
    "prefix": "h_"
  }
}

Common ASPRS class codes

2 = ground, 5 = high vegetation, 6 = building, 9 = water. See the LAS 1.4 spec.


Raster (Pro — pip install "gispulse[raster]")

Requires rasterio + rasterstats and a Pro license (GISPULSE_TIER=pro).

Pro tier

Raster capabilities call check_tier("pro") at runtime.

CapabilityDescriptionKey parameters
zonal_statsRaster statistics (min/max/mean/std/sum/count) per polygon.raster_path, stats
raster_clipClips a raster to a vector extent.raster_path, output_path
ndviNDVI = (NIR − RED) / (NIR + RED) from a multi-band raster.raster_path, nir_band, red_band
raster_reprojectRaster reprojection.raster_path, target_crs, output_path
raster_mergeMerges multiple rasters into one.raster_paths, output_path
change_detectionPolygonises changed areas between two rasters.raster_before, raster_after, threshold
json
{
  "capability": "zonal_stats",
  "config": {
    "raster_path": "data/ndvi.tif",
    "stats": ["min", "max", "mean", "std", "sum", "count"]
  }
}

Network analysis (Pro — pip install "gispulse[network]")

Requires networkx and a Pro license.

CapabilityDescriptionKey parameters
shortest_pathDijkstra shortest path between two points.origin, destination, weight_col
isochroneReachable area within a budget (distance / time).origin, max_distance, weight_col
od_matrixOrigin-destination matrix in long format.origins_layer, destinations_layer, weight_col
mstMinimum spanning tree of a line network.weight_col
network_allocationAllocates demand points to the nearest supply node on the network.supply_layer, weight_col, max_cost
connectivity_checkEnsures the network forms a connected graph and returns connected components.
json
{
  "capability": "isochrone",
  "config": { "origin": [2.3522, 48.8566], "max_distance": 1000, "weight_col": "length_m" }
}

PostGIS SQL (Pro)

postgis_sql

Runs a parameterised SQL query directly on PostGIS for advanced operations not covered by the other capabilities.

json
{
  "capability": "postgis_sql",
  "config": {
    "sql": "SELECT *, ST_Area(geom::geography) AS area_geo FROM {input_table} WHERE ST_IsValid(geom)",
    "geom_col": "geom",
    "params": {}
  }
}
ParameterTypeDescription
sqlstringQuery using {input_table} as placeholder
paramsobjectNamed parameters ($name) for the query
geom_colstringGeometry column (default: geom)
input_tablestringInput table (auto-created if missing)

Security

The DSN is never read from config — it is resolved from GISPULSE_POSTGIS_DSN. SQL identifiers are validated (operation_executor.py). Do not expose this capability to untrusted users.


Tier summary

CategoryCapsTierOptional extra
Vector — selection & join8Community
Vector — overlay & combine5Community
Vector — derived geometry10Community
Vector — editing & metrology17Community
Vector — attribute manipulation9Community
Vector — pivot / unpivot2Community
Vector — ordered selection & sampling4Community
Vector — multipart & Z/M dimensions6Community
Vector — geometric transforms3Community
Vector — boundary & projection4Community
Temporal2Community
Validation4Community
Classification & styling8Communitymapclassify (for jenks)
Spatial statistics3Community
Density & tessellation3Community
Clustering3Communitygispulse[cluster] (scikit-learn, hdbscan)
Line-network topology5Community
Polygon topology4Community
3D Pointcloud4Communitygispulse[pointcloud] (laspy, lazrs)
Raster6Progispulse[raster] (rasterio, rasterstats)
Network analysis6Progispulse[network] (networkx)
PostGIS SQL1Progispulse[postgis] + DSN
Total117

Build your own capability

See Developing a plugin for the entry-point publication flow.

python
from capabilities.base import Capability
from capabilities.registry import register

@register
class MyCapability(Capability):
    name = "my_cap"
    description = "Short description of my capability."

    def execute(self, gdf, my_parameter=1.0, **_):
        # business logic here
        return gdf

    def get_schema(self):
        return {
            "type": "object",
            "properties": {
                "my_parameter": {"type": "number", "default": 1.0}
            },
            "required": ["my_parameter"],
        }

A distributed capability can self-register via the gispulse.capabilities entry-point group (see the pyproject.toml in sdk/).

Published under AGPL-3.0 license.