Запуск сервера для получения высоты местности Цезия работает только один раз.Python

Программы на Python
Ответить
Anonymous
 Запуск сервера для получения высоты местности Цезия работает только один раз.

Сообщение Anonymous »

У меня есть несколько наборов данных с координатами, и я хочу нанести эти точки на график в Cesium для Unreal. Для этого мне нужно исправить высоту ландшафта, и я хочу, чтобы они были написаны на Python (поскольку я делаю и кое-что еще). Здесь я немного застрял.
Кажется, для этой задачи не существует API для Cesium, поэтому я использовал Python, чтобы создать HTML-файл, поместить туда координаты и получить высоты местности:

Код: Выделить всё

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"""




Cesium Terrain Fetch



html, body, #cesiumContainer {{width:100%; height:100%; margin:0; padding:0; overflow:hidden;}}





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.');
}}
}});
}});



"""

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 = "access_token"
terrain_data = get_terrain_heights(points, access_token)
Это на самом деле работает очень хорошо, возвращает список словарей с необходимой мне информацией. Итак, это работает, но только один раз. Во второй раз, когда я хочу использовать этот код, он выдает ошибку:
FileNotFoundError: [WinError 2] Система не может найти указанный файл: 'C:\Users\username\AppData\Local\Temp\tmp4y1vst8b.html'
Это логично, поскольку после использования он удаляет временный файл. Однако когда я удаляю этот фрагмент кода, он по-прежнему не работает: он продолжает работать в ядре Python, и ничего не происходит, никакие данные не извлекаются.
Может ли кто-нибудь помочь, как с этим справиться? Я хочу найти решение: я просто запускаю функцию, она получает нужную мне информацию и все готово. Если я захочу снова запустить его через 1 минуту с другой информацией, он сможет это сделать.

Подробнее здесь: https://stackoverflow.com/questions/797 ... s-one-time
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»