Article
Rで標識の距離から現在地を推定する小さな関数
主出典は、Rで都市名をジオコーディングし、標識に書かれた複数都市への距離から現在地候補を探す関数を紹介しています。Nominatim、geosphere、mapsの制約を押さえると、遊びのコードから地理データ処理の勘所が見えてきます。
Share
こはるの読みどころ
楽しい題材ですが、API利用制限、球面距離の近似、古い都市データという現実的な確認点があります。実用コードに近づけるなら、その3点を先に見ておきたいですね。

Rの小さな関数が標識の距離から現在地を推定
R-bloggersで紹介された「Little useless-useful R functions – Honest geographical location signposts」は、観光地などにある「東京まで何km、パリまで何km」といった標識が、実際の現在地と合っているかをRで試す記事です。主出典では、都市名を座標に変換し、各都市までの距離が標識の数値に近くなる地点を探索する関数 sign_location_finder() が示されています。
この関数は、都市名のジオコーディングにOpenStreetMapのNominatimを使い、距離計算に geosphere::distHaversine() を使います。記事中の例では、Koper、Celje、Maribor、Kranjからの距離を入力し、スロベニアの首都Ljubljanaを見つける想定になっています。発想はかなり遊び寄りですが、複数の距離制約から位置を推定する流れは、地理データ処理の小さな教材として読めますね。
koharu tone="tip" portrait="characters/deformed/confident-smile.webp" 遊びの関数でも、使っている部品を見ると学べることが多いね。API、距離式、データセットの古さを分けて見てみよう!
Nominatimの検索APIで都市名を緯度経度に変換
主出典の geocode_city() は、https://nominatim.openstreetmap.org/search に q、format=json、limit=1 を付けて問い合わせています。Nominatimの公式Search APIは、テキストや住所から場所を検索でき、q=<query> の自由形式検索と構造化検索をサポートしています。limit は返す候補数を制限するパラメータです。詳細はNominatim 5.3.2 ManualのSearch APIで確認できます。
ここで実務上かなり大事なのが、APIの使い方です。OpenStreetMap FoundationのNominatim Usage Policyは、公開APIについて「最大1リクエスト/秒」を上限とし、アプリケーションを識別できるHTTP RefererまたはUser-Agentを求めています。主出典のコードは user_agent("PointingSignFinder/1.0 (R script)") を設定し、Sys.sleep(1.1) で待機しているため、この制約を意識した形になっています。
ただし、同ポリシーは大量・反復的なジオコーディングや系統的なクエリを強く制限しています。記事のような小さな手元実験なら読みやすい例ですが、サービスやバッチ処理に転用するなら、キャッシュ、プロキシ、自前Nominatim、商用プロバイダーなどを検討する領域になります。
geosphereのHaversine距離は分かりやすいが近似を含む
位置候補の評価では、候補地点から各都市までの距離を geosphere::distHaversine() で計算し、標識の距離との差分を見ています。geosphereのリファレンスマニュアルによると、distHaversine() は2点間の大円距離をHaversine法で求める関数で、入力は経度・緯度の組、既定の地球半径は6378137m、戻り値の既定単位はメートルです。詳しくはgeosphere reference manualの distHaversine を参照できます。
ここで押さえたいのは、Haversine法が地球を球として扱い、楕円体の効果を無視する近似だという点です。同じマニュアルでは、より高い精度が必要な場合に distVincentyEllipsoid() を使えることも示されています。標識の距離が丸められている、あるいは「道路距離」ではなく「直線距離」なのかも不明な場合、数十km単位の許容誤差を置く主出典の設計は、遊びの探索としては自然な割り切りです。
グリッド探索は理解しやすい代わりに精度と計算量を調整する
主出典の探索は、最初に対象都市群の周辺へ探索範囲を広げ、粗いグリッドで候補地点を評価し、その最良点の周辺を細かいグリッドで再評価する流れです。各候補点について、都市ごとの距離差を計算し、その最大差分が小さい点を良い候補として扱っています。
この方法は最適化アルゴリズムとして洗練されているというより、Rコードとして読みやすく、途中結果も見やすいのが利点です。一方で、coarse_res、fine_res、tolerance の値で探索点数と結果の粗さが変わります。緯度経度の度数をそのままグリッドにしているため、緯度によって経度方向の実距離が変わることも、厳密な位置推定では気にしたいところです。
sfパッケージのCRAN説明では、sf は空間ベクトルデータを標準化して扱うための機能を提供し、測地座標の幾何演算では既定で s2 を使うと説明されています。Rで地理処理を広げるなら、単発の距離関数だけでなく、sfのリファレンスで座標参照系や幾何演算の扱いも見ておくと、次に進みやすいです。
maps::world.citiesは近隣都市表示の補助データとして読む
主出典の関数は推定地点を出したあと、maps::world.cities から人口条件に合う近隣都市を探して表示します。CRANのworld.citiesドキュメントでは、このデータは主に人口約4万人超の都市、任意人口の首都、多数の小規模都市を含むと説明されています。
同じドキュメントには、人口が2006年1月時点の概数であること、国名や都市名が古い可能性があること、元データに最近の更新がないことも書かれています。つまり、world.cities は「推定地点の近くに大きめの都市があるか」を見るには便利ですが、最新の人口や行政名を保証するものではありません。ここを知っておくと、結果の読み方がかなり落ち着きます。
手元実験として動かすならAPIと入力距離を先に切り分ける
この関数を試すときは、まず都市名がNominatimで期待通りの場所に解決されているかを見たいです。limit=1 はコードを簡単にしますが、同名の都市や曖昧な地名では、意図しない候補が先頭に来る可能性があります。国名を含める、結果の display_name をログで見る、といった小さな確認が効きます。
次に、標識の距離が直線距離なのか道路距離なのかを分けて考えたいですね。主出典の例は「air distance」を使った入力でLjubljanaに寄せています。道路案内の距離を混ぜると、Haversineの直線距離とは前提が変わるため、候補地点がずれる可能性があります。
最後に、公開Nominatim APIの制約を守ることです。数件の都市名を試すだけなら小さな実験ですが、候補地点の探索自体より、都市名のジオコーディング呼び出しの扱いが運用上の注意点になります。楽しいネタほど、外部サービスへの礼儀をセットで覚えると実用に近づきます。
出典
- Title: Little useless-useful R functions – Honest geographical location signposts
- URL: https://www.r-bloggers.com/2026/08/little-useless-useful-r-functions-honest-geographical-location-signposts/
Share
Related Articles
カテゴリやタグが近い記事を続けて読めるように並べています。




