energy_system_modelling_wor.../final_results.py

94 lines
3.4 KiB
Python

import folium
import geopandas as gpd
from pathlib import Path
import json
# Load the GeoJSON file and ensure the 'id' field is included
geojson_path = Path(__file__).parent / 'input_files' / 'buildings_to_map.geojson'
with open(geojson_path, 'r') as f:
geojson_data = json.load(f)
# Convert GeoJSON to GeoDataFrame, explicitly adding 'id' as a column
geo_data = gpd.GeoDataFrame.from_features(geojson_data["features"])
geo_data["id"] = [feature["id"] for feature in geojson_data["features"]]
# Ensure the GeoDataFrame has a CRS (assuming WGS84 if not already defined)
if geo_data.crs is None:
geo_data.set_crs(epsg=4326, inplace=True)
# Function to assign colors based on building function
def get_color(building_function):
color_map = {
"residential": "lightblue", # Changed from blue to lightblue for better text visibility
"secondary school": "green",
"medium office": "red",
"sports location": "orange", # Example for your data
"stand alone retail": "purple"
}
return color_map.get(building_function, "gray") # Default color is gray
# Create a style function for the GeoJson layer
def style_function(feature):
building_function = feature["properties"].get("function", "unknown")
return {
"fillColor": get_color(building_function),
"color": "black", # Outline color
"weight": 1,
"fillOpacity": 0.6
}
# Get the centroid coordinates for the map center
centroid = geo_data.geometry.centroid.iloc[0]
center = (centroid.y, centroid.x) # lat, lon
# Create a Folium map with CartoDB Positron tiles
m = folium.Map(location=center, zoom_start=50, tiles="CartoDB positron")
# Add the GeoJSON layer with color-coded styles
folium.GeoJson(
geojson_data,
name="Buildings",
style_function=style_function
).add_to(m)
# Add labels for each building
for _, row in geo_data.iterrows():
feature_id = row['id'] # Access the 'id' attribute
feature_centroid = row['geometry'].centroid # Get the centroid of the feature
# Create a rotated label
folium.Marker(
location=(feature_centroid.y, feature_centroid.x),
icon=folium.DivIcon(html=f'<div style="transform: rotate(90deg); font-size: 14px;">{feature_id}</div>')
).add_to(m)
# Add a legend to the map
legend_html = '''
<div style="
position: fixed;
bottom: 30px; left: 30px; width: 250px; height: 200px;
background-color: white;
border:2px solid grey; z-index:9999; font-size:14px;
padding: 10px; box-shadow: 2px 2px 5px rgba(0,0,0,0.3);">
<b>Legend</b><br>
<i style="background: lightblue; width: 10px; height: 10px; display: inline-block; margin-right: 5px;"></i> Residential<br>
<i style="background: green; width: 10px; height: 10px; display: inline-block; margin-right: 5px;"></i> Secondary School<br>
<i style="background: red; width: 10px; height: 10px; display: inline-block; margin-right: 5px;"></i> Medium Office<br>
<i style="background: orange; width: 10px; height: 10px; display: inline-block; margin-right: 5px;"></i> Sports Location<br>
<i style="background: purple; width: 10px; height: 10px; display: inline-block; margin-right: 5px;"></i> Stand Alone Retail<br>
</div>
'''
m.get_root().html.add_child(folium.Element(legend_html))
# Add a layer control to toggle layers
folium.LayerControl().add_to(m)
# Save the map as an HTML file
map_output_path = 'buildings_map_colored_with_legend.html'
m.save(map_output_path)
print(f"Map saved as {map_output_path}")