Fix/update geo layer export
This commit is contained in:
parent
53c2e359da
commit
ccf6710225
5 changed files with 232 additions and 11 deletions
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue