2

I am using the

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

to get the bound of all countries features. All works good, until I run into Fiji or Russia, which cross the anti-meridian.

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

Latitude feedbacks are perfect, let's ignore them for this question. The bounding box longitudinal width, however, is far too large however, going wild from W:-180 to E:+180.

It makes perfect sense from a computer or GIS point of view, but as an human I then completely miss the REAL Western most and Eastern most boundaries.

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

As of now, I don't see any way to get the real West (~177⁰) and East (~ -179⁰) values for these islands.

Is there a know way to get these island's REAL bounding box values via d3js ?

I currently plan to by-pass this issue by providing myself some approximative WSEN values, based on the former D3.geo : Spherical arcs rather than straight lines for paralles?. It's a bit ugly yet it will work.


EDIT: Interestingly, the area is computed right :

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

This let me think that D3js have an internal way to manage right the features crossing the anti-meridian without always doing a globe wide drama.

Community
  • 1
  • 1
Hugolpz
  • 17,296
  • 26
  • 100
  • 187

2 Answers2

4

You should use d3.geo.bounds for this, as you need bounding box in spherical coordinates.

(Using d3.geo.path with the identity function as a projection doesn’t work because d3.geo.path can only compute a bounding box in Cartesian coordinates.)

See Jason Davies’ Geographic Bounding Boxes page for details.

Hugolpz
  • 17,296
  • 26
  • 100
  • 187
mbostock
  • 51,423
  • 13
  • 175
  • 129
1

I hand-correct Fiji, Russia, and New Zealand's West-East values. Something like:

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())
            ]
        }
    }
}
Hugolpz
  • 17,296
  • 26
  • 100
  • 187