import folium import gradio as gr import os from bs4 import BeautifulSoup import simplekml # Function to create the permaculture map def create_permaculture_map(coordinates, output_dir="output"): # Create base map m = folium.Map( location=coordinates, zoom_start=18, control_scale=True, tiles="cartodbpositron" ) # Add north arrow north_arrow = """
↑ N
""" m.get_root().html.add_child(folium.Element(north_arrow)) # Add scale folium.plugins.MousePosition().add_to(m) # Add map elements elements = { "Building": {"loc": [0.0001, 0.0001], "color": "red", "icon": "home"}, "Vegetation": {"loc": [-0.0001, -0.0001], "color": "green", "icon": "tree"}, "Water Management": {"loc": [0.0003, -0.0003], "color": "blue", "icon": "tint"}, "Energy": {"loc": [-0.0003, 0.0003], "color": "orange", "icon": "bolt"} } for name, props in elements.items(): folium.Marker( location=[coordinates[0] + props["loc"][0], coordinates[1] + props["loc"][1]], icon=folium.Icon(color=props["color"], icon=props["icon"]), popup=name ).add_to(m) # Add paths folium.PolyLine( locations=[ [coordinates[0] - 0.0002, coordinates[1] - 0.0002], [coordinates[0] + 0.0002, coordinates[1] + 0.0002] ], color="brown", weight=2, popup="Path" ).add_to(m) # Save map os.makedirs(output_dir, exist_ok=True) map_path = os.path.join(output_dir, "map.html") m.save(map_path) return map_path # Gradio interface def generate_map(lat, lon): # Validate coordinates if not (-90 <= lat <= 90) or not (-180 <= lon <= 180): raise gr.Error("Invalid coordinates! Lat: -90 to 90, Lon: -180 to 180") map_path = create_permaculture_map([lat, lon]) with open(map_path, "r") as f: html = f.read() return f'' # Create Gradio app with gr.Blocks() as app: gr.Markdown("# 🌱 Permaculture Base Map Designer") with gr.Row(): with gr.Column(): # Map location picker map_picker = gr.Map(label="Click map to select location", height=300) # Coordinate inputs with gr.Row(): lat_input = gr.Number(label="Latitude", value=45.5236) lon_input = gr.Number(label="Longitude", value=-122.6750) gr.Markdown("### Map Options") gr.Button("Generate Map").click( generate_map, inputs=[lat_input, lon_input], outputs=gr.HTML(label="Generated Map") ) # Display generated map with gr.Column(): gr.HTML(label="Generated Map") # Connect map clicks to coordinate inputs def update_coords(map_data): if map_data and map_data.get("features"): lon, lat = map_data["features"][0]["geometry"]["coordinates"] return lat, lon return None, None map_picker.select(update_coords, outputs=[lat_input, lon_input]) # Launch app if __name__ == "__main__": app.launch()