{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n# Geneva Heat Demand\nIn this tutorial, we will learn how to display Geneva heat demand data in 3D.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We first import geneva's 3D buildings datasets\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from ipybuilding.datasets import geneva\n\nbase_path, facade_path, roof_path = geneva.load_data()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Then load them with geopandas\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import geopandas\n\nbases = geopandas.read_file(base_path)\nfacade = geopandas.read_file(facade_path)\ntoits = geopandas.read_file(roof_path)\n\nbases.columns = [s.lower() for s in bases.columns]\nfacade.columns = [s.lower() for s in facade.columns]\ntoits.columns = [s.lower() for s in toits.columns]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Next step is to load Geneva's heat demand data\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import pandas as pd\n\nDATA_URL = \"https://raw.githubusercontent.com/vferat/ipybuilding/main/tutorials/Geneva/SCANE_INDICE_DERNIER.csv\"\nheat_demand = pd.read_csv(DATA_URL, sep=';')\nheat_demand.columns = [s.lower() for s in heat_demand.columns]\nheat_demand.egid = heat_demand.egid.astype(int)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We then merge both datasets based on bulding's EGID\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "bases = bases.merge(heat_demand, on='egid')\nfacade = facade.merge(heat_demand, on='egid')\ntoits = toits.merge(heat_demand, on='egid')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We create a new column to store buidling colors based on heat demand indice:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import matplotlib as mpl\n\nnorm = mpl.colors.Normalize(vmin=1, vmax=toits.indice.quantile(0.95))\ncmap = mpl.cm.get_cmap('RdYlGn_r')\n\ncmap_val = cmap(norm(toits.indice)) \nbases['color'] = (cmap_val* 255).astype(int).tolist()\n\ncmap_val = cmap(norm(toits.indice)) \ntoits['color'] = (cmap_val* 255).astype(int).tolist()\n\ncmap_val = cmap(norm(facade.indice)) \nfacade['color'] = (cmap_val* 255).astype(int).tolist()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Only display a subset of building based on initial view\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "def filtered_buildings_geom(bbox):\n    return (bases.cx[bbox[0]: bbox[2], bbox[1]:bbox[3]],\n            facade.cx[bbox[0]: bbox[2], bbox[1]:bbox[3]],\n            toits.cx[bbox[0]: bbox[2], bbox[1]:bbox[3]])\n\nstart_point = (6.1402,46.208742)\ndelta = 0.001\nbbox =  (start_point[0] - delta, start_point[1]-delta, start_point[0] + delta, start_point[1]+delta) \n\nf_base, f_face, f_toit = filtered_buildings_geom(bbox)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "We can now plot our data thanks to pydeck\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import os\nimport pydeck\n\nMAPBOX_API_KEY = os.environ[\"MAPBOX_API_KEY\"]\n\ncoords = f_base.centroid.map(lambda p: [p.x, p.y])\nINITIAL_VIEW_STATE = pydeck.data_utils.compute_view(coords.values)\nINITIAL_VIEW_STATE.zoom = 16\nINITIAL_VIEW_STATE.max_zoom = 16\n\n# AWS Open Data Terrain Tiles\nTERRAIN_IMAGE = \"https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png\"\n\n# Define how to parse elevation tiles\nELEVATION_DECODER = {\"rScaler\": 256, \"gScaler\": 1, \"bScaler\": 1 / 256, \"offset\": -32768}\nSURFACE_IMAGE = f\"https://api.mapbox.com/v4/mapbox.satellite/{{z}}/{{x}}/{{y}}@2x.png?access_token={MAPBOX_API_KEY}\"\n\n\nterrain_layer = pydeck.Layer(\n    \"TerrainLayer\", elevation_decoder=ELEVATION_DECODER, texture=SURFACE_IMAGE, elevation_data=TERRAIN_IMAGE,\n    # light_settings=lights\n\n)\n\n\nbases_layer = pydeck.Layer('GeoJsonLayer', \n                           data=f_base, get_fill_color=[255,100,255], pickable=True\n                          )\nfacade_layer = pydeck.Layer('GeoJsonLayer', \n                            data=f_face, \n                            get_fill_color='color', \n                            line_width_scale=0.1,\n                            pickable=True,\n                            filled=True,\n                            wireframe=True,\n                           )\ntoits_layer = pydeck.Layer('GeoJsonLayer', \n                           data=f_toit, \n                           get_fill_color='color', \n                           pickable=True,\n                           stroked=False,\n                           filled=True,\n                           wireframe=True,\n                      )\n\nr = pydeck.Deck(\n    layers=[\n        terrain_layer,\n        bases_layer, \n        facade_layer, \n        toits_layer\n    ],\n    initial_view_state=INITIAL_VIEW_STATE,\n    map_style='satellite',\n    tooltip={\n        'text': 'IDC: {indice} MJ/m2\u00b7a'\n    }\n)\nr.to_html()\n\n#  .. image:: download.png"
      ]
    }
  ],
  "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.8.6"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}