{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Create centroid connectors\n\nWe use Coquimbo example to show how we can create centroids and connect them to\nthe existing network efficiently.\n\nWe use Folium to visualize the resulting network.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        ".. seealso::\n    Several functions, methods, classes and modules are used in this example:\n\n    * :func:`aequilibrae.project.Zoning`\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Imports\nimport folium\nfrom uuid import uuid4\nfrom tempfile import gettempdir\nfrom os.path import join\n\nfrom aequilibrae.utils.create_example import create_example"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# Let's create an arbitrary project folder\nfldr = join(gettempdir(), uuid4().hex)\n\n# And create our Coquimbo project\nproject = create_example(fldr, \"coquimbo\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "As Coquimbo already has centroids and centroid connectors, we should remove\nthem for the sake of this example.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "with project.db_connection as conn:\n    conn.execute(\"DELETE FROM links WHERE name LIKE 'centroid connector%'\")\n    conn.execute(\"DELETE FROM nodes WHERE is_centroid=1;\")\n    conn.commit()\n\n    centroids = conn.execute(\"SELECT COUNT(node_id) FROM nodes WHERE is_centroid=1;\").fetchone()[0]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "If you want to make sure your deletion process has worked, you can check the\nnumber of centroids!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print(\"Current number of centroids: \", centroids)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "zoning = project.zoning"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "This centroid connector creation is effective because it uses the existing\nzone layer to create the centroids and connect them to the existing network.\n\nFirst thing to do is add the centroids to all zones that doesn't have a centroid\nat the geographic centroid of the zone, using ``add_centroids()``, which has a\n``robust`` argument set to ``True`` as default. This means that it will automatically\nmove the centroid location around to avoid conflicts with existing nodes.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "zoning.add_centroids()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Let's connect the mode ``c``, that stands for car.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "mode = \"c\""
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Then we connect the centroid to the network, by selecting the desired mode,\nthe number of connectors, the allowed link types for connection, and if one\nwants to allow the connection to links in other zones. By setting ``limit_to_zone=False``,\nwe allow the centroid of one zone to be connected to a link outside the zone itself.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "zoning.connect_mode(mode_id=mode, connectors=1, limit_to_zone=False)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "It is possible to repeat the process above for a different mode, with different\nlink type, number of connectors and connection allowance, as desired.\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally, let's plot our data!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "links = project.network.links.data\ncentroids = links[links[\"link_type\"] == \"centroid_connector\"]\nlinks = links[links[\"link_type\"] != \"centroid_connector\"]\n\nnodes = project.network.nodes.data\nnodes = nodes[nodes[\"is_centroid\"] == 1]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "map = folium.Map(location=[-29.9568, -71.3456], zoom_start=14)\nzoning.data.explore(m=map, color=\"blue\", style_kwds={\"fillOpacity\": 0.05}, name=\"zones\")\ncentroids.explore(m=map, color=\"black\", style_kwds={\"weight\": 2.5}, name=\"centroid_connector\")\nlinks.explore(m=map, color=\"gray\", style_kwds={\"weight\": 1}, name=\"links\")\nnodes.explore(m=map, color=\"red\", style_kwds={\"radius\": 3, \"fillOpacity\": 1.0}, name=\"centroid\")\n\nfolium.LayerControl().add_to(map)\n\nmap"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "project.close()"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.10.18"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}