在Winkel Tripel投影上将纬度/经度转换为笛卡儿

时间:2013-02-21 21:22:24

标签: php graph maps cartesian map-projections

我有一张Winkel Tripel地图,我需要将标记放在上面。我给出了纬度/经度标记的位置。所以我需要一种方法将它转换为X,Y。

我找到了一些代码(下图),但是当我试用它时,45º对角线的图形具有适度的s曲线。所以这显然不正确。

任何帮助都会很棒。我在PHP中这样做,但我应该能够转换任何语言。

private function sinc($x){
    if($x == 0) return 1;
    return sin($x) / $x;
}

private function winkelTripelToCartesian($lat, $lng){
    $lat = deg2rad($lat);
    $lng = deg2rad($lng);

    $alpha = acos(cos($lat) * cos($lng / 2));

    $x = ($lng * M_2_PI + (2 * cos($lat) * sin($lng / 2)) / $this->sinc($alpha)) / 2;
    $y = ($lat + (sin($lat) / $this->sinc($alpha))) / 2;

    return array('x'=> strval($x), 'y' => strval($y));
}

1 个答案:

答案 0 :(得分:0)

该地图投影尝试将球体显示为2D对象,这会导致它改变形状的外观。这可能导致你的线弯曲。

如果你仍然不舒服,这里有一个脚本,用于使用Javascript在winkel III投影上绘制地图上的标记:

  // latitudes/longitudes to radians
  var latRadian = (latitudes[i] * Math.PI) / 180;
  var lngRadian = (longitudes[e] * Math.PI) / 180;
  console.log("Radian Coordinates = " + latRadian + ", " + lngRadian);

  //Radians to xy cartesian coordinates
  var alpha = Math.acos( Math.cos(latRadian) * Math.cos( lngRadian / 2 ) );
  var phi_1 = Math.acos( 2 / Math.PI );
  function sinc(x) {
      if (x == 0) {
          return 1;
      } else {
          return (Math.sin(x)/x);
      }
  }
  var x = (svgHeight/Math.PI) * ( lngRadian * Math.cos(phi_1) + 2 * ( Math.cos(latRadian) * Math.sin(lngRadian/2) / sinc(alpha) ) ) / 2;
  var y = (svgHeight/Math.PI) * ( latRadian + ( Math.sin(latRadian) / sinc(alpha) )) / 2;

您可以在此处找到完整示例:http://codepen.io/StinoM/pen/PZjYqw?editors=001

以下是我发现使用Ruby的一些代码:https://gist.github.com/duncanbeevers/195554