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
相关产品推荐
相关产品推荐

