srs.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. from django.contrib.gis.gdal import SpatialReference
  2. from django.db import DEFAULT_DB_ALIAS, connections
  3. def add_srs_entry(
  4. srs, auth_name="EPSG", auth_srid=None, ref_sys_name=None, database=None
  5. ):
  6. """
  7. Take a GDAL SpatialReference system and add its information to the
  8. `spatial_ref_sys` table of the spatial backend. Doing this enables
  9. database-level spatial transformations for the backend. Thus, this utility
  10. is useful for adding spatial reference systems not included by default with
  11. the backend:
  12. >>> from django.contrib.gis.utils import add_srs_entry
  13. >>> add_srs_entry(3857)
  14. Keyword Arguments:
  15. auth_name:
  16. This keyword may be customized with the value of the `auth_name` field.
  17. Defaults to 'EPSG'.
  18. auth_srid:
  19. This keyword may be customized with the value of the `auth_srid` field.
  20. Defaults to the SRID determined by GDAL.
  21. ref_sys_name:
  22. For SpatiaLite users only, sets the value of the `ref_sys_name` field.
  23. Defaults to the name determined by GDAL.
  24. database:
  25. The name of the database connection to use; the default is the value
  26. of `django.db.DEFAULT_DB_ALIAS` (at the time of this writing, its value
  27. is 'default').
  28. """
  29. database = database or DEFAULT_DB_ALIAS
  30. connection = connections[database]
  31. if not hasattr(connection.ops, "spatial_version"):
  32. raise Exception("The `add_srs_entry` utility only works with spatial backends.")
  33. if not connection.features.supports_add_srs_entry:
  34. raise Exception("This utility does not support your database backend.")
  35. SpatialRefSys = connection.ops.spatial_ref_sys()
  36. # If argument is not a `SpatialReference` instance, use it as parameter
  37. # to construct a `SpatialReference` instance.
  38. if not isinstance(srs, SpatialReference):
  39. srs = SpatialReference(srs)
  40. if srs.srid is None:
  41. raise Exception(
  42. "Spatial reference requires an SRID to be "
  43. "compatible with the spatial backend."
  44. )
  45. # Initializing the keyword arguments dictionary for both PostGIS
  46. # and SpatiaLite.
  47. kwargs = {
  48. "srid": srs.srid,
  49. "auth_name": auth_name,
  50. "auth_srid": auth_srid or srs.srid,
  51. "proj4text": srs.proj4,
  52. }
  53. # Backend-specific fields for the SpatialRefSys model.
  54. srs_field_names = {f.name for f in SpatialRefSys._meta.get_fields()}
  55. if "srtext" in srs_field_names:
  56. kwargs["srtext"] = srs.wkt
  57. if "ref_sys_name" in srs_field_names:
  58. # SpatiaLite specific
  59. kwargs["ref_sys_name"] = ref_sys_name or srs.name
  60. # Creating the spatial_ref_sys model.
  61. try:
  62. # Try getting via SRID only, because using all kwargs may
  63. # differ from exact wkt/proj in database.
  64. SpatialRefSys.objects.using(database).get(srid=srs.srid)
  65. except SpatialRefSys.DoesNotExist:
  66. SpatialRefSys.objects.using(database).create(**kwargs)