Example #1
0
    def assign_matrix(self, matrix: AequilibraeMatrix, result_name: str):
        conn = database_connection()

        sql = f"select link_id, direction, a_node, b_node, distance, 1 capacity from {DELAUNAY_TABLE}"

        df = pd.read_sql(sql, conn)
        centroids = np.array(np.unique(np.hstack((df.a_node.values, df.b_node.values))), int)

        g = Graph()
        g.mode = 'delaunay'
        g.network = df
        g.prepare_graph(centroids)
        g.set_blocked_centroid_flows(True)

        tc = TrafficClass('delaunay', g, matrix)
        ta = TrafficAssignment()
        ta.set_classes([tc])
        ta.set_time_field('distance')
        ta.set_capacity_field('capacity')
        ta.set_vdf('BPR')
        ta.set_vdf_parameters({"alpha": 0, "beta": 1.0})
        ta.set_algorithm('all-or-nothing')
        ta.execute()

        report = {"setup": str(ta.info())}
        data = [result_name, "Delaunay assignment", self.procedure_id, str(report), ta.procedure_date, '']
        conn.execute("""Insert into results(table_name, procedure, procedure_id, procedure_report, timestamp,
                                            description) Values(?,?,?,?,?,?)""", data)
        conn.commit()
        conn.close()

        cols = []
        for x in matrix.view_names:
            cols.extend([f'{x}_ab', f'{x}_ba', f'{x}_tot'])
        df = ta.results()[cols]
        conn = sqlite3.connect(join(environ[ENVIRON_VAR], "results_database.sqlite"))
        df.to_sql(result_name, conn)
        conn.close()
Example #2
0
    def build_graphs(self, fields: list = None, modes: list = None) -> None:
        """Builds graphs for all modes currently available in the model

        When called, it overwrites all graphs previously created and stored in the networks'
        dictionary of graphs

        Args:
            *fields* (:obj:`list`, optional): When working with very large graphs with large number of fields in the
                                              database, it may be useful to specify which fields to use
            *modes* (:obj:`list`, optional): When working with very large graphs with large number of fields in the
                                              database, it may be useful to generate only those we need

        To use the *fields* parameter, a minimalistic option is the following
        ::

            p = Project()
            p.open(nm)
            fields = ['distance']
            p.network.build_graphs(fields, modes = ['c', 'w'])

        """
        curr = self.conn.cursor()

        if fields is None:
            curr.execute("PRAGMA table_info(links);")
            field_names = curr.fetchall()

            ignore_fields = ["ogc_fid", "geometry"]
            all_fields = [
                f[1] for f in field_names if f[1] not in ignore_fields
            ]
        else:
            fields.extend(
                ["link_id", "a_node", "b_node", "direction", "modes"])
            all_fields = list(set(fields))

        if modes is None:
            modes = curr.execute("select mode_id from modes;").fetchall()
            modes = [m[0] for m in modes]
        elif isinstance(modes, str):
            modes = [modes]

        sql = f"select {','.join(all_fields)} from links"

        df = pd.read_sql(sql, self.conn).fillna(value=np.nan)
        valid_fields = list(df.select_dtypes(np.number).columns) + ["modes"]
        curr.execute(
            "select node_id from nodes where is_centroid=1 order by node_id;")
        centroids = np.array([i[0] for i in curr.fetchall()], np.uint32)

        data = df[valid_fields]
        for m in modes:
            net = pd.DataFrame(data, copy=True)
            net.loc[~net.modes.str.contains(m),
                    "b_node"] = net.loc[~net.modes.str.contains(m), "a_node"]
            g = Graph()
            g.mode = m
            g.network = net
            g.prepare_graph(centroids)
            g.set_blocked_centroid_flows(True)
            self.graphs[m] = g