def clip_rst_each_featcls(raster, clipFolder, outputFolder, template=None, snap=None, clipGeometry=None, clipFormat='.shp', outputFormat='.tif', useFileID=None): """ Clip a raster for each feature class in a folder """ import os from glass.pys.oss import lst_ff, fprop clipShp = lst_ff(clipFolder, file_format=clipFormat) outputFormat = outputFormat if outputFormat[0] == '.' else \ '.' + outputFormat rst_fn = None if not useFileID else fprop(raster, 'fn', forceLower=True) for shp in clipShp: fn = "{}{}".format( fprop(shp, 'fn', forceLower=True), outputFormat ) if not useFileID else "{}_{}{}".format( rst_fn, fprop(shp, 'fn', forceLower=True).split('_')[-1], outputFormat ) clip_rst(raster, shp, os.path.join( outputFolder, fn ), clipGeom=clipGeometry, template=template, snap=snap ) return outputFolder
def remove_deadend(inShp, outShp, db=None): """ Remove deadend """ from glass.pys.oss import fprop from glass.ng.sql.db import create_db from glass.g.it.db import shp_to_psql from glass.g.gp.cln.sql import rm_deadend from glass.g.it.shp import dbtbl_to_shp # Create DB if not db: db = create_db(fprop(inShp, 'fn', forceLower=True), api='psql') else: from glass.ng.prop.sql import db_exists isDb = db_exists(db) if not isDb: create_db(db, api='psql') # Send data to Database inTbl = shp_to_psql(db, inShp, api="shp2pgsql", encoding="LATIN1") # Produce result out_tbl = rm_deadend(db, inTbl, fprop( outShp, 'fn', forceLower=True)) # Export result return dbtbl_to_shp( db, out_tbl, "geom", outShp, inDB='psql', tableIsQuery=None, api="pgsql2shp" )
def break_lines_on_points(lineShp, pntShp, outShp, lnhidonpnt, api='shply', db=None): """ Break lines on points location api's available: - shply (shapely); - psql (postgis); """ if api == 'shply': result = shply_break_lines_on_points(lineShp, pntShp, lnhidonpnt, outShp) elif api == 'psql': from glass.pys.oss import fprop from glass.ng.sql.db import create_db from glass.g.it.db import shp_to_psql from glass.g.it.shp import dbtbl_to_shp from glass.g.gp.brk.sql import split_lines_on_pnt # Create DB if not db: db = create_db(fprop(lineShp, 'fn', forceLower=True), api='psql') else: from glass.ng.prop.sql import db_exists isDb = db_exists(db) if not isDb: db = create_db(db, api='psql') # Send Data to BD lnhTbl = shp_to_psql(db, lineShp, api="shp2pgsql") pntTbl = shp_to_psql(db, pntShp, api="shp2pgsql") # Get result outTbl = split_lines_on_pnt(db, lnhTbl, pntTbl, fprop(outShp, 'fn', forceLower=True), lnhidonpnt, 'gid') # Export result result = dbtbl_to_shp(db, outTbl, "geom", outShp, inDB='psql', tableIsQuery=None, api="pgsql2shp") else: raise ValueError("API {} is not available".format(api)) return result
def clip(inFeat, clipFeat, outFeat, api_gis="grass", clip_by_region=None): """ Clip Analysis api_gis Options: * grass * pygrass * ogr2ogr """ from glass.pys.oss import fprop if api_gis == "pygrass" or api_gis == "grass": import os from glass.g.wenv.grs import run_grass from glass.g.prop.prj import get_epsg epsg = get_epsg(inFeat) work = os.path.dirname(outFeat) refname = fprop(outFeat, 'fn') loc = f"loc_{refname}" grsbase = run_grass(work, location=loc, srs=epsg) import grass.script.setup as gsetup gsetup.init(grsbase, work, loc, 'PERMANENT') from glass.g.it.shp import shp_to_grs, grs_to_shp from glass.g.prop.feat import feat_count shp = shp_to_grs(inFeat, fprop(inFeat, 'fn')) clp = shp_to_grs(clipFeat, fprop(clipFeat, 'fn')) # Clip rslt = grsclip(shp, clp, refname, cmd=True if api_gis == "grass" else None, clip_by_region=clip_by_region) # Export grs_to_shp(rslt, outFeat, 'area') elif api_gis == 'ogr2ogr': from glass.pys import execmd from glass.g.prop import drv_name rcmd = execmd( ("ogr2ogr -f \"{}\" {} {} -clipsrc {} -clipsrclayer {}").format( drv_name(outFeat), outFeat, inFeat, clipFeat, fprop(clipFeat, 'fn'))) else: raise ValueError("{} is not available!".format(api_gis)) return outFeat
def matrix_od_mean_dist_by_group(MATRIX_OD, ORIGIN_COL, GROUP_ORIGIN_ID, GROUP_ORIGIN_NAME, GROUP_DESTINA_ID, GROUP_DESTINA_NAME, TIME_COL, epsg, db, RESULT_MATRIX): """ Calculate Mean GROUP distance from OD Matrix OD MATRIX EXAMPLE | origin_entity | origin_group | destina_entity | destina_group | distance | XXXX | XXXX | XXXX | XXX | XXX OUTPUT EXAMPLE | origin_group | destina_group | mean_distance | XXXX | XXXX | XXXX """ from glass.pys.oss import fprop from glass.g.it.db import shp_to_psql from glass.ng.sql.db import create_db from glass.ng.sql.q import q_to_ntbl from glass.ng.it import db_to_tbl db = create_db(fprop(MATRIX_OD, 'fn'), overwrite=True, api='psql') TABLE = shp_to_psql(db, MATRIX_OD, pgTable="tbl_{}".format(db), api="pandas", srsEpsgCode=epsg) OUT_TABLE = q_to_ntbl( db, fprop(RESULT_MATRIX, 'fn'), ("SELECT {groupOriginCod}, {groupOriginName}, {groupDestCod}, " "{groupDestName}, AVG(mean_time) AS mean_time FROM (" "SELECT {origin}, {groupOriginCod}, {groupOriginName}, " "{groupDestCod}, {groupDestName}, " "AVG({timeCol}) AS mean_time FROM {t} " "GROUP BY {origin}, {groupOriginCod}, {groupOriginName}, " "{groupDestCod}, {groupDestName}" ") AS foo " "GROUP BY {groupOriginCod}, {groupOriginName}, " "{groupDestCod}, {groupDestName} " "ORDER BY {groupOriginCod}, {groupDestCod}").format( groupOriginCod=GROUP_ORIGIN_ID, groupOriginName=GROUP_ORIGIN_NAME, groupDestCod=GROUP_DESTINA_ID, groupDestName=GROUP_DESTINA_NAME, origin=ORIGIN_COL, timeCol=TIME_COL, t=TABLE), api='psql') return db_to_tbl(db, "SELECT * FROM {}".format(OUT_TABLE), RESULT_MATRIX, sheetsNames="matrix", dbAPI='psql')
def union(lyrA, lyrB, outShp, api_gis="grass"): """ Calculates the geometric union of the overlayed polygon layers, i.e. the intersection plus the symmetrical difference of layers A and B. API's Available: * saga; * grass; * pygrass; """ if api_gis == "saga": from glass.pys import execmd rcmd = execmd( ("saga_cmd shapes_polygons 17 -A {} -B {} -RESULT {} -SPLIT 1" ).format(lyrA, lyrB, outShp)) elif api_gis == "pygrass" or api_gis == "grass": import os from glass.g.wenv.grs import run_grass from glass.pys.oss import fprop from glass.g.prop.prj import get_epsg ws = os.path.dirname(outShp) refname = fprop(outShp) loc = f"loc_{refname}" gbase = run_grass(ws, location=loc, srs=get_epsg(lyrA)) import grass.script.setup as gs gs.init(gbase, ws, loc, 'PERMANENT') # Import data from glass.g.it.shp import shp_to_grs, grs_to_shp lyr_a = shp_to_grs(lyrA, fprop(lyrA, 'fn'), asCMD=True) lyr_b = shp_to_grs(lyrB, fprop(lyrB, 'fn'), asCMD=True) shpunion = grsunion(lyr_a, lyr_b, refname, cmd=True if api_gis == "grass" else None) # Export data grs_to_shp(shpunion, outShp, "area") else: raise ValueError("{} is not available!".format(api_gis)) return outShp
def matrix_od(origins, destinations, networkShp, speedLimitCol, onewayCol, grsWorkspace, grsLocation, outputShp): """ Produce matrix OD using GRASS GIS """ from glass.pys.oss import fprop from glass.g.wenv.grs import run_grass # 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 # Add Data to GRASS GIS rdvMain = shp_to_grs(networkShp, fprop(networkShp, 'fn', forceLower=True)) """Get matrix distance:""" MATRIX_OD = prod_matrix(origins, destinations, rdvMain, speedLimitCol, onewayCol) return grs_to_shp(MATRIX_OD, outputShp, "line", lyrN=3)
def txts_to_db(folder, db, delimiter, __encoding='utf-8', apidb='psql', rewrite=None): """ Executes tbl_to_db for every file in a given folder The file name will be the table name """ from glass.pys.oss import lst_ff, fprop from glass.ng.prop.sql import db_exists if not db_exists(db): # Create database from glass.ng.sql.db import create_db create_db(db, api=apidb, overwrite=None) else: if rewrite: from glass.ng.sql.db import create_db create_db(db, api=db, overwrite=True) __files = lst_ff(folder, file_format=['.txt', '.csv', '.tsv']) """ Send data to DB using Pandas """ for __file in __files: tbl_to_db( __file, db, fprop(__file, 'fn'), delimiter=delimiter, encoding_=__encoding, api_db=apidb )
def kernel_density(pnt_feat, popField, radius, template, outRst): """ Kernel density estimation. If any point is currently in selection only selected points are taken into account. """ import os from glass.g.it.rst import saga_to_tif from glass.g.prop.rst import rst_ext, get_cellsize from glass.pys.oss import fprop left, right, bottom, top = rst_ext(template) cellsize = get_cellsize(template) SAGA_RASTER = os.path.join(os.path.dirname(outRst), 'saga_{}.sgrd'.format(fprop(outRst, 'fn'))) cmd = ("saga_cmd grid_gridding 6 -POINTS {} -POPULATION {} " "-RADIUS {} -TARGET_DEFINITION 0 -TARGET_USER_SIZE {} " "-TARGET_USER_XMIN {} -TARGET_USER_XMAX {} " "-TARGET_USER_YMIN {} -TARGET_USER_YMAX {} " "-TARGET_OUT_GRID {}").format(pnt_feat, popField, str(radius), str(abs(cellsize)), str(left), str(right), str(bottom), str(top), SAGA_RASTER) outcmd = execmd(cmd) # Convert to tiff saga_to_tif(SAGA_RASTER, outRst) return outRst
def foldershp_to_foldershp(inFld, outFld, destiny_file_format, file_format='.shp', useApi='ogr'): """ Execute shp_to_shp for every file in inFld (path to folder) useApi options: * ogr; """ import os from glass.pys.oss import lst_ff, fprop if not os.path.exists(outFld): from glass.pys.oss import mkdir mkdir(outFld) geo_files = lst_ff(inFld, file_format=file_format) for f in geo_files: shp_to_shp(f, os.path.join(outFld, '{}.{}'.format( fprop(f, 'fn'), destiny_file_format if \ destiny_file_format[0] == '.' else '.' + destiny_file_format )), gisApi=useApi) return outFld
def update_cols(table, upcol, nval): """ Update a feature class table with new values new_values = { new_value : where statment new_value : None # if no where statment } Where with OR condition new_values and ref_values are dict with fields as keys and values as keys values. """ import os from glass.pys import execmd from glass.pys.oss import fprop tn = fprop(table, 'fn') for v in nval: q = "UPDATE {} SET {}={}{}".format( tn, upcol, str(v) if type(v) != str else "'{}'".format(str(v)), "" if not nval[v] else " WHERE {}".format( nval[v] if type(nval[v]) != list else " OR ".join(nval[v]))) ogrinfo = 'ogrinfo {} -dialect sqlite -sql "{}"'.format(table, q) # Run command outcmd = execmd(ogrinfo)
def mdl_to_kml(mdl, outKml, filter=None): """ Query a database table and convert it to a KML File """ import json import os from django.http import HttpResponse from glass.pys.oss import fprop from glass.webg.djg.mdl.serial import mdl_serialize_to_json from glass.g.it.shp import shp_to_shp # Write data in JSON JSON_FILE = os.path.join(os.path.dirname(outKml), fprop(outKml, 'fn') + '.json') mdl_serialize_to_json(mdl, 'geojson', JSON_FILE, filterQ=filter) # Convert JSON into KML shp_to_shp(JSON_FILE, outKml, gisApi='ogr') # Create a valid DOWNLOAD RESPONSE with open(outKml, 'rb') as f: response = HttpResponse(f.read()) response['content_type'] = 'text/xml' response['Content-Disposition'] = 'attachment;filename={}'.format( os.path.basename(outKml)) return response
def viewshed(demrst, obsShp, output): """ This tool computes a visibility analysis using observer points from a point shapefile. """ import os from glass.pys import execmd from glass.pys.oss import fprop from glass.g.it.rst import saga_to_tif SAGA_RASTER = os.path.join( os.path.dirname(output), "sg_{}.sgrd".format(fprop(output, 'fn')) ) cmd = ( "saga_cmd ta_lighting 6 -ELEVATION {elv} -POINTS {pnt} " "-VISIBILITY {out} -METHOD 0" ).format( elv=demrst, pnt=obsShp, out=SAGA_RASTER ) outcmd = execmd(cmd) # Convert to Tiif saga_to_tif(SAGA_RASTER, output) return output
def shp_to_shp(inshp, outshp, gisApi='ogr', supportForSpatialLite=None): """ Convert a vectorial file to another with other file format API's Available: * ogr; * grass; When using gisApi='ogr' - Set supportForSpatialLite to True if outShp is a sqlite db and if you want SpatialLite support for that database. """ if gisApi == 'ogr': from glass.pys import execmd from glass.g.prop import drv_name out_driver = drv_name(outshp) if out_driver == 'SQLite' and supportForSpatialLite: splite = ' -dsco "SPATIALITE=YES"' else: splite = '' cmd = 'ogr2ogr -f "{drv}" {out} {_in}{lite}'.format(drv=out_driver, out=outshp, _in=inshp, lite=splite) # Run command cmdout = execmd(cmd) elif gisApi == 'grass': # TODO identify input geometry type import os from glass.pys.oss import fprop from glass.g.wenv.grs import run_grass from glass.g.prop.prj import get_epsg # Start GRASS GIS Session ws = os.path.dirname(outshp) loc = f'loc_{fprop(outshp, "fn")}' epsg = get_epsg(inshp) gbase = run_grass(ws, location=loc, srs=epsg) import grass.script.setup as gsetup gsetup.init(gbase, ws, loc, 'PERMANENT') from glass.g.it.shp import grs_to_shp, shp_to_grs gshp = shp_to_grs(inshp, fprop(inshp, 'fn')) grs_to_shp(gshp, outshp, 'area') else: raise ValueError('Sorry, API {} is not available'.format(gisApi)) return outshp
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")
def pnts_to_boundary(pntShp, outBound, distMeters): """ Create a boundary from Point using a tolerance in meters """ from osgeo import ogr from glass.pys.oss import fprop from glass.g.prop import drv_name from glass.g.gobj import new_pnt from glass.g.prop.prj import get_shp_sref SRS = get_shp_sref(pntShp) shp = ogr.GetDriverByName(drv_name(pntShp)).Open(pntShp) lyr = shp.GetLayer() outShp = ogr.GetDriverByName(drv_name(outBound)).CreateDataSource(outBound) outLyr = outShp.CreateLayer(fprop(outBound, 'fn', forceLower=True), SRS, geom_type=ogr.wkbPolygon) outDefn = outLyr.GetLayerDefn() for feat in lyr: __feat = ogr.Feature(outDefn) ring = ogr.Geometry(ogr.wkbLinearRing) geom = feat.GetGeometryRef() X, Y = geom.GetX(), geom.GetY() boundary_points = [ new_pnt(X - distMeters, Y + distMeters), # Topleft new_pnt(X + distMeters, Y + distMeters), # TopRight new_pnt(X + distMeters, Y - distMeters), # Lower Right new_pnt(X - distMeters, Y - distMeters), # Lower Left new_pnt(X - distMeters, Y + distMeters) ] for pnt in boundary_points: ring.AddPoint(pnt.GetX(), pnt.GetY()) polygon = ogr.Geometry(ogr.wkbPolygon) polygon.AddGeometry(ring) __feat.SetGeometry(polygon) outLyr.CreateFeature(__feat) feat.Destroy() __feat = None ring = None polygon = None shp.Destroy() outShp.Destroy() return outBound
def get_stop_words(inTbl, fidCol, txtCol, outFile, lang='portuguese', inSheet=None, db=None): """ Pick a text column and save it in a new column only with the stop words. Uses PostgreSQL dictionaries to get stop words """ from glass.pys.oss import fprop from glass.ng.prop.sql import cols_name from glass.ng.sql.db import create_db from glass.ng.it.sql import tbl_to_db from glass.ng.it import db_to_tbl FILENAME = fprop(inTbl, 'fn') # Create Temp database db = create_db("db_" + FILENAME if not db else db) # Send table to PostgreSQL tbl = tbl_to_db(inTbl, db, FILENAME, sheet=inSheet, api_db='psql') cols = cols_name(db, tbl, sanitizeSpecialWords=None, api='psql') # Sanitize data and create a new column only with stop words Q1 = ( "(SELECT *, to_tsvector('{_lang}', regexp_replace(" "regexp_replace(lower(unaccent({txt_c})), 'http://[^:\s]+(\S+)', " "' ', 'g'), '[^\w]+', ' ', 'g')) " "AS txt_data FROM {t}) AS stop_table" ).format(_lang=lang, txt_c=txtCol, t=tbl) Q2 = ( "SELECT {selCols}, ARRAY_TO_STRING(array_agg(" "word ORDER BY word_index), ' ', '*') AS {outCol}, " "REPLACE(CAST(STRIP(" "stop_table.txt_data) AS text), '''', '') AS no_duplicated " "FROM (" "SELECT fid, word, CAST(UNNEST(word_index) AS integer) " "AS word_index FROM (" "SELECT fid, SPLIT_PART(tst, ';', 1) AS word, " "STRING_TO_ARRAY(SPLIT_PART(tst, ';', 2), ',') AS word_index FROM (" "SELECT {fid} AS fid, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(" "CAST(UNNEST(txt_data) AS text), " "',{{', ',\"{{'), ',\"{{', ';'), '}}\"', ''), " "'(', ''), '}}', '') AS tst " "FROM {tbl}" ") AS foo" ") AS foo2" ") AS foo3 INNER JOIN {tbl} ON foo3.fid = stop_table.{fid} " "GROUP BY {selCols}, stop_table.txt_data" ).format( outCol="clean_" + txtCol, tbl=Q1, fid=fidCol, selCols=", ".join(["stop_table.{}".format(i) for i in cols]) ) # Export new table return db_to_tbl(db, Q2, outFile, sheetsNames=inSheet)
def thrd_lulc_by_cell(thrd_id, df_fishnet, l_lulc, result): # Create folder for this thread t_folder = mkdir(os.path.join(result, 'thrd_' + str(thrd_id))) # For each fishnet, do the job for idx, row in df_fishnet.iterrows(): rf = mkdir(os.path.join(result, fprop(row.fishnet, 'fn'))) lulc_by_cell(int(idx), row.bound, l_lulc, row.fishnet, rf, t_folder)
def rsts_to_gpkg(in_rsts, gpkg, rst_ff='.tif', basename=None): """ Raster Files to GeoPackage """ import os import numpy as np from glass.pys import execmd from glass.pys.oss import fprop from glass.g.prop.rst import rst_dtype if type(in_rsts) == list: rsts = in_rsts elif os.path.isdir(in_rsts): from glass.pys.oss import lst_ff rsts = lst_ff(in_rsts, file_format='.tif' if not rst_ff else rst_ff) else: rsts = [in_rsts] new_cmd = "gdal_translate -of GPKG {} {} -CO RASTER_TABLE={}{}" upd_cmd = ("gdal_translate -of GPKG {} {} -co APPEND_SUBDATASET=YES -CO " "RASTER_TABLE={}{}") for r in range(len(rsts)): rst_type = rst_dtype(rsts[r]) tname = fprop(rsts[r], 'fn') if not basename else \ "{}_{}".format(basename, fprop(rsts[r], 'fn').split('_')[-1]) if not r and not os.path.exists(gpkg): rcmd = execmd( new_cmd.format( rsts[r], gpkg, tname, " -ot Float32" if rst_type == np.float64 else "")) else: rcmd = execmd( upd_cmd.format( rsts[r], gpkg, tname, " -ot Float32" if rst_type == np.float64 else "")) return gpkg
def osm_to_featcls(xmlOsm, output, fileFormat='.shp', useXmlName=None, outepsg=4326): """ OSM to ESRI Shapefile """ import os from glass.g.tbl.filter import sel_by_attr from glass.pys.oss import fprop, del_file # Convert xml to sqliteDB gpkg = osm_to_gpkg(xmlOsm, os.path.join(output, fprop(xmlOsm, 'fn') + '.gpkg')) # sqliteDB to Feature Class TABLES = { 'points': 'pnt', 'lines': 'lnh', 'multilinestrings': 'mlnh', 'multipolygons': 'poly' } for T in TABLES: sel_by_attr( gpkg, "SELECT * FROM {}".format(T), os.path.join( output, "{}{}{}".format( "" if not useXmlName else fprop(xmlOsm, 'fn') + "_", TABLES[T], fileFormat if fileFormat[0] == '.' else "." + fileFormat)), api_gis='ogr', oEPSG=None if outepsg == 4326 else outepsg, iEPSG=4326) # Del temp DB del_file(gpkg) return output
def grscliprst(in_rst, clip_ext, outrst): """ Clip Raster using GRASS GIS """ import os from glass.pys.oss import fprop from glass.g.wenv.grs import run_grass from glass.g.wenv.grs import rst_to_region from glass.g.prop.prj import get_epsg # Get EPSG From Raster EPSG = get_epsg(in_rst) if not EPSG: raise ValueError( 'Cannot get EPSG code of Extent Template File ({})'.format(in_rst)) workspace = os.path.dirname(outrst) loc = 'loc_' + fprop(outrst, 'fn') # Create GRASS GIS Session gbase = run_grass(workspace, location=loc, srs=EPSG) import grass.script.setup as gsetup gsetup.init(gbase, workspace, loc, 'PERMANENT') # GRASS GIS modules from glass.g.it.rst import rst_to_grs, grs_to_rst, grs_to_mask # Add data to GRASS GIS rst = rst_to_grs(in_rst, fprop(in_rst, 'fn'), as_cmd=True) clip = rst_to_grs(clip_ext, fprop(clip_ext, 'fn'), as_cmd=True) # Set New region rst_to_region(clip) # Set Mask grs_to_mask(clip) # Export result return grs_to_rst(rst, outrst)
def line_intersect_to_pnt(inShp, outShp, db=None): """ Get Points where two line features of the same feature class intersects. """ from glass.pys.oss import fprop from glass.g.it.shp import dbtbl_to_shp from glass.ng.sql.db import create_db from glass.g.it.db import shp_to_psql from glass.g.gp.ovl.sql import line_intersection_pnt # Create DB if necessary if not db: db = create_db(fprop(inShp, 'fn', forceLower=True), api='psql') else: from glass.ng.prop.sql import db_exists isDb = db_exists(db) if not isDb: create_db(db, api='psql') # Send data to DB inTbl = shp_to_psql(db, inShp, api="shp2pgsql") # Get result outTbl = line_intersection_pnt(db, inTbl, fprop(outShp, 'fn', forceLower=True)) # Export data from DB outShp = dbtbl_to_shp(db, outTbl, "geom", outShp, inDB='psql', tableIsQuery=None, api="pgsql2shp") return outShp
def field_sum_by_table_folder(folderOne, joinFieldOne, folderTwo, joinFieldTwo, sum_field, outFolder): import os from glass.pys.oss import lst_ff, fprop tablesOne = lst_ff(folderOne, file_format=['.xls', '.xlsx']) tablesTwo = lst_ff(folderTwo, file_format=['.xls', '.xlsx']) for table in tablesOne: table_name = fprop(table, 'fn') for __table in tablesTwo: __table_name = fprop(__table, 'fn') if table_name == __table_name: field_sum_two_tables( table, __table, joinFieldOne, joinFieldTwo, sum_field, os.path.join(outFolder, os.path.basename(table))) break
def rstcalc(expression, output, api='saga', grids=None): """ Basic Raster Calculator """ if api == 'saga': # Using SAGA GIS import os from glass.pys import execmd from glass.pys.oss import fprop from glass.g.it.rst import saga_to_tif SAGA_RASTER = os.path.join( os.path.dirname(output), "sag_{}.sgrd".format(fprop(output, 'fn')) ) cmd = ( "saga_cmd grid_calculus 1 -FORMULA \"{}\" -GRIDS \"{}\" " "-RESULT {} -RESAMPLING 0" ).format( expression, ";".join(grids), SAGA_RASTER ) outcmd = execmd(cmd) # Convert to tiff saga_to_tif(SAGA_RASTER, output) elif api == 'pygrass': from grass.pygrass.modules import Module rc = Module( 'r.mapcalc', '{} = {}'.format(output, expression), overwrite=True, run_=False, quiet=True ) rc() elif api == 'grass': from glass.pys import execmd rcmd = execmd(( f"r.mapcalc \"{output} = {expression}\" " "--overwrite --quiet" )) else: raise ValueError(f"{api} is not available!") return output
def sel_by_loc(shp, boundary_filter, filtered_output): """ Filter a shp using the location of a boundary_filter shp For now the boundary must have only one feature Writes the filter on a new shp """ from osgeo import ogr from glass.g.prop import drv_name from glass.g.prop.feat import get_gtype from glass.g.lyr.fld import copy_flds from glass.g.cp import copy_feat from glass.pys.oss import fprop # Open main data dtSrc = ogr.GetDriverByName(drv_name(shp)).Open(shp, 0) lyr = dtSrc.GetLayer() # Get filter geom filter_shp = ogr.GetDriverByName( drv_name(boundary_filter)).Open(boundary_filter, 0) filter_lyr = filter_shp.GetLayer() c = 0 for f in filter_lyr: if c: break geom = f.GetGeometryRef() c += 1 filter_shp.Destroy() # Apply filter lyr.SetSpatialFilter(geom) # Copy filter objects to a new shape out = ogr.GetDriverByName( drv_name(filtered_output)).CreateDataSource(filtered_output) outLyr = out.CreateLayer( fprop(filtered_output, 'fn'), geom_type=get_gtype(shp, gisApi='ogr', name=None, py_cls=True) ) # Copy fields copy_flds(lyr, outLyr) copy_feat( lyr, outLyr, outDefn=outLyr.GetLayerDefn(), only_geom=False, gisApi='ogrlyr' )
def run_slope(tid, inrsts, outfolder, oname, percentage): """ Thread function """ iirsts = inrsts.mdt.tolist() # Create GRASS GIS Location loc_name = f'thread_{str(tid)}' gbase = run_grass( outfolder, location=loc_name, srs=iirsts[0] ) # Start GRASS GIS Session import grass.script as grass import grass.script.setup as gsetup gsetup.init(gbase, outfolder, loc_name, 'PERMANENT') from glass.g.it.rst import rst_to_grs, grs_to_rst from glass.g.rst.surf import slope from glass.g.wenv.grs import rst_to_region for rst in iirsts: # Import data mdt = rst_to_grs(rst, fprop(rst, 'fn')) # Set region rst_to_region(mdt) # Get ID in name mdt_id = re.search(r'\d+', mdt).group() # Get slope if percentage: slope_perc = slope( mdt, f"pp_{oname}_{mdt_id}", data='percent' ) slope_degr = slope( mdt, f"{oname}_{mdt_id}", data='degrees' ) # Export if percentage: grs_to_rst(slope_perc, os.path.join( percentage, slope_degr + '.tif' )) grs_to_rst(slope_degr, os.path.join( outfolder, slope_degr + '.tif' ))
def shp_to_lyr(s, name=None): """ Create a layer from a feature class data source """ import os from glass.pys.oss import fprop lyr = arcpy.MakeFeatureLayer_management(s, name if name else fprop(s, 'fn'), "", "", "") return lyr
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 multi_run(ti, df, ofolder): loc_name = 'loc_{}'.format(str(ti)) grsbase = run_grass(ofolder, location=loc_name, srs=srs_epsg) import grass.script.setup as gsetup gsetup.init(grsbase, ofolder, loc_name, 'PERMANENT') from glass.g.it.shp import shp_to_grs, grs_to_shp from glass.g.gp.ovl import grsunion for idx, row in df.iterrows(): # Import data into GRASS GIS lyr_a = shp_to_grs(df.shp_a, fprop(df.shp_a, 'fn'), asCMD=True) lyr_b = shp_to_grs(df.shp_b, fprop(df.shp_b, 'fn'), asCMD=True) # Run Union shpUnion = grsunion(lyr_a, lyr_b, f"{lyr_a[:10]}_{lyr_b[:10]}", cmd=True) # Export data result = grs_to_shp(shpUnion, os.path.join(ofolder, shpUnion + '.shp'), "area")
def priority_rule(osmshps, priorities, gis_software, db=None): """ Priority rule in Arcgis """ import copy import os if gis_software != 'psql': from glass.g.gp.ovl import erase else: from glass.g.gp.ovl.sql import pg_erase from glass.pys.oss import fprop 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: if gis_software == 'arcpy': tmpOut = os.path.join( os.path.dirname(osmshps[priorities[i]]), "{}_{}.shp".format( fprop(osmNameRef[priorities[i]], 'fn'), e)) else: tmpOut = "{}_{}".format(osmNameRef[priorities[i]], e) if gis_software == 'psql': osmshps[priorities[i]] = pg_erase( db, osmshps[priorities[i]], osmshps[priorities[e]], 'geom', 'geom', tmpOut) else: osmshps[priorities[i]] = erase(osmshps[priorities[i]], osmshps[priorities[e]], tmpOut, api=gis_software) return osmshps