世界の測量

Sibling of "Relevant, Timely, and Accurate, " but much lighter and shorter ※自らの所属する組織の見解を示すものでない

ベクトルタイル・いちさと(小学校区)Pt. 6・アンクリップトTopoJSON

アンプリップトTopoJSON対応をした。
f:id:hfu:20140109054452p:plain
http://handygeospatial.github.io/mapsites/2014/01/06/unclipped_topojson.html
コードはまだあまり整理されておらず、データのリファレンスカウント(もどき)がグローバル変数になっており、タイルをアンロードしたときの処理を考慮していない。TileLayer.Vector.Unclipped.js を参照するなどして、後ほどアップデートする必要がある。整理されていないコードなので、HTMLに埋め込んでいる。(リファレンスカウントもDOMに埋め込んだほうがいいかもしれない?)

<!doctype html>
<html>
<head>
  <!-- thx https://gist.github.com/NelsonMinar/5851197 -->
  <meta charset='UTF-8'>
  <meta name="viewport" 
   content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <meta name="apple-mobile-web-app-capable" content="yes"/>
  <meta name="apple-mobile-web-app-status-bar-style" 
   content="black-translucent" />
  <link rel="apple-touch-icon" 
   href="https://si0.twimg.com/profile_images/666603054/r.png"/>
  <title>ベクトルタイル・いちさと(小学校区)Unclipped TopoJSON</title>
  <link rel='stylesheet' href='http://cdn.leafletjs.com/leaflet-0.7/leaflet.css'>
  <script src='http://cdn.leafletjs.com/leaflet-0.7/leaflet.js'></script>
  <script src="http://handygeospatial.github.io/mapsites/2014/01/01/leaflet-hash.js"></script>
  <script src="http://d3js.org/d3.v3.min.js"></script>
  <script src="http://d3js.org/topojson.v1.min.js"></script>
  <script>
//<!--
/* Experimental vector tile layer for Leaflet
 * Uses D3 to render TopoJSON. Derived from a GeoJSON thing that was
 * Originally by Ziggy Jonsson: http://bl.ocks.org/ZJONSSON/5602552
 * Reworked by Nelson Minar: http://bl.ocks.org/NelsonMinar/5624141
 *
 * Todo:
 *   Make this work even if <svg> isn't in the DOM yet
 *   Make this work for tile types that aren't FeatureCollection
 *   Match D3 idioms for .classed(), .style(), etc
 *   Work on allowing feature popups, etc.
 */
// with a minor change by hfu 20140107 (for(key in tjData.objects) etc.)

FIDS = [];

L.TileLayer.d3_topoJSON =  L.TileLayer.extend({
  onAdd: function(map) {
    L.TileLayer.prototype.onAdd.call(this,map);
    this._path = d3.geo.path().projection(function(d) {
      var point = map.latLngToLayerPoint(new L.LatLng(d[1],d[0]));
      return [point.x,point.y];
    });
    this.on("tileunload",function(d) {
      // TODO: update FIDS
      if (d.tile.xhr) d.tile.xhr.abort();
        if (d.tile.nodes) d.tile.nodes.remove();
        d.tile.nodes = null;
        d.tile.xhr = null;
      });
  },
  _loadTile: function(tile,tilePoint) {
    var self = this;
    this._adjustTilePoint(tilePoint);
    if (!tile.nodes && !tile.xhr) {
      tile.xhr = d3.json(this.getTileUrl(tilePoint),function(error, tjData) {
        if (error) {
          console.log(error);
        } else {
          for(var key in tjData.objects) {
            var geoJson = topojson.feature(tjData, tjData.objects[key]);
            tile.xhr = null;
            tile.nodes = d3.select(map._container).select("svg").append("g");
            tile.nodes.selectAll("path")
              .data(geoJson.features.filter(function(d) {
                if(FIDS.indexOf(d.properties.id) == -1) {
                  FIDS = FIDS.concat(d.properties.id);
                  return true;
                } else {
                  return false;
                }
              })).enter()
            .append("path")
              .attr("d", self._path)
              .attr("class", self.options.class)
              .attr("style", self.options.style)
              .append("title").text(function(d) {
                var s = '';
                for(key in d.properties) {
                  s += key + ': ' + d.properties[key] + '\n';
                }
                return s;});
          }
        }
      });
    }
  }
});
//-->
  </script>
  <style>
  html, body, #mapdiv {margin: 0; padding: 0; width: 100%; height: 100%;}
  path {stroke-linejoin: round; stroke-linecap: round; fill: none;}
  path.es {stroke: #00f; fill: #00f; strokeOpacity: 0.3; fill-opacity: 0.2;}
  </style>
</head>
<body>
  <div id='mapdiv'/>
  <script>
map = new L.Map('mapdiv', {zoom: 13, center: [35.6822, 139.7386]});
hash = new L.Hash(map);

// this is important. see https://gist.github.com/NelsonMinar/5851197
new L.geoJson({"type": "LineString","coordinates":[[0,0],[0,0]]}).addTo(map);

map.addLayer(new L.TileLayer(
  'http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png',
  {attribution: '地理院タイル', minZoom: 13, maxZoom: 13}));

map.addLayer(new L.TileLayer.d3_topoJSON(
  'http://www.handygeospatial.info/2014/01/06/' + 
    'topojson_unclipped/{z}/{x}/{y}.topojson',
  {class: 'es',
   attribution: '国土数値情報(小学校区データ) 国土交通省', 
   minZoom: 13, maxZoom: 13,
  }));
  </script>
</body>
</html>