From 5d5f1424db9e918db1b0542bc71a596d5bb5db71 Mon Sep 17 00:00:00 2001 From: rrr-marble Date: Tue, 6 Feb 2024 03:55:12 +0000 Subject: [PATCH] add: file upload --- app/geojson2vt.py | 43 +++++++++++++++++++++++++++++++++++++++++++ app/main.py | 29 ++++++++++++++++++++++++++++- geojson2vt.py | 37 ------------------------------------- poetry.lock | 16 +++++++++++++++- pyproject.toml | 1 + 5 files changed, 87 insertions(+), 39 deletions(-) create mode 100644 app/geojson2vt.py delete mode 100644 geojson2vt.py diff --git a/app/geojson2vt.py b/app/geojson2vt.py new file mode 100644 index 0000000..d3c718d --- /dev/null +++ b/app/geojson2vt.py @@ -0,0 +1,43 @@ +import uuid +import subprocess +import shutil +from pathlib import Path +import json + +def geojson2vt(uploaded_geojson, storage_path = None) -> str: + """Convert geojson file to vector tiles + + Args: + uploaded_geojson: GeoJSON file uploaded by user + + Returns: + str: vector tiles id + """ + storage_path = storage_path or "" + # save the uploaded file + # get a path to the saved geojson + geojson_uuid = uuid.uuid4().hex + uploaded_geojson_path = Path(storage_path, "geojsons", geojson_uuid + ".geojson") + with open(uploaded_geojson_path, mode="xb") as geojson_file: + shutil.copyfileobj(uploaded_geojson.file, geojson_file) + vector_tiles_path = Path(storage_path, "vector_tiles", geojson_uuid) + tippecanoe_command = f"tippecanoe --maximum-zoom=g --output-to-directory={vector_tiles_path} --drop-densest-as-needed --no-tile-compression {uploaded_geojson_path}" + subprocess.run(tippecanoe_command, shell=True, check=True) # https://stackoverflow.com/a/51950538/14742462 + metadata_path = Path(vector_tiles_path, "metadata.json") + with open(metadata_path, "r") as metadata_file: + metadata = json.load(metadata_file) + + with open("catalog.json", "r") as catalog_file: + catalog = json.load(catalog_file) + catalog.append(metadata) + + with open("catalog.json", "w") as catalog_file: + json.dump(catalog, catalog_file, ensure_ascii=False) + return vector_tiles_id + +if __name__ == "__main__": + geojson2vt("ert") + + + + diff --git a/app/main.py b/app/main.py index aaf8d50..f3cf55d 100644 --- a/app/main.py +++ b/app/main.py @@ -1,7 +1,34 @@ -from fastapi import FastAPI +import os +from pathlib import Path + +from fastapi import Depends, FastAPI, UploadFile + +from .geojson2vt import geojson2vt + +#prepare data storage +def set_storage(): + storage_path = os.environ.get("STATE_DIRECTORY") + if storage_path: + try: + os.mkdir(Path(storage_path, "geojsons")) + except FileExistsError: + pass + try: + os.mkdir(Path(storage_path, "vector_tiles")) + except FileExistsError: + pass + return storage_path + +STORAGE_PATH = set_storage() app = FastAPI() + @app.get("/") async def root(): return {"message": "Hello World!"} + +@app.post("/upload/") +async def create_upload_file(file: UploadFile): + geojson2vt(file, storage_path=STORAGE_PATH) + return {"filename": file.filename} diff --git a/geojson2vt.py b/geojson2vt.py deleted file mode 100644 index 1bb5ee8..0000000 --- a/geojson2vt.py +++ /dev/null @@ -1,37 +0,0 @@ -import uuid -import subprocess -from pathlib import Path -import json - -def geojson2vt(uploaded_geojson) -> str: - """Convert geojson file to vector tiles - - Args: - uploaded_geojson: GeoJSON file uploaded by user - - Returns: - str: vector tiles id - """ - # save the uploaded file - # get a path to the saved geojson - uploaded_geojson_path = "land.geojson" # replace value with the path to the saved geojson - vector_tiles_id = uploaded_geojson_path + uuid.uuid4().hex - tippecanoe_command = f"tippecanoe --maximum-zoom=g --output-to-directory={vector_tiles_id} --drop-densest-as-needed --no-tile-compression {uploaded_geojson_path}" - subprocess.run(tippecanoe_command, shell=True) # https://stackoverflow.com/a/51950538/14742462 - metadata_path = Path(vector_tiles_id, "metadata.json") - with open(metadata_path, "r") as metadata_file: - metadata = json.load(metadata_file) - - with open("catalog.json", "r") as catalog_file: - catalog = json.load(catalog_file) - catalog.append(metadata) - - with open("catalog.json", "w") as catalog_file: - json.dump(catalog, catalog_file, ensure_ascii=False) - return vector_tiles_id - -geojson2vt("ert") - - - - diff --git a/poetry.lock b/poetry.lock index 451e3dd..7d0c172 100644 --- a/poetry.lock +++ b/poetry.lock @@ -207,6 +207,20 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "python-multipart" +version = "0.0.7" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python_multipart-0.0.7-py3-none-any.whl", hash = "sha256:b1fef9a53b74c795e2347daac8c54b252d9e0df9c619712691c1cc8021bd3c49"}, + {file = "python_multipart-0.0.7.tar.gz", hash = "sha256:288a6c39b06596c1b988bb6794c6fbc80e6c369e35e5062637df256bee0c9af9"}, +] + +[package.extras] +dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==2.2.0)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] + [[package]] name = "sniffio" version = "1.3.0" @@ -267,4 +281,4 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "f3bcc47b9274ec536168a19385d173378d272e74220e966aef2a34eca1e7c5ee" +content-hash = "ea9a5187e026efd84d1eaf25926de037c113f142e23f98d44c342a5aea7ff900" diff --git a/pyproject.toml b/pyproject.toml index d4437ef..cdc8b7f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,6 +10,7 @@ readme = "README.md" python = "^3.11" fastapi = "^0.109.2" uvicorn = "^0.27.0.post1" +python-multipart = "^0.0.7" [build-system]