Return geoapi store geojson

This commit is contained in:
phil 2023-12-17 12:20:07 +05:30
parent 4048e61221
commit 1b7db43ee7
4 changed files with 44 additions and 40 deletions

View file

@ -3,9 +3,11 @@ Geographical json stores, served under /gj
Used for displaying features on maps
"""
import logging
from typing import Annotated
from asyncio import CancelledError
from fastapi import FastAPI, HTTPException, status, responses
from fastapi import FastAPI, HTTPException, Response, status, responses, Header
from .redis_tools import store as redis_store
# from gisaf.live import live_server
from .registry import registry
@ -41,7 +43,10 @@ async def live_layer(store: str):
return ws
@api.get('/{store_name}')
async def get_geojson(store_name):
async def get_geojson(store_name,
If_None_Match: Annotated[str | None, Header()] = None,
simplify: Annotated[float | None, Header()] = 50.0,
):
"""
Some REST stores coded manually (route prefixed with "gj": geojson).
:param store_name: name of the model
@ -59,22 +64,22 @@ async def get_geojson(store_name):
if await redis_store.has_channel(store_name):
## Live layers
data = await redis_store.get_layer_as_json(store_name)
return web.Response(text=data.decode(), content_type='application/json')
return data.decode()
# elif not model:
# raise HTTPException(status.HTTP_404_NOT_FOUND)
if model.cache_enabled:
ttag = await redis_store.get_ttag(store_name)
if ttag and request.headers.get('If-None-Match') == ttag:
return web.HTTPNotModified()
if ttag and If_None_Match == ttag:
return status.HTTP_304_NOT_MODIFIED
if hasattr(model, 'get_geojson'):
geojson = await model.get_geojson(simplify_tolerance=float(request.headers.get('simplify', 50.0)))
geojson = await model.get_geojson(simplify_tolerance=simplify, registry=registry)
## Store to redis for caching
if use_cache:
await redis_store.store_json(model, geojson)
resp = web.Response(text=geojson, content_type='application/json')
resp = geojson
elif model.can_get_features_as_df:
## Get the GeoDataframe (gdf) with GeoPandas
@ -86,7 +91,7 @@ async def get_geojson(store_name):
raise err
except Exception as err:
logger.exception(err)
raise web.HTTPInternalServerError()
raise status.HTTP_500_INTERNAL_SERVER_ERROR
## The query of category defined models gets the status (not sure how and this could be skipped)
## Other models do not have: just add it manually from the model itself
if 'status' not in gdf.columns:
@ -106,19 +111,19 @@ async def get_geojson(store_name):
else:
logger.warn(f"{model} doesn't allow using dataframe for generating json!")
attrs, features_kwargs = await model.get_features_attrs(
float(request.headers.get('simplify', 50.0)))
attrs, features_kwargs = await model.get_features_attrs(simplify)
## Using gino: allows OO model (get_info, etc)
try:
attrs['features'] = await model.get_features_in_bulk_gino(**features_kwargs)
except Exception as err:
logger.exception(err)
raise web.HTTPInternalServerError()
raise status.HTTP_500_INTERNAL_SERVER_ERROR
resp = attrs
headers = {}
if model.cache_enabled and ttag:
resp.headers.add('ETag', ttag)
return resp
headers['ETag'] = ttag
return Response(content=resp, media_type="application/json", headers=headers)
@api.get('/gj/{store_name}/popup/{id}')