Analyzing Schools Locations in Malika: Find solutions for accidents
Analyzing Schools Locations in Malika
In this study, we will explore spatial data and go further into Polygon containing Points.
Two days back, one of our neighbors lost her small daughter in a tragedy scooter accident. The small lovely girl, who used to come to our home in evening to practice her lessons with my daughter, was quiet, lovely and happy. The accident happened in the afternoon when she was crossing the main road to go to school, a car was stopping to take customers and another scooter comes rapidly behind the car and there the tragic happened.
After returning from the cemetery, I’ve observed there must be a solution for this as my Dad told me he witnessed last week a similar case while she was going to sport. Let’s analyze the location of the tragedy; we are in Malika village, a district of Pikine in Dakar (capital of Senegal)
>>> src = 'D:\Research\PROJECT\pyexeriences\Geospatial experiences\Books Practices\Lerning geospatial with python third edition\output\malika_sat.jpg'
>>> from IPython.display import Image
The output is an image extracted from Google earth pro software; it’s the satellite view of Malika. When we look deeper in this image, we can observe a road leading to the main highway in the Cornish as the following:
The blue line represents the road leading to the Cornish, it’s about 1.44 km long, around 0.88 miles. There are a lot of districts in the left and right side of the blue line and most of them take this road daily to go to Dakar city and return from it in late afternoon. It’s used by all kind of cars, as I think there is no distinction. In this blue line, we have the location of almost all administrates representations from Municipality, hospital and some schools. The public school in this blue line where a lot of children and other from middle school study was there before this road take place and the Cornish itself. The public school was absolutely far from the road, there was no road leading to the Cornish since there were no Cornish at that time.
Let’s trace another line in the old road which was there always and crossing the district to other district
The green line represents the main road leading to other district and was there always there. I’ve traced another red line to show where my cousins and that nice girl passed away cross daily to go to school.
Let’s extract schools in this district (Malika).
>>> src2 = 'D:/Research/PROJECT/pyexeriences/Geospatial experiences/Books Practices/Lerning geospatial with python third edition/output/malika_schools.xlsx'
>>> import pandas as pd, geopandas, matplotlib.pyplot as pl, numpy as np, contextily as ctx, osmnx as ox
>>> schools = pd.read_excel(src2)
>>> schools.head()
As you can see in the name of schools or the addresses, there are names like ‘Keur Massar’ which is a district next to Malika, I will not remove them from the list at the moment, I first will clean the data, create latitude, longitude from the coordinates, then create the geometry column (change the dataframe to geodataframe), after that, I will create a polygon of Malika and check those school within Malika and those not inside the district I will remove them (at least that’s the scientific method to work with spatial data).
So far, let’s start with extracting latitude, longitude. The ‘, 0’, in the coordinate represents the altitude which is not important for us in this analyze.
# To remove any spaces between columns
schools.columns = schools.columns.str.strip()
We can observe there is a very close between longitude and latitude coordinates column separated by the first comma ‘, 1’. (Note: The second comma’, 0’ is the altitude). We need to separate them to split both:
>>> schools.coordinates = schools['coordinates'].str.replace(',1', ', 1')
>>> schools.coordinates.head()
0 -17.337383, 14.796181,0
1 -17.337383, 14.796181,0
2 -17.3309799, 14.7946624,0
3 -17.3363701, 14.7963104,0
4 -17.3282782, 14.7904304,0
Name: coordinates, dtype: object
Let’s remove the altitude ‘,0’ from the coordinates:
>>> schools.coordinates = schools['coordinates'].str.replace(',0', '')
>>> schools.head()
>>> schools[['longitude','latitude']] = schools.coordinates.str.split(', ', expand=True)
>>> schools.head()
# Check the type of our dataset
>>> schools.dtypes
school_names object
address object
coordinates object
longitude object
latitude object
dtype: object
>>> type(schools)
pandas.core.frame.DataFrame
# Lets create the geometry for our datasets
>>> geo_schools = geopandas.GeoDataFrame(schools, geometry=geopandas.points_from_xy(schools.longitude, schools.latitude))
# Let's check the unique value in school_names
>>> geo_schools.school_names.nunique()
29
>>> geo_schools = geo_schools.drop_duplicates()
>>> len(geo_schools)
30
We can see the concentration of school in upper line, consecutive points in a same line, if you remember that’s within the first blue line I traced in the road that lead to the Cornish
Let’s visualize school in folium library
>>> location=[14.360666063083011,-14.418834270435836],
tiles='Stamen Terrain',
zoom_start=12,
)
>>> geo_schools.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
>>> map1
With Stamen Toner tiles,
>>> location=[14.360666063083011,-14.418834270435836],
tiles='Stamen Toner,
zoom_start=12,
)
>>> geo_schools.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
>>> map1
In the image, we can see a lot of schools almost positioned on the main roads and others are very close to the roads. The public schools are much better positioned than private schools in Malika
Let’s visualize with stamen terrain:
map1 = folium.Map(
>>> location=[14.360666063083011,-14.418834270435836],
tiles='Stamen Terrain',
zoom_start=12,
)
>>> geo_schools.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
>>> map1
Let’s use layer control in Folium to get the better view of the area
map1 = folium.Map(
location=[14.360666063083011,-14.418834270435836],
tiles='Mapbox Bright',
zoom_start=6,
)
geo_schools.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
folium.TileLayer('openstreetmap').add_to(map1)
map1
Let’s move to the schools that are in Malika district. I’ve tried to find Polygon of Malika, but there is no result. I will just make it from scratch since I can imagine the equivalent start of the area and the end. There will be always a questioner asking the side that covers the area. I live in Malika since almost 2003. Before, we had families living there and one of them is known in our family by ‘Galle Baba Ibrahima Kane Malika’ (translated to English: The house of Father Ibrahima Kane’) and his house is not far from the starting point of Malika. For the end, I think I will just cross a line down of the Malika Montagne (Mountain of Malika).
There are two methods to extract Polygon of Malika:
Using google earth pro engine, adding polygon around Malika and save my file to kml, open an excel and import it, copy the coordinates and create a polygon. The next figure is the polygon of Malika extracted from google earth engine.
>>> points = [(-17.35355463029444,14.8006736920844), (-17.35330536074641,14.80032136553888), …..)]
The data is too long; you can download it from here
>>> from shapely import geometry
>>> poly = geometry.Polygon(points)
You can compare this output and the snapshot image above
>>> print(poly.wkt)
POLYGON ((-17.35355463029444 14.8006736920844, -17.35330536074641 14.80032136553888, -17.3531851687944 14.80020366986683, -17.35300165470559 14.80002245145695, -17.35276358789881 14.79978995493151, -17.35247754726531 14.79961964376718, -17.35230191048014 14.79944905799204, -17.35206386519626 14.79916386107546…]
Let’s find the schools within our polygon
Point in Polygon
#geo_schools['latitude'] = geo_schools.latitude.astype(np.float) # This is to make sure that’s your data types is correct, the longitude and latitude must be in float.
>>> geo_schools.dtypes
school_names object
address object
coordinates object
longitude float64
latitude float64
geometry geometry
withinMalika object
dtype: object
# add new column to geo_school
geo_schools['withinMalika'] = ""
>>> withinMalikalist = []
for lon,lat in zip(geo_schools.longitude, geo_schools.latitude):
pt = Point(lon, lat)
withinMalika = poly.contains(pt)
#print( withinMalika )
withinMalikalist.append(withinMalika)
# update values in the that column, values: True/False
>>> geo_schools['withinMalika'] = withinMalikalist
>>> geo_school.head()
Ooh yeah, from the table, we can see those schools within Malika shape.
The first five rows of the output shows all schools are within the polygon. Let’s count the True and False.
We have 14 schools in Malika within 29 schools in our dataset.
>>> len(schools_in_malika)
14
There are 15 other schools in our dataset; we need to find their exact district. Anyway, I think 14 schools (public and private) are enough to cover 1.5 km, it’s already too much. We didn’t forget those coming from another district to study within Malika.
Let’s visualize schools in Malika
map1 = folium.Map(
location=[14.360666063083011,-14.418834270435836],
tiles='Mapbox Bright',
zoom_start=6,
)
schools_in_malika.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
folium.TileLayer('openstreetmap').add_to(map1)
map1
Schools out of Malika (always within data we previously extracted from google earth engine)
Let’s mix them both in same graph
>>> map1 = folium.Map(
location=[14.360666063083011,-14.418834270435836], tiles='Mapbox Bright',zoom_start=6,)
schools_not_in_malika.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]], color='red').add_to(map1), axis=1)
folium.TileLayer('openstreetmap').add_to(map1)
schools_in_malika.apply(lambda row:folium.CircleMarker(location=[row["latitude"], row["longitude"]]).add_to(map1), axis=1)
folium.TileLayer('openstreetmap').add_to(map1)
map1
It’s very clear from the graph that’s our polygon extraction is not corporate, for a simple reason there is a blue circle far from the boundaries of blue circles blocks. (The most confuse point is that school in the middle of red blocks is giving an address of Malika, it might be possible since the shape is not rectangular). Let’s use the second method:
The next method is the buffer function from shapely library. We will buffer around 1.5 km to 2 km and that’s for a normal district. Buffering is extending a circle around a specific area. I will buffer 1.5 km from the first elementary school of Malika
Buffering method from Shapely Library
>>> bufferLength = 1.5 # 1.5 km
>>> polygonSides = 360
>>> x = -17.337650632687343 # longitude
>>> y = 14.795555876039021 # latitude
>>> angles = np.linspace(0, 2 * np.pi, polygonSides, endpoint=False)
>>> points_list = [(x + np.sin(a) * bufferLength, y + np.cos(a) bufferLength) for a in angles]
>>> print(points_list[:10])
[(-17.337650632687343, 16.29555587603902), (-17.311472023031417, 16.29532741877361), (-17.28530138763359, 16.294642116567665), (-17.259146698322926, 16.29350017817088), (-17.233015922071154, 16.291901951428756), (-17.206917018565854, 16.28984792317664), (-17.180857937785863, 16.28733871909143), (-17.154846617579622, 16.284375103501006), (-17.128890981247245, 16.280957979151378), (-17.102998935126998, 16.277088386931727)]
Ooh, I think my polygon is too large, the result means all schools are within the polygon.
In fact, there are a lot of schools within a very small district which is not more than 2 miles. The most of student comes from the old Malika (before crossing the green line which represent the main road, look to the first graphs) to the new Malika which is the blue road leading to the Cornish area.
Helping students to access to school easily with less tragedy is very important. However, the most common solution is to install bumps on the road. Bumps can be very important, but in the society like ours, there must be a lot of dumps from the first schools (when you come from the left side of the district) to the end. The prevention is not only schools but a lot of businesses and administrations. A lot of dumps is a perfect solution, I’ve seen them in another countries where I’ve been living for long time. Let’s dump:
Every school who’s located over the road must place two separate dumps both side (two in left, distantiate a little bit, another two in right side). This solution might help a lot; some cars will prefer to take other roads to avoid the dumps. Like taking the pink line road
Every school over the road must place the following three consecutives dumps together to avoid any unexpected craziness
In the main road where students come from the old Malika to the schools area, establishing a 5 to 8 dumps are necessary to save there life’s, because staying longer in the road is better staying long at hospital
Comments
Post a Comment