【问题标题】:How to plot GeoJson data in d3.js如何在 d3.js 中绘制 GeoJson 数据
【发布时间】:2020-07-22 13:10:29
【问题描述】:

我正在尝试使用 d3.js 和 vue js 向我的 web 应用程序显示平面图。数据来自 .json 文件,采用 geojson 格式。我从thisgeojson 网站生成了一些测试数据。我在想我可以使用 d3.js 路径函数将每个不同的对象绘制到 svg 元素。这是做这件事的正确方法吗?我查看了this 教程,以使用 geojson 数据制作美国地图。我认为如果您输入不同的数据,这将是正确的方法。然而,我的程序向 webapp 吐出随机矩形。我认为这可能是因为我正在使用的投影,但我不确定。我以前没有像这样使用过 d3.js,所以它对我来说是全新的。我在下面包含了我的代码。非常感谢任何帮助,我愿意使用不同的 java 脚本库,但首选 d3js。

createFloormap(){
      var svg = d3.select("svg")
      var width = +svg.attr("width")
      var height = +svg.attr("height")


      var path = d3.geoPath().projection(d3.geoAlbersUsa().scale(500))
      //var path = d3.geoPath()
      //var path = d3.geoPath().projection(d3.geoMercator().scale(100))



      var x = d3.scaleLinear()
          .domain([1, 10])
          .rangeRound([600, 860]);

      var color = d3.scaleThreshold()
          .domain(d3.range(2, 10))
          .range(d3.schemeBlues[9]);

      



    var promises = [
      d3.json("../static/data.json")
      //d3.json("https://raw.githubusercontent.com/adamjanes/udemy-d3/master/08/8.04/data/us-map.json")
    ]

    Promise.all(promises).then(function(data){
        ready(data[0]);
    })

    function ready(us) {
      console.log(us)
        svg.append("g")
            .selectAll("path")
              .data(us.features)
              //.data(topojson.feature(us, us.objects.states).features)
            .enter()
            .append("path")
                .attr("fill", "grey")
                .attr("d", path)
                .attr("stroke", "#fff")
                .attr("stroke-width", .2)
    }
    }
  },
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -144.140625,
              45.583289756006316
            ],
            [
              -65.390625,
              45.583289756006316
            ],
            [
              -65.390625,
              69.28725695167886
            ],
            [
              -144.140625,
              69.28725695167886
            ],
            [
              -144.140625,
              45.583289756006316
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              9.4921875,
              39.36827914916014
            ],
            [
              159.609375,
              39.36827914916014
            ],
            [
              159.609375,
              70.02058730174062
            ],
            [
              9.4921875,
              70.02058730174062
            ],
            [
              9.4921875,
              39.36827914916014
            ]
          ]
        ]
      }
    }
  ]
}

【问题讨论】:

  • 你能分享你正在使用的特定文件吗?我不确定它是否是注释掉的文件 - 将有助于提供明确的答案。
  • @AndrewReid 是的,我刚刚做了

标签: javascript d3.js


【解决方案1】:

我很抱歉,当 commenting 在您的最后一个 question 上时,我误导了您。我阅读了代码并看到了一个明显的问题 - 但错过了对平面图的参考 - 对于给定的坐标,不太可能以纬度/经度对进行测量。下面的答案适用于纬度/经度对的平面图(从 geojson.io 导出,因为投影在建筑规模上的相关性较低)或坐标以米/英尺为单位的 geojson 平面图。

任意笛卡尔坐标系中的 Geojson

您没有由以度数为单位的纬度/经度对组成的地理坐标(正如我在评论时所想的那样),您有由以米或英尺等单位测量的 x,y 值组成的坐标。

为了投影这些坐标,我们不想使用d3.geoSomeProjection,因为这些将球体上的纬度/经度对投影到二维平面。我们也不想使用空投影(d3.geoPath 的默认投影),因为它将 geojson 坐标视为像素坐标(当 geojson 中的坐标已经转换为像素值时,我们可以使用空投影 - 我们知道我们不希望这里有一个空投影,因为我们有负值)。

相反,我们可以使用d3.geoIdentitygeo 前缀表示它只是 D3 的 geo 模块的一部分,但它不需要地理坐标)。这种“投影”允许我们对数据应用一些投影方法,即.center().scale()。 D3 也有两个方便的方法可以同时设置:fitExtent 和 fitSize 将指定的 geojson 拉伸和转换为给定的尺寸:

var projection = d3.geoIdentity().fitSize([width,height],geoJsonObject)

var projection = d3.geoIdentity().fitExtent([[left,top],[right,bottom]],geoJsonObject)

所以,我们得到您的数据:

var data = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              -144.140625,
              45.583289756006316
            ],
            [
              -65.390625,
              45.583289756006316
            ],
            [
              -65.390625,
              69.28725695167886
            ],
            [
              -144.140625,
              69.28725695167886
            ],
            [
              -144.140625,
              45.583289756006316
            ]
          ]
        ]
      }
    },
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "type": "Polygon",
        "coordinates": [
          [
            [
              9.4921875,
              39.36827914916014
            ],
            [
              159.609375,
              39.36827914916014
            ],
            [
              159.609375,
              70.02058730174062
            ],
            [
              9.4921875,
              70.02058730174062
            ],
            [
              9.4921875,
              39.36827914916014
            ]
          ]
        ]
      }
    }
  ]
}

var width = 500;
var height = 300;
var svg = d3.select("svg")
  .attr("width",width)
  .attr("height",height);

var projection = d3.geoIdentity().fitSize([width,height],data)
var path = d3.geoPath(projection);

  
svg.selectAll("path")
  .data(data.features)
  .enter()
  .append("path")
  .attr("d",path);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg></svg>

需要注意的一点是,d3.geoIdentity 将坐标视为所在的 SVG 坐标空间具有与预期相反的约定:y=0 位于 SVG 的顶部,y 值增加为 1向下移动。如果您的坐标看起来是颠倒的,那么您可以使用d3.geoIdenity().fitSize(...).reflectY(true)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-03
    • 1970-01-01
    相关资源
    最近更新 更多