'On Validation for GIS Locations (before DB I/O)'

@staticmethod
def gis_location_onvalidation(form):

    T = current.T
    db = current.db
    gis = current.gis
    auth = current.auth
    response = current.response
    settings = current.deployment_settings
    s3 = response.s3
    form_vars = form.vars
    vars_get = form_vars.get
    level = vars_get('level', None)
    parent = vars_get('parent', None)
    lat = vars_get('lat', None)
    lon = vars_get('lon', None)
    addr_street = vars_get('addr_street', None)
    bulk = s3.bulk
    if (addr_street and (lat is None) and (lon is None) and bulk):
        geocoder = settings.get_gis_geocode_imported_addresses()
        if geocoder:
            postcode = vars_get('postcode', None)
            if parent:
                Lx_ids = gis.get_parents(parent, ids_only=True)
                if Lx_ids:
                    Lx_ids.append(parent)
                else:
                    Lx_ids = [parent]
            else:
                Lx_ids = None
            results = gis.geocode(addr_street, postcode, Lx_ids, geocoder)
            if isinstance(results, basestring):
                if settings.get_gis_ignore_geocode_errors():
                    current.log.warning(('Geocoder:    %s' % results))
                elif (auth.override and (not settings.get_gis_check_within_parent_boundaries())):
                    current.log.warning(('Geocoder:    %s' % results))
                else:
                    form.errors['addr_street'] = results
                    return
            else:
                form_vars.lon = lon = results['lon']
                form_vars.lat = lat = results['lat']
    if lon:
        if (lon > 180):
            form_vars.lon = lon = (lon - 360)
        elif (lon < (-180)):
            form_vars.lon = lon = (lon + 360)
    MAP_ADMIN = auth.s3_has_role(current.session.s3.system_roles.MAP_ADMIN)
    if (not MAP_ADMIN):
        if level:
            editable = (level != 'L0')
            if (editable and (level in gis.hierarchy_level_keys)):
                if ((level == 'L1') and (not parent)):
                    response.error = error = T('L1    locations    need    to    be    within    a    Country')
                    form.errors['level'] = error
                    return
                child = (parent or current.request.vars.get('id', None))
                editable = gis_hierarchy_editable(level, child)
            if ((not editable) and (not s3.synchronise_uuids)):
                response.error = T('Sorry,    only    users    with    the    MapAdmin    role    are    allowed    to    edit    these    locations')
                form.errors['level'] = T('This    level    is    not    open    for    editing.')
                return
    if parent:
        table = db.gis_location
        _parent = db((table.id == parent)).select(table.level, limitby=(0, 1)).first()
    if (level and parent and _parent):
        if (level[1:] < _parent.level[1:]):
            response.error = ('%s:    %s' % (T("Parent    level    should    be    higher    than    this    record's    level.    Parent    level    is"), gis.get_location_hierarchy()[_parent.level]))
            form.errors['level'] = T("Level    is    higher    than    parent's")
            return
    strict = gis.get_strict_hierarchy()
    if strict:
        if (level == 'L0'):
            parent = ''
        elif (not parent):
            response.error = ('%s:    %s' % (T('Parent    needs    to    be    set    for    locations    of    level'), gis.get_location_hierarchy()[level]))
            form.errors['parent'] = T('Parent    needs    to    be    set')
            return
        elif (not level):
            max_hierarchy = gis.get_max_hierarchy_level()
            if (_parent.level != max_hierarchy):
                response.error = ('%s:    %s' % (T('Specific    locations    need    to    have    a    parent    of    level'), gis.get_location_hierarchy()[max_hierarchy]))
                form.errors['parent'] = T('Parent    needs    to    be    of    the    correct    level')
                return
        elif ((int(level[1:]) - 1) != int(_parent.level[1:])):
            response.error = ('%s:    %s' % (T('Locations    of    this    level    need    to    have    a    parent    of    level'), gis.get_location_hierarchy()[('L%i' % (int(level[1:]) - 1))]))
            form.errors['parent'] = T('Parent    needs    to    be    of    the    correct    level')
            return
    if (level != 'L0'):
        if ((not ('gis_feature_type' in form_vars)) or (form_vars.gis_feature_type == '1')):
            if (lat and lon):
                name = form_vars.name
                if (parent and settings.get_gis_check_within_parent_boundaries()):
                    (lat_min, lon_min, lat_max, lon_max, parent_name) = gis.get_parent_bounds(parent=parent)
                    if ((lat > lat_max) or (lat < lat_min)):
                        lat_error = (T('Latitude    %(lat)s    is    invalid,    should    be    between    %(lat_min)s    &    %(lat_max)s') % dict(lat=lat, lat_min=lat_min, lat_max=lat_max))
                        form.errors['lat'] = lat_error
                    if ((lon > lon_max) or (lon < lon_min)):
                        lon_error = (T('Longitude    %(lon)s    is    invalid,    should    be    between    %(lon_min)s    &    %(lon_max)s') % dict(lon=lon, lon_min=lon_min, lon_max=lon_max))
                        form.errors['lon'] = lon_error
                    if form.errors:
                        if name:
                            error = (T('Sorry    location    %(location)s    appears    to    be    outside    the    area    of    parent    %(parent)s.') % dict(location=name, parent=parent_name))
                        else:
                            error = (T('Sorry    location    appears    to    be    outside    the    area    of    parent    %(parent)s.') % dict(parent=parent_name))
                        response.error = error
                        current.log.error(error)
                        return
                else:
                    config = gis.get_config()
                    if (config.lat_min is not None):
                        lat_min = config.lat_min
                    else:
                        lat_min = (-90)
                    if (config.lon_min is not None):
                        lon_min = config.lon_min
                    else:
                        lon_min = (-180)
                    if (config.lat_max is not None):
                        lat_max = config.lat_max
                    else:
                        lat_max = 90
                    if (config.lon_max is not None):
                        lon_max = config.lon_max
                    else:
                        lon_max = 180
                    if ((lat > lat_max) or (lat < lat_min)):
                        if name:
                            error = (T('Sorry    location    %(location)s    appears    to    be    outside    the    area    supported    by    this    deployment.') % dict(location=name))
                        else:
                            error = T('Sorry    location    appears    to    be    outside    the    area    supported    by    this    deployment.')
                        response.error = error
                        current.log.error(error)
                        lat_error = (T('Latitude    %(lat)s    is    invalid,    should    be    between    %(lat_min)s    &    %(lat_max)s') % dict(lat=lat, lat_min=lat_min, lat_max=lat_max))
                        form.errors['lat'] = lat_error
                        current.log.error(lat_error)
                        return
                    elif ((lon > lon_max) or (lon < lon_min)):
                        if name:
                            error = (T('Sorry    location    %(location)s    appears    to    be    outside    the    area    supported    by    this    deployment.') % dict(location=name))
                        else:
                            error = T('Sorry    location    appears    to    be    outside    the    area    supported    by    this    deployment.')
                        response.error = error
                        current.log.error(error)
                        lon_error = (T('Longitude    %(lon)s    is    invalid,    should    be    between    %(lon_min)s    &    %(lon_max)s') % dict(lon=lon, lon_min=lon_min, lon_max=lon_max))
                        form.errors['lon'] = lon_error
                        current.log.error(lon_error)
                        return
    gis.wkt_centroid(form)
    record = form.record
    if (form_vars.wkt and (not (form_vars.wkt[:3] == 'POI'))):
        form_vars.inherited = False
    elif bulk:
        if ((form_vars.lat not in (None, '')) and (form_vars.lon not in (None, ''))):
            form_vars.inherited = False
    elif (record and hasattr(record, 'inherited') and record.inherited):
        if (hasattr(record, 'wkt') and (form_vars.wkt != record.wkt)):
            form_vars.inherited = False
