0

ズームで d3 マップを単純化しようとしています。この例を出発点として使用しています。ただし、例の json ファイルを自分のファイル ( http://weather-bell.com/res/nws_regions.topojson ) に置き換えると、小さな逆さまの小さな地図が得られます。

ここに私の 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

The TopoJSON file doesn't have a projection built-in, you're simply using the default projection when you don't specify one (which is albersUsa, see the documentation). You can retrieve this projection by calling d3.geo.projection() without an argument. Then you can modify this projection in the usual way for zoom etc.

于 2013-09-27T14:37:57.917 に答える
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 に答える