Skip to content

Commit

Permalink
Add heatmaps to upload processing outputs
Browse files Browse the repository at this point in the history
  • Loading branch information
mhhd2020 committed Jul 12, 2023
1 parent 52440d9 commit c9953b2
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 8 deletions.
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ qrcode = "^7.3.1"
svglib = "^1.4.1"
PyMuPDF = {extras = ["Pillow"], version = "^1.21.0"}
psycopg2 = "^2.9.5"
geopandas = "^0.13.2"
# these dependencies are maintained by your local setup and have to be fixed for now, since poetry and (py)gdal packages can't work together
# if you change these versions, please change them in development-setup.md, Dockerfile and .github/workflows/python.yml as well
#numpy = "1.23.5"
Expand Down
4 changes: 3 additions & 1 deletion sketch_map_tool/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ def digitize_results_post() -> Response:
uuids = [args_["uuid"] for args_ in args]
bboxes = [args_["bbox"] for args_ in args]
map_frames = dict()
map_frame_buffer = BytesIO()
for uuid in set(uuids): # Only retrieve map_frame once per uuid to save memory
map_frame_buffer = BytesIO(db_client_flask.select_map_frame(UUID(uuid)))
map_frames[uuid] = to_array(map_frame_buffer.read())
Expand All @@ -130,8 +131,9 @@ def digitize_results_post() -> Response:
digitize_sketches.s(ids, file_names, uuids, map_frames, bboxes).apply_async().id
)

map_frame_buffer.seek(0)
result_id_3 = (
analyse_markings.s(ids, file_names, uuids, map_frames, bboxes).apply_async().id
analyse_markings.s(ids, file_names, uuids, map_frames, bboxes, map_frame_buffer).apply_async().id
)
# Unique id for current request
uuid = str(uuid4())
Expand Down
32 changes: 31 additions & 1 deletion sketch_map_tool/tasks.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from io import BytesIO
from typing import List, Tuple
from uuid import UUID
from zipfile import ZipFile

Expand All @@ -7,6 +8,7 @@
from celery.signals import worker_process_init, worker_process_shutdown
from geojson import FeatureCollection
from numpy.typing import NDArray
from tempfile import NamedTemporaryFile

from sketch_map_tool import celery_app as celery
from sketch_map_tool import map_generation
Expand All @@ -26,6 +28,7 @@
polygonize,
prepare_img_for_markings,
create_qgis_project,
generate_heatmap,
)
from sketch_map_tool.wms import client as wms_client

Expand Down Expand Up @@ -169,7 +172,12 @@ def analyse_markings(
uuids: list[str],
map_frames: dict[str, NDArray],
bboxes: list[Bbox],
map_frame_template: BytesIO
) -> AsyncResult | FeatureCollection:
if len(set(bboxes)) != 1:
raise ValueError("Because the map frame is used as background for the heatmap, this process only works "
"when uploading sketch maps covering exactly the same area.")

def process(
sketch_map_id: int, name: str, uuid: str, bbox: Bbox
) -> FeatureCollection:
Expand All @@ -190,9 +198,31 @@ def process(
geojsons.append(r_)
return merge(geojsons)

return create_qgis_project(BytesIO(geojson.dumps(merge(
def zip_(qgis_project: BytesIO, heatmaps: List[Tuple[str, BytesIO]]) -> BytesIO:
buffer = BytesIO()
with ZipFile(buffer, "w") as zip_file:
zip_file.writestr(f"qgis_project.zip", qgis_project.read())
for colour, heatmap in heatmaps:
zip_file.writestr(f"heatmap_{colour}.jpg", heatmap.read())
buffer.seek(0)
return buffer

qgis_project, overlaps = create_qgis_project(BytesIO(geojson.dumps(merge(
[
process(file_id, name, uuid, bbox)
for file_id, name, uuid, bbox in zip(file_ids, file_names, uuids, bboxes)
]
)).encode("utf-8")))
geojson_overlaps_file = NamedTemporaryFile(suffix=".geojson")
map_frame_template_file = NamedTemporaryFile(suffix=".jpg")
with open(geojson_overlaps_file.name, "wb") as fw:
fw.write(overlaps.read())
with open(map_frame_template_file.name, "wb") as fw:
fw.write(map_frame_template.read())
return zip_(qgis_project, generate_heatmap(
geojson_overlaps_file.name,
bboxes[0].lon_min,
bboxes[0].lat_min,
bboxes[0].lon_max,
bboxes[0].lat_max,
map_frame_template_file.name))
5 changes: 3 additions & 2 deletions sketch_map_tool/upload_processing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from .merge import merge
from .polygonize import polygonize
from .qr_code_reader import read as read_qr_code
from .count_overlaps import create_qgis_project
from .count_overlaps import create_qgis_project, generate_heatmap

__all__ = (
"enrich",
Expand All @@ -18,5 +18,6 @@
"read_qr_code",
"polygonize",
"merge",
"create_qgis_project"
"create_qgis_project",
"generate_heatmap",
)
14 changes: 10 additions & 4 deletions sketch_map_tool/upload_processing/count_overlaps.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from io import BytesIO
from tempfile import NamedTemporaryFile
from typing import List, Tuple

from qgis.core import (QgsProject, QgsVectorLayer, QgsCoordinateReferenceSystem, QgsApplication,
QgsProcessingFeatureSourceDefinition, QgsProcessingFeedback)
from zipfile import ZipFile
Expand Down Expand Up @@ -49,14 +51,18 @@ def create_qgis_project(markings: BytesIO):
project.addMapLayer(layer_result)
outfile = NamedTemporaryFile(suffix=".qgs")
project.write(outfile.name)
buffer = BytesIO()
with (ZipFile(buffer, "w") as zip_file, open(infile.name, "rb") as f_markings, open(outfile.name, "rb") as f_qgis,
buffer_project = BytesIO()
buffer_overlaps = BytesIO()
with (ZipFile(buffer_project, "w") as zip_file, open(infile.name, "rb") as f_markings, open(outfile.name, "rb") as f_qgis,
open(result_file.name, "rb") as f_result):
zip_file.writestr(infile.name.replace("tmp/", "./"), f_markings.read())
zip_file.writestr(result_file.name.replace("tmp/", "./"), f_result.read())
zip_file.writestr(f"project.qgs", f_qgis.read())
buffer.seek(0)
return buffer
f_result.seek(0)
buffer_overlaps.write(f_result.read())
buffer_project.seek(0)
buffer_overlaps.seek(0)
return buffer_project, buffer_overlaps


def generate_heatmap(geojson_path, lon_min, lat_min, lon_max, lat_max, bg_img_path) -> List[Tuple[str, BytesIO]]:
Expand Down

0 comments on commit c9953b2

Please sign in to comment.