13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

地域メッシュコードから緯度経度を取得してMapboxにポリゴンを描画

Posted at

できたもの

地域メッシュコード、例えば53392425123を与えてやるとその地域をポリゴンで表示してくれます。今回は8分の1メッシュコードまでを対応しています。
スクリーンショット 2019-08-02 13.12.10.png

ソース

細かい計算もあるので少し長くなってますがこの様になっています。

<!DOCTYPE html>
<html>
<head>
    <meta charset='utf-8' />
    <title>sample</title>
    <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
    <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.2.0/mapbox-gl.js'></script>
    <link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.2.0/mapbox-gl.css' rel='stylesheet' />
    <style>
        body { margin:0; padding:0; }
        #map { position:absolute; top:0; bottom:0; width:100%; }
    </style>
</head>
<body>

<div id='map'></div>

<script>
mapboxgl.accessToken = 'Mapboxのアクセスキーをここに貼り付けてください';
var map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v11',
    center: [139.5664063, 35.51822917],
    zoom: 15
});

map.on('load', function () {
    var geojson = {
        'id': 'hogehoge',
        'type': 'fill',
        'source': {
            'type': 'geojson'
        },
        'layout': {},
        'paint': {
            'fill-color': '#088',
            'fill-opacity': 0.8
        }
    }

    // ここからメッシュコードの計算
    var mesh_code = "53392425123";

    let first_coordinate = first(mesh_code);
    let second_coordinate = second(mesh_code);
    let third_coordinate = third(mesh_code);
    let forth_coordinate = forth(mesh_code);
    let fifth_coordinate = fifth(mesh_code);
    let sixth_coordinate = sixth(mesh_code);
    lat = (first_coordinate[1] + second_coordinate[1] + third_coordinate[1] + forth_coordinate[1] + fifth_coordinate[1] + sixth_coordinate[1]) / 3600;
    lon = (first_coordinate[0] + second_coordinate[0] + third_coordinate[0] + forth_coordinate[0] + fifth_coordinate[0] + sixth_coordinate[0]) / 3600;

    var upper_lat = lat + 3.75/3600;
    var right_log = lon + 5.625/3600;

    geojson['source']['data']  = {
      'type': 'Feature',
      'geometry': {
        'type': 'Polygon',
        'coordinates': [[
          [lon,lat],
          [lon,upper_lat],
          [right_log,upper_lat],
          [right_log,lat],
        ]]
      }
    };

    map.addLayer(geojson);
});
</script>

<script>
// それぞれの計算を定義
function first(mesh_code) {
  var lat = mesh_code.slice(0, 2);
  var lon = mesh_code.slice(2, 4);
  return [(parseInt(lon) + 100) * 3600, lat / 1.5 * 3600] // 3600をかけて秒に直す
}

function second(mesh_code) {
  var lat = mesh_code.slice(4, 5);
  var lon = mesh_code.slice(5, 6);
  return [lon * 7.5 * 60, lat * 5 * 60] // 60をかけて秒に直す
}

function third(mesh_code) {
  var lat = mesh_code.slice(6, 7);
  var lon = mesh_code.slice(7, 8);
  return [lon * 45, lat * 30]
}

function forth(mesh_code) {
  let forth = mesh_code.slice(8, 9);
  let lat;
  let lon;
  if (is_south(forth)) {
    lat = 0
  } else {
    lat = 15
  }

  if (is_west(forth)) {
    lon = 0;
  } else {
    lon = 22.5;
  }

  return [lon, lat];
}

function fifth(mesh_code) {
  let fifth = mesh_code.slice(9, 10);
  let lat;
  let lon;
  if (is_south(fifth)) {
    lat = 0
  } else {
    lat = 7.5
  }

  if (is_west(fifth)) {
    lon = 0;
  } else {
    lon = 11.25;
  }

  return [lon, lat];
}

function sixth(mesh_code) {
  let sixth = mesh_code.slice(10, 11);
  let lat;
  let lon;
  if (is_south(sixth)) {
    lat = 0
  } else {
    lat = 3.75
  }

  if (is_west(sixth)) {
    lon = 0;
  } else {
    lon = 5.625;
  }

  return [lon, lat];
}

function is_south(code) {
  if (code == 1 || code == 2) {
    return true
  }
  return false
}

function is_west(code) {
  if (code == 1 || code == 3) {
    return true;
  }
  return false;
}
</script>
</body>
</html>

解説

計算方法はWikipediaを参照しています。ちなみにメッシュから割り出している緯度経度はメッシュの南西端(左下の端っこ)を指しています。

1次メッシュコード

4桁の数字で、上2桁が緯度(1.5倍して分以下を切り上げたもの)、下2桁が経度(下2桁)を表す。1次メッシュコードはメッシュの南西端の緯度経度を用いて次式で算出される:緯度をlat[度]、経度をlon[度]とすると、 {\displaystyle (lat\times 1.5\times 100)+(lon-100)} {\displaystyle (lat\times 1.5\times 100)+(lon-100)}。

つまり…
経度は先頭二桁に100を足す。
緯度は3~4桁目を1.5で割ってあげれば良い

function first(mesh_code) {
  var lat = mesh_code.slice(0, 2);
  var lon = mesh_code.slice(2, 4);
  return [(parseInt(lon) + 100) * 3600, lat / 1.5 * 3600] // 3600をかけて秒に直す
}

2次メッシュコード

第2次メッシュ(二次メッシュ、正式名称は第2次地域区画)は第1次メッシュを緯線方向及び経線方向に8等分してできる区域で、2万5千分の1地形図の1図葉の区画に対応する。緯度差は5分、経度差は7分30秒で、1辺の長さは約10kmである。
2次メッシュコード
2桁の数字で、上1桁が緯度方向、下1桁が経度方向を表す。これに1次メッシュコードを合せて5339-23のように表す。

つまり...
経度は7.5をかける
緯度は5をかける

function second(mesh_code) {
  var lat = mesh_code.slice(4, 5);
  var lon = mesh_code.slice(5, 6);
  return [lon * 7.5 * 60, lat * 5 * 60] // 60をかけて秒に直す
}

3次メッシュコード

第3次メッシュ(三次メッシュ、正式名称は基準地域メッシュないし第3次地域区画)は第2次メッシュを緯線方向及び経線方向に10等分してできる区域である。緯度差は30秒、経度差は45秒で、1辺の長さは約1kmである。
3次メッシュコード
2次メッシュコードと同様に2桁の数字で、上1桁が緯度方向、下1桁が経度方向を表す。これに1次・2次メッシュコードを合せて5339-23-43のように表す。

つまり…
経度は45をかける
緯度は30をかける

function third(mesh_code) {
  var lat = mesh_code.slice(6, 7);
  var lon = mesh_code.slice(7, 8);
  return [lon * 45, lat * 30]
}

2分の1地域メッシュ(4次と呼ばれていることもある)

2分の1地域メッシュ
基準地域メッシュより細かな地域区分として2分の1地域メッシュがある。2分の1地域メッシュは基準地域メッシュを縦横に2等分したものである。緯度差は15秒、経度差は22.5秒で、1辺の長さは約500mである。南西側のメッシュを1、南東を2、北西を3、北東を4として、5339-23-43-1のように表す。

ここから計算方法が変わります。3次メッシュで割り出したメッシュを4分割していきそれぞれ南西、南東、北西、北東の順に1,2,3,4と割り振っていきます。なのでメッシュコードはここから1~4の数値しか現れません。その数値に合わせて経度・緯度を足していきます。

function forth(mesh_code) {
  let forth = mesh_code.slice(8, 9);
  let lat;
  let lon;
  if (is_south(forth)) {
    lat = 0
  } else {
    lat = 15
  }

  if (is_west(forth)) {
    lon = 0;
  } else {
    lon = 22.5;
  }

  return [lon, lat];
}

2分の1では緯度が15秒、経度は22.5秒の決まりでそこから4分の1、8分の1まではそれぞれ値を半分にすればよいです。
4分の1、8分の1は上記コードの通りで数値を変えるだけなので特に解説は入れません。

緯度経度が割り出せたら最後はメッシュコード分の秒数を足します。今回は8分の1に対応した秒数を足しています。

var upper_lat = lat + 3.75/3600;
var right_log = lon + 5.625/3600;

あとはgeojsonに割り出した緯度経度を渡してあげて描画させてあげると画像のようなものが現れます。
このあたりはMapboxのドキュメントにあるとおりです。
メッシュコードについて知識がなかったのでまとめてみました。
間違っている部分ありましたらご指摘お願いします。

13
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?