Оператору в помощь

green leaf

error
Кадровый Агент
Сообщения
325
Реакции
472
Доброго дня коллеги, решил выложить небольшой скрипт - в помощь оператору так сказать, возможно кому-то он будет полезен.
Что делает скрипт? Автоматически считает расстояние от проверяемого клада до кладов ранее проданных с выкладки.
Конечно все это можно сделать воспользовавшись линейкой в яндекс или гугл картах, но все это очень муторно и долго, поэтому я решил частично автоматизировать процесс и "нацарапал", то что "нацарапал" :D
Строго прошу не судить как умею так пишу)
Итак сам скрипт разворачивается локально и не требует установки на сервер, хотя при желании конечно можно и организовать.
Перейдем к интерфейсу.
После того как развернули проект, идем в браузер и прописываем 127.0.0.1:8080 ну или localhost:8080
Перед нами открывается скудненький интерфейс :)

1738393760507.png




Вводим адрес проверяемого клада, точнее его координаты и жмякаем --> отправить.
Далее на страничку подгрузится яндекс карта, нам же надо удостовериться, что клад выполнен не возле школы, ментов или упаси боже детского сада. :watsup:
1738393938168.png

Далее просто жмем --> Добавить точку и вбиваем координаты следующей точки

1738394067792.png


Повторяем процедуру со всеми координатами кладов выкладки и после того как внесли все точки, жмем --> Рассчитать

1738394218332.png

После чего скрипт выдаст все расстояния от проверяемого клада до ранее проданного.
1738394341835.png


Вот в общем то и весь незатейливый функционал. В будущем возможно буду дорабатывать и прикручу какие то более интересные фичи.
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)

```
 

Вложения

  • 1738393730213.png
    1738393730213.png
    31.9 КБ · Просмотры: 73
Последнее редактирование:
Если проект кого-то заинтересовал, то я добавил кнопку по клику на которую пересчитываются и сверяются расстояния между всеми точками и в случае обнаружения расстояния менее чем 25 метров, будет подсвечиваться соответствующее оповещение.
Пример не посредственного выявления нарушений в выкладке.
1738471575359.png
 

Вложения

  • 1738471485210.png
    1738471485210.png
    83.8 КБ · Просмотры: 37
Последнее редактирование:
а куда что где вводить?
непониль..
Проект надо для начала развернуть локально на своей машине (компьютере), в терминале после увидишь что-то навроде этого


1739743966773.png


В браузере откроешь ссылку и далее уже все станет понятно.
Откроется вот такое окно
1739744109481.png




Вот в bash все запихал.
Можно скачать тут.
Запуск - качаем скрипт, открываем терминал в папке куда скачали.
1) Даем права на исполнение, вводим в терминале
chmod +x setup.sh
2) Запускаем скрипт
./setup.sh
3) Когда все установиться , активируем витруальное окружение и запускаем скрипт. (в будущем для запуска используем только эту команду)
source venv/bin/activate && python3 main.py
 
Последнее редактирование:
Проект надо для начала развернуть локально на своей машине (компьютере), в терминале после увидишь что-то навроде этого


Посмотреть вложение 2037948

В браузере откроешь ссылку и далее уже все станет понятно.
Откроется вот такое окно
Посмотреть вложение 2037949
Сообщение обновлено:

#!/bin/bash

# Устанавливаем Python и venv, если не установлены
if ! command -v python3 &> /dev/null; then
echo "Устанавливаем Python3..."
sudo apt update && sudo apt install -y python3 python3-venv python3-pip
fi

# Создаём виртуальное окружение
if [ ! -d "venv" ]; then
echo "Создаём виртуальное окружение..."
python3 -m venv venv
fi

# Активируем виртуальное окружение
source venv/bin/activate

# Устанавливаем зависимости
pip install --upgrade pip
pip install requests pywebio

# Создаём Python-скрипт
cat <<EOF > main.py
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 check_all_distances(points):
violations = []
n = len(points)
for i in range(n):
for j in range(i + 1, n):
d = haversine(points[0], points[1], points[j][0], points[j][1])
if d < 26:
violations.append((points, points[j], round(d, 2)))
return violations

def main():
while True:
clear()
put_text("=== Ввод базовой точки ===")
base_str = input("Введите базовую точку (широта и долгота через пробел)",
placeholder="56.31337 43.97345", validate=validate_coords)
base_lat, base_lon = parse_coords(base_str)

put_text(f"Базовая точка установлена: ({base_lat}, {base_lon})")
additional_points = []

if __name__ == "__main__":
start_server(main, port=8080, debug=True)
EOF

# Выводим сообщение о завершении установки
echo "Установка завершена!"
echo "Для запуска введите:"
echo "source venv/bin/activate && python3 main.py"

Вот в bash все запихал.
Можно скачать тут.
Запуск - качаем скрипт, открываем терминал в папке куда скачали.
1) Даем права на исполнение, вводим в терминале
chmod +x setup.sh
2) Запускаем скрипт
./setup.sh
3) Когда все установиться , активируем витруальное окружение и запускаем скрипт. (в будущем для запуска используем только эту команду)
source venv/bin/activate && python3 main.py
теперь понятно
спасибо большое
 
Закатал все в бинарник, что бы не было проблем с сборкой проекта. Теперь можно просто скачать один файл дать ему права на исполнение и запустить командой ./main.bin

Это под линукс, если надо создам и под мак с виндой.
 
Добавил exe для виндоводов)

После запуска должна автоматически открыться страничка приложения в браузере.Протестировать не смог ввиду отсутствия винды, заморачиваться с виртуалкой попросту лень.
Сообщение обновлено:
 
Последнее редактирование:
Интересное чтиво, спасибо, добавил в закладки даже)
 
Последнее редактирование:
А с телефона можно? И можно ли делать сохранение точек? Условно создать несколько вкладок с уже прописанными координатами?
 
Назад
Сверху Снизу