Spaces:
Runtime error
Runtime error
Upload 5 files
Browse files- .gitignore +129 -0
- MyMap.html +0 -0
- README.md +2 -12
- ev_germany.py +216 -0
- requirements.txt +11 -0
.gitignore
ADDED
@@ -0,0 +1,129 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Byte-compiled / optimized / DLL files
|
2 |
+
__pycache__/
|
3 |
+
*.py[cod]
|
4 |
+
*$py.class
|
5 |
+
|
6 |
+
# C extensions
|
7 |
+
*.so
|
8 |
+
|
9 |
+
# Distribution / packaging
|
10 |
+
.Python
|
11 |
+
build/
|
12 |
+
develop-eggs/
|
13 |
+
dist/
|
14 |
+
downloads/
|
15 |
+
eggs/
|
16 |
+
.eggs/
|
17 |
+
lib/
|
18 |
+
lib64/
|
19 |
+
parts/
|
20 |
+
sdist/
|
21 |
+
var/
|
22 |
+
wheels/
|
23 |
+
pip-wheel-metadata/
|
24 |
+
share/python-wheels/
|
25 |
+
*.egg-info/
|
26 |
+
.installed.cfg
|
27 |
+
*.egg
|
28 |
+
MANIFEST
|
29 |
+
|
30 |
+
# PyInstaller
|
31 |
+
# Usually these files are written by a python script from a template
|
32 |
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
33 |
+
*.manifest
|
34 |
+
*.spec
|
35 |
+
|
36 |
+
# Installer logs
|
37 |
+
pip-log.txt
|
38 |
+
pip-delete-this-directory.txt
|
39 |
+
|
40 |
+
# Unit test / coverage reports
|
41 |
+
htmlcov/
|
42 |
+
.tox/
|
43 |
+
.nox/
|
44 |
+
.coverage
|
45 |
+
.coverage.*
|
46 |
+
.cache
|
47 |
+
nosetests.xml
|
48 |
+
coverage.xml
|
49 |
+
*.cover
|
50 |
+
*.py,cover
|
51 |
+
.hypothesis/
|
52 |
+
.pytest_cache/
|
53 |
+
|
54 |
+
# Translations
|
55 |
+
*.mo
|
56 |
+
*.pot
|
57 |
+
|
58 |
+
# Django stuff:
|
59 |
+
*.log
|
60 |
+
local_settings.py
|
61 |
+
db.sqlite3
|
62 |
+
db.sqlite3-journal
|
63 |
+
|
64 |
+
# Flask stuff:
|
65 |
+
instance/
|
66 |
+
.webassets-cache
|
67 |
+
|
68 |
+
# Scrapy stuff:
|
69 |
+
.scrapy
|
70 |
+
|
71 |
+
# Sphinx documentation
|
72 |
+
docs/_build/
|
73 |
+
|
74 |
+
# PyBuilder
|
75 |
+
target/
|
76 |
+
|
77 |
+
# Jupyter Notebook
|
78 |
+
.ipynb_checkpoints
|
79 |
+
|
80 |
+
# IPython
|
81 |
+
profile_default/
|
82 |
+
ipython_config.py
|
83 |
+
|
84 |
+
# pyenv
|
85 |
+
.python-version
|
86 |
+
|
87 |
+
# pipenv
|
88 |
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
89 |
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
90 |
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
91 |
+
# install all needed dependencies.
|
92 |
+
#Pipfile.lock
|
93 |
+
|
94 |
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
95 |
+
__pypackages__/
|
96 |
+
|
97 |
+
# Celery stuff
|
98 |
+
celerybeat-schedule
|
99 |
+
celerybeat.pid
|
100 |
+
|
101 |
+
# SageMath parsed files
|
102 |
+
*.sage.py
|
103 |
+
|
104 |
+
# Environments
|
105 |
+
.env
|
106 |
+
.venv
|
107 |
+
env/
|
108 |
+
venv/
|
109 |
+
ENV/
|
110 |
+
env.bak/
|
111 |
+
venv.bak/
|
112 |
+
|
113 |
+
# Spyder project settings
|
114 |
+
.spyderproject
|
115 |
+
.spyproject
|
116 |
+
|
117 |
+
# Rope project settings
|
118 |
+
.ropeproject
|
119 |
+
|
120 |
+
# mkdocs documentation
|
121 |
+
/site
|
122 |
+
|
123 |
+
# mypy
|
124 |
+
.mypy_cache/
|
125 |
+
.dmypy.json
|
126 |
+
dmypy.json
|
127 |
+
|
128 |
+
# Pyre type checker
|
129 |
+
.pyre/
|
MyMap.html
ADDED
The diff for this file is too large to render.
See raw diff
|
|
README.md
CHANGED
@@ -1,12 +1,2 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
emoji: 🐨
|
4 |
-
colorFrom: gray
|
5 |
-
colorTo: red
|
6 |
-
sdk: streamlit
|
7 |
-
sdk_version: 1.21.0
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
-
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
+
# Optimal location of EV charging stations
|
2 |
+
Display Saarbrucken map using streamlit to showcase optimal location for future EV charging stations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ev_germany.py
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import numpy as np
|
3 |
+
import json
|
4 |
+
import geopandas as gpd
|
5 |
+
import pyproj
|
6 |
+
import plotly.graph_objs as go
|
7 |
+
import folium
|
8 |
+
from streamlit_folium import st_folium
|
9 |
+
import pandas as pd
|
10 |
+
from folium.plugins import LocateControl, MarkerCluster
|
11 |
+
from bs4 import BeautifulSoup
|
12 |
+
from PIL import Image
|
13 |
+
|
14 |
+
|
15 |
+
def load_poi_data(path, target_crs="epsg:3005"):
|
16 |
+
df = pd.read_csv(path)
|
17 |
+
poi_data = gpd.GeoDataFrame(
|
18 |
+
df.loc[:, [c for c in df.columns if c != "geometry"]],
|
19 |
+
geometry=gpd.GeoSeries.from_wkt(df["geometry"]),
|
20 |
+
crs="epsg:3005", # Assuming the original CRS is EPSG:4326 (geographic CRS)
|
21 |
+
)
|
22 |
+
poi_data = poi_data.to_crs(target_crs) # Reproject to the target CRS
|
23 |
+
poi_data['geometry_center'] = poi_data['geometry'].centroid
|
24 |
+
return poi_data
|
25 |
+
|
26 |
+
def threshold(data):
|
27 |
+
threshold_scale = np.linspace(data.min(),
|
28 |
+
data.max(),
|
29 |
+
10, dtype=float)
|
30 |
+
# change the numpy array to a list
|
31 |
+
threshold_scale = threshold_scale.tolist()
|
32 |
+
threshold_scale[-1] = threshold_scale[-1]
|
33 |
+
return threshold_scale
|
34 |
+
|
35 |
+
#https://towardsdatascience.com/creating-interactive-maps-for-instagram-with-python-and-folium-68bc4691d075
|
36 |
+
|
37 |
+
# NOTE: This must be the first command in your app, and must be set only once
|
38 |
+
st.set_page_config( page_title="Optimal location of EV charging stations",
|
39 |
+
page_icon="https://img.icons8.com/external-phatplus-lineal-color-phatplus/64/external-ev-ev-car-phatplus-lineal-color-phatplus.png",
|
40 |
+
layout="wide")
|
41 |
+
|
42 |
+
|
43 |
+
# Power location: https://img.icons8.com/external-tal-revivo-green-tal-revivo/100/external-power-location-on-map-for-quick-ev-charge-battery-green-tal-revivo.png
|
44 |
+
# https://img.icons8.com/external-phatplus-lineal-color-phatplus/64/external-ev-ev-car-phatplus-lineal-color-phatplus.png", width=64
|
45 |
+
# logo_url = "https://img.icons8.com/external-others-phat-plus/64/external-electric-electric-vehicles-color-line-others-phat-plus-14.png"
|
46 |
+
logo_url = "https://img.icons8.com/external-phatplus-lineal-color-phatplus/64/external-ev-ev-car-phatplus-lineal-color-phatplus.png"
|
47 |
+
st.image(logo_url, width=64)
|
48 |
+
st.header("Optimal placement of EV charging stations in Saarbrücken, Germany")
|
49 |
+
# st.write("[](<https://gitHub.com/><username>/<repo>)")
|
50 |
+
st.markdown("Welcome to our mini-project.....")
|
51 |
+
|
52 |
+
# col1, col2 = st.columns(2)
|
53 |
+
|
54 |
+
# with col1:
|
55 |
+
# Sidebar
|
56 |
+
with st.expander("Select options to view"):
|
57 |
+
population_chk = st.checkbox(
|
58 |
+
"Population density"
|
59 |
+
)
|
60 |
+
parking_check = st.checkbox(
|
61 |
+
"Parking"
|
62 |
+
)
|
63 |
+
parkingSpaces_check = st.checkbox(
|
64 |
+
"Parking spaces"
|
65 |
+
)
|
66 |
+
restaurant_chk = st.checkbox(
|
67 |
+
"Restaurant"
|
68 |
+
)
|
69 |
+
residential_Chk = st.checkbox(
|
70 |
+
"Residential"
|
71 |
+
)
|
72 |
+
ev_stations_chk = st.checkbox(
|
73 |
+
"EV Charging Stations"
|
74 |
+
)
|
75 |
+
|
76 |
+
|
77 |
+
|
78 |
+
|
79 |
+
|
80 |
+
# Get cleaned data
|
81 |
+
df_ev_data = pd.read_csv('Data/cleaned_ev_data_germany.csv')
|
82 |
+
df_saarbrucken = df_ev_data[df_ev_data['City'] == 'Saarbrücken']
|
83 |
+
|
84 |
+
# # Multiselect
|
85 |
+
# cols = df_münchen['Operator'].unique()
|
86 |
+
# st_ms = st.multiselect("Filter data by operators", cols)
|
87 |
+
# mask_countries = df_münchen['Operator'].isin(st_ms)
|
88 |
+
# st.write('You selected:', df_münchen[mask_countries])
|
89 |
+
|
90 |
+
|
91 |
+
# create a map object of the city of München
|
92 |
+
saarbrucken_map_markers = folium.Map(location=[49.24015720000001, 6.996932700000002])
|
93 |
+
folium.Marker(
|
94 |
+
location=[49.24015720000001, 6.996932700000002],
|
95 |
+
popup="Saarbrucken",
|
96 |
+
icon=folium.Icon(color="red",icon="glyphicon glyphicon-pushpin"),
|
97 |
+
).add_to(saarbrucken_map_markers)
|
98 |
+
|
99 |
+
|
100 |
+
|
101 |
+
for cp,type, lat, lng in zip( df_saarbrucken['Number of Charging Points'],df_saarbrucken['Charging Station Type'],df_saarbrucken['Latitude'], df_saarbrucken['Longitude']):
|
102 |
+
# ev_img = 'https://img.icons8.com/external-tal-revivo-color-tal-revivo/96/external-power-location-on-map-for-quick-ev-charge-battery-color-tal-revivo.png'
|
103 |
+
# ev_img = "https://img.icons8.com/external-icongeek26-linear-colour-icongeek26/64/external-EV-Power-Tank-ev-station-icongeek26-linear-colour-icongeek26.png"
|
104 |
+
ev_img ='https://img.icons8.com/external-tal-revivo-filled-tal-revivo/96/external-power-location-on-map-for-quick-ev-charge-battery-filled-tal-revivo.png'
|
105 |
+
# Create custom icon with ev icon image
|
106 |
+
custom_icon = folium.CustomIcon(ev_img, icon_size=(20, 20), popup_anchor=(0, -22))
|
107 |
+
|
108 |
+
# Define html inside marker pop-up
|
109 |
+
ev_html = folium.Html(f"""<p style="text-align: center;"><span style="font-family: ariel; font-size: 16px;"><b>Number of charging points:</b> {cp} <br> <b>Charging Station Type:</b> {type}</span></p>
|
110 |
+
<p style="text-align: center;">
|
111 |
+
""", script=True)
|
112 |
+
# Create pop-up with html content
|
113 |
+
popup = folium.Popup(ev_html, max_width=700)
|
114 |
+
|
115 |
+
custom_marker = folium.Marker(location=[lat, lng], icon=custom_icon, popup=popup)
|
116 |
+
custom_marker.add_to(saarbrucken_map_markers)
|
117 |
+
# folium.CircleMarker(
|
118 |
+
# [lat, lng],
|
119 |
+
# radius=4,
|
120 |
+
# color='purple',
|
121 |
+
# opacity=0.4,
|
122 |
+
# fill=True,
|
123 |
+
# fill_color='blue').add_to(saarbrucken_map_markers)
|
124 |
+
|
125 |
+
# Enable geolocation button on map.
|
126 |
+
LocateControl(auto_start=False).add_to(saarbrucken_map_markers)
|
127 |
+
|
128 |
+
# Get Curated data
|
129 |
+
df_poi_data= load_poi_data('Data/all_city_data_with_pop.csv')
|
130 |
+
df_saarbrucken_poi = df_poi_data[df_poi_data['city'] == 'Saarbrucken']
|
131 |
+
|
132 |
+
#Plot centroids:
|
133 |
+
df_saarbrucken_poi["latitude"]=df_saarbrucken_poi["geometry_center"].get_coordinates()["y"]
|
134 |
+
df_saarbrucken_poi["longitude"]=df_saarbrucken_poi["geometry_center"].get_coordinates()["x"]
|
135 |
+
|
136 |
+
for lat, lng, parking, park_space, restaurant,residential,evs in zip(df_saarbrucken_poi.latitude,
|
137 |
+
df_saarbrucken_poi.longitude,
|
138 |
+
df_saarbrucken_poi.parking,
|
139 |
+
df_saarbrucken_poi.parking_space,
|
140 |
+
df_saarbrucken_poi.restaurant,
|
141 |
+
df_saarbrucken_poi.residential,
|
142 |
+
df_saarbrucken_poi.EV_stations):
|
143 |
+
park_icon = "https://img.icons8.com/ios-filled/100/parking.png"
|
144 |
+
parking_space ="https://img.icons8.com/external-bearicons-blue-bearicons/64/external-PARKING-SPACE-capsule-hotel-bearicons-blue-bearicons.png"
|
145 |
+
restaurant_icon ="https://img.icons8.com/color/96/restaurant-.png"
|
146 |
+
residential_icon="https://img.icons8.com/external-xnimrodx-lineal-xnimrodx/64/external-residential-city-xnimrodx-lineal-xnimrodx.png"
|
147 |
+
icons_size= 5
|
148 |
+
op =1
|
149 |
+
# folium.CircleMarker(
|
150 |
+
# [lat, lng],
|
151 |
+
# radius=4,
|
152 |
+
# color='red',
|
153 |
+
# opacity=0.4,
|
154 |
+
# fill=True,
|
155 |
+
# fill_color='blue').add_to(saarbrucken_map_markers)
|
156 |
+
|
157 |
+
if parking != 0 and parking_check==True:
|
158 |
+
custom_marker = folium.Marker(location=[lat, lng], popup=f"Parking: {parking}",opacity=op, icon=folium.CustomIcon(park_icon,icon_size=((parking+icons_size)/2, (parking+icons_size)/2), popup_anchor=(0, -22))).add_to(saarbrucken_map_markers)
|
159 |
+
if park_space != 0 and parkingSpaces_check ==True:
|
160 |
+
custom_marker = folium.Marker(location=[lat, lng], popup=f"Parking spaces: {park_space}",opacity=op, icon=folium.CustomIcon(parking_space,icon_size=((park_space+icons_size)/2, (park_space+icons_size)/2), popup_anchor=(0, -22))).add_to(saarbrucken_map_markers)
|
161 |
+
if restaurant != 0 and restaurant_chk:
|
162 |
+
custom_marker = folium.Marker(location=[lat, lng], popup=f"Restaurant: {restaurant}",opacity=op, icon=folium.CustomIcon(restaurant_icon,icon_size=((restaurant+icons_size)/2, (restaurant+icons_size)/2), popup_anchor=(0, -22))).add_to(saarbrucken_map_markers)
|
163 |
+
if residential != 0 and residential_Chk:
|
164 |
+
custom_marker = folium.Marker(location=[lat, lng], popup=f"Residential: {residential}", opacity=op, icon=folium.CustomIcon(residential_icon,icon_size=((residential+icons_size)/2, (residential+icons_size)/2), popup_anchor=(0, -22))).add_to(saarbrucken_map_markers)
|
165 |
+
if evs!=0 and ev_stations_chk:
|
166 |
+
folium.Circle(
|
167 |
+
location=[lat, lng],
|
168 |
+
radius=float(evs*20),
|
169 |
+
color='red',
|
170 |
+
fill=True,
|
171 |
+
fill_color='red',
|
172 |
+
opacity=1
|
173 |
+
).add_to(saarbrucken_map_markers)
|
174 |
+
|
175 |
+
|
176 |
+
|
177 |
+
# Make grid:
|
178 |
+
if population_chk:
|
179 |
+
sim_geo = gpd.GeoSeries(df_saarbrucken_poi["geometry"]).simplify(tolerance=0.001)
|
180 |
+
geo_json = sim_geo.to_json()
|
181 |
+
geo_j = folium.GeoJson(data=geo_json, style_function=lambda x: {'lineColor': '#228B22', "fill_opacity":0.7,"fillColor": "orange"})
|
182 |
+
geo_j.add_to(saarbrucken_map_markers)
|
183 |
+
|
184 |
+
|
185 |
+
ev_saar = df_saarbrucken_poi["population"]
|
186 |
+
maps=folium.Choropleth(
|
187 |
+
geo_data=geo_json,
|
188 |
+
name="choropleth",
|
189 |
+
data=ev_saar,
|
190 |
+
columns=["population"],
|
191 |
+
key_on="feature.id",
|
192 |
+
# fill_color="YlGn",
|
193 |
+
# fill_opacity=0.5,
|
194 |
+
# line_opacity=.1,
|
195 |
+
# threshold_scale=threshold(df_saarbrucken_poi["population"]),
|
196 |
+
fill_color='YlOrRd',
|
197 |
+
fill_opacity=0.7,
|
198 |
+
line_opacity=0.2,
|
199 |
+
highlight=True,
|
200 |
+
legend_name="Population (%)"
|
201 |
+
).add_to(saarbrucken_map_markers)
|
202 |
+
folium.LayerControl().add_to(saarbrucken_map_markers)
|
203 |
+
|
204 |
+
|
205 |
+
|
206 |
+
# Map folium markers
|
207 |
+
st_folium(saarbrucken_map_markers, width=1200, height=500, center=[49.24015720000001, 6.996932700000002], returned_objects=[],zoom=12)
|
208 |
+
st.caption("Map of Saarbrücken")
|
209 |
+
saarbrucken_map_markers.save("Mymap.html")
|
210 |
+
|
211 |
+
|
212 |
+
# with col2:
|
213 |
+
st.subheader("EDA")
|
214 |
+
image = Image.open('Data/Number of different types of infrastructure in Saarbrucken.png')
|
215 |
+
|
216 |
+
st.image(image, caption='Number of different types of infrastructure in Saarbrucken')
|
requirements.txt
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
pandas
|
3 |
+
geopandas
|
4 |
+
plotly
|
5 |
+
folium
|
6 |
+
streamlit_folium
|
7 |
+
folium.plugins
|
8 |
+
bs4
|
9 |
+
PIL
|
10 |
+
numpy
|
11 |
+
json
|