D3绘制零投影的经度/纬度

时间:2015-04-13 00:20:44

标签: javascript svg d3.js geo

d3.geo.path具有空投影,因为已经投影了TopoJSON,因此它可以按原样显示。我正试图在地图上以[经度,纬度]的形式绘制数据。

以下是我的代码基本上的样子:

var width, height, path, svg;

width = 960;
height = 600;
path = d3.geo.path().projection(null);
svg = d3.select('.viz').append('svg')
    .attr('width', width)
    .attr('height', height);

d3.json("counties.json", function(error, us) {
    svg.append('path')
        .datum(topojson.mesh(us))
        .attr('d', path);
});

svg.selectAll('.pin')
    .data(ds) // i.e. ds = {[12.521, 15.312], [616.122,-31.160]}
    .enter().append('circle', '.pin')
    .attr('r', 3)
    .attr('transform', function (d) {
        return 'translate(' + path([
            d.longitude,
            d.latitude
        ]) + ')';
    });

我通过这个调试,我确实得到了数据。但是,我收到的错误是“路径([d.longitude,d.latitude])”未定义。 “d”存在经度和纬度值。 “路径”也存在。我认为这是因为投影是空的。

我可以做些什么来完成这项工作?

-------编辑------- 我遵循Ben Lyall的建议,删除了在selectAll语句中使用“path”以及在.json()中移动selectAll语句。我还注意到我为ds添加了一个不正确的例子,所以我修改了注释。这是我更新的代码。

这显示地图很好,没有控制台错误,但我仍然没有在地图中看到任何圆圈。

var width, height, path, svg;

width = 960;
height = 600;
path = d3.geo.path().projection(null);
svg = d3.select('.viz').append('svg')
    .attr('width', width)
    .attr('height', height);

d3.json("counties.json", function(error, us) {
    svg.append('path')
        .datum(topojson.mesh(us))
        .attr('d', path);

    svg.selectAll('.pin')
        .data(ds) // i.e. ds = [{longitude: 12.521, latitude: 15.312}, {longitude: 616.122, latitude: -31.160}]
        .enter().append('circle', '.pin')
        .attr('r', 3)
        .attr('transform', function (d) {
            return 'translate(' +
                d.longitude + ',' + d.latitude +
            ')';
        });
});

-------编辑------- 该解决方案结合了Ben Lyall提出的解决方案,并考虑了.pin s在地图上已完成的预测。由于代码中的投影为null,我必须创建一个与地图投影匹配的新投影,然后在.pin上执行变换时使用它。

以下是解决方案:

var width, height, path, projection, svg;

width = 960;
height = 600;
path = d3.geo.path().projection(null);
projection = d3.geo.albersUsa().scale(1280).translate([width/2, height/2]);
svg = d3.select('.viz').append('svg')
    .attr('width', width)
    .attr('height', height);

d3.json("counties.json", function(error, us) {
    svg.append('path')
        .datum(topojson.mesh(us))
        .attr('d', path);

    svg.selectAll('.pin')
        .data(ds)
        .enter().append('circle', '.pin')
        .attr('r', 3)
        .attr('transform', function (d) {
            return 'translate(' +
                projection([d.longitude, d.latitude]) +
            ')';
        });
});

1 个答案:

答案 0 :(得分:2)

当您定位.pin元素时,为什么在path使用translate?您不想创建路径,d.latituded.longitude值应该已经是像素坐标,因为它们已经预测,所以您应该能够直接使用它们。

注意:您可能还希望代码中的那部分代码位于d3.json处理程序中,而不是外部,因为它会在您的数据设置为任何内容之前异步运行(这可能是实际问题)你的代码,而不是错误地使用path

如果没有一个示例来解决这个问题有点难以确认,但试试这个:

var width, height, path, svg;

width = 960;
height = 600;
path = d3.geo.path().projection(null);
svg = d3.select('.viz').append('svg')
    .attr('width', width)
    .attr('height', height);

d3.json("counties.json", function(error, us) {
    svg.append('path')
        .datum(topojson.mesh(us))
        .attr('d', path);

    svg.selectAll('.pin')
        .data(ds) // i.e. ds = {[12.521, 15.312], [616.122, -31.160]}
        .enter().append('circle', '.pin')
        .attr('r', 3)
        .attr('transform', function (d) { 
            return 'translate(' + d.longitude + "," + d.latitude + ')';
        });
});