Vertdure commited on
Commit
77d5d8c
1 Parent(s): b05bcc3

Update pages/5_📍_VertXtractor.py

Browse files
Files changed (1) hide show
  1. pages/5_📍_VertXtractor.py +192 -10
pages/5_📍_VertXtractor.py CHANGED
@@ -10,16 +10,15 @@ import geopandas as gpd
10
  import tempfile
11
  import os
12
 
13
- # Importing all the functions and constants from the original code
14
- from paste import (
15
- wgs84_to_lv95, lv95_to_wgs84, detect_and_convert_bbox,
16
- get_list_from_STAC_swisstopo, suppr_doublons_bati3D_v2,
17
- suppr_doublons_bati3D_v3, suppr_doublons_list_ortho,
18
- suppr_doublons_list_mnt, get_trees_points_from_bbox,
19
- geojson_forest, CATEGORIES, MERGE_CATEGORIES
20
- )
21
-
22
- # Constants from the notebook
23
  URL_STAC_SWISSTOPO_BASE = 'https://data.geo.admin.ch/api/stac/v0.9/collections/'
24
 
25
  DIC_LAYERS = {
@@ -30,6 +29,189 @@ DIC_LAYERS = {
30
  'bati3D_v3': 'ch.swisstopo.swissbuildings3d_3_0',
31
  }
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  # Function to get URLs based on bbox and selected options
34
  def get_urls(bbox_wgs84, mnt=True, mns=True, bati3D_v2=True, bati3D_v3=True, ortho=True, mnt_resol=0.5, ortho_resol=0.1):
35
  est, sud, ouest, nord = bbox_wgs84
 
10
  import tempfile
11
  import os
12
 
13
+ # Constants
14
+ CATEGORIES = {
15
+ 'Gebueschwald': 'Forêt buissonnante',
16
+ 'Wald': 'Forêt',
17
+ 'Wald offen': 'Forêt claisemée',
18
+ 'Gehoelzflaeche': 'Zone boisée',
19
+ }
20
+ MERGE_CATEGORIES = True
21
+
 
22
  URL_STAC_SWISSTOPO_BASE = 'https://data.geo.admin.ch/api/stac/v0.9/collections/'
23
 
24
  DIC_LAYERS = {
 
29
  'bati3D_v3': 'ch.swisstopo.swissbuildings3d_3_0',
30
  }
31
 
32
+ # Functions from the original notebook
33
+ def wgs84_to_lv95(lat, lon):
34
+ url = f'http://geodesy.geo.admin.ch/reframe/wgs84tolv95?easting={lat}&northing={lon}&format=json'
35
+ site = urllib.request.urlopen(url)
36
+ data = json.load(site)
37
+ return data['easting'], data['northing']
38
+
39
+ def lv95_to_wgs84(x, y):
40
+ url = f'http://geodesy.geo.admin.ch/reframe/lv95towgs84?easting={x}&northing={y}&format=json'
41
+ f = urllib.request.urlopen(url)
42
+ txt = f.read().decode('utf-8')
43
+ json_res = json.loads(txt)
44
+ return json_res
45
+
46
+ def detect_and_convert_bbox(bbox):
47
+ xmin, ymin, xmax, ymax = bbox
48
+
49
+ wgs84_margin = 0.9
50
+ wgs84_bounds = {
51
+ 'xmin': 5.96 - wgs84_margin,
52
+ 'ymin': 45.82 - wgs84_margin,
53
+ 'xmax': 10.49 + wgs84_margin,
54
+ 'ymax': 47.81 + wgs84_margin
55
+ }
56
+
57
+ lv95_margin = 100000
58
+ lv95_bounds = {
59
+ 'xmin': 2485000 - lv95_margin,
60
+ 'ymin': 1075000 - lv95_margin,
61
+ 'xmax': 2834000 + lv95_margin,
62
+ 'ymax': 1296000 + lv95_margin
63
+ }
64
+
65
+ if (wgs84_bounds['xmin'] <= xmin <= wgs84_bounds['xmax'] and
66
+ wgs84_bounds['ymin'] <= ymin <= wgs84_bounds['ymax'] and
67
+ wgs84_bounds['xmin'] <= xmax <= wgs84_bounds['xmax'] and
68
+ wgs84_bounds['ymin'] <= ymax <= wgs84_bounds['ymax']):
69
+
70
+ lv95_min = wgs84_to_lv95(xmin, ymin)
71
+ lv95_max = wgs84_to_lv95(xmax, ymax)
72
+
73
+ bbox_lv95 = (lv95_min[0], lv95_min[1], lv95_max[0], lv95_max[1])
74
+ return (bbox, bbox_lv95)
75
+
76
+ if (lv95_bounds['xmin'] <= xmin <= lv95_bounds['xmax'] and
77
+ lv95_bounds['ymin'] <= ymin <= lv95_bounds['ymax'] and
78
+ lv95_bounds['xmin'] <= xmax <= lv95_bounds['xmax'] and
79
+ lv95_bounds['ymin'] <= ymax <= lv95_bounds['ymax']):
80
+
81
+ wgs84_min = lv95_to_wgs84(xmin, ymin)
82
+ wgs84_max = lv95_to_wgs84(xmax, ymax)
83
+
84
+ bbox_wgs84 = (wgs84_min['easting'], wgs84_min['northing'], wgs84_max['easting'], wgs84_max['northing'])
85
+ return (bbox_wgs84, bbox)
86
+
87
+ return None
88
+
89
+ def get_list_from_STAC_swisstopo(url, est, sud, ouest, nord, gdb=False):
90
+ if gdb:
91
+ lst_indesirables = []
92
+ else:
93
+ lst_indesirables = ['.xyz.zip', '.gdb.zip']
94
+
95
+ sufixe_url = f"/items?bbox={est},{sud},{ouest},{nord}"
96
+ url += sufixe_url
97
+ res = []
98
+
99
+ while url:
100
+ f = urllib.request.urlopen(url)
101
+ txt = f.read().decode('utf-8')
102
+ json_res = json.loads(txt)
103
+ url = None
104
+ links = json_res.get('links', None)
105
+ if links:
106
+ for link in links:
107
+ if link['rel'] == 'next':
108
+ url = link['href']
109
+
110
+ for item in json_res['features']:
111
+ for k, dic in item['assets'].items():
112
+ href = dic['href']
113
+ if gdb:
114
+ if href[-8:] == '.gdb.zip':
115
+ if len(dic['href'].split('/')[-1].split('_')) == 7:
116
+ res.append(dic['href'])
117
+ else:
118
+ if href[-8:] not in lst_indesirables:
119
+ res.append(dic['href'])
120
+ return res
121
+
122
+ def suppr_doublons_bati3D_v2(lst_url):
123
+ dico = {}
124
+ dxf_files = [url for url in lst_url if url[-8:] == '.dxf.zip']
125
+ for dxf in dxf_files:
126
+ *a, date, feuille = dxf.split('/')[-2].split('_')
127
+ dico.setdefault(feuille, []).append((date, dxf))
128
+ res = []
129
+ for k, liste in dico.items():
130
+ res.append(sorted(liste, reverse=True)[0][1])
131
+ return res
132
+
133
+ def suppr_doublons_bati3D_v3(lst_url):
134
+ dico = {}
135
+ gdb_files = [url for url in lst_url if url[-8:] == '.gdb.zip']
136
+ for gdb in gdb_files:
137
+ *a, date, feuille = gdb.split('/')[-2].split('_')
138
+ dico.setdefault(feuille, []).append((date, gdb))
139
+ res = []
140
+ for k, liste in dico.items():
141
+ res.append(sorted(liste, reverse=True)[0][1])
142
+ return res
143
+
144
+ def suppr_doublons_list_ortho(lst):
145
+ dic = {}
146
+ for url in lst:
147
+ nom, an, noflle, taille_px, epsg = url.split('/')[-1][:-4].split('_')
148
+ dic.setdefault((noflle, float(taille_px)), []).append((an, url))
149
+ res = []
150
+ for noflle, lst in dic.items():
151
+ an, url = sorted(lst, reverse=True)[0]
152
+ res.append(url)
153
+ return res
154
+
155
+ def suppr_doublons_list_mnt(lst):
156
+ dic = {}
157
+ for url in lst:
158
+ nom, an, noflle, taille_px, epsg, inconnu = url.split('/')[-1][:-4].split('_')
159
+ dic.setdefault((noflle, float(taille_px)), []).append((an, url))
160
+ res = []
161
+ for noflle, lst in dic.items():
162
+ an, url = sorted(lst, reverse=True)[0]
163
+ res.append(url)
164
+ return res
165
+
166
+ def get_trees_points_from_bbox(bbox, fn_geojson):
167
+ xmin, ymin, xmax, ymax = bbox
168
+ url_base = 'https://hepiadata.hesge.ch/arcgis/rest/services/suisse/TLM_C4D_couverture_sol/FeatureServer/0/query?'
169
+ params = {
170
+ "geometry": f"{xmin},{ymin},{xmax},{ymax}",
171
+ "geometryType": "esriGeometryEnvelope",
172
+ "returnGeometry": "true",
173
+ "returnZ": "true",
174
+ "spatialRel": "esriSpatialRelIntersects",
175
+ "f": "json"
176
+ }
177
+ query_string = urllib.parse.urlencode(params)
178
+ url = url_base + query_string
179
+
180
+ with urllib.request.urlopen(url) as response:
181
+ response_data = response.read()
182
+ data = json.loads(response_data)
183
+
184
+ with open(fn_geojson, 'w') as f:
185
+ json.dump(data, f)
186
+
187
+ def geojson_forest(bbox, fn_geojson):
188
+ xmin, ymin, xmax, ymax = bbox
189
+ url_base = 'https://hepiadata.hesge.ch/arcgis/rest/services/suisse/TLM_C4D_couverture_sol/FeatureServer/1/query?'
190
+
191
+ sql = ' OR '.join([f"OBJEKTART='{cat}'" for cat in CATEGORIES.keys()])
192
+
193
+ params = {
194
+ "geometry": f"{xmin},{ymin},{xmax},{ymax}",
195
+ "geometryType": "esriGeometryEnvelope",
196
+ "returnGeometry": "true",
197
+ "outFields": "OBJEKTART",
198
+ "orderByFields": "OBJEKTART",
199
+ "where": sql,
200
+ "returnZ": "true",
201
+ "outSR": '2056',
202
+ "spatialRel": "esriSpatialRelIntersects",
203
+ "f": "geojson"
204
+ }
205
+ query_string = urllib.parse.urlencode(params)
206
+ url = url_base + query_string
207
+
208
+ with urllib.request.urlopen(url) as response:
209
+ response_data = response.read()
210
+ data = json.loads(response_data)
211
+
212
+ with open(fn_geojson, 'w') as f:
213
+ json.dump(data, f)
214
+
215
  # Function to get URLs based on bbox and selected options
216
  def get_urls(bbox_wgs84, mnt=True, mns=True, bati3D_v2=True, bati3D_v3=True, ortho=True, mnt_resol=0.5, ortho_resol=0.1):
217
  est, sud, ouest, nord = bbox_wgs84