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 tissot
Available 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 tissot
Step 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):
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"])
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.