Вопрос или проблема
На самом деле, я отслеживаю судно, для которого уже есть маршрут и текущая позиция. Теперь проблема в том, что очевидно, что судно не будет находиться на тех же координатах, что и указано в маршруте. Поэтому я хочу связать текущие координаты с маршрутом и получить обновленный маршрут.
Я уже подключился, но проблема в том, что судно идет длинным маршрутом. Это создаст проблемы для расчетов ETA.
Есть какие-либо предложения? Кроме того, изображение с картой получено с веб-сайта, просто для понимания.
Например, оригинальный маршрут заканчивается чем-то таким:
После обновления текущей позиции он должен выглядеть так:
Но моим способом я получаю это:
Вот мои данные и код:
p = {'route': [{'path': [[51.51309, 0.4836599999999862],
[51.512222970577746, 0.4838196951935174],
[51.50817683327391, 0.4845649394298732],
[51.50730980385166, 0.484724634623376],
[51.490146683273906, 0.6260075894298893],
[51.410052120577745, 1.285328045193495],
[51.392889, 1.4266110000000083],
[51.35695154999999, 1.4217484499999955],
[51.18924344999999, 1.3990565500000116],
[51.153306, 1.3941939999999988],
[50.939489249999994, 0.8940607000000114],
[49.94167775, -1.4398946999999964],
[49.727861, -1.9400280000000123],
[49.54469854999999, -2.366040450000014],
[48.689940449999995, -4.354098550000003],
[48.506778, -4.780111000000005],
[47.68888635, -5.458406800000006],
[43.87205865, -8.62378720000001],
[43.054167, -9.30208300000001],
[42.41353785, -9.331828900000005],
[39.42393515, -9.47064309999999],
[38.783306, -9.500389000000013],
[38.5191851, -9.424647249999992],
[37.286620899999996, -9.071185750000012],
[37.0225, -8.995443999999992],
[36.86918755, -8.487389949999994],
[36.15372945, -6.116471050000001],
[36.000417, -5.608417000000003],
[36.139162799999994, -4.182775300000003],
[36.7866432, 2.4702192999999966],
[36.925389, 3.8958609999999965],
[36.98901405, 4.773231850000002],
[37.285930949999994, 8.867629149999999],
[37.349556, 9.745000000000005],
[37.31056005, 9.939120849999995],
[37.12857895, 10.845018149999987],
[37.089583, 11.039139000000006],
[36.25582884999999, 14.171143199999989],
[32.36497615, 28.787162800000004],
[31.531222, 31.919167000000016],
[31.486459599999996, 31.97396710000001],
[31.2775684, 32.22970090000001],
[31.232806, 32.284501000000006],
[31.036959999999997, 32.32685409999999],
[30.123011999999996, 32.52450189999999],
[29.927166, 32.566855000000004],
[27.339266099999996, 34.20131845],
[15.262399899999998, 41.828814550000004],
[12.6745, 43.463278],
[12.6860083, 43.699777900000015],
[12.7397137, 44.80344410000001],
[12.751222, 45.03994399999999],
[12.944847099999999, 45.588698300000004],
[13.8484309, 48.14955170000002],
[14.042056, 48.698306],
[14.27693095, 49.22293100000002],
[15.37301405, 51.67118099999999],
[15.607889, 52.195806000000005],
[15.81688895, 52.6194309],
[16.79222205, 54.5963471],
[17.001222, 55.019971999999996],
[17.138847, 55.21973030000001],
[17.781097, 56.151935699999996],
[17.918722, 56.35169400000001],
[18.080792799999998, 56.575119],
[18.8371232, 57.61776900000001],
[18.999194, 57.841194],
[19.4823149, 58.13619825000001],
[21.736879099999996, 59.51288475000001],
[22.22, 59.80788899999999],
[22.840945849999997, 59.31257655000002],
[25.73869315, 57.00111844999998],
[26.359639, 56.50580600000001],
[26.160997649670072, 56.29158290493038],
[25.234004681463745, 55.29187512793891],
[25.035363331133816, 55.07765203286928],
[25.00255, 55.10811000000001]],
'type': 'SEA'}]}
from shapely.geometry import Point, LineString, Polygon
from shapely.ops import transform
from functools import partial
import pyproj
from shapely.ops import split
from itertools import chain
total_path=p['route'][0]['path'][1:-1] ##### Общий маршрут
total_line = LineString(total_path)
project = partial(
pyproj.transform,
pyproj.Proj('EPSG:4326'),
pyproj.Proj('EPSG:32633'))
total_ls = transform(project, total_line)
total_distance = total_ls.length/1852 ###### Общая длина в морских милях
print(total_distance, "Расстояние")
current_pin = (13.752724664396988, 56.42578125)
position = Point(current_pin)
all_points_coords = chain(total_line.coords,position.coords)
all_points = map(Point, all_points_coords)
new_line = LineString(sorted(all_points, key=total_line.project))
new_ls = transform(project, new_line)
new_distance = new_ls.length/1852
## остаточное расстояние от текущей позиции
remain = LineString(new_line.coords[new_line.coords[:].index(current_pin):])
remain = transform(project, remain)
r_distance = remain.length/1852
print(r_distance,"остаточное расстояние")
print(r_distance/13)
new_ls
Здесь моя главная проблема заключалась в близких точках моего currentpoint
. Поэтому я пришел к идее сократить ненужные/близкие точки, не теряя форму моей линии. А затем добавить currentpoint
.
Поэтому я добавил этот код к своему существующему коду:
from itertools import chain
def process(input_list, threshold=2.3):
combos = itertools.combinations(input_list, 2)
points_to_remove = [point2 for point1, point2 in combos if math.dist(point1, point2)<=threshold]
points_to_keep = [point for point in input_list if point not in points_to_remove]
return points_to_keep
total_path = process(p['route'][0]['path'])
Выход:
Тем не менее, я все еще не получаю лучший результат, буду рад услышать любые предложения по улучшению моей модели.
Кроме того, мне нужно получить остаточное расстояние около 1025 морских миль за 78 часов. Но из моего текущего кода я получил 1164 морские мили за 89,5 часа.
Ответ или решение
Для решения вашей проблемы по сглаживанию линии пути после добавления текущей координаты судна можно использовать несколько более продвинутых методов, чем просто удаление соседних точек. Ниже представлена краткая инструкция по улучшению качества линий и уменьшению расстояния до пути с использованием библиотеки Shapely и методов, которые помогут достичь более точных расчетов.
Понимание задачи
Вы хотите соединить текущую позицию (координаты судна) с существующим маршрутом, учитывая, что судно может отклоняться от заранее заданного пути. При этом важно сохранить точность маршрута и обеспечить реалистичное расчетное время прибытия, снизив нецелесообразные отклонения.
Этапы решения
-
Добавление текущей позиции:
Первым шагом является добавление текущей позиции судна к существующему маршруту. Вы можете использовать ту же логику, что и в вашем коде, однако вместо простого добавления точки, стоит рассмотреть также возможность вставки точки в правильную позицию вдоль маршрута. -
Сглаживание линий пути:
Вместо простого удаления точек, используйте метод "взвешенного сглаживания" или "интерполяции", чтобы сделать путь более плавным. Это разрешит вам уменьшать количество точек, сохраняя при этом общую форму линии.
import numpy as np
def smooth_line(line, factor=0.5):
smoothed_coords = []
coords = list(line.coords)
for i in range(len(coords) - 1):
start = np.array(coords[i])
end = np.array(coords[i + 1])
midpoint = (start + end) / 2.0
smoothed_coords.append(start)
smoothed_coords.append(midpoint * factor + end * (1 - factor))
smoothed_coords.append(coords[-1])
return LineString(smoothed_coords)
- Обновление расстояний:
После того как вы добавили текущую позицию и изменили линию с использованием метода сглаживания, пересчитайте оставшееся расстояние до конца маршрута.
total_path = LineString(process(p['route'][0]['path']))
smoothed_path = smooth_line(total_path)
new_line = LineString(sorted(chain(smoothed_path.coords, position.coords), key=smoothed_path.project))
# Пересчитать оставшееся расстояние
remain_distance = LineString(new_line.coords[new_line.coords[:].index(current_pin):])
- Улучшение оценки ETA:
Чтобы улучшить расчет ETA, можно использовать текущее местоположение и скорость судна. Если известна скорость судна, можно улучшить точность расчета времени до следующих точек.
velocity = 13 # Узлы
required_time_in_hours = remain_distance.length / (velocity * 1852)
print(required_time_in_hours, "часы до прибытия")
Рекомендации
- Используйте географические библиотеки: Попробуйте использовать более сложные географические библиотеки, такие как GeoPandas для интеграции данных и расчета.
- Параметры сглаживания: Настраивайте параметры сглаживания и оценки расстояний в зависимости от конкретной ситуации, ввиду различных путей и условий.
Заключение
Систематично подходя к изменениям, вы сможете создать более точный и оптимизированный маршрут, что в конечном счете положительно скажется на вашем расчете ETA и оптимизации пути для судна. Улучшения, внесенные в алгоритм, помогут значительно сократить ненужные расстояния и задержки, что сделает транспортировку более эффективной.