5

我有一些代码可以在 D3 中缩放和翻译地图,但性能非常糟糕。缩放和平移时,刷新大约需要 3 秒。我认为地图会更好看,包括所有县的线边界,但在 6MB+ 时,我怀疑这可能是瓶颈的来源。我应该有另一种方法来处理转换还是优化地图数据的方法?D3真的不适合这种细节水平吗?对 D3 来说非常新。 在此处输入图像描述

我在这里使用形状文件,使用 QGIS 从 DBF 转换为 Geojson: https ://www.census.gov/cgi-bin/geo/shapefiles2010/main

<!doctype html>
<html>

<head>
   <title>d3 map</title>
   <script src="http://d3js.org/d3.v3.min.js">
   </script>
</head>

<body>
   <script>
            var width = 800;
            var height = 600;

            var projection = d3.geo.mercator();
            var path = d3.geo.path().projection (projection);

            var canvas = d3.select ("body")
               .append ("svg")
               .attr ("width", width)
               .attr ("height", height)

            var zoomVar = d3.behavior.zoom()
               .translate(projection.translate())
               .scale(projection.scale())
               .scaleExtent([height, 60 * height])
               .on("zoom", onPostZoom);

            var hotbox = canvas.append("g").call(zoomVar);

            hotbox.append("rect")
               .attr("class", "background")
               .attr("width", width)
               .attr("fill", "white")
               .attr("height", height);     

            d3.json ("cali.geojson", function (data) 
            {
               hotbox.append("g")
                  .attr("id", "geometry")
                  .selectAll("path")
                  .data(data.features)
                     .enter()
                        .append("path")
                        .attr("d", path)
                        .attr("fill", "steelblue")
                        .on("click", onClick);

            })




function onClick (d) 
{
   var centroid = path.centroid(d), translate = projection.translate();

   projection.translate(
   [translate[0] - centroid[0] + width / 2,
    translate[1] - centroid[1] + height / 2 ]);

   zoomVar.translate(projection.translate());

   hotbox.selectAll("path").transition()
      .duration(700)
      .attr("d", path);

}     


function onPostZoom() 
{
  projection.translate(d3.event.translate).scale(d3.event.scale);
  hotbox.selectAll("path").attr("d", path);
}

</script>
</body>
</html>
4

2 回答 2

10

正如 Lars 所说,您绝对应该将数据简化为适当的分辨率。根据您想要放大的距离选择最大分辨率。我建议topojson -s简化,因为您还将获得较小的TopoJSON 格式的好处。

如果您只是平移和缩放,另一件大事是避免重投影。重投影是一种相对昂贵的三角运算,在 SVG 中序列化非常大的路径字符串也是如此。您可以通过简单地在路径元素或包含 G 元素上设置transform 属性来避免平移和缩放(平移和缩放) 。请参阅以下示例:

您还应该考虑使用将投影烘焙到 TopoJSON 文件中的投影 TopoJSON替代示例)。这使得客户端更快:它永远不必投影!

于 2013-07-26T19:46:40.807 回答
4

您遇到的问题并不是因为 D3,而是因为浏览器。主要瓶颈是渲染所有视觉元素,而不是计算它们的位置等。

避免这种情况的唯一方法是减少数据。一种开始的方法是简化 QGIS 中的边界,例如使用dpsimplify插件。

于 2013-07-26T18:35:06.790 回答