欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

何为大地坐标,何为火星坐标,在地图上如何使用-----来自无人机应用的实战

程序员文章站 2022-04-04 12:54:20
...

火星坐标?(百度)

是一种国家保密插件,也叫做加密插件或者加偏或者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;
    }

}
动动你的小手收藏下吧!也算有我一点功劳,集前人之经验,验证并整理!