Overture Maps Buildings¶
This notebook will give a quick overview of using the new Overture Maps Python library with Lonboard.
We'll pass in a bounding box covering New York City and the Overture Python API will fetch only the data inside that bounding box. While Overture's buildings dataset contains 2.3 billion rows, by using a relatively small bounding box, we can download data for our query relatively quickly (around 30 seconds on my internet connection).
This uses the latest advancements of the GeoParquet specification. Data is fetched directly from the cloud with no server in the middle!
You can view a hosted version of this notebook on Notebook Sharing Space (26MB download).
Dependendencies¶
This notebook requires Lonboard (tested with version 0.8) and overturemaps
(tested with version 0.4). To install overturemaps
, run:
pip install overturemaps
Imports¶
import numpy as np
import overturemaps
from matplotlib.colors import LogNorm
from palettable.colorbrewer.sequential import Oranges_9
from lonboard import Map, PolygonLayer
from lonboard.colormap import apply_continuous_cmap
Using this bounding box tool we can find a bounding box covering Manhattan. Choose "CSV" in the drop down box, then paste the result in the following cell:
bbox = -74.02169, 40.696423, -73.891338, 40.831263
Ensure you pass the bbox into overturemaps.record_batch_reader
as in the next line.
record_batch_reader
returns a RecordBatchReader, an iterator of Arrow RecordBatches. We call .read_all()
to materialize all batches into memory. This cell fetches the relevant data from the cloud (AWS S3), so it may take a minute to download.
table = overturemaps.record_batch_reader("building", bbox).read_all()
# Temporarily required as of Lonboard 0.8 to avoid a Lonboard bug
table = table.combine_chunks()
Let's color buildings by their heights. First, convert the "height" column to a numpy array, then replace any null values with 1
.
heights = table["height"].to_numpy()
heights = np.nan_to_num(heights, nan=1)
Building heights tend to scale non-linearly. That is, the vast majority of buildings are relatively low, but a few buildings are very tall. So that the low buildings aren't completely washed out, we'll use matplotlib's LogNorm
to normalize these values according to a log scale.
normalizer = LogNorm(1, heights.max(), clip=True)
normalized_heights = normalizer(heights)
Then we can apply a colormap to these heights. For this case, we'll use the Oranges_9
colormap.
Oranges_9.mpl_colormap
Using apply_continuous_cmap
, we can apply our values onto this colormap.
colors = apply_continuous_cmap(normalized_heights, Oranges_9)
We create a PolygonLayer
with our data, passing in the heights and colors from before.
layer = PolygonLayer(
# Select only a few attribute columns from the table
table=table.select(["id", "height", "geometry", "names"]),
extruded=True,
get_elevation=heights,
get_fill_color=colors,
)
We manually set the view state here for the original NYC data so that the map will start pitched. Remove or change this view_state
call if you change the input dataset.
view_state = {
"longitude": -73.98416810282863,
"latitude": 40.72651721370669,
"zoom": 12.726630492730596,
"pitch": 59.80465353190481,
"bearing": 13.243243243243244,
}
m = Map(layer, view_state=view_state)
m