d3.js fisheye distortion on map

牧云@^-^@ 提交于 2019-12-08 05:59:23

问题


I'm trying to distort a d3.geo.path() map with the fisheye.js plugin (https://github.com/d3/d3-plugins/tree/master/fisheye).

To distort an object the plugin needs x & y attributes.

In the d3.js wiki it says:

A projection function takes a two-element array of numbers representing the coordinates of a location, [longitude, latitude], and returns a similar two-element array of numbers representing the projected pixel position [x, y]. For example, a rudimentary spherical Mercator projection:

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

So the distortion should be possible, I just can't wrap my head around it.

I'm using the world-50m.json for my projection. Once loaded there is an the arcs array. I think those are the coordinates I need to manipulate. But this is guesswork...

Thanks,

Kim


回答1:


I found your post looking for the answer, and it doesn't appear to be out there on the internets. But, like you say, it's possible!

Following the documentation from the fisheye.js (https://github.com/d3/d3-plugins/tree/master/fisheye), in the mousemove callback you need to use fisheye on the coordinates.

Since fisheye uses the .x and .y attributes, I modified the fisheye code to just use the two pair [x,y] to avoid making that intermediate data structure every time in the callback.

Then you can do it like this:

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);
    });

You can view a live version here: http://panometer.org/instruments/teletherms/?window=25&var=maxT&year=1914&city=BURLINGTON%20WSO%20AP,%20VT



来源:https://stackoverflow.com/questions/30473547/d3-js-fisheye-distortion-on-map

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!