mirror of
https://github.com/django/django.git
synced 2025-06-01 17:49:12 +00:00
Added raster support for GDAL Driver class
Based on Daniel Wiesmann's work. Refs #23804.
This commit is contained in:
parent
ac51496ceb
commit
00fa1474d7
@ -67,10 +67,7 @@ class DataSource(GDALBase):
|
|||||||
# See also http://trac.osgeo.org/gdal/wiki/rfc23_ogr_unicode
|
# See also http://trac.osgeo.org/gdal/wiki/rfc23_ogr_unicode
|
||||||
self.encoding = encoding
|
self.encoding = encoding
|
||||||
|
|
||||||
# Registering all the drivers, this needs to be done
|
Driver.ensure_registered()
|
||||||
# _before_ we try to open up a data source.
|
|
||||||
if not capi.get_driver_count():
|
|
||||||
capi.register_all()
|
|
||||||
|
|
||||||
if isinstance(ds_input, six.string_types):
|
if isinstance(ds_input, six.string_types):
|
||||||
# The data source driver is a void pointer.
|
# The data source driver is a void pointer.
|
||||||
|
@ -1,70 +1,97 @@
|
|||||||
# prerequisites imports
|
|
||||||
from ctypes import c_void_p
|
from ctypes import c_void_p
|
||||||
from django.contrib.gis.gdal.base import GDALBase
|
from django.contrib.gis.gdal.base import GDALBase
|
||||||
from django.contrib.gis.gdal.error import OGRException
|
from django.contrib.gis.gdal.error import OGRException
|
||||||
from django.contrib.gis.gdal.prototypes import ds as capi
|
from django.contrib.gis.gdal.prototypes import ds as vcapi, raster as rcapi
|
||||||
|
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes, force_text
|
||||||
|
|
||||||
|
|
||||||
# For more information, see the OGR C API source code:
|
|
||||||
# http://www.gdal.org/ogr/ogr__api_8h.html
|
|
||||||
#
|
|
||||||
# The OGR_Dr_* routines are relevant here.
|
|
||||||
class Driver(GDALBase):
|
class Driver(GDALBase):
|
||||||
"Wraps an OGR Data Source Driver."
|
"""
|
||||||
|
Wraps a GDAL/OGR Data Source Driver.
|
||||||
|
For more information, see the C API source code:
|
||||||
|
http://www.gdal.org/gdal_8h.html - http://www.gdal.org/ogr__api_8h.html
|
||||||
|
"""
|
||||||
|
|
||||||
# Case-insensitive aliases for OGR Drivers.
|
# Case-insensitive aliases for some GDAL/OGR Drivers.
|
||||||
_alias = {'esri': 'ESRI Shapefile',
|
# For a complete list of original driver names see
|
||||||
'shp': 'ESRI Shapefile',
|
# http://www.gdal.org/ogr_formats.html (vector)
|
||||||
'shape': 'ESRI Shapefile',
|
# http://www.gdal.org/formats_list.html (raster)
|
||||||
'tiger': 'TIGER',
|
_alias = {
|
||||||
'tiger/line': 'TIGER',
|
# vector
|
||||||
}
|
'esri': 'ESRI Shapefile',
|
||||||
|
'shp': 'ESRI Shapefile',
|
||||||
|
'shape': 'ESRI Shapefile',
|
||||||
|
'tiger': 'TIGER',
|
||||||
|
'tiger/line': 'TIGER',
|
||||||
|
# raster
|
||||||
|
'tiff': 'GTiff',
|
||||||
|
'tif': 'GTiff',
|
||||||
|
'jpeg': 'JPEG',
|
||||||
|
'jpg': 'JPEG',
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, dr_input):
|
def __init__(self, dr_input):
|
||||||
"Initializes an OGR driver on either a string or integer input."
|
"""
|
||||||
|
Initializes an GDAL/OGR driver on either a string or integer input.
|
||||||
|
"""
|
||||||
if isinstance(dr_input, six.string_types):
|
if isinstance(dr_input, six.string_types):
|
||||||
# If a string name of the driver was passed in
|
# If a string name of the driver was passed in
|
||||||
self._register()
|
self.ensure_registered()
|
||||||
|
|
||||||
# Checking the alias dictionary (case-insensitive) to see if an alias
|
# Checking the alias dictionary (case-insensitive) to see if an
|
||||||
# exists for the given driver.
|
# alias exists for the given driver.
|
||||||
if dr_input.lower() in self._alias:
|
if dr_input.lower() in self._alias:
|
||||||
name = self._alias[dr_input.lower()]
|
name = self._alias[dr_input.lower()]
|
||||||
else:
|
else:
|
||||||
name = dr_input
|
name = dr_input
|
||||||
|
|
||||||
# Attempting to get the OGR driver by the string name.
|
# Attempting to get the GDAL/OGR driver by the string name.
|
||||||
dr = capi.get_driver_by_name(force_bytes(name))
|
for iface in (vcapi, rcapi):
|
||||||
|
driver = iface.get_driver_by_name(force_bytes(name))
|
||||||
|
if driver:
|
||||||
|
break
|
||||||
elif isinstance(dr_input, int):
|
elif isinstance(dr_input, int):
|
||||||
self._register()
|
self.ensure_registered()
|
||||||
dr = capi.get_driver(dr_input)
|
for iface in (vcapi, rcapi):
|
||||||
|
driver = iface.get_driver(dr_input)
|
||||||
|
if driver:
|
||||||
|
break
|
||||||
elif isinstance(dr_input, c_void_p):
|
elif isinstance(dr_input, c_void_p):
|
||||||
dr = dr_input
|
driver = dr_input
|
||||||
else:
|
else:
|
||||||
raise OGRException('Unrecognized input type for OGR Driver: %s' % str(type(dr_input)))
|
raise OGRException('Unrecognized input type for GDAL/OGR Driver: %s' % str(type(dr_input)))
|
||||||
|
|
||||||
# Making sure we get a valid pointer to the OGR Driver
|
# Making sure we get a valid pointer to the OGR Driver
|
||||||
if not dr:
|
if not driver:
|
||||||
raise OGRException('Could not initialize OGR Driver on input: %s' % str(dr_input))
|
raise OGRException('Could not initialize GDAL/OGR Driver on input: %s' % str(dr_input))
|
||||||
self.ptr = dr
|
self.ptr = driver
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns the string name of the OGR Driver."
|
return self.name
|
||||||
return capi.get_driver_name(self.ptr)
|
|
||||||
|
|
||||||
def _register(self):
|
@classmethod
|
||||||
"Attempts to register all the data source drivers."
|
def ensure_registered(cls):
|
||||||
|
"""
|
||||||
|
Attempts to register all the data source drivers.
|
||||||
|
"""
|
||||||
# Only register all if the driver count is 0 (or else all drivers
|
# Only register all if the driver count is 0 (or else all drivers
|
||||||
# will be registered over and over again)
|
# will be registered over and over again)
|
||||||
if not self.driver_count:
|
if not cls.driver_count():
|
||||||
capi.register_all()
|
vcapi.register_all()
|
||||||
|
rcapi.register_all()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def driver_count(cls):
|
||||||
|
"""
|
||||||
|
Returns the number of GDAL/OGR data source drivers registered.
|
||||||
|
"""
|
||||||
|
return vcapi.get_driver_count() + rcapi.get_driver_count()
|
||||||
|
|
||||||
# Driver properties
|
|
||||||
@property
|
@property
|
||||||
def driver_count(self):
|
def name(self):
|
||||||
"Returns the number of OGR data source drivers registered."
|
"""
|
||||||
return capi.get_driver_count()
|
Returns description/name string for this driver.
|
||||||
|
"""
|
||||||
|
return force_text(rcapi.get_driver_description(self.ptr))
|
||||||
|
@ -15,7 +15,7 @@ c_int_p = POINTER(c_int) # shortcut type
|
|||||||
register_all = void_output(lgdal.OGRRegisterAll, [], errcheck=False)
|
register_all = void_output(lgdal.OGRRegisterAll, [], errcheck=False)
|
||||||
cleanup_all = void_output(lgdal.OGRCleanupAll, [], errcheck=False)
|
cleanup_all = void_output(lgdal.OGRCleanupAll, [], errcheck=False)
|
||||||
get_driver = voidptr_output(lgdal.OGRGetDriver, [c_int])
|
get_driver = voidptr_output(lgdal.OGRGetDriver, [c_int])
|
||||||
get_driver_by_name = voidptr_output(lgdal.OGRGetDriverByName, [c_char_p])
|
get_driver_by_name = voidptr_output(lgdal.OGRGetDriverByName, [c_char_p], errcheck=False)
|
||||||
get_driver_count = int_output(lgdal.OGRGetDriverCount, [])
|
get_driver_count = int_output(lgdal.OGRGetDriverCount, [])
|
||||||
get_driver_name = const_string_output(lgdal.OGR_Dr_GetName, [c_void_p], decoding='ascii')
|
get_driver_name = const_string_output(lgdal.OGR_Dr_GetName, [c_void_p], decoding='ascii')
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import unittest
|
import unittest
|
||||||
from unittest import skipUnless
|
|
||||||
|
|
||||||
from django.contrib.gis.gdal import HAS_GDAL
|
from django.contrib.gis.gdal import HAS_GDAL
|
||||||
|
|
||||||
@ -7,29 +6,39 @@ if HAS_GDAL:
|
|||||||
from django.contrib.gis.gdal import Driver, OGRException
|
from django.contrib.gis.gdal import Driver, OGRException
|
||||||
|
|
||||||
|
|
||||||
valid_drivers = ('ESRI Shapefile', 'MapInfo File', 'TIGER', 'S57', 'DGN',
|
valid_drivers = (
|
||||||
'Memory', 'CSV', 'GML', 'KML')
|
# vector
|
||||||
|
'ESRI Shapefile', 'MapInfo File', 'TIGER', 'S57', 'DGN', 'Memory', 'CSV',
|
||||||
|
'GML', 'KML',
|
||||||
|
# raster
|
||||||
|
'GTiff', 'JPEG', 'netCDF', 'MEM', 'PNG',
|
||||||
|
)
|
||||||
|
|
||||||
invalid_drivers = ('Foo baz', 'clucka', 'ESRI Shp')
|
invalid_drivers = ('Foo baz', 'clucka', 'ESRI Shp', 'ESRI rast')
|
||||||
|
|
||||||
aliases = {'eSrI': 'ESRI Shapefile',
|
aliases = {
|
||||||
'TigER/linE': 'TIGER',
|
'eSrI': 'ESRI Shapefile',
|
||||||
'SHAPE': 'ESRI Shapefile',
|
'TigER/linE': 'TIGER',
|
||||||
'sHp': 'ESRI Shapefile',
|
'SHAPE': 'ESRI Shapefile',
|
||||||
}
|
'sHp': 'ESRI Shapefile',
|
||||||
|
'tiFf': 'GTiff',
|
||||||
|
'tIf': 'GTiff',
|
||||||
|
'jPEg': 'JPEG',
|
||||||
|
'jpG': 'JPEG',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@skipUnless(HAS_GDAL, "GDAL is required")
|
@unittest.skipUnless(HAS_GDAL, "GDAL is required")
|
||||||
class DriverTest(unittest.TestCase):
|
class DriverTest(unittest.TestCase):
|
||||||
|
|
||||||
def test01_valid_driver(self):
|
def test01_valid_driver(self):
|
||||||
"Testing valid OGR Data Source Drivers."
|
"Testing valid GDAL/OGR Data Source Drivers."
|
||||||
for d in valid_drivers:
|
for d in valid_drivers:
|
||||||
dr = Driver(d)
|
dr = Driver(d)
|
||||||
self.assertEqual(d, str(dr))
|
self.assertEqual(d, str(dr))
|
||||||
|
|
||||||
def test02_invalid_driver(self):
|
def test02_invalid_driver(self):
|
||||||
"Testing invalid OGR Data Source Drivers."
|
"Testing invalid GDAL/OGR Data Source Drivers."
|
||||||
for i in invalid_drivers:
|
for i in invalid_drivers:
|
||||||
self.assertRaises(OGRException, Driver, i)
|
self.assertRaises(OGRException, Driver, i)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user