Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
Archivo: dmx.py Proyecto: zonakre/gasp
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
Ejemplo n.º 6
0
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