Я новичок в d3 - попробую объяснить, как я это понимаю, но не уверен, что все правильно понял.
Секрет в том, что некоторые методы работают с картографическим пространством (широта, долгота), а другие - с декартовым пространством (x, y на экране). Картографическое пространство (наша планета) (почти) сферическое, декартово пространство (экран) - плоское - чтобы наложить одно на другое, вам понадобится алгоритм, который называется проекцией . Это пространство слишком мало, чтобы углубляться в увлекательную тему проекций и то, как они искажают географические особенности, чтобы превратить сферическую в плоскость; одни предназначены для сохранения углов, другие - для сохранения расстояний и так далее - всегда есть компромисс (у Майка Бостока есть огромная коллекция примеров ).
В d3 объект проекции имеет свойство / сеттер center, заданное в единицах карты:
projection.center ([местоположение])
Если указан центр, устанавливает центр проекции в указанное место, двухэлементный массив долготы и широты в градусах и возвращает проекцию. Если центр не указан, возвращает текущий центр, который по умолчанию равен 0 °, 0 °⟩.
Также есть перевод в пикселях, где центр проекции стоит относительно холста:
projection.translate ([точка])
Если указана точка, устанавливает смещение перемещения проекции равным указанному двухэлементному массиву [x, y] и возвращает проекцию. Если точка не указана, возвращает текущее смещение перемещения, которое по умолчанию равно [480, 250]. Смещение перемещения определяет пиксельные координаты центра проекции. Смещение сдвига по умолчанию помещает ⟨0 °, 0 °⟩ в центр области 960 × 500.
Когда я хочу центрировать объект на холсте, мне нравится устанавливать центр проекции в центр ограничивающего прямоугольника объекта - это работает для меня при использовании меркатора. (WGS 84, используется в картах Google) для моей страны (Бразилия), никогда не тестировался с использованием других проекций и полушарий. Возможно, вам придется внести коррективы в другие ситуации, но если вы усвоите эти основные принципы, все будет в порядке.
Например, с учетом проекции и пути:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
bounds
Метод из path
возвращает ограничивающий прямоугольник в пикселях . Используйте его, чтобы найти правильный масштаб, сравнивая размер в пикселях с размером в единицах карты (0,95 дает вам запас 5% по сравнению с наилучшим подходом по ширине или высоте). Базовая геометрия здесь, вычисление ширины / высоты прямоугольника с учетом диагонально противоположных углов:
var b = path.bounds(feature),
s = 0.9 / Math.max(
(b[1][0] - b[0][0]) / width,
(b[1][1] - b[0][1]) / height
);
projection.scale(s);
Используйте этот d3.geo.bounds
метод, чтобы найти ограничивающую рамку в единицах карты:
b = d3.geo.bounds(feature);
Установите центр проекции в центр ограничивающей рамки:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
Используйте этот translate
метод, чтобы переместить центр карты в центр холста:
projection.translate([width/2, height/2]);
К настоящему времени у вас должен быть объект в центре карты, увеличенный с запасом 5%.