安装模块

pip install pyserial
pip install serial

完整代码

# 导入模块
import os
from time import sleep
from serial import Serial
from serial.tools import list_ports
from math import sqrt, fabs, sin, cos, atan2, radians, asin, degrees# 电脑串口
def computer_Port1():os.system('cls')print("程序开始运行")serial_port_list = list(list_ports.comports())if len(serial_port_list) <= 0:print('未发现可用串口')else:for i in range(len(serial_port_list)):print(serial_port_list[i])port_gps = 'com' + input('请输入GPS模块所在串口:')ser = Serial(port_gps, 9600, timeout=2)# ser = Serial('com9', 9600, timeout=2)print("串口连接成功")return ser# 树莓派串口
def linux_Port2():print("程序开始运行")ser = Serial("/dev/ttyUSB0", 9600, timeout=1)  # todo 树莓派串口print("串口连接成功")return ser# 遍历ser,对应的帧头,按顺序排列好gps字符串
def get_array_Str(get_Str):""":param get_Str:传入gps字符串:return 返回按顺序排列好的gps字符串"""get_Str_Pro = ['$GPRMC', '$GPVTG', '$GPGGA', '$GPGSA']for List in get_Str:if List.split(',')[0] == '$GPRMC' in List:  # List.split(',')[0]  按逗号切片,然后查找(第0个数据 = '$GPRMC)的字符串get_Str_Pro[0] = List  # 等于就将该字符串排在get_Str_Pro列表的第0个位置elif List.split(',')[0] == '$GPVTG' in List:get_Str_Pro[1] = Listelif List.split(',')[0] == '$GPGGA' in List:get_Str_Pro[2] = Listelif List.split(',')[0] == '$GPGSA' in List:get_Str_Pro[3] = Listreturn get_Str_Pro# gps_$GPRMC解析
def gprmc_Parsing(gprmc_Str):""":param gprmc_Str:传入gprmc字符串:return: 卫星定位有效时返回解析后的数据列表 卫星定位无效时返回gprmc源数据"""source_data = str(gprmc_Str)gprmc_Str = gprmc_Str.split(',')  # 按','切片if gprmc_Str[2] == 'V':print('当前卫星定位无效')print('源数据:' + source_data + '\n')  # 定位无效时打印源数据return source_data  # 定位无效返回源数据elif gprmc_Str[2] == 'A':# --------------------------------------------# 北京时间hour = int(gprmc_Str[1][0:2]) + 8  # 时if hour >= 24:# 防止超过24hour = hour % 24  # %-取模-返回除法的余数minute = int(gprmc_Str[1][2:4])  # 分second = int(gprmc_Str[1][4:6])  # 秒millisecond = int(gprmc_Str[1][7:10])  # 毫秒year = int(gprmc_Str[9][4:6]) + 2000  # 年month = int(gprmc_Str[9][2:4])  # 月day = int(gprmc_Str[9][0:2])  # 日time_Pro1 = '%d-%.2d-%.2d' % (year, month, day)  # 年月日time_Pro2 = '%.2d:%.2d:%.2d' % (hour, minute, second)  # 时分秒  # %.2d向前补几位数# print(time_Pro1, time_Pro2)  # 打印日期,时间# ---------------------------------------------# 速度speed = float(gprmc_Str[7]) * 1.852  # 海里/时,单位是节# print('速度(km/h):' + '%.2f' % speed)  # 1海里=1.852公里(千米) (中国标准)# ---------------------------------------------# 航向angle = float(gprmc_Str[8])  # 偏离正北的角度# print('航向(度):' + str(angle))# ---------------------------------------------# WGS84  经纬度 十进制 latitude-纬度  longitude-经度WGS84_lat = float('%.6f' % (int(gprmc_Str[3][0:2]) + float(gprmc_Str[3][2:11]) / 60))WGS84_lon = float('%.6f' % (int(gprmc_Str[5][0:3]) + float(gprmc_Str[5][3:12]) / 60))# print('WGS-84: ' + '%.7f' % WGS84_lat + ',' + '%.7f' % WGS84_lon)  # %.7f - 7f表示有7位小数def print_Pro():"""打印各类数据:return: 无返回值"""print('定位正常')print(time_Pro1, time_Pro2)  # 打印日期,时间print('速度(km/h):' + '%.2f' % speed)  # 速度print('航向(度):' + str(angle))  # 打印航向print('WGS-84坐标: ' + '%.6f' % WGS84_lat + ',' + '%.6f' % WGS84_lon)  # 打印经纬度print_Pro()gprmc_Parsing_Result = [time_Pro1, time_Pro2, speed, angle, WGS84_lat, WGS84_lon]  # 解析后的数据列表# print(gprmc_Parsing_Result)return gprmc_Parsing_Result# WGS84坐标系转火星坐标系(GCJ-02)
def wgs84_to_gcj02(WGS84_lat, WGS84_lng):"""WGS84坐标系转火星坐标系(GCJ-02)Google Earth、中国外的Google Map——>谷歌(中国内), 高德地图:param WGS84_lng: WGS84坐标系的经度:param WGS84_lat: WGS84坐标系的纬度:return:"""pi = 3.1415926535897932384626  # πa = 6378245.0  # 长半轴ee = 0.00669342162296594323  # 偏心率平方def _transformlat(lng, lat):"""WGS84坐标系转火星坐标系(GCJ-02)时 需要用到:param lng::param lat::return:"""ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * sqrt(fabs(lng))ret += (20.0 * sin(6.0 * lng * pi) + 20.0 * sin(2.0 * lng * pi)) * 2.0 / 3.0ret += (20.0 * sin(lat * pi) + 40.0 * sin(lat / 3.0 * pi)) * 2.0 / 3.0ret += (160.0 * sin(lat / 12.0 * pi) + 320 * sin(lat * pi / 30.0)) * 2.0 / 3.0return retdef _transformlng(lng, lat):"""WGS84坐标系转火星坐标系(GCJ-02)时 需要用到:param lng::param lat::return:"""ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * sqrt(fabs(lng))ret += (20.0 * sin(6.0 * lng * pi) + 20.0 * sin(2.0 * lng * pi)) * 2.0 / 3.0ret += (20.0 * sin(lng * pi) + 40.0 * sin(lng / 3.0 * pi)) * 2.0 / 3.0ret += (150.0 * sin(lng / 12.0 * pi) + 300.0 * sin(lng / 30.0 * pi)) * 2.0 / 3.0return retdlat = _transformlat(WGS84_lng - 105.0, WGS84_lat - 35.0)dlng = _transformlng(WGS84_lng - 105.0, WGS84_lat - 35.0)radlat = WGS84_lat / 180.0 * pimagic = sin(radlat)magic = 1 - ee * magic * magicsqrtmagic = sqrt(magic)dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)dlng = (dlng * 180.0) / (a / sqrtmagic * cos(radlat) * pi)GCJ02_lat = float('%.6f' % (WGS84_lat + dlat))GCJ02_lng = float('%.6f' % (WGS84_lng + dlng))return [GCJ02_lat, GCJ02_lng]# 火星坐标系(GCJ-02)转百度坐标系(BD-09)
def gcj02_to_bd09(GCJ02_lat, GCJ02_lng):"""火星坐标系(GCJ-02)转百度坐标系(BD-09)谷歌(中国内)、高德——>百度:param GCJ02_lng: 火星坐标经度:param GCJ02_lat: 火星坐标纬度:return:"""x_pi = 3.14159265358979324 * 3000.0 / 180.0z = sqrt(GCJ02_lng * GCJ02_lng + GCJ02_lat * GCJ02_lat) + 0.00002 * sin(GCJ02_lat * x_pi)theta = atan2(GCJ02_lat, GCJ02_lng) + 0.000003 * cos(GCJ02_lng * x_pi)BD09_lng = float('%.6f' % (z * cos(theta) + 0.0065))BD09_lat = float('%.6f' % (z * sin(theta) + 0.006))return [BD09_lat, BD09_lng]# 用haversine公式计算球面两点间的距离
def get_distance_hav(lat0, lng0, lat1, lng1):"""1.用haversine公式计算球面两点间的距离(单位:m)。2.传入坐标为基于WGS-84标准,为Google Earth上的经纬度。:param lat0: 起点_纬度:param lng0: 起点_经度:param lat1: 终点_纬度:param lng1: 终点_经度:return: 返回两点间的直线距离"""EARTH_RADIUS = 6371  # 地球平均半径,6371kmdef hav(theta):s = sin(theta / 2)return s * s# 经纬度转换成弧度lat0 = radians(lat0)lat1 = radians(lat1)lng0 = radians(lng0)lng1 = radians(lng1)dlng = fabs(lng0 - lng1)dlat = fabs(lat0 - lat1)h = hav(dlat) + cos(lat0) * cos(lat1) * hav(dlng)distance = 2 * EARTH_RADIUS * asin(sqrt(h)) * 1000return distance# 已知两个点的经纬度,求它们的方位角
def get_Degree(lat0, lng0, lat1, lng1):"""1.已知两个点的经纬度,求它们的方位角2.传入坐标为基于WGS-84标准,为Google Earth上的经纬度。:param lat0: 起点_纬度:param lng0: 起点_经度:param lat1: 终点_纬度:param lng1: 终点_经度:return: 返回两点间的直线距离"""radLat0 = radians(lat0)radLng0 = radians(lng0)radLat1 = radians(lat1)radLng1 = radians(lng1)dLon = radLng1 - radLng0y = sin(dLon) * cos(radLat1)x = cos(radLat0) * sin(radLat1) - sin(radLat0) * cos(radLat1) * cos(dLon)brng = degrees(atan2(y, x))brng = (brng + 360) % 360return brng# 主函数
def mian(ser):i = 2while True:if ser.in_waiting > 0:sleep(0.6)  # todo 请在0.4-0.8范围内调试修改, 过低数据不完整,过高数据被覆盖!get_Strs = ser.read(ser.in_waiting)get_Str = get_Strs.decode()  # decode() 方法以 encoding 指定的编码格式解码字符串。默认编码为字符串编码。get_Str = get_Str.split('\r\n')  # 按'\r\n'切片# 排列顺序a = get_array_Str(get_Str=get_Str)# 跳过前3次数据if i:i -= 1print('稳定串口接收中:%d' % i)continue# 解析GPRMC数据b = gprmc_Parsing(gprmc_Str=a[0])# 判断:是否定位无效if not isinstance(b, str):  # 判断'b'类型是'str'# 转换为百度坐标c = wgs84_to_gcj02(WGS84_lat=b[4], WGS84_lng=b[5])# 转换为百度坐标d = gcj02_to_bd09(GCJ02_lat=c[0], GCJ02_lng=c[1])print(d)# 求距离e = get_distance_hav(lat0=b[4], lng0=b[5], lat1=22.8964558, lng1=113.8578790)print(e, '米')# 求方位角f = get_Degree(lat0=b[4], lng0=b[5], lat1=22.8964558, lng1=113.8578790)print(f, '度')# 测试
def test():a = '$GPRMC,152151.500,A,2251.41921,N,11350.25453,E,005.0,002.0,010821,,,A*6F'# 解析GPRMC数据b = gprmc_Parsing(gprmc_Str=a)# print('WGS84坐标', b[4], b[5])# 转换为高德坐标c = wgs84_to_gcj02(WGS84_lat=b[4], WGS84_lng=b[5])print('高德坐标:', c[0], c[1])# 转换为百度坐标d = gcj02_to_bd09(GCJ02_lat=c[0], GCJ02_lng=c[1])print('百度坐标:', d[0], d[1])# 求距离e = get_distance_hav(lat0=b[4], lng0=b[5], lat1=22.8964558, lng1=113.8578790)print('距下一点', e, '米')# 求方位角f = get_Degree(lat0=b[4], lng0=b[5], lat1=22.8964558, lng1=113.8578790)print('与下一点', f, '度')if __name__ == '__main__':# mian(ser=computer_Port1())test()

结果输出

定位正常
2021-08-01 23:21:51
速度(km/h):9.26
航向(度):2.0
WGS-84坐标: 22.856987,113.837575
高德坐标: 22.854084 113.842583
百度坐标: 22.859956 113.849115
距下一点 4856.732170504513 米
与下一点 25.355519084457796 度

python GPS解析,坐标转换,两经纬度直线距离,方位角相关推荐

  1. 如何使用sql语句算两经纬度的距离

    本文章转载于https://segmentfault.com/a/1190000013922206 经纬度计算距离公式 对以上公式描述 1.Lung1 Lat1表示A点经纬度, Lung2 Lat2表 ...

  2. python计算两经纬度坐标距离和角度以及给定第一个坐标、距离和航向角计算第二个坐标

    总结三个坐标相关公式 因为需要用到三角函数,导入math库 import math 两个坐标计算距离的函数 def distance(Alongitude, Alatitude, Blongitude ...

  3. 两个坐标的距离C语言,计算两个经纬度直线距离 安卓app开发

    .Net计算方式 public static class CCalculationGPSCoordinateDistance { private const double dEARTH_RADIUS ...

  4. python通过两点之间的经纬度测算距离

    首先是公式,百度即可知道,需要注意的点是python中不能直接使用三角函数,需要import math库,并且在三角函数中输入的变量并不是角度,而是弧度,由于经纬度从某种意义上来说是角度,所以要换算成 ...

  5. 【华为OD机试真题 python】数轴上两个点集距离

    题目描述 同一个数轴x有两个点的集合A={A1,A2,-,Am}和B={B1,B2,-,Bm},A(i)和B(j)均为正整数.A.B已经按照从小到大排好序,A.B均不为空.给定一个距离R 正整数,列出 ...

  6. python中用plot绘制两条直线_在Matplotlib中绘制两条直线之间角度的最佳方法

    您可以使用^{}绘制相应角度度量值的弧. 绘制角弧: 定义一个函数,该函数可以接受2matplotlib.lines.Line2D个对象,计算角度并返回一个matplotlib.patches.Arc ...

  7. 两经纬度之间的距离计算

    以下是计算两经纬度之间距离的代码,分为:头文件.源代码和测试代码三部分. 具体如下: 1 // LatLonDistanceDlg.h : 头文件 2 // 3 4 #pragma once 5 6 ...

  8. PostgreSQL(PgSQL)根据经纬度计算距离

    今天在使用PostgreSQL的PostGIS功能来实现根据经纬度计算距离和计算某一经纬度附近X米之内的地点,发现了一些错误,实现SQL语句和更正的语句如下: 计算两经纬度之间距离: select S ...

  9. 算法提高 两条直线(二分法 + 枚举)

    试题 算法提高 两条直线 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定平面上n个点. 求两条直线,这两条直线互相垂直,而且它们与x轴的夹角为45度,并且n个点中离这两条直线的 ...

最新文章

  1. 【LeetCode OJ】Same Tree
  2. linux消息信号丢失,Linux信号丢失问题分析
  3. 旧文重发:做人、做事,做架构师——架构师能力模型解析
  4. centos 6.3 x86_64安装32位JDK的问题
  5. java 安卓视频播放器_java - 学习做一个安卓视频播放器,有一些小问题!忘大家请教...
  6. IntelliJ IDEA激活破解有效方法
  7. 反射类 Method类的使用
  8. MT2503芯片平台方案开发项目资料介绍
  9. 基于AP6212实现 Airkiss NDK编程
  10. WebLog(网页日志)的数据分析之uv(独立访客数)
  11. VLAN隔离技术 — MUX VLAN
  12. 贵阳市交通大数据中心
  13. consonant combination
  14. 关于win11右键的慢问题的建议
  15. 浅谈CMMI3认证从评估前准备到正式评估的全部过程
  16. 最优化理论极简入门(第一部分):最优化条件和KKT条件
  17. 华硕服务器 u盘安装系统,华硕台式机一键U盘装系统win7教程
  18. python实现微信hook_GitHub - zhouxionger/wechathook: 借助微信hook,拦截修改某些call,填充进我们的Python代码,进行微信公众号文章的爬取...
  19. html给页面添加艺术型边框,如何为2016word的页面设置艺术型页面边框
  20. python代码风格指南_记录Python代码:完整指南

热门文章

  1. 古墓丽影暗影显卡测试软件,游戏新消息:战地5古墓丽影暗影8K测试单显卡根本带不动...
  2. Python3脚本抢票
  3. Good Luck in CET-4 Everybody! (巴什博弈 bash game)
  4. 写一个函数,实现 n 的阶乘
  5. MacBook 连接投影仪
  6. Ubuntu11.10安装科磊NW336驱动
  7. 泥瓦匠想做一个与众不同的技术匠
  8. 泥瓦匠聊并发编程基础篇:线程中断和终止
  9. BP神经网络(Back Propagation Neural Network)Matlab简单实现
  10. 微信看一看小程序视频缓存到手机的位置