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: 115
Ways: 908
Relations: 35

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)
/tmp/ipykernel_141/192227028.py:3: DeprecationWarning: 
Pyarrow will become a required dependency of pandas in the next major release of pandas (pandas 3.0),
(to allow more performant data types, such as the Arrow string type, and better interoperability with other libraries)
but was not found to be installed on your system.
If this would cause problems for you,
please provide us feedback at https://github.com/pandas-dev/pandas/issues/54466
        
  import pandas as pd
---------------------------------------------------------------------------
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:310, in _modified_open(file, *args, **kwargs)
    303 if file in {0, 1, 2}:
    304     raise ValueError(
    305         f"IPython won't let you open fd={file} by default "
    306         "as it is likely to crash IPython. If you know what you are doing, "
    307         "you can use builtins' open."
    308     )
--> 310 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
                }
            ]
        }
    ]
}