Skip to content

Commit

Permalink
feat(backend): generate backmaps on project creation
Browse files Browse the repository at this point in the history
  • Loading branch information
spwoodcock committed Jan 17, 2024
1 parent 7668117 commit 214da39
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 5 deletions.
68 changes: 63 additions & 5 deletions src/backend/app/projects/project_crud.py
Original file line number Diff line number Diff line change
Expand Up @@ -2101,22 +2101,79 @@ async def get_extracted_data_from_db(db: Session, project_id: int, outfile: str)


# NOTE defined as non-async to run in separate thread
def get_project_tiles(
def init_project_basemaps(
db: Session,
project_id: int,
background_task_id: uuid.UUID,
source: str,
) -> None:
"""Init basemaps for the project and task areas.
A PMTiles archive is created for the entire project, plus
individual mbtile archives for each task area.
Args:
db (Session): SQLAlchemy db session.
project_id (int): Associated project ID.
background_task_id (uuid.UUID): Pre-generated background task ID.
source (str): Source to use for basemap tiles.
Returns:
None
"""
# Generate PMTiles for project area
generate_project_or_task_basemap(
db,
project_id,
background_task_id,
source,
output_format="pmtiles",
)

# Generate MBTiles for each task
get_tasks_async = async_to_sync(tasks_crud.get_task_id_list)
task_list = get_tasks_async(db, project_id)

# TODO optimise to run with threadpool
for task_id in task_list:
generate_project_or_task_basemap(
db,
project_id,
background_task_id,
source,
output_format="mbtiles",
task_id=task_id,
)


# NOTE defined as non-async to run in separate thread
def generate_project_or_task_basemap(
db: Session,
project_id: int,
background_task_id: uuid.UUID,
source: str,
source: str = "esri",
output_format: str = "pmtiles",
tms: str = None,
task_id: int = None,
):
"""For a given project or task area, generate a basemap."""
) -> None:
"""For a given project or task area, generate a basemap.
Wrapper that extracts the project or task bbox prior to calling
generate_basemap_for_bbox function.
Args:
db (Session): SQLAlchemy db session.
project_id (int): ID of project to create tiles for.
background_task_id (uuid.UUID): UUID of background task to track.
source (str): Tile source ("esri", "bing", "topo", "google", "oam").
output_format (str, optional): Default "mbtiles".
Other options: "pmtiles", "sqlite3".
tms (str, optional): Default None. Custom TMS provider URL.
task_id (bool): If set, create for a task boundary only.
Returns:
None
"""
if not task_id:
# Project Outline
log.debug(f"Getting bbox for project: {project_id}")
Expand Down Expand Up @@ -2163,11 +2220,12 @@ def generate_basemap_for_bbox(
tms: str = None,
task_id: int = None,
):
"""Get basemap tiles for a project.
"""Get basemap tiles for a given bounding box.
Args:
db (Session): SQLAlchemy db session.
project_id (int): ID of project to create tiles for.
bbox (tuple): the bounding box for generate for.
background_task_id (uuid.UUID): UUID of background task to track.
source (str): Tile source ("esri", "bing", "topo", "google", "oam").
output_format (str, optional): Default "mbtiles".
Expand Down
36 changes: 36 additions & 0 deletions src/backend/app/projects/project_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,42 @@ async def generate_project_tiles(
return JSONResponse(status_code=200, content={"success": True})


@router.get("/tiles/{project_id}/init")
async def init_project_tiles(
background_tasks: BackgroundTasks,
project_id: int,
source: str = Query(
..., description="Select a source for tiles", enum=TILES_SOURCE
),
db: Session = Depends(database.get_db),
):
"""Init all basemaps for a project, optional on project creation.
Args:
project_id (int): ID of project to create tiles for.
source (str): Tile source ("esri", "bing", "topo", "google", "oam").
Returns:
dict: Success message that tile generation started.
"""
# Create task in db and return uuid
log.debug(
f"Creating init_project_tiles background task for project ID: {project_id}"
)
background_task_id = await project_crud.insert_background_task_into_database(
db, name="init tiles", project_id=project_id
)

background_tasks.add_task(
project_crud.init_project_basemaps,
db,
project_id,
background_task_id,
source,
)

return JSONResponse(status_code=200, content={"success": True})


@router.get("/tiles_list/{project_id}/")
async def tiles_list(project_id: int, db: Session = Depends(database.get_db)):
Expand Down

0 comments on commit 214da39

Please sign in to comment.