D3js:如何获得穿过反子午线的真实边界框?

D3js : How to get the real bounding box of features crossing the anti-meridian?

我正在使用

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:+180。

从计算机或 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 获取这些岛的真实边界框值?

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


编辑: 有趣的是,面积计算正确:

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

这让我认为 D3js 有一种内部方法可以正确管理跨越反子午线的特征,而不必总是在全球范围内大放异彩。

我手动更正了斐济、俄罗斯和新西兰的东西方价值观。类似于:

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())
            ]
        }
    }
}

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

(使用 d3.geo.path 和身份函数作为投影不起作用,因为 d3.geo.path 只能计算笛卡尔坐标中的边界框。)

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