| 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() |
| except requests.RequestException as e: |
| st.error(f"Error fetching data: {e}") |
| return None |
|
|
|
|
| def parse_json_data(json_data): |
| geojson_list = [] |
|
|
| try: |
| |
| rfz_features = json_data.get('data', {}).get('rfzFeatures', []) |
| for feature_str in rfz_features: |
| try: |
| geojson = json.loads(feature_str) |
| 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") |
| |
| 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']) |
|
|
| |
| 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() |
|
|