緑の丸は、この2週間に誰かが混雑度を投稿した路線です。
すでにご購入の方
前の端末で控えた KMD- から始まるIDを入れると、 この端末でもプレミアム版が使えます。! 時刻は目安です。時刻表とはつないでいません。
| 号車 | 乗車数 | 着いた時 | 発車する時 | 混雑度 |
|---|
自分が乗っている号車だけで大丈夫です。分かる号車を選んで送ってください。
この駅で乗り換えるとき、どの号車で降りると近いかを教えてください。 同じ内容が3件そろうと、乗り換えの案内に載ります。
いまは、下に挙げた機能をすべて無料でお使いいただけます。
予想の精度を上げるには、実際に乗っている方からの投稿がどうしても必要です。 まずは多くの方に使っていただき、投稿を集める時期と考えています。
有料版を始めるときは、この画面でご案内します。いま使えている機能が、 ある日いきなり使えなくなるようなことはしません。
いつでも解約できます
このIDを絶対に無くさないでください。 スクリーンショットを撮るか、紙に書き写してください。 機種を変えたときは、これを入れるだけで元に戻ります。 人に教えると、その人も使えてしまいます。
すでにご購入の方
前の端末で控えた KMD- から始まるIDを入れると、 この端末でも使えます(同時に2台まで)。買い直しにはなりません。お支払いは Stripe の画面で行います。カード番号をコミデンが 受け取ることはありません。この画面に入力する欄もありません。
販売事業者:高山 直也 / 所在地・連絡先は 特定商取引法に基づく表記 をご覧ください。
プレミアム版は月額300円(税込)の自動更新です。次のことをご確認ください。
「同意して進む」を押すと、Stripe のお支払いページへ移ります。
支払いが終わると、この画面に戻ります。反映まで数十秒かかることがあります。
プレミアム版の機能がすべて使えるようになりました。
ここで保存すると、次にアプリを開いた人全員に反映されます。 アップロードし直す必要はありません。
太字にしたいところをなぞってからこのボタンを押すと、
その前後に ** が付きます(例:**予想**)。
手で打ってもかまいません。使える印はこれだけで、
タグを書いても、そのまま文字として出ます。
IDを変えると、前に「閉じる」を押した人にももう一度出ます。 文章だけ直したいときは、IDはそのままにしてください。
ここで保存すると、次にそのページを開いた人全員に反映されます。 ファイルをアップロードし直す必要はありません。
# 見出し大きい見出し## 小見出し小さい見出し- 箇条書き続けて書くと1つのまとまりに| 項目 | 内容表の1行。左が見出しの列! 注意書き黄色い囲み**太字**太字(空行)段落の区切りタグは書けません。書いても、そのまま文字として出ます (細工を防ぐため、わざとそうしてあります)。
利用者に控えてもらうのは、この1つだけです。
英数12文字。まちがえやすい I・L・O・U を外した32文字から選ぶので、
約60ビットあります。総当たりで当てられる桁数ではありません。
端末の中で crypto.getRandomValues が作ります。
平文を持っているのは、利用者本人と決済会社だけです。 こちらの表には SHA-256 しか入りません。表が丸ごと漏れても、 そこから使えるIDは復元できません。
| 控えてもらう | 買った直後に、全画面で1度だけ大きく出します。 「コピーする」と「控えました」の2つのボタンだけで、閉じられません。 あとからでも、プレミアムの画面でいつでも見られます。 |
|---|---|
| 無限に配れない | 同時に使えるのは2台まで(Web版とiOS版を想定)。 3台目は断り、どれかを外してもらいます。外しては入れ、を繰り返して グループで回されないよう、30日に4台までの上限も置いています。 いちど外した自分の端末に戻るのは、この回数に数えません。 |
| 忘れても戻せる | 決済のときに、利用IDの平文を決済会社へ預けています。 メールアドレスやカード下4桁から決済を探せば、そこにIDがあります。 手順は次の「利用IDを忘れた人への対応」に書きました。 |
| 個人情報を持たない | 氏名・メール・IPアドレス・User-Agent、 どれも保存しません。端末の種別も「iPhone」程度の粗さだけです。 |
sub_xxxxx(Stripeのサブスク番号)を自分の表に持つと、
管理画面に貼るだけで顧客名・メール・カード情報が1クリックで出ます。
個人情報保護法でいう容易照合性があり、その時点でこの表は
個人データになります。漏えい報告義務の対象にもなります。
そこで、参照を一方通行にしてあります。
更新や解約の連絡は、決済会社が利用IDを載せて送ってくるので、 それで自分の行を引けます。持つ必要がありません。
| Stripe | client_reference_id と
subscription の metadata.sub_token。いま動いているのはこれです。 |
|---|---|
| PayPay | merchantPaymentId(加盟店が決める注文ID)。
Stripe 経由なら Checkout と同じ扱いになります。
※ 定期購入では使えません。「1か月だけ」の一回払いなら使えます。 |
| Apple | appAccountToken。UUIDの形しか受け取らないので、
利用IDから SHA-256("apple|" + ID) で一方向に導いたUUIDを使います
(subs.apple_ref に索引として持っています)。
Apple で買った人は、アプリの「購入を復元」で自動的に戻るので、
IDが要るのは「Webでも使いたいとき」だけです。 |
| sql/komiden-id.sql | 表(subs・sub_devices)と関数(sub_redeem・sub_release・sub_grant) |
|---|---|
| edge/redeem | アプリからの問い合わせ口。端末の登録もここで行います |
| edge/stripe-webhook | 支払いが済んだら SHA-256 にして書き込みます |
前の版の sub_status() は使いません。
IDを知っていれば誰でも「有効」と答えてしまう関数で、
それでは台数の制限が意味を持たないためです。
こちらから利用IDを検索することはできません。 サーバには SHA-256 しか無いためです。 決済会社側の記録から引きます。
sub_token があります。
これがその人の利用IDです。client_reference_id を見てください。PayPay の加盟店管理画面で、その決済の merchantPaymentId を見ます。
それがそのまま利用IDです。
Apple はこちらに顧客情報を開示しません。ただしその必要もありません。 同じ Apple ID でサインインしていれば、iOSアプリの「購入を復元」で 自動的に戻ります。復元したあと、アプリの画面に利用IDが出るので、 それをWeb版に入れてもらえば両方で使えます。
| 「3台目で使えない」 | 同時に2台までです。 前の端末のアプリで、プレミアムの画面 →「利用ID」の一覧から、 使っていない端末を「外す」で外してもらってください。 前の端末が手元に無いときは、こちらで外せます(下のSQL)。 |
|---|---|
| 「しばらくお待ちください と出る」 | 30日に4台までの上限です。 事情を聞いて妥当なら、こちらで記録を消せます(下のSQL)。 |
| 「IDが違うと言われる」 | 小文字やハイフン無しでも通ります。 まちがえやすい I・L・O・U は使っていないので、 1とI、0とO の取りちがえが多いです。そこを確認してください。 |
| 「払ったのに使えない」 | 決済会社からの連絡が届いていない可能性があります。
Stripe の「開発者 → Webhook」でエラーが出ていないか確認してください。
届いていれば、Supabase の subs に行があります
(検索は SHA-256 が要るので、件数と日時で当たりを付けます)。 |
利用IDの平文が分かっているとき、そのハッシュは Supabase の SQL Editor でこう出せます。
ハイフンは外し、大文字にしてから渡してください(アプリもそう揃えています)。
この端末だけ、プレミアム版の機能を開けたり閉めたりします。 支払いは発生しません。この端末の中だけの切りかえで、ほかの人には影響しません。
★ 以前はプレミアム版の画面に置いていましたが、 そこは一般の方も開ける画面でした。決済をつなぐまでのあいだ、 誰でも押せば有料機能が使えてしまう状態だったので、ここへ移しました。
このIDを知っている人は、誰でも無料でプレミアム版が使えます。 そのため、配るファイル(index.html・config.js)には書いていません。 書いた瞬間に、アプリを開いた全員が無料で使えるようになるためです。 ここはこの端末の中にだけ控えておく場所です。
sql/komiden-master-id.sql の中に書いてあるIDを、ここに控えてください。 控えると、次からはこの画面に出ます。
まず時間帯ごとに「その駅から乗る人の数」と「その駅で降りる人の数」を出し、そのうえで出発駅と到着駅の組み合わせを作ります。遠い駅ほど選ばれにくい重力モデルを種にして、行の合計=乗る人、列の合計=降りる人にそろうまで繰り返し調整します(Furness法)。
これにより「北千住や秋葉原でどっと降りる」といった動きが、仮定ではなく計算から出てきます。降車も号車ごとに正確に分かるようになりました。
以前は種別ごとに「好まれやすさ」を手で決めていましたが、いまは停車駅から所要時間を計算し、本数から待ち時間を出して選ばれ方を決めます。目的地に停まらない種別に乗る人は、手前の停車駅までを乗車区間として扱います。
いちばん大きな変更点です。以前は「降車駅で便利な位置」を全員共通の1つの数字にしていましたが、いまは行き先ごとに、その駅の出口の位置を使います。出口の位置は、改札からの距離で重みづけした動線の平均位置として自動で求まります(北千住の上りなら66m付近=3号車あたり)。乗車時間が短い人は降り口をあまり気にしないので、効き具合は乗車時間に応じて弱まります。
乗車客を10回に分けて配り、そのつど混み具合を更新するので、混んだ号車ほど次の人が入りにくくなります。乗車率240%を上限とし、超えるぶんは次の電車へ回します。
計算部分は路線のデータから独立しています。新しい路線は次を用意すれば動きます。
環状線(山手線・大阪環状線など)は、駅の並びが端で折り返さずつながります。loop:true を立てると、駅番号の差を輪の長さで割った余りで数え、内回り・外回りは短いほうの向きに自動で振り分けます。1周ぶんだけ計算すると「起点の駅がいつも空で始まる」不自然さが出るので、3周ぶん流して2周目だけを採用し、混み具合が一巡して落ち着いた状態を見ています。山手線の外回りは朝7:30の上野→御徒町がいちばん混み、公表値と同じ水準になります。
直通運転は、複数の路線をつないだ一続きの運転系統として扱えるようにしてあります。駅の並びに他社線の駅を続けて書けば、OD も号車の選択もそのまま境界をまたいで計算されます。編成両数が変わる直通(10両と8両が混じるなど)も、種別ごとに両数を持たせて表せます。
投稿された6段階を代表乗車率(45/75/100/125/155/195%)に直し、同じ駅・方向・曜日区分の予測と比べます。投稿は分かる号車だけで成立します。
ズレは4つの層に分けて覚えます。上の層ほど多くの投稿で決まるので早く安定し、下の層は投稿が集まってから効きはじめます。
各層は件数 n に応じて n/(n+k) だけ効かせます(k は路線8・駅6・時間帯4・号車3)。投稿が少ないうちは自動的に上の層へ寄り、増えるほど細かい層が立ち上がります。平均は外れ値に強いHuber平均を使い、さらに「混んだ号車ほど投稿されやすい」偏りを打ち消すため、1件あたりの重みを 1 / max(0.35, 予測混雑率) にしています。
号車ぶんの件数がしきい値を超えたら、λ_g・λ_p・β をその駅の投稿に合う値に探索し直します。
実測に基づくのは、駅別の乗車人員(2025年度)、営業キロ、ホーム長と編成定員、号車の向き、女性専用車、種別ごとの停車駅、公表されている最混雑区間の水準です。表定速度と1駅あたりの停車時分は、路線ごとに公表されている所要時間から逆算しています(TXは快速45分・普通57分、山手線は1周約60分)。各駅の動線の座標・改札からの距離・通過能力は公式構内図からの目測で、アイソメ図から読む都合上おおむね±1両の誤差があります。山手線・東西線・千代田線・銀座線・埼京線は、各駅の乗車位置案内(何号車の何番ドアが階段・エスカレーター・エレベーターに近いか)を書き写したもので、ドア単位(±5m程度)の精度です。改札までの距離までは分からないため、そこは種類ごとの標準値を置いています。埼京線は大崎〜浮間舟渡の10駅ぶんだけで、残りは未確認です。方向シェア・時間帯分布・運転本数・種別の構成比も仮定値です。
路線ごとに scale(公表の乗車人員と、実際に電車に乗っている人数の差を埋める倍率。乗り換えだけの利用や定期外の流入を含みます)と allday(終日まんべんなく使われる度合い。山手線のように通勤の山が緩い路線で使います)の2つを、公表されている最混雑区間の値に合うように決めています。いま対応している9路線それぞれについて、公表されている最混雑区間の値にぴったり合うように決めてあります(つくばエクスプレス 北千住154%/山手線 外回り上野→御徒町135%/中央線快速 中野→新宿158%/京浜東北線 大井町→品川159%・川口→赤羽158%/総武線各停 錦糸町→両国151%/東西線 木場→門前仲町160%/千代田線 町屋→西日暮里150%/銀座線 赤坂見附→溜池山王153%/埼京線 板橋→池袋167%)。路線ごとに使ったのは、この1〜2点だけです。あてはめに使っていない値でも合います:山手線の内回りは、こちらから場所を指定していないのに、公表と同じ新大久保→新宿がいちばん混む区間になり(134%、公表136%)、総武線各停の代々木→千駄ケ谷も93.8%(公表93%)になります。これらのズレは投稿が集まるほど較正が吸収します。
この試作は、投稿の保存先を3つのうち使えるものへ自動で切り替えます。上から順に試し、最初に使えたものを採用します。
いまの保存先は「投稿で予測がどれだけ直ったか」のいちばん上に出ています。この画面(claude.ai のアーティファクト)は外部への通信が塞がれているため、ここでは 1 の Supabase は選ばれません。自分のサーバーや Vercel などにこの HTML を置いたときだけ有効になります。
プロジェクトを作り、SQL Editor で komiden-supabase.sql を実行します。作られるのは次の4つです。
RLS は「読むのは誰でも可・入れるのも誰でも可・書き換えと消しは誰も不可」にします。UPDATE と DELETE のポリシーを作らなければ、RLS が有効なかぎり全部拒否されます。
この HTML を読み込む前に、次の1行を置くだけです。ここに書く anon キーは公開前提のもので、RLS が実際の守りになります。
無料プランはデータベース500MB・帯域5GB/月・月間アクティブ5万人です。投稿1件はおよそ150バイトなので、1日1万件でも1日1.5MB、180日ぶんで270MB。読み取りは「路線ごとに直近90日を一括で1回」だけなので、起動1回あたり数十KBに収まります。
無料プランは7日間まったくアクセスが無いと止まります。SQL に週1回の軽い読み取りを入れてあるので、利用が無い時期でも止まりません。180日より古い投稿と90日より古い精度ログは毎晩消して、500MBに収まり続けるようにしています。
アカウントはありません。メールアドレスもパスワードも受け取りません。投稿は端末の中で作った匿名IDのまま行い、保存した条件もその端末に残ります。
お支払いが済むと、その人だけの利用ID(KMD- で始まる英数12文字)が1本出ます。機種変更や2台目は、このIDを入れてもらうことで引き継ぎます。こちらの表に入るのは、このIDを SHA-256 で潰した文字列だけで、元のIDには戻せません。誰が買ったかを、こちらから知る手立てはありません。IDを忘れた方への対応は、決済会社側の記録から引きます(手順は「利用IDを忘れた人への対応」)。
すでにご購入の方
前の端末で控えた KMD- から始まるIDを入れると、 この端末でも使えます(同時に2台まで)。買い直しにはなりません。