Restructure api
Fixes in geo api, registry Cleanups
This commit is contained in:
parent
c84dd61f6a
commit
8c299f0041
17 changed files with 212 additions and 162 deletions
|
@ -27,7 +27,7 @@ class UserBase(SQLModel):
|
|||
|
||||
class User(UserBase, table=True):
|
||||
__table_args__ = gisaf_admin.table_args
|
||||
id: int | None = Field(default=None, primary_key=True)
|
||||
id: str | None = Field(default=None, primary_key=True)
|
||||
roles: list["Role"] = Relationship(back_populates="users",
|
||||
link_model=UserRoleLink)
|
||||
password: str | None = None
|
||||
|
|
|
@ -61,8 +61,8 @@ class CategoryBase(BaseModel):
|
|||
style: str | None = Field(sa_type=TEXT)
|
||||
symbol: str | None = Field(sa_type=String(1)) # type: ignore
|
||||
mapbox_type_custom: str | None = Field(sa_type=String(12)) # type: ignore
|
||||
mapbox_paint: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
mapbox_layout: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
mapbox_paint: dict[str, dict | list | float | int | str] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
mapbox_layout: dict[str, dict | list | float | int | str] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
viewable_role: str | None
|
||||
extra: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
|
||||
|
|
|
@ -14,20 +14,20 @@ import shapely # type: ignore
|
|||
import pyproj
|
||||
|
||||
from pydantic import BaseModel
|
||||
from sqlmodel import select, Field, Relationship
|
||||
from sqlmodel import select, Field
|
||||
from sqlmodel.ext.asyncio.session import AsyncSession
|
||||
from sqlalchemy import BigInteger, MetaData, String, func, and_, text
|
||||
from sqlalchemy import BigInteger, String, func, and_, text
|
||||
from sqlalchemy.sql import sqltypes
|
||||
from sqlalchemy.orm import declared_attr
|
||||
from psycopg2.extensions import adapt
|
||||
from geoalchemy2.shape import from_shape
|
||||
from geoalchemy2.types import Geometry, WKBElement
|
||||
from shapely import wkb, from_wkb
|
||||
from shapely.geometry import mapping
|
||||
from shapely.geometry import mapping # type: ignore
|
||||
from shapely.ops import transform # type: ignore
|
||||
|
||||
from shapefile import (
|
||||
Writer as ShapeFileWriter, # type: ignore
|
||||
from shapefile import ( # type: ignore
|
||||
Writer as ShapeFileWriter,
|
||||
POINT, POINTZ,
|
||||
POLYLINE, POLYLINEZ,
|
||||
POLYGON, POLYGONZ,
|
||||
|
@ -35,8 +35,9 @@ from shapefile import (
|
|||
|
||||
from gisaf.database import db_session
|
||||
from gisaf.config import conf
|
||||
from gisaf.models.map_bases import MaplibreStyle
|
||||
from gisaf.models.models_base import Model
|
||||
from gisaf.models.metadata import gisaf_survey, gisaf_admin, survey
|
||||
from gisaf.models.metadata import gisaf_survey, gisaf_admin, survey, raw_survey
|
||||
from gisaf.models.misc import Qml
|
||||
from gisaf.models.category import Category
|
||||
from gisaf.models.to_migrate import InfoItem
|
||||
|
@ -157,6 +158,7 @@ class SurveyModel(BaseSurveyModel):
|
|||
# status: str = Field(sa_type=String(1))
|
||||
|
||||
get_gdf_with_related: ClassVar[bool] = False
|
||||
category_name: ClassVar[str]
|
||||
|
||||
filtered_columns_on_map: ClassVar[list[str]] = [
|
||||
'equip_id',
|
||||
|
@ -219,9 +221,8 @@ class SurveyModel(BaseSurveyModel):
|
|||
|
||||
@classmethod
|
||||
async def get_geojson(cls,
|
||||
registry=None, simplify_tolerance=0, preserve_topology=False):
|
||||
if registry is None:
|
||||
from ..registry import registry
|
||||
simplify_tolerance=0, preserve_topology=False):
|
||||
from gisaf.registry import registry
|
||||
|
||||
## Fastest, but the id is in properties and needs the front end (eg Gisaf for mapbox)
|
||||
## to move it at the feature level
|
||||
|
@ -592,36 +593,35 @@ class GeoModelNoStatus(Model):
|
|||
return zip_file
|
||||
|
||||
@classmethod
|
||||
async def get_mapbox_style(cls):
|
||||
async def get_maplibre_style(cls) -> MaplibreStyle | None:
|
||||
"""
|
||||
Get the mapbox style (paint, layout, attribution...)
|
||||
"""
|
||||
## If the model is from survey, it should have a category, which has a style
|
||||
## Get from database
|
||||
style = {}
|
||||
if hasattr(cls, 'category'):
|
||||
category = await Category.get_item_by_pk(pk=cls.category.name)
|
||||
if category:
|
||||
if category['mapbox_paint'] is not None:
|
||||
style['paint'] = category['mapbox_paint']
|
||||
if category['mapbox_layout'] is not None:
|
||||
style['layout'] = category['mapbox_layout']
|
||||
|
||||
else:
|
||||
category = None
|
||||
|
||||
qml = await Qml.get_item_by_pk(pk=cls.__name__)
|
||||
if qml:
|
||||
if qml['mapbox_paint']:
|
||||
style['paint'] = qml['mapbox_paint']
|
||||
if qml['mapbox_layout']:
|
||||
style['layout'] = qml['mapbox_layout']
|
||||
|
||||
if cls.attribution is not None:
|
||||
style['attribution'] = cls.attribution
|
||||
style: MaplibreStyle | None
|
||||
async with db_session() as session:
|
||||
if hasattr(cls, 'category'):
|
||||
category = await session.get(Category, cls.get_store_name())
|
||||
if category:
|
||||
style = MaplibreStyle(
|
||||
layout=category.mapbox_layout,
|
||||
paint=category.mapbox_paint,
|
||||
)
|
||||
else:
|
||||
style = None
|
||||
else:
|
||||
qml = await session.get(Qml, cls.__name__)
|
||||
if qml:
|
||||
style = MaplibreStyle(
|
||||
layout=qml.mapbox_layout,
|
||||
paint=qml.mapbox_paint,
|
||||
attribution=qml.attr,
|
||||
)
|
||||
else:
|
||||
style = None
|
||||
return style
|
||||
|
||||
|
||||
@classmethod
|
||||
async def get_features_attrs(cls, simplify_tolerance):
|
||||
"""
|
||||
|
@ -1094,10 +1094,13 @@ class RawSurveyBaseModel(BaseSurveyModel, GeoPointModelNoStatus):
|
|||
"""
|
||||
Abstract base class for category based raw survey point models
|
||||
"""
|
||||
# metadata: ClassVar[MetaData] = raw_survey
|
||||
geom: Annotated[str, WKBElement] = Field(sa_type=Geometry('POINTZ', dimension=3,
|
||||
srid=conf.geo.raw_survey.srid))
|
||||
status: str = Field(sa_type=String(1))
|
||||
__table_args__ = raw_survey.table_args
|
||||
geom: Annotated[str, WKBElement] = Field(
|
||||
sa_type=Geometry('POINTZ',
|
||||
dimension=3,
|
||||
srid=conf.geo.raw_survey.srid),
|
||||
) # type: ignore
|
||||
status: str = Field(sa_type=String(1)) # type: ignore
|
||||
|
||||
## store_name is set in category_models_maker.make_category_models
|
||||
store_name: ClassVar[str | None] = None
|
||||
|
|
|
@ -28,30 +28,6 @@ class BaseStyle(Model, table=True):
|
|||
return f'<models.BaseStyle {self.name:s}>'
|
||||
|
||||
|
||||
class BaseMap(Model, table=True):
|
||||
__table_args__ = gisaf_map.table_args
|
||||
__tablename__: str = 'base_map' # type: ignore
|
||||
|
||||
class Admin:
|
||||
menu = 'Other'
|
||||
|
||||
id: int | None = Field(primary_key=True, default=None)
|
||||
name: str
|
||||
layers: list['BaseMapLayer'] = Relationship(back_populates='base_map')
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<models.BaseMap {self.name:s}>'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
@classmethod
|
||||
def selectinload(cls) -> list[list['BaseMapLayer']]:
|
||||
return [
|
||||
cls.layers
|
||||
]
|
||||
|
||||
|
||||
class BaseMapLayer(Model, table=True):
|
||||
__table_args__ = gisaf_map.table_args
|
||||
__tablename__: str = 'base_map_layer' # type: ignore
|
||||
|
@ -62,7 +38,7 @@ class BaseMapLayer(Model, table=True):
|
|||
id: int | None = Field(primary_key=True, default=None)
|
||||
base_map_id: int = Field(foreign_key=gisaf_map.table('base_map.id'),
|
||||
index=True)
|
||||
base_map: BaseMap = Relationship(back_populates='layers')
|
||||
base_map: 'BaseMap' = Relationship() #back_populates='layers')
|
||||
store: str = Field(sa_type=String(100)) # type: ignore
|
||||
|
||||
@classmethod
|
||||
|
@ -78,8 +54,46 @@ class BaseMapLayer(Model, table=True):
|
|||
return f"{self.store or '':s}"
|
||||
|
||||
|
||||
class BaseMap(Model, table=True):
|
||||
__table_args__ = gisaf_map.table_args
|
||||
__tablename__: str = 'base_map' # type: ignore
|
||||
|
||||
class Admin:
|
||||
menu = 'Other'
|
||||
|
||||
id: int | None = Field(primary_key=True, default=None)
|
||||
name: str
|
||||
# layers: list['BaseMapLayer'] = Relationship(
|
||||
# back_populates='base_map',
|
||||
# # link_model=BaseMapLayer
|
||||
# )
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f'<models.BaseMap {self.name:s}>'
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
# @classmethod
|
||||
# def selectinload(cls) -> list[list[BaseMapLayer]]:
|
||||
# return [
|
||||
# cls.layers
|
||||
# ]
|
||||
|
||||
|
||||
class BaseMapWithStores(BaseModel):
|
||||
name: str
|
||||
stores: list[str]
|
||||
|
||||
|
||||
class MapInitData(BaseModel):
|
||||
baseStyles: list[BaseStyle] = []
|
||||
baseMaps: list[BaseMap] = []
|
||||
baseMaps: list[BaseMapWithStores] = []
|
||||
groups: list[CategoryGroup] = []
|
||||
stores: list[Store] = []
|
||||
stores: list[Store] = []
|
||||
|
||||
|
||||
class MaplibreStyle(BaseModel):
|
||||
paint: dict[str, dict | list | float | int | str] | None = None
|
||||
layout: dict[str, dict | list | float | int | str] | None = None
|
||||
attribution: str | None = None
|
|
@ -14,11 +14,11 @@ class NotADataframeError(Exception):
|
|||
pass
|
||||
|
||||
|
||||
class Qml(Model):
|
||||
class Qml(Model, table=True):
|
||||
"""
|
||||
Model for storing qml (QGis style)
|
||||
"""
|
||||
model_config = ConfigDict(protected_namespaces=())
|
||||
model_config = ConfigDict(protected_namespaces=()) # type: ignore
|
||||
__table_args__ = gisaf_map.table_args
|
||||
|
||||
class Admin:
|
||||
|
@ -26,11 +26,11 @@ class Qml(Model):
|
|||
flask_admin_model_view = 'QmlModelView'
|
||||
|
||||
model_name: str | None = Field(default=None, primary_key=True)
|
||||
qml: str
|
||||
attr: str
|
||||
style: str
|
||||
mapbox_paint: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True))
|
||||
mapbox_layout: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True))
|
||||
qml: str | None = None
|
||||
attr: str | None = None
|
||||
style: str | None = None
|
||||
mapbox_paint: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
mapbox_layout: dict[str, Any] | None = Field(sa_type=JSON(none_as_null=True)) # type: ignore
|
||||
|
||||
def __repr__(self):
|
||||
return '<models.Qml {self.model_name:s}>'.format(self=self)
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
from typing import Any
|
||||
from pydantic import BaseModel
|
||||
from gisaf.models.geo_models_base import GeoModel, RawSurveyBaseModel, GeoPointSurveyModel
|
||||
|
||||
|
||||
class MapLibreStyle(BaseModel):
|
||||
...
|
||||
|
||||
|
||||
class StoreNameOnly(BaseModel):
|
||||
|
@ -12,6 +6,7 @@ class StoreNameOnly(BaseModel):
|
|||
|
||||
|
||||
class Store(StoreNameOnly):
|
||||
category: str | None = None
|
||||
auto_import: bool
|
||||
# base_gis_type: str
|
||||
count: int | None = None
|
||||
|
@ -39,7 +34,6 @@ class Store(StoreNameOnly):
|
|||
#raw_model: GeoPointSurveyModel
|
||||
#raw_model_store_name: str
|
||||
status: str
|
||||
store: str
|
||||
style: str | None
|
||||
symbol: str | None
|
||||
title: str
|
||||
|
|
|
@ -73,11 +73,3 @@ class FeatureInfo(BaseModel):
|
|||
files: list[Attachment] = []
|
||||
images: list[Attachment] = []
|
||||
externalRecordUrl: str | None = None
|
||||
|
||||
|
||||
class MapboxPaint(BaseModel):
|
||||
...
|
||||
|
||||
|
||||
class MapboxLayout(BaseModel):
|
||||
...
|
Loading…
Add table
Add a link
Reference in a new issue