如何做平滑过渡的地图重投影在d3 js [英] How to do smooth transition for map reprojection in d3 js

查看:206
本文介绍了如何做平滑过渡的地图重投影在d3 js的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我正在建立的迷你应用程式中进行alber / orthographic之间的平滑过渡,非常类似这个例子:

I'd like to do a smooth transition between alber/orthographic in a mini app I am building, much like this example:

http://mbostock.github.io/d3/talk/20111018/#27

似乎这个平滑的过渡在v3中被破坏了,但是有一个相当波动的地图路径转换:

It seems like this smooth transition is broken in v3 however, with a rather choppy transition of the map paths:

https://www.evernote.com/shard/s236/sh/46b002bd-9c5b-4e9b-87ef-270c303eb677/2eaeebb267a3fc59df5a8447bbbcc58b/res/37917835-5aad-4509-b534-31a3e3034762/Worst_Tornado_Outbreaks_of_All_Time-20130611-074050 .jpg.jpg?resizeSmall& width = 832

代码非常简单,我将地图初始化为albers,然后运行ortho 。

Code is pretty straight forward, I initialize the map as albers, then run ortho() to update it.

function ortho() {
  var self = this, 
    h = 1000,
    w = document.width;

  this.projection = d3.geo.orthographic()
    .scale(500)
    .translate([ (w - 300) / 2, h / 2])
    .clipAngle(90)
    .rotate([90, 0, 0])
    .precision(.1);

  this.path = d3.geo.path()
    .projection(this.projection);

  //update path WITH transition
  d3.selectAll('path')
    .transition()
    .duration(900)
    .attr('d', app.path);

}

地图从albers变为orthographic,不光滑。任何想法将是伟大的。

The map changes from albers to orthographic, but the transition is not smooth. Any thoughts would be great.

推荐答案

如果使用D3的天真字符串插值器插入路径( d3.interpolateString ),则起始路径中的坐标数量和结束路径中的坐标数量必须完全匹配,包括以相同的顺序。但是,由于剪切,剪切重新取样。可以进行形状插值(使用多个 策略),但它一般难以解决的问题。请参见此解释 Path Transitions )为什么天真插值不够。

If you interpolate the path using D3’s naïve string interpolator (d3.interpolateString), then the number of coordinates in the starting path and the number of the coordinates in the ending path must match exactly, including in the same order. But this is almost never the case due to clipping, cutting and resampling. Shape interpolation is possible (using multiple strategies), but it’s a hard problem to solve in the general case. See this explanation (part of the Path Transitions) for why naïve interpolation is insufficient.

您要插入投影。插值投影不需要坐标之间的精确对应,因此避免了插值伪影。请参阅以下示例进行演示:

Instead of interpolating the path, you want to interpolate the projection. Interpolating the projection does not require an exact correspondence between coordinates and therefore avoids interpolation artifacts. See these examples for a demonstration:

  • http://bl.ocks.org/mbostock/5731632
  • http://bl.ocks.org/mbostock/3711652
  • http://www.jasondavies.com/maps/transition/

如第一个例子所示,这里是一个可以使用的实现:

As shown in the first example, here is an implementation you can use:

function interpolatedProjection(a, b) {
  var projection = d3.geo.projection(raw).scale(1),
      center = projection.center,
      translate = projection.translate,
      α;

  function raw(λ, φ) {
    var pa = a([λ *= 180 / Math.PI, φ *= 180 / Math.PI]), pb = b([λ, φ]);
    return [(1 - α) * pa[0] + α * pb[0], (α - 1) * pa[1] - α * pb[1]];
  }

  projection.alpha = function(_) {
    if (!arguments.length) return α;
    α = +_;
    var ca = a.center(), cb = b.center(),
        ta = a.translate(), tb = b.translate();
    center([(1 - α) * ca[0] + α * cb[0], (1 - α) * ca[1] + α * cb[1]]);
    translate([(1 - α) * ta[0] + α * tb[0], (1 - α) * ta[1] + α * tb[1]]);
    return projection;
  };

  delete projection.scale;
  delete projection.translate;
  delete projection.center;
  return projection.alpha(0);
}

使用两个投影创建插值投影 code>和 b ,然后将插值的alpha设置为0( a )和1( b )。

Create the interpolated projection using two projections a and b, and then set the interpolated alpha to a value between 0 (for a) and 1 (for b).

这篇关于如何做平滑过渡的地图重投影在d3 js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆