kopia lustrzana https://github.com/OpenDroneMap/WebODM
Added OffDbRasterField, changed orthophoto type from RasterField to OffDbRasterField
rodzic
dcdf69feb9
commit
5c54aca9c1
|
@ -4,7 +4,6 @@ import shutil
|
|||
import zipfile
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.gis.db import models as gismodels
|
||||
from django.contrib.gis.gdal import GDALRaster
|
||||
from django.contrib.postgres import fields
|
||||
from django.core.exceptions import ValidationError
|
||||
|
@ -18,6 +17,7 @@ from guardian.models import UserObjectPermissionBase
|
|||
from guardian.shortcuts import get_perms_for_model, assign_perm
|
||||
|
||||
from app import pending_actions
|
||||
from app.postgis import OffDbRasterField
|
||||
from nodeodm import status_codes
|
||||
from nodeodm.exceptions import ProcessingException
|
||||
from nodeodm.models import ProcessingNode
|
||||
|
@ -139,7 +139,7 @@ class Task(models.Model):
|
|||
ground_control_points = models.FileField(null=True, blank=True, upload_to=gcp_directory_path, help_text="Optional Ground Control Points file to use for processing")
|
||||
|
||||
# georeferenced_model
|
||||
orthophoto = gismodels.RasterField(null=True, blank=True, srid=4326, help_text="Orthophoto created by OpenDroneMap")
|
||||
orthophoto = OffDbRasterField(null=True, blank=True, srid=4326, help_text="Orthophoto created by OpenDroneMap")
|
||||
# textured_model
|
||||
# mission
|
||||
created_at = models.DateTimeField(default=timezone.now, help_text="Creation date")
|
||||
|
|
|
@ -7,11 +7,14 @@ from django.contrib.gis.db.backends.postgis.pgraster import (
|
|||
STRUCT_SIZE,
|
||||
pack)
|
||||
from django.contrib.gis.db.backends.postgis.pgraster import chunk, unpack
|
||||
from django.contrib.gis.db.models.fields import RasterField
|
||||
from django.contrib.gis.db.models.fields import RasterField, BaseSpatialField
|
||||
from django.contrib.gis.gdal import GDALException
|
||||
from django.contrib.gis.gdal import GDALRaster
|
||||
from django.forms import ValidationError
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class OutOfDbRasterField(RasterField):
|
||||
|
||||
class OffDbRasterField(RasterField):
|
||||
"""
|
||||
Out-of-db Raster field for GeoDjango -- evaluates into GDALRaster objects.
|
||||
"""
|
||||
|
@ -19,14 +22,42 @@ class OutOfDbRasterField(RasterField):
|
|||
description = _("Out-of-db Raster Field")
|
||||
|
||||
def from_db_value(self, value, expression, connection, context):
|
||||
return connection.ops.parse_raster(value)
|
||||
return from_pgraster(value, True)
|
||||
|
||||
def get_db_prep_save(self, value, connection):
|
||||
"""
|
||||
Prepare the value for saving in the database.
|
||||
"""
|
||||
if not value:
|
||||
return None
|
||||
else:
|
||||
return to_pgraster(value, True)
|
||||
|
||||
def get_db_prep_value(self, value, connection, prepared=False):
|
||||
self._check_connection(connection)
|
||||
# Prepare raster for writing to database.
|
||||
if not prepared:
|
||||
value = connection.ops.deconstruct_raster(value)
|
||||
return super(OutOfDbRasterField, self).get_db_prep_value(value, connection, prepared)
|
||||
value = to_pgraster(value, True)
|
||||
|
||||
# Call RasterField's base class get_db_prep_value
|
||||
return BaseSpatialField.get_db_prep_value(self, value, connection, prepared)
|
||||
|
||||
def get_raster_prep_value(self, value, is_candidate):
|
||||
"""
|
||||
Return a GDALRaster if conversion is successful, otherwise return None.
|
||||
"""
|
||||
if isinstance(value, GDALRaster):
|
||||
return value
|
||||
elif is_candidate:
|
||||
try:
|
||||
return GDALRaster(value)
|
||||
except GDALException:
|
||||
pass
|
||||
elif isinstance(value, (dict, str)):
|
||||
try:
|
||||
return GDALRaster(value)
|
||||
except GDALException:
|
||||
raise ValueError("Couldn't create spatial object from lookup value '%s'." % value)
|
||||
|
||||
|
||||
class POSTGIS_BANDTYPES(object):
|
||||
|
@ -35,7 +66,7 @@ class POSTGIS_BANDTYPES(object):
|
|||
BANDTYPE_FLAG_ISNODATA = 1 << 5
|
||||
|
||||
|
||||
def from_pgraster(data):
|
||||
def from_pgraster(data, offdb = False):
|
||||
"""
|
||||
Convert a PostGIS HEX String into a dictionary.
|
||||
"""
|
||||
|
@ -111,16 +142,18 @@ def from_pgraster(data):
|
|||
if len(set(pixeltypes)) != 1:
|
||||
raise ValidationError("Band pixeltypes are not all equal.")
|
||||
|
||||
|
||||
return {
|
||||
'srid': int(header[9]),
|
||||
'width': header[10], 'height': header[11],
|
||||
'datatype': pixeltypes[0],
|
||||
'origin': (header[5], header[6]),
|
||||
'scale': (header[3], header[4]),
|
||||
'skew': (header[7], header[8]),
|
||||
'bands': bands,
|
||||
}
|
||||
if offdb and len(bands) > 0:
|
||||
return bands[0]['path']
|
||||
else:
|
||||
return {
|
||||
'srid': int(header[9]),
|
||||
'width': header[10], 'height': header[11],
|
||||
'datatype': pixeltypes[0],
|
||||
'origin': (header[5], header[6]),
|
||||
'scale': (header[3], header[4]),
|
||||
'skew': (header[7], header[8]),
|
||||
'bands': bands,
|
||||
}
|
||||
|
||||
|
||||
def to_pgraster(rast, offdb = False):
|
|
@ -1,22 +0,0 @@
|
|||
from django.contrib.gis.gdal import GDALRaster
|
||||
|
||||
from .classes import BootTestCase
|
||||
from app.fields import from_pgraster, to_pgraster
|
||||
import os
|
||||
|
||||
class TestApi(BootTestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_pgraster_functions(self):
|
||||
# Make sure conversion from PostGIS <---> GDALRaster works
|
||||
# for out-of-db
|
||||
raster = GDALRaster(os.path.join("app", "fixtures", "orthophoto.tif"))
|
||||
|
||||
self.assertTrue(raster.srid == 32615)
|
||||
self.assertTrue(raster.width == 212)
|
||||
|
||||
#hexwkb =
|
|
@ -0,0 +1,38 @@
|
|||
from django.contrib.gis.gdal import GDALRaster
|
||||
|
||||
from .classes import BootTestCase
|
||||
from app.postgis import from_pgraster, to_pgraster
|
||||
import os
|
||||
|
||||
class TestApi(BootTestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_pgraster_functions(self):
|
||||
# Make sure conversion from PostGIS <---> GDALRaster works
|
||||
# for out-of-db
|
||||
raster = GDALRaster(os.path.join("app", "fixtures", "orthophoto.tif"))
|
||||
|
||||
self.assertTrue(raster.srid == 32615)
|
||||
self.assertTrue(raster.width == 212)
|
||||
|
||||
# Classic
|
||||
hexwkb = to_pgraster(raster)
|
||||
deserialized_raster = GDALRaster(from_pgraster(hexwkb))
|
||||
self.assertTrue(len(deserialized_raster.bands) == 4)
|
||||
self.assertTrue(deserialized_raster.srid == raster.srid)
|
||||
self.assertTrue(deserialized_raster.width == raster.width)
|
||||
self.assertTrue(deserialized_raster.height == raster.height)
|
||||
|
||||
# Off-db
|
||||
hexwkb = to_pgraster(raster, True)
|
||||
deserialized_raster = GDALRaster(from_pgraster(hexwkb, True))
|
||||
|
||||
self.assertTrue(deserialized_raster.name == raster.name)
|
||||
self.assertTrue(deserialized_raster.srid == raster.srid)
|
||||
self.assertTrue(deserialized_raster.width == raster.width)
|
||||
self.assertTrue(deserialized_raster.height == raster.height)
|
||||
|
Ładowanie…
Reference in New Issue