10

私はnycMapを作成しました。これは、angularJS(MVC)、yeoman(ビルド)、d3(マッピング)、geoJSON(地理データ)を使用するプロジェクトです。

すべてが非常にうまく機能しますが、適切なスケールと翻訳を取得するためにかなりの時間を費やす必要がありました。マップが最適な縮尺でどのスケールで表示され、どのx値とy値が変換に含まれるかを自動的に把握するにはどうすればよいでしょうか。

'use strict';

japanAndCo2App.controller('MainCtrl', function($scope) {

 function makeJapanAll(){
    var path, vis, xy;

    xy = d3.geo.mercator().scale(16000).translate([-5600,2200]);
    path = d3.geo.path().projection(xy);
    vis = d3.select("#japanAll").append("svg:svg").attr("width", 1024).attr("height", 700);
    d3.json("data/JPN_geo4.json", function(json) {
      return vis.append("svg:g")
          .attr("class", "tracts")
          .selectAll("path")
          .data(json.features).enter()
          .append("svg:path")
          .attr("d", path)
          .attr("fill",function(d,i){ return d.properties.color || "transparent"});
    });
  }
  makeJapanAll();
});

(コードに興味がある場合は、すべてgithubにあります。マップのコードはscripts / controllers / main.jsにあり、上記と同じです。)

4

3 に答える 3

15

私も同じ問題を抱えていました。しかし、GeoJSON から決定できる境界ボックスがある場合 (meetamit が言ったように)、または GeoJson の作成中に行うのは非常に簡単です。そして、必要な SVG の幅。

変数lattop, lonleft, lonright, widthheight、geojson のバウンディング ボックスと画像の寸法から始めます。緯度の差から適切な高さを計算することにまだ専念していません。そのため、高さは画像に収まるのに十分な大きさであると推定されます。残りはコードから明らかです。

var xym = d3.geo.mercator();

// Coordinates of Flanders
var lattop = 51.6;
var lonleft = 2.4;
var lonright = 7.7;
var width = 1500;
var height =1000;

// make the scale so that the difference of longitude is 
// exactly the width of the image
var scale = 360*width/(lonright-lonleft);
xym.scale(scale);

// translate the origin of the map to [0,0] as a start, 
// not to the now meaningless default of [480,250]
xym.translate([0,0]);

// check where your top left coordinate is projected
var trans = xym([lonleft,lattop]);
// translate your map in the negative direction of that result
xym.translate([-1*trans[0],-1*trans[1]]);


var path = d3.geo.path().projection(xym);

var svg = d3.select("body").append("svg").attr("width",width).attr("height",height);

日付変更線 (180 度) を超える場合は、オーバーフローを考慮する必要があることに注意してください。

于 2012-11-18T10:03:28.083 に答える
8

これを考えると:

xy = d3.geo.mercator().scale(someScale).translate([0, 0]);

someScaleメルカトル図法を使用して投影した場合の世界全体ピクセル幅です。したがって、json データに全世界のアウトライン (lat/lng -180,90 から latLng 180,-90 まで) があり、1024 の場合、世界は 1024x1024 ピクセル内に正確に収まるように描画されます。四角。それが、この Google マップのビューに表示されているものです(うーん... ある意味... かなりではありません... 読み進めてください...)。someScale

それでも十分ではありません。世界が 1024 ピクセルで描画され、変換が行われない場合、緯度/経度 0,0 (つまり、世界の「中央」) は、投影された地図 (つまり、左上) の 0,0 ピクセルに位置します。これらの条件下では、北半球全体と西半球全体で x または y の値が負になるため、描画された領域から外れます。また、これらの条件下では、世界の右下 (緯度/経度 -90, 180) は 1024x1024 の正方形のちょうど真ん中 (ピクセル 512,512) に位置します。

したがって、ここで説明した正方形の中心に世界を配置するにtranslateは、マップの X 方向と Y 方向の幅を半分にする必要があります。つまり、あなたが必要です

xy = d3.geo.mercator().scale(1024).translate([512, 512]);

これにより、リンク先の Google マップ ビューが正確に表示されます。

json データに世界の一部 (ニューヨーク州やニューヨーク州など) しか含まれていない場合、この xy 投影法で描画すると、1024x1024 の世界にまたがる地域全体に対して正しい地理的位置にアウトラインがレンダリングされます。そのため、空白が多く、かなり小さく表示されます。

課題は、問題の領域が 1024x1024 の正方形を埋めるように、投影をどのようにスケーリングおよび変換するかです。そして... これまでのところ、私はこの質問に答えていませんが、この説明が、この数学を理解するための正しい方向を示していることを願っています. また、時間ができたら、後で回答を続けようと思います。:/

于 2012-11-07T19:56:16.313 に答える
0

ここに、geojson から国の境界を取得し、地図をその国にスケーリングして変換する例があります。コードは少し見にくいです。ただし、将来これを簡単にするための取り組みがあります (これこの問題を参照してください)。

于 2012-11-07T19:12:19.733 に答える