SASGIS - SAS.Планета
View Issue Details
0001116SAS.Планета[All Projects] Хотелкаpublic16-01-2012 04:5730-09-2013 21:04
Tolik 
 
lowfeatureN/A
confirmedopen 
110418 
29xxxx 
0001116: При измерении расстояний отображать линии в виде дуг
Сейчас расстояние между двумя точками измеряется по кратчайшему расстоянию между ними, но на карте изображается отрезок вместо дуги.

Во-первых, это сбивает с толку: непонятно, что мы измерили. Например, если поставить 2 точки на 60-й параллели от меридиана 50 до 130, получится 4189 км (это кратчайший путь). А если на том же самом отрезке поставить несколько промежуточных точек, получится 4476 км (это - грубо - расстояние вдоль параллели). Но визуально разницы нет.

Во-вторых, просто очень хочется видеть, какой именно путь самый короткий.
GE даёт примерно тот же результат, но рисует дуги.
линейка
parent of 0001188resolved zed Алгоритм проецирования точки на эллипсоиде 
parent of 0002088resolved zed Добавить в IDatum функцию построения N промежуточных точек отрезка 
related to 0001021resolved zed Измерение растояния 
Issue History
16-01-2012 04:57TolikNew Issue
16-01-2012 04:58TolikStatusnew => acknowledged
16-01-2012 04:58TolikDescription Updatedbug_revision_view_page.php?rev_id=2487#r2487
16-01-2012 05:00TolikDescription Updatedbug_revision_view_page.php?rev_id=2488#r2488
16-01-2012 05:11TolikAdditional Information Updatedbug_revision_view_page.php?rev_id=2492#r2492
16-01-2012 06:06vdemidovNote Added: 0004998
16-01-2012 09:49gpsMaxTag Attached: линейка
27-01-2012 21:29vdemidovStatusacknowledged => confirmed
27-01-2012 21:29vdemidovProduct Version.Nightly => 110418
27-01-2012 21:29vdemidovTarget Version => 29xxxx
27-02-2012 08:56vdemidovRelationship addedparent of 0001188
08-10-2012 14:19vdemidovRelationship addedrelated to 0001021
13-08-2013 12:47vdemidovRelationship addedparent of 0002088
30-09-2013 18:07zedNote Added: 0012996
30-09-2013 19:25zedNote Added: 0012997
30-09-2013 20:37vdemidovNote Added: 0012998
30-09-2013 20:41vdemidovNote Added: 0012999
30-09-2013 20:41zedNote Added: 0013000
30-09-2013 20:47vdemidovNote Added: 0013001
30-09-2013 21:01vasketsovNote Added: 0013004
30-09-2013 21:04vdemidovNote Added: 0013005
30-09-2013 21:04vdemidovNote Deleted: 0013005
30-09-2013 21:04vasketsovNote Added: 0013006

Notes
(0004998)
vdemidov   
16-01-2012 06:06   
Когда кто-нибудь напишет процедуры для работы с "Большим кругом" на эллипсоиде можно будет подумать. Нужна процедура разбиения отрезка на части, процедура проецирования точки по азимуту и расстоянию. Это по минимуму. А пока увы.
(0012996)
zed   
30-09-2013 18:07   
Сейчас вроде есть всё необходимое, чтобы рисовать дугу?

Алгоритм мне видится такой:
1. Берём 2 точки, между которыми нужно нарисовать дугу и измеряем расстояние между ними (TDatum.CalcDist). При этом, мы получаем начальный азимут.
2. Делим расстояние на 2 и используя начальный азимут из предыдущего шага, находим координаты промежуточной точки.
3. Собственно, можем рисовать дугу.

У меня только возник вопрос, где у нас происходит отрисовка этой линии/дуги? В TCalcLineLayer только рендерится текст, но в параметрах присутствует IPathOnMapEdit. Кто его рисует? Мы там можем определить, что рисуем именно линейку, а не путь, чтобы рисовать дугу (TBitmap32.Canvas.Arc). Или можно рисовать дуги и для путей?
(0012997)
zed   
30-09-2013 19:25   
Доработал 0002088 - теперь у IDatum можно сразу попросить эту промежуточную точку, без лишних телодвижений.

Теперь вопрос, как это нарисовать? Хочется рисовать именно дугу, а не несколько ломанных линий.
(0012998)
vdemidov   
30-09-2013 20:37   
А зачем дугу? ИМХО гораздо проще таки ломаную линию, просто нужно правильно подбирать количество промежуточных точек. Делать это нужно на этапе построения спроецированной линии. Я представляю себе это как-то так:
1. Есть 2 точки в LonLat.
2. Получаем их спроецированные координаты.
3. Смотрим расстояние в пикселях.
4. Сравниваем расстояние, если меньше какого-то определенного числа, то вообще оставляем как есть.
5. Если больше то разбиваем на количество точек пропорциональное расстоянию в пикселах, но не больше максимального.
5а. Как вариант (только сейчас придумал), разбивать отрезок напополам и смотреть насколько промежуточная точка отличается простой середины отрезка и если она больше порогового значения в 2-10 пикселей, то повторять процедуру для каждого из полученных отрезков.
(0012999)
vdemidov   
30-09-2013 20:41   
Для варианта 5а нужно не забывать, что расстояние в пикселах нужно считать ближайшее через 0-й или 180-мередиан, а то получим бесконечную рекурсию.
(0013000)
zed   
30-09-2013 20:41   
>А зачем дугу?
А почему нет? Чем тебе не нравится вызов Canvas.Arc с четырьмя параметрами, который нарисует честную дугу без всяких аппроксимаций.
(0013001)
vdemidov   
30-09-2013 20:47   
Ну хотя бы тем, что их понадобиться пробрасывать через кучу уровней включая кэширование и 2 трансформации. Я не возьмусь такое реализовывать и потом поддерживать.
(0013004)
vasketsov   
30-09-2013 21:01   
>пробрасывать через кучу уровней включая кэширование и 2 трансформации
Почему не сделать как отдельный тип геопримитива?
Те же метки в виде окружности можно сделать честными, а не 64-угольниками.
И дуги можно (окружность будет как частный случай дуги).
(0013006)
vasketsov   
30-09-2013 21:04   
Проблема конечно будет с операциями над полигонами и окружностями, типа вычитания или объединения, но их пока нет.