'DRY routine for calling a spatial stored procedure on a geometry column
and attaching its output as an attribute of the model.
Arguments:
att:
The name of the spatial attribute that holds the spatial
SQL function to call.
settings:
Dictonary of internal settings to customize for the spatial procedure.
Public Keyword Arguments:
field_name:
The name of the geographic field to call the spatial
function on.  May also be a lookup to a geometry field
as part of a foreign key relation.
model_att:
The name of the model attribute to attach the output of
the spatial function to.'

def _spatial_attribute(self, att, settings, field_name=None, model_att=None):

    settings.setdefault('desc', None)
    settings.setdefault('geom_args', ())
    settings.setdefault('geom_field', None)
    settings.setdefault('procedure_args', {})
    settings.setdefault('procedure_fmt', '%(geo_col)s')
    settings.setdefault('select_params', [])
    connection = connections[self.db]
    backend = connection.ops
    if settings.get('setup', True):
        (default_args, geo_field) = self._spatial_setup(att, desc=settings['desc'], field_name=field_name, geo_field_type=settings.get('geo_field_type', None))
        for (k, v) in six.iteritems(default_args):
            settings['procedure_args'].setdefault(k, v)
    else:
        geo_field = settings['geo_field']
    if (not isinstance(model_att, six.string_types)):
        model_att = att
    for name in settings['geom_args']:
        geom = geo_field.get_prep_value(settings['procedure_args'][name])
        params = geo_field.get_db_prep_lookup('contains', geom, connection=connection)
        geom_placeholder = geo_field.get_placeholder(geom, connection)
        old_fmt = ('%%(%s)s' % name)
        new_fmt = (geom_placeholder % '%%s')
        settings['procedure_fmt'] = settings['procedure_fmt'].replace(old_fmt, new_fmt)
        settings['select_params'].extend(params)
    fmt = ('%%(function)s(%s)' % settings['procedure_fmt'])
    if settings.get('select_field', False):
        sel_fld = settings['select_field']
        if (isinstance(sel_fld, GeomField) and backend.select):
            self.query.custom_select[model_att] = backend.select
        if connection.ops.oracle:
            sel_fld.empty_strings_allowed = False
        self.query.extra_select_fields[model_att] = sel_fld
    return self.extra(select={model_att: (fmt % settings['procedure_args'])}, select_params=settings['select_params'])
