'Import Locations from the Geonames database
@param country: the 2-letter country code
@param level: the ADM level to import
Designed to be run from the CLI
Levels should be imported sequentially.
It is assumed that L0 exists in the DB already
L1-L3 may have been imported from Shapefiles with Polygon info
Geonames can then be used to populate the lower levels of hierarchy'

def import_geonames(self, country, level=None):

    import codecs
    from shapely.geometry import point
    from shapely.geos import ReadingError
    from shapely.wkt import loads as wkt_loads
    try:
        from shapely import speedups
        speedups.enable()
    except:
        current.log.info('S3GIS', 'Upgrade    Shapely    for    Performance    enhancements')
    db = current.db
    s3db = current.s3db
    request = current.request
    table = s3db.gis_location
    ttable = s3db.gis_location_tag
    url = (('http://download.geonames.org/export/dump/' + country) + '.zip')
    cachepath = os.path.join(request.folder, 'cache')
    filename = (country + '.txt')
    filepath = os.path.join(cachepath, filename)
    if os.access(filepath, os.R_OK):
        cached = True
    else:
        cached = False
        if (not os.access(cachepath, os.W_OK)):
            current.log.error('Folder    not    writable', cachepath)
            return
    if (not cached):
        from gluon.tools import fetch
        try:
            f = fetch(url)
        except (urllib2.URLError,):
            e = sys.exc_info()[1]
            current.log.error('URL    Error', e)
            return
        except (urllib2.HTTPError,):
            e = sys.exc_info()[1]
            current.log.error('HTTP    Error', e)
            return
        if (f[:2] == 'PK'):
            fp = StringIO(f)
            import zipfile
            myfile = zipfile.ZipFile(fp)
            try:
                myfile.extract(filename, cachepath)
                myfile.close()
            except IOError:
                current.log.error("Zipfile    contents    don't    seem    correct!")
                myfile.close()
                return
    f = codecs.open(filepath, encoding='utf-8')
    if (level == 'L1'):
        fc = 'ADM1'
        parent_level = 'L0'
    elif (level == 'L2'):
        fc = 'ADM2'
        parent_level = 'L1'
    elif (level == 'L3'):
        fc = 'ADM3'
        parent_level = 'L2'
    elif (level == 'L4'):
        fc = 'ADM4'
        parent_level = 'L3'
    else:
        try:
            level = 'L5'
            parent_level = 'L4'
        except:
            level = 'L4'
            parent_level = 'L3'
        finally:
            fc = 'PPL'
    deleted = (table.deleted == False)
    query = (deleted & (table.level == parent_level))
    all_parents = db(query).select(table.wkt, table.lon_min, table.lon_max, table.lat_min, table.lat_max, table.id)
    if (not all_parents):
        parent_level = ('L' + str((int(parent_level[1:]) + 1)))
        query = (deleted & (table.level == parent_level))
        all_parents = db(query).select(table.wkt, table.lon_min, table.lon_max, table.lat_min, table.lat_max, table.id)
    current_row = 0
    for line in f:
        current_row += 1
        (geonameid, name, asciiname, alternatenames, lat, lon, feature_class, feature_code, country_code, cc2, admin1_code, admin2_code, admin3_code, admin4_code, population, elevation, gtopo30, timezone, modification_date) = line.split(' DCTB ')
        if (feature_code == fc):
            lat = float(lat)
            lon = float(lon)
            wkt = self.latlon_to_wkt(lat, lon)
            shape = point.Point(lon, lat)
            lon_min = lon_max = lon
            lat_min = lat_max = lat
            parent = ''
            def in_bbox(row):
                return ((((row.lon_min < lon_min) & (row.lon_max > lon_max)) & (row.lat_min < lat_min)) & (row.lat_max > lat_max))
            for row in all_parents.find((lambda row: in_bbox(row))):
                try:
                    parent_shape = wkt_loads(row.wkt)
                    if parent_shape.intersects(shape):
                        parent = row.id
                        break
                except ReadingError:
                    current.log.error('Error    reading    wkt    of    location    with    id', row.id)
            new_id = table.insert(name=name, level=level, parent=parent, lat=lat, lon=lon, wkt=wkt, lon_min=lon_min, lon_max=lon_max, lat_min=lat_min, lat_max=lat_max)
            ttable.insert(location_id=new_id, tag='geonames', value=geonameid)
        else:
            continue
    current.log.debug('All    done!')
    return
