d3的path.bounds如何工作?

时间:2016-10-23 09:17:14

标签: d3.js topojson datamaps

我有TopoJson格式的文件world.topo.json,我从https://datamaps.github.io/获取并在 d3 地理图表中使用它(使用merchant投影)。< / p>

效果很好,但当我调用path.bounds(<TopoJson File Content>.objects.world.feature)并获取这些值时,我发现很奇怪:

[
    [-25.272818452358365, -114.9648719971861],
    [917.2049776245796, 507.5180814546301]
]

那么,为什么botom / left corner指向-25和-114?它们不应该是0,0-917, -507吗?

更新:我有一个缩放行为对象绑定到我的d3图表,对我来说完全符合预期。所以,我为每次缩放/拖动写了console.log,如下所示:

const topojson = <response of an ajax request>;
const bounds = path.bounds(topojson.objects.world.feature);
console.log(translate, JSON.stringify(path.bounds(feature))); // XXX

因此,每次调用zoom / drag均被调用,这是我得到的输出类型:

[25, 120] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"

第一个数组是当前翻译,第二个数组是边界。

但是,当我拖动/平移或缩放时,这是输出:

[0.021599999999999998, 0.10368] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[24.88185889212827, 119.4329226822157] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[25, 120] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[25, 120] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-15, 119] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-27, 117] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-27.32184332502962, 117.03468139278337] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-125.83796642848066, 127.65064293410353] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-165.15379127139124, 131.88726199045166] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-173.98081187505056, 132.83844955550114] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-173.98081187505056, 132.83844955550114] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-173.4557969093005, 132.7818746669505] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-89.06290511198648, 123.68781305086063] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"
[-89.06290511198648, 123.68781305086063] "[[-25.272818452358365,-114.9648719971861],[917.2049776245796,507.5180814546301]]"

正如您所看到的,虽然第一个参数根据缩放和平移事件不断变化,但边界保持不变。

1 个答案:

答案 0 :(得分:1)

关于path.bounds(object) documentation涵盖了它:

  

返回指定GeoJSON对象的投影平面边界框(通常以像素为单位)。边界框由二维数组表示:[[x 0,y 0],[x 1,y 1]],其中x 0是最小x坐标,y 0是最小y坐标,x 1是最大x坐标,和y 1是最大的y坐标。

因此,-25和-114是最小xy值,并参考左上角角(在SVG坐标系中),而不是左下角。

请注意path.boundsgeoBounds不同,其中:{/ p>

  

返回指定GeoJSON要素的球形边界框。边界框由二维数组表示:[[left,bottom],[right,top]],其中left是最小经度,bottom是最小纬度,right是最大经度,top是最大纬度。

它是如何运作的?

path.bounds(object)将使用您的投影来绘制一个&#34;矩形&#34;在你的对象周围,将返回一个包含该矩形四角的数组,如上所述。让我们看看它在这些演示中是如何工作的(这段代码不是我的):

在第一个演示中,日本地图的比例为1000.检查控制台以查看path.bounds

&#13;
&#13;
var topoJsonUrl = "https://dl.dropboxusercontent.com/u/1662536/topojson/japan.topo.json";

var width = 500,
    height = 500,
    scale = 1;

d3.select("body").append("svg")
	.attr("width", width)
	.attr("height", height)
    .append("g").attr("id", "all-g");

var projection = d3.geo.mercator()
		.center([138, 38])
		.scale(1000)
		.translate([width / 2, height / 2]);
    
d3.json(topoJsonUrl, onLoadMap);

function onLoadMap (error, jpn) {
    var path = d3.geo.path()
        		.projection(projection);
	var features = topojson.object(jpn, jpn.objects.japan);
  
  var mapJapan = features;
  
 console.log(JSON.stringify(path.bounds(mapJapan)))
  

	d3.select("#all-g")
        .append("g").attr("id", "path-g").selectAll("path")
            .data(features.geometries)
            .enter()
            .append("path")
            .attr("fill", "#f0f0f0")
            .attr("id", function(d,i){ return "path" + i})
            .attr("stroke", "#999")
            .attr("stroke-width", 0.5/scale)
            .attr("d", path);

}
&#13;
path {
  stroke: black;
  }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://d3js.org/topojson.v0.min.js"></script>
&#13;
&#13;
&#13;

记录:

[[-12.878670523380151,73.71036362631844],[529.0014631418044,535.5463567314675]]

[[x0,y0],[x1,y1]]值。

现在使用相同的代码,但比例为500:

&#13;
&#13;
var topoJsonUrl = "https://dl.dropboxusercontent.com/u/1662536/topojson/japan.topo.json";

var width = 500,
    height = 500,
    scale = 1;

d3.select("body").append("svg")
	.attr("width", width)
	.attr("height", height)
    .append("g").attr("id", "all-g");

var projection = d3.geo.mercator()
		.center([138, 38])
		.scale(500)
		.translate([width / 2, height / 2]);
    
d3.json(topoJsonUrl, onLoadMap);

function onLoadMap (error, jpn) {
    var path = d3.geo.path()
        		.projection(projection);
	var features = topojson.object(jpn, jpn.objects.japan);
  
  var mapJapan = features;
  
 console.log(JSON.stringify(path.bounds(mapJapan)))
  

	d3.select("#all-g")
        .append("g").attr("id", "path-g").selectAll("path")
            .data(features.geometries)
            .enter()
            .append("path")
            .attr("fill", "#f0f0f0")
            .attr("id", function(d,i){ return "path" + i})
            .attr("stroke", "#999")
            .attr("stroke-width", 0.5/scale)
            .attr("d", path);

}
&#13;
path {
  stroke: black;
  }
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://d3js.org/topojson.v0.min.js"></script>
&#13;
&#13;
&#13;

记录不同的值:

[[118.56066473830992,161.85518181315928],[389.5007315709022,392.77317836573377]]