3D座標系與經緯度座標換算

在開發與經緯度有關的項目時,通常需要將經緯度座標與3D引擎中的座標系進行互相換算。本次創新以Unity3D爲例,使用一系列算法將經緯度座標與3D座標系進行換算。

1.座標系分析(以Unity3D左手座標系爲例)

 

經緯度座標是描述球面上某個點的位置,若已知球體半徑(R)和球體中心點的3D座標(O)便可通過一些列計算的到3D座標系中的座標點(P)。

        通過經度可以計算出 ∠AOB的度數

        通過緯度可以計算出 ∠BOP的度數

 

        經度轉3D座標公式:

        X=R*Cos(∠BOP)*Cos(∠AOB)

        Y=R*Cos(∠BOP)*Sin(∠AOB)

        Z=R*(∠BOP)

 

        經度轉3D座標公式:

        ∠BOP=Asin(Z/R)

        ∠AOB=Asin(Y/X)

2.具體實現:

    座標轉換功能

using UnityEngine;  
using System.Collections;  
  
public class SaiGetLatLog : MonoBehaviour {  
  
    public Transform firstPoint; //Unity中左上點  
    public Transform secondPoint;//Unity中右下點  
  
      
    public SaiEarth firstSai;//地圖中對應的左上經緯度點  
    public SaiEarth secondSai;//地圖中對應的右下經緯度點  
  
    private float z_offset,x_offset,z_w_offset,x_w_offset;  
  
    private RaycastHit rayHit;  
  
    // Use this for initialization  
    void Start () {  
        InitBasicNum ();//初始化參數  
    }  
      
    // Update is called once per frame  
    void Update () {  
        if (Input.GetMouseButton (0) && Physics.Raycast (Camera.main.ScreenPointToRay (Input.mousePosition), out rayHit, Mathf.Infinity)) {  
  
            print ( getWorldPoint(firstSai).x+","+ getWorldPoint(firstSai).z);  
  
        }  
    }  
  
    void InitBasicNum()  
    {  
  
        firstSai = new SaiEarth (new Vector3 (116f, 23f, 9.27f), new Vector3 (39f, 55f, 15.74f));  
        secondSai = new SaiEarth (new Vector3(116f,23f,44.39f),new Vector3(39f,54f,44.27f));  
  
        z_offset = Mathf.Abs ((firstSai.latitude.x+firstSai.latitude.y/60+firstSai.latitude.z/3600) - (secondSai.latitude.x+secondSai.latitude.y/60+secondSai.latitude.z/3600));//地圖中的維度差  
        x_offset = Mathf.Abs ((firstSai.longitude.x+firstSai.longitude.y/60+firstSai.longitude.z/3600)-(secondSai.longitude.x+secondSai.longitude.y/60+secondSai.longitude.z/3600));//地圖中的經度差  
  
         z_w_offset = Mathf.Abs (firstPoint.localPosition.z - secondPoint.localPosition.z);//unity中的維度差  
         x_w_offset = Mathf.Abs (firstPoint.localPosition.x - secondPoint.localPosition.x);//unity中的經度差  
  
  
    }  
  
  
    Vector3 getWorldPoint(SaiEarth se)//由經緯度得到位置點  
    {  
  
        float tempX = (float)(se.longitude.x + se.longitude.y / 60 + se.longitude.z / 3600 - (secondSai.longitude.x + secondSai.longitude.y / 60 + secondSai.longitude.z / 3600));  
        float tempZ = (float)(se.latitude.x + se.latitude.y / 60 + se.latitude.z / 3600 - (secondSai.latitude.x + secondSai.latitude.y / 60 + secondSai.latitude.z / 3600));  
  
        float _tempX = (float)(tempX * x_w_offset / x_offset + secondPoint.localPosition.x);  
        float _tempZ = (float)(tempZ * z_w_offset / z_offset + secondPoint.localPosition.z);  
  
        return new Vector3((float)_tempX,0f,(float)_tempZ);  
  
  
    }  
  
    SaiEarth getLatLon(Vector3 curPoint)//由位置點得到經緯度  
    {  
        SaiEarth tempEarth = new SaiEarth();  
  
        float _z_offset = Mathf.Abs (curPoint.z - secondPoint.localPosition.z) * z_offset / z_w_offset;  
        float _x_offset = Mathf.Abs (curPoint.x - secondPoint.localPosition.x) * x_offset / x_w_offset;  
  
        float resultX = _x_offset + (secondSai.longitude.x + secondSai.longitude.y/60 + secondSai.longitude.z/3600);  
        float resultZ = _z_offset + (secondSai.latitude.x + secondSai.latitude.y/60 + secondSai.latitude.z/3600);  
  
        tempEarth.longitude = new Vector3 ((int)resultX, (int)((resultX - (int)resultX)*60),((resultX - (int)resultX)*60 - (int)((resultX - (int)resultX)*60))*60);  
        tempEarth.latitude = new Vector3 ((int)resultZ, (int)((resultZ - (int)resultZ)*60),((resultZ - (int)resultZ)*60 - (int)((resultZ - (int)resultZ)*60))*60);  
  
        return tempEarth;  
  
    }  
}
using UnityEngine;  
using System.Collections;  
  
public class SaiEarth  {  
  
  
    public Vector3 longitude;  
    public Vector3 latitude;  
  
    public SaiEarth()  
    {  
  
    }  
  
    public SaiEarth(Vector3 longitude,Vector3 latitude)  
    {  
        this.latitude = latitude;  
        this.longitude = longitude;  
    }  
  
    public string toString()  
    {  
        return "Lat:"+this.latitude + ",Long:" + this.longitude;  
    }  
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章