d3js缩放,转换和翻译

cli*_*oid 9 d3.js

我创建了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();
});
Run Code Online (Sandbox Code Playgroud)

(如果你对代码感兴趣,那就全部在github上.地图的代码在scripts/controllers/main.js中,与上面显示的相同.)

san*_*d17 15

我遇到了同样的问题.但是当你有一个边界框时很容易做到,这可以从GeoJSON(如meetamit所说)或创建GeoJson时确定.和想要的SVG的宽度.

我将从变量lattop, lonleft, lonright, widthheightgeojson的边界框以及图像的尺寸开始.我还没有从latutude的差异中计算出一个好的高度.因此估计高度足以适应图像.其余的应该从代码中清楚:

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);
Run Code Online (Sandbox Code Playgroud)

注意,如果你越过日期线(180度),你将不得不考虑溢出.


mee*_*mit 7

鉴于这种:

xy = d3.geo.mercator().scale(someScale).translate([0, 0]);
Run Code Online (Sandbox Code Playgroud)

someScale像素宽度的的整个世界投影时使用墨卡托投影.所以,如果你的json数据有整个世界的轮廓 - 从lat/lng -180,90到latLng 180,-90 - 如果someScale是1024,那么将绘制世界,使其完全适合1024x1024像素广场.这就是你在这个谷歌地图视图中看到的内容(好吧......有点......不太......继续......).

但这还不够.当世界以1024px绘制时,没有任何平移,lat/lng 0,0(即世界的"中间")将位于投影地图的0,0像素(即左上角).在这些条件下,整个北半球和西半球都有负x或y值,因此落在绘制区域之外.此外,在这些条件下,世界的右下角(即lat/lng -90,180)将位于1024x1024平方的正中间(即像素512,512).

因此,为了将世界置于此处描述的方格中心,您需要translate将地图宽度的一半放在X和Y方向上.也就是说你需要

xy = d3.geo.mercator().scale(1024).translate([512, 512]);
Run Code Online (Sandbox Code Playgroud)

这将为您提供我链接到的Google地图视图.

如果您的json数据仅包含世界的一部分(例如,nyc或NY状态),则使用此xy投影绘制它将使相对于整个1024x1024世界范围区域的正确地理位置呈现轮廓.所以看起来很小,有很多空白.

挑战在于如何缩放和翻译投影,使得所讨论的区域填满1024x1024平方.而且...到目前为止我还没有回答这个问题,但我希望这个解释能指出你正确的方向来计算这个数学.当我有更多时间时,我也会尝试继续回答.:/