在Google地图上覆盖d3path?

我正在尝试使用d3.geo和GeoJson将地图叠加到Google地图上。 我设法强制d3使用Google Map的投影来绘制path,这非常简单。 以下是我到目前为止:

http://www.caudillweb.com/temp/d3_choropleth.html

这适用于我放大和缩小:

地图缩小地图放大

但是当我平移时,SVG叠加也会移动,并且由于它的大小是固定的,所以形状会被截断:

地图平移下来

有没有人得到这样的工作? 任何想法,我可以从这里去? 上面的例子是一个单独的自包含的HTML文件,如果有人想玩它。

在这个例子中,svg的宽度和高度被设置为8000 x 8000,这看起来是正确的,直到缩放级别9-10。 顶部和左侧设置为-4000 x -4000以居中。 最后,投影被移动/偏移,以便它在svg的中心:

放大和中心svg:

.SvgOverlay svg { position: absolute; top: -4000px; left: -4000px; width: 8000px; height: 8000px; } 

抵消投影:

 return [pixelCoordinates.x + 4000, pixelCoordinates.y + 4000]; 

一种select是将初始地图大小设置为非常大,例如1000 x 1000像素或更大。 这将强制SVG覆盖在可视区域内渲染(这似乎是Firefox的限制)。 我意识到这可能会与您的网站的devise,所以你可能要考虑用div来包裹地图来隐藏溢出。

 #map-wrap { width: 500px; height: 500px; overflow: hidden; } #map { width: 1000px; /* just big enough to show the whole thing at zoom #6 */ height: 1000px; } 

地图渲染完成后,您可以将地图重新​​调整为所需的500 x 500大小,然后重新放置地图。 这可以在bounds_changed事件中完成:

 google.maps.event.addListener(map, 'bounds_changed', function() { $map.css({ height: '500px', width: '500px' }); // back to desired dims google.maps.event.trigger(map, 'resize'); // trigger a 'refresh' map.setCenter(new google.maps.LatLng(-18.2, 35.1)); // re-center map google.maps.event.clearListeners(map, 'bounds_changed'); // don't do this again }); 

这是一个工作示例 (在Firefox和Chrome中testing)。

一些注意事项:

  1. 你想让人们放大的距离越远,你需要渲染最初的“临时”地图。 例如,如果要允许缩放级别7,则可能需要使初始地图2000 x 2000进行补偿。 渲染一个大的地图显然有性能问题。 正如分散指出的,限制缩放级别可能是明智的。
  2. 由于最后一刻resize,地图重新调整后会出现闪烁。 您可能需要考虑使用jQuery来隐藏/显示地图,或者在地图上放置一个白色覆盖图,直到地图完成重新调整。

我能够通过使svg更大,添加一些填充,并提供一个像上面这样的负向顶部和左侧位置来解决这个缩放级别的问题:

  .SvgOverlay, .SvgOverlay svg { position: absolute; top: -250px; left: -250px; padding: 500px; } var svg = layer.append("svg") .attr("width", 1000) .attr("height", 1000) 

如果你想让你的用户进一步放大,你将不得不增加所有这些数字。 例如,将它们增加10倍,似乎可以解决所有缩放级别的问题。 但是,您可能想要限制用户的缩放能力,因为在进一步放大时,svg叠加层的用处会减小。

这是一个小提琴展示的想法。 http://jsfiddle.net/VHWqq/7/

编辑:正如草药指出,这种方法不适用于Firefox。