Working With COG¶
For this demo we will use the new DigitalGlobe OpenData
dataset https://www.digitalglobe.com/ecosystem/open-data
Requirements¶
- folium
- httpx
pip install folium httpx
In [ ]:
Copied!
# Uncomment this line if you need to install the dependencies
# !pip install folium httpx
# Uncomment this line if you need to install the dependencies
# !pip install folium httpx
In [ ]:
Copied!
import json
import httpx
from folium import Map, TileLayer
%matplotlib inline
import json
import httpx
from folium import Map, TileLayer
%matplotlib inline
In [ ]:
Copied!
titiler_endpoint = (
"https://titiler.xyz" # Developmentseed Demo endpoint. Please be kind.
)
url = "https://opendata.digitalglobe.com/events/mauritius-oil-spill/post-event/2020-08-12/105001001F1B5B00/105001001F1B5B00.tif"
titiler_endpoint = (
"https://titiler.xyz" # Developmentseed Demo endpoint. Please be kind.
)
url = "https://opendata.digitalglobe.com/events/mauritius-oil-spill/post-event/2020-08-12/105001001F1B5B00/105001001F1B5B00.tif"
Get COG Info¶
In [ ]:
Copied!
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params={
"url": url,
},
).json()
bounds = r["bounds"]
print(r)
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params={
"url": url,
},
).json()
bounds = r["bounds"]
print(r)
Get COG Metadata¶
In [ ]:
Copied!
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/statistics",
params={
"url": url,
},
).json()
print(json.dumps(r, indent=4))
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/statistics",
params={
"url": url,
},
).json()
print(json.dumps(r, indent=4))
Display Tiles¶
In [ ]:
Copied!
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={
"url": url,
},
).json()
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=13
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="DigitalGlobe OpenData").add_to(m)
m
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={
"url": url,
},
).json()
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=13
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="DigitalGlobe OpenData").add_to(m)
m
Work with non-byte data¶
In [ ]:
Copied!
url = "https://data.geo.admin.ch/ch.swisstopo.swissalti3d/swissalti3d_2019_2573-1085/swissalti3d_2019_2573-1085_0.5_2056_5728.tif"
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params={
"url": url,
},
).json()
print(r)
print("Data is of type:", r["dtype"])
# This dataset has statistics metadata
minv, maxv = (
r["band_metadata"][0][1]["STATISTICS_MINIMUM"],
r["band_metadata"][0][1]["STATISTICS_MAXIMUM"],
)
print("With values from ", minv, "to ", maxv)
url = "https://data.geo.admin.ch/ch.swisstopo.swissalti3d/swissalti3d_2019_2573-1085/swissalti3d_2019_2573-1085_0.5_2056_5728.tif"
# Fetch File Metadata to get min/max rescaling values (because the file is stored as float32)
r = httpx.get(
f"{titiler_endpoint}/cog/info",
params={
"url": url,
},
).json()
print(r)
print("Data is of type:", r["dtype"])
# This dataset has statistics metadata
minv, maxv = (
r["band_metadata"][0][1]["STATISTICS_MINIMUM"],
r["band_metadata"][0][1]["STATISTICS_MAXIMUM"],
)
print("With values from ", minv, "to ", maxv)
In [ ]:
Copied!
# We could get the min/max values using the statistics endpoint
r = httpx.get(
f"{titiler_endpoint}/cog/statistics",
params={
"url": url,
},
).json()
print(json.dumps(r["b1"], indent=4))
# We could get the min/max values using the statistics endpoint
r = httpx.get(
f"{titiler_endpoint}/cog/statistics",
params={
"url": url,
},
).json()
print(json.dumps(r["b1"], indent=4))
Display Tiles¶
Note: By default if the metadata has min/max
statistics, titiler will use those to rescale the data
In [ ]:
Copied!
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={
"url": url,
},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo").add_to(m)
m
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={
"url": url,
},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo").add_to(m)
m
Apply ColorMap
Now that the data is rescaled to byte values (0 -> 255) we can apply a colormap
In [ ]:
Copied!
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={"url": url, "rescale": f"{minv},{maxv}", "colormap_name": "terrain"},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo").add_to(m)
m
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={"url": url, "rescale": f"{minv},{maxv}", "colormap_name": "terrain"},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo").add_to(m)
m
Apply non-linear colormap (intervals)
see https://cogeotiff.github.io/rio-tiler/colormap/#intervals-colormaps
In [ ]:
Copied!
import json
cmap = json.dumps(
[
# ([min, max], [r, g, b, a])
([0, 1500], [255, 255, 204, 255]),
([1500, 1700], [161, 218, 180, 255]),
([1700, 1900], [65, 182, 196, 255]),
([1900, 2000], [44, 127, 184, 255]),
([2000, 3000], [37, 52, 148, 255]),
]
)
# https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=5
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={"url": url, "colormap": cmap},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
aod_layer = TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo")
aod_layer.add_to(m)
m
import json
cmap = json.dumps(
[
# ([min, max], [r, g, b, a])
([0, 1500], [255, 255, 204, 255]),
([1500, 1700], [161, 218, 180, 255]),
([1700, 1900], [65, 182, 196, 255]),
([1900, 2000], [44, 127, 184, 255]),
([2000, 3000], [37, 52, 148, 255]),
]
)
# https://colorbrewer2.org/#type=sequential&scheme=YlGnBu&n=5
r = httpx.get(
f"{titiler_endpoint}/cog/WebMercatorQuad/tilejson.json",
params={"url": url, "colormap": cmap},
).json()
bounds = r["bounds"]
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=r["minzoom"] + 1,
)
aod_layer = TileLayer(tiles=r["tiles"][0], opacity=1, attr="Swisstopo")
aod_layer.add_to(m)
m
In [ ]:
Copied!