Eu sou novo no d3 - tentarei explicar como eu o entendo, mas não tenho certeza se entendi tudo direito.
O segredo é saber que alguns métodos irão operar no espaço cartográfico (latitude, longitude) e outros no espaço cartesiano (x, y na tela). O espaço cartográfico (nosso planeta) é (quase) esférico, o espaço cartesiano (tela) é plano - para mapear um sobre o outro, você precisa de um algoritmo, chamado de projeção . Esse espaço é muito curto para aprofundar o assunto fascinante das projeções e como elas distorcem as características geográficas para transformar esféricas em plano; alguns são projetados para conservar ângulos, outros conservam distâncias e assim por diante - sempre há um compromisso (Mike Bostock tem uma enorme coleção de exemplos ).
Em d3, o objeto de projeção possui uma propriedade / setter central, dada em unidades de mapa:
projection.center ([local])
Se o centro for especificado, define o centro da projeção no local especificado, uma matriz de dois elementos de longitude e latitude em graus e retorna a projeção. Se o centro não for especificado, retornará o centro atual com o padrão ⟨0 °, 0 °⟩.
Há também a tradução, dada em pixels - onde o centro da projeção fica em relação à tela:
projection.translate ([point])
Se point for especificado, define o deslocamento da conversão da projeção para a matriz de dois elementos especificada [x, y] e retorna a projeção. Se o ponto não for especificado, retornará o deslocamento atual da conversão, cujo padrão é [480, 250]. O deslocamento da translação determina as coordenadas do pixel do centro da projeção. O deslocamento de conversão padrão coloca ⟨0 °, 0 °⟩ no centro de uma área de 960 × 500.
Quando quero centralizar um recurso na tela, gosto de definir o centro de projeção no centro da caixa delimitadora de recursos - isso funciona para mim ao usar o mercator (WGS 84, usado no google maps) para o meu país (Brasil), nunca testado usando outras projeções e hemisférios. Pode ser necessário fazer ajustes para outras situações, mas se você seguir esses princípios básicos, ficará bem.
Por exemplo, dada uma projeção e caminho:
var projection = d3.geo.mercator()
.scale(1);
var path = d3.geo.path()
.projection(projection);
O bounds
método from path
retorna a caixa delimitadora em pixels . Use-o para encontrar a escala correta, comparando o tamanho em pixels com o tamanho nas unidades do mapa (0,95 fornece uma margem de 5% sobre o melhor ajuste para largura ou altura). Geometria básica aqui, calculando a largura / altura do retângulo, dada os cantos opostos na diagonal:
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);
Use o d3.geo.bounds
método para encontrar a caixa delimitadora nas unidades de mapa:
b = d3.geo.bounds(feature);
Defina o centro da projeção no centro da caixa delimitadora:
projection.center([(b[1][0]+b[0][0])/2, (b[1][1]+b[0][1])/2]);
Use o translate
método para mover o centro do mapa para o centro da tela:
projection.translate([width/2, height/2]);
Até agora você deve ter o recurso no centro do mapa ampliado com uma margem de 5%.