From 68c84e1c4fdf7cfa839431476421d57d4f1308bd Mon Sep 17 00:00:00 2001 From: Sara <sarasdj@stud.ntnu.no> Date: Thu, 14 Mar 2024 12:13:14 +0100 Subject: [PATCH] fix: separate tiles to json --- .../__pycache__/get_relation.cpython-311.pyc | Bin 5237 -> 4763 bytes server/map/get_relation.py | 83 +++++++----------- 2 files changed, 31 insertions(+), 52 deletions(-) diff --git a/server/map/__pycache__/get_relation.cpython-311.pyc b/server/map/__pycache__/get_relation.cpython-311.pyc index 94d100007332813dbf0f83044e989f98f48831da..1b6c6ebc2a4069d240d6fbba5d55c7855f217958 100644 GIT binary patch delta 1995 zcmZV;TWs4@^g8h?&dYhVY139swm!14belR_vaVaZv6QJodr?GTiqc#+BubOWamO|s z8c;uiC}@=#Ork>hfPu6LP3))e!|#M95m%lX8BGcj{P7Vn@z1@^60PI<-s9tY-Y@?< z`qhx*JG-3&Xr+GtM{wIV9e(24=E(d(I|Pu(Iu@OfSmYroxRy<jS|=CXkQU4cXAtgz z>^fNVZhj$H8Kl9C&eK^^p^0A)%j6kw<&zQ(nGz#evHsSQX_>iW0^lw>tyN-Wwn{6T zE}xmsFbdCfDLIpKjJ-o3E_B*llBbOWApei5+%xqMtn#(Fk46fqstqahc1eNfWN0L1 zSjINy39zw&-Iu8|;11%t+u<x(prypg78JnYl2ztpE99mS6}?S89j=U{jaHr5)*7^~ zgS|c@0h=MnLF$GbfD*TH1lm&oI<`zDn_*zNWQ9)In&I2ZGOjiz4Ye`DH20k8P9~tG zbE|YSP8wV60m|#t!06tXAirgTt}S!PF595HBLrHB@3!xC9OWh@gR0NSA@saRM5HcE z@<T85?JXt&5V0E*m08+j^|wQ)_Talw=~(*$fJ~=0vTd)0Y9D4c!7k-9dLPmK;78g< z5WMmWb9pWGzW0aNA2+@^ne221(nz6$bMiEbz?UF}oVemI5z=!!nGP-!DdOG>mD)6I z^jrdAB20*Q7Q!aooGL)w78CMk5>n!<m{<|QCehJ{h&m~yvqBN~@8F<_3n${5-56AY z7XNGMqLj?96sAMysyK>38PsgC*1kXf=_SqH|2<i~TC+z~dqlHGIz-WpHDRqfS6p3+ zD?hXIL_lFIlWQYb7dBJ|4`&{ou3fmOUAX)(S_X!U?!fFYeKnpGa*`nGuCqcyS`~%U z`D|85O6hzK#Y0Nh3xdurw@5{udB%jI!bK7X5D1&aL5$-R=v+a}7X(pC3sg}I0-$VL zB6Pp#Lp0@Y%bRc0!Zk_ALA?uwyOhoe@syZ`@%PfwyYWIkdtGO-H)1{wbt+LPWUsfh zy5jMakdLRaqsxh;5RdC-^r4gKY(A;eQa+0ksQk%Ic9EH4KBrS~b)`_$X(5-)Lm})? zhOANLL+il)me<{er$#;E20zmd5KpJ_*cy5zh7dG+pm-kTwhW#)-5aG^|AgwC)SQ#$ zxw<ECd#<{u^&QswqTA`6zL@5jE6>-R7nKRy$>D}4&;%@XnrOiaQ}_BSmM47RcC7lA z%8zOMScR%9KiS6Cc<-&nDy8~{HQ%txk7)czg=(;#UAA|J?R^|La(`s|m>QVT0y8Q* ztFf~+V>gWE*glT>K()m*Tde$Q!{siYtMk4lFjIa5RLFY&NQJDtqq4pA;7~QA1&?UK z=x*@TPViK1<_)yfwcvslT&R#Wd%wyK)LHk<#K+DGSK%7HhqjN_T+?VjQ){8dngD?c z+3@z){e4?@%|G$iK(M;MDr=!}E%eHEPzz0|11GeB6ZOz=ZDc|VP40$H?u1UNp&2bS z)1=G+2XYMohVgJsz<Bm^6{g7pi|1xkV+VHGp&fRpno`+_#ztz!Zjh{!c0|X~d;Q!l z>D?i{w=RFaSmjjTLCtq?*LQTscl7>*>N~Faj;rL9Mo!h*`@wIHQ^asDs$<x!(@Xi) z94v|?`V<e~JF7T{@mUPcDaZJiY^_PnqQ(>h$_n4Zg)t3-=?6FYkBHDSU7XR1MKmWx z-PXa;%!mh+are-^^H}T>0!93j8N{nK^ASwIU_p`HX@^g@pvEpFaxhU8each!f>Spa zvXV}V=q|q^MwRoPeOBC!h8JQ)`M}f9CD1qiGZh~x-+EFnTg%2%2ku&XH+XN^-eeCE SC#uONK(80U5}{0cC;kIl-uYMn delta 2433 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 Y{JZQql00VQcM1Ib0es1!qrMaW2j@I&!~g&Q diff --git a/server/map/get_relation.py b/server/map/get_relation.py index ec017cbb..c4270d84 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 = [] -- GitLab