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