From 19fad1641408cd9db3053499296380e1a097cf3f Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Thu, 14 Jan 2010 17:43:46 +0000 Subject: [PATCH] Fixed #12591 -- Renamed `add_postgis_srs` to `add_srs_entry` (keeping backwards-compatible alias), added `database` keyword for multi-db, removed deprecated `SpatialBackend` references; no longer use `get_or_create` and look for existing entry based on SRID value. git-svn-id: http://code.djangoproject.com/svn/django/trunk@12228 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/utils/__init__.py | 2 +- django/contrib/gis/utils/srs.py | 86 ++++++++++++++++++---------- 2 files changed, 58 insertions(+), 30 deletions(-) diff --git a/django/contrib/gis/utils/__init__.py b/django/contrib/gis/utils/__init__.py index f336bcadbf..1cff4d9e04 100644 --- a/django/contrib/gis/utils/__init__.py +++ b/django/contrib/gis/utils/__init__.py @@ -6,7 +6,7 @@ from django.contrib.gis.gdal import HAS_GDAL if HAS_GDAL: from django.contrib.gis.utils.ogrinfo import ogrinfo, sample from django.contrib.gis.utils.ogrinspect import mapping, ogrinspect - from django.contrib.gis.utils.srs import add_postgis_srs + from django.contrib.gis.utils.srs import add_postgis_srs, add_srs_entry try: # LayerMapping requires DJANGO_SETTINGS_MODULE to be set, # so this needs to be in try/except. diff --git a/django/contrib/gis/utils/srs.py b/django/contrib/gis/utils/srs.py index 3fbf5d6103..989929eb61 100644 --- a/django/contrib/gis/utils/srs.py +++ b/django/contrib/gis/utils/srs.py @@ -1,49 +1,77 @@ -def add_postgis_srs(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None): - """ - This function takes a GDAL SpatialReference system and adds its - information to the PostGIS `spatial_ref_sys` table -- enabling - spatial transformations with PostGIS. This is handy for adding - spatial reference systems not included by default with PostGIS. - For example, the following adds the so-called "Google Maps Mercator - Projection" (available in GDAL 1.5): +from django.contrib.gis.gdal import SpatialReference +from django.db import connections, DEFAULT_DB_ALIAS - >>> add_postgis_srs(SpatialReference(900913)) +def add_srs_entry(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None, + database=DEFAULT_DB_ALIAS): + """ + This function takes a GDAL SpatialReference system and adds its information + to the `spatial_ref_sys` table of the spatial backend. Doing this enables + database-level spatial transformations for the backend. Thus, this utility + is useful for adding spatial reference systems not included by default with + the backend -- for example, the so-called "Google Maps Mercator Projection" + is excluded in PostGIS 1.3 and below, and the following adds it to the + `spatial_ref_sys` table: + + >>> from django.contrib.gis.utils import add_srs_entry + >>> add_srs_entry(900913) Keyword Arguments: - auth_name: This keyword may be customized with the value of the - `auth_name` field. Defaults to 'EPSG'. + auth_name: + This keyword may be customized with the value of the `auth_name` field. + Defaults to 'EPSG'. - auth_srid: This keyword may be customized with the value of the - `auth_srid` field. Defaults to the SRID determined - by GDAL. + auth_srid: + This keyword may be customized with the value of the `auth_srid` field. + Defaults to the SRID determined by GDAL. - ref_sys_name: For SpatiaLite users only, sets the value of the - the `ref_sys_name` field. Defaults to the name - determined by GDAL. + ref_sys_name: + For SpatiaLite users only, sets the value of the the `ref_sys_name` field. + Defaults to the name determined by GDAL. + + database: + The name of the database connection to use; the default is the value + of `django.db.DEFAULT_DB_ALIAS` (at the time of this writing, it's value + is 'default'). """ - from django.contrib.gis.db.backend import SpatialBackend - from django.contrib.gis.models import SpatialRefSys - from django.contrib.gis.gdal import SpatialReference - - if SpatialBackend.oracle or SpatialBackend.mysql: - raise Exception('This utility not supported on Oracle or MySQL spatial backends.') + connection = connections[database] + if not hasattr(connection.ops, 'spatial_version'): + raise Exception('The `add_srs_entry` utility only works ' + 'with spatial backends.') + if connection.ops.oracle or connection.ops.mysql: + raise Exception('This utility does not support the ' + 'Oracle or MySQL spatial backends.') + SpatialRefSys = connection.ops.spatial_ref_sys() + # If argument is not a `SpatialReference` instance, use it as parameter + # to construct a `SpatialReference` instance. if not isinstance(srs, SpatialReference): srs = SpatialReference(srs) if srs.srid is None: - raise Exception('Spatial reference requires an SRID to be compatible with PostGIS.') + raise Exception('Spatial reference requires an SRID to be ' + 'compatible with the spatial backend.') - # Initializing the keyword arguments dictionary for both PostGIS and SpatiaLite. + # Initializing the keyword arguments dictionary for both PostGIS + # and SpatiaLite. kwargs = {'srid' : srs.srid, 'auth_name' : auth_name, 'auth_srid' : auth_srid or srs.srid, 'proj4text' : srs.proj4, } - # Backend-specific keyword settings. - if SpatialBackend.postgis: kwargs['srtext'] = srs.wkt - if SpatialBackend.spatialite: kwargs['ref_sys_name'] = ref_sys_name or srs.name + # Backend-specific fields for the SpatialRefSys model. + if connection.ops.postgis: + kwargs['srtext'] = srs.wkt + if connection.ops.spatialite: + kwargs['ref_sys_name'] = ref_sys_name or srs.name # Creating the spatial_ref_sys model. - sr, created = SpatialRefSys.objects.get_or_create(**kwargs) + try: + # Try getting via SRID only, because using all kwargs may + # differ from exact wkt/proj in database. + sr = SpatialRefSys.objects.get(srid=srs.srid) + except SpatialRefSys.DoesNotExist: + sr = SpatialRefSys.objects.create(**kwargs) + +# Alias is for backwards-compatibility purposes. +add_postgis_srs = add_srs_entry