简体   繁体   English

如何 d3.js 中的 plot GeoJson 数据

[英]How to plot GeoJson data in d3.js

I am trying to display a floorplan to my webapp using d3.js and vue js.我正在尝试使用 d3.js 和 vue js 向我的 web 应用程序显示平面图。 The data comes from a.json file and is in a geojson format.数据来自 .json 文件,采用 geojson 格式。 I generated some test data from this geojson website.我从这个geojson 网站生成了一些测试数据。 I was thinking I could use the d3.js path function to plot each different object to a svg element. I was thinking I could use the d3.js path function to plot each different object to a svg element. Would this be the correct way to go about doing this?这是 go 关于这样做的正确方法吗? I have looked at this tutorial to make a united states map from geojson data.我查看了教程以从 geojson 数据制作美国 map。 I was thinking this would be the right way to do it if you inputted different data.我认为如果您输入不同的数据,这将是正确的方法。 However my program spits out random rectangles to the webapp.然而,我的程序向 webapp 吐出随机矩形。 I think this may be becauseof the projection I am using but Im not sure.我认为这可能是因为我正在使用的投影,但我不确定。 I havent used d3.js like this before so its all new to me.我以前没有像这样使用过 d3.js,所以它对我来说是全新的。 I included my code in below.我在下面包含了我的代码。 Any help is greatly appreciated and im open to possibly using a different java script library but d3js is preferred.非常感谢任何帮助,我愿意使用不同的 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
            ]
          ]
        ]
      }
    }
  ]
}

网络应用

My apologies, I mislead you when commenting on your last question .抱歉,我在评论您的最后一个问题时误导了您。 I read the code and saw an obvious issue - but missed the reference to a floor plan - which for the coordinates given was unlikely to be measured in latitude/longitude pairs.我阅读了代码并看到了一个明显的问题 - 但错过了对平面图的参考 - 对于给定的坐标,不太可能以纬度/经度对测量。 The answer below would be appropriate for a floor plan in lat/long pairs (as would be exported from geojson.io and because projection is less relevant at the building scale) or a geojson floor plan with coordinates in meters/feet.下面的答案适用于纬度/经度对的平面图(从 geojson.io 导出,因为投影在建筑规模上的相关性较低)或坐标以米/英尺为单位的 geojson 平面图。

Geojson in an arbitrary Cartesian coordinate system任意笛卡尔坐标系中的 Geojson

You don't have geographic coordinates consisting of latitude/longitude pairs measured in degrees (as I thought when commenting), you have coordinates consisting of x,y values measured in some unit like metres or feet.您没有由以度数为单位的纬度/经度对组成的地理坐标(正如我在评论时所想的那样),您的坐标由以米或英尺等单位测量的 x,y 值组成。

To project these corodinates we do not want to use d3.geoSomeProjection because these project latitude/longitude pairs on a sphere to a 2d plane.为了投影这些坐标,我们不想使用d3.geoSomeProjection因为这些将球体上的纬度/经度对投影到二维平面。 Nor do we want to use a null projection (the default projection for d3.geoPath) because that treats geojson coordinates as pixel coordinates (we can use a null projection when the coordinates in the geojson have been already been converted to pixel values - we know we don't want a null projection here because we have negative values).我们也不想使用 null 投影(d3.geoPath 的默认投影),因为它将 geojson 坐标视为像素坐标(当 geojson 中的坐标已经转换为像素值时,我们可以使用 null 投影 - 我们知道我们在这里不想要 null 投影,因为我们有负值)。

Instead we can use d3.geoIdentity (the geo prefix indicates it is just part of the geo module of D3 but it doesn't require geographic coordinates).相反,我们可以使用d3.geoIdentitygeo前缀表示它只是 D3 的geo模块的一部分,但它不需要地理坐标)。 This "projection" allows us to apply some projection methods to the data, namely .center() or .scale() .这种“投影”允许我们对数据应用一些投影方法,即.center().scale() D3 also has two convenience methods that set both simultaneously: fitExtent and fitSize which stretch and translate specified geojson to given dimensions: D3 还有两个同时设置的便捷方法:fitExtent 和 fitSize,它们将指定的 geojson 拉伸和转换为给定的尺寸:

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

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

So, with your data we get:因此,根据您的数据,我们得到:

 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>

One thing to note is that SVG coordinates space, to which d3.geoIdentity is treating coordinates as being in, has the opposite convention as might be expected: y=0 is at the top of the SVG with y values increasing as one moves down.需要注意的一点是,SVG 坐标空间(d3.geoIdentity 将坐标视为所在的空间)具有与预期相反的约定:y=0 位于 SVG 的顶部,y 值随着向下移动而增加。 If your coordinates appear to be upside down, then you can use d3.geoIdenity().fitSize(...).reflectY(true)如果您的坐标看起来是颠倒的,那么您可以使用d3.geoIdenity().fitSize(...).reflectY(true)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM