0

“Momepy 是一个用于城市形态定量分析的库 - 城市形态计量学。它是 PySAL(Python 空间分析库)的一部分,构建在 GeoPandas、其他 PySAL 模块和 networkX 之上。” momepy 文档

使用 Fleischmann、Martin、Alessandra Feliciotti 和 William Kerr 的代码(下面的相关部分)。“城市模式的演变:城市形态学作为一种开放的可重复数据科学。” 地理分析,2021 年 7 月 15 日,gean.12302。https://doi.org/10.1111/gean.12302

我正在使用 OSM 数据来检查美国伊利诺伊州中部四个小城市的形态特征。由于某种我无法理解的原因,我只在一个城市中遇到了计算形态镶嵌单元的问题。我已经包含了一个指向下面镶嵌单元图像的链接(我不允许嵌入照片)。

感谢您的任何帮助!

%%capture --no-stdout

for i, coords in cases.origin.iteritems():
    s = time()
    """
    donwload and process elements of urban form
    """
    # download buildings from OSM
    point = tuple(map(float, coords[1:-1].split(', ')))[::-1]
    buildings = osmnx.geometries.geometries_from_point(point, dist=1000, tags={'building':True})
    buildings = osmnx.projection.project_gdf(buildings)
    buildings = buildings[buildings.geom_type.isin(['Polygon', 'MultiPolygon'])]
    buildings = buildings.reset_index(drop=True).explode().reset_index(drop=True)
    buildings = buildings[["geometry"]]

    # download streets from OSM
    streets_graph = osmnx.graph_from_point(point, 1250, network_type='drive')
    streets_graph = osmnx.get_undirected(streets_graph)
    streets_graph = osmnx.projection.project_graph(streets_graph)
    streets = osmnx.graph_to_gdfs(streets_graph, nodes=False, edges=True,
                                            node_geometry=False, fill_edge_geometry=True)
    streets = streets[["geometry"]]

    # check CRS
    assert buildings.crs.equals(streets.crs)

    # generate tessellation
    buildings['uID'] = range(len(buildings))
    tessellation = mm.Tessellation(buildings, "uID", limit=box(*buildings.total_bounds), verbose=False).tessellation

    """
    measure morphometric characters
    """
    # cell area
    tessellation['cell_area'] = tessellation.area

    # building area
    buildings['blg_area'] = buildings.area

    # coverage area ratio
    tessellation["car"] = mm.AreaRatio(tessellation, buildings, "cell_area", buildings.area, "uID").series

    # segment length
    streets["length"] = streets.length

    # segment linearity
    streets["linearity"] = mm.Linearity(streets, verbose=False).series

    # street profile
    profile = mm.StreetProfile(streets, buildings, distance=3)
    streets["width"] = profile.w
    streets["width_deviation"] = profile.wd
    streets["openness"] = profile.o

    # perimeter wall
    buildings["wall"] = mm.PerimeterWall(buildings, verbose=False).series

    # generate binary contiguity-based W objects of first order and inclusive order 3
    W1 = libpysal.weights.Queen.from_dataframe(tessellation, ids="uID")
    W3 = mm.sw_high(k=3, weights=W1)

    # building adjacency
    buildings["adjacency"] = mm.BuildingAdjacency(buildings, W3, "uID", verbose=False).series

    # interbuilding distance
    buildings['neighbour_distance'] = mm.NeighborDistance(buildings, W1, 'uID', verbose=False).series

    # generate networkx.MultiGraph object
    G = mm.gdf_to_nx(streets)

    # meshedness
    G = mm.meshedness(G, verbose=False)

    # convert networkx.MultiGraph to geopandas.GeoDataFrames
    nodes, edges = mm.nx_to_gdf(G)

    """
    link all characters to tessellation cells
    """
    # merge street network edges based on proximity
    edges["nID"] = range(len(edges))
    buildings["nID"] = mm.get_network_id(buildings, edges, "nID", 500, verbose=False)
    buildings = buildings.merge(edges.drop(columns="geometry"), on="nID", how="left")

    # merge nodes based on edge ID and proximity
    buildings["nodeID"] = mm.get_node_id(buildings, nodes, edges, "nodeID", "nID", verbose=False)
    buildings = buildings.merge(nodes.drop(columns="geometry"), on="nodeID", how="left")

    # merge buildings based on a shared attribute
    tessellation = tessellation.merge(buildings.drop(columns="geometry"), on="uID", how="left")

    """
    save all to GeoPackage
    """
    tessellation.to_file(f"~/work/{cases.loc[i, 'case']}.gpkg", layer="tessellation", driver="GPKG")
    buildings.to_file(f"~/work/{cases.loc[i, 'case']}.gpkg", layer="buildings", driver="GPKG")
    edges.to_file(f"~/work/{cases.loc[i, 'case']}.gpkg", layer="edges", driver="GPKG")
    nodes.to_file(f"~/work/{cases.loc[i, 'case']}.gpkg", layer="nodes", driver="GPKG")

    print(f"{cases.loc[i, 'case']} done in {time() - s} seconds.")

请注意密集的镶嵌单元束 - 它们与下面的建筑物不正确对应。

4

0 回答 0