Unity實用功能之經緯度和Unity座標之間轉換| 8月更文挑戰

概述

在作模擬仿真的項目時,有時候須要加載地圖上某一塊的地貌和建築,這時候咱們只知道這些建築在地圖上的經緯度座標,並不知道其在Unity中的世界座標,那麼如何才能將全部建築按照真實地圖顯示出來就成了一個問題,本篇文章主要介紹的就是,如何經過經緯度,計算出其在Unity中的世界座標。markdown

注:由於Unity中的Vector3是float,因此本文中使用的是float類型的數據,精準度會有些許誤差,若是對精準度要求比較高,還請本身重寫下Unity的Vector,將其重寫爲double類型的,在換算過程當中我將使用double,只是最後返回值得時候會轉成float。spa

思路分析

經緯度組合起來就是一個Vector2類型的數據。咱們首先在Unity中建立兩個點,兩個點的位置就是一個正方形(長方形等)的對角線的位置便可,分別在地圖上找到兩個點的經緯度,也就是使用這兩點,在地圖上圈出來一個範圍,將找到的這個兩個點的經緯度,分別賦給在Unity中建立的兩個點,這樣咱們在Unity中的範圍位置,就和顯示地圖中的位置相對應了起來,在經過其座標的X,Z軸的值和經緯度的差值,從而計算出座標。具體示意圖以下:3d

image.png

image.png 上圖中,只要將圖二中的AB點的經緯度,賦值給圖一種AB點,便可經過座標差,實時計算出由AB兩點組成的正方形內的全部點的座標code

功能實現

上圖中兩個球就是肯定位置的關鍵點。若是這兩個點都沒有肯定好,那麼一切都是白扯。 說通俗一點就是,已知A,B的位置和對應的數值,和 C 的位置,讓你求 C 對應的值,是一個道理。 而咱們在程序中們能夠使用動態設置這兩個定位點的位置,而不用一遍遍使用手動調節。orm

在程序中,咱們還能夠經過獲取中心點的經緯度,經過向左右加減的方式,肯定兩角的座標,這樣作的好處就是不管是什麼樣的經緯度均可以計算出,而且不超出定位點單的範圍。it

首先進行程序的初始化,先肯定兩個定位點的座標,以及兩個座標點在Unity中的經緯度的差io

//本案例中是直接肯定經緯度,不是經過中間點加減肯定的
//點1
BottomRightSai = new Vector2(113.98071f, 22.52864f);
//點2
TopLeftSai = new Vector2(80.15071f, 40.56864f);
z_offset = BottomRightSai.y - TopLeftSai.y;//地圖中的維度差  
x_offset = BottomRightSai.x - TopLeftSai.x;//地圖中的經度差  
z_w_offset = BottomRightPoint.position.z - TopLeftPoint.position.z;//unity中的維度差  
x_w_offset = BottomRightPoint.position.x - TopLeftPoint.position.x;//unity中的經度差
複製代碼

接下來是經過已知的經緯度,計算出該點在Unity中的座標table

注:此方法無法計算出在Unity中的高度,全部物體的Y軸是固定的,同定位點。若是想要使用高度,須要Unity讀取灰度圖纔可以獲取到高度class

/// <summary>
    /// 由經緯度獲得位置點  
    /// </summary>
    /// <param name="se"></param>
    /// <returns></returns>
    public Vector3 GetWorldPoint(Vector2 se)
    {
        double tempX = se.x - TopLeftSai.x;
        double tempZ = se.y - BottomRightSai.y;
        double _tempX = (tempX * x_w_offset / x_offset + TopLeftPoint.position.x);//計算X軸
        double _tempZ = (tempZ * z_w_offset / z_offset + BottomRightPoint.position.z);//計算Z軸
        //獲取該點世界座標
        return new Vector3((float)_tempX, 0, (float)_tempZ);
    }
複製代碼

由Unity座標逆推經緯度一樣的原理,仍是上面提到的問題,經緯度通常都是double數據,此方法中使用的是float,精準度會有誤差,若是定位點範圍較大可能不會有大影響,可是範圍若是很小誤差可能會比較明顯import

/// <summary>
    /// 由位置點獲得經緯度  
    /// </summary>
    /// <param name="curPoint"></param>
    /// <returns></returns>
    public Vector3 GetLatLon(Vector3 curPoint)
    {
        //座標誤差
        double _x_offset = (curPoint.x - BottomRightPoint.position.x) * x_offset / x_w_offset;
        double _z_offset = (curPoint.z - TopLeftPoint.position.z) * z_offset / z_w_offset;
        double resultX = _x_offset + BottomRightSai.x;
        double resultZ = _z_offset + TopLeftSai.y;
        return new Vector2((float)resultX, (float)resultZ);
    }
複製代碼

到這裏在Unity中經緯度轉和世界座標互轉的功能就實現了,若是還有不明白的能夠多研究下代碼,其實原理仍是很好理解的,案例源代碼會在以後整理好以後放出。

注意

此案例功能比較單一,精準度因爲float和double之間的轉換,會有些許誤差,介意的同窗請繞道。

寫在最後

總體項目案例會在後期整理好以後分享給你們,若有錯誤之處還請多多指出。

相關文章
相關標籤/搜索