何为大地坐标,何为火星坐标,在地图上如何使用-----来自无人机应用的实战
程序员文章站
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;
}
}
动动你的小手收藏下吧!也算有我一点功劳,集前人之经验,验证并整理!