D3js:如何获得跨越反子午线的真正边界框?

时间:2015-01-28 00:06:14

标签: d3.js bounding-box d3.geo

我正在使用

var bounds = d3.geo.path()
    .projection(function(d) { return d; })
    .bounds;

获取所有国家/地区功能的界限。一切都很好,直到我遇到穿过反子午线的斐济或俄罗斯。

Fiji.bb = [[-180,-18.294755298529864], [180.00000000000006,-16.037142847284727]];
// with [[West,South],[East,North]]

纬度反馈是完美的,让我们忽略它们来解决这个问题。然而,边界框的纵向宽度太大了,从W:-180到E:+80../ / p>

从计算机或GIS的角度来看,这是完全合理的,但作为一个人,我完全错过了 REAL 西部最东部和最东部的边界。

// current data back
Fiji.bb = [[-180,-18.294...],[180.00000000000006,-16.0371...]];
// wanted data back
Fiji.bb = [[177,-18.294...],[-179,-16.0371...]];

到目前为止,我还没有看到任何方法来获得这些岛屿的真正西方(~177⁰)和东方(〜-179⁰)值。

有没有办法通过d3js获取这些岛屿的真实边界框值?

我目前计划通过为自己提供一些基于前D3.geo : Spherical arcs rather than straight lines for paralles?的近似WSEN值来绕过这个问题。它有点难看但它会起作用。


修改 有趣的是,该区域的计算正确:

var area = d3.geo.path()
    .projection(function(d) { return d; })
    .area;
// area = 1.639711598252461;

这让我觉得D3js有一种内部方式来管理穿越反子午线的特征,而不是总是在全球范围内戏剧化。

2 个答案:

答案 0 :(得分:4)

您应该使用d3.geo.bounds,因为您需要球坐标中的边界框。

(使用带有标识功能的d3.geo.path作为投影不起作用,因为d3.geo.path只能计算笛卡尔坐标系中的边界框。)

有关详细信息,请参阅Jason Davies的Geographic Bounding Boxes页面。

答案 1 :(得分:1)

我亲自纠正了斐济,俄罗斯和新西兰的东西方价值观。类似的东西:

var bounds = d3.geo.path()
    .projection(function(d) { return d; })
    .bounds;
var bb = bounds(countries[i]);
var red_rect = function () {
    if (countries[i].id === "Fiji") {bb[0][0] = 177; bb[1][0] = -179;}
    if (countries[i].id === "Russia") { bb[0][0] = 19.5; bb[1][0] = -169; }
    if (countries[i].id === "New Zealand") { bb[0][0] = 165.5; bb[1][0] = -176;}
    if (true) {
        return t = {
            type: "Polygon",
            coordinates: [ 
                [ [bb[0][0] - 5, bb[0][1] - 5] ]
                .concat(parallel(bb[1][1] + 5, bb[0][0] - 5, bb[1][0] + 5))
                .concat(parallel(bb[0][1] - 5, bb[0][0] - 5, bb[1][0] + 5).reverse())
            ]
        }
    }
}