Вычислить параллельные линии вдоль центральной линии в PostGIS

10

У меня есть улица (осевая линия дороги) и таблицы многоугольников в моей базе данных PostgreSQL. Пример сценария выглядит следующим образом:

Пример сценария

Проблема:

Мне нужно вычислить параллельные линии вдоль улицы на пересечении 50-метрового буфера вокруг улицы и ближайшего многоугольника здания с обеих сторон. Желаемый выходной сценарий:

Желаемый выходной сценарий

Что я пробовал:

Мой подход был:

 1) Generate 50m buffer around street layer
 2) get the intersection of buffer and polygons
 3) Compute the distance
 4) Draw offset curves (parallel lines) at both sides of street layer
 5) Merge both curves to get parallel lines at the intersection

Вот моя попытка:

    WITH street_buffer AS (
     SELECT
      street.gid street_id,
      street.geom street_geom,
      ST_Buffer(street.geom, 50, 'endcap=square join=round') geom1,
      building.geom  geom2  
     FROM street
     LEFT JOIN building on ST_DWithin(building.geom, street.geom, 50)
     ORDER BY street_id
    ),
    selected_buildings AS (
     SELECT
      street_id,
      street_geom,
      ST_Intersection(geom1, geom2) geom
     FROM street_buffer
    ),
    distance AS (
     SELECT 
      street_id,
      street_geom,
      ST_Distance(street_geom, geom) as dist
     FROM selected_buildings 
    ),
    curves AS (
     SELECT 
      street_id,
      ST_OffsetCurve(ST_LineMerge(street_geom), dist) as curve1,
      ST_OffsetCurve(ST_LineMerge(street_geom), -dist) as curve2
     FROM distance
     ORDER BY street_id
    )
    SELECT 
     street_id,
     ST_Union(curve1, curve2) geom 
    FROM curves
    ORDER BY street_id

Проблема с вышеприведенным кодом состоит в том, что он не возвращает параллельные линии в соответствии с желаемым выходным значением, то есть параллельные линии на всех пересечениях полигонов генерируются вместо пересечения ближайших полигонов.

EDIT_1:

Фактический результат вышеприведенного кода:

code_output

Хотя в приведенном выше выводе требуются только желтые параллельные линии (кривые смещения до ближайших многоугольников по обе стороны улицы):

необходимые строки в фактическом выводе

Кто-нибудь может подсказать, как получить желаемый результат?

khajlk
источник
Можете ли вы добавить изображение фактического вывода, а? Это помогает в понимании проблемы.
наклон
@ TILT: я редактировал вопрос. Просто добавил фактический вывод и необходимые параллельные линии в фактическом выводе.
Хайлк
Вопрос сложнее, чем вы думаете. Жажда, вы должны выяснить, на какой стороне улицы дома. Только тогда вы сможете найти ближайший с обеих сторон. Вот сообщение с примером кода для поиска правильной стороны: gis.stackexchange.com/questions/156578/…
tilt
В действительности могут быть случаи, когда здания находятся только с одной стороны (я бы назвал это исключениями). Я мог бы изменить свой код для обработки исключений, как только смогу достичь желаемого результата. Выше вы все еще видите строительные полигоны с обеих сторон. На данный момент мое требование состоит в том, чтобы провести параллельные линии по обе стороны улицы (как показано на рисунке). Что касается вашей ссылки, я мог бы использовать пример кода для улучшения моего кода выше, вероятно, позже.
Хайлк
Я вижу, что буфер избыточен. Вы можете просто использовать stdwithin и использовать 50 в качестве расстояния. (Выберите улицы, здания, где st_dwithin (улицы, здания, 50))
jbalk

Ответы:

1

Если вы изменили расстояние CTE следующим образом:

distance AS (
 SELECT 
  street_id,
  street_geom,
  MIN(ST_Distance(street_geom, geom)) as dist
 FROM selected_buildings
 GROUP BY street_id, street_geom
)

тогда для каждой улицы будет возвращено только самое короткое расстояние, и на этом расстоянии будет сгенерирована одна пара линий смещения.

Энди Харфут
источник
Спасибо за предложение. Я проверю это и посмотрю, даст ли он ожидаемый результат. Я копался, чтобы решить эту проблему. Я обнаружил одну сумасшедшую идею: начать с буфера 1 м вокруг улицы и программно увеличить буфер И искать здания с обеих сторон, пока количество зданий не станет равным 2, а затем вернуть это буферное расстояние как ширину улицы. Конечная цель всех вышеперечисленных упражнений.
Хайлк
Это правда, что только одна пара смещения генерируется с использованием вашего предложения. Тем не менее, желтые параллельные линии, показанные выше, все еще отсутствуют :(
khajlk