Python GeoPandas 将 LineString 2D 转换为 3D - 仅添加 z 坐标

问题描述 投票:0回答:1

我花了很多时间寻找解决方案,但还没有找到合适的解决方案。

我有一个地理数据框,其中两点之间有 2D LineString,每个 2D LineString 还有 2 个不同的 Z 值/坐标。 我想要一种直接的方法将这些 z 坐标添加到受尊重的 LineString 部分。 有没有一种好的方法可以通过使用 ex shapely.ops.transform 来实现此目的?或者任何其他技术?.

我知道我可以通过多种方式访问 LineString x,y 坐标,构建两个 3D 点,然后使用 x,y,z 坐标在这两个点之间创建 3D LineString,因此我不会搜索所有方法。但我想要一种更直接的方法来做到这一点,而不是首先创建 3D 点,然后创建 3D LineString。

我也不是在寻找如何将专用 z 值添加到 2D LineString 以创建 3D LineString。我需要在 LineStrings 的不同部分使用不同的 Z 坐标。

我的代码:

    import pandas as pd
    import geopandas as gpd
    from shapely import wkt
    
    df = pd.DataFrame(
        {
        "ID": [1, 2, 3],
        "z1": [133.56, 184.84, 230.53],
        "z2": [158.66, 212.68, 241.20],
        "geometry": [
            "LINESTRING (565035.0499992011 6622605.24012313, 565064.889999201 6622483.90012313)",
            "LINESTRING (565084.009999201 6622367.28012313, 565101.339999201 6622257.27012313)",
            "LINESTRING (565119.8599992 6622140.37012313, 565144.4599992 6621985.04012313)"]
    }
    )
    
    print(df)
    df["geometry"] = gpd.GeoSeries.from_wkt(df["geometry"])
    
    gdf = gpd.GeoDataFrame(df, geometry="geometry")
    gdf = gdf.set_crs('epsg:25832')
    print(gdf.crs)
    print(gdf.dtypes)
    
    print(gdf['geometry'][0])
    print(gdf['geometry'][1])
    print(gdf['geometry'][2])
    gdf

结果: 每股收益:25832 ID int64 z1 浮点数64 z2 浮点数64 几何 几何 数据类型:对象

线串(565035.0499992011 6622605.24012313、565064.889999201 6622483.90012313)

线串(565084.009999201 6622367.28012313、565101.339999201 6622257.27012313)

线串(565119.8599992 6622140.37012313、565144.4599992 6621985.04012313)

我想添加受尊重的 z 坐标,以便输出地理数据框几何形状变为:

"geometry": [
"LINESTRING Z(565035.0499992011 6622605.24012313 133.56, 565064.889999201         6622483.90012313 158.66)",
"LINESTRING Z(565084.009999201 6622367.28012313 184.84, 565101.339999201 6622257.27012313 212.68)",
"LINESTRING Z(565119.8599992 6622140.37012313 230.53, 565144.4599992 6621985.04012313 241.20)"]    

我感谢任何帮助

问候拉尔斯

我尝试过严格的 shapely.ops.transform 代码,但没有一个能解决这个问题

python gis geopandas shapely
1个回答
0
投票

按照你的

transform
想法,你可以这样做:

import pandas as pd
from shapely import LineString
from shapely.ops import transform

l3d = [
    LineString(
        (
            transform(lambda x, y, z=z1: (x, y, z), p1),
            transform(lambda x, y, z=z2: (x, y, z), p2),
        )
    )
    for p1, p2, z1, z2 in pd.concat(
        [
            gdf.boundary.explode(index_parts=True).unstack(),
            gdf[["z1", "z2"]]
        ],
        axis=1,
    ).to_numpy()
]

gdf.geometry = l3d # is a list of LineString Z objects

输出:

>>> l3d

[
    <LINESTRING Z (565035.05 6622605.24 133.56, 565064.89 6622483.9 158.66)>,
    <LINESTRING Z (565084.01 6622367.28 184.84, 565101.34 6622257.27 212.68)>,
    <LINESTRING Z (565119.86 6622140.37 230.53, 565144.46 6621985.04 241.2)>
]

>>> gdf

   ID      z1      z2                                           geometry
0   1  133.56  158.66  LINESTRING Z (565035.050 6622605.240 133.560, ...
1   2  184.84  212.68  LINESTRING Z (565084.010 6622367.280 184.840, ...
2   3  230.53  241.20  LINESTRING Z (565119.860 6622140.370 230.530, ...
© www.soinside.com 2019 - 2024. All rights reserved.