Зараз я працюю в галузі ізохронів та основоположних алгоритмів. Що зараз спричиняє проблеми - це не розрахунок, якщо сам ізохрон, а візуалізація результатів.
Результатом мого ізохронічного алгоритму є точки та ребра. Насправді у мене є робоче рішення, але для 3873 країв і 1529 вузлів, здається, це займе назавжди (приблизно 2,0 секунди на моєму ноутбуці Lenovo T440s, який містить процесор Core i7 2015 i досить швидкий 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)? Насправді я міг би жити, втрачаючи деякі деталі до тих пір, поки ділянки, показані в моєму результаті, залишаються відокремленими, а обчислення стають (набагато) швидшими.