Как уплотнить вершины LineString в Shapely / GeoPandas
Я ищу аналог инструмента уплотнения в ArcGIS, но с GeoPandas или Shapely. У меня есть линия, которую хотелось бы уплотнить на определенном расстоянии; как добавить вершины линии с помощью Python?
Предположим, у меня есть линия с двумя вершинами (WKT) LINESTRING (0 0, 9 0). как мне разделить линию на равное расстояние 1, чтобы она возвращала ту же строку, но вместо 2 вершин у нее было 10 вершин? В результате я ожидаю:
LINESTRING (0 0, 1 0, 2 0, 3 0, 4 0, 5 0, 6 0, 7 0, 8 0, 9 0). Я нашел этот пост, который похож на то, что я хочу, но в нем используется ArcGIS вместо GeoPandas и Shapely.
Ответы
Я создал для вас функцию. Вот ваша строка, которую я называю old_line:
old_line=LineString([(0,0), (9,0)]) # your line with 2 vertices
Вот функция, которая принимает линейную геометрию в качестве основного ввода, вы назначаете шаг (т.е. интервал вдоль старой линии) и дополнительную систему координат (crs) для привязки новой уплотненной линии.
def densify_geometry (line_geometry, step, crs=None):
# crs: epsg code of a coordinate reference system you want your line to be georeferenced with
# step: add a vertice every step in whatever unit your coordinate reference system use.
length_m=line_geometry.length # get the length
xy=[] # to store new tuples of coordinates
for distance_along_old_line in np.arange(0,int(length_m),step):
point = line_geometry.interpolate(distance_along_old_line) # interpolate a point every step along the old line
xp,yp = point.x, point.y # extract the coordinates
xy.append((xp,yp)) # and store them in xy list
new_line=LineString(xy) # Here, we finally create a new line with densified points.
if crs != None: # If you want to georeference your new geometry, uses crs to do the job.
new_line_geo=gpd.geoseries.GeoSeries(new_line,crs=crs)
return new_line_geo
else:
return new_line
Теперь бегаем:
densify_geometry(line_geometry=old_line, step= 0.5, crs= 32754)
возвращает:
LINESTRING (0.00000 0.00000, 0.50000 0.00000, ...
dtype: geometry
Если вы хотите применить его ко всемуGeoDataFrame столбцу геометрии :
kwargs_dict={'step':0.5,
'crs':32754}
your_gdf["new_geometry"]=your_gdf.geometry.apply(densify_geometry, kwargs=**kwargs_dict)
Это должно сработать.