微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

地理坐标偏移 - 机场跑道图

如何解决地理坐标偏移 - 机场跑道图

我正在尝试生成机场跑道图,如下所示:

airport runways

每个机场都有一个跑道列表,如下所示:

const runways = [
    {
      identifier1: "110L",identifier2: "28R",length: 3107,width: 75,latitude1: 37.66247544,longitude1: -122.12726156,latitude2: 37.65822686,longitude2: -122.11795339,},{
      identifier1: "10R",identifier2: "28L",length: 5694,width: 150,latitude1: 37.66204453,longitude1: -122.12979078,latitude2: 37.65426,longitude2: -122.11273375,];

如您所见,每条跑道都有起点和终点地理点。 对于我使用 svg-airports 的视觉效果,上面的跑道示例如下所示:

<airport-diagram width="200" height="200">
  <airport-runway
    length-ft="3107"
    true-heading="119"
    offset-angle="29"
    offset-x="300"
    offset-y="1000"
  >
    <runway-id name="10L" pattern="left"></runway-id>
    <runway-id name="28R" pattern="right"></runway-id>
  </airport-runway>
  <airport-runway
    length-ft="5694"
    true-heading="119"
    offset-angle="29"
    offset-x="300"
    offset-y="-1000"
  >
    <runway-id name="10R" pattern="right"></runway-id>
    <runway-id name="28L" pattern="left"></runway-id>
  </airport-runway>
</airport-diagram>

如您所见,每条跑道都有以下值

  • 长度
  • 真实标题
  • 偏移角度
  • 偏移-x
  • 偏移-y

我可以提供长度,因为我已经从我的 airport 中获得了该信息,并且我正在计算真实航向(方位),如下所示:

function radians(n) {
  return n * (Math.PI / 180);
}
function degrees(n) {
  return n * (180 / Math.PI);
}

function getbearing(startLat,startLong,endLat,endLong) {
  startLat = radians(startLat);
  startLong = radians(startLong);
  endLat = radians(endLat);
  endLong = radians(endLong);

  var dLong = endLong - startLong;

  var dPhi = Math.log(
    Math.tan(endLat / 2.0 + Math.PI / 4.0) /
      Math.tan(startLat / 2.0 + Math.PI / 4.0)
  );
  if (Math.abs(dLong) > Math.PI) {
    if (dLong > 0.0) dLong = -(2.0 * Math.PI - dLong);
    else dLong = 2.0 * Math.PI + dLong;
  }

  return (degrees(Math.atan2(dLong,dPhi)) + 180.0) % 180.0;
}

问题是,我可以根据跑道之间的地理坐标计算offset-angleoffset-xoffset-y吗?

P.S:偏移值以英尺为单位。

解决方法

将经度/纬度转换为笛卡尔坐标。那么它应该很容易。 我认为转换是问题所在。

对于机场(相对较小),可以使用简单的 equirectangular projection

<!doctype html>
<html>
<body>
   <script src="t.js"></script>
   <script src="svg-airports-1.0.js" async></script>
</body>
</html>
// t.js
// important parts within ////// commments
const runways = [
   {
      identifier1: "110L",identifier2: "28R",length: 3107,width: 75,latitude1: 37.66247544,longitude1: -122.12726156,latitude2: 37.65822686,longitude2: -122.11795339,},{
      identifier1: "10R",identifier2: "28L",length: 5694,width: 150,latitude1: 37.66204453,longitude1: -122.12979078,latitude2: 37.65426,longitude2: -122.11273375,];

function runways2html(runways,scale=1.0) {
   //
   airport = document.createElement("airport-diagram")
   document.body.appendChild(airport)
   //////////////////////////////////////////////////////////////////////
   const radians = n => n * (Math.PI / 180)
   const degrees = n => n * (180 / Math.PI)
   const avg = (v1,v2) => .5*(v1+v2)
   const lon2x = lon => R*(lon-lon0)*cosLat0
   const lat2y = lat => R*(lat-lat0)
   //
   var lons = runways.map(({longitude1,longitude2}) => [longitude1,longitude2]).flat().map(v => radians(v))
   var lats = runways.map(({latitude1,latitude2}) => [latitude1,latitude2]).flat().map(v => radians(v))
   var lonMax = Math.max(...lons)
   var lonMin = Math.min(...lons)
   var latMax = Math.max(...lats)
   var latMin = Math.min(...lats)
   var lon0 = avg(lonMin,lonMax)
   var lat0 = avg(latMin,latMax)
   var cosLat0 = Math.cos(lat0)
   var R = 20902000 // Earth radius in feet (??)
   //////////////////////////////////////////////////////////////////////
   var [xMin,xMax] = [lonMin,lonMax].map(lon2x)
   var [yMin,yMax] = [latMin,latMax].map(lat2y)
   var width = xMax-xMin
   var height = yMax-yMin
   var [width,height] = [width,height].map(v => v*scale)
   airport.setAttribute("width",width)
   airport.setAttribute("height",height)
   //
   runways.forEach(runway => {
      var {
         identifier1,identifier2,length,width,latitude1,longitude1,latitude2,longitude2,} = runway
      //////////////////////////////////////////////////////////////////////
      var [longitude1,latitude2] = [longitude1,latitude2].map(v => radians(v))
      var [x1,x2] = [longitude1,longitude2].map(lon2x)
      var [y1,y2] = [latitude1,latitude2].map(lat2y)
      var heading = Math.atan2(x2-x1,y2-y1)
      heading = degrees(heading)
      var x = avg(x1,x2)
      var y = avg(y1,y2)
      //////////////////////////////////////////////////////////////////////
      var runway = document.createElement("airport-runway")
      runway.setAttribute("length-ft",length)
      runway.setAttribute("true-heading",heading)
      runway.setAttribute("offset-angle",0)
      runway.setAttribute("offset-x",x)
      runway.setAttribute("offset-y",y)
      var [id1,id2] = [0,1].map(i => document.createElement("runway-id"))
      id1.setAttribute("name",identifier1)
      id1.setAttribute("pattern",identifier1.endsWith("L")?"left":"right") // ??
      id2.setAttribute("name",identifier2)
      id2.setAttribute("pattern",identifier1.endsWith("L")?"right":"left") // ??
      runway.appendChild(id1)
      runway.appendChild(id2)
      airport.appendChild(runway)
   })
}

runways2html(runways,0.2)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。