web/lib/django/contrib/gis/utils/srs.py
author ymh <ymh.work@gmail.com>
Wed, 02 Jun 2010 18:57:35 +0200
changeset 38 77b6da96e6f1
permissions -rw-r--r--
update django
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     1
from django.contrib.gis.gdal import SpatialReference
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     2
from django.db import connections, DEFAULT_DB_ALIAS
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     3
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     4
def add_srs_entry(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     5
                  database=DEFAULT_DB_ALIAS):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     6
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     7
    This function takes a GDAL SpatialReference system and adds its information
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     8
    to the `spatial_ref_sys` table of the spatial backend.  Doing this enables
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
     9
    database-level spatial transformations for the backend.  Thus, this utility
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    10
    is useful for adding spatial reference systems not included by default with
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    11
    the backend -- for example, the so-called "Google Maps Mercator Projection"
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    12
    is excluded in PostGIS 1.3 and below, and the following adds it to the
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    13
    `spatial_ref_sys` table:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    14
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    15
    >>> from django.contrib.gis.utils import add_srs_entry
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    16
    >>> add_srs_entry(900913)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    17
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    18
    Keyword Arguments:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    19
     auth_name:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    20
       This keyword may be customized with the value of the `auth_name` field.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    21
       Defaults to 'EPSG'.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    22
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    23
     auth_srid:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    24
       This keyword may be customized with the value of the `auth_srid` field.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    25
       Defaults to the SRID determined by GDAL.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    26
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    27
     ref_sys_name:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    28
       For SpatiaLite users only, sets the value of the the `ref_sys_name` field.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    29
       Defaults to the name determined by GDAL.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    30
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    31
     database:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    32
      The name of the database connection to use; the default is the value
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    33
      of `django.db.DEFAULT_DB_ALIAS` (at the time of this writing, it's value
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    34
      is 'default').
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    35
    """
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    36
    connection = connections[database]
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    37
    if not hasattr(connection.ops, 'spatial_version'):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    38
        raise Exception('The `add_srs_entry` utility only works '
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    39
                        'with spatial backends.')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    40
    if connection.ops.oracle or connection.ops.mysql:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    41
        raise Exception('This utility does not support the '
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    42
                        'Oracle or MySQL spatial backends.')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    43
    SpatialRefSys = connection.ops.spatial_ref_sys()
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    44
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    45
    # If argument is not a `SpatialReference` instance, use it as parameter
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    46
    # to construct a `SpatialReference` instance.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    47
    if not isinstance(srs, SpatialReference):
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    48
        srs = SpatialReference(srs)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    49
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    50
    if srs.srid is None:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    51
        raise Exception('Spatial reference requires an SRID to be '
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    52
                        'compatible with the spatial backend.')
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    53
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    54
    # Initializing the keyword arguments dictionary for both PostGIS
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    55
    # and SpatiaLite.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    56
    kwargs = {'srid' : srs.srid,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    57
              'auth_name' : auth_name,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    58
              'auth_srid' : auth_srid or srs.srid,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    59
              'proj4text' : srs.proj4,
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    60
              }
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    61
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    62
    # Backend-specific fields for the SpatialRefSys model.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    63
    if connection.ops.postgis:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    64
        kwargs['srtext'] = srs.wkt
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    65
    if connection.ops.spatialite:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    66
        kwargs['ref_sys_name'] = ref_sys_name or srs.name
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    67
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    68
    # Creating the spatial_ref_sys model.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    69
    try:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    70
        # Try getting via SRID only, because using all kwargs may
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    71
        # differ from exact wkt/proj in database.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    72
        sr = SpatialRefSys.objects.get(srid=srs.srid)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    73
    except SpatialRefSys.DoesNotExist:
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    74
        sr = SpatialRefSys.objects.create(**kwargs)
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    75
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    76
# Alias is for backwards-compatibility purposes.
77b6da96e6f1 update django
ymh <ymh.work@gmail.com>
parents:
diff changeset
    77
add_postgis_srs = add_srs_entry