Source code for rivus.utils.pandashp

import pandas as pd
from . import shapelytools
import warnings
from shapely.geometry import LineString
from geopandas import GeoDataFrame


[docs]def match_vertices_and_edges(vertices, edges, vertex_cols=('Vertex1', 'Vertex2')): """Add columns to edges DataFrame, with the corresponding vertex IDS per edge. Identifies, which nodes coincide with the endpoints of edges and creates matching IDs for matching points, thus creating a node-edge graph whose edges are encoded purely by node ID pairs. The optional argument vertex_cols specifies which DataFrame columns of edges are added, default is 'Vertex1' and 'Vertex2'. Args: vertices (DataFrame): pandas DataFrame with geometry column of type Point edges: pandas DataFrame with geometry column of type LineString vertex_cols (indexable): tuple of 2 strings for the IDs numbers Returns: Nothing, the matching IDs are added to the columns vertex_cols in argument edges Note: Although different column names than ``Vertex1`` and ``Vertex2`` are possible, if you want to work with ``rivus.main`` then you should use these as these are pretty much hart coded into the other functions... """ vertex_indices = [] for e, line in enumerate(edges.geometry): edge_endpoints = [] for k, vertex in enumerate(vertices.geometry): if line.touches(vertex) or line.intersects(vertex): edge_endpoints.append(vertices.index[k]) # For imperfectly drawn vector layers: if (vertex.buffer(0.001).intersects(line) or line.intersects(vertex)): edge_endpoints.append(vertices.index[k]) if len(edge_endpoints) == 0: warnings.warn("edge " + str(e) + " has no endpoints: " + str(edge_endpoints)) elif len(edge_endpoints) == 1: warnings.warn("edge " + str(e) + " has only 1 endpoint: " + str(edge_endpoints)) vertex_indices.append(edge_endpoints) edges[vertex_cols[0]] = pd.Series([min(n1n2) for n1n2 in vertex_indices], index=edges.index) edges[vertex_cols[1]] = pd.Series([max(n1n2) for n1n2 in vertex_indices], index=edges.index)
[docs]def find_closest_edge(polygons, edges, to_attr='index', column='nearest'): """Find closest edge for centroid of polygons. Args: polygons (GeoDataFrame): GeoDataFrame with Polygons edges (GeoDataFrame): GeoDataFrame with LineStrings to_attr (str): a column name in GeoDataFrame edges (default: index) column (str): a column name to be added/overwrite in ``polygons`` with the value of column ``to_attr`` from the nearest edge in edges Returns: a list of LineStrings connecting polygons' centroids with the nearest point in in edges. Side effect: polygons receives new column with the attribute value of nearest edge. Warning: if column exists, it is overwritten. """ connecting_lines = [] nearest_indices = [] centroids = [b.centroid for b in polygons['geometry']] for centroid in centroids: nearest_edge, _, nearest_index = shapelytools.closest_object( edges['geometry'], centroid) nearest_point = shapelytools.project_point_to_object( centroid, nearest_edge) connecting_lines.append( LineString(tuple(centroid.coords) + tuple(nearest_point.coords))) nearest_indices.append(edges[to_attr][nearest_index]) polygons[column] = pd.Series(nearest_indices, index=polygons.index) return GeoDataFrame(geometry=connecting_lines, crs=polygons.crs)
[docs]def total_bounds(gdf): """Return bounding box (minx, miny, maxx, maxy) of all geometries. Parameters ---------- gdf : GeoDataFrame Any GeoDataFrame, in rivus usually vertex or edge. Returns ------- Tuple global (minx, miny, maxx, maxy) """ b = gdf.bounds return (b['minx'].min(), b['miny'].min(), b['maxx'].max(), b['maxy'].max())