JavaScript
GoogleMapsAPI

日本一マクドナルドから遠い場所

きっかけ

日本マクドナルド様のサイトの店舗検索の地図をみてたら、やたらたくさんの店舗が一度に表示できる。
これって全店舗一度に読み込んでるのかな、とChromeのデベロッパーツールで覗いてみると、全店舗分のJSONが見えた。
全店舗2887件。
ちょっと拝借して長年の疑問を晴らしてみようと思った。『はたして、日本で一番マクドナルドから遠い場所はどこなのか?』

注) 離島は除きます。離島を含めると南鳥島がぶっちぎりです。

Fusion Tablesでプロットしてみる

Fusion Tablesに緯度経度をインポートすることでマップに位置をプロットできるのでやってみた。
Fusion Tablesの導入その他に関しては他に説明を譲ります。

とりあえずデベロッパーツールからJSONを丸ごとコピペして編集の末にCSVファイルをでっちあげた。
Fusion Tablesで扱えるように、先頭行にはカラム名を付けておく。
name,address,lat,lng の並びでCSVを用意した。

Fusion Tablesにインポートすると自動で"Map of lat" の名前でマップが生成されている。
なんてらくちんなんだ!

FusionTable_plot.png

ヒートマップを見てみる

左側に[Heatmap]なるメニューがある。クリックするだけでヒートマップが表示される。

FusionTable_heatmap.png

なんか西日本が表示されてない。
画面の上の方を見ると、1000地点までしか表示できないらしい。残念。

FusionTable_heatmap_zoom.png

ポイントの半径を大きくしていってマップが埋まっていないところを調べていけばマクドナルド最遠の地がわかるかと目論んだけど、そもそもこれでは厳密に調べられそうもない。
作戦変更。

Google Maps JavaScript APIでプロットしてみる

GoogleマップのAPIをJavaScriptから利用して全地点をプロット、そこを中心とした円を描く。
円の径を大きくしてゆき、最後に塗り残された場所がマクドナルド最遠の地という算段だ。

Googleマップ上にAPIで描画する必要性

Googleマップ上へのAPIでの図形描画では、メルカトル図法のひずみが考慮される。
この球面幾何学的に正確な描画は今回のミッションには必須要件となっている。
(すみません球面幾何学とかほんとはわかってません。かっこよさげに適当なこと言いました)

紙の地図に単純に同じ大きさの円を描いたとすれば、沖縄と北海道では驚くほどの誤差が出る。
下に掲載した画像でも、沖縄と北海道の円の大きさの違いははっきり分かる。

用意したもの

HTMLファイルとJavaScriptファイルを用意すれば、サーバに上げることなく実行できる。
用意したものは次の通り:

  • Chromeのデベロッパーツールで拝借した店舗位置情報のJSONファイル(丸のままUTF-8でテキストとして保存したもの)
  • APIを操作するJavaScriptファイル
  • それを開くHTMLファイル
  • 中心点をプロットするための画像ファイル
  • APIキー

APIキーの取得はGoogle Developers Consoleから行う。
長くなるので説明は割愛するが、ポイントは以下の通り:

  • Google Maps JavaScript API を利用する
  • APIキーの制限はなにも掛けない (ローカルPC上で利用できるようにするため)
  • プロジェクト名、APIキー名は何でもよい(動作には関係ない)
  • 無料。個人でこれくらいの利用なら課金されることはない

ローカルPC上で実行できるようにするためにAPIキーに制限は掛けない。
入手されるとどこのだれでもこのキーを利用できてしまうので、流出させないように注意は必要。


こんなHTMLとJavaScript、プロット用PNG画像をローカルに用意した。
HTMLの<YOUR_API_KEY>の部分にAPIキーを充てる。
HTMLを開いて[ファイルを選択]でJSONを与えると地図への描画が行われる。
描画円の半径の変更はmaps.jsのRADIUSを毎回書き換えて行なう。

maps.html
<!DOCTYPE html>
<html lang="ja">
  <head>
    <style>
      html {height: 100%;}
      body {height: 100%;margin: 0;}
      #maps{height: 100%;}
    </style>
  </head>
  <body>
    <script src="maps.js"></script>
    <form>
      <input type="file" onchange="load(this.files);"/>
    </form>

    <div id="maps"></div>
    <script src="https://maps.googleapis.com/maps/api/js?key=<YOUR_API_KEY>&callback=initMap" async></script>
    <script>
      var map;
      function initMap() {
        var mapPosition = {lat: 35.693132, lng: 139.6909533}
        var mapArea = document.getElementById('maps');
        var mapOptions = {
          center: mapPosition,
          zoom: 6,
        };
        map = new google.maps.Map(mapArea, mapOptions);
      }
    </script>
  </body>
</html>
maps.js
var RADIUS=100;

function load(files) {
    var file=files[0];
    var reader = new FileReader();
    reader.readAsText(file);
    reader.addEventListener( 'load', function() {
            onLoad(reader.result);
        })
}

function onLoad(text) {
    processJSON( JSON.parse(text) );
}

function processJSON(j) {
    var result="";
    var startRow = 0;
    var len=j.length;

    for(var rowS=startRow;rowS<len;rowS++) {
        var latS=j[rowS].latitude;
        var lngS=j[rowS].longitude;
        var name=j[rowS].name;

        plot(latS,lngS,name);
    }
}

function plot(latS,lngS,name) {
    var markerOptions = {
        map: map,
        position: {lat: latS, lng: lngS},
        title: name,
        icon: {
                url: 'dot.png', //アイコンのURL
                scaledSize: new google.maps.Size(6, 6)  //サイズ
            }   
    };
    var marker = new google.maps.Marker(markerOptions);

    var circle = new google.maps.Circle({
        strokeColor: '#FF0000',
        strokeOpacity: 0.8,
        strokeWeight: 1,
        fillColor: '#FF0000',
        fillOpacity: 0.35,
        map: map,
        center: {lat: latS, lng: lngS},
        radius: RADIUS
    });
}

画像ファイル :dot.png dot.png

とりあえずプロット

McDnalds20180427_dot.png
2887店舗くらいならどうってことはなく描画してくれる。

東名阪あたりはこんな感じ:
McDnalds20180427_tmh.png

半径20km

McDnalds20180427_20km.png
まだまだ点群という感じ。
円を描くと表示開始までは割と時間がかかる。

半径50km

McDnalds20180427_50km.png
だいぶ埋まってきた。


南方はこんな感じ:
McDnalds20180427_50km_south.png


九州、四国、本州はこんな感じ:
McDnalds20180427_50km_middle.png
九州全土は埋まっている。
四国は室戸岬東岸が残っている。四国で一番のマクドナルド過疎地帯ということになる。
本州では、能登半島先端と南会津町・会津大川郵便局周辺、岩手県大船渡市の東岸、岩手県久慈市の南方一帯、竜飛岬の突端の計5か所が残る。


北海道はこんな感じ:
McDnalds20180427_50km_north.png
余裕です。
決戦地は北海道ということになりそうです。

半径90km

McDnalds20180427_90km.png
日本国民に残された地はないのかとか錯覚しそうな画像となっている。
もはや離島しか残されていないように見えるが、望みをかけて北海道を確認してみる。

McDnalds20180427_90km_hokkaido.png
襟裳岬は沈んでしまったが、北海道最西端・せたな町と東の果て・知床岬突端部に残された土地が見える。
人類は死に絶えてはいなかった。

どちらが残るか、最後の確認を行う。

半径93km

知床岬
McDnalds20180427_93km_shiretoko.png

拡大
McDnalds20180427_93km_shiretoko_zoom.png
しずんでいる


せたな町
McDnalds20180427_93km_setana.png

拡大
McDnalds20180427_93km_setana_zoom.png
のこっている

McDnalds20180427_93km_setana_morezoom.png
たしかにのこっている

結論

日本で一番マクドナルドから遠い場所は、北海道最西端・せたな町 尾花岬。
(2018年4月27日時点・離島除く)
obanamisaki.png

最寄り店舗は"37号伊達店"。距離約93km。

付記

孤立・近接店舗

せっかく座標がそろっているので全店舗間の距離も調べた。

  • 日本で一番孤立した(=隣のマクドナルドとの距離が最も遠い)マクドナルドは、日本最北店でもある"40号稚内店"。最寄り店は"イオン名寄店"。店舗間隔 131.56km
    ※サハリンにマクドナルドがないことは確認済

  • 二番目に孤立しているのは"宮古島店"と"石垣サンエー店"。店舗間隔 121.98km.。

  • 本州で一番孤立したマクドナルドは"106宮古店"。最寄り店は"4号線盛岡南店"。店舗間隔 67.29km。

  • 本州で二番目に孤立したマクドナルドは"むつ中央店"。最寄り店は"青森東バイパス店"。店舗間隔 60.86km。

    • ただし実際に移動するには陸奥湾を大きく迂回した経路を取る必要があるため、実質の距離は80kmを超える。
  • 日本で最も近接したマクドナルドは"高松ゆめタウン店"と"高松ゆめタウンフードコート店"。店舗間隔 60.4m(ただし水平距離)。


Googleスプレッドシートにデータを置いてGASで算出しましたが、GASはこのデータ量の規模の計算では音を上げますので、このような用途にはお勧めしません。
計算時間の割り当てが計算途中で切れてしまうので手管を弄する必要があります。

備考

本稿の内容は本当は2018年2月くらいに試したんですが、改めて記事にしてみました。
そのときどこかでこの内容を目にされた方もいるかもしれません。

追記

  • なお、日本一マクドナルドから遠い場所であるところの尾花岬には実際に行きました。
    本当の先端へは険し気な道を行く必要もあり、到達をあきらめました。

  • 日本一孤立したマクドナルド"40号稚内店"、本州一、二に孤立した"106宮古店"、"むつ中央店"も行きました。いずれも普通のマクドナルドだったことを報告しておきます。

  • より正確に検証している方がおられます。ぜひこちらをご参照ください:
    日本一マクドナルドから遠い場所 をより精確に求めてみた