test_spatialrefsys.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import re
  2. from django.test import TestCase, skipUnlessDBFeature
  3. from .utils import SpatialRefSys, oracle, postgis, spatialite
  4. test_srs = ({
  5. 'srid': 4326,
  6. 'auth_name': ('EPSG', True),
  7. 'auth_srid': 4326,
  8. # Only the beginning, because there are differences depending on installed libs
  9. 'srtext': 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"',
  10. # +ellps=WGS84 has been removed in the 4326 proj string in proj-4.8
  11. 'proj_re': r'\+proj=longlat (\+ellps=WGS84 )?(\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?',
  12. 'spheroid': 'WGS 84', 'name': 'WGS 84',
  13. 'geographic': True, 'projected': False, 'spatialite': True,
  14. # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
  15. 'ellipsoid': (6378137.0, 6356752.3, 298.257223563),
  16. 'eprec': (1, 1, 9),
  17. 'wkt': re.sub(r'[\s+]', '', """
  18. GEOGCS["WGS 84",
  19. DATUM["WGS_1984",
  20. SPHEROID["WGS 84",6378137,298.257223563,
  21. AUTHORITY["EPSG","7030"]],
  22. AUTHORITY["EPSG","6326"]],
  23. PRIMEM["Greenwich",0,
  24. AUTHORITY["EPSG","8901"]],
  25. UNIT["degree",0.01745329251994328,
  26. AUTHORITY["EPSG","9122"]],
  27. AUTHORITY["EPSG","4326"]]
  28. """)
  29. }, {
  30. 'srid': 32140,
  31. 'auth_name': ('EPSG', False),
  32. 'auth_srid': 32140,
  33. 'srtext': (
  34. 'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",'
  35. 'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"'
  36. ),
  37. 'proj_re': r'\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? |\+lat_0=27.83333333333333? |'
  38. r'\+lon_0=-99 ){4}\+x_0=600000 \+y_0=4000000 (\+ellps=GRS80 )?'
  39. r'(\+datum=NAD83 |\+towgs84=0,0,0,0,0,0,0 )?\+units=m \+no_defs ?',
  40. 'spheroid': 'GRS 1980', 'name': 'NAD83 / Texas South Central',
  41. 'geographic': False, 'projected': True, 'spatialite': False,
  42. # From proj's "cs2cs -le" and Wikipedia (semi-minor only)
  43. 'ellipsoid': (6378137.0, 6356752.31414, 298.257222101),
  44. 'eprec': (1, 5, 10),
  45. })
  46. @skipUnlessDBFeature("has_spatialrefsys_table")
  47. class SpatialRefSysTest(TestCase):
  48. def test_get_units(self):
  49. epsg_4326 = next(f for f in test_srs if f['srid'] == 4326)
  50. unit, unit_name = SpatialRefSys().get_units(epsg_4326['wkt'])
  51. self.assertEqual(unit_name, 'degree')
  52. self.assertAlmostEqual(unit, 0.01745329251994328)
  53. def test_retrieve(self):
  54. """
  55. Test retrieval of SpatialRefSys model objects.
  56. """
  57. for sd in test_srs:
  58. srs = SpatialRefSys.objects.get(srid=sd['srid'])
  59. self.assertEqual(sd['srid'], srs.srid)
  60. # Some of the authority names are borked on Oracle, e.g., SRID=32140.
  61. # also, Oracle Spatial seems to add extraneous info to fields, hence the
  62. # the testing with the 'startswith' flag.
  63. auth_name, oracle_flag = sd['auth_name']
  64. if postgis or (oracle and oracle_flag):
  65. self.assertTrue(srs.auth_name.startswith(auth_name))
  66. self.assertEqual(sd['auth_srid'], srs.auth_srid)
  67. # No PROJ and different srtext on oracle backends :(
  68. if postgis:
  69. self.assertTrue(srs.wkt.startswith(sd['srtext']))
  70. self.assertRegex(srs.proj4text, sd['proj_re'])
  71. def test_osr(self):
  72. """
  73. Test getting OSR objects from SpatialRefSys model objects.
  74. """
  75. for sd in test_srs:
  76. sr = SpatialRefSys.objects.get(srid=sd['srid'])
  77. self.assertTrue(sr.spheroid.startswith(sd['spheroid']))
  78. self.assertEqual(sd['geographic'], sr.geographic)
  79. self.assertEqual(sd['projected'], sr.projected)
  80. if not (spatialite and not sd['spatialite']):
  81. # Can't get 'NAD83 / Texas South Central' from PROJ string
  82. # on SpatiaLite
  83. self.assertTrue(sr.name.startswith(sd['name']))
  84. # Testing the SpatialReference object directly.
  85. if postgis or spatialite:
  86. srs = sr.srs
  87. self.assertRegex(srs.proj, sd['proj_re'])
  88. self.assertTrue(srs.wkt.startswith(sd['srtext']))
  89. def test_ellipsoid(self):
  90. """
  91. Test the ellipsoid property.
  92. """
  93. for sd in test_srs:
  94. # Getting the ellipsoid and precision parameters.
  95. ellps1 = sd['ellipsoid']
  96. prec = sd['eprec']
  97. # Getting our spatial reference and its ellipsoid
  98. srs = SpatialRefSys.objects.get(srid=sd['srid'])
  99. ellps2 = srs.ellipsoid
  100. for i in range(3):
  101. self.assertAlmostEqual(ellps1[i], ellps2[i], prec[i])
  102. @skipUnlessDBFeature('supports_add_srs_entry')
  103. def test_add_entry(self):
  104. """
  105. Test adding a new entry in the SpatialRefSys model using the
  106. add_srs_entry utility.
  107. """
  108. from django.contrib.gis.utils import add_srs_entry
  109. add_srs_entry(3857)
  110. self.assertTrue(
  111. SpatialRefSys.objects.filter(srid=3857).exists()
  112. )
  113. srs = SpatialRefSys.objects.get(srid=3857)
  114. self.assertTrue(
  115. SpatialRefSys.get_spheroid(srs.wkt).startswith('SPHEROID[')
  116. )