【问题标题】:How can I scale my map to fit my svg size with d3 and geojson path data如何使用 d3 和 geojson 路径数据缩放我的地图以适合我的 svg 大小
【发布时间】:2019-05-03 14:51:31
【问题描述】:

我正在尝试创建一个 d3 SVG 来绘制纽约州的地图并对其进行缩放以适合我的 SVG 的大小,我遇到的问题是当我使用 .fitSize([height, width], mapObject) 时它只返回一个 @ 987654324@控制台报错。

我正在使用的topoJSON file of NYS

我可以在不缩放的情况下显示地图,但当然,它没有优化,需要缩放

我已经尝试过post 中所说的内容,但我还没有找到正确的解决方案

var map = d3.json('./ny.json')

Promise.all([map]).then(data => {
  var height = 800;
  var width  = 800;
  var mapData = data[0]

  // original geoJSON to that works without scaling 
  // var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
  //

  var geoData = topojson.feature(mapData, {
    type:"GeometryCollection",
    geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
  })

  var projection = d3.geoMercator()
                     .fitSize([width, height], geoData)

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

  d3.select('svg')
    .attr('height', height)
    .attr('width', width)
    .selectAll('.county')
      .data(geoData)
      .enter()
      .append('path')
        .classed('.county', true)
        .attr('d', path)

})

我很确定这是我的格式错误,但我不确定 .fitSize().fitExtent() 试图与哪些数据进行比较。

现在代码站点的方式我没有收到错误输出到控制台,但我也没有数据附加到 SVG

【问题讨论】:

    标签: html d3.js svg geojson topojson


    【解决方案1】:

    问题是 fitSize 采用 geojson object 而 selectAll.data() 采用 array,您在 geoData 中使用这两者之一。这留下了两个解决方案:

    解决方案 1:

    如果我们使用

    var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
    
    var projection = d3.geoMercator()
                     .fitSize([width, height], geoData)
    

    我们得到 NaN 错误,因为投影设置不正确,因为我们没有传递 geojson 对象,只是一个 geojson 对象数组。我们可以通过使用geoData 制作特征集合并将其传递给 fitSize 来解决这个问题:

    var geoData = topojson.feature(mapData, mapData.objects["cb_2015_new_york_county_20m"]).features
    
    var projection = d3.geoMercator()
         .fitSize([width, height], {type:"FeatureCollection", features: geoData})
    

    现在我们将 geojson 特征集合传递给 fitSize,我们都在进行投影,并且由于 geoData 仍然是一个数组,我们可以将其传递给 selectAll.data() 不变。

    Here's a block.

    解决方案 2:

    如果我们使用:

    var geoData = topojson.feature(mapData, {
      type:"GeometryCollection",
      geometries: mapData.objects["cb_2015_new_york_county_20m"].geometries,
    })
    

    我们得到一个 geojson 对象,projection.fitSize 有效,但 selectAll().data(geoData) 没有添加任何特征,因为它不是一个数组 - 输入选择是空的。我们可以替换selectAll().data(geoData.features) 来解决这个问题并为每个特征输入一个路径(或者我们可以使用.data([geoData]) 为所有路径输入一个特征)。

    Here's a block.

    两个块都以正确的比例绘制 - 地图超出了块的边界,因为我没有改变你的 800x800 尺寸

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-19
      • 1970-01-01
      • 2016-06-18
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多