def path_from_coords_to_shp(latOrigin, lngOrigin, latDest, lngDest, outshp, transmod='foot-walking', outepsg=4326): """ Receive coords and get path. Save path as Feature Class """ import pandas from gasp.web.orouteserv import directions from gasp.to.geom import regulardf_to_geodf, json_obj_to_geodf from gasp.to.shp import df_to_shp path = directions( latOrigin, lngOrigin, latDest, lngDest, modeTransportation=transmod ) geodf = json_obj_to_geodf(path, 4326) geodf.drop(['segments', 'bbox', 'way_points'], axis=1, inplace=True) geodf["summary"] = geodf['summary'][0] geodf = pandas.concat([ geodf.drop(['summary'], axis=1), geodf['summary'].apply(pandas.Series) ], axis=1) geodf = regulardf_to_geodf(geodf, "geometry", 4326) if outepsg != 4326: from gasp.mng.prj import project geodf = project(geodf, None, outepsg, gisApi='pandas') return df_to_shp(geodf, outshp)
def joinLines_by_spatial_rel_raster(mainLines, mainId, joinLines, joinCol, outfile, epsg): """ Join Attributes based on a spatial overlap. An raster based approach """ import os; import pandas from geopandas import GeoDataFrame from gasp.to.geom import regulardf_to_geodf from gasp.session import run_grass from gasp.oss import get_filename from gasp.oss.ops import create_folder from gasp.mng.ext import shpextent_to_boundary from gasp.mng.joins import join_dfs from gasp.mng.df import df_groupBy from gasp.to.rst import shp_to_raster from gasp.fm import tbl_to_obj from gasp.to.shp import df_to_shp workspace = create_folder(os.path.join( os.path.dirname(mainLines, 'tmp_dt') )) # Create boundary file boundary = shpextent_to_boundary( mainLines, os.path.join(workspace, "bound.shp"), epsg ) boundRst = shp_to_raster(boundary, None, 5, -99, os.path.join( workspace, "rst_base.tif"), epsg=epsg, api='gdal') # Start GRASS GIS Session gbase = run_grass(workspace, location="grs_loc", srs=boundRst) import grass.script as grass import grass.script.setup as gsetup gsetup.init(gbase, workspace, "grs_loc", "PERMANENT") from gasp.spanlst.local import combine from gasp.cpu.grs.spanlst import get_rst_report_data from gasp.to.shp.grs import shp_to_grs, grs_to_shp from gasp.to.rst import shp_to_raster # Add data to GRASS GIS mainVector = shp_to_grs( mainLines, get_filename(mainLines, forceLower=True)) joinVector = shp_to_grs( joinLines, get_filename(joinLines, forceLower=True)) mainRst = shp_to_raster( mainVector, mainId, None, None, "rst_" + mainVector, api='pygrass' ); joinRst = shp_to_raster( joinVector, joinCol, None, None, "rst_" + joinVector, api='pygrass' ) combRst = combine(mainRst, joinRst, "combine_rst", api="pygrass") combine_data = get_rst_report_data(combRst, UNITS="c") combDf = pandas.DataFrame(combine_data, columns=[ "comb_cat", "rst_1", "rst_2", "ncells" ]) combDf = combDf[combDf["rst_2"] != '0'] combDf["ncells"] = combDf["ncells"].astype(int) gbdata = df_groupBy(combDf, ["rst_1"], "MAX", "ncells") fTable = join_dfs(gbdata, combDf, ["rst_1", "ncells"], ["rst_1", "ncells"]) fTable["rst_2"] = fTable["rst_2"].astype(int) fTable = df_groupBy( fTable, ["rst_1", "ncells"], STAT='MIN', STAT_FIELD="rst_2" ) mainLinesCat = grs_to_shp( mainVector, os.path.join(workspace, mainVector + '.shp'), 'line') mainLinesDf = tbl_to_obj(mainLinesCat) resultDf = join_dfs( mainLinesDf, fTable, "cat", "rst_1", onlyCombinations=None ) resultDf.rename(columns={"rst_2" : joinCol}, inplace=True) resultDf = regulardf_to_geodf(resultDf, "geometry", epsg) df_to_shp(resultDf, outfile) return outfile
def join_attr_by_distance(mainTable, joinTable, workGrass, epsg_code, output): """ Find nearest feature and join attributes of the nearest feature to the mainTable Uses GRASS GIS to find near lines. """ import os from gasp.session import run_grass from gasp.fm import tbl_to_obj from gasp.to.geom import regulardf_to_geodf from gasp.to.shp import df_to_shp from gasp.oss import get_filename # Create GRASS GIS Location grassBase = run_grass(workGrass, location='join_loc', srs=epsg_code) import grass.script as grass import grass.script.setup as gsetup gsetup.init(grassBase, workGrass, 'join_loc', 'PERMANENT') # Import some GRASS GIS tools from gasp.anls.prox import grs_near as near from gasp.cpu.grs.mng.feat import geomattr_to_db from gasp.to.shp.grs import shp_to_grs, grs_to_shp # Import data into GRASS GIS grsMain = shp_to_grs(mainTable, get_filename( mainTable, forceLower=True) ); grsJoin = shp_to_grs(joinTable, get_filename( joinTable, forceLower=True) ) # Get distance from each feature of mainTable to the nearest feature # of the join table near(grsMain, grsJoin, nearCatCol="tocat", nearDistCol="todistance") # Export data from GRASS GIS ogrMain = grs_to_shp(grsMain, os.path.join( workGrass, 'join_loc', grsMain + '_grs.shp'), None, asMultiPart=True ); ogrJoin = grs_to_shp(grsJoin, os.path.join( workGrass, 'join_loc', grsJoin + '_grs.shp'), None, asMultiPart=True) dfMain = tbl_to_obj(ogrMain) dfJoin = tbl_to_obj(ogrJoin) dfResult = dfMain.merge(dfJoin, how='inner', left_on='tocat', right_on='cat') dfResult.drop(["geometry_y", "cat_y"], axis=1, inplace=True) dfResult.rename(columns={"cat_x" : "cat_grass"}, inplace=True) dfResult["tocat"] = dfResult["tocat"] - 1 dfResult["cat_grass"] = dfResult["cat_grass"] - 1 dfResult = regulardf_to_geodf(dfResult, "geometry_x", epsg_code) df_to_shp(dfResult, output) return output
def address_from_featcls(inShp, outShp, epsg_in): """ Read a point geometry and return a table with the addresses """ from gasp.web.glg.geocod import get_address from gasp.fm import tbl_to_obj from gasp.to.geom import regulardf_to_geodf from gasp.fm.geom import pointxy_to_cols from gasp.prop.feat import get_geom_type from gasp.to.obj import df_to_dict, dict_to_df from gasp.to.shp import df_to_shp # Convert ESRI Shapefile to GeoDataFrame geoDf = tbl_to_obj(inShp) # Get Geometry field name for col in geoDf.columns.values: if col == 'geom' or col == 'geometry': F_GEOM = col break else: continue # Check if inShp has a Geom of Type Point inGeomType = get_geom_type(geoDf, geomCol=F_GEOM, gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') # Reproject geodf if necessary if epsg_in != 4326: from gasp.mng.prj import project geoDf = project(geoDf, None, 4326, gisApi='pandas') # Get Coords of each point geoDf = pointxy_to_cols(geoDf, F_GEOM, colX="x", colY='y') # Search for addresses geoDict = df_to_dict(geoDf) for idx in geoDict: glg_response = get_address(geoDict[idx]["y"], geoDict[idx]["x"]) geoDict[idx]["G_ADDRESS"] = glg_response[0]['formatted_address'] for i in glg_response[0]["address_components"]: if i["types"][0] == 'street_mumber' : F = "G_PORT" elif i["types"][0] == 'route' : F = "G_STREET" elif i["types"][0] == 'postal_code' : F = "G_ZIPCODE" else: continue geoDict[idx][F] = i["long_name"] # Save results in a new file geoDf = dict_to_df(geoDict) geoDf = regulardf_to_geodf(geoDf, F_GEOM, 4326) geoDf.drop(["x", "y"], axis=1, inplace=True) if epsg_in != 4326: geoDf = project(geoDf, None, epsg_in, gisApi='pandas') df_to_shp(geoDf, outShp) return geoDf
def pnt_to_facility(pnt, pntSrs, facilities, facSrs, transMode="driving"): """ Calculate distance between points and the nearest facility. # TODO: Add the possibility to save the path between origins and destinations """ import os import time from gasp.fm import tbl_to_obj from gasp.to.geom import regulardf_to_geodf from gasp.mng.prj import project_df from gasp.prop.feat import get_geom_type from gasp.oss import get_filename from gasp.to.obj import df_to_dict, dict_to_df from gasp.to.shp import df_to_shp from gasp.web.glg.distmx import dist_matrix # Convert SHPs to GeoDataFrame pntDf = tbl_to_obj(pnt) tbl_to_obj(facilities) # Check if SHPs are points originsGeom = get_geom_type(pntDf, geomCol="geometry", gisApi='pandas') if originsGeom != 'Point' and originsGeom != 'MultiPoint': raise ValueError('All input geometry must be of type point') destGeom = get_geom_type(facil, geomCol="geometry", gisApi='pandas') if destGeom != 'Point' and destGeom != 'MultiPoint': raise ValueError('All input geometry must be of type point') # Re-Project if necessary pntDf = pntDf if pntSrs == 4326 else project( pntDf, None, 4326, gisApi='pandas') facil = facil if facSrs == 4326 else project( facil, None, 4326, gisApi='pandas') # Coords to cols as str pntDf["geom"] = pntDf["geometry"].y.astype(str) + "," + \ pntDf["geometry"].x.astype(str) facil["geom"] = facil["geometry"].y.astype(str) + "," + \ facil["geometry"].y.astype(str) # Get distance between points and nearest facility pntDict = df_to_dict(pntDf) for idx in pntDict: destStr = str(facil["geom"].str.cat(sep="|")) glg_resp = dist_matrix(pntDict[idx]["geom"], destStr, 1, int(facil.shape[0]), transport_mode=transMode) matrix = pandas.DataFrame(glg_resp[0]["elements"]) matrix.drop(["status", "distance"], axis=1, inplace=True) matrix = pandas.concat([ matrix.drop(["duration"], axis=1), matrix["duration"].apply( pandas.Series) ], axis=1) matrix.drop("text", axis=1, inplace=True) matrix.rename(columns={"value": "duration"}, inplace=True) pntDict[idx]["duration"] = matrix.duration.min() / 60.0 pntDf = dict_to_df(pntDict) pntDf = regulardf_to_geodf(pntDf, "geometry", 4326) if pntSrs != 4326: pntDf = project(pntDf, None, pntSrs, gisApi='pandas') df_to_shp( pntDf, os.path.join(os.path.dirname(pnt), "{}_{}.shp".format(get_filename(pnt), "result"))) return pntDf
def dist_onedest_network(pntShp, pntRouteId, networkShp, netRouteId, netOrder, netDuration, srs, output): """ Imagine-se uma rede cujos arcos levam a um unico destino Este programa calcula a distancia entre um ponto e esse destino em duas fases: * calculo da distancia ao ponto de entrada na rede mais proximo; * distancia entre essa entrada o destino da rede. A rede e composta por circuitos, e suposto partir-se de um ponto, entrar num circuito e nunca sair dele ate ao destino. O circuito associado a cada ponto deve constar na tabela dos pontos. """ import pandas import time from geopandas import GeoDataFrame from gasp.fm import tbl_to_obj from gasp.web.glg.direct import pnt_to_pnt_duration from gasp.to.geom import regulardf_to_geodf, pnt_dfwxy_to_geodf from gasp.mng.df import df_groupBy from gasp.mng.prj import project from gasp.fm.geom import geom_endpoints_to_cols, pointxy_to_cols from gasp.mng.fld.df import distinct_of_distinct from gasp.to.obj import df_to_dict, dict_to_df from gasp.to.shp import df_to_shp netDataFrame = tbl_to_obj(networkShp) pntDataFrame = tbl_to_obj(pntShp) # Get entrance nodes netDataFrame = geom_endpoints_to_cols(netDataFrame, geomCol="geometry") geoEntrances = pnt_dfwxy_to_geodf(netDataFrame, "start_x", "start_y", srs) # To WGS if srs != 4326: geoEntrances = project(geoEntrances, None, 4326, gisApi='pandas') pntDataFrame = project(pntDataFrame, None, 4326, gisApi='pandas') # Get entrances by circuit routesEntrances = distinct_of_distinct(geoEntrances, netRouteId, netOrder) pntRelStops = pntDataFrame.merge(geoEntrances, how='inner', left_on=pntRouteId, right_on=netRouteId) pntRelStops = pointxy_to_cols(pntRelStops, geomCol="geometry", colX="start_x", colY="start_y") pntRelStops = pointxy_to_cols(pntRelStops, geomCol="geometry", colX="node_x", colY="node_y") pntRelStopsDict = df_to_dict(pntRelStops) for idx in pntRelStopsDict: ape = pnt_to_pnt_duration(pntRelStopsDict[idx]["start_y"], pntRelStopsDict[idx]["start_x"], pntRelStopsDict[idx]["node_y"], pntRelStopsDict[idx]["node_x"], mode="walking") time.sleep(5) pntRelStopsDict[idx]["gduration"] = ape pntRelStops = dict_to_df(pntRelStopsDict) pntRelStops_gp = df_groupBy( pntRelStops, [x for x in list(pntDataFrame.columns.values) if x != "geometry"], STAT='MIN', STAT_FIELD="gduration") pntRelStops_gp = pntRelStops_gp.merge( pntRelStops, how='inner', left_on=list(pntRelStops_gp.columns.values), right_on=list(pntRelStops_gp.columns.values)) final_time = [] for idx, row in pntRelStops_gp.iterrows(): circ = row[pntRouteId] order = row[netOrder] for i in range(len(routesEntrances[circ])): if order == routesEntrances[circ][i]: checkpoints = routesEntrances[circ][i:] else: continue timedistance = [] for check in checkpoints: val = int(netDataFrame.loc[(netDataFrame[netRouteId] == circ) & (netDataFrame[netOrder] == check), [netDuration]][netDuration]) timedistance.append(val) final_time.append(row["gduration"] + sum(timedistance)) pntRelStops_gp["final_time"] = pandas.Series(final_time) # Save result pntRelStops_gp.drop(["geometry_y"], axis=1, inplace=True) gd = regulardf_to_geodf(pntRelStops_gp, "geometry_x", 4326) if srs != 4326: gd = project(gd, None, srs, gisApi='pandas') df_to_shp(gd, output) return output