Как разбить LineString на сегменты - PullRequest
1 голос
/ 28 мая 2020

Мой набор данных состоит из LineString, и я хочу отфильтровать отдельные линейные сегменты этого LineString. Точнее, каждый отдельный сегмент улицы.

До сих пор я извлекал отдельные точки из набора данных и сохранял их в отдельном списке. Кроме того, я хотел бы снова собрать эти точки и создать из них отдельные LineString, чтобы сохранить их в Geodataframe. Данные имеют следующую форму:

LINESTRING (3275.284016199762 340555.8579582386, 3241.504528076811 340504.1348617533, 3245.415803206172 340501.457084205, 3280.414559049542 340552.7138220053, 3285.19053022

Моя проблема в том, что мне пришлось бы создавать и явно сохранять отдельный LineString для каждой итерации. Кто-нибудь может мне с этим помочь? Есть ли лучший способ для этого?

from shapely.geometry import Point, LineString

#Loop over LineString and gather Points
c=[]

for i in range(0,end):
    c.append(Point(route1.coords[i]))


iterator=len(c)
max=len(c)-1

#Loop to store LineStrings - got stuck here
for i in np.arange(0,iterator):
    if i<max:
        LineString([c[i], c[i+1]]).wkt

    else:
        break;

Результат должен выглядеть так:

Linestring(Point A, Point B)  
Linestring(Point B, Point C)  
Linestring(Point C, Point D)  
...  
Linestring(Point Y, Point Z)

Ответы [ 2 ]

1 голос
/ 28 мая 2020

Добро пожаловать в SO.

Вам не нужно писать код для разделения LineString. Пусть PostGIS выполнит эту работу :) В быстром и грязном примере ниже используется CTE to ST_DumpPoints из вашего LineString, а затем создается еще одна строка с path, path + 1, используя оконная функция lead():

WITH j AS (
  SELECT ST_DumpPoints('LINESTRING (10 10, 12 12, 14 14, 16 16, 18 18)') AS g
)
SELECT ST_AsText(point) FROM (
  SELECT ST_MakeLine((g).geom, lead((g).geom,1) OVER ()) AS point
  FROM j) i
WHERE i.point IS NOT NULL

            st_astext        
-------------------------
 LINESTRING(10 10,12 12)
 LINESTRING(12 12,14 14)
 LINESTRING(14 14,16 16)
 LINESTRING(16 16,18 18)
(4 Zeilen)
0 голосов
/ 28 мая 2020

Говоря о Shapely, он не предоставляет функции для разделения объекта кривой (LineString или LinearRing) на сегменты, поэтому вам придется написать свой собственный. Вот пример того, как вы могли бы сделать это, используя zip для перебора пар координат и map их до LineString:

from shapely.geometry import LineString, LinearRing


def segments(curve):
    return list(map(LineString, zip(curve.coords[:-1], curve.coords[1:])))


line = LineString([(0, 0), (1, 1), (2, 2)])
ring = LinearRing([(0, 0), (1, 0), (1, 1), (0, 1)])

line_segments = segments(line)
for segment in line_segments:
    print(segment)
# LINESTRING (0 0, 1 1)
# LINESTRING (1 1, 2 2)

ring_segments = segments(ring)
for segment in ring_segments:
    print(segment)
# LINESTRING (0 0, 1 0)
# LINESTRING (1 0, 1 1)
# LINESTRING (1 1, 0 1)
# LINESTRING (0 1, 0 0)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...