Fix map basestyle with static_ul
All checks were successful
/ test (push) Successful in 33s
/ build (push) Successful in 25s

This commit is contained in:
phil 2024-12-22 02:41:56 +01:00
parent 244194e832
commit c3bdc9c52f
4 changed files with 76 additions and 51 deletions

View file

@ -32,6 +32,7 @@ dependencies = [
"websockets>=12.0",
"pyxdg>=0.28",
"typer-slim>=0.15.1",
"httpx>=0.28.1",
]
requires-python = ">=3.12"
readme = "README.md"
@ -62,5 +63,4 @@ dev-dependencies = [
"types-python-jose>=3.3.4.20240106",
"types-passlib>=1.7.7.20240311",
"pytest>=8.3.4",
"httpx>=0.28.1",
]

View file

@ -1,15 +1,21 @@
from collections import OrderedDict, defaultdict
import logging
from json import dumps
from json import dumps, loads
from fastapi import (APIRouter, Request, HTTPException,
Response, status)
from httpx import AsyncClient
from fastapi import APIRouter, Request, HTTPException, Response, status
from sqlalchemy.orm import selectinload
from sqlalchemy.exc import NoResultFound
from sqlmodel import select
from gisaf.models.map_bases import (BaseMap, BaseMapLayer, BaseMapWithStores,
BaseStyle, MapInitData, MaplibreStyle)
from gisaf.models.map_bases import (
BaseMap,
BaseMapLayer,
BaseMapWithStores,
BaseStyle,
MapInitData,
MaplibreStyle,
)
from gisaf.models.misc import Qml
from gisaf.registry import registry
from gisaf.database import db_session, fastapi_db_session
@ -24,21 +30,27 @@ api = APIRouter(
# responses={404: {"description": "Not found"}},
)
async def get_base_styles():
async with db_session() as session:
query = select(BaseStyle.name)\
.where(BaseStyle.enabled==True)\
.order_by(BaseStyle.id) # type: ignore # noqa: E712
query = (
select(BaseStyle.name)
.where(BaseStyle.enabled == True)
.order_by(BaseStyle.id)
) # type: ignore # noqa: E712
data = await session.exec(query)
base_styles = data.all()
## TODO: tiles_registry
logger.warning('TODO: tiles_registry')
logger.warning("TODO: tiles_registry")
# base_styles.extend(tiles_registry.mbtiles.values())
return [BaseStyle(name=bs) for bs in base_styles] # type: ignore
async def get_base_maps() -> list[BaseMapWithStores]:
async with db_session() as session:
query1 = select(BaseMap) #.options(selectinload(BaseMap.layers)) # type: ignore
query1 = select(
BaseMap
) # .options(selectinload(BaseMap.layers)) # type: ignore
data1 = await session.exec(query1)
base_maps = data1.all()
base_map_dict = {bm.id: bm.name for bm in base_maps}
@ -54,23 +66,28 @@ async def get_base_maps() -> list[BaseMapWithStores]:
for bm, bmls in OrderedDict(sorted(bms.items())).items()
]
@api.get('/init-data')
@api.get("/init-data")
async def get_init_data() -> MapInitData:
await registry.update_stores_counts()
df = registry.stores.reset_index().\
drop(columns=['model', 'raw_model', 'base_gis_type'])
df = registry.stores.reset_index().drop(
columns=["model", "raw_model", "base_gis_type"]
)
return MapInitData(
baseStyles=await get_base_styles(),
baseMaps=await get_base_maps(),
groups=registry.primary_groups,
stores=df.to_dict(orient='records') # type: ignore
stores=df.to_dict(orient="records"), # type: ignore
)
@api.get('/base_style/{name}')
async def get_base_style(request: Request, name: str,
@api.get("/base_style/{name}")
async def get_base_style(
request: Request,
name: str,
db_session: fastapi_db_session,
) -> BaseStyle:
data = await db_session.exec(select(BaseStyle).where(BaseStyle.name==name))
) -> BaseStyle:
data = await db_session.exec(select(BaseStyle).where(BaseStyle.name == name))
try:
base_style = data.one()
except NoResultFound:
@ -79,19 +96,26 @@ async def get_base_style(request: Request, name: str,
# name=name,
# style=dumps({})
# )
if base_style.static_url is not None:
## Externally managed style, no need to get anything from tiles registry
async with AsyncClient() as client:
resp = await client.get(base_style.static_url)
base_style.style = loads(resp.content)
if name in tiles_registry.mbtiles:
## Try to get base_style from tiles_registry
tiles = tiles_registry.mbtiles['name']
style = dumps(await tiles.get_style(style_record=base_style,
request=request))
tiles = tiles_registry.mbtiles["name"]
style = dumps(await tiles.get_style(style_record=base_style, request=request))
else:
style = base_style.style # type: ignore
return BaseStyle(name=name, style=style) # type: ignore
@api.get('/layer_style/{store}')
async def get_layer_style(request: Request, store: str,
@api.get("/layer_style/{store}")
async def get_layer_style(
request: Request,
store: str,
response: Response,
) -> MaplibreStyle | None:
) -> MaplibreStyle | None:
try:
store_record = registry.stores.loc[store]
except KeyError:
@ -101,18 +125,18 @@ async def get_layer_style(request: Request, store: str,
## Get layer_defs from live redis and give symbol
return await redis_store.get_maplibre_style(store)
## Set the etag based on the last modification of the model's style.
#if store in info.schema.app['registry'].geom_auto:
# if store in info.schema.app['registry'].geom_auto:
if store_record.custom:
## The style is in Qml
ttag_channel = 'gisaf_map.qml'
ttag_channel = "gisaf_map.qml"
else:
## The style is in Category
ttag_channel = 'gisaf_survey.category'
ttag_channel = "gisaf_survey.category"
## Check if the request was etagged:
ttag = await redis_store.get_ttag(ttag_channel)
if ttag and request.headers.get('If-None-Match') == ttag:
if ttag and request.headers.get("If-None-Match") == ttag:
raise HTTPException(status_code=status.HTTP_304_NOT_MODIFIED)
# request.not_modified = True
# return MaplibreStyle()
response.headers['ETag'] = ttag
response.headers["ETag"] = ttag
return await store_record.model.get_maplibre_style()

View file

@ -12,30 +12,31 @@ class Store(StoreNameOnly):
count: int | None = None
custom: bool
description: str
#extra: dict[str, Any] | None
# extra: dict[str, Any] | None
gis_type: str
group: str
#icon: str
# icon: str
in_menu: bool
is_db: bool
is_line_work: bool
is_live: bool
long_name: str | None
#mapbox_layout: dict[str, Any] | None
#mapbox_paint: dict[str, Any] | None
# mapbox_layout: dict[str, Any] | None
# mapbox_paint: dict[str, Any] | None
type: str
# mapbox_type_custom: str | None
#mapbox_type_default: str
# mapbox_type_default: str
minor_group_1: str | None
minor_group_2: str | None
#model: GeoModel
#name_letter: str
#name_number: int
#raw_model: GeoPointSurveyModel
#raw_model_store_name: str
# model: GeoModel
# name_letter: str
# name_number: int
# raw_model: GeoPointSurveyModel
# raw_model_store_name: str
status: str
style: str | None
symbol: str | None
title: str
viewable_role: str | None
z_index: int
viewable_role: str | None = None
z_index: int = 500

6
uv.lock generated
View file

@ -538,7 +538,7 @@ wheels = [
[[package]]
name = "gisaf-backend"
version = "0.6.0a0"
version = "0.0.0"
source = { editable = "." }
dependencies = [
{ name = "aiopath" },
@ -548,6 +548,7 @@ dependencies = [
{ name = "fastapi" },
{ name = "geoalchemy2" },
{ name = "geopandas" },
{ name = "httpx" },
{ name = "itsdangerous" },
{ name = "matplotlib" },
{ name = "orjson" },
@ -586,7 +587,6 @@ mqtt = [
[package.dev-dependencies]
dev = [
{ name = "asyncpg-stubs" },
{ name = "httpx" },
{ name = "ipdb" },
{ name = "pandas-stubs" },
{ name = "pretty-errors" },
@ -610,6 +610,7 @@ requires-dist = [
{ name = "geopandas", specifier = ">=1.0.1" },
{ name = "gisaf-backend", extras = ["contextily"], marker = "extra == 'all'" },
{ name = "gisaf-backend", extras = ["mqtt"], marker = "extra == 'all'" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "itsdangerous", specifier = ">=2.1.2" },
{ name = "matplotlib", specifier = ">=3.8.3" },
{ name = "orjson", specifier = ">=3.9.10" },
@ -636,7 +637,6 @@ requires-dist = [
[package.metadata.requires-dev]
dev = [
{ name = "asyncpg-stubs", specifier = ">=0.29.1" },
{ name = "httpx", specifier = ">=0.28.1" },
{ name = "ipdb", specifier = ">=0.13.13" },
{ name = "pandas-stubs", specifier = ">=2.1.4.231218" },
{ name = "pretty-errors", specifier = ">=1.2.25" },