0

我正在尝试简化缩放时的 d3 地图,并使用此示例作为起点。但是,当我用我自己的 ( http://weather-bell.com/res/nws_regions.topojson ) 替换示例中的 json 文件时,我得到了一个小小的倒置的小地图。

这是我的 jsfiddle:http: //jsfiddle.net/8ejmH 代码:

var width = 900,
    height = 500;

var chesapeake = [-75.959, 38.250];

var scale,
translate,
visibleArea, // minimum area threshold for points inside viewport
invisibleArea; // minimum area threshold for points outside viewport

var simplify = d3.geo.transform({
    point: function (x, y, z) {
        if (z < visibleArea) return;
        x = x * scale + translate[0];
        y = y * scale + translate[1];
        if (x >= 0 && x <= width && y >= 0 && y <= height || z >= invisibleArea) this.stream.point(x, y);
    }
});

var zoom = d3.behavior.zoom()
    .size([width, height])
    .on("zoom", zoomed);

// This projection is baked into the TopoJSON file,
// but is used here to compute the desired zoom translate.
var projection = d3.geo.mercator().translate([0, 0])



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

var context = canvas.node().getContext("2d");

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

d3.json("http://weather-bell.com/res/nws_regions.topojson", function (error, json) {
    canvas.datum(topojson.mesh(topojson.presimplify(json)))
        .call(zoomTo(chesapeake, 0.05).event)
        .transition()
        .duration(5000)
        .each(jump);
});

function zoomTo(location, scale) {
    var point = projection(location);
    return zoom.translate([width / 2 - point[0] * scale, height / 2 - point[1] * scale])
        .scale(scale);
}

function zoomed(d) {
    translate = zoom.translate();
    scale = zoom.scale();
    visibleArea = 1 / scale / scale;
    invisibleArea = 200 * visibleArea;
    context.clearRect(0, 0, width, height);
    context.beginPath();
    path(d);
    context.stroke();
}

function jump() {
    var t = d3.select(this);
    (function repeat() {
        t = t.transition()
            .call(zoomTo(chesapeake, 100).event)
            .transition()
            .call(zoomTo(chesapeake, 0.05).event)
            .each("end", repeat);
    })();
}

我的猜测是我正在使用的 topojson 文件已经内置了投影,所以我应该在 d3 中使用空投影。如果我根本不使用投影,地图会正确渲染:(http://jsfiddle.net/KQfrK/1/) - 但是我无法简化缩放。

我觉得我错过了一些基本的东西......也许我只需要在我的第一个小提琴中以某种方式旋转并放大地图。

无论哪种方式,我都会很感激一些帮助。一直在努力解决这个问题。

编辑:我使用 QGIS 来保存带有“EPSG:3857 - WGS 84 / Pseudo Mercator”投影的 geojson 文件。但是,当我使用 topojson 命令行实用程序将其转换为 topojson,然后使用与上面相同的代码使用 D3 显示它时,我得到一个空白屏幕。

我应该在 topojson 命令行实用程序中指定投影吗?我试图这样做,但我收到一条错误消息:

topojson --projection EPSG:3857 E:\gitstore\public\res\nws.geojson -o E:\gitstore\public\res\nws.topojson --id-property NAME


[SyntaxError: Unexpected token :]
4

2 回答 2

0

我使用墨卡托投影设置了这个小提琴,并根据这个块采用了不同的方法来放大和缩小,这对我来说是一种更简单的方法。我感觉翻译位中的 zoomTo 函数存在问题,但我可以确切地知道它是什么。所以我用下面的代码替换并包含了一个递归调用:

function clicked(k) {

    if (typeof k === 'undefined') k = 8;

    g.transition()
        .duration(5000)
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(" + k + ")translate(" + -projection(chesapeake)[0] + "," + -projection(chesapeake)[1] + ")")
        .each("end", function () {
        (k === 8) ? k = 1 : k = 8;
        clicked(k);
    });
于 2013-09-29T00:03:36.087 回答
0

TopoJSON 文件没有内置投影,当您未指定投影时,您只是使用默认投影(即 albersUsa,请参阅文档)。d3.geo.projection()您可以通过不带参数调用来检索此投影。然后您可以以通常的方式修改此投影以进行缩放等。

于 2013-09-27T14:37:57.917 回答