1. 程式人生 > >何為大地座標,何為火星座標,在地圖上如何使用-----來自無人機應用的實戰

何為大地座標,何為火星座標,在地圖上如何使用-----來自無人機應用的實戰

火星座標?(百度)

是一種國家保密外掛,也叫做加密外掛或者加偏或者SM模組,其實就是對真實座標系統進行人為的加偏處理,按照特殊的演算法,將真實的座標加密成虛假的座標,而這個加偏並不是線性的加偏,所以各地的偏移情況都會有所不同。而加密後的座標也常被人稱為火星座標系統

所有的電子地圖、導航裝置,都需要加入國家保密外掛。第一步,地圖公司測繪地圖,測繪完成後,送到國家測繪局,將真實座標的電子地圖,加密成“火星座標”,這樣的地圖才是可以出版和釋出的,然後才可以讓GPS公司處理。第二步,所有的GPS公司,只要需要汽車導航的,需要用到導航電子地圖的,都需要在軟體中加入國家保密演算法,將COM口讀出來的真實的座標訊號,加密轉換成國家要求的保密的座標。這樣,GPS導航儀和導航電子地圖就可以完全匹配,GPS也就可以正常工作了。

大地座標?

大地座標(Geodetic coordinate)是大地測量中以參考橢球面為基準面的座標,地面點P的位置用大地經度L、大地緯度B和大地高H表示。大地座標多應用於大地測量學,測繪學等。

好了基礎的我們都能百度,Google 的到!重點在下面,其實這篇文章與其說是原創,倒不是說是整理,在我工作的專案中,同時用到了高德地圖(Amap),和谷歌地圖(Google map),並且需要和飛機進行互動,做進一步的開發。之所以談到座標系,是因為飛機的GPS定位模組都是採用大地座標,真實的座標來定位的。因此在和APP 互動的時候避免不了要轉來轉去的。並且這些轉換方法是經過驗證可行

的!所以看到這篇文章趕緊收藏把!內部的原理我也是略懂!略懂!哈哈~

我在程式碼中註釋的特別清楚,火星轉大地大地轉火星

/**
 * <P>shang ps: 高德地圖用的始終是火星座標,飛機定位是大地座標</P>
 * <P>大地座標:是國際統一定義並使用</P>
 * <P>火星座標:為了保障國家的隱私,中國定義了火星座標</P>
 */
public class GPSTranslateGuide {

    static double pi = 3.14159265358979324;//pai
    static double a = 6378245.0;//地球半徑
    static double ee = 0.00669342162296594323;


    /**
     * <P>接受到航點的座標並顯示於地圖 </P>
     * <P>高德地圖座標轉換</P>
     * <P>大地座標轉換火星座標(中國座標)</P>
     * @param wgLat
     * @param wgLon
     * @return
     */
    public static com.amap.api.maps.model.LatLng AmapTransform(double wgLat, double wgLon) {

        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = wgLat + dLat;
        double mgLon = wgLon + dLon;

        com.amap.api.maps.model.LatLng latLng = new com.amap.api.maps.model.LatLng(mgLat, mgLon);

        return latLng;

    }

    /**
     * <P>接受到航點的座標並顯示於地圖 </P>
     * <P>Google 地圖轉換 </P>
     * <P>大地座標轉換火星座標</P>
     * @param wgLat
     * @param wgLon
     * @return
     */
    public static com.google.android.gms.maps.model.LatLng GoogleTransform(double wgLat, double wgLon) {

        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = wgLat + dLat;
        double mgLon = wgLon + dLon;

        com.google.android.gms.maps.model.LatLng latLng = new com.google.android.gms.maps.model.LatLng(mgLat, mgLon);

        return latLng;

    }

    //轉換經緯度地緯度
    static double transformLat(double x, double y) {
        double ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(y * pi) + 40.0 * Math.sin(y / 3.0 * pi)) * 2.0 / 3.0;
        ret += (160.0 * Math.sin(y / 12.0 * pi) + 320 * Math.sin(y * pi / 30.0)) * 2.0 / 3.0;
        return ret;
    }

    //轉換經緯度的緯度
    static double transformLon(double x, double y) {
        double ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
        ret += (20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0 / 3.0;
        ret += (20.0 * Math.sin(x * pi) + 40.0 * Math.sin(x / 3.0 * pi)) * 2.0 / 3.0;
        ret += (150.0 * Math.sin(x / 12.0 * pi) + 300.0 * Math.sin(x / 30.0 * pi)) * 2.0 / 3.0;
        return ret;
    }


    /**
     * 高德
     * <p>GCJ02座標系:即火星座標系</p>
     * <p>WGS座標系:即地球座標</p>
     * <p>火星座標轉地球座標</p>
     * @param lon
     * @param lat
     * @return
     */
    public static com.amap.api.maps.model.LatLng gcj2wgs(double lon, double lat) {
        double lontitude = lon
                - (((Double) transformtoWGS(lon, lat).get("lon")).doubleValue() - lon);
        double latitude = (lat - (((Double) (transformtoWGS(lon, lat))
                .get("lat")).doubleValue() - lat));

        com.amap.api.maps.model.LatLng latLng = new com.amap.api.maps.model.LatLng(latitude, lontitude);
        return latLng;
    }

    /**
     * <p>(地球)大地座標</p>
     *
     * @param lon
     * @param lat
     * @return
     */
    public static Map<String, Double> transformtoWGS(double lon, double lat) {
        HashMap<String, Double> localHashMap = new HashMap<String, Double>();
        double dLat = transformLat(lon - 105.0, lat - 35.0);
        double dLon = transformLon(lon - 105.0, lat - 35.0);
        double radLat = lat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = lat + dLat;
        double mgLon = lon + dLon;
        localHashMap.put("lon", mgLon);
        localHashMap.put("lat", mgLat);
        return localHashMap;
    }
    /**
     *谷歌
     * <P>火星座標轉大地座標</P>
     * @param lon
     * @param lat
     * @return
     */
    public static com.google.android.gms.maps.model.LatLng gcj_To_wgs84(double lon, double lat) {
        double lontitude = lon
                - (((Double) transformtoWGS(lon, lat).get("lon")).doubleValue() - lon);
        double latitude = (lat - (((Double) (transformtoWGS(lon, lat))
                .get("lat")).doubleValue() - lat));
        com.google.android.gms.maps.model.LatLng latLng = new com.google.android.gms.maps.model.LatLng(latitude, lontitude);
        return latLng;
    }

    /**
     * @anthor yuhao
     * 大地座標轉火星座標
     * @param wgLat
     * @param wgLon
     * @return
     */
    public static LatLng transform2Mars(double wgLat, double wgLon)
    {
        double dLat = transformLat(wgLon - 105.0, wgLat - 35.0);
        double dLon = transformLon(wgLon - 105.0, wgLat - 35.0);
        double radLat = wgLat / 180.0 * pi;
        double magic = Math.sin(radLat);
        magic = 1 - ee * magic * magic;
        double sqrtMagic = Math.sqrt(magic);
        dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi);
        dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * pi);
        double mgLat = wgLat + dLat;
        double mgLon = wgLon + dLon;
        LatLng latLng = new LatLng(mgLat, mgLon);
        return latLng;
    }

}
動動你的小手收藏下吧!也算有我一點功勞,集前人之經驗,驗證並整理!