在淘宝买的ATGM336H
用串口工具在室外读取了下面的数据
这些字符串是GPS定位设备输出的NMEA 0183格式的数据。
NMEA 0183是一种用于在船舶、飞机和其他移动设备中传输位置、速度和时间等信息的标准协议。
$BDGSV,39,,,27*62 22:29:38.654
$GNRMC,142939.000,A,3036.7460,K,A*23 22:29:38.754
$GNZDA,142939.000,31,03,2024,00,00*49 22:29:38.858
$GPTXT,01,01,0
$GNGGA,142940.000,3036.74671,N,10408.54235,E,1,07,1.2,573.5,M,0.0,M,,*75 22:29:38.958
$GNGLL,3036.74671,N,10408.54235,E,142940.000,A,A*40 22:29:39.061
$GPGSA,A,3,05,15,20,23,29,195,,,,,,,2.2,1.2,1.9*0D 22:29:39.161
$BDGSA,A,3,19,,,,,,,,,,,SV,3,1,09,05,33,064,32,10,,,27,13,40,04,216,37*48 22:29:39.263 -> $GPGSV,3,3,09,195,42,139,19*78 22:29:39.366
$BDGSV,1,1,04,02,,,33,09,,,29,19,45,275,33,39,,,27*5A 22:29:39.468
$GNRMC,142940.000,A,3036.74671,N,10408.54235,E,0.00,0.00,310324,,,A*70
比较有用的是GNGGA,有经纬度,有卫星数,有海拔之类的信息
但是他使用的数据需要转换先转换成WGS84再转换成GCJ02
而百度地图/高德地图的一般接受GCJ02
1.获取对应串口数据的经纬度(这里是C代码)
//主要是靠索引来查询找到数据
void GPSTask(void *parameter){for(;;){delay(100); String GpsMsg=Serial2.readStringUntil('\n');Serial.println(GpsMsg);int isIndex=GpsMsg.indexOf("$GNRMC");if (isIndex==-1){continue;}lon = extractLongitude(GpsMsg);lat = extractLatitude(GpsMsg);}
}// 提取经度信息
float extractLongitude(String nmea) {int pos = 0; // 找到第一个逗号的位置for (int i = 0; i < 5; i++) {pos = nmea.indexOf(",", pos) + 1; // 找到第三个逗号的位置if (pos==-1){return 0;}}String longitudeStr = nmea.substring(pos, nmea.indexOf(",", pos));if (longitudeStr==""){return 0;}float longitude = longitudeStr.toFloat();return longitude;
}// 提取纬度信息
float extractLatitude(String nmea) {int pos = 0; // 找到第一个逗号的位置for (int i = 0; i < 3; i++) {pos = nmea.indexOf(",", pos) + 1; // 找到第五个逗号的位置if (pos==-1){return 0;}}String latitudeStr = nmea.substring(pos, nmea.indexOf(",", pos));if (latitudeStr==""){return 0;}float latitude = latitudeStr.toFloat();return latitude;
}
2.将串口的数据转成WGS84
public static double[] SerialtoWGS84(String lng, String lat) {int lngIndex = lng.indexOf(".") - 2;int latIndex = lat.indexOf(".") - 2;if (lngIndex < 0 || latIndex < 0){return null;}double lngDouble1 = Double.parseDouble(lng.substring(0, lngIndex));double lngDouble2 = Double.parseDouble(lng.substring( lngIndex));double lngDouble = lngDouble1 + lngDouble2 / 60;double latDouble1 = Double.parseDouble(lat.substring(0, latIndex));double latDouble2 = Double.parseDouble(lat.substring( latIndex));double latDouble = latDouble1 + latDouble2 / 60;if (lngDouble > 0 && latDouble > 0){return new double[]{lngDouble, latDouble};}return null;}
3.将WGS84的数据转成GCJ02
public static double ee = 0.00669342162296594323; //偏心率平方public static double a = 6378245.0;// # 长半轴/*** GPS84转GCJ02(火星坐标系)** @param lng_wgs WGS84坐标系的经度* @param lat_wgs WGS84坐标系纬度* @return 转换后的GCJ02下经纬度*/public static double[] WGS84toGCJ02(double lng_wgs, double lat_wgs) {if (outOfChina(lng_wgs, lat_wgs)) {return new double[]{lng_wgs, lat_wgs};}double[] GCJ02 = new double[2];double dlat = transformlat(lng_wgs - 105.0, lat_wgs - 35.0);double dlng = transformlng(lng_wgs - 105.0, lat_wgs - 35.0);double radlat = lat_wgs / 180.0 * Math.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) * Math.PI);dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * Math.PI);double gcj_lat = lat_wgs + dlat;double gcj_lng = lng_wgs + dlng;GCJ02[0] = gcj_lng;GCJ02[1] = gcj_lat;return GCJ02;}private static double transformlat(double lng, double lat) {double ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat +0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 *Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lat * Math.PI) + 40.0 *Math.sin(lat / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (160.0 * Math.sin(lat / 12.0 * Math.PI) + 320 *Math.sin(lat * Math.PI / 30.0)) * 2.0 / 3.0;return ret;}private static double transformlng(double lng, double lat) {double ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng +0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));ret += (20.0 * Math.sin(6.0 * lng * Math.PI) + 20.0 *Math.sin(2.0 * lng * Math.PI)) * 2.0 / 3.0;ret += (20.0 * Math.sin(lng * Math.PI) + 40.0 *Math.sin(lng / 3.0 * Math.PI)) * 2.0 / 3.0;ret += (150.0 * Math.sin(lng / 12.0 * Math.PI) + 300.0 *Math.sin(lng / 30.0 * Math.PI)) * 2.0 / 3.0;return ret;}/*** 判断是否在国内,不在国内不做偏移** @param lng* @param lat* @return*/private static boolean outOfChina(double lng, double lat) {return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);}
WGS84:地球坐标系,是国际上通用的坐标系,设备一般包含GPS芯片或者北斗芯片获取的经纬度为WGS84地理坐标系GCJ02:火星坐标系,是由中国国家测绘局制订的地理信息系统的坐标系统。在中国使用的地图产品使用的都必须是加密后的坐标
-
$BDGSV,39,27*62 22:29:38.654:BDGSV表示北斗卫星的可见卫星信息,39表示总共有39颗卫星,但是这个字符串中没有提供具体的卫星信息。
-
$GNRMC,142939.000,A,3036.7460,K,A*23 22:29:38.754:GNRMC表示推荐的最小定位信息,142939.000表示定位时间,A表示定位有效,3036.7460表示纬度,K表示速度单位为千米/小时,A表示方向有效。
-
$GNZDA,142939.000,31,03,2024,00,00*49 22:29:38.858:GNZDA表示日期和时间信息,142939.000表示时间,31表示日期,03表示月份,2024表示年份,00表示本地时区的小时偏移量,00表示本地时区的分钟偏移量。
-
$GPTXT,01,01,0:GPTXT表示文本信息,这个字符串中没有提供具体的文本内容。
-
$GNGGA,142940.000,3036.74671,N,10408.54235,E,1,07,1.2,573.5,M,0.0,M,*75 22:29:38.958:GNGGA表示全球定位系统定位信息,142940.000表示定位时间,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,1表示定位质量指示,07表示使用的卫星数量,1.2表示水平精度因子,573.5表示海拔高度,M表示单位为米,0.0表示大地水准面的高度,M表示单位为米。
-
$GNGLL,3036.74671,N,10408.54235,E,142940.000,A,A*40 22:29:39.061:GNGLL表示地理定位信息,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,142940.000表示定位时间,A表示定位有效,A表示数据来源为GPS。
-
$GPGSA,A,3,05,15,20,23,29,195,2.2,1.2,1.9*0D 22:29:39.161:GPGSA表示GNSS DOP和活动卫星信息,A表示自动选择2D/3D定位模式,3表示定位模式为3D定位,05、15、20、23、29、195表示使用的卫星编号,2.2表示PDOP(位置精度因子),1.2表示HDOP(水平精度因子),1.9表示VDOP(垂直精度因子)。
-
$BDGSA,A,3,19,SV,3,1,09,05,33,064,32,10,27,13,40,04,216,3748 22:29:39.263 -> $GPGSV,3,3,09,195,42,139,1978 22:29:39.366:BDGSA表示北斗卫星的DOP和活动卫星信息,A表示自动选择2D/3D定位模式,3表示定位模式为3D定位,19表示使用的卫星编号,SV表示卫星编号的开始,3表示卫星编号的数量,1、09、05、33、064、32、10、27、13、40、04、216、37表示具体的卫星编号。
-
$BDGSV,1,1,04,02,33,09,29,19,45,275,33,39,27*5A 22:29:39.468:BDGSV表示北斗卫星的可见卫星信息,1表示总共有1颗卫星,1表示当前是第1个字符串,04表示总共有4个字符串,02、33、09、29、19、45、275、33、39、27表示具体的卫星信息。
-
$GNRMC,142940.000,A,3036.74671,N,10408.54235,E,0.00,0.00,310324,A*70:GNRMC表示推荐的最小定位信息,142940.000表示定位时间,A表示定位有效,3036.74671表示纬度,N表示北纬,10408.54235表示经度,E表示东经,0.00表示速度,0.00表示方向,310324表示日期,A表示数据来源为GPS。