D3 未在 JSON 文件中渲染地图数据

D3 not rendering map data in JSON file

我正在使用 D3 JS 库来显示地图。正在加载 U.S。州地图工作正常,但如果我尝试加载各个州的县地图,它就无法正常工作。我在所有州使用的文件位于 https://raw.githubusercontent.com/d3/d3.github.com/master/us-10m.v1.json. The state map I am currently using is https://raw.githubusercontent.com/deldersveld/topojson/master/countries/us-states/MI-26-michigan-counties.json,尽管其他州具有相同的行为。

使用 Chrome 开发人员工具,我注意到状态(有效的状态)使用一个 "path" 元素渲染,整个地图在其下方有一个 "d" 元素:

<path d="M558.8236946374037,348.30360060633L559.3534721355569,348.2802219377176L567.3201262115587,347.9178525742255L571.2684679430778,347.7775805625511L572.0381446856777,347.7542018939387L577.0160540079474…

各县用多个 "path" 元素呈现一个 "g" 元素:

<g class="counties"><path d="M-86.2371554117112,44.517643343110294L-85.81834245759008,44.51265840274941L-85.82187674412275,44.16371257748768L-86.04276965241448,44.16620504766812L-86.38912973261591,44.178667398570326L-86.35201972402291,44.22851680217914L-86.26896399050521,44.344416665569646L-86.25305970110821,44.40049724462957L-86.24952541457554,44.48274876058412Z"></path><path d="M-84.13072063824123,42.42521462663013L-83.66596195919543,42.43144580208123L-83.55286479015007…

我用来渲染它们的D3代码是一样的,只是指向不同的数据源。这个指向(工作)状态代码:

d3.json("us-10m.v1.json", function (error, us) {
svg.append("g")
.attr("class", "counties")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter()
.append("path")
.attr("d", path).append("svg:title");

文件本身的格式似乎相同,但数据(当然)不同,所以我不知道为什么 svg 代码的生成方式存在巨大差异。我看到的两个区别是U.S。状态文件有状态文件缺少的 "bbox" 元素,密歇根文件在几何集合中有 "properties" 元素。

你的问题与此相反。美国 topojson 已经投影(到 960x600 像素区域)——topojson 中的基础坐标表示像素坐标。使用预投影地理特征的地图不使用 d3 地理投影。如果使用路径生成器绘制,则如下所示:

 var path = d3.geoPath(); // or
 var path = d3.geoPath().projection(null);

但是,密歇根数据包含 latitude/longitude 对。如果我们将您的密歇根 topojson 转换为 geojson(这样我们就有了人类可读的坐标),我们将得到如下值:[-87.86292721673836,45.35386708864823]。如果我们使用空投影并将它们视为像素值,则特征将位于可视 SVG 的左侧,因为 x 值为负。所以我们需要为我们的路径投影:

var path = d3.geoPath().projection(someProjection);

我不确定你想要什么投影 - 预先投影的美国数据使用阿尔伯斯投影,所以如果我们想复制这个 and 比例和密歇根中心,我们可以使用:

var projection = d3.geoAlbers()
   .fitSize([width,height],geojsonObject);   // width/height of SVG/canvas
var path = d3.geoPath().projection(projection);

Albers 是为美国量身定做的,如果在世界其他地方使用 fitSize 或 fitExtent,结果可能与预期不符,必须设置投影旋转以考虑不同的位置。

还有其他方法可用于 center/scale 地图,但这在很多 questions/answers 中都有介绍。但是,要显示地理数据,您需要将其从球坐标投影到平面坐标,任何 d3 geoProjection 都可以做到这一点。