地域メッシュで遊んでみる


メッシュは何も考える必要がない縦幅と横幅だけの世界なので、まあ楽。
多分あってると思うが確認は適当。
Mesh_3

メッシュ用のクラス作って確認

var map = L.map('map').setView([36, 140], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
  attribution: '地図データ: &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>'
}).addTo(map);

var meshUtil = new JpnMesh();
meshUtil.setLatLon(36, 140);
var res = meshUtil.latlonResults[2];
var array = meshUtil.createTiles(res, 3);

for (var i = 0; i < array.length; i++) {
  if (array[i].meshNo != 3)
    continue;

  var rect = L.rectangle(array[i].shp, { color: "#000", fillColor: "#80FF80", weight: 2 });
  rect.bindPopup(array[i].code);
  rect.addTo(map);

  console.log(rect.toGeoJSON());
}

メッシュ用Util

function JpnMesh() {
  this._meshSize = null,
  this._meshSplit = null;
  this.latlonResults = null,
  this._init();
};
JpnMesh.prototype = {
  _init: function () {
    //this._meshSplit = { 1: 1.0 };
    this._meshSplit = {};
    this._meshSplit[2] = 8.0;
    this._meshSplit[3] = 10.0;
    this._meshSplit[4] = 2.0;
    this._meshSplit[5] = 2.0;
    this._meshSplit[6] = 2.0;

    this._meshSize = { 1: { w: 1, h: 2 / 3 } };

    for (var key in this._meshSplit) {
      var preMeshKey = key - 1;
      this._meshSize[key] = {
        w: this._meshSize[preMeshKey].w / this._meshSplit[key],
        h: this._meshSize[preMeshKey].h / this._meshSplit[key]
      };
    }//end loop
  },
  setLatLon: function (lat, lon) {
    for (var key in this._meshSize) {
      this._setLatLon(lat, lon, key);
    }//end loop
  },
  _setLatLon: function (lat, lon, mesh) {

    var preMesh = mesh - 1;

    //1次
    if (mesh == 1) {
      var a = Math.round(Math.floor(lat * 15.0 / 10.0));
      var o = Math.round(Math.floor(lon - 100.0));
      var mesh1 = { code: String(a) + String(o), lat: a / 15.0 * 10.0, lon: o + 100.0, meshNo: mesh };
      this.latlonResults = {};
      this.latlonResults[mesh] = mesh1;
      return;
    }//end if

    var preMeshRes = this.latlonResults[preMesh];

    var a = Math.floor((lat - preMeshRes.lat) / this._meshSize[mesh].h);
    var o = Math.floor((lon - preMeshRes.lon) / this._meshSize[mesh].w);
    var code = this._getCode(mesh, preMeshRes.code, a, o);

    var tmpRes =
        {
          code: code,
          lat: preMeshRes.lat + (a * this._meshSize[mesh].h),
          lon: preMeshRes.lon + (o * this._meshSize[mesh].w),
          meshNo: mesh
        };
    this.latlonResults[mesh] = tmpRes;
  },//end func
  // mesh = 1次/2次..メッシュno
  // c = 横方向のタイル数 r = 縦方向のタイル数
  _getCode: function (mesh, preCode, r, c) {
    //2・3次
    if (mesh < 4) {
      code = preCode + '-' + String(r) + String(c);
    } else {
      // 1/nメッシュ

      code = r < 1 ? String(c + 1) : String(c + 1 + 2);
      code = preCode + '-' + code;
    }//end if
    return code;
  },

  createTiles: function (latlonResult, maxVal) {

    var result = new Array();
    var a = latlonResult.lat;
    var o = latlonResult.lon;
    var code = latlonResult.code;
    var mesh = parseInt(latlonResult.meshNo);
    var size = this._meshSize[mesh];
    result.push({ shp: [[a, o], [a + size.h, o + size.w]], code: code, meshNo: mesh });

    if (maxVal == mesh)
      return result;

    this._createTiles(a, o, code, mesh + 1, maxVal, result);
    return result;
  },
  _createTiles: function (lat, lon, preCode, mesh, maxVal, array) {

    var split = this._meshSplit[mesh];
    var size = this._meshSize[mesh];

    for (var r = 0; r < split; r++) {
      for (var c = 0; c < split; c++) {
        var a = lat + (size.h * r);
        var o = lon + (size.w * c);
        var code = this._getCode(mesh, preCode, r, c);

        array.push({ shp: [[a, o], [a + size.h, o + size.w]], code: code, meshNo : mesh });

        //再帰呼び出し
        if (mesh != maxVal)
          this._createTiles(a, o, code, mesh + 1, maxVal, array);
      }//end loop
    }//end loop

  }//end func
};
カテゴリー: 開発 タグ: パーマリンク