From 35b4d8a0cd472d5a89c057beefb55584635180a3 Mon Sep 17 00:00:00 2001 From: Robert John Date: Wed, 16 Aug 2023 22:17:14 +0200 Subject: [PATCH] make usage of landuse. FIRST: you need to fetch osm data whrer landuse is not null! --- ding0/config/landuse_table_and_sql_request.py | 26 +++++++++++++ ding0/core/__init__.py | 9 ++++- ding0/grid/lv_grid/clustering.py | 4 +- ding0/grid/lv_grid/routing.py | 38 ++++++++++++++++++- 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 ding0/config/landuse_table_and_sql_request.py diff --git a/ding0/config/landuse_table_and_sql_request.py b/ding0/config/landuse_table_and_sql_request.py new file mode 100644 index 00000000..bed169e7 --- /dev/null +++ b/ding0/config/landuse_table_and_sql_request.py @@ -0,0 +1,26 @@ +# landuse has to be fetched and stored in DB as selct * from osm data where osmdata.landuse is not null; + +class Landuse(Base): + """Landuse Model""" + + __tablename__ = "landuse" + + osm_id = Column(Integer, primary_key=True) + landuse = Column(String(50)) + natural = Column(String(50)) + geometry = Column(Geometry('POLYGON')) + area = Column(Float) + + + +def get_osm_landuse(geo_area, session_osm): + """ load ways from db for given polygon as geo_area_wkt """ + + landuse = session_osm.query(Landuse).filter( + func.st_intersects(func.ST_GeomFromText(geo_area, srid), Landuse.geometry)) + + landuse_sql_df = pd.read_sql( + landuse.statement, + con=session_osm.bind) +# con=engine_osm both ways are working. select the easier/ more appropriate one + return landuse_sql_df diff --git a/ding0/core/__init__.py b/ding0/core/__init__.py index 9daa1529..ae9568d7 100644 --- a/ding0/core/__init__.py +++ b/ding0/core/__init__.py @@ -839,11 +839,17 @@ def import_lv_load_areas_and_build_new_lv_districts( # Get n_clusters based on capacity of the load area. n_cluster = get_cluster_numbers(buildings_w_loads_df, simp_graph) + + # fetch landuse like oam ways + # todo: check if wokring. landuse has to be stored in DB before ! + landuse_sql_df = db_io.get_osm_landuse(self.orm, session, buffer_poly_list[-1].wkt) + landuse_gdf['geometry'] = landuse_gdf.geometry.apply(to_shape) + landuse_gdf = gpd.GeoDataFrame(landuse_gdf, geometry="geometry", crs=3035) # Cluster graph and locate lv stations based on load center per cluster. clustering_successfully, cluster_graph, mvlv_subst_list, nodes_w_labels = \ distance_restricted_clustering( - simp_graph, n_cluster, street_loads_df, mv_grid_district, id_db + simp_graph, n_cluster, street_loads_df, mv_grid_district, id_db, landuse_sql_df ) if not clustering_successfully: return f"Clustering not successful for " \ @@ -920,6 +926,7 @@ def import_lv_load_areas_and_build_new_lv_districts( # Get convex hull for ding0 objects. points = get_points_in_load_area(cluster_geo_list) + if create_lvgd_geo_method == 'convex_hull': polygon = get_convex_hull_from_points(points) elif create_lvgd_geo_method == 'bounding_box': diff --git a/ding0/grid/lv_grid/clustering.py b/ding0/grid/lv_grid/clustering.py index 41940b49..61cca45e 100644 --- a/ding0/grid/lv_grid/clustering.py +++ b/ding0/grid/lv_grid/clustering.py @@ -65,7 +65,7 @@ def apply_AgglomerativeClustering(G, k, round_decimals=True): else: return np.array([0]) -def distance_restricted_clustering(simp_graph, n_cluster, street_loads_df, mv_grid_district, id_db): +def distance_restricted_clustering(simp_graph, n_cluster, street_loads_df, mv_grid_district, id_db, landuse): """ Apply ward hierarchical AgglomerativeClustering with connectivity constraints for underlying graph https://scikit-learn.org/stable/modules/clustering.html#hierarchical-clustering @@ -101,7 +101,7 @@ def distance_restricted_clustering(simp_graph, n_cluster, street_loads_df, mv_gr # locate stations for districts mvlv_subst_list, valid_cluster_distance = get_mvlv_subst_loc_list(cluster_graph, nodes_w_labels, \ street_loads_df, labels, n_cluster, \ - check_distance_criterion) + check_distance_criterion, landuse) if valid_cluster_distance: diff --git a/ding0/grid/lv_grid/routing.py b/ding0/grid/lv_grid/routing.py index 41619b65..97d33e3b 100644 --- a/ding0/grid/lv_grid/routing.py +++ b/ding0/grid/lv_grid/routing.py @@ -120,7 +120,25 @@ def loads_in_ons_dist_threshold(dm_cluster, cluster_nodes, osmid): return True -def get_mvlv_subst_loc_list(cluster_graph, nodes, street_loads_df, labels, n_cluster, check_distance_criterion=True): +def _get_landuse_in_area(landuse_gdf, area_geo): + landuse_gdf.loc[:, "intersecting_cluster"] = landuse_gdf.intersects(area_geo) + landuse_gdf = landuse_gdf.loc[landuse_gdf.intersecting_cluster] + landuse_intersecting_dict = {} + for landuse, grp in landuse_gdf.groupby("landuse"): + areasin = grp.intersection(area_geo.buffer(0)) + areasqm = 0 + if len(areasin) > 1: + for ain in areasin: + areasqm += ain.area + else: + areasqm = areasin.area.item() + landuse_intersecting_dict[landuse] = areasqm + + return landuse_intersecting_dict + + + +def get_mvlv_subst_loc_list(cluster_graph, nodes, street_loads_df, labels, n_cluster, check_distance_criterion=True, landuse_gdf=None): """ identify position of station at street load center get list of location of mvlv substations for load areal @@ -154,9 +172,27 @@ def get_mvlv_subst_loc_list(cluster_graph, nodes, street_loads_df, labels, n_clu # due to distance threshold to ons is trespassed valid_cluster_distance = False return mvlv_subst_list, valid_cluster_distance + + area_geo = df_cluster.geometry.to_list() # looks like duple somewhere in further coding, maybe just keep from here instead same processing later + if len(area_geo) == 1: + area_geo = area_geo[0] + area_geo_area = 100 + elif len(area_geo) == 2: + area_geo = LineString(area_geo) + area_geo_area = area_geo.length + else: + area_geo = Polygon(area_geo) + area_geo_area = area_geo.area + + if landuse_gdf is not None: + landuse_gdf.loc[:, "intersecting_cluster"] = False # init False and set True where intersecting + landuse_dict = _get_landuse_in_area(landuse_gdf, area_geo) + else: + landuse_dict = {} mvlv_subst_loc = cluster_graph.nodes[osmid] mvlv_subst_loc['osmid'] = osmid + mvlv_subst_loc['landuse'] = landuse_dict # todo: reagarding this dict: how to choose if village, rural, city or whatever ? mvlv_subst_loc['graph_district'] = cluster_subgraph mvlv_subst_list.append(mvlv_subst_loc)