D3js: Как получить реальную ограничивающую рамку объектов, пересекающих анти-меридиан?

Я использую

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.

Это имеет смысл с точки зрения компьютера или ГИС, но, как человек, я полностью пропускаю РЕАЛЬНЫЕ западные и восточные границы.

// 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: Сферические дуги, а не прямые линии для параллов?, Это немного некрасиво, но это сработает.


РЕДАКТИРОВАТЬ: Интересно, площадь вычисляется правильно:

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

Это позволило мне подумать, что у D3js есть внутренний способ правильно управлять функциями, пересекающими анти-меридиан, не выполняя всю глобальную драму.

2 ответа

Решение

Вы должны использовать d3.geo.bounds для этого вам понадобится ограничительная рамка в сферических координатах.

(С помощью d3.geo.path с функцией тождественности в качестве проекции не работает, потому что d3.geo.path может вычислять ограничивающий прямоугольник только в декартовых координатах.)

Подробнее смотрите на странице " Географические рамки" Джейсона Дэвиса.

Я вручную исправляю ценности Фиджи, России и Новой Зеландии на Западе-Востоке. Что-то вроде:

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())
            ]
        }
    }
}
Другие вопросы по тегам