Я пытаюсь вернуть гео-координаты [x, y] на карте гео-плитки. Если вы посмотрите в консольном журнале на следующем jsfiddle, вы увидите, что они ошибаются. Я использую функцию projection.invert(), которая, как я полагаю, работает назад от пикселей, чтобы вернуться к геоколям... что я делаю неправильно?
Это бит кода, который пытается захватить координаты:
function mousemoved() {
console.log(formatLocation(projection.invert(d3.mouse(this)), d3.zoomTransform(this).k));
}
function formatLocation(p, k) {
var format = d3.format("." + Math.floor(Math.log(k) / 2 - 2) + "f");
return (p[1] < 0 ? format(-p[1]) + "°S" : format(p[1]) + "°N") + " "
+ (p[0] < 0 ? format(-p[0]) + "°W" : format(p[0]) + "°E");
}
Примеры D3-плитки (и ваша скрипка), о которых я знаю (в том числе большинство примеров в документации d3-плитки), обычно используют масштаб проекции 1/tau (и значения перевода не переводятся), которые будут рисовать землю внутри пространство одного пикселя.
var projection = d3.geoMercator()
.scale(1 / tau)
.translate([0, 0]);
В то время как проекция преобразует 3-мерные пары широты/долготы в декартовы координаты, d3-zoom делает все масштабирование и перевод, чтобы заполнить размеры карты. Этот масштаб следует учитывать при обращении координат мыши к длине/латам.
Поэтому, чтобы получить пары широты/долготы точки на svg, нам нужно отступить. Сначала нам нужно получить координату мыши, если мы хотим инвертировать масштаб, а затем мы можем инвертировать проекцию:
var transform = d3.zoomTransform(svg.node()); // get the current zoom
var xy = transform.invert(d3.mouse(this));
var longlat = projection.invert(xy);
(См. Также, этот ответ на transform.invert())
Здесь обновленная скрипка.