diff --git a/docs/create_docs_data.py b/docs/create_docs_data.py index d94e41467..7138e343f 100644 --- a/docs/create_docs_data.py +++ b/docs/create_docs_data.py @@ -1,3 +1,4 @@ +import os import sys from pathlib import Path @@ -14,4 +15,15 @@ project = create_example("/tmp/test_project_gc") project.close() project = create_example("/tmp/test_project_ga") -project.close() \ No newline at end of file +project.close() +project = create_example("/tmp/accessing_sfalls_data") +project.close() +project = create_example("/tmp/accessing_nauru_data", "nauru") +project.close() +project = create_example("/tmp/accessing_coquimbo_data", "coquimbo") +project.close() + +# Create empty folder +if not os.path.exists("/tmp/matrix_example"): + + os.makedirs("/tmp/matrix_example") \ No newline at end of file diff --git a/docs/source/examples/assignment_workflows/plot_forecasting.py b/docs/source/examples/assignment_workflows/plot_forecasting.py index d2c079f3f..fd86d7b25 100644 --- a/docs/source/examples/assignment_workflows/plot_forecasting.py +++ b/docs/source/examples/assignment_workflows/plot_forecasting.py @@ -10,6 +10,19 @@ distributing these trips into the network. Later, we estimate a set of future demand vectors which are going to be the input of a future year assignnment with select link analysis. """ +# %% +# .. seealso:: +# The use of the following functions, methods, classes and modules is shown in this example: +# +# * :func:`aequilibrae.paths.Graph` +# * :func:`aequilibrae.paths.TrafficClass` +# * :func:`aequilibrae.paths.TrafficAssignment` +# * :func:`aequilibrae.distribution.Ipf` +# * :func:`aequilibrae.distribution.GravityCalibration` +# * :func:`aequilibrae.distribution.GravityApplication` +# * :func:`aequilibrae.distribution.SyntheticGravityModel` +# * :func:`aequilibrae.matrix.AequilibraeData` + # %% # Imports @@ -425,16 +438,3 @@ def plot_tlfd(demand, skim, name): # %% # Close the project project.close() - -# %% -# .. seealso:: -# The use of the following functions, methods, classes and modules is shown in this example: -# -# * :func:`aequilibrae.paths.Graph` -# * :func:`aequilibrae.paths.TrafficClass` -# * :func:`aequilibrae.paths.TrafficAssignment` -# * :func:`aequilibrae.distribution.Ipf` -# * :func:`aequilibrae.distribution.GravityCalibration` -# * :func:`aequilibrae.distribution.GravityApplication` -# * :func:`aequilibrae.distribution.SyntheticGravityModel` -# * :func:`aequilibrae.matrix.AequilibraeData` diff --git a/docs/source/examples/assignment_workflows/plot_public_transit_assignment.py b/docs/source/examples/assignment_workflows/plot_public_transit_assignment.py index 1459f47a2..2bdab2c14 100644 --- a/docs/source/examples/assignment_workflows/plot_public_transit_assignment.py +++ b/docs/source/examples/assignment_workflows/plot_public_transit_assignment.py @@ -9,6 +9,22 @@ We use data from Coquimbo, a city in La Serena Metropolitan Area in Chile. """ +# %% +# .. admonition:: References +# +# * :ref:`transit_assignment_graph` +# * :ref:`transit_hyperpath_routing` + +# %% +# .. seealso:: +# The use of the following functions, methods, classes and modules is shown in this example: +# +# * :func:`aequilibrae.transit.Transit` +# * :func:`aequilibrae.transit.TransitGraphBuilder` +# * :func:`aequilibrae.paths.TransitClass` +# * :func:`aequilibrae.paths.TransitAssignment` +# * :func:`aequilibrae.matrix.AequilibraeMatrix` + # %% # Imports for example construction @@ -170,19 +186,3 @@ # %% # Wrapping up project.close() - -# %% -# .. admonition:: References -# -# * :ref:`transit_assignment_graph` -# * :ref:`transit_hyperpath_routing` - -# %% -# .. seealso:: -# The use of the following functions, methods, classes and modules is shown in this example: -# -# * :func:`aequilibrae.transit.Transit` -# * :func:`aequilibrae.transit.TransitGraphBuilder` -# * :func:`aequilibrae.paths.TransitClass` -# * :func:`aequilibrae.paths.TransitAssignment` -# * :func:`aequilibrae.matrix.AequilibraeMatrix` \ No newline at end of file diff --git a/docs/source/examples/assignment_workflows/plot_route_choice_basics.py b/docs/source/examples/assignment_workflows/plot_route_choice_basics.py index 3e41d0eaa..90f51e60b 100644 --- a/docs/source/examples/assignment_workflows/plot_route_choice_basics.py +++ b/docs/source/examples/assignment_workflows/plot_route_choice_basics.py @@ -7,6 +7,18 @@ In this example, we show how to perform route choice set generation using BFSLE and Link penalisation, for a city in La Serena Metropolitan Area in Chile. """ +# %% +# .. admonition:: References +# +# :ref:`route_choice` + +# %% +# .. seealso:: +# The use of the following functions, methods, classes and modules is shown in this example: +# +# * :func:`aequilibrae.paths.Graph` +# * :func:`aequilibrae.paths.RouteChoice` +# * :func:`aequilibrae.matrix.AequilibraeMatrix` # %% @@ -224,16 +236,3 @@ def plot_results(link_loads): # %% project.close() - -# %% -# .. admonition:: References -# -# :ref:`route_choice` - -# %% -# .. seealso:: -# The use of the following functions, methods, classes and modules is shown in this example: -# -# * :func:`aequilibrae.paths.Graph` -# * :func:`aequilibrae.paths.RouteChoice` -# * :func:`aequilibrae.matrix.AequilibraeMatrix` \ No newline at end of file diff --git a/docs/source/examples/assignment_workflows/plot_route_choice_set.py b/docs/source/examples/assignment_workflows/plot_route_choice_set.py index fb3fcc91c..209194b9d 100644 --- a/docs/source/examples/assignment_workflows/plot_route_choice_set.py +++ b/docs/source/examples/assignment_workflows/plot_route_choice_set.py @@ -7,6 +7,16 @@ In this example, we show how to generate route choice sets for estimation of route choice models, using a a city in La Serena Metropolitan Area in Chile. """ +# %% +# .. admonition:: References +# +# :ref:`route_choice` + +# %% +# .. seealso:: +# The use of the following functions, methods, classes and modules is shown in this example: +# +# * :func:`aequilibrae.paths.RouteChoice` # %% @@ -147,14 +157,3 @@ # %% project.close() - -# %% -# .. admonition:: References -# -# :ref:`route_choice` - -# %% -# .. seealso:: -# The use of the following functions, methods, classes and modules is shown in this example: -# -# * :func:`aequilibrae.paths.RouteChoice` \ No newline at end of file diff --git a/docs/source/examples/visualization/plot_display.py b/docs/source/examples/visualization/plot_display.py index a070ef9cf..24198659e 100644 --- a/docs/source/examples/visualization/plot_display.py +++ b/docs/source/examples/visualization/plot_display.py @@ -33,6 +33,11 @@ links = project.network.links.data nodes = project.network.nodes.data +# %% +# And if you want to take a quick look in your GeoDataFrames, you can plot it! + +# links.plot() + # %% # We create our Folium layers network_links = folium.FeatureGroup("links") diff --git a/docs/source/modeling_with_aequilibrae/index.rst b/docs/source/modeling_with_aequilibrae/index.rst index f57d77dd3..be4daf525 100644 --- a/docs/source/modeling_with_aequilibrae/index.rst +++ b/docs/source/modeling_with_aequilibrae/index.rst @@ -16,7 +16,6 @@ a start guide to a complete view into AequilibraE's data structure. .. toctree:: :maxdepth: 1 - :caption: A guide to AequilibraE project project_database/index diff --git a/docs/source/modeling_with_aequilibrae/project_database/modes.rst b/docs/source/modeling_with_aequilibrae/project_database/modes.rst index 8ee7ffd43..c583769ef 100644 --- a/docs/source/modeling_with_aequilibrae/project_database/modes.rst +++ b/docs/source/modeling_with_aequilibrae/project_database/modes.rst @@ -97,4 +97,5 @@ required. .. seealso:: - :func:`aequilibrae.project.network.Modes` + * :func:`aequilibrae.project.network.Modes` + * :ref:`modes_network_data_model` diff --git a/docs/source/modeling_with_aequilibrae/project_database/network.rst b/docs/source/modeling_with_aequilibrae/project_database/network.rst index 94d4f4801..b246838ed 100644 --- a/docs/source/modeling_with_aequilibrae/project_database/network.rst +++ b/docs/source/modeling_with_aequilibrae/project_database/network.rst @@ -27,9 +27,14 @@ other changes to the layers or preventing the changes. implementation requires a complete overahaul of the path-building code, so that is still a long-term goal, barred specific development efforts. +.. seealso:: + + * :ref:`links_network_data_model` + * :ref:`nodes_network_data_model` + .. toctree:: :maxdepth: 1 :caption: Dive deep into network! - network_import_and_export.rst network_geometry.rst + network_import_and_export.rst diff --git a/docs/source/modeling_with_aequilibrae/project_pieces/accessing_project_data.rst b/docs/source/modeling_with_aequilibrae/project_pieces/accessing_project_data.rst index 32424063f..11a681b0c 100644 --- a/docs/source/modeling_with_aequilibrae/project_pieces/accessing_project_data.rst +++ b/docs/source/modeling_with_aequilibrae/project_pieces/accessing_project_data.rst @@ -13,16 +13,13 @@ cover the main points regarding them. This method allows you to access the API resources to manipulate the 'links' table. Each item in the 'links' table is a ``Link`` object. -.. testsetup:: * - - >>> folder = getfixture("create_path") - .. code-block:: python + >>> from aequilibrae import Project >>> from shapely.geometry import LineString - >>> from aequilibrae.utils.create_example import create_example - >>> project = create_example(folder, "coquimbo") + >>> project = Project() + >>> project.open("/tmp/accessing_coquimbo_data") >>> project_links = project.network.links @@ -208,9 +205,9 @@ Each item in the 'zones' table is a ``Zone`` object. >>> zones = project_zones.data # To get a Shapely Polygon or Multipolygon with the entire zoning coverage - >>> project_zones.coverage() # doctest: +SKIP + >>> boundaries = project_zones.coverage() - # And to get the nearest zone to giver geometry + # And to get the nearest zone to a given geometry >>> project_zones.get_closest_zone(Point(-71.3336, -29.9490)) 57 diff --git a/docs/source/modeling_with_aequilibrae/project_pieces/aequilibrae_matrix.rst b/docs/source/modeling_with_aequilibrae/project_pieces/aequilibrae_matrix.rst index e55b1e5f5..58699bcab 100644 --- a/docs/source/modeling_with_aequilibrae/project_pieces/aequilibrae_matrix.rst +++ b/docs/source/modeling_with_aequilibrae/project_pieces/aequilibrae_matrix.rst @@ -24,10 +24,8 @@ There are three ways of creating an ``AequilibraeMatrix``: >>> import numpy as np >>> from os.path import join >>> from aequilibrae.matrix import AequilibraeMatrix - - >>> folder = getfixture("tmp_path") - >>> file = join(folder, "path_to_my_matrix.aem") + >>> file = "/tmp/matrix_example/path_to_my_matrix.aem" >>> num_zones = 5 >>> index = np.arange(1, 6, dtype=np.int32) >>> mtx = np.ones((5, 5), dtype=np.float32) @@ -83,16 +81,16 @@ for CSV file, in which all cores will be exported as separate columns in the out .. code-block:: python - >>> mat.export(join(folder, 'my_new_omx_file.omx')) + >>> mat.export('/tmp/matrix_example/my_new_omx_file.omx') - >>> mat.export(join(folder, 'my_new_csv_file.csv')) + >>> mat.export('/tmp/matrix_example/my_new_csv_file.csv') The ``export`` method also allows you to change your mind and save your AequilibraE matrix into an AEM file, if it's only in memory. .. code-block:: python - >>> mat.export(join(folder, 'my_new_aem_file.aem')) + >>> mat.export('/tmp/matrix_example/my_new_aem_file.aem') .. is there a better name rather than error? @@ -109,7 +107,7 @@ AequilibraE matrices in disk can be reused and loaded once again. .. code-block:: python >>> mat = AequilibraeMatrix() - >>> mat.load(join(folder, 'my_new_aem_file.aem')) + >>> mat.load('/tmp/matrix_example/my_new_aem_file.aem') >>> mat.get_matrix("only_ones") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE memmap([[1., 1., 1., 1., 1.], @@ -152,8 +150,8 @@ Creating an AequilibraE matrix from an OMX file is pretty straightforward. .. code-block:: python - >>> file_path = join(folder, "path_to_new_matrix.aem") - >>> omx_path = join(folder, 'my_new_omx_file.omx') + >>> file_path = "/tmp/matrix_example/path_to_new_matrix.aem" + >>> omx_path = '/tmp/matrix_example/my_new_omx_file.omx' >>> omx_mat = AequilibraeMatrix() >>> omx_mat.create_from_omx(file_path, omx_path) diff --git a/docs/source/modeling_with_aequilibrae/project_pieces/project_components.rst b/docs/source/modeling_with_aequilibrae/project_pieces/project_components.rst index b48aa61e8..83c52c477 100644 --- a/docs/source/modeling_with_aequilibrae/project_pieces/project_components.rst +++ b/docs/source/modeling_with_aequilibrae/project_pieces/project_components.rst @@ -31,15 +31,6 @@ enables the access to manipulate the 'links' table, and each item in the items t In this section, we'll briefly discuss about the project components without geo-spatial information. -.. testsetup:: * - - >>> from uuid import uuid4 - >>> from aequilibrae.utils.create_example import create_example - -.. testcleanup:: * - - >> project.close() - ``project.about`` ----------------- @@ -48,8 +39,10 @@ edit the existing ones as necessary, but everytime you add or modify a field, yo this information, otherwise it will be lost. .. doctest:: + >>> from aequilibrae import Project - >>> project = create_example(f"/tmp/{uuid4().hex}") + >>> project = Project() + >>> project.open("/tmp/accessing_sfalls_data") >>> project.about.add_info_field("my_new_field") >>> project.about.my_new_field = "add some useful information about the field" @@ -70,6 +63,8 @@ this information, otherwise it will be lost. # it is possible to create one too. >>> project.about.create() + >>> project.close() + .. admonition:: References * :ref:`tables_about` @@ -92,7 +87,8 @@ This class is directly accessed from within the corresponding module one wants t .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}", "nauru") + >>> project = Project() + >>> project.open("/tmp/accessing_nauru_data") # We'll edit the fields in the 'nodes' table >>> node_fields = project.network.nodes.fields @@ -114,6 +110,8 @@ This class is directly accessed from within the corresponding module one wants t >>> node_fields.all_fields() # doctest: +ELLIPSIS ['is_centroid', ..., 'my_new_field'] + >>> project.close() + All field descriptions are kept in the table 'attributes_documentation'. .. admonition:: References @@ -134,7 +132,8 @@ It is possible to access the log file contents, as presented in the next code bl .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}", "nauru") + >>> project = Project() + >>> project.open("/tmp/accessing_nauru_data") >>> project_log = project.log() @@ -146,6 +145,8 @@ It is possible to access the log file contents, as presented in the next code bl # Use this option wiesly once the deletion of data in the log file can't be undone. >>> project_log.clear() + >>> project.close() + .. admonition:: References * :ref:`useful-log-tips` @@ -164,7 +165,8 @@ records in the 'matrices' table. Each item in the 'matrices' table is a ``Matri .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}") + >>> project = Project() + >>> project.open("/tmp/accessing_sfalls_data") >>> matrices = project.matrices @@ -199,6 +201,8 @@ records in the 'matrices' table. Each item in the 'matrices' table is a ``Matri # get an AequilibraE matrix. >>> matrices.get_matrix("demand_aem") # doctest: +SKIP + >>> project.close() + .. admonition:: References * :ref:`matrix_table` @@ -217,7 +221,8 @@ Each item in the 'link_types' table is a ``LinkType`` object. .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}", "coquimbo") + >>> project = Project() + >>> project.open("/tmp/accessing_coquimbo_data") >>> link_types = project.network.link_types @@ -242,8 +247,8 @@ Each item in the 'link_types' table is a ``LinkType`` object. >>> link_types.save() # To check all `LinkTypes` in the project as a dictionary whose keys are the `link_type_id`'s - >>> link_types.all_types() # doctest: +SKIP - {'z': ...} + >>> link_types.all_types() # doctest: +ELLIPSIS + {'z': } # There are two ways to get a LinkType from the 'link_types' table # using the `link_type_id` @@ -252,6 +257,8 @@ Each item in the 'link_types' table is a ``LinkType`` object. # or using the `link_type` >>> get_link = link_types.get_by_name("primary") + >>> project.close() + .. admonition:: References * :ref:`tables_link_types` @@ -270,7 +277,8 @@ Each item in 'modes' table is a ``Mode`` object. .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}", "coquimbo") + >>> project = Project() + >>> project.open("/tmp/accessing_coquimbo_data") >>> modes = project.network.modes @@ -290,7 +298,8 @@ Each item in 'modes' table is a ``Mode`` object. >>> modes.delete("k") # To check all `Modes` in the project as a dictionary whose keys are the `mode_id`'s - >>> modes.all_modes() # doctest: +SKIP + >>> modes.all_modes() # doctest: +ELLIPSIS + {'b': } # There are two ways to get a Mode from the 'modes' table # using the ``mode_id`` @@ -299,6 +308,8 @@ Each item in 'modes' table is a ``Mode`` object. # or using the ``mode_name`` >>> get_mode = modes.get_by_name("car") + >>> project.close() + .. admonition:: References * :ref:`tables_modes` @@ -317,7 +328,8 @@ Each item in the 'periods' table is a ``Period`` object. .. doctest:: - >>> project = create_example(f"/tmp/{uuid4().hex}", "coquimbo") + >>> project = Project() + >>> project.open("/tmp/accessing_coquimbo_data") >>> periods = project.network.periods @@ -335,7 +347,7 @@ Each item in the 'periods' table is a ``Period`` object. >>> select_period.save() # To see all periods data as a Pandas' DataFrame - >>> periods.data # doctest: +SKIP + >>> all_periods = periods.data # To add a new period >>> new_period = periods.new_period(2, 21600, 43200, "6AM to noon") @@ -351,6 +363,8 @@ Each item in the 'periods' table is a ``Period`` object. # of this example, we'll save the addition of a new period to our table right away >>> periods.save() + >>> project.close() + .. admonition:: References * :ref:`tables_period` diff --git a/docs/source/modeling_with_aequilibrae/route_choice/index.rst b/docs/source/modeling_with_aequilibrae/route_choice/index.rst index 4eee3487b..87fb8a50b 100644 --- a/docs/source/modeling_with_aequilibrae/route_choice/index.rst +++ b/docs/source/modeling_with_aequilibrae/route_choice/index.rst @@ -80,8 +80,8 @@ be presented at the ATRF 2024 [1]_ [3]_ [4]_. .. [2] Rieser-Schüssler, N., Balmer, M., & Axhausen, K. W. (2012). Route choice sets for very high-resolution data. Transportmetrica A: Transport Science, 9(9), 825–845. DOI: https://doi.org/10.1080/18128602.2012.671383 -.. [3] Camargo, P. V. de, and R. Imai. Map-Matching Large Streams of Vehicle GPS Data into Bespoke Networks (Submitted). +.. [3] Camargo, P. V. de, and R. Imai. Map-Matching Large Streams of Vehicle GPS Data into Bespoke Networks. Presented at the ATRF, Melbourne, 2024. .. [4] Moss, J., P. V. de Camargo, C. de Freitas, and R. Imai. High-Performance Route Choice Set Generation on - Large Networks (Submitted). Presented at the ATRF, Melbourne, 2024. + Large Networks. Presented at the ATRF, Melbourne, 2024. diff --git a/docs/source/useful_information/support.rst b/docs/source/useful_information/support.rst index 05cd46fb5..a0bcbd935 100644 --- a/docs/source/useful_information/support.rst +++ b/docs/source/useful_information/support.rst @@ -10,6 +10,17 @@ Support AequilibraE is developed by a small but dedicated team of professionals with limited funding. +Paid support +~~~~~~~~~~~~ + +Paid support for AequilibraE is offered by Outer Loop Consulting, an Australia-based consulting company, +with support available in English, Portuguese, German & Spanish. + +All support is offered in prepaid packages of a minimum of 10h of consulting by phone, e-mail or Microsoft Teams +at a fixed rate of USD 150/h. + +To acquire a paid support package for AequilibraE, please e-mail aequilibrae@outerloop.io + Free support ~~~~~~~~~~~~ @@ -22,17 +33,6 @@ already asked in the past, with the first option being the most often used as of Please note that all questions and answers in both forums are public. -Paid support -~~~~~~~~~~~~ - -Paid support for AequilibraE is offered by Outer Loop Consulting, an Australia-based consulting company, -with support available in English, Portuguese, German & Spanish. - -All support is offered in prepaid packages of a minimum of 10h of consulting by phone, e-mail or Microsoft Teams -at a fixed rate of USD 150/h. - -To acquire a paid support package for AequilibraE, please e-mail aequilibrae@outerloop.io - .. _sponsors: Sponsors diff --git a/docs/table_documentation.py b/docs/table_documentation.py index c16dbef5d..5a27807b5 100644 --- a/docs/table_documentation.py +++ b/docs/table_documentation.py @@ -23,12 +23,13 @@ def __init__(self, component: str, tgt_fldr: str): self.proj.new(self.proj_path) Transit(self.proj) - folder = "network" if component == "project_database" else "transit" + self.__folder = "network" if component == "project_database" else "transit" self.stub = "data_model" # Get the appropriate data for the database we are documenting - self.conn = database_connection(db_type=folder, project_path=self.proj_path) + self.conn = database_connection(db_type=self.__folder, project_path=self.proj_path) self.path = join( - *Path(realpath(__file__)).parts[:-1], f"../aequilibrae/project/database_specification/{folder}/tables" + *Path(realpath(__file__)).parts[:-1], + f"../aequilibrae/project/database_specification/{self.__folder}/tables", ) self.doc_path = str(Path(realpath(__file__)).parent / "source" / "modeling_with_aequilibrae" / tgt_fldr) @@ -44,9 +45,12 @@ def create(self): for table_name in all_tables: descr = self.conn.execute(f"pragma table_info({table_name})").fetchall() + # Data model reference + reference = f".. _{table_name}_{self.__folder}_data_model:\n" + # Title of the page title = f'**{table_name.replace("_", " ")}** table structure' - txt = [title, "=" * len(title), ""] + txt = [reference, title, "=" * len(title), ""] docstrings = self.__get_docstrings(table_name) sql_code = self.__get_sql_code(table_name)