RING

駅を囲む、
見えない輪。

その内側に自転車を停めると、警告のうえ即日撤去される。 けれど、その輪がどこにあるのかを知る手段は、どこにもなかった。

Ring は、いま自分が立っている場所が輪の内か外かを答えるブラウザアプリです。

01 — なぜ作ったか

「近くの駐輪場」を探すサービスはある。
Ring はその逆をやる。

自転車を路上に停めてよいかどうかは、放置禁止区域の中か外かで決まります。 区域の中なら、警告のうえ即日撤去。取り戻すには自転車で 3,000 円前後、原付で 5,000 円前後かかり、 平日の昼間に保管所まで取りに行く時間が必要です。

ところが、この区域がどこなのかを事前に知る手段が、事実上ありません。

境界が見えない

区域の境界は道の途中にあります。こちら側は大丈夫でも、数メートル先はアウト。標識を見つけられなければ気づけません。

区ごとにバラバラ

千代田区は案内図、渋谷区は PDF と地図システム、大田区は区域図。形式も見せ方も違い、横断して見る方法がありません。

しかも動く

渋谷区は原宿・神宮前の区域を 2025 年 10 月に、渋谷駅周辺を 2026 年 4 月に拡大しました。昨日まで大丈夫だった場所が、今日から対象になります。

既存の駐輪場検索は「安全な場所のリスト」です。 リストに載っていない場所については、何も言えません。

けれど実際に人が停めるのは —— 駐輪場が満車のとき、近くに駐輪場がないとき、5 分だけ停めたいとき。 つまりリストの外側です。

Ring は路上のどこを指しても答えを返します。これが唯一かつ最大の違いです。

02 — 何ができるか

判定して終わりにしない。
行動が変わるところまで運ぶ。

  1. 停めていいかの判定

    画面中央の十字が指す地点について、放置禁止区域の内か外かを 5 段階で答えます。地図を動かすと連続的に更新されるので、指を動かすだけで「どこから危ないのか」が体感できます。

  2. 境界の警告

    「あと 12m で撤去対象」——判定点から最も近い境界まで線を引き、距離をメートルで表示します。境界は目に見えないので、ここが一番危ない。

  3. 代替の提示

    撤去対象だった場合、近くの駐輪場を距離順に提示します。収容台数・料金・利用時間つき。「停めるな」だけでは行動は変わりません。

  4. 区域変更のお知らせ

    施行前の拡大予定と、最近施行された変更を伝えます。「いつも停めている場所が来月から対象になる」は、現地の標識では気づけません。

  5. 撤去された後の案内

    どの保管所に行けばよいか、開いている曜日と時間、必要な持ち物。今日は開いているかも端末の時計から判定します。

  6. 根拠の開示

    すべての判定に、出典名・出典 URL・最終確認日・データの精度区分を添えます。根拠を示せないデータは画面に出しません。

東京駅で「撤去される可能性が高い」と判定された画面。赤い輪が地図に描かれている
赤い輪が放置禁止区域。中央の十字が判定点。
区域の外へ移動して「撤去対象ではありません」と表示された画面
区域の外へ出ると判定が変わる。境界まで線が引かれる。
判定の根拠・近くの駐輪場・保管所が並んだ画面
カードを引き上げると、代替と根拠が出てくる。

03 — ぶつかった壁

放置禁止区域のデータは、
どこにも公開されていなかった。

作りはじめて最初にやったのは、区域データを探すことでした。結果は次のとおりです。

調べたもの結果
東京都オープンデータカタログサイト
全文検索
「禁止区域」に該当する 125 件を確認。自転車の放置禁止区域は 0 件。
杉並区「自転車放置禁止区域」
カタログに唯一登録されていた CSV
登録 URL が 404。すぎナビ(区の地図システム)ごと到達不能。
千代田区・文京区・港区
公式ページ
区域は駅ごとの地図画像(JPG / PNG)としてのみ公開。町丁目や街路名による文章記述は無し。
条例・施行規則の別表 境界を文章で定義した別表は見つからず。

区は地図を持っているのに、機械が読める形では出していない。 これが本企画最大の障害であり、同時に企画の中身でもあります。

そこで、都の Excel に埋もれていた公式フラグを掘り起こした

東京都都民安全総合対策本部が毎年公表している 「駅別放置自転車の状況(令和 7 年度)」の Excel を開いたところ、 駅名の隣に の列がありました。凡例にはこう書かれています。

(注)*印がある駅周辺には自転車等駐車場が整備され、
      放置禁止区域が指定されている。

これは、全都 53 自治体・663 行・702 駅を網羅する、唯一の公式かつ機械可読な指定情報でした。 区域の「形」は分からなくても、どの駅に区域があるのかは、これで全都分わかります。

519放置禁止区域の指定がある駅
99.9%都Excel × 国土数値情報の駅名突合率
(702 駅中 701 駅)
0公開されている区域ポリゴン

この発見によって、Ring は「代表的な区だけのデモ」ではなく 東京全域で答えが返るサービスになりました。

04 — どう作ったか

区域データを 2 階層で持つ

精度の異なるデータを 1 つの箱に混ぜると、どこまで信じてよいか分からなくなります。 Ring は区域を Tier A / Tier B に分け、精度をデータそのものに持たせました。

Tier A — 区域ポリゴン

区の公式区域図から作図した多角形。精度は traced(図をトレース)または described(公開文書から作図)。

現在 0 件。各区が区域を画像でしか公開しておらず、作図元となる公開データが存在しないためです。 データ形式と取り込み口は実装済みで、公開され次第そのまま載ります。

Tier B — 駅指定リング

都 Excel の指定フラグ+駅座標から生成する円。精度は estimated(推定)。

現在 519 件で全都を覆います。半径は固定値ではなく、 その駅の乗入台数(放置台数+実収容台数)から算出しています。

リングの半径を、駅の規模から決める

秋葉原と小さな駅を同じ円で塗るのは実態から遠い。そこで都 Excel から得られる乗入台数を使いました。

r = clamp(100 + 3.0 × √(乗入台数), 120m, 400m)

結果、半径は 120〜400m に分布し、中央値は 181m。 各区が公開する区域図がおおむね駅から 120〜400m の範囲を指定していることに合わせています。 これは推定であり、実測ではありません。アプリはそのことを毎回画面に明記します。

技術構成 —— この問題の何が難しいか

「地図に区域を出す」だけなら難しくありません。難しいのは 地図を動かすたびに、任意の 1 点を 519 件の区域に対して判定し続けることと、 データの精度差を利用者に嘘をつかずに伝えることの 2 つでした。

領域採用この問題で必要だった理由
判定Turf.js + 自前の絞り込み層 点-多角形判定と最近傍境界点を毎フレーム計算する。全件に Haversine を回すと確実に重くなるため、bbox による粗選別と、区域ごとの bbox・境界線の WeakMap キャッシュで包み、requestAnimationFrame で 1 フレーム 1 回に間引いた
設計判定エンジンを純粋関数に分離 UI に一切依存させない。穴あきポリゴン・施行日境界・Tier 優先など 18 件のテストで固定し、判定の正しさと描画の不具合を切り分けられるようにした
地図MapLibre GL JS v5 raster-* の paint プロパティで基図の色調をコード側から制御でき、境界線だけを主役にする描画を作れる。CSS filter では上に乗せる区域や線まで着色されてしまう
基図地理院タイル(淡色地図) 区域の境界は道の途中にある。日本の道路形状が最も正確な基図でなければ、「あと 12m」という表示の説得力が成立しない
TypeScript (strict) 区域・駅・判定結果の型を ETL とアプリで共有する。traced / described / estimated の取り違えはユーザーへの嘘に直結するので、コンパイル時に落とす
UIReact 19 判定状態 → 画面の対応を宣言的に書く。地図移動のたびに変わる状態を手続き的な DOM 操作で扱うと破綻する
データETL 出力をリポジトリに固定 調査中に公式データの URL が 404・ホスト移転・アクセス拒否を返した。外部取得をビルドから切り離し、区のサイトの都合でこちらが壊れないようにした

一番難しかったのは速度ではなく「わからない」の設計でした。 判定に likely(推定)と unknown を持たせたことで、 データの精度差を利用者に嘘をつかずに渡せるようになりました。 技術選定はすべて、この 2 つを成立させるためのものです。

サーバを持たない

判定は純粋関数で、必要なデータは全東京分でも数 MB です。サーバに置く理由がありません。 端末内で完結させたことで、位置座標が一切外部に出ないことと、 電波が弱い路上でも判定が続くことが、運用の努力ではなく 構造として保証されます。このアプリが使われるのは、まさにその状況です。

ETL の出力はリポジトリにコミットする

調査中、複数の公式 URL が 404・ホスト移転・アクセス拒否を返しました。 ビルド時に外部から取得する設計にすると、区のサイトの都合でこちらのサイトが壊れます。 そこで取得結果を JSON にしてリポジトリに置き、CI はそれをビルドするだけにしています。

05 — 判定のしくみ

精度の高いデータが、常に勝つ

judge(地点) →

  STEP 0  施行前の区域の中か        → 「◯月◯日から対象になります」を添える
  STEP 1  Tier A の内側か           → inside
  STEP 2  Tier A の境界から 30m 以内 → near
  STEP 3  Tier B のリングの内側か    → likely(推定)
          ※ Tier A が覆う駅では Tier B を使わない
  STEP 4  それ以外                  → outside / 都外なら unknown

STEP 3 の除外規則が最も重要です。 Tier A のポリゴンで精密に「外」と判定した地点を、Tier B の粗い円で「内かも」と塗り潰してはいけません。

5 つの判定

ここは撤去対象です 作図された区域の内側。警告のうえ即日撤去されることがあります。
あと◯mで撤去対象 区域のすぐ外側(30m 以内)。境界には目印がないため、少し進むだけで対象になります。
撤去される可能性が高い 指定駅の推定リングの内側。「推定」と明示し、事実として断定しません。
撤去対象ではありません 区域外。ただし「歩行者の通行を妨げる場所や私有地には停められません」を必ず併記します。
ここは判定できません データが無い場所。「停めてよい」とは決して言いません。

判定できないことは失敗ではありません。判定できないのに答えることが失敗です。

このアプリは「撤去されるか」を答えます。データの無い場所で「大丈夫」と言えば、 ユーザーは実際に損害を受けます。だから unknown という状態を明示的に持っています。

判定エンジンはテストで守る

判定は UI に一切依存しない純粋関数として実装し、境界ケースを 18 件のテストで固定しています。 「ポリゴンの穴の中を内側と誤判定しないか」「Tier A の覆域で Tier B に落ちないか」 「すべての判定に出典が付いているか」——ここが壊れるとアプリの存在意義が消えるためです。

「動きました」を証拠なしに言わない

実装とは別に、実ブラウザをスマホ幅(390×844)で自動操作する検証スクリプトを用意しました。 判定の表示、区域が実際に地図へ描画されているか、横スクロールの有無、 連続パン・空入力・1000 文字入力への耐性、位置情報を拒否した場合、オフライン時、コンソールエラー—— 20 項目を毎回実際に操作して確認し、スクリーンショットを残しています。

この検証は実際に役立ちました。判定は正しいのに区域が地図に一度も描画されていない不具合を見つけています (MapLibre の isStyleLoaded() がレイヤ追加より先に true になり、 データが黙って捨てられていた)。判定ロジックのテストだけでは絶対に見つかりませんでした。

06 — 使い方

開いて、合わせるだけ

  1. アプリを開く

    ring-5oq.pages.dev をスマートフォンのブラウザで開きます。インストールは不要です。位置情報を許可すると現在地へ移動します。

  2. 停めたい場所に十字を合わせる

    タップではなく、地図を動かして中央の十字を合わせます。動かしている間ずっと判定が更新されるので、境界の位置が指先で分かります。

  3. カードを引き上げる

    下のカードを上へドラッグすると、近くの駐輪場・保管所・判定の根拠が出てきます。

  4. 位置情報を許可しなくても使える

    拒否した場合は東京駅から始まります。検索(🔍)から駅名を入れれば、どこでも調べられます。検索は端末の中だけで動き、通信しません。

  5. 電波がなくても動く

    一度開いたあとは、機内モードでも判定・駐輪場・保管所が動きます。地図タイルは取得済みの範囲だけ表示されます。

駅名で検索している画面
端末内検索。放置禁止区域がある駅には印が付く。
区域変更のお知らせ一覧
区域変更のお知らせ。施行日と区の告知へのリンク。
オープンデータ公開リクエストの文面生成画面
区への公開リクエスト文面を生成できる。

07 — 使ったオープンデータ

すべて公開データで動いています

データ提供元用途
駅別放置自転車の状況(令和7年度)東京都都民安全総合対策本部放置禁止区域の指定有無・放置台数・収容能力
国土数値情報 N02 鉄道データ(2024)国土交通省駅の座標・路線名・事業者名
自転車駐車場文京区駐輪場の位置・収容台数
区営/民間自転車駐輪場品川区駐輪場の位置・料金
自転車等駐輪場一覧目黒区駐輪場の位置・料金・利用時間
区営自転車駐車場設置箇所中野区駐輪場の位置・料金・利用時間
区営二輪車駐車場一覧中央区二輪車駐車場の位置・料金
保管所一覧大田区撤去駅と保管所の対応・開所時間
区営自転車保管場所設置箇所中野区撤去区域と保管所の対応・開所時間
地理院タイル(淡色地図)国土地理院地図の基図

このほか、品川区「駅前放置自転車撤去情報」や目黒区・港区「自転車シェアリングポート」も取得しましたが、 現在の実装では読み込んでいないため、アプリの「使っているデータ」には載せていません。

ライセンスは各提供元の規約(東京都オープンデータカタログ由来は CC BY 4.0 相当、 国土数値情報は利用約款、地理院タイルは出典明記で利用可)に従っています。 アプリ内の「データについて」画面と docs/DATA.md でも確認できます。

そして、データを返す

Ring が生成した区域データ(GeoJSON)は CC BY 4.0 で公開しています。 さらにアプリの中に 「区に、区域データの公開をお願いする」機能を入れました。 区を選ぶと、現在の公開形式・求める形式・理由・想定される公益を書いた依頼文面が生成され、コピーできます。 送信はしません。送るのは人の行為として残しています。

区域データが公開されれば、Ring は推定ではなく正確な境界で答えられるようになります。 それがこのプロジェクトのゴールです。

08 — できないこと

正直に書いておきます

区域の「形」は分かりません

現在の判定はすべて推定リングによるものです。実際の境界は多角形で、円ではありません。アプリは判定のたびに「推定」と表示します。

駐輪場データは全区分ではありません

オープンデータを公開している区が限られているため、159 件(6 区)にとどまります。0 件のときは「持っていない」と正直に表示します。

保管所データは 2 区分だけです

大田区と中野区のみ。ほかの区は区の公式ページへ誘導します。空振りで終わらせないためです。

区域変更は人力で追っています

オープンデータが無いため、区の告知を人が確認して記録しています。抜けがある可能性があります。

Ring が示すのは参考情報です。
最終的な判断は、必ず現地の標識で行ってください。