В настоящее время я работаю в области изохрон и базовых алгоритмов. В настоящее время возникают проблемы не в расчете самой изохроны, а в визуализации результатов.
Результатом моего изохронного алгоритма являются точки и ребра. На самом деле у меня есть работающее решение, но для 3873 ребер и для 1529 узлов все, кажется, занимает вечность (около 2,0 секунд на моем ноутбуке Lenovo T440s, который содержит процессор Core i7 2015 года и довольно быстрый SSD). Вместо секунд я хочу что-то более похожее на msec :-).
Может быть, кто-то может помочь мне сократить время расчета, необходимое для построения полигонов, которые визуализируют достижимые области.
Но подождите ... обо всем по порядку!
Вот визуализация ребер, которые я
являю результатом вычисления моей изохроны:
Эти ребра хранятся в таблице базы данных PostGIS и являются простыми линейными строками.
То, что я хочу показать пользователю, выглядит следующим образом: Обратите внимание на отключенные области на самом юге и очень востоке изображения. Они должны быть нарисованы как отдельные области (поэтому слияние не допускается :-))
В настоящее время я использую этот запрос:
SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
SELECT ST_MakePolygon(ST_ExteriorRing(ST_GeometryN(segments, generate_series(1, ST_NumGeometries(segments))))) AS polygons FROM (
SELECT ST_Union(ST_Buffer("GEOMETRY", 20, 'quad_segs=2')) AS segments FROM my_edges AS a
) AS b
) AS c
Я уже провел некоторые эксперименты и прочитал много документации, но просто не могу найти лучшего решения.
На мой взгляд, большая проблема заключается в использовании ST_Union (как указано в документации, эта функция может быть медленной). Очень интересно то, что замена его на ST_Collect, кажется, замедляет вычисление ST_Buffer, так что в целом следующий запрос занимает больше времени, хотя он не заполняет области между краями (он только создает буфер вокруг строк ):
SELECT ST_AsGeoJson(St_Transform(ST_Multi(ST_Collect(polygons)), 4326)) AS coverage FROM (
SELECT ST_Buffer(ST_Collect(ST_LineMerge("GEOMETRY")), 20, 'quad_segs=2') AS polygons FROM my_edges AS a
) AS b
Это занимает около 3,8 секунды в моей системе (так почти вдвое больше). Мой первый вывод из этого небольшого теста состоит в том, что ST_Buffer неожиданно замедляется, когда дело доходит до MultiLineStrings (даже медленнее, чем при создании буферов для каждой строки и объединении буферов - что на мой взгляд просто странно)
Я также пытался использовать альфа-формы (используя реализацию из pgRouting), но так как альфа-значение не нужно устанавливать (и на самом деле я бы сейчас не знал, какое значение установить для такого значения), я просто получил один отличный полигон ( поэтому я бы потерял регионы на самом юге и востоке как отдельные регионы, а это не то, чего я хочу).
Кроме того, ST_Polygonize (который был первым, что пришло мне в голову) не дал никаких полезных результатов, но, возможно, я что-то здесь упустил ...
Есть ли лучший способ создать область, показанную в PostGIS? Может также использовать java-код (jts) или код javascript на стороне клиента (jsts)? Фактически, я мог бы потерять некоторые детали, пока области, показанные в моем результате, остаются разделенными, и вычисление становится (намного) быстрее.