diff --git a/server/map/__pycache__/get_relation.cpython-311.pyc b/server/map/__pycache__/get_relation.cpython-311.pyc index 94d100007332813dbf0f83044e989f98f48831da..1b6c6ebc2a4069d240d6fbba5d55c7855f217958 100644 Binary files a/server/map/__pycache__/get_relation.cpython-311.pyc and b/server/map/__pycache__/get_relation.cpython-311.pyc differ diff --git a/server/map/get_relation.py b/server/map/get_relation.py index ec017cbbdb9fca60aac0267cc48a122e76a2c38c..c4270d84c28991765d1a5490c3d344dbaae0dbc5 100644 --- a/server/map/get_relation.py +++ b/server/map/get_relation.py @@ -3,6 +3,7 @@ from shapely.geometry import Polygon, LineString from shapely.ops import linemerge, unary_union, polygonize import matplotlib.pyplot as plt import random +import json import numpy as np polygon_min_x = None # The left most point of the entire polygon @@ -10,75 +11,53 @@ polygon_min_x = None # The left most point of the entire polygon # Read a json file with relation data and send to response object def get_relation(self, body_of_water: str): # NB: implement body_of_water - - # Load GeoJSON data using geopandas + # Read relation from GeoJson file and extract all polygons geo_data = gpd.read_file("server/map/mjosa.geojson") - - # Filter only polygons, exclude points and other feature types to reduce response size polygon_data = geo_data[geo_data['geometry'].geom_type == 'Polygon'] - - # Extract coordinates from polygons and create polygon objects polygons = [Polygon(polygon.exterior) for polygon in polygon_data['geometry']] - if len(polygons) <= 1: # Return if conversion to polygon fails + if len(polygons) <= 1: print("Failed to convert to polygons") return - divided_map = [] # List to store map shapes while splitting - polygon_counter = 1 - num_of_polygons = len(polygons) + divided_map = [] - print("Dividing map... This may take a few minutes") - # Divide all polygons into sections for polygon in polygons: - cell_size = 0.04 # NB smaller values require patience - # Divide the length and with of polygon into a grid of equally sized parts + cell_size = 0.04 lines = create_grid(polygon, cell_size) - lines.append(polygon.boundary) lines = unary_union(lines) lines = linemerge(lines) - lines = (list(polygonize(lines))) - - divided_map = combine_gird_with_poly(polygon, lines) - - print("Polygon nr.", polygon_counter, " finished processing. ", num_of_polygons - polygon_counter, - " polygons left to process.") - polygon_counter += 1 - - break - - tiles = gpd.GeoDataFrame(geometry=divided_map) + lines = list(polygonize(lines)) + + divided_map.extend(combine_grid_with_poly(polygon, lines)) + + tiles = [gpd.GeoDataFrame(geometry=[tile]) for tile in divided_map] + + sub_div_id = 0 + for tile in tiles: + tile['sub_div_id'] = sub_div_id + tile['sub_div_center'] = tile['geometry'].centroid.apply(lambda x: [x.x, x.y]) + sub_div_id += 1 + + tiles_json = {'type': 'FeatureCollection', 'features': []} + for tile in tiles: + feature = { + 'type': 'Feature', + 'geometry': tile.geometry.__geo_interface__, + 'properties': { + 'sub_div_id': int(tile['sub_div_id'].iloc[0]), + 'sub_div_center': tile['sub_div_center'].tolist() + } + } + tiles_json['features'].append(feature) - print("Adding ID's and center coordinates") - tiles['subdiv_id'] = range(len(tiles)) # Give each subdivision a unique ID - # Calculate the center coordinates of each tile - tiles['subdiv_center'] = tiles['geometry'].centroid.apply(lambda x: [x.x, x.y]) - - print("Plotting map...") - # NB test plot - fig, ax = plt.subplots() - ax.set_aspect(1.5) - - # Plot the divided_map - tiles.plot(ax=ax, facecolor='none', edgecolor='none') - - for i, tile in enumerate(tiles.geometry): - random_color = "#{:06x}".format(random.randint(0, 0xFFFFFF)) - gpd.GeoSeries(tile).plot(ax=ax, facecolor=random_color, edgecolor='none') - - plt.show() - - # Convert GeoDataFrame to GeoJSON - tiles_json = tiles.to_json() - - # Set headers self.send_response(200) self.send_header("Content-type", "application/json") self.end_headers() - # Write GeoJSON to response object - self.wfile.write(tiles_json.encode('utf-8')) + self.wfile.write(json.dumps(tiles_json).encode('utf-8')) + def create_grid(poly: Polygon, cell_size): @@ -105,7 +84,7 @@ def create_grid(poly: Polygon, cell_size): return grid_lines -def combine_gird_with_poly(polygon, grid): +def combine_grid_with_poly(polygon, grid): # Create an empty list to store tiles intersecting the polygon intersecting_tiles = []