zhanggrace commited on
Commit
3c83daf
·
1 Parent(s): 21e03ae

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +515 -0
app.py ADDED
@@ -0,0 +1,515 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import json
3
+ import datetime
4
+ import streamlit as st
5
+ import streamlit.components.v1 as components
6
+ import re
7
+ import warnings
8
+ import traceback
9
+
10
+ warnings.filterwarnings("ignore")
11
+
12
+ # os.environ['SDK_CLIENT_HOST'] = 'https://pre-engine-aiearth.aliyun.com'
13
+ import aie
14
+
15
+
16
+ default_map_html = '''
17
+ <!DOCTYPE html>
18
+ <html lang="en">
19
+ <head>
20
+ <meta charset="UTF-8">
21
+ <title>IPyWidget export</title>
22
+ </head>
23
+ <body>
24
+
25
+
26
+ <!-- Load require.js. Delete this if your page already loads require.js -->
27
+ <script src="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/components/jquery/dist/jquery.min.js"></script>
28
+ <link rel="stylesheet" href="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/components/jquery/dist/jquery-ui.min.css">
29
+ <script src="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/components/jquery/dist/jquery-ui.min.js"></script>
30
+ <script src="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/components/requirejs/require.js"></script>
31
+ <script src="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/components/moment/min/moment.min.js"></script>
32
+ <link href="https://g.alicdn.com/aie/jp-notebook/0.1.15/static/build/theme.css" rel="stylesheet">
33
+
34
+ <style>
35
+ #map {
36
+ height: 100% !important;
37
+ }
38
+ .map-trigger {
39
+ display: none;
40
+ }
41
+ </style>
42
+
43
+ <script type="application/vnd.jupyter.widget-state+json">
44
+ {"version_major": 2, "version_minor": 0, "state": {"94ea4efec6cf44c3bfdae7ea872b2ec3": {"model_name": "LeafletMapStyleModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {}}, "397323d9da4942d79ae7a5c917d300e0": {"model_name": "LeafletMapStyleModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"cursor": "move"}}, "f481ac800c3746f78f47085d05ae63b0": {"model_name": "LeafletLayerGroupModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "layers": ["IPY_MODEL_36a8e8e546534e548e65cdda5aba81c6", "IPY_MODEL_b0dce2566b604debb38b19c9f25833cd"], "name": "\u7ebf\u753b\u5730\u56fe", "options": []}}, "36a8e8e546534e548e65cdda5aba81c6": {"model_name": "LeafletTDTLayerModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "key": "2d585d36d89ab86049e29f6f10364dc3", "options": ["attribution", "bounds", "detect_retina", "key", "max_native_zoom", "max_zoom", "min_native_zoom", "min_zoom", "no_wrap", "proj", "subdomains", "tile_size", "tms", "zoom_offset"], "proj": "c", "subdomains": ["0", "1", "2", "3", "4", "5", "6", "7"], "url": "https://t{s}.tianditu.gov.cn/vec_{proj}/wmts?layer=vec&style=default&tilematrixset={proj}&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}", "zoom_offset": 1}}, "b0dce2566b604debb38b19c9f25833cd": {"model_name": "LeafletTDTLayerModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "key": "2d585d36d89ab86049e29f6f10364dc3", "options": ["attribution", "bounds", "detect_retina", "key", "max_native_zoom", "max_zoom", "min_native_zoom", "min_zoom", "no_wrap", "proj", "subdomains", "tile_size", "tms", "zoom_offset"], "proj": "c", "subdomains": ["0", "1", "2", "3", "4", "5", "6", "7"], "url": "https://t{s}.tianditu.gov.cn/cva_{proj}/wmts?layer=cva&style=default&tilematrixset={proj}&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}", "zoom_offset": 1}}, "d12e84fcb7c84ef08e01fd06cff095b0": {"model_name": "LeafletLayerGroupModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "layers": ["IPY_MODEL_7a8015a60adb47b4b047f9013b77f21d", "IPY_MODEL_622608fb288f43d08511308cf829d853"], "name": "\u9065\u611f\u5730\u56fe", "options": []}}, "7a8015a60adb47b4b047f9013b77f21d": {"model_name": "LeafletTDTLayerModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "key": "2d585d36d89ab86049e29f6f10364dc3", "options": ["attribution", "bounds", "detect_retina", "key", "max_native_zoom", "max_zoom", "min_native_zoom", "min_zoom", "no_wrap", "proj", "subdomains", "tile_size", "tms", "zoom_offset"], "proj": "c", "subdomains": ["0", "1", "2", "3", "4", "5", "6", "7"], "url": "https://t{s}.tianditu.gov.cn/img_{proj}/wmts?layer=img&style=default&tilematrixset={proj}&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}", "zoom_offset": 1}}, "622608fb288f43d08511308cf829d853": {"model_name": "LeafletTDTLayerModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"base": true, "key": "2d585d36d89ab86049e29f6f10364dc3", "options": ["attribution", "bounds", "detect_retina", "key", "max_native_zoom", "max_zoom", "min_native_zoom", "min_zoom", "no_wrap", "proj", "subdomains", "tile_size", "tms", "zoom_offset"], "proj": "c", "subdomains": ["0", "1", "2", "3", "4", "5", "6", "7"], "url": "https://t{s}.tianditu.gov.cn/cia_{proj}/wmts?layer=cia&style=default&tilematrixset={proj}&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk={key}", "zoom_offset": 1}}, "50ebd50ae88c4b1f805d489b9b30523d": {"model_name": "LayoutModel", "model_module": "@jupyter-widgets/base", "model_module_version": "2.0.0", "state": {"height": "600px", "width": "100%"}}, "03b29492f1cb40429e461a12468e7e30": {"model_name": "LeafletMapStyleModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {}}, "350441dafd5b4772bb1a67f9fee4c49c": {"model_name": "LeafletMapModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"_dom_classes": [], "center": [39.916668, 116.383331], "controls": ["IPY_MODEL_4025e26e20e745609ea8d442f4747020", "IPY_MODEL_07a7ab3bb9f54361ab752f3e0d779487", "IPY_MODEL_562b3406280e489c955781f8361e49f5", "IPY_MODEL_a14f44ef9941473c801376919b07ab08", "IPY_MODEL_4e83034b92eb447ca7982055140df1ef"], "crs": {"name": "EPSG4326", "custom": false}, "default_style": "IPY_MODEL_94ea4efec6cf44c3bfdae7ea872b2ec3", "dragging_style": "IPY_MODEL_397323d9da4942d79ae7a5c917d300e0", "layers": ["IPY_MODEL_f481ac800c3746f78f47085d05ae63b0", "IPY_MODEL_d12e84fcb7c84ef08e01fd06cff095b0"], "layout": "IPY_MODEL_50ebd50ae88c4b1f805d489b9b30523d", "options": ["bounce_at_zoom_limits", "box_zoom", "center", "close_popup_on_click", "double_click_zoom", "dragging", "fullscreen", "inertia", "inertia_deceleration", "inertia_max_speed", "interpolation", "keyboard", "keyboard_pan_offset", "keyboard_zoom_offset", "max_zoom", "min_zoom", "prefer_canvas", "scroll_wheel_zoom", "tap", "tap_tolerance", "touch_zoom", "world_copy_jump", "zoom", "zoom_animation_threshold", "zoom_delta", "zoom_snap", "zoom_start"], "style": "IPY_MODEL_03b29492f1cb40429e461a12468e7e30", "zoom": 3.0}}, "4025e26e20e745609ea8d442f4747020": {"model_name": "LeafletZoomControlModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"options": ["position", "zoom_in_text", "zoom_in_title", "zoom_out_text", "zoom_out_title"]}}, "07a7ab3bb9f54361ab752f3e0d779487": {"model_name": "LeafletLayersControlModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"options": ["position"], "position": "topright"}}, "562b3406280e489c955781f8361e49f5": {"model_name": "LeafletScaleControlModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"options": ["imperial", "max_width", "metric", "position", "update_when_idle"], "position": "bottomleft"}}, "a14f44ef9941473c801376919b07ab08": {"model_name": "LeafletFullScreenControlModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"options": ["position"]}}, "4e83034b92eb447ca7982055140df1ef": {"model_name": "LeafletMeasureControlModel", "model_module": "jupyter-leaflet", "model_module_version": "^0.15.1", "state": {"_custom_units": {}, "active_color": "orange", "options": ["active_color", "capture_z_index", "completed_color", "popup_options", "position", "primary_area_unit", "primary_length_unit", "secondary_area_unit", "secondary_length_unit"], "popup_options": {"className": "leaflet-measure-resultpopup", "autoPanPadding": [10, 10]}, "position": "bottomleft", "primary_length_unit": "kilometers"}}}}
45
+ </script>
46
+ <script type="application/vnd.jupyter.widget-view+json">
47
+ {"version_major": 2, "version_minor": 0, "model_id": "350441dafd5b4772bb1a67f9fee4c49c"}
48
+ </script>
49
+
50
+ <script>
51
+ (function() {
52
+ function addWidgetsRenderer() {
53
+ var mimeElement = document.querySelector('script[type="application/vnd.jupyter.widget-view+json"]');
54
+ var scriptElement = document.createElement('script');
55
+ var widgetRendererSrc = "https://g.alicdn.com/aie/jp-notebook/0.1.15/@jupyter-widgets/html-manager/embed-amd.js";
56
+ var widgetState;
57
+
58
+ try {
59
+ widgetState = mimeElement && JSON.parse(mimeElement.innerHTML);
60
+
61
+ if (widgetState && (widgetState.version_major < 2 || !widgetState.version_major)) {
62
+ widgetRendererSrc = 'https://g.alicdn.com/aie/jp-notebook/0.1.15/jupyter-js-widgets@*/dist/embed.js';
63
+ }
64
+ } catch(e) {}
65
+
66
+ scriptElement.src = widgetRendererSrc;
67
+ document.body.appendChild(scriptElement);
68
+ }
69
+
70
+ document.addEventListener('DOMContentLoaded', addWidgetsRenderer);
71
+ }());
72
+ window.API_SERVER_CONSOLE="https://engine-aiearth.aliyun.com";
73
+ </script>
74
+
75
+ <div id="map"></div>
76
+
77
+ </body>
78
+ </html>
79
+ '''
80
+
81
+ label_text_tmpl='''
82
+ <style>
83
+ .filter-label {{
84
+ font-size: 14px;
85
+ #font-family: "sans serif";
86
+ vertical-align: middle;
87
+ color: #e8eaed;
88
+ padding-top: 2px;
89
+ }}
90
+ </style>
91
+ <div class="filter-label">
92
+ {LABEL_TEXT}
93
+ </div>
94
+ '''
95
+
96
+ secondary_label_text_tmpl='''
97
+ <style>
98
+ .filter-label {{
99
+ font-size: 12px;
100
+ #font-family: "sans serif";
101
+ vertical-align: middle;
102
+ color: rgb(232, 234, 237, 0.699999988079071);
103
+ padding-top: 2px;
104
+ white-space:nowrap;
105
+ }}
106
+ </style>
107
+ <div class="filter-label">
108
+ {LABEL_TEXT}
109
+ </div>
110
+ '''
111
+
112
+ page_title_text_tmpl='''
113
+ <style>
114
+ .page_title {{
115
+ font-size: 18px;
116
+ // font-family: "sans serif";
117
+ // vertical-align: middle;
118
+ color: rgb(232, 234, 237, 0.699999988079071);
119
+ font-weight: 600;
120
+ }}
121
+
122
+ .page_desc {{
123
+ font-size: 14px;
124
+ //font-family: "sans serif";
125
+ //vertical-align: middle;
126
+ color: rgb(232, 234, 237, 0.699999988079071);
127
+ //font-weight: 600;
128
+ margin-top: 12px;
129
+ }}
130
+ </style>
131
+ <div class="page_title">
132
+ {TITLE_TEXT}
133
+ </div>
134
+ <div class="page_desc">
135
+ {DESC_TEXT}
136
+ </div>
137
+ '''
138
+
139
+
140
+ label_text_component_height = 41
141
+
142
+
143
+ st.set_page_config(layout="wide")
144
+
145
+ # AIE数据集stac code
146
+ aie_dataset_category = [
147
+ "LANDSAT_LT05_T02_T1_L2"
148
+ ,"LANDSAT_LE07_E02_T1_L2"
149
+ ,"LANDSAT_LC08_C02_T1_L2"
150
+ ,"LANDSAT_LC09_C02_T1_L2"
151
+ ,"SENTINEL_MSIL2A"
152
+ ]
153
+
154
+ # L5:1984-2011
155
+ # L7:1999-至今
156
+ # L8:2014-至今
157
+ # L9:2021-至今
158
+ # S2:2018-至今
159
+
160
+ # 数据集时间范围
161
+ dataset_timestamp = {
162
+ "LANDSAT_LT05_T02_T1_L2": {"startDate": "1984-01-01", "endDate": "2011-12-31", "sampleStart": "2011-11-01", "sampleEnd": "2011-11-30"},
163
+ "LANDSAT_LE07_E02_T1_L2": {"startDate": "1999-01-01", "endDate": "2021-12-31", "sampleStart": "2021-12-01", "sampleEnd": "2021-12-31"},
164
+ "LANDSAT_LC08_C02_T1_L2": {"startDate": "2014-01-01", "endDate": "__NOW__", "sampleStart": "2023-02-01", "sampleEnd": "2023-03-28"},
165
+ "LANDSAT_LC09_C02_T1_L2": {"startDate": "2021-01-01", "endDate": "__NOW__", "sampleStart": "2023-01-01", "sampleEnd": "2023-03-01"},
166
+ "SENTINEL_MSIL2A": {"startDate": "2018-01-01", "endDate": "__NOW__", "sampleStart": "2023-03-01", "sampleEnd": "2023-03-28"}
167
+ }
168
+
169
+ # aie_area_meta = {}
170
+
171
+
172
+ image_collection_reduce_funcs = [
173
+ "median",
174
+ "min",
175
+ "max",
176
+ "mosaic",
177
+ "mean"
178
+ ]
179
+
180
+
181
+ def aie_init():
182
+ token = os.environ.get("SDK_TOKEN")
183
+ #token = "81921ae3af932cf35f1e56de4a8b1ca4"
184
+ aie.Authenticate(token=token)
185
+ aie.Initialize()
186
+
187
+
188
+ @st.cache_resource
189
+ def load_area_select_options():
190
+ file_path = "./china-area.json"
191
+ with open(file_path, 'r', encoding="utf-8") as reader:
192
+ area_arr = json.loads(reader.read())
193
+ area_dic = {}
194
+ for item in area_arr:
195
+ province_name = item['levelOneAreaName']
196
+ city_name = item['levelTwoAreaName']
197
+ district_name = item['areaName']
198
+ if not province_name in area_dic:
199
+ area_dic[province_name] = {}
200
+
201
+ cities = area_dic[province_name]
202
+ if not city_name in cities:
203
+ cities[city_name] = {}
204
+
205
+ districts = cities[city_name]
206
+ if not district_name in districts:
207
+ districts[district_name] = district_name
208
+
209
+ print("tianxun area data init complete")
210
+ return area_dic
211
+
212
+ @st.cache_resource
213
+ def load_dataset_info():
214
+ file_path = "./aie_dataset_meta.json"
215
+ with open(file_path, 'r', encoding="utf-8") as reader:
216
+ _dataset = json.loads(reader.read())
217
+ return _dataset
218
+
219
+
220
+
221
+ def page_reset_callback():
222
+ st.session_state['dateset_picker'] = 'LANDSAT_LT05_T02_T1_L2'
223
+ st.session_state['region_province_select'] = '北京市'
224
+ st.session_state['region_city_select'] = '请选择'
225
+ st.session_state['region_district_select'] = '请选择'
226
+ st.session_state['time_picker'] = [datetime.date(2011, 1, 1), datetime.date(2011, 6, 30)]
227
+ st.session_state['cloud_picker'] = '20%'
228
+ st.session_state['reduce_picker'] = 'median'
229
+ st.session_state['band_picker'] = []
230
+ st.session_state['min_input'] = '8000'
231
+ st.session_state['max_input'] = '13000'
232
+ st.session_state['render_map_html'] = None
233
+
234
+
235
+
236
+ def page_components_render(ctr_panel, map_panel):
237
+ with ctr_panel:
238
+ hide_streamlit_menu = """
239
+ <style>
240
+ #MainMenu {visibility: hidden;}
241
+ </style>
242
+
243
+ """
244
+ st.markdown(hide_streamlit_menu, unsafe_allow_html=True)
245
+
246
+ area_selections = load_area_select_options()
247
+ dataset_meta = load_dataset_info()
248
+
249
+ # title
250
+ components.html(page_title_text_tmpl.format(TITLE_TEXT="影像快速检索", DESC_TEXT="卫星影像数据获取是业务应用分析的第一步工作,基于平台现有Landsat和Sentinel系列卫星数据资源,根据用户选择的感兴趣行政区、时间范围、云量等参数,可快速获取覆盖区域内的已镶嵌和裁剪后的卫星数据。"), height=160)
251
+
252
+
253
+ # 选择数据集类型
254
+ dataset_label, dataset_select = st.columns([1.1, 3.9])
255
+ # todo: 实在不行,label用html渲染
256
+ with dataset_label:
257
+ # st.text("数据类型")
258
+ components.html(label_text_tmpl.format(LABEL_TEXT="数据类型"), height=label_text_component_height)
259
+
260
+ with dataset_select:
261
+ dataset_empty = st.empty()
262
+
263
+ dataset = dataset_empty.selectbox(label="请选择数据类型", options=aie_dataset_category, key="dateset_picker", label_visibility="collapsed")
264
+
265
+ # 区域过滤
266
+ region_label, province_select, city_select = st.columns([1.65,2.8,2.75])
267
+
268
+ with region_label:
269
+ # st.text("区域选择")
270
+ components.html(label_text_tmpl.format(LABEL_TEXT="区域选择"), height=label_text_component_height)
271
+
272
+ with province_select:
273
+ region_province_options = [name for name in area_selections]
274
+ region_province = st.selectbox(label="请选择省", options=region_province_options, key="region_province_select", label_visibility="collapsed")
275
+
276
+ with city_select:
277
+ region_city_options = []
278
+ if region_province:
279
+ region_city_options = [name for name in area_selections[region_province]]
280
+
281
+ region_city_options_update = ['请选择'] + region_city_options
282
+ region_city = st.selectbox(label="请选择市", options=region_city_options_update, key="region_city_select", label_visibility="collapsed")
283
+
284
+ # 选择时间区间
285
+ time_label, time_select = st.columns([1.1, 3.9])
286
+ with time_label:
287
+ # st.text("检索日期")
288
+ components.html(label_text_tmpl.format(LABEL_TEXT="检索日期"), height=label_text_component_height)
289
+
290
+ with time_select:
291
+ try:
292
+ min_time = datetime.date(2011, 1, 1)
293
+ max_time = datetime.date(2011, 6, 30)
294
+ sample_start_time = datetime.date(2011, 1, 1)
295
+ sample_end_time = datetime.date(2011, 6, 30)
296
+ if dataset and dataset in dataset_timestamp:
297
+ min_time = datetime.datetime.strptime(dataset_timestamp[dataset]['startDate'], '%Y-%m-%d')
298
+ if dataset_timestamp[dataset]['endDate'] == '__NOW__':
299
+ # max_time = datetime.date.today()
300
+ max_time = datetime.datetime.strptime(str(datetime.date.today()), '%Y-%m-%d')
301
+ else:
302
+ max_time = datetime.datetime.strptime(dataset_timestamp[dataset]['endDate'], '%Y-%m-%d')
303
+
304
+ # print(f"[DEBUG] {dataset} max_time = {max_time}, min_time = {min_time}")
305
+ sample_start_time = datetime.datetime.strptime(dataset_timestamp[dataset]['sampleStart'], '%Y-%m-%d')
306
+ sample_end_time = datetime.datetime.strptime(dataset_timestamp[dataset]['sampleEnd'], '%Y-%m-%d')
307
+
308
+
309
+ start_date, end_date = st.date_input(label="Select image time range", min_value=min_time, max_value=max_time,value=[sample_start_time, sample_end_time], key="time_picker", label_visibility="collapsed")
310
+ except Exception as e:
311
+ print("date picker error. ignore")
312
+
313
+ # 选择云量
314
+ cloud_label, cloud_select = st.columns([1.1, 3.9])
315
+ with cloud_label:
316
+ # st.text("云量")
317
+ components.html(label_text_tmpl.format(LABEL_TEXT="云 量"), height=label_text_component_height)
318
+
319
+ with cloud_select:
320
+ cloud_options = [ str(x) + "%" for x in range(0, 105, 5)]
321
+ end_cloud = st.select_slider(
322
+ '选择云量',
323
+ options=cloud_options,
324
+ key='cloud_picker',
325
+ value='20%', label_visibility="collapsed")
326
+
327
+ # 选择镶嵌方式
328
+ crop_label, crop_select = st.columns([1.1, 3.9])
329
+ with crop_label:
330
+ #st.text("镶嵌方式")
331
+ components.html(label_text_tmpl.format(LABEL_TEXT="镶嵌方式"), height=label_text_component_height)
332
+
333
+ with crop_select:
334
+ crop_type = st.selectbox(label="请选择镶嵌方式", options=image_collection_reduce_funcs, key="reduce_picker", label_visibility="collapsed")
335
+
336
+
337
+ # 波段选择(默认填充前3个)
338
+ band_label, band_select = st.columns([1.1, 3.9])
339
+ with band_label:
340
+ # st.text("波段选择")
341
+ components.html(label_text_tmpl.format(LABEL_TEXT="波段选择"), height=label_text_component_height)
342
+
343
+ with band_select:
344
+ bands_option = []
345
+ if dataset and dataset in dataset_meta:
346
+ bands_option = [band_name for band_name in dataset_meta[dataset]['bands']]
347
+ bands = st.multiselect("Select bands to display", options=bands_option, key="band_picker", label_visibility="collapsed", max_selections=3)
348
+
349
+
350
+ minmax_label, min_label, min_select, max_label, max_select = st.columns([1.55, 1.22, 1.74, 1.23, 1.74])
351
+ with min_label:
352
+ # st.text("最小值")
353
+ components.html(secondary_label_text_tmpl.format(LABEL_TEXT="最小值"), height=label_text_component_height)
354
+
355
+ with min_select:
356
+ default_min = 100
357
+ if dataset and dataset in dataset_meta:
358
+ default_min = dataset_meta[dataset]['min']
359
+ min = st.text_input(label="Enter image min",value=str(default_min), key="min_input", label_visibility="collapsed")
360
+
361
+ with max_label:
362
+ #st.text("最大值")
363
+ components.html(secondary_label_text_tmpl.format(LABEL_TEXT="最大值"), height=label_text_component_height)
364
+
365
+ with max_select:
366
+ default_max = 10000
367
+ if dataset and dataset in dataset_meta:
368
+ default_max = dataset_meta[dataset]['max']
369
+ max = st.text_input(label="Enter image max",value=str(default_max), key="max_input", label_visibility="collapsed")
370
+
371
+ reset_btn, query_btn = st.columns([1, 2])
372
+ with reset_btn:
373
+ page_reset = st.button("重置", type='secondary', key='reset_btn', use_container_width=True, on_click=page_reset_callback)
374
+
375
+ with query_btn:
376
+ submit = st.button("检索", type='primary', key='submit_btn', use_container_width=True)
377
+
378
+ # date_debug = str(dataset) + ", max_time = " + str(max_time) + ", min_time = " + str(min_time)
379
+ # st.write(date_debug)
380
+
381
+ if page_reset:
382
+ with map_panel:
383
+ components.html(default_map_html, height=780, scrolling=False)
384
+ return
385
+
386
+ if submit:
387
+ # 参数校验
388
+ errMsg = None
389
+ if not start_date or not end_date:
390
+ errMsg = "请选择时间"
391
+ elif start_date >= max_time.date():
392
+ errMsg = "未检索到数据,请重新设置检索日期"
393
+ elif not bands or len(bands) == 0:
394
+ errMsg = "请选择波段"
395
+ elif not min or not max:
396
+ errMsg = "请输入最大最小值"
397
+ else:
398
+ try:
399
+ ti = float(min)
400
+ ta = float(max)
401
+ except Exception as e:
402
+ errMsg = "最大最小值只能为数字"
403
+
404
+
405
+ if errMsg:
406
+ aie_init()
407
+ with ctr_panel:
408
+ st.error(errMsg)
409
+
410
+ with map_panel:
411
+ components.html(default_map_html, height=780, scrolling=False)
412
+
413
+ return
414
+
415
+ if dataset:
416
+ try:
417
+ # 拼接AIE 数据查询SDK语句
418
+ aie_init()
419
+ image_collection = aie.ImageCollection(dataset)
420
+ if start_date and end_date:
421
+ image_collection = image_collection.filterDate(start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d'))
422
+
423
+ if region_province or region_city:
424
+ fc = aie.FeatureCollection('China_City')
425
+
426
+ if region_province:
427
+ fc = fc.filter(aie.Filter.eq('province', region_province))
428
+
429
+ if region_city and region_city != '请选择':
430
+ fc = fc.filter(aie.Filter.eq('city', region_city))
431
+
432
+
433
+ # 用选择的数据重新初始化map组件
434
+ aie_map = aie.Map(
435
+ center=fc.getCenter(),
436
+ height=800,
437
+ zoom=7
438
+ )
439
+
440
+ region_vis_params = {
441
+ 'color': '#00FF00'
442
+ }
443
+ aie_map.addLayer(
444
+ fc,
445
+ region_vis_params,
446
+ '行政区划边界',
447
+ bounds=fc.getBounds()
448
+ )
449
+ image_collection = image_collection.filterBounds(fc.geometry())
450
+
451
+ if end_cloud:
452
+ end_cloud_val = end_cloud.replace('%','')
453
+ image_collection = image_collection.filter(aie.Filter.lte('eo:cloud_cover', int(end_cloud_val)))
454
+
455
+
456
+ if crop_type == 'median':
457
+ image_collection = image_collection.median()
458
+ elif crop_type == 'min':
459
+ image_collection = image_collection.min()
460
+ elif crop_type == 'max':
461
+ image_collection = image_collection.max()
462
+ elif crop_type == 'mosaic':
463
+ image_collection = image_collection.mosaic()
464
+ elif crop_type == 'mean':
465
+ image_collection = image_collection.mean()
466
+
467
+ if region_province or region_city:
468
+ image_collection = image_collection.clipToCollection(fc)
469
+
470
+ vis_params = {}
471
+ if bands:
472
+ vis_params['bands'] = list(bands)
473
+
474
+ if min and max:
475
+ vis_params['min'] = float(min)
476
+ vis_params['max'] = float(max)
477
+
478
+ aie_map.addLayer(
479
+ image_collection,
480
+ vis_params,
481
+ dataset,
482
+ bounds=image_collection.getBounds()
483
+ )
484
+
485
+ except Exception as e:
486
+ traceback.print_exc()
487
+ with ctr_panel:
488
+ # st.error(e)
489
+ st.error("未检索到数据集信息, 请重新设置查询条件")
490
+
491
+ with map_panel:
492
+ components.html(default_map_html, height=780, scrolling=False)
493
+
494
+ return
495
+
496
+
497
+ with map_panel:
498
+ # 对��未点击submit的情况, 直接读取静态html字符串来加快load速度
499
+ if submit:
500
+ map_html_source = aie_map.to_html()
501
+ st.session_state['render_map_html'] = map_html_source
502
+ components.html(map_html_source, height=780, scrolling=False)
503
+ else:
504
+ display_template = default_map_html
505
+ if 'render_map_html' in st.session_state and st.session_state['render_map_html']:
506
+ display_template = st.session_state['render_map_html']
507
+
508
+ components.html(display_template, height=780, scrolling=False)
509
+ # components.html(default_map_html, height=800, scrolling=False)
510
+
511
+
512
+ row1_col1, row1_col2 = st.columns([0.8, 2.2])
513
+ page_components_render(row1_col1, row1_col2)
514
+
515
+