D3.geo:平行线是球弧而不是直线? [英] D3.geo : Spherical arcs rather than straight lines for parallels?

查看:18
本文介绍了D3.geo:平行线是球弧而不是直线?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚制作了一个 D3js 地球定位器,如下所示:

如果仔细观察,红色方块看起来很难看,因为它不遵循地球曲线.我有十进制度数的区域边界框:

var bb = {W:-5.0, N:50.0, E:10.0, S:40.0 }

我画的线如下:

svg.append("path").datum({type: "LineString", 坐标:[[-5, 40], [-5, 50], [10, 50], [10, 40], [-5, 40]]}).attr("d", 路径);

对于更大的区域,它甚至是与预期相反的曲线(对于边界框):

如何添加相当优雅的球面弧?

解决方案

给定一个已知的十进制度数边界框(

var bb = { "item":"India", "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0 },localisator("body", 200, bb.item, bb.W, bb.N, bb.E, bb.S);

+1 欢迎.

I just made a D3js globe localisator, which looks like this :

If you look carefully, the red square looks ugly since it doesn't follow the Earth's curve. I have the area bounding box in decimal degrees :

var bb = {W:-5.0, N:50.0, E:10.0, S:40.0 }

And I draw the lines as follow:

svg.append("path")
.datum({type: "LineString", coordinates: 
        [[-5, 40], [-5, 50], [10, 50], [10, 40], [-5, 40]]
       })
.attr("d", path);

For larger areas, it's even the opposite curve from expectations (for a bounding box):

How to add rather elegant spherical arcs ?

解决方案

Given a known decimal degrees bounding box (dig in start here for bb) such as :

  bounds = [[-50.8,20.0][30,51.5]];
  WNES0 = bounds[0][0], // West    "W":-50.8  
  WNES1 = bounds[1][2], // North   "N": 51.5
  WNES2 = bounds[1][0], // East    "E": 30
  WNES3 = bounds[0][3], // South   "S": 20.0

Some maths are needed.

// *********** MATH TOOLKIT ********** //
function parallel(φ, λ0, λ1) {
  if (λ0 > λ1) λ1 += 360;
  var dλ = λ1 - λ0,
      step = dλ / Math.ceil(dλ);
  return d3.range(λ0, λ1 + .5 * step, step).map(function(λ) { return [normalise(λ), φ]; });
}
function normalise(x) {
  return (x + 180) % 360 - 180;
}   

Then, let's both calculate the polygon's coordinates and project it:

// *********** APPEND SHAPES ********** //
svg.append("path")
.datum({type: "Polygon", coordinates: [
    [[WNES0,WNES3]]
      .concat(parallel(WNES1, WNES0, WNES2))
      .concat(parallel(WNES3, WNES0, WNES2).reverse())
  ]})
.attr("d", path)
.style({'fill': '#B10000', 'fill-opacity': 0.3, 'stroke': '#B10000', 'stroke-linejoin': 'round'})
.style({'stroke-width': 1 });

180th meridian crossing: Boxes upon the 180th meridian need special management. By example, localising a set of pacific island between 155⁰ East and -155 West initially gives.... ...with correct rotation (+180⁰) : ... and with correct boxing:

Localisator now perfect ! Live demo on blocks

var bb = { "item":"India", "W": 67.0, "N":37.5, "E": 99.0, "S": 5.0 }, 
localisator("body", 200, bb.item, bb.W, bb.N, bb.E, bb.S);

+1 welcome.

这篇关于D3.geo:平行线是球弧而不是直线?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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