2

I am processing a raster image inside my Django app. From a GeoTIFF file I am converting it to a COG. I am using gdal.Translate for the operation. I want to save the processed image without saving it locally. I want to use the GDAL dataset to read its bytes and be saved in a Django model's file field.

But suppose in this example, I am opening a dataset using gdal.Open. How can I save that to FileField?

from django.core.files.base import ContentFile
from django.db.models.fields.files import FileField
import osgeo
from osgeo import gdal

dataset = gdal.Open('/path/to/dataset.tif')
data_bytes = dataset.ReadAsArray().tobytes()

file_field = FileField()
file_field.save('dataset.tif', content_file, save=False)

model_instance = MyModel(file_field=file_field)
model_instance.save()

I am using GDAL 3.2.2.1 due to some constraints. Does function ReadAsArray not available in the version?

ModuleNotFoundError: No module named 'osgeo._gdal_array'

How can I do this correctly?

1 Answer 1

1

You can save the file to the expected destination with GDAL and just update the model.

With the storage attribute of the FileField you can get the expected path.


output_raster_name = "my_raster.tif"

# If you don't have an instance at this point just create a fake one
# my_model = MyModel()
my_model = MyModel.objects.get(pk=my_pk)

# This returns an absolute path taking into accound settings.MEDIA_ROOT
# and upload_to
output_raster = my_model.file_field.storage.path(name=output_raster_name)


dataset = gdal.Open("/path/to/dataset.tif")
warp = gdal.Warp(output_raster, dataset, dstSRS="EPSG:4326")
warp = None # Closes the files

If you are not using FileSysteStorage probably you can use more or less the same trick using GDAL Virtual File Systems, but i don't have experience doing it.

Also I think that gdal_array module should be present in your GDAL version so this shoud work:

from osgeo import gdal_array

# dataset_numpyarray = gdal_array.LoadFile("/path/to/dataset.tif")
# or

dataset = gdal.Open("/path/to/dataset.tif")
data_bytes = gdal_array.DatasetReadAsArray(dataset).tobytes()
2
  • This is tricky. What if I am using a cloud storage such as S3 or Google Cloud?
    – Nikko
    Commented Apr 10, 2023 at 4:55
  • Hi! I was able to write the file. However, the model object does not reference the file_field to that saved file/location. Am I missing something? Of course I saved i.e. my_model.save()
    – Nikko
    Commented May 19, 2023 at 15:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.