ちかくの駐車場
現在地か地名から、近くの駐車場を地図と距離順のリストで同時に出す。並べる軸は有料・無料・料金不明の3値で、金額での比較はしない。OpenStreetMapに金額が書かれているのは実測で0〜0.5%しかないため
制作メモ
- AIに任せた
- OpenStreetMapの駐車場タグの埋まり率を先に実測して設計を決めたこと。秋田駅の400m圏81件のうちfeeタグは12件(15%)でしかも全部yes、charge(金額)は0件、opening_hoursも0件(800m圏まで広げると225件)。東京駅はfeeが74%。この差から「金額での比較はやらない」「料金は3値だけ」「営業時間はあるときだけ出す」を設計原則にした/検索の待ち時間の原因を実測で切り分けたこと。半径400mで4.8秒、3200mで1.9秒と、広いほうが速いことがあった。所要時間は半径ではなくOverpassの順番待ちで決まっていたので、400→800→1600→3200と段階的に広げる作りは往復回数を増やすだけで何も買っていなかった。800→3200の2段に減らした/「2系統フェイルオーバー」が実は1台だったことをDNSで見つけたこと。overpass-api.deは162.55.144.139と65.109.112.52の2台に振り分けられ、lz4.overpass-api.deは後者だけを指す。素のホスト名を1系統目にすると同じマシンを2回叩きうる。z.(前者)とlz4.(後者)を名指しして別マシンにした。同じ日に両方が別々のタイミングで落ちるのを観測している/Overpassのスロット超過が429で返ること(406も同じ扱い)を、同じクエリ4本同時で再現して特定したこと。それまでは他の失敗と同じに扱って1.5秒後に叩き直しており、詰まっているサーバーに追い打ちをかけていた/公開するにあたって利用方針に反することを、一次情報を読んで止めたこと。Overpassは「アプリの利用は全利用者の合計で数える」「常設なら1日100クエリ・10MB未満」「アプリを識別できるUser-Agentを付ける」「キャッシュとレート制限をする」と定めていて、ブラウザから直接叩く形では満たせない。Nominatimも識別可能なUser-Agentとキャッシュを要求する。Cloudflare Functionsの中継(functions/api/day-025/)に寄せ、座標を約110m四方に丸めてエッジで7日キャッシュする形にした/MapLibreをCDNから読むのをやめて同梱したこと。このリポジトリのCSPはscript-src 'self'で、外部スクリプトを読むアプリが1つも無い。CDNを許可するとCSPを緩める初めてのDayになるため、BSD-3-Clauseのビルドをvendor/へ置いた/地図の描画とロジックを分けて、DOMに触らない純関数(クエリ組み立て・タグ正規化・距離計算・半径拡大・表示上限)だけをNodeからテストできるようにしたこと
- 自分でやった
- 「近くの駐車場を出すアプリ」という題材の発案/検索が遅いという指摘と、速くする案のうち「タイムアウト短縮」「段階拡大の廃止」を採り、「2系統へ同時投げ」は不採用にする判断(ボランティア運営のサーバーへの負荷が2倍になるため)/公開にあたって、実行時にAPIを叩き続ける形ではなく中継API方式を選ぶ判断/デモ動画を音ありのプロモーション型にする指定
- 失敗と修正
- 表示を近い順50件で打ち切るようにしたのに、見出しは「50件」のままだった。上限に当たった数字なのか実数なのか区別できず、このアプリが掲げている「分からないものは分からないと出す」に反していた → 切る前の該当件数を別に数え、上限に当たったときだけ「204件中50件」と出すようにした
Overpassの取得上限を200件にしていたが、Overpassの件数上限は距離順ではなく内部のID順で切る。秋田駅の800m圏は実測225件あり、200で切ると落ちた25件に最寄りが混ざりうる状態だった → 上限を500件に上げ、距離順に並べてから表示側で50件に切るようにした。中継側で画面が使うタグだけに削っているので、返る量はむしろ減った
Node(undici)からOverpassを叩く通し確認が、再現性なく406やAbortErrorで失敗した。同じクエリをcurlと実ブラウザに投げると200が2.7秒で返る。これを見て一度「タイムアウト8秒は短すぎたか」と判断しかけた → 実ブラウザ(Playwright)で通すようにした。あわせて、遅さを測る前にOverpassの/api/statusで空きスロットを確認する手順にした。自分のテスト実行で2枠を使い切ると、その後の計測が全部遅く見える
デモ動画の尺がOverpassの混み具合で2〜15秒動いた → 候補を選んだ直後から結果が出る直前まで(両側ともスケルトン表示でつなぎ目が見えない区間)を自動で切るようにした
合成しただけのデモ音声が-29.9 LUFSで、SNSのタイムラインでは実質無音だった → loudnorm で-16 LUFS / トゥルーピーク-1.5 dBTPに合わせた























