2016-04-19 17:35:50 +08:00
|
|
|
import re
|
2013-07-01 20:22:27 +08:00
|
|
|
|
2020-09-14 13:58:05 +08:00
|
|
|
from django.db import connection
|
2016-12-08 06:42:31 +08:00
|
|
|
from django.test import TestCase, skipUnlessDBFeature
|
2020-09-14 13:58:05 +08:00
|
|
|
from django.utils.functional import cached_property
|
2010-10-11 20:55:17 +08:00
|
|
|
|
2014-09-04 20:15:09 +08:00
|
|
|
test_srs = (
|
|
|
|
{
|
|
|
|
"srid": 4326,
|
|
|
|
"auth_name": ("EPSG", True),
|
|
|
|
"auth_srid": 4326,
|
|
|
|
# Only the beginning, because there are differences depending on installed libs
|
|
|
|
"srtext": 'GEOGCS["WGS 84",DATUM["WGS_1984",SPHEROID["WGS 84"',
|
2020-05-11 04:30:03 +08:00
|
|
|
"proj_re": (
|
2023-01-12 01:30:10 +08:00
|
|
|
r"\+proj=longlat (\+datum=WGS84 |\+towgs84=0,0,0,0,0,0,0 )\+no_defs ?"
|
2020-05-11 04:30:03 +08:00
|
|
|
),
|
2014-09-04 20:15:09 +08:00
|
|
|
"spheroid": "WGS 84",
|
|
|
|
"name": "WGS 84",
|
|
|
|
"geographic": True,
|
|
|
|
"projected": False,
|
|
|
|
"spatialite": True,
|
|
|
|
# From proj's "cs2cs -le" and Wikipedia (semi-minor only)
|
|
|
|
"ellipsoid": (6378137.0, 6356752.3, 298.257223563),
|
|
|
|
"eprec": (1, 1, 9),
|
2016-09-17 00:15:00 +08:00
|
|
|
"wkt": re.sub(
|
|
|
|
r"[\s+]",
|
|
|
|
"",
|
|
|
|
"""
|
2016-04-19 17:35:50 +08:00
|
|
|
GEOGCS["WGS 84",
|
|
|
|
DATUM["WGS_1984",
|
|
|
|
SPHEROID["WGS 84",6378137,298.257223563,
|
|
|
|
AUTHORITY["EPSG","7030"]],
|
|
|
|
AUTHORITY["EPSG","6326"]],
|
|
|
|
PRIMEM["Greenwich",0,
|
|
|
|
AUTHORITY["EPSG","8901"]],
|
|
|
|
UNIT["degree",0.01745329251994328,
|
|
|
|
AUTHORITY["EPSG","9122"]],
|
|
|
|
AUTHORITY["EPSG","4326"]]
|
|
|
|
""",
|
2022-02-04 03:24:19 +08:00
|
|
|
),
|
2014-09-04 20:15:09 +08:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"srid": 32140,
|
|
|
|
"auth_name": ("EPSG", False),
|
|
|
|
"auth_srid": 32140,
|
|
|
|
"srtext": (
|
|
|
|
'PROJCS["NAD83 / Texas South Central",GEOGCS["NAD83",'
|
|
|
|
'DATUM["North_American_Datum_1983",SPHEROID["GRS 1980"'
|
|
|
|
),
|
2020-05-11 04:30:03 +08:00
|
|
|
"proj_re": (
|
|
|
|
r"\+proj=lcc (\+lat_1=30.28333333333333? |\+lat_2=28.38333333333333? "
|
|
|
|
r"|\+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 ?"
|
|
|
|
),
|
2014-09-04 20:15:09 +08:00
|
|
|
"spheroid": "GRS 1980",
|
|
|
|
"name": "NAD83 / Texas South Central",
|
|
|
|
"geographic": False,
|
|
|
|
"projected": True,
|
|
|
|
"spatialite": False,
|
|
|
|
# From proj's "cs2cs -le" and Wikipedia (semi-minor only)
|
|
|
|
"ellipsoid": (6378137.0, 6356752.31414, 298.257222101),
|
|
|
|
"eprec": (1, 5, 10),
|
|
|
|
},
|
|
|
|
)
|
2008-08-06 02:13:06 +08:00
|
|
|
|
2013-11-03 04:12:09 +08:00
|
|
|
|
2014-08-20 00:11:10 +08:00
|
|
|
@skipUnlessDBFeature("has_spatialrefsys_table")
|
2016-12-08 06:42:31 +08:00
|
|
|
class SpatialRefSysTest(TestCase):
|
2020-09-14 13:58:05 +08:00
|
|
|
@cached_property
|
|
|
|
def SpatialRefSys(self):
|
|
|
|
return connection.ops.connection.ops.spatial_ref_sys()
|
|
|
|
|
2016-04-19 17:35:50 +08:00
|
|
|
def test_get_units(self):
|
|
|
|
epsg_4326 = next(f for f in test_srs if f["srid"] == 4326)
|
2020-09-14 13:58:05 +08:00
|
|
|
unit, unit_name = self.SpatialRefSys().get_units(epsg_4326["wkt"])
|
2016-04-19 17:35:50 +08:00
|
|
|
self.assertEqual(unit_name, "degree")
|
|
|
|
self.assertAlmostEqual(unit, 0.01745329251994328)
|
|
|
|
|
2014-01-30 16:37:15 +08:00
|
|
|
def test_retrieve(self):
|
|
|
|
"""
|
|
|
|
Test retrieval of SpatialRefSys model objects.
|
|
|
|
"""
|
2008-08-06 02:13:06 +08:00
|
|
|
for sd in test_srs:
|
2020-09-14 13:58:05 +08:00
|
|
|
srs = self.SpatialRefSys.objects.get(srid=sd["srid"])
|
2008-08-06 02:13:06 +08:00
|
|
|
self.assertEqual(sd["srid"], srs.srid)
|
|
|
|
|
|
|
|
# Some of the authority names are borked on Oracle, e.g., SRID=32140.
|
|
|
|
# also, Oracle Spatial seems to add extraneous info to fields, hence the
|
|
|
|
# the testing with the 'startswith' flag.
|
|
|
|
auth_name, oracle_flag = sd["auth_name"]
|
2020-11-14 22:08:30 +08:00
|
|
|
# Compare case-insensitively because srs.auth_name is lowercase
|
|
|
|
# ("epsg") on Spatialite.
|
|
|
|
if not connection.ops.oracle or oracle_flag:
|
|
|
|
self.assertIs(srs.auth_name.upper().startswith(auth_name), True)
|
2010-10-11 20:55:17 +08:00
|
|
|
|
2008-08-06 02:13:06 +08:00
|
|
|
self.assertEqual(sd["auth_srid"], srs.auth_srid)
|
|
|
|
|
2020-11-14 22:08:30 +08:00
|
|
|
# No PROJ and different srtext on Oracle.
|
|
|
|
if not connection.ops.oracle:
|
2012-09-13 22:17:32 +08:00
|
|
|
self.assertTrue(srs.wkt.startswith(sd["srtext"]))
|
2020-05-11 04:30:03 +08:00
|
|
|
self.assertRegex(srs.proj4text, sd["proj_re"])
|
2008-08-06 02:13:06 +08:00
|
|
|
|
2014-01-30 16:37:15 +08:00
|
|
|
def test_osr(self):
|
|
|
|
"""
|
|
|
|
Test getting OSR objects from SpatialRefSys model objects.
|
|
|
|
"""
|
2008-08-06 02:13:06 +08:00
|
|
|
for sd in test_srs:
|
2020-09-14 13:58:05 +08:00
|
|
|
sr = self.SpatialRefSys.objects.get(srid=sd["srid"])
|
2015-04-27 22:59:16 +08:00
|
|
|
self.assertTrue(sr.spheroid.startswith(sd["spheroid"]))
|
2008-08-06 02:13:06 +08:00
|
|
|
self.assertEqual(sd["geographic"], sr.geographic)
|
|
|
|
self.assertEqual(sd["projected"], sr.projected)
|
2020-11-14 22:08:30 +08:00
|
|
|
self.assertIs(sr.name.startswith(sd["name"]), True)
|
2008-08-06 02:13:06 +08:00
|
|
|
# Testing the SpatialReference object directly.
|
2020-11-14 22:08:30 +08:00
|
|
|
if not connection.ops.oracle:
|
2008-08-06 02:13:06 +08:00
|
|
|
srs = sr.srs
|
2020-05-11 04:30:03 +08:00
|
|
|
self.assertRegex(srs.proj, sd["proj_re"])
|
2016-05-31 23:31:51 +08:00
|
|
|
self.assertTrue(srs.wkt.startswith(sd["srtext"]))
|
2008-08-06 02:13:06 +08:00
|
|
|
|
2014-01-30 16:37:15 +08:00
|
|
|
def test_ellipsoid(self):
|
|
|
|
"""
|
|
|
|
Test the ellipsoid property.
|
|
|
|
"""
|
2008-08-06 02:13:06 +08:00
|
|
|
for sd in test_srs:
|
|
|
|
# Getting the ellipsoid and precision parameters.
|
|
|
|
ellps1 = sd["ellipsoid"]
|
|
|
|
prec = sd["eprec"]
|
|
|
|
|
|
|
|
# Getting our spatial reference and its ellipsoid
|
2020-09-14 13:58:05 +08:00
|
|
|
srs = self.SpatialRefSys.objects.get(srid=sd["srid"])
|
2008-08-06 02:13:06 +08:00
|
|
|
ellps2 = srs.ellipsoid
|
|
|
|
|
|
|
|
for i in range(3):
|
|
|
|
self.assertAlmostEqual(ellps1[i], ellps2[i], prec[i])
|
|
|
|
|
2014-09-18 03:55:34 +08:00
|
|
|
@skipUnlessDBFeature("supports_add_srs_entry")
|
2014-01-30 16:37:15 +08:00
|
|
|
def test_add_entry(self):
|
|
|
|
"""
|
|
|
|
Test adding a new entry in the SpatialRefSys model using the
|
|
|
|
add_srs_entry utility.
|
|
|
|
"""
|
2014-02-03 03:03:23 +08:00
|
|
|
from django.contrib.gis.utils import add_srs_entry
|
|
|
|
|
2014-04-18 03:10:41 +08:00
|
|
|
add_srs_entry(3857)
|
2020-09-14 13:58:05 +08:00
|
|
|
self.assertTrue(self.SpatialRefSys.objects.filter(srid=3857).exists())
|
|
|
|
srs = self.SpatialRefSys.objects.get(srid=3857)
|
2014-01-30 16:37:15 +08:00
|
|
|
self.assertTrue(
|
2020-09-14 13:58:05 +08:00
|
|
|
self.SpatialRefSys.get_spheroid(srs.wkt).startswith("SPHEROID[")
|
2014-01-30 16:37:15 +08:00
|
|
|
)
|