Cities for People: Can I calculate the space covered by objects?

Is it possible to calculate the space needed by a city like Brunswick?

In other words, can I calculate the space covered by a(n) area, node relation or way?

If the answer is yes:

The following Overpass query replies with about 3 thousand point of interest (POI’s) consisting if nodes, relations and ways regarding parking amenities.

out body center qt;

Can I calculate the space required by this queries reply?

At the end of the day I am aiming for the proportion of space for people vs. cars in areas like cities.


1 Like

In a simple way you can only do it for areas.
For roads you can roughly estimate the area, better if width or number of lanes is tagged.
Nodes are obviously difficult, you may be able to estimate area from tags, e.g. parking capacity or assume some default size for objects like turning circles.

Possibly you also need to consider that some areas might be duplicated, e.g. service roads on parking, or roads on intersections.

1 Like
  1. A line on its own has no exact area information. It can only be approximated with lanes= etc. Even if it has width= etc, it is still less accurate than actual areas. area:highway= for road shapes is a high detail that’s not commonly drawn.
  2. No, because you obviously can’t calculate the area of a point alone. Only areas in theory. You could illustrate how many parking facilities exist, but the representation varies. Especially for =street_side and =lane . Unfortunately, area size can only be inferred from perimeter length now. Allow filtering by area size · Issue #526 · drolbr/Overpass-API · GitHub
    Furthermore, I suppose there may be issue with choosing planar vs geodesic area calculation for larger single object areas, when the use case is for type=boundary . Exporting for use in other GIS software is what you can do now. Filtering to get the total area size in JOSM is also a possibility.
1 Like

If you don’t mind a bit of Python scripting, you could use GeoDesk for this task. (We’re due to release an early-access version of GeoDesk for Python next week, but the binaries are already on PyPI).

  1. Download the .osm.pbf files for the area you want to analyze (e.g. Geofabrik’s extracts for Germany)

  2. Build a Geographic Object Library (GOL):

  3. Install Python and pip install geodesk

  4. Run the following script:

import geodesk
germany = geodesk.Features('/path/to/de.gol')
city_name = "Braunschweig"
city = germany(f"a[boundary=administrative][admin_level=6][name={city_name}]").one
parking_lots = germany("a[amenity=parking]")
city_parking_lots = parking_lots.within(city)
print(f"{city_parking_lots.area / city.area * 100 :.2f}% of the area" 
    f" of {city_name} is used for parking")

Here is what this script does:

  1. It opens the GOL that you’ve created (in Step 2 above) and assigns it to germany (This is the set of all features in the GOL)

  2. It looks up the city that you want to analyze (or rather, the landkreis, since we’re using admin_level=6)

  3. It creates a set of all parking lots

  4. It then restricts that set to only the parking lots within the city’s area

  5. Finally, it calculates the ratio of the total area of the city’s parking lots versus the entire city area, and reports it as a percentage.

Your result will look like this:

    0.95% of the area of Braunschweig is used for parking

But if you really want to know just how much space is sacrificed to the Moloch dedicated to vehicles, you will want to take the road surfaces into account, as well. This part is trickier: In OSM, roads are mapped as ways, i.e. linestrings that by definition don’t have an area. A common approach is to take these lines and buffer them, which essentially turns them into polygons, whose area we can then calculate.

In the example below, I’m assuming that the average road is 6 meters wide, so we buffer the road shapes by 3 meters. (You can make this more accurate by querying each road type individually and applying different-sized buffers, then union the results.)

from geodesk import *
germany = Features('/path/to/de.gol')
city_name = "Braunschweig"
city = germany(f"a[boundary=administrative][admin_level=6][name={city_name}]").one
roads = germany("w[highway=residential,primary,secondary,tertiary,unclassified,service]")
road_shape = roads.within(city).shape.buffer(to_mercator(meters=3, lat=52))
print(f"{road_shape.area / city.shape.area * 100 :.2f}% of the area" 
    f" of {city_name} is used for roads")


    3.96% of the area of Braunschweig is used for roads

(The buffer() operation may take a minute or two)

I hope you will find this useful; let me know if you run into any issues. As I mentioned above, this is still pre-release, so you may encounter bugs (You can report them on GitHub).