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
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)
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) }
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
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
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
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
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