Skip to content

Getting started

This page walks through installing opentrash and running the three core products on your own data. For a high-level package overview, see Home; for the structural design, see Architecture.

Install

pip install opentrash

Requires Python 3.11 or newer. The base install brings in pandas, pyarrow, duckdb, geopandas, shapely, pyproj, and openpyxl.

Optional extras

pip install "opentrash[geotab]"     # Geotab GPS adapter
pip install "opentrash[postgres]"   # PostgreSQL/PostGIS GPS adapter
pip install "opentrash[dev]"        # pytest, ruff for development

Each extra is opt-in: install only the GPS adapters you need.

From source

If you'd like to contribute, modify, or pin to a specific commit:

git clone https://github.com/malsheikhyass/opentrash.git
cd opentrash
pip install -e ".[dev,geotab,postgres]"
pytest -q

Prepare your inputs

opentrash works with four kinds of input data:

Layer Format Purpose
Parcel polygons parquet (WKB) Service-point lookup; the unit of analysis for patterns
Route polygons parquet (WKB) Which route each GPS ping belongs to
Facility points or polygons parquet (WKB) Distinguishes landfill dwell from depot dwell
GPS pings parquet Vehicle telematics, date-partitioned in a cache

The opentrash.prep module includes helpers for one-time preparation of parcels, routes, and facilities from common source formats (shapefile, GeoJSON, GeoPackage). The opentrash.cache module manages a date-partitioned GPS cache populated by the GPS adapters.

The working coordinate reference system is EPSG:2230 (California State Plane Zone 6, US feet) by default. The web CRS for rendered HTML is EPSG:4326. The CRS is configurable through opentrash.core.crs if your area of operations sits in a different state plane zone.

Run the pipeline

The three entry points form a pipeline. Run them in order on the first day; on subsequent days, run only the steps whose inputs changed.

1. Enrich GPS pings

from opentrash.engine.enrichment import enrich_pings

enrich_pings(
    gps_cache_root="cache/",
    parcels_wkb_path="prep/parcels_wkb.parquet",
    routes_path="prep/routes.parquet",
    facilities_path="prep/facilities.parquet",
    out_root="enriched/",
    day="2026-01-18",
)

This performs the single spatial-join pass that backs every downstream product. Output: enriched/2026-01-18/<vehicle_id>.parquet files where each ping carries route_id, apn, in_landfill, and at_depot.

2. Detect patterns

from opentrash.patterns.runner import run_patterns

run_patterns(
    enriched_root="enriched/",
    parcels_wkb_path="prep/parcels_wkb.parquet",
    out_root="patterns/",
    period="past_year",
)

Output: per-window parquet files at patterns/<window_label>/by_route/<route_id>.parquet plus a _manifest.parquet. Patterns are idempotent; rerunning the same window with the same data is a no-op (the runner skips if outputs are fresh).

3. Render a route view

from datetime import date
from opentrash.routeview.runner import render_routeview

render_routeview(
    enriched_root="enriched/",
    segments_root="segments/",
    parcels_wkb_path="prep/parcels_wkb.parquet",
    routes_path="prep/routes.parquet",
    facilities_path="prep/facilities.parquet",
    out_root="routeview/",
    route_id="11722",
    day=date(2026, 1, 18),
    vehicle_id="815001",
    patterns_root="patterns/",
    patterns_window="2025-01-18_to_2026-01-18",
)

Output: a single self-contained HTML at routeview/2026-01-18/11722__815001.html. Open it in any browser.

Batch rendering

To render every route for a day:

from opentrash.routeview.runner import render_all_routes_for_day
render_all_routes_for_day(...)

Or render the top-N vehicles per route:

from opentrash.routeview.runner import render_top_n_vehicles
render_top_n_vehicles(...)

Next steps

  • Read Architecture to understand why the package is organized the way it is.
  • See the Roadmap for what's coming in future releases.
  • Sample data and step-by-step tutorials are planned for an upcoming release (see Roadmap).