'Export admin areas to /static/cache for use by interactive web-mapping services
- designed for use by the Vulnerability Mapping
@param countries: list of ISO2 country codes
@param levels: list of which Lx levels to export
@param format: Only GeoJSON supported for now (may add KML &/or OSM later)
@param simplify: tolerance for the simplification algorithm. False to disable simplification
@param precision: number of decimal points to include in the coordinates'

@staticmethod
def export_admin_areas(countries=[], levels=('L0', 'L1', 'L2', 'L3'), format='geojson', simplify=0.01, precision=4):

    db = current.db
    s3db = current.s3db
    table = s3db.gis_location
    ifield = table.id
    if countries:
        ttable = s3db.gis_location_tag
        cquery = (((((table.level == 'L0') & (table.end_date == None)) & (ttable.location_id == ifield)) & (ttable.tag == 'ISO2')) & ttable.value.belongs(countries))
    else:
        cquery = (((table.level == 'L0') & (table.end_date == None)) & (table.deleted != True))
    if current.deployment_settings.get_gis_spatialdb():
        spatial = True
        _field = table.the_geom
        if simplify:
            field = _field.st_simplify(simplify).st_asgeojson(precision=precision).with_alias('geojson')
        else:
            field = _field.st_asgeojson(precision=precision).with_alias('geojson')
    else:
        spatial = False
        field = table.wkt
        if simplify:
            _simplify = GIS.simplify
        else:
            from shapely.wkt import loads as wkt_loads
            from ..geojson import dumps
            try:
                from shapely import speedups
                speedups.enable()
            except:
                current.log.info('S3GIS', 'Upgrade    Shapely    for    Performance    enhancements')
    folder = os.path.join(current.request.folder, 'static', 'cache')
    features = []
    append = features.append
    if ('L0' in levels):
        _decimals = (precision - 1)
        if spatial:
            if simplify:
                field = _field.st_simplify(simplify).st_asgeojson(precision=_decimals).with_alias('geojson')
            else:
                field = _field.st_asgeojson(precision=_decimals).with_alias('geojson')
        countries = db(cquery).select(ifield, field)
        for row in countries:
            if spatial:
                id = row['gis_location'].id
                geojson = row.geojson
            elif simplify:
                id = row.id
                wkt = row.wkt
                if wkt:
                    geojson = _simplify(wkt, tolerance=simplify, precision=_decimals, output='geojson')
                else:
                    name = db((table.id == id)).select(table.name, limitby=(0, 1)).first().name
                    print >>sys.stderr, ('No    WKT:    L0    %s    %s' % (name, id))
                    continue
            else:
                id = row.id
                shape = wkt_loads(row.wkt)
                geojson = dumps(shape, separators=SEPARATORS)
            if geojson:
                f = dict(type='Feature', properties={'id': id}, geometry=json.loads(geojson))
                append(f)
        if features:
            data = dict(type='FeatureCollection', features=features)
            filename = os.path.join(folder, 'countries.geojson')
            File = open(filename, 'w')
            File.write(json.dumps(data, separators=SEPARATORS))
            File.close()
    q1 = (((table.level == 'L1') & (table.deleted != True)) & (table.end_date == None))
    q2 = (((table.level == 'L2') & (table.deleted != True)) & (table.end_date == None))
    q3 = (((table.level == 'L3') & (table.deleted != True)) & (table.end_date == None))
    q4 = (((table.level == 'L4') & (table.deleted != True)) & (table.end_date == None))
    if ('L1' in levels):
        if ('L0' not in levels):
            countries = db(cquery).select(ifield)
        if simplify:
            simplify = (simplify / 2)
            if spatial:
                field = _field.st_simplify(simplify).st_asgeojson(precision=precision).with_alias('geojson')
        for country in countries:
            if ((not spatial) or ('L0' not in levels)):
                _id = country.id
            else:
                _id = country['gis_location'].id
            query = (q1 & (table.parent == _id))
            features = []
            append = features.append
            rows = db(query).select(ifield, field)
            for row in rows:
                if spatial:
                    id = row['gis_location'].id
                    geojson = row.geojson
                elif simplify:
                    id = row.id
                    wkt = row.wkt
                    if wkt:
                        geojson = _simplify(wkt, tolerance=simplify, precision=precision, output='geojson')
                    else:
                        name = db((table.id == id)).select(table.name, limitby=(0, 1)).first().name
                        print >>sys.stderr, ('No    WKT:    L1    %s    %s' % (name, id))
                        continue
                else:
                    id = row.id
                    shape = wkt_loads(row.wkt)
                    geojson = dumps(shape, separators=SEPARATORS)
                if geojson:
                    f = dict(type='Feature', properties={'id': id}, geometry=json.loads(geojson))
                    append(f)
            if features:
                data = dict(type='FeatureCollection', features=features)
                filename = os.path.join(folder, ('1_%s.geojson' % _id))
                File = open(filename, 'w')
                File.write(json.dumps(data, separators=SEPARATORS))
                File.close()
            else:
                current.log.debug(('No    L1    features    in    %s' % _id))
    if ('L2' in levels):
        if (('L0' not in levels) and ('L1' not in levels)):
            countries = db(cquery).select(ifield)
        if simplify:
            simplify = (simplify / 4)
            if spatial:
                field = _field.st_simplify(simplify).st_asgeojson(precision=precision).with_alias('geojson')
        for country in countries:
            if ((not spatial) or ('L0' not in levels)):
                id = country.id
            else:
                id = country['gis_location'].id
            query = (q1 & (table.parent == id))
            l1s = db(query).select(ifield)
            for l1 in l1s:
                query = (q2 & (table.parent == l1.id))
                features = []
                append = features.append
                rows = db(query).select(ifield, field)
                for row in rows:
                    if spatial:
                        id = row['gis_location'].id
                        geojson = row.geojson
                    elif simplify:
                        id = row.id
                        wkt = row.wkt
                        if wkt:
                            geojson = _simplify(wkt, tolerance=simplify, precision=precision, output='geojson')
                        else:
                            name = db((table.id == id)).select(table.name, limitby=(0, 1)).first().name
                            print >>sys.stderr, ('No    WKT:    L2    %s    %s' % (name, id))
                            continue
                    else:
                        id = row.id
                        shape = wkt_loads(row.wkt)
                        geojson = dumps(shape, separators=SEPARATORS)
                    if geojson:
                        f = dict(type='Feature', properties={'id': id}, geometry=json.loads(geojson))
                        append(f)
                if features:
                    data = dict(type='FeatureCollection', features=features)
                    filename = os.path.join(folder, ('2_%s.geojson' % l1.id))
                    File = open(filename, 'w')
                    File.write(json.dumps(data, separators=SEPARATORS))
                    File.close()
                else:
                    current.log.debug(('No    L2    features    in    %s' % l1.id))
    if ('L3' in levels):
        if (('L0' not in levels) and ('L1' not in levels) and ('L2' not in levels)):
            countries = db(cquery).select(ifield)
        if simplify:
            simplify = (simplify / 2)
            if spatial:
                field = _field.st_simplify(simplify).st_asgeojson(precision=precision).with_alias('geojson')
        for country in countries:
            if ((not spatial) or ('L0' not in levels)):
                id = country.id
            else:
                id = country['gis_location'].id
            query = (q1 & (table.parent == id))
            l1s = db(query).select(ifield)
            for l1 in l1s:
                query = (q2 & (table.parent == l1.id))
                l2s = db(query).select(ifield)
                for l2 in l2s:
                    query = (q3 & (table.parent == l2.id))
                    features = []
                    append = features.append
                    rows = db(query).select(ifield, field)
                    for row in rows:
                        if spatial:
                            id = row['gis_location'].id
                            geojson = row.geojson
                        elif simplify:
                            id = row.id
                            wkt = row.wkt
                            if wkt:
                                geojson = _simplify(wkt, tolerance=simplify, precision=precision, output='geojson')
                            else:
                                name = db((table.id == id)).select(table.name, limitby=(0, 1)).first().name
                                print >>sys.stderr, ('No    WKT:    L3    %s    %s' % (name, id))
                                continue
                        else:
                            id = row.id
                            shape = wkt_loads(row.wkt)
                            geojson = dumps(shape, separators=SEPARATORS)
                        if geojson:
                            f = dict(type='Feature', properties={'id': id}, geometry=json.loads(geojson))
                            append(f)
                    if features:
                        data = dict(type='FeatureCollection', features=features)
                        filename = os.path.join(folder, ('3_%s.geojson' % l2.id))
                        File = open(filename, 'w')
                        File.write(json.dumps(data, separators=SEPARATORS))
                        File.close()
                    else:
                        current.log.debug(('No    L3    features    in    %s' % l2.id))
    if ('L4' in levels):
        if (('L0' not in levels) and ('L1' not in levels) and ('L2' not in levels) and ('L3' not in levels)):
            countries = db(cquery).select(ifield)
        if simplify:
            simplify = (simplify / 2)
            if spatial:
                field = _field.st_simplify(simplify).st_asgeojson(precision=precision).with_alias('geojson')
        for country in countries:
            if ((not spatial) or ('L0' not in levels)):
                id = country.id
            else:
                id = country['gis_location'].id
            query = (q1 & (table.parent == id))
            l1s = db(query).select(ifield)
            for l1 in l1s:
                query = (q2 & (table.parent == l1.id))
                l2s = db(query).select(ifield)
                for l2 in l2s:
                    query = (q3 & (table.parent == l2.id))
                    l3s = db(query).select(ifield)
                    for l3 in l3s:
                        query = (q4 & (table.parent == l3.id))
                        features = []
                        append = features.append
                        rows = db(query).select(ifield, field)
                        for row in rows:
                            if spatial:
                                id = row['gis_location'].id
                                geojson = row.geojson
                            elif simplify:
                                id = row.id
                                wkt = row.wkt
                                if wkt:
                                    geojson = _simplify(wkt, tolerance=simplify, precision=precision, output='geojson')
                                else:
                                    name = db((table.id == id)).select(table.name, limitby=(0, 1)).first().name
                                    print >>sys.stderr, ('No    WKT:    L4    %s    %s' % (name, id))
                                    continue
                            else:
                                id = row.id
                                shape = wkt_loads(row.wkt)
                                geojson = dumps(shape, separators=SEPARATORS)
                            if geojson:
                                f = dict(type='Feature', properties={'id': id}, geometry=json.loads(geojson))
                                append(f)
                        if features:
                            data = dict(type='FeatureCollection', features=features)
                            filename = os.path.join(folder, ('4_%s.geojson' % l3.id))
                            File = open(filename, 'w')
                            File.write(json.dumps(data, separators=SEPARATORS))
                            File.close()
                        else:
                            current.log.debug(('No    L4    features    in    %s' % l3.id))
