【问题标题】:D3 - Large GeoJSON File does not show draw map properly using projectionsD3 - 大型 GeoJSON 文件未使用投影正确显示绘制地图
【发布时间】:2014-07-20 03:22:54
【问题描述】:

我在绘制从 data.seattle.gov 获取的 GeoJSON 文件时遇到问题。具体来说,我使用的是 here 的 Shape 文件。我将其转换为 GeoJSON 文件,并在下面提供了一个小示例。

通过使用 D3,我希望画出西雅图的不同区域应该是什么(实际上我并不完全确定它应该是什么,这就是我要画它的原因......哈......)但是出于某种原因,尽管路径计算正确,但它没有正确显示。

我已经托管了我的示例here。当我有时间设置它时,我会尝试用 jsFiddle 替换这个链接。问题是,GeoJSON 文件非常大,所以我认为 jsFiddle 不太理想。

我的代码非常简单...我只是根据 GeoJSON 文件的特性添加路径。

var width = 1000,
    height = 1000;

var svg = d3.select("body")
            .append("svg")
            .attr("width", width + "px")
            .attr("height", height + "px");

var projection = d3.geo.mercator()
    .scale(150)
    .translate([width/2, height/2]);

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

var g = svg.append("g");

d3.json("geojson/data.geo.json", function(data) {
    console.log(data);
    g.selectAll("path")
        .data(data.features)
        .enter()
        .append("path")
        .attr("d", path)
        .attr("stroke", "black")
        .attr("stroke-width", "5px")
        .attr("fill-opacity", 0);
});

不幸的是,我觉得它只显示了其中一条路径,而不是所有路径。起初我认为这可能是因为有某种填充,它们只是相互隐藏,但我将 fill-opacity 设置为 0,这也没有帮助。

这是 GeoJSON 文件的一个小样本。

{
    "type": "FeatureCollection",
    "features": [
        {
            "type": "Feature",
            "geometry": {
                "type": "Polygon",
                "coordinates": [
                    [
                        [
                            -122.349453,
                            47.717771
                        ],
                        [
                            -122.34948,
                            47.719585
                        ],
                        [
                            -122.349504,
                            47.721403
                        ],
                        [
                            -122.350214,
                            47.721404
                        ],
                        ...
                        [
                            -122.350337,
                            47.721405
                        ],
                        [
                            -122.350258,
                            47.71596
                        ],
                        [
                            -122.349425,
                            47.715958
                        ],
                        [
                            -122.349453,
                            47.717771
                    ]
                ]
            ]
        },
        "properties": {
            "name": "B1",
            "styleUrl": "#PolyStyle00",
            "styleHash": "-59c62042",
            "description": "<html xmlns:fo=\"http://www.w3.org/1999/XSL/Format\" xmlns:msxsl=\"urn:schemas-microsoft-com:xslt\">\n\n<head>\n\n<META http-equiv=\"Content-Type\" content=\"text/html\">\n\n</head>\n\n<body style=\"margin:0px 0px 0px 0px;overflow:auto;background:#FFFFFF;\">\n\n<table style=\"font-family:Arial,Verdana,Times;font-size:12px;text-align:left;width:100;border-collapse:collapse;padding:3px 3px 3px 3px\">\n\n<tr style=\"text-align:center;font-weight:bold;background:#9CBCE2\">\n\n<td>B1</td>\n\n</tr>\n\n<tr>\n\n<td>\n\n<table style=\"font-family:Arial,Verdana,Times;font-size:12px;text-align:left;width:100;border-spacing:0px; padding:3px 3px 3px 3px\">\n\n<tr>\n\n<td>FID</td>\n\n<td>0</td>\n\n</tr>\n\n<tr bgcolor=\"#D4E4F3\">\n\n<td>BEAT</td>\n\n<td>B1</td>\n\n</tr>\n\n<tr>\n\n<td>PRECINCT</td>\n\n<td>N</td>\n\n</tr>\n\n<tr bgcolor=\"#D4E4F3\">\n\n<td>Shape_Leng</td>\n\n<td>53375.265498</td>\n\n</tr>\n\n</table>\n\n</td>\n\n</tr>\n\n</table>\n\n</body>\n\n</html>\n\n"
        }
    },
    ...

最后画出来的是这个……

任何帮助将不胜感激。

编辑:抱歉,我的学生帐户似乎从很久以前就消失了。我可以稍后尝试重新创建示例。

【问题讨论】:

  • 你需要适当设置缩放和平移,见here
  • @LarsKotthoff 感谢您的链接。我试着弄乱我的投影居中,但我仍然得到一个带有边界框的空白 svg。在 Mike 的示例 here 中,他通过过滤其他状态来引用单个状态以作为中心。我不确定我应该如何指定以我的 GeoJSON 文件中所有多边形的集合为中心:/ 知道如何解决这个问题吗?并感谢您的回复!
  • 我链接到的问题的第一个答案集中在整个文件上。
  • 我尝试使用该代码,但仍然没有成功。它最终只是简单地绘制了 svg 的轮廓以及 GeoJSON 文件的轮廓,而没有显示任何节拍区域:/ 我复制了它here

标签: javascript d3.js maps data-visualization geojson


【解决方案1】:

我看了你的问题。问题似乎出在地图上。我遇到了与您相同的问题,尽管从您链接到的站点上的旧(2008 年之前)文件创建地图没有问题。 Mapshaper (mapshaper.org) 绘制两张图都没有问题,所以问题似乎出在 d3 和这张特定的地图上。我没有时间调查这个原因。

使用 mapshaper 简化地图(这可能是您无论如何都想做的事情)似乎会产生可以正确绘制的地图:

ogr2ogr -f GeoJSON map_tmp.json spd_beats_wgs84.kmz
mapshaper -p 0.5 --repair -o map.json map_tmp.json

然后我可以使用以下代码绘制地图:

var width = 800;
var height = 500;

var vis = d3.select("#vis").append("svg")
    .attr("width", width).attr("height", height);

d3.json("map.json", function(map) {
  var projection = d3.geo.mercator().scale(1).translate([0,0]).precision(0);
  var path = d3.geo.path().projection(projection);
  var bounds = path.bounds(map);

  var scale = .95 / Math.max((bounds[1][0] - bounds[0][0]) / width,
      (bounds[1][1] - bounds[0][1]) / height);
  var transl = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2,
      (height - scale * (bounds[1][1] + bounds[0][1])) / 2];
  projection.scale(scale).translate(transl);

  vis.selectAll("path").data(map.features).enter().append("path")
    .attr("d", path)
    .style("fill", "none")
    .style("stroke", "black");
});

导致:

【讨论】:

  • 我最终使用 R 将地图绘制为 SVG,将其另存为 SVG 文件,然后上传到网页为那些想知道的人解决我的直接问题,但这绝对是我正在寻找的答案为了。我一定会看看 Mapshaper。不用说非常感谢。如果您有时间,我非常感谢您知道地图出了什么问题,因为我认为这对观众最有利。如果我发现任何问题,我也会调查并更新您的答案。
  • bounds 是一个 2x2 数组。您如何获得索引 [0][3]、[1][4] 和 [0][5]?你想要:``` var scale = 0.95 / Math.max((bounds[1][0] - bounds[0][0]) / width, (bounds[1][1] - bounds[0][1 ]) / 高度); var transl = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2, (height - scale * (bounds[1][1] + bounds[0][1 ])) / 2]; ```
  • @AshwinBalamohan:你是对的。诡异的。我已经纠正了这一点。感谢您的报告。
  • @JanvanderLaan 感谢您的解决方案。这很有帮助。我看到你已经更新了 transl 变量的赋值,但是 scale 变量的数组索引仍然大于 1。
  • @AshwinBalamohan 现在也已修复。
猜你喜欢
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 2018-08-24
  • 1970-01-01
  • 2023-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多