Urban Layer¶
This notebook will guide you through creating urban layers—like streets, intersections, and cities features as well as regions — for urban analysis.
Let’s dive in! 🚀
To get started, we need to import the urban_mapper module and create an instance of the UrbanMapper class. This instance, called mapper, will be our tool for building urban layers throughout the notebook.
import urban_mapper as um
# Fire up UrbanMapper
mapper = um.UrbanMapper()
/Users/sgp28/Desktop/Delivery/NYU/UrbanMapper/.venv/lib/python3.10/site-packages/DataProfileViewer/_plot_metadata_table.py:1: UserWarning: pkg_resources is deprecated as an API. See https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources package is slated for removal as early as 2025-11-30. Refrain from using this package or pin to Setuptools<81. import pkg_resources
Mapping Streets and Roads¶
Time to create our first urban layer! We’ll map the streets and roads of Downtown Brooklyn using the urban_layer module. This layer type, streets_roads, pulls data from Open Street Map (OSM) via OSMnx, and we’ll specify a driving network. Further could be explored via https://osmnx.readthedocs.io/en/stable/user-reference.html#osmnx.graph.graph_from_place as we wrap that.
Next steps:
- Set the layer type to
streets_roads. - Define the location as Downtown Brooklyn.
- Render the layer visually with
static_render().
Here we go! 🛣️
# Create streets layer
layer = (
mapper
.urban_layer # From the urban_layer module
.with_type("streets_roads") # With the type streets_roads
.from_place("Downtown Brooklyn, New York City, USA", network_type="drive") # From a place
# Note that after the place name we can specify what's called kwargs in Python.
# Which are extra arguments / parameters that could be passed to the just chosen urban layer's type.
# Here we chose the streets roads which are leveraged thanks to OSMNX, hence, network_type is one of their parameters.
# See further in the documentation for the others.
.build()
)
# Render layer
layer.preview()
layer.static_render()
Creating an Uber H3 Grid¶
Generate a hexagonal grid over a place of interest using the uber_h3 urban layer type.
uber_h3_layer = (
mapper.urban_layer.with_type("uber_h3")
.from_place("Manhattan, New York City, USA", resolution=9)
.with_mapping(
longitude_column="longitude",
latitude_column="latitude",
output_column="nearest_h3_cell",
)
.build()
)
uber_h3_layer.preview()
uber_h3_layer.static_render()
Plotting Street Intersections¶
Next up, let’s map the intersections in Downtown Brooklyn. Using the streets_intersections type, we’ll see where the roads meet—perfect for traffic or urban planning studies!
What’s next:
- Switch the layer type to
streets_intersections. - Use the same location and network type.
- Render the intersections visually.
Let’s check it out! 🚦
# Create streets layer
layer = (
mapper
.urban_layer # From the urban_layer module
.with_type("streets_intersections") # With the type streets_intersections
.from_place("Downtown Brooklyn, New York City, USA", network_type="drive") # From a place
# Note that after the place name we can specify what's called kwargs in Python.
# Which are extra arguments / parameters that could be passed to the just chosen urban layer's type.
# Here we chose the streets roads which are leveraged thanks to OSMNX, hence, network_type is one of their parameters.
# See further in the documentation for the others.
.build()
)
# Render layer
layer.static_render()
Adding Sidewalks from Tile2Net¶
Now, let’s bring in sidewalks! The streets_sidewalks type uses a shapefile (from Tile2Net, in this case) instead of a place name. You’ll need to replace the placeholder path with your actual file location.
Follow their readme to have an inference of sidewalks given a location of interest: https://github.com/VIDA-NYU/tile2net
If you believe this to be bothering your workflow, come shout out this issue: https://github.com/VIDA-NYU/UrbanMapper/issues/17
Next up:
- Set the layer type to
streets_sidewalks. - Load data from a shapefile.
- Render the sidewalks.
Ready to walk the walk? 🚶♂️
# Create streets layer
layer = (
mapper
.urban_layer # From the urban_layer module
.with_type("streets_sidewalks") # With the type streets_sidewalks
.from_file("<path_towards_a_tile_2_net_shp_inference.shp") # Here you need to infer from Tile2Net to get the shapefile path to put here.
.build()
)
# Render layer
layer.static_render()
Mapping Crosswalks from Tile2Net¶
Crosswalks are up next! Similar to sidewalks, the streets_crosswalks type uses a shapefile. Update the path to point to your Tile2Net output, and we’ll visualise pedestrian crossings.
Follow their readme to have an inference of sidewalks given a location of interest: https://github.com/VIDA-NYU/tile2net
What’s happening:
- Use
streets_crosswalksas the layer type. - Load the shapefile data.
- Display the crosswalks.
Let’s cross over! 🚸
# Create streets layer
layer = (
mapper
.urban_layer # From the urban_layer module
.with_type("streets_crosswalks") # With the type streets_crosswalks
.from_file("<path_towards_a_tile_2_net_shp_inference.shp") # Here you need to infer from Tile2Net to get the shapefile path to put here.
.build()
)
# Render layer
layer.static_render()
Exploring Parks in Brooklyn¶
Let’s switch gears and map some urban features! Using streets_features, we’ll find all the parks in Brooklyn by setting a leisure tag. See how tags works here https://osmnx.readthedocs.io/en/stable/user-reference.html#osmnx.features.features_from_place and here for more precision over the tags https://wiki.openstreetmap.org/wiki/Map_features
Next steps:
- Set the layer type to
streets_features. - Filter for parks in Brooklyn.
- Render the result.
Time to analyse around the park! 🌳
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"leisure": "park"} # get the parks.
)
# Note that after the place name we can specify what's called kwargs in Python.
# Which are extra arguments / parameters that could be passed to the just chosen urban layer's type.
# Here we chose the streets roads which are leveraged thanks to OSMNX, hence, network_type is one of their parameters.
# See further in the documentation for the others.
.build()
)
layer.static_render()
Finding Restaurants in Brooklyn¶
Hungry? Let’s map restaurants in Brooklyn with the amenity tag set to restaurant. This shows how flexible streets_features is for urban exploration.
What’s next:
- Keep using
streets_features. - Filter for restaurants.
- Visualise the dining spots.
Bon appétit! 🍽️
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"amenity": "restaurant"} # get the restaurants.
)
.build()
)
layer.static_render()
Locating Schools in Brooklyn¶
Now, let’s find schools! Using the amenity tag again, we’ll map educational institutions across Brooklyn.
Next up:
- Target schools with
streets_features. - Render the school locations.
Class is in session! 📚
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"amenity": "school"} # get the schools.
)
.build()
)
layer.static_render()
Mapping Hospitals in Brooklyn¶
Health matters! Let’s map hospitals in Brooklyn using the amenity tag set to hospital.
What’s happening:
- Use
streets_featuresto find hospitals. - Display the results.
Stay healthy! 🏥
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"amenity": "hospital"} # get the hospitals.
)
.build()
)
layer.static_render()
Charting Cycleways in Brooklyn¶
For the cyclists out there, let’s map cycleways using the highway tag. This highlights bike-friendly paths in Brooklyn.
Next steps:
- Set the tag to
cycleway. - Render the bike lanes.
Pedal on! 🚲
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"highway": "cycleway"} # get the cycleways.
)
.build()
)
layer.static_render()
Pinpointing Public Transport Stops¶
Let’s map public transport stops in Brooklyn with the public_transport tag. Great for transit planning!
What’s next:
- Filter for
stop_position. - Visualise the stops.
All aboard! 🚌
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"public_transport": "stop_position"} # get the public transport stops.
)
.build()
)
layer.static_render()
Highlighting Water Bodies¶
Nature time! Let’s map water bodies in Brooklyn using the natural tag set to water.
Next up:
- Target water features.
- Render the map.
Splash! 💧
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={"natural": "water"} # get the water bodies.
)
.build()
)
layer.static_render()
Combining Parks and Playgrounds¶
Why choose one when you can have both? Let’s map parks and playgrounds in Brooklyn by using a list in the leisure tag.
What’s happening:
- Use a list to filter multiple features.
- Display the combined result.
Fun for all! 🎠
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags = {"leisure": ["park", "playground"]} # get the parks and playgrounds.
)
.build()
)
layer.static_render()
Savoring French Cuisine¶
Craving something specific? Let’s find French restaurants in Brooklyn with the cuisine tag.
Next steps:
- Filter for French cuisine.
- Render the tasty spots.
Ooh la la! 🇫🇷
# Create streets layer
layer = (
mapper.urban_layer.with_type("streets_features") # From with the urban_layer module and with the type streets_features
.from_place(
"Brooklyn, New York City, USA",
tags={ "cuisine": "french" } # get the french restaurants.
)
.build()
)
layer.static_render()
___________________________________¶
Mapping Cities¶
We will be switching to what we call as regions based urban layers from now on. Having a larger zoom at the world map layer.
First, let’s map the cities in Hérault, France. We’re using the region_cities layer type to fetch city boundaries from OpenStreetMap. The from_place method targets 'Hérault, France', and we’ll build and render the layer, adding an interactive map with city names in tooltips. Note that the tooltip is not necessary, but open street map returns a lot of noise attributes that are not needed for this very example, feel free to explore that yourself.
layer = (
mapper.urban_layer.with_type("region_cities") # From with the urban_layer module and with the type region_cities
.from_place("Hérault, France") # From a place
.build()
)
layer.static_render()
layer.get_layer().explore(tooltip=["name"])
Mapping States¶
In this section, we’re mapping states in Grenada. The region_states layer type retrieves state or province boundaries. Using from_place with 'Grenada', we’ll construct and visualise the layer interactively.
layer = (
mapper.urban_layer.with_type("region_states") # From with the urban_layer module and with the type region_states
.from_place("Grenada") # From a place
.build()
)
layer.static_render()
layer.get_layer().explore()
Mapping Neighbourhoods¶
Here, we’re mapping neighbourhoods in Paris, France. The region_neighbourhoods layer type focuses on smaller administrative areas like districts. We’ll use from_place with 'Paris, France' to build and display the layer, complete with neighbourhood names in an interactive map.
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_place("Paris, France") # From a place
.build()
)
layer.static_render()
layer.get_layer().explore(tooltip=["name"])
Next, we’re applying the same approach to map neighbourhoods in Montpellier, France. This shows how region_neighbourhoods can be used across different cities to visualise local administrative boundaries.
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_place("Montpellier, France") # From a place
.build()
)
layer.static_render()
layer.get_layer().explore(tooltip=["name"])
Now, we’re mapping neighbourhoods in New York City, United States. Due to incomplete data in OpenStreetMap, we’re overriding the default admin level to '7' with overwrite_admin_level to get accurate boundaries, then displaying them interactively.
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_place("New York City, United States", overwrite_admin_level="7") # Here we overwrite because the inference do not find a correct enough level due to the lack of information on OSM.
.build()
)
layer.get_layer().reset_index().explore(tooltip=["name"])
Let’s switch back to cities and map those in Corsica. Using region_cities, we’ll retrieve and render city boundaries for this region, adding an interactive map with tooltips.
layer = (
mapper.urban_layer.with_type("region_cities") # From with the urban_layer module and with the type region_cities
.from_place("Corsica") # From a place
.build()
)
layer.static_render()
layer.get_layer().reset_index().explore(tooltip=["name"])
Here, we’re mapping neighbourhoods around a specific address in London: 'Tower Bridge Rd, London SE1 2UP, United Kingdom'. The from_address method with a 1000-metre radius lets us focus on a precise area, which we’ll visualise interactively.
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_address("Tower Bridge Rd, London SE1 2UP, United Kingdom", dist=1000.0) # From a specific address and a distance radius from it
.build()
)
layer.static_render()
layer.get_layer().reset_index().explore(tooltip=["name"])
Similarly, we’re mapping neighbourhoods around '370 Jay St, Brooklyn, New York 11201, United States'. Using from_address with a 1000-metre distance, we’ll build and display the local administrative areas.
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_address("370 Jay St, Brooklyn, New York 11201, United States", dist=1000.0) # From a specific address and a distance radius from it
.build()
)
layer.static_render()
layer.get_layer().reset_index().explore(tooltip=["name"])
In this example, we’re mapping neighbourhoods in Barcelona, Spain, using a polygon. We geocode 'Barcelona, Spain' to get its shape, then use from_polygon to build and render the neighbourhood layer interactively.
from geopy.geocoders import Nominatim
from shapely.wkt import loads
# Geocoding Tokyo Japan as a polygon form.
geolocator = Nominatim(user_agent="urban_mapper")
place_polygon = None
location = geolocator.geocode("Barcelona, Spain", geometry="wkt")
place_polygon = loads(location.raw["geotext"])
layer = (
mapper.urban_layer.with_type("region_neighborhoods") # From with the urban_layer module and with the type region_neighborhoods
.from_polygon(place_polygon) # From a polygon
.build()
)
layer.static_render()
layer.get_layer().reset_index().explore(tooltip=["name"])
Custom Urban Layer's File & Re-using Previous Urban Layer's¶
Here, we’re mapping showing that you could use your own geojson && shapefile file to load a urban layer for a complete urban mapper's analysis. For instance, in the very case below, we show the very detailed map of neighbourhoods in New York City, USA; as well as, the European Union's countries. On the other case, we also show that we could load the urban layer of a previous analysis.
from urban_mapper.modules.urban_layer import UrbanLayerFactory
# Think of the following as a full urban mapper's analysis
streets_layer = (
UrbanLayerFactory()
.with_type("streets_roads")
.from_place("Downtown Brooklyn, NY")
.build()
)
# Think of the following as the start of a new urba analysis using the previous one's enriched layer
custom_layer = (
UrbanLayerFactory()
.with_type("custom_urban_layer")
.from_urban_layer(streets_layer)
.build()
)
print(custom_layer.preview())
custom_layer.static_render()
from urban_mapper.modules.urban_layer import UrbanLayerFactory
custom_layer = (
UrbanLayerFactory()
.with_type("custom_urban_layer")
.from_file("./NYC Neighborhoods.geojson")
.build()
)
print(custom_layer.preview())
custom_layer.static_render()
from urban_mapper.modules.urban_layer import UrbanLayerFactory
custom_layer = (
UrbanLayerFactory()
.with_type("custom_urban_layer")
.from_file("./Europe_merged.shp")
.build()
)
print(custom_layer.preview())
custom_layer.static_render()
Previewing Your Layer¶
Curious about your layer’s details? The preview() method gives you a quick rundown of the layer type, source, and more—super useful for sharing or debugging.
Next up:
- Print a preview of the last layer you executed.
Take a peek! 👀
# Preview layer
print(layer.preview())
Congratulations!¶
Awesome work! 🎉 You’ve built a variety of urban layers, from streets to state boundaries, and even explored them interactively. You’re now ready to take it further—maybe enrich your layers with more data or analyze them with enricher?
What’s next:
- Experiment with new tags or areas.
- Dive into the
urban_mapperdocs for more tricks.
Happy mapping! 🗺️