demo
titiler.PgSTAC Demo¶
This Notebook aims to show the different features provided by titiler.pgstac application
In order to run this demo you'll need to have a PgSTAC database and the titiler.pgstac application running. The easiest way to launch them is to use the repo's docker-compose.yml
docker compose up tiler
Python requirements¶
pip install httpx2 folium pypgstac psycopg psycopg-pool geojson-pydantic
Populate the PgSTAC db with data¶
$ pypgstac load collections tests/fixtures/noaa-emergency-response.json --dsn postgresql://username:password@localhost:5439/postgis --method insert
$ pypgstac load items tests/fixtures/noaa-eri-nashville2020.json --dsn postgresql://username:password@localhost:5439/postgis --method insert
In [ ]:
Copied!
import json
import httpx2 as httpx
from folium import Map, TileLayer, GeoJson
from geojson_pydantic import Feature, Polygon
endpoint = "http://127.0.0.1:8081"
print(httpx.get(f"{endpoint}/healthz").json())
import json
import httpx2 as httpx
from folium import Map, TileLayer, GeoJson
from geojson_pydantic import Feature, Polygon
endpoint = "http://127.0.0.1:8081"
print(httpx.get(f"{endpoint}/healthz").json())
In [ ]:
Copied!
# bounds of the noaa-eri-nashville2020.json items
bounds = (-87.0251, 36.0999, -85.4249, 36.2251)
poly = Polygon.from_bounds(*bounds)
geojson = Feature(type="Feature", geometry=poly, properties=None).model_dump(
exclude_none=True
)
m = Map(
tiles="OpenStreetMap",
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=9,
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 3,
},
)
geo_json.add_to(m)
m
# bounds of the noaa-eri-nashville2020.json items
bounds = (-87.0251, 36.0999, -85.4249, 36.2251)
poly = Polygon.from_bounds(*bounds)
geojson = Feature(type="Feature", geometry=poly, properties=None).model_dump(
exclude_none=True
)
m = Map(
tiles="OpenStreetMap",
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2),
zoom_start=9,
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 3,
},
)
geo_json.add_to(m)
m
Register Search query¶
In [ ]:
Copied!
search_request = {
# Filter collection
"collections": ["noaa-emergency-response"],
# limit bounds of the known items (note: the bbox will also be used in the tilejson response)
"bbox": bounds,
"filter-lang": "cql2-json",
}
response = httpx.post(
f"{endpoint}/searches/register",
json=search_request,
).json()
print(response)
searchid = response["id"]
search_request = {
# Filter collection
"collections": ["noaa-emergency-response"],
# limit bounds of the known items (note: the bbox will also be used in the tilejson response)
"bbox": bounds,
"filter-lang": "cql2-json",
}
response = httpx.post(
f"{endpoint}/searches/register",
json=search_request,
).json()
print(response)
searchid = response["id"]
Show list of Mosaics¶
In [ ]:
Copied!
response = httpx.get(f"{endpoint}/searches/").json()
print(
json.dumps(
[
(search["search"]["hash"], search["search"]["metadata"].get("name"))
for search in response["searches"]
],
indent=4,
)
)
response = httpx.get(f"{endpoint}/searches/").json()
print(
json.dumps(
[
(search["search"]["hash"], search["search"]["metadata"].get("name"))
for search in response["searches"]
],
indent=4,
)
)
Get Search Metadata¶
In [ ]:
Copied!
info_response = httpx.get(f"{endpoint}/searches/{searchid}/info").json()
print(json.dumps(info_response, indent=4))
info_response = httpx.get(f"{endpoint}/searches/{searchid}/info").json()
print(json.dumps(info_response, indent=4))
Get TileJSON¶
Note: to return a valid tilejson document you'll need to pass either the assets or expression option.
In [ ]:
Copied!
tj_response = httpx.get(
f"{endpoint}/searches/{searchid}/WebMercatorQuad/tilejson.json?assets=cog&tilesize=256&minzoom=14&maxzoom=18"
).json()
print(json.dumps(tj_response, indent=4))
tj_response = httpx.get(
f"{endpoint}/searches/{searchid}/WebMercatorQuad/tilejson.json?assets=cog&tilesize=256&minzoom=14&maxzoom=18"
).json()
print(json.dumps(tj_response, indent=4))
Load tiles¶
In [ ]:
Copied!
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=14
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 1,
},
)
geo_json.add_to(m)
aod_layer = TileLayer(
tiles=tj_response["tiles"][0],
attr="Mosaic",
min_zoom=14,
max_zoom=18,
max_native_zoom=18,
)
aod_layer.add_to(m)
m
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=14
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 1,
},
)
geo_json.add_to(m)
aod_layer = TileLayer(
tiles=tj_response["tiles"][0],
attr="Mosaic",
min_zoom=14,
max_zoom=18,
max_native_zoom=18,
)
aod_layer.add_to(m)
m
Register a Mosaic with Metadata¶
In [ ]:
Copied!
search_request = {
# Filter collection
"collections": ["noaa-emergency-response"],
# limit bounds of the known items (note: the bbox will also be used in the tilejson response)
"bbox": bounds,
"filter-lang": "cql2-json",
"metadata": {
"bounds": [
-87.0251,
36.0999,
-85.4249,
36.2251,
], # This is redondant because it's in the bbox filter
"minzoom": 14,
"maxzoom": 18,
"assets": ["cog"],
"defaults": {
"true_color": {
"assets": ["cog|bidx=1,2,3"],
},
"b1": {
"assets": ["cog|bidx=1"],
},
},
},
}
response = httpx.post(
f"{endpoint}/searches/register",
json=search_request,
).json()
print(json.dumps(response, indent=4))
searchid = response["id"]
search_request = {
# Filter collection
"collections": ["noaa-emergency-response"],
# limit bounds of the known items (note: the bbox will also be used in the tilejson response)
"bbox": bounds,
"filter-lang": "cql2-json",
"metadata": {
"bounds": [
-87.0251,
36.0999,
-85.4249,
36.2251,
], # This is redondant because it's in the bbox filter
"minzoom": 14,
"maxzoom": 18,
"assets": ["cog"],
"defaults": {
"true_color": {
"assets": ["cog|bidx=1,2,3"],
},
"b1": {
"assets": ["cog|bidx=1"],
},
},
},
}
response = httpx.post(
f"{endpoint}/searches/register",
json=search_request,
).json()
print(json.dumps(response, indent=4))
searchid = response["id"]
In [ ]:
Copied!
tj_response = httpx.get(
f"{endpoint}/searches/{searchid}/WebMercatorQuad/tilejson.json?assets=cog&tilesize=256"
).json()
print(json.dumps(tj_response, indent=4))
tj_response = httpx.get(
f"{endpoint}/searches/{searchid}/WebMercatorQuad/tilejson.json?assets=cog&tilesize=256"
).json()
print(json.dumps(tj_response, indent=4))
In [ ]:
Copied!
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=14
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 1,
},
)
geo_json.add_to(m)
aod_layer = TileLayer(
tiles=tj_response["tiles"][0],
attr="Mosaic",
min_zoom=tj_response["minzoom"],
max_zoom=tj_response["maxzoom"],
max_native_zoom=tj_response["maxzoom"],
)
aod_layer.add_to(m)
m
m = Map(
location=((bounds[1] + bounds[3]) / 2, (bounds[0] + bounds[2]) / 2), zoom_start=14
)
geo_json = GeoJson(
data=geojson,
style_function=lambda x: {
"opacity": 1,
"dashArray": "1",
"fillOpacity": 0,
"weight": 1,
},
)
geo_json.add_to(m)
aod_layer = TileLayer(
tiles=tj_response["tiles"][0],
attr="Mosaic",
min_zoom=tj_response["minzoom"],
max_zoom=tj_response["maxzoom"],
max_native_zoom=tj_response["maxzoom"],
)
aod_layer.add_to(m)
m
In [ ]:
Copied!