【问题标题】:d3.js fisheye distortion on mapd3.js 地图上的鱼眼失真
【发布时间】:2015-05-27 05:00:55
【问题描述】:

我正在尝试使用 fisheye.js 插件 (https://github.com/d3/d3-plugins/tree/master/fisheye) 扭曲 d3.geo.path() 地图。

要扭曲对象,插件需要 x & y 属性。

在 d3.js wiki 中它说:

投影函数采用表示位置坐标 [longitude, latitude] 的二元素数组,并返回表示投影像素位置 [x, y] 的类似二元素数组。例如,一个基本的球形墨卡托投影:

https://github.com/mbostock/d3/wiki/Geo-Paths

所以失真应该是可能的,我只是无法绕过它。

我正在使用 world-50m.json 进行投影。一旦加载,就会有一个 arcs 数组。我认为这些是我需要操纵的坐标。但这是猜测......

谢谢,

【问题讨论】:

    标签: javascript d3.js maps fisheye


    【解决方案1】:

    我发现您的帖子正在寻找答案,但它似乎没有出现在互联网上。但是,就像你说的,这是可能的!

    根据 fisheye.js (https://github.com/d3/d3-plugins/tree/master/fisheye) 中的文档,在 mousemove 回调中,您需要在坐标上使用 fisheye。

    由于fisheye 使用.x.y 属性,我将fisheye 代码修改为仅使用两对[x,y] 以避免每次在回调中都生成中间数据结构。

    那么你可以这样:

    canvas.on("mousemove", function() {
        // console.log("mouse:");
        // console.log(d3.mouse(this));
        var here = d3.mouse(this);
        // console.log(here); // [1030, 125]
        // console.log(projection.invert(here)); // [-72.4713375653601, 45.14035261565636]
        var inverted = projection.invert([here[0],here[1]]); // [-72.4713375653601, 45.14035261565636]
        // console.log(inverted); // [-72.4713375653601, 45.14035261565636]
        // burlington is lat 44, lon -73
        fisheye.focus(inverted);
    
        // of course, the path function takes [longitude, latitude], so -72, 44 for burlington
        // https://github.com/mbostock/d3/wiki/Geo-Paths
        // (so that's what it gives back)
    
        states.attr("d",null)
            .attr("d", function(d) {
                // console.log("original:");
                // console.log(d.geometry);
    
                if (d.geometry.type === "Polygon") {
                    var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return fisheye(f);}); });
                }
                else {
                    var b = d.geometry.coordinates.map(function(d) { return d.map(function(f) { return f.map(function(g) { return fisheye(g); }); }); });
                }
                // console.log(b);
                var c = {type: d.geometry.type, coordinates: b};
    
                // console.log("new:");
                // console.log(c);
    
                return path(c);
        });
    

    您可以在此处查看实时版本:http://panometer.org/instruments/teletherms/?window=25&var=maxT&year=1914&city=BURLINGTON%20WSO%20AP,%20VT

    【讨论】:

    • 嗨,Andy,您介意解释一下 if/else 部分中 d.mapf.map 语句的顺序吗?他们到底在做什么,为什么你在第一个中使用d.map,然后在第二个中使用d.mapf.map?我正在尝试以类似的方式实现鱼眼失真,但是在解决这个问题时遇到了一些麻烦,因此出现了错误(所有路径最终都变成了 NaN)。谢谢!
    • 为简短的回答道歉-JS变量是函数范围的,这就是原因。我建议阅读“JS: The good parts”(Crawford 撰写)以获得良好的 JS 参考资料(我在 D3 中已经走得很远,没有太多 JS,但它赶上了)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多