예제 #1
0
def main(adminIsPoint=False):

    ## Define filepath
    path = os.path.realpath(
        os.path.abspath(
            os.path.split(inspect.getfile(inspect.currentframe()))[0]))
    path = os.path.split(path)[0]

    ## Define dash. This .xlsm includes settings for the criticality script
    dash = os.path.join(path, r'dashboard.xlsm')
    ctrl = pd.read_excel(dash, sheetname="AGGREGATE", index_col=0)

    ## Define operative district. Note, this parameter can be anything - it is the sub folder in input, Runtime where files are drawn from
    district = ctrl['Weight'].loc['DISTRICT']

    ## Add logging
    logging.basicConfig(filename=os.path.join(path, 'runtime', district,
                                              "PCS_Criticality_log.log"),
                        level=logging.INFO,
                        format="%(asctime)s-%(levelname)s: %(message)s")
    logging.info("Starting Criticality Process")
    print "Running: Criticality Analysis on %s. Do not interrupt" % district

    ## Path Settings
    # outputs
    outpath = os.path.join(path, 'Outputs', '%s' % district)

    # ensure folders exist
    runtime = os.path.join(path, r'PCS\Criticality\runtime\%s\\' % district)
    for d in [outpath, runtime]:
        if not os.path.isdir(d):
            os.mkdir(d)

    ## Input file setting
    # location of road network
    NETWORK_IN = os.path.join(path, r'runtime\%s\\' % district)

    # location of OD
    OD_IN = os.path.join(path, 'PCS\Criticality\input', '%s' % district)

    # location of administrative boundaries file
    DATA_IN = os.path.join(path, 'PCS\Criticality\Vietnam_Data_Layers')
    inAdmin = os.path.join(DATA_IN, 'Poverty_Communes_2009.shp')

    # road network import. Must be a .csv including geometry information of roads.
    inNetworkFile = os.path.join(NETWORK_IN, 'Network.csv')

    # set WGS 84 coordinate reference system
    crs_in = {'init': 'epsg:4326'}

    # ensure folders exist
    for d in [outpath, runtime, OD_IN]:
        if not os.path.isdir(d):
            os.mkdir(d)

    # error checking - Check input data existence
    for curFile in [dash, inNetworkFile, inAdmin, DATA_IN, OD_IN, NETWORK_IN]:
        if not os.path.exists(curFile):
            logging.error("No input found: %s" % curFile)
            raise ValueError("No input found: %s" % curFile)

    # import input dataframes - road network and control dashboard
    inNetwork = pd.read_csv(inNetworkFile)
    ctrldf = pd.read_excel(dash, sheetname="CRITICALITY", index_col='COL_ID')

    #Inputs
    network = os.path.join(runtime, 'Network.shp')

    ## Network Preparation
    # set default iri value as the mean iri of roads for which iri exists.
    fillvalue = inNetwork['iri_med'].mean()

    # fill iri value where missing
    inNetwork['TC_iri_med'] = inNetwork['iri_med'].fillna(fillvalue)

    # set cost of traversing segment according to length and IRI, per settings in the excel dashboard
    inNetwork['total_cost'] = inNetwork['length'] * (
        ctrldf['Base_cost_km'][0] +
        (ctrldf['IRI_Coeff'][0] * inNetwork['TC_iri_med']))

    # convert the pandas DataFrame to a GeoDataFrame
    ginNetwork = gpd.GeoDataFrame(inNetwork,
                                  crs=crs_in,
                                  geometry=inNetwork['Line_Geometry'].map(
                                      shapely.wkt.loads))

    # set up Shapefile of road network
    ginNetwork.to_file(network, driver='ESRI Shapefile')
    logging.info("Successfully loaded data")

    # Generate admin boundary centroids
    if not adminIsPoint:
        prepareAdminCentroids(ginNetwork, inAdmin, crs_in,
                              os.path.join(OD_IN, 'adm_centroids.shp'))
        logging.info("Created admin centroids")

    # define function for loading origin files into a dictionary. Paramters controlled from dashboard excel
    def makeOrigin(n, ctrldf):
        origindict = {
            'name':
            ctrldf['OName'][n],
            'file':
            os.path.join(path, 'PCS', 'Criticality', 'input', district,
                         '%s.shp' % ctrldf['OName'][n]),
            'scalar_column':
            ctrldf['OScalar'][n]
        }
        return origindict

    # define function for loading destination files into a dictionary. Paramters controlled from dashboard excel
    def makeDestination(n, ctrldf):
        destdict = {
            'name':
            ctrldf['DName'][n],
            'file':
            os.path.join(path, 'PCS', 'Criticality', 'input', district,
                         '%s.shp' % ctrldf['DName'][n]),
            'penalty':
            ctrldf['DPenalty'][n],
            'importance':
            ctrldf['DImportance'][n],
            'annual':
            ctrldf['DAnnual'][n],
            'scalar_column':
            ctrldf['DScalar'][n]
        }
        return destdict

    # load origins and destinations into dictionary, create dictionaries of each set
    origin_1, origin_2, origin_3, origin_4, origin_5 = makeOrigin(
        0, ctrldf), makeOrigin(1, ctrldf), makeOrigin(2, ctrldf), makeOrigin(
            3, ctrldf), makeOrigin(4, ctrldf)
    originlist = {
        '%s' % ctrldf['OName'][0]: origin_1,
        '%s' % ctrldf['OName'][1]: origin_2,
        '%s' % ctrldf['OName'][2]: origin_3,
        '%s' % ctrldf['OName'][3]: origin_4,
        '%s' % ctrldf['OName'][4]: origin_5,
    }
    destination_1, destination_2, destination_3, destination_4, destination_5 = makeDestination(
        0, ctrldf), makeDestination(1, ctrldf), makeDestination(
            2, ctrldf), makeDestination(3, ctrldf), makeDestination(4, ctrldf)
    destinationlist = {
        '%s' % ctrldf['DName'][0]: destination_1,
        '%s' % ctrldf['DName'][1]: destination_2,
        '%s' % ctrldf['DName'][2]: destination_3,
        '%s' % ctrldf['DName'][3]: destination_4,
        '%s' % ctrldf['DName'][4]: destination_5,
    }
    logging.debug("Opened origins and destinations")

    # Prepation of network via TU Delft code
    gdf_points, gdf_node_pos, gdf = net_p.prepare_centroids_network(
        origin_1['file'], network)

    # Create Networkx MultiGraph object from the GeoDataFrame
    G = net_p.gdf_to_simplified_multidigraph(gdf_node_pos, gdf, simplify=False)

    # Change the MultiGraph object to Graph object to reduce computation cost
    G_tograph = net_p.multigraph_to_graph(G)
    logging.debug(
        'Loaded road network: number of disconnected components is: %d' %
        nx.number_connected_components(G_tograph))

    # Observe the properties of the Graph object
    nx.info(G_tograph)

    # Take only the largest subgraph with all connected links
    len_old = 0
    for g in nx.connected_component_subgraphs(G_tograph):
        if len(list(g.edges())) > len_old:
            G1 = g
            len_old = len(list(g.edges()))
    G_sub = G1.copy()

    nx.info(G_sub)

    # Save the simplified transport network into a GeoDataFrame
    gdf_sub = net_p.graph_to_df(G_sub)
    blank, gdf_node_pos2, gdf_new = net_p.prepare_newOD(
        origin_1['file'], gdf_sub)

    #Road Network Graph prep
    G2_multi = net_p.gdf_to_simplified_multidigraph(gdf_node_pos2,
                                                    gdf_new,
                                                    simplify=False)

    # Dump files to runtime if dump = 1
    Filedump(gdf_new, 'Road_Lines', runtime)
    Filedump(gdf_node_pos2, 'Road_Nodes', runtime)
    G2 = net_p.multigraph_to_graph(G2_multi)
    gdf2 = net_p.graph_to_df(G2)
    nLink = len(G2.edges())

    # open empty lists
    Outputs, cost_list, iso_list = [], [], []

    ## Run the calculateOD function for each combination of origins and destinations specified in the control excel
    # append all outputs to the Outputs, cost_list and iso_list objects just created
    for z in ctrldf.index:
        if (((ctrldf['ComboO'][z]) != 0) & ((ctrldf['ComboD'][z]) != 0) &
            (pd.notnull(ctrldf['ComboO'][z])) &
            (pd.notnull(ctrldf['ComboO'][z]))):
            Q = int(ctrldf['ComboNumber'][z])
            logging.info(
                'Computing | combination %s as origin and %s as destination ' %
                (ctrldf['ComboO'][z], ctrldf['ComboD'][z]))
            xx = calculateOD(originlist['%s' % ctrldf['ComboO'][z]],
                             destinationlist['%s' % ctrldf['ComboD'][z]], Q,
                             gdf_sub, G2, nLink, gdf2, runtime, ctrldf)
            Outputs.append(xx)
            cost_list.append("Social_Cost_%s" % Q)
            iso_list.append("Isolated_Trips_%s" % Q)

    # drop unneccessary columns
    Output = inNetwork.drop(["geometry", 'TC_iri_med', 'total_cost'], axis=1)

    # for each object in the Outputs list:
    for o_d_calc in range(0, len(Outputs)):

        # Merge the objects together. This creates multiple columns showing each scenario
        Output = Output.merge(Outputs[o_d_calc]['summary'],
                              how='left',
                              on='ID')

    # sum across the relevant columns - the 'Social_Cost' columns generated above in calculateOD for each O-D file combo
    Output['Cost_total'] = Output[cost_list].sum(axis=1)

    # sum across the relevant columns - the 'Isolated_Trips' columns generated above in calculateOD for each O-D file combo
    Output['Iso_total'] = Output[iso_list].sum(axis=1)

    # Generate an overall criticality score for each road based on user input weights between isolated trips and disrupted trips
    Output['CRIT_SCORE'] = (
        ctrldf['Disrupt_Weight'][0] * Output['Cost_total'] +
        ctrldf['Isolate_Weight'][0] * Output['Iso_total'])

    # normalize for each road
    Output['CRIT_SCORE'] = (
        (Output['CRIT_SCORE'] - Output['CRIT_SCORE'].min()) /
        (Output['CRIT_SCORE'].max() - Output['CRIT_SCORE'].min()))
    logging.info("Calculated PCS Criticality")
    FileOut(Output, 'criticality_output', outpath)
예제 #2
0
gdf_points, gdf_node_pos, gdf = net_p.prepare_centroids_network(
    centroid, network)
# save only the graph information as gdf_clean to increase the computational speed
gdf_clean_0 = gdf.iloc[:, 105:114]
gdf_clean_1 = pd.concat([gdf_clean_0, gdf.loc[:, 'OBJECTID']], axis=1)
gdf_clean = gdf_clean_1.rename(
    columns={'OBJECTID':
             'OBJECT_ID'})  # rename to keep name consistent with Fiji data

# Create Networkx MultiGraph object from the GeoDataFrame
G = net_p.gdf_to_simplified_multidigraph(gdf_node_pos,
                                         gdf_clean,
                                         simplify=False)

# Change the MultiGraph object to Graph object to reduce computation cost
G_tograph = net_p.multigraph_to_graph(G)

# Observe the properties of the Graph object
nx.info(G_tograph)

# Take only the largest subgraph which all connected links
len_old = 0
for g in nx.connected_component_subgraphs(G_tograph):
    if len(list(g.edges())) > len_old:
        G1 = g
        len_old = len(list(g.edges()))
G_sub = G1.copy()

#print('number of disconnected compoents is', nx.number_connected_components(G_sub))
nx.info(G_sub)
예제 #3
0
def main(adminIsPoint=False):
    path = os.path.realpath(
        os.path.abspath(
            os.path.split(inspect.getfile(inspect.currentframe()))[0]))
    path = os.path.split(path)[0]
    dash = os.path.join(path, r'dashboard.xlsm')
    ctrl = pd.read_excel(dash, sheetname="AGGREGATE", index_col=0)
    district = ctrl['Weight'].loc['DISTRICT']

    logging.basicConfig(filename=os.path.join(path, 'runtime', district,
                                              "PCS_Criticality_log.log"),
                        level=logging.INFO,
                        format="%(asctime)s-%(levelname)s: %(message)s")
    logging.info("Starting Criticality Process")
    print "Running: Criticality Analysis on %s. Do not interrupt" % district
    # Path Settings
    outpath = os.path.join(path, 'Outputs', '%s' % district)
    runtime = os.path.join(path, r'PCS\Criticality\runtime\%s\\' % district)
    for d in [outpath, runtime]:
        if not os.path.isdir(d):
            os.mkdir(d)
    NETWORK_IN = os.path.join(path, r'runtime\%s\\' % district)
    OD_IN = os.path.join(path, 'PCS\Criticality\input', '%s' % district)
    DATA_IN = os.path.join(path, 'PCS\Criticality\Vietnam_Data_Layers')
    inAdmin = os.path.join(DATA_IN, 'Poverty_Communes_2009.shp')
    inNetworkFile = os.path.join(NETWORK_IN, 'Network.csv')

    crs_in = {'init': 'epsg:4326'}  #WGS 84

    #Create folders for analysis
    for d in [outpath, runtime, OD_IN]:
        if not os.path.isdir(d):
            os.mkdir(d)
    #Error checking - Check input data
    for curFile in [dash, inNetworkFile, inAdmin, DATA_IN, OD_IN, NETWORK_IN]:
        if not os.path.exists(curFile):
            logging.error("No input found: %s" % curFile)
            raise ValueError("No input found: %s" % curFile)

    inNetwork = pd.read_csv(inNetworkFile)
    ctrldf = pd.read_excel(dash, sheetname="CRITICALITY", index_col='COL_ID')
    #Inputs
    network = os.path.join(runtime, 'Network.shp')

    #Network Prep
    fillvalue = inNetwork['iri_med'].mean()
    inNetwork['TC_iri_med'] = inNetwork['iri_med'].fillna(fillvalue)
    inNetwork['total_cost'] = inNetwork['length'] * (
        ctrldf['Base_cost_km'][0] +
        (ctrldf['IRI_Coeff'][0] * inNetwork['TC_iri_med']))
    ginNetwork = gpd.GeoDataFrame(inNetwork,
                                  crs=crs_in,
                                  geometry=inNetwork['Line_Geometry'].map(
                                      shapely.wkt.loads))
    ginNetwork.to_file(network, driver='ESRI Shapefile')
    logging.info("Successfully loaded data")
    if not adminIsPoint:
        prepareAdminCentroids(ginNetwork, inAdmin, crs_in,
                              os.path.join(OD_IN, 'adm_centroids.shp'))
        logging.info("Created admin centroids")

    def makeOrigin(n, ctrldf):
        origindict = {
            'name':
            ctrldf['OName'][n],
            'file':
            os.path.join(path, 'PCS', 'Criticality', 'input', district,
                         '%s.shp' % ctrldf['OName'][n]),
            'scalar_column':
            ctrldf['OScalar'][n]
        }
        return origindict

    def makeDestination(n, ctrldf):
        destdict = {
            'name':
            ctrldf['DName'][n],
            'file':
            os.path.join(path, 'PCS', 'Criticality', 'input', district,
                         '%s.shp' % ctrldf['DName'][n]),
            'penalty':
            ctrldf['DPenalty'][n],
            'importance':
            ctrldf['DImportance'][n],
            'annual':
            ctrldf['DAnnual'][n],
            'scalar_column':
            ctrldf['DScalar'][n]
        }
        return destdict

    origin_1, origin_2, origin_3, origin_4, origin_5 = makeOrigin(
        0, ctrldf), makeOrigin(1, ctrldf), makeOrigin(2, ctrldf), makeOrigin(
            3, ctrldf), makeOrigin(4, ctrldf)
    originlist = {
        '%s' % ctrldf['OName'][0]: origin_1,
        '%s' % ctrldf['OName'][1]: origin_2,
        '%s' % ctrldf['OName'][2]: origin_3,
        '%s' % ctrldf['OName'][3]: origin_4,
        '%s' % ctrldf['OName'][4]: origin_5,
    }
    destination_1, destination_2, destination_3, destination_4, destination_5 = makeDestination(
        0, ctrldf), makeDestination(1, ctrldf), makeDestination(
            2, ctrldf), makeDestination(3, ctrldf), makeDestination(4, ctrldf)
    destinationlist = {
        '%s' % ctrldf['DName'][0]: destination_1,
        '%s' % ctrldf['DName'][1]: destination_2,
        '%s' % ctrldf['DName'][2]: destination_3,
        '%s' % ctrldf['DName'][3]: destination_4,
        '%s' % ctrldf['DName'][4]: destination_5,
    }
    logging.debug("Opened origins and destinations")
    # Prepation of network
    gdf_points, gdf_node_pos, gdf = net_p.prepare_centroids_network(
        origin_1['file'], network)
    # Create Networkx MultiGraph object from the GeoDataFrame
    G = net_p.gdf_to_simplified_multidigraph(gdf_node_pos, gdf, simplify=False)
    # Change the MultiGraph object to Graph object to reduce computation cost
    G_tograph = net_p.multigraph_to_graph(G)
    logging.debug(
        'Loaded road network: number of disconnected components is: %d' %
        nx.number_connected_components(G_tograph))
    # Observe the properties of the Graph object
    nx.info(G_tograph)
    # Take only the largest subgraph with all connected links
    len_old = 0
    for g in nx.connected_component_subgraphs(G_tograph):
        if len(list(g.edges())) > len_old:
            G1 = g
            len_old = len(list(g.edges()))
    G_sub = G1.copy()

    nx.info(G_sub)

    # Save the simplified transport network into a GeoDataFrame
    gdf_sub = net_p.graph_to_df(G_sub)
    blank, gdf_node_pos2, gdf_new = net_p.prepare_newOD(
        origin_1['file'], gdf_sub)

    #Road Network Graph prep
    G2_multi = net_p.gdf_to_simplified_multidigraph(gdf_node_pos2,
                                                    gdf_new,
                                                    simplify=False)
    Filedump(gdf_new, 'Road_Lines', runtime)
    Filedump(gdf_node_pos2, 'Road_Nodes', runtime)
    G2 = net_p.multigraph_to_graph(G2_multi)
    gdf2 = net_p.graph_to_df(G2)
    nLink = len(G2.edges())

    Outputs, cost_list, iso_list = [], [], []

    for z in ctrldf.index:
        if (((ctrldf['ComboO'][z]) != 0) & ((ctrldf['ComboD'][z]) != 0) &
            (pd.notnull(ctrldf['ComboO'][z])) &
            (pd.notnull(ctrldf['ComboO'][z]))):
            Q = int(ctrldf['ComboNumber'][z])
            logging.info(
                'Computing | combination %s as origin and %s as destination ' %
                (ctrldf['ComboO'][z], ctrldf['ComboD'][z]))
            xx = calculateOD(originlist['%s' % ctrldf['ComboO'][z]],
                             destinationlist['%s' % ctrldf['ComboD'][z]], Q,
                             gdf_sub, G2, nLink, gdf2, runtime, ctrldf)
            Outputs.append(xx)
            cost_list.append("Social_Cost_%s" % Q)
            iso_list.append("Isolated_Trips_%s" % Q)

    Output = inNetwork.drop(["geometry", 'TC_iri_med', 'total_cost'], axis=1)
    for o_d_calc in range(0, len(Outputs)):
        Output = Output.merge(Outputs[o_d_calc]['summary'],
                              how='left',
                              on='ID')

    Output['Cost_total'] = Output[cost_list].sum(axis=1)
    Output['Iso_total'] = Output[iso_list].sum(axis=1)
    Output['CRIT_SCORE'] = (
        ctrldf['Disrupt_Weight'][0] * Output['Cost_total'] +
        ctrldf['Isolate_Weight'][0] * Output['Iso_total'])
    Output['CRIT_SCORE'] = (
        (Output['CRIT_SCORE'] - Output['CRIT_SCORE'].min()) /
        (Output['CRIT_SCORE'].max() - Output['CRIT_SCORE'].min()))
    logging.info("Calculated PCS Criticality")
    FileOut(Output, 'criticality_output', outpath)