Ejemplo n.º 1
0
Archivo: mtx.py Proyecto: jasp382/glass
def bash_matrix_od(origins, destinationShp, network, costCol, oneway, grsWork,
                   output):
    """
    Produce matrix OD using GRASS GIS - BASH MODE
    """

    from glass.g.wenv.grs import run_grass
    from glass.pys.oss import fprop, mkdir
    from glass.g.dp.split import splitShp_by_range
    from glass.g.dp.mge import shps_to_shp

    # SPLIT ORIGINS IN PARTS
    originsFld = mkdir(os.path.join(grsWork, 'origins_parts'))

    originsList = splitShp_by_range(origins, 100, originsFld)

    # Open an GRASS GIS Session
    gbase = run_grass(grsWork,
                      grassBIN="grass76",
                      location='location',
                      srs=network)

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

    RESULTS = []
    R_FOLDER = mkdir(os.path.join(grsWork, 'res_parts'))

    for e in range(len(originsList)):
        gsetup.init(gbase, grsWork, "grs_loc_{}".format(e), 'PERMANENT')

        from glass.g.it.shp import shp_to_grs, grs_to_shp

        # Add Data to GRASS GIS
        rdvMain = shp_to_grs(network, fprop(network, 'fn', forceLower=True))

        # Produce Matrix
        result_part = prod_matrix(originsList[e], destinationShp, rdvMain,
                                  costCol, oneway)

        # Export Result
        shp = grs_to_shp(result_part,
                         os.path.join(R_FOLDER, result_part + '.shp'),
                         geom_type="line",
                         lyrN=3)

        RESULTS.append(shp)

    shps_to_shp(RESULTS, output, api='pandas')

    return output
Ejemplo n.º 2
0
def distance_between_catpoints(srcShp, facilitiesShp, networkShp,
                               speedLimitCol, onewayCol, grsWorkspace,
                               grsLocation, outputShp):
    """
    Path bet points
    
    TODO: Work with files with cat
    """

    import os
    from glass.pys.oss import fprop
    from glass.g.wenv.grs import run_grass
    from glass.g.dp.mge import shps_to_shp
    from glass.g.prop.feat import feat_count

    # Merge Source points and Facilities into the same Feature Class
    SRC_NFEAT = feat_count(srcShp, gisApi='pandas')
    FACILITY_NFEAT = feat_count(facilitiesShp, gisApi='pandas')

    POINTS = shps_to_shp([srcShp, facilitiesShp],
                         os.path.join(os.path.dirname(outputShp),
                                      "points_net.shp"),
                         api='pandas')

    # Open an GRASS GIS Session
    gbase = run_grass(grsWorkspace,
                      grassBIN="grass76",
                      location=grsLocation,
                      srs=networkShp)

    import grass.script as grass
    import grass.script.setup as gsetup
    gsetup.init(gbase, grsWorkspace, grsLocation, 'PERMANENT')

    # Import GRASS GIS Module
    from glass.g.it.shp import shp_to_grs, grs_to_shp
    from glass.g.tbl.attr import geomattr_to_db
    from glass.g.cp import copy_insame_vector
    from glass.g.tbl import category
    from glass.g.tbl.grs import add_table, update_table
    from glass.g.mob.grstbx.vnet import network_from_arcs
    from glass.g.mob.grstbx.vnet import add_pnts_to_network
    from glass.g.mob.grstbx.vnet import netpath

    # Add Data to GRASS GIS
    rdvMain = shp_to_grs(networkShp, fprop(networkShp, 'fn', forceLower=True))
    pntShp = shp_to_grs(POINTS, "points_net")
    """Get closest facility layer:"""
    # Connect Points to Network
    newNetwork = add_pnts_to_network(rdvMain, pntShp, "rdv_points")

    # Sanitize Network Table and Cost Columns
    newNetwork = category(newNetwork,
                          "rdv_points_time",
                          "add",
                          LyrN="3",
                          geomType="line")

    add_table(newNetwork,
              ("cat integer,kph double precision,length double precision,"
               "ft_minutes double precision,"
               "tf_minutes double precision,oneway text"),
              lyrN=3)

    copy_insame_vector(newNetwork, "kph", speedLimitCol, 3, geomType="line")
    copy_insame_vector(newNetwork, "oneway", onewayCol, 3, geomType="line")

    geomattr_to_db(newNetwork,
                   "length",
                   "length",
                   "line",
                   createCol=False,
                   unit="meters",
                   lyrN=3)

    update_table(newNetwork, "kph", "3.6", "kph IS NULL", lyrN=3)
    update_table(newNetwork,
                 "ft_minutes",
                 "(length * 60) / (kph * 1000.0)",
                 "ft_minutes IS NULL",
                 lyrN=3)
    update_table(newNetwork,
                 "tf_minutes",
                 "(length * 60) / (kph * 1000.0)",
                 "tf_minutes IS NULL",
                 lyrN=3)

    # Exagerate Oneway's
    update_table(newNetwork, "ft_minutes", "1000", "oneway = 'TF'", lyrN=3)
    update_table(newNetwork, "tf_minutes", "1000", "oneway = 'FT'", lyrN=3)

    # Produce result
    result = netpath(newNetwork,
                     "",
                     "ft_minutes",
                     "tf_minutes",
                     fprop(outputShp, 'fn'),
                     arcLyr=3,
                     nodeLyr=2)

    return grs_to_shp(result, outputShp, geomType="line", lyrN=3)
Ejemplo n.º 3
0
def vector_based(osmdata, nomenclature, refRaster, lulcShp,
                 overwrite=None, dataStore=None, RoadsAPI='POSTGIS'):
    """
    Convert OSM Data into Land Use/Land Cover Information
    
    An vector based approach.
    
    TODO: Add a detailed description.
    
    RoadsAPI Options:
    * GRASS
    * SQLITE
    * POSTGIS
    """
    
    # ************************************************************************ #
    # Python Modules from Reference Packages #
    # ************************************************************************ #
    import datetime; import os; import copy
    # ************************************************************************ #
    # glass dependencies #
    # ************************************************************************ #
    from glass.pys.oss               import fprop, mkdir
    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.ng.sql.db            import drop_db
        from glass.ng.sql.bkup        import dump_db
    else:
        from glass.g.it.osm import osm_to_sqdb
    from glass.ete.osm2lulc.utils    import osm_project, add_lulc_to_osmfeat, get_ref_raster
    from glass.g.dp.mge    import shps_to_shp
    from glass.ete.osm2lulc.mod1     import grs_vector
    if RoadsAPI == 'SQLITE' or RoadsAPI == 'POSTGIS':
        from glass.ete.osm2lulc.mod2 import roads_sqdb
    else:
        from glass.ete.osm2lulc.mod2 import grs_vec_roads
    from glass.ete.osm2lulc.m3_4     import grs_vect_selbyarea
    from glass.ete.osm2lulc.mod5     import grs_vect_bbuffer
    from glass.ete.osm2lulc.mod6     import vector_assign_pntags_to_build
    from glass.g.dp.mge    import same_attr_to_shp
    from glass.g.prj            import def_prj
    # ************************************************************************ #
    # Global Settings #
    # ************************************************************************ #
    # Check if input parameters exists!
    if not os.path.exists(os.path.dirname(lulcShp)):
        raise ValueError('{} does not exist!'.format(os.path.dirname(lulcShp)))
    
    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)
    
    # Create workspace for temporary files
    workspace = os.path.join(os.path.dirname(
        lulcShp), '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 Reference Raster
    refRaster, epsg = get_ref_raster(refRaster, workspace, cellsize=10)
    
    from glass.ete.osm2lulc import osmTableData, PRIORITIES, LEGEND
    
    __priorities = PRIORITIES[nomenclature]
    __legend     = LEGEND[nomenclature]
    
    time_b = datetime.datetime.now().replace(microsecond=0)
    
    if RoadsAPI != 'POSTGIS':
        # ******************************************************************** #
        # Convert OSM file to SQLITE DB #
        # ******************************************************************** #
        osm_db = osm_to_sqdb(osmdata, os.path.join(workspace, 'osm.sqlite'))
    else:
        # Convert OSM file to POSTGRESQL DB #
        osm_db = create_db(fprop(
            osmdata, 'fn', forceLower=True), overwrite=True)
        osm_db = osm_to_psql(osmdata, osm_db)
    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='SQLITE' if RoadsAPI != 'POSTGIS' else RoadsAPI
    )
    time_d = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # Transform SRS of OSM Data #
    # ************************************************************************ #
    osmTableData = osm_project(
        osm_db, epsg,
        api='SQLITE' if RoadsAPI != 'POSTGIS' else 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.gp.ovl       import erase
    from glass.g.wenv.grs     import rst_to_region
    from glass.g.gp.gen     import dissolve
    from glass.g.tbl.grs import add_and_update, reset_table, update_table
    from glass.g.tbl.col import add_fields
    from glass.g.it.shp import shp_to_grs, grs_to_shp
    from glass.g.it.rst     import rst_to_grs
    # ************************************************************************ #
    # 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 #
    # ************************************************************************ #
    osmShps = []
    # ************************************************************************ #
    # 1 - Selection Rule #
    # ************************************************************************ #
    ruleOneShp, timeCheck1 = grs_vector(
        osm_db, osmTableData['polygons'], apidb=RoadsAPI
    )
    osmShps.append(ruleOneShp)
    
    time_g = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 2 - Get Information About Roads Location #
    # ************************************************************************ #
    ruleRowShp, timeCheck2 = roads_sqdb(
        osm_db, osmTableData['lines'], osmTableData['polygons'], apidb=RoadsAPI
    ) if RoadsAPI == 'SQLITE' or RoadsAPI == 'POSTGIS' else grs_vec_roads(
        osm_db, osmTableData['lines'], osmTableData['polygons'])
    
    osmShps.append(ruleRowShp)
    time_h = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 3 - Area Upper than #
    # ************************************************************************ #
    if nomenclature != "GLOBE_LAND_30":
        ruleThreeShp, timeCheck3 = grs_vect_selbyarea(
            osm_db, osmTableData['polygons'], UPPER=True, apidb=RoadsAPI
        )
    
        osmShps.append(ruleThreeShp)
        time_l = datetime.datetime.now().replace(microsecond=0)
    else:
        timeCheck3 = None
        time_l     = None
    # ************************************************************************ #
    # 4 - Area Lower than #
    # ************************************************************************ #
    if nomenclature != "GLOBE_LAND_30":
        ruleFourShp, timeCheck4 = grs_vect_selbyarea(
            osm_db, osmTableData['polygons'], UPPER=False, apidb=RoadsAPI
        )
    
        osmShps.append(ruleFourShp)
        time_j = datetime.datetime.now().replace(microsecond=0)
    else:
        timeCheck4 = None
        time_j     = None
    # ************************************************************************ #
    # 5 - Get data from lines table (railway | waterway) #
    # ************************************************************************ #
    ruleFiveShp, timeCheck5 = grs_vect_bbuffer(
        osm_db, osmTableData["lines"], api_db=RoadsAPI
    )
    
    osmShps.append(ruleFiveShp)
    time_m = datetime.datetime.now().replace(microsecond=0)
    # ************************************************************************ #
    # 7 - Assign untagged Buildings to tags #
    # ************************************************************************ #
    if nomenclature != "GLOBE_LAND_30":
        ruleSeven11, ruleSeven12, timeCheck7 = vector_assign_pntags_to_build(
            osm_db, osmTableData['points'], osmTableData['polygons'],
            apidb=RoadsAPI
        )
        
        if ruleSeven11:
            osmShps.append(ruleSeven11)
        
        if ruleSeven12:
            osmShps.append(ruleSeven12)
        
        time_n = datetime.datetime.now().replace(microsecond=0)
    
    else:
        timeCheck7 = None
        time_n = datetime.datetime.now().replace(microsecond=0)
    
    # ************************************************************************ #
    # Produce LULC Map  #
    # ************************************************************************ #
    """
    Get Shps with all geometries related with one class - One Shape for Classe
    """
    
    _osmShps = []
    for i in range(len(osmShps)):
        if not osmShps[i]: continue
        
        _osmShps.append(grs_to_shp(
            osmShps[i], os.path.join(workspace, osmShps[i] + '.shp'),
            'auto', lyrN=1, asCMD=True, asMultiPart=None
        ))
    
    for shp in _osmShps:
        def_prj(os.path.splitext(shp)[0] + '.prj', epsg=epsg, api='epsgio')
    
    _osmShps = same_attr_to_shp(
        _osmShps, "cat", workspace, "osm_", resultDict=True
    )
    del osmShps
    
    time_o = datetime.datetime.now().replace(microsecond=0)
    
    """
    Merge all Classes into one feature class using a priority rule
    """
    
    osmShps = {}
    for cls in _osmShps:
        if cls == '1':
            osmShps[1221] = shp_to_grs(_osmShps[cls], "osm_1221", asCMD=True)
        
        else:
            osmShps[int(cls)] = shp_to_grs(_osmShps[cls], "osm_" + cls,
                asCMD=True)
    
    # Erase overlapping areas by priority
    osmNameRef = copy.deepcopy(osmShps)
    
    for e in range(len(__priorities)):
        if e + 1 == len(__priorities): break
        
        if __priorities[e] not in osmShps:
            continue
        else:
            for i in range(e+1, len(__priorities)):
                if __priorities[i] not in osmShps:
                    continue
                else:
                    osmShps[__priorities[i]] = erase(
                        osmShps[__priorities[i]], osmShps[__priorities[e]],
                        "{}_{}".format(osmNameRef[__priorities[i]], e),
                        notTbl=True, api='pygrass'
                    )
    
    time_p = datetime.datetime.now().replace(microsecond=0)
    
    # Export all classes
    lst_merge = []
    a = None
    for i in range(len(__priorities)):
        if __priorities[i] not in osmShps:
            continue
        
        if not a:
            reset_table(
                osmShps[__priorities[i]],
                {'cls' : 'varchar(5)', 'leg' : 'varchar(75)'},
                {'cls' : str(__priorities[i]), 'leg' : str(__legend[__priorities[i]])}
            )
            
            a = 1
        
        else:
            add_and_update(
                osmShps[__priorities[i]],
                {'cls' : 'varchar(5)'},
                {'cls' : str(__priorities[i])}
            )
        
        ds = dissolve(
            osmShps[__priorities[i]],
            'dl_{}'.format(str(__priorities[i])), 'cls', api="grass"
        )
        
        add_fields(ds, {'leg': 'varchar(75)'}, api="grass")
        update_table(ds, 'leg', str(__legend[__priorities[i]]), 'leg is null')
        
        lst_merge.append(grs_to_shp(
            ds, os.path.join(
                workspace, "lulc_{}.shp".format(str(__priorities[i]))
            ), 'auto', lyrN=1, asCMD=True, asMultiPart=None
        ))
    
    time_q = datetime.datetime.now().replace(microsecond=0)
    
    if fprop(lulcShp, 'ff') != '.shp':
        lulcShp = os.path.join(
            os.path.dirname(lulcShp), fprop(lulcShp, 'fn') + '.shp')
    
    shps_to_shp(lst_merge, lulcShp, api='pandas')

    # Check if prj of lulcShp exists and create it if necessary
    prj_ff = os.path.splitext(lulcShp)[0] + '.prj'
    if not os.path.exists(prj_ff):
        def_prj(prj_ff, epsg=epsg, api='epsgio')
    
    time_r = 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 lulcShp, {
        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 : ('disj_cls', time_o - time_n),
        12 : ('priority_rule', time_p - time_o),
        13 : ('export_cls', time_q - time_p),
        14 : ('merge_cls', time_r - time_q)
    }
Ejemplo n.º 4
0
def optimized_union_anls(lyr_a,
                         lyr_b,
                         outShp,
                         ref_boundary,
                         workspace=None,
                         multiProcess=None):
    """
    Optimized Union Analysis
    
    Goal: optimize v.overlay performance for Union operations
    """

    import os
    from glass.pys.oss import fprop, lst_ff
    from glass.pys.oss import cpu_cores
    from glass.g.smp import create_fishnet
    from glass.g.wenv.grs import run_grass
    from glass.g.dp.split import eachfeat_to_newshp
    from glass.g.dp.mge import shps_to_shp
    from glass.g.wt.rst import shpext_to_rst
    from glass.g.prop.ext import get_ext

    if workspace:
        if not os.path.exists(workspace):
            from glass.pys.oss import mkdir

            mkdir(workspace, overwrite=True)

    else:
        from glass.pys.oss import mkdir

        workspace = mkdir(os.path.join(os.path.dirname(outShp), "union_work"))

    # Create Fishnet
    ncpu = cpu_cores()
    if ncpu == 12:
        nrow = 4
        ncol = 3
    elif ncpu == 8:
        nrow = 4
        ncol = 2
    else:
        nrow = 2
        ncol = 2

    ext = get_ext(ref_boundary)
    width = (ext[1] - ext[0]) / ncol
    height = (ext[3] - ext[2]) / nrow

    gridShp = create_fishnet(ref_boundary,
                             os.path.join(workspace, 'ref_grid.shp'),
                             width,
                             height,
                             xy_row_col=None)

    # Split Fishnet in several files
    cellsShp = eachfeat_to_newshp(gridShp, workspace)

    if not multiProcess:
        # INIT GRASS GIS Session
        grsbase = run_grass(workspace, location="grs_loc", srs=ref_boundary)

        import grass.script.setup as gsetup

        gsetup.init(grsbase, workspace, "grs_loc", 'PERMANENT')

        # Add data to GRASS GIS
        from glass.g.it.shp import shp_to_grs

        cellsShp = [
            shp_to_grs(shp, fprop(shp, 'fn'), asCMD=True) for shp in cellsShp
        ]

        LYR_A = shp_to_grs(lyr_a, fprop(lyr_a, 'fn'), asCMD=True)
        LYR_B = shp_to_grs(lyr_b, fprop(lyr_b, 'fn'), asCMD=True)

        # Clip Layers A and B for each CELL in fishnet
        LYRS_A = [
            grsclip(LYR_A, cellsShp[x], LYR_A + "_" + str(x), cmd=True)
            for x in range(len(cellsShp))
        ]
        LYRS_B = [
            grsclip(LYR_B, cellsShp[x], LYR_B + "_" + str(x), cmd=True)
            for x in range(len(cellsShp))
        ]

        # Union SHPS
        UNION_SHP = [
            grsunion(LYRS_A[i], LYRS_B[i], f"un_{str(i)}", cmd=True)
            for i in range(len(cellsShp))
        ]

        # Export Data
        from glass.g.it.shp import grs_to_shp

        _UNION_SHP = [
            grs_to_shp(shp, os.path.join(workspace, shp + ".shp"), "area")
            for shp in UNION_SHP
        ]

    else:

        def clip_and_union(la, lb, cell, work, proc, output):
            ref_rst = shpext_to_rst(cell,
                                    os.path.join(os.path.dirname(cell),
                                                 fprop(cell, 'fn') + '.tif'),
                                    cellsize=10)

            # Start GRASS GIS Session
            loc = "proc_" + str(proc)
            grsbase = run_grass(work, location=loc, srs=ref_rst)
            import grass.script.setup as gsetup
            gsetup.init(grsbase, work, loc, 'PERMANENT')

            # Import GRASS GIS modules
            from glass.g.it.shp import shp_to_grs, grs_to_shp
            from glass.g.prop.feat import feat_count

            # Add data to GRASS
            a = shp_to_grs(la, fprop(la, 'fn'), filterByReg=True, asCMD=True)
            b = shp_to_grs(lb, fprop(lb, 'fn'), filterByReg=True, asCMD=True)

            if not feat_count(a, gisApi="grass", work=work, loc=loc):
                return

            if not feat_count(b, gisApi="grass", work=work, loc=loc):
                return

            # Clip
            a_clip = grsclip(a,
                             None,
                             "{}_clip".format(a),
                             cmd=True,
                             clip_by_region=True)
            b_clip = grsclip(b,
                             None,
                             "{}_clip".format(b),
                             cmd=True,
                             clip_by_region=True)

            # Union
            u_shp = grsunion(a_clip,
                             b_clip,
                             f"un_{fprop(cell, 'fn')}",
                             cmd=True)

            # Export
            o = grs_to_shp(u_shp, output, "area")

        import multiprocessing

        thrds = [
            multiprocessing.Process(
                target=clip_and_union,
                name="th-{}".format(i),
                args=(lyr_a, lyr_b, cellsShp[i],
                      os.path.join(workspace, "th_{}".format(i)), i,
                      os.path.join(workspace, "uniao_{}.shp".format(i))))
            for i in range(len(cellsShp))
        ]

        for t in thrds:
            t.start()

        for t in thrds:
            t.join()

        ff_shp = lst_ff(workspace, file_format='.shp')
        _UNION_SHP = []
        for i in range(len(cellsShp)):
            p = os.path.join(workspace, "uniao_{}.shp".format(i))

            if p in ff_shp:
                _UNION_SHP.append(p)
            else:
                continue

    # Merge all union into the same layer
    MERGED_SHP = shps_to_shp(_UNION_SHP, outShp, api="ogr2ogr")

    return MERGED_SHP
Ejemplo n.º 5
0
def cf_based_on_relations(incidents,
                          incidents_id,
                          group_incidents_col,
                          facilities,
                          facilities_id,
                          rel_inc_fac,
                          sheet,
                          group_fk,
                          facilities_fk,
                          output,
                          impedante='TravelTime'):
    """
    Calculate time travel considering specific facilities
    for each group of incidents

    Relations between incidents and facilities are in a auxiliar table (rel_inc_fac).
    Auxiliar table must be a xlsx file
    """

    import os
    import pandas as pd
    from glass.ng.rd import tbl_to_obj
    from glass.g.rd.shp import shp_to_obj
    from glass.g.wt.shp import obj_to_shp
    from glass.g.prop.prj import get_shp_epsg
    from glass.pys.oss import mkdir, fprop
    from glass.g.dp.mge import shps_to_shp

    # Avoid problems when facilities_id == facilities_fk
    facilities_fk = facilities_fk + '_fk' if facilities_id == facilities_fk else \
        facilities_fk

    # Open data
    incidents_df = shp_to_obj(incidents)
    facilities_df = shp_to_obj(facilities)

    rel_df = tbl_to_obj(rel_inc_fac, sheet=sheet)

    # Get SRS
    epsg = get_shp_epsg(incidents)

    # Create dir for temporary files
    tmpdir = mkdir(os.path.join(os.path.dirname(output), fprop(output, 'fn')),
                   overwrite=True)

    # Relate facilities with incidents groups
    facilities_df = facilities_df.merge(rel_df,
                                        how='inner',
                                        left_on=facilities_id,
                                        right_on=facilities_fk)

    # List Groups
    grp_df = pd.DataFrame({
        'cnttemp':
        incidents_df.groupby([group_incidents_col
                              ])[group_incidents_col].agg('count')
    }).reset_index()

    # Do the calculations
    res = []
    for idx, row in grp_df.iterrows():
        # Get incidents for that group
        new_i = incidents_df[incidents_df[group_incidents_col] ==
                             row[group_incidents_col]]

        new_i = obj_to_shp(
            new_i, 'geometry', epsg,
            os.path.join(tmpdir, 'i_{}.shp'.format(row[group_incidents_col])))

        # Get facilities for that group
        new_f = facilities_df[facilities_df[group_fk] ==
                              row[group_incidents_col]]
        new_f = obj_to_shp(
            new_f, 'geometry', epsg,
            os.path.join(tmpdir, 'f_{}.shp'.format(row[group_incidents_col])))

        # calculate closest facility
        cf = closest_facility(
            new_i, incidents_id, new_f,
            os.path.join(tmpdir, 'cf_{}.shp'.format(row[group_incidents_col])))

        res.append(cf)

    # Produce final result
    shps_to_shp(res, output, api="pandas")

    return output
Ejemplo n.º 6
0
def lulc_by_cell(tid, boundary, lulc_shps, fishnet, result, workspace):
    from glass.g.wenv.grs import run_grass
    from glass.g.dp.torst import shp_to_rst

    bname = fprop(boundary, 'fn')
    # Boundary to Raster
    ref_rst = shp_to_rst(boundary, None, 10, 0,
                         os.path.join(workspace, f'rst_{bname}.tif'))

    # Create GRASS GIS Session
    loc_name = 'loc_' + bname
    gbase = run_grass(workspace, location=loc_name, srs=ref_rst)

    import grass.script.setup as gsetup

    gsetup.init(gbase, workspace, loc_name, 'PERMANENT')

    # GRASS GIS Modules
    from glass.g.it.shp import shp_to_grs, grs_to_shp
    from glass.g.gp.ovl import grsintersection
    from glass.g.tbl.attr import geomattr_to_db
    from glass.g.prop.feat import feat_count

    # Send Fishnet to GRASS GIS
    fnet = shp_to_grs(fishnet, fprop(fishnet, 'fn'), asCMD=True)

    # Processing
    ulst = []
    l_lulc_grs = []
    for shp in lulc_shps:
        iname = fprop(shp, 'fn')

        # LULC Class to GRASS GIS
        lulc_grs = shp_to_grs(shp, iname, filterByReg=True, asCMD=True)

        if not feat_count(
                lulc_grs, gisApi='grass', work=workspace, loc=loc_name):
            continue

        # Intersect Fishnet | LULC CLass
        union_grs = grsintersection(fnet, lulc_grs, iname + '_i', cmd=True)

        # Get Areas
        geomattr_to_db(union_grs, "areav", "area", "boundary", unit='meters')

        # Export Table
        funion = grs_to_shp(union_grs, os.path.join(result, iname + '.shp'),
                            'area')

        ulst.append(funion)
        l_lulc_grs.append(lulc_grs)

    # Intersect between all LULC SHPS
    ist_shp = []
    if len(l_lulc_grs) > 1:
        for i in range(len(l_lulc_grs)):
            for e in range(i + 1, len(l_lulc_grs)):
                ishp = grsintersection(l_lulc_grs[i],
                                       l_lulc_grs[e],
                                       'lulcint_' + str(i) + '_' + str(e),
                                       cmd=True)

                if not feat_count(
                        ishp, gisApi='grass', work=workspace, loc=loc_name):
                    continue
                else:
                    ist_shp.append(ishp)

        if len(ist_shp):
            from glass.g.gp.gen import dissolve
            from glass.g.tbl.grs import reset_table

            if len(ist_shp) > 1:
                from glass.g.dp.mge import shps_to_shp

                # Export shapes
                _ist_shp = [
                    grs_to_shp(s, os.path.join(workspace, loc_name,
                                               s + '.shp'), 'area')
                    for s in ist_shp
                ]

                # Merge Intersections
                merge_shp = shps_to_shp(_ist_shp,
                                        os.path.join(workspace, loc_name,
                                                     'merge_shp.shp'),
                                        api='pandas')

                # Import GRASS
                merge_shp = shp_to_grs(merge_shp, 'merge_shp')

            else:
                merge_shp = ist_shp[0]

            # Dissolve Shape
            reset_table(merge_shp, {'refid': 'varchar(2)'}, {'refid': '1'})
            overlay_areas = dissolve(merge_shp,
                                     'overlay_areas',
                                     'refid',
                                     api='grass')

            # Union Fishnet | Overlay's
            union_ovl = grsintersection(fnet,
                                        overlay_areas,
                                        'ovl_union',
                                        cmd=True)

            funion_ovl = grs_to_shp(union_ovl,
                                    os.path.join(result, union_ovl + '.shp'),
                                    'area')

            ulst.append(funion_ovl)

    # Export Tables
    return ulst
Ejemplo n.º 7
0
Archivo: mtx.py Proyecto: jasp382/glass
def prod_matrix(origins,
                destinations,
                networkGrs,
                speedLimitCol,
                onewayCol,
                thrdId="1",
                asCmd=None):
    """
    Get Matrix Distance:
    """

    from glass.g.tbl import category
    from glass.g.tbl.filter import sel_by_attr
    from glass.g.tbl.col import add_fields
    from glass.g.tbl.grs import add_table, update_table
    from glass.g.mob.grstbx.vnet import add_pnts_to_network
    from glass.g.mob.grstbx.vnet import run_allpairs
    from glass.g.cp import copy_insame_vector
    from glass.g.tbl.attr import geomattr_to_db
    from glass.g.dp.mge import shps_to_shp
    from glass.g.prop.feat import feat_count
    from glass.g.it.shp import shp_to_grs

    # Merge Origins and Destinations into the same Feature Class
    ORIGINS_NFEAT = feat_count(origins, gisApi='pandas')
    DESTINATIONS_NFEAT = feat_count(destinations, gisApi='pandas')

    ORIGINS_DESTINATIONS = shps_to_shp([origins, destinations],
                                       os.path.join(
                                           os.path.dirname(origins),
                                           "points_od_{}.shp".format(thrdId)),
                                       api='pandas')

    pointsGrs = shp_to_grs(ORIGINS_DESTINATIONS,
                           "points_od_{}".format(thrdId),
                           asCMD=asCmd)

    # Connect Points to Network
    newNetwork = add_pnts_to_network(networkGrs,
                                     pointsGrs,
                                     "rdv_points_{}".format(thrdId),
                                     asCMD=asCmd)

    # Sanitize Network Table and Cost Columns
    newNetwork = category(newNetwork,
                          "rdv_points_time_{}".format(thrdId),
                          "add",
                          LyrN="3",
                          geomType="line",
                          asCMD=asCmd)

    add_table(newNetwork,
              ("cat integer,kph double precision,length double precision,"
               "ft_minutes double precision,"
               "tf_minutes double precision,oneway text"),
              lyrN=3,
              asCMD=asCmd)

    copy_insame_vector(newNetwork,
                       "kph",
                       speedLimitCol,
                       3,
                       geomType="line",
                       asCMD=asCmd)
    copy_insame_vector(newNetwork,
                       "oneway",
                       onewayCol,
                       3,
                       geomType="line",
                       asCMD=asCmd)

    geomattr_to_db(newNetwork,
                   "length",
                   "length",
                   "line",
                   createCol=False,
                   unit="meters",
                   lyrN=3,
                   ascmd=asCmd)

    update_table(newNetwork, "kph", "3.6", "kph IS NULL", lyrN=3, ascmd=asCmd)
    update_table(newNetwork, "kph", "3.6", "oneway = 'N'", lyrN=3, ascmd=asCmd)
    update_table(newNetwork,
                 "ft_minutes",
                 "(length * 60) / (kph * 1000.0)",
                 "ft_minutes IS NULL",
                 lyrN=3,
                 ascmd=asCmd)
    update_table(newNetwork,
                 "tf_minutes",
                 "(length * 60) / (kph * 1000.0)",
                 "tf_minutes IS NULL",
                 lyrN=3,
                 ascmd=asCmd)

    # Exagerate Oneway's
    update_table(newNetwork,
                 "ft_minutes",
                 "1000",
                 "oneway = 'TF'",
                 lyrN=3,
                 ascmd=asCmd)
    update_table(newNetwork,
                 "tf_minutes",
                 "1000",
                 "oneway = 'FT'",
                 lyrN=3,
                 ascmd=asCmd)

    # Produce matrix
    matrix = run_allpairs(newNetwork,
                          "ft_minutes",
                          "tf_minutes",
                          'result_{}'.format(thrdId),
                          arcLyr=3,
                          nodeLyr=2,
                          asCMD=asCmd)

    # Exclude unwanted OD Pairs
    q = "({}) AND ({})".format(
        " OR ".join(
            ["from_cat={}".format(str(i + 1)) for i in range(ORIGINS_NFEAT)]),
        " OR ".join([
            "to_cat={}".format(str(ORIGINS_NFEAT + i + 1))
            for i in range(DESTINATIONS_NFEAT)
        ]))

    matrix_sel = sel_by_attr(matrix,
                             q,
                             "sel_{}".format(matrix),
                             geomType="line",
                             lyrN=3,
                             asCMD=asCmd)

    add_fields(matrix_sel, "from_fid", "INTEGER", lyrN=3, asCMD=asCmd)
    add_fields(matrix_sel, "to_fid", "INTEGER", lyrN=3, asCMD=asCmd)

    update_table(matrix_sel,
                 "from_fid",
                 "from_cat - 1",
                 "from_fid IS NULL",
                 lyrN=3,
                 ascmd=asCmd)
    update_table(matrix_sel,
                 "to_fid",
                 "to_cat - {} - 1".format(str(ORIGINS_NFEAT)),
                 "to_fid IS NULL",
                 lyrN=3,
                 ascmd=asCmd)

    return matrix_sel
Ejemplo n.º 8
0
Archivo: mtx.py Proyecto: jasp382/glass
def thrd_matrix_od(origins, destinationShp, network, costCol, oneway, grsWork,
                   grsLoc, output):
    """
    Produce matrix OD using GRASS GIS - Thread MODE
    
    PROBLEM:
    * O programa baralha-se todo porque ha muitas sessoes do grass a serem 
    executadas. E preciso verificar se e possivel segregar as varias sessoes
    do grass
    """

    from threading import Thread
    from glass.g.wenv.grs import run_grass
    from glass.pys.oss import fprop, mkdir
    from glass.g.dp.mge import shps_to_shp
    from glass.g.dp.split import splitShp_by_range

    # SPLIT ORIGINS IN PARTS
    originsFld = mkdir(os.path.join(grsWork, 'origins_parts'))

    originsList = splitShp_by_range(origins, 100, originsFld)

    gbase = run_grass(grsWork,
                      grassBIN="grass76",
                      location=grsLoc,
                      srs=network)

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

    gsetup.init(gbase, grsWork, grsLoc, 'PERMANENT')

    from glass.g.it.shp import shp_to_grs

    # Add Data to GRASS GIS
    rdvMain = shp_to_grs(network,
                         fprop(network, 'fn', forceLower=True),
                         asCMD=True)

    RESULTS = []
    R_FOLDER = mkdir(os.path.join(grsWork, 'res_parts'))

    def __prod_mtxod(O, D, THRD):
        result_part = prod_matrix(O,
                                  D,
                                  rdvMain,
                                  costCol,
                                  oneway,
                                  thrdId=THRD,
                                  asCmd=True)

        shp = shp_to_grs(result_part,
                         os.path.join(R_FOLDER, result_part + '.shp'),
                         geom_type="line",
                         lyrN=3,
                         asCMD=True)

        RESULTS.append(shp)

    thrds = []
    for i in range(len(originsList)):
        thrds.append(
            Thread(name='tk-{}'.format(str(i)),
                   target=__prod_mtxod,
                   args=(originsList[i], destinationShp, str(i))))

    for t in thrds:
        t.start()

    for t in thrds:
        t.join()

    shps_to_shp(RESULTS, output, api='pandas')

    return output