Esempio n. 1
0
def ob_ref_rst(ref, folder, cellsize=None):
    """
    Get Reference Raster
    """

    from glass.g.prop import check_isRaster

    # Check if refRaster is really a Raster
    isRst = check_isRaster(ref)

    if not isRst:
        from glass.g.prop import check_isShp

        if not check_isShp(ref):
            raise ValueError((
                'Extent Template File has an invalid file format. '
                'Please give a file with one of the following extensions: '
                'shp, gml, json, kml, tif or img'
            ))
        else:
            # We have a shapefile
            # Convert it to Raster
            from glass.g.dp.torst import shp_to_rst

            ref_rst = shp_to_rst(
                ref, None, 10 if not cellsize else cellsize,
                -1, os.path.join(folder, 'ref_raster.tif'), api='gdal'
            )

            return ref_rst
    else:
        return ref
Esempio n. 2
0
def get_ext(inFile, outEpsg=None):
    """
    Get Extent of any GIS Data
    
    return None if inFile is not a GIS File
    """

    from glass.g.prop import check_isRaster, check_isShp

    if check_isRaster(inFile):
        from glass.g.prop.rst import rst_ext

        extent = rst_ext(inFile)

    else:
        if check_isShp(inFile):
            from glass.g.prop.feat import get_ext as gext

            extent = gext(inFile)

        else:
            return None

    if outEpsg:
        from glass.g.prop.prj import get_epsg

        fileEpsg = get_epsg(inFile)

        if not fileEpsg:
            raise ValueError('cannot get EPSG of input file')

        if fileEpsg != outEpsg:
            from glass.g.gobj import new_pnt
            from glass.g.prj.obj import prj_ogrgeom

            bt_left = prj_ogrgeom(new_pnt(extent[0], extent[2]),
                                  fileEpsg,
                                  outEpsg,
                                  api='ogr' if outEpsg != 4326 else 'shapely')
            top_right = prj_ogrgeom(
                new_pnt(extent[1], extent[3]),
                fileEpsg,
                outEpsg,
                api='ogr' if outEpsg != 4326 else 'shapely')

            left, bottom = bt_left.GetX(), bt_left.GetY()
            right, top = top_right.GetX(), top_right.GetY()

            extent = [left, right, bottom, top]

    return extent
Esempio n. 3
0
File: prj.py Progetto: jasp382/glass
def get_epsg(inFile):
    """
    Get EPSG of any GIS File
    """
    
    from glass.g.prop import check_isRaster, check_isShp
    
    if check_isRaster(inFile):
        return get_rst_epsg(inFile)
    else:
        if check_isShp(inFile):
            return get_shp_epsg(inFile)
        else:
            return None
Esempio n. 4
0
def fext_to_geof(inF, outF, ocellsize=10):
    """
    Extent of a File to Raster or Shapefile
    """
    
    from glass.g.prop.ext import get_ext
    from glass.g.prop     import check_isRaster
    from glass.g.prop.prj import get_epsg
    
    # Get extent
    left, right, bottom, top = get_ext(inF)
    
    # Get EPSG of inF
    EPSG = get_epsg(inF)
    
    # Export Boundary
    isRst = check_isRaster(outF)
    
    if isRst:
        from glass.g.wt.rst import ext_to_rst
        
        return ext_to_rst(
            (left, top), (right, bottom), outF,
            cellsize=ocellsize, epsg=EPSG, invalidResultAsNull=None
        )
    else:
        from glass.g.prop import check_isShp
        
        isShp = check_isShp(outF)
        
        if isShp:
            return coords_to_boundshp(
                (left, top), (right, bottom), EPSG, outF
            )
        
        else:
            raise ValueError(
                '{} is not recognized as a file with GeoData'.format(
                    inF
                )
            )
Esempio n. 5
0
def get_ref_raster(refBoundBox, folder, cellsize=None):
    """
    Get Reference Raster
    """

    import os
    from glass.g.prop import check_isRaster

    # Check if refRaster is really a Raster
    isRst = check_isRaster(refBoundBox)

    if not isRst:
        from glass.g.prop import check_isShp

        if not check_isShp(refBoundBox):
            raise ValueError((
                'refRaster File has an invalid file format. Please give a file '
                'with one of the following extensions: '
                'shp, gml, json, kml, tif or img'))

        else:
            # We have a shapefile

            # Check SRS and see if it is a projected SRS
            from glass.g.prop.prj import get_shp_epsg

            epsg, isProj = get_shp_epsg(refBoundBox, returnIsProj=True)

            if not epsg:
                raise ValueError(
                    'Cannot get epsg code from {}'.format(refBoundBox))

            if not isProj:
                # A conversion between SRS is needed
                from glass.g.prj import proj

                ref_shp = proj(refBoundBox,
                               os.path.join(folder, 'tmp_ref_shp.shp'),
                               outEPSG=3857,
                               inEPSG=epsg,
                               gisApi='ogr2ogr')
                epsg = 3857
            else:
                ref_shp = refBoundBox

            # Convert to Raster
            from glass.g.dp.torst import shp_to_rst

            refRaster = shp_to_rst(ref_shp,
                                   None,
                                   2 if not cellsize else cellsize,
                                   -1,
                                   os.path.join(folder, 'ref_raster.tif'),
                                   api='gdal')

    else:
        # We have a raster
        from glass.g.prop.prj import get_rst_epsg

        epsg, isProj = get_rst_epsg(refBoundBox, returnIsProj=True)

        if not epsg:
            raise ValueError(
                'Cannot get epsg code from {}'.format(refBoundBox))

        # Check if Raster has a SRS with projected coordinates
        if not isProj:
            # We need to reproject raster
            from glass.g.prj import reprj_rst

            refRaster = reprj_rst(refBoundBox,
                                  os.path.join(folder, 'refrst_3857.tif'),
                                  epsg, 3857)
            epsg = 3857
        else:
            refRaster = refBoundBox

    return refRaster, epsg
Esempio n. 6
0
def raster_based(osmdata, nomenclature, refRaster, lulcRst,
                 overwrite=None, dataStore=None, roadsAPI='POSTGIS'):
    """
    Convert OSM Data into Land Use/Land Cover Information
    
    An raster based approach.
    
    TODO: Add detailed description
    """
    
    # ************************************************************************ #
    # Python Modules from Reference Packages #
    # ************************************************************************ #
    import datetime; import os; import pandas; import copy
    # ************************************************************************ #
    # glass dependencies #
    # ************************************************************************ #
    from glass.pys.oss               import mkdir, fprop
    from glass.g.prop           import check_isRaster
    from glass.g.prop.prj          import get_rst_epsg
    from glass.g.wenv.grs          import run_grass
    if roadsAPI == 'POSTGIS':
        from glass.ng.sql.db            import create_db
        from glass.g.it.db           import osm_to_psql 
        from glass.ete.osm2lulc.mod2 import roads_sqdb
        from glass.ng.sql.bkup        import dump_db
        from glass.ng.sql.db            import drop_db
    else:
        from glass.g.it.osm  import osm_to_sqdb
        from glass.ete.osm2lulc.mod2 import grs_rst_roads
    from glass.ete.osm2lulc.utils    import osm_project, add_lulc_to_osmfeat, osmlulc_rsttbl
    from glass.ete.osm2lulc.utils    import get_ref_raster
    from glass.ete.osm2lulc.mod1     import grs_rst
    from glass.ete.osm2lulc.m3_4     import rst_area
    from glass.ete.osm2lulc.mod5     import basic_buffer
    from glass.ete.osm2lulc.mod6     import rst_pnt_to_build
    # ************************************************************************ #
    # Global Settings #
    # ************************************************************************ #
    # Check if input parameters exists!
    if not os.path.exists(os.path.dirname(lulcRst)):
        raise ValueError('{} does not exist!'.format(os.path.dirname(lulcRst)))
    
    if not os.path.exists(osmdata):
        raise ValueError('File with OSM DATA ({}) does not exist!'.format(osmdata))
    
    if not os.path.exists(refRaster):
        raise ValueError('File with reference area ({}) does not exist!'.format(refRaster))
    
    # Check if Nomenclature is valid
    nomenclature = "URBAN_ATLAS" if nomenclature != "URBAN_ATLAS" and \
        nomenclature != "CORINE_LAND_COVER" and \
        nomenclature == "GLOBE_LAND_30" else nomenclature
    
    time_a = datetime.datetime.now().replace(microsecond=0)
    
    workspace = os.path.join(os.path.dirname(
        lulcRst), 'osmtolulc') if not dataStore else dataStore
    
    # Check if workspace exists
    if os.path.exists(workspace):
        if overwrite:
            mkdir(workspace)
        else:
            raise ValueError('Path {} already exists'.format(workspace))
    else:
        mkdir(workspace)
    
    # Get Ref Raster
    refRaster, epsg = get_ref_raster(refRaster, workspace, cellsize=2)
    
    from glass.ete.osm2lulc import PRIORITIES, osmTableData, LEGEND
    
    __priorites = PRIORITIES[nomenclature]
    __legend    = LEGEND[nomenclature]
    time_b = datetime.datetime.now().replace(microsecond=0)
    
    # ************************************************************************ #
    # Convert OSM file to SQLITE DB or to POSTGIS DB #
    # ************************************************************************ #
    if roadsAPI == 'POSTGIS':
        osm_db = create_db(fprop(
            osmdata, 'fn', forceLower=True), overwrite=True)
        osm_db = osm_to_psql(osmdata, osm_db)
    else:
        osm_db = osm_to_sqdb(osmdata, os.path.join(workspace, 'osm.sqlite'))
    time_c = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Add Lulc Classes to OSM_FEATURES by rule #
    # ************************************************************************ #
    add_lulc_to_osmfeat(osm_db, osmTableData, nomenclature, api=roadsAPI)
    time_d = datetime.datetime.now().replace(microsecond=0)
    
    # ************************************************************************ #
    # Transform SRS of OSM Data #
    # ************************************************************************ #
    osmTableData = osm_project(
        osm_db, epsg, api=roadsAPI,
        isGlobeLand=None if nomenclature != 'GLOBE_LAND_30' else True
    )
    time_e = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Start a GRASS GIS Session #
    # ************************************************************************ #
    grass_base = run_grass(
        workspace, grassBIN='grass78', location='grloc', srs=epsg)
    import grass.script as grass
    import grass.script.setup as gsetup
    gsetup.init(grass_base, workspace, 'grloc', 'PERMANENT')
    
    # ************************************************************************ #
    # IMPORT SOME glass MODULES FOR GRASS GIS #
    # ************************************************************************ #
    from glass.g.it.rst   import rst_to_grs, grs_to_rst
    from glass.g.rst.mos import rsts_to_mosaic
    from glass.g.wenv.grs   import rst_to_region
    # ************************************************************************ #
    # SET GRASS GIS LOCATION EXTENT #
    # ************************************************************************ #
    extRst = rst_to_grs(refRaster, 'extent_raster')
    rst_to_region(extRst)
    time_f = datetime.datetime.now().replace(microsecond=0)
    
    # ************************************************************************ #
    # MapResults #
    mergeOut = {}
    # ************************************************************************ #
    # ************************************************************************ #
    # 1 - Selection Rule #
    # ************************************************************************ #
    """
    selOut = {
        cls_code : rst_name, ...
    }
    """
    selOut, timeCheck1 = grs_rst(osm_db, osmTableData['polygons'], api=roadsAPI)

    for cls in selOut:
        mergeOut[cls] = [selOut[cls]]
    
    time_g = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 2 - Get Information About Roads Location #
    # ************************************************************************ #
    """
    roads = {
        cls_code : rst_name, ...
    }
    """
    
    if roadsAPI != 'POSTGIS':
        roads, timeCheck2 = grs_rst_roads(
            osm_db, osmTableData['lines'], osmTableData['polygons'],
            workspace, 1221 if nomenclature != "GLOBE_LAND_30" else 801
        )
    else:
        roadCls = 1221 if nomenclature != "GLOBE_LAND_30" else 801
        
        roads, timeCheck2 = roads_sqdb(
            osm_db, osmTableData['lines'], osmTableData['polygons'],
            apidb='POSTGIS', asRst=roadCls
        )
        
        roads = {roadCls : roads}
    
    for cls in roads:
        if cls not in mergeOut:
            mergeOut[cls] = [roads[cls]]
        else:
            mergeOut[cls].append(roads[cls])
    
    time_h = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 3 - Area Upper than #
    # ************************************************************************ #
    """
    auOut = {
        cls_code : rst_name, ...
    }
    """
    
    if nomenclature != 'GLOBE_LAND_30':
        auOut, timeCheck3 = rst_area(
            osm_db, osmTableData['polygons'], UPPER=True, api=roadsAPI
        )
        
        for cls in auOut:
            if cls not in mergeOut:
                mergeOut[cls] = [auOut[cls]]
            else:
                mergeOut[cls].append(auOut[cls])
    
        time_l = datetime.datetime.now().replace(microsecond=0)
    else:
        timeCheck3 = None
        time_l     = None
    # ************************************************************************ #
    # 4 - Area Lower than #
    # ************************************************************************ #
    """
    alOut = {
        cls_code : rst_name, ...
    }
    """
    if nomenclature != 'GLOBE_LAND_30':
        alOut, timeCheck4 = rst_area(
            osm_db, osmTableData['polygons'], UPPER=None, api=roadsAPI
        )
        for cls in alOut:
            if cls not in mergeOut:
                mergeOut[cls] = [alOut[cls]]
            else:
                mergeOut[cls].append(alOut[cls])
    
        time_j = datetime.datetime.now().replace(microsecond=0)
    else:
        timeCheck4 = None
        time_j     = None
    # ************************************************************************ #
    # 5 - Get data from lines table (railway | waterway) #
    # ************************************************************************ #
    """
    bfOut = {
        cls_code : rst_name, ...
    }
    """
    
    bfOut, timeCheck5 = basic_buffer(
        osm_db, osmTableData['lines'], workspace, apidb=roadsAPI
    )
    for cls in bfOut:
        if cls not in mergeOut:
            mergeOut[cls] = [bfOut[cls]]
        else:
            mergeOut[cls].append(bfOut[cls])
    
    time_m = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 7 - Assign untagged Buildings to tags #
    # ************************************************************************ #
    if nomenclature != "GLOBE_LAND_30":
        buildsOut, timeCheck7 = rst_pnt_to_build(
            osm_db, osmTableData['points'], osmTableData['polygons'],
            api_db=roadsAPI
        )
        
        for cls in buildsOut:
            if cls not in mergeOut:
                mergeOut[cls] = buildsOut[cls]
            else:
                mergeOut[cls] += buildsOut[cls]
        
        time_n = datetime.datetime.now().replace(microsecond=0)
    
    else:
        timeCheck7 = None
        time_n = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Produce LULC Map  #
    # ************************************************************************ #
    """
    Merge all results for one cls into one raster
    mergeOut = {
        cls_code : [rst_name, rst_name, ...], ...
    }
    into
    mergeOut = {
        cls_code : patched_raster, ...
    }
    """
    
    for cls in mergeOut:
        if len(mergeOut[cls]) == 1:
            mergeOut[cls] = mergeOut[cls][0]
        
        else:
            mergeOut[cls] = rsts_to_mosaic(
                mergeOut[cls], 'mosaic_{}'.format(str(cls)), api="grass"
            )
    
    time_o = datetime.datetime.now().replace(microsecond=0)
    
    """
    Merge all Class Raster using a priority rule
    """
    
    __priorities = PRIORITIES[nomenclature]
    lst_rst = []
    for cls in __priorities:
        if cls not in mergeOut:
            continue
        else:
            lst_rst.append(mergeOut[cls])
    
    outGrs = rsts_to_mosaic(lst_rst, os.path.splitext(
        os.path.basename(lulcRst))[0], api="grass"
    )
    time_p = datetime.datetime.now().replace(microsecond=0)
    
    # Ceck if lulc Rst has an valid format
    outIsRst = check_isRaster(lulcRst)
    if not outIsRst:
        from glass.pys.oss import fprop
        lulcRst = os.path.join(
            os.path.dirname(lulcRst),
            fprop(lulcRst, 'fn') + '.tif'
        )
    
    grs_to_rst(outGrs, lulcRst, as_cmd=True)
    osmlulc_rsttbl(nomenclature, os.path.join(
        os.path.dirname(lulcRst), os.path.basename(lulcRst) + '.vat.dbf'
    ))
    
    time_q = datetime.datetime.now().replace(microsecond=0)

    # Dump Database if PostGIS was used
    # Drop Database if PostGIS was used
    if roadsAPI == 'POSTGIS':
        dump_db(osm_db, os.path.join(
            workspace, osm_db + '.sql'
        ), api='psql')
        drop_db(osm_db)
    
    return lulcRst, {
        0  : ('set_settings', time_b - time_a),
        1  : ('osm_to_sqdb', time_c - time_b),
        2  : ('cls_in_sqdb', time_d - time_c),
        3  : ('proj_data', time_e - time_d),
        4  : ('set_grass', time_f - time_e),
        5  : ('rule_1', time_g - time_f, timeCheck1),
        6  : ('rule_2', time_h - time_g, timeCheck2),
        7  : None if not timeCheck3 else ('rule_3', time_l - time_h, timeCheck3),
        8  : None if not timeCheck4 else ('rule_4', time_j - time_l, timeCheck4),
        9  : ('rule_5', time_m - time_j if timeCheck4 else time_m - time_h, timeCheck5),
        10 : None if not timeCheck7 else ('rule_7', time_n - time_m, timeCheck7),
        11 : ('merge_rst', time_o - time_n),
        12 : ('priority_rule', time_p - time_o),
        13 : ('export_rst', time_q - time_p)
    }
Esempio n. 7
0
def shp_diff_fm_ref(refshp, refcol, shps, out_folder, refrst, db=None):
    """
    Check differences between each shp in shps and one reference shape

    Dependencies:
    - GRASS;
    - PostgreSQL with Postgis or GeoPandas;
    """

    import os
    from glass.g.prop import check_isRaster
    from glass.g.wenv.grs import run_grass
    from glass.pys.oss import fprop
    from glass.g.tbl.tomtx import tbl_to_areamtx

    # Check if folder exists, if not create it
    if not os.path.exists(out_folder):
        from glass.pys.oss import mkdir
        mkdir(out_folder)

    # Start GRASS GIS Session
    gbase = run_grass(out_folder,
                      grassBIN='grass78',
                      location='shpdif',
                      srs=refrst)

    import grass.script.setup as gsetup

    gsetup.init(gbase, out_folder, 'shpdif', 'PERMANENT')

    from glass.g.it.shp import shp_to_grs, grs_to_shp
    from glass.g.it.rst import rst_to_grs
    from glass.g.tbl.col import rn_cols
    from glass.g.dp.rst.toshp import rst_to_polyg

    # Convert to SHAPE if file is Raster
    # Rename interest columns
    i = 0
    lstff = [refshp] + list(shps.keys())
    __shps = {}
    for s in lstff:
        is_rst = check_isRaster(s)

        if is_rst:
            # To GRASS
            rname = fprop(s, 'fn')
            inrst = rst_to_grs(s, "rst_" + rname, as_cmd=True)

            # To vector
            d = rst_to_polyg(inrst,
                             rname,
                             rstColumn="lulc_{}".format(str(i)),
                             gisApi="grass")

        else:
            # To GRASS
            d = shp_to_grs(s, fprop(s, 'fn'), asCMD=True)

            # Change name of interest colum
            rn_cols(d, {shps[s] if i else refcol: "lulc_{}".format(str(i))},
                    api="grass")

        # Export To Shapefile
        if not i:
            refshp = grs_to_shp(d, os.path.join(out_folder, d + '.shp'),
                                'area')
            refcol = "lulc_{}".format(str(i))

        else:
            shp = grs_to_shp(d, os.path.join(out_folder, d + '.shp'), 'area')
            __shps[shp] = "lulc_{}".format(str(i))

        i += 1

    # Union Shapefiles
    union_shape = {}

    for shp in __shps:
        # Optimized Union
        sname = fprop(shp, 'fn')
        union_shape[shp] = optimized_union_anls(
            shp,
            refshp,
            os.path.join(out_folder, sname + '_un.shp'),
            refrst,
            os.path.join(out_folder, "wk_" + sname),
            multiProcess=True)

        # Produce confusion matrices
        mtxf = tbl_to_areamtx(union_shape[shp],
                              "a_" + __shps[shp],
                              'b_' + refcol,
                              os.path.join(out_folder, sname + '.xlsx'),
                              db=db,
                              with_metrics=True)

    return out_folder
Esempio n. 8
0
def check_shape_diff(SHAPES_TO_COMPARE, OUT_FOLDER, REPORT, DB,
                     GRASS_REGION_TEMPLATE):
    """
    Script to check differences between pairs of Feature Classes
    
    Suponha que temos diversas Feature Classes (FC) e que cada uma delas
    possui um determinado atributo; imagine tambem que,
    considerando todos os pares possiveis entre estas FC,
    se pretende comparar as diferencas na distribuicao dos valores
    desse atributo para cada par.
    
    * Dependencias:
    - GRASS;
    - PostgreSQL;
    - PostGIS.
    """

    import datetime
    import os
    import pandas
    from glass.ng.sql.q import q_to_obj
    from glass.ng.it import db_to_tbl
    from glass.g.wt.sql import df_to_db
    from glass.g.dp.rst.toshp import rst_to_polyg
    from glass.g.it.db import shp_to_psql
    from glass.g.dp.tomtx import tbl_to_area_mtx
    from glass.g.prop import check_isRaster
    from glass.pys.oss import fprop
    from glass.ng.sql.db import create_db
    from glass.ng.sql.tbl import tbls_to_tbl
    from glass.ng.sql.q import q_to_ntbl

    # Check if folder exists, if not create it
    if not os.path.exists(OUT_FOLDER):
        from glass.pys.oss import mkdir
        mkdir(OUT_FOLDER, overwrite=None)
    else:
        raise ValueError('{} already exists!'.format(OUT_FOLDER))

    from glass.g.wenv.grs import run_grass

    gbase = run_grass(OUT_FOLDER,
                      grassBIN='grass78',
                      location='shpdif',
                      srs=GRASS_REGION_TEMPLATE)

    import grass.script as grass
    import grass.script.setup as gsetup

    gsetup.init(gbase, OUT_FOLDER, 'shpdif', 'PERMANENT')

    from glass.g.it.shp import shp_to_grs, grs_to_shp
    from glass.g.it.rst import rst_to_grs
    from glass.g.tbl.col import rn_cols

    # Convert to SHAPE if file is Raster
    i = 0
    _SHP_TO_COMPARE = {}
    for s in SHAPES_TO_COMPARE:
        isRaster = check_isRaster(s)

        if isRaster:
            # To GRASS
            rstName = fprop(s, 'fn')
            inRst = rst_to_grs(s, "rst_" + rstName, as_cmd=True)
            # To Vector
            d = rst_to_polyg(inRst,
                             rstName,
                             rstColumn="lulc_{}".format(i),
                             gisApi="grass")

            # Export Shapefile
            shp = grs_to_shp(d, os.path.join(OUT_FOLDER, d + '.shp'), "area")

            _SHP_TO_COMPARE[shp] = "lulc_{}".format(i)

        else:
            # To GRASS
            grsV = shp_to_grs(s, fprop(s, 'fn'), asCMD=True)

            # Change name of column with comparing value
            ncol = "lulc_{}".format(str(i))
            rn_cols(grsV, {SHAPES_TO_COMPARE[s]: "lulc_{}".format(str(i))},
                    api="grass")

            # Export
            shp = grs_to_shp(grsV, os.path.join(OUT_FOLDER, grsV + '_rn.shp'),
                             "area")

            _SHP_TO_COMPARE[shp] = "lulc_{}".format(str(i))

        i += 1

    SHAPES_TO_COMPARE = _SHP_TO_COMPARE
    __SHAPES_TO_COMPARE = SHAPES_TO_COMPARE

    # Create database
    create_db(DB, api='psql')
    """ Union SHAPEs """

    UNION_SHAPE = {}
    FIX_GEOM = {}

    SHPS = list(__SHAPES_TO_COMPARE.keys())
    for i in range(len(SHPS)):
        for e in range(i + 1, len(SHPS)):
            # Optimized Union
            print("Union between {} and {}".format(SHPS[i], SHPS[e]))
            time_a = datetime.datetime.now().replace(microsecond=0)
            __unShp = optimized_union_anls(
                SHPS[i],
                SHPS[e],
                os.path.join(OUT_FOLDER, "un_{}_{}.shp".format(i, e)),
                GRASS_REGION_TEMPLATE,
                os.path.join(OUT_FOLDER, "work_{}_{}".format(i, e)),
                multiProcess=True)
            time_b = datetime.datetime.now().replace(microsecond=0)
            print(time_b - time_a)

            # Rename cols
            unShp = rn_cols(
                __unShp, {
                    "a_" + __SHAPES_TO_COMPARE[SHPS[i]]:
                    __SHAPES_TO_COMPARE[SHPS[i]],
                    "b_" + __SHAPES_TO_COMPARE[SHPS[e]]:
                    __SHAPES_TO_COMPARE[SHPS[e]]
                })

            UNION_SHAPE[(SHPS[i], SHPS[e])] = unShp

    # Send data to postgresql
    SYNTH_TBL = {}

    for uShp in UNION_SHAPE:
        # Send data to PostgreSQL
        union_tbl = shp_to_psql(DB, UNION_SHAPE[uShp], api='shp2pgsql')

        # Produce table with % of area equal in both maps
        areaMapTbl = q_to_ntbl(
            DB,
            "{}_syn".format(union_tbl),
            ("SELECT CAST('{lulc_1}' AS text) AS lulc_1, "
             "CAST('{lulc_2}' AS text) AS lulc_2, "
             "round("
             "CAST(SUM(g_area) / 1000000 AS numeric), 4"
             ") AS agree_area, round("
             "CAST((SUM(g_area) / MIN(total_area)) * 100 AS numeric), 4"
             ") AS agree_percentage, "
             "round("
             "CAST(MIN(total_area) / 1000000 AS numeric), 4"
             ") AS total_area FROM ("
             "SELECT {map1_cls}, {map2_cls}, ST_Area(geom) AS g_area, "
             "CASE "
             "WHEN {map1_cls} = {map2_cls} "
             "THEN 1 ELSE 0 "
             "END AS isthesame, total_area FROM {tbl}, ("
             "SELECT SUM(ST_Area(geom)) AS total_area FROM {tbl}"
             ") AS foo2"
             ") AS foo WHERE isthesame = 1 "
             "GROUP BY isthesame").format(
                 lulc_1=fprop(uShp[0], 'fn'),
                 lulc_2=fprop(uShp[1], 'fn'),
                 map1_cls=__SHAPES_TO_COMPARE[uShp[0]],
                 map2_cls=__SHAPES_TO_COMPARE[uShp[1]],
                 tbl=union_tbl),
            api='psql')

        # Produce confusion matrix for the pair in comparison
        matrixTbl = tbl_to_area_mtx(DB, union_tbl,
                                    __SHAPES_TO_COMPARE[uShp[0]],
                                    __SHAPES_TO_COMPARE[uShp[1]],
                                    union_tbl + '_mtx')

        SYNTH_TBL[uShp] = {"TOTAL": areaMapTbl, "MATRIX": matrixTbl}

    # UNION ALL TOTAL TABLES
    total_table = tbls_to_tbl(DB, [SYNTH_TBL[k]["TOTAL"] for k in SYNTH_TBL],
                              'total_table')

    # Create table with % of agreement between each pair of maps
    mapsNames = q_to_obj(
        DB,
        ("SELECT lulc FROM ("
         "SELECT lulc_1 AS lulc FROM {tbl} GROUP BY lulc_1 "
         "UNION ALL "
         "SELECT lulc_2 AS lulc FROM {tbl} GROUP BY lulc_2"
         ") AS lu GROUP BY lulc ORDER BY lulc").format(tbl=total_table),
        db_api='psql').lulc.tolist()

    FLDS_TO_PIVOT = ["agree_percentage", "total_area"]

    Q = ("SELECT * FROM crosstab('"
         "SELECT CASE "
         "WHEN foo.lulc_1 IS NOT NULL THEN foo.lulc_1 ELSE jtbl.tmp1 "
         "END AS lulc_1, CASE "
         "WHEN foo.lulc_2 IS NOT NULL THEN foo.lulc_2 ELSE jtbl.tmp2 "
         "END AS lulc_2, CASE "
         "WHEN foo.{valCol} IS NOT NULL THEN foo.{valCol} ELSE 0 "
         "END AS agree_percentage FROM ("
         "SELECT lulc_1, lulc_2, {valCol} FROM {tbl} UNION ALL "
         "SELECT lulc_1, lulc_2, {valCol} FROM ("
         "SELECT lulc_1 AS lulc_2, lulc_2 AS lulc_1, {valCol} "
         "FROM {tbl}"
         ") AS tst"
         ") AS foo FULL JOIN ("
         "SELECT lulc_1 AS tmp1, lulc_2 AS tmp2 FROM ("
         "SELECT lulc_1 AS lulc_1 FROM {tbl} GROUP BY lulc_1 "
         "UNION ALL "
         "SELECT lulc_2 AS lulc_1 FROM {tbl} GROUP BY lulc_2"
         ") AS tst_1, ("
         "SELECT lulc_1 AS lulc_2 FROM {tbl} GROUP BY lulc_1 "
         "UNION ALL "
         "SELECT lulc_2 AS lulc_2 FROM {tbl} GROUP BY lulc_2"
         ") AS tst_2 WHERE lulc_1 = lulc_2 GROUP BY lulc_1, lulc_2"
         ") AS jtbl ON foo.lulc_1 = jtbl.tmp1 AND foo.lulc_2 = jtbl.tmp2 "
         "ORDER BY lulc_1, lulc_2"
         "') AS ct("
         "lulc_map text, {crossCols}"
         ")")

    TOTAL_AGREE_TABLE = None
    TOTAL_AREA_TABLE = None
    for f in FLDS_TO_PIVOT:
        if not TOTAL_AGREE_TABLE:
            TOTAL_AGREE_TABLE = q_to_ntbl(
                DB,
                "agreement_table",
                Q.format(tbl=total_table,
                         valCol=f,
                         crossCols=", ".join([
                             "{} numeric".format(map_) for map_ in mapsNames
                         ])),
                api='psql')

        else:
            TOTAL_AREA_TABLE = q_to_ntbl(DB,
                                         "area_table",
                                         Q.format(tbl=total_table,
                                                  valCol=f,
                                                  crossCols=", ".join([
                                                      "{} numeric".format(map_)
                                                      for map_ in mapsNames
                                                  ])),
                                         api='psql')

    # Union Mapping
    UNION_MAPPING = pandas.DataFrame(
        [[k[0], k[1], fprop(UNION_SHAPE[k], 'fn')] for k in UNION_SHAPE],
        columns=['shp_a', 'shp_b', 'union_shp'])

    UNION_MAPPING = df_to_db(DB, UNION_MAPPING, 'union_map', api='psql')

    # Export Results
    TABLES = [UNION_MAPPING, TOTAL_AGREE_TABLE, TOTAL_AREA_TABLE
              ] + [SYNTH_TBL[x]["MATRIX"] for x in SYNTH_TBL]

    SHEETS = ["union_map", "agreement_percentage", "area_with_data_km"] + [
        "{}_{}".format(fprop(x[0], 'fn')[:15],
                       fprop(x[1], 'fn')[:15]) for x in SYNTH_TBL
    ]

    db_to_tbl(DB, ["SELECT * FROM {}".format(x) for x in TABLES],
              REPORT,
              sheetsNames=SHEETS,
              dbAPI='psql')

    return REPORT
Esempio n. 9
0
def download_by_boundary(input_boundary, folder_out, osm_name, epsg,
                         GetUrl=True, db_name=None, geomCol=None,
                         justOneFeature=None):
    """
    Download data from OSM using a bounding box
    """
    
    import os
    from osgeo         import ogr
    from glass.pys.web import get_file
    from glass.pys.oss import os_name
    
    OS_NAME = os_name()
    
    EXTENTS = []
    
    if db_name and geomCol:
        """
        Assuming input_boundary is a PostgreSQL Table
        """
        
        from glass.pys        import obj_to_lst
        from glass.g.prop.gql import tbl_ext
        
        for t in obj_to_lst(input_boundary):
            EXTENTS.append(tbl_ext(db_name, t, geomCol))
    
    else:
        if type(input_boundary) == dict:
            if 'top' in input_boundary and 'bottom' in input_boundary \
                and 'left' in input_boundary and 'right' in input_boundary:
                
                EXTENTS.append([
                    input_boundary['left'],input_boundary['right'],
                    input_boundary['bottom'], input_boundary['top']
                ])
        
            else:
                raise ValueError((
                    'input_boundary is a dict but the keys are not correct. '
                    'Please use left, right, top and bottom as keys'
                ))
    
        elif type(input_boundary) == list:
            if len(input_boundary) == 4:
                EXTENTS.append(input_boundary)
        
            else:
                raise ValueError((
                    'input boundary is a list with more than 4 objects. '
                    'The list should be like: '
                    'l = [left, right, bottom, top]'
                ))
    
        elif type(input_boundary) == ogr.Geometry:
            EXTENTS.append(input_boundary.GetEnvelope())
    
        else:
            # Assuming input boundary is a file
        
            #Check if file exists
            if not os.path.exists(input_boundary):
                raise ValueError((
                    "Sorry, but the file {} does not exist inside the folder {}!"
                ).format(
                    os.path.basename(input_boundary),
                    os.path.dirname(input_boundary)
                ))
        
            # Check if is a raster
            from glass.g.prop import check_isRaster
            isRst = check_isRaster(input_boundary)
        
            # Get EPSG
            if not epsg:
                from glass.g.prop.prj import get_epsg
            
                epsg = get_epsg(input_boundary)
        
            if isRst:
                from glass.g.prop.rst import rst_ext
            
                # Get raster extent
                EXTENTS.append(rst_ext(input_boundary))
        
            else:
                from glass.g.prop import drv_name
                
                # Todo: check if it is shape
                
                # Open Dataset
                inSrc = ogr.GetDriverByName(drv_name(
                    input_boundary)).Open(input_boundary)
                
                lyr = inSrc.GetLayer()
                
                i = 1
                for feat in lyr:
                    geom = feat.GetGeometryRef()
                    
                    featext = geom.GetEnvelope()
                    
                    EXTENTS.append(featext)
                    
                    if justOneFeature:
                        break
    
    if epsg != 4326:
        from glass.g.gobj import new_pnt
        from glass.g.prj.obj  import prj_ogrgeom
        
        for i in range(len(EXTENTS)):
            bottom_left = prj_ogrgeom(new_pnt(
                EXTENTS[i][0], EXTENTS[i][2]), epsg, 4326)
        
            top_right   = prj_ogrgeom(new_pnt(
                EXTENTS[i][1], EXTENTS[i][3]), epsg, 4326)
        
            left , bottom = bottom_left.GetX(), bottom_left.GetY()
            right, top    = top_right.GetX()  , top_right.GetY()
            
            EXTENTS[i] = [left, right, bottom, top]
    
    #url = "https://overpass-api.de/api/map?bbox={}"
    url = "https://lz4.overpass-api.de/api/interpreter?bbox={}"
    
    RESULTS = []
    for e in range(len(EXTENTS)):
        bbox_str = ','.join([str(p) for p in EXTENTS[e]])
        
        if GetUrl:
            RESULTS.append(url.format(bbox_str))
            continue
        
        if len(EXTENTS) == 1:
            outOsm = os.path.join(folder_out, osm_name + '.xml')
        else:
            outOsm = os.path.join(folder_out, "{}_{}.xml".format(osm_name, str(e)))
        
        osm_file = get_file(
            url.format(bbox_str), outOsm,
            useWget=None if OS_NAME == 'Windows' else None
        )
        
        RESULTS.append(osm_file)
    
    return RESULTS[0] if len(RESULTS) == 1 else RESULTS
Esempio n. 10
0
def osm_extraction(boundary, osmdata, output, each_feat=None, epsg=None):
    """
    Extract OSM Data from a xml file with osmosis
    
    The extraction is done using the extent of a boundary
    """

    import os
    from glass.pys import execmd
    from glass.g.prj.obj import prj_ogrgeom
    from glass.g.prop import check_isRaster

    # Check if boundary is a file
    if os.path.isfile(boundary):
        # Check if boundary is a raster
        is_rst = check_isRaster(boundary)

        if is_rst:
            # Get Raster EPSG and Extent
            from glass.g.prop.prj import get_rst_epsg
            from glass.g.prop.rst import rst_ext
            from glass.g.gobj import create_polygon

            in_epsg = get_rst_epsg(boundary)
            left, right, bottom, top = rst_ext(boundary)
            boundaries = [
                create_polygon([(left, top), (right, top), (right, bottom),
                                (left, bottom), (left, top)])
            ]

        else:
            # Get Shape EPSG
            from glass.g.prop.prj import get_shp_epsg

            in_epsg = get_shp_epsg(boundary)

            if not each_feat:
                # Get Shape Extent
                from glass.g.prop.feat import get_ext
                from glass.g.gobj import create_polygon

                left, right, bottom, top = get_ext(boundary)
                boundaries = [
                    create_polygon([(left, top), (right, top), (right, bottom),
                                    (left, bottom), (left, top)])
                ]

            else:
                # Get Extent of each feature
                from osgeo import ogr
                from glass.g.prop import drv_name

                src = ogr.GetDriverByName(drv_name(boundary)).Open(boundary)
                lyr = src.GetLayer()

                boundaries = [feat.GetGeometryRef() for feat in lyr]
    else:
        from glass.g.gobj import wkt_to_geom

        in_epsg = 4326 if not epsg else epsg

        if type(boundary) == str:
            # Assuming it is a WKT string
            wkt_boundaries = [boundary]
        elif type(boundary) == list:
            # Assuming it is a List with WKT strings
            wkt_boundaries = boundary
        else:
            raise ValueError('Given boundary has a not valid value')

        boundaries = [wkt_to_geom(g) for g in wkt_boundaries]

        if None in boundaries:
            raise ValueError(
                ("boundary parameter is a string, but it is not a valid path "
                 "to a file or a valid WKT string"))

    # Get output files
    if len(boundaries) == 1:
        if os.path.isdir(output):
            fn, ff = os.path.splitext(os.path.basename(osmdata))

            out_files = [os.path.join(output, "ect_{}.{}".format(fn, ff))]
        else:
            out_files = [output]
    else:
        fn, ff = os.path.splitext(os.path.basename(osmdata))
        path = output if os.path.isdir(output) else os.path.dirname(output)
        out_files = [
            os.path.join(path, "ect_{}_{}.{}".format(fn, str(i), ff))
            for i in range(len(boundaries))
        ]

    # Extract data using OSMOSIS
    cmd = ("osmosis --read-{_f} {dtparse}file={_in} "
           "--bounding-box top={t} left={l} bottom={b} right={r} "
           "--write-{outext} file={_out}")
    for g in range(len(boundaries)):
        # Convert boundary to WGS84 -EPSG 4326
        geom_wgs = prj_ogrgeom(
            boundaries[g], int(in_epsg), 4326,
            api='shapely') if int(in_epsg) != 4326 else boundaries[g]

        # Get boundary extent
        left, right, bottom, top = geom_wgs.GetEnvelope()

        # Osmosis shell comand
        osmext = os.path.splitext(osmdata)[1]

        # Execute command
        outcmd = execmd(
            cmd.format(
                _f='pbf' if osmext == '.pbf' else 'xml',
                _in=osmdata,
                t=str(top),
                l=str(left),
                b=str(bottom),
                r=str(right),
                _out=out_files[g],
                outext=os.path.splitext(out_files[g])[1][1:],
                dtparse="" if osmext == '.pbf' else "enableDataParsing=no "))

    return output
Esempio n. 11
0
File: rst.py Progetto: jasp382/glass
def adjust_ext_to_snap(outExt, snapRst):
    """
    Adjust extent for a output raster to snap with other raster
    """

    from glass.g.prop import check_isShp, check_isRaster
    from glass.g.prop.rst import rst_ext, get_cellsize
    from glass.g.gobj import new_pnt, create_polygon

    # Check if outExt is a raster or not
    isRst = check_isRaster(outExt)

    if isRst:
        shpAExt = rst_ext(outExt)

    else:
        isShp = check_isShp(outExt)

        if isShp:
            from glass.g.prop.feat import get_ext

            shpAExt = get_ext(outExt)

        else:
            raise ValueError(
                ("outExt value should be a path to a SHP or to a Raster file"))

    # Check if snapRst is a raster
    isRst = check_isRaster(snapRst)

    if not isRst:
        raise ValueError(("snapRst should be a path to a raster file"))

    # Get snapRst Extent
    snapRstExt = rst_ext(snapRst)

    # Get cellsize
    csize = get_cellsize(snapRst)

    # Find extent point of outExt inside the two extents
    # This will be used as pseudo origin

    snapRstPnt = [
        new_pnt(snapRstExt[0], snapRstExt[3]),
        new_pnt(snapRstExt[1], snapRstExt[3]),
        new_pnt(snapRstExt[1], snapRstExt[2]),
        new_pnt(snapRstExt[0], snapRstExt[2]),
        new_pnt(snapRstExt[0], snapRstExt[3]),
    ]

    poly_snap_rst = create_polygon(snapRstPnt)

    outExtPnt = {
        'top_left': new_pnt(shpAExt[0], shpAExt[3]),
        'top_right': new_pnt(shpAExt[1], shpAExt[3]),
        'bottom_right': new_pnt(shpAExt[1], shpAExt[2]),
        'bottom_left': new_pnt(shpAExt[0], shpAExt[2])
    }

    out_rst_pseudo = {}
    for pnt in outExtPnt:
        out_rst_pseudo[pnt] = outExtPnt[pnt].Intersects(poly_snap_rst)

    pseudoOrigin = outExtPnt['top_left'] if out_rst_pseudo['top_left'] else \
        outExtPnt['bottom_left'] if out_rst_pseudo['bottom_left'] else \
        outExtPnt['top_right'] if out_rst_pseudo['top_right'] else \
        outExtPnt['bottom_right'] if out_rst_pseudo['bottom_right'] else None

    if not pseudoOrigin:
        raise ValueError(('Extents doesn\'t have overlapping areas'))

    pseudoOriginName = 'top_left' if out_rst_pseudo['top_left'] else \
        'bottom_left' if out_rst_pseudo['bottom_left'] else \
        'top_right' if out_rst_pseudo['top_right'] else \
        'bottom_right' if out_rst_pseudo['bottom_right'] else None

    # Get out Raster Shape
    n_col = int((shpAExt[1] - shpAExt[0]) / csize)
    n_row = int((shpAExt[3] - shpAExt[2]) / csize)

    # Get Output Raster real origin/top left
    yName, xName = pseudoOriginName.split('_')

    if xName == 'left':
        # Obtain left of output Raster
        left_out_rst = snapRstExt[0] + (csize * int(
            (shpAExt[0] - snapRstExt[0]) / csize))

    else:
        # obtain right of output Raster
        right_out_rst = snapRstExt[1] - (csize * int(
            (snapRstExt[1] - shpAExt[1]) / csize))

        # Use right to obtain left coordinate
        left_out_rst = right_out_rst - (n_col * csize)

    if yName == 'top':
        # Obtain top of output Raster
        top_out_rst = snapRstExt[3] - (csize * int(
            (snapRstExt[3] - shpAExt[3]) / csize))

    else:
        # obtain bottom of output raster
        bot_out_rst = snapRstExt[2] + (csize * int(
            (shpAExt[2] - snapRstExt[2]) / csize))

        # use bottom to find the top of the output raster
        top_out_rst = bot_out_rst + (n_row * csize)

    return left_out_rst, top_out_rst, n_row, n_col, csize
Esempio n. 12
0
File: num.py Progetto: jasp382/glass
def osm2lulc(osmdata,
             nomenclature,
             refRaster,
             lulcRst,
             overwrite=None,
             dataStore=None,
             roadsAPI='POSTGIS'):
    """
    Convert OSM data into Land Use/Land Cover Information
    
    A matrix based approach
    
    roadsAPI Options:
    * SQLITE
    * POSTGIS
    """

    # ************************************************************************ #
    # Python Modules from Reference Packages #
    # ************************************************************************ #
    import os
    import numpy
    import datetime
    from threading import Thread
    from osgeo import gdal
    # ************************************************************************ #
    # Dependencies #
    # ************************************************************************ #
    from glass.g.rd.rst import rst_to_array
    from glass.g.prop import check_isRaster
    from glass.g.prop.rst import get_cellsize
    from glass.pys.oss import mkdir, copy_file
    from glass.pys.oss import fprop
    if roadsAPI == 'POSTGIS':
        from glass.ng.sql.db import create_db
        from glass.g.it.db import osm_to_psql
        from glass.ete.osm2lulc.mod2 import pg_num_roads
        from glass.ng.sql.bkup import dump_db
        from glass.ng.sql.db import drop_db
    else:
        from glass.g.it.osm import osm_to_sqdb
        from glass.ete.osm2lulc.mod2 import num_roads
    from glass.ete.osm2lulc.utils import osm_project, add_lulc_to_osmfeat
    from glass.ete.osm2lulc.utils import osmlulc_rsttbl
    from glass.ete.osm2lulc.utils import get_ref_raster
    from glass.ete.osm2lulc.mod1 import num_selection
    from glass.ete.osm2lulc.m3_4 import num_selbyarea
    from glass.ete.osm2lulc.mod5 import num_base_buffer
    from glass.ete.osm2lulc.mod6 import num_assign_builds
    from glass.g.wt.rst import obj_to_rst
    # ************************************************************************ #
    # Global Settings #
    # ************************************************************************ #
    # Check if input parameters exists!
    if not os.path.exists(os.path.dirname(lulcRst)):
        raise ValueError('{} does not exist!'.format(os.path.dirname(lulcRst)))

    if not os.path.exists(osmdata):
        raise ValueError(
            'File with OSM DATA ({}) does not exist!'.format(osmdata))

    if not os.path.exists(refRaster):
        raise ValueError(
            'File with reference area ({}) does not exist!'.format(refRaster))

    # Check if Nomenclature is valid
    nomenclature = "URBAN_ATLAS" if nomenclature != "URBAN_ATLAS" and \
        nomenclature != "CORINE_LAND_COVER" and \
        nomenclature == "GLOBE_LAND_30" else nomenclature

    time_a = datetime.datetime.now().replace(microsecond=0)

    workspace = os.path.join(os.path.dirname(lulcRst),
                             'num_osmto') if not dataStore else dataStore

    # Check if workspace exists:
    if os.path.exists(workspace):
        if overwrite:
            mkdir(workspace, overwrite=True)
        else:
            raise ValueError('Path {} already exists'.format(workspace))
    else:
        mkdir(workspace, overwrite=None)

    # Get Ref Raster and EPSG
    refRaster, epsg = get_ref_raster(refRaster, workspace, cellsize=2)
    CELLSIZE = get_cellsize(refRaster, gisApi='gdal')

    from glass.ete.osm2lulc import osmTableData, PRIORITIES

    time_b = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Convert OSM file to SQLITE DB or to POSTGIS DB #
    # ************************************************************************ #
    if roadsAPI == 'POSTGIS':
        osm_db = create_db(fprop(osmdata, 'fn', forceLower=True),
                           overwrite=True)
        osm_db = osm_to_psql(osmdata, osm_db)

    else:
        osm_db = osm_to_sqdb(osmdata, os.path.join(workspace, 'osm.sqlite'))
    time_c = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Add Lulc Classes to OSM_FEATURES by rule #
    # ************************************************************************ #
    add_lulc_to_osmfeat(osm_db, osmTableData, nomenclature, api=roadsAPI)
    time_d = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Transform SRS of OSM Data #
    # ************************************************************************ #
    osmTableData = osm_project(
        osm_db,
        epsg,
        api=roadsAPI,
        isGlobeLand=None if nomenclature != "GLOBE_LAND_30" else True)
    time_e = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # MapResults #
    # ************************************************************************ #
    mergeOut = {}
    timeCheck = {}
    RULES = [1, 2, 3, 4, 5, 7]

    def run_rule(ruleID):
        time_start = datetime.datetime.now().replace(microsecond=0)
        _osmdb = copy_file(
            osm_db,
            os.path.splitext(osm_db)[0] +
            '_r{}.sqlite'.format(ruleID)) if roadsAPI == 'SQLITE' else None
        # ******************************************************************** #
        # 1 - Selection Rule #
        # ******************************************************************** #
        if ruleID == 1:
            res, tm = num_selection(_osmdb if _osmdb else osm_db,
                                    osmTableData['polygons'],
                                    workspace,
                                    CELLSIZE,
                                    epsg,
                                    refRaster,
                                    api=roadsAPI)
        # ******************************************************************** #
        # 2 - Get Information About Roads Location #
        # ******************************************************************** #
        elif ruleID == 2:
            res, tm = num_roads(
                _osmdb, nomenclature, osmTableData['lines'],
                osmTableData['polygons'], workspace, CELLSIZE, epsg,
                refRaster) if _osmdb else pg_num_roads(
                    osm_db, nomenclature, osmTableData['lines'],
                    osmTableData['polygons'], workspace, CELLSIZE, epsg,
                    refRaster)

        # ******************************************************************** #
        # 3 - Area Upper than #
        # ******************************************************************** #
        elif ruleID == 3:
            if nomenclature != "GLOBE_LAND_30":
                res, tm = num_selbyarea(osm_db if not _osmdb else _osmdb,
                                        osmTableData['polygons'],
                                        workspace,
                                        CELLSIZE,
                                        epsg,
                                        refRaster,
                                        UPPER=True,
                                        api=roadsAPI)
            else:
                return

        # ******************************************************************** #
        # 4 - Area Lower than #
        # ******************************************************************** #
        elif ruleID == 4:
            if nomenclature != "GLOBE_LAND_30":
                res, tm = num_selbyarea(osm_db if not _osmdb else _osmdb,
                                        osmTableData['polygons'],
                                        workspace,
                                        CELLSIZE,
                                        epsg,
                                        refRaster,
                                        UPPER=False,
                                        api=roadsAPI)
            else:
                return

        # ******************************************************************** #
        # 5 - Get data from lines table (railway | waterway) #
        # ******************************************************************** #
        elif ruleID == 5:
            res, tm = num_base_buffer(osm_db if not _osmdb else _osmdb,
                                      osmTableData['lines'],
                                      workspace,
                                      CELLSIZE,
                                      epsg,
                                      refRaster,
                                      api=roadsAPI)
        # ******************************************************************** #
        # 7 - Assign untagged Buildings to tags #
        # ******************************************************************** #
        elif ruleID == 7:
            if nomenclature != "GLOBE_LAND_30":
                res, tm = num_assign_builds(osm_db if not _osmdb else _osmdb,
                                            osmTableData['points'],
                                            osmTableData['polygons'],
                                            workspace,
                                            CELLSIZE,
                                            epsg,
                                            refRaster,
                                            apidb=roadsAPI)

            else:
                return

        time_end = datetime.datetime.now().replace(microsecond=0)
        mergeOut[ruleID] = res
        timeCheck[ruleID] = {'total': time_end - time_start, 'detailed': tm}

    thrds = []
    for r in RULES:
        thrds.append(
            Thread(name="to_{}".format(str(r)), target=run_rule, args=(r, )))

    for t in thrds:
        t.start()
    for t in thrds:
        t.join()

    # Merge all results into one Raster
    compileResults = {}
    for rule in mergeOut:
        for cls in mergeOut[rule]:
            if cls not in compileResults:
                if type(mergeOut[rule][cls]) == list:
                    compileResults[cls] = mergeOut[rule][cls]
                else:
                    compileResults[cls] = [mergeOut[rule][cls]]

            else:
                if type(mergeOut[rule][cls]) == list:
                    compileResults[cls] += mergeOut[rule][cls]
                else:
                    compileResults[cls].append(mergeOut[rule][cls])

    time_m = datetime.datetime.now().replace(microsecond=0)
    # All Rasters to Array
    arrayRst = {}
    for cls in compileResults:
        for raster in compileResults[cls]:
            if not raster:
                continue

            array = rst_to_array(raster)

            if cls not in arrayRst:
                arrayRst[cls] = [array.astype(numpy.uint8)]

            else:
                arrayRst[cls].append(array.astype(numpy.uint8))
    time_n = datetime.datetime.now().replace(microsecond=0)

    # Sum Rasters of each class
    for cls in arrayRst:
        if len(arrayRst[cls]) == 1:
            sumArray = arrayRst[cls][0]

        else:
            sumArray = arrayRst[cls][0]

            for i in range(1, len(arrayRst[cls])):
                sumArray = sumArray + arrayRst[cls][i]

        arrayRst[cls] = sumArray

    time_o = datetime.datetime.now().replace(microsecond=0)

    # Apply priority rule
    __priorities = PRIORITIES[nomenclature + "_NUMPY"]

    for lulcCls in __priorities:
        __lulcCls = rstcls_map(lulcCls)

        if __lulcCls not in arrayRst:
            continue
        else:
            numpy.place(arrayRst[__lulcCls], arrayRst[__lulcCls] > 0, lulcCls)

    for i in range(len(__priorities)):
        lulc_i = rstcls_map(__priorities[i])

        if lulc_i not in arrayRst:
            continue

        else:
            for e in range(i + 1, len(__priorities)):
                lulc_e = rstcls_map(__priorities[e])

                if lulc_e not in arrayRst:
                    continue

                else:
                    numpy.place(arrayRst[lulc_e],
                                arrayRst[lulc_i] == __priorities[i], 0)

    time_p = datetime.datetime.now().replace(microsecond=0)

    # Merge all rasters
    startCls = 'None'
    for i in range(len(__priorities)):
        lulc_i = rstcls_map(__priorities[i])

        if lulc_i in arrayRst:
            resultSum = arrayRst[lulc_i]
            startCls = i
            break

    if startCls == 'None':
        return 'NoResults'

    for i in range(startCls + 1, len(__priorities)):
        lulc_i = rstcls_map(__priorities[i])

        if lulc_i not in arrayRst:
            continue

        resultSum = resultSum + arrayRst[lulc_i]

    # Save Result
    outIsRst = check_isRaster(lulcRst)
    if not outIsRst:
        from glass.pys.oss import fprop

        lulcRst = os.path.join(os.path.dirname(lulcRst),
                               fprop(lulcRst, 'fn') + '.tif')

    numpy.place(resultSum, resultSum == 0, 1)
    obj_to_rst(resultSum, lulcRst, refRaster, noData=1)

    osmlulc_rsttbl(
        nomenclature + "_NUMPY",
        os.path.join(os.path.dirname(lulcRst),
                     os.path.basename(lulcRst) + '.vat.dbf'))

    time_q = datetime.datetime.now().replace(microsecond=0)

    # Dump Database if PostGIS was used
    # Drop Database if PostGIS was used
    if roadsAPI == 'POSTGIS':
        dump_db(osm_db, os.path.join(workspace, osm_db + '.sql'), api='psql')
        drop_db(osm_db)

    return lulcRst, {
        0: ('set_settings', time_b - time_a),
        1: ('osm_to_sqdb', time_c - time_b),
        2: ('cls_in_sqdb', time_d - time_c),
        3: ('proj_data', time_e - time_d),
        4: ('rule_1', timeCheck[1]['total'], timeCheck[1]['detailed']),
        5: ('rule_2', timeCheck[2]['total'], timeCheck[2]['detailed']),
        6:
        None if 3 not in timeCheck else
        ('rule_3', timeCheck[3]['total'], timeCheck[3]['detailed']),
        7:
        None if 4 not in timeCheck else
        ('rule_4', timeCheck[4]['total'], timeCheck[4]['detailed']),
        8: ('rule_5', timeCheck[5]['total'], timeCheck[5]['detailed']),
        9:
        None if 7 not in timeCheck else
        ('rule_7', timeCheck[7]['total'], timeCheck[7]['detailed']),
        10: ('rst_to_array', time_n - time_m),
        11: ('sum_cls', time_o - time_n),
        12: ('priority_rule', time_p - time_o),
        13: ('merge_rst', time_q - time_p)
    }