- Сообщения
- 325
- Реакции
- 472
Доброго дня коллеги, решил выложить небольшой скрипт - в помощь оператору так сказать, возможно кому-то он будет полезен.
Что делает скрипт? Автоматически считает расстояние от проверяемого клада до кладов ранее проданных с выкладки.
Конечно все это можно сделать воспользовавшись линейкой в яндекс или гугл картах, но все это очень муторно и долго, поэтому я решил частично автоматизировать процесс и "нацарапал", то что "нацарапал"
Строго прошу не судить как умею так пишу)
Итак сам скрипт разворачивается локально и не требует установки на сервер, хотя при желании конечно можно и организовать.
Перейдем к интерфейсу.
После того как развернули проект, идем в браузер и прописываем 127.0.0.1:8080 ну или localhost:8080
Перед нами открывается скудненький интерфейс
Вводим адрес проверяемого клада, точнее его координаты и жмякаем --> отправить.
Далее на страничку подгрузится яндекс карта, нам же надо удостовериться, что клад выполнен не возле школы, ментов или упаси боже детского сада.
Далее просто жмем --> Добавить точку и вбиваем координаты следующей точки
Повторяем процедуру со всеми координатами кладов выкладки и после того как внесли все точки, жмем --> Рассчитать
После чего скрипт выдаст все расстояния от проверяемого клада до ранее проданного.
Вот в общем то и весь незатейливый функционал. В будущем возможно буду дорабатывать и прикручу какие то более интересные фичи.
P.S Я только учусь)
Собственно как развернуть скрипт?
1) Потребуется установленный python версии 3.х
2) Библиотека PyWebIO устанавливается командой pip install pywebio
И .... все!
Код проекта:
```
import requests
from pywebio.input import input, actions
from pywebio.output import put_text, put_table, put_html, clear, put_buttons
from pywebio import start_server
from math import radians, sin, cos, sqrt, atan2
def haversine(lat1, lon1, lat2, lon2):
R = 6371000 # Радиус Земли в метрах
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat / 2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return R * c
def parse_coords(text: str):
parts = text.strip().split()
if len(parts) != 2:
raise ValueError("Введите ровно два числа, разделённых пробелом.")
try:
lat, lon = map(float, parts)
except ValueError:
raise ValueError("Неверный формат чисел. Введите координаты корректно.")
return lat, lon
def validate_coords(text):
try:
parse_coords(text)
except ValueError as e:
return str(e)
return None
def main():
while True:
clear()
put_text("=== Ввод базовой точки ===")
base_str = input("Введите базовую точку (широта и долгота через пробел)",
placeholder="00.000 00.0000", validate=validate_coords)
base_lat, base_lon = parse_coords(base_str)
put_text(f"Базовая точка установлена: ({base_lat}, {base_lon})")
additional_points = []
def render_map():
"""Функция отрисовки карты с точками"""
all_points = [(base_lat, base_lon)] + additional_points
points_js = ','.join(f"[{lat}, {lon}]" for lat, lon in all_points)
put_html(f'''
<div id="map" style="width: 100%; height: 400px; margin-top: 20px;"></div>
<script type="text/javascript">
function initMap() {{
var script = document.createElement('script');
script.src = '
document.head.appendChild(script);
}}
function onYaMapsLoad() {{
ymaps.ready(function () {{
var map = new ymaps.Map("map", {{
center: [{base_lat}, {base_lon}],
zoom: 13
}});
var points = [{points_js}];
for (var i = 0; i < points.length; i++) {{
var placemark = new ymaps.Placemark(points, {{
hintContent: (i === 0) ? "Базовая точка" : "Точка " + i,
balloonContent: "Координаты: " + points[0] + ", " + points[1],
preset: (i === 0) ? 'islands#redDotIcon' : 'islands#blueDotIcon'
}});
map.geoObjects.add(placemark);
}}
}});
}}
initMap();
</script>
''')
render_map() # Первоначальная отрисовка карты
while True:
action = actions("Выберите действие", buttons=["Добавить точку", "Рассчитать", "Сброс"])
if action == "Добавить точку":
point_str = input("Введите точку (широта и долгота через пробел)",
placeholder="00.0000 00.0000", validate=validate_coords)
lat, lon = parse_coords(point_str)
additional_points.append((lat, lon))
put_text(f"Добавлена точка: ({lat}, {lon})")
clear() # Очищаем интерфейс перед обновлением карты
put_text(f"Базовая точка: ({base_lat}, {base_lon})")
render_map()
elif action == "Рассчитать":
if not additional_points:
put_text("Не добавлено ни одной точки. Сначала добавьте хотя бы одну точку.")
continue
table_data = [["#", "Широта", "Долгота", "Расстояние (м)"]]
for idx, (lat, lon) in enumerate(additional_points, start=1):
distance = haversine(base_lat, base_lon, lat, lon)
table_data.append([idx, lat, lon, round(distance, 2)])
clear()
put_text(f"Базовая точка: ({base_lat}, {base_lon})")
put_table(table_data)
render_map() # Перерисовываем карту, чтобы сохранить точки
next_action = actions("Действие", buttons=["Сброс", "Выход"])
if next_action == "Сброс":
break
else:
return
elif action == "Сброс":
put_text("Сброс данных. Начинаем заново.")
break
if __name__ == '__main__':
start_server(main, port=8080)
```
Что делает скрипт? Автоматически считает расстояние от проверяемого клада до кладов ранее проданных с выкладки.
Конечно все это можно сделать воспользовавшись линейкой в яндекс или гугл картах, но все это очень муторно и долго, поэтому я решил частично автоматизировать процесс и "нацарапал", то что "нацарапал"

Строго прошу не судить как умею так пишу)
Итак сам скрипт разворачивается локально и не требует установки на сервер, хотя при желании конечно можно и организовать.
Перейдем к интерфейсу.
После того как развернули проект, идем в браузер и прописываем 127.0.0.1:8080 ну или localhost:8080
Перед нами открывается скудненький интерфейс

Вводим адрес проверяемого клада, точнее его координаты и жмякаем --> отправить.
Далее на страничку подгрузится яндекс карта, нам же надо удостовериться, что клад выполнен не возле школы, ментов или упаси боже детского сада.
Далее просто жмем --> Добавить точку и вбиваем координаты следующей точки
Повторяем процедуру со всеми координатами кладов выкладки и после того как внесли все точки, жмем --> Рассчитать
После чего скрипт выдаст все расстояния от проверяемого клада до ранее проданного.
Вот в общем то и весь незатейливый функционал. В будущем возможно буду дорабатывать и прикручу какие то более интересные фичи.
P.S Я только учусь)
Собственно как развернуть скрипт?
1) Потребуется установленный python версии 3.х
2) Библиотека PyWebIO устанавливается командой pip install pywebio
И .... все!
Пожалуйста Войдите или Зарегистрируйтесь чтобы видеть скрытые ссылки.
Сообщение обновлено:
Код проекта:
```
import requests
from pywebio.input import input, actions
from pywebio.output import put_text, put_table, put_html, clear, put_buttons
from pywebio import start_server
from math import radians, sin, cos, sqrt, atan2
def haversine(lat1, lon1, lat2, lon2):
R = 6371000 # Радиус Земли в метрах
dlat = radians(lat2 - lat1)
dlon = radians(lon2 - lon1)
a = sin(dlat / 2)**2 + cos(radians(lat1)) * cos(radians(lat2)) * sin(dlon / 2)**2
c = 2 * atan2(sqrt(a), sqrt(1 - a))
return R * c
def parse_coords(text: str):
parts = text.strip().split()
if len(parts) != 2:
raise ValueError("Введите ровно два числа, разделённых пробелом.")
try:
lat, lon = map(float, parts)
except ValueError:
raise ValueError("Неверный формат чисел. Введите координаты корректно.")
return lat, lon
def validate_coords(text):
try:
parse_coords(text)
except ValueError as e:
return str(e)
return None
def main():
while True:
clear()
put_text("=== Ввод базовой точки ===")
base_str = input("Введите базовую точку (широта и долгота через пробел)",
placeholder="00.000 00.0000", validate=validate_coords)
base_lat, base_lon = parse_coords(base_str)
put_text(f"Базовая точка установлена: ({base_lat}, {base_lon})")
additional_points = []
def render_map():
"""Функция отрисовки карты с точками"""
all_points = [(base_lat, base_lon)] + additional_points
points_js = ','.join(f"[{lat}, {lon}]" for lat, lon in all_points)
put_html(f'''
<div id="map" style="width: 100%; height: 400px; margin-top: 20px;"></div>
<script type="text/javascript">
function initMap() {{
var script = document.createElement('script');
script.src = '
Пожалуйста Войдите или Зарегистрируйтесь чтобы видеть скрытые ссылки.
document.head.appendChild(script);
}}
function onYaMapsLoad() {{
ymaps.ready(function () {{
var map = new ymaps.Map("map", {{
center: [{base_lat}, {base_lon}],
zoom: 13
}});
var points = [{points_js}];
for (var i = 0; i < points.length; i++) {{
var placemark = new ymaps.Placemark(points, {{
hintContent: (i === 0) ? "Базовая точка" : "Точка " + i,
balloonContent: "Координаты: " + points[0] + ", " + points[1],
preset: (i === 0) ? 'islands#redDotIcon' : 'islands#blueDotIcon'
}});
map.geoObjects.add(placemark);
}}
}});
}}
initMap();
</script>
''')
render_map() # Первоначальная отрисовка карты
while True:
action = actions("Выберите действие", buttons=["Добавить точку", "Рассчитать", "Сброс"])
if action == "Добавить точку":
point_str = input("Введите точку (широта и долгота через пробел)",
placeholder="00.0000 00.0000", validate=validate_coords)
lat, lon = parse_coords(point_str)
additional_points.append((lat, lon))
put_text(f"Добавлена точка: ({lat}, {lon})")
clear() # Очищаем интерфейс перед обновлением карты
put_text(f"Базовая точка: ({base_lat}, {base_lon})")
render_map()
elif action == "Рассчитать":
if not additional_points:
put_text("Не добавлено ни одной точки. Сначала добавьте хотя бы одну точку.")
continue
table_data = [["#", "Широта", "Долгота", "Расстояние (м)"]]
for idx, (lat, lon) in enumerate(additional_points, start=1):
distance = haversine(base_lat, base_lon, lat, lon)
table_data.append([idx, lat, lon, round(distance, 2)])
clear()
put_text(f"Базовая точка: ({base_lat}, {base_lon})")
put_table(table_data)
render_map() # Перерисовываем карту, чтобы сохранить точки
next_action = actions("Действие", buttons=["Сброс", "Выход"])
if next_action == "Сброс":
break
else:
return
elif action == "Сброс":
put_text("Сброс данных. Начинаем заново.")
break
if __name__ == '__main__':
start_server(main, port=8080)
```
Вложения
Последнее редактирование:
