pysal / momepy

Urban Morphology Measuring Toolkit
https://docs.momepy.org
BSD 3-Clause "New" or "Revised" License
465 stars 56 forks source link

Adding metrics to strokes made by COINS #591

Open csebastiao opened 1 month ago

csebastiao commented 1 month ago

Description / Summary

COINS is an algorithm building on Intersection Continuity Negotiation, and is implemented in momepy with a class. As it allows creating objects larger than single edges, it allows studying at a larger, sometimes more relevant scale a street network, and find a hierarchy of the street network through the geometry of the graph only.

While the strokes created are valuable by themselves, there is as of now no additional relevant information on them that is implemented in the class, giving only the geometry of the strokes and a mapping to the original edges. But indicators and even centralities can be computed on them, looking at the literature on dual graph and space syntax. A recent example can be found in this article. Those indicators do not require more information than the geometries of the strokes, that are already computed, which is aligned with the momepy approach focusing on the urban form.

Value / benefit

The metrics shown in the article mentioned above are already implemented in a QGIS package called Morpheo, using a revised ICN algorithm with a very similar functioning as COINS; a quick run of both algorithm on the same graph gives slightly different but close results.

While the QGIS plugin Morpheo already compute a lot of relevant metrics (on top of other abilities), adding computation on COINS' strokes in momepy would allow using this analysis in a full Python workflow, inside a well-maintained and integrated package that can easily communicate with the rest of the Python environment of networkx, geopandas, osmnx, etc.

While anyone could compute themselves the metrics from the geometries, going beyond the length of each stroke would require a lot of work and knowledge from users, impeding the ease of use of such metrics for fast analysis of urban form. One can already look at literature about the benefits and limitations of such approach (see the Space Syntax research program of Hillier, (Ratti, 2004) or (Porta et al., 2006a) and (Portal et al., 2006b)), but already having the strokes, to get access to a dual graph analysis from a set of LineStrings in Python easily would be beneficial.

Implementation details

Implementation could happen fully inside the COINS module. The only necessary information is about the geometries of the stroke which are already computed, and how they are intersecting with one another, which can be found using tools from geopandas.

The most obvious space to add such metrics is on the GeoDataFrame created by momepy.COINS.stroke_gdf(), since it contains everything we need.

Tasks to complete

In the hypothesis that this is an interesting addition to momepy, the most important function to create would be to find to which other strokes each stroke is intersecting with, something in the like of:

def get_stroke_neighbors(stroke_gdf):
    stroke_gdf = stroke_gdf.copy()
    stroke_gdf["neighbors"] = [[val for val in stroke_gdf[stroke_gdf.geometry.intersects(x)]["stroke_group"].values if val != ids] for ids, x in enumerate(stroke_gdf.geometry)]
    return stroke_gdf

Or, but I'm not as familiar with the existing functions, but since there already is a momepy.gdf_to_nx() function, there might be a way with some tweaking to get the same result from there.

From there, a large panel of indicators could be imagined, picking from the literature of street dual graph analysis.

With the list of neighbors, you can then easily recreate the dual graph by making each stroke a node and each edge a link if two strokes intersects thus are neighbors, and compute from there typical network indicators on strokes: the degree, the (unweighted) closeness centrality, the (unweighted) betweenness centrality. With the dual graph can also be computed the local and global integration.

In the article mentioned above, we can also find some metrics based on the geometrical relationship between the strokes. Having the list of neighbors already computed, then functions could run on the resulting list of geometries. In their vocabulary, computing the connectivity (the number of connection to the observed stroke, since a single neighboring stroke can have multiple connections to it) and the orthogonality (the angle of the connections to the observed stroke), gives also access to the accessibility and the spacing.

csebastiao commented 1 month ago

Pinging @anastassiavybornova if you want to add anything !

anastassiavybornova commented 1 month ago

backing up this proposal, and happy to help out with the implementation too (will be useful for a project i'm currently working on, too). so in a nutshell, the topic is here to compute metrics that are defined on network strokes rather than on network edges, and the idea would be to write a bunch of functions, one for each metric, that

curious to get your thoughts on this @martinfleis @jGaboardi since we're using these COINS quite a bit now, as well

ah and i think i would try to avoid implement anything that relies on networkx functions, to keep it simpler (in terms of really just using the geometries which is the only information we need for the proposal above right?)

martinfleis commented 1 month ago

Hey both,

I am generally in favour of this but you'll need to develop it yourself :). Happy to provide guidance.

It would be good to be as specific as you can here. Which metrics? How are they defined? Is there a reference implementation? Paper with the definition/formula?

@anastassiavybornova can we quickly pick it up after the next simplification call?

anastassiavybornova commented 1 month ago

nice! sounds great yes! and agree, this will imply some additional literature research (though I suspect Clément has already quite a long list of references which is great)

anastassiavybornova commented 1 month ago

@csebastiao then would be nice to have a call about this next week, to prepare some more specifics? i'll text you on slack with suggestions