A visual-first geospatial diagnostics engine.
Named after Tissot's indicatrix — the ellipses that reveal what map projections hide.
Tissot makes spatial data problems visible. One command, zero config, opens an interactive map in your browser.
# See how your projection distorts your data
tissot xray parcels.gpkg
# Check data quality (topology, schema, duplicates)
tissot check parcels.gpkg
# Get a quality score (like Lighthouse, but for maps)
tissot score project.qgz
# Visual before/after diff with slider
tissot diff Q3_parcels.gpkg Q4_parcels.gpkg
# Auto-fix: reproject to optimal CRS
tissot fix parcels.gpkg --reproject
# Watch a directory for changes
tissot watch ./pipeline/output/Every GIS professional has been told "don't use Web Mercator for area calculations." But have you ever seen the actual error on your actual data?
tissot xray computes per-feature distortion, generates a heatmap overlaid on your data, draws Tissot ellipses at sample locations, and recommends a better CRS — with quantified proof.
$ tissot xray kentucky_permits.gpkg
Current CRS: EPSG:3857 (Web Mercator)
Area distortion — Max: 18.3% Mean: 11.7%
Recommended: EPSG:3089 (NAD83 / Kentucky Single Zone)
Area distortion — Max: 0.02% Mean: 0.01%
→ Interactive report opened in browser
# From crates.io (Rust)
cargo install tissot
# From PyPI (Python)
pip install tissotAvailable from the QGIS Plugin Repository.
Step 1 — Install the tissot Python package into the same Python runtime used by QGIS:
# macOS
"/Applications/QGIS.app/Contents/MacOS/python" -m pip install tissot
# Windows (OSGeo4W Shell)
python -m pip install tissot
# Linux
python3 -m pip install tissotStep 2 — In QGIS: Plugins → Manage and Install Plugins... → search for Tissot Processing Provider → Install.
The plugin adds four Processing algorithms (available in the toolbox and model builder):
- Projection X-Ray — per-feature distortion analysis
- Data Quality Check — linting with spatial findings
- Map Quality Score — 0-100 Lighthouse-style rating
- Spatial Diff — categorized change layer between two datasets
PyO3 bindings are in progress. Today, Python environments install the tissot
CLI, which can be called from Python via subprocess.
import json
import subprocess
result = subprocess.run(
["tissot", "check", "data.gpkg", "--json"],
check=True,
capture_output=True,
text=True,
)
report = json.loads(result.stdout)
print(report["summary"]["total"])- Visual-first — Browser maps are the default output, not terminal text
- Zero-config — Works immediately, no setup required
- Autofix — Don't just report problems, fix them
- Scored — 0-100 quality rating like Lighthouse for websites
- Cloud-native — Validates FlatGeobuf, GeoParquet, and cloud-optimized format best practices
- Offline — All reports work without internet
- Fast — Rust core, Rayon parallelism, sub-second for typical datasets
Rust core using the GeoRust ecosystem. Python bindings via PyO3. Visual reports powered by MapLibre GL JS. Cloud-native format guidance aligned with the CNG Formats Guide.
🚧 In Development — Phase 1 (X-Ray + Data Quality + Cloud Optimization + Score)
Dual-licensed under MIT or Apache-2.0, at your option.
Tissot uses an AI-assisted development workflow. See CLAUDE.md for project context and ai-dev/ for architecture docs, agent configurations, and coding standards.
The easiest way to contribute is to add a new checker rule: implement the Rule trait in a new file under src/checkers/. See existing rules for the pattern.