Вопрос или проблема
У меня есть геодатафрейм. Я хочу объединить пересекающиеся объекты и конкатенировать поле “Text”. Я пробовал сделать это с помощью dissolve, но это не сработало.
import geopandas as gpd
import pandas as pd
from shapely.geometry import MultiLineString
data = {
"type": "FeatureCollection",
"name": "lines",
"features": [
{ "type": "Feature", "properties": { "Text": "A" },
"geometry": { "type": "MultiLineString",
"coordinates": [ [ [ 0.0, 0.0, 0.0 ], [ 10.0, 0.0, 0.0 ] ] ] } },
{ "type": "Feature", "properties": { "Text": "B" },
"geometry": { "type": "MultiLineString",
"coordinates": [ [ [ 0.0, 0.0, 0.0 ], [ 16.37797725526616, 0.0, 0.0 ] ] ] } },
{ "type": "Feature", "properties": { "Text": "C" },
"geometry": { "type": "MultiLineString",
"coordinates": [ [ [ 0.0, 0.0, 0.0 ], [ 4.247235166607424, 7.041334981156978, 0.0 ],
[ 16.742636807728559, 8.986970615165774, 0.0 ] ] ] } },
{ "type": "Feature", "properties": { "Text": "D" },
"geometry": { "type": "MultiLineString",
"coordinates": [ [ [ 0.0, 0.0, 0.0 ], [ 4.247235166607424, 7.041334981156978, 0.0 ] ] ] } }
]
}
features = data['features']
geometries = []
properties = []
for feature in features:
coords_3d = feature['geometry']['coordinates']
coords_2d = [[(x, y) for x, y, z in line] for line in coords_3d]
multiline = MultiLineString(coords_2d)
geometries.append(multiline)
properties.append(feature['properties'])
df = pd.DataFrame(properties)
gdf = gpd.GeoDataFrame(df, geometry=geometries)
Что я ищу:
Объединить пересекающиеся объекты
Ответ или решение
Чтобы объединить пересекающиеся или соприкасающиеся линейные геометрические объекты в GeoPandas и конкатенировать связанные текстовые поля, можно использовать метод dissolve
. Однако, как вы заметили, простое объединение может не всегда работать как ожидается, особенно в трехмерных координатах. Необходимо будет дополнительно обработать геометрические объекты, чтобы достичь желаемого результата.
Вот пример того, как это можно сделать:
import geopandas as gpd
import pandas as pd
from shapely.geometry import MultiLineString, LineString
# Данные
data = {
"type": "FeatureCollection",
"name": "lines",
"features": [
{"type": "Feature", "properties": {"Text": "A"},
"geometry": {"type": "MultiLineString",
"coordinates": [[[0.0, 0.0, 0.0], [10.0, 0.0, 0.0]]]}},
{"type": "Feature", "properties": {"Text": "B"},
"geometry": {"type": "MultiLineString",
"coordinates": [[[0.0, 0.0, 0.0], [16.37797725526616, 0.0, 0.0]]]}},
{"type": "Feature", "properties": {"Text": "C"},
"geometry": {"type": "MultiLineString",
"coordinates": [[[0.0, 0.0, 0.0], [4.247235166607424, 7.041334981156978, 0.0],
[16.742636807728559, 8.986970615165774, 0.0]]]}},
{"type": "Feature", "properties": {"Text": "D"},
"geometry": {"type": "MultiLineString",
"coordinates": [[[0.0, 0.0, 0.0], [4.247235166607424, 7.041334981156978, 0.0]]]}},
]
}
# Создание GeoDataFrame
features = data['features']
geometries = []
properties = []
for feature in features:
coords_3d = feature['geometry']['coordinates']
coords_2d = [[(x, y) for x, y, z in line] for line in coords_3d]
multiline = MultiLineString(coords_2d)
geometries.append(multiline)
properties.append(feature['properties'])
df = pd.DataFrame(properties)
gdf = gpd.GeoDataFrame(df, geometry=geometries)
# Объединение пересекающихся линий
# Создаем 2D представление для растворения (dissolve)
gdf['geometry'] = gdf['geometry'].apply(lambda geom: geom.dissolve())
# Объединение по идентификатору (обычно по уникальному идентификатору, в данном случае обходимся без него)
gdf_combined = gdf.dissolve(by=None, aggfunc='sum')
# Получаем текстовые поля
gdf_combined['Text'] = gdf['Text'].str.cat(sep='; ')
# Выводим результат
print(gdf_combined)
В этом коде мы:
- Загружаем ваши данные в
GeoDataFrame
. - Упрощаем геометрию до 2D.
- Используем метод
dissolve
, который объединяет геометрии, которые пересекаются или соприкасаются, и агрегирует связанные данные. Здесь мы используемaggfunc='sum'
, чтобы объединить строки на основе текстового поля. - Конкатенируем все значения текстового поля с помощью метода
str.cat()
.
Убедитесь, что у вас установлены необходимые библиотеки (geopandas
, shapely
, pandas
), чтобы код работал правильно. После выполнения вы получите объединенный GeoDataFrame
с правильными геометриями и конкатенированными текстами, соответствующими вашим требованиям.