Schools Count Exercise in Python#
Count Schools in Berlin using Overpass API through Python#
This analysis uses the OSMPythonTools to query the Overpass API. In addition Nominatim is queried first to define the area of interest.
from OSMPythonTools.overpass import Overpass
from OSMPythonTools.overpass import overpassQueryBuilder
from OSMPythonTools.nominatim import Nominatim
nominatim = Nominatim()
overpass = Overpass()
query = overpassQueryBuilder(
area=nominatim.query('Berlin').areaId(),
elementType=['node', 'way', 'relation'],
selector=['"amenity"="school"']
)
result = overpass.query(query)
print(f"Nodes: {len(result.nodes())}")
print(f"Ways: {len(result.ways())}")
print(f"Relations: {len(result.relations())}")
[nominatim] downloading data: search
[overpass] downloading data: [timeout:25][out:json];area(3600062422)->.searchArea;(node["amenity"="school"](area.searchArea);way["amenity"="school"](area.searchArea);relation["amenity"="school"](area.searchArea);); out body;
Nodes: 105
Ways: 892
Relations: 45
Count Schools per District using ohsome-py package#
Here we use the ohsome-py package to query the ohsome API. We use the elements/count/groupBy/boundary
endpoint.
For this analysis we assume that you already downloaded the district boundaries for Berlin. If not do this via OSM Boundaries.
import json
import matplotlib.pyplot as plt
import pandas as pd
from ohsome import OhsomeClient
client = OhsomeClient()
infile = "../../data/berlin_districts.geojson"
with open(infile) as f:
boundaries = json.load(f)
filter_schools = "amenity=school"
response = client.elements.count.groupByBoundary.post(
bpolys=json.dumps(boundaries),
filter=filter_schools
)
schools_df = response.as_dataframe()
display(schools_df)
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
Cell In[2], line 8
5 client = OhsomeClient()
7 infile = "../../data/berlin_districts.geojson"
----> 8 with open(infile) as f:
9 boundaries = json.load(f)
11 filter_schools = "amenity=school"
File /usr/local/lib/python3.10/site-packages/IPython/core/interactiveshell.py:324, in _modified_open(file, *args, **kwargs)
317 if file in {0, 1, 2}:
318 raise ValueError(
319 f"IPython won't let you open fd={file} by default "
320 "as it is likely to crash IPython. If you know what you are doing, "
321 "you can use builtins' open."
322 )
--> 324 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: '../../data/berlin_districts.geojson'
Count Schools in Berlin per district using ohsome API through Python#
This example directly queries the ohsome API using Python’s request
module. As above we use this endpoint elements/count/groupBy/boundary
.
import json
from datetime import datetime
import requests
base_url = "https://api.ohsome.org/v1"
endpoint = "/elements/count/groupBy/boundary"
url = base_url + endpoint
# open geojson file
with open("../../data/berlin_districts.geojson", "r") as file:
bpolys = json.load(file)
parameters = {
"bpolys": json.dumps(bpolys), # pass GeoJSON as string.
"filter": "amenity=school",
"format": "json",
"time": "2022-01-01",
}
response = requests.post(url, data=parameters)
response.raise_for_status() # Raise an Exception if HTTP Status Code is not 200
print("Response:")
print(json.dumps(response.json(), indent=4)) # Pretty print response
result = response.json()["groupByResult"]
Response:
{
"attribution": {
"url": "https://ohsome.org/copyrights",
"text": "\u00a9 OpenStreetMap contributors"
},
"apiVersion": "1.7.0",
"groupByResult": [
{
"groupByObject": "feature1",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 72.0
}
]
},
{
"groupByObject": "feature2",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 113.0
}
]
},
{
"groupByObject": "feature3",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 141.0
}
]
},
{
"groupByObject": "feature4",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 76.0
}
]
},
{
"groupByObject": "feature5",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 80.0
}
]
},
{
"groupByObject": "feature6",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 91.0
}
]
},
{
"groupByObject": "feature7",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 92.0
}
]
},
{
"groupByObject": "feature8",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 75.0
}
]
},
{
"groupByObject": "feature9",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 102.0
}
]
},
{
"groupByObject": "feature10",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 117.0
}
]
},
{
"groupByObject": "feature11",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 80.0
}
]
},
{
"groupByObject": "feature12",
"result": [
{
"timestamp": "2022-01-01T00:00:00Z",
"value": 87.0
}
]
}
]
}