GPS数据解析、可视化及经纬度距离计算

2023-05-16

一、GPS数据解析

根据NMEA协议,我们从传感器上接收到的GPS经纬度数据格式如下:

例:$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
字段0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息
字段1:UTC时间,hhmmss.sss格式
字段2:状态,A=定位,V=未定位
字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段4:纬度N(北纬)或S(南纬)
字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段6:经度E(东经)或W(西经)
字段7:速度,节,Knots
字段8:方位角,度
字段9:UTC日期,DDMMYY格式
字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
字段11:磁偏角方向,E=东W=西
字段12:模式,A=自动,D=差分,E=估测,N=数据无效(3.0协议内容)
字段13:校验值($与*之间的数异或后的值)

实际上Python已经有现成的库可以调用——pymea2

pip3 install pynmea2
import pynmea2

text = "$GNRMC,074733.00,A,2241.28818,N,11358.44210,E,3.866,,070720,,,A*60"
msg = pynmea2.parse(text)

msg
Out[6]: <RMC(timestamp=datetime.time(7, 47, 33), status='A', lat='2241.28818', lat_dir='N', lon='11358.44210', lon_dir='E', spd_over_grnd=3.866, true_course=None, datestamp=datetime.date(2020, 7, 7), mag_variation='', mag_var_dir='') data=['A']>
#输出维度
msg.latitude
Out[7]: 22.688136333333333
#输出经度
msg.longitude
Out[8]: 113.974035

#该函数主要针对整个文件的gps进行解析
def parse_file(file_path):
    txt_tables = []
    f = open(file_path, "r",encoding='utf-8')
    line = f.readline() # 读取第一行
    locations = []
    while line:
        text = line[11:]
        msg = pynmea2.parse(text)
        # print(msg.latitude)  #24.551053333333332
        # print(msg.longitude)  #118.1067375
        tmp = []
        if(msg.latitude == 0.0 or msg.longitude == 0.0):
            line = f.readline() # 读取下一行
            continue
        tmp.append(msg.latitude)
        tmp.append(msg.longitude)
        locations.append(tmp)
        line = f.readline() # 读取下一行
    return locations    

实际解析过程,待后续完善。

二、GPS可视化

这个功能真是强大的不行,主要也是通过python进行可视化。

我们得到如下gps地址,顺序为[纬度,经度]:

locations = [[22.674574, 113.993353], [22.674544, 113.993362], [22.674521, 113.993376], [22.67447, 113.99342], [22.674471, 113.993428], [22.674485, 113.993434], [22.674487, 113.993437], [22.674471, 113.993416], [22.674452, 113.993416], [22.674449, 113.993412], [22.674443, 113.993389], [22.674444, 113.993382], [22.67445, 113.993363], [22.67444, 113.993358], [22.67444, 113.993351], [22.67444, 113.993338], [22.674441, 113.993331], [22.674485, 113.993265], [22.674452, 113.993305], [22.674511, 113.99323], [22.674504, 113.993236], [22.674484, 113.99326], [22.674419, 113.993359], [22.67441, 113.993369], [22.674403, 113.993381], [22.674406, 113.993385], [22.674406, 113.993395], [22.674404, 113.993397], [22.674403, 113.9934], [22.674402, 113.993411], [22.6744, 113.993414], [22.674398, 113.993417], [22.674308, 113.993457], [22.674269, 113.99347], [22.67423, 113.99349], [22.674191, 113.993506], [22.674151, 113.993532], [22.674045, 113.993583], [22.673965, 113.993597], [22.673879, 113.993607], [22.673724, 113.993639], [22.673321, 113.993752], [22.673212, 113.993784], [22.673101, 113.993825], [22.672887, 113.993894], [22.672785, 113.993937], [22.672684, 113.993977], [22.672476, 113.994081], [22.672063, 113.994352], [22.671971, 113.994427], [22.671873, 113.994503], [22.67178, 113.994583], [22.671449, 113.994935], [22.671373, 113.995017], [22.671315, 113.995096], [22.671252, 113.995173], [22.671199, 113.995219], [22.671165, 113.99525], [22.671108, 113.995304], [22.671128, 113.995301], [22.671125, 113.995312], [22.671131, 113.995302], [22.671133, 113.995301], [22.671136, 113.99531], [22.671135, 113.995313], [22.671131, 113.995316], [22.671077, 113.995376], [22.671059, 113.995395], [22.671039, 113.995415], [22.670993, 113.995452], [22.670868, 113.995574], [22.670666, 113.995825], [22.67061, 113.995877], [22.670563, 113.995943], [22.670503, 113.996008], [22.670448, 113.996076], [22.670393, 113.996143], [22.670233, 113.996335], [22.670022, 113.996558], [22.669967, 113.996622], [22.669913, 113.996683], [22.669862, 113.996741], [22.669812, 113.996795], [22.669768, 113.996847], [22.669734, 113.996899], [22.669687, 113.996965], [22.669639, 113.997026], [22.669441, 113.997291], [22.669385, 113.997353], [22.669331, 113.997423], [22.669274, 113.997491], [22.669216, 113.997564], [22.66915, 113.997639], [22.668873, 113.997982], [22.668809, 113.998056], [22.668754, 113.998126], [22.668686, 113.998199], [22.668632, 113.998269], [22.668578, 113.998336], [22.66852, 113.998408], [22.668462, 113.998486], [22.668212, 113.998776], [22.668152, 113.998849], [22.668082, 113.998925], [22.667963, 113.999024], [22.667923000000002, 113.999077], [22.667784, 113.999228], [22.667669, 113.999349], [22.667521, 113.999529], [22.667482, 113.999574], [22.667442, 113.999625], [22.667401, 113.999676], [22.667358, 113.999724], [22.667321, 113.999774], [22.667283, 113.99982], [22.667246, 113.999863], [22.667209, 113.999906], [22.667169, 113.999947], [22.667128, 113.999992], [22.667085, 114.000046], [22.667043, 114.000096], [22.667, 114.000147], [22.666961, 114.000199], [22.66692, 114.000247], [22.66688, 114.000286], [22.666841, 114.000334], [22.666797, 114.000384], [22.66673, 114.000437], [22.666673, 114.000496], [22.666607, 114.000549], [22.666545, 114.000612], [22.666287, 114.000833], [22.66621, 114.000882], [22.666138, 114.000926], [22.66606, 114.00099], [22.665972, 114.001058], [22.665891, 114.001114], [22.665809, 114.001158], [22.665725, 114.001216], [22.665635, 114.001275], [22.665255, 114.001479], [22.665149, 114.001524], [22.66504, 114.001577], [22.664923, 114.001628], [22.664575, 114.001775], [22.664114, 114.001933], [22.664001, 114.001966], [22.663888, 114.00199], [22.663774, 114.002035], [22.663655, 114.002067], [22.66353, 114.002101], [22.663402, 114.002132], [22.663275, 114.002169], [22.663148, 114.002203], [22.66266, 114.002342], [22.662544, 114.002373], [22.662429, 114.0024], [22.662106, 114.002517], [22.662032, 114.00255], [22.661957, 114.002583], [22.661886, 114.002604], [22.661814, 114.002636], [22.661663, 114.0027], [22.661583, 114.00274], [22.661315, 114.002878], [22.661247, 114.002907], [22.661185, 114.002932], [22.66113, 114.00296], [22.660899, 114.003051], [22.660847, 114.003065], [22.660659, 114.003121], [22.660608, 114.003139], [22.66058, 114.003162], [22.660565, 114.003191], [22.660538, 114.003213], [22.660508, 114.003231], [22.660495, 114.003259], [22.660458, 114.003296], [22.660429, 114.003397], [22.660408, 114.003464], [22.660378, 114.00354], [22.660363, 114.003564], [22.660314, 114.003608], [22.6602, 114.003818], [22.660175, 114.003876], [22.660049, 114.004195], [22.660021, 114.004256], [22.66, 114.004318], [22.659912, 114.004546], [22.659893, 114.004602], [22.659884, 114.004656], [22.659863, 114.004709], [22.65984, 114.004772], [22.659823, 114.004833], [22.659774, 114.004916], [22.659742, 114.004953], [22.659702, 114.004991], [22.659526, 114.00511], [22.659313, 114.005117], [22.659275, 114.005128], [22.659236, 114.005143], [22.659204, 114.005154], [22.659177, 114.005174], [22.659, 114.005249], [22.658954, 114.005246], [22.65891, 114.005242], [22.658881, 114.005232], [22.658862, 114.005226], [22.658822, 114.005206], [22.658791, 114.005192], [22.658759, 114.005171], [22.658612, 114.005036], [22.658563, 114.005019], [22.658514, 114.005001], [22.65846, 114.004978], [22.65841, 114.004958], [22.658359, 114.004939], [22.658102, 114.0049], [22.658043, 114.004901], [22.6577, 114.00493], [22.657606, 114.004941], [22.657507, 114.004945], [22.657422, 114.004959], [22.657338, 114.00497], [22.657009, 114.005009], [22.656778, 114.005121], [22.656726, 114.005149], [22.656679, 114.005174], [22.656635, 114.005197], [22.656598, 114.005217], [22.656512, 114.00526], [22.656477, 114.005279], [22.656426, 114.005314], [22.656315, 114.005396], [22.656256, 114.00544], [22.656188, 114.00549], [22.65605, 114.005583], [22.655815, 114.005766], [22.655529, 114.005985], [22.655465, 114.006031], [22.655409, 114.006071], [22.655205, 114.00624], [22.65511, 114.006312], [22.655066, 114.006345], [22.654989, 114.006407], [22.65491, 114.006467], [22.654868, 114.006496], [22.654832, 114.006524], [22.654792, 114.006552], [22.654674, 114.006626], [22.654656, 114.006641], [22.654631, 114.006665], [22.654624, 114.006669], [22.654613, 114.006677], [22.654597, 114.006687], [22.65459, 114.006694], [22.654584, 114.006698], [22.654579, 114.006702], [22.654573, 114.006706], [22.654555, 114.006716], [22.654554, 114.006715], [22.654555, 114.006715], [22.654555, 114.006715], [22.654555, 114.006717], [22.654555, 114.006719], [22.654539, 114.00674], [22.654529, 114.006756], [22.654509, 114.00678], [22.654481, 114.006809], [22.654417, 114.006871], [22.654407, 114.006882], [22.654394, 114.006892], [22.654363, 114.006916], [22.65432, 114.006949], [22.654302, 114.006962], [22.654289, 114.006973], [22.654275, 114.006982], [22.654257, 114.006994], [22.65424, 114.007007], [22.654223, 114.007018], [22.654195, 114.007035], [22.654146, 114.007078], [22.65413, 114.007096], [22.654124, 114.007102], [22.654116, 114.00711], [22.654035, 114.00718], [22.653994, 114.007212], [22.653942, 114.007248], [22.653891, 114.007284], [22.653837, 114.007319], [22.653782, 114.00736], [22.653725, 114.007406], [22.653665, 114.007455], [22.653604, 114.007507], [22.653537, 114.007559], [22.653237, 114.007795], [22.653162000000002, 114.007853], [22.652859, 114.008086], [22.65279, 114.008141], [22.652722, 114.008193], [22.652486, 114.008392], [22.652425, 114.008436], [22.652364, 114.008478], [22.652141, 114.008652], [22.651907, 114.008831], [22.651843, 114.008877], [22.651779, 114.008923], [22.651713, 114.008971], [22.651653, 114.009008], [22.651391, 114.009213], [22.651153, 114.009397], [22.651097, 114.00944], [22.651041, 114.009481], [22.650994, 114.009514], [22.650954, 114.009544], [22.650919000000002, 114.009572], [22.650851, 114.009628], [22.650815, 114.009661], [22.65078, 114.00969], [22.650748, 114.009719], [22.650626, 114.009822], [22.65059, 114.009849], [22.65056, 114.009878], [22.65052, 114.009909], [22.6504, 114.010005], [22.650277, 114.010077], [22.650266, 114.01009], [22.65026, 114.010104], [22.65026, 114.010105], [22.650258, 114.010107], [22.650254, 114.01011], [22.650244, 114.010115], [22.65025, 114.010123], [22.65025, 114.010126], [22.650253, 114.010131], [22.650257, 114.010133], [22.650256, 114.010134], [22.650252000000002, 114.010136], [22.65025, 114.010136], [22.650243, 114.010136], [22.650249, 114.010139], [22.650238, 114.010139], [22.650215, 114.010136], [22.650215, 114.010139], [22.650212, 114.010143], [22.650206, 114.010148], [22.650205, 114.010155], [22.6502, 114.010159], [22.650197, 114.010161], [22.650194, 114.010163], [22.650187, 114.010171], [22.650187, 114.010172], [22.650187, 114.010174], [22.650187, 114.010176], [22.650187, 114.010178], [22.650186, 114.010178], [22.650176, 114.010181], [22.65017, 114.010186], [22.650168999999998, 114.010187], [22.65017, 114.010188], [22.65017, 114.010189], [22.650174, 114.01019], [22.650174, 114.01019], [22.650175, 114.010185], [22.650177, 114.010184], [22.65018, 114.010183], [22.650181, 114.010184], [22.650179, 114.010183], [22.650175, 114.010181], [22.650164, 114.010177], [22.650164, 114.010168], [22.65016, 114.010171], [22.650156, 114.010171], [22.650077, 114.010223], [22.65005, 114.010245], [22.650019, 114.010266], [22.64999, 114.01029], [22.64996, 114.010309], [22.649917, 114.010341], [22.649892, 114.010353], [22.649874, 114.010367], [22.649844, 114.01039], [22.649637, 114.010561], [22.649569, 114.010614], [22.649493, 114.010679], [22.649349, 114.010807], [22.64928, 114.010869], [22.649211, 114.010927], [22.649142, 114.010986], [22.649075, 114.011046], [22.64888, 114.01122], [22.648835, 114.011255], [22.648791, 114.01129], [22.648697, 114.011371], [22.648469, 114.011552], [22.64841, 114.011602], [22.648349, 114.011651], [22.648288, 114.011697], [22.648226, 114.011744], [22.648162, 114.01179], [22.647882, 114.012002], [22.647812000000002, 114.012056], [22.647737, 114.012115], [22.647455, 114.01231], [22.647386, 114.01235], [22.647316, 114.01239], [22.647259, 114.01242], [22.647165, 114.012422], [22.647145, 114.012414], [22.647127, 114.012402], [22.647107, 114.012387], [22.647089, 114.012372], [22.647061, 114.012348], [22.647032, 114.012301], [22.646994, 114.012256], [22.646963, 114.012211], [22.646934, 114.012167], [22.6469, 114.012126], [22.646858, 114.012074], [22.646829, 114.012025], [22.646798, 114.011976], [22.646676, 114.011792], [22.646641, 114.011738], [22.646593, 114.011682], [22.646548, 114.011619], [22.646392, 114.011391], [22.646359, 114.011348], [22.646242, 114.011275], [22.64621, 114.011284], [22.646176, 114.011308], [22.646057, 114.011403], [22.646036, 114.011422], [22.646023, 114.011419], [22.645966, 114.011418], [22.645968, 114.01141], [22.645971, 114.011398], [22.645968, 114.011385], [22.645959, 114.011384], [22.645965, 114.011382], [22.645963, 114.011381], [22.645963, 114.011377], [22.645955, 114.011391], [22.64595, 114.011385], [22.645947, 114.011383], [22.64595, 114.011378], [22.645932, 114.011349], [22.645955999999998, 114.011367], [22.645954, 114.011364], [22.64595, 114.011361], [22.645944, 114.011363], [22.645945, 114.011366], [22.645925, 114.011378], [22.645917, 114.011377], [22.645914, 114.01137], [22.645915, 114.011394], [22.645914, 114.011395], [22.645919, 114.011399], [22.645902, 114.011416], [22.645927, 114.01145], [22.645934, 114.01145], [22.645931, 114.011415], [22.645931, 114.011423], [22.64594, 114.011465], [22.645958, 114.011438], [22.64597, 114.011438], [22.645948, 114.011414], [22.645972, 114.011407], [22.645969, 114.011389], [22.645957, 114.011383], [22.645966, 114.011391], [22.646028, 114.011349], [22.646038, 114.011348], [22.646038, 114.011346], [22.646144, 114.011338], [22.646165, 114.011331], [22.646185, 114.011323], [22.646296, 114.011279], [22.646366, 114.011254], [22.646385, 114.011245], [22.646409, 114.011188], [22.64643, 114.011175], [22.645819, 114.011172], [22.645744, 114.011106], [22.645695, 114.011069], [22.64569, 114.011058], [22.64581, 114.011152], [22.645709, 114.011067], [22.645675, 114.011042], [22.645633, 114.011031], [22.645633, 114.011066], [22.645639, 114.011083], [22.645645000000002, 114.01109], [22.64563, 114.011079], [22.645635, 114.011107], [22.645651, 114.011131], [22.645679, 114.011169], [22.645688, 114.011188], [22.645694, 114.011194], [22.645697, 114.011206], [22.6457, 114.011215], [22.645707, 114.011226], [22.645692, 114.011203], [22.645708, 114.011211], [22.645718, 114.011244], [22.645722, 114.011281]]
import folium
#高德地图
def draw_gps(locations, map_file_name):
    """
    绘制gps轨迹图
    :param locations: list, 需要绘制轨迹的经纬度信息,格式为[[lat1, lon1], [lat2, lon2], ...]
    :param output_path: str, 轨迹图保存路径
    :param file_name: str, 轨迹图保存文件名
    :return: None
    """
    m = folium.Map(locations[0],  # 中心区域的确定
                   zoom_start=15,
                   tiles="http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",  # 设置高德底图
                   attr='default')

    folium.PolyLine(    # polyline方法为将坐标用线段形式连接起来
        locations,    # 将坐标点连接起来
        weight=3,  # 线的大小为3
        color='orange',  # 线的颜色为橙色
        opacity=0.8    # 线的透明度
    ).add_to(m)    # 将这条线添加到刚才的区域m内
    
    # 起始点,结束点
    folium.Marker(locations[0], popup='<b>Starting Point</b>').add_to(m)
    folium.Marker(locations[-1], popup='<b>End Point</b>').add_to(m)
    m.save(map_file_name)  # 将结果以HTML形式保存到指定路径

#谷歌地图
def draw_gps2(locations, map_file_name):
    """
    绘制gps轨迹图
    :param locations: list, 需要绘制轨迹的经纬度信息,格式为[[lat1, lon1], [lat2, lon2], ...]
    :param output_path: str, 轨迹图保存路径
    :param file_name: str, 轨迹图保存文件名
    :return: None
    """
    m = folium.Map(locations[0], zoom_start=15, attr='default')  #中心区域的确定

    folium.PolyLine(    # polyline方法为将坐标用线段形式连接起来
        locations,    # 将坐标点连接起来
        weight=3,  # 线的大小为3
        # color='orange',  # 线的颜色为橙色
        color='blue',  # 线的颜色为橙色
        opacity=0.8    # 线的透明度
    ).add_to(m)    # 将这条线添加到刚才的区域m内
    
    # 起始点,结束点
    folium.Marker(locations[0], popup='<b>Starting Point</b>').add_to(m)
    folium.Marker(locations[-1], popup='<b>End Point</b>').add_to(m)
    m.save(map_file_name)  # 将结果以HTML形式保存到指定路径

记得根据自己的gps数据进行绘制,我自己的gps设备用高德地图画的不准,用谷歌的就很准,感动死我。

以下内容详细讲到各个用法,可到原网址看看

https://python-visualization.github.io/folium/quickstart.html

三、经纬度距离计算

背景知识

这些经纬线是怎样定出来的呢?

地球是在不停地绕地轴旋转(地轴是一根通过地球南北两极和地球中心的假想线),在地球中腰画一个与地轴垂直的大圆圈,使圈上的每一点都和南北两极的距离相等,这个圆圈就叫作“赤道”。

在赤道的南北两边,画出许多和赤道平行的圆圈,就是“纬圈”;构成这些圆圈的线段,叫做纬线。我们把赤道定为纬度零度,向南向北各为90度,在赤道以南的叫南纬,在赤道以北的叫北纬。北极就是北纬90度,南极就是南纬90度。纬度的高低也标志着气候的冷热,如赤道和低纬度地地区无冬,两极和高纬度地区无夏,中纬度地区四季分明。

其次,从北极点到南极点,可以画出许多南北方向的与地球赤道垂直的大圆圈,这叫作“经圈”;构成这些圆圈的线段,就叫经线。公元1884平面坐标图年,国际上规定以通过英国伦敦近郊的格林尼治天文台的

经线作为计算经度的起点,即经度零度零分零秒,也称“本初子午线”。在它东面的为东经,共180度;在它西面的为西经,共180度。因为地球是圆的,所以东经180度和西经180度的经线是同一条经线。各国公定180度经线为“国际日期变更线”。为了避免同一地区使用两个不同的日期,国际日期变线在遇陆地时略有偏离。

每一经度和纬度还可以再细分为60分,每一分再分为60秒以及秒的小数。利用经纬线,我们就可以确定地球上每一个地方的具体位置,并且把它在地图或地球仪上表示出来。

例如问北京的经纬度是多少?我们很容易从地图上查出来是东经116度24分,北纬39度54分。在大海中航行的船只,只要把所在地的经度测出来,就可以确定船在海洋中的位置和前进方向。

纬度共有90度。赤道为0度,向两极排列,圈子越小,度数越大。横线是纬度,竖线是经度。

当然可以计算,四元二次方程。

经度和纬度都是一种角度。经度是个两面角,是两个经线平面的夹角。因所有经线都是一样长,为了度量经度选取一个起点面,经1884年国际会议协商,决定以通过英国伦敦近郊、泰晤士河南岸的格林尼治皇家天文台(旧址)的一台主要子午仪十字丝的那条经线为起始经线,称为本初子午线。

本初子午线平面是起点面,终点面是本地经线平面。

某一点的经度,就是该点所在的经线平面与本初子午线平面间的夹角。在赤道上度量,自本初子午线平面作为起点面,分别往东往西度量,往东量值称为东经度,往西量值称为西经度。由此可见,一地的经度是该地对于本初子午线的方向和角距离。本初子午线是0°经度,东经度的最大值为180°,西经度的最大值为180°,东、西经180°经线是同一根经线,因此不分东经或西经,而统称180°经线。

纬度是个线面角。起点面是赤道平面,线是本地的地面法线。所谓法线,即垂直于参考扁球体表面的线。某地的纬度就是该地的法线与赤道平面之间的夹角。纬度在本地经线上度量,由赤道向南、北度量,向北量值称为北纬度,向南量值称为南纬度。由此可见,一地的纬度是该地对于赤道的方向和角距离。赤道是0°纬线,北纬度的最大值为90°,即北极点;南纬度的最大值为90°,即南极点。

原理附注,这边直接上结论:
已知两点经纬度计算球面距离的公式,一搜一大堆,形式如下:

也有

其中latitude是纬度,longitude是经度

a=latitude1 - latitude2为两点纬度之差 b=longitude1-longitude2 为两点经度之差;

6378.137(KM) 为地球半径

其中计算代码诸如:

 

public class CaculateDistance {

	private final static double EARTH_RADIUS = 6378.137;

	private static double rad(double d) {
		return d * Math.PI / 180.0;
	}

	/**
	 * 根据两点间经纬度坐标(double值),计算两点间距离,单位为米
	 */
	public static double GetDistance(double lat1, double lng1, double lat2, double lng2) {
		double radLat1 = rad(lat1);
		double radLat2 = rad(lat2);
		double a = radLat1 - radLat2;
		double b = rad(lng1) - rad(lng2);
		double s = 2 * Math.asin(Math.sqrt(
				Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
		s = s * EARTH_RADIUS;
		s = (s * 10000) / 10;
		return s;
	}

	public static void main(String[] args) {
		System.out.println("距离差" + GetDistance(30.535275, 114.352175,30.5352806, 114.3521917) + "米");
	}
}

这些公式或多或少其实跟实际还是有较大的偏差,其中最大的偏差来源来自于地球半径,差一点就差了好多。

以下是我自己写的一套测算距离的,包括:

1、已知两点经纬度,求相对距离;

2、维度相同,求经度实际距离;

3、经度相同,求维度差的实际距离。

其中距离有正负号,主要因为以东经为横坐标正方向,维度以纵坐标正方向。2、3种主要是算差一个经度或者一个维度,在实际距离中差了多少。

#flag主要是为了辨别是第一种还是第2、3种情况
def latlon_to_dist(lat1,lon1,lat2,lon2,flag = 0):
    R = 6378140
    R = R - 21 * math.sin(lat1 * math.pi /180)
    
    if(flag):
        if((lon2 == lon1)):
            Distance = (lat2 - lat1) * math.pi * R /180 * math.cos(lat1 * math.pi / 180)
        if((lat2 == lat1)):
            Distance = (lon2 - lon1) * math.pi * R / 180
    else:
        a = lat1 * math.pi / 180 - lat2* math.pi / 180
        b = (lon1-lon2)* math.pi / 180
        s = 2 * math.asin(math.sqrt(math.pow(math.sin(a/2), 2) + math.cos( lat1 * math.pi / 180) * math.cos( lat1 * math.pi / 180) * math.pow(math.sin(b/2), 2)))
        Distance = math.fabs(s) * R                
    return Distance

我认为在理论正确的前提下,差距比较大的在于R的选择,那么可以做一个R的标定,代码如下:

#标定计算地球半径
def calibration_earth_radius(lat1,lon1,lat2,lon2,real_dist):
    a = lat1 * math.pi / 180 - lat2* math.pi / 180
    b = (lon1-lon2)* math.pi / 180
    s = 2 * math.asin(math.sqrt(math.pow(math.sin(a/2), 2) + math.cos( lat1 * math.pi / 180) * math.cos( lat1 * math.pi / 180) * math.pow(math.sin(b/2), 2)))
    R = real_dist / math.fabs(s)
    return R

四、经纬度距离计算原理

首先画个图(图1),要不然空间想象能力差的话容易犯糊涂。首先对图1做个大致的说明,红色的半圆表示赤道,蓝色的圆弧表示本初子午线(也就是经度为0的子午线)。球最上方是北极点,点A和点B分别为要计算的两个点,坐标分别为A(jA,wA)和B(jB,wB)。

使用空间直角坐标系来推导,很方便。首先我们需要建立一个空间坐标系:在赤道平面内,X轴由球心O指向本初子午线,Y轴在赤道平面内垂直于X轴,Z轴垂直于赤道平面朝向北极。还是假设AB两点的经纬度坐标为:A(jA,wA),B(jB,wB)。由该坐标系的定义以及经纬度的定义可以把上面的AB两点的坐标转换为该坐标系中的坐标如下:

由两点距离公式可以得到AB的直线距离为:

对于球面上的任意一个点(X,Y,Z),都有:

把上面的公式整理就可以得到(下面用到了一个积化和差公式):

好了,大功告成,是不是比用立体几何要简单的多。接下来就是用上面的弦长和弧长的关系来计算AB的弧长就可以了。

以上内容主要源自网上资源,再次感谢各个大佬无私奉献。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GPS数据解析、可视化及经纬度距离计算 的相关文章

  • MetaX组件化框架

    目录 MetaX 框架介绍MetaX 是如何设计的MetaX 运行效果 1 MetaX 框架介绍 MetaX 是 58无线 Android 团队开发的一套增强版的组件化框架 xff0c 它制定了一系列的标准和规范 xff0c 来解决现有组件
  • 58同城首页腰部动态化技术选型(布局动态化)

    1 行业情况 1 1 基本概念介绍 1 1 1 Web混合 Web 前端和客户端的混合开发 使用 WebView 进行页面渲染 逻辑执行 xff1b 依赖客户端的能力需要通过 JSBridge 通信桥 的方式进行调用 xff0c 比如调用客
  • Java篇 - 四种引用(Reference)实战

    Java的垃圾回收 GC 是虚拟机自动管理的 xff0c 前面我有篇文章专门讲GC xff1a JVM篇 GC给你整明白 Java内存管理分为内存分配和内存回收 xff0c 都不需要程序员负责 xff0c 垃圾回收的机制主要是看对象是否有引
  • 网络篇 - https协议中的数据是否需要二次加密

    随着互联网整体的发展 xff0c https 也被越来越多的应用 甚至苹果去年还曾经放言要强制所有的 app 都使用 https xff0c 可见在如今的互联网它的重要性 前面的文章说了 OSI 七层模型 xff0c https 可以保证数
  • 加解密篇 - 对称加密算法 (DES、3DES、AES、RC)

    这篇文章来讲讲对称加密 xff0c 对称加密在开发中用的很多 xff0c 如 AES xff0c DES xff0c 3DES xff0c RC 目录 介绍优点和缺点DES算法3DES算法AES算法RC算法 1 介绍 1 1 概念 采用单钥
  • 加解密篇 - 非对称加密算法 (RSA、DSA、ECC、DH)

    最近的文章中多次出现了非对称加密 xff0c 今天就来分析一下非对称加密的算法 目录 xff1a 简介RSA算法DSA算法ECC算法DH算法 1 简介 1 1 概念 非对称加密需要两个密钥 xff1a 公钥 publickey 和私钥 pr
  • 跨平台技术篇 - 使用 Flutter 与原生技术混合开发示例

    目前主流的混合开发方案有两种集成方式 xff1a 源码集成 xff1a 也就是谷歌官方提供的方案 https github com flutter flutter wiki Add Flutter to existing apps 产物集成
  • 音视频篇 - Android 音视频涉及到的技术

    前言 现在市面上的图像 xff0c 音视频软件越来越多 xff0c 最近两年也是直播 xff0c 短视频的红利期 而图像 音视频一直是互联网视觉的入口 xff0c 掌握并熟练运用音视频 图像技术已经是当前互联网时代不可或缺的技能 xff0c
  • sockaddr_in的一个小理解

    之前一直认为是sockaddr 设计时有缺陷 xff0c 在编写网络通信时 xff0c 都使用sockaddr in xff0c 因为它将sockaddr 中的 char sa data 14 拆分为了 unsigned short sin
  • Linux虚拟机下WWW(HTTP)服务器的搭建与使用(详细)

    1 简介 1 1 关于www服务器 WWW服务器是被动程序 xff0c 只有接收到互联网中其他计算机发出的请求后才会响应 xff0c 然后WWW服务器才会使用HTTP或者HTTPS将指导文件传输到客户机的浏览器上 1 2 关于HTTP协议
  • 非抢占式优先级调度算法

    Priority scheduling is a type of scheduling algorithm used by the operating system to schedule the processes for executi
  • Eclipse中使用jstl标签库

    在MyEclipse中使用jstl标签只需导读jstl jar就能使用 xff0c 但是在Eclipse中还需要一点小套路 步骤 xff1a 一 导入jstl jar 二 导入导入standard jar 三 web xml加上如下配置 l
  • hibernate HQL 投影查询 + 多表关联

    64 Test public void testQueryProjection Session session 61 HibernateUtils openSession session beginTransaction 操作 hql 默认
  • NetEQ 算法

    NetEQ 算法中集成了自适应抖动控制算法以及语音包丢失隐藏算法 这项技术使其能够快速且高解析度地适应不断变化的网络环境 xff0c 确保音质优美且缓冲延迟最小 研究的重点是 NetEQ 模块 xff0c 其中所涉及的处理过程包括抖动消除
  • 数组的形参与实参,通过引用传递数组

    数组形参 xff1a void printValues int void printValues int void printValues int 10 以上三种是等价的 通常 xff0c 将数组形参直接定义为指针要比使用语法定义更好 第三
  • java 简单员工管理系统

    package cn test import java io import java util class Emp 64 Override public String toString return 34 Emp empNo 61 34 4
  • 关闭虚拟机vmware自动挂起

    1 xff0c 桌面右键 属性 xff0c 里的屏幕保护程序 xff0c 选 无 2 xff0c 控制面板的电源选项 xff0c 方案为 一直开着 xff0c 具体选项选 从不关机 3 xff0c 在Windows 2003 Server点
  • GTK+2.0之初始学习篇(二)—— g_signal_connect宏解释及HelloWorld

    GTK 43 2 0中利用信号 回调函数机制来处理窗口外部传来的事件 消息或信号 以下实现的是单击窗口关闭按钮 xff0c 窗口自动关闭 在程序中调用了gtk main quit 函数实现退出主循环 include lt gtk gtk h
  • linux-----页、页表、页框(块)

    基本介绍 我们知道 xff0c 在linux操作系统中 xff0c CPU在执行一个进程的时候 xff0c 都会访问内存 但CPU并不是直接访问物理内存地址 xff0c 而是通过虚拟地址空间来间接的访问物理内存地址 所谓的虚拟地址空间 xf
  • CMake交叉编译配置

    罗列一下cmake常用的命令 CMake支持大写 小写 混合大小写的命令 1 添加头文件目录INCLUDE DIRECTORIES 语法 xff1a include directories AFTER BEFORE SYSTEM dir1

随机推荐

  • 8086CPU的14个寄存器全称

    通用寄存器 xff1a ax accumulate register 累加器 bx based register 基地址寄存器 cx count register 计数器 dx data registered 数据寄存器 段寄存器 xff1
  • 项目开发-后台管理框架

    开发中几乎的平台都需要一个后台管理 xff0c 但是从零开发一套后台控制面板并不容易 xff0c 幸运的是有很多开源免费的后台控制面板可以给开发者使用 xff0c 那么有哪些优秀的开源免费的控制面板呢 xff1f 我在 Github 上收集
  • 项目经理必备工具-个人推荐

    点击链接 项目经理必备工具 进入详细说明
  • 如何绕过CDN找源站ip?

    如何绕过CDN找源站ip xff1f 这是一个总结帖 xff0c 查了一下关于这个问题的国内外大大小小的网站 xff0c 对其中说的一些方法总结归纳形成 xff0c 里面具体发现ip的方法不是原创 xff0c 所有参考的原贴都也贴在了后面
  • Navicat修改MySQL数据库密码就是这么简单

    方法1 xff1a 用SET PASSWORD命令 首先登录MySQL 格式 xff1a mysql gt set password for 用户名 64 localhost 61 password 39 新密码 39 例子 xff1a m
  • Axure 元件库-原型

    元件名称 xff1a 1 Axure交互原型设计指南 rp 2 PC和移动原型常用元件 rp 3 后台模板 rp 4 全局说明 rp https pan baidu com s 1vmac 08MZAKj6qsdjwIZlg 提取码 xff
  • Node.js 通过http调用外部接口

    通过http request发送带参数的post请求 data xff1a 发送的内容 opt xff1a 描述将要发出的请求 data xff1a 事件在数据到达时被触发 end xff1a 请求结束时触发 error xff1a 发生错
  • 想成为出色的 CTO,你要具备这七大能力

    编者按 xff1a 首席技术官这一职位在20世纪80年代出现于美国 起于做很多技术研发的大公司 xff0c 如General Electric 主要职能是将科研成果转化实际效益 简单地说 xff0c 就是一个企业中技术的最高负责人 要扮演好
  • Keil中添加自己的头文件

    xfeff xfeff 方法一 在keil的开发环境下添加 xff1a 请注意上面的系统生成的头文件目录是 xff1a xff0c 即 dd jj pp kk xff0c 其中 是相对于项目文件 uvproj 而言的 其中 表示项目文件所在
  • http authorization 基本认证

    最近做的一个项目需要与其它系统对接接口 xff0c 对方提供的是webservice的接口 xff0c 并且需要Basic Authorization基本认证 xff0c 一开始都是用postman请求 xff0c 用户名和密码需要填在Ba
  • 终端命令安装 chrome for linux

    终端里安装chrome for linux 备注 xff1a 我是在Linux Mint 17 1 64位系统下安装的chrome for linux xff0c 其它Debian衍生版应该也是一样的 1 在终端里输入下载命令 xff1a
  • Arduino串口函数详解

    本文总结了Arduino常用串口操作函数 xff0c 函数说明部分来源于Arduino 官网串口使用指南 xff0c 示例与实验部分为自编 本文是对Arduino串口操作函数的较全面总结 xff0c 可作为工具贴查找使用 1 串口设置 xf
  • STM32CubeMX——霍尔编码器、L298N驱动电机

    前言 人生如逆旅 xff0c 我亦是行人 苏轼 临江仙 送钱穆父 目录 xff1a L298N电机驱动介绍编码器介绍电机介绍新建工程编写代码实验结果 一 L298N电机驱动介绍 B站 视频讲解 xff1a l298n电机驱动模块 电机正反转
  • AT命令拨电话,如何判断手机的状态?

    我使用AT命令拨电话 xff0c 如 xff1a ATD10086 我怎么知道我拨打的电话是否成功了呢 xff1f 比如SIM卡欠费了 xff0c 那么肯定算是没有拨通 xff1b 再比如网络有问题 xff0c 被叫方没有收到来电 xff0
  • GPS模块(GPS-NEO-6M)

    ATK NEO 6M GPS 模块简介 ATK NEO 6M V23 模块 xff0c 是 ALIENTEK 生产的一款高性能 GPS 模块 xff0c 模块核心采用 UBLOX公司的 NEO 6M 模组 xff0c 具有 50 个 通道
  • toCharArray()

    toCharArray 是将一个字符串内容转换为字符数组 xff0c 例如 String str 61 34 abc 34 System out println str toCharArray 43 34 34 将输出a b c 转载于 h
  • 基于Arduino的GPS数据解析程序

    这篇博客讲了我利用arduino来解析和转发原始nema 0813数据的思想和实现方法 因为arduino比较简单 xff0c 无法实现串口数据接收中断 xff0c 所以都写在主循环里面了 不知道代码存在何种缺陷和漏洞 xff0c 欢迎大家
  • VsCode安装和配置c/c++环境(超完整,小白专用)

    文章目录 1 vsCode配置C C 43 43 环境 1 vsCode下载和安装 1 下载Microsoft vsCode2 安装vsCode3 下载中文插件2 MinGW编译器下载和配置 1 下载MinGW2 下载后放到自己方便的目录
  • 各版本esp32和esp8266开发板引脚图(附各开发板特殊通信接口如IIC、SPI接口等默认引脚查看方法)

    目录 esp32 GPIO可用资源 1 esp32开发板 2 esp32开发板 查看特殊通信接口的方法 esp8266 esp32 GPIO可用资源 GPIO 6 11 连接到SPI Flash GPIO 34 39 只能作为输入且没有内部
  • GPS数据解析、可视化及经纬度距离计算

    一 GPS数据解析 根据NMEA协议 xff0c 我们从传感器上接收到的GPS经纬度数据格式如下 xff1a 例 xff1a GPRMC 024813 640 A 3158 4608 N 11848 3737 E 10 05 324 27