Dropped support for GEOS 3.5 and GDAL 2.0.

This commit is contained in:
Claude Paroz 2021-04-07 17:38:37 +02:00 committed by Mariusz Felisiak
parent 98abc0c90e
commit 3ae4344bbd
6 changed files with 14 additions and 38 deletions

View File

@ -5,7 +5,7 @@ related data structures.
from ctypes import POINTER, c_bool, c_char_p, c_double, c_int, c_void_p from ctypes import POINTER, c_bool, c_char_p, c_double, c_int, c_void_p
from functools import partial from functools import partial
from django.contrib.gis.gdal.libgdal import GDAL_VERSION, std_call from django.contrib.gis.gdal.libgdal import std_call
from django.contrib.gis.gdal.prototypes.generation import ( from django.contrib.gis.gdal.prototypes.generation import (
chararray_output, const_string_output, double_output, int_output, chararray_output, const_string_output, double_output, int_output,
void_output, voidptr_output, void_output, voidptr_output,
@ -40,6 +40,7 @@ copy_ds = voidptr_output(
add_band_ds = void_output(std_call('GDALAddBand'), [c_void_p, c_int]) add_band_ds = void_output(std_call('GDALAddBand'), [c_void_p, c_int])
get_ds_description = const_string_output(std_call('GDALGetDescription'), [c_void_p]) get_ds_description = const_string_output(std_call('GDALGetDescription'), [c_void_p])
get_ds_driver = voidptr_output(std_call('GDALGetDatasetDriver'), [c_void_p]) get_ds_driver = voidptr_output(std_call('GDALGetDatasetDriver'), [c_void_p])
get_ds_info = const_string_output(std_call('GDALInfo'), [c_void_p, c_void_p])
get_ds_xsize = int_output(std_call('GDALGetRasterXSize'), [c_void_p]) get_ds_xsize = int_output(std_call('GDALGetRasterXSize'), [c_void_p])
get_ds_ysize = int_output(std_call('GDALGetRasterYSize'), [c_void_p]) get_ds_ysize = int_output(std_call('GDALGetRasterYSize'), [c_void_p])
get_ds_raster_count = int_output(std_call('GDALGetRasterCount'), [c_void_p]) get_ds_raster_count = int_output(std_call('GDALGetRasterCount'), [c_void_p])
@ -56,11 +57,6 @@ get_ds_metadata_item = const_string_output(std_call('GDALGetMetadataItem'), [c_v
set_ds_metadata_item = const_string_output(std_call('GDALSetMetadataItem'), [c_void_p, c_char_p, c_char_p, c_char_p]) set_ds_metadata_item = const_string_output(std_call('GDALSetMetadataItem'), [c_void_p, c_char_p, c_char_p, c_char_p])
free_dsl = void_output(std_call('CSLDestroy'), [POINTER(c_char_p)], errcheck=False) free_dsl = void_output(std_call('CSLDestroy'), [POINTER(c_char_p)], errcheck=False)
if GDAL_VERSION >= (2, 1):
get_ds_info = const_string_output(std_call('GDALInfo'), [c_void_p, c_void_p])
else:
get_ds_info = None
# Raster Band Routines # Raster Band Routines
band_io = void_output( band_io = void_output(
std_call('GDALRasterIO'), std_call('GDALRasterIO'),
@ -75,10 +71,7 @@ get_band_datatype = int_output(std_call('GDALGetRasterDataType'), [c_void_p])
get_band_color_interp = int_output(std_call('GDALGetRasterColorInterpretation'), [c_void_p]) get_band_color_interp = int_output(std_call('GDALGetRasterColorInterpretation'), [c_void_p])
get_band_nodata_value = double_output(std_call('GDALGetRasterNoDataValue'), [c_void_p, POINTER(c_int)]) get_band_nodata_value = double_output(std_call('GDALGetRasterNoDataValue'), [c_void_p, POINTER(c_int)])
set_band_nodata_value = void_output(std_call('GDALSetRasterNoDataValue'), [c_void_p, c_double]) set_band_nodata_value = void_output(std_call('GDALSetRasterNoDataValue'), [c_void_p, c_double])
if GDAL_VERSION >= (2, 1): delete_band_nodata_value = void_output(std_call('GDALDeleteRasterNoDataValue'), [c_void_p])
delete_band_nodata_value = void_output(std_call('GDALDeleteRasterNoDataValue'), [c_void_p])
else:
delete_band_nodata_value = None
get_band_statistics = void_output( get_band_statistics = void_output(
std_call('GDALGetRasterStatistics'), std_call('GDALGetRasterStatistics'),
[ [

View File

@ -152,8 +152,6 @@ class GDALBand(GDALRasterBase):
Set the nodata value for this band. Set the nodata value for this band.
""" """
if value is None: if value is None:
if not capi.delete_band_nodata_value:
raise ValueError('GDAL >= 2.1 required to delete nodata values.')
capi.delete_band_nodata_value(self._ptr) capi.delete_band_nodata_value(self._ptr)
elif not isinstance(value, (int, float)): elif not isinstance(value, (int, float)):
raise ValueError('Nodata value must be numeric or None.') raise ValueError('Nodata value must be numeric or None.')

View File

@ -500,6 +500,4 @@ class GDALRaster(GDALRasterBase):
Return information about this raster in a string format equivalent Return information about this raster in a string format equivalent
to the output of the gdalinfo command line utility. to the output of the gdalinfo command line utility.
""" """
if not capi.get_ds_info:
raise ValueError('GDAL ≥ 2.1 is required for using the info property.')
return capi.get_ds_info(self.ptr, None).decode() return capi.get_ds_info(self.ptr, None).decode()

View File

@ -5,28 +5,26 @@ Installing Geospatial libraries
GeoDjango uses and/or provides interfaces for the following open source GeoDjango uses and/or provides interfaces for the following open source
geospatial libraries: geospatial libraries:
======================== ==================================== ================================ ====================================== ======================== ==================================== ================================ =================================
Program Description Required Supported Versions Program Description Required Supported Versions
======================== ==================================== ================================ ====================================== ======================== ==================================== ================================ =================================
:doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.9, 3.8, 3.7, 3.6, 3.5 :doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.9, 3.8, 3.7, 3.6
`PROJ`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 7.x. 6.x, 5.x, 4.x `PROJ`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 7.x. 6.x, 5.x, 4.x
:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.2, 3.1, 3.0, 2.4, 2.3, 2.2, 2.1, 2.0 :doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.2, 3.1, 3.0, 2.4, 2.3, 2.2, 2.1
:doc:`GeoIP <../geoip2>` IP-based geolocation library No 2 :doc:`GeoIP <../geoip2>` IP-based geolocation library No 2
`PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4 `PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4
`SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3 `SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3
======================== ==================================== ================================ ====================================== ======================== ==================================== ================================ =================================
Note that older or more recent versions of these libraries *may* also work Note that older or more recent versions of these libraries *may* also work
totally fine with GeoDjango. Your mileage may vary. totally fine with GeoDjango. Your mileage may vary.
.. ..
Libs release dates: Libs release dates:
GEOS 3.5.0 2015-08-15
GEOS 3.6.0 2016-10-25 GEOS 3.6.0 2016-10-25
GEOS 3.7.0 2018-09-10 GEOS 3.7.0 2018-09-10
GEOS 3.8.0 2019-10-10 GEOS 3.8.0 2019-10-10
GEOS 3.9.0 2020-12-14 GEOS 3.9.0 2020-12-14
GDAL 2.0.0 2015-06
GDAL 2.1.0 2016-04 GDAL 2.1.0 2016-04
GDAL 2.2.0 2017-05 GDAL 2.2.0 2017-05
GDAL 2.3.0 2018-05 GDAL 2.3.0 2018-05

View File

@ -314,6 +314,8 @@ backends.
* Support for PostGIS 2.3 is removed. * Support for PostGIS 2.3 is removed.
* Support for GDAL 2.0 and GEOS 3.5 is removed.
Dropped support for PostgreSQL 9.6 Dropped support for PostgreSQL 9.6
---------------------------------- ----------------------------------

View File

@ -4,7 +4,7 @@ import struct
import tempfile import tempfile
from unittest import mock from unittest import mock
from django.contrib.gis.gdal import GDAL_VERSION, GDALRaster, SpatialReference from django.contrib.gis.gdal import GDALRaster, SpatialReference
from django.contrib.gis.gdal.error import GDALException from django.contrib.gis.gdal.error import GDALException
from django.contrib.gis.gdal.raster.band import GDALBand from django.contrib.gis.gdal.raster.band import GDALBand
from django.contrib.gis.shortcuts import numpy from django.contrib.gis.shortcuts import numpy
@ -270,8 +270,6 @@ class GDALRasterTests(SimpleTestCase):
self.assertEqual(result, [23] * 4) self.assertEqual(result, [23] * 4)
def test_set_nodata_none_on_raster_creation(self): def test_set_nodata_none_on_raster_creation(self):
if GDAL_VERSION < (2, 1):
self.skipTest("GDAL >= 2.1 is required for this test.")
# Create raster without data and without nodata value. # Create raster without data and without nodata value.
rast = GDALRaster({ rast = GDALRaster({
'datatype': 1, 'datatype': 1,
@ -322,11 +320,6 @@ class GDALRasterTests(SimpleTestCase):
self.assertNotIn('OWNER', source.metadata['DEFAULT']) self.assertNotIn('OWNER', source.metadata['DEFAULT'])
def test_raster_info_accessor(self): def test_raster_info_accessor(self):
if GDAL_VERSION < (2, 1):
msg = 'GDAL ≥ 2.1 is required for using the info property.'
with self.assertRaisesMessage(ValueError, msg):
self.rs.info
return
infos = self.rs.info infos = self.rs.info
# Data # Data
info_lines = [line.strip() for line in infos.split('\n') if line.strip() != ''] info_lines = [line.strip() for line in infos.split('\n') if line.strip() != '']
@ -389,8 +382,7 @@ class GDALRasterTests(SimpleTestCase):
compressed = GDALRaster(compressed.name) compressed = GDALRaster(compressed.name)
self.assertEqual(compressed.metadata['IMAGE_STRUCTURE']['COMPRESSION'], 'PACKBITS',) self.assertEqual(compressed.metadata['IMAGE_STRUCTURE']['COMPRESSION'], 'PACKBITS',)
self.assertEqual(compressed.bands[0].metadata['IMAGE_STRUCTURE']['PIXELTYPE'], 'SIGNEDBYTE') self.assertEqual(compressed.bands[0].metadata['IMAGE_STRUCTURE']['PIXELTYPE'], 'SIGNEDBYTE')
if GDAL_VERSION >= (2, 1): self.assertIn('Block=40x23', compressed.info)
self.assertIn('Block=40x23', compressed.info)
def test_raster_warp(self): def test_raster_warp(self):
# Create in memory raster # Create in memory raster
@ -796,13 +788,8 @@ class GDALBandTests(SimpleTestCase):
'height': 1, 'height': 1,
'bands': [{'data': [0], 'nodata_value': 1}], 'bands': [{'data': [0], 'nodata_value': 1}],
}) })
if GDAL_VERSION < (2, 1): rsmem.bands[0].nodata_value = None
msg = 'GDAL >= 2.1 required to delete nodata values.' self.assertIsNone(rsmem.bands[0].nodata_value)
with self.assertRaisesMessage(ValueError, msg):
rsmem.bands[0].nodata_value = None
else:
rsmem.bands[0].nodata_value = None
self.assertIsNone(rsmem.bands[0].nodata_value)
def test_band_data_replication(self): def test_band_data_replication(self):
band = GDALRaster({ band = GDALRaster({