
ALPR監視対策PWA。カメラアーカイブはデバイス上に保存されます。
they watching. we watching back.
ドライバーが自動ナンバープレート読取装置のそばを通過する前に、それがどこにあるかを知らせる、 Android 優先の対監視 PWA です。
オフラインでも動作するカメラアーカイブに対するリアルタイムの近接アラート、ローカルの露出履歴、 署名およびハッシュチェーンされたカメラ報告のオンデバイスキュー、そして周辺のカメラを運用して いる機関に関する、出典に基づく公開記録のコンテキストを提供します。
デプロイされたアプリには報告アップロード用のエンドポイントがありません。報告は現在 IndexedDB に 留まります。送信ゲートウェイはオペレーター用コードとして存在しますが、デプロイされたルートでは ありません。この区別はこの README 全体を通じて意図的なものです。
これは意図的に 6 つ目のことを行いません。すなわち、いかなるベンダーのシステムにも問い合わせず、 ナンバープレートの値がデバイスから出ることはありません。
darkroute/
├── apps/
│ ├── pwa/ React 19 + TypeScript + Vite PWA
│ ├── desktop/ api.darkroute.ai の開発者コンソール。その functions/ が /v1 と /api/v1 を apex にプロキシする
│ └── android/ ビルド可能な Android Trusted Web Activity シェル
├── packages/
│ ├── core/ 純粋な幾何計算とアラートエンジン。DOM も I/O もなし
│ └── api-client/ 空のプレースホルダ。実際のコントラクトは GET /api/v1/openapi.json
├── functions/
│ ├── cameras/ CAMERA_TILES R2 バインディングからの同一オリジンのカメラタイル
│ └── api/
│ ├── v1/ 公開 API: 読み取り、/submit (PR を作成)、/photo、openapi.json、_middleware
│ └── admin/ Cloudflare Access テスター許可リスト (プライベート開発ホストのみ)
├── scripts/ カメラパイプライン、デプロイ、アセットおよびポリシーチェック
├── docs/ 実装、運用および公開ドキュメント
├── the design-gap ledger 未解決の設計上の決定と代替実装
└── installer.sh
LoRa スタックは Meshtastic 自身のもので、改変されていません。このプロジェクトはファームウェアを
ビルドせず、純正ノードとペアリングします。packages/api-client はプレースホルダのままであり、
本番の PWA はこれを使用しません。
デプロイされた製品は、静的 PWA と Cloudflare Pages Functions です。すなわち、カメラタイルルート、
/api/v1/ 配下の公開 API (公開 API を参照)、そしてプライベート開発ホスト上の
Access で保護された 2 つの管理ルートです。FastAPI プロセス、Postgres データベース、プレゼンス
API、デプロイされた報告エンドポイントはありません。唯一の書き込みパスである
POST /api/v1/submit は、何かに書き込むのではなく、公開プルリクエストを作成します。
flowchart LR
OSM["OpenStreetMap"] --> PIPE["scheduled Node camera pipeline"]
PIPE --> R2[("R2 camera archive")]
R2 --> CAM["/cameras/* Pages Function"]
subgraph device["Browser or Android TWA"]
GPS["geolocation + other adapters"] --> CORE["packages/core alert engine"]
CORE --> UI["DRIVE / map / reports"]
UI <--> IDB[("IndexedDB + service-worker cache")]
end
CAM --> IDB
MAP["project tile host (PMTiles)"] --> UI
カメラタイルは同一オリジンの /cameras/* から要求され、CAMERA_TILES R2 バインディングから
配信され、オフライン用にキャッシュされます。ベースマップと速度アーカイブは、プロジェクトが運用
する公開タイルホストへのクロスオリジンのレンジリクエストです。darkroute.ai が公開アプリです。
管理用 Functions はこのディストリビューションの完全に外側に存在します。
キュレーションツールと送信ゲートウェイはオペレーター用コードであり、このディストリビューション には含まれていません。どちらもデプロイされたランタイムサーバーではなく、このリポジトリ内の いかなるものも両者に依存していません。アプリはそれらなしでビルド、実行、テスト、監査できます。
地理空間計算は packages/core にあります。画面はストアとアダプターを利用します。プレートの
マッチング、トリップ履歴、報告の証拠チェーンはデバイス上に留まります。
アーカイブは誰でも、キーなしで https://darkroute.ai/api/v1/ から読み取れます。これは
https://api.darkroute.ai/v1/ および、開発者コンソールのプロキシ経由で
https://api.darkroute.ai/api/v1/ としても提供されます。機械可読なコントラクトは
GET /api/v1/openapi.json です。説明文は
docs/public/API.md §1.3 にあり、試せるコンソールは
api.darkroute.ai です。
| ルート | 何に答えるか |
|---|---|
GET /api/v1/cameras | bbox 内のカメラ (1 辺 ≤ 1.5°、≤ 24 タイル、≤ 1000 行)、任意の owner フィルター |
GET /api/v1/stats | アーカイブのサイズ、世代、ビルドおよび上流のタイムスタンプ |
GET /api/v1/abuse | 文書化された事例と生成日。任意の郡 fips |
GET /api/v1/news | 自動収集された ALPR の見出し、ソースリンクおよび収集状況 |
GET /api/v1/atlas | 郡別の EFF Atlas の機関とベンダー、取得/確認日付付き。任意の fips |
GET /api/v1/monitoring | 道路監視機器のインベントリ。任意の kind と bbox |
GET /api/v1/monitoring/image?id=... | 選択された交通カメラについて利用可能な発行者写真 |
GET /api/v1/place | 米国/PR の場所検索。ジオコーダーがドライバーの住所を見ることがないようプロキシされる |
GET /api/v1/route | 最大 60 地点を回避する運転ルート。決してキャッシュされない |
GET /api/v1/doc/{name} | 公開ミラーから公開されたドキュメントを Markdown として |
POST /api/v1/submit | 訂正を [unreviewed] プルリクエストに変換する。アーカイブには何も書き込まれない |
PUT /api/v1/photo | 送信が参照する写真。そのバイト列をキーとする。GET /api/v1/photo/{key} がそれを返す |
カメラのレスポンスは OpenStreetMap の帰属表示を伴い、Atlas のレスポンスはそのソースの帰属表示を
伴います。収集スケジュールと、アプリと API がどのようにデータを共有するかについては
報告とデータの鮮度 を参照してください。デフォルトで有効な機器レイヤー、
ソースのカバレッジ、オンデマンドのカメラ写真については
道路監視 を参照してください。公開されているすべてのデータセット、
直接ダウンロード、個別のカウント、鮮度、およびデバイス上にのみ存在するデータについては
完全なデータインベントリ を参照してください。カメラの合計には監視機器、
機関の配備、報告は含まれません。すべてのエラーは安定した error コードを持つ JSON です。
/api/v1/ 配下の未知のパスはアプリではなく 404 JSON です。アドレスごとに毎分 60 リクエストは
速度制限であり、上限ではありません。上限はリクエストごとのキャップです。空の回答は、そこに
カメラがマッピングされていないことを意味するだけで、存在しないことを決して意味しません。
アーカイブ全体はデータセットとして公開されています。大量の作業にはそれを利用してください。
sequenceDiagram
participant GPS as Geolocation adapter
participant Core as Alert engine
participant Store as Alert store
participant UI as DRIVE
participant Out as Haptics / notifications
GPS->>Core: position tick (lat, lon, speed, heading, accuracy)
Core->>Core: accuracy gate - poor fix computes but does not alert
Core->>Core: stationary dwell - a red light does not toggle alerts
Core->>Core: nearest camera, dedupe, hysteresis band
Core->>Store: AlertState + distance + relative direction
Store->>UI: selectors - digits snap, they never tween
Store->>Out: only via useShouldAlertUser()
Note over Store,Out: Muted suppresses this arrow and nothing else.<br/>Detection, logging, exposure counts and map<br/>rendering are identical whether muted or not.
alt camera enters threshold
Out->>Out: camera haptic (2 pulses when multiple)
UI->>UI: alert takes over the screen, above any sheet
else county line crossed
Out->>Out: silent - haptics are reserved for cameras
end
Python、FastAPI、Postgres、PostGIS はこのリポジトリの前提条件ではありません。ローカルの PWA 開発にはアカウント、データベース、バックエンドの認証情報は不要です。
git clone https://github.com/darkcodelabs/darkroute.git
cd darkroute
corepack enable
corepack prepare [email protected] --activate
./installer.sh