Fix map basestyle with static_ul
This commit is contained in:
parent
244194e832
commit
c3bdc9c52f
4 changed files with 76 additions and 51 deletions
|
@ -32,6 +32,7 @@ dependencies = [
|
||||||
"websockets>=12.0",
|
"websockets>=12.0",
|
||||||
"pyxdg>=0.28",
|
"pyxdg>=0.28",
|
||||||
"typer-slim>=0.15.1",
|
"typer-slim>=0.15.1",
|
||||||
|
"httpx>=0.28.1",
|
||||||
]
|
]
|
||||||
requires-python = ">=3.12"
|
requires-python = ">=3.12"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
@ -62,5 +63,4 @@ dev-dependencies = [
|
||||||
"types-python-jose>=3.3.4.20240106",
|
"types-python-jose>=3.3.4.20240106",
|
||||||
"types-passlib>=1.7.7.20240311",
|
"types-passlib>=1.7.7.20240311",
|
||||||
"pytest>=8.3.4",
|
"pytest>=8.3.4",
|
||||||
"httpx>=0.28.1",
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
from collections import OrderedDict, defaultdict
|
from collections import OrderedDict, defaultdict
|
||||||
import logging
|
import logging
|
||||||
from json import dumps
|
from json import dumps, loads
|
||||||
|
|
||||||
from fastapi import (APIRouter, Request, HTTPException,
|
from httpx import AsyncClient
|
||||||
Response, status)
|
from fastapi import APIRouter, Request, HTTPException, Response, status
|
||||||
from sqlalchemy.orm import selectinload
|
from sqlalchemy.orm import selectinload
|
||||||
from sqlalchemy.exc import NoResultFound
|
from sqlalchemy.exc import NoResultFound
|
||||||
from sqlmodel import select
|
from sqlmodel import select
|
||||||
|
|
||||||
from gisaf.models.map_bases import (BaseMap, BaseMapLayer, BaseMapWithStores,
|
from gisaf.models.map_bases import (
|
||||||
BaseStyle, MapInitData, MaplibreStyle)
|
BaseMap,
|
||||||
|
BaseMapLayer,
|
||||||
|
BaseMapWithStores,
|
||||||
|
BaseStyle,
|
||||||
|
MapInitData,
|
||||||
|
MaplibreStyle,
|
||||||
|
)
|
||||||
from gisaf.models.misc import Qml
|
from gisaf.models.misc import Qml
|
||||||
from gisaf.registry import registry
|
from gisaf.registry import registry
|
||||||
from gisaf.database import db_session, fastapi_db_session
|
from gisaf.database import db_session, fastapi_db_session
|
||||||
|
@ -24,25 +30,31 @@ api = APIRouter(
|
||||||
# responses={404: {"description": "Not found"}},
|
# responses={404: {"description": "Not found"}},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
async def get_base_styles():
|
async def get_base_styles():
|
||||||
async with db_session() as session:
|
async with db_session() as session:
|
||||||
query = select(BaseStyle.name)\
|
query = (
|
||||||
.where(BaseStyle.enabled==True)\
|
select(BaseStyle.name)
|
||||||
.order_by(BaseStyle.id) # type: ignore # noqa: E712
|
.where(BaseStyle.enabled == True)
|
||||||
|
.order_by(BaseStyle.id)
|
||||||
|
) # type: ignore # noqa: E712
|
||||||
data = await session.exec(query)
|
data = await session.exec(query)
|
||||||
base_styles = data.all()
|
base_styles = data.all()
|
||||||
## TODO: tiles_registry
|
## TODO: tiles_registry
|
||||||
logger.warning('TODO: tiles_registry')
|
logger.warning("TODO: tiles_registry")
|
||||||
# base_styles.extend(tiles_registry.mbtiles.values())
|
# base_styles.extend(tiles_registry.mbtiles.values())
|
||||||
return [BaseStyle(name=bs) for bs in base_styles] # type: ignore
|
return [BaseStyle(name=bs) for bs in base_styles] # type: ignore
|
||||||
|
|
||||||
|
|
||||||
async def get_base_maps() -> list[BaseMapWithStores]:
|
async def get_base_maps() -> list[BaseMapWithStores]:
|
||||||
async with db_session() as session:
|
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)
|
data1 = await session.exec(query1)
|
||||||
base_maps = data1.all()
|
base_maps = data1.all()
|
||||||
base_map_dict = {bm.id: bm.name for bm in base_maps}
|
base_map_dict = {bm.id: bm.name for bm in base_maps}
|
||||||
query2 = select(BaseMapLayer).options(selectinload(BaseMapLayer.base_map)) # type: ignore
|
query2 = select(BaseMapLayer).options(selectinload(BaseMapLayer.base_map)) # type: ignore
|
||||||
data2 = await session.exec(query2)
|
data2 = await session.exec(query2)
|
||||||
base_map_layers = data2.all()
|
base_map_layers = data2.all()
|
||||||
bms: dict[str, list] = defaultdict(list)
|
bms: dict[str, list] = defaultdict(list)
|
||||||
|
@ -54,23 +66,28 @@ async def get_base_maps() -> list[BaseMapWithStores]:
|
||||||
for bm, bmls in OrderedDict(sorted(bms.items())).items()
|
for bm, bmls in OrderedDict(sorted(bms.items())).items()
|
||||||
]
|
]
|
||||||
|
|
||||||
@api.get('/init-data')
|
|
||||||
|
@api.get("/init-data")
|
||||||
async def get_init_data() -> MapInitData:
|
async def get_init_data() -> MapInitData:
|
||||||
await registry.update_stores_counts()
|
await registry.update_stores_counts()
|
||||||
df = registry.stores.reset_index().\
|
df = registry.stores.reset_index().drop(
|
||||||
drop(columns=['model', 'raw_model', 'base_gis_type'])
|
columns=["model", "raw_model", "base_gis_type"]
|
||||||
|
)
|
||||||
return MapInitData(
|
return MapInitData(
|
||||||
baseStyles=await get_base_styles(),
|
baseStyles=await get_base_styles(),
|
||||||
baseMaps=await get_base_maps(),
|
baseMaps=await get_base_maps(),
|
||||||
groups=registry.primary_groups,
|
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}")
|
||||||
db_session: fastapi_db_session,
|
async def get_base_style(
|
||||||
) -> BaseStyle:
|
request: Request,
|
||||||
data = await db_session.exec(select(BaseStyle).where(BaseStyle.name==name))
|
name: str,
|
||||||
|
db_session: fastapi_db_session,
|
||||||
|
) -> BaseStyle:
|
||||||
|
data = await db_session.exec(select(BaseStyle).where(BaseStyle.name == name))
|
||||||
try:
|
try:
|
||||||
base_style = data.one()
|
base_style = data.one()
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
|
@ -79,19 +96,26 @@ async def get_base_style(request: Request, name: str,
|
||||||
# name=name,
|
# name=name,
|
||||||
# style=dumps({})
|
# 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:
|
if name in tiles_registry.mbtiles:
|
||||||
## Try to get base_style from tiles_registry
|
## Try to get base_style from tiles_registry
|
||||||
tiles = tiles_registry.mbtiles['name']
|
tiles = tiles_registry.mbtiles["name"]
|
||||||
style = dumps(await tiles.get_style(style_record=base_style,
|
style = dumps(await tiles.get_style(style_record=base_style, request=request))
|
||||||
request=request))
|
|
||||||
else:
|
else:
|
||||||
style = base_style.style # type: ignore
|
style = base_style.style # type: ignore
|
||||||
return BaseStyle(name=name, 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}")
|
||||||
response: Response,
|
async def get_layer_style(
|
||||||
) -> MaplibreStyle | None:
|
request: Request,
|
||||||
|
store: str,
|
||||||
|
response: Response,
|
||||||
|
) -> MaplibreStyle | None:
|
||||||
try:
|
try:
|
||||||
store_record = registry.stores.loc[store]
|
store_record = registry.stores.loc[store]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -101,18 +125,18 @@ async def get_layer_style(request: Request, store: str,
|
||||||
## Get layer_defs from live redis and give symbol
|
## Get layer_defs from live redis and give symbol
|
||||||
return await redis_store.get_maplibre_style(store)
|
return await redis_store.get_maplibre_style(store)
|
||||||
## Set the etag based on the last modification of the model's style.
|
## 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:
|
if store_record.custom:
|
||||||
## The style is in Qml
|
## The style is in Qml
|
||||||
ttag_channel = 'gisaf_map.qml'
|
ttag_channel = "gisaf_map.qml"
|
||||||
else:
|
else:
|
||||||
## The style is in Category
|
## The style is in Category
|
||||||
ttag_channel = 'gisaf_survey.category'
|
ttag_channel = "gisaf_survey.category"
|
||||||
## Check if the request was etagged:
|
## Check if the request was etagged:
|
||||||
ttag = await redis_store.get_ttag(ttag_channel)
|
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)
|
raise HTTPException(status_code=status.HTTP_304_NOT_MODIFIED)
|
||||||
# request.not_modified = True
|
# request.not_modified = True
|
||||||
# return MaplibreStyle()
|
# return MaplibreStyle()
|
||||||
response.headers['ETag'] = ttag
|
response.headers["ETag"] = ttag
|
||||||
return await store_record.model.get_maplibre_style()
|
return await store_record.model.get_maplibre_style()
|
||||||
|
|
|
@ -12,30 +12,31 @@ class Store(StoreNameOnly):
|
||||||
count: int | None = None
|
count: int | None = None
|
||||||
custom: bool
|
custom: bool
|
||||||
description: str
|
description: str
|
||||||
#extra: dict[str, Any] | None
|
# extra: dict[str, Any] | None
|
||||||
gis_type: str
|
gis_type: str
|
||||||
group: str
|
group: str
|
||||||
#icon: str
|
# icon: str
|
||||||
in_menu: bool
|
in_menu: bool
|
||||||
is_db: bool
|
is_db: bool
|
||||||
is_line_work: bool
|
is_line_work: bool
|
||||||
is_live: bool
|
is_live: bool
|
||||||
long_name: str | None
|
long_name: str | None
|
||||||
#mapbox_layout: dict[str, Any] | None
|
# mapbox_layout: dict[str, Any] | None
|
||||||
#mapbox_paint: dict[str, Any] | None
|
# mapbox_paint: dict[str, Any] | None
|
||||||
type: str
|
type: str
|
||||||
# mapbox_type_custom: str | None
|
# mapbox_type_custom: str | None
|
||||||
#mapbox_type_default: str
|
# mapbox_type_default: str
|
||||||
minor_group_1: str | None
|
minor_group_1: str | None
|
||||||
minor_group_2: str | None
|
minor_group_2: str | None
|
||||||
#model: GeoModel
|
# model: GeoModel
|
||||||
#name_letter: str
|
# name_letter: str
|
||||||
#name_number: int
|
# name_number: int
|
||||||
#raw_model: GeoPointSurveyModel
|
# raw_model: GeoPointSurveyModel
|
||||||
#raw_model_store_name: str
|
# raw_model_store_name: str
|
||||||
status: str
|
status: str
|
||||||
style: str | None
|
style: str | None
|
||||||
symbol: str | None
|
symbol: str | None
|
||||||
title: str
|
title: str
|
||||||
viewable_role: str | None
|
viewable_role: str | None = None
|
||||||
z_index: int
|
z_index: int = 500
|
||||||
|
|
||||||
|
|
6
uv.lock
generated
6
uv.lock
generated
|
@ -538,7 +538,7 @@ wheels = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gisaf-backend"
|
name = "gisaf-backend"
|
||||||
version = "0.6.0a0"
|
version = "0.0.0"
|
||||||
source = { editable = "." }
|
source = { editable = "." }
|
||||||
dependencies = [
|
dependencies = [
|
||||||
{ name = "aiopath" },
|
{ name = "aiopath" },
|
||||||
|
@ -548,6 +548,7 @@ dependencies = [
|
||||||
{ name = "fastapi" },
|
{ name = "fastapi" },
|
||||||
{ name = "geoalchemy2" },
|
{ name = "geoalchemy2" },
|
||||||
{ name = "geopandas" },
|
{ name = "geopandas" },
|
||||||
|
{ name = "httpx" },
|
||||||
{ name = "itsdangerous" },
|
{ name = "itsdangerous" },
|
||||||
{ name = "matplotlib" },
|
{ name = "matplotlib" },
|
||||||
{ name = "orjson" },
|
{ name = "orjson" },
|
||||||
|
@ -586,7 +587,6 @@ mqtt = [
|
||||||
[package.dev-dependencies]
|
[package.dev-dependencies]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "asyncpg-stubs" },
|
{ name = "asyncpg-stubs" },
|
||||||
{ name = "httpx" },
|
|
||||||
{ name = "ipdb" },
|
{ name = "ipdb" },
|
||||||
{ name = "pandas-stubs" },
|
{ name = "pandas-stubs" },
|
||||||
{ name = "pretty-errors" },
|
{ name = "pretty-errors" },
|
||||||
|
@ -610,6 +610,7 @@ requires-dist = [
|
||||||
{ name = "geopandas", specifier = ">=1.0.1" },
|
{ name = "geopandas", specifier = ">=1.0.1" },
|
||||||
{ name = "gisaf-backend", extras = ["contextily"], marker = "extra == 'all'" },
|
{ name = "gisaf-backend", extras = ["contextily"], marker = "extra == 'all'" },
|
||||||
{ name = "gisaf-backend", extras = ["mqtt"], marker = "extra == 'all'" },
|
{ name = "gisaf-backend", extras = ["mqtt"], marker = "extra == 'all'" },
|
||||||
|
{ name = "httpx", specifier = ">=0.28.1" },
|
||||||
{ name = "itsdangerous", specifier = ">=2.1.2" },
|
{ name = "itsdangerous", specifier = ">=2.1.2" },
|
||||||
{ name = "matplotlib", specifier = ">=3.8.3" },
|
{ name = "matplotlib", specifier = ">=3.8.3" },
|
||||||
{ name = "orjson", specifier = ">=3.9.10" },
|
{ name = "orjson", specifier = ">=3.9.10" },
|
||||||
|
@ -636,7 +637,6 @@ requires-dist = [
|
||||||
[package.metadata.requires-dev]
|
[package.metadata.requires-dev]
|
||||||
dev = [
|
dev = [
|
||||||
{ name = "asyncpg-stubs", specifier = ">=0.29.1" },
|
{ name = "asyncpg-stubs", specifier = ">=0.29.1" },
|
||||||
{ name = "httpx", specifier = ">=0.28.1" },
|
|
||||||
{ name = "ipdb", specifier = ">=0.13.13" },
|
{ name = "ipdb", specifier = ">=0.13.13" },
|
||||||
{ name = "pandas-stubs", specifier = ">=2.1.4.231218" },
|
{ name = "pandas-stubs", specifier = ">=2.1.4.231218" },
|
||||||
{ name = "pretty-errors", specifier = ">=1.2.25" },
|
{ name = "pretty-errors", specifier = ">=1.2.25" },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue