Получить длину подсегмента "линейная строка" в заданной области (используя ST_DWithin) - PullRequest
1 голос
/ 04 апреля 2019

Мне нужно получить длину части геометрического объекта линейной линии внутри круга (точка + радиус).

В настоящее время я использую функцию ST_DWithin, но, к сожалению, она возвращает полный объект, а не часть объекта внутри области.Действительно, изменение радиуса (от 100 до 70) не приводит к изменению полученной длины.

osm_data=# select highway, st_length(way) from planet_osm_line where ST_DWITHIN(ST_Transform(way,4326),ST_GeomFromText('POINT(4.1884918 51.144580)',4326)::geography,100) and highway is not null;
   highway    |    st_length     
--------------+------------------
 motorway     | 5079.24632083105
 unclassified | 1110.56834915499
 motorway     | 1499.83459080537
(3 rows)

osm_data=# select highway, st_length(way) from planet_osm_line where ST_DWITHIN(ST_Transform(way,4326),ST_GeomFromText('POINT(4.1884918 51.144580)',4326)::geography,70) and highway is not null;
   highway    |    st_length     
--------------+------------------
 motorway     | 5079.24632083105
 unclassified | 1110.56834915499
 motorway     | 1499.83459080537
(3 rows)

1 Ответ

0 голосов
/ 04 апреля 2019

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

Чтобы вычислить фактическую длину (или площадь для полигонов) внутри, вам нужно будет вычислить пересечение.

select highway, 
   st_length(way) full_length,   
   st_length(
     ST_INTERSECTION(
        ST_Transform(way,4326)::geography,
        ST_BUFFER(
          ST_GeomFromText('POINT(4.1884918 51.144580)',4326)::geography,
         100)
      )
   )
  from planet_osm_line 
  where
    ST_DWITHIN(
      ST_Transform(way,4326)::geography,
      ST_GeomFromText('POINT(4.1884918 51.144580)',4326)::geography,100) 
    and highway is not null;

Для оптимизации этого запроса вы должны использовать

WITH buff as (
   SELECT ST_BUFFER(
            ST_GeomFromText('POINT(4.1884918 51.144580)',4326)::geography, 
            1000) as geog)  
select highway, 
   st_length(way) full_length,   
   st_length(
     ST_INTERSECTION(
        ST_Transform(way,4326)::geography,
        buff.geog
      )
   )
from osm.osm_line
    INNER JOIN buff
        ON ST_DWITHIN(
          ST_Transform(way,4326),
          buff.geog,
          1000) 
where highway is not null;

Обратите внимание, что буфер - это только приблизительное значение круга, поэтому результат может быть немного не таким.

...