Python学习:利用python解析GPS模块数据,并生成可视化地图显示

一、GPS模块数据格式

        笔者在项目中使用过移远L76K以及梦芯MXT905HM两款GPS定位芯片,两款芯片均是采用串口输出数据,而且数据包采用的是NEMA协议消息结构,消息结构如下:

 数据包格式如下:

$GNTXT,01,01,02,ANTSTATUS=OPEN*35
$GNRMC,032323.000,A,3028.123102,N,11423.526968,E,0.682,113.01,210622,,E,A,V*7E
$GNVTG,113.01,T,,M,0.682,N,1.263,K,A*2B
$GNGGA,032323.000,3028.123102,N,11423.526968,E,1,10,1.05,68.932,M,-13.78,M,,*5B
$GNGSA,A,3,01,03,14,19,30,194,195,,,,,,1.77,1.05,1.42,1*0E
$GNGSA,A,3,01,04,28,,,,,,,,,,1.77,1.05,1.42,4*09
$GPGSV,2,1,08,01,18,044,27,03,42,066,45,06,,,22,14,72,167,18,1*59
$GPGSV,2,2,08,19,43,318,27,30,11,196,23,194,45,154,38,195,66,053,40,1*69
$GBGSV,1,1,04,01,42,130,37,04,30,115,34,28,56,016,40,33,,,12,1*4F
$GNGLL,3028.123102,N,11423.526968,E,032323.000,A,A*4D

二、应用说明        

        实际应用中需要根据GPS坐标信息得到设备分布位置,以及根据相邻位置坐标获取设备移动距离,这里使用python对GPS模块输出的位置坐标信息进行提取,并使用python库对坐标位置进行描点,生成设备位置分布图,根据前后两点的坐标计算出设备移动的距离

 1、python解析数据

        使用串口助手将GPS模组数据提取出来,并保存为gps.txt文档,放到python脚本目录下。编写程序提取坐标信息

def create_float_value(tmpfloat):
    intPart = 0.0
    fractPart = 0.0
    fractPart, intPart = math.modf(tmpfloat)
    #print(fractPart, intPart)
    tempVal1 = int(intPart / 100)
    tempVal2 = int(intPart % 100)
    tempVal3 = tempVal2 + fractPart
    tempVal4 = tempVal3 / 60.0
    tempVal5 = tempVal1 + tempVal4
    return tempVal5


fp = open("gps.txt", 'r')
lines = fp.readlines()
line_num = 0
longitude_list = []
latitude_list = []
for line in lines:
    if line[:6] == '$GNGLL':
        longitude_list.append(create_float_value(float(line.split(',')[3])))
        latitude_list.append(create_float_value(float(line.split(',')[1])))
    else:
        continue

函数create_float_value():浮点数转换函数,模块回复数据中的坐标采用ddmm.mmmmm格式,需要转换成度.分的浮点数据

将数据提取到列表中,分别对应经度和纬度

 2、使用folium库将数据展示出来

        folium库可将WGS-84坐标直接带入使用,模块回复数据也是WGS-84坐标,所以直接带入调试。这里笔者使用的是pycharm,安装folium库非常方便。

import folium

map_info = folium.Map(location=[30.2813, 114.2352], zoom_start=12, control_scale=True)
for longitude, latitude in zip(longitude_list, latitude_list):
    folium.Circle((latitude, longitude), radius=7, color='yellow', fill=True,
                  fill_color='red', fill_opacity=0.7).add_to(map_info)
lenth = len(longitude_list)
for i in range(lenth):
    folium.Marker(location=[latitude_list[i], longitude_list[i]], popup='点',
                  icon=folium.Icon(icon='cloud')).add_to(map_info)
map_info.add_child(folium.LatLngPopup())
map_info.save('gps.html')

        这里笔者将所有点用同一个图标在地图上显示出来,所以实际效果中图标大部分重合在一起,有兴趣的朋友可以自行去修改,显示不同的点,最后生成一个html格式的网页文件,用浏览器打开即可看到分布

3、坐标系转换 

        在验证坐标准确性的时候,笔者使用的是百度坐标拾取系统, 但是模块输出的并非百度坐标系,所以需要用算法去转换,这里笔者参考网上资料(C语言)常用的几种在线地图(天地图、百度地图、高德地图)坐标系之间的转换算法_四域公子的博客-CSDN博客_天地图坐标系自行编写了python函数来实现坐标转换,先调用transform_both_all(),之后再调用mars_to_baidu(),即可获得百度坐标,笔者实测,转换后的坐标在百度拾取系统中基本一致(存在浮点数计算的误差),有兴趣的朋友可以自行去计算误差,然后补偿

import math
import os

PI = 3.14159265358979324
ax = 6378245.0
ee = 0.00669342162296594323
x_pi = 52.3598775598298873

def outofChina(lat, lon):
    if (lon < 72.004 or lon > 137.8347) and (lat < 0.8293 or lat > 55.8271):
        return True
    else:
        return False


def mars_to_baidu(longtide, latitude):
    baidu_long = 0.0
    baidu_lati = 0.0
    z = math.sqrt(longtide*longtide + latitude*latitude) + 0.00002 * math.sin(latitude * x_pi)
    theta = math.atan2(latitude, longtide) + 0.000003 * math.cos(longtide * x_pi)
    baidu_long = z * math.cos(theta) + 0.0065
    baidu_lati = z * math.sin(theta) + 0.006
    return baidu_long, baidu_lati

def transformLat(x , y):
    ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(math.fabs(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.0 * math.sin(y * PI / 30.0)) * 2.0 / 3.0
    return ret

def transformLon(x, y):
    ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(math.fabs(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

def transform_both_all(wgLat, wgLon):
    trans_long = 0.0
    trans_lati = 0.0
    if outofChina(wgLat, wgLon):
        trans_long = wgLon
        trans_lati = wgLat
        return 0, 0
    dLat = transformLat(wgLon - 105.0, wgLat - 35.0)
    dLon = transformLon(wgLon - 105.0, wgLat - 35.0)
    radLat = wgLat / 180.0 * PI
    magic = math.sin(radLat)
    magic_2 = 1 - ee * magic * magic
    sqrtMagic = math.sqrt(magic_2)
    dLat_2 = (dLat * 180.0) / ((ax * (1 - ee)) / (magic_2 * sqrtMagic) * PI)
    dLon_2 = (dLon * 180.0) / (ax / sqrtMagic * math.cos(radLat) * PI)
    trans_lati = wgLat + dLat_2
    trans_long = wgLon + dLon_2
    return trans_long, trans_lati

4、相邻坐标换算距离

        已知两个点的经纬度坐标信息,计算两个点之间的距离,笔者用同一位置模块输出位置信息测试,传入相邻点的位置信息,计算出来的距离(KM),参考代码:根据坐标经纬度计算两点之间的距离_weixin_33696106的博客-CSDN博客

def ConvertDegreesToRadians(degrees):
    return degrees * PI / 180.0

def ConvertRadiansToDegrees(radian):
    return radian * 180.0 / PI

def HaveSin(theta):
    val = math.sin(theta / 2)
    return val * val

def Long_Lati_Distance(lat1, long1, lat2, long2):
    earth_radius = 6371.0
    temp_lat_1 = ConvertDegreesToRadians(lat1)
    temp_lon_1 = ConvertDegreesToRadians(long1)
    temp_lat_2 = ConvertDegreesToRadians(lat2)
    temp_lon_2 = ConvertDegreesToRadians(long2)

    vLon = math.fabs(temp_lon_1 - temp_lon_2)
    vLat = math.fabs(temp_lat_1-temp_lat_2)

    high = HaveSin(vLat) + math.cos(temp_lat_1) * math.cos(temp_lat_2) * HaveSin(vLon)
    distance = 2 * earth_radius * math.asin(math.sqrt(high))
    return distance

完整代码:python提取gps数据,利用folium库生成位置分布图,包含百度坐标转换以及两点距离换算函数-智慧城市文档类资源-CSDN下载

  • 5
    点赞
  • 87
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值