Недавно я просматривал веб-страницы авиакомпаний, на которых отображаются их маршруты, вылетающие из определенного города во все другие города, которые они обслуживают. Я хотел бы иметь возможность создавать похожие кривые маршруты между точками. Кто-нибудь создал сценарии или функции, которые будут генерировать изогнутые дуги, подобные тем, что показаны в этом примере ?
В PostGIS, есть ли реализация ST_MakeLine, которая позволила бы вам указать количество кривой, которая будет использоваться при соединении 2 точек?
Хотя в настоящее время я использую PostGIS и QGIS, я хотел бы услышать о других вариантах программного обеспечения, которые могут создать такой же внешний вид.
Ответы:
Создание больших кругов может дать вам желаемый эффект.
Может быть, что-то вроде того, что обсуждается на http://lists.osgeo.org/pipermail/postgis-users/2008-F February/018620.html
Обновить:
Я развил эту идею в «Визуализации глобальных связей» . Это чисто PostGIS-решение, использующее перепроектирование для создания дуг.
(Определение CRS для 953027 можно найти здесь: http://spatialreference.org/ref/esri/53027/ )
источник
Задача состоит в том, чтобы выяснить, насколько сильно изгибаются дуги, чтобы улучшить их визуальное разрешение.
Вот одно из решений (среди множества возможных). Давайте рассмотрим все дуги, происходящие из общего происхождения. Здесь дуги самые многолюдные. Чтобы разделить их наилучшим образом, давайте расположим их так, чтобы они распределялись под равными углами . Это проблема, если мы рисуем отрезки прямых линий от источника до пунктов назначения, потому что обычно в разных направлениях будут кластеры пунктов назначения. Давайте использовать нашу свободу, чтобы изгибать дуги, чтобы расположить исходящие углы как можно более равномерно.
Для простоты давайте используем круговые дуги на карте. Естественной мерой «изгиба» в дуге от точки y к точке x является разность между ее направлением в y и подшипником непосредственно от y до x . Такая дуга является сектором круга, на котором лежат оба y и x ; элементарная геометрия показывает, что угол изгиба равен половине включенного угла в дуге.
Для описания алгоритма нам понадобится немного больше обозначений. Пусть y будет исходной точкой (как спроецировано на карту), и пусть x_1 , x_2 , ..., x_n будут точками назначения. Определите a_i как отношение от y к x_i , i = 1, 2, ..., n .
В качестве предварительного шага предположим, что подшипники (все от 0 до 360 градусов) расположены в порядке возрастания: для этого необходимо рассчитать подшипники и затем отсортировать их; оба простые задачи.
В идеале мы хотели бы, чтобы подшипники дуг равнялись 360 / n , 2 * 360 / n и т. Д. Относительно некоторого начального подшипника. Таким образом, различия между требуемыми подшипниками и действительными подшипниками равны i * 360 / n - a_i плюс начальный подшипник, a0 . Наибольшая разница - это максимум этих n различий, а наименьшая разница - их минимум. Давайте установим a0 на полпути между максимумом и минимумом; это хороший кандидат на пусковой подшипник, поскольку он сводит к минимуму максимальный изгиб, который может произойти . Следовательно, определить
b_i = i * 360 / n - a0 - a_i:
это изгиб, чтобы использовать .
Элементарной геометрией является рисование дуги окружности от y до x, которая составляет угол 2 b_i, поэтому я пропущу детали и перейду прямо к примеру. Вот иллюстрации решений для 64, 16 и 4 случайных точек, помещенных в прямоугольную карту
Как вы можете видеть, решения, кажется, становятся лучше с увеличением количества пунктов назначения. Решение для n = 4 ясно показывает, как подшипники расположены на одинаковом расстоянии, поскольку в этом случае расстояние равно 360/4 = 90 градусов, и очевидно, что расстояние точно достигнуто.
Это решение не идеально: вы можете определить несколько дуг, которые можно настроить вручную для улучшения графики. Но это не сделает ужасную работу и, кажется, действительно хорошее начало.
Алгоритм также имеет преимущество простоты: самая сложная часть состоит в сортировке пунктов назначения в соответствии с их ориентирами.
кодирование
Я не знаю PostGIS, но, возможно, код, который я использовал для рисования примеров, может служить руководством для реализации этого алгоритма в PostGIS (или любой другой ГИС).
Считайте следующее псевдокодом (но Mathematica выполнит его :-). (Если бы этот сайт поддерживал TeX, как это делают математика, статистика и TCS, я мог бы сделать это намного более читабельным.) Нотация включает в себя:
Исполняемая часть кода, к счастью, короткая - менее 20 строк - потому что более половины ее составляют либо декларативные накладные расходы, либо комментарии.
Нарисуй карту
z
это список направлений иy
является источником.Создайте дугу окружности от точки
x
к точке,y
начиная под углом\[Beta]
относительно подшипника x -> y.Вычислить подшипники от начала координат до списка точек.
Вычислите средние значения остатков набора подшипников.
x
это список подшипников в отсортированном порядке. В идеале, x [[i]] ~ 2 [Pi] i / n.источник
Попробуйте ST_CurveToLine
Что-то вроде например:
Вы можете визуализировать это, скопировав запрос в текстовое поле и нажав Map1 на http://www.postgisonline.org/map.php
источник
Я бы подумал, что вы просто захотите свернуть свою собственную ломаную с какой-нибудь векторной математикой, http://en.wikipedia.org/wiki/B%C3%A9zier_curve , или если ваш gis имеет интерфейс ICurve .
источник
Я закончил тем, что попытался изогнуть набор «двухточечных» строк, используя функцию ST_CurveToLine, как предложено @Nicklas Avén.
Я передал следующие 3 набора координат в функцию ST_OffsetCurve:
Я использовал функцию ST_OffsetCurve для вычисления смещения - 1/10-й длины исходной линии в моем примере.
Вот SQL, который я использовал для генерации кривых линий из исходных прямых линий:
источник