You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cesium地形高度获取函数仅能单次运行的问题求助

Cesium地形高度获取函数仅能单次运行的问题求助

我现在有个需求:用Python处理带坐标的数据集,需要修正地形高度(后续要在Cesium for Unreal里绘图)。因为我还在用Python做其他处理,所以希望整个流程都在Python里完成。

目前我没有找到直接可用的Cesium地形高度查询Python API,所以写了一段代码:通过Python生成临时HTML文件,在浏览器里用Cesium JS获取地形高度,再把结果传回Python。这段代码第一次运行完全正常,能返回包含地形高度、椭球高度等信息的字典列表,但第二次运行就出问题了:

  • 如果保留删除临时文件的代码,会报错:FileNotFoundError: [WinError 2] The system cannot find the file specified: 'C:\Users\username\AppData\Local\Temp\tmp4y1vst8b.html'(这很合理,因为第一次运行已经把临时文件删了)
  • 如果删掉删除临时文件的代码,第二次运行时Python内核会一直卡着,完全获取不到任何数据

我想要的是:每次调用get_terrain_heights函数,它能正常获取地形高度数据,运行完成后自动清理,并且可以多次调用(比如间隔1分钟用新的坐标数据再跑一次)。有没有大佬能帮忙看看怎么修改这段代码?

以下是我当前的完整代码:

import json
import threading
import time
from flask import Flask, request, send_file
import webbrowser
import tempfile
import os

def get_terrain_heights(points, access_token):
    results = []
    app = Flask(__name__)
    
    temp_html_file = tempfile.NamedTemporaryFile(delete=False, suffix=".html")
    temp_html_file.close()

    html_content = f"""
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cesium Terrain Fetch</title>
    <link href="https://cdn.jsdelivr.net/npm/cesium@1.105.1/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/cesium@1.105.1/Build/Cesium/Cesium.js"></script>
    <style>
        html, body, #cesiumContainer {{width:100%; height:100%; margin:0; padding:0; overflow:hidden;}}
    </style>
</head>
<body>
    <div id="cesiumContainer"></div>
    <script>
        Cesium.Ion.defaultAccessToken = '{access_token}';
        const viewer = new Cesium.Viewer('cesiumContainer', {{
            terrainProvider: Cesium.createWorldTerrain()
        }});
        const points = {json.dumps(points)};
        let results = [];

        function sendToPython(data) {{
            fetch('/submit', {{
                method: 'POST',
                headers: {{'Content-Type': 'application/json'}},
                body: JSON.stringify(data)
            }});
        }}

        points.forEach(p => {{
            const position = Cesium.Cartographic.fromDegrees(p.lon, p.lat);
            Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, [position]).then(updatedPositions => {{
                const terrainHeight = updatedPositions[0].height;
                const ellipsoidHeight = terrainHeight + p.alt_above_ground;
                results.push({{
                    lat: p.lat,
                    lon: p.lon,
                    alt_above_ground: p.alt_above_ground,
                    terrain_height: terrainHeight,
                    alt_ellipsoid: ellipsoidHeight
                }});
                if (results.length === points.length) {{
                    sendToPython(results);
                    alert('Terrain heights fetched. You can close this window.');
                }}
            }});
        }});
    </script>
</body>
</html>
    """
    with open(temp_html_file.name, "w") as f:
        f.write(html_content)

    @app.route('/')
    def index():
        return send_file(temp_html_file.name)

    @app.route('/submit', methods=['POST'])
    def submit():
        nonlocal results
        results = request.json
        return {"status": "ok"}

    def run_app():
        app.run(port=5000)

    thread = threading.Thread(target=run_app, daemon=True)
    thread.start()

    webbrowser.open("http://127.0.0.1:5000/")

    while not results:
        time.sleep(0.5)

    # Delete the temporary file only after getting results
    try:
        os.unlink(temp_html_file.name)
    except:
        pass

    return results

# Usage:
# points = [{"lat": 52.3109, "lon": 4.77028, "alt_above_ground": 0}, {"lat": 52.3109, "lon": 4.57028, "alt_above_ground": 0}]
# access_token = "your_cesium_ion_access_token"
# terrain_data = get_terrain_heights(points, access_token)

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 07:33:09