def servarea_from_points(pntShp, inEPSG, range, outShp, mode='foot-walking', intervals=None): """ Calculate isochrones for all points in a Point Feature Class """ import time from shapely.geometry import shape from threading import Thread from gasp.web.orouteserv import get_keys, isochrones from gasp.fm import tbl_to_obj from gasp.mng.split import split_df_inN from gasp.fm.geom import pointxy_to_cols from gasp.mng.gen import merge_df from gasp.prop.feat import get_geom_type from gasp.mng.prj import project from gasp.to.geom import dict_to_geodf from gasp.to.obj import df_to_dict from gasp.to.shp import df_to_shp # SHP TO GEODATAFRAME pntDf = tbl_to_obj(pntShp) # Check if SHPs are points inGeomType = get_geom_type(pntDf, geomCol="geometry", gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') # Reproject geodf if necessary if inEPSG != 4326: pntDf = project(pntDf, None, 4326, gisApi='pandas') pntDf["old_fid"] = pntDf.index pntDf = pointxy_to_cols( pntDf, geomCol="geometry", colX="longitude", colY="latitude" ) # Get Keys KEYS = get_keys() df_by_key = split_df_inN(pntDf, KEYS.shape[0]) keys_list = KEYS['key'].tolist() results = [] def get_isochrones(df, key): pntDict = df_to_dict(df) for k in pntDict: iso = isochrones( "{},{}".format(pntDict[k]["longitude"], pntDict[k]["latitude"]), range, range_type='time', modeTransportation=mode, intervals=intervals ) pntDict[k]["geometry"] = shape(iso["features"][0]["geometry"]) time.sleep(5) pntDf = dict_to_geodf(pntDict, "geometry", 4326) results.append(pntDf) # Create threads thrds = [] i = 1 for df in df_by_key: thrds.append(Thread( name='tk{}'.format(str(i)), target=get_isochrones, args=(df, keys_list[i - 1]) )) i += 1 # Start all threads for thr in thrds: thr.start() # Wait for all threads to finish for thr in thrds: thr.join() # Join all dataframes pntDf = merge_df(results, ignIndex=False) if inEPSG != 4326: pntDf = project(pntDf, None, inEPSG, gisApi='pandas') return df_to_shp(pntDf, outShp)
def cost_od(shpOrigins, shpDestinations, epsgOrigins, epsgDestinations, table_result, mode='foot-walking'): """ Matrix od Service Implementation """ import pandas from threading import Thread from gasp.fm.api.orouteserv import get_keys from gasp.fm.api.orouteserv import matrix_od from gasp.fm import shp_to_df from gasp.mng.split import split_df_inN from gasp.fm.geom import pointxy_to_cols from gasp.mng.prj import project from gasp.mng.gen import merge_df from gasp.prop.feat import get_geom_type from gasp.to import obj_to_tbl origensDf = tbl_to_obj( shpOrigins) destinoDf = tbl_to_obj(shpDestinations) # Check if SHPs are points inGeomType = get_geom_type(origensDf, geomCol="geometry", gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') inGeomType = get_geom_type(destinoDf, geomCol="geometry", gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') # Re-project if needed if epsgOrigins != 4326: origensDf = project(origensDf, None, 4326, gisApi='pandas') if epsgDestinations != 4326: destinoDf = project(destinoDf, None, 4326, gisApi='pandas') origensDf = pointxy_to_cols( origensDf, geomCol="geometry", colX="longitude", colY="latitude" ); destinoDf = pointxy_to_cols( destinoDf, geomCol="geometry", colX="longitude", colY="latitude" ) origensDf["location"] = origensDf.longitude.astype(str) + "," + \ origensDf.latitude.astype(str) destinoDf["location"] = destinoDf.longitude.astype(str) + "," + \ destinoDf.latitude.astype(str) origensDf["old_fid"] = origensDf.index destinoDf["old_fid"] = destinoDf.index # Get Keys KEYS = get_keys() origensByKey = split_df_inN(origensDf, KEYS.shape[0]) lst_keys = KEYS["key"].tolist() # Produce matrix results = [] def get_matrix(origins, key): origins.reset_index(inplace=True) origins["rqst_idx"] = origins.index.astype(str) destinations = destinoDf.copy() strSource = origins.location.str.cat(sep="|") idxSource = origins.rqst_idx.str.cat(sep=",") destinations["rqst_idx"] = destinations.old_fid + origins.shape[0] destinations["rqst_idx"] = destinations.rqst_idx.astype(str) strDestin = destinations.location.str.cat(sep="|") idxDestin = destinations.rqst_idx.str.cat(sep=",") rslt = matrix_od( strSource + "|" + strDestin, idxSources=idxSource, idxDestinations=idxDestin, useKey=key, modeTransportation=mode ) rslt = pandas.DataFrame(rslt["durations"]) originsFID = origins.old_fid.tolist() destinaFID = destinations.old_fid.tolist() mm = [] for lnh in range(len(originsFID)): for col in range(len(destinaFID)): ll = [ originsFID[lnh], destinaFID[col], rslt.iloc[lnh, col] ] mm.append(ll) matrix = pandas.DataFrame( mm, columns=["fid_origin", "fid_destin", "cost"]) results.append(matrix) # Create threads thrds = [] i= 1 for df in origensByKey: thrds.append(Thread( name="tk{}".format(str(i)), target=get_matrix, args=(df, lst_keys[i - 1]) )) i += 1 # Start all threads for thr in thrds: thr.start() # Wait for all threads to finish for thr in thrds: thr.join() # Join all dataframes RESULT = merge_df(results, ignIndex=False) RESULT = RESULT.merge( origensDf , how='inner', left_on=["fid_origin"], right_on=["old_fid"] ); RESULT.drop([ x for x in origensDf.columns.values if x != "geometry"], axis=1, inplace=True ); RESULT.rename(columns={"geometry" : "origin_geom"}, inplace=True) RESULT = RESULT.merge( destinoDf, how='inner', left_on=["fid_destin"], right_on=["old_fid"] ); RESULT.drop([ x for x in destinoDf.columns.values if x != "geometry"], axis=1, inplace=True ); RESULT.rename(columns={"geometry" : "destin_geom"}, inplace=True) RESULT["origin_geom"] = RESULT.origin_geom.astype(str) RESULT["destin_geom"] = RESULT.destin_geom.astype(str) return obj_to_tbl(RESULT, table_result)
def matrix_od(originsShp, destinationShp, originsEpsg, destinationEpsg, resultShp, modeTrans="driving"): """ Use Pandas to Retrieve data from MapBox Matrix OD Service """ import time from threading import Thread from gasp.web.mapbx import get_keys, matrix from gasp.fm import tbl_to_obj from gasp.mng.split import split_df, split_df_inN from gasp.mng.fld.df import listval_to_newcols from gasp.fm.geom import pointxy_to_cols from gasp.mng.prj import project from gasp.mng.gen import merge_df from gasp.prop.feat import get_geom_type from gasp.to.shp import df_to_shp # Data to GeoDataFrame origens = tbl_to_obj( originsShp) destinos = tbl_to_obj(destinationShp) # Check if SHPs are points inGeomType = get_geom_type(origens, geomCol="geometry", gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') inGeomType = get_geom_type(destinos, geomCol="geometry", gisApi='pandas') if inGeomType != 'Point' and inGeomType != 'MultiPoint': raise ValueError('The input geometry must be of type point') # Re-Project data to WGS if originsEpsg != 4326: origens = project(origens, None, 4326, gisApi='pandas') if destinationEpsg != 4326: destinos = project(destinos, None, 4326, gisApi='pandas') origens = pointxy_to_cols( origens, geomCol="geometry", colX="longitude", colY="latitude" ); destinos = pointxy_to_cols( destinos, geomCol="geometry", colX="longitude", colY="latitude" ) # Prepare coordinates Str origens["location"] = origens.longitude.astype(str) \ + "," + origens.latitude.astype(str) destinos["location"] = destinos.longitude.astype(str) \ + "," + destinos.latitude.astype(str) # Split destinations DataFrame into Dafaframes with # 24 rows lst_destinos = split_df(destinos, 24) # Get Keys to use KEYS = get_keys() # Split origins by key origensByKey = split_df_inN(origens, KEYS.shape[0]) lst_keys= KEYS["key"].tolist() # Produce matrix results = [] def get_matrix(origins, key): def def_apply(row): rowResults = [] for df in lst_destinos: strDest = df.location.str.cat(sep=";") strLocations = row["location"] + ";" + strDest dados = matrix( strLocations, idxSources="0", idxDestinations=";".join([str(i) for i in range(1, df.shape[0] + 1)]), useKey=key, modeTransportation=modeTrans ) time.sleep(5) rowResults += dados["durations"][0] row["od_matrix"] = rowResults return row newOrigins = origins.apply( lambda x: def_apply(x), axis=1 ) results.append(newOrigins) # Create threads thrds = [] i = 1 for df in origensByKey: thrds.append(Thread( name="tk{}".format(str(i)), target=get_matrix, args=(df, lst_keys[i - 1]) )) i += 1 # Start all threads for thr in thrds: thr.start() # Wait for all threads to finish for thr in thrds: thr.join() # Join all dataframes RESULT = merge_df(results, ignIndex=False) RESULT = listval_to_newcols(RESULT, "od_matrix") RESULT.rename( columns={ c: "dest_{}".format(c) for c in RESULT.columns.values if type(c) == int or type(c) == long }, inplace=True ) if originsEpsg != 4326: RESULT = project(RESULT, None, originsEpsg, gisApi='pandas') return df_to_shp(RESULT, resultShp) return results
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 get_points_elv(pntShp, output, epsg, elevationColumn="openelv"): """ Extract elevation for several points """ import pandas from threading import Thread from gasp.fm import tbl_to_obj from gasp.mng.split import split_df from gasp.mng.prj import project from gasp.fm.geom import pointxy_to_cols from gasp.mng.gen import merge_df from gasp.prop.feat import df_geom_type from gasp.to.obj import df_to_list from gasp.to.shp import df_to_shp # SHP TO DF df = tbl_to_obj(pntShp) # Check Geometry - shape should be of type point dfGeom = get_geom_type(df, geomCol="geometry", gisApi='pandas') if dfGeom != 'Point' and dfGeom != 'MultiPoint': raise ValueError('Geometries must be of type point') # Re-project GeoDataframes if needed if epsg != 4326: df = project(df, None, 4326, gisApi='pandas') df = pointxy_to_cols(df, geomCol="geometry", colX="longitude", colY="latitude") df2 = df.drop( [c for c in df.columns.values if c != "longitude" and c != "latitude"], axis=1, inplace=False) dfs = split_df(df2, 200) RESULTS = [] # Go to the net and extract elevation def extraction(pntDf): locations = df_to_list(pntDf) __result = locations_elev({"locations": locations}) RESULTS.append(pandas.DataFrame(__result["results"])) thrds = [] for i in range(len(dfs)): thrds.append( Thread(name="elvt{}".format(str(i)), target=extraction, args=(dfs[i], ))) for t in thrds: t.start() for t in thrds: t.join() finalDf = merge_df(RESULTS, ignIndex=True) finalDf.rename(columns={"elevation": elevationColumn}, inplace=True) # Join with Original Shape df["long_join"] = df.longitude.round(6) * 1000000 df["long_join"] = df.long_join.astype(int) df["lat_join"] = df.latitude.round(6) * 1000000 df["lat_join"] = df.lat_join.astype(int) finalDf["jlat"] = finalDf.latitude.round(6) * 1000000 finalDf["jlat"] = finalDf.jlat.astype(int) finalDf["jlng"] = finalDf.longitude.round(6) * 1000000 finalDf["jlng"] = finalDf.jlng.astype(int) newDf = df.merge(finalDf, how="outer", left_on=["long_join", "lat_join"], right_on=["jlng", "jlat"]) if epsg != 4326: newDf = project(newDf, None, epsg, gisApi='pandas') newDf.drop([ "longitude_x", "longitude_y", "latitude_x", "latitude_y", "long_join", "lat_join", "jlng", "jlat" ], axis=1, inplace=True) return df_to_shp(newDf, output)
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