【问题标题】:Venue/Indoor Map using D3.js and Geojson使用 D3.js 和 Geojson 的场地/室内地图
【发布时间】:2014-03-01 06:32:19
【问题描述】:

我创建了包含购物中心一楼所有功能的geojson文件。我使用 d3.js 投影了具有不同颜色的场地地图,但只有某些部分不是完整的地图。下面是脚本代码和 geojson 文件的链接。另请注意,我没有将此 geojson 转换为 topojson 并使用 Qgis 绘制地图和 c#.net 将几何数据转换为 geojson 对象。谁能检查我的 json 和我的 d3.js 代码?我需要使用任何其他投影吗?

https://www.dropbox.com/s/8pu2s0yamfkd89p/JSONfromDB_8Feb2014.json

 $(document).ready(function () {                       
      parseResultShopDetails();                     
 });

 function parseResultShopDetails() {

    var width = 600, height = 300;

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

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

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

      d3.json("http://localhost:1209/data/JSONfromDB_8Feb2014.json", function (error,       jsonData) {
        var color1 = d3.scale.category10();

        svg.selectAll("path")
        .data(jsonData.features)
                        .enter()
                        .append("path")
                        .attr("d", path)
                        .attr("text", function (d, i) { return "js"; })
                        .attr("fill", function (d, i) { return color1(i); });


    });           
}        

【问题讨论】:

  • 你生成了很多 NaN。我不确定你的坐标,对于墨卡托(或任何)投影来说,它们似乎太大了。我不认为使用地球投影将是商场设计的最佳选择。你可以使用局部坐标系吗? gg 上的这个conversation 可能会有所帮助。

标签: d3.js geojson


【解决方案1】:

如果您尝试使用经度和纬度以外的坐标,看起来 d3 映射工具真的会崩溃。

我尝试创建一个仅返回输入值的“空”投影,但负数和大于 360 的数字在传递给投影函数之前仍被 d3 包裹。这避免了墨卡托投影的触发错误,并且创造了有趣的艺术,但不是您希望的平面图:

var projection = d3.geo.projection(function(λ, φ) {
  return [ λ, φ ];
});

http://fiddle.jshell.net/rR2hG/1/

但是,一切都没有丢失。该示例中的第二个图像是通过将坐标数组作为<polygon> 元素的点传递来创建的。我认为这更接近你想要的。因此,您需要做更多工作才能从数据文件中获取点,但您绝对可以将它们可视化为坐标数组。

    svg2.selectAll("polygon")
        .data(jsonData.features)
        .enter()
        .append("polygon")
        .attr("points", function(d){ return d3.merge(d.geometry.coordinates);})
        .attr("fill", function (d, i) {
            return color1(i);
        });

唯一的其他建议是编写一个脚本来将您的 geoJSON 文件转换为地理单位。它们不必是特定地点的实际纬度和经度(您仍然可以使地图以您选择的参考点为中心),但比例尺必须以度为单位,而不是英尺或米或您使用的任何值。

【讨论】:

  • 阿米莉亚,非常感谢您的帮助。我尝试了您的代码并得到了相同的结果。我认为应该有一些几何坐标的投影。
  • 你好,我能再问你一个问题,为什么在使用 D3.js 渲染时,商场图像比原始图像被翻转吗?
  • 垂直翻转?原始坐标可能在图像底部使用了 y=0,但在 SVG 中默认 y=0 是图像顶部,并且随着向下移动,坐标会增加。如果您想要相反,则需要使用范围(输出)的最大值和最小值与域(输入)的最大值和最小值方向相反的比例。
  • 您好阿米莉亚,感谢您的快速回复。您能否更新您之前创建的 jsfiddle (fiddle.jshell.net/rR2hG/1) 上的代码。我发现了如何获得最大值,最小值,但不确定在哪里放入该(jsfiddle)代码。 d3.max(d.geometry.coordinates[0], function (dt) { console.log("max : " + dt[1]); });
  • 使用d3 scale会更容易;查看其他答案并查看通用 d3 教程以了解如何使用秤。
【解决方案2】:

D3 的映射投影旨在将 3D 地球坐标转换为 2D 浏览器坐标,因此它们在转换本地坐标方面并不如您所拥有的那样出色。正如 Amelia 概述的那样,您输入的坐标超出了预期。

你最好做两件事之一;根据this google groups 讨论中概述的 2 个线性比例创建几何流;或者使用 d3 的路径生成器。

在 d3 中创建 2D 路径生成器很简单,这样可以工作:

var shops = d3.svg.line()
    .interpolate("linear")
    .x(function(d) {
        return xScale(d.x);
    })
    .y(function(d) {
        return yScale(d.y);
    }) 

这里真正的诀窍是访问 json 对象的“正确”部分。如果您查看 geojson 结构,您会看到有一个几何部分和一个属性部分。您需要深入挖掘以提取坐标,然后将它们传递给路面生成器。在这种情况下,它将是:

d.geometry.coordinates

显然需要正确引用。

请注意,如果您有复杂的几何形状(例如多面体),此处概述的方法将不起作用,您需要做更多的工作。如果这就是你所拥有的,你会想要创建一个自定义几何流。

现在把所有这些放在一起here's a working example 你们是 json。

【讨论】:

  • 非常感谢@user1614080,您的回答对我很有帮助。我将处理您提供的解决方案,生成完整的地图并让您知道结果。再次感谢。
  • 你好,我能再问你一个问题,为什么在使用 D3.js 渲染时,商场图像比原始图像被翻转吗?
  • 嗨,也许你可以看看这个帖子。我对多面体有同样的问题。 stackoverflow.com/questions/30359640/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多