背景需要:

须要实现飞机仿真实时挪动地位,然而提供的数据量较为宏大,而咱们的数据都是通过kafka发送,再由ue4承接数据来做渲染。然而数据量较为宏大,在增大飞行速度的同时渲染比拟吃力,于是想到点位个数压缩,数据推送频率不变来实现。

构思原理:利用普克拉斯算法,通过该点位压缩算法来压缩点的个数
这里提供的数据是excel,我打算把他解决成geosjon格局数据,而后用leaflet加载,判断是否和原数据是否重合。

'''Author: nicoDate: 2023-06-07 10:21:42LastEditTime: 2023-06-07 10:21:46Description: '''import mathimport pandas as pddef douglas_peucker(coords, epsilon):    # 找到间隔端点最远的点    dmax = 0    index = 0    for i in range(1, len(coords)-1):        d = distance(coords[i], coords[0], coords[-1])        if d > dmax:            index = i            dmax = d    # 如果最大间隔大于阈值,则递归地对两个子段进行解决    if dmax > epsilon:        results1 = douglas_peucker(coords[:index+1], epsilon)        results2 = douglas_peucker(coords[index:], epsilon)        # 将后果合并        return results1[:-1] + results2    else:        # 如果最大间隔小于阈值,则保留该段的终点和起点        return [coords[0], coords[-1]]        def distance(p, p1, p2):    # 计算点到线段的间隔    x0, y0 = p    x1, y1 = p1    x2, y2 = p2    dx = x2 - x1    dy = y2 - y1    if dx == 0 and dy == 0:        return math.sqrt((x0 - x1)**2 + (y0 - y1)**2)    else:        t = ((x0 - x1) * dx + (y0 - y1) * dy) / (dx*dx + dy*dy)        if t < 0:            px, py = x1, y1        elif t > 1:            px, py = x2, y2        else:            px, py = x1 + t*dx, y1 + t*dy        return math.sqrt((x0 - px)**2 + (y0 - py)**2)# 示例用法def getData():    # 读取Excel数据到DataFrame    df = pd.read_excel('data.xlsx')    # 将经纬度转换为坐标点    coordinates = []    for index, row in df.iterrows():        coordinates.append([row['lat'], row['lon']])    return coordinatescoords = getData()epsilon = 0.0000009print(len(coords))simplified_coords = douglas_peucker(coords, epsilon)new_list = [[sublist[1], sublist[0]] for sublist in simplified_coords]print(len(new_list),new_list)simplified_geojson = {    "type": "FeatureCollection",    "features": [        {            "type": "Feature",            "properties": {},            "geometry": {                "type": "LineString",                "coordinates":new_list            }        }    ]}# 将GeoJSON写入文件with open('chouxi10.json', 'w') as f:    f.write(str(simplified_geojson))

原作者地址:https://segmentfault.com/u/yourena_c
这里我用leaflet来测试造成的geojson是否和未解决的元数据合乎,所以经纬度对位也同时做了解决。

<!DOCTYPE html><html><head>    <title>Leaflet GeoJSON Example</title>    <meta charset="utf-8" />    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <script src="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.3/leaflet.min.js"></script>    <link href="https://cdn.bootcdn.net/ajax/libs/leaflet/1.9.3/leaflet.min.css" rel="stylesheet">    <script src="./chouxi1.js"></script>    <script src="./chouxi2.js"></script>    <script src="./chouxi4.js"></script>    <script src="./chouxi10.js"></script></head><body>    <div id="mapid" style="height: 500px;"></div>    <script>        var mymap = L.map('mapid').setView([39.519334,116.437151], 19);        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {            maxZoom: 19,            attribution: 'Map data © <a href="https://openstreetmap.org">OpenStreetMap</a> contributors'        }).addTo(mymap);        var myStyle = {            "color": "#ff0000",            "weight": 15,            "opacity": 1        };        var myStyle2 = {            "color": "#00FF00",            "weight": 10,            "opacity": 1        };        var myStyle4 = {            "color": "#800000",            "weight": 5,            "opacity": 1        };        var myStyle10 = {            "color": "#00FF00",            "weight": 1,            "opacity": 1        };                console.log(geoData);        L.geoJSON(geoData, {            style: myStyle        }).addTo(mymap);                L.geoJSON(geoData2, {            style: myStyle2        }).addTo(mymap);                L.geoJSON(geoData4, {            style: myStyle4        }).addTo(mymap);                L.geoJSON(geoData10, {            style: myStyle10        }).addTo(mymap);    </script></body></html>



最初后果是抽稀10倍,局部特色隐没,然而根本吻合。