dilithjay commited on
Commit
aea4fce
·
1 Parent(s): efcf489

Support downloading grid and its info

Browse files
Files changed (2) hide show
  1. app.py +35 -23
  2. geo_tools.py +15 -6
app.py CHANGED
@@ -1,10 +1,11 @@
1
  import os
 
2
  import gradio as gr
3
  import plotly.graph_objects as go
4
 
5
  from geo_tools import (
6
  shapefile_to_latlong,
7
- shapefile_to_grid_indices,
8
  points_to_shapefile,
9
  get_cached_grid_indices,
10
  )
@@ -19,7 +20,6 @@ OUT_DIR = "out/"
19
  def gr_generate_map(
20
  token: str,
21
  side_len: str,
22
- show_grid: bool,
23
  show_mask: bool,
24
  show_hospitals: bool = True,
25
  show_police: bool = True,
@@ -28,21 +28,33 @@ def gr_generate_map(
28
  side_len = float(side_len)
29
 
30
  scattermaps = []
31
- if show_grid:
32
- grid_path = MASK_PATH[: -len(".shp")] + f"-len={side_len}.shp"
33
- if not os.path.exists(grid_path):
34
- indices = shapefile_to_grid_indices(MASK_PATH, side_len)
35
- points_to_shapefile(indices, grid_path)
36
- else:
37
- indices, _ = get_cached_grid_indices(grid_path)
38
- box = go.Scattermapbox(
39
- lat=indices[:, 1],
40
- lon=indices[:, 0],
41
- mode="markers",
42
- marker=go.scattermapbox.Marker(size=6),
43
- )
44
- box.name = "Grids"
45
- scattermaps.append(box)
 
 
 
 
 
 
 
 
 
 
 
 
46
  if show_mask:
47
  contours = shapefile_to_latlong(MASK_PATH)
48
  for contour in contours:
@@ -129,7 +141,7 @@ def gr_generate_map(
129
  ),
130
  )
131
 
132
- return fig
133
 
134
 
135
  with gr.Blocks() as demo:
@@ -141,7 +153,6 @@ with gr.Blocks() as demo:
141
  )
142
  grid_side_len = gr.Textbox(value="100", label="Sampling Gap (m)")
143
 
144
- grid_show_grid = gr.Checkbox(True, label="Show Grid")
145
  grid_show_mask = gr.Checkbox(False, label="Show Mask")
146
  grid_show_hosp = gr.Checkbox(True, label="Show Hospitals")
147
  grid_show_police = gr.Checkbox(True, label="Show Police Stations")
@@ -161,11 +172,13 @@ with gr.Blocks() as demo:
161
  "Seruwila",
162
  ],
163
  )
 
 
164
 
165
  grid_button.click(
166
  gr_generate_map,
167
- inputs=[grid_token, grid_side_len, grid_show_grid, grid_show_mask],
168
- outputs=grid_map,
169
  )
170
 
171
  grid_region.change(
@@ -173,13 +186,12 @@ with gr.Blocks() as demo:
173
  inputs=[
174
  grid_token,
175
  grid_side_len,
176
- grid_show_grid,
177
  grid_show_mask,
178
  grid_show_hosp,
179
  grid_show_police,
180
  grid_region,
181
  ],
182
- outputs=grid_map,
183
  )
184
 
185
  demo.queue(concurrency_count=10).launch(debug=True)
 
1
  import os
2
+ import zipfile
3
  import gradio as gr
4
  import plotly.graph_objects as go
5
 
6
  from geo_tools import (
7
  shapefile_to_latlong,
8
+ mask_shapefile_to_grid_indices,
9
  points_to_shapefile,
10
  get_cached_grid_indices,
11
  )
 
20
  def gr_generate_map(
21
  token: str,
22
  side_len: str,
 
23
  show_mask: bool,
24
  show_hospitals: bool = True,
25
  show_police: bool = True,
 
28
  side_len = float(side_len)
29
 
30
  scattermaps = []
31
+ grid_path = MASK_PATH[: -len(".shp")] + f"-gap={side_len}.shp"
32
+ prefix = ".".join(grid_path.split(".")[:-1])
33
+ if not os.path.exists(grid_path):
34
+ indices, labels = mask_shapefile_to_grid_indices(MASK_PATH, side_len)
35
+ points_to_shapefile(indices, labels, grid_path)
36
+
37
+ file_list = [prefix + ext for ext in (".shp", ".shx", ".prj", ".dbf", ".cpg")]
38
+ with zipfile.ZipFile(prefix + ".zip", "w") as fp:
39
+ for file in file_list:
40
+ fp.write(file, compress_type=zipfile.ZIP_DEFLATED)
41
+
42
+ with open(prefix + ".csv", "w") as fp:
43
+ fp.write("Label, Latitude, Longitude\n")
44
+ for lbl, idx in zip(labels, indices):
45
+ fp.write(f"{lbl}, {idx[1]}, {idx[0]}\n")
46
+ else:
47
+ indices, labels = get_cached_grid_indices(grid_path)
48
+ box = go.Scattermapbox(
49
+ lat=indices[:, 1],
50
+ lon=indices[:, 0],
51
+ mode="markers+text",
52
+ text=labels,
53
+ marker=go.scattermapbox.Marker(size=6),
54
+ )
55
+ box.name = "Grids"
56
+ scattermaps.append(box)
57
+
58
  if show_mask:
59
  contours = shapefile_to_latlong(MASK_PATH)
60
  for contour in contours:
 
141
  ),
142
  )
143
 
144
+ return fig, prefix + ".zip", prefix + ".csv"
145
 
146
 
147
  with gr.Blocks() as demo:
 
153
  )
154
  grid_side_len = gr.Textbox(value="100", label="Sampling Gap (m)")
155
 
 
156
  grid_show_mask = gr.Checkbox(False, label="Show Mask")
157
  grid_show_hosp = gr.Checkbox(True, label="Show Hospitals")
158
  grid_show_police = gr.Checkbox(True, label="Show Police Stations")
 
172
  "Seruwila",
173
  ],
174
  )
175
+ grid_shapefile = gr.File(label="Grid Shapefile")
176
+ grid_point_info = gr.File(label="Sample Point Info")
177
 
178
  grid_button.click(
179
  gr_generate_map,
180
+ inputs=[grid_token, grid_side_len, grid_show_mask],
181
+ outputs=[grid_map, grid_shapefile, grid_point_info],
182
  )
183
 
184
  grid_region.change(
 
186
  inputs=[
187
  grid_token,
188
  grid_side_len,
 
189
  grid_show_mask,
190
  grid_show_hosp,
191
  grid_show_police,
192
  grid_region,
193
  ],
194
+ outputs=[grid_map, grid_shapefile, grid_point_info],
195
  )
196
 
197
  demo.queue(concurrency_count=10).launch(debug=True)
geo_tools.py CHANGED
@@ -30,15 +30,20 @@ def shapefile_to_latlong(file_path: str):
30
  return contours
31
 
32
 
33
- def shapefile_to_grid_indices(
34
  file_path: str, side_len_m: float = 100, meters_per_px: float = 10
35
  ):
36
  c = fiona.open(file_path, "r")
37
  all_indices = []
 
 
38
  side_len = side_len_m / meters_per_px
39
 
40
  for poly in c:
41
  coords = poly["geometry"].coordinates
 
 
 
42
  for coord_set in tqdm(coords):
43
  contour = np.array(coord_set[0] if len(coord_set) == 1 else coord_set)
44
 
@@ -62,16 +67,20 @@ def shapefile_to_grid_indices(
62
  indices = np.array(get_optimal_grid(mask, side_len=side_len)[0])
63
  indices = indices * meters_per_px + cmin
64
 
65
- all_indices += indices.tolist()
 
 
 
 
66
 
67
  transformer = Transformer.from_crs(c.crs, 4326, always_xy=True)
68
  all_indices = list(transformer.itransform(all_indices))
69
 
70
- return np.array(all_indices)
71
 
72
 
73
- def points_to_shapefile(points: np.ndarray, file_path: str):
74
- schema = {"geometry": "Point", "properties": [("ID", "int")]}
75
 
76
  # open a fiona object
77
  pointShp = fiona.open(
@@ -85,7 +94,7 @@ def points_to_shapefile(points: np.ndarray, file_path: str):
85
  for i, (x, y) in enumerate(points):
86
  rowDict = {
87
  "geometry": {"type": "Point", "coordinates": (x, y)},
88
- "properties": {"ID": i},
89
  }
90
  pointShp.write(rowDict)
91
  # close fiona object
 
30
  return contours
31
 
32
 
33
+ def mask_shapefile_to_grid_indices(
34
  file_path: str, side_len_m: float = 100, meters_per_px: float = 10
35
  ):
36
  c = fiona.open(file_path, "r")
37
  all_indices = []
38
+ all_labels = []
39
+ city_counts = {}
40
  side_len = side_len_m / meters_per_px
41
 
42
  for poly in c:
43
  coords = poly["geometry"].coordinates
44
+ city = poly["properties"]["City"]
45
+ if city not in city_counts:
46
+ city_counts[city] = 0
47
  for coord_set in tqdm(coords):
48
  contour = np.array(coord_set[0] if len(coord_set) == 1 else coord_set)
49
 
 
67
  indices = np.array(get_optimal_grid(mask, side_len=side_len)[0])
68
  indices = indices * meters_per_px + cmin
69
 
70
+ all_indices += sorted(indices.tolist(), key=lambda x: x[1])
71
+ all_labels += [
72
+ f"{city}-{city_counts[city] + i}" for i in range(len(indices))
73
+ ]
74
+ city_counts[city] += len(indices)
75
 
76
  transformer = Transformer.from_crs(c.crs, 4326, always_xy=True)
77
  all_indices = list(transformer.itransform(all_indices))
78
 
79
+ return np.array(all_indices), all_labels
80
 
81
 
82
+ def points_to_shapefile(points: np.ndarray, labels: list, file_path: str):
83
+ schema = {"geometry": "Point", "properties": [("ID", "int"), ("Name", "str")]}
84
 
85
  # open a fiona object
86
  pointShp = fiona.open(
 
94
  for i, (x, y) in enumerate(points):
95
  rowDict = {
96
  "geometry": {"type": "Point", "coordinates": (x, y)},
97
+ "properties": {"ID": i, "Name": labels[i]},
98
  }
99
  pointShp.write(rowDict)
100
  # close fiona object