Fix/update geo layer export

This commit is contained in:
phil 2024-04-28 01:10:41 +02:00
parent 53c2e359da
commit ccf6710225
5 changed files with 232 additions and 11 deletions

View file

@ -16,6 +16,7 @@ from gisaf.security import (
from gisaf.models.authentication import (User, UserRead, Role, RoleRead)
from gisaf.registry import registry, NotInRegistry
from gisaf.plugins import DownloadResponse, manager as plugin_manager
from gisaf.exporters import export_with_fiona, export_with_pyshp
logger = logging.getLogger(__name__)
@ -80,6 +81,87 @@ async def download_csv(
return response
@api.get('/geodata/{stores}')
async def download_geodata(
user: Annotated[UserRead, Depends(get_current_active_user)],
stores: str,
format: str = 'gpkg',
reproject: bool = False,
) -> Response:
## Check permissions
try:
layers_registry = registry.stores.loc[stores.split(',')]
except KeyError:
## Empty dataframe
layers_registry = registry.stores[0:0]
live_stores = [
layer for layer in stores.split(',')
if layer.startswith('live:')
]
def _check_permission(model):
if not hasattr(model, 'downloadable_role'):
return True
if user is None:
return False
return user.has_role(model.downloadable_role)
stores_allowed: list[str] = [
c[0] for c in layers_registry.model.items()
if _check_permission(c[1])
] # type: ignore
store_names = ','.join(stores_allowed + live_stores)
if len(store_names) == 0:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
formats = {
'gpkg': (
export_with_fiona, {
'extension': 'gpkg',
'driver': 'GPKG',
'mimetype': 'application/geopackage+vnd.sqlite3',
}
),
'dxf': (
export_with_fiona, {
'extension': 'dxf',
'driver': 'DXF',
'mimetype': 'application/x-dxf',
'filter_columns': ['geom'],
}
),
'shapefile': (
## Fiona/ogr has several limitations for writing shapefiles (eg. dbf, shx not supported): use export_with_pyshp
#export_with_fiona, {
# 'extension': 'shp',
# 'driver': 'ESRI Shapefile',
# 'mimetype': 'application/octet-stream',
#}
export_with_pyshp, {}
),
}
if format not in formats:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
detail=f"{format} not in known formats: {', '.join(formats.keys())}")
fn, kwargs = formats[format]
if reproject and reproject not in ['false', '0', 'no']:
kwargs['reproject'] = True
body, filename, content_type = await fn(store_names=store_names, **kwargs)
headers = {
'Content-Disposition': f'attachment; filename="{filename}"'
}
return Response(
body,
headers=headers,
media_type=content_type,
)
@api.get('/plugin/{name}/{store}/{id}')
async def execute_action(
name: str,