Zonal - A Workspace for Analysis Tools and Workflows.
Zonal
- class madina.zonal.zonal.Zonal
Bases:
objectA class to manage and organize urban data into layers and networks, acting as a workspace that manages data and facilitate interoperability across tools. A Zonal object populated with a veriety of data layeers and network could be used as input toi many urban analysis tools. Please look at the examples to see a gallery of use cases.
- Example:
>>> shaqra = Zonal() >>> shaqra.add_layer(name='streets', source='streets.geojson') >>> shaqra.create_map(save_as='street_map.html', basemap=False)
- clear_nodes() None
Erase the existing origins and destinations from the current network, but retains the network nodes and edges
- create_graph(light_graph: bool = True, d_graph: bool = True, od_graph: bool = False) None
After creating a street network, adding origin nodes, and destination nodes, this function must be called to construct a NetworkX object internally. This is needed to run UNA tools.
- Parameters:
light_graph (bool, optional) – contains only network nodes and edges, defaults to True
d_graph (bool, optional) – contains all destination nodes and network intersectionsa. This is needed to run UNA tools, defaults to True
od_graph (bool, optional) – contains all origin, destination, network, etc. nodes, defaults to False
- Example:
>>> shaqra = Zonal() # Create a Zonal object. >>> shaqra.load_layer('streets', 'streets.geojson') # load streets layer >>> shaqra.create_street_network("streets") # Create a street network >>> shaqra.load_layer('homes', 'homes.geojson') >>> shaqra.insert_node('homes', label="origin", weight_attribute="residents") >>> shaqra.load_layer('schools', 'schools.geojson') >>> shaqra.insert_node('schools', label="destination", weight_attribute="school_enrollment") >>> shaqra.create_graph() # The zonal object now have everything it needs to be used as input in a UNA tool.
- create_map(layer_list: list = None, save_as: str = None, basemap: bool = False) Deck
Create a map visualization using the specified layers within the Zonal object.
- Parameters:
layer_list (list, optional) – A list of dictionaries, each containing a ‘gdf’ key with a GeoDataFrame, defaults to None. If None, the method includes all visible layers from the Zonal object.
save_as (str, optional) – The filename to save the map visualization. Default is None (not saved)., defaults to None
basemap (bool, optional) – Include a basemap in the map if True. Default is False.
- Returns:
returns a PyDeck’s Deck object that can be visualized in Jupyter notebooks.
- Return type:
pdk.Deck
- Example:
>>> zonal = Zonal() # Create a Zonal object. >>> zonal.load_layer("streets", "streets.geojson") # load streets layer. >>> zonal.load_layer("homes", "homes.geojson") # load homes layer. >>> zonal.create_map(layer_list=[{"gdf": zonal.layers["streets"].gdf}], save_as="map.html", basemap=True) # Create a map visualization with a custom layer and a basemap, and save it as an HTML file.
- create_street_network(source_layer: str, weight_attribute: str = None, node_snapping_tolerance: int | float = 0, redundant_edge_treatment: str = 'discard', turn_threshold_degree: int | float = 45, turn_penalty_amount: int | float = 30) None
Create a topologically connected street network from a specified layer in the Zonal object.
- Parameters:
source_layer (str) – The name of the source layer to create the network from. Layer must be loaded using ‘load_layer()’ first.
weight_attribute (str, optional) – Name of the attribute to use as percieved diatance. Given name must exist in layer attributes. Default is None, and the network cost would be calculated using geometric distance.
node_snapping_tolerance (int | float, optional) – Tolerance for snapping nodes. Default is 0.0 assuming that line geometries that are connected share identical common start/end points, defaults to 0.0
redundant_edge_treatment (str, optional) – Due to current limitations, only one edge can exist between a pair of nodes. Three options: “keep”: redundant edges will be kept, posing a risk for error in network construction/calculations. “discard”: The shortest edge of redundant edges will be kept. others are discarded. is kept if set to True. “split”: Split redundant edges by thier centroids into non-redundant segments. Default “split”.
turn_threshold_degree (int | float, optional) – Degree threshold for considering a turn. Default is 45. This threshold would only be used whem enabling turn penalty in UNA operations. The angle is measured as the deviation from a straight line. Can only be between 0-180. 90 degrees means a right or left turn, a 180 degree means a full U-turn
turn_penalty_amount (int | float, optional) – Penalty amount for turns. Default is 30. This penalty (in the units of the layers’ CRS) would be used as turn cost when enabling turn penalty in UNA operations. Cannot b e negative. defaults to 30
- Raises:
ValueError – if the source layer did not exist in the object.
- Example:
>>> zonal = Zonal() # Create a Zonal object. >>> zonal.create_street_network( ... source_layer="streets", ... weight_attribute="length", ... node_snapping_tolerance=0.001, ... ) # Create a street network using 'streets' layer and allowing geometries to be atr most 0.001 CRS units apart to form a node.
- describe() None
prints a textual representation of the zonal objecgt, listing and describing layers
- Example:
>>> zshaqra = Zonal() >>> shaqra.describe() >>> shaqra.load_layer('homes', 'homes.geojson') >>> shaqra.describe() a string representation of the `Zonal` object, a list of layers if any exists.
- insert_node(layer_name: str, label: str, weight_attribute: str = None) None
Insert “origin” and “destination” nodes into the network. This function must be called aftet the ‘create_street_network’ function is called, and the corresponding layer have already been loaded by calling ‘load_layer’
- Parameters:
layer_name (str) – The name of the layer to insert the nodes from.
label (str) – The label for the new node. Could either be “origin” or “destination”.
weight_attribute (str, optional) – Name of the attribute to use as the node’s weight. Default is None. If no weight is given, all nodes are weighted equally (Assigned a weight of 1). The attribute name must exist in the layer.
- Example:
>>> shaqra = Zonal() # Create a Zonal object. >>> shaqra.load_layer('streets', 'streets.geojson') # load streets layer >>> shaqra.create_street_network("streets") # Create a street network >>> shaqra.load_layer('homes', 'homes.geojson') >>> shaqra.insert_node('homes', label="origin", weight_attribute="residents") >>> shaqra.load_layer('schools', 'schools.geojson') >>> shaqra.insert_node('schools', label="destination", weight_attribute="school_enrollment") # Insert a homes as origins, schools as destinations into the 'shgaqra' Zonal object
- load_layer(name: str, source: str | Path | GeoDataFrame, pos: int = None, first: bool = False, before: str = None, after: str = None) None
Loads a new layer from the given source with the specified layer name.
- Parameters:
name (str) – A name for the layer the new layer.
source (str | Path | gpd.GeoDataFrame) – The data source of this layer. Could either be an existing GeoDataFrame, or a path to an acceptable file. Supported types are ‘.geojson’, ‘.shp’, or any file accepted by geopanda’s read_file()
pos (int, optional) – position of this layer in the list of layers, defaults adding a layer at the end of the list.
first (bool, optional) – if True, inserts this layer at the top of the list, defaults to False
before (str, optional) – insert before the specified layer name if specified
after (str, optional) – insert after the specified layer name if specified
- Raises:
TypeError – _description_
TypeError – _description_
- Example:
>>> shaqra = Zonal() # Create a Zonal object. >>> zonal.load_layer("streets", "path/to/streets.geojson", first=True) # Load a new layer at the beginning of the layers list.
- set_turn_parameters(turn_threshold_degree: int | float, turn_penalty_amount: int | float) None
Set the turn penalty threshold and turn penalty amount for use when turn penalty is enabled in analysis tools. :param turn_threshold_degree: Degree threshold for considering a turn. Default is 45. This threshold would only be used whem enabling turn penalty in UNA operations. The angle is measured as the deviation from a straight line. Can only be between 0-180. 90 degrees means a right or left turn, a 180 degree means a full U-turn :type turn_threshold_degree: int | float :param turn_penalty_amount: Penalty amount for turns. Default is 30. This penalty (in the units of the layers’ CRS) would be used as turn cost when enabling turn penalty in UNA operations. Cannot b e negative. defaults to 30 :type turn_penalty_amount: int | float :raises TypeError: if parameter turn_threshold_degree is not int or float :raises ValueError: if parameter turn_threshold_degree is not between 0 and 180 degrees. :raises TypeError: if parameter turn_penalty_amount is not int or float :raises ValueError: if parameter turn_penalty_amount is negative