import streamlit as st import folium from streamlit_folium import folium_static import requests import json import geopandas as gpd st.set_page_config(page_title="No Fly Zones Map", layout="wide") @st.cache_data def fetch_data(): url = "https://esua.cad.gov.hk/web/droneMap/getData" try: response = requests.get(url) response.raise_for_status() return response.json() # Directly parse JSON response except requests.RequestException as e: st.error(f"Error fetching data: {e}") return None def parse_json_data(json_data): geojson_list = [] try: # Extract the list of GeoJSON features from the JSON data rfz_features = json_data.get('data', {}).get('rfzFeatures', []) for feature_str in rfz_features: try: geojson = json.loads(feature_str) # Parse the GeoJSON string geojson_list.append(geojson) except json.JSONDecodeError as e: st.warning(f"Could not parse GeoJSON from feature: {feature_str[:100]}... Error: {e}") except Exception as e: st.error(f"Error processing JSON data: {e}") return geojson_list def main(): st.subheader("Restricted Flying Zones (“RFZ”) from Civil Aviation Department") # Fetch data with st.spinner("Fetching data..."): json_data = fetch_data() if json_data: geojson_list = parse_json_data(json_data) if geojson_list: m = folium.Map(location=[22.3193, 114.1694], zoom_start=11, tiles='https://landsd.azure-api.net/dev/osm/xyz/basemap/gs/WGS84/tile/{z}/{x}/{y}.png?key=f4d3e21d4fc14954a1d5930d4dde3809', attr="Map information from Lands Department") folium.TileLayer( tiles='https://mapapi.geodata.gov.hk/gs/api/v1.0.0/xyz/label/hk/en/wgs84/{z}/{x}/{y}.png', attr="Map Map information from Lands Department" ).add_to(m) for geojson in geojson_list: gdf = gpd.GeoDataFrame.from_features(geojson['features']) # Set the CRS to EPSG:4326 (WGS 84) gdf.set_crs(epsg=4326, inplace=True) folium.GeoJson( gdf, tooltip=folium.GeoJsonTooltip(fields=['name'], aliases=['Name'], localize=True) ).add_to(m) folium_static(m, width=1500, height=800) else: st.error("No valid GeoJSON data found in the response.") else: st.error("Failed to fetch data. Please try again later.") st.write("Restricted Flying Zones (“RFZ”) reflected in this drone map are designated by the Small Unmanned Aircraft Order (Cap. 448G). In connection to other restricted areas/ zones under other legislation or regulation such as the Air Navigation (Flight Prohibition) Order (Cap. 448E), users should refer to other maps for information.") if __name__ == "__main__": main()