Skip to content

Commit 05ead0a

Browse files
authored
Merge pull request #192 from UW-Macrostrat/measurements
Measurements tile route
2 parents 477f1d2 + bfd18d0 commit 05ead0a

File tree

2 files changed

+120
-0
lines changed

2 files changed

+120
-0
lines changed

services/tileserver/macrostrat/tileserver/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ async def shutdown_event():
200200

201201
app.include_router(fossils_router, tags=["PBDB"], prefix="/pbdb")
202202

203+
from .measurements import router as measurements_router
204+
205+
app.include_router(measurements_router, tags=["Measurements"], prefix="/measurements")
206+
203207
from .integrations import router as integrations_router
204208

205209
app.include_router(integrations_router, tags=["Integrations"], prefix="/integrations")
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
from pathlib import Path
2+
3+
from buildpg import render
4+
from fastapi import APIRouter, Request, Response
5+
from timvt.resources.enums import MimeTypes
6+
7+
router = APIRouter()
8+
9+
__here__ = Path(__file__).parent
10+
11+
12+
@router.get("/tile/{z}/{x}/{y}")
13+
async def tile_query(
14+
request: Request,
15+
z: int,
16+
x: int,
17+
y: int,
18+
):
19+
"""Get a tile from the tileserver."""
20+
pool = request.app.state.pool
21+
22+
where = ""
23+
24+
params = {
25+
"z": z,
26+
"x": x,
27+
"y": y,
28+
}
29+
30+
if "type" in request.query_params:
31+
type_vals = request.query_params["type"].split(",")
32+
type_vals = [v.strip() for v in type_vals if v.strip()]
33+
where += " AND type = ANY(:type_vals)"
34+
params["type_vals"] = type_vals
35+
36+
if "cluster" in request.query_params:
37+
cluster_val = request.query_params["cluster"]
38+
cluster = cluster_val.lower() not in ("false", "0", "no")
39+
40+
else:
41+
cluster = True
42+
43+
clusterSQL = """
44+
,
45+
46+
mvt_features AS (
47+
SELECT id,
48+
ST_SnapToGrid(geom, 256, 256) AS cluster_geom,
49+
geom
50+
FROM points
51+
),
52+
grouped_features AS (
53+
SELECT
54+
tile_utils.cluster_expansion_zoom(ST_Collect(geom), :z) AS expansion_zoom,
55+
count(*) AS n,
56+
st_centroid(ST_Collect(geom)) AS geom,
57+
CASE
58+
WHEN count(*) < 2 THEN string_agg(f.id::text, ',')
59+
ELSE null
60+
END AS id
61+
FROM mvt_features f
62+
GROUP BY cluster_geom
63+
)
64+
SELECT ST_AsMVT(row) AS mvt
65+
FROM (SELECT * FROM grouped_features) AS row;
66+
"""
67+
68+
unclusteredSQL = """
69+
SELECT ST_AsMVT(
70+
points.*,
71+
'default',
72+
4096,
73+
'geom'
74+
) AS mvt
75+
FROM points
76+
"""
77+
78+
if cluster:
79+
ending = clusterSQL
80+
else:
81+
ending = unclusteredSQL
82+
83+
query = f"""
84+
WITH
85+
tile AS (
86+
SELECT ST_TileEnvelope(:z, :x, :y) AS envelope,
87+
tile_layers.geographic_envelope(:x, :y, :z, 0.01) AS envelope_4326
88+
),
89+
points AS (
90+
SELECT
91+
id,
92+
type,
93+
tile_layers.tile_geom(
94+
ST_Intersection(geometry, envelope_4326),
95+
envelope
96+
) AS geom
97+
FROM macrostrat_api.measurements_with_type
98+
JOIN tile ON true
99+
WHERE
100+
lat IS NOT NULL AND lng IS NOT NULL
101+
AND ST_Intersects(
102+
ST_SetSRID(ST_MakePoint(lng, lat), 4326),
103+
envelope_4326
104+
)
105+
{where}
106+
)
107+
{ending}
108+
"""
109+
110+
q, p = render(query, **params)
111+
q = q.replace("textarray", "text[]")
112+
113+
async with pool.acquire() as con:
114+
data = await con.fetchval(q, *p)
115+
116+
return Response(data, media_type=MimeTypes.pbf.value)

0 commit comments

Comments
 (0)