Skip to content
This repository was archived by the owner on Dec 22, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .idea/sqldialects.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

72 changes: 72 additions & 0 deletions macrostrat_tileserver/single_map/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
from pathlib import Path
from typing import List

from buildpg import V, render
from fastapi import APIRouter, Request, Query
from macrostrat.utils import get_logger

from ..utils import scales_for_zoom, MapCompilation, get_layer_sql, VectorTileResponse

log = get_logger(__name__)

router = APIRouter()

__here__ = Path(__file__).parent


@router.get("/{slug}/{z}/{x}/{y}")
async def get_tile(
request: Request,
slug: str,
z: int,
x: int,
y: int,
):
"""Get a tile from the tileserver."""
pool = request.app.state.pool

params = dict(
z=z,
x=x,
y=y,
slug=slug,
)

async with pool.acquire() as con:
units_ = await run_layer_query(
con,
"units",
compilation=V(compilation_name + ".polygons"),
lithology=lithology,
**params,
)
lines_ = await run_layer_query(
con, "lines", compilation=V(compilation_name + ".lines"), **params
)
return VectorTileResponse(units_, lines_)


def build_lithology_clause(lithology: List[str]):
"""Build a WHERE clause to filter by lithology."""
if lithology is None or len(lithology) == 0:
return "true"

LITHOLOGY_COLUMNS = [
"lith_group",
"lith_class",
"lith_type",
"lith",
]

cols = [f"liths.{col}::text = ANY(:lithology)" for col in LITHOLOGY_COLUMNS]
q = " OR ".join(cols)
return f"({q})"


async def run_layer_query(con, layer_name, **params):
query = get_layer_sql(__here__ / "queries", layer_name)
if ":where_lithology" in query:
lith_clause = build_lithology_clause(params.get("lithology"))
query = query.replace(":where_lithology", lith_clause)
q, p = render(query, layer_name=layer_name, **params)
return await con.fetchval(q, *p)
12 changes: 12 additions & 0 deletions macrostrat_tileserver/single_map/queries/lines.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
SELECT
l.line_id,
l.source_id,
coalesce(l.descrip, '') AS descrip,
coalesce(l.name, '') AS name,
coalesce(l.direction, '') AS direction,
coalesce(l.type, '') AS "type",
tile_layers.tile_geom(l.geom, :envelope) AS geom
FROM maps.lines l
JOIN maps.sources s ON l.source_id = s.source_id
WHERE s.slug = :slug
AND ST_Intersects(geom, ST_Transform(:envelope, 4326))
13 changes: 13 additions & 0 deletions macrostrat_tileserver/single_map/queries/points.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

SELECT
strike,
dip,
dip_dir,
point_type,
certainty,
comments,
tile_layers.tile_geom(geom, :envelope) AS geom
FROM maps.points p
JOIN maps.sources s
WHERE p.source_id = s.source_id
AND ST_Intersects(geom, ST_Transform(:envelope, 4326))
14 changes: 14 additions & 0 deletions macrostrat_tileserver/single_map/queries/units.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
SELECT
p.map_id,
p.source_id,
l.*, -- map legend info
tile_layers.tile_geom(z.geom, :envelope) AS geom
FROM maps.polygons p
JOIN maps.sources s
ON p.source_id = s.source_id
LEFT JOIN maps.map_legend ml
ON p.map_id = ml.map_id
LEFT JOIN tile_layers.map_legend_info AS l
ON l.legend_id = ml.legend_id
WHERE s.slug = :slug
AND ST_Intersects(geom, ST_Transform(:envelope, 4326))