diff --git a/django/contrib/gis/gdal/__init__.py b/django/contrib/gis/gdal/__init__.py index 6a0f5360d86..1d8c6884bd7 100644 --- a/django/contrib/gis/gdal/__init__.py +++ b/django/contrib/gis/gdal/__init__.py @@ -37,11 +37,13 @@ from django.contrib.gis.gdal.libgdal import ( GDAL_VERSION, gdal_full_version, gdal_version, ) from django.contrib.gis.gdal.raster.source import GDALRaster -from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference +from django.contrib.gis.gdal.srs import ( + AxisOrder, CoordTransform, SpatialReference, +) __all__ = ( - 'Driver', 'DataSource', 'CoordTransform', 'Envelope', 'GDALException', - 'GDALRaster', 'GDAL_VERSION', 'OGRGeometry', 'OGRGeomType', - 'SpatialReference', 'SRSException', 'check_err', 'gdal_version', - 'gdal_full_version', + 'AxisOrder', 'Driver', 'DataSource', 'CoordTransform', 'Envelope', + 'GDALException', 'GDALRaster', 'GDAL_VERSION', 'OGRGeometry', + 'OGRGeomType', 'SpatialReference', 'SRSException', 'check_err', + 'gdal_version', 'gdal_full_version', ) diff --git a/django/contrib/gis/gdal/prototypes/srs.py b/django/contrib/gis/gdal/prototypes/srs.py index 45d52343464..004319f1b96 100644 --- a/django/contrib/gis/gdal/prototypes/srs.py +++ b/django/contrib/gis/gdal/prototypes/srs.py @@ -1,6 +1,6 @@ from ctypes import POINTER, c_char_p, c_int, c_void_p -from django.contrib.gis.gdal.libgdal import lgdal, std_call +from django.contrib.gis.gdal.libgdal import GDAL_VERSION, lgdal, std_call from django.contrib.gis.gdal.prototypes.generation import ( const_string_output, double_output, int_output, srs_output, string_output, void_output, @@ -31,6 +31,9 @@ release_srs = void_output(lgdal.OSRRelease, [c_void_p], errcheck=False) destroy_srs = void_output(std_call('OSRDestroySpatialReference'), [c_void_p], errcheck=False) srs_validate = void_output(lgdal.OSRValidate, [c_void_p]) +if GDAL_VERSION >= (3, 0): + set_axis_strategy = void_output(lgdal.OSRSetAxisMappingStrategy, [c_void_p, c_int]) + # Getting the semi_major, semi_minor, and flattening functions. semi_major = srs_double(lgdal.OSRGetSemiMajor) semi_minor = srs_double(lgdal.OSRGetSemiMinor) diff --git a/django/contrib/gis/gdal/srs.py b/django/contrib/gis/gdal/srs.py index 850196ccc30..d2e781e3817 100644 --- a/django/contrib/gis/gdal/srs.py +++ b/django/contrib/gis/gdal/srs.py @@ -27,13 +27,20 @@ NAD83 / Texas South Central """ from ctypes import byref, c_char_p, c_int +from enum import IntEnum from django.contrib.gis.gdal.base import GDALBase from django.contrib.gis.gdal.error import SRSException +from django.contrib.gis.gdal.libgdal import GDAL_VERSION from django.contrib.gis.gdal.prototypes import srs as capi from django.utils.encoding import force_bytes, force_str +class AxisOrder(IntEnum): + TRADITIONAL = 0 + AUTHORITY = 1 + + class SpatialReference(GDALBase): """ A wrapper for the OGRSpatialReference object. According to the GDAL Web site, @@ -42,17 +49,25 @@ class SpatialReference(GDALBase): """ destructor = capi.release_srs - def __init__(self, srs_input='', srs_type='user'): + def __init__(self, srs_input='', srs_type='user', axis_order=None): """ Create a GDAL OSR Spatial Reference object from the given input. The input may be string of OGC Well Known Text (WKT), an integer EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83'). """ - + if not isinstance(axis_order, (type(None), AxisOrder)): + raise ValueError( + 'SpatialReference.axis_order must be an AxisOrder instance.' + ) + self.axis_order = axis_order or AxisOrder.TRADITIONAL if srs_type == 'wkt': self.ptr = capi.new_srs(c_char_p(b'')) self.import_wkt(srs_input) + if self.axis_order == AxisOrder.TRADITIONAL and GDAL_VERSION >= (3, 0): + capi.set_axis_strategy(self.ptr, self.axis_order) + elif self.axis_order != AxisOrder.TRADITIONAL and GDAL_VERSION < (3, 0): + raise ValueError('%s is not supported in GDAL < 3.0.' % self.axis_order) return elif isinstance(srs_input, str): try: @@ -85,6 +100,10 @@ class SpatialReference(GDALBase): else: self.ptr = srs + if self.axis_order == AxisOrder.TRADITIONAL and GDAL_VERSION >= (3, 0): + capi.set_axis_strategy(self.ptr, self.axis_order) + elif self.axis_order != AxisOrder.TRADITIONAL and GDAL_VERSION < (3, 0): + raise ValueError('%s is not supported in GDAL < 3.0.' % self.axis_order) # Importing from either the user input string or an integer SRID. if srs_type == 'user': self.import_user_input(srs_input) @@ -143,7 +162,7 @@ class SpatialReference(GDALBase): def clone(self): "Return a clone of this SpatialReference object." - return SpatialReference(capi.clone_srs(self.ptr)) + return SpatialReference(capi.clone_srs(self.ptr), axis_order=self.axis_order) def from_esri(self): "Morph this SpatialReference from ESRI's format to EPSG." diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py index 221af4fc68a..8fb0117b3e2 100644 --- a/django/contrib/gis/geos/geometry.py +++ b/django/contrib/gis/geos/geometry.py @@ -434,7 +434,7 @@ class GEOSGeometryBase(GEOSBase): if self.srid: try: return gdal.SpatialReference(self.srid) - except gdal.SRSException: + except (gdal.GDALException, gdal.SRSException): pass return None diff --git a/docs/ref/contrib/gis/install/geolibs.txt b/docs/ref/contrib/gis/install/geolibs.txt index b0878a9e4c7..ee60ee3fbd4 100644 --- a/docs/ref/contrib/gis/install/geolibs.txt +++ b/docs/ref/contrib/gis/install/geolibs.txt @@ -9,8 +9,8 @@ geospatial libraries: Program Description Required Supported Versions ======================== ==================================== ================================ =================================== :doc:`GEOS <../geos>` Geometry Engine Open Source Yes 3.7, 3.6, 3.5 -`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 5.2, 5.1, 5.0, 4.x -:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 2.4, 2.3, 2.2, 2.1, 2.0 +`PROJ.4`_ Cartographic Projections library Yes (PostgreSQL and SQLite only) 6.3, 6.2, 6.1, 6.0, 5.x, 4.x +:doc:`GDAL <../gdal>` Geospatial Data Abstraction Library Yes 3.0, 2.4, 2.3, 2.2, 2.1, 2.0 :doc:`GeoIP <../geoip2>` IP-based geolocation library No 2 `PostGIS`__ Spatial extensions for PostgreSQL Yes (PostgreSQL only) 3.0, 2.5, 2.4, 2.3, 2.2 `SpatiaLite`__ Spatial extensions for SQLite Yes (SQLite only) 4.3 @@ -29,6 +29,7 @@ totally fine with GeoDjango. Your mileage may vary. GDAL 2.2.0 2017-05 GDAL 2.3.0 2018-05 GDAL 2.4.0 2018-12 + GDAL 3.0.0 2019-05 PostGIS 2.2.0 2015-10-17 PostGIS 2.3.0 2016-09-26 PostGIS 2.4.0 2017-09-30 diff --git a/docs/releases/3.1.txt b/docs/releases/3.1.txt index 2d9ae7ed4c0..7a446c68d8a 100644 --- a/docs/releases/3.1.txt +++ b/docs/releases/3.1.txt @@ -145,7 +145,7 @@ Minor features * Added the :class:`~django.contrib.gis.db.models.functions.AsWKB` and :class:`~django.contrib.gis.db.models.functions.AsWKT` functions. -* Added support for PostGIS 3. +* Added support for PostGIS 3 and GDAL 3. :mod:`django.contrib.humanize` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/gis_tests/gdal_tests/test_raster.py b/tests/gis_tests/gdal_tests/test_raster.py index 018871efc3a..3369d71ea02 100644 --- a/tests/gis_tests/gdal_tests/test_raster.py +++ b/tests/gis_tests/gdal_tests/test_raster.py @@ -146,7 +146,11 @@ class GDALRasterTests(SimpleTestCase): # Reload newly created raster from file restored_raster = GDALRaster(rstfile.name) - self.assertEqual(restored_raster.srs.wkt, self.rs.srs.wkt) + # Presence of TOWGS84 depend on GDAL/Proj versions. + self.assertEqual( + restored_raster.srs.wkt.replace('TOWGS84[0,0,0,0,0,0,0],', ''), + self.rs.srs.wkt.replace('TOWGS84[0,0,0,0,0,0,0],', '') + ) self.assertEqual(restored_raster.geotransform, self.rs.geotransform) if numpy: numpy.testing.assert_equal( @@ -322,54 +326,33 @@ class GDALRasterTests(SimpleTestCase): with self.assertRaisesMessage(ValueError, msg): self.rs.info return - gdalinfo = """ - Driver: GTiff/GeoTIFF - Files: {} - Size is 163, 174 - Coordinate System is: - PROJCS["NAD83 / Florida GDL Albers", - GEOGCS["NAD83", - DATUM["North_American_Datum_1983", - SPHEROID["GRS 1980",6378137,298.257222101, - AUTHORITY["EPSG","7019"]], - TOWGS84[0,0,0,0,0,0,0], - AUTHORITY["EPSG","6269"]], - PRIMEM["Greenwich",0, - AUTHORITY["EPSG","8901"]], - UNIT["degree",0.0174532925199433, - AUTHORITY["EPSG","9122"]], - AUTHORITY["EPSG","4269"]], - PROJECTION["Albers_Conic_Equal_Area"], - PARAMETER["standard_parallel_1",24], - PARAMETER["standard_parallel_2",31.5], - PARAMETER["latitude_of_center",24], - PARAMETER["longitude_of_center",-84], - PARAMETER["false_easting",400000], - PARAMETER["false_northing",0], - UNIT["metre",1, - AUTHORITY["EPSG","9001"]], - AXIS["X",EAST], - AXIS["Y",NORTH], - AUTHORITY["EPSG","3086"]] - Origin = (511700.468070655711927,435103.377123198588379) - Pixel Size = (100.000000000000000,-100.000000000000000) - Metadata: - AREA_OR_POINT=Area - Image Structure Metadata: - INTERLEAVE=BAND - Corner Coordinates: - Upper Left ( 511700.468, 435103.377) ( 82d51'46.16"W, 27d55' 1.53"N) - Lower Left ( 511700.468, 417703.377) ( 82d51'52.04"W, 27d45'37.50"N) - Upper Right ( 528000.468, 435103.377) ( 82d41'48.81"W, 27d54'56.30"N) - Lower Right ( 528000.468, 417703.377) ( 82d41'55.54"W, 27d45'32.28"N) - Center ( 519850.468, 426403.377) ( 82d46'50.64"W, 27d50'16.99"N) - Band 1 Block=163x50 Type=Byte, ColorInterp=Gray - NoData Value=15 - """.format(self.rs_path) + infos = self.rs.info # Data - info_dyn = [line.strip() for line in self.rs.info.split('\n') if line.strip() != ''] - info_ref = [line.strip() for line in gdalinfo.split('\n') if line.strip() != ''] - self.assertEqual(info_dyn, info_ref) + info_lines = [line.strip() for line in infos.split('\n') if line.strip() != ''] + for line in [ + 'Driver: GTiff/GeoTIFF', + 'Files: {}'.format(self.rs_path), + 'Size is 163, 174', + 'Origin = (511700.468070655711927,435103.377123198588379)', + 'Pixel Size = (100.000000000000000,-100.000000000000000)', + 'Metadata:', + 'AREA_OR_POINT=Area', + 'Image Structure Metadata:', + 'INTERLEAVE=BAND', + 'Band 1 Block=163x50 Type=Byte, ColorInterp=Gray', + 'NoData Value=15' + ]: + self.assertIn(line, info_lines) + for line in [ + r'Upper Left \( 511700.468, 435103.377\) \( 82d51\'46.1\d"W, 27d55\' 1.5\d"N\)', + r'Lower Left \( 511700.468, 417703.377\) \( 82d51\'52.0\d"W, 27d45\'37.5\d"N\)', + r'Upper Right \( 528000.468, 435103.377\) \( 82d41\'48.8\d"W, 27d54\'56.3\d"N\)', + r'Lower Right \( 528000.468, 417703.377\) \( 82d41\'55.5\d"W, 27d45\'32.2\d"N\)', + r'Center \( 519850.468, 426403.377\) \( 82d46\'50.6\d"W, 27d50\'16.9\d"N\)', + ]: + self.assertRegex(infos, line) + # CRS (skip the name because string depends on the GDAL/Proj versions). + self.assertIn("NAD83 / Florida GDL Albers", infos) def test_compressed_file_based_raster_creation(self): rstfile = tempfile.NamedTemporaryFile(suffix='.tif') diff --git a/tests/gis_tests/gdal_tests/test_srs.py b/tests/gis_tests/gdal_tests/test_srs.py index 02af60bc7a4..27974c8b802 100644 --- a/tests/gis_tests/gdal_tests/test_srs.py +++ b/tests/gis_tests/gdal_tests/test_srs.py @@ -1,8 +1,11 @@ -import unittest +from unittest import skipIf from django.contrib.gis.gdal import ( - CoordTransform, GDALException, SpatialReference, SRSException, + GDAL_VERSION, AxisOrder, CoordTransform, GDALException, SpatialReference, + SRSException, ) +from django.contrib.gis.geos import GEOSGeometry +from django.test import SimpleTestCase class TestSRS: @@ -20,7 +23,8 @@ srlist = ( 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84",6378137,298.257223563,' 'AUTHORITY["EPSG","7030"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","6326"]],' 'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",' - '0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4326"]]', + '0.0174532925199433,AUTHORITY["EPSG","9122"]],AXIS["Latitude",NORTH],' + 'AXIS["Longitude",EAST],AUTHORITY["EPSG","4326"]]', epsg=4326, projected=False, geographic=True, local=False, lin_name='unknown', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, auth={'GEOGCS': ('EPSG', '4326'), 'spheroid': ('EPSG', '7030')}, @@ -30,14 +34,14 @@ srlist = ( 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",DATUM["North_American_Datum_1983",' 'SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],' 'AUTHORITY["EPSG","6269"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],' - 'UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],' + 'UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],' 'AUTHORITY["EPSG","4269"]],PROJECTION["Lambert_Conformal_Conic_2SP"],' - 'PARAMETER["standard_parallel_1",30.28333333333333],' - 'PARAMETER["standard_parallel_2",28.38333333333333],' - 'PARAMETER["latitude_of_origin",27.83333333333333],' + 'PARAMETER["standard_parallel_1",30.2833333333333],' + 'PARAMETER["standard_parallel_2",28.3833333333333],' + 'PARAMETER["latitude_of_origin",27.8333333333333],' 'PARAMETER["central_meridian",-99],PARAMETER["false_easting",600000],' 'PARAMETER["false_northing",4000000],UNIT["metre",1,AUTHORITY["EPSG","9001"]],' - 'AUTHORITY["EPSG","32140"]]', + 'AXIS["Easting",EAST],AXIS["Northing",NORTH],AUTHORITY["EPSG","32140"]]', epsg=32140, projected=True, geographic=False, local=False, lin_name='metre', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, auth={'PROJCS': ('EPSG', '32140'), 'spheroid': ('EPSG', '7019'), 'unit': ('EPSG', '9001')}, @@ -48,25 +52,27 @@ srlist = ( ), ), TestSRS( - 'PROJCS["NAD_1983_StatePlane_Texas_South_Central_FIPS_4204_Feet",' - 'GEOGCS["GCS_North_American_1983",DATUM["North_American_Datum_1983",' - 'SPHEROID["GRS_1980",6378137.0,298.257222101]],PRIMEM["Greenwich",0.0],' + 'PROJCS["NAD83 / Texas South Central (ftUS)",' + 'GEOGCS["NAD83",DATUM["North_American_Datum_1983",' + 'SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],AUTHORITY["EPSG","6269"]],' + 'PRIMEM["Greenwich",0],' 'UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic_2SP"],' - 'PARAMETER["False_Easting",1968500.0],PARAMETER["False_Northing",13123333.33333333],' - 'PARAMETER["Central_Meridian",-99.0],PARAMETER["Standard_Parallel_1",28.38333333333333],' - 'PARAMETER["Standard_Parallel_2",30.28333333333334],PARAMETER["Latitude_Of_Origin",27.83333333333333],' - 'UNIT["Foot_US",0.3048006096012192]]', + 'PARAMETER["false_easting",1968500],PARAMETER["false_northing",13123333.3333333],' + 'PARAMETER["central_meridian",-99],PARAMETER["standard_parallel_1",28.3833333333333],' + 'PARAMETER["standard_parallel_2",30.2833333333333],PARAMETER["latitude_of_origin",27.8333333333333],' + 'UNIT["US survey foot",0.304800609601219],AXIS["Easting",EAST],AXIS["Northing",NORTH]]', epsg=None, projected=True, geographic=False, local=False, - lin_name='Foot_US', ang_name='Degree', lin_units=0.3048006096012192, ang_units=0.0174532925199, + lin_name='US survey foot', ang_name='Degree', lin_units=0.3048006096012192, ang_units=0.0174532925199, auth={'PROJCS': (None, None)}, - attr=(('PROJCS|GeOgCs|spheroid', 'GRS_1980'), (('projcs', 9), 'UNIT'), (('projcs', 11), None),), + attr=(('PROJCS|GeOgCs|spheroid', 'GRS 1980'), (('projcs', 9), 'UNIT'), (('projcs', 11), 'AXIS'),), ), # This is really ESRI format, not WKT -- but the import should work the same TestSRS( - 'LOCAL_CS["Non-Earth (Meter)",LOCAL_DATUM["Local Datum",0],UNIT["Meter",1.0],AXIS["X",EAST],AXIS["Y",NORTH]]', + 'LOCAL_CS["Non-Earth (Meter)",LOCAL_DATUM["Local Datum",32767],' + 'UNIT["Meter",1],AXIS["X",EAST],AXIS["Y",NORTH]]', esri=True, epsg=None, projected=False, geographic=False, local=True, lin_name='Meter', ang_name='degree', lin_units=1.0, ang_units=0.0174532925199, - attr=(('LOCAL_DATUM', 'Local Datum'), ('unit', 'Meter')), + attr=(('LOCAL_DATUM', 'Local Datum'),), ), ) @@ -146,7 +152,7 @@ bad_srlist = ( ) -class SpatialRefTest(unittest.TestCase): +class SpatialRefTest(SimpleTestCase): def test01_wkt(self): "Testing initialization on valid OGC WKT." @@ -168,7 +174,11 @@ class SpatialRefTest(unittest.TestCase): "Testing getting the WKT." for s in srlist: srs = SpatialReference(s.wkt) - self.assertEqual(s.wkt, srs.wkt) + # GDAL 3 strips UNIT part in the last occurrence. + self.assertEqual( + s.wkt.replace(',UNIT["Meter",1]', ''), + srs.wkt.replace(',UNIT["Meter",1]', ''), + ) def test04_proj(self): "Test PROJ.4 import and export." @@ -264,11 +274,11 @@ class SpatialRefTest(unittest.TestCase): 'GEOGCS["DHDN",DATUM["Deutsches_Hauptdreiecksnetz",' 'SPHEROID["Bessel 1841",6377397.155,299.1528128,AUTHORITY["EPSG","7004"]],AUTHORITY["EPSG","6314"]],' 'PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],' - 'UNIT["degree",0.01745329251994328,AUTHORITY["EPSG","9122"]],' - 'AUTHORITY["EPSG","4314"]],UNIT["metre",1,AUTHORITY["EPSG","9001"]],' - 'PROJECTION["Cassini_Soldner"],PARAMETER["latitude_of_origin",50.66738711],' - 'PARAMETER["central_meridian",6.28935703],PARAMETER["false_easting",0],' - 'PARAMETER["false_northing",0],AUTHORITY["mj10777.de","187939"],AXIS["x",NORTH],AXIS["y",EAST]]' + 'UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]],' + 'AUTHORITY["EPSG","4314"]],PROJECTION["Cassini_Soldner"],' + 'PARAMETER["latitude_of_origin",50.66738711],PARAMETER["central_meridian",6.28935703],' + 'PARAMETER["false_easting",0],PARAMETER["false_northing",0],' + 'UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["X",NORTH],AXIS["Y",EAST],AUTHORITY["mj10777.de","187939"]]' ) srs = SpatialReference(wkt) srs_list = [srs, srs.clone()] @@ -279,3 +289,31 @@ class SpatialRefTest(unittest.TestCase): self.assertEqual(srs.wkt, wkt) self.assertIn('Langschoß', srs.pretty_wkt) self.assertIn('Langschoß', srs.xml) + + @skipIf(GDAL_VERSION < (3, 0), 'GDAL >= 3.0 is required') + def test_axis_order(self): + wgs84_trad = SpatialReference(4326, axis_order=AxisOrder.TRADITIONAL) + wgs84_auth = SpatialReference(4326, axis_order=AxisOrder.AUTHORITY) + # Coordinate interpretation may depend on the srs axis predicate. + pt = GEOSGeometry('POINT (992385.4472045 481455.4944650)', 2774) + pt_trad = pt.transform(wgs84_trad, clone=True) + self.assertAlmostEqual(pt_trad.x, -104.609, 3) + self.assertAlmostEqual(pt_trad.y, 38.255, 3) + pt_auth = pt.transform(wgs84_auth, clone=True) + self.assertAlmostEqual(pt_auth.x, 38.255, 3) + self.assertAlmostEqual(pt_auth.y, -104.609, 3) + # clone() preserves the axis order. + pt_auth = pt.transform(wgs84_auth.clone(), clone=True) + self.assertAlmostEqual(pt_auth.x, 38.255, 3) + self.assertAlmostEqual(pt_auth.y, -104.609, 3) + + def test_axis_order_invalid(self): + msg = 'SpatialReference.axis_order must be an AxisOrder instance.' + with self.assertRaisesMessage(ValueError, msg): + SpatialReference(4326, axis_order='other') + + @skipIf(GDAL_VERSION > (3, 0), "GDAL < 3.0 doesn't support authority.") + def test_axis_order_non_traditional_invalid(self): + msg = 'AxisOrder.AUTHORITY is not supported in GDAL < 3.0.' + with self.assertRaisesMessage(ValueError, msg): + SpatialReference(4326, axis_order=AxisOrder.AUTHORITY) diff --git a/tests/gis_tests/geos_tests/test_geos.py b/tests/gis_tests/geos_tests/test_geos.py index e43561e67cf..ca493c87f12 100644 --- a/tests/gis_tests/geos_tests/test_geos.py +++ b/tests/gis_tests/geos_tests/test_geos.py @@ -828,8 +828,8 @@ class GEOSTest(SimpleTestCase, TestDataMixin): gdal.SpatialReference(4326)) new_pnt = pnt.transform(c2w, clone=True) self.assertEqual(new_pnt.srid, 4326) - self.assertAlmostEqual(new_pnt.x, 1, 3) - self.assertAlmostEqual(new_pnt.y, 2, 3) + self.assertAlmostEqual(new_pnt.x, 1, 1) + self.assertAlmostEqual(new_pnt.y, 2, 1) def test_mutable_geometries(self): "Testing the mutability of Polygons and Geometry Collections." diff --git a/tests/gis_tests/test_geoforms.py b/tests/gis_tests/test_geoforms.py index 0ce3b5f66b6..0360156b50e 100644 --- a/tests/gis_tests/test_geoforms.py +++ b/tests/gis_tests/test_geoforms.py @@ -28,7 +28,7 @@ class GeometryFieldTest(SimpleTestCase): # Making the field in a different SRID from that of the geometry, and # asserting it transforms. fld = forms.GeometryField(srid=32140) - tol = 0.0000001 + tol = 0.0001 xform_geom = GEOSGeometry('POINT (951640.547328465 4219369.26171664)', srid=32140) # The cleaned geometry is transformed to 32140 (the widget map_srid is 3857). cleaned_geom = fld.clean('SRID=3857;POINT (-10615777.40976205 3473169.895707852)') diff --git a/tests/gis_tests/test_spatialrefsys.py b/tests/gis_tests/test_spatialrefsys.py index 90e8084af1f..6c5a1b92184 100644 --- a/tests/gis_tests/test_spatialrefsys.py +++ b/tests/gis_tests/test_spatialrefsys.py @@ -11,7 +11,7 @@ test_srs = ({ # Only the beginning, because there are differences depending on installed libs 'srtext': 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"', # +ellps=WGS84 has been removed in the 4326 proj string in proj-4.8 - 'proj4_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ', + 'proj4_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?', 'spheroid': 'WGS 84', 'name': 'WGS 84', 'geographic': True, 'projected': False, 'spatialite': True, # From proj's "cs2cs -le" and Wikipedia (semi-minor only) @@ -37,9 +37,9 @@ test_srs = ({ 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",' 'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"' ), - 'proj4_re': r'\+proj=lcc \+lat_1=30.28333333333333 \+lat_2=28.38333333333333 \+lat_0=27.83333333333333 ' - r'\+lon_0=-99 \+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?' - r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ', + 'proj4_re': r'\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |' + r'\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?' + r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?', 'spheroid': 'GRS 1980', 'name': 'NAD83 / Texas South Central', 'geographic': False, 'projected': True, 'spatialite': False, # From proj's "cs2cs -le" and Wikipedia (semi-minor only)