From 33ec9d087940340b74043b5999ff872e7de4db4e Mon Sep 17 00:00:00 2001 From: Chellison Date: Sat, 25 Apr 2026 15:48:55 -0400 Subject: [PATCH] add lts as pre-commuted safety score --- .../LTS_preprocessing-checkpoint.ipynb | 9524 +++++++++++++++++ lts/LTS.xlsx | Bin 0 -> 22531 bytes lts/LTS_preprocessing.ipynb | 9524 +++++++++++++++++ lts/readme.md | 15 + mvp_map/data_processing.ipynb | 2818 ----- .../data_processing_bespokeRidescore.ipynb | 2828 +++++ mvp_map/index.html | 72 +- mvp_map/readme.md | 17 +- 8 files changed, 21959 insertions(+), 2839 deletions(-) create mode 100644 lts/.ipynb_checkpoints/LTS_preprocessing-checkpoint.ipynb create mode 100644 lts/LTS.xlsx create mode 100644 lts/LTS_preprocessing.ipynb create mode 100644 lts/readme.md delete mode 100644 mvp_map/data_processing.ipynb create mode 100644 mvp_map/data_processing_bespokeRidescore.ipynb diff --git a/lts/.ipynb_checkpoints/LTS_preprocessing-checkpoint.ipynb b/lts/.ipynb_checkpoints/LTS_preprocessing-checkpoint.ipynb new file mode 100644 index 0000000..d413a52 --- /dev/null +++ b/lts/.ipynb_checkpoints/LTS_preprocessing-checkpoint.ipynb @@ -0,0 +1,9524 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f98adb95-d4bf-4945-9e09-0d6b5bc873b2", + "metadata": {}, + "source": [ + "# Implement LTS (2022 version)\n", + "\n", + "This notebook implements the [Level of Traffic Stress](https://peterfurth.sites.northeastern.edu/2014/05/21/criteria-for-level-of-traffic-stress/) model. Specifically, the [2022 edition](https://bpb-us-e1.wpmucdn.com/sites.northeastern.edu/dist/e/618/files/2014/05/LTS-Tables-v2.2.pdf) though there is more background in the [original model](https://peterfurth.sites.northeastern.edu/level-of-traffic-stress/).\n", + "\n", + "In short, this quantifies how stressful or comfortable a road is to bike on.\n", + "* Level 1: Cyclists are not in contact with traffic (except for slow, low volume traffice); comfortable for all level of cycling abilities (including children).\n", + "* Level 2: Cyclists have their own space and intersections are easy to navigate; comfortable for adult cyclists.\n", + "* Level 3: Cyclists interact with some moderate/multi-lane traffic or close to higher-speed traffic; acceptable for 'enthused and confident' cyclists.\n", + "* Level 4: Cyclists interact with or are near high-speed traffic; acceptable for 'strong and fearless' cyclists.\n", + "\n", + "The first step was find correspondence between the descriptions and the available [DC road data](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about). This is summarized in the table below.\n", + "\n", + "| [Method](https://bpb-us-e1.wpmucdn.com/sites.northeastern.edu/dist/e/618/files/2014/05/LTS-Tables-v2.2.pdf) | [Data](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) |\n", + "| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n", + "| Bike lane type (bikes in mixed traffic) | TOTALBIKELANES (if it’s zero, then it’s mixed traffic) |\n", + "| Bike lane type (conventional; buffered considered conventional with buffer width considered part of lane width; also mentions advisory and shoulder) | BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED |\n", + "| Bike lane (separate from traffic) | BIKELANE_DUAL_PROTECTED, BIKELANE_PROTECTED |\n", + "| Bike lane (conventional, advisory, shoulder) adjacency to parking lane | BIKELANE_PARKINGLANE_ADJACENT |\n", + "| Bike lane width | TOTALBIKELANEWIDTH (no direct way of getting buffer width so subtract all individual elements from total cross width, assuming the leftover difference is the bike lane buffer) divide by TOTALBIKELANES (substitute for not having width-per-lane) |\n", + "| Is bike lane frequently blocked? | No equivalent (might be worth surveying users) |\n", + "| Is bike lane next to curb, road edge, or discontinuous? | No equivalent |\n", + "| Centerline | No direct comparison (using DOUBLEYELLOW_LINE and TOTALRAISEDBUFFERS) |\n", + "| Number of trave lanes in each direction (not always clear what to do if there is, say, 1 lane in one direction and 2 in the other) | TOTALTRAVELLANES, TOTALTRAVELLANESINBOUND, TOTALTRAVELLANESOUTBOUND (other lane types include: TOTALTRAVELLANESBIDIRECTIONAL and TOTALTRAVELLANESREVERSIBLE) |\n", + "| Road width | TOTALCROSSSECTIONWIDTH |\n", + "| Parking lane (none, one side, both sides) | TOTALPARKINGLANES (doesn’t specify which side of road but number of lanes is probably a fairly good proxy) |\n", + "| ADT (average daily traffic) | AADT |\n", + "| Prevailing traffic speed | Closest we can get is speedlimit (SPEEDLIMITS_OB) |\n", + "\n", + "\n", + "The tables have been translated into 'LTS.xlsx'" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "5750ddcb-5417-467c-99f9-1a5b180ed128", + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import geopandas as gpd\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "id": "103590cd-86d3-489d-b94f-5fe89dadbc60", + "metadata": {}, + "source": [ + "## Get road data from DC website" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "9e8a4862-24db-4f46-a858-695780d5f643", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "trying website\n", + "\n", + "https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_COMBINATIONAADT_COMBINATION_YEARAADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindex
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...118.02020.0254.02020.011None419502700
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaNNaNNaNNaN11None419502801
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...32.02020.0435.02020.011None419502902
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...312.02020.01443.02020.011None419503003
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaNNaNNaNNaN11YES419503104
..................................................................
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...111.02020.0736.02020.011None4211500013833
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaNNaNNaNNaN11None4211501013834
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaNNaNNaNNaN11None4211502013835
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaNNaNNaNNaN11None4211503013836
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaNNaNNaNNaN1073None4211504013837
\n", + "

13838 rows × 102 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_COMBINATION \\\n", + "0 0 37 ... 118.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 32.0 \n", + "3 1 40 ... 312.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13833 0 42 ... 111.0 \n", + "13834 0 20 ... NaN \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " AADT_COMBINATION_YEAR AADT_SINGLE_UNIT AADT_SINGLE_UNIT_YEAR \\\n", + "0 2020.0 254.0 2020.0 \n", + "1 NaN NaN NaN \n", + "2 2020.0 435.0 2020.0 \n", + "3 2020.0 1443.0 2020.0 \n", + "4 NaN NaN NaN \n", + "... ... ... ... \n", + "13833 2020.0 736.0 2020.0 \n", + "13834 NaN NaN NaN \n", + "13835 NaN NaN NaN \n", + "13836 NaN NaN NaN \n", + "13837 NaN NaN NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "0 1 1 None \n", + "1 1 1 None \n", + "2 1 1 None \n", + "3 1 1 None \n", + "4 1 1 YES \n", + "... ... ... ... \n", + "13833 1 1 None \n", + "13834 1 1 None \n", + "13835 1 1 None \n", + "13836 1 1 None \n", + "13837 10 73 None \n", + "\n", + " OBJECTID SHAPELEN index \n", + "0 4195027 0 0 \n", + "1 4195028 0 1 \n", + "2 4195029 0 2 \n", + "3 4195030 0 3 \n", + "4 4195031 0 4 \n", + "... ... ... ... \n", + "13833 4211500 0 13833 \n", + "13834 4211501 0 13834 \n", + "13835 4211502 0 13835 \n", + "13836 4211503 0 13836 \n", + "13837 4211504 0 13837 \n", + "\n", + "[13838 rows x 102 columns]" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 2) Get Roadblock data from website\n", + "CRS = 'EPSG:4326'\n", + "def try_fetch_dc_roads():\n", + " url = \"https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\"\n", + " try:\n", + " print('trying website')\n", + " r = requests.get(url, timeout=60)\n", + " r.raise_for_status()\n", + " print(r)\n", + " print(url)\n", + " if r.ok:\n", + " gj = r.json()\n", + " roads = gpd.GeoDataFrame.from_features(gj[\"features\"], crs=CRS)\n", + " return roads\n", + " except Exception as error:\n", + " print('Error reading road data from dc gov website')\n", + "\n", + "roads = try_fetch_dc_roads()\n", + "roads['index'] = roads.index\n", + "roads = roads.drop(columns='geometry')\n", + "roads.to_csv('Roadway_Block_downloaded.csv')\n", + "roads" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "2e9d238d-7ca3-4133-818f-428346708591", + "metadata": {}, + "outputs": [], + "source": [ + "# read in file if it's already saved\n", + "#roads = pd.read_csv('Roadway_Block_downloaded.csv')" + ] + }, + { + "cell_type": "markdown", + "id": "46c6e731-6983-480c-8d68-5fe45dc3646b", + "metadata": {}, + "source": [ + "## Make additional columns (PERBIKELANEWIDTH, ADJPLREACH)\n", + "\n", + "* PERBIKELANEWIDTH: Model needs bike lane with to include buffer width but there is no column for this so test if width of convetional lanes is less than buffered lanes. It is so, so find un-accounted for width of roads with buffered bike lanes and add that to bike lane width (so just divide by number of bike lanes).\n", + "* ADJPRLREACH: adjacent to parking lane reach (includes bike width and parking lane width), should be per-lane (so just divide by number of bike lanes)" + ] + }, + { + "cell_type": "markdown", + "id": "88c2790a-4ccf-4c55-8409-a8fbcff44439", + "metadata": {}, + "source": [ + "### PERBIKELANEWIDTH" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "58ef4810-4ea6-4267-8c8a-dd80e49fe09d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number of buffered lanes: 185\n", + "number of just buffered lanes: 119\n", + "mean width: 5.436974789915967\n", + "avg_width\n", + "5.0 68\n", + "6.0 24\n", + "8.0 10\n", + "4.0 7\n", + "7.0 3\n", + "4.5 3\n", + "6.5 2\n", + "2.0 1\n", + "5.5 1\n", + "Name: count, dtype: int64\n", + "leftover_width\n", + "3 21\n", + "4 19\n", + "7 18\n", + "2 14\n", + "11 9\n", + "5 6\n", + "6 5\n", + "16 4\n", + "13 3\n", + "21 3\n", + "12 2\n", + "14 2\n", + "9 2\n", + "10 2\n", + "18 2\n", + "17 2\n", + "8 2\n", + "19 1\n", + "27 1\n", + "15 1\n", + "Name: count, dtype: int64\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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SZOKs1tSmup0+PDholdk+vTpp/s2AMAQUVbPx5e+9KWYO3duMSySTp998MEH44knnojHH3+8GFpZsmRJrFy5MiZPnlws6ec0byONAQEAlB0+XnnllfjEJz4RL7/8cpx99tnFBcdS8EjjRsmyZcvi0KFDsXjx4ti/f39MmzYtNm3aFKNHj1ZtAKD88PHAAw+87uOp9yOdvZIWAIDe+G4XACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIQPACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIbnfTsAyjWlaWN0HK0r+3Uv3n2tYjMg6fkAALISPgCArIQPACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIQPACAr4QMAGLjh46677oorrrgiRo8eHRdccEHceOONsXPnzm7PKZVK0dTUFBMmTIiRI0fGrFmzYseOHf293QBALYSPLVu2xK233hpPP/10bN68OV577bWYM2dOHDx4sOs5q1atitWrV8fatWujubk5xo0bF7Nnz462trZKbD8AMMgML+fJjz/+eLf769atK3pAnnnmmfjABz5Q9HqsWbMmGhsbY968ecVz1q9fH2PHjo0NGzbEokWL+nfrAYChHT56OnDgQHF7zjnnFLe7du2Kffv2Fb0hnerr62PmzJmxdevWXsNHR0dHsXRqbW0tbo8cOVIs/amzvf5udyhSK7Wq5H5VP6x02m3UgtOtVy3Wqpb+zQOtVuW0V1dK3RV9kF52ww03xP79++Opp54q1qWAMWPGjNi7d28x56PTwoULY/fu3bFx48YT2knzQ1asWHHC+tRTMmrUqL5sGgCQWXt7e8yfP7/omBgzZkxlej4++9nPxs9//vP40Y9+dMJjdXV1JwSVnus6LV++PJYuXdqt56OhoaHoPTnVxvcllaW5KmkOyogRI/q17aFGrdSqkvvVl7cNi45jvX8mnMpzTddErTjdetVirXy+V69WnSMXb0Sfwsdtt90WjzzySDz55JMxceLErvVpcmmShl7Gjx/ftb6lpaWY99GbNCyTlp5SQSoVECrZ9lCjVmpVCekXacfRvoWPWjx2+1qv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print('number of buffered lanes: '+str(len(roads[~roads['BIKELANE_BUFFERED'].isna()])))\n", + "print('number of just buffered lanes: '+str(len(roads[(~roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())])))\n", + "roads_buffered = roads[(~roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())]\n", + "roads_buffered = roads_buffered[['BIKELANE_CONTRAFLOW', 'BIKELANE_CONVENTIONAL', 'BIKELANE_DUAL_PROTECTED', 'BIKELANE_PROTECTED', 'BIKELANE_BUFFERED', 'TOTALBIKELANES', 'TOTALBIKELANEWIDTH', 'TOTALTRAVELLANEWIDTH', 'TOTALCROSSSECTIONWIDTH', 'TOTALPARKINGLANEWIDTH', 'TOTALRAISEDBUFFERWIDTH']]\n", + "roads_buffered['avg_width'] = roads_buffered['TOTALBIKELANEWIDTH']/roads_buffered['TOTALBIKELANES']\n", + "roads_buffered['leftover_width'] = roads_buffered['TOTALCROSSSECTIONWIDTH']-roads_buffered['TOTALTRAVELLANEWIDTH']-roads_buffered['TOTALPARKINGLANEWIDTH']-roads_buffered['TOTALRAISEDBUFFERWIDTH']-roads_buffered['TOTALBIKELANEWIDTH']\n", + "print('mean width: '+str(roads_buffered['avg_width'].mean()))\n", + "print(roads_buffered['avg_width'].value_counts())\n", + "print(roads_buffered['leftover_width'].value_counts())\n", + "roads_buffered['avg_width'].hist(bins = 30)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "4d4456bd-4328-4119-b1a6-3f46fda52183", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "roads_buffered['leftover_width'].hist(bins = 30)" + ] + }, + { + "cell_type": "code", + "execution_count": 59, + "id": "fa3cbda3-2434-4328-b3c5-19700ad9e132", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number of conventional lanes: 1046\n", + "number of just convential lanes: 900\n", + "mean width: 5.038703703703703\n", + "avg_width\n", + "5.000000 827\n", + "6.000000 35\n", + "4.000000 21\n", + "5.500000 6\n", + "4.500000 3\n", + "7.500000 2\n", + "3.000000 2\n", + "4.333333 1\n", + "11.000000 1\n", + "16.000000 1\n", + "7.000000 1\n", + "Name: count, dtype: int64\n", + "leftover_width\n", + "0 463\n", + "1 406\n", + "3 5\n", + "8 4\n", + "2 4\n", + "5 4\n", + "6 4\n", + "10 3\n", + "4 2\n", + "9 2\n", + "16 1\n", + "12 1\n", + "14 1\n", + "Name: count, dtype: int64\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print('number of conventional lanes: '+str(len(roads[~roads['BIKELANE_CONVENTIONAL'].isna()])))\n", + "print('number of just convential lanes: '+str(len(roads[(roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (~roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())])))\n", + "roads_conv = roads[(roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (~roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())]\n", + "roads_conv = roads_conv[['BIKELANE_CONTRAFLOW', 'BIKELANE_CONVENTIONAL', 'BIKELANE_DUAL_PROTECTED', 'BIKELANE_PROTECTED', 'BIKELANE_BUFFERED', 'TOTALBIKELANES', 'TOTALBIKELANEWIDTH', 'TOTALTRAVELLANEWIDTH', 'TOTALCROSSSECTIONWIDTH', 'TOTALPARKINGLANEWIDTH', 'TOTALRAISEDBUFFERWIDTH']]\n", + "roads_conv['avg_width'] = roads_conv['TOTALBIKELANEWIDTH']/roads_conv['TOTALBIKELANES']\n", + "roads_conv['leftover_width'] = roads_conv['TOTALCROSSSECTIONWIDTH']-roads_conv['TOTALTRAVELLANEWIDTH']-roads_conv['TOTALPARKINGLANEWIDTH']-roads_conv['TOTALRAISEDBUFFERWIDTH']-roads_conv['TOTALBIKELANEWIDTH']\n", + "print('mean width: '+str(roads_conv['avg_width'].mean()))\n", + "print(roads_conv['avg_width'].value_counts())\n", + "print(roads_conv['leftover_width'].value_counts())\n", + "roads_conv['avg_width'].hist(bins = 20)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "ccf08baa-02d4-4629-83df-91741e3bbc30", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "roads_conv['leftover_width'].hist(bins = 20)" + ] + }, + { + "cell_type": "markdown", + "id": "5e63aaec-1b1a-4450-be98-f07b240a316a", + "metadata": {}, + "source": [ + "Looks like un-accounted for space in cross section is likely buffer. So let's create a 'total bikelane width' column. It if there is a buffered bike lane, it will include the unaccounted for space. If there isn't, it'll just be the total bikelane width. Also create a per-lane width as well. (just divide total width by number of bike lanes)\n", + "\n", + "This will not account for different bike lane types." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "1b681f64-2438-4391-a998-47076380ecb2", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\2165435094.py:8: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[8.5 5. 5. ... 5. 9. 5. ]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.\n", + " roads.loc[lane_ind, 'PERBIKELANEWIDTH'] = roads['TOTALBIKELANEWIDTH_WEXTRA'][lane_ind]/roads['TOTALBIKELANES'][lane_ind]\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...254.02020.011None41950270000.0
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaNNaN11None41950280100.0
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...435.02020.011None41950290200.0
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...1443.02020.011None41950300300.0
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaNNaN11YES41950310400.0
..................................................................
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...736.02020.011None421150001383300.0
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaNNaN11None4211501013834105.0
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaNNaN11None421150201383500.0
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaNNaN11None421150301383600.0
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaNNaN1073None421150401383700.0
\n", + "

13838 rows × 104 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT \\\n", + "0 0 37 ... 254.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 435.0 \n", + "3 1 40 ... 1443.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13833 0 42 ... 736.0 \n", + "13834 0 20 ... NaN \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " AADT_SINGLE_UNIT_YEAR DC_MAINTENANCE_OPERATIONS \\\n", + "0 2020.0 1 \n", + "1 NaN 1 \n", + "2 2020.0 1 \n", + "3 2020.0 1 \n", + "4 NaN 1 \n", + "... ... ... \n", + "13833 2020.0 1 \n", + "13834 NaN 1 \n", + "13835 NaN 1 \n", + "13836 NaN 1 \n", + "13837 NaN 10 \n", + "\n", + " MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION OBJECTID SHAPELEN index \\\n", + "0 1 None 4195027 0 0 \n", + "1 1 None 4195028 0 1 \n", + "2 1 None 4195029 0 2 \n", + "3 1 None 4195030 0 3 \n", + "4 1 YES 4195031 0 4 \n", + "... ... ... ... ... ... \n", + "13833 1 None 4211500 0 13833 \n", + "13834 1 None 4211501 0 13834 \n", + "13835 1 None 4211502 0 13835 \n", + "13836 1 None 4211503 0 13836 \n", + "13837 73 None 4211504 0 13837 \n", + "\n", + " TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "0 0 0.0 \n", + "1 0 0.0 \n", + "2 0 0.0 \n", + "3 0 0.0 \n", + "4 0 0.0 \n", + "... ... ... \n", + "13833 0 0.0 \n", + "13834 10 5.0 \n", + "13835 0 0.0 \n", + "13836 0 0.0 \n", + "13837 0 0.0 \n", + "\n", + "[13838 rows x 104 columns]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads['TOTALBIKELANEWIDTH_WEXTRA'] = 0\n", + "roads['PERBIKELANEWIDTH'] = 0\n", + "buffered_ind = ~roads['BIKELANE_BUFFERED'].isna()\n", + "roads.loc[buffered_ind, 'TOTALBIKELANEWIDTH_WEXTRA'] = roads['TOTALCROSSSECTIONWIDTH'][buffered_ind]-roads['TOTALTRAVELLANEWIDTH'][buffered_ind]-roads['TOTALPARKINGLANEWIDTH']-roads['TOTALRAISEDBUFFERWIDTH']\n", + "lane_not_buffered_ind = roads['BIKELANE_BUFFERED'].isna() & ~roads['BIKELANE_CONVENTIONAL'].isna()\n", + "roads.loc[lane_not_buffered_ind, 'TOTALBIKELANEWIDTH_WEXTRA'] = roads['TOTALBIKELANEWIDTH'][lane_not_buffered_ind]\n", + "lane_ind = buffered_ind | lane_not_buffered_ind\n", + "roads.loc[lane_ind, 'PERBIKELANEWIDTH'] = roads['TOTALBIKELANEWIDTH_WEXTRA'][lane_ind]/roads['TOTALBIKELANES'][lane_ind]\n", + "roads" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "ad2d73b2-2d10-4802-af3a-1d89e8797594", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TOTALBIKELANESBIKELANE_CONVENTIONALBIKELANE_BUFFEREDTOTALBIKELANEWIDTHTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
222NoneBD10178.5
1352IBOB102010.0
1361NoneOB599.0
1951NoneIB699.0
2691NoneOB51717.0
.....................
136271NoneOB81111.0
137002OBIB10147.0
137592OBIB10126.0
137951NoneOB81111.0
138322NoneIB10189.0
\n", + "

185 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " TOTALBIKELANES BIKELANE_CONVENTIONAL BIKELANE_BUFFERED \\\n", + "22 2 None BD \n", + "135 2 IB OB \n", + "136 1 None OB \n", + "195 1 None IB \n", + "269 1 None OB \n", + "... ... ... ... \n", + "13627 1 None OB \n", + "13700 2 OB IB \n", + "13759 2 OB IB \n", + "13795 1 None OB \n", + "13832 2 None IB \n", + "\n", + " TOTALBIKELANEWIDTH TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "22 10 17 8.5 \n", + "135 10 20 10.0 \n", + "136 5 9 9.0 \n", + "195 6 9 9.0 \n", + "269 5 17 17.0 \n", + "... ... ... ... \n", + "13627 8 11 11.0 \n", + "13700 10 14 7.0 \n", + "13759 10 12 6.0 \n", + "13795 8 11 11.0 \n", + "13832 10 18 9.0 \n", + "\n", + "[185 rows x 6 columns]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads[buffered_ind][['TOTALBIKELANES','BIKELANE_CONVENTIONAL','BIKELANE_BUFFERED', 'TOTALBIKELANEWIDTH', 'TOTALBIKELANEWIDTH_WEXTRA', 'PERBIKELANEWIDTH']]" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "6c458ecb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TOTALBIKELANESBIKELANE_CONVENTIONALBIKELANE_BUFFEREDTOTALBIKELANEWIDTHTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
241OBNone555.0
311OBNone555.0
431OBNone555.0
582BDNone10105.0
641IBNone555.0
.....................
137731IBNone555.0
137802BDNone10105.0
137872IBNone10105.0
138112BDNone10105.0
138342BDNone10105.0
\n", + "

1046 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " TOTALBIKELANES BIKELANE_CONVENTIONAL BIKELANE_BUFFERED \\\n", + "24 1 OB None \n", + "31 1 OB None \n", + "43 1 OB None \n", + "58 2 BD None \n", + "64 1 IB None \n", + "... ... ... ... \n", + "13773 1 IB None \n", + "13780 2 BD None \n", + "13787 2 IB None \n", + "13811 2 BD None \n", + "13834 2 BD None \n", + "\n", + " TOTALBIKELANEWIDTH TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "24 5 5 5.0 \n", + "31 5 5 5.0 \n", + "43 5 5 5.0 \n", + "58 10 10 5.0 \n", + "64 5 5 5.0 \n", + "... ... ... ... \n", + "13773 5 5 5.0 \n", + "13780 10 10 5.0 \n", + "13787 10 10 5.0 \n", + "13811 10 10 5.0 \n", + "13834 10 10 5.0 \n", + "\n", + "[1046 rows x 6 columns]" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads[~roads['BIKELANE_CONVENTIONAL'].isna()][['TOTALBIKELANES','BIKELANE_CONVENTIONAL','BIKELANE_BUFFERED', 'TOTALBIKELANEWIDTH', 'TOTALBIKELANEWIDTH_WEXTRA', 'PERBIKELANEWIDTH']]" + ] + }, + { + "cell_type": "markdown", + "id": "30057dea-0cc1-43d6-ab66-b6b2c3df3a8e", + "metadata": {}, + "source": [ + "### ADJPRLREACH" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "1e593f5f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
24110008026026.1362306210.0161138TH ST NW17028022eb2ddc14b56a7d5e090c8996112010...NaN11YES419505102455.012.5
3111001202764.513489872.43902612TH ST NW1a0c7260c3824e5d98a8272a0dea4719722020...NaN11None419505803155.014.0
4311064412769.510315792.968201NEW MEXICO AVE NW15cce0fd3e2d6d45f5b7bbdeac883f3a022020...2020.011None419507004355.013.0
58110007022102.7517092221.9924327TH ST NW1186de2ca1ec920117b3a3c3efed0380f22022...2020.011None4195085058105.013.0
64110338621641.0141601702.536743EUCLID ST NW12f7e6a2a12583aecba70dc3e18550bf312010...NaN11None419509106455.012.5
..................................................................
1375913034462154.392395225.167496EAST CAPITOL ST SE16f386fee838ed54d564cf493c0808a8b22020...NaN11None4211426013759126.014.0
1377313001402125.595001210.84429914TH ST SE151cbaeebbf932bd5a35ae70d28dc18201208...NaN11None421144001377355.013.0
1378013031332481.594086610.044189E ST SE12d375e469680fbc169c6e912f9fba3a022020...NaN11None4211447013780105.013.0
13811130001021383.7203371480.8403321ST ST SE1fb2d00801282fe317232b851a2aa253242044...NaN11None4211478013811105.013.0
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaN11None4211501013834105.014.0
\n", + "

924 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "24 11000802 6026.136230 6210.016113 8TH ST NW 1 \n", + "31 11001202 764.513489 872.439026 12TH ST NW 1 \n", + "43 11064412 769.510315 792.968201 NEW MEXICO AVE NW 1 \n", + "58 11000702 2102.751709 2221.992432 7TH ST NW 1 \n", + "64 11033862 1641.014160 1702.536743 EUCLID ST NW 1 \n", + "... ... ... ... ... ... \n", + "13759 13034462 154.392395 225.167496 EAST CAPITOL ST SE 1 \n", + "13773 13001402 125.595001 210.844299 14TH ST SE 1 \n", + "13780 13031332 481.594086 610.044189 E ST SE 1 \n", + "13811 13000102 1383.720337 1480.840332 1ST ST SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "24 7028022eb2ddc14b56a7d5e090c89961 1 2 \n", + "31 a0c7260c3824e5d98a8272a0dea47197 2 2 \n", + "43 5cce0fd3e2d6d45f5b7bbdeac883f3a0 2 2 \n", + "58 186de2ca1ec920117b3a3c3efed0380f 2 2 \n", + "64 2f7e6a2a12583aecba70dc3e18550bf3 1 2 \n", + "... ... ... ... \n", + "13759 6f386fee838ed54d564cf493c0808a8b 2 2 \n", + "13773 51cbaeebbf932bd5a35ae70d28dc1820 1 2 \n", + "13780 2d375e469680fbc169c6e912f9fba3a0 2 2 \n", + "13811 fb2d00801282fe317232b851a2aa2532 4 2 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "24 0 10 ... NaN \n", + "31 0 20 ... NaN \n", + "43 0 20 ... 2020.0 \n", + "58 0 22 ... 2020.0 \n", + "64 0 10 ... NaN \n", + "... ... ... ... ... \n", + "13759 0 20 ... NaN \n", + "13773 0 8 ... NaN \n", + "13780 0 20 ... NaN \n", + "13811 0 44 ... NaN \n", + "13834 0 20 ... NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "24 1 1 YES \n", + "31 1 1 None \n", + "43 1 1 None \n", + "58 1 1 None \n", + "64 1 1 None \n", + "... ... ... ... \n", + "13759 1 1 None \n", + "13773 1 1 None \n", + "13780 1 1 None \n", + "13811 1 1 None \n", + "13834 1 1 None \n", + "\n", + " OBJECTID SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \\\n", + "24 4195051 0 24 5 5.0 \n", + "31 4195058 0 31 5 5.0 \n", + "43 4195070 0 43 5 5.0 \n", + "58 4195085 0 58 10 5.0 \n", + "64 4195091 0 64 5 5.0 \n", + "... ... ... ... ... ... \n", + "13759 4211426 0 13759 12 6.0 \n", + "13773 4211440 0 13773 5 5.0 \n", + "13780 4211447 0 13780 10 5.0 \n", + "13811 4211478 0 13811 10 5.0 \n", + "13834 4211501 0 13834 10 5.0 \n", + "\n", + " ADJPLREACH \n", + "24 12.5 \n", + "31 14.0 \n", + "43 13.0 \n", + "58 13.0 \n", + "64 12.5 \n", + "... ... \n", + "13759 14.0 \n", + "13773 13.0 \n", + "13780 13.0 \n", + "13811 13.0 \n", + "13834 14.0 \n", + "\n", + "[924 rows x 105 columns]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads['ADJPLREACH'] = 0.0\n", + "adjPLReach_ind = ((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (~roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())\n", + "roads.loc[adjPLReach_ind, 'ADJPLREACH'] = roads[adjPLReach_ind]['PERBIKELANEWIDTH'] + roads[adjPLReach_ind]['TOTALPARKINGLANEWIDTH']/roads[adjPLReach_ind]['TOTALPARKINGLANES']\n", + "roads[adjPLReach_ind]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "81bce7bc-b4c5-4c66-b237-4ab9fda1ce0f", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROUTEID\n", + "FROMMEASURE\n", + "TOMEASURE\n", + "ROUTENAME\n", + "ROADTYPE\n", + "BLOCKKEY\n", + "TOTALTRAVELLANES\n", + "TOTALPARKINGLANES\n", + "TOTALRAISEDBUFFERS\n", + "TOTALTRAVELLANEWIDTH\n", + "TOTALCROSSSECTIONWIDTH\n", + "TOTALPARKINGLANEWIDTH\n", + "TOTALRAISEDBUFFERWIDTH\n", + "TOTALTRAVELLANESINBOUND\n", + "TOTALTRAVELLANESOUTBOUND\n", + "TOTALTRAVELLANESBIDIRECTIONAL\n", + "TOTALTRAVELLANESREVERSIBLE\n", + "SUMMARYDIRECTION\n", + "BIKELANE_PARKINGLANE_ADJACENT\n", + "BIKELANE_THROUGHLANE_ADJACENT\n", + "BIKELANE_POCKETLANE_ADJACENT\n", + "BIKELANE_CONTRAFLOW\n", + "BIKELANE_CONVENTIONAL\n", + "BIKELANE_DUAL_PROTECTED\n", + "BIKELANE_PROTECTED\n", + "BIKELANE_BUFFERED\n", + "DOUBLEYELLOW_LINE\n", + "SECTIONFLAGS\n", + "LOC_ERROR\n", + "MIDMEASURE\n", + "AADT\n", + "AADT_YEAR\n", + "FHWAFUNCTIONALCLASS\n", + "HPMSID\n", + "HPMSSECTIONTYPE\n", + "ID\n", + "IRI\n", + "IRI_DATE\n", + "NHSCODE\n", + "OWNERSHIP\n", + "PCI_CONDCATEGORY\n", + "PCI_LASTINSPECTED\n", + "PCI_SCORE\n", + "QUADRANT\n", + "SIDEWALK_IB_PAVTYPE\n", + "SIDEWALK_IB_WIDTH\n", + "SIDEWALK_OB_PAVTYPE\n", + "SIDEWALK_OB_WIDTH\n", + "SPEEDLIMITS_IB\n", + "SPEEDLIMITS_IB_ALT\n", + "SPEEDLIMITS_OB\n", + "SPEEDLIMITS_OB_ALT\n", + "STREETNAME\n", + "STREETTYPE\n", + "BLOCK_NAME\n", + "ADDRESS_RANGE_HIGH\n", + "ADDRESS_RANGE_LOW\n", + "ADDRESS_RANGE_RIGHT_HIGH\n", + "ADDRESS_RANGE_LEFT_HIGH\n", + "ADDRESS_RANGE_RIGHT_LOW\n", + "MAR_ID\n", + "ADDRESS_RANGE_LEFT_LOW\n", + "BLOCKID\n", + "DCFUNCTIONALCLASS\n", + "NHSTYPE\n", + "SNOWROUTE_DDOT\n", + "SNOWROUTE_DPW\n", + "SNOWSECTION_DDOT\n", + "SNOWZONE_DDOT\n", + "SNOWZONE_DPW\n", + "LEFTTURN_CURBLANE_EXCL\n", + "LEFTTURN_CURBLANE_EXCL_LEN\n", + "RIGHTTURN_CURBLANE_EXCL\n", + "RIGHTTURN_CURBLANE_EXCL_LEN\n", + "TOTALBIKELANES\n", + "TOTALBIKELANEWIDTH\n", + "RPPDIRECTION\n", + "RPPSIDE\n", + "SLOWSTREETINFO\n", + "BIKELANE_DUAL_BUFFERED\n", + "RIGHTTURN_EXCLUSIVE\n", + "LEFTTURN_EXCLUSIVE\n", + "BUSLANE_INBOUND\n", + "BUSLANE_OUTBOUND\n", + "FROMSTREET\n", + "TOSTREET\n", + "WARD_ID\n", + "ANC_ID\n", + "SMD_ID\n", + "SURFACE_TYPE\n", + "PARKINGZONE_ROP\n", + "PARKINGZONE_RPP\n", + "AADT_COMBINATION\n", + "AADT_COMBINATION_YEAR\n", + "AADT_SINGLE_UNIT\n", + "AADT_SINGLE_UNIT_YEAR\n", + "DC_MAINTENANCE_OPERATIONS\n", + "MAINTENANCE_OPERATIONS\n", + "VERTICAL_DEFLECTION\n", + "OBJECTID\n", + "SHAPELEN\n", + "index\n", + "TOTALBIKELANEWIDTH_WEXTRA\n", + "PERBIKELANEWIDTH\n", + "ADJPLREACH\n" + ] + } + ], + "source": [ + "for c in roads.columns:\n", + " print(c)" + ] + }, + { + "cell_type": "markdown", + "id": "52162e82-5e5f-4a58-b266-fb59e9f285e1", + "metadata": {}, + "source": [ + "## Mixed roads\n", + "\n", + "This scenario has the most complex logic. The general logic is based on the number of lanes (whether there is a centerline, if it's two-way, if it's wide, how many lanes there are), the average daily traffic (ADT), and prevailing speed. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "### Variable equivalence\n", + "\n", + "* to use this table: TOTALBIKELANES == 0\n", + "* Directionality: SUMMARYDIRECTION == BD or ?? is two way, IB or OB is one way, sometimes don't need to check\n", + "* centerline: DOUBLEYELLOW_LINE == yes or TOTALRAISEDBUFFERS > 0 (no centerline- DOUBLEYELLOW_LINE != yes and TOTALRAISEDBUFFERS == 0\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes inbound: TOTALTRAVELLANESINBOUND\n", + "* Number of travel lanes outbound: TOTALTRAVELLANESOUTBOUND\n", + "* width_onewaynparking: TOTALPARKINGLANES is 0,1, or 2/greater (doesn't mean it's on both sides), width: TOTALCROSSSECTIONWIDTH (threshold will depend on number of parking lanes\n", + "* min ADT and max ADT: AADT\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB" + ] + }, + { + "cell_type": "markdown", + "id": "db43faed-1b6a-4508-9a8c-c4444380ba58", + "metadata": {}, + "source": [ + "### Set up mixed-traffic" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "53e7b97a-9850-4f0c-97a5-b6dd3709c9ad", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionDirectionalitycenterlineTotal number of Travel LanesNumber of travel lanes in one directionwidth_onewaymin ADTmax ADT23.528.533.538.543.548.5100
0noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.01122333
1noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN750.01500.01123333
2noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN1500.03000.02223344
3noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN3000.01000000.02233444
4noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaNNaNNaN2223344
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Directionality centerline \\\n", + "0 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "1 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "2 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "3 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "4 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 max2 NaN \n", + "1 max2 NaN \n", + "2 max2 NaN \n", + "3 max2 NaN \n", + "4 max2 NaN \n", + "\n", + " width_oneway min ADT max ADT 23.5 28.5 33.5 38.5 43.5 48.5 100 \n", + "0 NaN 0.0 750.0 1 1 2 2 3 3 3 \n", + "1 NaN 750.0 1500.0 1 1 2 3 3 3 3 \n", + "2 NaN 1500.0 3000.0 2 2 2 3 3 4 4 \n", + "3 NaN 3000.0 1000000.0 2 2 3 3 4 4 4 \n", + "4 NaN NaN NaN 2 2 2 3 3 4 4 " + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'MixedTraffic' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "2e834ff1-5a31-49ef-a14d-ecc025704f70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index([ 'Bike lane',\n", + " 'Description',\n", + " 'Directionality',\n", + " 'centerline',\n", + " 'Total number of Travel Lanes',\n", + " 'Number of travel lanes in one direction',\n", + " 'width_oneway',\n", + " 'min ADT',\n", + " 'max ADT',\n", + " 'level_9',\n", + " 0],\n", + " dtype='object')\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionDirectionalitycenterlineTotal number of Travel LanesNumber of travel lanes in one directionwidth_onewaymin ADTmax ADTmaxspeedminspeedlevel
0noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.023.50.01
1noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.028.523.51
2noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.033.528.52
3noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.038.533.52
4noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.043.538.53
.......................................
142none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN33.528.54
143none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN38.533.54
144none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN43.538.54
145none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN48.543.54
146none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN100.048.54
\n", + "

147 rows × 12 columns

\n", + "
" + ], + "text/plain": [ + " Bike lane Description Directionality \\\n", + "0 none Unlaned 2-way street (no centerline) 2.0 \n", + "1 none Unlaned 2-way street (no centerline) 2.0 \n", + "2 none Unlaned 2-way street (no centerline) 2.0 \n", + "3 none Unlaned 2-way street (no centerline) 2.0 \n", + "4 none Unlaned 2-way street (no centerline) 2.0 \n", + ".. ... ... ... \n", + "142 none 3+ thru lanes in at least one direction NaN \n", + "143 none 3+ thru lanes in at least one direction NaN \n", + "144 none 3+ thru lanes in at least one direction NaN \n", + "145 none 3+ thru lanes in at least one direction NaN \n", + "146 none 3+ thru lanes in at least one direction NaN \n", + "\n", + " centerline Total number of Travel Lanes \\\n", + "0 0.0 max2 \n", + "1 0.0 max2 \n", + "2 0.0 max2 \n", + "3 0.0 max2 \n", + "4 0.0 max2 \n", + ".. ... ... \n", + "142 NaN NaN \n", + "143 NaN NaN \n", + "144 NaN NaN \n", + "145 NaN NaN \n", + "146 NaN NaN \n", + "\n", + " Number of travel lanes in one direction width_oneway min ADT max ADT \\\n", + "0 NaN NaN 0.0 750.0 \n", + "1 NaN NaN 0.0 750.0 \n", + "2 NaN NaN 0.0 750.0 \n", + "3 NaN NaN 0.0 750.0 \n", + "4 NaN NaN 0.0 750.0 \n", + ".. ... ... ... ... \n", + "142 min3 NaN NaN NaN \n", + "143 min3 NaN NaN NaN \n", + "144 min3 NaN NaN NaN \n", + "145 min3 NaN NaN NaN \n", + "146 min3 NaN NaN NaN \n", + "\n", + " maxspeed minspeed level \n", + "0 23.5 0.0 1 \n", + "1 28.5 23.5 1 \n", + "2 33.5 28.5 2 \n", + "3 38.5 33.5 2 \n", + "4 43.5 38.5 3 \n", + ".. ... ... ... \n", + "142 33.5 28.5 4 \n", + "143 38.5 33.5 4 \n", + "144 43.5 38.5 4 \n", + "145 48.5 43.5 4 \n", + "146 100.0 48.5 4 \n", + "\n", + "[147 rows x 12 columns]" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "print(df.columns)\n", + "df = df.rename(columns={'level_9':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "4d540f09-2ecd-42cf-9154-5ca3ffb53798", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...2020.011None41950270000.00.0
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaN11None41950280100.00.0
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...2020.011None41950290200.00.0
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...2020.011None41950300300.00.0
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaN11YES41950310400.00.0
..................................................................
13831130056020.00000075.67289756TH ST SE14f134473a059c441693e485dbec5a6c112016...NaN11YES421149801383100.00.0
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...2020.011None421150001383300.00.0
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaN11None421150201383500.00.0
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaN11None421150301383600.00.0
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaN1073None421150401383700.00.0
\n", + "

12358 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13831 13005602 0.000000 75.672897 56TH ST SE 1 \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13831 4f134473a059c441693e485dbec5a6c1 1 2 \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "0 0 37 ... 2020.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 2020.0 \n", + "3 1 40 ... 2020.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13831 0 16 ... NaN \n", + "13833 0 42 ... 2020.0 \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "0 1 1 None \n", + "1 1 1 None \n", + "2 1 1 None \n", + "3 1 1 None \n", + "4 1 1 YES \n", + "... ... ... ... \n", + "13831 1 1 YES \n", + "13833 1 1 None \n", + "13835 1 1 None \n", + "13836 1 1 None \n", + "13837 10 73 None \n", + "\n", + " OBJECTID SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \\\n", + "0 4195027 0 0 0 0.0 \n", + "1 4195028 0 1 0 0.0 \n", + "2 4195029 0 2 0 0.0 \n", + "3 4195030 0 3 0 0.0 \n", + "4 4195031 0 4 0 0.0 \n", + "... ... ... ... ... ... \n", + "13831 4211498 0 13831 0 0.0 \n", + "13833 4211500 0 13833 0 0.0 \n", + "13835 4211502 0 13835 0 0.0 \n", + "13836 4211503 0 13836 0 0.0 \n", + "13837 4211504 0 13837 0 0.0 \n", + "\n", + " ADJPLREACH \n", + "0 0.0 \n", + "1 0.0 \n", + "2 0.0 \n", + "3 0.0 \n", + "4 0.0 \n", + "... ... \n", + "13831 0.0 \n", + "13833 0.0 \n", + "13835 0.0 \n", + "13836 0.0 \n", + "13837 0.0 \n", + "\n", + "[12358 rows x 105 columns]" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#keep the roads with no bikelanes (bikes go in the car lane traffic)\n", + "roads_mixed = roads[roads['TOTALBIKELANES'] ==0]\n", + "roads_mixed" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "id": "0dd1db9b-51ff-4dd6-916e-bdb88a32c2e0", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each ADT and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, ADT, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "def get_levels(curr_df, curr_roads, road_levels, ignore_ADT = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/ADT/speedlimit combo\n", + " sel = []\n", + " print(str(row['min ADT'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by ADT, just by speedlimit\n", + " if ignore_ADT:\n", + " sel = curr_roads[((curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed']))]\n", + " print(len(sel)) \n", + " #if ADT delinations are made, use this section\n", + " else:\n", + " if pd.isna(row['max ADT']):\n", + " sel = curr_roads[curr_roads['AADT'].isna() & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " else:\n", + " sel = curr_roads[ (curr_roads['AADT']>=row['min ADT']) & (curr_roads['AADT'] < row['max ADT']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/ADT/speedlimit combo and the road segments matching the description, assign the approriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373])\n", + " #if there are any road segment elft over, assign them to the highest value (the last one used, generally 4) to be conservative\n", + " #this happens if there is an unusual configuration (ex- 0 lanes in either direction on a 1-way street, etc)\n", + " #the nubmer of 'left over' roads is printed out so it can be verified that it's not too large, which could point to a large problem.\n", + " inds = np.setdiff1d(curr_roads['index'].values, list(road_levels.keys()))\n", + " print('left over')\n", + " print(len(inds))\n", + " sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " print('no speedlimit')\n", + " print(len(sel))\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level'] \n", + " return road_levels" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "8a240770", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8741\n", + "8741\n", + "-----\n", + "0.0---0.0\n", + "8\n", + "0.0---23.5\n", + "1\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "750.0---0.0\n", + "43\n", + "750.0---23.5\n", + "30\n", + "750.0---28.5\n", + "0\n", + "750.0---33.5\n", + "0\n", + "750.0---38.5\n", + "0\n", + "750.0---43.5\n", + "0\n", + "750.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "208\n", + "1500.0---23.5\n", + "204\n", + "1500.0---28.5\n", + "9\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "3000.0---0.0\n", + "405\n", + "3000.0---23.5\n", + "631\n", + "3000.0---28.5\n", + "38\n", + "3000.0---33.5\n", + "3\n", + "3000.0---38.5\n", + "0\n", + "3000.0---43.5\n", + "0\n", + "3000.0---48.5\n", + "0\n", + "nan---0.0\n", + "6175\n", + "nan---23.5\n", + "519\n", + "nan---28.5\n", + "33\n", + "nan---33.5\n", + "1\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "433\n", + "no speedlimit\n", + "433\n", + "8741\n", + "92\n", + "-----\n", + "0.0---0.0\n", + "1\n", + "0.0---23.5\n", + "0\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "0\n", + "1000.0---23.5\n", + "0\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "12\n", + "1500.0---23.5\n", + "21\n", + "1500.0---28.5\n", + "2\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "nan---0.0\n", + "45\n", + "nan---23.5\n", + "4\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "7\n", + "no speedlimit\n", + "7\n", + "8833\n", + "786\n", + "786\n", + "-----\n", + "0.0---0.0\n", + "5\n", + "0.0---23.5\n", + "4\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "2\n", + "1000.0---23.5\n", + "1\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "23\n", + "1500.0---23.5\n", + "19\n", + "1500.0---28.5\n", + "0\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "nan---0.0\n", + "289\n", + "nan---23.5\n", + "9\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "434\n", + "no speedlimit\n", + "434\n", + "9619\n", + "391\n", + "391\n", + "-----\n", + "0.0---0.0\n", + "1\n", + "0.0---23.5\n", + "0\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "600.0---0.0\n", + "0\n", + "600.0---23.5\n", + "0\n", + "600.0---28.5\n", + "0\n", + "600.0---33.5\n", + "0\n", + "600.0---38.5\n", + "0\n", + "600.0---43.5\n", + "0\n", + "600.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "3\n", + "1000.0---23.5\n", + "3\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "nan---0.0\n", + "188\n", + "nan---23.5\n", + "8\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "188\n", + "no speedlimit\n", + "188\n", + "10010\n", + "1461\n", + "1461\n", + "-----\n", + "0.0---0.0\n", + "113\n", + "0.0---23.5\n", + "91\n", + "0.0---28.5\n", + "12\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "8000.0---0.0\n", + "217\n", + "8000.0---23.5\n", + "280\n", + "8000.0---28.5\n", + "244\n", + "8000.0---33.5\n", + "11\n", + "8000.0---38.5\n", + "3\n", + "8000.0---43.5\n", + "3\n", + "8000.0---48.5\n", + "0\n", + "nan---0.0\n", + "214\n", + "nan---23.5\n", + "37\n", + "nan---28.5\n", + "31\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "205\n", + "no speedlimit\n", + "205\n", + "11471\n", + "810\n", + "810\n", + "-----\n", + "nan---0.0\n", + "320\n", + "nan---23.5\n", + "210\n", + "nan---28.5\n", + "108\n", + "nan---33.5\n", + "13\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "3\n", + "nan---48.5\n", + "1\n", + "left over\n", + "155\n", + "no speedlimit\n", + "155\n", + "12281\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the ADT/speedlimit divisions\n", + "\n", + "#check directionality, centerline, and number of lanes (2,0,2)\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'BD') | (roads_mixed['SUMMARYDIRECTION'] == '??')) & \\\n", + " ((roads_mixed['DOUBLEYELLOW_LINE'] != 'yes') & (roads_mixed['TOTALRAISEDBUFFERS'] == 0)) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] <= 2)\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 2) & (df['centerline'] == 0) & (df['Total number of Travel Lanes'] == 'max2')]\n", + "road_levels = {}\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality, centerline, and number of lanes in one direction (2,1,1perDir)\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'BD') | (roads_mixed['SUMMARYDIRECTION'] == '??')) & \\\n", + " ((roads_mixed['DOUBLEYELLOW_LINE'] == 'yes') | (roads_mixed['TOTALRAISEDBUFFERS'] > 0)) & \\\n", + " ((roads_mixed['TOTALTRAVELLANESINBOUND'] == 1) & (roads_mixed['TOTALTRAVELLANESOUTBOUND'] == 1))\n", + "curr_roads = roads_mixed[curr_check]\n", + "curr_df = df[(df['Directionality'] == 2) & (df['centerline'] == 1) & (df['Number of travel lanes in one direction'] == '1perDir')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality and number of lanes (1, 1) and wide roads\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'IB') | (roads_mixed['SUMMARYDIRECTION'] == 'OB')) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] == 1) & \\\n", + " (((roads_mixed['TOTALPARKINGLANES'] == 0) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 15)) | ((roads_mixed['TOTALPARKINGLANES'] == 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 22)) | ((roads_mixed['TOTALPARKINGLANES'] > 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 30)))\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 1) & (df['Total number of Travel Lanes'] == 1) & (df['width_oneway'] == 'wide')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality and number of lanes (1, 1) and narrow roads\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'IB') | (roads_mixed['SUMMARYDIRECTION'] == 'OB')) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] == 1) & \\\n", + " (((roads_mixed['TOTALPARKINGLANES'] == 0) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 15)) | ((roads_mixed['TOTALPARKINGLANES'] == 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 22)) | ((roads_mixed['TOTALPARKINGLANES'] > 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 30)))\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 1) & (df['Total number of Travel Lanes'] == 1)& (df['width_oneway'] == 'narrow')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality (2) and 2 thru lanes in at least on direction\n", + "curr_check = (((roads_mixed['TOTALTRAVELLANESINBOUND'] == 2) & (roads_mixed['TOTALTRAVELLANESOUTBOUND'] <= 2)) | ((roads_mixed['TOTALTRAVELLANESOUTBOUND'] == 2)& (roads_mixed['TOTALTRAVELLANESINBOUND'] <= 2))) \n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max2')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality (2) and 3 thru lanes in at leat least on direction\n", + "curr_check = ((roads_mixed['TOTALTRAVELLANESINBOUND'] > 2) | (roads_mixed['TOTALTRAVELLANESOUTBOUND'] > 2)) \n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels, ignore_ADT = True)\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "b4790af4", + "metadata": {}, + "source": [ + "# Conventional bike lane, not adjacent to a parking lane\n", + "\n", + "\n", + "The logic is based on the number of lanes, bike lane width, and prevailing speed. The bike lane width includes any buffer area. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "## Variable equivalence\n", + "\n", + "* Is the bike lane adjacent to a parking lane: BIKELANE_PARKINGLANE_ADJACENT\n", + "* bike lane: BIKELANE_CONTRAFLOW, BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED\n", + "* BirectionalLane: TOTALTRAVELLANESBIDIRECTIONAL (check if 0 or >0)\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes in one direction: TOTALTRAVELLANESOUTBOUND and TOTALTRAVELLANESINBOUND\n", + "* max bike lane width and min bike lane width: PERBIKELANEWIDTH (might not be accurate)\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "07cee2d7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane widthmin bike lane width28.533.538.543.548.5100
0conventional00NaNNaNmax1other0100.06.0112333
1conventional00NaNNaNmax1other06.04.0222334
2conventional000.0NaNexactly1100.06.0112333
3conventional000.0NaNexactly16.04.0222334
4conventional001.0NaNexactly1100.04.0112333
5conventional001.0NaNexactly14.02.0222334
6conventional00NaNNaNmax2100.06.0222333
7conventional00NaNNaNmax26.04.0222344
8conventional00NaNNaNmin3NaNNaN333444
9conventional00NaNNaNmin3NaNNaN333444
\n", + "
" + ], + "text/plain": [ + " Bike lane Frequent blocks AdjacentToParking BirectionalLane \\\n", + "0 conventional 0 0 NaN \n", + "1 conventional 0 0 NaN \n", + "2 conventional 0 0 0.0 \n", + "3 conventional 0 0 0.0 \n", + "4 conventional 0 0 1.0 \n", + "5 conventional 0 0 1.0 \n", + "6 conventional 0 0 NaN \n", + "7 conventional 0 0 NaN \n", + "8 conventional 0 0 NaN \n", + "9 conventional 0 0 NaN \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 NaN max1other0 \n", + "1 NaN max1other0 \n", + "2 NaN exactly1 \n", + "3 NaN exactly1 \n", + "4 NaN exactly1 \n", + "5 NaN exactly1 \n", + "6 NaN max2 \n", + "7 NaN max2 \n", + "8 NaN min3 \n", + "9 NaN min3 \n", + "\n", + " max bike lane width min bike lane width 28.5 33.5 38.5 43.5 48.5 100 \n", + "0 100.0 6.0 1 1 2 3 3 3 \n", + "1 6.0 4.0 2 2 2 3 3 4 \n", + "2 100.0 6.0 1 1 2 3 3 3 \n", + "3 6.0 4.0 2 2 2 3 3 4 \n", + "4 100.0 4.0 1 1 2 3 3 3 \n", + "5 4.0 2.0 2 2 2 3 3 4 \n", + "6 100.0 6.0 2 2 2 3 3 3 \n", + "7 6.0 4.0 2 2 2 3 4 4 \n", + "8 NaN NaN 3 3 3 4 4 4 \n", + "9 NaN NaN 3 3 3 4 4 4 " + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'conventional_notPL' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "ad1089fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane widthmin bike lane widthmaxspeedminspeedlevel
0conventional00NaNNaNmax1other0100.06.028.50.01
1conventional00NaNNaNmax1other0100.06.033.528.51
2conventional00NaNNaNmax1other0100.06.038.533.52
3conventional00NaNNaNmax1other0100.06.043.538.53
4conventional00NaNNaNmax1other0100.06.048.543.53
5conventional00NaNNaNmax1other0100.06.0100.048.53
6conventional00NaNNaNmax1other06.04.028.50.02
7conventional00NaNNaNmax1other06.04.033.528.52
8conventional00NaNNaNmax1other06.04.038.533.52
9conventional00NaNNaNmax1other06.04.043.538.53
10conventional00NaNNaNmax1other06.04.048.543.53
11conventional00NaNNaNmax1other06.04.0100.048.54
12conventional000.0NaNexactly1100.06.028.50.01
13conventional000.0NaNexactly1100.06.033.528.51
14conventional000.0NaNexactly1100.06.038.533.52
15conventional000.0NaNexactly1100.06.043.538.53
16conventional000.0NaNexactly1100.06.048.543.53
17conventional000.0NaNexactly1100.06.0100.048.53
18conventional000.0NaNexactly16.04.028.50.02
19conventional000.0NaNexactly16.04.033.528.52
20conventional000.0NaNexactly16.04.038.533.52
21conventional000.0NaNexactly16.04.043.538.53
22conventional000.0NaNexactly16.04.048.543.53
23conventional000.0NaNexactly16.04.0100.048.54
24conventional001.0NaNexactly1100.04.028.50.01
25conventional001.0NaNexactly1100.04.033.528.51
26conventional001.0NaNexactly1100.04.038.533.52
27conventional001.0NaNexactly1100.04.043.538.53
28conventional001.0NaNexactly1100.04.048.543.53
29conventional001.0NaNexactly1100.04.0100.048.53
30conventional001.0NaNexactly14.02.028.50.02
31conventional001.0NaNexactly14.02.033.528.52
32conventional001.0NaNexactly14.02.038.533.52
33conventional001.0NaNexactly14.02.043.538.53
34conventional001.0NaNexactly14.02.048.543.53
35conventional001.0NaNexactly14.02.0100.048.54
36conventional00NaNNaNmax2100.06.028.50.02
37conventional00NaNNaNmax2100.06.033.528.52
38conventional00NaNNaNmax2100.06.038.533.52
39conventional00NaNNaNmax2100.06.043.538.53
40conventional00NaNNaNmax2100.06.048.543.53
41conventional00NaNNaNmax2100.06.0100.048.53
42conventional00NaNNaNmax26.04.028.50.02
43conventional00NaNNaNmax26.04.033.528.52
44conventional00NaNNaNmax26.04.038.533.52
45conventional00NaNNaNmax26.04.043.538.53
46conventional00NaNNaNmax26.04.048.543.54
47conventional00NaNNaNmax26.04.0100.048.54
48conventional00NaNNaNmin3NaNNaN28.50.03
49conventional00NaNNaNmin3NaNNaN33.528.53
50conventional00NaNNaNmin3NaNNaN38.533.53
51conventional00NaNNaNmin3NaNNaN43.538.54
52conventional00NaNNaNmin3NaNNaN48.543.54
53conventional00NaNNaNmin3NaNNaN100.048.54
54conventional00NaNNaNmin3NaNNaN28.50.03
55conventional00NaNNaNmin3NaNNaN33.528.53
56conventional00NaNNaNmin3NaNNaN38.533.53
57conventional00NaNNaNmin3NaNNaN43.538.54
58conventional00NaNNaNmin3NaNNaN48.543.54
59conventional00NaNNaNmin3NaNNaN100.048.54
\n", + "
" + ], + "text/plain": [ + " Bike lane Frequent blocks AdjacentToParking BirectionalLane \\\n", + "0 conventional 0 0 NaN \n", + "1 conventional 0 0 NaN \n", + "2 conventional 0 0 NaN \n", + "3 conventional 0 0 NaN \n", + "4 conventional 0 0 NaN \n", + "5 conventional 0 0 NaN \n", + "6 conventional 0 0 NaN \n", + "7 conventional 0 0 NaN \n", + "8 conventional 0 0 NaN \n", + "9 conventional 0 0 NaN \n", + "10 conventional 0 0 NaN \n", + "11 conventional 0 0 NaN \n", + "12 conventional 0 0 0.0 \n", + "13 conventional 0 0 0.0 \n", + "14 conventional 0 0 0.0 \n", + "15 conventional 0 0 0.0 \n", + "16 conventional 0 0 0.0 \n", + "17 conventional 0 0 0.0 \n", + "18 conventional 0 0 0.0 \n", + "19 conventional 0 0 0.0 \n", + "20 conventional 0 0 0.0 \n", + "21 conventional 0 0 0.0 \n", + "22 conventional 0 0 0.0 \n", + "23 conventional 0 0 0.0 \n", + "24 conventional 0 0 1.0 \n", + "25 conventional 0 0 1.0 \n", + "26 conventional 0 0 1.0 \n", + "27 conventional 0 0 1.0 \n", + "28 conventional 0 0 1.0 \n", + "29 conventional 0 0 1.0 \n", + "30 conventional 0 0 1.0 \n", + "31 conventional 0 0 1.0 \n", + "32 conventional 0 0 1.0 \n", + "33 conventional 0 0 1.0 \n", + "34 conventional 0 0 1.0 \n", + "35 conventional 0 0 1.0 \n", + "36 conventional 0 0 NaN \n", + "37 conventional 0 0 NaN \n", + "38 conventional 0 0 NaN \n", + "39 conventional 0 0 NaN \n", + "40 conventional 0 0 NaN \n", + "41 conventional 0 0 NaN \n", + "42 conventional 0 0 NaN \n", + "43 conventional 0 0 NaN \n", + "44 conventional 0 0 NaN \n", + "45 conventional 0 0 NaN \n", + "46 conventional 0 0 NaN \n", + "47 conventional 0 0 NaN \n", + "48 conventional 0 0 NaN \n", + "49 conventional 0 0 NaN \n", + "50 conventional 0 0 NaN \n", + "51 conventional 0 0 NaN \n", + "52 conventional 0 0 NaN \n", + "53 conventional 0 0 NaN \n", + "54 conventional 0 0 NaN \n", + "55 conventional 0 0 NaN \n", + "56 conventional 0 0 NaN \n", + "57 conventional 0 0 NaN \n", + "58 conventional 0 0 NaN \n", + "59 conventional 0 0 NaN \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 NaN max1other0 \n", + "1 NaN max1other0 \n", + "2 NaN max1other0 \n", + "3 NaN max1other0 \n", + "4 NaN max1other0 \n", + "5 NaN max1other0 \n", + "6 NaN max1other0 \n", + "7 NaN max1other0 \n", + "8 NaN max1other0 \n", + "9 NaN max1other0 \n", + "10 NaN max1other0 \n", + "11 NaN max1other0 \n", + "12 NaN exactly1 \n", + "13 NaN exactly1 \n", + "14 NaN exactly1 \n", + "15 NaN exactly1 \n", + "16 NaN exactly1 \n", + "17 NaN exactly1 \n", + "18 NaN exactly1 \n", + "19 NaN exactly1 \n", + "20 NaN exactly1 \n", + "21 NaN exactly1 \n", + "22 NaN exactly1 \n", + "23 NaN exactly1 \n", + "24 NaN exactly1 \n", + "25 NaN exactly1 \n", + "26 NaN exactly1 \n", + "27 NaN exactly1 \n", + "28 NaN exactly1 \n", + "29 NaN exactly1 \n", + "30 NaN exactly1 \n", + "31 NaN exactly1 \n", + "32 NaN exactly1 \n", + "33 NaN exactly1 \n", + "34 NaN exactly1 \n", + "35 NaN exactly1 \n", + "36 NaN max2 \n", + "37 NaN max2 \n", + "38 NaN max2 \n", + "39 NaN max2 \n", + "40 NaN max2 \n", + "41 NaN max2 \n", + "42 NaN max2 \n", + "43 NaN max2 \n", + "44 NaN max2 \n", + "45 NaN max2 \n", + "46 NaN max2 \n", + "47 NaN max2 \n", + "48 NaN min3 \n", + "49 NaN min3 \n", + "50 NaN min3 \n", + "51 NaN min3 \n", + "52 NaN min3 \n", + "53 NaN min3 \n", + "54 NaN min3 \n", + "55 NaN min3 \n", + "56 NaN min3 \n", + "57 NaN min3 \n", + "58 NaN min3 \n", + "59 NaN min3 \n", + "\n", + " max bike lane width min bike lane width maxspeed minspeed level \n", + "0 100.0 6.0 28.5 0.0 1 \n", + "1 100.0 6.0 33.5 28.5 1 \n", + "2 100.0 6.0 38.5 33.5 2 \n", + "3 100.0 6.0 43.5 38.5 3 \n", + "4 100.0 6.0 48.5 43.5 3 \n", + "5 100.0 6.0 100.0 48.5 3 \n", + "6 6.0 4.0 28.5 0.0 2 \n", + "7 6.0 4.0 33.5 28.5 2 \n", + "8 6.0 4.0 38.5 33.5 2 \n", + "9 6.0 4.0 43.5 38.5 3 \n", + "10 6.0 4.0 48.5 43.5 3 \n", + "11 6.0 4.0 100.0 48.5 4 \n", + "12 100.0 6.0 28.5 0.0 1 \n", + "13 100.0 6.0 33.5 28.5 1 \n", + "14 100.0 6.0 38.5 33.5 2 \n", + "15 100.0 6.0 43.5 38.5 3 \n", + "16 100.0 6.0 48.5 43.5 3 \n", + "17 100.0 6.0 100.0 48.5 3 \n", + "18 6.0 4.0 28.5 0.0 2 \n", + "19 6.0 4.0 33.5 28.5 2 \n", + "20 6.0 4.0 38.5 33.5 2 \n", + "21 6.0 4.0 43.5 38.5 3 \n", + "22 6.0 4.0 48.5 43.5 3 \n", + "23 6.0 4.0 100.0 48.5 4 \n", + "24 100.0 4.0 28.5 0.0 1 \n", + "25 100.0 4.0 33.5 28.5 1 \n", + "26 100.0 4.0 38.5 33.5 2 \n", + "27 100.0 4.0 43.5 38.5 3 \n", + "28 100.0 4.0 48.5 43.5 3 \n", + "29 100.0 4.0 100.0 48.5 3 \n", + "30 4.0 2.0 28.5 0.0 2 \n", + "31 4.0 2.0 33.5 28.5 2 \n", + "32 4.0 2.0 38.5 33.5 2 \n", + "33 4.0 2.0 43.5 38.5 3 \n", + "34 4.0 2.0 48.5 43.5 3 \n", + "35 4.0 2.0 100.0 48.5 4 \n", + "36 100.0 6.0 28.5 0.0 2 \n", + "37 100.0 6.0 33.5 28.5 2 \n", + "38 100.0 6.0 38.5 33.5 2 \n", + "39 100.0 6.0 43.5 38.5 3 \n", + "40 100.0 6.0 48.5 43.5 3 \n", + "41 100.0 6.0 100.0 48.5 3 \n", + "42 6.0 4.0 28.5 0.0 2 \n", + "43 6.0 4.0 33.5 28.5 2 \n", + "44 6.0 4.0 38.5 33.5 2 \n", + "45 6.0 4.0 43.5 38.5 3 \n", + "46 6.0 4.0 48.5 43.5 4 \n", + "47 6.0 4.0 100.0 48.5 4 \n", + "48 NaN NaN 28.5 0.0 3 \n", + "49 NaN NaN 33.5 28.5 3 \n", + "50 NaN NaN 38.5 33.5 3 \n", + "51 NaN NaN 43.5 38.5 4 \n", + "52 NaN NaN 48.5 43.5 4 \n", + "53 NaN NaN 100.0 48.5 4 \n", + "54 NaN NaN 28.5 0.0 3 \n", + "55 NaN NaN 33.5 28.5 3 \n", + "56 NaN NaN 38.5 33.5 3 \n", + "57 NaN NaN 43.5 38.5 4 \n", + "58 NaN NaN 48.5 43.5 4 \n", + "59 NaN NaN 100.0 48.5 4 " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "df = df.rename(columns={'level_8':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "0d6432ab", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
36110578523723.6967773849.773682M ST NW134aff18001cc26b963e031ae2f74570a31023...NaNNaN37849571103655.00.0
97110534922807.1406252961.828857L ST NW16f57b130652ee5665b6800501d485cd521020...NaNNaN3785018110971111.00.0
116110200220.00000039.681999CALVERT ST NW18c0b3aff2db6e698c631eeb1103cf10e30134...NaNNaN3785037110116199.50.0
137110017022571.9794922654.19946317TH ST NW1cf4d2c8a3c0baa5d307e54b6212404bf12010...NaNNaN37850581101371515.00.0
146110646721752.6352541819.327148NEW YORK AVE NW1a4a03e7d6b749855970e499e3ef673b160261...NaNNaN378506711014694.50.0
..................................................................
1362512092622443.586090562.646484WEST VIRGINIA AVE NE1113953025d018971f10811a46056a01c21020...2020.0NaN381822611013625147.00.0
13642140007021147.3774411249.4969487TH ST SW15c356003a4b48dc0ea70be156a05720641040...NaNNaN381824311013642157.50.0
13667130011021687.2309571834.13757311TH ST SE14a3ef9e4e3d66ed0c15f8300979f227f60161...NaNNaN381826811013667105.00.0
13775130004021036.8702391117.5223394TH ST SE1d1c2228b6607677f3f48b194d9d9d1c530039...NaNNaN38183761101377555.00.0
13777120926222024.5301512134.030029WEST VIRGINIA AVE NE133c780ee1f2199da446042092482f21130030...2020.0NaN3818378110137773015.00.0
\n", + "

254 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "36 11057852 3723.696777 3849.773682 M ST NW 1 \n", + "97 11053492 2807.140625 2961.828857 L ST NW 1 \n", + "116 11020022 0.000000 39.681999 CALVERT ST NW 1 \n", + "137 11001702 2571.979492 2654.199463 17TH ST NW 1 \n", + "146 11064672 1752.635254 1819.327148 NEW YORK AVE NW 1 \n", + "... ... ... ... ... ... \n", + "13625 12092622 443.586090 562.646484 WEST VIRGINIA AVE NE 1 \n", + "13642 14000702 1147.377441 1249.496948 7TH ST SW 1 \n", + "13667 13001102 1687.230957 1834.137573 11TH ST SE 1 \n", + "13775 13000402 1036.870239 1117.522339 4TH ST SE 1 \n", + "13777 12092622 2024.530151 2134.030029 WEST VIRGINIA AVE NE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "36 34aff18001cc26b963e031ae2f74570a 3 1 \n", + "97 6f57b130652ee5665b6800501d485cd5 2 1 \n", + "116 8c0b3aff2db6e698c631eeb1103cf10e 3 0 \n", + "137 cf4d2c8a3c0baa5d307e54b6212404bf 1 2 \n", + "146 a4a03e7d6b749855970e499e3ef673b1 6 0 \n", + "... ... ... ... \n", + "13625 113953025d018971f10811a46056a01c 2 1 \n", + "13642 5c356003a4b48dc0ea70be156a057206 4 1 \n", + "13667 4a3ef9e4e3d66ed0c15f8300979f227f 6 0 \n", + "13775 d1c2228b6607677f3f48b194d9d9d1c5 3 0 \n", + "13777 33c780ee1f2199da446042092482f211 3 0 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "36 0 23 ... NaN \n", + "97 0 20 ... NaN \n", + "116 1 34 ... NaN \n", + "137 0 10 ... NaN \n", + "146 2 61 ... NaN \n", + "... ... ... ... ... \n", + "13625 0 20 ... 2020.0 \n", + "13642 0 40 ... NaN \n", + "13667 1 61 ... NaN \n", + "13775 0 39 ... NaN \n", + "13777 0 30 ... 2020.0 \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "36 NaN 3784957 1 \n", + "97 NaN 3785018 1 \n", + "116 NaN 3785037 1 \n", + "137 NaN 3785058 1 \n", + "146 NaN 3785067 1 \n", + "... ... ... ... \n", + "13625 NaN 3818226 1 \n", + "13642 NaN 3818243 1 \n", + "13667 NaN 3818268 1 \n", + "13775 NaN 3818376 1 \n", + "13777 NaN 3818378 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "36 1 0 36 5 \n", + "97 1 0 97 11 \n", + "116 1 0 116 19 \n", + "137 1 0 137 15 \n", + "146 1 0 146 9 \n", + "... ... ... ... ... \n", + "13625 1 0 13625 14 \n", + "13642 1 0 13642 15 \n", + "13667 1 0 13667 10 \n", + "13775 1 0 13775 5 \n", + "13777 1 0 13777 30 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "36 5.0 0.0 \n", + "97 11.0 0.0 \n", + "116 9.5 0.0 \n", + "137 15.0 0.0 \n", + "146 4.5 0.0 \n", + "... ... ... \n", + "13625 7.0 0.0 \n", + "13642 7.5 0.0 \n", + "13667 5.0 0.0 \n", + "13775 5.0 0.0 \n", + "13777 15.0 0.0 \n", + "\n", + "[254 rows x 105 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_conventional_notPL = roads[((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())]\n", + "roads_conventional_notPL" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "1e734909", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each bike-lane width and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, bike-lane width, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "\n", + "def get_levels_conventional(curr_df, curr_roads, road_levels, ignore_width = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/bikelane-width/speedlimit combo\n", + " sel = []\n", + " print(str(row['min bike lane width'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by reach, just by speedlimit\n", + " if ignore_width:\n", + " sel = curr_roads[(curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel)) \n", + " #if bikelane width delinations are made, use this section\n", + " else:\n", + " sel = curr_roads[ (curr_roads['PERBIKELANEWIDTH']>=row['min bike lane width']) & (curr_roads['PERBIKELANEWIDTH'] < row['max bike lane width']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/bikelane width/speedlimit combo and the road segments matching the description, assign the approriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373]) \n", + " #if ther is no speedlimit for some roads, go with the largest level (the last one)\n", + " sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level'] \n", + " return road_levels\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "9bf411ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24\n", + "24\n", + "-----\n", + "6.0---0.0\n", + "8\n", + "6.0---28.5\n", + "0\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "4\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12302\n", + "93\n", + "93\n", + "-----\n", + "6.0---0.0\n", + "59\n", + "6.0---28.5\n", + "1\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "33\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12395\n", + "12395\n", + "0\n", + "0\n", + "-----\n", + "4.0---0.0\n", + "0\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "2.0---0.0\n", + "0\n", + "2.0---28.5\n", + "0\n", + "2.0---33.5\n", + "0\n", + "2.0---38.5\n", + "0\n", + "2.0---43.5\n", + "0\n", + "2.0---48.5\n", + "0\n", + "12395\n", + "12395\n", + "84\n", + "84\n", + "-----\n", + "6.0---0.0\n", + "43\n", + "6.0---28.5\n", + "1\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "29\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12479\n", + "12479\n", + "53\n", + "53\n", + "-----\n", + "nan---0.0\n", + "36\n", + "nan---28.5\n", + "1\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "nan---0.0\n", + "36\n", + "nan---28.5\n", + "1\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "12532\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the bike lane width/speedlimit divisions\n", + "\n", + "# max1other0\n", + "curr_check = (((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 0) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] <= 1) ) | ((roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 0) & (roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] <= 1)))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max1other0')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "all_road_levels = road_levels\n", + "\n", + "# no birectional lane, one in each direction\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_notPL['TOTALTRAVELLANESBIDIRECTIONAL'] == 0)\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==0)]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# birectional lane, one in each direction\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_notPL['TOTALTRAVELLANESBIDIRECTIONAL'] > 0)\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==1)]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# max2\n", + "curr_check = (((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] ==2) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] <= 2) ) | ((roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 2) & (roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] <= 2)))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max2')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# at least 3\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] >=3) | (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] >=3))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels, ignore_width = True)\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "297d6fce", + "metadata": {}, + "source": [ + "# Conventional, Adjacent to parking lane\n", + "\n", + "The logic is based on the number of lanes, reach (bike and parking lane) width, and prevailing speed. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "## Variable equivalence\n", + "\n", + "* Is the bike lane adjacent to a parking lane: BIKELANE_PARKINGLANE_ADJACENT\n", + "* bike lane: BIKELANE_CONTRAFLOW, BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED\n", + "* BirectionalLane: TOTALTRAVELLANESBIDIRECTIONAL (check if 0 or >0)\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes in one direction: TOTALTRAVELLANESOUTBOUND and TOTALTRAVELLANESINBOUND\n", + "* max bike lane width and min bike lane width: PERBIKELANEWIDTH (might not be accurate)\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB\n", + "* min bike lane reach width and max bike lane reach width: ADJPLREACH" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "c53ed5fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane reach widthmin bike lane reach width28.533.538.5100
0conventional1 thru lane per direction010.0NaNexactly1100.015.01223
1conventional1 thru lane per direction010.0NaNexactly115.012.02233
2conventional1 thru lane per direction011.0NaNexactly1100.013.01223
3conventional1 thru lane per direction011.0NaNexactly113.011.02233
4conventional1-way multi-lane01NaNNaNoneIs0100.015.02333
5conventional1-way multi-lane01NaNNaNoneIs015.012.03333
6conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.02333
7conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.03333
8conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN3333
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Frequent blocks \\\n", + "0 conventional 1 thru lane per direction 0 \n", + "1 conventional 1 thru lane per direction 0 \n", + "2 conventional 1 thru lane per direction 0 \n", + "3 conventional 1 thru lane per direction 0 \n", + "4 conventional 1-way multi-lane 0 \n", + "5 conventional 1-way multi-lane 0 \n", + "6 conventional 2-way and 2 lanes per direction 0 \n", + "7 conventional 2-way and 2 lanes per direction 0 \n", + "8 conventional other 2-way multilane 0 \n", + "\n", + " AdjacentToParking BirectionalLane Total number of Travel Lanes \\\n", + "0 1 0.0 NaN \n", + "1 1 0.0 NaN \n", + "2 1 1.0 NaN \n", + "3 1 1.0 NaN \n", + "4 1 NaN NaN \n", + "5 1 NaN NaN \n", + "6 1 NaN NaN \n", + "7 1 NaN NaN \n", + "8 1 NaN NaN \n", + "\n", + " Number of travel lanes in one direction max bike lane reach width \\\n", + "0 exactly1 100.0 \n", + "1 exactly1 15.0 \n", + "2 exactly1 100.0 \n", + "3 exactly1 13.0 \n", + "4 oneIs0 100.0 \n", + "5 oneIs0 15.0 \n", + "6 oneIs2otherIs1or2 100.0 \n", + "7 oneIs2otherIs1or2 15.0 \n", + "8 min3andMin1 NaN \n", + "\n", + " min bike lane reach width 28.5 33.5 38.5 100 \n", + "0 15.0 1 2 2 3 \n", + "1 12.0 2 2 3 3 \n", + "2 13.0 1 2 2 3 \n", + "3 11.0 2 2 3 3 \n", + "4 15.0 2 3 3 3 \n", + "5 12.0 3 3 3 3 \n", + "6 15.0 2 3 3 3 \n", + "7 12.0 3 3 3 3 \n", + "8 NaN 3 3 3 3 " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'conventional_AdjacentToPL' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "743113bc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index([ 'Bike lane',\n", + " 'Description',\n", + " 'Frequent blocks',\n", + " 'AdjacentToParking',\n", + " 'BirectionalLane',\n", + " 'Total number of Travel Lanes',\n", + " 'Number of travel lanes in one direction',\n", + " 'max bike lane reach width',\n", + " 'min bike lane reach width',\n", + " 'level_9',\n", + " 0],\n", + " dtype='object')\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane reach widthmin bike lane reach widthmaxspeedminspeedlevel
0conventional1 thru lane per direction010.0NaNexactly1100.015.028.50.01
1conventional1 thru lane per direction010.0NaNexactly1100.015.033.528.52
2conventional1 thru lane per direction010.0NaNexactly1100.015.038.533.52
3conventional1 thru lane per direction010.0NaNexactly1100.015.0100.038.53
4conventional1 thru lane per direction010.0NaNexactly115.012.028.50.02
5conventional1 thru lane per direction010.0NaNexactly115.012.033.528.52
6conventional1 thru lane per direction010.0NaNexactly115.012.038.533.53
7conventional1 thru lane per direction010.0NaNexactly115.012.0100.038.53
8conventional1 thru lane per direction011.0NaNexactly1100.013.028.50.01
9conventional1 thru lane per direction011.0NaNexactly1100.013.033.528.52
10conventional1 thru lane per direction011.0NaNexactly1100.013.038.533.52
11conventional1 thru lane per direction011.0NaNexactly1100.013.0100.038.53
12conventional1 thru lane per direction011.0NaNexactly113.011.028.50.02
13conventional1 thru lane per direction011.0NaNexactly113.011.033.528.52
14conventional1 thru lane per direction011.0NaNexactly113.011.038.533.53
15conventional1 thru lane per direction011.0NaNexactly113.011.0100.038.53
16conventional1-way multi-lane01NaNNaNoneIs0100.015.028.50.02
17conventional1-way multi-lane01NaNNaNoneIs0100.015.033.528.53
18conventional1-way multi-lane01NaNNaNoneIs0100.015.038.533.53
19conventional1-way multi-lane01NaNNaNoneIs0100.015.0100.038.53
20conventional1-way multi-lane01NaNNaNoneIs015.012.028.50.03
21conventional1-way multi-lane01NaNNaNoneIs015.012.033.528.53
22conventional1-way multi-lane01NaNNaNoneIs015.012.038.533.53
23conventional1-way multi-lane01NaNNaNoneIs015.012.0100.038.53
24conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.028.50.02
25conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.033.528.53
26conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.038.533.53
27conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.0100.038.53
28conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.028.50.03
29conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.033.528.53
30conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.038.533.53
31conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.0100.038.53
32conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN28.50.03
33conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN33.528.53
34conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN38.533.53
35conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN100.038.53
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Frequent blocks \\\n", + "0 conventional 1 thru lane per direction 0 \n", + "1 conventional 1 thru lane per direction 0 \n", + "2 conventional 1 thru lane per direction 0 \n", + "3 conventional 1 thru lane per direction 0 \n", + "4 conventional 1 thru lane per direction 0 \n", + "5 conventional 1 thru lane per direction 0 \n", + "6 conventional 1 thru lane per direction 0 \n", + "7 conventional 1 thru lane per direction 0 \n", + "8 conventional 1 thru lane per direction 0 \n", + "9 conventional 1 thru lane per direction 0 \n", + "10 conventional 1 thru lane per direction 0 \n", + "11 conventional 1 thru lane per direction 0 \n", + "12 conventional 1 thru lane per direction 0 \n", + "13 conventional 1 thru lane per direction 0 \n", + "14 conventional 1 thru lane per direction 0 \n", + "15 conventional 1 thru lane per direction 0 \n", + "16 conventional 1-way multi-lane 0 \n", + "17 conventional 1-way multi-lane 0 \n", + "18 conventional 1-way multi-lane 0 \n", + "19 conventional 1-way multi-lane 0 \n", + "20 conventional 1-way multi-lane 0 \n", + "21 conventional 1-way multi-lane 0 \n", + "22 conventional 1-way multi-lane 0 \n", + "23 conventional 1-way multi-lane 0 \n", + "24 conventional 2-way and 2 lanes per direction 0 \n", + "25 conventional 2-way and 2 lanes per direction 0 \n", + "26 conventional 2-way and 2 lanes per direction 0 \n", + "27 conventional 2-way and 2 lanes per direction 0 \n", + "28 conventional 2-way and 2 lanes per direction 0 \n", + "29 conventional 2-way and 2 lanes per direction 0 \n", + "30 conventional 2-way and 2 lanes per direction 0 \n", + "31 conventional 2-way and 2 lanes per direction 0 \n", + "32 conventional other 2-way multilane 0 \n", + "33 conventional other 2-way multilane 0 \n", + "34 conventional other 2-way multilane 0 \n", + "35 conventional other 2-way multilane 0 \n", + "\n", + " AdjacentToParking BirectionalLane Total number of Travel Lanes \\\n", + "0 1 0.0 NaN \n", + "1 1 0.0 NaN \n", + "2 1 0.0 NaN \n", + "3 1 0.0 NaN \n", + "4 1 0.0 NaN \n", + "5 1 0.0 NaN \n", + "6 1 0.0 NaN \n", + "7 1 0.0 NaN \n", + "8 1 1.0 NaN \n", + "9 1 1.0 NaN \n", + "10 1 1.0 NaN \n", + "11 1 1.0 NaN \n", + "12 1 1.0 NaN \n", + "13 1 1.0 NaN \n", + "14 1 1.0 NaN \n", + "15 1 1.0 NaN \n", + "16 1 NaN NaN \n", + "17 1 NaN NaN \n", + "18 1 NaN NaN \n", + "19 1 NaN NaN \n", + "20 1 NaN NaN \n", + "21 1 NaN NaN \n", + "22 1 NaN NaN \n", + "23 1 NaN NaN \n", + "24 1 NaN NaN \n", + "25 1 NaN NaN \n", + "26 1 NaN NaN \n", + "27 1 NaN NaN \n", + "28 1 NaN NaN \n", + "29 1 NaN NaN \n", + "30 1 NaN NaN \n", + "31 1 NaN NaN \n", + "32 1 NaN NaN \n", + "33 1 NaN NaN \n", + "34 1 NaN NaN \n", + "35 1 NaN NaN \n", + "\n", + " Number of travel lanes in one direction max bike lane reach width \\\n", + "0 exactly1 100.0 \n", + "1 exactly1 100.0 \n", + "2 exactly1 100.0 \n", + "3 exactly1 100.0 \n", + "4 exactly1 15.0 \n", + "5 exactly1 15.0 \n", + "6 exactly1 15.0 \n", + "7 exactly1 15.0 \n", + "8 exactly1 100.0 \n", + "9 exactly1 100.0 \n", + "10 exactly1 100.0 \n", + "11 exactly1 100.0 \n", + "12 exactly1 13.0 \n", + "13 exactly1 13.0 \n", + "14 exactly1 13.0 \n", + "15 exactly1 13.0 \n", + "16 oneIs0 100.0 \n", + "17 oneIs0 100.0 \n", + "18 oneIs0 100.0 \n", + "19 oneIs0 100.0 \n", + "20 oneIs0 15.0 \n", + "21 oneIs0 15.0 \n", + "22 oneIs0 15.0 \n", + "23 oneIs0 15.0 \n", + "24 oneIs2otherIs1or2 100.0 \n", + "25 oneIs2otherIs1or2 100.0 \n", + "26 oneIs2otherIs1or2 100.0 \n", + "27 oneIs2otherIs1or2 100.0 \n", + "28 oneIs2otherIs1or2 15.0 \n", + "29 oneIs2otherIs1or2 15.0 \n", + "30 oneIs2otherIs1or2 15.0 \n", + "31 oneIs2otherIs1or2 15.0 \n", + "32 min3andMin1 NaN \n", + "33 min3andMin1 NaN \n", + "34 min3andMin1 NaN \n", + "35 min3andMin1 NaN \n", + "\n", + " min bike lane reach width maxspeed minspeed level \n", + "0 15.0 28.5 0.0 1 \n", + "1 15.0 33.5 28.5 2 \n", + "2 15.0 38.5 33.5 2 \n", + "3 15.0 100.0 38.5 3 \n", + "4 12.0 28.5 0.0 2 \n", + "5 12.0 33.5 28.5 2 \n", + "6 12.0 38.5 33.5 3 \n", + "7 12.0 100.0 38.5 3 \n", + "8 13.0 28.5 0.0 1 \n", + "9 13.0 33.5 28.5 2 \n", + "10 13.0 38.5 33.5 2 \n", + "11 13.0 100.0 38.5 3 \n", + "12 11.0 28.5 0.0 2 \n", + "13 11.0 33.5 28.5 2 \n", + "14 11.0 38.5 33.5 3 \n", + "15 11.0 100.0 38.5 3 \n", + "16 15.0 28.5 0.0 2 \n", + "17 15.0 33.5 28.5 3 \n", + "18 15.0 38.5 33.5 3 \n", + "19 15.0 100.0 38.5 3 \n", + "20 12.0 28.5 0.0 3 \n", + "21 12.0 33.5 28.5 3 \n", + "22 12.0 38.5 33.5 3 \n", + "23 12.0 100.0 38.5 3 \n", + "24 15.0 28.5 0.0 2 \n", + "25 15.0 33.5 28.5 3 \n", + "26 15.0 38.5 33.5 3 \n", + "27 15.0 100.0 38.5 3 \n", + "28 12.0 28.5 0.0 3 \n", + "29 12.0 33.5 28.5 3 \n", + "30 12.0 38.5 33.5 3 \n", + "31 12.0 100.0 38.5 3 \n", + "32 NaN 28.5 0.0 3 \n", + "33 NaN 33.5 28.5 3 \n", + "34 NaN 38.5 33.5 3 \n", + "35 NaN 100.0 38.5 3 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "print(df.columns)\n", + "df = df.rename(columns={'level_9':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "7b7a579a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
3110513522193.0302732296.614258KANSAS AVE NW1c448b8a91c9e954e73db5fb1563d10a322022...2020.0NaN37849241103105.013.0
611067402542.831299667.220215ONTARIO RD NW1fb6a8d2fbe65ada17c5da91f65616ac112011...NaNNaN3784927110655.012.0
10110014024551.2397464569.19580114TH ST NW124619988e5d7556d9366681fe23de6a822022...2020.0NaN378493111010105.013.0
2411064412724.403198769.510315NEW MEXICO AVE NW19c91fb1e43cbb603a2e39b6222ea364722020...2020.0NaN37849451102455.013.0
28110642221615.2697751661.559937NEW HAMPSHIRE AVE NW19e64ad520f12c71e8ce968fbabffd80522020...2020.0NaN378494911028105.013.0
..................................................................
136701300110264.289101245.51269511TH ST SE1f6591609898a0ec6015a5e091ccea0e522022...NaNNaN381827111013670105.013.0
1368213081382268.410889475.594086SOUTH CAROLINA AVE SE15e86c702ab797fb3c02292d6516dd0c322020...NaNNaN381828311013682105.013.0
1373513000402788.719116947.6192024TH ST SE1c74620ee640cd3cf6f8c62573920598412013...NaNNaN38183361101373555.013.0
1378213001502880.905273947.53710915TH ST SE14a41e9643eadfd7095971da6fcf0faa312011...NaNNaN38183831101378255.013.0
13801130001021480.8403321568.9265141ST ST SE1e42b248e6bbc2fd0d7aede95ffc8f87842044...NaNNaN381840211013801105.013.0
\n", + "

924 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "3 11051352 2193.030273 2296.614258 KANSAS AVE NW 1 \n", + "6 11067402 542.831299 667.220215 ONTARIO RD NW 1 \n", + "10 11001402 4551.239746 4569.195801 14TH ST NW 1 \n", + "24 11064412 724.403198 769.510315 NEW MEXICO AVE NW 1 \n", + "28 11064222 1615.269775 1661.559937 NEW HAMPSHIRE AVE NW 1 \n", + "... ... ... ... ... ... \n", + "13670 13001102 64.289101 245.512695 11TH ST SE 1 \n", + "13682 13081382 268.410889 475.594086 SOUTH CAROLINA AVE SE 1 \n", + "13735 13000402 788.719116 947.619202 4TH ST SE 1 \n", + "13782 13001502 880.905273 947.537109 15TH ST SE 1 \n", + "13801 13000102 1480.840332 1568.926514 1ST ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2 2 \n", + "6 fb6a8d2fbe65ada17c5da91f65616ac1 1 2 \n", + "10 24619988e5d7556d9366681fe23de6a8 2 2 \n", + "24 9c91fb1e43cbb603a2e39b6222ea3647 2 2 \n", + "28 9e64ad520f12c71e8ce968fbabffd805 2 2 \n", + "... ... ... ... \n", + "13670 f6591609898a0ec6015a5e091ccea0e5 2 2 \n", + "13682 5e86c702ab797fb3c02292d6516dd0c3 2 2 \n", + "13735 c74620ee640cd3cf6f8c625739205984 1 2 \n", + "13782 4a41e9643eadfd7095971da6fcf0faa3 1 2 \n", + "13801 e42b248e6bbc2fd0d7aede95ffc8f878 4 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "3 0 22 ... 2020.0 \n", + "6 0 11 ... NaN \n", + "10 0 22 ... 2020.0 \n", + "24 0 20 ... 2020.0 \n", + "28 0 20 ... 2020.0 \n", + "... ... ... ... ... \n", + "13670 0 22 ... NaN \n", + "13682 0 20 ... NaN \n", + "13735 0 13 ... NaN \n", + "13782 0 11 ... NaN \n", + "13801 0 44 ... NaN \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "3 NaN 3784924 1 \n", + "6 NaN 3784927 1 \n", + "10 NaN 3784931 1 \n", + "24 NaN 3784945 1 \n", + "28 NaN 3784949 1 \n", + "... ... ... ... \n", + "13670 NaN 3818271 1 \n", + "13682 NaN 3818283 1 \n", + "13735 NaN 3818336 1 \n", + "13782 NaN 3818383 1 \n", + "13801 NaN 3818402 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "3 1 0 3 10 \n", + "6 1 0 6 5 \n", + "10 1 0 10 10 \n", + "24 1 0 24 5 \n", + "28 1 0 28 10 \n", + "... ... ... ... ... \n", + "13670 1 0 13670 10 \n", + "13682 1 0 13682 10 \n", + "13735 1 0 13735 5 \n", + "13782 1 0 13782 5 \n", + "13801 1 0 13801 10 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "3 5.0 13.0 \n", + "6 5.0 12.0 \n", + "10 5.0 13.0 \n", + "24 5.0 13.0 \n", + "28 5.0 13.0 \n", + "... ... ... \n", + "13670 5.0 13.0 \n", + "13682 5.0 13.0 \n", + "13735 5.0 13.0 \n", + "13782 5.0 13.0 \n", + "13801 5.0 13.0 \n", + "\n", + "[924 rows x 105 columns]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_conventional_adjPL = roads[((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (~roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())]\n", + "roads_conventional_adjPL" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "e1f9fd41", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each reach-lane width and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, reach-lane width, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "\n", + "def get_levels_conventional_adjPL(curr_df, curr_roads, road_levels, ignore_width = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/reach-width/speedlimit combo\n", + " sel = []\n", + " print(str(row['min bike lane reach width'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by reach, just by speedlimit\n", + " if ignore_width:\n", + " sel = curr_roads[(curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel)) \n", + " #if bikelane width delinations are made, use this section\n", + " else:\n", + " sel = curr_roads[ (curr_roads['ADJPLREACH']>=row['min bike lane reach width']) & (curr_roads['ADJPLREACH'] < row['max bike lane reach width']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/bikelane width/speedlimit combo and the road segments matching the description, assign the appropriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " print(len(road_levels))\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373]) \n", + " #sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " #if there are any road segment left over, assign them to the highest value (the last one used, generally 4) to be conservative\n", + " #this happens if there is an unusual configuration (ex- 0 lanes in either direction on a 1-way street, etc)\n", + " #the nubmer of 'left over' roads is printed out so it can be verified that it's not too large, which could point to a large problem.\n", + " inds = np.setdiff1d(curr_roads['index'].values, list(road_levels.keys()))\n", + " print('left over')\n", + " print(len(inds))\n", + " print(inds)\n", + " sel = curr_roads[curr_roads['index'].isin(inds)]\n", + " print(len(sel)) \n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " return road_levels\n" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "2fc5a7e7", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "356\n", + "12532\n", + "356\n", + "-----\n", + "15.0---0.0\n", + "24\n", + "12556\n", + "15.0---28.5\n", + "4\n", + "12560\n", + "15.0---33.5\n", + "0\n", + "12560\n", + "15.0---38.5\n", + "0\n", + "12560\n", + "12.0---0.0\n", + "283\n", + "12843\n", + "12.0---28.5\n", + "28\n", + "12871\n", + "12.0---33.5\n", + "0\n", + "12871\n", + "12.0---38.5\n", + "0\n", + "12871\n", + "left over\n", + "17\n", + "[ 3996 8596 10027 10054 10157 10475 10496 10676 11012 11384 11392 11522\n", + " 11843 12301 12340 12877 13124]\n", + "17\n", + "12888\n", + "13\n", + "12888\n", + "13\n", + "-----\n", + "13.0---0.0\n", + "9\n", + "12897\n", + "13.0---28.5\n", + "4\n", + "12901\n", + "13.0---33.5\n", + "0\n", + "12901\n", + "13.0---38.5\n", + "0\n", + "12901\n", + "11.0---0.0\n", + "0\n", + "12901\n", + "11.0---28.5\n", + "0\n", + "12901\n", + "11.0---33.5\n", + "0\n", + "12901\n", + "11.0---38.5\n", + "0\n", + "12901\n", + "left over\n", + "0\n", + "[]\n", + "0\n", + "12901\n", + "447\n", + "12901\n", + "447\n", + "-----\n", + "15.0---0.0\n", + "20\n", + "12921\n", + "15.0---28.5\n", + "0\n", + "12921\n", + "15.0---33.5\n", + "0\n", + "12921\n", + "15.0---38.5\n", + "0\n", + "12921\n", + "12.0---0.0\n", + "225\n", + "13146\n", + "12.0---28.5\n", + "5\n", + "13151\n", + "12.0---33.5\n", + "0\n", + "13151\n", + "12.0---38.5\n", + "0\n", + "13151\n", + "left over\n", + "197\n", + "[ 72 111 155 228 242 275 327 561 583 672 913 1409\n", + " 1464 1523 1553 1632 1692 1809 1941 1957 2042 2049 2083 2102\n", + " 2377 2438 2487 2527 2793 2857 2988 3002 3081 3186 3205 3231\n", + " 3291 3341 3452 3587 3784 3892 3921 3966 4111 4140 4231 4294\n", + " 4457 4505 4622 4623 4987 5034 5069 5095 5238 5245 5310 5359\n", + " 5365 5368 5371 5373 5374 5381 5385 5412 5418 5438 5440 5696\n", + " 5716 5758 5784 5790 5816 5842 5854 5861 5911 6076 6131 6134\n", + " 6172 6202 6210 6245 6306 6369 6406 6435 6487 6621 6665 6748\n", + " 6835 6873 6884 6885 6898 6907 7005 7066 7083 7091 7100 7124\n", + " 7126 7249 7282 7309 7340 7364 7381 7570 7607 7613 7675 7722\n", + " 7726 7733 7813 7818 7907 7911 8078 8330 8360 8397 8551 8613\n", + " 8629 8649 8685 8721 8763 8828 8936 8950 8963 9025 9041 9063\n", + " 9079 9095 9159 9167 9217 9291 9298 9311 9389 9440 9486 9528\n", + " 9535 9597 9640 9653 9706 9735 9749 9829 9858 9922 9945 9987\n", + " 10010 10167 10334 10382 10616 10618 10835 10854 10895 10922 10998 11114\n", + " 11163 11317 11529 11534 11576 11791 11883 11889 11932 11945 12245 12325\n", + " 12350 12616 12736 12961 13176]\n", + "197\n", + "13348\n", + "101\n", + "13348\n", + "101\n", + "-----\n", + "15.0---0.0\n", + "12\n", + "13360\n", + "15.0---28.5\n", + "1\n", + "13361\n", + "15.0---33.5\n", + "0\n", + "13361\n", + "15.0---38.5\n", + "0\n", + "13361\n", + "12.0---0.0\n", + "77\n", + "13438\n", + "12.0---28.5\n", + "7\n", + "13445\n", + "12.0---33.5\n", + "0\n", + "13445\n", + "12.0---38.5\n", + "0\n", + "13445\n", + "left over\n", + "4\n", + "[5253 5317 8401 9680]\n", + "4\n", + "13449\n", + "7\n", + "13449\n", + "7\n", + "-----\n", + "nan---0.0\n", + "4\n", + "13453\n", + "nan---28.5\n", + "0\n", + "13453\n", + "nan---33.5\n", + "0\n", + "13453\n", + "nan---38.5\n", + "0\n", + "13453\n", + "left over\n", + "3\n", + "[10519 12225 13327]\n", + "3\n", + "13456\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the reach lane width/speedlimit divisions\n", + "\n", + "# no birectional lane, one in each direction\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_adjPL['TOTALTRAVELLANESBIDIRECTIONAL'] == 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==0)]\n", + "#all_road_levels = {}\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# birectional lane, one in each direction\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_adjPL['TOTALTRAVELLANESBIDIRECTIONAL'] > 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==1)]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# birectional lane, one in each direction\n", + "curr_check = (roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 0) | (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'oneIs0')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# one direction is 2 lanes, other direction is 1 or 2 lanes\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 2) & ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 2) |(roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1))) | ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 2) & ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 2) |(roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1)))\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'oneIs2otherIs1or2')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# one direction is at least 3 lanes and other is at least 2 lanes\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] >=3) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] >=1)) | ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] >=3) & (roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] >=1))\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3andMin1')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels, ignore_width = True)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n" + ] + }, + { + "cell_type": "markdown", + "id": "2d9ac646-c90d-4a97-8f24-f085c08dc63f", + "metadata": {}, + "source": [ + "# Protected and dual-protected bike lanes" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7bd7e4a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
13110005023074.3991703193.3032235TH ST NW19ed8ed522bd67dccd92d1d5093dfaf8c12211...NaNNaN37849341101300.00.0
82110009021432.8323971478.0620129TH ST NW1b73d8b891b5136c91ccf503660c0c3bc50250...2020.0NaN37850031108200.00.0
20411052972140.757400505.979492KLINGLE RD NW1d138276f2f7c7b52703443f707ee24d020328...NaNNaN380480511020400.00.0
23211048752450.915894756.346375IRVING ST NW1028925d6eed296709bdc329a4697d99840244...2020.0NaN380483311023200.00.0
266110386121876.7893072070.267090G ST NW164c03c846136f580302a06e3dcbce3d111111...NaNNaN380486711026600.00.0
..................................................................
13556140004020.000000100.7942964TH ST SW179e5ded2c338b125eb39f63314644f3530233...NaNNaN38181571101355600.00.0
13633130718921644.1766361813.948975POTOMAC AVE SE1991827a21c5cff0c4e638d600b6f808c12111...2020.0NaN38182341101363300.00.0
136431405850263.963001104.609001MAINE AVE SW1e0f31320570eb8910928efb12e616fca52450...2020.0NaN38182441101364300.00.0
1370913001902405.588989494.07089219TH ST SE16abb362ff34b8ccba0fd36b199a359b011211...NaNNaN38183101101370900.00.0
13794130718921471.9941411611.014404POTOMAC AVE SE1fbdf2fa8d5e2b140760725ac2855cc1f21122...2020.0NaN38183951101379400.00.0
\n", + "

268 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "13 11000502 3074.399170 3193.303223 5TH ST NW 1 \n", + "82 11000902 1432.832397 1478.062012 9TH ST NW 1 \n", + "204 11052972 140.757400 505.979492 KLINGLE RD NW 1 \n", + "232 11048752 450.915894 756.346375 IRVING ST NW 1 \n", + "266 11038612 1876.789307 2070.267090 G ST NW 1 \n", + "... ... ... ... ... ... \n", + "13556 14000402 0.000000 100.794296 4TH ST SW 1 \n", + "13633 13071892 1644.176636 1813.948975 POTOMAC AVE SE 1 \n", + "13643 14058502 63.963001 104.609001 MAINE AVE SW 1 \n", + "13709 13001902 405.588989 494.070892 19TH ST SE 1 \n", + "13794 13071892 1471.994141 1611.014404 POTOMAC AVE SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "13 9ed8ed522bd67dccd92d1d5093dfaf8c 1 2 \n", + "82 b73d8b891b5136c91ccf503660c0c3bc 5 0 \n", + "204 d138276f2f7c7b52703443f707ee24d0 2 0 \n", + "232 028925d6eed296709bdc329a4697d998 4 0 \n", + "266 64c03c846136f580302a06e3dcbce3d1 1 1 \n", + "... ... ... ... \n", + "13556 79e5ded2c338b125eb39f63314644f35 3 0 \n", + "13633 991827a21c5cff0c4e638d600b6f808c 1 2 \n", + "13643 e0f31320570eb8910928efb12e616fca 5 2 \n", + "13709 6abb362ff34b8ccba0fd36b199a359b0 1 1 \n", + "13794 fbdf2fa8d5e2b140760725ac2855cc1f 2 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "13 2 11 ... NaN \n", + "82 2 50 ... 2020.0 \n", + "204 3 28 ... NaN \n", + "232 2 44 ... 2020.0 \n", + "266 1 11 ... NaN \n", + "... ... ... ... ... \n", + "13556 2 33 ... NaN \n", + "13633 1 11 ... 2020.0 \n", + "13643 4 50 ... 2020.0 \n", + "13709 2 11 ... NaN \n", + "13794 1 22 ... 2020.0 \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "13 NaN 3784934 1 \n", + "82 NaN 3785003 1 \n", + "204 NaN 3804805 1 \n", + "232 NaN 3804833 1 \n", + "266 NaN 3804867 1 \n", + "... ... ... ... \n", + "13556 NaN 3818157 1 \n", + "13633 NaN 3818234 1 \n", + "13643 NaN 3818244 1 \n", + "13709 NaN 3818310 1 \n", + "13794 NaN 3818395 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "13 1 0 13 0 \n", + "82 1 0 82 0 \n", + "204 1 0 204 0 \n", + "232 1 0 232 0 \n", + "266 1 0 266 0 \n", + "... ... ... ... ... \n", + "13556 1 0 13556 0 \n", + "13633 1 0 13633 0 \n", + "13643 1 0 13643 0 \n", + "13709 1 0 13709 0 \n", + "13794 1 0 13794 0 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "13 0.0 0.0 \n", + "82 0.0 0.0 \n", + "204 0.0 0.0 \n", + "232 0.0 0.0 \n", + "266 0.0 0.0 \n", + "... ... ... \n", + "13556 0.0 0.0 \n", + "13633 0.0 0.0 \n", + "13643 0.0 0.0 \n", + "13709 0.0 0.0 \n", + "13794 0.0 0.0 \n", + "\n", + "[268 rows x 105 columns]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#if bikelane is buffered, then set level to 1\n", + "roads_protectedBL = roads[((roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_BUFFERED'].isna()) & ((~roads['BIKELANE_DUAL_PROTECTED'].isna()) | (~roads['BIKELANE_PROTECTED'].isna())))]\n", + "roads_protectedBL" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3d72d3bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13724\n" + ] + } + ], + "source": [ + "for j, row_sel in roads_protectedBL.iterrows():\n", + " road_levels[row_sel['index']] = 1\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "1dc39f33-9de7-4f87-8703-a030a0c9ee75", + "metadata": {}, + "source": [ + "# Left-over road segments" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "8c45b18c-8112-407f-9b0f-0b8e1ac3e5c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13833" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#check if there are any left-over roads (weird roads that didn't fall under any logic)\n", + "left_over_ind = np.setdiff1d(roads['index'].values, list(road_levels.keys()))\n", + "len(left_over_ind)\n", + "roads_left_over = roads[roads['index'].isin(left_over_ind)]\n", + "\n", + "#if less than or equal to 2 lanes and speedlimit < 30mph, then 2\n", + "# if greater than than or equal to 6 lanes or speedlimit > 40mph, then 4\n", + "#otherwise 3\n", + "for j, row_sel in roads_left_over.iterrows():\n", + " if (row_sel['TOTALTRAVELLANES'] <=2) & (row_sel['SPEEDLIMITS_OB']<=30):\n", + " road_levels[row_sel['index']] = 2\n", + " elif (row_sel['TOTALTRAVELLANES'] >=6) | (row_sel['SPEEDLIMITS_OB']>40):\n", + " road_levels[row_sel['index']] = 4\n", + " else:\n", + " road_levels[row_sel['index']] = 3\n", + "len(road_levels)" + ] + }, + { + "cell_type": "markdown", + "id": "2ddcd424-7c46-411b-8a78-002b519c1081", + "metadata": {}, + "source": [ + "# Save info" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "d988cd3c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indlevels
014411
115011
215061
338281
442901
.........
13828132093
13829132853
13830133763
13831134792
13832138263
\n", + "

13833 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " ind levels\n", + "0 1441 1\n", + "1 1501 1\n", + "2 1506 1\n", + "3 3828 1\n", + "4 4290 1\n", + "... ... ...\n", + "13828 13209 3\n", + "13829 13285 3\n", + "13830 13376 3\n", + "13831 13479 2\n", + "13832 13826 3\n", + "\n", + "[13833 rows x 2 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "road_levels_pd = pd.DataFrame({'ind': road_levels.keys(), 'levels':road_levels.values()})\n", + "#save levels\n", + "road_levels_pd.to_csv('level.csv')\n", + "road_levels_pd" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "7f945fe6-f172-40d0-a5d6-21ba8e93eed5", + "metadata": {}, + "outputs": [], + "source": [ + "roads_level_pd = pd.read_csv('level.csv')\n", + "roads = roads.merge(roads_level_pd[['ind', 'levels']], how = 'left', left_on = 'index', right_on = 'ind')\n", + "#save levels merged with road data\n", + "roads.to_csv('roads_merge_level.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "e0469382-e25f-4d1c-ab2f-ee9cf034a1d1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...OBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACHindlevels
011036462645.778625734.415527FLORAL ST NW12734c1c8f9ed5634689fd7116fbaa74f22016...3784921110000.00.002
1110007026134.0766606198.1767587TH ST NW158da4df6640a4f63bc3dee905873701422016...3784922110100.00.012
2110005026554.0693366672.9995125TH ST NW1cc7f7163fe7b5c65303feb636296e30121024...3784923110200.00.022
3110513522193.0302732296.614258KANSAS AVE NW1c448b8a91c9e954e73db5fb1563d10a322022...37849241103105.013.032
4110016025792.8745125866.60644516TH ST NW1051cac1b00b502c715a0aaa169bc566e50050...3784925110400.00.044
..................................................................
13828130585421079.4969481185.059570MALCOLM X AVE SE172c26fc9f2add8684d83f55631cb12f222022...38184291101382800.00.0138283
13829120872320.00000093.154198U ST NE1fecd0265786dfc8087588378879d07e211011...38184301101382900.00.0138292
13830130248320.000000145.923004CONDON TER SE19aafe80dc9210141065a12b36693769c22018...38184311101383000.00.0138302
13831130085822706.7019042905.013428A ST SE1e8a29ad34481906f5074fc78ef7c113d12010...38184321101383100.00.0138312
13832130014021129.5345461139.75134314TH ST SE194fafe51d9bafc4aefef560c583767b622016...38184331101383200.00.0138322
\n", + "

13833 rows × 107 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11036462 645.778625 734.415527 FLORAL ST NW 1 \n", + "1 11000702 6134.076660 6198.176758 7TH ST NW 1 \n", + "2 11000502 6554.069336 6672.999512 5TH ST NW 1 \n", + "3 11051352 2193.030273 2296.614258 KANSAS AVE NW 1 \n", + "4 11001602 5792.874512 5866.606445 16TH ST NW 1 \n", + "... ... ... ... ... ... \n", + "13828 13058542 1079.496948 1185.059570 MALCOLM X AVE SE 1 \n", + "13829 12087232 0.000000 93.154198 U ST NE 1 \n", + "13830 13024832 0.000000 145.923004 CONDON TER SE 1 \n", + "13831 13008582 2706.701904 2905.013428 A ST SE 1 \n", + "13832 13001402 1129.534546 1139.751343 14TH ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 2734c1c8f9ed5634689fd7116fbaa74f 2 2 \n", + "1 58da4df6640a4f63bc3dee9058737014 2 2 \n", + "2 cc7f7163fe7b5c65303feb636296e301 2 1 \n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2 2 \n", + "4 051cac1b00b502c715a0aaa169bc566e 5 0 \n", + "... ... ... ... \n", + "13828 72c26fc9f2add8684d83f55631cb12f2 2 2 \n", + "13829 fecd0265786dfc8087588378879d07e2 1 1 \n", + "13830 9aafe80dc9210141065a12b36693769c 2 2 \n", + "13831 e8a29ad34481906f5074fc78ef7c113d 1 2 \n", + "13832 94fafe51d9bafc4aefef560c583767b6 2 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... OBJECTID \\\n", + "0 0 16 ... 3784921 \n", + "1 0 16 ... 3784922 \n", + "2 0 24 ... 3784923 \n", + "3 0 22 ... 3784924 \n", + "4 0 50 ... 3784925 \n", + "... ... ... ... ... \n", + "13828 0 22 ... 3818429 \n", + "13829 0 11 ... 3818430 \n", + "13830 0 18 ... 3818431 \n", + "13831 0 10 ... 3818432 \n", + "13832 0 16 ... 3818433 \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS SHAPELEN index \\\n", + "0 1 1 0 0 \n", + "1 1 1 0 1 \n", + "2 1 1 0 2 \n", + "3 1 1 0 3 \n", + "4 1 1 0 4 \n", + "... ... ... ... ... \n", + "13828 1 1 0 13828 \n", + "13829 1 1 0 13829 \n", + "13830 1 1 0 13830 \n", + "13831 1 1 0 13831 \n", + "13832 1 1 0 13832 \n", + "\n", + " TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH ADJPLREACH ind levels \n", + "0 0 0.0 0.0 0 2 \n", + "1 0 0.0 0.0 1 2 \n", + "2 0 0.0 0.0 2 2 \n", + "3 10 5.0 13.0 3 2 \n", + "4 0 0.0 0.0 4 4 \n", + "... ... ... ... ... ... \n", + "13828 0 0.0 0.0 13828 3 \n", + "13829 0 0.0 0.0 13829 2 \n", + "13830 0 0.0 0.0 13830 2 \n", + "13831 0 0.0 0.0 13831 2 \n", + "13832 0 0.0 0.0 13832 2 \n", + "\n", + "[13833 rows x 107 columns]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads" + ] + }, + { + "cell_type": "markdown", + "id": "c8118650-7866-4eda-b12d-41b39e426193", + "metadata": {}, + "source": [ + "## Combine with bespoke ridescore info if also calculated\n", + "\n", + "Using blockkey" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "d48a469f-07bb-4f1f-a79b-e6150ccf6929", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BLOCKKEYoriginal_lts
02734c1c8f9ed5634689fd7116fbaa74f2
158da4df6640a4f63bc3dee90587370142
2cc7f7163fe7b5c65303feb636296e3012
3c448b8a91c9e954e73db5fb1563d10a32
4051cac1b00b502c715a0aaa169bc566e4
.........
1382872c26fc9f2add8684d83f55631cb12f23
13829fecd0265786dfc8087588378879d07e22
138309aafe80dc9210141065a12b36693769c2
13831e8a29ad34481906f5074fc78ef7c113d2
1383294fafe51d9bafc4aefef560c583767b62
\n", + "

13833 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " BLOCKKEY original_lts\n", + "0 2734c1c8f9ed5634689fd7116fbaa74f 2\n", + "1 58da4df6640a4f63bc3dee9058737014 2\n", + "2 cc7f7163fe7b5c65303feb636296e301 2\n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2\n", + "4 051cac1b00b502c715a0aaa169bc566e 4\n", + "... ... ...\n", + "13828 72c26fc9f2add8684d83f55631cb12f2 3\n", + "13829 fecd0265786dfc8087588378879d07e2 2\n", + "13830 9aafe80dc9210141065a12b36693769c 2\n", + "13831 e8a29ad34481906f5074fc78ef7c113d 2\n", + "13832 94fafe51d9bafc4aefef560c583767b6 2\n", + "\n", + "[13833 rows x 2 columns]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lts_block = roads[['BLOCKKEY', 'levels']]\n", + "lts_block = lts_block.rename(columns = {'levels': 'original_lts'})\n", + "lts_block" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "f00f2610-076c-4519-a6ac-9e6bdf7a759a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['route_id', 'route_name', 'blockkey', 'function', 'num_lanes',\n", + " 'num_lanes_raw', 'speed_limit', 'speed_limit_raw', 'bike_facility_type',\n", + " 'parking_presence', 'road_width', 'slow_street', 'pavement_condition',\n", + " 'lts_level', 'len', 'crash_count_5yr', 'serious_injury_count_5yr',\n", + " 'fatal_count_5yr', 's_LTS', 's_crash', 's_facility', 'ridescore_v1',\n", + " 'lts_score', 'speedlimit_score', 'num_lanes_score', 'facility_score',\n", + " 'function_score', 'road_width_score', 'pavement_condition_score',\n", + " 'geometry', 'BLOCKKEY', 'original_lts'],\n", + " dtype='object')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\3647879414.py:3: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\3647879414.py:3: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presence...lts_scorespeedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_scoregeometryBLOCKKEYoriginal_lts
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0none1...1060.02505044100LINESTRING Z (-77.01991 38.90358 0, -77.0199 3...4af7e25abf59911305f2724cadc85a083.0
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0none1...4050.07501006875LINESTRING Z (-77.06517 38.95331 0, -77.06517 ...5b3f1964647d6c0b30c8189fd594208c2.0
211037892FOXHALL RD NWfb2d4a22a88f8d4a7566a28b49aee1f9Minor Arterial2225.025.0none0...1050.07505075100LINESTRING Z (-77.09076 38.92905 0, -77.09106 ...fb2d4a22a88f8d4a7566a28b49aee1f92.0
31100160216TH ST NWa9903cf6a4ade86eb26343cd52cf1ffbPrincipal/Primary Arterial4430.030.0none0...1040.02502550100LINESTRING Z (-77.03639 38.96543 0, -77.03639 ...a9903cf6a4ade86eb26343cd52cf1ffb4.0
411033472EMERSON ST NW4cfb9ba5eb597b707b798513462ef851Local2220.020.0none1...7560.075010068100LINESTRING Z (-77.01994 38.94995 0, -77.02201 ...4cfb9ba5eb597b707b798513462ef8512.0
..................................................................
1382913081512SOUTHERN AVE SE03ceb30917e33f51246b9427451bf29aMinor Arterial4430.030.0none0...1040.0250505775LINESTRING Z (-76.98733 38.83212 0, -76.98573 ...03ceb30917e33f51246b9427451bf29a4.0
1383013064282NEW JERSEY AVE SEf8c1e5fae8a0321753beea69ef9d88f1Collector2220.020.0painted_lane1...7560.07550755150LINESTRING Z (-77.00486 38.87841 0, -77.00454 ...f8c1e5fae8a0321753beea69ef9d88f12.0
1383113018522BRUCE PL SE6e06a429de20637fc25ec5ee5bdad443Local2220.020.0none1...7560.07501006675LINESTRING Z (-76.98232 38.85084 0, -76.98101 ...6e06a429de20637fc25ec5ee5bdad4432.0
1383213076442ROBINSON PL SEa476aa40bc64479559e7361d9c105d16Local2220.020.0none0...7560.075010072100LINESTRING Z (-76.9889 38.85219 0, -76.98844 3...a476aa40bc64479559e7361d9c105d162.0
1383313069532PAULDING ST SEcb8e955725acf60fbb9a51e0f8cfd753Local1120.020.0none1...7560.010001006450LINESTRING Z (-76.9956 38.8754 0, -76.99557 38...cb8e955725acf60fbb9a51e0f8cfd7532.0
\n", + "

13834 rows × 32 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c \n", + "2 11037892 FOXHALL RD NW fb2d4a22a88f8d4a7566a28b49aee1f9 \n", + "3 11001602 16TH ST NW a9903cf6a4ade86eb26343cd52cf1ffb \n", + "4 11033472 EMERSON ST NW 4cfb9ba5eb597b707b798513462ef851 \n", + "... ... ... ... \n", + "13829 13081512 SOUTHERN AVE SE 03ceb30917e33f51246b9427451bf29a \n", + "13830 13064282 NEW JERSEY AVE SE f8c1e5fae8a0321753beea69ef9d88f1 \n", + "13831 13018522 BRUCE PL SE 6e06a429de20637fc25ec5ee5bdad443 \n", + "13832 13076442 ROBINSON PL SE a476aa40bc64479559e7361d9c105d16 \n", + "13833 13069532 PAULDING ST SE cb8e955725acf60fbb9a51e0f8cfd753 \n", + "\n", + " function num_lanes num_lanes_raw speed_limit \\\n", + "0 Minor Arterial 4 4 20.0 \n", + "1 Local 2 2 25.0 \n", + "2 Minor Arterial 2 2 25.0 \n", + "3 Principal/Primary Arterial 4 4 30.0 \n", + "4 Local 2 2 20.0 \n", + "... ... ... ... ... \n", + "13829 Minor Arterial 4 4 30.0 \n", + "13830 Collector 2 2 20.0 \n", + "13831 Local 2 2 20.0 \n", + "13832 Local 2 2 20.0 \n", + "13833 Local 1 1 20.0 \n", + "\n", + " speed_limit_raw bike_facility_type parking_presence ... lts_score \\\n", + "0 20.0 none 1 ... 10 \n", + "1 25.0 none 1 ... 40 \n", + "2 25.0 none 0 ... 10 \n", + "3 30.0 none 0 ... 10 \n", + "4 20.0 none 1 ... 75 \n", + "... ... ... ... ... ... \n", + "13829 30.0 none 0 ... 10 \n", + "13830 20.0 painted_lane 1 ... 75 \n", + "13831 20.0 none 1 ... 75 \n", + "13832 20.0 none 0 ... 75 \n", + "13833 20.0 none 1 ... 75 \n", + "\n", + " speedlimit_score num_lanes_score facility_score function_score \\\n", + "0 60.0 25 0 50 \n", + "1 50.0 75 0 100 \n", + "2 50.0 75 0 50 \n", + "3 40.0 25 0 25 \n", + "4 60.0 75 0 100 \n", + "... ... ... ... ... \n", + "13829 40.0 25 0 50 \n", + "13830 60.0 75 50 75 \n", + "13831 60.0 75 0 100 \n", + "13832 60.0 75 0 100 \n", + "13833 60.0 100 0 100 \n", + "\n", + " road_width_score pavement_condition_score \\\n", + "0 44 100 \n", + "1 68 75 \n", + "2 75 100 \n", + "3 50 100 \n", + "4 68 100 \n", + "... ... ... \n", + "13829 57 75 \n", + "13830 51 50 \n", + "13831 66 75 \n", + "13832 72 100 \n", + "13833 64 50 \n", + "\n", + " geometry \\\n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.0199 3... \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... \n", + "2 LINESTRING Z (-77.09076 38.92905 0, -77.09106 ... \n", + "3 LINESTRING Z (-77.03639 38.96543 0, -77.03639 ... \n", + "4 LINESTRING Z (-77.01994 38.94995 0, -77.02201 ... \n", + "... ... \n", + "13829 LINESTRING Z (-76.98733 38.83212 0, -76.98573 ... \n", + "13830 LINESTRING Z (-77.00486 38.87841 0, -77.00454 ... \n", + "13831 LINESTRING Z (-76.98232 38.85084 0, -76.98101 ... \n", + "13832 LINESTRING Z (-76.9889 38.85219 0, -76.98844 3... \n", + "13833 LINESTRING Z (-76.9956 38.8754 0, -76.99557 38... \n", + "\n", + " BLOCKKEY original_lts \n", + "0 4af7e25abf59911305f2724cadc85a08 3.0 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2.0 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2.0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4.0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2.0 \n", + "... ... ... \n", + "13829 03ceb30917e33f51246b9427451bf29a 4.0 \n", + "13830 f8c1e5fae8a0321753beea69ef9d88f1 2.0 \n", + "13831 6e06a429de20637fc25ec5ee5bdad443 2.0 \n", + "13832 a476aa40bc64479559e7361d9c105d16 2.0 \n", + "13833 cb8e955725acf60fbb9a51e0f8cfd753 2.0 \n", + "\n", + "[13834 rows x 32 columns]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_wRS = gpd.read_file('render_dcdata_wCrashes.geojson')\n", + "roads_wRS = roads_wRS.merge(lts_block, how = 'left', left_on = 'blockkey', right_on = 'BLOCKKEY')\n", + "roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n", + "print(roads_wRS.columns)\n", + "roads_wRS" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f4eb05fe-d7c3-47a0-9ff9-739e80f199c2", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:2: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:2: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:3: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:3: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:4: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:4: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:5: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:5: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presence...speedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_scoregeometryBLOCKKEYoriginal_ltslts_100
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0none1...60.02505044100LINESTRING Z (-77.01991 38.90358 0, -77.0199 3...4af7e25abf59911305f2724cadc85a083.040
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0none1...50.07501006875LINESTRING Z (-77.06517 38.95331 0, -77.06517 ...5b3f1964647d6c0b30c8189fd594208c2.060
211037892FOXHALL RD NWfb2d4a22a88f8d4a7566a28b49aee1f9Minor Arterial2225.025.0none0...50.07505075100LINESTRING Z (-77.09076 38.92905 0, -77.09106 ...fb2d4a22a88f8d4a7566a28b49aee1f92.060
31100160216TH ST NWa9903cf6a4ade86eb26343cd52cf1ffbPrincipal/Primary Arterial4430.030.0none0...40.02502550100LINESTRING Z (-77.03639 38.96543 0, -77.03639 ...a9903cf6a4ade86eb26343cd52cf1ffb4.010
411033472EMERSON ST NW4cfb9ba5eb597b707b798513462ef851Local2220.020.0none1...60.075010068100LINESTRING Z (-77.01994 38.94995 0, -77.02201 ...4cfb9ba5eb597b707b798513462ef8512.060
..................................................................
1382913081512SOUTHERN AVE SE03ceb30917e33f51246b9427451bf29aMinor Arterial4430.030.0none0...40.0250505775LINESTRING Z (-76.98733 38.83212 0, -76.98573 ...03ceb30917e33f51246b9427451bf29a4.010
1383013064282NEW JERSEY AVE SEf8c1e5fae8a0321753beea69ef9d88f1Collector2220.020.0painted_lane1...60.07550755150LINESTRING Z (-77.00486 38.87841 0, -77.00454 ...f8c1e5fae8a0321753beea69ef9d88f12.060
1383113018522BRUCE PL SE6e06a429de20637fc25ec5ee5bdad443Local2220.020.0none1...60.07501006675LINESTRING Z (-76.98232 38.85084 0, -76.98101 ...6e06a429de20637fc25ec5ee5bdad4432.060
1383213076442ROBINSON PL SEa476aa40bc64479559e7361d9c105d16Local2220.020.0none0...60.075010072100LINESTRING Z (-76.9889 38.85219 0, -76.98844 3...a476aa40bc64479559e7361d9c105d162.060
1383313069532PAULDING ST SEcb8e955725acf60fbb9a51e0f8cfd753Local1120.020.0none1...60.010001006450LINESTRING Z (-76.9956 38.8754 0, -76.99557 38...cb8e955725acf60fbb9a51e0f8cfd7532.060
\n", + "

13834 rows × 33 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c \n", + "2 11037892 FOXHALL RD NW fb2d4a22a88f8d4a7566a28b49aee1f9 \n", + "3 11001602 16TH ST NW a9903cf6a4ade86eb26343cd52cf1ffb \n", + "4 11033472 EMERSON ST NW 4cfb9ba5eb597b707b798513462ef851 \n", + "... ... ... ... \n", + "13829 13081512 SOUTHERN AVE SE 03ceb30917e33f51246b9427451bf29a \n", + "13830 13064282 NEW JERSEY AVE SE f8c1e5fae8a0321753beea69ef9d88f1 \n", + "13831 13018522 BRUCE PL SE 6e06a429de20637fc25ec5ee5bdad443 \n", + "13832 13076442 ROBINSON PL SE a476aa40bc64479559e7361d9c105d16 \n", + "13833 13069532 PAULDING ST SE cb8e955725acf60fbb9a51e0f8cfd753 \n", + "\n", + " function num_lanes num_lanes_raw speed_limit \\\n", + "0 Minor Arterial 4 4 20.0 \n", + "1 Local 2 2 25.0 \n", + "2 Minor Arterial 2 2 25.0 \n", + "3 Principal/Primary Arterial 4 4 30.0 \n", + "4 Local 2 2 20.0 \n", + "... ... ... ... ... \n", + "13829 Minor Arterial 4 4 30.0 \n", + "13830 Collector 2 2 20.0 \n", + "13831 Local 2 2 20.0 \n", + "13832 Local 2 2 20.0 \n", + "13833 Local 1 1 20.0 \n", + "\n", + " speed_limit_raw bike_facility_type parking_presence ... \\\n", + "0 20.0 none 1 ... \n", + "1 25.0 none 1 ... \n", + "2 25.0 none 0 ... \n", + "3 30.0 none 0 ... \n", + "4 20.0 none 1 ... \n", + "... ... ... ... ... \n", + "13829 30.0 none 0 ... \n", + "13830 20.0 painted_lane 1 ... \n", + "13831 20.0 none 1 ... \n", + "13832 20.0 none 0 ... \n", + "13833 20.0 none 1 ... \n", + "\n", + " speedlimit_score num_lanes_score facility_score function_score \\\n", + "0 60.0 25 0 50 \n", + "1 50.0 75 0 100 \n", + "2 50.0 75 0 50 \n", + "3 40.0 25 0 25 \n", + "4 60.0 75 0 100 \n", + "... ... ... ... ... \n", + "13829 40.0 25 0 50 \n", + "13830 60.0 75 50 75 \n", + "13831 60.0 75 0 100 \n", + "13832 60.0 75 0 100 \n", + "13833 60.0 100 0 100 \n", + "\n", + " road_width_score pavement_condition_score \\\n", + "0 44 100 \n", + "1 68 75 \n", + "2 75 100 \n", + "3 50 100 \n", + "4 68 100 \n", + "... ... ... \n", + "13829 57 75 \n", + "13830 51 50 \n", + "13831 66 75 \n", + "13832 72 100 \n", + "13833 64 50 \n", + "\n", + " geometry \\\n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.0199 3... \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... \n", + "2 LINESTRING Z (-77.09076 38.92905 0, -77.09106 ... \n", + "3 LINESTRING Z (-77.03639 38.96543 0, -77.03639 ... \n", + "4 LINESTRING Z (-77.01994 38.94995 0, -77.02201 ... \n", + "... ... \n", + "13829 LINESTRING Z (-76.98733 38.83212 0, -76.98573 ... \n", + "13830 LINESTRING Z (-77.00486 38.87841 0, -77.00454 ... \n", + "13831 LINESTRING Z (-76.98232 38.85084 0, -76.98101 ... \n", + "13832 LINESTRING Z (-76.9889 38.85219 0, -76.98844 3... \n", + "13833 LINESTRING Z (-76.9956 38.8754 0, -76.99557 38... \n", + "\n", + " BLOCKKEY original_lts lts_100 \n", + "0 4af7e25abf59911305f2724cadc85a08 3.0 40 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2.0 60 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2.0 60 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4.0 10 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2.0 60 \n", + "... ... ... ... \n", + "13829 03ceb30917e33f51246b9427451bf29a 4.0 10 \n", + "13830 f8c1e5fae8a0321753beea69ef9d88f1 2.0 60 \n", + "13831 6e06a429de20637fc25ec5ee5bdad443 2.0 60 \n", + "13832 a476aa40bc64479559e7361d9c105d16 2.0 60 \n", + "13833 cb8e955725acf60fbb9a51e0f8cfd753 2.0 60 \n", + "\n", + "[13834 rows x 33 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#change scale from 1 to 4 to 0-100 levels\n", + "roads_wRS['lts_100'] = 0\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n", + "roads_wRS" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "fa747659-ceb7-493a-b593-a0a4f78ead3d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([3., 2., 4., 1.])" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_wRS['original_lts'].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "507338e2-5f61-4428-a79f-692df222e01b", + "metadata": {}, + "outputs": [], + "source": [ + "roads_wRS['seg_id'] = roads_wRS.index" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "4e0edab5-ccf9-4eab-a59a-704b1a426d48", + "metadata": {}, + "outputs": [], + "source": [ + "roads_wRS.to_file('road_lts_wCrashes.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "f3e78256-7d98-48f7-bbd3-81102eb531c9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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RZ55f7x53WsNROfOnZM+ffrIvHnzzETLVzJ79mzz/FYNkk6ivG3bNnn77bcJRAAAoGAahprWbeTXl2fo0KHywAMPmJUirhaIEhISnJMlWzp16iTz58+X3NxcsyyXt1FDBAAAbsjSpUtl+/btpsmsMHThds8F1nX/4sWLpnbKdVF3byEQAQCA65aammo6UOvSWtcyA7euWerKWjjD87i3EIgAAMB1S0pKMgu0N2/e3HksLy9P1q9fb9YNzc7OdltfVEVERJhaIlf6HLo2qS7W7gsEIgAAcN10UfVdu3a5HXvyySelYcOG8sILL+QLQ6p169byxRdfuB3TGqYWLVr4pP+QIhABAIDrFhoaKjExMW7HKlasaGp6rOPjx4+Xo0ePyscff2z2db4hrT3SeYh06L12stYO1Z9++qn4CoEIAAA/p8PhS/LrpKWlmTmVLLoq/cqVK2X06NHy/vvvm4kZZ8yY4bMh94pABACAn9JZo3WiRJ0byFtCgkPM696ItWvXuu0vXLgwX5m4uDgzMs1fEIgAAPBTOnmhzhpdkpbuKKkIRAAA+DENJ3YMKN7GavcAAMD2CEQAAMD2CEQAAMD2CEQAAHiRtUQF/OuaEogAAPACawbmzMxMrncRs67pjcxyzSgzAAC8QJewuPnmm82aXSokJMRnC5mWppqhzMxMc0312ha0TEhhEYgAAPASXdRUWaEIRUPDkHVtrxeBCAAAL9EaoZo1a0p4eLjk5uZy3YuANpPdSM2QhUAEAICX6Rd4UXyJo+jQqRoAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANie3wSiyZMnS5kyZWTUqFHOYw6HQyZOnCi1atWS4OBgadu2rezZs8ftcdnZ2TJ8+HAJCwuTihUrSvfu3eXIkSNuZU6dOiV9+/aVypUrm01vnz592mvvDQAA+De/CERbt26VuXPnSpMmTdyOT5kyRaZOnSozZ840ZSIiIqRDhw5y9uxZZxkNUMuXL5elS5fKhg0b5Ny5c9KtWzfJy8tzlundu7fs2LFDVq1aZTa9raEIAADALwKRBpg+ffrIvHnzpEqVKm61Q9OnT5cJEyZIz549JSYmRj766CPJzMyUJUuWmDIZGRkyf/58eeedd6R9+/Zy1113yaJFi2TXrl2yZs0aUyY5OdmEoL/+9a/SunVrs+lrffnll7J//36fvW8AAOA/fB6Ihg4dKg888IAJNK5SUlLk+PHj0rFjR+ex8uXLS1xcnGzatMnsJyUlSW5urlsZbV7T8GSVSUhIMM1kLVu2dJZp1aqVOWaVAQAA9hboyxfXZq7t27eb5jBPGoZUjRo13I7r/qFDh5xlypUr51azZJWxHq8/w8PD8z2/HrPKFET7JulmOXPmzDW/PwAAUDL4rIYoNTVVRo4caZq4KlSocNly2tHalTaleR7z5FmmoPJXex7t5G11wtYtMjLyKu8IAACUVD4LRNrclZ6eLs2bN5fAwECzrVu3TmbMmGFuWzVDnrU4+hjrPu1knZOTY0aRXanMiRMn8r3+yZMn89U+uRo/frzpo2RtGuAAAEDp5LNA1K5dO9P5WUd8WVuLFi1MB2u9Xa9ePRNm4uPjnY/R8KOhqU2bNmZfw1RQUJBbmbS0NNm9e7ezjHai1kCTmJjoLLNlyxZzzCpTEO2vVKlSJbcNAACUTj7rQxQaGmo6P7vSeYSqVavmPK5D6idNmiQNGjQwm94OCQkxw+iVNmUNGDBAxowZYx5XtWpVGTt2rDRu3NjZSTs6Olo6d+4sAwcOlDlz5phjgwYNMkPzo6KivP6+AQCA//Fpp+qrGTdunGRlZcmQIUNMs5iOFFu9erUJU5Zp06aZJrZevXqZslrztHDhQgkICHCWWbx4sYwYMcI5Gk0nb9S5jQAAAFQZh/YuxlXpKDOtkdKmNprPAKB00dHOefEfS2z93wfQbD2QKgEd+klsbKyvTw1e+v72+TxEAAAAvkYgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtkcgAgAAtnddgahevXry73//O9/x06dPm/sAAABKfSA6ePCg5OXl5TuenZ0tR48eLYrzAgAA8JrAaym8YsUK5+2vv/5aKleu7NzXgPTNN9/IbbfdVrRnCAAA4E+BqEePHuZnmTJlpH///m73BQUFmTD0zjvvFO0ZAgAA+FMgunTpkvlZt25d2bp1q4SFhRXXeQEAAPhnILKkpKQU/ZkAAACUpECktL+Qbunp6c6aI8uHH35YFOcGAADgv4Ho1Vdflddee01atGghNWvWNH2KAAAAbBWIZs+eLQsXLpS+ffsW/RkBAACUhHmIcnJypE2bNkV/NgAAACUlED399NOyZMmSoj8bAACAktJkduHCBZk7d66sWbNGmjRpYuYgcjV16tSiOj8AAAD/DEQ//PCDNGvWzNzevXu32310sAYAALYIRN99913RnwkAAEBJ6kMEAAAgdq8huv/++6/YNPbtt9/eyDkBAAD4fyCy+g9ZcnNzZceOHaY/keeirwAAAKUyEE2bNq3A4xMnTpRz587d6DkBAACU3D5Ejz/+OOuYAQAAeweihIQEqVChQlE+JQAAgH82mfXs2dNt3+FwSFpammzbtk1efvnlojo3AAAA/w1ElStXdtsvW7asREVFyWuvvSYdO3YsqnMDAADw30C0YMGCoj8TAACAkhSILElJSZKcnGzmJGrUqJHcddddRXdmAAAA/hyI0tPT5dFHH5W1a9fKzTffbPoQZWRkmAkbly5dKtWrVy/6MwUAAPCnUWbDhw+XM2fOyJ49e+S3336TU6dOmUkZ9diIESOK/iwBAAD8rYZo1apVsmbNGomOjnYe0yaz999/n07VAADAHjVEly5dkqCgoHzH9ZjeBwAAUOoD0R/+8AcZOXKkHDt2zHns6NGjMnr0aGnXrl1Rnh8AAIB/BqKZM2fK2bNn5bbbbpPbb79d6tevL3Xr1jXH3nvvvUI/z6xZs6RJkyZSqVIls7Vu3Vq++uor5/3aWVvXR6tVq5YEBwdL27ZtTb8lV9nZ2aZPU1hYmFSsWFG6d+8uR44ccSujfZz69u1r5k/STW+fPn36et46AAAoha4rEEVGRsr27dvln//8p4waNcp0pF65cqUZhl+nTp1CP4+WfeONN8wM17ppzdNDDz3kDD1TpkyRqVOnmgC2detWiYiIkA4dOpjgZdHXX758uRndtmHDBrO4bLdu3SQvL89Zpnfv3rJjxw7T90k3va2hCAAAwHBcg2+++cYRHR3tyMjIyHff6dOnHY0aNXKsX7/ecSOqVKni+Otf/+q4dOmSIyIiwvHGG28477tw4YKjcuXKjtmzZztfMygoyLF06VJnmaNHjzrKli3rWLVqldnfu3evQ9/m5s2bnWUSEhLMsX379hX6vPQ962MKeu8AgJItMTHRkfD6MMfFz940m97WYyj5Cvv9fU01RNOnT5eBAwea5i1P2hQ1ePBgU6NzPbRGR2t5zp8/b5rOUlJS5Pjx426j1sqXLy9xcXGyadMms681Urm5uW5ltHktJibGWUYXnNVza9mypbNMq1atzDGrDAAAsLdrCkQ7d+6Uzp07X/Z+DSYaUq7Frl275KabbjJh55lnnjHNXzqEX8OQqlGjhlt53bfu05/lypWTKlWqXLFMeHh4vtfVY1aZgmjfJJ1XyXUDAACl0zUFohMnThQ43N4SGBgoJ0+evKYT0EVhtU/P5s2b5dlnn5X+/fvL3r17nffrsiCutKO15zFPnmUKKn+155k8ebKzE7Zu2m8KAACUTtcUiGrXrm1qdC7nhx9+kJo1a17TCWgNj45Sa9GihQkhTZs2lXfffdd0oFaetTi6bIhVa6RlcnJyzCiyK5XRIOdJg5tn7ZOr8ePHm+VIrC01NfWa3hcAACilgahr167y5z//WS5cuJDvvqysLHnllVfMCK8boTU32lylw/g1zMTHxzvv0/Czbt06adOmjdlv3ry5qbFyLZOWlmaWEbHKaH8kDTSJiYnOMlu2bDHHrDIF0SY8azoAawMAAKXTNS3d8dJLL8myZcvkjjvukGHDhpnmLm120hXvddkO7Rg9YcKEQj/fiy++KF26dDHNUTqUXjtV64KxOjRen1eH1E+aNEkaNGhgNr0dEhJihtErbcoaMGCAjBkzRqpVqyZVq1aVsWPHSuPGjaV9+/amjC4vov2etDP4nDlzzLFBgwaZ4KbnDwAAcE2BSJuYdGSW9vXRJiWtzVEaXjp16iQffPDBFZuhPGlTls4HpLU6Gm50kkYNQzrXkBo3bpypeRoyZIhpFtORYqtXr5bQ0FDnc0ybNs30XerVq5cpqzNlL1y4UAICApxlFi9ebOZKskaj6eSNOrcRAACAyTI69v56LoUGlAMHDphQpLU3niO9ShsdZaahTZvaaD4DgNJFJ//Ni/9YYuv/PoBm64FUCejQT2JjY319avDS9/d1rXavNADxiwIAAGy7dAcAAEBpQiACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC2RyACAAC259NANHnyZImNjZXQ0FAJDw+XHj16yP79+93KOBwOmThxotSqVUuCg4Olbdu2smfPHrcy2dnZMnz4cAkLC5OKFStK9+7d5ciRI25lTp06JX379pXKlSubTW+fPn3aK+8TAAD4N58GonXr1snQoUNl8+bNEh8fLxcvXpSOHTvK+fPnnWWmTJkiU6dOlZkzZ8rWrVslIiJCOnToIGfPnnWWGTVqlCxfvlyWLl0qGzZskHPnzkm3bt0kLy/PWaZ3796yY8cOWbVqldn0toYiAACAMg6tgvETJ0+eNDVFGpTuu+8+UzukNUMaeF544QVnbVCNGjXkzTfflMGDB0tGRoZUr15dPvnkE3nkkUdMmWPHjklkZKSsXLlSOnXqJMnJydKoUSMTvFq2bGnK6O3WrVvLvn37JCoq6qrndubMGVOzpK9XqVKlYr4SAABv0j+48+I/ltj6kb/vH0iVgA79TCsGSrbCfn/7VR8iPVlVtWpV8zMlJUWOHz9uao0s5cuXl7i4ONm0aZPZT0pKktzcXLcyGqJiYmKcZRISEszFsMKQatWqlTlmlfGkwUsvousGAABKJ78JRFob9Nxzz8m9995rwozSMKS0RsiV7lv36c9y5cpJlSpVrlhGa5486TGrTEH9m6z+RrppjRMAACid/CYQDRs2TH744Qf59NNP891XpkyZfOHJ85gnzzIFlb/S84wfP97UWFlbamrqNbwbAABQkvhFINIRYitWrJDvvvtO6tSp4zyuHaiVZy1Oenq6s9ZIy+Tk5JhRZFcqc+LEiQL7LHnWPrk2zWlbo+sGAABKJ58GIq2h0ZqhZcuWybfffit169Z1u1/3NczoCDSLhh/tdN2mTRuz37x5cwkKCnIrk5aWJrt373aW0c7TWsuTmJjoLLNlyxZzzCoDAADsK9CXL65D7pcsWSL/+7//a+YismqCtM+OzjmkzVk6wmzSpEnSoEEDs+ntkJAQM4zeKjtgwAAZM2aMVKtWzXTIHjt2rDRu3Fjat29vykRHR0vnzp1l4MCBMmfOHHNs0KBBZmh+YUaYAQCA0s2ngWjWrFnmp0626GrBggXyxBNPmNvjxo2TrKwsGTJkiGkW05Fiq1evNgHKMm3aNAkMDJRevXqZsu3atZOFCxdKQECAs8zixYtlxIgRztFoOnmjzm0EAADgV/MQ+TPmIQKA0ot5iEqvEjkPEQAAgC8QiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0RiAAAgO0F2v4KADaRk5MjO3fudDvWtGlTKVeunM/OCQD8BYEIsAkNQ7sWvCWN6tQw+3uPnBB58nmJjY319akBgM8RiAAb0TAUWz/S16cBAH6HPkQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2CEQAAMD2mKkasCmHOGTv3r1ux1jbDIBdEYgAm8rKzJIvVifK0YyKZv/IoZ/kSRHWNgNgSwQiwMbCIyKlflRjX58GAPgcfYgAAIDtEYgAAIDtEYgAAIDtEYgAAIDtEYgAAIDtEYgAAIDtEYgAAIDt+TQQrV+/Xh588EGpVauWlClTRj7//HO3+x0Oh0ycONHcHxwcLG3btpU9e/a4lcnOzpbhw4dLWFiYVKxYUbp37y5HjhxxK3Pq1Cnp27evVK5c2Wx6+/Tp0155jwAAwP/5NBCdP3/eLBUwc+bMAu+fMmWKTJ061dy/detWiYiIkA4dOsjZs2edZUaNGiXLly+XpUuXyoYNG+TcuXPSrVs3ycvLc5bp3bu37NixQ1atWmU2va2hCAAAwOczVXfp0sVsBdHaoenTp8uECROkZ8+e5thHH30kNWrUkCVLlsjgwYMlIyND5s+fL5988om0b9/elFm0aJFERkbKmjVrpFOnTpKcnGxC0ObNm6Vly5amzLx586R169ayf/9+iYqK8uI7BgAA/shv+xClpKTI8ePHpWPHjs5j5cuXl7i4ONm0aZPZT0pKktzcXLcy2rwWExPjLJOQkGCayawwpFq1amWOWWUAAIC9+e1aZhqGlNYIudL9Q4cOOcuUK1dOqlSpkq+M9Xj9GR4enu/59ZhVpiDaN0k3y5kzZ27wHQEAAH/ltzVEFu1s7dmU5nnMk2eZgspf7XkmT57s7IStmzbDAQCA0slvA5F2oFaetTjp6enOWiMtk5OTY0aRXanMiRMn8j3/yZMn89U+uRo/frzpo2RtqampRfK+AACA//HbQFS3bl0TZuLj453HNPysW7dO2rRpY/abN28uQUFBbmXS0tJk9+7dzjLaeVoDTWJiorPMli1bzDGrTEG0v1KlSpXcNgAAUDr5tA+RDpE/cOCAW0dqHRJftWpVueWWW8yQ+kmTJkmDBg3MprdDQkLMMHqlTVkDBgyQMWPGSLVq1czjxo4dK40bN3aOOouOjpbOnTvLwIEDZc6cOebYoEGDzNB8RpgBAACfB6Jt27bJ/fff79x/7rnnzM/+/fvLwoULZdy4cZKVlSVDhgwxzWI6Umz16tUSGhrqfMy0adMkMDBQevXqZcq2a9fOPDYgIMBZZvHixTJixAjnaDSdvPFycx8BgD/QGvGdO3fmO65zt+lgEgClKBDpzNPauflytNOzzlSt2+VUqFBB3nvvPbNdjtYc6fxEAFBSaBja8uHX0rDO7c5j+478LPKUSGxsrE/PDSiN/HbYPQDYnYahu2+P8fVpALbgt52qAQAAvIVABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI+ZqgH8znFJ9u7d63Y1WDcLgF0QiAAYmZlZsnt9gtQ+8vvCoaybBcBOCEQAnG4Lr8PaWQBsiT5EAADA9ghEAADA9ghEAADA9ghEAADA9ghEAADA9ghEAADA9ghEAADA9ghEAADA9ghEAADA9pipGgB8ICcnR3bu3Ol2jLXjAN8hEAGAD2gY2rXgLWlUp4bZ33vkhMiTz0tsbCyfB+ADBCIAJUppqlnRMBRbP9LXpwGAQFQylKYvAOBGUbMCoDhQQ1RCvgAWLF0jdW5tYPaPHPpJnhShah22Rc0KgKJGICohNAzVj2rs69MAAKBUYtg9AACwPQIRAACwPQIRAACwPfoQAQBQDBghXLIQiAAAKAaMEC5ZCEQl4C+KvXv3ysWLzDkEACUNI4RLDgKRn086p84fOCTHq7SRhnfe7dNzAwCgtCIQlYBJ5zIzM2V3lk9PCQBwjTX81O6XLAQiAACKoYaf2v2ShUAEAEAx1PBTu1+yEIhKIsclUxXrisVeAQC4fgSiEigzM0t2r0+Q2kd+H3m278jPIk+x2CsAANeLQFRC3RZeR+6+PcbXpwEAgJSGSSgJRAAA4IZoGHpn1d+kxu23mf0TPx+UMVKyWi4IRAAA4IZpGLolJkpKKgIRgBLNIQ4GGQC4YQQiACVaVmaWfLE6UY5mVDT7Rw79JE+WsKp6bykN/TyA4kIgAlDihUdESv2oxr4+Db9XGvp5AMXFVoHogw8+kLfeekvS0tLkzjvvlOnTp8t//ud/+vq0UIz4ixgoXf08fNkU61mjVtBSHfUu5nn1PFF0bBOIPvvsMxk1apQJRffcc4/MmTNHunTpYn6Bb7nlFl+fHrw0lf7eIydEnnze+RdxQYGptDQj8J91yf4C1tvhF8v69JzszLMptqDmWM8at0M/7pPup36VNg1/30fJYptANHXqVBkwYIA8/fTTZl9rh77++muZNWuWTJ482denBy9NpV/Ql86pjSkSc+v//4u5tEx0WVr+s7ZLsPP8Aj6w/xdpfilIWkY18/WplUqF+b0qTFOsa41bZuZ5kVMniumMUdwC7fKLn5SUJH/605/cjnfs2FE2bdokvmSX/+z95XoW+KUTEFRqJ7ksDf9ZX3Ow89Olba71Czjz/HmRw6k+P09/uX6l4g8GP/3dLBYO9z8+c3Nzzc+goCC/fe+2CES//vqr5OXlSY0avzebWHT/+PHjBT4mOzvbbJaMjAzz88yZM0V6bhrU/vzX9+TmmuFmP/3wEYnLPic5Lv9R7jh4TI7mlJXdO7eY/YO/JMuZE+nyrz2JZv/HYykSmpQh586dE7vbv3+/LP7X6steT72Wubl15MKFTLOfk5Mt+0+kOq9labqeei2OpO6X7Mwss39s38+y72i6rN39c4n6vdL3kXsh2/k+crNzrvg+fvlpr2zbvUMO/1/IPfprmjTr8Z8SFRXl97+bV/o8iuIz8fydOJlyWJLOBLg9n5b531WbJCy8ltn/Nf2YPNS5jc+vn69/r9Sxwz9LUrlfndfrWv+N+evvZlHY73EtUvf9JMc3bZb023+vnf85LV1+yA2T26OaXPb3qnnz5sVybtb3tsPhuHJBhw0cPXpUr4Jj06ZNbsf/8pe/OKKiogp8zCuvvGIew8Y14HeA3wF+B/gd4HdASvw1SE1NvWJWsEUNUVhYmAQEBOSrDUpPT89Xa2QZP368PPfcc879S5cuyW+//SbVqlWTMmXKFPs5o+CUHxkZKampqVKpUiUukZ/icyoZ+JxKBj6nG6c1Q2fPnpVatX6v9bwcWwQibaPUqrj4+Hj54x//6Dyu+w899FCBjylfvrzZXN18883Ffq64Og1DBCL/x+dUMvA5lQx8TjemcuXKVy1ji0CktLanb9++0qJFC2ndurXMnTtXDh8+LM8884yvTw0AAPiYbQLRI488Iv/+97/ltddeMxMzxsTEyMqVK+XWW2/19akBAAAfs00gUkOGDDEbSiZtwnzllVfyNWXCv/A5lQx8TiUDn5P3lNGe1V58PQAAAL/DvPAAAMD2CEQAAMD2CEQAAMD2CETwK7rQri6qGhoaKuHh4dKjRw8zJbwr7fY2ceJEM8lWcHCwtG3bVvbs2eOzc7Y7/cx0stJRo0Y5j/EZ+Y+jR4/K448/biaVDQkJkWbNmpklgyx8Vr538eJFeemll6Ru3brm/7R69eqZEdE6IbCFz6n4EYjgV9atWydDhw6VzZs3m4kz9T8KXYT3vC50+X+mTJkiU6dOlZkzZ8rWrVslIiJCOnToYGYihXfp9dc5vZo0+X19Ij4j/3Lq1Cm55557zIKaX331lVls85133nGbZJZ/T7735ptvyuzZs83/acnJyeYzeeutt+S9995zluFz8oKiXDMMKGrp6elmDZp169aZ/UuXLjkiIiIcb7zxhrPMhQsXHJUrV3bMnj2bD8CLzp4962jQoIEjPj7eERcX5xg5ciSfkZ954YUXHPfee+9l7+ffk3944IEHHE899ZTbsZ49ezoef/xxc5vPyTuoIYJfy8jIMD+rVq1qfqakpJg16bTWyHWejri4ONm0aZPPztOOtCbvgQcekPbt27sd5zPyHytWrDCz8z/88MOmCfquu+6SefPmOe/ns/IP9957r3zzzTfy448/mv2dO3fKhg0bpGvXrmafz8k7bDUxI0oWbTPXJVf0PwudWVxZC/R6Lsqr+4cOHfLJedrR0qVLZfv27abJzBOfkf/45ZdfZNasWebf0YsvviiJiYkyYsQI80dEv379+Kz8xAsvvGD++GvYsKFZiDwvL09ef/11eeyxx8z9/JvyDgIR/NawYcPkhx9+MH8pedJOvJ7hyfMYikdqaqqMHDlSVq9eLRUqVLhsOT4j39NOuVpDNGnSJLOvNUQ6AEFDkgYiC5+Vb3322WeyaNEiWbJkidx5552yY8cOM0hBB47079/fWY7PqXjRZAa/NHz4cFPd/91330mdOnWcx7UDtetfTJb09PR8tUYoHjpCSa938+bNJTAw0GzaGX7GjBnmtvU58Bn5Xs2aNaVRo0Zux6Kjo83C1op/T/7h+eeflz/96U/y6KOPSuPGjc1C5KNHjzYjOBWfk3cQiOBXtKZHa4aWLVsm3377rRmG6kr39T8HHYFmycnJMV/Ibdq08cEZ20+7du1k165d5q9Ya9NaiD59+pjbOmSYz8g/6Agzz2krtJ+Ktag1/578Q2ZmppQt6/51rE1n1rB7Picv8VLnbaBQnn32WTNibO3atY60tDTnlpmZ6SyjI8y0zLJlyxy7du1yPPbYY46aNWs6zpw5w1X2EddRZnxG/iMxMdERGBjoeP311x0//fSTY/HixY6QkBDHokWLnGX49+R7/fv3d9SuXdvx5ZdfOlJSUsz/bWFhYY5x48Y5y/A5FT8CEfyKZvSCtgULFjjL6BDUV155xQy/L1++vOO+++4zwQj+E4j4jPzHF1984YiJiTH/Vho2bOiYO3eu2/18Vr6nf8zpv59bbrnFUaFCBUe9evUcEyZMcGRnZzvL8DkVP1a7BwAAtkcfIgAAYHsEIgAAYHsEIgAAYHsEIgAAYHsEIgAAYHsEIgAAYHsEIgAAYHsEIgAAYHsEIgBepSt2f/7555e9/+DBg6aMrosGAN5CIALgVWlpadKlSxeu+lWMHDlSmjdvLuXLl5dmzZpxvYBiRiAC4DU5OTkSERFhvuRLqtzcXK+8ji7t99RTT8kjjzzildcD7I5ABKDYtG3bVoYNGybPPfechIWFSYcOHfI1mSUmJspdd90lFSpUkBYtWsj333+f73n27t0rXbt2lZtuuklq1Kghffv2lV9//dV5/9///ndp3LixBAcHS7Vq1aR9+/Zy/vx55/0ffvih3HnnnSaI1axZ05yT5fDhw/LQQw+Z565UqZL06tVLTpw44bx/4sSJpoZGn6NevXrmOTSsZGRkyKBBgyQ8PNw87g9/+IPs3Lnzqtdk//795hrs27fP7fjUqVPltttuM8+tZsyYIUOHDjWvCaD4EYgAFKuPPvpIAgMDZePGjTJnzhy3+zS0dOvWTaKioiQpKcmEj7Fjx+ZrYouLizOhZNu2bbJq1SoTWDS4WPc/9thjpjYlOTlZ1q5dKz179nQGi1mzZplgoeFl165dsmLFCqlfv765T8v06NFDfvvtN1m3bp3Ex8fLzz//nK9W5sCBA/K3v/1N/vGPfzj7Nj3wwANy/PhxWblypTn3u+++W9q1a2ee60r0vWpT2OLFi92OL1myRHr37m3CEgAf+P8L3wNA0YqLi3M0a9bM7Zj+t7N8+XJze86cOY6qVas6zp8/77x/1qxZpsz3339v9l9++WVHx44d3Z4jNTXVlNm/f78jKSnJ3D548GCB51CrVi3HhAkTCrxv9erVjoCAAMfhw4edx/bs2WOeLzEx0ey/8sorjqCgIEd6erqzzDfffOOoVKmS48KFC27Pd/vtt5v3dDVTp0511KtXz7mv70NfU1/bk75+06ZNr/qcAG4MNUQAipU2g12O1ug0bdpUQkJCnMdat27tVkZrX7777jvTpGVtDRs2NPdpbY4+XmtmtMns4Ycflnnz5smpU6fM/enp6XLs2DFz/+VePzIy0myWRo0ayc0332zus9x6661SvXp1t3M6d+6caZ5zPa+UlBRzTlfz6KOPyqFDh2Tz5s1mX2uLtAZMXxuAbwT66HUB2ETFihUve5/VrHUlly5dkgcffFDefPPNfPdpf6CAgADT1LVp0yZZvXq1vPfeezJhwgTZsmWL6bd0Jfr6BTVReR73fA96Tvra2jznScPU1ehj77//ftNM1qpVK/n0009l8ODBV30cgOJDDREAn9EaEe2InJWV5Txm1ZpYtG/Onj17TIdj7fvjullBRcPLPffcI6+++qrplF2uXDlZvny5hIaGmsd98803l3197VSdmprq1oFbO0xHR0df9rz1nLT/kPaN8jynq4UwS58+feSzzz6ThIQEU6uktUYAfIdABMBntBNx2bJlZcCAASaIaAflt99+262MdojWjsracVpHpP3yyy+mJkg7Uefl5ZmaoEmTJpkO1xpuli1bJidPnnQGGu2o/c4775hRWz/99JNs377d1CIpHY3WpEkTE070uD5/v379TCfuKzX16eO0aU87ZH/99ddmMkmtoXrppZfMeRSGdvw+c+aMPPvss6a2qHbt2vk6cmsHbg1eGhj1tm46dQGAokcgAuAz2u/miy++MGFIh95rU5dn01itWrXMCDUNP506dZKYmBgzaWHlypVNmNIh7+vXrzfD8u+44w4TSjQAWZM/9u/fX6ZPny4ffPCBGXqvo9o0GClrCoAqVarIfffdZ4KODnPXmpsr0cdpeNPHaDDT19UaHg1GOi1AYeh5a1Og1pBpIPP09NNPm2uiI/N+/PFHc1s37RMFoOiV0Z7VxfC8AAAAJQY1RAAAwPYIRABQxLRpznU4vuvmOSEjAP9AkxkAFDGdY+hya55pHyMd/QbAvxCIAACA7dFkBgAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAbI9ABAAAxO7+H9gdbyBE/w0bAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sns.histplot(data=roads_wRS, x=\"ridescore_v1\", hue=\"original_lts\", multiple = 'dodge', palette = 'Set2')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lts/LTS.xlsx b/lts/LTS.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ca4f6b5241a998a31fbda9d6d376ef8b3bf900c3 GIT binary patch literal 22531 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 literal 0 HcmV?d00001 diff --git a/lts/LTS_preprocessing.ipynb b/lts/LTS_preprocessing.ipynb new file mode 100644 index 0000000..1817537 --- /dev/null +++ b/lts/LTS_preprocessing.ipynb @@ -0,0 +1,9524 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f98adb95-d4bf-4945-9e09-0d6b5bc873b2", + "metadata": {}, + "source": [ + "# Implement LTS (2022 version)\n", + "\n", + "This notebook implements the [Level of Traffic Stress](https://peterfurth.sites.northeastern.edu/2014/05/21/criteria-for-level-of-traffic-stress/) model. Specifically, the [2022 edition](https://bpb-us-e1.wpmucdn.com/sites.northeastern.edu/dist/e/618/files/2014/05/LTS-Tables-v2.2.pdf) though there is more background in the [original model](https://peterfurth.sites.northeastern.edu/level-of-traffic-stress/).\n", + "\n", + "In short, this quantifies how stressful or comfortable a road is to bike on.\n", + "* Level 1: Cyclists are not in contact with traffic (except for slow, low volume traffic); comfortable for all level of cycling abilities (including children).\n", + "* Level 2: Cyclists have their own space and intersections are easy to navigate; comfortable for adult cyclists.\n", + "* Level 3: Cyclists interact with some moderate/multi-lane traffic or close to higher-speed traffic; acceptable for 'enthused and confident' cyclists.\n", + "* Level 4: Cyclists interact with or are near high-speed traffic; acceptable for 'strong and fearless' cyclists.\n", + "\n", + "The first step was find correspondence between the descriptions and the available [DC road data](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about). This is summarized in the table below.\n", + "\n", + "| [Method](https://bpb-us-e1.wpmucdn.com/sites.northeastern.edu/dist/e/618/files/2014/05/LTS-Tables-v2.2.pdf) | [Data](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) |\n", + "| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n", + "| Bike lane type (bikes in mixed traffic) | TOTALBIKELANES (if it’s zero, then it’s mixed traffic) |\n", + "| Bike lane type (conventional; buffered considered conventional with buffer width considered part of lane width; also mentions advisory and shoulder) | BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED |\n", + "| Bike lane (separate from traffic) | BIKELANE_DUAL_PROTECTED, BIKELANE_PROTECTED |\n", + "| Bike lane (conventional, advisory, shoulder) adjacency to parking lane | BIKELANE_PARKINGLANE_ADJACENT |\n", + "| Bike lane width | TOTALBIKELANEWIDTH (no direct way of getting buffer width so subtract all individual elements from total cross width, assuming the leftover difference is the bike lane buffer) divide by TOTALBIKELANES (substitute for not having width-per-lane) |\n", + "| Is bike lane frequently blocked? | No equivalent (might be worth surveying users) |\n", + "| Is bike lane next to curb, road edge, or discontinuous? | No equivalent |\n", + "| Centerline | No direct comparison (using DOUBLEYELLOW_LINE and TOTALRAISEDBUFFERS) |\n", + "| Number of trave lanes in each direction (not always clear what to do if there is, say, 1 lane in one direction and 2 in the other) | TOTALTRAVELLANES, TOTALTRAVELLANESINBOUND, TOTALTRAVELLANESOUTBOUND (other lane types include: TOTALTRAVELLANESBIDIRECTIONAL and TOTALTRAVELLANESREVERSIBLE) |\n", + "| Road width | TOTALCROSSSECTIONWIDTH |\n", + "| Parking lane (none, one side, both sides) | TOTALPARKINGLANES (doesn’t specify which side of road but number of lanes is probably a fairly good proxy) |\n", + "| ADT (average daily traffic) | AADT |\n", + "| Prevailing traffic speed | Closest we can get is speedlimit (SPEEDLIMITS_OB) |\n", + "\n", + "\n", + "The tables have been translated into 'LTS.xlsx'" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "id": "5750ddcb-5417-467c-99f9-1a5b180ed128", + "metadata": {}, + "outputs": [], + "source": [ + "import requests\n", + "import geopandas as gpd\n", + "import pandas as pd\n", + "import numpy as np\n", + "import seaborn as sns" + ] + }, + { + "cell_type": "markdown", + "id": "103590cd-86d3-489d-b94f-5fe89dadbc60", + "metadata": {}, + "source": [ + "## Get road data from DC website" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "9e8a4862-24db-4f46-a858-695780d5f643", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "trying website\n", + "\n", + "https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_COMBINATIONAADT_COMBINATION_YEARAADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindex
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...118.02020.0254.02020.011None419502700
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaNNaNNaNNaN11None419502801
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...32.02020.0435.02020.011None419502902
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...312.02020.01443.02020.011None419503003
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaNNaNNaNNaN11YES419503104
..................................................................
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...111.02020.0736.02020.011None4211500013833
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaNNaNNaNNaN11None4211501013834
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaNNaNNaNNaN11None4211502013835
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaNNaNNaNNaN11None4211503013836
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaNNaNNaNNaN1073None4211504013837
\n", + "

13838 rows × 102 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_COMBINATION \\\n", + "0 0 37 ... 118.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 32.0 \n", + "3 1 40 ... 312.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13833 0 42 ... 111.0 \n", + "13834 0 20 ... NaN \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " AADT_COMBINATION_YEAR AADT_SINGLE_UNIT AADT_SINGLE_UNIT_YEAR \\\n", + "0 2020.0 254.0 2020.0 \n", + "1 NaN NaN NaN \n", + "2 2020.0 435.0 2020.0 \n", + "3 2020.0 1443.0 2020.0 \n", + "4 NaN NaN NaN \n", + "... ... ... ... \n", + "13833 2020.0 736.0 2020.0 \n", + "13834 NaN NaN NaN \n", + "13835 NaN NaN NaN \n", + "13836 NaN NaN NaN \n", + "13837 NaN NaN NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "0 1 1 None \n", + "1 1 1 None \n", + "2 1 1 None \n", + "3 1 1 None \n", + "4 1 1 YES \n", + "... ... ... ... \n", + "13833 1 1 None \n", + "13834 1 1 None \n", + "13835 1 1 None \n", + "13836 1 1 None \n", + "13837 10 73 None \n", + "\n", + " OBJECTID SHAPELEN index \n", + "0 4195027 0 0 \n", + "1 4195028 0 1 \n", + "2 4195029 0 2 \n", + "3 4195030 0 3 \n", + "4 4195031 0 4 \n", + "... ... ... ... \n", + "13833 4211500 0 13833 \n", + "13834 4211501 0 13834 \n", + "13835 4211502 0 13835 \n", + "13836 4211503 0 13836 \n", + "13837 4211504 0 13837 \n", + "\n", + "[13838 rows x 102 columns]" + ] + }, + "execution_count": 53, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 2) Get Roadblock data from website\n", + "CRS = 'EPSG:4326'\n", + "def try_fetch_dc_roads():\n", + " url = \"https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\"\n", + " try:\n", + " print('trying website')\n", + " r = requests.get(url, timeout=60)\n", + " r.raise_for_status()\n", + " print(r)\n", + " print(url)\n", + " if r.ok:\n", + " gj = r.json()\n", + " roads = gpd.GeoDataFrame.from_features(gj[\"features\"], crs=CRS)\n", + " return roads\n", + " except Exception as error:\n", + " print('Error reading road data from dc gov website')\n", + "\n", + "roads = try_fetch_dc_roads()\n", + "roads['index'] = roads.index\n", + "roads = roads.drop(columns='geometry')\n", + "roads.to_csv('Roadway_Block_downloaded.csv')\n", + "roads" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "2e9d238d-7ca3-4133-818f-428346708591", + "metadata": {}, + "outputs": [], + "source": [ + "# read in file if it's already saved\n", + "#roads = pd.read_csv('Roadway_Block_downloaded.csv')" + ] + }, + { + "cell_type": "markdown", + "id": "46c6e731-6983-480c-8d68-5fe45dc3646b", + "metadata": {}, + "source": [ + "## Make additional columns (PERBIKELANEWIDTH, ADJPLREACH)\n", + "\n", + "* PERBIKELANEWIDTH: Model needs bike lane with to include buffer width but there is no column for this so test if width of conventional lanes is less than buffered lanes. It is so, so find un-accounted for width of roads with buffered bike lanes and add that to bike lane width (so just divide by number of bike lanes).\n", + "* ADJPRLREACH: adjacent to parking lane reach (includes bike width and parking lane width), should be per-lane (so just divide by number of bike lanes)" + ] + }, + { + "cell_type": "markdown", + "id": "88c2790a-4ccf-4c55-8409-a8fbcff44439", + "metadata": {}, + "source": [ + "### PERBIKELANEWIDTH" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "58ef4810-4ea6-4267-8c8a-dd80e49fe09d", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number of buffered lanes: 185\n", + "number of just buffered lanes: 119\n", + "mean width: 5.436974789915967\n", + "avg_width\n", + "5.0 68\n", + "6.0 24\n", + "8.0 10\n", + "4.0 7\n", + "7.0 3\n", + "4.5 3\n", + "6.5 2\n", + "2.0 1\n", + "5.5 1\n", + "Name: count, dtype: int64\n", + "leftover_width\n", + "3 21\n", + "4 19\n", + "7 18\n", + "2 14\n", + "11 9\n", + "5 6\n", + "6 5\n", + "16 4\n", + "13 3\n", + "21 3\n", + "12 2\n", + "14 2\n", + "9 2\n", + "10 2\n", + "18 2\n", + "17 2\n", + "8 2\n", + "19 1\n", + "27 1\n", + "15 1\n", + "Name: count, dtype: int64\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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SZOKs1tSmup0+PDholdk+vTpp/s2AMAQUVbPx5e+9KWYO3duMSySTp998MEH44knnojHH3+8GFpZsmRJrFy5MiZPnlws6ec0byONAQEAlB0+XnnllfjEJz4RL7/8cpx99tnFBcdS8EjjRsmyZcvi0KFDsXjx4ti/f39MmzYtNm3aFKNHj1ZtAKD88PHAAw+87uOp9yOdvZIWAIDe+G4XACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIQPACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIbnfTsAyjWlaWN0HK0r+3Uv3n2tYjMg6fkAALISPgCArIQPACAr4QMAyEr4AACyEj4AgKyEDwAgK+EDAMhK+AAAshI+AICshA8AICvhAwDISvgAALISPgCArIQPACAr4QMAGLjh46677oorrrgiRo8eHRdccEHceOONsXPnzm7PKZVK0dTUFBMmTIiRI0fGrFmzYseOHf293QBALYSPLVu2xK233hpPP/10bN68OV577bWYM2dOHDx4sOs5q1atitWrV8fatWujubk5xo0bF7Nnz462trZKbD8AMMgML+fJjz/+eLf769atK3pAnnnmmfjABz5Q9HqsWbMmGhsbY968ecVz1q9fH2PHjo0NGzbEokWL+nfrAYChHT56OnDgQHF7zjnnFLe7du2Kffv2Fb0hnerr62PmzJmxdevWXsNHR0dHsXRqbW0tbo8cOVIs/amzvf5udyhSK7Wq5H5VP6x02m3UgtOtVy3Wqpb+zQOtVuW0V1dK3RV9kF52ww03xP79++Opp54q1qWAMWPGjNi7d28x56PTwoULY/fu3bFx48YT2knzQ1asWHHC+tRTMmrUqL5sGgCQWXt7e8yfP7/omBgzZkxlej4++9nPxs9//vP40Y9+dMJjdXV1JwSVnus6LV++PJYuXdqt56OhoaHoPTnVxvcllaW5KmkOyogRI/q17aFGrdSqkvvVl7cNi45jvX8mnMpzTddErTjdetVirXy+V69WnSMXb0Sfwsdtt90WjzzySDz55JMxceLErvVpcmmShl7Gjx/ftb6lpaWY99GbNCyTlp5SQSoVECrZ9lCjVmpVCekXacfRvoWPWjx2+1qv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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print('number of buffered lanes: '+str(len(roads[~roads['BIKELANE_BUFFERED'].isna()])))\n", + "print('number of just buffered lanes: '+str(len(roads[(~roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())])))\n", + "roads_buffered = roads[(~roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())]\n", + "roads_buffered = roads_buffered[['BIKELANE_CONTRAFLOW', 'BIKELANE_CONVENTIONAL', 'BIKELANE_DUAL_PROTECTED', 'BIKELANE_PROTECTED', 'BIKELANE_BUFFERED', 'TOTALBIKELANES', 'TOTALBIKELANEWIDTH', 'TOTALTRAVELLANEWIDTH', 'TOTALCROSSSECTIONWIDTH', 'TOTALPARKINGLANEWIDTH', 'TOTALRAISEDBUFFERWIDTH']]\n", + "roads_buffered['avg_width'] = roads_buffered['TOTALBIKELANEWIDTH']/roads_buffered['TOTALBIKELANES']\n", + "roads_buffered['leftover_width'] = roads_buffered['TOTALCROSSSECTIONWIDTH']-roads_buffered['TOTALTRAVELLANEWIDTH']-roads_buffered['TOTALPARKINGLANEWIDTH']-roads_buffered['TOTALRAISEDBUFFERWIDTH']-roads_buffered['TOTALBIKELANEWIDTH']\n", + "print('mean width: '+str(roads_buffered['avg_width'].mean()))\n", + "print(roads_buffered['avg_width'].value_counts())\n", + "print(roads_buffered['leftover_width'].value_counts())\n", + "roads_buffered['avg_width'].hist(bins = 30)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "4d4456bd-4328-4119-b1a6-3f46fda52183", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiwAAAGdCAYAAAAxCSikAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJk9JREFUeJzt3QtQVOf5x/FnEURJRccQBRSvYybxMsZ4tynivwNEHatRow0zEZs2l4lJo45j1ehkaRIxNhdjtDptE9FYotNR1BYbxYlAjJdRE010EqtTFBsljmlkFSKi7H/et1nCZVlY2GXfPfv9zByXc+WcZw/w8z3vOWtzOp1OAQAAMFhYoHcAAACgMQQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxwsUiqqqq5NKlS9KhQwex2WyB3h0AANAE6vm1169fl/j4eAkLC7N+YFFhJSEhIdC7AQAAmuHixYvSvXt36wcW1bLiOuDo6OhA747xKisrZe/evZKSkiIRERGB3h1Lo9bU2Uo4n6mzrzkcDt3g4Po7bvnA4roMpMIKgaVpv3SioqJ0rQgs/kWtWwd1ps5WEorns62R7hx0ugUAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwXnigd8Dqei3Kbfa651dM9Om+AAAQrGhhAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMBagSUzM1OGDx8uHTp0kC5dusiUKVPkzJkztZZxOp1it9slPj5e2rdvL0lJSXL69OlGt71t2zbp37+/REZG6tecnBzvjwYAAFiSV4GloKBA5syZI4cPH5a8vDy5ffu2pKSkSFlZWfUyK1eulDfffFPWrFkjR48eldjYWElOTpbr1683uN1Dhw7JzJkz5fHHH5eTJ0/q1xkzZsiRI0dadnQAAMASwr1Z+MMPP6w1vmHDBt3Scvz4cUlMTNStK6tWrZIXX3xRpk6dqpfZuHGjdO3aVbKzs+Xpp592u121jgo1ixcv1uPqVYUjNf2DDz5o/tEBAIDQCyx1lZaW6tfOnTvr16KiIikpKdGtLi7qEs/YsWPl4MGDDQYW1cIyb968WtNSU1N1YGlIRUWFHlwcDod+rays1IMpIts4m72uP4/DtW2TamVV1Jo6WwnnM3X2tab+HWp2YFGtKfPnz5eHHnpIBg4cqKepsKKoFpWa1PiFCxca3JZaz906ru011J8mIyOj3vS9e/dKVFSUmGLliOavu3v3bvE3dWkPrYNaU2cr4Xymzr5SXl7u38Dy3HPPyeeffy4HDhyoN89ms9ULN3WntXQdddlIBaaaLSwJCQm6dSc6OlpMMdC+p9nrnrKnij8TrfqFoy7FRURE+O37gFq3Fs5p6mwloXQ+O364QuKXwPL888/Lrl27pLCwULp37149XXWwVVTLSFxcXPX0K1eu1GtBqUmtV7c1pbF11KUmNdSl3liT3tyKO56DmietcRym1cvKqDV1thLOZ+rsK039G+TVXUKq1UO1rGzfvl0++ugj6d27d635alyFj5pNhbdu3dIdaMeMGdPgdkePHl2veVFd2vG0DgAACB1etbCoW5rV3T47d+7Uz2JxtYp07NhRP3NFXcKZO3euLF++XPr166cH9bXqU5KWlla9nVmzZkm3bt10PxTlhRde0HcZvfbaazJ58mS9/X379rm93AQAAEKPV4Fl3bp1+lU9DK7u7c2zZ8/WXy9cuFC+//57efbZZ+W7776TkSNH6tYSFXBciouLJSzsx8Yd1ZKyZcsWWbp0qSxbtkz69u0rW7du1esCAACEe3tJqDGqlUU96VYNDcnPz683bfr06XoAAACoi88SAgAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAABrPZofravXotxmr3t+xUSf7gsAAIFECwsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgvPBA7wDg0mtRbrOLcX7FRAoJABZGCwsAADAegQUAABiPwAIAAKwXWAoLC2XSpEkSHx8vNptNduzYUWu+muZu+MMf/tDgNrOystyuc/PmzeYdFQAACO3AUlZWJoMHD5Y1a9a4nX/58uVaw3vvvafDx7Rp0zxuNzo6ut667dq183b3AACABXl9l9D48eP10JDY2Nha4zt37pRx48ZJnz59PG5XhZq66wIAAPj9tuZvvvlGcnNzZePGjY0ue+PGDenZs6fcuXNHHnjgAXn55ZdlyJAhDS5fUVGhBxeHw6FfKysr9WCKyDbOgHzfxmrgmm+VWpl0HMFQayuiztTZSkLpfK5s4jHanE5ns/9KqFaRnJwcmTJlitv5K1eulBUrVsilS5c8Xt45fPiwnDt3TgYNGqSDx9tvvy27d++WkydPSr9+/dyuY7fbJSMjo9707OxsiYqKau4hAQCAVlReXi5paWlSWlqqu4cEJLDcd999kpycLO+8845X262qqpIHH3xQEhMTZfXq1U1uYUlISJCrV696PODWNtC+JyDf95Q9tdFEm5eXp9+fiIgICfZaNXa8gWRira2IOlNnKwml89nhcEhMTEyjgcVvl4Q+/vhjOXPmjGzdutXrdcPCwmT48OFy9uzZBpeJjIzUQ13qjTXpza24YwvI921qDUyqV0tqZcoxBEutrYw6U2crCYXzOaKJx+e357C8++67MnToUH1HkbdUo8+JEyckLi7OL/sGAACCi9ctLKpzrOpv4lJUVKTDRefOnaVHjx7VzTt/+9vf5I033nC7jVmzZkm3bt0kMzNTj6u+KKNGjdL9VdS66jKQ2ubatWubf2QAACB0A8uxY8f0bcou8+fP16/p6en6AXDKli1bdCvJY4895nYbxcXF+rKPy7Vr1+Spp56SkpIS6dixo747SD2gbsSIEc05JgAAEOqBJSkpSYcRT1T4UEND8vPza42/9dZbegAAAHCHzxICAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAAFgvsBQWFsqkSZMkPj5ebDab7Nixo9b82bNn6+k1h1GjRjW63W3btkn//v0lMjJSv+bk5Hi7awAAwKK8DixlZWUyePBgWbNmTYPLPPzww3L58uXqYffu3R63eejQIZk5c6Y8/vjjcvLkSf06Y8YMOXLkiLe7BwAALCjc2xXGjx+vB09UK0lsbGyTt7lq1SpJTk6WxYsX63H1WlBQoKd/8MEH3u4iAAAI9cDSFPn5+dKlSxfp1KmTjB07Vl599VU97qmFZd68ebWmpaam6sDSkIqKCj24OBwO/VpZWakHU0S2cQbk+zZWA9d8q9TKpOMIhlpbEXWmzlYSSudzZROP0eZ0Opv9V0L1T1F9TaZMmVI9bevWrfKTn/xEevbsKUVFRbJs2TK5ffu2HD9+XLe8uNO2bVvJysqStLS06mnZ2dnyq1/9qlYoqclut0tGRka96Wq9qKio5h4SAABoReXl5frvf2lpqURHR7deC4vqi+IycOBAGTZsmA4vubm5MnXqVI/hpyaVo+pOq0ldNpo/f36tFpaEhARJSUnxeMCtbaB9T0C+7yl7aqOJNi8vT1+Ki4iIkGCvVWPHG0gm1tqKqDN1tpJQOp8dP1whCcgloZri4uJ0YDl79myDy6j+LiUlJbWmXblyRbp27drgOqq1xl2LjXpjTXpzK+40HLr8qak1MKleLamVKccQLLW2MupMna0kFM7niCYen9+fw/Ltt9/KxYsXdXBpyOjRo3WSrGnv3r0yZswYf+8eAAAIAl63sNy4cUPOnTtXPa76qZw4cUI6d+6sB9W3ZNq0aTqgnD9/XpYsWSIxMTHyyCOPVK8za9Ys6datm2RmZurxF154QRITE+W1116TyZMny86dO2Xfvn1y4MABXx0nAAAIpcBy7NgxGTduXPW4qx9Jenq6rFu3Tr744gvZtGmTXLt2TYcWtazqiNuhQ4fqdYqLiyUs7MfGHdWSsmXLFlm6dKnupNu3b1+9zsiRI1t+hAAAIPQCS1JSku4Q25A9e/Y06bbnuqZPn64HAACAuvgsIQAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAACw3qP5Q1GvRbmB3gUAAEIaLSwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAABYL7AUFhbKpEmTJD4+Xmw2m+zYsaN6XmVlpfzud7+TQYMGyV133aWXmTVrlly6dMnjNrOysvS26g43b95s3lEBAIDQDixlZWUyePBgWbNmTb155eXl8umnn8qyZcv06/bt2+Vf//qX/OIXv2h0u9HR0XL58uVaQ7t27bzdPQAAYEHh3q4wfvx4PbjTsWNHycvLqzXtnXfekREjRkhxcbH06NGjwe2qFpXY2FhvdwcAAIQArwOLt0pLS3UY6dSpk8flbty4IT179pQ7d+7IAw88IC+//LIMGTKkweUrKir04OJwOKovS6nBlyLbOCXYNFYD13xf1ypQdTbpOIKh1lZEnamzlYTS+VzZxGO0OZ3OZv+VUEEkJydHpkyZ4na+6oPy0EMPyX333SebN29ucDuHDx+Wc+fO6b4vKni8/fbbsnv3bjl58qT069fP7Tp2u10yMjLqTc/OzpaoqKjmHhIAAGhFqjtJWlqabuBQ3UNaPbCoxPToo4/qS0H5+fked6KuqqoqefDBByUxMVFWr17d5BaWhIQEuXr1qlffqykG2vdIsDllT/U4X70/6vJdcnKyREREiAlaUufGjjeQTKy1FVFn6mwloXQ+OxwOiYmJaTSwhPur0DNmzJCioiL56KOPvA4QYWFhMnz4cDl79myDy0RGRuqhLvXG+vrNrbhjk2DT1Br4o16BqLMpxxAstbYy6kydrSQUzueIJh5fmL/Cigob+/btk7vvvtvrbahGnxMnTkhcXJyvdw8AAAQhr1tYVOdY1d/ERbWiqHDRuXNn/dyV6dOn61ua//GPf+gOtCUlJXo5Nb9t27b6a/Vslm7duklmZqYeV31RRo0apfurqKYhdRlIbXPt2rW+O1IAABA6geXYsWMybty46vH58+fr1/T0dN0RdteuXXpc3elT0/79+yUpKUl/rfq1qMs+LteuXZOnnnpKhxt1a7S6O0g9oE7dDg0AAOB1YFGhw1M/3ab04VWdcGt666239AAAAOAOnyUEAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGC9wFJYWCiTJk2S+Ph4sdlssmPHjlrznU6n2O12Pb99+/aSlJQkp0+fbnS727Ztk/79+0tkZKR+zcnJ8XbXAACARXkdWMrKymTw4MGyZs0at/NXrlwpb775pp5/9OhRiY2NleTkZLl+/XqD2zx06JDMnDlTHn/8cTl58qR+nTFjhhw5csTb3QMAABYU7u0K48eP14M7qnVl1apV8uKLL8rUqVP1tI0bN0rXrl0lOztbnn76abfrqXVUqFm8eLEeV68FBQV6+gcffODtLgIAAIvxaR+WoqIiKSkpkZSUlOpp6hLP2LFj5eDBgx5bWGquo6SmpnpcBwAAhA6vW1g8UWFFUS0qNanxCxcueFzP3Tqu7blTUVGhBxeHw6FfKysr9eBLkW2cEmwaq4Frvq9rFag6m3QcwVBrK6LO1NlKQul8rmziMfo0sLiozrh1LxXVndbSdTIzMyUjI6Pe9L1790pUVJT40soREnR2797dpOXy8vLEFC2pc1OPN5BMqrWVUWfqbCWhcD6Xl5e3fmBRHWwV1TISFxdXPf3KlSv1WlDqrle3NaWxdVQ/l/nz59dqYUlISNCXlqKjo8WXBtr3SLA5ZU9tNNGqHwTVdygiIkJM0JI6N3a8gWRira2IOlNnKwml89nxwxWSVg0svXv31uFDFXnIkCF62q1bt3QH2tdee63B9UaPHq3XmTdvXq2WkjFjxjS4juobo4a61Bvr6ze34o7n1iETNbUG/qhXIOpsyjEES62tjDpTZysJhfM5oonH53VguXHjhpw7d65WR9sTJ05I586dpUePHjJ37lxZvny59OvXTw/qa3WJJi0trXqdWbNmSbdu3fRlHeWFF16QxMREHWomT54sO3fulH379smBAwe83T0AAGBBXgeWY8eOybhx46rHXZdl0tPTJSsrSxYuXCjff/+9PPvss/Ldd9/JyJEjdWtJhw4dqtcpLi6WsLAfb1BSLSlbtmyRpUuXyrJly6Rv376ydetWvS4AAIDXgUU9uVZ1iG2I6iirnnSrhobk5+fXmzZ9+nQ9AAAA1MVnCQEAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8Xz6ac0AvNNrUW6zS3Z+xUTKDSBk0MICAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAABA6AWWXr16ic1mqzfMmTPH7fL5+flul//qq698vWsAACBIhft6g0ePHpU7d+5Uj586dUqSk5Pl0Ucf9bjemTNnJDo6unr8nnvu8fWuAQCAIOXzwFI3aKxYsUL69u0rY8eO9bhely5dpFOnTr7eHQAAYAF+7cNy69Yt2bx5szzxxBP6Mo8nQ4YMkbi4OPn5z38u+/fv9+duAQCAUG9hqWnHjh1y7do1mT17doPLqJDypz/9SYYOHSoVFRXy/vvv69Ci+rYkJiY2uJ5aVg0uDodDv1ZWVurBlyLbOCXYNFYD13xf1ypQdTbpOLyptVWPORBMPKetiDpTZ19r6s+szel0+u2vcWpqqrRt21b+/ve/e7XepEmTdIvMrl27GlzGbrdLRkZGvenZ2dkSFRXVrP0FAACtq7y8XNLS0qS0tLRWX9ZWCywXLlyQPn36yPbt22Xy5Mlerfvqq6/qS0lffvmlVy0sCQkJcvXqVY8H3BwD7Xsk2JyypzaaaPPy8nSH6IiICDFBS+rc2PEGkqdaW/WYA8HEc9qKqDN19jX19zsmJqbRwOK3S0IbNmzQHWknTpzo9bqfffaZvlTkSWRkpB7qUr+ofP3LquKO5/43JmpqDfxRr0DU2ZRj8LbWVj/mQDDpnLYy6kydfaWpP69+CSxVVVU6sKSnp0t4eO1vsXjxYvn6669l06ZNenzVqlX62S0DBgyo7qS7bds2PQAAAPgtsOzbt0+Ki4v13UF1Xb58Wc9zUSFlwYIFOsS0b99eB5fc3FyZMGEC7xAAAPBfYElJSZGGusZkZWXVGl+4cKEeAAAAGsJnCQEAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB44YHeAfhHr0W5HudHtnHKyhEiA+17pOKOrda88ysm8rYAAIxCCwsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAQi+w2O12sdlstYbY2FiP6xQUFMjQoUOlXbt20qdPH1m/fr2vdwsAAAQxv3z44YABA2Tfvn3V423atGlw2aKiIpkwYYI8+eSTsnnzZvnkk0/k2WeflXvuuUemTZvmj90DAABBxi+BJTw8vNFWFRfVmtKjRw9ZtWqVHr///vvl2LFj8vrrrxNYAACA/wLL2bNnJT4+XiIjI2XkyJGyfPlyfanHnUOHDklKSkqtaampqfLuu+9KZWWlREREuF2voqJCDy4Oh0O/qnXU4EuRbZxiNZFhzlqvNfm6fq1R50Dtszf75m4frXrMptUZ1DnYhNL5XNnEY7Q5nU6f/jX+5z//KeXl5XLvvffKN998I6+88op89dVXcvr0abn77rvrLa+Wmz17tixZsqR62sGDB+WnP/2pXLp0SeLi4hrsK5ORkVFvenZ2tkRFRfnykAAAgJ+ozJCWlialpaUSHR3dei0s48ePr/560KBBMnr0aOnbt69s3LhR5s+f73Yd1TG3JleGqju9psWLF9fanmphSUhI0K01ng64OQba94jVqJaVl4dVybJjYVJR1XCdvXXKnhqQOrfk+7bG/x7y8vIkOTm5XouhVY/ZtDqDOgebUDqfHT9cIQnIJaGa7rrrLh1c1GUid1Rfl5KSklrTrly5ovvBuGuRcVGXm9RQl3pjff3mVtzx3R9006iw4svja0ntW7IfwfAD7e7ctPoxB4I/fgeAOgdKKJzPEU08Pr8/h0X1M/nyyy8bvLSjWmBUiqxp7969MmzYMMu/SQAAQAITWBYsWKCfq6JuVz5y5IhMnz5dN/ekp6dXX8qZNWtW9fLPPPOMXLhwQV/eUcHmvffe0x1u1XYAAAD8cknoP//5jzz22GNy9epV/SyVUaNGyeHDh6Vnz556/uXLl6W4uLh6+d69e8vu3btl3rx5snbtWn130erVq7mlGQAA+C+wbNmyxeP8rKysetPGjh0rn376qa93BQAAWASfJQQAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAofdofgAwTa9Fuc1e9/yKiT7dFwDNQwsLAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYLzwQO8AgODSa1Fus9c9v2KiT/cFZuHcgD/RwgIAAIxHYAEAAMYjsAAAgNALLJmZmTJ8+HDp0KGDdOnSRaZMmSJnzpzxuE5+fr7YbLZ6w1dffeXr3QMAAEHI54GloKBA5syZI4cPH5a8vDy5ffu2pKSkSFlZWaPrqmBz+fLl6qFfv36+3j0AABCEfH6X0IcfflhrfMOGDbql5fjx45KYmOhxXbVcp06dfL1LAAAgyPn9tubS0lL92rlz50aXHTJkiNy8eVP69+8vS5culXHjxjW4bEVFhR5cHA6Hfq2srNSDL0W2cYrVRIY5a736Sktq35I6+/o99yXXvrnbx2A8ZlP32Wp1NhV1Dnydraapx2hzOp1++2usNj158mT57rvv5OOPP/Z4KaiwsFCGDh2qQ8j7778v69ev131bGmqVsdvtkpGRUW96dna2REVF+fQ4AACAf5SXl0taWppu4IiOjg5MYFF9WXJzc+XAgQPSvXt3r9adNGmS7ni7a9euJrewJCQkyNWrVz0ecHMMtO8Rq1EtKy8Pq5Jlx8Kkosrms+2esqcGpM4t+b6t8b8H1Z8rOTlZIiIigv6YTd1nq9XZVNQ58HW2GvX3OyYmptHA4rdLQs8//7wOG6rlxNuwoowaNUo2b97c4PzIyEg91KXeWF+/uRV3fPcH3TQqrPjy+FpS+5bsRzD8QLs7N4PxmE3fZ6vU2XTUOXB1tpqmHp/PA4tqsFFhJScnR1/S6d27d7O289lnn0lcXJyvdw8AAAShcH9cBlL9SHbu3KmfxVJSUqKnd+zYUdq3b6+/Xrx4sXz99deyadMmPb5q1Srp1auXDBgwQG7duqVbVrZt26YHAAAAnweWdevW6dekpKR6tzfPnj1bf62esVJcXFw9T4WUBQsW6BCjQo0KLqrvy4QJE3iHAACAfy4JNSYrK6vW+MKFC/UAAADgDp8lBAAAjEdgAQAAxvP7k26B1tBrUa6xhVZPWV054n/PAjHlFvlA1asl3/f8iokSbAJV52CsFdAYWlgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgPEILAAAwHgEFgAAYDwCCwAAMB6BBQAAGI/AAgAAjEdgAQAAxiOwAAAA44UHegcAoCl6Lcr1OD+yjVNWjhAZaN8jFXdsIV3UxmrlyfkVE326LzBLryA+N2hhAQAAxiOwAAAA4xFYAACA8QgsAADAeAQWAABgPAILAAAwHoEFAAAYj8ACAACMR2ABAADGI7AAAADjEVgAAEDoBpY//vGP0rt3b2nXrp0MHTpUPv74Y4/LFxQU6OXU8n369JH169f7a9cAAECQ8Utg2bp1q8ydO1defPFF+eyzz+RnP/uZjB8/XoqLi90uX1RUJBMmTNDLqeWXLFkiv/3tb2Xbtm3+2D0AABBk/BJY3nzzTfn1r38tv/nNb+T++++XVatWSUJCgqxbt87t8qo1pUePHno5tbxa74knnpDXX3/dH7sHAACCTLivN3jr1i05fvy4LFq0qNb0lJQUOXjwoNt1Dh06pOfXlJqaKu+++65UVlZKREREvXUqKir04FJaWqpf//vf/+p1fCn8dplYTXiVU8rLqyS8MkzuVNl8tt1vv/22+ftkwTor1Jo6B5PGfobV79fy8nK9XN3fzS35GW7J7w4r8lTnljDxPbp+/bp+dTqdnhd0+tjXX3+tvqPzk08+qTX91Vdfdd57771u1+nXr5+eX5NaX23n0qVLbtd56aWX9HwGasA5wDnAOcA5wDkgQV+DixcveswXPm9hcbHZav+vXSWnutMaW97ddJfFixfL/Pnzq8erqqp068rdd9/t8fvgfxwOh75Md/HiRYmOjqYsfkStWwd1ps5WEkrns9Pp1K0s8fHxHpfzeWCJiYmRNm3aSElJSa3pV65cka5du7pdJzY21u3y4eHhOoC4ExkZqYeaOnXq1OL9DzXqB8HqPwymoNbU2Uo4n6mzL3Xs2LH1O922bdtW356cl5dXa7oaHzNmjNt1Ro8eXW/5vXv3yrBhw3x67Q4AAAQnv9wlpC7V/OUvf5H33ntPvvzyS5k3b56+pfmZZ56pvpwza9as6uXV9AsXLuj11PJqPdXhdsGCBf7YPQAAEGT80odl5syZujfx73//e7l8+bIMHDhQdu/eLT179tTz1bSaz2RRD5hT81WwWbt2rb6OtXr1apk2bZo/dg8/XFJ76aWX6l1Wg+9R69ZBnamzlXA+12dTPW/dTAcAADAGnyUEAACMR2ABAADGI7AAAADjEVgAAIDxCCwhxm636ycB1xzUg/vQMoWFhTJp0iR9h5uq6Y4dO2rNV33bVe3V/Pbt20tSUpKcPn2asvu4zrNnz653fo8aNYo6eykzM1OGDx8uHTp0kC5dusiUKVPkzJkznNMBqDPn9I8ILCFowIAB+tZy1/DFF18EepeCXllZmQwePFjWrFnjdv7KlSv1p5ir+UePHtUhMTk5ufpDv+CbOisPP/xwrfNbPTIB3ikoKJA5c+bI4cOH9UM9b9++rT+gVtWfc7p166xwTv/A2w83RHBTHxo5ePDgQO+Gpakfq5ycnOrxqqoqZ2xsrHPFihXV027evOns2LGjc/369QHaS+vVWUlPT3dOnjw5YPtkVVeuXNH1Ligo0OOc061TZ4Vz+ke0sISgs2fP6iZ19cC+X/7yl/Lvf/870LtkaUVFRfqzstT/nGo+FGrs2LFy8ODBgO6bFeXn5+vm9XvvvVeefPJJ/blkaJnS0lL92rlzZ/3KOd06dXbhnP4fAkuIGTlypGzatEn27Nkjf/7zn/UfUvUZT+rJxPAP1wd71v3wTzVe90M/0TLjx4+Xv/71r/LRRx/JG2+8oS+//d///Z9UVFRQ2mZSjVnqY1Meeugh/dRyhXO6deqscE77+dH8MJc6+V0GDRqkP3iyb9++snHjRv3DAv9RHUDr/oKqOw0t/1gQF/VLX32AqvpIkNzcXJk6dSrlbYbnnntOPv/8czlw4EC9eZzT/q8z5/SPaGEJcXfddZcOLuoyEfzDdRdW3dYUdamibqsLfCsuLk4HFs7v5nn++edl165dsn//funevXv1dM7p1qmzO3EhfE4TWEKcaipXn5CtfgjgH6qvkPoFr+4CcLl165a+Q0BdjoP/qEudFy9e5Pz2kmr9U//j3759u768ps7hmjinW6fO7nwbwuc0l4RCzIIFC/RzLHr06KH/h//KK6+Iw+GQ9PT0QO9aULtx44acO3euelx1Sjxx4oTuPKdqPXfuXFm+fLn069dPD+rrqKgoSUtLC+h+W6nOalDPulGf8q5+mZ8/f16WLFkiMTEx8sgjjwR0v4ONutU2Oztbdu7cqZ8R4mod7Nixo36OkLoUxDnt/zqr851zuoYadwwhBMycOdMZFxfnjIiIcMbHxzunTp3qPH36dKB3K+jt379f345Yd1C3JLpuA1W3lKvbmyMjI52JiYnOL774ItC7bak6l5eXO1NSUpz33HOPPr979OihpxcXFwd6t4OOuxqrYcOGDdXLcE77v86c07XZ1D81AwwAAIBp6MMCAACMR2ABAADGI7AAAADjEVgAAIDxCCwAAMB4BBYAAGA8AgsAADAegQUAABiPwAIAAIxHYAEAAMYjsAAAAOMRWAAAgJju/wEb3edfuiT6/AAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "roads_buffered['leftover_width'].hist(bins = 30)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fa3cbda3-2434-4328-b3c5-19700ad9e132", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number of conventional lanes: 1046\n", + "number of just convential lanes: 900\n", + "mean width: 5.038703703703703\n", + "avg_width\n", + "5.000000 827\n", + "6.000000 35\n", + "4.000000 21\n", + "5.500000 6\n", + "4.500000 3\n", + "7.500000 2\n", + "3.000000 2\n", + "4.333333 1\n", + "11.000000 1\n", + "16.000000 1\n", + "7.000000 1\n", + "Name: count, dtype: int64\n", + "leftover_width\n", + "0 463\n", + "1 406\n", + "3 5\n", + "8 4\n", + "2 4\n", + "5 4\n", + "6 4\n", + "10 3\n", + "4 2\n", + "9 2\n", + "16 1\n", + "12 1\n", + "14 1\n", + "Name: count, dtype: int64\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 59, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print('number of conventional lanes: '+str(len(roads[~roads['BIKELANE_CONVENTIONAL'].isna()])))\n", + "print('number of just conventional lanes: '+str(len(roads[(roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (~roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())])))\n", + "roads_conv = roads[(roads['BIKELANE_BUFFERED'].isna()) & (roads['BIKELANE_CONTRAFLOW'].isna()) & (~roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_DUAL_PROTECTED'].isna()) & (roads['BIKELANE_PROTECTED'].isna())]\n", + "roads_conv = roads_conv[['BIKELANE_CONTRAFLOW', 'BIKELANE_CONVENTIONAL', 'BIKELANE_DUAL_PROTECTED', 'BIKELANE_PROTECTED', 'BIKELANE_BUFFERED', 'TOTALBIKELANES', 'TOTALBIKELANEWIDTH', 'TOTALTRAVELLANEWIDTH', 'TOTALCROSSSECTIONWIDTH', 'TOTALPARKINGLANEWIDTH', 'TOTALRAISEDBUFFERWIDTH']]\n", + "roads_conv['avg_width'] = roads_conv['TOTALBIKELANEWIDTH']/roads_conv['TOTALBIKELANES']\n", + "roads_conv['leftover_width'] = roads_conv['TOTALCROSSSECTIONWIDTH']-roads_conv['TOTALTRAVELLANEWIDTH']-roads_conv['TOTALPARKINGLANEWIDTH']-roads_conv['TOTALRAISEDBUFFERWIDTH']-roads_conv['TOTALBIKELANEWIDTH']\n", + "print('mean width: '+str(roads_conv['avg_width'].mean()))\n", + "print(roads_conv['avg_width'].value_counts())\n", + "print(roads_conv['leftover_width'].value_counts())\n", + "roads_conv['avg_width'].hist(bins = 20)" + ] + }, + { + "cell_type": "code", + "execution_count": 60, + "id": "ccf08baa-02d4-4629-83df-91741e3bbc30", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 60, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "roads_conv['leftover_width'].hist(bins = 20)" + ] + }, + { + "cell_type": "markdown", + "id": "5e63aaec-1b1a-4450-be98-f07b240a316a", + "metadata": {}, + "source": [ + "Looks like un-accounted for space in cross section is likely buffer. So let's create a 'total bikelane width' column. It if there is a buffered bike lane, it will include the unaccounted for space. If there isn't, it'll just be the total bikelane width. Also create a per-lane width as well. (just divide total width by number of bike lanes)\n", + "\n", + "This will not account for different bike lane types." + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "1b681f64-2438-4391-a998-47076380ecb2", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\2165435094.py:8: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[8.5 5. 5. ... 5. 9. 5. ]' has dtype incompatible with int64, please explicitly cast to a compatible dtype first.\n", + " roads.loc[lane_ind, 'PERBIKELANEWIDTH'] = roads['TOTALBIKELANEWIDTH_WEXTRA'][lane_ind]/roads['TOTALBIKELANES'][lane_ind]\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...254.02020.011None41950270000.0
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaNNaN11None41950280100.0
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...435.02020.011None41950290200.0
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...1443.02020.011None41950300300.0
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaNNaN11YES41950310400.0
..................................................................
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...736.02020.011None421150001383300.0
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaNNaN11None4211501013834105.0
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaNNaN11None421150201383500.0
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaNNaN11None421150301383600.0
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaNNaN1073None421150401383700.0
\n", + "

13838 rows × 104 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT \\\n", + "0 0 37 ... 254.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 435.0 \n", + "3 1 40 ... 1443.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13833 0 42 ... 736.0 \n", + "13834 0 20 ... NaN \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " AADT_SINGLE_UNIT_YEAR DC_MAINTENANCE_OPERATIONS \\\n", + "0 2020.0 1 \n", + "1 NaN 1 \n", + "2 2020.0 1 \n", + "3 2020.0 1 \n", + "4 NaN 1 \n", + "... ... ... \n", + "13833 2020.0 1 \n", + "13834 NaN 1 \n", + "13835 NaN 1 \n", + "13836 NaN 1 \n", + "13837 NaN 10 \n", + "\n", + " MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION OBJECTID SHAPELEN index \\\n", + "0 1 None 4195027 0 0 \n", + "1 1 None 4195028 0 1 \n", + "2 1 None 4195029 0 2 \n", + "3 1 None 4195030 0 3 \n", + "4 1 YES 4195031 0 4 \n", + "... ... ... ... ... ... \n", + "13833 1 None 4211500 0 13833 \n", + "13834 1 None 4211501 0 13834 \n", + "13835 1 None 4211502 0 13835 \n", + "13836 1 None 4211503 0 13836 \n", + "13837 73 None 4211504 0 13837 \n", + "\n", + " TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "0 0 0.0 \n", + "1 0 0.0 \n", + "2 0 0.0 \n", + "3 0 0.0 \n", + "4 0 0.0 \n", + "... ... ... \n", + "13833 0 0.0 \n", + "13834 10 5.0 \n", + "13835 0 0.0 \n", + "13836 0 0.0 \n", + "13837 0 0.0 \n", + "\n", + "[13838 rows x 104 columns]" + ] + }, + "execution_count": 64, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads['TOTALBIKELANEWIDTH_WEXTRA'] = 0\n", + "roads['PERBIKELANEWIDTH'] = 0\n", + "buffered_ind = ~roads['BIKELANE_BUFFERED'].isna()\n", + "roads.loc[buffered_ind, 'TOTALBIKELANEWIDTH_WEXTRA'] = roads['TOTALCROSSSECTIONWIDTH'][buffered_ind]-roads['TOTALTRAVELLANEWIDTH'][buffered_ind]-roads['TOTALPARKINGLANEWIDTH']-roads['TOTALRAISEDBUFFERWIDTH']\n", + "lane_not_buffered_ind = roads['BIKELANE_BUFFERED'].isna() & ~roads['BIKELANE_CONVENTIONAL'].isna()\n", + "roads.loc[lane_not_buffered_ind, 'TOTALBIKELANEWIDTH_WEXTRA'] = roads['TOTALBIKELANEWIDTH'][lane_not_buffered_ind]\n", + "lane_ind = buffered_ind | lane_not_buffered_ind\n", + "roads.loc[lane_ind, 'PERBIKELANEWIDTH'] = roads['TOTALBIKELANEWIDTH_WEXTRA'][lane_ind]/roads['TOTALBIKELANES'][lane_ind]\n", + "roads" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "ad2d73b2-2d10-4802-af3a-1d89e8797594", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TOTALBIKELANESBIKELANE_CONVENTIONALBIKELANE_BUFFEREDTOTALBIKELANEWIDTHTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
222NoneBD10178.5
1352IBOB102010.0
1361NoneOB599.0
1951NoneIB699.0
2691NoneOB51717.0
.....................
136271NoneOB81111.0
137002OBIB10147.0
137592OBIB10126.0
137951NoneOB81111.0
138322NoneIB10189.0
\n", + "

185 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " TOTALBIKELANES BIKELANE_CONVENTIONAL BIKELANE_BUFFERED \\\n", + "22 2 None BD \n", + "135 2 IB OB \n", + "136 1 None OB \n", + "195 1 None IB \n", + "269 1 None OB \n", + "... ... ... ... \n", + "13627 1 None OB \n", + "13700 2 OB IB \n", + "13759 2 OB IB \n", + "13795 1 None OB \n", + "13832 2 None IB \n", + "\n", + " TOTALBIKELANEWIDTH TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "22 10 17 8.5 \n", + "135 10 20 10.0 \n", + "136 5 9 9.0 \n", + "195 6 9 9.0 \n", + "269 5 17 17.0 \n", + "... ... ... ... \n", + "13627 8 11 11.0 \n", + "13700 10 14 7.0 \n", + "13759 10 12 6.0 \n", + "13795 8 11 11.0 \n", + "13832 10 18 9.0 \n", + "\n", + "[185 rows x 6 columns]" + ] + }, + "execution_count": 65, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads[buffered_ind][['TOTALBIKELANES','BIKELANE_CONVENTIONAL','BIKELANE_BUFFERED', 'TOTALBIKELANEWIDTH', 'TOTALBIKELANEWIDTH_WEXTRA', 'PERBIKELANEWIDTH']]" + ] + }, + { + "cell_type": "code", + "execution_count": 66, + "id": "6c458ecb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
TOTALBIKELANESBIKELANE_CONVENTIONALBIKELANE_BUFFEREDTOTALBIKELANEWIDTHTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTH
241OBNone555.0
311OBNone555.0
431OBNone555.0
582BDNone10105.0
641IBNone555.0
.....................
137731IBNone555.0
137802BDNone10105.0
137872IBNone10105.0
138112BDNone10105.0
138342BDNone10105.0
\n", + "

1046 rows × 6 columns

\n", + "
" + ], + "text/plain": [ + " TOTALBIKELANES BIKELANE_CONVENTIONAL BIKELANE_BUFFERED \\\n", + "24 1 OB None \n", + "31 1 OB None \n", + "43 1 OB None \n", + "58 2 BD None \n", + "64 1 IB None \n", + "... ... ... ... \n", + "13773 1 IB None \n", + "13780 2 BD None \n", + "13787 2 IB None \n", + "13811 2 BD None \n", + "13834 2 BD None \n", + "\n", + " TOTALBIKELANEWIDTH TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \n", + "24 5 5 5.0 \n", + "31 5 5 5.0 \n", + "43 5 5 5.0 \n", + "58 10 10 5.0 \n", + "64 5 5 5.0 \n", + "... ... ... ... \n", + "13773 5 5 5.0 \n", + "13780 10 10 5.0 \n", + "13787 10 10 5.0 \n", + "13811 10 10 5.0 \n", + "13834 10 10 5.0 \n", + "\n", + "[1046 rows x 6 columns]" + ] + }, + "execution_count": 66, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads[~roads['BIKELANE_CONVENTIONAL'].isna()][['TOTALBIKELANES','BIKELANE_CONVENTIONAL','BIKELANE_BUFFERED', 'TOTALBIKELANEWIDTH', 'TOTALBIKELANEWIDTH_WEXTRA', 'PERBIKELANEWIDTH']]" + ] + }, + { + "cell_type": "markdown", + "id": "30057dea-0cc1-43d6-ab66-b6b2c3df3a8e", + "metadata": {}, + "source": [ + "### ADJPRLREACH" + ] + }, + { + "cell_type": "code", + "execution_count": 67, + "id": "1e593f5f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
24110008026026.1362306210.0161138TH ST NW17028022eb2ddc14b56a7d5e090c8996112010...NaN11YES419505102455.012.5
3111001202764.513489872.43902612TH ST NW1a0c7260c3824e5d98a8272a0dea4719722020...NaN11None419505803155.014.0
4311064412769.510315792.968201NEW MEXICO AVE NW15cce0fd3e2d6d45f5b7bbdeac883f3a022020...2020.011None419507004355.013.0
58110007022102.7517092221.9924327TH ST NW1186de2ca1ec920117b3a3c3efed0380f22022...2020.011None4195085058105.013.0
64110338621641.0141601702.536743EUCLID ST NW12f7e6a2a12583aecba70dc3e18550bf312010...NaN11None419509106455.012.5
..................................................................
1375913034462154.392395225.167496EAST CAPITOL ST SE16f386fee838ed54d564cf493c0808a8b22020...NaN11None4211426013759126.014.0
1377313001402125.595001210.84429914TH ST SE151cbaeebbf932bd5a35ae70d28dc18201208...NaN11None421144001377355.013.0
1378013031332481.594086610.044189E ST SE12d375e469680fbc169c6e912f9fba3a022020...NaN11None4211447013780105.013.0
13811130001021383.7203371480.8403321ST ST SE1fb2d00801282fe317232b851a2aa253242044...NaN11None4211478013811105.013.0
13834130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f122020...NaN11None4211501013834105.014.0
\n", + "

924 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "24 11000802 6026.136230 6210.016113 8TH ST NW 1 \n", + "31 11001202 764.513489 872.439026 12TH ST NW 1 \n", + "43 11064412 769.510315 792.968201 NEW MEXICO AVE NW 1 \n", + "58 11000702 2102.751709 2221.992432 7TH ST NW 1 \n", + "64 11033862 1641.014160 1702.536743 EUCLID ST NW 1 \n", + "... ... ... ... ... ... \n", + "13759 13034462 154.392395 225.167496 EAST CAPITOL ST SE 1 \n", + "13773 13001402 125.595001 210.844299 14TH ST SE 1 \n", + "13780 13031332 481.594086 610.044189 E ST SE 1 \n", + "13811 13000102 1383.720337 1480.840332 1ST ST SE 1 \n", + "13834 13064282 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "24 7028022eb2ddc14b56a7d5e090c89961 1 2 \n", + "31 a0c7260c3824e5d98a8272a0dea47197 2 2 \n", + "43 5cce0fd3e2d6d45f5b7bbdeac883f3a0 2 2 \n", + "58 186de2ca1ec920117b3a3c3efed0380f 2 2 \n", + "64 2f7e6a2a12583aecba70dc3e18550bf3 1 2 \n", + "... ... ... ... \n", + "13759 6f386fee838ed54d564cf493c0808a8b 2 2 \n", + "13773 51cbaeebbf932bd5a35ae70d28dc1820 1 2 \n", + "13780 2d375e469680fbc169c6e912f9fba3a0 2 2 \n", + "13811 fb2d00801282fe317232b851a2aa2532 4 2 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "24 0 10 ... NaN \n", + "31 0 20 ... NaN \n", + "43 0 20 ... 2020.0 \n", + "58 0 22 ... 2020.0 \n", + "64 0 10 ... NaN \n", + "... ... ... ... ... \n", + "13759 0 20 ... NaN \n", + "13773 0 8 ... NaN \n", + "13780 0 20 ... NaN \n", + "13811 0 44 ... NaN \n", + "13834 0 20 ... NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "24 1 1 YES \n", + "31 1 1 None \n", + "43 1 1 None \n", + "58 1 1 None \n", + "64 1 1 None \n", + "... ... ... ... \n", + "13759 1 1 None \n", + "13773 1 1 None \n", + "13780 1 1 None \n", + "13811 1 1 None \n", + "13834 1 1 None \n", + "\n", + " OBJECTID SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \\\n", + "24 4195051 0 24 5 5.0 \n", + "31 4195058 0 31 5 5.0 \n", + "43 4195070 0 43 5 5.0 \n", + "58 4195085 0 58 10 5.0 \n", + "64 4195091 0 64 5 5.0 \n", + "... ... ... ... ... ... \n", + "13759 4211426 0 13759 12 6.0 \n", + "13773 4211440 0 13773 5 5.0 \n", + "13780 4211447 0 13780 10 5.0 \n", + "13811 4211478 0 13811 10 5.0 \n", + "13834 4211501 0 13834 10 5.0 \n", + "\n", + " ADJPLREACH \n", + "24 12.5 \n", + "31 14.0 \n", + "43 13.0 \n", + "58 13.0 \n", + "64 12.5 \n", + "... ... \n", + "13759 14.0 \n", + "13773 13.0 \n", + "13780 13.0 \n", + "13811 13.0 \n", + "13834 14.0 \n", + "\n", + "[924 rows x 105 columns]" + ] + }, + "execution_count": 67, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads['ADJPLREACH'] = 0.0\n", + "adjPLReach_ind = ((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (~roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())\n", + "roads.loc[adjPLReach_ind, 'ADJPLREACH'] = roads[adjPLReach_ind]['PERBIKELANEWIDTH'] + roads[adjPLReach_ind]['TOTALPARKINGLANEWIDTH']/roads[adjPLReach_ind]['TOTALPARKINGLANES']\n", + "roads[adjPLReach_ind]" + ] + }, + { + "cell_type": "code", + "execution_count": 68, + "id": "81bce7bc-b4c5-4c66-b237-4ab9fda1ce0f", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "ROUTEID\n", + "FROMMEASURE\n", + "TOMEASURE\n", + "ROUTENAME\n", + "ROADTYPE\n", + "BLOCKKEY\n", + "TOTALTRAVELLANES\n", + "TOTALPARKINGLANES\n", + "TOTALRAISEDBUFFERS\n", + "TOTALTRAVELLANEWIDTH\n", + "TOTALCROSSSECTIONWIDTH\n", + "TOTALPARKINGLANEWIDTH\n", + "TOTALRAISEDBUFFERWIDTH\n", + "TOTALTRAVELLANESINBOUND\n", + "TOTALTRAVELLANESOUTBOUND\n", + "TOTALTRAVELLANESBIDIRECTIONAL\n", + "TOTALTRAVELLANESREVERSIBLE\n", + "SUMMARYDIRECTION\n", + "BIKELANE_PARKINGLANE_ADJACENT\n", + "BIKELANE_THROUGHLANE_ADJACENT\n", + "BIKELANE_POCKETLANE_ADJACENT\n", + "BIKELANE_CONTRAFLOW\n", + "BIKELANE_CONVENTIONAL\n", + "BIKELANE_DUAL_PROTECTED\n", + "BIKELANE_PROTECTED\n", + "BIKELANE_BUFFERED\n", + "DOUBLEYELLOW_LINE\n", + "SECTIONFLAGS\n", + "LOC_ERROR\n", + "MIDMEASURE\n", + "AADT\n", + "AADT_YEAR\n", + "FHWAFUNCTIONALCLASS\n", + "HPMSID\n", + "HPMSSECTIONTYPE\n", + "ID\n", + "IRI\n", + "IRI_DATE\n", + "NHSCODE\n", + "OWNERSHIP\n", + "PCI_CONDCATEGORY\n", + "PCI_LASTINSPECTED\n", + "PCI_SCORE\n", + "QUADRANT\n", + "SIDEWALK_IB_PAVTYPE\n", + "SIDEWALK_IB_WIDTH\n", + "SIDEWALK_OB_PAVTYPE\n", + "SIDEWALK_OB_WIDTH\n", + "SPEEDLIMITS_IB\n", + "SPEEDLIMITS_IB_ALT\n", + "SPEEDLIMITS_OB\n", + "SPEEDLIMITS_OB_ALT\n", + "STREETNAME\n", + "STREETTYPE\n", + "BLOCK_NAME\n", + "ADDRESS_RANGE_HIGH\n", + "ADDRESS_RANGE_LOW\n", + "ADDRESS_RANGE_RIGHT_HIGH\n", + "ADDRESS_RANGE_LEFT_HIGH\n", + "ADDRESS_RANGE_RIGHT_LOW\n", + "MAR_ID\n", + "ADDRESS_RANGE_LEFT_LOW\n", + "BLOCKID\n", + "DCFUNCTIONALCLASS\n", + "NHSTYPE\n", + "SNOWROUTE_DDOT\n", + "SNOWROUTE_DPW\n", + "SNOWSECTION_DDOT\n", + "SNOWZONE_DDOT\n", + "SNOWZONE_DPW\n", + "LEFTTURN_CURBLANE_EXCL\n", + "LEFTTURN_CURBLANE_EXCL_LEN\n", + "RIGHTTURN_CURBLANE_EXCL\n", + "RIGHTTURN_CURBLANE_EXCL_LEN\n", + "TOTALBIKELANES\n", + "TOTALBIKELANEWIDTH\n", + "RPPDIRECTION\n", + "RPPSIDE\n", + "SLOWSTREETINFO\n", + "BIKELANE_DUAL_BUFFERED\n", + "RIGHTTURN_EXCLUSIVE\n", + "LEFTTURN_EXCLUSIVE\n", + "BUSLANE_INBOUND\n", + "BUSLANE_OUTBOUND\n", + "FROMSTREET\n", + "TOSTREET\n", + "WARD_ID\n", + "ANC_ID\n", + "SMD_ID\n", + "SURFACE_TYPE\n", + "PARKINGZONE_ROP\n", + "PARKINGZONE_RPP\n", + "AADT_COMBINATION\n", + "AADT_COMBINATION_YEAR\n", + "AADT_SINGLE_UNIT\n", + "AADT_SINGLE_UNIT_YEAR\n", + "DC_MAINTENANCE_OPERATIONS\n", + "MAINTENANCE_OPERATIONS\n", + "VERTICAL_DEFLECTION\n", + "OBJECTID\n", + "SHAPELEN\n", + "index\n", + "TOTALBIKELANEWIDTH_WEXTRA\n", + "PERBIKELANEWIDTH\n", + "ADJPLREACH\n" + ] + } + ], + "source": [ + "for c in roads.columns:\n", + " print(c)" + ] + }, + { + "cell_type": "markdown", + "id": "52162e82-5e5f-4a58-b266-fb59e9f285e1", + "metadata": {}, + "source": [ + "## Mixed roads\n", + "\n", + "This scenario has the most complex logic. The general logic is based on the number of lanes (whether there is a centerline, if it's two-way, if it's wide, how many lanes there are), the average daily traffic (ADT), and prevailing speed. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "### Variable equivalence\n", + "\n", + "* to use this table: TOTALBIKELANES == 0\n", + "* Directionality: SUMMARYDIRECTION == BD or ?? is two way, IB or OB is one way, sometimes don't need to check\n", + "* centerline: DOUBLEYELLOW_LINE == yes or TOTALRAISEDBUFFERS > 0 (no centerline- DOUBLEYELLOW_LINE != yes and TOTALRAISEDBUFFERS == 0\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes inbound: TOTALTRAVELLANESINBOUND\n", + "* Number of travel lanes outbound: TOTALTRAVELLANESOUTBOUND\n", + "* width_onewaynparking: TOTALPARKINGLANES is 0,1, or 2/greater (doesn't mean it's on both sides), width: TOTALCROSSSECTIONWIDTH (threshold will depend on number of parking lanes\n", + "* min ADT and max ADT: AADT\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB" + ] + }, + { + "cell_type": "markdown", + "id": "db43faed-1b6a-4508-9a8c-c4444380ba58", + "metadata": {}, + "source": [ + "### Set up mixed-traffic" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "id": "53e7b97a-9850-4f0c-97a5-b6dd3709c9ad", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionDirectionalitycenterlineTotal number of Travel LanesNumber of travel lanes in one directionwidth_onewaymin ADTmax ADT23.528.533.538.543.548.5100
0noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.01122333
1noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN750.01500.01123333
2noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN1500.03000.02223344
3noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN3000.01000000.02233444
4noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaNNaNNaN2223344
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Directionality centerline \\\n", + "0 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "1 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "2 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "3 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "4 none Unlaned 2-way street (no centerline) 2.0 0.0 \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 max2 NaN \n", + "1 max2 NaN \n", + "2 max2 NaN \n", + "3 max2 NaN \n", + "4 max2 NaN \n", + "\n", + " width_oneway min ADT max ADT 23.5 28.5 33.5 38.5 43.5 48.5 100 \n", + "0 NaN 0.0 750.0 1 1 2 2 3 3 3 \n", + "1 NaN 750.0 1500.0 1 1 2 3 3 3 3 \n", + "2 NaN 1500.0 3000.0 2 2 2 3 3 4 4 \n", + "3 NaN 3000.0 1000000.0 2 2 3 3 4 4 4 \n", + "4 NaN NaN NaN 2 2 2 3 3 4 4 " + ] + }, + "execution_count": 73, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'MixedTraffic' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "id": "2e834ff1-5a31-49ef-a14d-ecc025704f70", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index([ 'Bike lane',\n", + " 'Description',\n", + " 'Directionality',\n", + " 'centerline',\n", + " 'Total number of Travel Lanes',\n", + " 'Number of travel lanes in one direction',\n", + " 'width_oneway',\n", + " 'min ADT',\n", + " 'max ADT',\n", + " 'level_9',\n", + " 0],\n", + " dtype='object')\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionDirectionalitycenterlineTotal number of Travel LanesNumber of travel lanes in one directionwidth_onewaymin ADTmax ADTmaxspeedminspeedlevel
0noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.023.50.01
1noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.028.523.51
2noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.033.528.52
3noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.038.533.52
4noneUnlaned 2-way street (no centerline)2.00.0max2NaNNaN0.0750.043.538.53
.......................................
142none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN33.528.54
143none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN38.533.54
144none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN43.538.54
145none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN48.543.54
146none3+ thru lanes in at least one directionNaNNaNNaNmin3NaNNaNNaN100.048.54
\n", + "

147 rows × 12 columns

\n", + "
" + ], + "text/plain": [ + " Bike lane Description Directionality \\\n", + "0 none Unlaned 2-way street (no centerline) 2.0 \n", + "1 none Unlaned 2-way street (no centerline) 2.0 \n", + "2 none Unlaned 2-way street (no centerline) 2.0 \n", + "3 none Unlaned 2-way street (no centerline) 2.0 \n", + "4 none Unlaned 2-way street (no centerline) 2.0 \n", + ".. ... ... ... \n", + "142 none 3+ thru lanes in at least one direction NaN \n", + "143 none 3+ thru lanes in at least one direction NaN \n", + "144 none 3+ thru lanes in at least one direction NaN \n", + "145 none 3+ thru lanes in at least one direction NaN \n", + "146 none 3+ thru lanes in at least one direction NaN \n", + "\n", + " centerline Total number of Travel Lanes \\\n", + "0 0.0 max2 \n", + "1 0.0 max2 \n", + "2 0.0 max2 \n", + "3 0.0 max2 \n", + "4 0.0 max2 \n", + ".. ... ... \n", + "142 NaN NaN \n", + "143 NaN NaN \n", + "144 NaN NaN \n", + "145 NaN NaN \n", + "146 NaN NaN \n", + "\n", + " Number of travel lanes in one direction width_oneway min ADT max ADT \\\n", + "0 NaN NaN 0.0 750.0 \n", + "1 NaN NaN 0.0 750.0 \n", + "2 NaN NaN 0.0 750.0 \n", + "3 NaN NaN 0.0 750.0 \n", + "4 NaN NaN 0.0 750.0 \n", + ".. ... ... ... ... \n", + "142 min3 NaN NaN NaN \n", + "143 min3 NaN NaN NaN \n", + "144 min3 NaN NaN NaN \n", + "145 min3 NaN NaN NaN \n", + "146 min3 NaN NaN NaN \n", + "\n", + " maxspeed minspeed level \n", + "0 23.5 0.0 1 \n", + "1 28.5 23.5 1 \n", + "2 33.5 28.5 2 \n", + "3 38.5 33.5 2 \n", + "4 43.5 38.5 3 \n", + ".. ... ... ... \n", + "142 33.5 28.5 4 \n", + "143 38.5 33.5 4 \n", + "144 43.5 38.5 4 \n", + "145 48.5 43.5 4 \n", + "146 100.0 48.5 4 \n", + "\n", + "[147 rows x 12 columns]" + ] + }, + "execution_count": 74, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "print(df.columns)\n", + "df = df.rename(columns={'level_9':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "id": "4d540f09-2ecd-42cf-9154-5ca3ffb53798", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
0110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a0842037...2020.011None41950270000.00.0
1110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c22016...NaN11None41950280100.00.0
2110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f920024...2020.011None41950290200.00.0
3110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb40140...2020.011None41950300300.00.0
411033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef85122016...NaN11YES41950310400.00.0
..................................................................
13831130056020.00000075.67289756TH ST SE14f134473a059c441693e485dbec5a6c112016...NaN11YES421149801383100.00.0
13833130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a40042...2020.011None421150001383300.00.0
1383513018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad44322018...NaN11None421150201383500.00.0
13836130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d1620028...NaN11None421150301383600.00.0
138371306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd75311014...NaN1073None421150401383700.00.0
\n", + "

12358 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11000602 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 11003202 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 11037892 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 11001602 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 11033472 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... ... \n", + "13831 13005602 0.000000 75.672897 56TH ST SE 1 \n", + "13833 13081512 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13835 13018522 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 13076442 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 13069532 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13831 4f134473a059c441693e485dbec5a6c1 1 2 \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "0 0 37 ... 2020.0 \n", + "1 0 16 ... NaN \n", + "2 0 24 ... 2020.0 \n", + "3 1 40 ... 2020.0 \n", + "4 0 16 ... NaN \n", + "... ... ... ... ... \n", + "13831 0 16 ... NaN \n", + "13833 0 42 ... 2020.0 \n", + "13835 0 18 ... NaN \n", + "13836 0 28 ... NaN \n", + "13837 0 14 ... NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "0 1 1 None \n", + "1 1 1 None \n", + "2 1 1 None \n", + "3 1 1 None \n", + "4 1 1 YES \n", + "... ... ... ... \n", + "13831 1 1 YES \n", + "13833 1 1 None \n", + "13835 1 1 None \n", + "13836 1 1 None \n", + "13837 10 73 None \n", + "\n", + " OBJECTID SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH \\\n", + "0 4195027 0 0 0 0.0 \n", + "1 4195028 0 1 0 0.0 \n", + "2 4195029 0 2 0 0.0 \n", + "3 4195030 0 3 0 0.0 \n", + "4 4195031 0 4 0 0.0 \n", + "... ... ... ... ... ... \n", + "13831 4211498 0 13831 0 0.0 \n", + "13833 4211500 0 13833 0 0.0 \n", + "13835 4211502 0 13835 0 0.0 \n", + "13836 4211503 0 13836 0 0.0 \n", + "13837 4211504 0 13837 0 0.0 \n", + "\n", + " ADJPLREACH \n", + "0 0.0 \n", + "1 0.0 \n", + "2 0.0 \n", + "3 0.0 \n", + "4 0.0 \n", + "... ... \n", + "13831 0.0 \n", + "13833 0.0 \n", + "13835 0.0 \n", + "13836 0.0 \n", + "13837 0.0 \n", + "\n", + "[12358 rows x 105 columns]" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#keep the roads with no bikelanes (bikes go in the car lane traffic)\n", + "roads_mixed = roads[roads['TOTALBIKELANES'] ==0]\n", + "roads_mixed" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dd1db9b-51ff-4dd6-916e-bdb88a32c2e0", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each ADT and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, ADT, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "def get_levels(curr_df, curr_roads, road_levels, ignore_ADT = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/ADT/speedlimit combo\n", + " sel = []\n", + " print(str(row['min ADT'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by ADT, just by speedlimit\n", + " if ignore_ADT:\n", + " sel = curr_roads[((curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed']))]\n", + " print(len(sel)) \n", + " #if ADT delinations are made, use this section\n", + " else:\n", + " if pd.isna(row['max ADT']):\n", + " sel = curr_roads[curr_roads['AADT'].isna() & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " else:\n", + " sel = curr_roads[ (curr_roads['AADT']>=row['min ADT']) & (curr_roads['AADT'] < row['max ADT']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/ADT/speedlimit combo and the road segments matching the description, assign the appropriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373])\n", + " #if there are any road segment left over, assign them to the highest value (the last one used, generally 4) to be conservative\n", + " #this happens if there is an unusual configuration (ex- 0 lanes in either direction on a 1-way street, etc)\n", + " #the number of 'left over' roads is printed out so it can be verified that it's not too large, which could point to a large problem.\n", + " inds = np.setdiff1d(curr_roads['index'].values, list(road_levels.keys()))\n", + " print('left over')\n", + " print(len(inds))\n", + " sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " print('no speedlimit')\n", + " print(len(sel))\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level'] \n", + " return road_levels" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "id": "8a240770", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8741\n", + "8741\n", + "-----\n", + "0.0---0.0\n", + "8\n", + "0.0---23.5\n", + "1\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "750.0---0.0\n", + "43\n", + "750.0---23.5\n", + "30\n", + "750.0---28.5\n", + "0\n", + "750.0---33.5\n", + "0\n", + "750.0---38.5\n", + "0\n", + "750.0---43.5\n", + "0\n", + "750.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "208\n", + "1500.0---23.5\n", + "204\n", + "1500.0---28.5\n", + "9\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "3000.0---0.0\n", + "405\n", + "3000.0---23.5\n", + "631\n", + "3000.0---28.5\n", + "38\n", + "3000.0---33.5\n", + "3\n", + "3000.0---38.5\n", + "0\n", + "3000.0---43.5\n", + "0\n", + "3000.0---48.5\n", + "0\n", + "nan---0.0\n", + "6175\n", + "nan---23.5\n", + "519\n", + "nan---28.5\n", + "33\n", + "nan---33.5\n", + "1\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "433\n", + "no speedlimit\n", + "433\n", + "8741\n", + "92\n", + "-----\n", + "0.0---0.0\n", + "1\n", + "0.0---23.5\n", + "0\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "0\n", + "1000.0---23.5\n", + "0\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "12\n", + "1500.0---23.5\n", + "21\n", + "1500.0---28.5\n", + "2\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "nan---0.0\n", + "45\n", + "nan---23.5\n", + "4\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "7\n", + "no speedlimit\n", + "7\n", + "8833\n", + "786\n", + "786\n", + "-----\n", + "0.0---0.0\n", + "5\n", + "0.0---23.5\n", + "4\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "2\n", + "1000.0---23.5\n", + "1\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "1500.0---0.0\n", + "23\n", + "1500.0---23.5\n", + "19\n", + "1500.0---28.5\n", + "0\n", + "1500.0---33.5\n", + "0\n", + "1500.0---38.5\n", + "0\n", + "1500.0---43.5\n", + "0\n", + "1500.0---48.5\n", + "0\n", + "nan---0.0\n", + "289\n", + "nan---23.5\n", + "9\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "434\n", + "no speedlimit\n", + "434\n", + "9619\n", + "391\n", + "391\n", + "-----\n", + "0.0---0.0\n", + "1\n", + "0.0---23.5\n", + "0\n", + "0.0---28.5\n", + "0\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "600.0---0.0\n", + "0\n", + "600.0---23.5\n", + "0\n", + "600.0---28.5\n", + "0\n", + "600.0---33.5\n", + "0\n", + "600.0---38.5\n", + "0\n", + "600.0---43.5\n", + "0\n", + "600.0---48.5\n", + "0\n", + "1000.0---0.0\n", + "3\n", + "1000.0---23.5\n", + "3\n", + "1000.0---28.5\n", + "0\n", + "1000.0---33.5\n", + "0\n", + "1000.0---38.5\n", + "0\n", + "1000.0---43.5\n", + "0\n", + "1000.0---48.5\n", + "0\n", + "nan---0.0\n", + "188\n", + "nan---23.5\n", + "8\n", + "nan---28.5\n", + "0\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "188\n", + "no speedlimit\n", + "188\n", + "10010\n", + "1461\n", + "1461\n", + "-----\n", + "0.0---0.0\n", + "113\n", + "0.0---23.5\n", + "91\n", + "0.0---28.5\n", + "12\n", + "0.0---33.5\n", + "0\n", + "0.0---38.5\n", + "0\n", + "0.0---43.5\n", + "0\n", + "0.0---48.5\n", + "0\n", + "8000.0---0.0\n", + "217\n", + "8000.0---23.5\n", + "280\n", + "8000.0---28.5\n", + "244\n", + "8000.0---33.5\n", + "11\n", + "8000.0---38.5\n", + "3\n", + "8000.0---43.5\n", + "3\n", + "8000.0---48.5\n", + "0\n", + "nan---0.0\n", + "214\n", + "nan---23.5\n", + "37\n", + "nan---28.5\n", + "31\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "left over\n", + "205\n", + "no speedlimit\n", + "205\n", + "11471\n", + "810\n", + "810\n", + "-----\n", + "nan---0.0\n", + "320\n", + "nan---23.5\n", + "210\n", + "nan---28.5\n", + "108\n", + "nan---33.5\n", + "13\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "3\n", + "nan---48.5\n", + "1\n", + "left over\n", + "155\n", + "no speedlimit\n", + "155\n", + "12281\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the ADT/speedlimit divisions\n", + "\n", + "#check directionality, centerline, and number of lanes (2,0,2)\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'BD') | (roads_mixed['SUMMARYDIRECTION'] == '??')) & \\\n", + " ((roads_mixed['DOUBLEYELLOW_LINE'] != 'yes') & (roads_mixed['TOTALRAISEDBUFFERS'] == 0)) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] <= 2)\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 2) & (df['centerline'] == 0) & (df['Total number of Travel Lanes'] == 'max2')]\n", + "road_levels = {}\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality, centerline, and number of lanes in one direction (2,1,1perDir)\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'BD') | (roads_mixed['SUMMARYDIRECTION'] == '??')) & \\\n", + " ((roads_mixed['DOUBLEYELLOW_LINE'] == 'yes') | (roads_mixed['TOTALRAISEDBUFFERS'] > 0)) & \\\n", + " ((roads_mixed['TOTALTRAVELLANESINBOUND'] == 1) & (roads_mixed['TOTALTRAVELLANESOUTBOUND'] == 1))\n", + "curr_roads = roads_mixed[curr_check]\n", + "curr_df = df[(df['Directionality'] == 2) & (df['centerline'] == 1) & (df['Number of travel lanes in one direction'] == '1perDir')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality and number of lanes (1, 1) and wide roads\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'IB') | (roads_mixed['SUMMARYDIRECTION'] == 'OB')) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] == 1) & \\\n", + " (((roads_mixed['TOTALPARKINGLANES'] == 0) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 15)) | ((roads_mixed['TOTALPARKINGLANES'] == 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 22)) | ((roads_mixed['TOTALPARKINGLANES'] > 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] >= 30)))\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 1) & (df['Total number of Travel Lanes'] == 1) & (df['width_oneway'] == 'wide')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality and number of lanes (1, 1) and narrow roads\n", + "curr_check = ((roads_mixed['SUMMARYDIRECTION'] == 'IB') | (roads_mixed['SUMMARYDIRECTION'] == 'OB')) & \\\n", + " (roads_mixed['TOTALTRAVELLANES'] == 1) & \\\n", + " (((roads_mixed['TOTALPARKINGLANES'] == 0) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 15)) | ((roads_mixed['TOTALPARKINGLANES'] == 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 22)) | ((roads_mixed['TOTALPARKINGLANES'] > 1) & (roads_mixed['TOTALCROSSSECTIONWIDTH'] < 30)))\n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Directionality'] == 1) & (df['Total number of Travel Lanes'] == 1)& (df['width_oneway'] == 'narrow')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality (2) and 2 thru lanes in at least on direction\n", + "curr_check = (((roads_mixed['TOTALTRAVELLANESINBOUND'] == 2) & (roads_mixed['TOTALTRAVELLANESOUTBOUND'] <= 2)) | ((roads_mixed['TOTALTRAVELLANESOUTBOUND'] == 2)& (roads_mixed['TOTALTRAVELLANESINBOUND'] <= 2))) \n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max2')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "\n", + "#check directionality (2) and 3 thru lanes in at leat least on direction\n", + "curr_check = ((roads_mixed['TOTALTRAVELLANESINBOUND'] > 2) | (roads_mixed['TOTALTRAVELLANESOUTBOUND'] > 2)) \n", + "curr_roads = roads_mixed[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3')]\n", + "road_levels = get_levels(curr_df, curr_roads, road_levels, ignore_ADT = True)\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "b4790af4", + "metadata": {}, + "source": [ + "# Conventional bike lane, not adjacent to a parking lane\n", + "\n", + "\n", + "The logic is based on the number of lanes, bike lane width, and prevailing speed. The bike lane width includes any buffer area. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "## Variable equivalence\n", + "\n", + "* Is the bike lane adjacent to a parking lane: BIKELANE_PARKINGLANE_ADJACENT\n", + "* bike lane: BIKELANE_CONTRAFLOW, BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED\n", + "* BidirectionalLane: TOTALTRAVELLANESBIDIRECTIONAL (check if 0 or >0)\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes in one direction: TOTALTRAVELLANESOUTBOUND and TOTALTRAVELLANESINBOUND\n", + "* max bike lane width and min bike lane width: PERBIKELANEWIDTH (might not be accurate)\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB\n" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "07cee2d7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane widthmin bike lane width28.533.538.543.548.5100
0conventional00NaNNaNmax1other0100.06.0112333
1conventional00NaNNaNmax1other06.04.0222334
2conventional000.0NaNexactly1100.06.0112333
3conventional000.0NaNexactly16.04.0222334
4conventional001.0NaNexactly1100.04.0112333
5conventional001.0NaNexactly14.02.0222334
6conventional00NaNNaNmax2100.06.0222333
7conventional00NaNNaNmax26.04.0222344
8conventional00NaNNaNmin3NaNNaN333444
9conventional00NaNNaNmin3NaNNaN333444
\n", + "
" + ], + "text/plain": [ + " Bike lane Frequent blocks AdjacentToParking BirectionalLane \\\n", + "0 conventional 0 0 NaN \n", + "1 conventional 0 0 NaN \n", + "2 conventional 0 0 0.0 \n", + "3 conventional 0 0 0.0 \n", + "4 conventional 0 0 1.0 \n", + "5 conventional 0 0 1.0 \n", + "6 conventional 0 0 NaN \n", + "7 conventional 0 0 NaN \n", + "8 conventional 0 0 NaN \n", + "9 conventional 0 0 NaN \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 NaN max1other0 \n", + "1 NaN max1other0 \n", + "2 NaN exactly1 \n", + "3 NaN exactly1 \n", + "4 NaN exactly1 \n", + "5 NaN exactly1 \n", + "6 NaN max2 \n", + "7 NaN max2 \n", + "8 NaN min3 \n", + "9 NaN min3 \n", + "\n", + " max bike lane width min bike lane width 28.5 33.5 38.5 43.5 48.5 100 \n", + "0 100.0 6.0 1 1 2 3 3 3 \n", + "1 6.0 4.0 2 2 2 3 3 4 \n", + "2 100.0 6.0 1 1 2 3 3 3 \n", + "3 6.0 4.0 2 2 2 3 3 4 \n", + "4 100.0 4.0 1 1 2 3 3 3 \n", + "5 4.0 2.0 2 2 2 3 3 4 \n", + "6 100.0 6.0 2 2 2 3 3 3 \n", + "7 6.0 4.0 2 2 2 3 4 4 \n", + "8 NaN NaN 3 3 3 4 4 4 \n", + "9 NaN NaN 3 3 3 4 4 4 " + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'conventional_notPL' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "ad1089fc", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane widthmin bike lane widthmaxspeedminspeedlevel
0conventional00NaNNaNmax1other0100.06.028.50.01
1conventional00NaNNaNmax1other0100.06.033.528.51
2conventional00NaNNaNmax1other0100.06.038.533.52
3conventional00NaNNaNmax1other0100.06.043.538.53
4conventional00NaNNaNmax1other0100.06.048.543.53
5conventional00NaNNaNmax1other0100.06.0100.048.53
6conventional00NaNNaNmax1other06.04.028.50.02
7conventional00NaNNaNmax1other06.04.033.528.52
8conventional00NaNNaNmax1other06.04.038.533.52
9conventional00NaNNaNmax1other06.04.043.538.53
10conventional00NaNNaNmax1other06.04.048.543.53
11conventional00NaNNaNmax1other06.04.0100.048.54
12conventional000.0NaNexactly1100.06.028.50.01
13conventional000.0NaNexactly1100.06.033.528.51
14conventional000.0NaNexactly1100.06.038.533.52
15conventional000.0NaNexactly1100.06.043.538.53
16conventional000.0NaNexactly1100.06.048.543.53
17conventional000.0NaNexactly1100.06.0100.048.53
18conventional000.0NaNexactly16.04.028.50.02
19conventional000.0NaNexactly16.04.033.528.52
20conventional000.0NaNexactly16.04.038.533.52
21conventional000.0NaNexactly16.04.043.538.53
22conventional000.0NaNexactly16.04.048.543.53
23conventional000.0NaNexactly16.04.0100.048.54
24conventional001.0NaNexactly1100.04.028.50.01
25conventional001.0NaNexactly1100.04.033.528.51
26conventional001.0NaNexactly1100.04.038.533.52
27conventional001.0NaNexactly1100.04.043.538.53
28conventional001.0NaNexactly1100.04.048.543.53
29conventional001.0NaNexactly1100.04.0100.048.53
30conventional001.0NaNexactly14.02.028.50.02
31conventional001.0NaNexactly14.02.033.528.52
32conventional001.0NaNexactly14.02.038.533.52
33conventional001.0NaNexactly14.02.043.538.53
34conventional001.0NaNexactly14.02.048.543.53
35conventional001.0NaNexactly14.02.0100.048.54
36conventional00NaNNaNmax2100.06.028.50.02
37conventional00NaNNaNmax2100.06.033.528.52
38conventional00NaNNaNmax2100.06.038.533.52
39conventional00NaNNaNmax2100.06.043.538.53
40conventional00NaNNaNmax2100.06.048.543.53
41conventional00NaNNaNmax2100.06.0100.048.53
42conventional00NaNNaNmax26.04.028.50.02
43conventional00NaNNaNmax26.04.033.528.52
44conventional00NaNNaNmax26.04.038.533.52
45conventional00NaNNaNmax26.04.043.538.53
46conventional00NaNNaNmax26.04.048.543.54
47conventional00NaNNaNmax26.04.0100.048.54
48conventional00NaNNaNmin3NaNNaN28.50.03
49conventional00NaNNaNmin3NaNNaN33.528.53
50conventional00NaNNaNmin3NaNNaN38.533.53
51conventional00NaNNaNmin3NaNNaN43.538.54
52conventional00NaNNaNmin3NaNNaN48.543.54
53conventional00NaNNaNmin3NaNNaN100.048.54
54conventional00NaNNaNmin3NaNNaN28.50.03
55conventional00NaNNaNmin3NaNNaN33.528.53
56conventional00NaNNaNmin3NaNNaN38.533.53
57conventional00NaNNaNmin3NaNNaN43.538.54
58conventional00NaNNaNmin3NaNNaN48.543.54
59conventional00NaNNaNmin3NaNNaN100.048.54
\n", + "
" + ], + "text/plain": [ + " Bike lane Frequent blocks AdjacentToParking BirectionalLane \\\n", + "0 conventional 0 0 NaN \n", + "1 conventional 0 0 NaN \n", + "2 conventional 0 0 NaN \n", + "3 conventional 0 0 NaN \n", + "4 conventional 0 0 NaN \n", + "5 conventional 0 0 NaN \n", + "6 conventional 0 0 NaN \n", + "7 conventional 0 0 NaN \n", + "8 conventional 0 0 NaN \n", + "9 conventional 0 0 NaN \n", + "10 conventional 0 0 NaN \n", + "11 conventional 0 0 NaN \n", + "12 conventional 0 0 0.0 \n", + "13 conventional 0 0 0.0 \n", + "14 conventional 0 0 0.0 \n", + "15 conventional 0 0 0.0 \n", + "16 conventional 0 0 0.0 \n", + "17 conventional 0 0 0.0 \n", + "18 conventional 0 0 0.0 \n", + "19 conventional 0 0 0.0 \n", + "20 conventional 0 0 0.0 \n", + "21 conventional 0 0 0.0 \n", + "22 conventional 0 0 0.0 \n", + "23 conventional 0 0 0.0 \n", + "24 conventional 0 0 1.0 \n", + "25 conventional 0 0 1.0 \n", + "26 conventional 0 0 1.0 \n", + "27 conventional 0 0 1.0 \n", + "28 conventional 0 0 1.0 \n", + "29 conventional 0 0 1.0 \n", + "30 conventional 0 0 1.0 \n", + "31 conventional 0 0 1.0 \n", + "32 conventional 0 0 1.0 \n", + "33 conventional 0 0 1.0 \n", + "34 conventional 0 0 1.0 \n", + "35 conventional 0 0 1.0 \n", + "36 conventional 0 0 NaN \n", + "37 conventional 0 0 NaN \n", + "38 conventional 0 0 NaN \n", + "39 conventional 0 0 NaN \n", + "40 conventional 0 0 NaN \n", + "41 conventional 0 0 NaN \n", + "42 conventional 0 0 NaN \n", + "43 conventional 0 0 NaN \n", + "44 conventional 0 0 NaN \n", + "45 conventional 0 0 NaN \n", + "46 conventional 0 0 NaN \n", + "47 conventional 0 0 NaN \n", + "48 conventional 0 0 NaN \n", + "49 conventional 0 0 NaN \n", + "50 conventional 0 0 NaN \n", + "51 conventional 0 0 NaN \n", + "52 conventional 0 0 NaN \n", + "53 conventional 0 0 NaN \n", + "54 conventional 0 0 NaN \n", + "55 conventional 0 0 NaN \n", + "56 conventional 0 0 NaN \n", + "57 conventional 0 0 NaN \n", + "58 conventional 0 0 NaN \n", + "59 conventional 0 0 NaN \n", + "\n", + " Total number of Travel Lanes Number of travel lanes in one direction \\\n", + "0 NaN max1other0 \n", + "1 NaN max1other0 \n", + "2 NaN max1other0 \n", + "3 NaN max1other0 \n", + "4 NaN max1other0 \n", + "5 NaN max1other0 \n", + "6 NaN max1other0 \n", + "7 NaN max1other0 \n", + "8 NaN max1other0 \n", + "9 NaN max1other0 \n", + "10 NaN max1other0 \n", + "11 NaN max1other0 \n", + "12 NaN exactly1 \n", + "13 NaN exactly1 \n", + "14 NaN exactly1 \n", + "15 NaN exactly1 \n", + "16 NaN exactly1 \n", + "17 NaN exactly1 \n", + "18 NaN exactly1 \n", + "19 NaN exactly1 \n", + "20 NaN exactly1 \n", + "21 NaN exactly1 \n", + "22 NaN exactly1 \n", + "23 NaN exactly1 \n", + "24 NaN exactly1 \n", + "25 NaN exactly1 \n", + "26 NaN exactly1 \n", + "27 NaN exactly1 \n", + "28 NaN exactly1 \n", + "29 NaN exactly1 \n", + "30 NaN exactly1 \n", + "31 NaN exactly1 \n", + "32 NaN exactly1 \n", + "33 NaN exactly1 \n", + "34 NaN exactly1 \n", + "35 NaN exactly1 \n", + "36 NaN max2 \n", + "37 NaN max2 \n", + "38 NaN max2 \n", + "39 NaN max2 \n", + "40 NaN max2 \n", + "41 NaN max2 \n", + "42 NaN max2 \n", + "43 NaN max2 \n", + "44 NaN max2 \n", + "45 NaN max2 \n", + "46 NaN max2 \n", + "47 NaN max2 \n", + "48 NaN min3 \n", + "49 NaN min3 \n", + "50 NaN min3 \n", + "51 NaN min3 \n", + "52 NaN min3 \n", + "53 NaN min3 \n", + "54 NaN min3 \n", + "55 NaN min3 \n", + "56 NaN min3 \n", + "57 NaN min3 \n", + "58 NaN min3 \n", + "59 NaN min3 \n", + "\n", + " max bike lane width min bike lane width maxspeed minspeed level \n", + "0 100.0 6.0 28.5 0.0 1 \n", + "1 100.0 6.0 33.5 28.5 1 \n", + "2 100.0 6.0 38.5 33.5 2 \n", + "3 100.0 6.0 43.5 38.5 3 \n", + "4 100.0 6.0 48.5 43.5 3 \n", + "5 100.0 6.0 100.0 48.5 3 \n", + "6 6.0 4.0 28.5 0.0 2 \n", + "7 6.0 4.0 33.5 28.5 2 \n", + "8 6.0 4.0 38.5 33.5 2 \n", + "9 6.0 4.0 43.5 38.5 3 \n", + "10 6.0 4.0 48.5 43.5 3 \n", + "11 6.0 4.0 100.0 48.5 4 \n", + "12 100.0 6.0 28.5 0.0 1 \n", + "13 100.0 6.0 33.5 28.5 1 \n", + "14 100.0 6.0 38.5 33.5 2 \n", + "15 100.0 6.0 43.5 38.5 3 \n", + "16 100.0 6.0 48.5 43.5 3 \n", + "17 100.0 6.0 100.0 48.5 3 \n", + "18 6.0 4.0 28.5 0.0 2 \n", + "19 6.0 4.0 33.5 28.5 2 \n", + "20 6.0 4.0 38.5 33.5 2 \n", + "21 6.0 4.0 43.5 38.5 3 \n", + "22 6.0 4.0 48.5 43.5 3 \n", + "23 6.0 4.0 100.0 48.5 4 \n", + "24 100.0 4.0 28.5 0.0 1 \n", + "25 100.0 4.0 33.5 28.5 1 \n", + "26 100.0 4.0 38.5 33.5 2 \n", + "27 100.0 4.0 43.5 38.5 3 \n", + "28 100.0 4.0 48.5 43.5 3 \n", + "29 100.0 4.0 100.0 48.5 3 \n", + "30 4.0 2.0 28.5 0.0 2 \n", + "31 4.0 2.0 33.5 28.5 2 \n", + "32 4.0 2.0 38.5 33.5 2 \n", + "33 4.0 2.0 43.5 38.5 3 \n", + "34 4.0 2.0 48.5 43.5 3 \n", + "35 4.0 2.0 100.0 48.5 4 \n", + "36 100.0 6.0 28.5 0.0 2 \n", + "37 100.0 6.0 33.5 28.5 2 \n", + "38 100.0 6.0 38.5 33.5 2 \n", + "39 100.0 6.0 43.5 38.5 3 \n", + "40 100.0 6.0 48.5 43.5 3 \n", + "41 100.0 6.0 100.0 48.5 3 \n", + "42 6.0 4.0 28.5 0.0 2 \n", + "43 6.0 4.0 33.5 28.5 2 \n", + "44 6.0 4.0 38.5 33.5 2 \n", + "45 6.0 4.0 43.5 38.5 3 \n", + "46 6.0 4.0 48.5 43.5 4 \n", + "47 6.0 4.0 100.0 48.5 4 \n", + "48 NaN NaN 28.5 0.0 3 \n", + "49 NaN NaN 33.5 28.5 3 \n", + "50 NaN NaN 38.5 33.5 3 \n", + "51 NaN NaN 43.5 38.5 4 \n", + "52 NaN NaN 48.5 43.5 4 \n", + "53 NaN NaN 100.0 48.5 4 \n", + "54 NaN NaN 28.5 0.0 3 \n", + "55 NaN NaN 33.5 28.5 3 \n", + "56 NaN NaN 38.5 33.5 3 \n", + "57 NaN NaN 43.5 38.5 4 \n", + "58 NaN NaN 48.5 43.5 4 \n", + "59 NaN NaN 100.0 48.5 4 " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "df = df.rename(columns={'level_8':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "0d6432ab", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
36110578523723.6967773849.773682M ST NW134aff18001cc26b963e031ae2f74570a31023...NaNNaN37849571103655.00.0
97110534922807.1406252961.828857L ST NW16f57b130652ee5665b6800501d485cd521020...NaNNaN3785018110971111.00.0
116110200220.00000039.681999CALVERT ST NW18c0b3aff2db6e698c631eeb1103cf10e30134...NaNNaN3785037110116199.50.0
137110017022571.9794922654.19946317TH ST NW1cf4d2c8a3c0baa5d307e54b6212404bf12010...NaNNaN37850581101371515.00.0
146110646721752.6352541819.327148NEW YORK AVE NW1a4a03e7d6b749855970e499e3ef673b160261...NaNNaN378506711014694.50.0
..................................................................
1362512092622443.586090562.646484WEST VIRGINIA AVE NE1113953025d018971f10811a46056a01c21020...2020.0NaN381822611013625147.00.0
13642140007021147.3774411249.4969487TH ST SW15c356003a4b48dc0ea70be156a05720641040...NaNNaN381824311013642157.50.0
13667130011021687.2309571834.13757311TH ST SE14a3ef9e4e3d66ed0c15f8300979f227f60161...NaNNaN381826811013667105.00.0
13775130004021036.8702391117.5223394TH ST SE1d1c2228b6607677f3f48b194d9d9d1c530039...NaNNaN38183761101377555.00.0
13777120926222024.5301512134.030029WEST VIRGINIA AVE NE133c780ee1f2199da446042092482f21130030...2020.0NaN3818378110137773015.00.0
\n", + "

254 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "36 11057852 3723.696777 3849.773682 M ST NW 1 \n", + "97 11053492 2807.140625 2961.828857 L ST NW 1 \n", + "116 11020022 0.000000 39.681999 CALVERT ST NW 1 \n", + "137 11001702 2571.979492 2654.199463 17TH ST NW 1 \n", + "146 11064672 1752.635254 1819.327148 NEW YORK AVE NW 1 \n", + "... ... ... ... ... ... \n", + "13625 12092622 443.586090 562.646484 WEST VIRGINIA AVE NE 1 \n", + "13642 14000702 1147.377441 1249.496948 7TH ST SW 1 \n", + "13667 13001102 1687.230957 1834.137573 11TH ST SE 1 \n", + "13775 13000402 1036.870239 1117.522339 4TH ST SE 1 \n", + "13777 12092622 2024.530151 2134.030029 WEST VIRGINIA AVE NE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "36 34aff18001cc26b963e031ae2f74570a 3 1 \n", + "97 6f57b130652ee5665b6800501d485cd5 2 1 \n", + "116 8c0b3aff2db6e698c631eeb1103cf10e 3 0 \n", + "137 cf4d2c8a3c0baa5d307e54b6212404bf 1 2 \n", + "146 a4a03e7d6b749855970e499e3ef673b1 6 0 \n", + "... ... ... ... \n", + "13625 113953025d018971f10811a46056a01c 2 1 \n", + "13642 5c356003a4b48dc0ea70be156a057206 4 1 \n", + "13667 4a3ef9e4e3d66ed0c15f8300979f227f 6 0 \n", + "13775 d1c2228b6607677f3f48b194d9d9d1c5 3 0 \n", + "13777 33c780ee1f2199da446042092482f211 3 0 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "36 0 23 ... NaN \n", + "97 0 20 ... NaN \n", + "116 1 34 ... NaN \n", + "137 0 10 ... NaN \n", + "146 2 61 ... NaN \n", + "... ... ... ... ... \n", + "13625 0 20 ... 2020.0 \n", + "13642 0 40 ... NaN \n", + "13667 1 61 ... NaN \n", + "13775 0 39 ... NaN \n", + "13777 0 30 ... 2020.0 \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "36 NaN 3784957 1 \n", + "97 NaN 3785018 1 \n", + "116 NaN 3785037 1 \n", + "137 NaN 3785058 1 \n", + "146 NaN 3785067 1 \n", + "... ... ... ... \n", + "13625 NaN 3818226 1 \n", + "13642 NaN 3818243 1 \n", + "13667 NaN 3818268 1 \n", + "13775 NaN 3818376 1 \n", + "13777 NaN 3818378 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "36 1 0 36 5 \n", + "97 1 0 97 11 \n", + "116 1 0 116 19 \n", + "137 1 0 137 15 \n", + "146 1 0 146 9 \n", + "... ... ... ... ... \n", + "13625 1 0 13625 14 \n", + "13642 1 0 13642 15 \n", + "13667 1 0 13667 10 \n", + "13775 1 0 13775 5 \n", + "13777 1 0 13777 30 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "36 5.0 0.0 \n", + "97 11.0 0.0 \n", + "116 9.5 0.0 \n", + "137 15.0 0.0 \n", + "146 4.5 0.0 \n", + "... ... ... \n", + "13625 7.0 0.0 \n", + "13642 7.5 0.0 \n", + "13667 5.0 0.0 \n", + "13775 5.0 0.0 \n", + "13777 15.0 0.0 \n", + "\n", + "[254 rows x 105 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_conventional_notPL = roads[((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())]\n", + "roads_conventional_notPL" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1e734909", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each bike-lane width and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, bike-lane width, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "\n", + "def get_levels_conventional(curr_df, curr_roads, road_levels, ignore_width = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/bikelane-width/speedlimit combo\n", + " sel = []\n", + " print(str(row['min bike lane width'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by reach, just by speedlimit\n", + " if ignore_width:\n", + " sel = curr_roads[(curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel)) \n", + " #if bikelane width delineations are made, use this section\n", + " else:\n", + " sel = curr_roads[ (curr_roads['PERBIKELANEWIDTH']>=row['min bike lane width']) & (curr_roads['PERBIKELANEWIDTH'] < row['max bike lane width']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/bikelane width/speedlimit combo and the road segments matching the description, assign the appropriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373]) \n", + " #if there is no speedlimit for some roads, go with the largest level (the last one)\n", + " sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level'] \n", + " return road_levels\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9bf411ca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "24\n", + "24\n", + "-----\n", + "6.0---0.0\n", + "8\n", + "6.0---28.5\n", + "0\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "4\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12302\n", + "93\n", + "93\n", + "-----\n", + "6.0---0.0\n", + "59\n", + "6.0---28.5\n", + "1\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "33\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12395\n", + "12395\n", + "0\n", + "0\n", + "-----\n", + "4.0---0.0\n", + "0\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "2.0---0.0\n", + "0\n", + "2.0---28.5\n", + "0\n", + "2.0---33.5\n", + "0\n", + "2.0---38.5\n", + "0\n", + "2.0---43.5\n", + "0\n", + "2.0---48.5\n", + "0\n", + "12395\n", + "12395\n", + "84\n", + "84\n", + "-----\n", + "6.0---0.0\n", + "43\n", + "6.0---28.5\n", + "1\n", + "6.0---33.5\n", + "0\n", + "6.0---38.5\n", + "0\n", + "6.0---43.5\n", + "0\n", + "6.0---48.5\n", + "0\n", + "4.0---0.0\n", + "29\n", + "4.0---28.5\n", + "0\n", + "4.0---33.5\n", + "0\n", + "4.0---38.5\n", + "0\n", + "4.0---43.5\n", + "0\n", + "4.0---48.5\n", + "0\n", + "12479\n", + "12479\n", + "53\n", + "53\n", + "-----\n", + "nan---0.0\n", + "36\n", + "nan---28.5\n", + "1\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "nan---0.0\n", + "36\n", + "nan---28.5\n", + "1\n", + "nan---33.5\n", + "0\n", + "nan---38.5\n", + "0\n", + "nan---43.5\n", + "0\n", + "nan---48.5\n", + "0\n", + "12532\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the bike lane width/speedlimit divisions\n", + "\n", + "# max1other0\n", + "curr_check = (((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 0) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] <= 1) ) | ((roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 0) & (roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] <= 1)))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max1other0')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "all_road_levels = road_levels\n", + "\n", + "# no bidirectional lane, one in each direction\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_notPL['TOTALTRAVELLANESBIDIRECTIONAL'] == 0)\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==0)]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# bidirectional lane, one in each direction\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_notPL['TOTALTRAVELLANESBIDIRECTIONAL'] > 0)\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==1)]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# max2\n", + "curr_check = (((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] ==2) & (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] <= 2) ) | ((roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] == 2) & (roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] <= 2)))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'max2')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "print(len(all_road_levels))\n", + "\n", + "# at least 3\n", + "curr_check = ((roads_conventional_notPL['TOTALTRAVELLANESOUTBOUND'] >=3) | (roads_conventional_notPL['TOTALTRAVELLANESINBOUND'] >=3))\n", + "curr_roads = roads_conventional_notPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3')]\n", + "road_levels = get_levels_conventional(curr_df, curr_roads, road_levels, ignore_width = True)\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "297d6fce", + "metadata": {}, + "source": [ + "# Conventional, Adjacent to parking lane\n", + "\n", + "The logic is based on the number of lanes, reach (bike and parking lane) width, and prevailing speed. LTS.xlsx contains the logic to assign the level to the roads that fit each criteria.\n", + "\n", + "## Variable equivalence\n", + "\n", + "* Is the bike lane adjacent to a parking lane: BIKELANE_PARKINGLANE_ADJACENT\n", + "* bike lane: BIKELANE_CONTRAFLOW, BIKELANE_CONVENTIONAL, BIKELANE_BUFFERED\n", + "* BirectionalLane: TOTALTRAVELLANESBIDIRECTIONAL (check if 0 or >0)\n", + "* Total number of Travel Lanes: TOTALTRAVELLANES\n", + "* Number of travel lanes in one direction: TOTALTRAVELLANESOUTBOUND and TOTALTRAVELLANESINBOUND\n", + "* max bike lane width and min bike lane width: PERBIKELANEWIDTH (might not be accurate)\n", + "* maxspeed and minspeed: SPEEDLIMITS_OB\n", + "* min bike lane reach width and max bike lane reach width: ADJPLREACH" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "c53ed5fd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane reach widthmin bike lane reach width28.533.538.5100
0conventional1 thru lane per direction010.0NaNexactly1100.015.01223
1conventional1 thru lane per direction010.0NaNexactly115.012.02233
2conventional1 thru lane per direction011.0NaNexactly1100.013.01223
3conventional1 thru lane per direction011.0NaNexactly113.011.02233
4conventional1-way multi-lane01NaNNaNoneIs0100.015.02333
5conventional1-way multi-lane01NaNNaNoneIs015.012.03333
6conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.02333
7conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.03333
8conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN3333
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Frequent blocks \\\n", + "0 conventional 1 thru lane per direction 0 \n", + "1 conventional 1 thru lane per direction 0 \n", + "2 conventional 1 thru lane per direction 0 \n", + "3 conventional 1 thru lane per direction 0 \n", + "4 conventional 1-way multi-lane 0 \n", + "5 conventional 1-way multi-lane 0 \n", + "6 conventional 2-way and 2 lanes per direction 0 \n", + "7 conventional 2-way and 2 lanes per direction 0 \n", + "8 conventional other 2-way multilane 0 \n", + "\n", + " AdjacentToParking BirectionalLane Total number of Travel Lanes \\\n", + "0 1 0.0 NaN \n", + "1 1 0.0 NaN \n", + "2 1 1.0 NaN \n", + "3 1 1.0 NaN \n", + "4 1 NaN NaN \n", + "5 1 NaN NaN \n", + "6 1 NaN NaN \n", + "7 1 NaN NaN \n", + "8 1 NaN NaN \n", + "\n", + " Number of travel lanes in one direction max bike lane reach width \\\n", + "0 exactly1 100.0 \n", + "1 exactly1 15.0 \n", + "2 exactly1 100.0 \n", + "3 exactly1 13.0 \n", + "4 oneIs0 100.0 \n", + "5 oneIs0 15.0 \n", + "6 oneIs2otherIs1or2 100.0 \n", + "7 oneIs2otherIs1or2 15.0 \n", + "8 min3andMin1 NaN \n", + "\n", + " min bike lane reach width 28.5 33.5 38.5 100 \n", + "0 15.0 1 2 2 3 \n", + "1 12.0 2 2 3 3 \n", + "2 13.0 1 2 2 3 \n", + "3 11.0 2 2 3 3 \n", + "4 15.0 2 3 3 3 \n", + "5 12.0 3 3 3 3 \n", + "6 15.0 2 3 3 3 \n", + "7 12.0 3 3 3 3 \n", + "8 NaN 3 3 3 3 " + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "file_path = 'LTS.xlsx' \n", + "sheet_name = 'conventional_AdjacentToPL' # Replace with the actual sheet name\n", + "\n", + "# Read the specific sheet into a DataFrame\n", + "df = pd.read_excel(file_path, sheet_name=sheet_name)\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "743113bc", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index([ 'Bike lane',\n", + " 'Description',\n", + " 'Frequent blocks',\n", + " 'AdjacentToParking',\n", + " 'BirectionalLane',\n", + " 'Total number of Travel Lanes',\n", + " 'Number of travel lanes in one direction',\n", + " 'max bike lane reach width',\n", + " 'min bike lane reach width',\n", + " 'level_9',\n", + " 0],\n", + " dtype='object')\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneDescriptionFrequent blocksAdjacentToParkingBirectionalLaneTotal number of Travel LanesNumber of travel lanes in one directionmax bike lane reach widthmin bike lane reach widthmaxspeedminspeedlevel
0conventional1 thru lane per direction010.0NaNexactly1100.015.028.50.01
1conventional1 thru lane per direction010.0NaNexactly1100.015.033.528.52
2conventional1 thru lane per direction010.0NaNexactly1100.015.038.533.52
3conventional1 thru lane per direction010.0NaNexactly1100.015.0100.038.53
4conventional1 thru lane per direction010.0NaNexactly115.012.028.50.02
5conventional1 thru lane per direction010.0NaNexactly115.012.033.528.52
6conventional1 thru lane per direction010.0NaNexactly115.012.038.533.53
7conventional1 thru lane per direction010.0NaNexactly115.012.0100.038.53
8conventional1 thru lane per direction011.0NaNexactly1100.013.028.50.01
9conventional1 thru lane per direction011.0NaNexactly1100.013.033.528.52
10conventional1 thru lane per direction011.0NaNexactly1100.013.038.533.52
11conventional1 thru lane per direction011.0NaNexactly1100.013.0100.038.53
12conventional1 thru lane per direction011.0NaNexactly113.011.028.50.02
13conventional1 thru lane per direction011.0NaNexactly113.011.033.528.52
14conventional1 thru lane per direction011.0NaNexactly113.011.038.533.53
15conventional1 thru lane per direction011.0NaNexactly113.011.0100.038.53
16conventional1-way multi-lane01NaNNaNoneIs0100.015.028.50.02
17conventional1-way multi-lane01NaNNaNoneIs0100.015.033.528.53
18conventional1-way multi-lane01NaNNaNoneIs0100.015.038.533.53
19conventional1-way multi-lane01NaNNaNoneIs0100.015.0100.038.53
20conventional1-way multi-lane01NaNNaNoneIs015.012.028.50.03
21conventional1-way multi-lane01NaNNaNoneIs015.012.033.528.53
22conventional1-way multi-lane01NaNNaNoneIs015.012.038.533.53
23conventional1-way multi-lane01NaNNaNoneIs015.012.0100.038.53
24conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.028.50.02
25conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.033.528.53
26conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.038.533.53
27conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or2100.015.0100.038.53
28conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.028.50.03
29conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.033.528.53
30conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.038.533.53
31conventional2-way and 2 lanes per direction01NaNNaNoneIs2otherIs1or215.012.0100.038.53
32conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN28.50.03
33conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN33.528.53
34conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN38.533.53
35conventionalother 2-way multilane01NaNNaNmin3andMin1NaNNaN100.038.53
\n", + "
" + ], + "text/plain": [ + " Bike lane Description Frequent blocks \\\n", + "0 conventional 1 thru lane per direction 0 \n", + "1 conventional 1 thru lane per direction 0 \n", + "2 conventional 1 thru lane per direction 0 \n", + "3 conventional 1 thru lane per direction 0 \n", + "4 conventional 1 thru lane per direction 0 \n", + "5 conventional 1 thru lane per direction 0 \n", + "6 conventional 1 thru lane per direction 0 \n", + "7 conventional 1 thru lane per direction 0 \n", + "8 conventional 1 thru lane per direction 0 \n", + "9 conventional 1 thru lane per direction 0 \n", + "10 conventional 1 thru lane per direction 0 \n", + "11 conventional 1 thru lane per direction 0 \n", + "12 conventional 1 thru lane per direction 0 \n", + "13 conventional 1 thru lane per direction 0 \n", + "14 conventional 1 thru lane per direction 0 \n", + "15 conventional 1 thru lane per direction 0 \n", + "16 conventional 1-way multi-lane 0 \n", + "17 conventional 1-way multi-lane 0 \n", + "18 conventional 1-way multi-lane 0 \n", + "19 conventional 1-way multi-lane 0 \n", + "20 conventional 1-way multi-lane 0 \n", + "21 conventional 1-way multi-lane 0 \n", + "22 conventional 1-way multi-lane 0 \n", + "23 conventional 1-way multi-lane 0 \n", + "24 conventional 2-way and 2 lanes per direction 0 \n", + "25 conventional 2-way and 2 lanes per direction 0 \n", + "26 conventional 2-way and 2 lanes per direction 0 \n", + "27 conventional 2-way and 2 lanes per direction 0 \n", + "28 conventional 2-way and 2 lanes per direction 0 \n", + "29 conventional 2-way and 2 lanes per direction 0 \n", + "30 conventional 2-way and 2 lanes per direction 0 \n", + "31 conventional 2-way and 2 lanes per direction 0 \n", + "32 conventional other 2-way multilane 0 \n", + "33 conventional other 2-way multilane 0 \n", + "34 conventional other 2-way multilane 0 \n", + "35 conventional other 2-way multilane 0 \n", + "\n", + " AdjacentToParking BirectionalLane Total number of Travel Lanes \\\n", + "0 1 0.0 NaN \n", + "1 1 0.0 NaN \n", + "2 1 0.0 NaN \n", + "3 1 0.0 NaN \n", + "4 1 0.0 NaN \n", + "5 1 0.0 NaN \n", + "6 1 0.0 NaN \n", + "7 1 0.0 NaN \n", + "8 1 1.0 NaN \n", + "9 1 1.0 NaN \n", + "10 1 1.0 NaN \n", + "11 1 1.0 NaN \n", + "12 1 1.0 NaN \n", + "13 1 1.0 NaN \n", + "14 1 1.0 NaN \n", + "15 1 1.0 NaN \n", + "16 1 NaN NaN \n", + "17 1 NaN NaN \n", + "18 1 NaN NaN \n", + "19 1 NaN NaN \n", + "20 1 NaN NaN \n", + "21 1 NaN NaN \n", + "22 1 NaN NaN \n", + "23 1 NaN NaN \n", + "24 1 NaN NaN \n", + "25 1 NaN NaN \n", + "26 1 NaN NaN \n", + "27 1 NaN NaN \n", + "28 1 NaN NaN \n", + "29 1 NaN NaN \n", + "30 1 NaN NaN \n", + "31 1 NaN NaN \n", + "32 1 NaN NaN \n", + "33 1 NaN NaN \n", + "34 1 NaN NaN \n", + "35 1 NaN NaN \n", + "\n", + " Number of travel lanes in one direction max bike lane reach width \\\n", + "0 exactly1 100.0 \n", + "1 exactly1 100.0 \n", + "2 exactly1 100.0 \n", + "3 exactly1 100.0 \n", + "4 exactly1 15.0 \n", + "5 exactly1 15.0 \n", + "6 exactly1 15.0 \n", + "7 exactly1 15.0 \n", + "8 exactly1 100.0 \n", + "9 exactly1 100.0 \n", + "10 exactly1 100.0 \n", + "11 exactly1 100.0 \n", + "12 exactly1 13.0 \n", + "13 exactly1 13.0 \n", + "14 exactly1 13.0 \n", + "15 exactly1 13.0 \n", + "16 oneIs0 100.0 \n", + "17 oneIs0 100.0 \n", + "18 oneIs0 100.0 \n", + "19 oneIs0 100.0 \n", + "20 oneIs0 15.0 \n", + "21 oneIs0 15.0 \n", + "22 oneIs0 15.0 \n", + "23 oneIs0 15.0 \n", + "24 oneIs2otherIs1or2 100.0 \n", + "25 oneIs2otherIs1or2 100.0 \n", + "26 oneIs2otherIs1or2 100.0 \n", + "27 oneIs2otherIs1or2 100.0 \n", + "28 oneIs2otherIs1or2 15.0 \n", + "29 oneIs2otherIs1or2 15.0 \n", + "30 oneIs2otherIs1or2 15.0 \n", + "31 oneIs2otherIs1or2 15.0 \n", + "32 min3andMin1 NaN \n", + "33 min3andMin1 NaN \n", + "34 min3andMin1 NaN \n", + "35 min3andMin1 NaN \n", + "\n", + " min bike lane reach width maxspeed minspeed level \n", + "0 15.0 28.5 0.0 1 \n", + "1 15.0 33.5 28.5 2 \n", + "2 15.0 38.5 33.5 2 \n", + "3 15.0 100.0 38.5 3 \n", + "4 12.0 28.5 0.0 2 \n", + "5 12.0 33.5 28.5 2 \n", + "6 12.0 38.5 33.5 3 \n", + "7 12.0 100.0 38.5 3 \n", + "8 13.0 28.5 0.0 1 \n", + "9 13.0 33.5 28.5 2 \n", + "10 13.0 38.5 33.5 2 \n", + "11 13.0 100.0 38.5 3 \n", + "12 11.0 28.5 0.0 2 \n", + "13 11.0 33.5 28.5 2 \n", + "14 11.0 38.5 33.5 3 \n", + "15 11.0 100.0 38.5 3 \n", + "16 15.0 28.5 0.0 2 \n", + "17 15.0 33.5 28.5 3 \n", + "18 15.0 38.5 33.5 3 \n", + "19 15.0 100.0 38.5 3 \n", + "20 12.0 28.5 0.0 3 \n", + "21 12.0 33.5 28.5 3 \n", + "22 12.0 38.5 33.5 3 \n", + "23 12.0 100.0 38.5 3 \n", + "24 15.0 28.5 0.0 2 \n", + "25 15.0 33.5 28.5 3 \n", + "26 15.0 38.5 33.5 3 \n", + "27 15.0 100.0 38.5 3 \n", + "28 12.0 28.5 0.0 3 \n", + "29 12.0 33.5 28.5 3 \n", + "30 12.0 38.5 33.5 3 \n", + "31 12.0 100.0 38.5 3 \n", + "32 NaN 28.5 0.0 3 \n", + "33 NaN 33.5 28.5 3 \n", + "34 NaN 38.5 33.5 3 \n", + "35 NaN 100.0 38.5 3 " + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#set speedlimit with min and max speedlimit to take the more human-readable version of the table and make it more machine-readable\n", + "def is_float(element):\n", + " try:\n", + " float(element)\n", + " return True\n", + " except ValueError:\n", + " return False\n", + " \n", + "max_speedlimit = [x for x in df.columns if is_float(x)]\n", + "non_speedlimit = [x for x in df.columns if not is_float(x)]\n", + "min_speedlimit = [0.0]+max_speedlimit[:-1]\n", + "df = df.set_index(non_speedlimit)\n", + "df = df.stack().reset_index()\n", + "print(df.columns)\n", + "df = df.rename(columns={'level_9':'maxspeed', 0:'level'})\n", + "df['minspeed'] = 0\n", + "df['minspeed'] = df['maxspeed'].apply(lambda x: min_speedlimit[max_speedlimit.index(x)])\n", + "cols = list(df.columns)\n", + "cols[-1], cols[-2] = cols[-2], cols[-1]\n", + "df = df[cols]\n", + "df" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "7b7a579a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
3110513522193.0302732296.614258KANSAS AVE NW1c448b8a91c9e954e73db5fb1563d10a322022...2020.0NaN37849241103105.013.0
611067402542.831299667.220215ONTARIO RD NW1fb6a8d2fbe65ada17c5da91f65616ac112011...NaNNaN3784927110655.012.0
10110014024551.2397464569.19580114TH ST NW124619988e5d7556d9366681fe23de6a822022...2020.0NaN378493111010105.013.0
2411064412724.403198769.510315NEW MEXICO AVE NW19c91fb1e43cbb603a2e39b6222ea364722020...2020.0NaN37849451102455.013.0
28110642221615.2697751661.559937NEW HAMPSHIRE AVE NW19e64ad520f12c71e8ce968fbabffd80522020...2020.0NaN378494911028105.013.0
..................................................................
136701300110264.289101245.51269511TH ST SE1f6591609898a0ec6015a5e091ccea0e522022...NaNNaN381827111013670105.013.0
1368213081382268.410889475.594086SOUTH CAROLINA AVE SE15e86c702ab797fb3c02292d6516dd0c322020...NaNNaN381828311013682105.013.0
1373513000402788.719116947.6192024TH ST SE1c74620ee640cd3cf6f8c62573920598412013...NaNNaN38183361101373555.013.0
1378213001502880.905273947.53710915TH ST SE14a41e9643eadfd7095971da6fcf0faa312011...NaNNaN38183831101378255.013.0
13801130001021480.8403321568.9265141ST ST SE1e42b248e6bbc2fd0d7aede95ffc8f87842044...NaNNaN381840211013801105.013.0
\n", + "

924 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "3 11051352 2193.030273 2296.614258 KANSAS AVE NW 1 \n", + "6 11067402 542.831299 667.220215 ONTARIO RD NW 1 \n", + "10 11001402 4551.239746 4569.195801 14TH ST NW 1 \n", + "24 11064412 724.403198 769.510315 NEW MEXICO AVE NW 1 \n", + "28 11064222 1615.269775 1661.559937 NEW HAMPSHIRE AVE NW 1 \n", + "... ... ... ... ... ... \n", + "13670 13001102 64.289101 245.512695 11TH ST SE 1 \n", + "13682 13081382 268.410889 475.594086 SOUTH CAROLINA AVE SE 1 \n", + "13735 13000402 788.719116 947.619202 4TH ST SE 1 \n", + "13782 13001502 880.905273 947.537109 15TH ST SE 1 \n", + "13801 13000102 1480.840332 1568.926514 1ST ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2 2 \n", + "6 fb6a8d2fbe65ada17c5da91f65616ac1 1 2 \n", + "10 24619988e5d7556d9366681fe23de6a8 2 2 \n", + "24 9c91fb1e43cbb603a2e39b6222ea3647 2 2 \n", + "28 9e64ad520f12c71e8ce968fbabffd805 2 2 \n", + "... ... ... ... \n", + "13670 f6591609898a0ec6015a5e091ccea0e5 2 2 \n", + "13682 5e86c702ab797fb3c02292d6516dd0c3 2 2 \n", + "13735 c74620ee640cd3cf6f8c625739205984 1 2 \n", + "13782 4a41e9643eadfd7095971da6fcf0faa3 1 2 \n", + "13801 e42b248e6bbc2fd0d7aede95ffc8f878 4 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "3 0 22 ... 2020.0 \n", + "6 0 11 ... NaN \n", + "10 0 22 ... 2020.0 \n", + "24 0 20 ... 2020.0 \n", + "28 0 20 ... 2020.0 \n", + "... ... ... ... ... \n", + "13670 0 22 ... NaN \n", + "13682 0 20 ... NaN \n", + "13735 0 13 ... NaN \n", + "13782 0 11 ... NaN \n", + "13801 0 44 ... NaN \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "3 NaN 3784924 1 \n", + "6 NaN 3784927 1 \n", + "10 NaN 3784931 1 \n", + "24 NaN 3784945 1 \n", + "28 NaN 3784949 1 \n", + "... ... ... ... \n", + "13670 NaN 3818271 1 \n", + "13682 NaN 3818283 1 \n", + "13735 NaN 3818336 1 \n", + "13782 NaN 3818383 1 \n", + "13801 NaN 3818402 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "3 1 0 3 10 \n", + "6 1 0 6 5 \n", + "10 1 0 10 10 \n", + "24 1 0 24 5 \n", + "28 1 0 28 10 \n", + "... ... ... ... ... \n", + "13670 1 0 13670 10 \n", + "13682 1 0 13682 10 \n", + "13735 1 0 13735 5 \n", + "13782 1 0 13782 5 \n", + "13801 1 0 13801 10 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "3 5.0 13.0 \n", + "6 5.0 12.0 \n", + "10 5.0 13.0 \n", + "24 5.0 13.0 \n", + "28 5.0 13.0 \n", + "... ... ... \n", + "13670 5.0 13.0 \n", + "13682 5.0 13.0 \n", + "13735 5.0 13.0 \n", + "13782 5.0 13.0 \n", + "13801 5.0 13.0 \n", + "\n", + "[924 rows x 105 columns]" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_conventional_adjPL = roads[((~roads['BIKELANE_CONVENTIONAL'].isna()) | (~roads['BIKELANE_BUFFERED'].isna())) & (~roads['BIKELANE_PARKINGLANE_ADJACENT'].isna())]\n", + "roads_conventional_adjPL" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "e1f9fd41", + "metadata": {}, + "outputs": [], + "source": [ + "# This function goes through each reach-lane width and speedlimit option for the general criteria outlined in the next section.\n", + "# Given the general criteria, reach-lane width, and speelimit, the LTS is assigned to any road segment matching all the necessary elements\n", + "\n", + "def get_levels_conventional_adjPL(curr_df, curr_roads, road_levels, ignore_width = False):\n", + " print(len(curr_roads))\n", + " print('-----')\n", + " for i, row in curr_df.iterrows():\n", + " #sel will contain the selected road segments fitting a criteria/reach-width/speedlimit combo\n", + " sel = []\n", + " print(str(row['min bike lane reach width'])+'---'+str(row['minspeed']))\n", + " #some general criteria don't break down by reach, just by speedlimit\n", + " if ignore_width:\n", + " sel = curr_roads[(curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel)) \n", + " #if bikelane width delinations are made, use this section\n", + " else:\n", + " sel = curr_roads[ (curr_roads['ADJPLREACH']>=row['min bike lane reach width']) & (curr_roads['ADJPLREACH'] < row['max bike lane reach width']) & (curr_roads['SPEEDLIMITS_OB']>=row['minspeed']) & (curr_roads['SPEEDLIMITS_OB'] < row['maxspeed'])]\n", + " print(len(sel))\n", + " #print(row['level'])\n", + " #for criteria/bikelane width/speedlimit combo and the road segments matching the description, assign the appropriate level to the road segment id\n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " print(len(road_levels))\n", + " #print(row_sel['index'])\n", + " #print(road_levels[row_sel['index']])\n", + " #print(road_levels[9373]) \n", + " #sel = curr_roads[curr_roads['SPEEDLIMITS_OB'].isna()]\n", + " #if there are any road segment left over, assign them to the highest value (the last one used, generally 4) to be conservative\n", + " #this happens if there is an unusual configuration (ex- 0 lanes in either direction on a 1-way street, etc)\n", + " #the nubmer of 'left over' roads is printed out so it can be verified that it's not too large, which could point to a large problem.\n", + " inds = np.setdiff1d(curr_roads['index'].values, list(road_levels.keys()))\n", + " print('left over')\n", + " print(len(inds))\n", + " print(inds)\n", + " sel = curr_roads[curr_roads['index'].isin(inds)]\n", + " print(len(sel)) \n", + " for j, row_sel in sel.iterrows():\n", + " road_levels[row_sel['index']] = row['level']\n", + " return road_levels\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2fc5a7e7", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "356\n", + "12532\n", + "356\n", + "-----\n", + "15.0---0.0\n", + "24\n", + "12556\n", + "15.0---28.5\n", + "4\n", + "12560\n", + "15.0---33.5\n", + "0\n", + "12560\n", + "15.0---38.5\n", + "0\n", + "12560\n", + "12.0---0.0\n", + "283\n", + "12843\n", + "12.0---28.5\n", + "28\n", + "12871\n", + "12.0---33.5\n", + "0\n", + "12871\n", + "12.0---38.5\n", + "0\n", + "12871\n", + "left over\n", + "17\n", + "[ 3996 8596 10027 10054 10157 10475 10496 10676 11012 11384 11392 11522\n", + " 11843 12301 12340 12877 13124]\n", + "17\n", + "12888\n", + "13\n", + "12888\n", + "13\n", + "-----\n", + "13.0---0.0\n", + "9\n", + "12897\n", + "13.0---28.5\n", + "4\n", + "12901\n", + "13.0---33.5\n", + "0\n", + "12901\n", + "13.0---38.5\n", + "0\n", + "12901\n", + "11.0---0.0\n", + "0\n", + "12901\n", + "11.0---28.5\n", + "0\n", + "12901\n", + "11.0---33.5\n", + "0\n", + "12901\n", + "11.0---38.5\n", + "0\n", + "12901\n", + "left over\n", + "0\n", + "[]\n", + "0\n", + "12901\n", + "447\n", + "12901\n", + "447\n", + "-----\n", + "15.0---0.0\n", + "20\n", + "12921\n", + "15.0---28.5\n", + "0\n", + "12921\n", + "15.0---33.5\n", + "0\n", + "12921\n", + "15.0---38.5\n", + "0\n", + "12921\n", + "12.0---0.0\n", + "225\n", + "13146\n", + "12.0---28.5\n", + "5\n", + "13151\n", + "12.0---33.5\n", + "0\n", + "13151\n", + "12.0---38.5\n", + "0\n", + "13151\n", + "left over\n", + "197\n", + "[ 72 111 155 228 242 275 327 561 583 672 913 1409\n", + " 1464 1523 1553 1632 1692 1809 1941 1957 2042 2049 2083 2102\n", + " 2377 2438 2487 2527 2793 2857 2988 3002 3081 3186 3205 3231\n", + " 3291 3341 3452 3587 3784 3892 3921 3966 4111 4140 4231 4294\n", + " 4457 4505 4622 4623 4987 5034 5069 5095 5238 5245 5310 5359\n", + " 5365 5368 5371 5373 5374 5381 5385 5412 5418 5438 5440 5696\n", + " 5716 5758 5784 5790 5816 5842 5854 5861 5911 6076 6131 6134\n", + " 6172 6202 6210 6245 6306 6369 6406 6435 6487 6621 6665 6748\n", + " 6835 6873 6884 6885 6898 6907 7005 7066 7083 7091 7100 7124\n", + " 7126 7249 7282 7309 7340 7364 7381 7570 7607 7613 7675 7722\n", + " 7726 7733 7813 7818 7907 7911 8078 8330 8360 8397 8551 8613\n", + " 8629 8649 8685 8721 8763 8828 8936 8950 8963 9025 9041 9063\n", + " 9079 9095 9159 9167 9217 9291 9298 9311 9389 9440 9486 9528\n", + " 9535 9597 9640 9653 9706 9735 9749 9829 9858 9922 9945 9987\n", + " 10010 10167 10334 10382 10616 10618 10835 10854 10895 10922 10998 11114\n", + " 11163 11317 11529 11534 11576 11791 11883 11889 11932 11945 12245 12325\n", + " 12350 12616 12736 12961 13176]\n", + "197\n", + "13348\n", + "101\n", + "13348\n", + "101\n", + "-----\n", + "15.0---0.0\n", + "12\n", + "13360\n", + "15.0---28.5\n", + "1\n", + "13361\n", + "15.0---33.5\n", + "0\n", + "13361\n", + "15.0---38.5\n", + "0\n", + "13361\n", + "12.0---0.0\n", + "77\n", + "13438\n", + "12.0---28.5\n", + "7\n", + "13445\n", + "12.0---33.5\n", + "0\n", + "13445\n", + "12.0---38.5\n", + "0\n", + "13445\n", + "left over\n", + "4\n", + "[5253 5317 8401 9680]\n", + "4\n", + "13449\n", + "7\n", + "13449\n", + "7\n", + "-----\n", + "nan---0.0\n", + "4\n", + "13453\n", + "nan---28.5\n", + "0\n", + "13453\n", + "nan---33.5\n", + "0\n", + "13453\n", + "nan---38.5\n", + "0\n", + "13453\n", + "left over\n", + "3\n", + "[10519 12225 13327]\n", + "3\n", + "13456\n" + ] + } + ], + "source": [ + "#go through the different general criteria, then run get_levels to go through the reach lane width/speedlimit divisions\n", + "\n", + "# no bidirectional lane, one in each direction\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_adjPL['TOTALTRAVELLANESBIDIRECTIONAL'] == 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==0)]\n", + "#all_road_levels = {}\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# bidirectional lane, one in each direction\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1)) & (roads_conventional_adjPL['TOTALTRAVELLANESBIDIRECTIONAL'] > 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'exactly1') & (df['BirectionalLane'] ==1)]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# bidirectional lane, one in each direction\n", + "curr_check = (roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 0) | (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 0)\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'oneIs0')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# one direction is 2 lanes, other direction is 1 or 2 lanes\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 2) & ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 2) |(roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 1))) | ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] == 2) & ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 2) |(roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] == 1)))\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'oneIs2otherIs1or2')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n", + "\n", + "# one direction is at least 3 lanes and other is at least 2 lanes\n", + "curr_check = ((roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] >=3) & (roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] >=1)) | ((roads_conventional_adjPL['TOTALTRAVELLANESINBOUND'] >=3) & (roads_conventional_adjPL['TOTALTRAVELLANESOUTBOUND'] >=1))\n", + "curr_roads = roads_conventional_adjPL[curr_check]\n", + "print(len(curr_roads))\n", + "curr_df = df[(df['Number of travel lanes in one direction'] == 'min3andMin1')]\n", + "print(len(road_levels))\n", + "road_levels = get_levels_conventional_adjPL(curr_df, curr_roads, road_levels, ignore_width = True)\n", + "print(len(road_levels))\n", + "#all_road_levels |= road_levels\n", + "#print(len(all_road_levels))\n" + ] + }, + { + "cell_type": "markdown", + "id": "2d9ac646-c90d-4a97-8f24-f085c08dc63f", + "metadata": {}, + "source": [ + "# Protected and dual-protected bike lanes" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "id": "7bd7e4a7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...AADT_SINGLE_UNIT_YEARSPEEDHUMP_PRESENTOBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACH
13110005023074.3991703193.3032235TH ST NW19ed8ed522bd67dccd92d1d5093dfaf8c12211...NaNNaN37849341101300.00.0
82110009021432.8323971478.0620129TH ST NW1b73d8b891b5136c91ccf503660c0c3bc50250...2020.0NaN37850031108200.00.0
20411052972140.757400505.979492KLINGLE RD NW1d138276f2f7c7b52703443f707ee24d020328...NaNNaN380480511020400.00.0
23211048752450.915894756.346375IRVING ST NW1028925d6eed296709bdc329a4697d99840244...2020.0NaN380483311023200.00.0
266110386121876.7893072070.267090G ST NW164c03c846136f580302a06e3dcbce3d111111...NaNNaN380486711026600.00.0
..................................................................
13556140004020.000000100.7942964TH ST SW179e5ded2c338b125eb39f63314644f3530233...NaNNaN38181571101355600.00.0
13633130718921644.1766361813.948975POTOMAC AVE SE1991827a21c5cff0c4e638d600b6f808c12111...2020.0NaN38182341101363300.00.0
136431405850263.963001104.609001MAINE AVE SW1e0f31320570eb8910928efb12e616fca52450...2020.0NaN38182441101364300.00.0
1370913001902405.588989494.07089219TH ST SE16abb362ff34b8ccba0fd36b199a359b011211...NaNNaN38183101101370900.00.0
13794130718921471.9941411611.014404POTOMAC AVE SE1fbdf2fa8d5e2b140760725ac2855cc1f21122...2020.0NaN38183951101379400.00.0
\n", + "

268 rows × 105 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "13 11000502 3074.399170 3193.303223 5TH ST NW 1 \n", + "82 11000902 1432.832397 1478.062012 9TH ST NW 1 \n", + "204 11052972 140.757400 505.979492 KLINGLE RD NW 1 \n", + "232 11048752 450.915894 756.346375 IRVING ST NW 1 \n", + "266 11038612 1876.789307 2070.267090 G ST NW 1 \n", + "... ... ... ... ... ... \n", + "13556 14000402 0.000000 100.794296 4TH ST SW 1 \n", + "13633 13071892 1644.176636 1813.948975 POTOMAC AVE SE 1 \n", + "13643 14058502 63.963001 104.609001 MAINE AVE SW 1 \n", + "13709 13001902 405.588989 494.070892 19TH ST SE 1 \n", + "13794 13071892 1471.994141 1611.014404 POTOMAC AVE SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "13 9ed8ed522bd67dccd92d1d5093dfaf8c 1 2 \n", + "82 b73d8b891b5136c91ccf503660c0c3bc 5 0 \n", + "204 d138276f2f7c7b52703443f707ee24d0 2 0 \n", + "232 028925d6eed296709bdc329a4697d998 4 0 \n", + "266 64c03c846136f580302a06e3dcbce3d1 1 1 \n", + "... ... ... ... \n", + "13556 79e5ded2c338b125eb39f63314644f35 3 0 \n", + "13633 991827a21c5cff0c4e638d600b6f808c 1 2 \n", + "13643 e0f31320570eb8910928efb12e616fca 5 2 \n", + "13709 6abb362ff34b8ccba0fd36b199a359b0 1 1 \n", + "13794 fbdf2fa8d5e2b140760725ac2855cc1f 2 1 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... AADT_SINGLE_UNIT_YEAR \\\n", + "13 2 11 ... NaN \n", + "82 2 50 ... 2020.0 \n", + "204 3 28 ... NaN \n", + "232 2 44 ... 2020.0 \n", + "266 1 11 ... NaN \n", + "... ... ... ... ... \n", + "13556 2 33 ... NaN \n", + "13633 1 11 ... 2020.0 \n", + "13643 4 50 ... 2020.0 \n", + "13709 2 11 ... NaN \n", + "13794 1 22 ... 2020.0 \n", + "\n", + " SPEEDHUMP_PRESENT OBJECTID DC_MAINTENANCE_OPERATIONS \\\n", + "13 NaN 3784934 1 \n", + "82 NaN 3785003 1 \n", + "204 NaN 3804805 1 \n", + "232 NaN 3804833 1 \n", + "266 NaN 3804867 1 \n", + "... ... ... ... \n", + "13556 NaN 3818157 1 \n", + "13633 NaN 3818234 1 \n", + "13643 NaN 3818244 1 \n", + "13709 NaN 3818310 1 \n", + "13794 NaN 3818395 1 \n", + "\n", + " MAINTENANCE_OPERATIONS SHAPELEN index TOTALBIKELANEWIDTH_WEXTRA \\\n", + "13 1 0 13 0 \n", + "82 1 0 82 0 \n", + "204 1 0 204 0 \n", + "232 1 0 232 0 \n", + "266 1 0 266 0 \n", + "... ... ... ... ... \n", + "13556 1 0 13556 0 \n", + "13633 1 0 13633 0 \n", + "13643 1 0 13643 0 \n", + "13709 1 0 13709 0 \n", + "13794 1 0 13794 0 \n", + "\n", + " PERBIKELANEWIDTH ADJPLREACH \n", + "13 0.0 0.0 \n", + "82 0.0 0.0 \n", + "204 0.0 0.0 \n", + "232 0.0 0.0 \n", + "266 0.0 0.0 \n", + "... ... ... \n", + "13556 0.0 0.0 \n", + "13633 0.0 0.0 \n", + "13643 0.0 0.0 \n", + "13709 0.0 0.0 \n", + "13794 0.0 0.0 \n", + "\n", + "[268 rows x 105 columns]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#if bikelane is buffered, then set level to 1\n", + "roads_protectedBL = roads[((roads['BIKELANE_CONVENTIONAL'].isna()) & (roads['BIKELANE_BUFFERED'].isna()) & ((~roads['BIKELANE_DUAL_PROTECTED'].isna()) | (~roads['BIKELANE_PROTECTED'].isna())))]\n", + "roads_protectedBL" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "3d72d3bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "13724\n" + ] + } + ], + "source": [ + "for j, row_sel in roads_protectedBL.iterrows():\n", + " road_levels[row_sel['index']] = 1\n", + "print(len(road_levels))" + ] + }, + { + "cell_type": "markdown", + "id": "1dc39f33-9de7-4f87-8703-a030a0c9ee75", + "metadata": {}, + "source": [ + "# Left-over road segments" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "8c45b18c-8112-407f-9b0f-0b8e1ac3e5c2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "13833" + ] + }, + "execution_count": 33, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#check if there are any left-over roads (weird roads that didn't fall under any logic)\n", + "left_over_ind = np.setdiff1d(roads['index'].values, list(road_levels.keys()))\n", + "len(left_over_ind)\n", + "roads_left_over = roads[roads['index'].isin(left_over_ind)]\n", + "\n", + "#if less than or equal to 2 lanes and speedlimit < 30mph, then 2\n", + "# if greater than than or equal to 6 lanes or speedlimit > 40mph, then 4\n", + "#otherwise 3\n", + "for j, row_sel in roads_left_over.iterrows():\n", + " if (row_sel['TOTALTRAVELLANES'] <=2) & (row_sel['SPEEDLIMITS_OB']<=30):\n", + " road_levels[row_sel['index']] = 2\n", + " elif (row_sel['TOTALTRAVELLANES'] >=6) | (row_sel['SPEEDLIMITS_OB']>40):\n", + " road_levels[row_sel['index']] = 4\n", + " else:\n", + " road_levels[row_sel['index']] = 3\n", + "len(road_levels)" + ] + }, + { + "cell_type": "markdown", + "id": "2ddcd424-7c46-411b-8a78-002b519c1081", + "metadata": {}, + "source": [ + "# Save info" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "d988cd3c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
indlevels
014411
115011
215061
338281
442901
.........
13828132093
13829132853
13830133763
13831134792
13832138263
\n", + "

13833 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " ind levels\n", + "0 1441 1\n", + "1 1501 1\n", + "2 1506 1\n", + "3 3828 1\n", + "4 4290 1\n", + "... ... ...\n", + "13828 13209 3\n", + "13829 13285 3\n", + "13830 13376 3\n", + "13831 13479 2\n", + "13832 13826 3\n", + "\n", + "[13833 rows x 2 columns]" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "road_levels_pd = pd.DataFrame({'ind': road_levels.keys(), 'levels':road_levels.values()})\n", + "#save levels\n", + "road_levels_pd.to_csv('level.csv')\n", + "road_levels_pd" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "7f945fe6-f172-40d0-a5d6-21ba8e93eed5", + "metadata": {}, + "outputs": [], + "source": [ + "roads_level_pd = pd.read_csv('level.csv')\n", + "roads = roads.merge(roads_level_pd[['ind', 'levels']], how = 'left', left_on = 'index', right_on = 'ind')\n", + "#save levels merged with road data\n", + "roads.to_csv('roads_merge_level.csv')" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "e0469382-e25f-4d1c-ab2f-ee9cf034a1d1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERSTOTALTRAVELLANEWIDTH...OBJECTIDDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSSHAPELENindexTOTALBIKELANEWIDTH_WEXTRAPERBIKELANEWIDTHADJPLREACHindlevels
011036462645.778625734.415527FLORAL ST NW12734c1c8f9ed5634689fd7116fbaa74f22016...3784921110000.00.002
1110007026134.0766606198.1767587TH ST NW158da4df6640a4f63bc3dee905873701422016...3784922110100.00.012
2110005026554.0693366672.9995125TH ST NW1cc7f7163fe7b5c65303feb636296e30121024...3784923110200.00.022
3110513522193.0302732296.614258KANSAS AVE NW1c448b8a91c9e954e73db5fb1563d10a322022...37849241103105.013.032
4110016025792.8745125866.60644516TH ST NW1051cac1b00b502c715a0aaa169bc566e50050...3784925110400.00.044
..................................................................
13828130585421079.4969481185.059570MALCOLM X AVE SE172c26fc9f2add8684d83f55631cb12f222022...38184291101382800.00.0138283
13829120872320.00000093.154198U ST NE1fecd0265786dfc8087588378879d07e211011...38184301101382900.00.0138292
13830130248320.000000145.923004CONDON TER SE19aafe80dc9210141065a12b36693769c22018...38184311101383000.00.0138302
13831130085822706.7019042905.013428A ST SE1e8a29ad34481906f5074fc78ef7c113d12010...38184321101383100.00.0138312
13832130014021129.5345461139.75134314TH ST SE194fafe51d9bafc4aefef560c583767b622016...38184331101383200.00.0138322
\n", + "

13833 rows × 107 columns

\n", + "
" + ], + "text/plain": [ + " ROUTEID FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 11036462 645.778625 734.415527 FLORAL ST NW 1 \n", + "1 11000702 6134.076660 6198.176758 7TH ST NW 1 \n", + "2 11000502 6554.069336 6672.999512 5TH ST NW 1 \n", + "3 11051352 2193.030273 2296.614258 KANSAS AVE NW 1 \n", + "4 11001602 5792.874512 5866.606445 16TH ST NW 1 \n", + "... ... ... ... ... ... \n", + "13828 13058542 1079.496948 1185.059570 MALCOLM X AVE SE 1 \n", + "13829 12087232 0.000000 93.154198 U ST NE 1 \n", + "13830 13024832 0.000000 145.923004 CONDON TER SE 1 \n", + "13831 13008582 2706.701904 2905.013428 A ST SE 1 \n", + "13832 13001402 1129.534546 1139.751343 14TH ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 2734c1c8f9ed5634689fd7116fbaa74f 2 2 \n", + "1 58da4df6640a4f63bc3dee9058737014 2 2 \n", + "2 cc7f7163fe7b5c65303feb636296e301 2 1 \n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2 2 \n", + "4 051cac1b00b502c715a0aaa169bc566e 5 0 \n", + "... ... ... ... \n", + "13828 72c26fc9f2add8684d83f55631cb12f2 2 2 \n", + "13829 fecd0265786dfc8087588378879d07e2 1 1 \n", + "13830 9aafe80dc9210141065a12b36693769c 2 2 \n", + "13831 e8a29ad34481906f5074fc78ef7c113d 1 2 \n", + "13832 94fafe51d9bafc4aefef560c583767b6 2 2 \n", + "\n", + " TOTALRAISEDBUFFERS TOTALTRAVELLANEWIDTH ... OBJECTID \\\n", + "0 0 16 ... 3784921 \n", + "1 0 16 ... 3784922 \n", + "2 0 24 ... 3784923 \n", + "3 0 22 ... 3784924 \n", + "4 0 50 ... 3784925 \n", + "... ... ... ... ... \n", + "13828 0 22 ... 3818429 \n", + "13829 0 11 ... 3818430 \n", + "13830 0 18 ... 3818431 \n", + "13831 0 10 ... 3818432 \n", + "13832 0 16 ... 3818433 \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS SHAPELEN index \\\n", + "0 1 1 0 0 \n", + "1 1 1 0 1 \n", + "2 1 1 0 2 \n", + "3 1 1 0 3 \n", + "4 1 1 0 4 \n", + "... ... ... ... ... \n", + "13828 1 1 0 13828 \n", + "13829 1 1 0 13829 \n", + "13830 1 1 0 13830 \n", + "13831 1 1 0 13831 \n", + "13832 1 1 0 13832 \n", + "\n", + " TOTALBIKELANEWIDTH_WEXTRA PERBIKELANEWIDTH ADJPLREACH ind levels \n", + "0 0 0.0 0.0 0 2 \n", + "1 0 0.0 0.0 1 2 \n", + "2 0 0.0 0.0 2 2 \n", + "3 10 5.0 13.0 3 2 \n", + "4 0 0.0 0.0 4 4 \n", + "... ... ... ... ... ... \n", + "13828 0 0.0 0.0 13828 3 \n", + "13829 0 0.0 0.0 13829 2 \n", + "13830 0 0.0 0.0 13830 2 \n", + "13831 0 0.0 0.0 13831 2 \n", + "13832 0 0.0 0.0 13832 2 \n", + "\n", + "[13833 rows x 107 columns]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads" + ] + }, + { + "cell_type": "markdown", + "id": "c8118650-7866-4eda-b12d-41b39e426193", + "metadata": {}, + "source": [ + "## Combine with bespoke ridescore info if also calculated\n", + "\n", + "Using blockkey" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "d48a469f-07bb-4f1f-a79b-e6150ccf6929", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
BLOCKKEYoriginal_lts
02734c1c8f9ed5634689fd7116fbaa74f2
158da4df6640a4f63bc3dee90587370142
2cc7f7163fe7b5c65303feb636296e3012
3c448b8a91c9e954e73db5fb1563d10a32
4051cac1b00b502c715a0aaa169bc566e4
.........
1382872c26fc9f2add8684d83f55631cb12f23
13829fecd0265786dfc8087588378879d07e22
138309aafe80dc9210141065a12b36693769c2
13831e8a29ad34481906f5074fc78ef7c113d2
1383294fafe51d9bafc4aefef560c583767b62
\n", + "

13833 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " BLOCKKEY original_lts\n", + "0 2734c1c8f9ed5634689fd7116fbaa74f 2\n", + "1 58da4df6640a4f63bc3dee9058737014 2\n", + "2 cc7f7163fe7b5c65303feb636296e301 2\n", + "3 c448b8a91c9e954e73db5fb1563d10a3 2\n", + "4 051cac1b00b502c715a0aaa169bc566e 4\n", + "... ... ...\n", + "13828 72c26fc9f2add8684d83f55631cb12f2 3\n", + "13829 fecd0265786dfc8087588378879d07e2 2\n", + "13830 9aafe80dc9210141065a12b36693769c 2\n", + "13831 e8a29ad34481906f5074fc78ef7c113d 2\n", + "13832 94fafe51d9bafc4aefef560c583767b6 2\n", + "\n", + "[13833 rows x 2 columns]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "lts_block = roads[['BLOCKKEY', 'levels']]\n", + "lts_block = lts_block.rename(columns = {'levels': 'original_lts'})\n", + "lts_block" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f00f2610-076c-4519-a6ac-9e6bdf7a759a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Index(['route_id', 'route_name', 'blockkey', 'function', 'num_lanes',\n", + " 'num_lanes_raw', 'speed_limit', 'speed_limit_raw', 'bike_facility_type',\n", + " 'parking_presence', 'road_width', 'slow_street', 'pavement_condition',\n", + " 'lts_level', 'len', 'crash_count_5yr', 'serious_injury_count_5yr',\n", + " 'fatal_count_5yr', 's_LTS', 's_crash', 's_facility', 'ridescore_v1',\n", + " 'lts_score', 'speedlimit_score', 'num_lanes_score', 'facility_score',\n", + " 'function_score', 'road_width_score', 'pavement_condition_score',\n", + " 'geometry', 'BLOCKKEY', 'original_lts'],\n", + " dtype='object')\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\3647879414.py:3: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\3647879414.py:3: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presence...lts_scorespeedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_scoregeometryBLOCKKEYoriginal_lts
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0none1...1060.02505044100LINESTRING Z (-77.01991 38.90358 0, -77.0199 3...4af7e25abf59911305f2724cadc85a083.0
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0none1...4050.07501006875LINESTRING Z (-77.06517 38.95331 0, -77.06517 ...5b3f1964647d6c0b30c8189fd594208c2.0
211037892FOXHALL RD NWfb2d4a22a88f8d4a7566a28b49aee1f9Minor Arterial2225.025.0none0...1050.07505075100LINESTRING Z (-77.09076 38.92905 0, -77.09106 ...fb2d4a22a88f8d4a7566a28b49aee1f92.0
31100160216TH ST NWa9903cf6a4ade86eb26343cd52cf1ffbPrincipal/Primary Arterial4430.030.0none0...1040.02502550100LINESTRING Z (-77.03639 38.96543 0, -77.03639 ...a9903cf6a4ade86eb26343cd52cf1ffb4.0
411033472EMERSON ST NW4cfb9ba5eb597b707b798513462ef851Local2220.020.0none1...7560.075010068100LINESTRING Z (-77.01994 38.94995 0, -77.02201 ...4cfb9ba5eb597b707b798513462ef8512.0
..................................................................
1382913081512SOUTHERN AVE SE03ceb30917e33f51246b9427451bf29aMinor Arterial4430.030.0none0...1040.0250505775LINESTRING Z (-76.98733 38.83212 0, -76.98573 ...03ceb30917e33f51246b9427451bf29a4.0
1383013064282NEW JERSEY AVE SEf8c1e5fae8a0321753beea69ef9d88f1Collector2220.020.0painted_lane1...7560.07550755150LINESTRING Z (-77.00486 38.87841 0, -77.00454 ...f8c1e5fae8a0321753beea69ef9d88f12.0
1383113018522BRUCE PL SE6e06a429de20637fc25ec5ee5bdad443Local2220.020.0none1...7560.07501006675LINESTRING Z (-76.98232 38.85084 0, -76.98101 ...6e06a429de20637fc25ec5ee5bdad4432.0
1383213076442ROBINSON PL SEa476aa40bc64479559e7361d9c105d16Local2220.020.0none0...7560.075010072100LINESTRING Z (-76.9889 38.85219 0, -76.98844 3...a476aa40bc64479559e7361d9c105d162.0
1383313069532PAULDING ST SEcb8e955725acf60fbb9a51e0f8cfd753Local1120.020.0none1...7560.010001006450LINESTRING Z (-76.9956 38.8754 0, -76.99557 38...cb8e955725acf60fbb9a51e0f8cfd7532.0
\n", + "

13834 rows × 32 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c \n", + "2 11037892 FOXHALL RD NW fb2d4a22a88f8d4a7566a28b49aee1f9 \n", + "3 11001602 16TH ST NW a9903cf6a4ade86eb26343cd52cf1ffb \n", + "4 11033472 EMERSON ST NW 4cfb9ba5eb597b707b798513462ef851 \n", + "... ... ... ... \n", + "13829 13081512 SOUTHERN AVE SE 03ceb30917e33f51246b9427451bf29a \n", + "13830 13064282 NEW JERSEY AVE SE f8c1e5fae8a0321753beea69ef9d88f1 \n", + "13831 13018522 BRUCE PL SE 6e06a429de20637fc25ec5ee5bdad443 \n", + "13832 13076442 ROBINSON PL SE a476aa40bc64479559e7361d9c105d16 \n", + "13833 13069532 PAULDING ST SE cb8e955725acf60fbb9a51e0f8cfd753 \n", + "\n", + " function num_lanes num_lanes_raw speed_limit \\\n", + "0 Minor Arterial 4 4 20.0 \n", + "1 Local 2 2 25.0 \n", + "2 Minor Arterial 2 2 25.0 \n", + "3 Principal/Primary Arterial 4 4 30.0 \n", + "4 Local 2 2 20.0 \n", + "... ... ... ... ... \n", + "13829 Minor Arterial 4 4 30.0 \n", + "13830 Collector 2 2 20.0 \n", + "13831 Local 2 2 20.0 \n", + "13832 Local 2 2 20.0 \n", + "13833 Local 1 1 20.0 \n", + "\n", + " speed_limit_raw bike_facility_type parking_presence ... lts_score \\\n", + "0 20.0 none 1 ... 10 \n", + "1 25.0 none 1 ... 40 \n", + "2 25.0 none 0 ... 10 \n", + "3 30.0 none 0 ... 10 \n", + "4 20.0 none 1 ... 75 \n", + "... ... ... ... ... ... \n", + "13829 30.0 none 0 ... 10 \n", + "13830 20.0 painted_lane 1 ... 75 \n", + "13831 20.0 none 1 ... 75 \n", + "13832 20.0 none 0 ... 75 \n", + "13833 20.0 none 1 ... 75 \n", + "\n", + " speedlimit_score num_lanes_score facility_score function_score \\\n", + "0 60.0 25 0 50 \n", + "1 50.0 75 0 100 \n", + "2 50.0 75 0 50 \n", + "3 40.0 25 0 25 \n", + "4 60.0 75 0 100 \n", + "... ... ... ... ... \n", + "13829 40.0 25 0 50 \n", + "13830 60.0 75 50 75 \n", + "13831 60.0 75 0 100 \n", + "13832 60.0 75 0 100 \n", + "13833 60.0 100 0 100 \n", + "\n", + " road_width_score pavement_condition_score \\\n", + "0 44 100 \n", + "1 68 75 \n", + "2 75 100 \n", + "3 50 100 \n", + "4 68 100 \n", + "... ... ... \n", + "13829 57 75 \n", + "13830 51 50 \n", + "13831 66 75 \n", + "13832 72 100 \n", + "13833 64 50 \n", + "\n", + " geometry \\\n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.0199 3... \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... \n", + "2 LINESTRING Z (-77.09076 38.92905 0, -77.09106 ... \n", + "3 LINESTRING Z (-77.03639 38.96543 0, -77.03639 ... \n", + "4 LINESTRING Z (-77.01994 38.94995 0, -77.02201 ... \n", + "... ... \n", + "13829 LINESTRING Z (-76.98733 38.83212 0, -76.98573 ... \n", + "13830 LINESTRING Z (-77.00486 38.87841 0, -77.00454 ... \n", + "13831 LINESTRING Z (-76.98232 38.85084 0, -76.98101 ... \n", + "13832 LINESTRING Z (-76.9889 38.85219 0, -76.98844 3... \n", + "13833 LINESTRING Z (-76.9956 38.8754 0, -76.99557 38... \n", + "\n", + " BLOCKKEY original_lts \n", + "0 4af7e25abf59911305f2724cadc85a08 3.0 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2.0 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2.0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4.0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2.0 \n", + "... ... ... \n", + "13829 03ceb30917e33f51246b9427451bf29a 4.0 \n", + "13830 f8c1e5fae8a0321753beea69ef9d88f1 2.0 \n", + "13831 6e06a429de20637fc25ec5ee5bdad443 2.0 \n", + "13832 a476aa40bc64479559e7361d9c105d16 2.0 \n", + "13833 cb8e955725acf60fbb9a51e0f8cfd753 2.0 \n", + "\n", + "[13834 rows x 32 columns]" + ] + }, + "execution_count": 39, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_wRS = gpd.read_file('../render_dcdata_wCrashes.geojson')\n", + "roads_wRS = roads_wRS.merge(lts_block, how = 'left', left_on = 'blockkey', right_on = 'BLOCKKEY')\n", + "roads_wRS['original_lts'][roads_wRS['original_lts'].isna()] = 3\n", + "print(roads_wRS.columns)\n", + "roads_wRS" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "id": "f4eb05fe-d7c3-47a0-9ff9-739e80f199c2", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:2: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:2: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:3: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:3: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:4: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:4: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:5: FutureWarning: ChainedAssignmentError: behaviour will change in pandas 3.0!\n", + "You are setting values through chained assignment. Currently this works in certain cases, but when using Copy-on-Write (which will become the default behaviour in pandas 3.0) this will never work to update the original DataFrame or Series, because the intermediate object on which we are setting values will behave as a copy.\n", + "A typical example is when you are setting values in a column of a DataFrame, like:\n", + "\n", + "df[\"col\"][row_indexer] = value\n", + "\n", + "Use `df.loc[row_indexer, \"col\"] = values` instead, to perform the assignment in a single step and ensure this keeps updating the original `df`.\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + "\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n", + "C:\\Users\\cle9a\\AppData\\Local\\Temp\\ipykernel_26552\\1811925195.py:5: SettingWithCopyWarning: \n", + "A value is trying to be set on a copy of a slice from a DataFrame\n", + "\n", + "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", + " roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presence...speedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_scoregeometryBLOCKKEYoriginal_ltslts_100
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0none1...60.02505044100LINESTRING Z (-77.01991 38.90358 0, -77.0199 3...4af7e25abf59911305f2724cadc85a083.040
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0none1...50.07501006875LINESTRING Z (-77.06517 38.95331 0, -77.06517 ...5b3f1964647d6c0b30c8189fd594208c2.060
211037892FOXHALL RD NWfb2d4a22a88f8d4a7566a28b49aee1f9Minor Arterial2225.025.0none0...50.07505075100LINESTRING Z (-77.09076 38.92905 0, -77.09106 ...fb2d4a22a88f8d4a7566a28b49aee1f92.060
31100160216TH ST NWa9903cf6a4ade86eb26343cd52cf1ffbPrincipal/Primary Arterial4430.030.0none0...40.02502550100LINESTRING Z (-77.03639 38.96543 0, -77.03639 ...a9903cf6a4ade86eb26343cd52cf1ffb4.010
411033472EMERSON ST NW4cfb9ba5eb597b707b798513462ef851Local2220.020.0none1...60.075010068100LINESTRING Z (-77.01994 38.94995 0, -77.02201 ...4cfb9ba5eb597b707b798513462ef8512.060
..................................................................
1382913081512SOUTHERN AVE SE03ceb30917e33f51246b9427451bf29aMinor Arterial4430.030.0none0...40.0250505775LINESTRING Z (-76.98733 38.83212 0, -76.98573 ...03ceb30917e33f51246b9427451bf29a4.010
1383013064282NEW JERSEY AVE SEf8c1e5fae8a0321753beea69ef9d88f1Collector2220.020.0painted_lane1...60.07550755150LINESTRING Z (-77.00486 38.87841 0, -77.00454 ...f8c1e5fae8a0321753beea69ef9d88f12.060
1383113018522BRUCE PL SE6e06a429de20637fc25ec5ee5bdad443Local2220.020.0none1...60.07501006675LINESTRING Z (-76.98232 38.85084 0, -76.98101 ...6e06a429de20637fc25ec5ee5bdad4432.060
1383213076442ROBINSON PL SEa476aa40bc64479559e7361d9c105d16Local2220.020.0none0...60.075010072100LINESTRING Z (-76.9889 38.85219 0, -76.98844 3...a476aa40bc64479559e7361d9c105d162.060
1383313069532PAULDING ST SEcb8e955725acf60fbb9a51e0f8cfd753Local1120.020.0none1...60.010001006450LINESTRING Z (-76.9956 38.8754 0, -76.99557 38...cb8e955725acf60fbb9a51e0f8cfd7532.060
\n", + "

13834 rows × 33 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c \n", + "2 11037892 FOXHALL RD NW fb2d4a22a88f8d4a7566a28b49aee1f9 \n", + "3 11001602 16TH ST NW a9903cf6a4ade86eb26343cd52cf1ffb \n", + "4 11033472 EMERSON ST NW 4cfb9ba5eb597b707b798513462ef851 \n", + "... ... ... ... \n", + "13829 13081512 SOUTHERN AVE SE 03ceb30917e33f51246b9427451bf29a \n", + "13830 13064282 NEW JERSEY AVE SE f8c1e5fae8a0321753beea69ef9d88f1 \n", + "13831 13018522 BRUCE PL SE 6e06a429de20637fc25ec5ee5bdad443 \n", + "13832 13076442 ROBINSON PL SE a476aa40bc64479559e7361d9c105d16 \n", + "13833 13069532 PAULDING ST SE cb8e955725acf60fbb9a51e0f8cfd753 \n", + "\n", + " function num_lanes num_lanes_raw speed_limit \\\n", + "0 Minor Arterial 4 4 20.0 \n", + "1 Local 2 2 25.0 \n", + "2 Minor Arterial 2 2 25.0 \n", + "3 Principal/Primary Arterial 4 4 30.0 \n", + "4 Local 2 2 20.0 \n", + "... ... ... ... ... \n", + "13829 Minor Arterial 4 4 30.0 \n", + "13830 Collector 2 2 20.0 \n", + "13831 Local 2 2 20.0 \n", + "13832 Local 2 2 20.0 \n", + "13833 Local 1 1 20.0 \n", + "\n", + " speed_limit_raw bike_facility_type parking_presence ... \\\n", + "0 20.0 none 1 ... \n", + "1 25.0 none 1 ... \n", + "2 25.0 none 0 ... \n", + "3 30.0 none 0 ... \n", + "4 20.0 none 1 ... \n", + "... ... ... ... ... \n", + "13829 30.0 none 0 ... \n", + "13830 20.0 painted_lane 1 ... \n", + "13831 20.0 none 1 ... \n", + "13832 20.0 none 0 ... \n", + "13833 20.0 none 1 ... \n", + "\n", + " speedlimit_score num_lanes_score facility_score function_score \\\n", + "0 60.0 25 0 50 \n", + "1 50.0 75 0 100 \n", + "2 50.0 75 0 50 \n", + "3 40.0 25 0 25 \n", + "4 60.0 75 0 100 \n", + "... ... ... ... ... \n", + "13829 40.0 25 0 50 \n", + "13830 60.0 75 50 75 \n", + "13831 60.0 75 0 100 \n", + "13832 60.0 75 0 100 \n", + "13833 60.0 100 0 100 \n", + "\n", + " road_width_score pavement_condition_score \\\n", + "0 44 100 \n", + "1 68 75 \n", + "2 75 100 \n", + "3 50 100 \n", + "4 68 100 \n", + "... ... ... \n", + "13829 57 75 \n", + "13830 51 50 \n", + "13831 66 75 \n", + "13832 72 100 \n", + "13833 64 50 \n", + "\n", + " geometry \\\n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.0199 3... \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... \n", + "2 LINESTRING Z (-77.09076 38.92905 0, -77.09106 ... \n", + "3 LINESTRING Z (-77.03639 38.96543 0, -77.03639 ... \n", + "4 LINESTRING Z (-77.01994 38.94995 0, -77.02201 ... \n", + "... ... \n", + "13829 LINESTRING Z (-76.98733 38.83212 0, -76.98573 ... \n", + "13830 LINESTRING Z (-77.00486 38.87841 0, -77.00454 ... \n", + "13831 LINESTRING Z (-76.98232 38.85084 0, -76.98101 ... \n", + "13832 LINESTRING Z (-76.9889 38.85219 0, -76.98844 3... \n", + "13833 LINESTRING Z (-76.9956 38.8754 0, -76.99557 38... \n", + "\n", + " BLOCKKEY original_lts lts_100 \n", + "0 4af7e25abf59911305f2724cadc85a08 3.0 40 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2.0 60 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2.0 60 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4.0 10 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2.0 60 \n", + "... ... ... ... \n", + "13829 03ceb30917e33f51246b9427451bf29a 4.0 10 \n", + "13830 f8c1e5fae8a0321753beea69ef9d88f1 2.0 60 \n", + "13831 6e06a429de20637fc25ec5ee5bdad443 2.0 60 \n", + "13832 a476aa40bc64479559e7361d9c105d16 2.0 60 \n", + "13833 cb8e955725acf60fbb9a51e0f8cfd753 2.0 60 \n", + "\n", + "[13834 rows x 33 columns]" + ] + }, + "execution_count": 40, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#change scale from 1 to 4 to 0-100 levels\n", + "roads_wRS['lts_100'] = 0\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 1] = 90\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 2] = 60\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 3] = 40\n", + "roads_wRS['lts_100'][roads_wRS['original_lts'] == 4] = 10\n", + "roads_wRS" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "id": "fa747659-ceb7-493a-b593-a0a4f78ead3d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "array([3., 2., 4., 1.])" + ] + }, + "execution_count": 41, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "roads_wRS['original_lts'].unique()" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "id": "507338e2-5f61-4428-a79f-692df222e01b", + "metadata": {}, + "outputs": [], + "source": [ + "roads_wRS['seg_id'] = roads_wRS.index" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "4e0edab5-ccf9-4eab-a59a-704b1a426d48", + "metadata": {}, + "outputs": [], + "source": [ + "roads_wRS.to_file('road_lts_wCrashes.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "f3e78256-7d98-48f7-bbd3-81102eb531c9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 46, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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RZ55f7x53WsNROfOnZM+ffrIvHnzzETLVzJ79mzz/FYNkk6ivG3bNnn77bcJRAAAoGAahprWbeTXl2fo0KHywAMPmJUirhaIEhISnJMlWzp16iTz58+X3NxcsyyXt1FDBAAAbsjSpUtl+/btpsmsMHThds8F1nX/4sWLpnbKdVF3byEQAQCA65aammo6UOvSWtcyA7euWerKWjjD87i3EIgAAMB1S0pKMgu0N2/e3HksLy9P1q9fb9YNzc7OdltfVEVERJhaIlf6HLo2qS7W7gsEIgAAcN10UfVdu3a5HXvyySelYcOG8sILL+QLQ6p169byxRdfuB3TGqYWLVr4pP+QIhABAIDrFhoaKjExMW7HKlasaGp6rOPjx4+Xo0ePyscff2z2db4hrT3SeYh06L12stYO1Z9++qn4CoEIAAA/p8PhS/LrpKWlmTmVLLoq/cqVK2X06NHy/vvvm4kZZ8yY4bMh94pABACAn9JZo3WiRJ0byFtCgkPM696ItWvXuu0vXLgwX5m4uDgzMs1fEIgAAPBTOnmhzhpdkpbuKKkIRAAA+DENJ3YMKN7GavcAAMD2CEQAAMD2CEQAAMD2CEQAAHiRtUQF/OuaEogAAPACawbmzMxMrncRs67pjcxyzSgzAAC8QJewuPnmm82aXSokJMRnC5mWppqhzMxMc0312ha0TEhhEYgAAPASXdRUWaEIRUPDkHVtrxeBCAAAL9EaoZo1a0p4eLjk5uZy3YuANpPdSM2QhUAEAICX6Rd4UXyJo+jQqRoAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANgegQgAANie3wSiyZMnS5kyZWTUqFHOYw6HQyZOnCi1atWS4OBgadu2rezZs8ftcdnZ2TJ8+HAJCwuTihUrSvfu3eXIkSNuZU6dOiV9+/aVypUrm01vnz592mvvDQAA+De/CERbt26VuXPnSpMmTdyOT5kyRaZOnSozZ840ZSIiIqRDhw5y9uxZZxkNUMuXL5elS5fKhg0b5Ny5c9KtWzfJy8tzlundu7fs2LFDVq1aZTa9raEIAADALwKRBpg+ffrIvHnzpEqVKm61Q9OnT5cJEyZI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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "sns.histplot(data=roads_wRS, x=\"ridescore_v1\", hue=\"original_lts\", multiple = 'dodge', palette = 'Set2')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/lts/readme.md b/lts/readme.md new file mode 100644 index 0000000..195ff21 --- /dev/null +++ b/lts/readme.md @@ -0,0 +1,15 @@ +# Level of Traffic Stress Implementation + +This notebook implements the [Level of Traffic Stress](https://peterfurth.sites.northeastern.edu/2014/05/21/criteria-for-level-of-traffic-stress/) model. Specifically, the [2022 edition](https://bpb-us-e1.wpmucdn.com/sites.northeastern.edu/dist/e/618/files/2014/05/LTS-Tables-v2.2.pdf) though there is more background in the [original model](https://peterfurth.sites.northeastern.edu/level-of-traffic-stress/). + +In short, this quantifies how stressful or comfortable a road is to bike on. +* Level 1: Cyclists are not in contact with traffic (except for slow, low volume traffic); comfortable for all level of cycling abilities (including children). +* Level 2: Cyclists have their own space and intersections are easy to navigate; comfortable for adult cyclists. +* Level 3: Cyclists interact with some moderate/multi-lane traffic or close to higher-speed traffic; acceptable for 'enthused and confident' cyclists. +* Level 4: Cyclists interact with or are near high-speed traffic; acceptable for 'strong and fearless' cyclists. + +The first step was find correspondence between the descriptions and the available [DC road data](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about). + +Then, the LTS descriptions are translated into criteria that can be extracted from the data (see LTS.xlsx) + +Lastly, the new per road segment data is added to the postgis database and the function and html files are updated to incorporate the LTS. See 'mvp_map' folder. \ No newline at end of file diff --git a/mvp_map/data_processing.ipynb b/mvp_map/data_processing.ipynb deleted file mode 100644 index b73a3f2..0000000 --- a/mvp_map/data_processing.ipynb +++ /dev/null @@ -1,2818 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3f089b9b", - "metadata": {}, - "source": [ - "# DC Bike Safety Map: Data Processing\n", - "\n", - "This notebook takes [road](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) and [crash](https://opendata.dc.gov/datasets/crashes-in-dc/about) data from the DC data website and processes it for the [DC Bike Safety Map](http://161.35.142.176/). The LTS and ridescore build on 01_lts_osm_elia_v2.ipynb.\n", - "\n", - "This is preliminary work and future work could include:\n", - "* see if same data can be extracted from OSM\n", - "* Taking directionality of road into account\n", - "* Adding bike trails\n", - "* Implement standard LTS methodology\n", - "* Refine scaling factors to 0 to 100 scale" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "ac844942", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Versions → osmnx 2.0.7 | geopandas 1.1.2\n" - ] - } - ], - "source": [ - "# 1) Imports + settings\n", - "import warnings, math, re, os, json\n", - "\n", - "import pandas as pd\n", - "import geopandas as gpd\n", - "from shapely.geometry import LineString, MultiLineString, Point\n", - "import osmnx as ox\n", - "import folium\n", - "from folium.plugins import MeasureControl\n", - "import requests\n", - "import matplotlib.pyplot as plt\n", - "import numpy as np\n", - "\n", - "import requests\n", - "\n", - "import time\n", - "from datetime import date\n", - "from dateutil.relativedelta import relativedelta\n", - "\n", - "ox.settings.use_cache = True\n", - "ox.settings.log_console = False\n", - "\n", - "print(\"Versions →\", \n", - " \"osmnx\", ox.__version__, \n", - " \"| geopandas\", gpd.__version__)" - ] - }, - { - "cell_type": "markdown", - "id": "18ebf500-b920-40ee-b3c9-7accb73c069a", - "metadata": {}, - "source": [ - "## Road Data" - ] - }, - { - "cell_type": "code", - "execution_count": 19, - "id": "14cdcd9b-30c1-40a4-bafb-c65581692b52", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "trying website\n", - "\n", - "https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
geometryROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERS...PARKINGZONE_RPPAADT_COMBINATIONAADT_COMBINATION_YEARAADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELEN
0LINESTRING Z (-77.06513 38.95849 0, -77.06519 ...110640220.00000080.945198NEVADA AVE NW1d70b65e6ea22f0071f19cf09d5553717220...NoneNaNNaNNaNNaN11.0None40314090
1LINESTRING Z (-77.02599 38.90725 0, -77.02599 ...110010021682.6739501830.72656210TH ST NW1528f6e548b149fa21ae83561cdc63dae120...115.02020.031.02020.011.0None40314100
2LINESTRING Z (-77.0179 38.9141 0, -77.01801 38...110642822537.7758792602.471924NEW JERSEY AVE NW105124d80213b35ef82e5b47e5b017084400...None101.02020.0432.02020.011.0None40314110
3LINESTRING Z (-77.01481 38.9385 0, -77.0145 38...110579320.000000120.393799MACARTHUR DR NW189a29f6d9a6d16994604fb73fd88dea8200...NoneNaNNaNNaNNaN1174.0None40314120
4LINESTRING Z (-77.02378 38.93282 0, -77.0238 3...110400421846.1541751869.230347GEORGIA AVE NW19294a0e372f55c25c7fd7e47bb61c7ab420...None166.02020.0580.02020.011.0None40314130
..................................................................
13833LINESTRING Z (-76.99091 38.83236 0, -76.99084 ...13013262491.352692666.291809BARNABY ST SE1831193e3c6319eeffcd4b450bdd2d3dd220...2NaNNaNNaNNaN11.0YES40642500
13834LINESTRING Z (-76.98831 38.88146 0, -76.98831 ...13001302925.6519161167.68383813TH ST SE1a1789777713c61fa6aa73fb581afbed0230...3NaNNaNNaNNaN11.0None40642510
13835LINESTRING Z (-76.9815 38.84737 0, -76.98145 3...13084782105.780403192.215302TANNER ST SE1f286b3f4bca7b6e81a3918ad7afe539e220...NoneNaNNaNNaNNaN11.0None40642520
13836LINESTRING Z (-76.99845 38.88128 0, -76.99835 ...13038612311.641998508.683807G ST SE15fb6a403d1ca5c8c54a76e6273dc14a8220...1NaNNaNNaNNaN11.0None40642530
13837LINESTRING Z (-77.01844 38.83859 0, -77.01849 ...14021882161.074600385.713806CHANDLER ST SW1d17c659fb7c4c44bf447570332728e71220...NoneNaNNaNNaNNaN972.0None40642540
\n", - "

13838 rows × 102 columns

\n", - "
" - ], - "text/plain": [ - " geometry ROUTEID \\\n", - "0 LINESTRING Z (-77.06513 38.95849 0, -77.06519 ... 11064022 \n", - "1 LINESTRING Z (-77.02599 38.90725 0, -77.02599 ... 11001002 \n", - "2 LINESTRING Z (-77.0179 38.9141 0, -77.01801 38... 11064282 \n", - "3 LINESTRING Z (-77.01481 38.9385 0, -77.0145 38... 11057932 \n", - "4 LINESTRING Z (-77.02378 38.93282 0, -77.0238 3... 11040042 \n", - "... ... ... \n", - "13833 LINESTRING Z (-76.99091 38.83236 0, -76.99084 ... 13013262 \n", - "13834 LINESTRING Z (-76.98831 38.88146 0, -76.98831 ... 13001302 \n", - "13835 LINESTRING Z (-76.9815 38.84737 0, -76.98145 3... 13084782 \n", - "13836 LINESTRING Z (-76.99845 38.88128 0, -76.99835 ... 13038612 \n", - "13837 LINESTRING Z (-77.01844 38.83859 0, -77.01849 ... 14021882 \n", - "\n", - " FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", - "0 0.000000 80.945198 NEVADA AVE NW 1 \n", - "1 1682.673950 1830.726562 10TH ST NW 1 \n", - "2 2537.775879 2602.471924 NEW JERSEY AVE NW 1 \n", - "3 0.000000 120.393799 MACARTHUR DR NW 1 \n", - "4 1846.154175 1869.230347 GEORGIA AVE NW 1 \n", - "... ... ... ... ... \n", - "13833 491.352692 666.291809 BARNABY ST SE 1 \n", - "13834 925.651916 1167.683838 13TH ST SE 1 \n", - "13835 105.780403 192.215302 TANNER ST SE 1 \n", - "13836 311.641998 508.683807 G ST SE 1 \n", - "13837 161.074600 385.713806 CHANDLER ST SW 1 \n", - "\n", - " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", - "0 d70b65e6ea22f0071f19cf09d5553717 2 2 \n", - "1 528f6e548b149fa21ae83561cdc63dae 1 2 \n", - "2 05124d80213b35ef82e5b47e5b017084 4 0 \n", - "3 89a29f6d9a6d16994604fb73fd88dea8 2 0 \n", - "4 9294a0e372f55c25c7fd7e47bb61c7ab 4 2 \n", - "... ... ... ... \n", - "13833 831193e3c6319eeffcd4b450bdd2d3dd 2 2 \n", - "13834 a1789777713c61fa6aa73fb581afbed0 2 3 \n", - "13835 f286b3f4bca7b6e81a3918ad7afe539e 2 2 \n", - "13836 5fb6a403d1ca5c8c54a76e6273dc14a8 2 2 \n", - "13837 d17c659fb7c4c44bf447570332728e71 2 2 \n", - "\n", - " TOTALRAISEDBUFFERS ... PARKINGZONE_RPP AADT_COMBINATION \\\n", - "0 0 ... None NaN \n", - "1 0 ... 1 15.0 \n", - "2 0 ... None 101.0 \n", - "3 0 ... None NaN \n", - "4 0 ... None 166.0 \n", - "... ... ... ... ... \n", - "13833 0 ... 2 NaN \n", - "13834 0 ... 3 NaN \n", - "13835 0 ... None NaN \n", - "13836 0 ... 1 NaN \n", - "13837 0 ... None NaN \n", - "\n", - " AADT_COMBINATION_YEAR AADT_SINGLE_UNIT AADT_SINGLE_UNIT_YEAR \\\n", - "0 NaN NaN NaN \n", - "1 2020.0 31.0 2020.0 \n", - "2 2020.0 432.0 2020.0 \n", - "3 NaN NaN NaN \n", - "4 2020.0 580.0 2020.0 \n", - "... ... ... ... \n", - "13833 NaN NaN NaN \n", - "13834 NaN NaN NaN \n", - "13835 NaN NaN NaN \n", - "13836 NaN NaN NaN \n", - "13837 NaN NaN NaN \n", - "\n", - " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", - "0 1 1.0 None \n", - "1 1 1.0 None \n", - "2 1 1.0 None \n", - "3 11 74.0 None \n", - "4 1 1.0 None \n", - "... ... ... ... \n", - "13833 1 1.0 YES \n", - "13834 1 1.0 None \n", - "13835 1 1.0 None \n", - "13836 1 1.0 None \n", - "13837 9 72.0 None \n", - "\n", - " OBJECTID SHAPELEN \n", - "0 4031409 0 \n", - "1 4031410 0 \n", - "2 4031411 0 \n", - "3 4031412 0 \n", - "4 4031413 0 \n", - "... ... ... \n", - "13833 4064250 0 \n", - "13834 4064251 0 \n", - "13835 4064252 0 \n", - "13836 4064253 0 \n", - "13837 4064254 0 \n", - "\n", - "[13838 rows x 102 columns]" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 2) Get Roadblock data from website\n", - "CRS = 'EPSG:4326'\n", - "def try_fetch_dc_roads():\n", - " url = \"https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\"\n", - " try:\n", - " print('trying website')\n", - " r = requests.get(url, timeout=60)\n", - " r.raise_for_status()\n", - " print(r)\n", - " print(url)\n", - " if r.ok:\n", - " gj = r.json()\n", - " roads = gpd.GeoDataFrame.from_features(gj[\"features\"], crs=CRS)\n", - " return roads\n", - " except Exception as error:\n", - " print('Error reading road data from dc gov website')\n", - "\n", - "edges = try_fetch_dc_roads()\n", - "edges.to_file('edges.geojson')\n", - "edges" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "ba1c349e-feb2-4b9f-bfa9-fa51f3d411dd", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "geometry\n", - "ROUTEID\n", - "FROMMEASURE\n", - "TOMEASURE\n", - "ROUTENAME\n", - "ROADTYPE\n", - "BLOCKKEY\n", - "TOTALTRAVELLANES\n", - "TOTALPARKINGLANES\n", - "TOTALRAISEDBUFFERS\n", - "TOTALTRAVELLANEWIDTH\n", - "TOTALCROSSSECTIONWIDTH\n", - "TOTALPARKINGLANEWIDTH\n", - "TOTALRAISEDBUFFERWIDTH\n", - "TOTALTRAVELLANESINBOUND\n", - "TOTALTRAVELLANESOUTBOUND\n", - "TOTALTRAVELLANESBIDIRECTIONAL\n", - "TOTALTRAVELLANESREVERSIBLE\n", - "SUMMARYDIRECTION\n", - "BIKELANE_PARKINGLANE_ADJACENT\n", - "BIKELANE_THROUGHLANE_ADJACENT\n", - "BIKELANE_POCKETLANE_ADJACENT\n", - "BIKELANE_CONTRAFLOW\n", - "BIKELANE_CONVENTIONAL\n", - "BIKELANE_DUAL_PROTECTED\n", - "BIKELANE_PROTECTED\n", - "BIKELANE_BUFFERED\n", - "DOUBLEYELLOW_LINE\n", - "SECTIONFLAGS\n", - "LOC_ERROR\n", - "MIDMEASURE\n", - "AADT\n", - "AADT_YEAR\n", - "FHWAFUNCTIONALCLASS\n", - "HPMSID\n", - "HPMSSECTIONTYPE\n", - "ID\n", - "IRI\n", - "IRI_DATE\n", - "NHSCODE\n", - "OWNERSHIP\n", - "PCI_CONDCATEGORY\n", - "PCI_LASTINSPECTED\n", - "PCI_SCORE\n", - "QUADRANT\n", - "SIDEWALK_IB_PAVTYPE\n", - "SIDEWALK_IB_WIDTH\n", - "SIDEWALK_OB_PAVTYPE\n", - "SIDEWALK_OB_WIDTH\n", - "SPEEDLIMITS_IB\n", - "SPEEDLIMITS_IB_ALT\n", - "SPEEDLIMITS_OB\n", - "SPEEDLIMITS_OB_ALT\n", - "STREETNAME\n", - "STREETTYPE\n", - "BLOCK_NAME\n", - "ADDRESS_RANGE_HIGH\n", - "ADDRESS_RANGE_LOW\n", - "ADDRESS_RANGE_RIGHT_HIGH\n", - "ADDRESS_RANGE_LEFT_HIGH\n", - "ADDRESS_RANGE_RIGHT_LOW\n", - "MAR_ID\n", - "ADDRESS_RANGE_LEFT_LOW\n", - "BLOCKID\n", - "DCFUNCTIONALCLASS\n", - "NHSTYPE\n", - "SNOWROUTE_DDOT\n", - "SNOWROUTE_DPW\n", - "SNOWSECTION_DDOT\n", - "SNOWZONE_DDOT\n", - "SNOWZONE_DPW\n", - "LEFTTURN_CURBLANE_EXCL\n", - "LEFTTURN_CURBLANE_EXCL_LEN\n", - "RIGHTTURN_CURBLANE_EXCL\n", - "RIGHTTURN_CURBLANE_EXCL_LEN\n", - "TOTALBIKELANES\n", - "TOTALBIKELANEWIDTH\n", - "RPPDIRECTION\n", - "RPPSIDE\n", - "SLOWSTREETINFO\n", - "BIKELANE_DUAL_BUFFERED\n", - "RIGHTTURN_EXCLUSIVE\n", - "LEFTTURN_EXCLUSIVE\n", - "BUSLANE_INBOUND\n", - "BUSLANE_OUTBOUND\n", - "FROMSTREET\n", - "TOSTREET\n", - "WARD_ID\n", - "ANC_ID\n", - "SMD_ID\n", - "SURFACE_TYPE\n", - "PARKINGZONE_ROP\n", - "PARKINGZONE_RPP\n", - "AADT_COMBINATION\n", - "AADT_COMBINATION_YEAR\n", - "AADT_SINGLE_UNIT\n", - "AADT_SINGLE_UNIT_YEAR\n", - "DC_MAINTENANCE_OPERATIONS\n", - "MAINTENANCE_OPERATIONS\n", - "VERTICAL_DEFLECTION\n", - "OBJECTID\n", - "SHAPELEN\n" - ] - } - ], - "source": [ - "#look at columns\n", - "for c in gdf.columns:\n", - " print(c)" - ] - }, - { - "cell_type": "code", - "execution_count": 21, - "id": "8990d5a7", - "metadata": {}, - "outputs": [], - "source": [ - "# 3) Helpers for tag parsing\n", - "def classify_facility(tags):\n", - " # standardize bike lane types into 3 categories (protected, buffered, and painted). Sharrows don't seem to be indicated in dataset\n", - " # directionality of road is not taken into account\n", - " if (tags.get(\"BIKELANE_PROTECTED\") in {\"IB\", \"OB\", \"BD\"}) or (tags.get(\"BIKELANE_DUAL_PROTECTED\") in {\"IB\", \"OB\", \"BD\"}):\n", - " return \"protected_track\"\n", - " elif (tags.get(\"BIKELANE_BUFFERED\") in {\"IB\", \"OB\", \"BD\"}):\n", - " return \"buffered_lane\"\n", - " elif (tags.get(\"BIKELANE_CONVENTIONAL\") in {\"IB\", \"OB\", \"BD\"}):\n", - " return \"painted_lane\"\n", - " else:\n", - " return \"none\"\n", - "\n", - "#replace function number with name\n", - "function_dict = {11: 'Interstate', 12: 'Other Freeway and Expressway', 14: 'Principal/Primary Arterial', 16: 'Minor Arterial', 17: 'Collector', 19:'Local'}\n", - "def name_function(tags):\n", - " if tags['DCFUNCTIONALCLASS'] in function_dict.keys():\n", - " return function_dict[tags['DCFUNCTIONALCLASS']]\n", - " else:\n", - " return 'Other'\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 22, - "id": "083ea52e", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "0\n", - "1000\n", - "2000\n", - "3000\n", - "4000\n", - "5000\n", - "6000\n", - "7000\n", - "8000\n", - "9000\n", - "10000\n", - "11000\n", - "12000\n", - "13000\n", - "Normalized segments: 13838\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
route_idroute_namefunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presenceroad_widthslow_streetpavement_conditiongeometry
011064022NEVADA AVE NWCollector2220.020.0noneTrue33NoneExcellentLINESTRING Z (-77.06513 38.95849 0, -77.06519 ...
11100100210TH ST NWCollector1125.0NaNpainted_laneTrue31NoneExcellentLINESTRING Z (-77.02599 38.90725 0, -77.02599 ...
\n", - "
" - ], - "text/plain": [ - " route_id route_name function num_lanes num_lanes_raw speed_limit \\\n", - "0 11064022 NEVADA AVE NW Collector 2 2 20.0 \n", - "1 11001002 10TH ST NW Collector 1 1 25.0 \n", - "\n", - " speed_limit_raw bike_facility_type parking_presence road_width \\\n", - "0 20.0 none True 33 \n", - "1 NaN painted_lane True 31 \n", - "\n", - " slow_street pavement_condition \\\n", - "0 None Excellent \n", - "1 None Excellent \n", - "\n", - " geometry \n", - "0 LINESTRING Z (-77.06513 38.95849 0, -77.06519 ... \n", - "1 LINESTRING Z (-77.02599 38.90725 0, -77.02599 ... " - ] - }, - "execution_count": 22, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 3) simplify and impute fields as needed.\n", - "# while the safety scores my included the impute values to ensure it processes without error, the raw values are displayed on the map.\n", - "\n", - "rows = []\n", - "for i, r in edges.reset_index(drop=True).iterrows():\n", - " if (i%1000) == 0:\n", - " print(i)\n", - " tags = r.to_dict()\n", - " facility = classify_facility(tags)\n", - " function = name_function(tags)\n", - " rows.append({\n", - " \"route_id\": tags['ROUTEID'],\n", - " \"route_name\": tags['ROUTENAME'],\n", - " \"function\": function,\n", - " \"num_lanes\": tags['TOTALTRAVELLANES'] if tags['TOTALTRAVELLANES'] >-1 else 1, #set number of travels to 1 if no value is available \n", - " \"num_lanes_raw\": tags['TOTALTRAVELLANES'],\n", - " \"speed_limit\": tags['SPEEDLIMITS_OB'] if tags['SPEEDLIMITS_OB'] >1 else 25, #speed limit is set to 25 is no values is available\n", - " \"speed_limit_raw\": tags['SPEEDLIMITS_OB'],\n", - " \"bike_facility_type\": facility,\n", - " \"parking_presence\": True if tags[\"TOTALPARKINGLANES\"] > 0 else False,\n", - " \"road_width\": tags['TOTALCROSSSECTIONWIDTH'],\n", - " \"slow_street\": tags['SLOWSTREETINFO'],\n", - " \"pavement_condition\": tags['PCI_CONDCATEGORY'],\n", - " \"geometry\": r.geometry\n", - " })\n", - "\n", - "gdf = gpd.GeoDataFrame(rows, geometry=\"geometry\", crs=CRS)\n", - "print(\"Normalized segments:\", len(gdf))\n", - "gdf.head(2)" - ] - }, - { - "cell_type": "markdown", - "id": "75801f70-9dbd-40db-aa08-300e22c5966b", - "metadata": {}, - "source": [ - "### Modified Level of Traffic Stress score\n", - "\n", - "We use our own, modified level of traffic stress (LTS) calculator.\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Bike laneNumber of lanesSpeed limitRoad functionLTS
Protected track---1
Buffered lane or painted lane<= 2<= 25-2
None<= 2<= 25Local2
Buffered lane or painted lane>2 and <=3>25 and <= 30-3
None<=2>25 and <= 30Local3
Any other combination4
" - ] - }, - { - "cell_type": "code", - "execution_count": 25, - "id": "86d95644", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "lts_level\n", - "1 285\n", - "2 7564\n", - "3 1606\n", - "4 4383\n", - "Name: count, dtype: int64" - ] - }, - "execution_count": 25, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 4) LTS rules (compact + tunable)\n", - "\n", - "def lts_level(facility, speed, lanes, function=\"\"):\n", - " hw = (function or \"\").lower()\n", - " if facility in {\"protected_track\"}: return 1 # or hw in {\"cycleway\",\"path\"}: return 1, also include ,\"separated_lane\" here\n", - " if facility in {\"buffered_lane\",\"painted_lane\"}:\n", - " if speed <= 25 and lanes <= 2: return 2\n", - " if speed <= 30 and lanes <= 3: return 3\n", - " return 4\n", - " if facility in {\"none\"}: #include \"shared\" here\n", - " if speed <= 20 and lanes <= 2 and hw in {\"local\"}: \n", - " return 2\n", - " if speed <= 30 and lanes <= 2 and hw in {\"local\"}: return 3\n", - " return 4\n", - " return 4\n", - "\n", - "gdf[\"lts_level\"] = gdf.apply(lambda r: lts_level(r.bike_facility_type, int(r.speed_limit), int(r.num_lanes), r.function), axis=1)\n", - "gdf[\"lts_level\"].value_counts().sort_index()" - ] - }, - { - "cell_type": "markdown", - "id": "8629f210-60d0-459c-9886-78e9985945be", - "metadata": {}, - "source": [ - "### Data exploration\n", - "Let's look at some of the columns of interest" - ] - }, - { - "cell_type": "code", - "execution_count": 31, - "id": "d4cc6df8-ac18-475a-9ccc-448995e3db12", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHFCAYAAAAT5Oa6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOltJREFUeJzt3Q98zXX///HX2h+GbTEMEbpai0hd9DUqU2OI9O+K0rV0EYpo4RrLVamry1Ch8k1yifInXVdSXZG2Sv7kb8rlT0g1ojCKDWlbc3631/t3O5/vOWczm8Y52/txv90+7ZzPeZ/P+ZzPPu08vd7v9+cEuVwulwAAAFjsAn/vAAAAgL8RiAAAgPUIRAAAwHoEIgAAYD0CEQAAsB6BCAAAWI9ABAAArEcgAgAA1iMQAQAA6xGIgAA0e/ZsCQoKks8//7zYx3v06CFNmjTxWqf377vvvjK9zurVq2Xs2LFy9OjR37W/NnnzzTfliiuukPDwcPM72rRpU7HtPv30U/O4/nRbsmSJOd7l6Wx+7+dKx44dzQJURAQioJJYtGiRPPbYY2UORE8++SSBqJQOHTokycnJ8oc//EGWLl0qa9askcsuu6zUx1sDkR5vAIEnxN87AKB8XH311RXuUBYUFJgqSkhIxfhT9PXXX5t9/vOf/ywJCQn+3h0A5YgKEVBJ+HadnDp1Sp5++mmJi4sz3TsXXnihXHnllfL888+bx7Xr5q9//au53bRpUxNMPLt49PkTJ06Uyy+/XKpUqSJ169aVe++9V/bt2+f1uvr90OPGjZPGjRtL1apVpU2bNpKZmVmk+8TdhTRnzhwZMWKEXHTRRWa733zzjam8DB48WJo3by41atQwr3XjjTfKypUrvV5r9+7dZhvPPPOMTJgwwbxnfW/6Ou6wMnr0aGnQoIFERUXJbbfdJtnZ2aU6fu+99560a9dOqlWrJhEREdK5c2dTAXLTY3vdddeZ27179zb7UZbuIX3+//7v/5rb7mOti74n9e9//1vatm1r9lv34ZJLLpF+/frJ2cjNzZWRI0ea32tYWJg51ikpKXLixAmvAH399dcXeW5hYaFpf/vttzvr8vPzzbnkPhfq1Kkjf/nLX8zv7UymTZsmrVq1Mr9XPa66jUcfffSs3hdwLlWMf5YBltIPp99++63Ieg0hZ6JhRkPP3/72N+nQoYMJCzt27HC6x+6//375+eef5cUXX5S3335b6tevb9ZrKFEPPvigvPLKK/LQQw+ZMUv6wa1dchpsvvjiC6ldu7ZpN2bMGElPT5eBAweaD9G9e/eabevrFdedlJaWZoLHyy+/LBdccIEJP+4P1ieeeELq1asnx48fN12AGjg+/vjjIsFDg4WGO/2p70cD1s0332wCRWhoqLz66quyZ88eEwp0XzTslGT+/Plyzz33SFJSkrzxxhuSl5dnjp/79TUI6Xv/n//5HxkyZIgJgDfccINERkZKaenzNZC89dZbXkFLj7ve15Cli/7ONFjq/n/yySdSVr/88oupXmlw1eChx2nbtm3y+OOPy5YtW+Sjjz4yQUwDzcMPPyy7du2S2NhY5/kZGRny448/msfdwfiWW24x4TQ1NVXat29v9k1/V3p8dJybhtLiLFiwwATdoUOHyrPPPmt+3xqAv/rqqzK/L+CccwEIOLNmzdLEU+LSuHFjr+fo/b59+zr3e/To4brqqqtKfJ1nnnnGbCsrK8tr/fbt2836wYMHe61ft26dWf/oo4+a+z///LOrSpUqrt69e3u1W7NmjWmXkJDgrFu2bJlZ16FDhzO+/99++81VUFDgSkxMdN12223Oet1P3UarVq1chYWFzvopU6aY9T179vTaTkpKilmfk5Nz2tfS7TRo0MDVsmVLr20eO3bMVbduXVf79u2LvId///vfZ3wP7rb6023IkCFmna9nn33WrD969KirrHx/7+np6a4LLrjAtWHDBq92b731lnmNJUuWmPuHDx92hYWFOb9Lt169erliYmLM8VdvvPGGed7ChQu92un2df1LL73krNPft+fv/KGHHnJdeOGFZX5PgD/QZQYEsNdff102bNhQZHF33ZREqxn//e9/zb/QP/zwQ9ONUlrLli0zP31nL+k2mzVrZqomau3ataaa0qtXL6928fHxRWbBud1xxx3FrteK0R//+EdTHdExRVrp0dfZvn17kbY33XSTqTa46T6p7t27e7Vzr//+++9P+1537txpKiI6WNpzm9rFo/uq71GrLufSNddcY37qcfzXv/4lP/zww1lv6/3335cWLVrIVVddZaqL7qVLly5eXaLR0dGmqvbaa6+ZKpA6cuSIvPvuu6Zr1D2uS7en3a3a1nN7un2t5nnOovOl54tW8O6++26z3cOHD5/1+wLONQIREMD0A13H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dACBhwoRgHMaAFJTU+Wiiy6S6tWrS9u2bc03zqucnBwJDw+XpUuXej3n7bffNm2PHz9u7v/www/Su3dvqVmzpkRHR8stt9wiu3fvLtN+LFy4UK644gqpUqWKNGnSRJ577jmvbj69v2LFCtNdpveL89///lduuOEGiYiIMF1rrVu3ls8//9y8H/3mbn0/+nxdxo4da56jr/X000+bbj2tOg0YMMCs10pUhw4dzPtv1KiRDBs2TE6cOOG81ksvvSSxsbFStWpViYmJkT/96U/OY2+99Za0bNnSPFePR6dOnbyeC+DsEIgAnDMaFD777DNZsGCBbN68We68807p2rWr7Nq1ywSE7t27y7x587yeM3/+fBN6atSoYcb2aAjR2xpYVq1aZW7rNjRslcbGjRulV69ectddd8mWLVtMWHnsscdMN5c7gGlQadeuneku0/vFueeee6Rhw4ayYcMGs83Ro0dLaGiotG/fXqZMmWJCkj5fl5EjRzrPe+aZZ0zlSZ+jr6v70KVLF7n99tvNMXnzzTfN+3rooYdMew1ZGpCeeuop2blzpwmMGp6Ubvvuu++Wfv36yfbt200Y0+3wlZRAOTinXx0LwNpvsP7mm29cQUFBrh9++MGrjX4reFpamrn99ttvu2rUqOE6ceKEuZ+Tk2O+Ddz9LeAzZ850xcXFuU6dOuU8Py8vzxUeHu768MMPnW/JvuWWW067T3369HF17tzZa91f//pXV/PmzZ37us++37TtKyIiwjV79uxiH5s1a5YrKiqqyHr9NvRbb73Va11ycrJr4MCBXutWrlzpuuCCC1wnT550LVy40BUZGenKzc0tsr2NGzfql3G7du/eXeK+Aig7KkQAzokvvvjCVC4uu+wyU9VxL8uXLzdjdpRWiEJCQuS9995zura0SyopKcnc16rKN998Y9a5n1+rVi359ddfnW2ciVZSrr32Wq91el+rVIWFhaV+P8OHD5f777/fdFGNHz++1K/fpk0br/v6nrQ65XlMtGJ06tQpycrKks6dO0vjxo3lkksukeTkZFNB00qZatWqlSQmJpouM622zZgxQ44cOVLq9wDg9BhUDeCc0A/44OBgEwD0pycNAUoHGOv4GO0m0y4t/anjhTQkubehY3V8u9VUnTp1SrUfGsp0XI/vurLSrrY+ffrI4sWL5YMPPpAnnnjCdAXedtttJT5Px0N50vc0aNAg0y3m6+KLLzbHRMOkdodlZGTI448/bl5bu+p0JltmZqYZg6SPvfjiizJmzBhZt26dNG3atMzvCcD/IRABOCeuvvpqU4HJzs6W66+//rTtdGyOVoS2bdsmy5Ytk7///e/OY3/84x/NGJu6deuaMTpno3nz5maMjicNFFq58g1qZ6LP0eWRRx4xY3lmzZplApGGmNJWm/Q96Xu99NJLT9tGA6FWonTR4KVB6JNPPjHjhTTcaYVLFw1LWk1atGiRqWABOHt0mQE4JzQ4aNi59957zUBl7Q7SKseECRNkyZIlTruEhAQzk0rb6qys+Ph45zFdV7t2bTPIWq8TpNvQLreHH35Y9u3bV6r9GDFihHz88ccmaH399dfmmkNTp071Gvh8JidPnjSDnrVqs2fPHjNQXN+LTtVXut86K05f5/Dhw04XV3FGjRola9askSFDhsimTZtM1512GQ4dOtQ8/v7778sLL7xgHtPXev31101VKS4uzlSCxo0bZwZef//99+a4Hjp0yNkPAGePQATgnNEKigYiDSX6gd6zZ0/zoa5Tzd204qHVFp3WrgHIU7Vq1czsMu1K0uqIfvDrDCsNKKWtGGlF5l//+pfp3tLZXlpV0RlcOhW+tLSS9NNPP5n3okFPZ61169ZNnnzySfO4zjR74IEHTHefduVNnDjxtNu68sorTajTIKSVM62k6eyz+vXrm8e1GqRB58YbbzTv9+WXX5Y33njDXDZA37Mej5tuusnsx9/+9jdzyQDdFwC/T5COrP6d2wAAAKjQqBABAADrEYgAAID1CEQAAMB6BCIAAGA9AhEAALAegQgAAFiPQAQAAKxHIAIAANYjEAEAAOsRiAAAgPUIRAAAwHoEIgAAILb7f9FVYRvtmj5HAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.hist(gdf['lts_level'])\n", - "plt.xlabel('level of stress')\n", - "plt.ylabel('count')\n", - "plt.title('Histogram of lts levels')\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 37, - "id": "a986a5be-f50b-4f52-94b4-c6363e7f9ac1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "length of road network: 1899.29km\n" - ] - } - ], - "source": [ - "#change crs to get length in meters\n", - "gdf = gdf.to_crs(gdf.estimate_utm_crs())\n", - "gdf['len'] = gdf.length\n", - "print(\"length of road network: {:.2f}km\".format(sum(gdf['len'])/1000))" - ] - }, - { - "cell_type": "code", - "execution_count": 69, - "id": "8b84b9cf-a88b-4df4-a99c-7cec7a3e184b", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAABKUAAAXRCAYAAABPeS4oAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQABAABJREFUeJzs3Qu8VFXZOP6FoggKeOeSqGhoKZIXDEUTTKHMTKMyxWsXXw1N8RJJdEFDUEzCsuzVVxErsotalq8KecGKSLylopkmKplIKgIiQsL8P896/zO/cw4HPMA5+5w5fL+fz4aZvffsWXvPPjNrP/tZa7UplUqlBAAAAAAF2qjINwMAAACAICgFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoRYt2ww03pDZt2lSmtm3bph122CF97nOfSy+99FKqdk8++WQaPXp0ev755xt923fffXfq27dv2nzzzfOx+/Wvf51aqvvuuy+XMf4v2pQpU9LEiRNTSxLnRByPV199tbD3HDhwYJ7K3nrrrVyO+j6T9S3fqaeemnbeeeda88aOHduo52hznlN1xd93lCW+z4DWSX1l3amvNIz6SvH1leasM3znO99JG5LyZ7Uudch4HvMbU91t/utf/8plfPTRRxv1ffg/bf///6FFmzRpUnrf+96Xli5dmu6///40bty4NH369PT444/noEs1B6Uuuuii/ONa9wt2fZRKpXTsscem3XbbLd122235GO2+++6Ntv3WJCp5TzzxRBo+fHjakP3whz+s9TwqeXFuhpqVv6YSQalPf/rT6Zhjjmny9wJoKuora0d9peHUV1pGfYWW59Zbb02dOnVq0m1GUCrOs7he23vvvRv1vRCUokr07t07Z/2EQw89NK1YsSJ9+9vfzpkVJ5xwwnptO37MOnTokFqT+OJ8/fXX0yc/+cl02GGHrfXr//Of/1Qy0yhOBF0322yzZjnke+yxR7O8L0Bror6ydtRXqpP6Ci3JPvvsUxXbZPU036MqHXDAAfn/F154oXKnLe6cROS6ffv2aauttspZF88991yt18UdlKgwRrZV//79czDq85//fF72xhtvpPPPPz/tsssuqV27dmn77bdPH/vYx9Lf/va3yuuXL1+exowZk7O2Yp3tttsuNyX8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589fJXuqrmjm16lTp1oTAEBTEpQCAKhi0RfUU089lbp165b7mIrA1LRp0yrLly9fnqZPn56b+AEAtCRtm7sAAAA03AUXXJCOOuqotOOOO+YMqDFjxuROyU855ZTcRG/48OFp7NixqVevXnmKxx06dEhDhw51mAGAFkVQCgCgivzzn/9Mxx9/fHr11VfTdtttlw444IA0c+bMtNNOO+XlI0aMSEuXLk3Dhg1LCxYsyB2jT506NXXs2LG5iw4AUIugFABAFbnpppvWuDyypUaPHp0nAICWTJ9SAAAAABROUAoAAACAwglKAQAAALDhBqXGjRtXGTGmrFQq5f4Qunfvntq3b58GDhyYZs+e3azlBAAAAKCVBKVmzZqVrrnmmtSnT59a88ePH58mTJiQrrrqqrxO165d06BBg9LixYubrawAAAAAtIKg1JtvvplOOOGEdO2116atttqqVpbUxIkT06hRo9KQIUNS79690+TJk9Nbb72VpkyZ0qxlBgAAAKDKg1JnnnlmOvLII9Phhx9ea/6cOXPSvHnz0uDBgyvz2rVrlwYMGJBmzJix2u0tW7YsLVq0qNYEAAAAQMvStjnf/KabbkoPP/xwbppXVwSkQpcuXWrNj+cvvPDCGvumuuiii5qgtAAAAABUfabU3Llz0znnnJN+8pOfpM0222y160Xn5zVFs76682oaOXJkWrhwYWWK9wEAAACgZWm2TKmHHnoozZ8/P+23336VeStWrEj3339/7tj86aefrmRMdevWrbJOvKZu9lRN0cQvJgAAAABarmbLlDrssMPS448/nh599NHK1Ldv39zpeTzeZZdd8mh706ZNq7xm+fLlafr06al///7NVWwAAAAAqjlTqmPHjnlEvZo233zztM0221TmDx8+PI0dOzb16tUrT/G4Q4cOaejQoc1UagAAAACqvqPzdzNixIi0dOnSNGzYsLRgwYLUr1+/NHXq1BzQAgAAAKB6taig1H333VfreXRoPnr06DwBAAAA0Ho0W59SAAAAAGy4BKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAFSxcePGpTZt2qThw4dX5pVKpTR69OjUvXv3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MI0ZMyZ3ohmddJYdeuih6c9//vO6bBIAoNVThwIAWM+g1OOPP54++clPrjJ/u+22S6+99tq6bBIAoNVThwIAWM+g1JZbbpk716zrkUceSe95z3vWZZMAAK2eOhQAwHoGpWJI4a9+9atp3rx5uTPNlStXpj/96U/pggsuSCeffPK6bBIAoNVThwIAWM+g1CWXXJJ23HHHnBUVnZzvscce6UMf+lDq379/+vrXv74umwQAaPXUoQAA/p+2aR1ssskm6ac//Wn69re/nR588MGcLbXPPvuk9773veuyOQCADYI6FADAegalwnXXXZe++93vpmeeeSY/79WrVxo+fHj64he/uK6bBABo9dShAADWIyj1jW98IwekvvzlL6cDDzwwz/vzn/+czj333PT888+nMWPGrMtmAQBaNXUoAID1DEpdffXV6dprr03HH398Zd4nPvGJ1KdPnxyoEpQCAFCHAgBo9I7OV6xYkfr27bvK/P322y+9884767JJAIBWTx0KAGA9g1Innnhizpaq65prrkknnHDCumwSAKDVU4cCAGikjs6nTp2aDjjggPx85syZae7cuenkk09O5513XmW9CRMmrOtbAAC0OupQAADrEZR64okn0r777psf/+Mf/8j/b7fddnmKZWVt2rRZl80DALRK6lAAAOsZlLr33nvX5WUAABs0dSgAgPXsU6qxjBs3Lu2///6pY8eOafvtt0/HHHNMevrpp2utUyqV0ujRo1P37t1T+/bt08CBA9Ps2bObrcwAAAAAVHlQavr06enMM8/M/VFNmzYtj9w3ePDgtGTJkso648ePz/1SXXXVVWnWrFmpa9euadCgQWnx4sXNWXQAAAAAmqOj88Zw55131no+adKknDH10EMPpUMOOSRnSU2cODGNGjUqDRkyJK8zefLk1KVLlzRlypR0+umnN1PJAQAAAKjaTKm6Fi5cmP/feuut8/9z5sxJ8+bNy9lTZe3atUsDBgxIM2bMqHcby5YtS4sWLao1AQAAANCytJigVGRFnXfeeenggw9OvXv3zvMiIBUiM6qmeF5eVl8/VZ07d65MPXr0KKD0AAAAAFRlUOqss85Kjz32WPrZz362yrI2bdqsEsCqO69s5MiROeOqPM2dO7fJygwAAABAFfYpVfblL3853Xbbben+++9PO+ywQ2V+dGoeIiuqW7dulfnz589f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0pfyd8M999zT3MWjQOedd169UwQOLr300spzWBe33nprOuigg1KHDh1S9+7dU7du3fLjmPfrX/+6xR5UQTTCrFmz0gknnJB69uyZ2rdvn8/deBzzHnzwwRZ5kKqxzDSdajsfqq28rD9BqQ3U66+/niZPntzcxaAgf//739P73//+dMghh6S99torDRw4ML388suV5QsXLkyf+9znfB4bkDvvvDPtvffe6YILLkj77LNPfh7nx7PPPptefPHF9JGPfERgagMyceLEdO+996ZHHnmk1hTN9yJ4GY8fffTR5i4mVei///u/03HHHZf69OmTfv7zn+ebI3/4wx/y45gXy6699trUklRjEK3aLuKqpbzxecfnHvXmc845J11//fXpf/7nf/LjBQsW5GW/+c1vUktSjWWulvOhGstbbedDtZW3Gs+JsshcPumkk/LvXNu2bdPGG29caypSm5IOI1ql2267bY3Ln3vuuXT++edLn99AfPKTn0zvvPNOzop54403csbDE088ke67776044475i+l+ELSnGLD0b9///ThD384jRkzJt10001p2LBhOUvqkksuyctHjRqVf2CnTp3a3EWlAOPGjcuBgaj4xXlRtskmm6S//vWvaY899vA5sE7e+973ppEjR6YvfOEL9S6PC4743vnHP/7RYoJoZ599ds4YjeB8ly5dcnA2mhzedddd+Xf0+9//fjrttNNSS7qIO/bYY9Nhhx22SpnjO/zuu+9Ov/jFL9LRRx+dWoJqKm/v3r3TiSeemC688MJ6l1922WU503z27Nmppai2MlfT+VCN5a2286HayluN50TZEUcckW9En3XWWfnmS5s2bVJNhZY3glK0Pm3atClttNFG+f/VTbGcDcP2229feuyxx2rNGzZsWGnHHXcs/eMf/yjNmzfP+bCB6dSpU+mZZ57Jj1esWFFq27Zt6aGHHqosf/zxx0tdunRpxhJStAceeKC02267lc4///zS8uXL87w4L2bPnu3DYJ1tttlmpb/97W+rXf7UU0/ldVqKXXfdtfQ///M/q11+3XXXlXbZZZdSS7LnnnuWxo0bt9rll156aWmPPfYotRTVVN527dqVnn766dUuj3M71mlJqq3M1XQ+VGN5q+18qLbyVuM5UbbFFluUHnnkkVJLoPleKxXRzptvvjmtXLmy3unhhx9u7iJScH9SkZZZ0w9+8IP0iU98Ig0YMCA372PDtdFGG6XNNtssbbnllpV5HTt2zM062XDsv//+6aGHHkr//ve/U9++fdPjjz++yl0zWFt77rlnuuaaa1a7PDL0Yp2W4qWXXkoHH3zwGrNM//Wvf6WWJJpdDxkyZLXLjznmmBaTiVZt5d11113X2GQzmhHtsssuqSWptjJX0/lQjeWttvOh2spbjedEWY8ePVrMKMu1r1JpNfbbb78ceIo/gvrEhUZLOQlpeu973/tye+boV6qmaIIQ50EEp9iw7LzzzvlHNJrWhD//+c+5KWfNwRAiuM2GZYsttsj9DUaTzkGDBmnSy3q74oor0pFHHpn7rRs8eHBu1hB1kHnz5qVp06alF154If3v//5viwuiRbmrIYhW8yJuxIgRVXERV03lvfjii3O/Z9OnT6/3/I2mOfF92ZJUW5mr6XyoxvJW2/lQbeWtxnOiZn+i0Uwymq3HdUFz0qdUKxWdiC5ZsiR99KMfrXd5LIsgRWTJsGH0FxPnxOoq/tGf0I9+9KOcRceGIT7vuEMSF4v1iT6loq+x6GOIDdM///nPnDl1+OGHp80337y5i0MVe/7559PVV1+dZs6cmS8sQteuXdOBBx6YzjjjjGavDNcUF0LxvbjTTjutMYj2oQ99KLUUkRkfF3FR3jVdxK3pTn6Rqq28cdPmyiuvzP/XPX+j8+X4v6WppjJX2/lQbeWttvOhGstbjedE2GqrrdJbb72V+x2OjtmjH9GaorP5oghKAQBAFQbRqvUirtrKS9OqtvOh2spL06vGc2Ly5MlrXH7KKacUVhZBKQAAAAAKp6NzAACaRdyJ/fCHP+zoU5W+9rWvpc9//vOpmlRjmWk61XY+VFt5q2lQrEWLFtWaiiQoBQBAs+jevXvuv6laVGMQrdou4qqpvDFaYzT3rCbVVuZqOh+qsbzVdj5UW3lb8jmxZMmSdNZZZ6Xtt98+D3QTfUzVnIpk9D2gRRo4cGDae++988gQjem+++5Lhx56aFqwYEHacsstUxHix7Nnz57pkUceyfsEwP8biKPagmgbbVRd93TjIi5GVK0W1VTed+uTpSWqtjJX0/lQjeWttvOh2srbks+JESNGpHvvvTf98Ic/TCeffHL6wQ9+kMsao/FdeumlhZZFn1JAiw9KRaeyw4cPz9P6EpQCKH4kx+g4fMaMGbkD2BiVKEYn6t+/f/rSl76UdthhBx8JABRoxx13TDfeeGO+5urUqVN6+OGH03vf+9704x//OP3sZz9b7ajtTUGmFAAATeKPf/xjOuKII1KPHj0qw2WXSqU0f/789Otf/zp9//vfT3fccUc66KCDWuQnEFm1cWf+mWeeSd26dcvN92Jf2HBEE5cpU6asElSNc/b4449Pm2++eWrJ/vOf/6Tbb7+9cg5/8pOfbPFlpnFV8zns/G06r7/+em7JESIoFc/DwQcfnG8YFUmmFNCiM6UeffTRNH369FrL4oLmhRdeyO2g44Jn+fLlOZvq8ssvTx/72MfWOlMqfqQvvPDCNGvWrLTtttvmCls0KYkf6ZEjR+bU1hgavKY+ffrk9S666KL8fNKkSWn8+PFpzpw5uSxnn312GjZsWF6m+R6wodp///1zBfe73/1uvcvPPffc/D0e378tpXne448/nrbZZpv8fR7ZXGGvvfZKTz31VFq8eHH+PXjf+96XWhIXnU3jySefTIMGDUpvvfVWGjBgQL6QLwdVo24S9YSpU6emPfbYI7UUcc5GhkPUcf7973+nww47LD399NO577ZoQhT9x0S95z3veU9qKZy/TafazuFqPH+r9Rzu06dPvjEU50XcMIrn3/nOd9L3vve9fE0TWc6FKQG0QAMGDCidc845pddee620ww47lC6++OLSyy+/nKdw5JFHlgYNGlR67LHHSv/4xz9Kv/3tb0vTp09/1+3ee++9pfjqW7BgQX4er99iiy1K3/3ud0t///vfS3/6059K++yzT+nUU0/Nyx9//PG8/rPPPlvZxhNPPJHnPf300/n5NddcU+rWrVvp5ptvLj333HP5/6233rp0ww035OVz5szJ6z/yyCNNcqwAWqrNNtus9Le//W21y5966qm8TkvRpk2b0iuvvJIfH3fccaWBAweWlixZkp+//fbbpY9//OOlT3/606WWZPbs2aXu3buXttxyy9LRRx9d+q//+q/Saaedlh/HvPe85z15nZbiwAMPrPwGz58/v7TXXnuVNt1001KvXr3yubDjjjuW/vnPf5Zagvj84zxYtmzZKsti3vHHH5/XaUlqnsNxHuy9996VutOrr75a6t+/f+nzn/98qaVw/jatajuHq+38rcZzuGzChAmlK6+8Mj++5557Su3bt8/fxRtttFFp4sSJpSIJSgEtOigVdtpppxw0qikqsaNHj17r7dYNSp100kn5x6OmP/zhD/kLeenSpfl5nz59clCsbOTIkaX999+/8rxHjx6lKVOm1NrGt7/97VzxDoJSwIaqZ8+epeuvv361y2NZrNMSL4iiXHfffXet5TNnzsw3SloSF51NJy7S1nQxGTeuYp2WpOY5vNtuu5V+97vfrVIP2nnnnUsthfO3aVXbOVxt5281nsOr88ILL+Qb648++mipaPqUAqpSNI+L9s6Rcnz44YenT33qUzntdG099NBD6dlnn00//elPK/MiYL9y5crcdOP9739/OuGEE9L111+fvvGNb+Rl0flfudP1SC2OdOIvfOEL6bTTTqts45133kmdO3dupL0FqE4XXHBBOuOMM/J3bTQhieYM0awhmjdMmzYt/c///E+jj7K6vqJ8YdmyZbm8NcXz+N5vSf7yl7+kBx98MG266aarLIt5MRz5Bz/4wdQSRfOhCRMmpK5du+bn0WzykksuSZ/73OdSSxDDokdfTKtr2hT1h6KHTl+bc/iNN96o9BlTFs9ffvnl1FI4f5tWNZ7D1XT+Vvs5fPfdd+cpmnPGtU9Nce1TFEEpoCp98YtfTB/5yEdy550RmIo+oK644or05S9/ea22E1/Ap59+eg5y1TcqRRg6dGjucypGpVi6dGkOQh133HGV14drr7029evXr9brN9544/XYQ4DqF33rRaAh+pSKYaZXrFhR+X7cb7/98sg/xx57bGpJog+Ttm3bpkWLFqW///3vac8996wse/HFF3Pfgy2Ji86mEzebonP7r3/96/UGVceOHdsoIwM3tlNPPTW1a9cudxIdfXDWDEjEBX25T82WwPnbtKrxHK6m87daz+EQ/eJefPHFqW/fvnkQhHIwsDkISgEtXtxlKF/I1BQjIMUd+JiiQ/IIDK1tUGrfffdNs2fPzkOgrk4MV37IIYfkbKoISkVmVvnuefwfnS0+99xzOaMKgNo++9nP5ikuMF599dU8LwI7m2yySYs7VN/61rdqPe/QoUOt57/97W/Thz70odSSuOhsOqNHj07t27fP2VwjRoyoXLRF1nRkd8UNq5jfkkQAouzoo49Ob775Zq3lN998cx5IpqVw/jatajuHq+38rdZzOPzoRz9KN9xwQzrppJNSczP6HtCiR9+LZh0xIkT8oP7whz/Md07iYia+3GOY8d122y2PpBdN+WLU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xClvf8CAAbnp24MPPpjuvPPO9Morr6Rjjz22so2vfOUrefux7alTp+YyPPTQQ426n9/61rdyWR9++OGcrRT7PGLEiBxoKgeLvvnNb9b72ljnwAMPTKeddlren5h69OjRoPeN9xg3blw+hn369ElvvvlmDtBFIOqRRx7JAaajjjoqvfjii5VmgnEcy0G7OI7bbrtt5Xi+8847acaMGfmYAsWQ3wgAANAEIsASgY4IRO200055Xs1MnU033TRdf/31qUOHDmnPPfdMF198cQ4iffvb305Lly5NEyZMSPfcc08O2oTImPrjH/+Y/vu//zsHTiJYte+++6axY8dWthnbi6BOZCt17949XXfddenGG29MgwYNyssnT56cdthhh0bdzwsuuCAHgMI555yTg1IRcDvooIPyvC984QvphhtuWG1TvjgOcQzWtmlgHK/yfoXIRItssrIxY8bkYNxtt92WzjrrrNS7d++8TgShPvWpT+UA3fnnn5+++93v5vUju+vtt99OBx988DodB2DtCUoBAAA0gQiQHHbYYTkQFUGbwYMHp09/+tOVjsJjeQRjyiL4FNk+c+fOTfPnz88BkppBlxDN+/bZZ5/8ODKeIgsqmqrVFdlJEdiK9ctBrbD11lun3XffvVH3M7KUyqLpXN3gW8yL/Wls0XSvpmiqGJlmv/vd79K//vWvHBCMY1DOlIqmeoccckgORsXnEllTZ5xxRvrOd75TyWSLIF99xxNoGoJSAAAATWDjjTdO06ZNy03Coulc9Gk0atSo9Je//GWNr4vgycqVK/Pj22+/Pb3nPe+ptTz6UAqxTjRPu+yyy1bZRvQf9cwzz6QibLLJJrXKXt+88v40ps0337zW88gyi36mIsj03ve+N/dxFUHAmv10RRO+a665JjcrjKDglltumQNVkT0VQalYDhRHUAoAAKCJREAmmrHFFP0qRTO+aFIW/vrXv+ZMngiehJkzZ+YsnWheF9lUEXyKLJ/V9XEUWT0333xz2nnnnesdeS4CMxEciu3uuOOOed6CBQty076W1G9SNN+L0fPWVwSaouP0T37yk/l5ZJ3V7TQ9gk7RxDA6jC8HoOJYRD9UETyMZUBxdHQOAADQBCIjKvp7ik7II7h0yy235FHo3v/+9+flkcET/S3FCHp33HFH7jA8+j7aaKONUseOHXNfTdG5efQDFc3xovPuGCkunoczzzwzvf7667kPpwceeCA999xzOSMrOlaPIE8EuGL7kUEUfTw98cQTOWgT229JIqgWxyoCSNEJ+bpmVUUQLo7xo48+mgN+Q4cOXWVb5X6lfvrTn1aCUvF/jMQXAUL9SUGxWta3EQAAQCvRqVOndP/99+cR4Xbbbbc8Qt0VV1yRjjjiiLw8+jXq1atXbj4WI+ZFU7zRo0dXXh8dnkd2VYwwF4Gs6Jfqt7/9berZs2deHh2Z/+lPf8oBqFgWAZfI9InOw8uBp8svvzxv/xOf+EQ6/PDDc9Blv/32Sy1JBN+iqeMee+yRtttuu0ofUGsrOiyPDLP+/fvnYxnHJLLJ6maulbPEPvShD1X6xIpjFn11xWcGFKdNqTweKQAAAIWIjKU33ngjZ+gAbKhkSgEAAABQOEEpAACADVB0DB79Tq1uai5nnHHGassUy4DWQ/M9AACADVB07P3SSy+tsePw5jB//vy0aNGiepdFn0/bb7994WUCmoagFAAAAACF03wPAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QqkrdcMMNqU2bNpWpbdu2aYcddkif+9zn0ksvvZSq3ZNPPplGjx6dnn/++Ubf9t1335369u2bNt9883zsfv3rX6eW6r777stljP+LNmXKlDRx4sTUksQ5Ecfj1VdfLew9Bw4cmKeyt956K5ejvs+kOcq3vuJvLMr8ne98J7UW1bZPr7/+ejruuOPS9ttvn8t9zDHHNPh8BFoG9bJ1p17WMOpl/0e9rHUq16Hfzamnnpp23nnnWvPiecxvTHW3+a9//SuX8dFHH23U9+H/tP3//6dKTZo0Kb3vfe9LS5cuTffff38aN25cmj59enr88cdz0KWag1IXXXRR/uGp+8WzPkqlUjr22GPTbrvtlm677bZ8jHbfffdG235rEpWfJ554Ig0fPjxtyH74wx/Weh5BqTg3g+AAjeHb3/52uvXWW9P111+fdt1117T11ls7sFCl1MvWjnpZw6mX/R/1MuqKOlSnTp2adJsRlIr6f1yX7r333j6ERiYoVeV69+6ds37CoYcemlasWJEvcCL754QTTlivbcfFd4cOHVJrEl8okZXwyU9+Mh122GFr/fr//Oc/lcw0ihNB180226xZDvkee+zRLO9Ly9dY3wcR/I1g1Pp+ZwPNT71s7aiXVSf1MlqSffbZpyq2yeppvtfKHHDAAfn/F154oXIHKu4oRES3ffv2aauttkqf/vSn03PPPVfrdZHxERWpyLbq379/DkZ9/vOfz8veeOONdP7556dddtkltWvXLjcx+djHPpb+9re/VV6/fPnyNGbMmJy1Fetst912uSnhv//971rvE9Hlj3/84+nOO+9M++67by5TvCYyBGqmwH/mM5+pBNrKTRRj/pr88Y9/zIGmjh075vLHftx+++2V5ZFyGU0cw1e/+tW8zTVlYZWbzv34xz/O+/+e97wn79uzzz6bl//+97/P7xdR9Hi/gw46KKeg1xTrxnHo1atXXie2cdRRR+VMtrrieH70ox/N62277bbpjDPOSIsXL17jPtfctyjr7Nmz0/HHH586d+6cunTpkj/DhQsX1lq3IedE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oIrcdtttqW/fvukzn/lM2n777dM+++yTrr322sryOXPmpHnz5qXBgwdX5rVr1y4NGDAgzZgxY7XbXbZsWVq0aFGtCQCgKcmUoqrtfOHthb3X85ceWdh7AcDqPPfcc+nqq69O5513Xvra176WHnjggXT22WfnwNPJJ5+cA1IhMqNqiucvvPDCarc7bty4dNFFFznwVJ0i64NrQ90R4N3JlAIAqCIrV65M++67bxo7dmzOkormeKeddloOVNXUpk2bWs+jWV/deTWNHDkyLVy4sDLNnTu3yfYBACAISgEAVJFu3bqlPfbYo9a897///enFF1/Mj6NT81DOmCqbP3/+KtlTNUWmVadOnWpNAABNSVAKAKCKxMh7Tz/9dK15f//739NOO+2UH/fs2TMHpqZNm1ZZvnz58jR9+vTUv3//wssLALA6+pQCAKgi5557bg4uRfO9Y489Nvcpdc011+QpRBO94cOH5+W9evXKUzzu0KFDGjp0aHMXHwCgQlAKAKCK7L///unWW2/NfUBdfPHFOTNq4sSJ6YQTTqisM2LEiLR06dI0bNiwtGDBgtSvX780derU1LFjx2YtOwBATYJSAABV5uMf/3ieVieypUaPHp0nAICWSp9SAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAAAbXlDqpZdeSieeeGLaZpttUocOHdLee++dHnroocryUqmURo8enbp3757at2+fBg4cmGbPnt2sZQYAAACgioNSCxYsSAcddFDaZJNN0h133JGefPLJdMUVV6Qtt9yyss748ePThAkT0lVXXZVmzZqVunbtmgYNGpQWL17cnEUHAAAAYD20Tc3osssuSz169EiTJk2qzNt5551rZUlNnDgxjRo1Kg0ZMiTPmzx5curSpUuaMmVKOv3005ul3AAAAABUcabUbbfdlvr27Zs+85nPpO233z7ts88+6dprr60snzNnTpo3b14aPHhwZV67du3SgAED0owZM+rd5rJly9KiRYtqTQAAAAC0LM0alHruuefS1VdfnXr16pXuuuuudMYZZ6Szzz473XjjjXl5BKRCZEbVFM/Ly+oaN25c6ty5c2WKTCwAAAAAWpZmDUqtXLky7bvvvmns2LE5Syqa45122mk5UFVTmzZtaj2PZn1155WNHDkyLVy4sDLNnTu3SfcBAAAAgCoLSnXr1i3tsccetea9//3vTy+++GJ+HJ2ah7pZUfPnz18le6pm875OnTrVmgAAAABoWZo1KBUj7z399NO15v39739PO+20U37cs2fPHJiaNm1aZfny5cvT9OnTU//+/QsvLwAAAACtYPS9c889NweXovnesccemx544IF0zTXX5ClEE73hw4fn5dHvVEzxuEOHDmno0KHNWXQAAAAAqjUotf/++6dbb7019wN18cUX58yoiRMnphNOOKGyzogRI9LSpUvTsGHD0oIFC1K/fv3S1KlTU8eOHZuz6AAAAABUa1AqfPzjH8/T6kS21OjRo/MEAAAAQOvQrH1KAQAAALBhEpQCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgCgiowePTq1adOm1tS1a9fK8lKplNfp3r17at++fRo4cGCaPXt2s5YZAKA+glIAAFVmzz33TC+//HJlevzxxyvLxo8fnyZMmJCuuuqqNGvWrBywGjRoUFq8eHGzlhkAoK62q8wBAKBFa9u2ba3sqJpZUhMnTkyjRo1KQ4YMyfMmT56cunTpkqZMmZJOP/301W5z2bJleSpbtGhRE5UeAOD/yJQCAKgyzzzzTG6e17Nnz3Tcccel5557Ls+fM2dOmjdvXho8eHBl3Xbt2qUBAwakGTNmrHGb48aNS507d65MPXr0aPL9AAA2bIJSAABVpF+/funGG29Md911V7r22mtzEKp///7ptddey49DZEbVFM/Ly1Zn5MiRaeHChZVp7ty5TbofAACa7wEAVJEjjjii8nivvfZKBx54YNp1111zM70DDjggz4/Oz+s266s7r67IqIoJAKAoMqUAAKrY5ptvnoNT0aSv3M9U3ayo+fPnr5I9BQDQ3ASlAACqWHRO/tRTT6Vu3brlPqYiMDVt2rTK8uXLl6fp06fnJn4AAC2J5nsAAFXkggsuSEcddVTacccdcwbUmDFj8kh5p5xySm6iN3z48DR27NjUq1evPMXjDh06pKFDhzZ30QEAahGUAgCoIv/85z/T8ccfn1599dW03Xbb5X6kZs6cmXbaaae8fMSIEWnp0qVp2LBhacGCBblj9KlTp6aOHTs2d9EBAGoRlAIAqCI33XTTGpdHttTo0aPzBADQkulTCgAAAIDCCUoBAAAAUDhBKQAAAAA2rKBU9HUQ/R7UnGIY47JSqZTX6d69e2rfvn0aOHBgmj17dnMWGQAAAIDWkCm15557ppdffrkyPf7445Vl48ePTxMmTEhXXXVVmjVrVg5YDRo0KC1evLhZywwAAABAlQel2rZtm4NN5SmGNi5nSU2cODGNGjUqDRkyJPXu3TtNnjw5vfXWW2nKlCnNXWwAAAAAqjko9cwzz+TmeT179kzHHXdceu655/L8OXPmpHnz5qXBgwdX1m3Xrl0aMGBAmjFjxmq3t2zZsrRo0aJaEwAAAAAtS7MGpfr165duvPHGdNddd6Vrr702B6H69++fXnvttfw4dOnSpdZr4nl5WX3GjRuXOnfuXJl69OjR5PsBAAAAQBUFpY444oj0qU99Ku21117p8MMPT7fffnueH830yqLz85qiWV/deTWNHDkyLVy4sDLNnTu3CfcAAAAAgKpsvlfT5ptvngNU0aSvPApf3ayo+fPnr5I9VVM08evUqVOtCQAAAICWpUUFpaI/qKeeeip169Yt9zEVgalp06ZVli9fvjxNnz49N/EDAAAAoHq1bc43v+CCC9JRRx2Vdtxxx5wBNWbMmNwx+SmnnJKb6A0fPjyNHTs29erVK0/xuEOHDmno0KHNWWwAAAAAqjko9c9//jMdf/zx6dVXX03bbbddOuCAA9LMmTPTTjvtlJePGDEiLV26NA0bNiwtWLAgd4w+derU1LFjx+YsNgAAAADVHJS66aab1rg8sqVGjx6dJwAAAABajxbVpxQAAAAAGwZBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAVWzcuHGpTZs2afjw4ZV5pVIpjR49OnXv3j21b98+DRw4MM2ePbtZywkAUJegFABAlZo1a1a65pprUp8+fWrNHz9+fJowYUK66qqr8jpdu3ZNgwYNSosXL262sgIA1CUoBQBQhd588810wgknpGuvvTZttdVWtbKkJk6cmEaNGpWGDBmSevfunSZPnpzeeuutNGXKlGYtMwBATYJSAABV6Mwzz0xHHnlkOvzww2vNnzNnTpo3b14aPHhwZV67du3SgAED0owZM1a7vWXLlqVFixbVmgAAmlLbJt06AACN7qabbkoPP/xwbppXVwSkQpcuXWrNj+cvvPDCGvumuuiii3xaAEBhZEoBAFSRuXPnpnPOOSf95Cc/SZttttlq14vOz2uKZn1159U0cuTItHDhwsoU7wMA0JRkSgEAVJGHHnoozZ8/P+23336VeStWrEj3339/7tj86aefrmRMdevWrbJOvKZu9lRN0cQvJgCAosiUAgCoIocddlh6/PHH06OPPlqZ+vbtmzs9j8e77LJLHm1v2rRpldcsX748TZ8+PfXv379Zyw4AUJNMKQCAKtKxY8c8ol5Nm2++edpmm20q84cPH57Gjh2bevXqlad43KFDhzR06NBmKjUAwKoEpQAAWpkRI0akpUuXpmHDhqUFCxakfv36palTp+aAFgBASyEoBQBQ5e67775az6ND89GjR+cJAKCl0qcUAAAAABtuUGrcuHH5rl70gVBz6OK4w9e9e/fUvn37NHDgwDR79uxmLScAAAAArSQoNWvWrHTNNdekPn361Jo/fvz4NGHChDy8cawTI8kMGjQoLV68uNnKCgAAAEArCEq9+eabeQjja6+9Nm211Va1sqQmTpyYRo0alYYMGZJHk5k8eXJ666230pQpU1a7vWXLlqVFixbVmgAAAABoBUGpXXbZJb322murzH/jjTfysrVx5plnpiOPPDIdfvjhtebPmTMnzZs3Lw0ePLgyr127dmnAgAFpxowZa2wG2Llz58rUo0ePtSoPAEBTacw6FADABhmUev7559OKFSvqzVJ66aWXGrydm266KT388MM5kFRXBKRCly5das2P5+Vl9Rk5cmRauHBhZZo7d26DywMA0JQaqw4FANAatF2blW+77bbK47vuuitnIpVFBevuu+9OO++8c4O2FcGic845J02dOjVtttlmq10vOj+vKZr11Z1XU2RTxQQA0FI0Zh0KAGCDDEodc8wx+f8ICp1yyim1lm2yySa5MnXFFVc0aFsPPfRQmj9/ftpvv/1qVcruv//+3LH5008/nedFVlS3bt0q68Rr6mZPAQC0ZI1ZhwIA2CCDUitXrsz/9+zZM4+Gt+22267zGx922GHp8ccfrzXvc5/7XHrf+96XvvrVr+Z+FWK0vWnTpqV99tknL1++fHmaPn16uuyyy9b5fQEAitaYdSgA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pf333z917Ngxbb/99umYY45JTz/9dK11SqVSGj16dOrevXtq3759GjhwYJo9e3azlRkAoD6CUgAAVWT69OnpzDPPTDNnzkzTpk1L77zzTho8eHBasmRJZZ3x48enCRMmpKuuuirNmjUrde3aNQ0aNCgtXry4WcsOAFBT21rPAABo0e68885azydNmpQzph566KF0yCGH5CypiRMnplGjRqUhQ4bkdSZPnpy6dOmSpkyZkk4//fRmKjkAQG0ypQAAqtjChQvz/1tvvXX+f86cOWnevHk5e6qsXbt2acCAAWnGjBmr3c6yZcvSokWLak0AAE1JUAoAoEpFVtR5552XDj744NS7d+88LwJSITKjaorn5WWr66uqc+fOlalHjx5NXHoAYEMnKAUAUKXOOuus9Nhjj6Wf/exnqyxr06bNKgGsuvNqGjlyZM66Kk9z585tkjIDALSIoJTRYwAA1s2Xv/zldNttt6V777037bDDDpX50al5qJsVNX/+/FWyp2qKJn6dOnWqNQEAtNqglNFjAADWTmQ8RYbULbfcku65557Us2fPWsvjeQSmYmS+suXLl+d6V//+/R1uAKDFaNvaRo+JTjpjKtNJJwDQmpx55pm5HvSb3/wmdezYsZIRFf1AtW/fPjfRGz58eBo7dmzq1atXnuJxhw4d0tChQ5u7+AAALbNPqcYYPUYnnQBAa3b11VfnOtPAgQNTt27dKtPPf/7zyjojRozIgalhw4alvn37ppdeeilNnTo1B7EAAFqKZs2UWp/RY1544YXVdtIZ26mZKWX0GACgtYg607uJbKnRo0fnCQCgpWoxQany6DF//OMf12v0mMikigkAAACAlmuj1jh6DAAAAAAtW7MGpYweAwAAALBhatbme0aPAQAAANgwtW3u0WNCjB5T06RJk9Kpp55aGT1m6dKlefSYBQsWpH79+hk9BgAAAKDKNWtQyugxAAAAABumFtHROQAAAAAbFkEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFK5t8W9Jc9n5wtsLe6/nLz2ysPcCAAAAqo9MKQAAAAAK9/+xdx9gTlRfH8cPvffem1ioUhQBFRDBggqif0WQbqEoIBZARYoURUVUBESkWMAKiiIISrEg0rsVaSJFAemdvM/v+iYm2V3YXZa0/X6eJ5CdZLOT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KQAAAAAAAMSWiK4pBQAAAAAAgNhEUAoAAAAAAAAhR1AKAAAAAAAAIUdQCgAAAAAAACFHUApARGIOBgAAAESjkydP2qRJk2zHjh3hXpWoMH/+/HCvAsKI2feS6Y8//rDRo0fbwoUL3cEmTZo0VqhQIatTp4516tTJSpQokbJbCkhlMmbMaKtWrbJLLrkk3KsCAAiTEydO2EUXXWSfffaZVahQge0AhNj06dMT/dxbbrnlvK5LtMmaNav9+OOPVqpUqXCvSsTLnDmzFStWzNq3b29t27blXDoePXv2tMQaPny4RZP04V6BaPTtt9/aDTfc4D4sjRs3djdldezatcs+/vhje+WVV2zmzJlWt25diyVbt261fv362fjx4y2aHDlyxJYtW2Z58+aN06E9evSovf/++9amTRuLJvqCW7RokdWuXdsuvvhi++mnn+yll16yY8eO2d13323XXHONRfsB9tSpU/bMM89Yvnz5ovLgGmzv3r3uitmvv/5qRYoUicov3BUrVlju3LmtTJky7ue3337bBee3bNniOlwPPPCAtWjRwqLJgw8+aHfccYddddVVFkv0PbR06VJr0qSJe39vvfWWDR061E6fPm3Nmze3gQMHWvr0dAEQ+TJkyOC+23TxD8mjvo5O+IDkaNasWaKep8+o+m74T61atWzlypUEpRLhzz//dP3KiRMnWv/+/a1hw4bWsWNHt//pQjXM9cMT+1mMNmRKJcNll11mV155pb344ovxPv7QQw+5wNWSJUsslihrpXr16lH1hfPLL7+4oKFOmvUB1YnnlClTXFBAdu7caUWLFo2q9zRr1ixr2rSpZc+e3Q4fPmzTpk1zQbWqVau64OiCBQvsiy++iJrAVNq0ad26K9jhT++jZs2ali1bNrft5s6da9FE+9WaNWtcUG3jxo0ui1IqV67sgooHDhxwgUUFFaOFPv8vvPCCNWjQwMaNG2fdunWze++912Wz/fzzz26ZgqMdOnSwaKH9T/tXuXLlXOdHwcLChQtbNHv66aftueeec8e+7777znr06OF+1neT3q++uzp37mwDBgywaHPo0CGbPHlynCxlXQS666673PECsUcXKHTxRccYgqmJowD04MGDbcyYMa6vo/5Q2bJlrW/fvla6dGl3vEvNqlWrlugTt+XLl5/39UFs+uCDD6x3797u+7dGjRpxvqOqVKkStnWLZArkKQlC52w6lrVq1cods3S+gNhEUCoZsmTJ4j4sSiePjzpO+rJThk4spef+/vvv9vDDD0dVAOfWW291Y7onTJhg//zzj8vKWbt2rRu3XLJkyagMSim4oYDToEGD7N1337UuXbq4E0x1PuWJJ55wAdHZs2dbNFD2xuuvv+5ONvwDabo6rkBotA7X0Mm/TpoLFizoTpZ1f8aMGS6VW1f9b7/9dnflWh2WaKHOlAJq+uwoQKWhyvfdd5/vcQULtB+uW7fOomk7zZkzxz799FN75513bN++fS4TVsG2G2+80T0ebRRgUxBKGVH6DKkjrCw9depEgezHHnvMZe1Fk/Xr11ujRo1cML5evXouGOXNUlYQW/unjnvReszAmb/Lv/rqK3cxRoH94BO7qVOn0nxBlA2pz73+1/FMfR8FpZQdrsD0999/n6rbLClBeY0SAJIjvj6EgqH67iKz7OyZU2PHjnUXJXQxQhmfGiGiQHvFihXZIWMMQalk8F5p0pjX+CgAoivVCuJEE2/GwJkKTEfbAVQnLV9++aXrxHp17drV1aaYN2+e69hGW1AqV65cbjjiBRdc4K4eZMqUyX744QcXJBB1PK+99tqoKqyoIJqGHd58880uSKWAVCwFpXTMCA66aZspMKVhsdEif/78LgtPQQ59thQA8L9qtWHDBvdZU9AgGreTatcoYKOrczpu6D22a9fOHev1eYsWCnzq4oiCh6K0d6V8eztxmzdvdp8rZR1FE2XoKYtNJ9rBqfzHjx9322r79u3u2I7YklB/y7/fhUA6Zr322mtuCEyOHDnc96m+i3Rs0ImdhpQDyaHvDl0I0CgEHXv9KYMa/9H37ZlQayqQ+mGffPKJ64fpgqFGTChDShd39+zZY7169XKJIbpIBXPnT7q4Hd9nMdou1lBQIhkeeeQRlyGgwICu2urERcEandjoA6STzxEjRli00ZC2V199NcGx4zoI6GQ0mihbLTjVX+9RJ6K60q7Mjmim96FsG/+hb+p8Ktsj2obE6vOkgKG+gDSmPBrHQwfzvgdlRuk44U8///XXXxZNlEGkGlI6xunz8+GHHwYEpXQFPpqCN8EUCFX9Jd30Ba9OkWob6CpdNAWuFbhRh01BKWVDad31szcopUw2BeGijQK5qpMVX20JLXv88cft8ssvD8u64fwi6JR027Zti/d4rItZOvEDkkMXOJRFrItPCk6pXuvff//tLoboe4WgVCCCTkmr8anheqIL1cOGDbNKlSr5HlcigfpjGn4Mc6NlVL5FpRoUf9D/6vMpHqHs4mhDUCoZNFxKdWKU/qyrUN6TlXTp0rmgzZtvvulOaqKN1l3j5hMKSp0tiyoSqV6PTmKCZ3BTEWC9l2icJUQH499++83X2VQKvjcjQpR5462ZFU00LEMZEDrIKtgbTUGAhOgKtYKi+/fvd/U8/NONFfRQ5lE0efbZZ13tHgWkFDxUfSkNhfXWlFKNLGUaxQJ9plRoU8M2lDUVTVq2bOk6Kqo9pyFPurKoiym7d+92x3ENsVSWXrTJkyeP63AllD2p46Keg9ilQL6ONdqPL7zwQitQoEC4Vyli6fvmm2++iXNSrKvqKjGB/6i/oT69LqzEl3GgDA38S7WRlNWuC1S6IKrvfV3QURChe/fuNFM8NNGIhpypvqj67PpMKnlBk8boexr/0sUznZ/ddtttCRY21+gWsqH/NWTIEHfc0gV9JSSopqv2qfvvvz8qzwN1Yo5zcPz4cc+ff/7pbrofzb7++mvPzJkzE3z84MGDnvnz53uiyZAhQzw33HBDgo937tzZkyaNG8UaNUaPHu357LPPEnz88ccf93Ts2NETzbZu3er5+OOP3T4Xrfr37x9wmzVrVsDjjzzyiKdFixaeaLN3715Pr169PBUqVPBkzpzZkzFjRk+pUqU8LVu29CxZssQTbUqXLu35+++/PbHk5MmTnkGDBnluuukmzzPPPOOWTZkyxVOiRAlPvnz5PO3atYvKz1a/fv08uXLl8jz33HOelStXerZv3+7ZsWOHu69lefLk8QwYMCDcq4nzQPtr+/btPenSpXPf2bqlT5/e06FDB8+hQ4do83hMnz7dfV50DMiaNav7jNxzzz3umD179mzazE/fvn09RYoUcW2k77Wnn37a9aN0vHzppZdoKz/ap3766Sff/fXr17v7ixYt8lx00UW0VZBRo0Z58ufP776Ts2TJ4tmwYYNbPmHCBE/9+vVpLyRb1qxZPRs3bnT3daxavXq1u6/PZOHChaOuZakpBQAAoiZbT1cDvTPvibJeNWRRswyqgDtij678KmNx5MiRLltTNMuxhgops1ZZG4hLNQB1NV3D4zVsT7Unn3rqKTfMA4GTQ7z88svWpEkTl3GgchXeZcoEivZSDylJ2Yma1VWZiprwSW103XXXuVpl2r+iqaZkKCizV59BjULxr+2m+q/169d3Qx8RN2MqvozFaBzdcj6VKFHCPv/8c1fLVaU0NMujam8pG+/666+PulIuDN8DAABRQUMRddMwCO9kDgpIKWUdseujjz5yNex0EuelujaaDVnlEghKxU/BAt1wZjqWeCfEUSkB78ncTTfd5CY2wn809FNlMRSU0uQTCnIqsKIhav6TCuFf+q6Kb7isJimKtslGzjdNEKZaSGvWrAkoGeO9ABULZT1S0lVXXeVqSelzp+9BDZ+dO3euW6byIdEm+ua6BgAAqZqCUJpBTDdvQEr19Dp06BDuVcN5oOyL4MkiRIWVycyIn7IxVEcu2D///OMew3+KFy/uZu4U1evUzLLema0UPMB/lPXjrVejmcZVY7dz5862a9cuGzt2LE0VRN9PyrwLNnPmzKidXfp8UVBF7bVz505XOF+Tsnz99deuhqnqlyKQModbtGjh7vfp08fVDlXbNW/e3N544w2LNgzfAwAAUU/DIjR8hKupsUdXfXXyq4lkNOOsd3bdtm3buiLU0TYZQahm51UGUPBMmzpp0UQOmhUW/9Kwl5w5c7oZPJWRpyEwmlRGQ4hU2FszfgHJnTlU2XaaGKZjx45u9uINGzbY0KFD3X1vUAHmJv9Rpk+VKlUsV65ctnjxYjdEVMsefvhhN/MjYhfD9wAAQMSbPn36WVP/EZs0U9UNN9zgMlpUO0PDOZR9oACV6iYh/s+J2kYnd14K2GpGTqZUD+QfdNLMpKrVorpJypqijg3ORfv27e3kyZOu3qGyOjU7brFixVxtRAJSgXR80vBZb4Dqzz//dEEpzVaoWVdhbjZvBdC998/E+7xoQaYUAACIiswP/zoT8dHjZErFJmVGvf32266gsvYBDX1p1aqVqyuFwM+JxPdZyZAhgwtIKWtD9ZKAxFAGqoKZefLkcfWRvDV+4rN8+XIaNQGqvaUJB4KzF/FfjSRlRKkovIJ3e/futSeffNINC9VkDSoOn9qlS5fODTXWPuTtEwXTcT8a+0JkSgEAgIinOiavvvqq67DGR5kzNWrUCPl64fxTXZE6derYvffeG7BcGQh67Oqrr2Yz/D+d9Ipqs6gmkjIOcGYaSqWaZcE16caPH29//fWXm1whNWvatKmvtlZCx1+cHZ/FM1MAylv8fdCgQS5wrkCVhm6/99577GJmbihj3rx5XVvMmzcvptqETCkAABDxNIzm0ksvtYEDByZYU0pX8b0n5YjNq8P+VMhby6LtijAii7LHJk+e7AKf/n744Qc3xEozqOHf4VXffvutq/mjrCmcnWq4qQC1Ms1UDD44e5Fj15mpZqD2tTNl56VGJ0+etMGDB7tAuoYbxwIypQAAQMR79NFHzziFtuq/xNqVQwQORwimoFS2bNlopgTo87JgwQJXsPv48eMBj3Xr1o12+38qCO+dUc5fgQIFfLPy4d/g8HXXXWc//vgjQalEateunfv8qdi59jGCKwmbM2eO1a1b18285+XNCkKg9OnT2/PPP+8m+4gVBKUAAEDEUxr/mSg4Ua9evZCtD84/TW0tOpHTyZ13CJE3w2D16tVxslvwL81UdeONN7riygpO6eRONW10wqfsMoJS//EWNteQR39aVrRoUXYpP5UrV3aTSgS3FeKnzLJvvvnGZfnizG677TY3K6iG4eu7vH79+i5I5S1+jriz0s6fP999N8YCglIAAACION6Z45QplSNHjoCi5hkzZrQrrrgiTp0p/Ouhhx6ym2++2UaPHm25c+e2RYsWuULnd999t3Xv3p1m8nPPPfdYjx497MSJE3bNNde4ZRpupRnTVHgZ/9GQIQ1He/rpp13wIDhTMdpm/ApFwPNMk3PgPypsvnjxYpfdqWCLakgePXrUFdpXgMp/lkyYm5G2T58+rgB8fJ/FaJs5lJpSAAAAiFgDBgxwwzf9h3XgzBSIUk0kTamu+99//71dcsklbpmGfGgWQ/xLQYPevXvbyy+/7BvmmDlzZlfg/KmnnqKZ4pndUfyHokXrjF/n2+zZs91sl6+99pqrXYbEU7BFQ9TeeecdVyuSfSvhz2KwaPwskikFAACAiNWmTRvbtm2blS9fPmD5r7/+6rJ/ONmLS+3iDRpoZjnVtVFQStlnuo//qJ2effZZV/dH9ZKUkad9zX+4KP5F3b6zCy7MreGz5cqVc0F1fS6DC3njX/rsebOk9L+CKldeeaUL6jE0P65Ym9SFoBQAAAAilmpmaJah4KCUsn7GjRvnTmIQSDNRLl261C688EJr0KCBy/hRTam33nrL1QVCXKpd4y1GTUAqfgQHzm7EiBF8vJKhYsWKbnIBDaVVgFg/I3E0zFHZndGM4XsAYoLGm6uQJJ0BAIgtqlOzfPlyN8Oiv99++81q1qxp//zzT9jWLVIpIHXgwAEXkPrrr7/ckD0VXVYbjh8/nsLLQRkHgwYNchkZBw8edMtUw0z1pJ544okzDpNJjVS4W8PRVPD8gw8+sGLFirlgp4qfK7MFSA4Fo77++mtbt26dOz6pX6+bJjmh2HlcyiQbMmSIjRkzxnbu3Gm//PKLlS1b1gX0lD3csWNHiyYcZQEAABCxlLmiAEuwffv2RV3djFBRsE4BKVH2weeff2779+93wT1mAgukwNPIkSNdIWXNWqg20sneK6+84k7w8J+PPvrIrrvuOjfEUe2k2dJEn0+1GQKlS5fOdu3aFadZdu/e7R7Df3RRWfuUAixPPvmkO7YrwzN//vxuUgvEnXRg4sSJNmzYMDfxh5cyYZVBHG0ISgFABPAWVwUABNKV8qFDhwYEoHRfy8jMiJ9mkYsvg0yBKe8Mc/jXpEmT3Elc586drUqVKla1alXr0qWLvf766+6kD/9RRpkyM9Q2/vWR6tSp4wIKCJTQzHsK5vkHEhCYuXjy5EnXL1Y7aVbMTZs20URB3nzzTRs7dqy1atUqIMCpY1g0TmRBUApAkimdtlu3bm665Lx581rhwoWtf//+7jF9ceiq9sqVK33PV8dYy7x1P/S/fv7iiy9c3QtdcVMnWVeTZs6c6YqxarjGXXfdZYcPH07WFnr77bfdlWKl4Gv9WrZsGXC1yrsOmvZZz1MBSnWqfv7554DX+fTTT91UqxqrrbRYzQKlL0svve+SJUu6+hNFixZ17ZIYSq1V5061UlR41jutuWb7UQ0QrY83DVdfyN6sAH3xLFu2zNfZUftfdtllvtedMmWKq4kBALFCV4Lnzp3rZpJr3769u+m+hno899xz4V69iKTvuPgudqj2iIZfIbDY9MUXXxynSbSMQtSB1Ee6+uqr47SV+mwMo/2PZnLUTf1MBTy9P+v24osvWteuXePd51Kz7t27u4BwwYIF7f7777c///zT7rvvPlu1apXt2LEj3KsXcbZt2xZnSLs3qOc9b4gmFDoHkOwriz179nSFZjXVtIIrdevWjVOI9kwU0FHKvAIwd9xxh7spuDN58mRX1+HWW2916fMK1CSVOuNPP/20O3FRMOqhhx5y66ghDMFp+6ojoeENnTp1csV0v/vuO/eYgmZ3332360ToSv2GDRvcF6T069fPPvzwQ9e5ePfdd11BRn1p6sszsXQypaCT0pS9FETTlVkFuNasWeOCVVqmAKCCVxp2oZMNBcpWr17tfkf/6+q3OoV6jEKkAGJJhQoV3HFO3xc6xupChmbke+CBB1xgHv/xfi/I+vXrA07mlF02a9YsVwMI/9GJsPYtfdf70zJlHeA/uuilWm7BM16qXpkupOFf6ht6Lx4qs8w/k0UZUmo/LUdgkEV9Xl34rlSpEk1zFjrv0AWGUqVKBSxXnTdd8I86HgBIonr16nmuvPLKgGWXXXaZp1evXp6NGzcqV9mzYsUK32N79+51y+bNm+d+1v/6+csvv/Q9Z+jQoW7Zhg0bfMvuv/9+z3XXXZfoderevXuCjy9evNi9/oEDBxJchxkzZrhlR44ccT9fddVVniFDhgS8zltvveUpUqSIu//CCy94LrzwQs/x48c9SVWqVClPs2bNzvq8YcOGeWrUqOH7uWfPnp6bbrrJ3R8xYoTn9ttv91SvXt2tu2h9Ro8eneT1AQBEvzRp0njSpk3rbroffMuaNavnjTfeCPdqRpT58+d7smXL5rnkkks8HTp08HTs2NHdz549u+frr78O9+pFlGeffdZToUIFz6JFizw5cuTwfPPNN563337bU6BAAc8rr7wS7tWLOPXr1/fs2bPHs2vXLs/ff/8d7tVBDJk+fbonV65cnmeeecYd15977jnPPffc48mYMaNn9uzZnmjD8D0AyRJ89VBXz+Ir5pjY1yhUqJBvyJr/sqS+ppeKlTZt2tRdQVCmka68yJYtWxJcB++wN+/f1DC5gQMHulk/vDddxdm+fbsbVvi///3Pjhw54tZZy6dNmxYwtO9sNGwwmLKvVCNFQw7195RJ5b/Oeh+6MqL03AULFvhmJ9F9XRHX7BtkSgGINTruKXNVw6x1RV0045cyNPCfjRs3uqxeZWgsXrzY/ey9qd2UVauMYPxH35n67lR2toagache8+bN3SxgEyZMoKn8KGu7WbNmroi+Mto1lO+ee+5xw62UuYj/aF9SOQqNIFCfTsPSVLRb7cRQx/hHYMyYMSNgX8udO7c75m/evJldK8jNN99s7733nhsBomGiKgr/448/urIjjRo1smjD8D0AyeJf4FJ0QFSgxDt1sn9xx4TGNvu/hn4/oddMqkOHDlnjxo3dTbWlNDRPgR3NGBNcYyN4HcT7N/W/akipcxpMNaZKlCjh6ivMmTPHvvzyS1cYVUPyFCAKfi/xyZYtW8DPixYtshYtWri/qXXVcD0NDdTwQi91ADXLjQqK6iRNQxS1Hpr1RkP71OlRJwgAYmnGr9atW7uCrvHN+BU8LDs18w7lSM53Z2qmIfOazcqfhorqRHn8+PFhW69IpHZS6QMND9V+puG1uoiG/yiwWbt2bRcI1nFL/TL1ixU0UIkG1TNduHCh5cmTh2b7fzqWjx492t1XWRANn9WMfJ999pkrwTF16lTaKojOFXSLBWRKAUhRCgCJsom8/Iueh4Jmnfj777/d9M6qBaViksnJuKpevboLOqmQYPDNG3xTbZNbbrnF1aJQPSd9kaoWVHKolpVOKNTZUxaVrq4FXx3y1pXSl7WCaOoM6j0qM0xf3GRJAYg1zPiVdGQd4HxQlp2CwcpsVz/l8ssvdwEpXQwkA+8/yrJX7ShlLb722mvWo0cPF1jRbGmqyaULl3oO/rN161Zf4e6PP/7Ybr/9dlfHVbOsMjlDXBqlsXv37jjLlYUXjfXdCEoBSFEK0lxxxRUuIKSraJodyb+QdyhoNjx1BlQk/ffff7fp06e7jKKkUiqsplxVQXal8esKl1Jlve9HV7veeOMNW7t2rfs7Gkqi9x9cdDCx9GWsjC5lR6kjo0CXhgQG03A9ZYApAKXAlK60KTildfMOUwSAWMGMX8nLOtD3kX/WgWYx1PAhnRwDyQ12qmxBMC1TfwnmC6o8//zzrgxFMA3l02cxvv5daqbgpjfIMnv2bLv22mt9IxPi2+dSu02bNrnJK4Ipk9g7xD2aMHwPQIpTqruumOkqmma/05evhtKFMltLAaPHH3/cBXaU8aTOgTKakkIpsco+0tUsvQdd2VLWleoniMa6K/imWQj1xVC5cmU3ljtfvnzJWm/VwNLJguoN6EulSZMmrqaUgmL+VMth+PDhAQEoBaiUkUamFIBYw4xfKZd1oFlyuXiBpFItMg0/002ZUgoUeKn/oyG0Kh8A840W0OxoCdHscv4zY8JcHST1rzVznGq8qQ8suigcPNtjajZ9+nTffc0SrhEU/p9FDQ2NxvZKo2rn4V4JAAAAID66KOCt7aMTF50Aa2izgvjKaKXAclwKEOiERSd4uqmt2rRp47Jwq1at6opUp3bx1YsMHgajGpHxZSOkNipZ4K27GR89pnqYKj8As2LFirnsdU1cEx8NR1MN0WjMaDlf9HnTSAQF1Dt37mzXX3+9W96vXz83+oF961/e8iHx0cVzBaRUi/amm26yaEJQCgAAABFNJyQvvviiHT161P2cKVMme+SRR5I1NDs1UHFl1VdUQGrKlCluaLiyeHWVXVnEGnae2rVv3z5Rz2MGPnPBOeUxXHPNNW7igbx58/raRwEDlS1QsXj8q2PHjq52lCbCUfv4Uya8MvHLlSvnSkAAyVGmTBlbunRpskdnRBqCUgAinjrTqpmUENWuUh2pSKErYDfccEOCj3OFGgCS7vDhw8z4lYSsAw3/1vcnWQdICSdPnnTDq7yz/iJhf/zxhythoeB5165dXekHb3911KhRLjClgALt+J9Zs2a5ulLe7LJXX33VXn/9ddf/131mKrSAWc1VFkVF9C+88EKLBQSlAERFR0gF/RKiVNX06SOnRJ4KMp4pJdtb5wMAgPPxnTl48GBX25GTXqSkHDlyuBmGo7FmTaht3LjRunTp4op2e6vlaJijhiBr4gH6goFUl/XZZ5+1G2+80e1jl112mavZOnfuXLvkkkvIWIynfu7ChQvdTN2xgKAUAAAAoqrej7+pU6ee13WJRso40BA9ggdISc2aNXO3du3a0bCJtHfvXvv111/dfQWi/Ic+Iv5jlib40f0PP/zQli9f7gJVFIYP9PDDD7saUppwKRZETmoBAAAAYBYwoxCSTtOpz58/n+ABUpRKE/Tp08cFDGrUqGHZsmULeDypsxynBhp2dvnll4d7NSKeam9piLZ8+eWXbmIGURBPsz8i0PHjx23cuHGubpmGigZ/FjVLdzQhUwoAAACIIao1omwDFTwneIBQzPyloWnMVIjkUkBTgZa6deu6umUa/qhZDDX8UTOs/vLLLzSunwYNGtiZzJs3z6IJQSkAAAAghhA8ABBNNCmDanBt3brVunXr5mYwlIceesgFO19++eVwryLOI4JSAAAAiCjVqlVzmReJoZojAMJn9+7d9tZbb1mPHj3YDECYnD592mbMmGFvvPGGffzxx1G1HagpBQAAgIiiYspIGUePHrXMmTPTnEhRmlFOQ6t0AvzJJ59Yzpw5CUrhnGzYsMHNsqf/X3rpJStYsKDNmjXLzSJasWJFWjcBKqQ/fvx4mzRpkiusf91111m0IVMKAAAAiCEa7jJkyBAbM2aM7dy509VjKVu2rPXt29fNbuUdGgMk1aZNm9wJ8MSJE23btm2ubpmKUqvGTbp06WhQJMuCBQtcIX3VlPr666/txx9/dMesYcOG2eLFi91MfPjPkSNH7P3333dB4UWLFrlj/osvvmgdOnRwMxlGm4Sr1QEAAAARYtmyZfb222/bO++8YytWrAj36kS0wYMHu6CBTug0q5VX5cqV3YxNQFIcO3bMpkyZYg0bNrRLLrnEzb6n2b1Uu6x3795utkcCUjgX2o8GDRrkZpPzP2Yp2Pn999/TuP9PAbr77rvPChcubCNHjrTbbrvN1eHSZ1Gfw2gMSAnD9wAAABCxdu3aZS1atLD58+db7ty53bChffv2uZOVd9991woUKBDuVYw4b775po0dO9YFETp16uRbXqVKFfvpp5/Cum6IPpoFrUKFCnb33Xe7jJU8efK45XfddVe4Vw0xYs2aNTZ58uQ4y3V8V80y/KtOnTr24IMPuuDURRddZLGCTCkAAABELHXA9+/fb+vWrbM9e/a4mhnK1NAyzdKEuDSs6oILLoi3EO6JEydoMiSJhgZp4gHdyIjC+aALDtu3b4+zXFmxCoriX9dcc40bsjdw4EBXb0sXaWIBQSkAAABELHW8R48e7YYNeSlr49VXX7WZM2eGdd0ilYoCf/PNN3GWf/DBB25mQyApFCzQkCEN4dOwIQ0ZmjZtWqJnyATOpmXLltarVy/bsWOH268UQP/uu+/skUcecTXL8C9NLqALNMqS6ty5sxUpUsS6d+/uHovmzyNBKQAAAEQsnZxkyJAhznIt02OIq1+/fvbAAw/Ys88+69po6tSpdu+997ri50899RRNhiTR7I0qaD537lw3zEoBYmUpnjx50tUvUx0gZVMByaX9qGTJki4r6uDBg+7Cw9VXX+2Gqz355JM0rB/NRqjj+MaNG+2tt95yQ9zTp09vTZs2tccff9yWL19u0YbZ9wAAABCx1NH+559/XJZG0aJF3TLvrF+qbaOMDcT1xRdfuCCUCsQrMFW9enV3ItO4cWOaC+dM+5T2MQ0l+vTTTy1Hjhz2999/07JIMg1B27Jli6sfpUwpBVW0fymrs3z58rRoImhYuyYC0cyYq1evjrogMUEpAAAARCzNLKTAlOpI6QqxhijoBEYzyX3yySdWvHjxcK8ikKr99ddfLmOjZ8+e4V4VRCEFoJSNp2FpBKHOnYJ6uggRTQhKAQAAIOJpiJBmjtNVdQ3t0PTXiF/ZsmVtyZIlli9fvoDlyjjTycrvv/9O0wGIqDp4yrq74oorwr0qCANqSgEAACDiqH6Ngk+aZU8aNWrkZuJTLZvLLrsswWLeMNu0aVO8wzeOHTvmhj4CQCQZNmyYPfrooy4jFqlP+nCvAAAAABBsxIgRrjh3zpw54zyWK1cuu//++2348OF21VVX0Xj/b/r06b62UL0ftZOXglRfffWVlS5dmvYCEFHuvvtuO3z4sFWtWtUyZsxoWbJkCXh8z549YVs3nH8M3wMAAEDEKVWqlM2aNcvN9BUfDeVT0W7Vl8K/0qb9dxCE6m5pmGPwbIUKSL3wwgt200030WQAIsakSZPO+Hjbtm1Dti4IPTKlAAAAEHF27tzpAikJ0RTYKrCMwILBUqZMGVdTKn/+/DQPUsSJEyfsoosuss8++8wNqwVSEkGnpOnfv7+1b9/eXbyJBdSUAgAAQMQpVqyYrVmzJsHHNe11kSJFQrpO0WLjxo0EpJCiFCBWTTJl4QHng4YYf/jhh/b000/boEGD7KOPPrKTJ0/S2PH49NNPrVy5ctawYUObPHmyHT161KIZw/cAAAAQcVTUfP78+S7jR9OF+zty5Ihdfvnl1qBBA3v55ZfDto6RTPWjdNu1a5cvg8pr/PjxYVsvRK9nnnnGDZsdN26cy1QEUooKnDdt2tR27NjhMvLkl19+sQIFCrhaeZUrV6ax47kwM2HCBBeUOn78uLVo0cI6dOjgJgKJNgSlAAAAEJHD96pXr27p0qWzBx54wJ2oKEvjxx9/tFdffdVdVV++fLkVKlQo3KsacQYMGGADBw60mjVrumyy4OyWadOmhW3dEL1uvfVWF+jMnj27CxJky5Yt4PGpU6eGbd0Q3a644gorWLCgqy2VJ08et2zv3r3Wrl07F1j//vvvw72KEevkyZMuc0oBKtVh1HflPffc49rOf7KLSEZQCgAAABFp8+bN1rlzZzeTnLdwtwIs1113nY0aNYqZ5BKgQJSmWG/dunUoNxdinGrYnIlOioHk0Gx7S5cutYoVK8bJoFLmj7JjET9lSelCgzJg586da3Xq1HEXdf788097/fXX7c4777RIR94lAAAAIpKKuH7++efuivlvv/3mAlPly5f3XUlHwicpOjEBUhJBJ5wvyu5RICU4KKUsqQsuuICGj8eyZcvcZ3LKlCmWKVMma9Omjcsi9raXZlrt1q1bVASlyJQCAAAAYkivXr3cEKu+ffuGe1UQgzTr5c8//+yyFi+88EJX9wc4F7r48Nhjj7lZ5TSUTxYtWuSGIauW2ZVXXul7bs6cOVN9Y1epUsUNZW/cuLHde++9dvPNN7uh7sGfUw1vD64pGIkISgEAAAAxpHv37vbmm2+6ExfdNHOav+HDh4dt3RC9Dh065CYg0L7lPdHVibAyNF555RXLmjVruFcRUSpt2rS++94aeP5Dtr0/677qCaZ2Tz/9tCtqrllqYwFBKQAAACCGaFbCM5k3b17I1gWx4/7777cvv/zSRo4caXXr1nXLvv32WzdEqFGjRjZ69OhwryKi1IIFCxL93Hr16llqduLECTfc8bPPPrMKFSpYLCAoBQAAAAA4o/z589uHH35o9evXjxPkvOOOO9xwIQDnX7FixVyA+JJLLomJ5qbQOQAAABADmjdvftbnaPjLRx99FJL1QWw5fPiwq1ETrGDBgu4xILlU/071pILrIu3bt886derkinnjPxpG++yzz9q4ceMsffroD+mQKQUAAADEgPbt2yfqecyihuRo2LCh5cuXz9WUypw5s1t25MgRa9u2re3Zs8dlbgDJnWm1SJEi9s4771i5cuXcsvnz57t6ZcoK+v7772lYP7feeqt99dVXbkKLypUrW7Zs2fwftqlTp1o0ISgFAAAAADijtWvX2vXXX29Hjx61qlWruqy7lStXugDVF198YRUrVqQFkSzKiFLNshkzZriJGH755Rd76aWXrHfv3tavX784GVSpXfuzXICItgsPBKUAAAAAAGelzKi3337bfvrpJzcbmgott2rVyrJkyULr4Zw98cQTNnToUDckbebMmS47D7GPoBQAAAAAAAibV155xXr16uWGpi1btsxlR02ePNll5SG2RX9VLAAAAADAeadhVar1s2vXLjt9+nTAY0899RRbAMlyww032JIlS1y9sttvv91l5PXs2dOuuOIKGzBggD322GO0bBDNhPn+++/bli1b7Pjx4wGPLV++3KIJmVIAAAAAgDN6/fXXrXPnzpY/f34rXLiwqynlO6lMkybqToQRORo1amSTJk2yokWLBixXjal77rnHtm/fHrZ1i0Qvv/yyG+qoSQb0uVSNqQ0bNrjAXteuXW3w4MEWTQhKAQAAAADOOkNaly5d3BAr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48ePxwm4IH5bt251gajixYtbtEob7hUAAAAAAACp04ABA2z48OF2xx132L59+6xnz55uaFratGmtf//+4V69iHPy5Enr27evm3mvdOnSbuij7j/55JNuBsNow/A9AAAAAAAQFuXKlbOXX37ZmjRpYjly5LCVK1f6li1atMgmT57MlvHTqVMnmzZtmg0cONBq167tln3//fcugNe0aVMbM2aMRROCUgAAAAAAICyyZctmP/74o5UsWdKKFCliM2bMsOrVq7si3tWqVXPZU/iPsqLeffddu+GGG/yWms2cOdPNUBht7cXwPQAAAAAAEBaqh7R9+3Z3/4ILLrDZs2e7+0uWLLFMmTKxVYJkzpzZDdsLpmUZM2a0aENQCgAAAAAAhMWtt95qX331lbvfvXt3Vy+pfPny1qZNG+vQoQNbJUjXrl3t6aeftmPHjvmW6f7gwYPtgQcesGjD8D0AAAAAABARfvjhB/vuu+9c1tQtt9wS7tWJ2CBepkyZrGrVqm7ZqlWr3KyFDRs2DHju1KlTLdIRlAIAAAAAAIgC7du3T/RzJ0yYYJGOoBQAAAAAAAiLokWLWv369d2tXr16dtFFF7ElUhGCUgAAAAAAICymTJliCxYssPnz59svv/xihQoVcsEpb5DqkksuYcvEMIJSAAAAAAAg7Hbu3Gnz5s2zzz77zN577z07ffq0nTp1ylK76tWruzpSefLksWrVqlmaNGkSfO7y5cstmqQP9woAAAAAAIDU6+DBg/btt9/6MqZWrFhhlStXdplSMGvatKkrbC7NmjWLqSYhUwoAAAAAAIRFrVq1bPXq1VapUiU3ZO/qq6+2q666ynLnzs0WSQXShnsFAAAAAABA6vTrr79a1qxZrWzZsu52wQUXEJA6gyVLltgPP/wQZ7mWLV261KINQSkAAAAAABAWe/bscXWk6tata19++aUbsle4cGG78847bcyYMWyVIF27drWtW7cGL7Zt27a5x6INw/cAAAAAAEBEWLZsmY0cOdLefvttCp3HI3v27G64o7LK/G3cuNGqVKliBw4csGhCoXMAAAAAABAWKmqu4ua6ffPNNy6oUrVqVevevbs1aNCArRJEBc81S2FwUGr79u2WPn30hXjIlAIAAAAAAGGhQEq1atXcsD1vofOcOXOyNRLQokUL27Fjh33yySeWK1cut+yff/5xs/IVLFjQ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AAAAABAjZs6caU2bNrX58+db2bJlLX/+/JY+ffrz+jfbtWtn//zzj3388ce+ZadOnbK//vorJH8fQPTi6AAAAAAAMWLDhg1WpEgRq1OnTljXI126dFa4cOGwrgOAyMfwPQAAAACIAcpYevDBB23Lli1u6Fzp0qXdbcSIEQHPu/TSS61///6+n/XccePG2a233mpZs2a18uXL2/Tp0wN+Z926ddakSRPLmTOn5ciRw6666ioXANPrTJo0yT755BP3OropSyu+4XsLFiywyy+/3DJlyuQCZ71797aTJ0/6Hq9fv75169bNHnvsMTf8UEEt//UEEHsISgEAAABADHjppZds4MCBVrx4cdu+fbstWbIk0b87YMAAu+OOO2z16tV24403WqtWrWzPnj3usW3bttnVV19tmTNntrlz59qyZcusQ4cOLqD0yCOPuN+7/vrr3d/ULb4sLb2GXveyyy6zVatW2ejRo+2NN96wQYMGBTxPAa5s2bLZDz/8YMOGDXPvZ86cOSnQOgAiEcP3AAAAACAG5MqVy2UxJWfonLKs7rrrLnd/yJAh9sorr9jixYtdsOnVV191r/3uu+9ahgwZ3HMuvPBC3+9myZLFjh07dsa/OWrUKCtRooSNHDnSZVBdfPHF9ueff1qvXr3sqaeesrRp/82XqFKlivXr18/dV8aWnv/VV19Zo0aNktUmACIbmVIAAAAAkMopGOSlTCUFt3bt2uV+1hA8DdfzBqSS48cff7TatWu7gJRX3bp17eDBg/bHH3/Eux6iYX7e9QAQewhKAQAAAECMUgaSx+MJWHbixIk4zwsOOCl4dPr0aV8m1LnSOvgHpLzLvH8rMesBIPYQlAIAAACAGFWgQAFX58lr//79tnHjxiS9hrKXvvnmm3iDWZIxY0Y7derUGV+jQoUKtnDhwoAAmX5WRlaxYsWStD4AYgdBKQAAAACIUddcc4299dZbLqi0du1aa9u2ras5lRQPPPCAC2a1aNHCli5dar/++qt7zZ9//tk9rhn+VCBdP//999/xBq+6dOliW7dudbMD/vTTT262PtWO6tmzp6+eFIDUh08/AAAAAMSoPn36uJnzbrrpJjf7XbNmzaxcuXJJeo18+fK5WfdU/6levXpWo0YNe/31131D7e6991676KKLrGbNmi4z67vvvovzGsqG+vzzz13x9KpVq1qnTp2sY8eO9uSTT6bYewUQfdJ4ggcYAwAAAAAAAOcZmVIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUgAAAAAAAAg5glIAAAAAAAAIOYJSAAAAAAAACDmCUjFs4sSJliZNGt8tffr0Vrx4cWvfvr1t27bNot369eutf//+tmnTphR/7a+++spq1qxp2bJlc2338ccfW6SaP3++W0f9H2qTJ0+2ESNGWCTRPqH2+Pvvv0P2N+vXr+9uXocPH3brEd82Ccf6nSt9xrTOzz///Dkdi5YuXXrW57Zr185Kly4dsEy/+8ADD1gsfoYi4XgHRBv6N8lH/yZx6N/8i/4Nzodo79MEfy68/WR9N3ktXLjQvcd//vnnrL8Ps/Q0QuybMGGCXXzxxXbkyBH7+uuvbejQobZgwQJbs2aNC7pE8wFtwIAB7kMdfBJ7Ljwej91xxx124YUX2vTp010bXXTRRSn2+rFEnba1a9dajx49LDUbNWpUwM8KSmnfFL50kqZv377WvXv3FNw6seF8He+AaEb/Jmno3yQe/Zt/0b/B+RBrfZoiRYrY999/b+XKlQsISuk96mJr7ty5z/i5AkGpVKFSpUou60caNGhgp06dsqefftpl/7Rq1eqcXlsn31mzZrVY8ueff9qePXvs1ltvtYYNGyb590+cOOHLTEPoKOiaOXPmsDR5hQoVwvJ3Y5H/FzoAnAn9m6ShfxOd6N8AkS1Tpkx2xRVXJPr5nDfExfC9VMj7odm8ebPvypkitpdeeqllyZLF8uTJY7fffrv9/vvvAb+naLY6gMq2qlOnjgtGdejQwT2m1MSHH37YypYt6z6YBQsWtBtvvNF++ukn3+8fP37cBg0a5LK29JwCBQq4oYR//fVXwN9RxPymm26yWbNmWfXq1d066XfGjx/ve47SI//3v//5Am3eIYr+aZPx+fbbb12gKUeOHG799T5mzJjhe1xplhriKL169XKveaYIvnfYz1tvveXef7Fixdx7++2339zjX375pft7OXPmdH+vbt26LnXen56rdihfvrx7jl7j5ptvdplswdSe119/vXte/vz5rVOnTnbgwIEzvmf/96Z1Xbdund11112WK1cuK1SokNuG+/btC3huYvYJ7Q9qO+1H/sNE5bLLLrMmTZoEvGblypXd40uWLPEtmzp1qlvm/17Pto38h27Mnj3brb/2JT332LFj8b53tZv2zVq1atmuXbvifY7aRa/5wQcf+JYtW7bMLatYsWLAc2+55RarUaNGQFt4M6KUwqv1EV0h8baLrpT427lz51m3Q0JSer9KzOfXa/jw4VamTBnLnj271a5d2xYtWmSJtXfvXrdOefPmdRmIWp/g40x8w/eCaf98/PHHLUOGDPb666/7lr/33ntunfTaWr/rrrvOVqxYYcmhoYYtWrRw66LPgP7X9vIeN4P3xXnz5lnnzp3d5zJfvnzWvHlzdwIYLDnreKbjnS4wKAC+devWOL+nfUrrcvTo0YBj67Rp06xKlSouiKtt/vLLL8f53f3799sjjzzitnXGjBnd/qOMyEOHDiW5LYFQoX9D/4b+TVz0b85f/8bbB5gzZ85Z+zd6TtOmTd15hr5/L7jgArv//vsDyjkoYUCvF9ynk9GjR7vHVq9eHdBXUZ9Uf1evWa1aNXv//ffjXce5c+favffe6/oF6j+2adPGfafv2LHDjRBRNo8yfvTdrwvs/iLhHE7bTJ9v9Zm1DiVLlnTvwb/vr9EbamOdt6g9dB4zadKkeM/dpkyZYk888YQVLVrUtce1115rP//8c5z+5rBhw6xUqVLu9fSeZs6cGWfdgofv6Zzr0Ucfdfe1T3nfo7dMRHzD9/bs2WNdunRx/S31u7TPav2Cz228JS107nnJJZe4Pn7VqlXts88+s6jmQcyaMGGCR5t4yZIlActfeuklt3zs2LHu53vvvdeTIUMGz8MPP+yZNWuWZ/LkyZ6LL77YU6hQIc+OHTt8v1evXj1P3rx5PSVKlPC88sornnnz5nkWLFjg2b9/v6dixYqebNmyeQYOHOj54osvPB999JGne/funrlz57rfPXXqlOf66693zxkwYIBnzpw5nnHjxnmKFSvmqVChgufw4cO+v1OqVClP8eLF3fI333zTvd7//vc/t876e7Jr1y7PkCFD3LJXX33V8/3337ublidk/vz57n3WqFHD895773k+/vhjT+PGjT1p0qTxvPvuu+45W7du9UydOtW97oMPPuhec/ny5Qm+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", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "fig, axes = plt.subplots(3, 2, figsize=(12, 15))\n", - "\n", - "\n", - "sp = gdf.groupby('lts_level', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with lts level', ylabel = 'percent', ax=axes[0,0])\n", - "\n", - "sp = gdf.groupby('speed_limit_raw', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with each speed limit', ylabel = 'percent', ax=axes[0,1])\n", - "\n", - "sp = gdf.groupby('num_lanes_raw', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with each number of lanes', ylabel = 'percent', ax=axes[1,0])\n", - "\n", - "sp = gdf.groupby('function', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with each speed limit', ylabel = 'percent', ax=axes[1,1])\n", - "\n", - "sp = gdf.groupby('bike_facility_type', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with each bike lane type', ylabel = 'percent', ax=axes[2,0])\n", - "\n", - "sp = gdf.groupby('pavement_condition', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", - "sp.plot(kind='bar', title = 'Percent of read network with each pavement condition', ylabel = 'percent', ax=axes[2,1])\n", - "\n", - "plt.tight_layout()\n", - "plt.show()" - ] - }, - { - "cell_type": "code", - "execution_count": 48, - "id": "436d6335-c580-4ab5-a955-e81689e034db", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAHJCAYAAABXHTnIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAANzFJREFUeJzt3QlYVGUf9/E/ooCVUIqipqKVa2QmmHu2YmaWbZo+aYuWZmZqm8ZbJi1amelTiVqZudNeppW2Uz5W8tjTYpaVphmoWIGVgeJ5r//9vmeumWFAhsWbge/nukaZM2fONmf5zb2cCXMcxxEAAABLatmaMQAAgCKMAAAAqwgjAADAKsIIAACwijACAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijJTBwoULJSwszPOoXbu2NGvWTK699lrZuXOnhLpNmzbJvffeK9u2bavwab/77ruSlJQkRx99tNl2r776qlRVH3zwgVlG/f9IW7ZsmcyaNUuqEt0ndHvk5OQcsXmeeeaZ5uH6+++/zXIE+kxsLF956TGmyzxjxgypLkJtnX777Te58sorpVGjRma5Bw4cWOr9ERWndgVOq8Z59tlnpV27drJ//3756KOPZNq0afLhhx/KV199ZS62oRxGpk6dag66li1bVth09ZcHBg0aJG3atJHXX3/dbKO2bdtW2PSrEw0jX3/9tYwfP15qsjlz5vg81zCi+6biooCKcN9998krr7wiCxYskBNPPFHq16/PhrWAMFIOCQkJ5lu+Ouuss6SwsNDs2Ppt/1//+le5Phg96R511FFSnfz666/mW8gll1wi55xzTtDvP3DggKckCkeOhu2oqCgrm7xDhw5W5ouqr6LOBxr6NYSU95yN8qGapgJ169bN/P/zzz97SgL0m12nTp2kbt26ctxxx8nll18uP/30k8/79BueBhstXenRo4cJIdddd5157Y8//pBbb71VTjjhBImMjDRFiRdccIFs3rzZ8/6CggK5//77TSmNjtOwYUNTZbRnzx6f+Wgpx4UXXihvvfWWdO7c2SyTvke/EXhXQV1xxRWegOVWRenwknz88ccmYNSrV88sv67HqlWrfIrQtSpL3XnnnWaaJZW6uFUkixcvNut//PHHm3X74YcfzOvvvPOOmV90dLSZX8+ePU0VkDcdV7dD69atzTg6jQEDBpiSK3+6Pc8//3wzXmxsrIwePVr27dtX4jp7r5su6zfffCNDhgyRmJgYiYuLM59hbm6uz7il2Sd0f9Btp/uRd3Wg6tKli/Tv399nmqeccop5/fPPP/cMe/nll80w73U93GfkXQW5Zs0as/y6L+m4+fn5Adddt5vum127dpXdu3cHHEe3i07zhRde8AzLzMw0w04++WSfcS+66CJJTEz02RZuCYgW/+vyKC0dcbfLNddc4zONXbt2HfZzKE5F71elOX5dM2fOlFatWskxxxwj3bt3l/Xr1x92ed3P6/3335cbb7zR7LsNGjSQSy+91IR/bzqe7qv+9Dj03obuNN977z25/vrrzfR0ewwfPlz++usvyc7ONiWcxx57rDRp0kRuu+02Ewz8HTp0SB544AFp0aKFCbP6xc1/W6otW7bI0KFDzbbRbdS+fXt58skngzofBKJffMaMGWPGjYiIMJ9BSkqKZ192q5P0M//22289+1Ow1bK6L+r+ryUqup303PrMM8+YYz3Y869Lt/GoUaPMOVOXXfcLnc/BgwfFW1pampx66qlmn9HjWqd31113SUjSX+1FcJ599lndy5zPP//cZ/js2bPN8Pnz55vn119/vVOnTh3n1ltvdd566y1n2bJlTrt27Zy4uDgnOzvb874+ffo49evXd5o3b+48/vjjzvvvv+98+OGHTl5ennPyySc7Rx99tJOamuq8/fbbzksvveTccsstznvvvWfeW1hY6Jx//vlmnKlTpzpr1651nn76aef44493OnTo4Pz999+e+cTHxzvNmjUzwxctWmSmd8UVV5hl1vmp3bt3Ow8++KAZ9uSTTzr/+c9/zEOHF+eDDz4w65mYmOikp6c7r776qpOcnOyEhYU5K1asMOPs2LHDefnll810b775ZjPN//73v8VOU7eBjqvrcfnllzuvv/6688Ybbzh79+51Fi9ebKY9cOBAM82VK1c6F154oRMeHu688847nmnoOum2f/HFF83fr7zyinlP3bp1nc2bN3vG08+iUaNGZl762a5evdr517/+5bRo0cIsgy5LSaZMmWLGa9u2rXPPPfeYz2DmzJlOZGSkc+211/qMW5p94ptvvnF69uzpNG7c2LP99aEmTZrkHHPMMU5BQYFn2XXeuk4PPPCAZz433nijmWYwn5H3vq3b4oYbbnDefPNNs/0OHjzoWc89e/Z4pnncccc5F198sfPXX3+VuI2aNGlipueaPn26WWad3s6dO82wAwcOONHR0c4dd9zhc2zoQ/3zzz9mm+l7RowY4dkuP/zwQ9CfQyAVvV+V5vjdunWrWeaWLVua41g/F32ccsopZtv+8ccfJS6z+3mdcMIJ5rjSeejxr+8966yzfMbV8XQb+dPzwtVXX11kmq1atTLruWbNGuehhx4y22HIkCFO586dnfvvv99s3zvvvNOM++ijj3re766Tns969epl1vmFF15wunTpYvbBdevWecbVfT0mJsasr56TdF46z1q1ajn33ntvqc4Hgezfv9/p2LGj2fYzZsww07377rud2rVrOxdccIFnf9L957TTTjPbz92fcnNzi93e3vuj65prrnGeeeYZsz30cd9995l9Qc/H/tv5cOdflZWVZbadjj9v3jyz7+k0dT/WebmWL1/uOZ/q+ul4c+fOdcaNG+eEIsJIGbgH6/r1680JdN++febAaNiwoVOvXj1zgdCd2v8gdS/KuqP6n3B13HfffddnXD2B6XDdwYvj7pB6wHvToKTD58yZ4xmmO3dUVJTz888/+xy0GoRGjRrlGaYnjtJchF3dunUzF3PdDi69eCUkJJiD79ChQz4nqUceeeSw03RPPmeccYbPcL3o6fIOGDDAZ7iGslNPPdU5/fTTi52mLpNexFu3bu1MmDDBM1xPqHoR+uKLL3zGP++884IKIw8//LDP8DFjxpjt7a5/MPtE//79zeflT084Oo2PPvrIPF+yZInZ53Re3hcfXcehQ4cG/Rm5+/bw4cOLXU8NI3rhjoiIMCc+3faHc9VVV5kTvuvcc881wUwvms8995wZ9sknn5jp64m1uJO/zru4i2ppP4dAKmO/Ks3x6x4TejHW6bg+++wzM1yP75K4n5euozfdBjpcL2xlDSN6kfOmgUuHa8Dz1qlTJxNQ/NepadOm5vziHc50G+tn7+rbt6/Z//wDwNixY81n9ttvv5V4PiiOXpR1/Oeff95nuIaqQPuYhsbSCBRG/PcXvSboZ9+gQQOffa60599Ro0aZLxze4ykNVbrsGuDcbXTsscc61QXVNOWslqlTp44pHtPit8aNG8ubb75piobfeOMNU+R31VVXmaI196HjaLGaf1GgFtefffbZPsN0WtrY89xzzy12GXQ+WlyqxcTe89FqAJ2X/3x0uBaburT4VOfhVi0F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HeZ9zxG9OZq+rqHlySefNEU1//73v+nWCwAAyt6AdcyYMeYRyMKFC4sM69Onj/z3v/+VqkyrhaZMmVKkeiiUVId1qC7rUR3WQbEeVQefRdXBZ1HxwpzD9bcBAACoRPxQHgAAsIowAgAArCKMAAAAqwgjAADAKsIIgBLRxh1AlezaWx388ssvkpaWZn5tWG9Xr7eZ11va9+jRw9yorar9Dg5gsxvj//73P2nfvj0fAoBKUSO79n788cfSr18/EziSk5NNCNHNoL+Zo7e2198TefPNN6Vnz54SynQ99F4Xetfbqmz//v2SmZkp9evXlw4dOvi89s8//8jzzz/vc1ffqkrvMLx+/XrzEwjt2rWTzZs3y+zZs80vUF911VVy9tlnS1Xm/XtQ3nQddPnd35KaOXOmhJLff/9dnnvuOdmyZYv5lfCrr766yn/Z2Lhxo/kJDL1ppFqyZIn58qQ3lNQbTI4dO1auvPJKqepuvvlmGTRokPTu3VtC2eOPPy4bNmyQ/v37m/VZvHix+UFX/d20Sy+91NwEVH9vLRT89ddfsmzZsiJfxPV6N2TIEDn66KPtLJhTAyUlJTnjx48v9nV9TccJdV988YVTq1Ytpyr77rvvnPj4eCcsLMwsa58+fZxff/3V83p2dnaVXwf15ptvOhEREU79+vWdqKgo87xhw4bOueee65xzzjlO7dq1nXfffdepyvQz6NSpk3PmmWf6PHR4ly5dzN9nnXWWU9U1adLEycnJMX//9NNPTuPGjc3jvPPOc5o1a+bExMQ43377rVOVnXbaac57771n/n7qqaecunXrOuPGjXPS0tLM+emYY45xnnnmGaeqc4/r1q1bO9OnT3eysrKcUJOamurUq1fPueyyy8x+pOvRoEED5/7773cefPBBc5zfc889Tij45ptvnKZNmzrHHnusc/HFFzs33HCDc/3115u/ddjxxx9vxrGhRoYRvVhs3ry52Nf1RKXjVHWvvfZaiY/HHnusyl/IBw4c6Fx44YXOnj17nC1btjgDBgxwWrVq5fz8888hFUa6d+/upKSkmL+XL1/uHHfccc5dd93leV3/1othVaYnVt32/qFJg5StE1RZL4C7du0yf1955ZUmRP3111/m+T///GP2t8svv9ypyo466ijPMaDBZN68eT6vL1261OnQoYMTCp/FO++849xyyy1ObGysU6dOHeeiiy5yVq5c6RQWFjqh4IQTTnBeeuklzxe88PBwZ8mSJZ7XX375Zeekk05yQsGZZ55pjon8/Pwir+mwIUOGmHFsqJFhRE+4CxYsKPZ1fU3HCZVvHfp/cY+qfiFv1KiR8+WXX/oMGzNmjNOiRQvnxx9/DJkwEh0dbcKU0pOsXsAzMzM9r3/11VdOXFycU9V99tlnTps2bZxbb73VKSgoCPkwEihcrV+/3pSQVGX6zXvDhg2eY0Qvgt5++OEHU1oSSp+F7k/p6elO3759zQVdv6FrSHePm6pKt7MbDJUGqq+//trzfNu2bSY8hoK6deuWeCzrecrWflUje9PoLwZrI1Wtd33ttddMPf+nn35q/tZhN954o9xxxx1S1Wn990svvWTqLQM9qvrvAbntRfzrWvUHFS+66CLzm0bff/+9hJpatWpJVFSUqfN31atXT3Jzc6Wq69Kli2m/s2fPHklKSpKvvvrK1CmHGneZtb2O1od70+e6flWZtmnTNiJKj4MXX3zR53VtR3XSSSdJKKlTp45pb/HWW2/JTz/9JNdff70sXbpU2rZtK1VZ48aNZdOmTeZvbXdUWFjoea6++eYbadSokYSC4447zqxDcX744QczjhVODbVixQqna9eu5lufW4qgf+swTe+hQKs07r777mJf129Tul5VmbZFWLRoUcDXbrrpJlOPGQolIx07djTtRLy/YRw4cMDzPCMjIyRK27xpdZOW5uj2D7WSkVNOOcVUb2jbCi1G9/bhhx+auvGqbOfOnU7Lli2dM844w5k4caL5ttqrVy9Tv6/DtH3SqlWrnFAqGQnk0KFDzpo1a5yqTKtftV3IyJEjzTE8efJkU3Kr7Xfmzp3rNG/e3JkwYYITCqZMmWLaTD3yyCPm+qBteLT0Wf/WYVq9PHXqVCvLViN703g7cOCA5OTkmL9jY2NNeg8VGRkZpmX0+eefH/B1fU1bgOs3q6pKW6TreqxevTrg6/rr0HPnzjUlPVWZLqP20NDW9oGkpKTIrl275Omnn5ZQ6wKvJSXnnnuuvVb2QZo6darP827duknfvn09z2+//XazXsuXL5eq7I8//pDp06fLypUrTUmCHgNaGqq9HiZMmGBKrqo67Q2k5yC3J1Yo0pIQ/Ry0BL1Xr15y5513yooVK0zp+d9//y0DBgyQJ554ImSOj4ceesj0kHN70iiNAVoCNH78eGu1AjU+jAAAUNNs3brVBBKlQcTtRm4LYQQAAIjNe1MRRgAAgOidljt37myqpo600LhlHAAAKJfXX3+9xNe1bZItlIwAAFAD1KpVyzRaLanfir5uo2SkRt5nBACAmqZJFb43FWEEAIAaIDExscTAcbhSk8pEmxEAAGqA22+/3dx/qjh6V9/3339fbKDNCAAAsIpqGgAAYBVhBAAAWEUYAQAAVhFGAACAVYQRAOV25plnml/8BICyIIwAAACrCCMAaryCgoIavw0AmwgjQAhWiYwbN07uuOMOqV+/vjRu3Fjuvfde89q2bdvMXRS/+OILz/h//PGHGfbBBx+Y5/q/Pn/77bfltNNOk7p168rZZ58tu3fvljfffFPat28v0dHRMmTIEPn777/LtIxLliyRpKQkqVevnlm+oUOHmum73GV49913zXhHHXWU9OjRQ7777juf6axcudLcNTIqKkpOOOEEmTp1qhw8eNDzuq53ixYtJDIyUpo2bWq2S2m0bNlS7r//frnmmmskJiZGrr/+ejP8zjvvlDZt2pjl0fndfffdcuDAAfNabm6uhIeHS2Zmpnmud6rU7d+lSxfPdJcvX25uuQ0gOIQRIAQ999xzcvTRR8unn34qDz/8sKSmpsratWuDmoZeyJ944glZt26d7NixQwYNGiSzZs2SZcuWyapVq8z0Hn/88TKXNNx3333mJ8lfffVV2bp1q7nw+0tJSZFHH31UNmzYILVr15brrrvO85qGpauuusoEjE2bNsm8efNk4cKF8sADD5jXX3zxRXnsscfM8C1btpj5nHLKKaVexkceeUQSEhJMuNDQoTQ86Tx0frNnz5annnrKzENpaOnUqZMn1H355Zee//Py8szf+lqfPn3KtM2AGs0BEFL69Onj9OrVy2dYly5dnDvvvNPZunWr/rCEs3HjRs9rv//+uxn2/vvvm+f6vz5/5513PONMmzbNDPvxxx89w0aNGuX07du31Mt0yy23FPv6Z599Zqa/b9++Ypdh1apVZtj+/fvN8969ezsPPvigz3QWL17sNGnSxPz96KOPOm3atHEKCgqcYMXHxzsDBw487HgPP/ywk5iY6Hk+ceJE58ILLzR/z5o1y7n88sudzp07m2VXujxpaWlBLw9Q01EyAoSgjh07+jzXqgHvapBgpxEXF+epmvAeFuw0XRs3bpSLL75Y4uPjTWmDVi2p7du3F7sMbvWGO08tsdASn2OOOcbz0OqUrKwsU310xRVXyP79+80y6/BXXnnFpwrncLR6yJ+WtvTq1ctULen8tMTEe5l1PTIyMswvnH744YfmuT707+zsbPn+++8pGQHKgDAChKA6der4PNf2F3qBrFXr/x3S3r+86bZ5KGka+v7iphks/SGu5ORkczHXtiOff/65CQqBGor6L4Ny56n/axsRbf/iPr766itTJaNtSJo3b27amDz55JOm3cuYMWPkjDPOKHZ9/Wk1l7f169fLlVdeKf369ZM33njDBCqtRvJeZp3+vn37zC+faijRIKLVMhpG9AfGGjVqZNrcAAgOv9oLVCMNGzY0/2vpgTZOVd6NWY+EzZs3S05OjkyfPt0EBqVtQoLVuXNnEzb0l0SLoyHkoosuMo+bbrpJ2rVrZwKLvjdYn3zyiSnJ0QDi+vnnn33GcduNaFsbDU8dOnQwDWc1uGiAob0IUDaEEaAa0Ytzt27dTBDQHiMaCv7P//k/R3QZtHdLRESEafw6evRo+frrr01j1mDdc889cuGFF5pAo1UyWuqjjUU1bGhPGG1oWlhYKF27djVVTIsXLzbrr4GiLDT0aJXMihUrTA8ZbcTrluh409IQbdx6ySWXmEBy3HHHmVCSnp4u//73v8s0b6Cmo5oGqGYWLFhgqiq0TcQtt9xiLtxHunRGg8ILL7xgLtIajGbMmBH0dPr27WtKG7RXj4YDDVkzZ870hI1jjz3W9Hbp2bOnaXui3YS1K3CDBg3KtNzaxmXChAkyduxYU/qhvYzcXjbezjrrLBOC3HYwSktEdBglI0DZhGkr1jK+FwAAoNwoGQEAAFYRRgCUSNtReHev9X/4d9e1TXu5lLS8AKoeqmkAlEjv3aG3mS+ONpTVu6dWFXrvkZ07dxb7ekm9cwDYQRgBAABWUU0DAACsIowAAACrCCMAAMAqwggAALCKMAIAAKwijAAAAKsIIwAAwCrCCAAAEJv+L1ZtwzfFXTvRAAAAAElFTkSuQmCC", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "image/png": "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XJd5eSCiFvP67bffUg381nFGXptjxEczrnytsBrABtbO0M+STkkR7FjyEp35Wn/4/Pzzz6bYmZ6T77//fjOAVeet8ardu3eb8XnBgjYN1NyCYCQEVatWNV+82uT+/fffm6yILl26yMMPP+zpCoA6MFVPnnoJ1h2j+0m7JLxKW0L0mPF90fjoMv3V4lUPPPCA+WLRwc167Pz5559mengthObVlOexY8f6W0a0CyvwF662iGjgpsu9TL90ta6T14OPlHQgr/44Llu2bLLlOjBcZ8h2C7JpcN527NhhTp76a1aLEelI98ATqM7b4+V+bk0/bN26tZQpU0bq169vvnh1YkWdGn7x4sX+VjavjqfRL2DtylOa7uyryuplmpE2f/580w2h2SM6CRyQnoULF0rnzp1N4bMRI0aYuljaFardN4sWLZIWLVqIGzBmJEQaed57771mkJ1G6EpTEbVp2as0EtdfbNocWKdOHXPbd9GmeC8HIr6U8F9//VXat29vxkJo14xWo9Vm5hkzZoiX6aC7hIQEE8R+/fXXJiXc64GIHiNVqlQxtWiKFy9ugnkdnKktsF4fS+Mbg/Xxxx/7b2sl40suucSck/WHkVe1adPGzFqsP3D0B4+2LmpNFg1S3BKIGLbTedyAVMT0zZw501m0aJH/9oABA0wKa/369Z3t27df8PfHbTZu3GjSfL2qe/fuztGjR1MtP378uLnPiw4ePOhcccUVTr58+Zz777/fGTt2rDNmzBjnvvvuM8sqV67sHDp0yPEy3T+fffaZub5mzRqTHj516lSnTZs2Tvv27W1vHjKJYCQEV199tfPmm2+a6/nz5/fncW/YsMGJjY11vI6TRMZ4PRjR175v375Uyw8cOGDqJHi1hka1atWcvXv3prpvz549TvXq1Z1+/fo5XqbBx44dO8x1rTHSuXNnc/2nn35yYmJiHK+Ki4tzEhISUi0/fPiwuc8t6KYJAamI6dMxEL7R3B9++KHccccdZpS7pj57ObUXyWn2mdbm0R9BWrdHb/suOm2ANjNr14QX6edG51mJjY1NdZ922WhG3wcffCBephlGWm/FN4fPDTfcYK5rxdG///5bvGr79u1B611p2rNvSIEbkE0TAlIRQztJ6EBNPUk89thjZrnXTxJITvv3fdlXOqliSrpcB9950Z49e9Itb67ZI4Gp816k4x90JmzN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Jpdddpl/WZ48ecxsxm5Mf6boGQDANRzHsb0JYSEpKSnZ7MW+Imhak8WNKAcPAIALg7Ju3bpJdHS0f5l20fTu3TtZppGWzXcDghEAQFibPn26KXqm9Jf/zJkzU2WN9O3bV7yka9euqZbde++94laMGQEAhC2tuHquol56/x9//HHRtglZj2AEAABYxQBWAABgFcEIAACwimAEAABYRTACAACsIhgBAIQ1Ted98803TSVWZE9k0wAAwl7evHll8+bNUrZsWdubgguAlhEAQNirW7eumZMG2RMVWAEAYa9Pnz7Sv39/2bVrl9SuXTtZyXNVo0YNa9uGzKObBgDgitl7g1Ve1Tla9H+dOA7uRcsIACDsbdu2zfYm4AKiZQQAAFjFAFYAgCu89dZb0rBhQylZsqTs2LHDLBs3bpx89NFHtjcNmUQwAgAIe5MnTzYDWG+++Wb566+//GNELrnkEhOQwN0IRgAAYe/VV1+V1157TQYPHiwRERH+5XXq1JEff/zR6rYh8whGAACuGMBas2bNVMujo6PlxIkTVrYJWYdgBAAQ9uLi4oIWPfvkk0+katWqVrYJWYfUXgBA2BswYIA89NBD8s8//5jaImvXrpW5c+fKqFGjZPr06bY3D5lEai8AwBV0zMjIkSNNFVZ12WWXybBhw6Rnz562Nw2ZRDACAHCVhIQEOXv2rBQrVsz2piCLEIwAAACrGMAKAAh7+/btk86dO5uCZ5GRkSa9N/ACd2MAKwAg7HXr1k127twpzzzzjJQoUcJMjofsg24aAEDYK1CggMTHx8vVV19te1NwAdBNAwAIe6VLlzYpvcieCEYAAGFP558ZOHCgbN++3fam4AKgmwYAEJYuvfTSZGNDtOx7YmKi5M2bV3LlypVs3UOHDlnYQmQVBrACAMISs/F6By0jAADAKsaMAADCntYS2b9/f6rlBw8epM5INkAwAgAIe2ll0pw6dUqioqIu+vYgazFmBAAQtl555RXzvw5k1dl58+fP778vKSlJvvjiC6lcubLFLURWYMwIACBsxcXFmf937NghpUqVStYloy0i5cqVkxEjRkjdunUtbiUyi2AEABD2rr/+epk/f75J90X2QzACAHCNhIQE02VTpEgR25uCLMQAVgBAWPvrr7/koYcekpiYGImNjZVixYqZ6w8//LC5D+5HywgAIGxpZdX69evL7t275Z577pEqVaqYzJrNmzfLnDlzzJw1a9asofvG5QhGAABhq1+/fvLZZ5/Jp59+alpFAu3du1datmwpzZs3l7Fjx1rbRmQewQgAIGxptszUqVPlxhtvDHr/kiVLpHfv3kyg53KMGQEAhK09e/bIlVdemeb91apVMy0kcDeCEQBA2NKBqtu3b0/z/m3btpFZkw0QjAAAwtZNN90kgwcPltOnTwctBf/MM8+YdeBujBkBAISt//73v1KnTh2Jjo426b2+0u+bNm2SSZMmmYBk3bp1JqsG7kUwAgAIa9oV06dPH1m2bJl/wjwtfNaiRQuZMGGCXH755bY3EZlEMAIAcIXDhw/L1q1bzXUNQAoXLmx7k5BFCEYAAIBVDGAFAABWEYwAAACrCEYAAIBVBCMAgtKshfvvv98MEtTMhY0bN1rZU1rwyubfB3DhMYAVQFCffPKJtG3bVlauXCnly5c3lTAjIyMv6N7q1q2bmRL+ww8/9C9LSkqSAwcOXJS/D8AOPtkAgvr999+lRIkS0qBBA6t7KCIiQooXL251GwBcWHTTAAjaQvHII4/Izp07TReJzpyql3HjxiVb7+qrr5Zhw4b5b+u606dPl/bt20vevHmlYsWKsmDBgmSP+fnnn6V169ZSsGBBKVCggDRq1MgEPvo8b775pnz00UfmefSirTLBumlWrVol1157ranKqQHTwIEDJTEx0X9/06ZNpW/fvvLkk0+abiYNZgK3E0B4IRgBkMr48eNlxIgRUqpUKTNr6rfffhvyXho+fLjcdddd8sMPP8jNN98s99xzjxw6dMjct3v3bmncuLHkzp1bVqxYIevXr5cePXqYQOKJJ54wj9N5RvRv6iVYq4w+hz7vNddcI99//71MnjxZXn/9dRk5cmSy9TSwyZcvn3zzzTfy4osvmtezfPly3m0gDNFNAyCVQoUKmVaL8+ki0VaVu+++21x//vnn5dVXX5W1a9eaIGPixInmud955x3JlSuXWeeKK67wPzZPnjxmrpH0/qbOR6LzkGgZcG0x0blK/vzzT3nqqadkyJAhkjPn/35j1ahRQ4YOHWquawuNrv/ZZ5+ZEuIAwgstIwCylAYBPtoyoUHN/v37zW3tatFuGV8gcj42b94s9evXN4GIT8OGDeX48eNmUrVg26G0O8e3HQDCC8EIgNBOFjlz+icp8zlz5kyq9VIGGho0nD171t/ykVm6DYGBiG+Z72+Fsh0AwgvBCICQFC1a1Izj8Dl69KiZTTUjtLUiPj4+aBCjoqKiTCpveqpWrSpr1qxJFhjpbW2BueyyyzK0PQDCA8EIgJA0a9ZM3nrrLRNM/PTTT9K1a1czpiQjHn74YRPEdOzYUdatW2dmYNXn/OWXX8z9mrGjA1/1dkJCQtCgRaeS37Vrl8n22bJli8m+0bEh/fv3948XAeAufHIBhGTQoEEmE+aWW24x2Szt2rWTChUqZGjvFSlSxGTR6PiOJk2aSO3ateW1117zd6ncd999UqlSJalTp45pifnyyy9TPYe2fixevNgMir3qqqukd+/e0rNnT3n66ad5JwGXogIrAACwipYRAABgFcEIAACwimAEAABYRTACAACsIhgBAABWEYwAAACrCEYAAIBVBCMAAMAqghEAAGAVwQgAALCKYAQAAFhFMAIAAMSm/we1mCKCqsbJAAAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 70, - "id": "c8f4f262-ae24-4380-b12d-6edbad307a2a", - "metadata": {}, - "outputs": [], - "source": [ - "gdf.to_file('levels.geojson')" - ] - }, - { - "cell_type": "markdown", - "id": "8c9dc7bc-22b1-4360-ac57-0cf5bb87eca2", - "metadata": {}, - "source": [ - "## Get Crash Data\n", - "\n", - "We only use crashes that resulted in a bicyclist fatality or injury from the last 5 years." - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "a167bd1d-ccfd-4e00-b73b-692ae8f302c1", - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "2021-03-01\n", - "2026-03-01\n", - "Fetched 1000 records...\n", - "Fetched 2000 records...\n", - "2016\n" - ] - } - ], - "source": [ - "def get_crashes_df(start_date, end_date, chunk_size=1000):\n", - " base_url = \"https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Public_Safety_WebMercator/MapServer/24/query\"\n", - "\n", - " all_rows = []\n", - " offset = 0\n", - "\n", - " while True:\n", - " params = {\n", - " \"where\": (\n", - " f\"REPORTDATE >= DATE '{start_date} 00:00:00' \"\n", - " f\"AND REPORTDATE <= DATE '{end_date} 23:59:59' \"\n", - " \"AND (MAJORINJURIES_BICYCLIST > 0 \"\n", - " \"OR MINORINJURIES_BICYCLIST > 0\"\n", - " \"OR UNKNOWNINJURIES_BICYCLIST > 0\"\n", - " \"OR FATAL_BICYCLIST > 0)\"\n", - " ),\n", - " \"outFields\": \"*\",\n", - " \"outSR\": 4326,\n", - " \"f\": \"json\",\n", - " \"orderByFields\": \"OBJECTID\",\n", - " \"resultOffset\": offset,\n", - " \"resultRecordCount\": chunk_size\n", - " }\n", - "\n", - " r = requests.get(base_url, params=params, timeout=120)\n", - " data = r.json()\n", - "\n", - " features = data.get(\"features\", [])\n", - "\n", - " #print(f\"Received {len(features)} features\")\n", - "\n", - " # Extract attribute dictionaries\n", - " for feature in features:\n", - " attrs = feature.get(\"attributes\", {})\n", - " geom = feature.get(\"geometry\")\n", - "\n", - " if geom and \"x\" in geom and \"y\" in geom:\n", - " attrs[\"geometry\"] = Point(geom[\"x\"], geom[\"y\"])\n", - " all_rows.append(attrs)\n", - "\n", - " # Stop when last page is reached\n", - " if len(features) < chunk_size:\n", - " break\n", - "\n", - " offset += chunk_size\n", - " print(f\"Fetched {offset} records...\")\n", - " time.sleep(0.05)\n", - "\n", - " # Convert to GeoDataFrame\n", - " df = pd.DataFrame(all_rows)\n", - " gdf = gpd.GeoDataFrame(df, geometry=\"geometry\", crs=\"EPSG:4326\")\n", - "\n", - " return gdf\n", - " \n", - "start_date = (date.today()-relativedelta(years=5)).isoformat()\n", - "print(start_date)\n", - "end_date = date.today().isoformat()\n", - "print(end_date)\n", - "crashes_new = get_crashes_df(start_date, end_date)\n", - "print(len(crashes_new))" - ] - }, - { - "cell_type": "code", - "execution_count": 72, - "id": "462237b1-c63d-4e0e-9998-6e518d01852d", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
geometrybbox_westbbox_southbbox_eastbbox_northplace_idosm_typeosm_idlatlonclasstypeplace_rankimportanceaddresstypenamedisplay_name
0POLYGON ((-77.11979 38.93435, -77.11977 38.934...-77.11979538.79163-76.90936638.995968394523734relation539619438.895037-77.036543placecity160.81477cityWashingtonWashington, District of Columbia, United States
\n", - "
" - ], - "text/plain": [ - " geometry bbox_west bbox_south \\\n", - "0 POLYGON ((-77.11979 38.93435, -77.11977 38.934... -77.119795 38.79163 \n", - "\n", - " bbox_east bbox_north place_id osm_type osm_id lat lon \\\n", - "0 -76.909366 38.995968 394523734 relation 5396194 38.895037 -77.036543 \n", - "\n", - " class type place_rank importance addresstype name \\\n", - "0 place city 16 0.81477 city Washington \n", - "\n", - " display_name \n", - "0 Washington, District of Columbia, United States " - ] - }, - "execution_count": 72, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# restrict crashes to DC (probably not necessary considering they are coming from DC website)\n", - "\n", - "PLACE_NAME = \"Washington, District of Columbia, USA\"\n", - "CRS = \"EPSG:4326\"\n", - "\n", - "# Crash join toggles (turn off if ArcGIS blocks)\n", - "CRASH_ENABLE = True\n", - "YEARS_BACK = 5\n", - "CRASH_BUFFER_M = 10\n", - "\n", - "# 3) Area of interest\n", - "aoi_gdf = ox.geocode_to_gdf(PLACE_NAME).to_crs(CRS)\n", - "aoi = aoi_gdf.geometry.iloc[0]\n", - "aoi_gdf" - ] - }, - { - "cell_type": "code", - "execution_count": 73, - "id": "67d06c72-c0db-4e40-9eb9-887f73227424", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
CRIMEIDCCNREPORTDATEROUTEIDMEASUREOFFSETSTREETSEGIDROADWAYSEGIDFROMDATETODATE...SUBBLOCKKEYCORRIDORIDNEARESTINTKEYMAJORINJURIESOTHERMINORINJURIESOTHERUNKNOWNINJURIESOTHERFATALOTHEROBJECTIDgeometryREPORTDATE_
026661162614211079031627946100000110014025579.1227.280.00.01627947960000None...84073fa307bbfb12d66bc2a398381da511001402_273435d5fb8f812ed226b15ebaa9a88f00.00.00.00.0445287826POINT (-77.03273 38.94045)2021-08-02 19:15:00-04:00
126667229361211083801628019360000110036022200.3317.84NaNNaN1628019360000None...104e644e8a45e4f8f5fae8a522dfb49211003602_6a38c5c59ffe947cd9e811e4da2f8d5c20.00.00.00.0445288297POINT (-77.06985 38.94695)2021-08-03 15:36:00-04:00
22668471915921108827162809274000012061162854.3144.49NaNNaN1628109120000None...a686015e5346e258d9d532aca3fe0b96None00.00.00.00.0445288845POINT (-76.948 38.89634)2021-08-04 11:59:00-04:00
326687496038211093091628163600000110014021537.8523.44NaNNaN1628167440000None...4ee4ad33be2250ce8d95d389255b342411001402_1f63110cea700e723ffd3d38eb1b4814c0.00.00.00.0445288994POINT (-77.03196 38.90339)2021-08-05 07:40:00-04:00
42668818767621109154162812490000012050892142.6445.05NaNNaN1628178660000None...ccf5a699cde70078619692f752acad3c12050892_140736cafb4216780e39074395946fe5a0.00.00.00.0445289238POINT (-77.00742 38.90252)2021-08-04 20:55:00-04:00
..................................................................
20046855074794126019716177100956000011051352729.6133.43NaNNaN1771032745000None...0ce55da149ac9f9d93607887be614e3f11051352_1850091b43e2caa128ef35eaa09d15c691.00.00.00.0445522184POINT (-77.02581 38.94206)2026-02-13 14:06:00-05:00
200568606733635260218721771425900000Route not found0.000.00NaNNaN1771430609000None...Route not foundRoute not foundRoute not found0.00.00.00.0445522217POINT (-77.00416 38.90565)2026-02-18 09:45:00-05:00
200668674853801260244221771888620000110015023063.7219.37NaNNaN1771892907000None...f21d99cb604ad1387dbcb38c044fd73911001502_2d8d9019d5c5ec0f6fcb972b23e18ba1f0.00.00.00.0445522459POINT (-77.03454 38.91578)2026-02-23 18:17:00-05:00
2007686490395642602359317717196000001201534236.3727.42NaNNaN1771730973000None...5e6c7d2133356808243f92a44b320ac812015342_104eab17816b0ebe7fe88f4688908ed7c0.00.00.00.0445522523POINT (-76.98303 38.90007)2026-02-21 19:20:00-05:00
200868720034156260256651772127900000110016022031.3034.89NaNNaN1772132327000None...0ccb17dad651356070da3931e3a1dfaf11001602_26a2a2d1c161fc28a26349f908585926f0.00.00.00.0445522640POINT (-77.0365 38.91799)2026-02-26 12:45:00-05:00
\n", - "

2009 rows × 66 columns

\n", - "
" - ], - "text/plain": [ - " CRIMEID CCN REPORTDATE ROUTEID MEASURE OFFSET \\\n", - "0 26661162614 21107903 1627946100000 11001402 5579.12 27.28 \n", - "1 26667229361 21108380 1628019360000 11003602 2200.33 17.84 \n", - "2 26684719159 21108827 1628092740000 12061162 854.31 44.49 \n", - "3 26687496038 21109309 1628163600000 11001402 1537.85 23.44 \n", - "4 26688187676 21109154 1628124900000 12050892 142.64 45.05 \n", - "... ... ... ... ... ... ... \n", - "2004 68550747941 26019716 1771009560000 11051352 729.61 33.43 \n", - "2005 68606733635 26021872 1771425900000 Route not found 0.00 0.00 \n", - "2006 68674853801 26024422 1771888620000 11001502 3063.72 19.37 \n", - "2007 68649039564 26023593 1771719600000 12015342 36.37 27.42 \n", - "2008 68720034156 26025665 1772127900000 11001602 2031.30 34.89 \n", - "\n", - " STREETSEGID ROADWAYSEGID FROMDATE TODATE ... \\\n", - "0 0.0 0.0 1627947960000 None ... \n", - "1 NaN NaN 1628019360000 None ... \n", - "2 NaN NaN 1628109120000 None ... \n", - "3 NaN NaN 1628167440000 None ... \n", - "4 NaN NaN 1628178660000 None ... \n", - "... ... ... ... ... ... \n", - "2004 NaN NaN 1771032745000 None ... \n", - "2005 NaN NaN 1771430609000 None ... \n", - "2006 NaN NaN 1771892907000 None ... \n", - "2007 NaN NaN 1771730973000 None ... \n", - "2008 NaN NaN 1772132327000 None ... \n", - "\n", - " SUBBLOCKKEY CORRIDORID \\\n", - "0 84073fa307bbfb12d66bc2a398381da5 11001402_2 \n", - "1 104e644e8a45e4f8f5fae8a522dfb492 11003602_6 \n", - "2 a686015e5346e258d9d532aca3fe0b96 None \n", - "3 4ee4ad33be2250ce8d95d389255b3424 11001402_1 \n", - "4 ccf5a699cde70078619692f752acad3c 12050892_1 \n", - "... ... ... \n", - "2004 0ce55da149ac9f9d93607887be614e3f 11051352_1 \n", - "2005 Route not found Route not found \n", - "2006 f21d99cb604ad1387dbcb38c044fd739 11001502_2 \n", - "2007 5e6c7d2133356808243f92a44b320ac8 12015342_1 \n", - "2008 0ccb17dad651356070da3931e3a1dfaf 11001602_2 \n", - "\n", - " NEARESTINTKEY MAJORINJURIESOTHER \\\n", - "0 73435d5fb8f812ed226b15ebaa9a88f0 0.0 \n", - "1 a38c5c59ffe947cd9e811e4da2f8d5c2 0.0 \n", - "2 0 0.0 \n", - "3 f63110cea700e723ffd3d38eb1b4814c 0.0 \n", - "4 40736cafb4216780e39074395946fe5a 0.0 \n", - "... ... ... \n", - "2004 850091b43e2caa128ef35eaa09d15c69 1.0 \n", - "2005 Route not found 0.0 \n", - "2006 d8d9019d5c5ec0f6fcb972b23e18ba1f 0.0 \n", - "2007 04eab17816b0ebe7fe88f4688908ed7c 0.0 \n", - "2008 6a2a2d1c161fc28a26349f908585926f 0.0 \n", - "\n", - " MINORINJURIESOTHER UNKNOWNINJURIESOTHER FATALOTHER OBJECTID \\\n", - "0 0.0 0.0 0.0 445287826 \n", - "1 0.0 0.0 0.0 445288297 \n", - "2 0.0 0.0 0.0 445288845 \n", - "3 0.0 0.0 0.0 445288994 \n", - "4 0.0 0.0 0.0 445289238 \n", - "... ... ... ... ... \n", - "2004 0.0 0.0 0.0 445522184 \n", - "2005 0.0 0.0 0.0 445522217 \n", - "2006 0.0 0.0 0.0 445522459 \n", - "2007 0.0 0.0 0.0 445522523 \n", - "2008 0.0 0.0 0.0 445522640 \n", - "\n", - " geometry REPORTDATE_ \n", - "0 POINT (-77.03273 38.94045) 2021-08-02 19:15:00-04:00 \n", - "1 POINT (-77.06985 38.94695) 2021-08-03 15:36:00-04:00 \n", - "2 POINT (-76.948 38.89634) 2021-08-04 11:59:00-04:00 \n", - "3 POINT (-77.03196 38.90339) 2021-08-05 07:40:00-04:00 \n", - "4 POINT (-77.00742 38.90252) 2021-08-04 20:55:00-04:00 \n", - "... ... ... \n", - "2004 POINT (-77.02581 38.94206) 2026-02-13 14:06:00-05:00 \n", - "2005 POINT (-77.00416 38.90565) 2026-02-18 09:45:00-05:00 \n", - "2006 POINT (-77.03454 38.91578) 2026-02-23 18:17:00-05:00 \n", - "2007 POINT (-76.98303 38.90007) 2026-02-21 19:20:00-05:00 \n", - "2008 POINT (-77.0365 38.91799) 2026-02-26 12:45:00-05:00 \n", - "\n", - "[2009 rows x 66 columns]" - ] - }, - "execution_count": 73, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "crashes_new = gpd.overlay(crashes_new, aoi_gdf[[\"geometry\"]], how=\"intersection\")\n", - "crashes_new['REPORTDATE_'] = pd.to_datetime(crashes_new[\"REPORTDATE\"], unit=\"ms\", utc=True).dt.tz_convert(\"America/New_York\")\n", - "crashes_new" - ] - }, - { - "cell_type": "code", - "execution_count": 74, - "id": "fdbe963a-d6f2-4d87-8673-d05a33e57beb", - "metadata": {}, - "outputs": [], - "source": [ - "crashes_new.to_file('crashes_dcdata.geojson')" - ] - }, - { - "cell_type": "code", - "execution_count": 76, - "id": "d29d67fc-3b26-4579-a565-739cd65b9600", - "metadata": {}, - "outputs": [], - "source": [ - "keep_columns = ['REPORTDATE_', 'ADDRESS', 'MAJORINJURIES_BICYCLIST', 'MINORINJURIES_BICYCLIST', 'UNKNOWNINJURIES_BICYCLIST','FATAL_BICYCLIST', 'TOTAL_BICYCLES', 'BICYCLISTSIMPAIRED', 'TOTAL_VEHICLES', 'TOTAL_PEDESTRIANS', 'geometry']\n", - "crashes_reduced = crashes_new[keep_columns]\n", - "crashes_reduced.to_file('crashes_reduced.geojson')" - ] - }, - { - "cell_type": "code", - "execution_count": 81, - "id": "62855a0b-645e-4cd1-80d4-c66e82009737", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "number of injuries and fatalities in the last 5 years:\n", - "MAJORINJURIES_BICYCLIST: 172\n", - "MINORINJURIES_BICYCLIST: 1849\n", - "UNKNOWNINJURIES_BICYCLIST: 5\n", - "FATAL_BICYCLIST: 8\n", - "total: 2034\n" - ] - } - ], - "source": [ - "print('number of injuries and fatalities in the last 5 years:')\n", - "inj = ['MAJORINJURIES_BICYCLIST', 'MINORINJURIES_BICYCLIST', 'UNKNOWNINJURIES_BICYCLIST','FATAL_BICYCLIST']\n", - "total= 0\n", - "for i in inj:\n", - " print(i+': '+str(sum(crashes_reduced[i])))\n", - " total = total + sum(crashes_reduced[i])\n", - "print('total: '+str(total))\n" - ] - }, - { - "cell_type": "code", - "execution_count": 82, - "id": "59f219bf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "joined\n", - "length of joined: 2810\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
crash_count_5yr
count13838.000000
mean0.198511
std0.646855
min0.000000
25%0.000000
50%0.000000
75%0.000000
max13.000000
\n", - "
" - ], - "text/plain": [ - " crash_count_5yr\n", - "count 13838.000000\n", - "mean 0.198511\n", - "std 0.646855\n", - "min 0.000000\n", - "25% 0.000000\n", - "50% 0.000000\n", - "75% 0.000000\n", - "max 13.000000" - ] - }, - "execution_count": 82, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 9) Crash counts → segments (buffered spatial join; handles no-spatial-index case)\n", - "\n", - "def count_crashes_near_segments(segments_gdf, crashes_gdf, buffer_m=10):\n", - " if crashes_gdf.empty or segments_gdf.empty:\n", - " segments_gdf[\"crash_count_5yr\"] = 0\n", - " return segments_gdf\n", - "\n", - " proj = \"EPSG:3857\" # meters\n", - " seg_p = segments_gdf.to_crs(proj).copy()\n", - " cr_p = crashes_gdf.to_crs(proj).copy()\n", - "\n", - " seg_p[\"buf\"] = seg_p.geometry.buffer(buffer_m)\n", - " seg_p = seg_p.set_geometry(\"buf\", crs=proj)\n", - "\n", - " try:\n", - " print('joined')\n", - " joined = gpd.sjoin(cr_p[[\"geometry\"]], seg_p[[\"buf\"]], how=\"left\", predicate=\"within\") #this will create multiple matches\n", - " print('length of joined: '+str(len(joined)))\n", - " except Exception as e:\n", - " # If spatial index missing, geopandas prints an rtree/pygeos message—fallback to brute force (slow but safe for MVP)\n", - " from shapely.prepared import prep\n", - " counts = []\n", - " prepped = [prep(g) for g in seg_p[\"buf\"]]\n", - " for pt in cr_p.geometry:\n", - " hits = [i for i, pg in enumerate(prepped) if pg.contains(pt)]\n", - " counts.extend(hits)\n", - " joined = pd.Series(counts).value_counts().rename_axis(\"index_right\").rename(\"size\").to_frame()\n", - "\n", - " seg_p[\"crash_count_5yr\"] = 0\n", - " seg_p.loc[joined.index, \"crash_count_5yr\"] = joined[\"size\"].values\n", - " return seg_p.drop(columns=[\"buf\"]).set_geometry(\"geometry\").to_crs(segments_gdf.crs)\n", - "\n", - " counts = joined.groupby(joined.index_right).size().rename(\"crash_count_5yr\")\n", - " seg_p = seg_p.drop(columns=[\"buf\"]).set_geometry(\"geometry\")\n", - " seg_p[\"crash_count_5yr\"] = counts.reindex(seg_p.index).fillna(0).astype(int)\n", - " return seg_p.to_crs(segments_gdf.crs)\n", - "\n", - "gdf = count_crashes_near_segments(gdf, crashes_new, buffer_m=CRASH_BUFFER_M)\n", - "gdf[\"serious_injury_count_5yr\"] = 0\n", - "gdf[\"fatal_count_5yr\"] = 0\n", - "gdf[[\"crash_count_5yr\"]].describe()" - ] - }, - { - "cell_type": "code", - "execution_count": 84, - "id": "efbed5fc-d51b-4246-af14-4bf3da2f6eca", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "segments with most crashes\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
route_idroute_namefunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presenceroad_widthslow_streetpavement_conditiongeometrylts_levellencrash_count_5yrserious_injury_count_5yrfatal_count_5yr
5501100140214TH ST NWMinor Arterial3325.025.0protected_trackTrue60NoneGoodLINESTRING Z (323805.757 4310841.384 0, 323805...1158.5723121300
416611050892K ST NWMinor Arterial3320.020.0buffered_laneTrue57NonePoorLINESTRING Z (325255.201 4307890.163 0, 325250...386.628948800
836110009029TH ST NWMinor Arterial3325.025.0protected_trackTrue54NoneExcellentLINESTRING Z (324504.955 4308431.516 0, 324505...1147.652490800
613812015342BENNING RD NEPrincipal/Primary Arterial8830.030.0noneFalse94NoneExcellentLINESTRING Z (328001.547 4307564.869 0, 328024...4173.938964800
8911050892K ST NWMinor Arterial3320.020.0noneTrue69NoneFairLINESTRING Z (324845.041 4307899.504 0, 324833...4174.413630800
.........................................................
18331100180218TH ST NWMinor Arterial2225.025.0noneTrue45NoneExcellentLINESTRING Z (322991.193 4309390.224 0, 322991...479.456192100
1363713057852M ST SEMinor Arterial6625.025.0noneFalse70NoneExcellentLINESTRING Z (326457.671 4304972.48 0, 326468....492.169768100
1363913074552RANDLE PL SECollector2220.020.0noneFalse25NoneExcellentLINESTRING Z (326606.324 4301397.974 0, 326609...4132.360287100
136471300300230TH ST SELocal2220.020.0noneTrue32NoneExcellentLINESTRING Z (329544.884 4304024.269 0, 329544...290.873276100
1383513084782TANNER ST SELocal2220.020.0noneTrue32NoneGoodLINESTRING Z (328042.732 4301705.289 0, 328046...286.436484100
\n", - "

1796 rows × 18 columns

\n", - "
" - ], - "text/plain": [ - " route_id route_name function num_lanes \\\n", - "550 11001402 14TH ST NW Minor Arterial 3 \n", - "4166 11050892 K ST NW Minor Arterial 3 \n", - "836 11000902 9TH ST NW Minor Arterial 3 \n", - "6138 12015342 BENNING RD NE Principal/Primary Arterial 8 \n", - "89 11050892 K ST NW Minor Arterial 3 \n", - "... ... ... ... ... \n", - "1833 11001802 18TH ST NW Minor Arterial 2 \n", - "13637 13057852 M ST SE Minor Arterial 6 \n", - "13639 13074552 RANDLE PL SE Collector 2 \n", - "13647 13003002 30TH ST SE Local 2 \n", - "13835 13084782 TANNER ST SE Local 2 \n", - "\n", - " num_lanes_raw speed_limit speed_limit_raw bike_facility_type \\\n", - "550 3 25.0 25.0 protected_track \n", - "4166 3 20.0 20.0 buffered_lane \n", - "836 3 25.0 25.0 protected_track \n", - "6138 8 30.0 30.0 none \n", - "89 3 20.0 20.0 none \n", - "... ... ... ... ... \n", - "1833 2 25.0 25.0 none \n", - "13637 6 25.0 25.0 none \n", - "13639 2 20.0 20.0 none \n", - "13647 2 20.0 20.0 none \n", - "13835 2 20.0 20.0 none \n", - "\n", - " parking_presence road_width slow_street pavement_condition \\\n", - "550 True 60 None Good \n", - "4166 True 57 None Poor \n", - "836 True 54 None Excellent \n", - "6138 False 94 None Excellent \n", - "89 True 69 None Fair \n", - "... ... ... ... ... \n", - "1833 True 45 None Excellent \n", - "13637 False 70 None Excellent \n", - "13639 False 25 None Excellent \n", - "13647 True 32 None Excellent \n", - "13835 True 32 None Good \n", - "\n", - " geometry lts_level \\\n", - "550 LINESTRING Z (323805.757 4310841.384 0, 323805... 1 \n", - "4166 LINESTRING Z (325255.201 4307890.163 0, 325250... 3 \n", - "836 LINESTRING Z (324504.955 4308431.516 0, 324505... 1 \n", - "6138 LINESTRING Z (328001.547 4307564.869 0, 328024... 4 \n", - "89 LINESTRING Z (324845.041 4307899.504 0, 324833... 4 \n", - "... ... ... \n", - "1833 LINESTRING Z (322991.193 4309390.224 0, 322991... 4 \n", - "13637 LINESTRING Z (326457.671 4304972.48 0, 326468.... 4 \n", - "13639 LINESTRING Z (326606.324 4301397.974 0, 326609... 4 \n", - "13647 LINESTRING Z (329544.884 4304024.269 0, 329544... 2 \n", - "13835 LINESTRING Z (328042.732 4301705.289 0, 328046... 2 \n", - "\n", - " len crash_count_5yr serious_injury_count_5yr fatal_count_5yr \n", - "550 158.572312 13 0 0 \n", - "4166 86.628948 8 0 0 \n", - "836 147.652490 8 0 0 \n", - "6138 173.938964 8 0 0 \n", - "89 174.413630 8 0 0 \n", - "... ... ... ... ... \n", - "1833 79.456192 1 0 0 \n", - "13637 92.169768 1 0 0 \n", - "13639 132.360287 1 0 0 \n", - "13647 90.873276 1 0 0 \n", - "13835 86.436484 1 0 0 \n", - "\n", - "[1796 rows x 18 columns]" - ] - }, - "execution_count": 84, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "print('segments with most crashes')\n", - "gdf[gdf['crash_count_5yr']>0].sort_values(by='crash_count_5yr', ascending = False)" - ] - }, - { - "cell_type": "code", - "execution_count": 85, - "id": "2463b802", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
s_LTSs_crashs_facilityridescore_v1
count13838.013838.013838.013838.0
mean50.987.00.556.7
std30.233.61.722.0
min10.00.00.06.0
25%10.0100.00.036.0
50%75.0100.00.075.0
75%75.0100.00.075.0
max100.0100.010.091.0
\n", - "
" - ], - "text/plain": [ - " s_LTS s_crash s_facility ridescore_v1\n", - "count 13838.0 13838.0 13838.0 13838.0\n", - "mean 50.9 87.0 0.5 56.7\n", - "std 30.2 33.6 1.7 22.0\n", - "min 10.0 0.0 0.0 6.0\n", - "25% 10.0 100.0 0.0 36.0\n", - "50% 75.0 100.0 0.0 75.0\n", - "75% 75.0 100.0 0.0 75.0\n", - "max 100.0 100.0 10.0 91.0" - ] - }, - "execution_count": 85, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 10) RideScore (0–100)\n", - "\n", - "def p95(values):\n", - " s = sorted([int(v) for v in values if pd.notnull(v)])\n", - " if not s: return 1\n", - " k = int(round(0.95 * (len(s) - 1)))\n", - " return max(s[k], 1)\n", - "\n", - "def lts_to_score(x): return {1:100, 2:75, 3:40, 4:10}.get(int(x), 10)\n", - "\n", - "facility_bonus = {\"protected_track\":10, \"separated_lane\":10, \"buffered_lane\":5, \"painted_lane\":3, \"shared\":0, \"none\":0}\n", - "\n", - "P95_CRASH = p95(gdf[\"crash_count_5yr\"])\n", - "def crash_inv(n): return 100.0 * (1.0 - min(max(float(n)/float(P95_CRASH), 0.0), 1.0))\n", - "\n", - "W_LTS, W_CRASH, W_FAC = 0.6, 0.3, 0.1\n", - "\n", - "gdf[\"s_LTS\"] = gdf[\"lts_level\"].map(lts_to_score)\n", - "gdf[\"s_crash\"] = gdf[\"crash_count_5yr\"].map(crash_inv)\n", - "gdf[\"s_facility\"] = gdf[\"bike_facility_type\"].map(facility_bonus).fillna(0)\n", - "gdf[\"ridescore_v1\"] = (W_LTS*gdf.s_LTS + W_CRASH*gdf.s_crash + W_FAC*gdf.s_facility).round(1)\n", - "\n", - "gdf[[\"s_LTS\",\"s_crash\",\"s_facility\",\"ridescore_v1\"]].describe().round(1)" - ] - }, - { - "cell_type": "code", - "execution_count": 86, - "id": "55ad5c7b-0549-45fc-8d3e-9d7a5212f305", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "(array([ 938., 0., 147., 3445., 608., 1459., 103., 0., 6956.,\n", - " 182.]),\n", - " array([ 6. , 14.5, 23. , 31.5, 40. , 48.5, 57. , 65.5, 74. , 82.5, 91. ]),\n", - " )" - ] - }, - "execution_count": 86, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjEAAAGdCAYAAADjWSL8AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAJitJREFUeJzt3X1QlXXex/Ev8SS4QCoCslnaLmMY9DDYKNQG9yqoq7mNO2lZZJOrlgZSuj7kzmTNJkoTusWsqetkKS79o22bZuJWbC4oZMum+FA7kWGCWMuTZmB47vn+7jnXzQGzUOPwg/dr5hfnus6Xw3XO1ZEPv4fr+LhcLpcAAABY5ipvHwAAAMClIMQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKzkJz3U+fPn5cSJExISEiI+Pj7ePhwAAPAD6DV4m5qaJDo6Wq666qreGWI0wAwePNjbhwEAAC5BVVWVXHPNNb0zxGgPjPtFCA0N9fbhAACAH6CxsdF0Qrh/j/fKEOMeQtIAQ4gBAMAuP2QqCBN7AQCAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAICeH2KGDBliLj7Tvs2dO9f5vINly5aZzzsICgqSlJQUqaio8HiM5uZmycjIkPDwcOnbt69MmjRJjh8/7lFTV1cn6enpEhYWZprerq+vvxLPFwAA9MYQU1ZWJtXV1U4rLCw0+++55x7zNScnR3JzcyUvL8/URkVFSWpqqvkgJ7esrCzZtm2bFBQUyJ49e+T06dMyceJEaW1tdWqmTZsm5eXlsnPnTtP0tgYZAAAAh+syzJs3z/Wzn/3Mdf78edOioqJcK1ascO7/5ptvXGFhYa6XXnrJbNfX17v8/f1dBQUFTs0XX3zhuuqqq1w7d+4024cOHXLpYe3du9epKSkpMfuOHDnyg4+toaHBfI9+BQAAdujM7+9LnhPT0tIimzdvlocfftgMKVVWVkpNTY2kpaU5NYGBgZKcnCzFxcVme//+/XLu3DmPGh16iouLc2pKSkrMENLIkSOdmlGjRpl97poL0WEq/dCotg0AAPRclxxiXn/9dTNP5aGHHjLbGmBUZGSkR51uu+/TrwEBAdKvX7+L1kRERHT4ebrPXXMh2dnZzhwabfoJmAAAoOe65BCzYcMGGT9+vOlJudinTupk3+/7JMr2NReq/77HWbJkiTQ0NDitqqqqE88GAADYxu9SvunYsWOye/du2bp1q7NPJ/Eq7S0ZNGiQs7+2ttbpndEaHYbS1Udte2O0Jikpyak5efJkh5956tSpDr08benQlTYAQO82ZPF2sdFnKyZ4+xB6R0/Myy+/bIZ3Jkz4/xd86NChJoC4VywpDSxFRUVOQElISBB/f3+PGl3ldPDgQacmMTHR9KSUlpY6Nfv27TP73DUAAACd7ok5f/68CTHTp08XP7///3Yd6tHl08uXL5eYmBjT9HZwcLBZMq10rsqMGTNk/vz5MmDAAOnfv78sWLBA4uPjZcyYMaYmNjZWxo0bJzNnzpS1a9eafbNmzTLLsIcNG8YZAwAAlxZidBjp888/N6uS2lu4cKGcPXtW5syZY4aMdIXRrl27JCQkxKlZtWqVCT9TpkwxtaNHj5aNGzeKr6+vU5Ofny+ZmZnOKia9IJ5eewYAAMDNR9dZSw+kS6y150eHoUJDQ719OACALsKcmN7z+5vPTgIAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAAD0jhDzxRdfyAMPPCADBgyQ4OBgueWWW2T//v3O/S6XS5YtWybR0dESFBQkKSkpUlFR4fEYzc3NkpGRIeHh4dK3b1+ZNGmSHD9+3KOmrq5O0tPTJSwszDS9XV9ffznPFQAA9NYQo8Hi9ttvF39/f3nrrbfk0KFD8vzzz8vVV1/t1OTk5Ehubq7k5eVJWVmZREVFSWpqqjQ1NTk1WVlZsm3bNikoKJA9e/bI6dOnZeLEidLa2urUTJs2TcrLy2Xnzp2m6W0NMgAAAMrHpV0nP9DixYvln//8p7z//vsXvF8fSntgNKQsWrTI6XWJjIyUlStXyuzZs6WhoUEGDhwomzZtkqlTp5qaEydOyODBg2XHjh0yduxYOXz4sAwfPlz27t0rI0eONDV6OzExUY4cOSLDhg373mNtbGw0PTj680JDQznbANBLDFm8XWz02YoJ3j6EbqEzv7871RPzxhtvyIgRI+See+6RiIgIufXWW2X9+vXO/ZWVlVJTUyNpaWnOvsDAQElOTpbi4mKzrUNP586d86jR4BMXF+fUlJSUmCfgDjBq1KhRZp+7BgAA9G6dCjGffvqprFmzRmJiYuTtt9+WRx55RDIzM+XVV18192uAUdrz0pZuu+/TrwEBAdKvX7+L1mhIak/3uWva0x4fTW9tGwAA6Ln8OlN8/vx50xOzfPlys609MTppV4PNgw8+6NT5+Ph0GGZqv6+99jUXqr/Y42RnZ8vTTz/dmacDAAB6S0/MoEGDzFyVtmJjY+Xzzz83t3USr2rfW1JbW+v0zmhNS0uLmSR8sZqTJ092+PmnTp3q0MvjtmTJEjN+5m5VVVWdeWoAAKAnhxhdmXT06FGPfR9//LFcd9115vbQoUNNACksLHTu18BSVFQkSUlJZjshIcGsbmpbU11dLQcPHnRqdAKvBpHS0lKnZt++fWafu6Y9nXujE4DaNgAA0HN1ajjp8ccfNyFCh5OmTJliQsa6detMUzrUoyuT9H6dN6NNb+v1ZHTJtNLJuTNmzJD58+eba830799fFixYIPHx8TJmzBind2fcuHEyc+ZMWbt2rdk3a9Ysswz7h6xMAgAAPV+nQsxtt91mru+iQzfPPPOM6XlZvXq13H///U7NwoUL5ezZszJnzhwzZKQrjHbt2iUhISFOzapVq8TPz88EIa0dPXq0bNy4UXx9fZ2a/Px8M2nYvYpJL4in154BAADo9HVibMJ1YgCgd+I6MXb70a4TAwAA0F0QYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAAA9P8QsW7ZMfHx8PFpUVJRzv8vlMjXR0dESFBQkKSkpUlFR4fEYzc3NkpGRIeHh4dK3b1+ZNGmSHD9+3KOmrq5O0tPTJSwszDS9XV9ff7nPFQAA9OaemBtvvFGqq6udduDAAee+nJwcyc3Nlby8PCkrKzMBJzU1VZqampyarKws2bZtmxQUFMiePXvk9OnTMnHiRGltbXVqpk2bJuXl5bJz507T9LYGGQAAADc/6SQ/Pz+P3pe2vTCrV6+WpUuXyuTJk82+V155RSIjI2XLli0ye/ZsaWhokA0bNsimTZtkzJgxpmbz5s0yePBg2b17t4wdO1YOHz5sgsvevXtl5MiRpmb9+vWSmJgoR48elWHDhnX2kAEAQA/U6Z6YTz75xAwXDR06VO6991759NNPzf7KykqpqamRtLQ0pzYwMFCSk5OluLjYbO/fv1/OnTvnUaOPFRcX59SUlJSYISR3gFGjRo0y+9w1F6LDVI2NjR4NAAD0XJ0KMRosXn31VXn77bdN74iGlqSkJPnqq6/MbaU9L23ptvs+/RoQECD9+vW7aE1ERESHn6373DUXkp2d7cyh0aa9OwAAoOfqVIgZP368/OY3v5H4+HgzHLR9+3Zn2MhNJ/u2H2Zqv6+99jUXqv++x1myZIkZrnK3qqqqzjw1AADQm5ZY6+oiDTQ6xOSeJ9O+t6S2ttbpndGalpYWs/roYjUnT57s8LNOnTrVoZenLR26Cg0N9WgAAKDnuqwQo/NQdCLuoEGDzBwZDSCFhYXO/RpYioqKzJCTSkhIEH9/f48aXeF08OBBp0Yn8GpPSmlpqVOzb98+s89dAwAA0KnVSQsWLJC77rpLrr32WtN78oc//MFMoJ0+fboZ6tHl08uXL5eYmBjT9HZwcLBZMq10rsqMGTNk/vz5MmDAAOnfv795TPfwlIqNjZVx48bJzJkzZe3atWbfrFmzzDJsViYBAIBLCjF6Ubr77rtPvvzySxk4cKBZNaRLoa+77jpz/8KFC+Xs2bMyZ84cM2SkE4F37dolISEhzmOsWrXKLNOeMmWKqR09erRs3LhRfH19nZr8/HzJzMx0VjHpBfH02jMAAABuPi6dMdsDaQ+R9vzoMBTzYwCg9xiy+P8WndjmsxUTvH0I1v3+5rOTAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAgN4XYrKzs8XHx0eysrKcfS6XS5YtWybR0dESFBQkKSkpUlFR4fF9zc3NkpGRIeHh4dK3b1+ZNGmSHD9+3KOmrq5O0tPTJSwszDS9XV9ffzmHCwAAepBLDjFlZWWybt06uemmmzz25+TkSG5uruTl5ZmaqKgoSU1NlaamJqdGQ8+2bdukoKBA9uzZI6dPn5aJEydKa2urUzNt2jQpLy+XnTt3mqa3NcgAAABccojR0HH//ffL+vXrpV+/fh69MKtXr5alS5fK5MmTJS4uTl555RX5+uuvZcuWLaamoaFBNmzYIM8//7yMGTNGbr31Vtm8ebMcOHBAdu/ebWoOHz5sgsuf//xnSUxMNE1/1ptvvilHjx7lzAEAgEsLMXPnzpUJEyaYENJWZWWl1NTUSFpamrMvMDBQkpOTpbi42Gzv379fzp0751GjQ08aeNw1JSUlZghp5MiRTs2oUaPMPndNezpE1djY6NEAAEDP5dfZb9AhoA8//NAMFbWnAUZFRkZ67NftY8eOOTUBAQEePTjuGvf369eIiIgOj6/73DUXmp/z9NNPd/bpAACA3tATU1VVJfPmzTPDP3369PnOOp3s25YOM7Xf1177mgvVX+xxlixZYoaq3E2PFQAA9FydCjE6FFRbWysJCQni5+dnWlFRkbzwwgvmtrsHpn1viX6P+z6d6NvS0mJWH12s5uTJkx1+/qlTpzr08rQdtgoNDfVoAACg5+pUiBk9erSZgKsrhdxtxIgRZpKv3r7++utNACksLHS+RwOLBp2kpCSzrQHI39/fo6a6uloOHjzo1OhEXu1NKS0tdWr27dtn9rlrAABA79apOTEhISFmAm5bep2XAQMGOPt1+fTy5cslJibGNL0dHBxslkwrnZw7Y8YMmT9/vvm+/v37y4IFCyQ+Pt6ZKBwbGyvjxo2TmTNnytq1a82+WbNmmWXYw4YNu1LPHQAA9KaJvd9n4cKFcvbsWZkzZ44ZMtIVRrt27TIByG3VqlVm+GnKlCmmVnt4Nm7cKL6+vk5Nfn6+ZGZmOquY9IJ4eu0ZAAAA5ePS2bI9kC6x1l4fHYJifgwA9B5DFm8XG322YoK3D8G63998dhIAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAAr+Xn7AICeZsji7WKbz1ZM8PYhAECn0RMDAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAAen6IWbNmjdx0000SGhpqWmJiorz11lvO/S6XS5YtWybR0dESFBQkKSkpUlFR4fEYzc3NkpGRIeHh4dK3b1+ZNGmSHD9+3KOmrq5O0tPTJSwszDS9XV9ff7nPFQAA9NYQc80118iKFSvkgw8+MO2Xv/yl/PrXv3aCSk5OjuTm5kpeXp6UlZVJVFSUpKamSlNTk/MYWVlZsm3bNikoKJA9e/bI6dOnZeLEidLa2urUTJs2TcrLy2Xnzp2m6W0NMgAAAG4+Lu0+uQz9+/eX5557Th5++GHTA6MhZdGiRU6vS2RkpKxcuVJmz54tDQ0NMnDgQNm0aZNMnTrV1Jw4cUIGDx4sO3bskLFjx8rhw4dl+PDhsnfvXhk5cqSp0dva63PkyBEZNmzYDzquxsZG04ujP1N7jYCuMmTxdute7M9WTPD2IQC9+j2oeB92/vf3Jc+J0Z4T7U05c+aMCRiVlZVSU1MjaWlpTk1gYKAkJydLcXGx2d6/f7+cO3fOo0aDT1xcnFNTUlJiDt4dYNSoUaPMPnfNhWhg0ifetgEAgJ6r0yHmwIED8pOf/MQElEceecQMDWnPiQYYpT0vbem2+z79GhAQIP369btoTURERIefq/vcNReSnZ3tzKHRpr07AACg5+p0iNHhHJ2jokM8jz76qEyfPl0OHTrk3O/j4+NRr6NV7fe1177mQvXf9zhLliwxXU/uVlVV1clnBgAAenSI0Z6Un//85zJixAjT+3HzzTfLH//4RzOJV7XvLamtrXV6Z7SmpaXFrD66WM3Jkyc7/NxTp0516OVpS3uG3Kum3A0AAPRcl32dGO0h0fkoQ4cONQGksLDQuU8DS1FRkSQlJZnthIQE8ff396iprq6WgwcPOjU6v0Z7UkpLS52affv2mX3uGgAAAL/OvARPPvmkjB8/3sw30WXTOrH3vffeM8ugdahHVyYtX75cYmJiTNPbwcHBZsm00rkqM2bMkPnz58uAAQPMyqYFCxZIfHy8jBkzxtTExsbKuHHjZObMmbJ27Vqzb9asWWYZ9g9dmQQAAHq+ToUYHebR67Vo74kGEr3wnQYYvRaMWrhwoZw9e1bmzJljhox0hdGuXbskJCTEeYxVq1aJn5+fTJkyxdSOHj1aNm7cKL6+vk5Nfn6+ZGZmOquY9IJ4eu0ZAACAK3admO6K68TAW2y8RgXXp0BPYuN7UPE+7MLrxAAAAHgTIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAADQ80NMdna23HbbbRISEiIRERFy9913y9GjRz1qXC6XLFu2TKKjoyUoKEhSUlKkoqLCo6a5uVkyMjIkPDxc+vbtK5MmTZLjx4971NTV1Ul6erqEhYWZprfr6+sv57kCAIDeGmKKiopk7ty5snfvXiksLJRvv/1W0tLS5MyZM05NTk6O5ObmSl5enpSVlUlUVJSkpqZKU1OTU5OVlSXbtm2TgoIC2bNnj5w+fVomTpwora2tTs20adOkvLxcdu7caZre1iADAACgfFzadXKJTp06ZXpkNNzceeedphdGe2A0pCxatMjpdYmMjJSVK1fK7NmzpaGhQQYOHCibNm2SqVOnmpoTJ07I4MGDZceOHTJ27Fg5fPiwDB8+3ISlkSNHmhq9nZiYKEeOHJFhw4Z977E1NjaaHhz9eaGhoZxtdJkhi7db92p/tmKCtw8B6NXvQcX7sPO/vy9rToz+ANW/f3/ztbKyUmpqakzvjFtgYKAkJydLcXGx2d6/f7+cO3fOo0aDT1xcnFNTUlJinoA7wKhRo0aZfe6a9jQs6RNv2wAAQM91ySFGe12eeOIJueOOO0wAURpglPa8tKXb7vv0a0BAgPTr1++iNdrD057uc9dcaL6Oe/6MNu3ZAQAAPdclh5jHHntMPvroI/nLX/7S4T4fH58Ogaf9vvba11yo/mKPs2TJEtMz5G5VVVWdeDYAAKBXhBhdWfTGG2/Iu+++K9dcc42zXyfxqva9JbW1tU7vjNa0tLSY1UcXqzl58uQF5+C07+VpO2ylY2dtGwAA6Lk6FWK0J0R7YLZu3SrvvPOODB061ON+3dYAoiuX3DSw6MTfpKQks52QkCD+/v4eNdXV1XLw4EGnRifwam9KaWmpU7Nv3z6zz10DAAB6N7/OFOvy6i1btshf//pXc60Yd4+LzkHRa8LoUI+uTFq+fLnExMSYpreDg4PNkml37YwZM2T+/PkyYMAAMyl4wYIFEh8fL2PGjDE1sbGxMm7cOJk5c6asXbvW7Js1a5ZZhv1DViYBAICer1MhZs2aNearXsCurZdfflkeeughc3vhwoVy9uxZmTNnjhky0hVGu3btMqHHbdWqVeLn5ydTpkwxtaNHj5aNGzeKr6+vU5Ofny+ZmZnOKia9IJ5eewYAAOCyrxPTnXGdGHiLjdeo4PoU6ElsfA8q3oddfJ0YAAAAbyHEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEp+3j4AALgUQxZvt+6F+2zFBG8fAtCj0BMDAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAvSPE/OMf/5C77rpLoqOjxcfHR15//XWP+10ulyxbtszcHxQUJCkpKVJRUeFR09zcLBkZGRIeHi59+/aVSZMmyfHjxz1q6urqJD09XcLCwkzT2/X19Zf6PAEAQG8PMWfOnJGbb75Z8vLyLnh/Tk6O5ObmmvvLysokKipKUlNTpampyanJysqSbdu2SUFBgezZs0dOnz4tEydOlNbWVqdm2rRpUl5eLjt37jRNb2uQAQAAUH6dfRnGjx9v2oVoL8zq1atl6dKlMnnyZLPvlVdekcjISNmyZYvMnj1bGhoaZMOGDbJp0yYZM2aMqdm8ebMMHjxYdu/eLWPHjpXDhw+b4LJ3714ZOXKkqVm/fr0kJibK0aNHZdiwYZw9AAB6uSs6J6ayslJqamokLS3N2RcYGCjJyclSXFxstvfv3y/nzp3zqNGhp7i4OKempKTEDCG5A4waNWqU2eeuAQAAvVune2IuRgOM0p6XtnT72LFjTk1AQID069evQ437+/VrREREh8fXfe6a9nSejTa3xsbGK/CMAABAr1qdpBN+2w8ztd/XXvuaC9Vf7HGys7OdScDadHgKAAD0XFc0xOgkXtW+t6S2ttbpndGalpYWs/roYjUnT57s8PinTp3q0MvjtmTJEjPfxt2qqqqu2PMCAAA9PMQMHTrUBJDCwkJnnwaWoqIiSUpKMtsJCQni7+/vUVNdXS0HDx50anQCrwaR0tJSp2bfvn1mn7umPZ17Exoa6tEAAEDP1ek5Mboc+j//+Y/HZF5d/ty/f3+59tprzfLp5cuXS0xMjGl6Ozg42CyZVjrUM2PGDJk/f74MGDDAfN+CBQskPj7eWa0UGxsr48aNk5kzZ8ratWvNvlmzZpll2N1lZdKQxdvFNp+tmODtQwAAwHsh5oMPPpD/+Z//cbafeOIJ83X69OmyceNGWbhwoZw9e1bmzJljhox0hdGuXbskJCTE+Z5Vq1aJn5+fTJkyxdSOHj3afK+vr69Tk5+fL5mZmc4qJr0g3nddmwYAAPQ+nQ4xegVenWD7XXTirV6xV9t36dOnj7z44oumfRftodHrxwAAAFwIn50EAACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCU/bx8AAO8bsni7tw8BADqNnhgAAGAlQgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACs5OftAwAAACJDFm+37mX4bMUEr/58emIAAICV6IlBt2bjXyYAgK5BTwwAALASPTEA0EVs7Fn09pwHwOqemD/96U8ydOhQ6dOnjyQkJMj777/v7UMCAADdQLcOMa+99ppkZWXJ0qVL5V//+pf84he/kPHjx8vnn3/u7UMDAABe1q1DTG5ursyYMUN++9vfSmxsrKxevVoGDx4sa9as8fahAQAAL+u2c2JaWlpk//79snjxYo/9aWlpUlxc3KG+ubnZNLeGhgbztbGx8Uc5vvPNX4ttfqzX4sdk4+sM9CT8u4Gu/v/D/Zgul8veEPPll19Ka2urREZGeuzX7Zqamg712dnZ8vTTT3fYrz03+D9hq3klAHQO/27AW/9/NDU1SVhYmJ0hxs3Hx8djW5NZ+31qyZIl8sQTTzjb58+fl//+978yYMCAC9bjx6dpWkNkVVWVhIaG8pJ3U5wnO3Ce7MB5unz6e14DTHR09PfWdtsQEx4eLr6+vh16XWprazv0zqjAwEDT2rr66qt/9OPE99MAQ4jp/jhPduA82YHzdHm+rwem20/sDQgIMEuqCwsLPfbrdlJSkteOCwAAdA/dtidG6fBQenq6jBgxQhITE2XdunVmefUjjzzi7UMDAABe1q1DzNSpU+Wrr76SZ555RqqrqyUuLk527Ngh1113nbcPDT+ADu899dRTHYb50L1wnuzAebID56lr+bh+yBomAACAbqbbzokBAAC4GEIMAACwEiEGAABYiRADAACsRIjBZdGPe7jtttskJCREIiIi5O6775ajR4961Ojc8WXLlpmrLwYFBUlKSopUVFTwynv5vOmVrPVT4jlP3csXX3whDzzwgLnaeHBwsNxyyy3mc+TceD9537fffiu///3vZejQoebftOuvv96sotUrxbtxnroGIQaXpaioSObOnSt79+41FyLUN7d+SOeZM2ecmpycHPOJ5Hl5eVJWViZRUVGSmppqLiuNrqfnQK+5dNNNN3ns5zx5X11dndx+++3i7+8vb731lhw6dEief/55j6uPc568b+XKlfLSSy+Zf9MOHz5szslzzz0nL774olPDeeoiusQauFJqa2t1yb6rqKjIbJ8/f94VFRXlWrFihVPzzTffuMLCwlwvvfQSL3wXa2pqcsXExLgKCwtdycnJrnnz5nGeupFFixa57rjjju+8n/dT9zBhwgTXww8/7LFv8uTJrgceeMDc5jx1HXpicEU1NDSYr/379zdfKysrzedfae9M24tBJScnS3FxMa9+F9NeswkTJsiYMWM89nOeuoc33njDXKH8nnvuMcOzt956q6xfv965n/PUPdxxxx3y97//XT7++GOz/e9//1v27Nkjv/rVr8w256nrdOsr9sIuOgasHxWhb3C9urJyf4Bn+w/t1O1jx4555Th7q4KCAvnwww/NcFJ7nKfu4dNPP5U1a9aY99GTTz4ppaWlkpmZaYL/gw8+yHnqJhYtWmT+YLvhhhvMBxW3trbKs88+K/fdd5+5n/dT1yHE4Ip57LHH5KOPPjJ/kbSnk0jbB572+/Djqaqqknnz5smuXbukT58+31nHefIunRiqPTHLly8329oTo5PgNdhoiHHjPHnXa6+9Jps3b5YtW7bIjTfeKOXl5WaSvC5emD59ulPHefrxMZyEKyIjI8N0hb/77rtyzTXXOPt1Em/bv0zcamtrO/TO4Mejq1v0NddPhvfz8zNNJ2W/8MIL5rb7XHCevGvQoEEyfPhwj32xsbHmg28V76fu4Xe/+50sXrxY7r33XomPjzcfVPz444+bVX+K89R1CDG4LNqjoj0wW7dulXfeeccsOWxLt/UNrSuX3FpaWswv0KSkJF79LjJ69Gg5cOCA+YvR3fQv/vvvv9/c1iWinCfv05VJ7S9RoPMu3B96y/upe/j666/lqqs8f33qsJJ7iTXnqQt14SRi9ECPPvqoWWn03nvvuaqrq5329ddfOzW6Mklrtm7d6jpw4IDrvvvucw0aNMjV2Njo1WPv7dquTlKcJ+8rLS11+fn5uZ599lnXJ5984srPz3cFBwe7Nm/e7NRwnrxv+vTprp/+9KeuN99801VZWWn+bQsPD3ctXLjQqeE8dQ1CDC7vfyCRC7aXX37ZqdHlhk899ZRZah0YGOi68847TZhB9woxnKfu4W9/+5srLi7OvFduuOEG17p16zzu5zx5n/4Bpu+da6+91tWnTx/X9ddf71q6dKmrubnZqeE8dQ0f/U9X9vwAAABcCcyJAQAAViLEAAAAKxFiAACAlQgxAADASoQYAABgJUIMAACwEiEGAABYiRADAACsRIgBAABWIsQAAAArEWIAAICVCDEAAEBs9L86pGs/2KsFMQAAAABJRU5ErkJggg==", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plt.hist(gdf['ridescore_v1'])" - ] - }, - { - "cell_type": "code", - "execution_count": 87, - "id": "8a695ee2-f51e-4842-a407-e5ae6b1e5839", - "metadata": {}, - "outputs": [], - "source": [ - "gdf.to_file('gdf_withScore_dcdata.geojson')" - ] - }, - { - "cell_type": "code", - "execution_count": 88, - "id": "49a6f8a7-07ab-4a58-908d-83bf6b4ce219", - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
pavement_conditionpavement_condition_score
0Excellent100
1Excellent100
2Good75
3None50
4Excellent100
.........
13833Poor25
13834Excellent100
13835Good75
13836Excellent100
13837None50
\n", - "

13838 rows × 2 columns

\n", - "
" - ], - "text/plain": [ - " pavement_condition pavement_condition_score\n", - "0 Excellent 100\n", - "1 Excellent 100\n", - "2 Good 75\n", - "3 None 50\n", - "4 Excellent 100\n", - "... ... ...\n", - "13833 Poor 25\n", - "13834 Excellent 100\n", - "13835 Good 75\n", - "13836 Excellent 100\n", - "13837 None 50\n", - "\n", - "[13838 rows x 2 columns]" - ] - }, - "execution_count": 88, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#value to scale\n", - "\n", - "#lts to lts_score (already done)\n", - "gdf['lts_score'] = gdf['s_LTS']\n", - "\n", - "#speed limit (if no value- speed is 25- too positive?)\n", - "def speedlimit_to_score(x):\n", - " return 100-(2*x)\n", - "gdf[\"speedlimit_score\"] = gdf[\"speed_limit\"].map(speedlimit_to_score)\n", - "\n", - "#number of lanes, blank goes to 10 score\n", - "def num_lanes_to_score(x): return {0:100, 1:100, 2:75, 3:50, 4:25, 5:25, 6:0, 7:0, 8:0, 10:0}.get(int(x), 10)\n", - "gdf[\"num_lanes_score\"] = gdf[\"num_lanes_raw\"].map(num_lanes_to_score)\n", - "\n", - "#bike lanes\n", - "def facility_to_score(x): return {'protected_track':100, 'buffered_lane':75, 'painted_lane': 50, 'none': 0}.get(x, 0)\n", - "gdf[\"facility_score\"] = gdf[\"bike_facility_type\"].map(facility_to_score)\n", - "\n", - "#road type\n", - "def function_to_score(x): return {'Local': 100, 'Collector': 75, 'Minor Arterial':50, \n", - " 'Principal/Primary Arterial':25, 'Other Freeway and Expressway': 0,\n", - " 'Interstate':0, 'Other':0}.get(x, 0)\n", - "gdf[\"function_score\"] = gdf[\"function\"].map(function_to_score)\n", - "\n", - "#road width\n", - "def road_width_to_score(x):\n", - " return 100-x\n", - "gdf[\"road_width_score\"] = gdf[\"road_width\"].map(road_width_to_score)\n", - "\n", - "#slow street- seems to have ended in 2021\n", - "\n", - "#pavement condition\n", - "def pavement_condition_to_score(x): return {'Excellent': 100, 'Good': 75, 'Fair':50, \n", - " 'Poor':25,'Very Poor': 0}.get(x, 50)\n", - "gdf[\"pavement_condition_score\"] = gdf[\"pavement_condition\"].map(pavement_condition_to_score)\n", - "\n", - "gdf[['pavement_condition', 'pavement_condition_score']]" - ] - }, - { - "cell_type": "code", - "execution_count": 89, - "id": "da910c7f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Render features: 13834\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
route_idroute_namefunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presenceroad_width...s_crashs_facilityridescore_v1lts_scorespeedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_score
011064022NEVADA AVE NWCollector2220.020.0noneTrue33...100.0036.01060.07507567100
11100100210TH ST NWCollector1125.0NaNpainted_laneTrue31...100.0375.37550.0100507569100
\n", - "

2 rows × 29 columns

\n", - "
" - ], - "text/plain": [ - " route_id route_name function num_lanes num_lanes_raw speed_limit \\\n", - "0 11064022 NEVADA AVE NW Collector 2 2 20.0 \n", - "1 11001002 10TH ST NW Collector 1 1 25.0 \n", - "\n", - " speed_limit_raw bike_facility_type parking_presence road_width ... \\\n", - "0 20.0 none True 33 ... \n", - "1 NaN painted_lane True 31 ... \n", - "\n", - " s_crash s_facility ridescore_v1 lts_score speedlimit_score \\\n", - "0 100.0 0 36.0 10 60.0 \n", - "1 100.0 3 75.3 75 50.0 \n", - "\n", - " num_lanes_score facility_score function_score road_width_score \\\n", - "0 75 0 75 67 \n", - "1 100 50 75 69 \n", - "\n", - " pavement_condition_score \n", - "0 100 \n", - "1 100 \n", - "\n", - "[2 rows x 29 columns]" - ] - }, - "execution_count": 89, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "# 10A) Build a lean render GeoDataFrame\n", - "\n", - "# === knobs you can tweak ===\n", - "SIMPLIFY_TOL_M = 4 # simplify by ~4 meters\n", - "ROUND_COORDS = 5 # round lon/lat (~1 m)\n", - "MIN_LENGTH_M = 8 # drop tiny segments\n", - "KEEP_FIELDS = gdf.columns # keep all\n", - "#[\"crash_count_5yr\",\"parking_presence\",\"num_lanes_raw\", \"speed_limit_raw\", \"bike_facility_type\", \"route_id\", \"lts_level\", \"ridescore_v1\", \"geometry\"]\n", - "#[\"segment_id\", \"lts_level\", \"ridescore_v1\", \"geometry\"]\n", - "FILTER_SCORE_MIN = None # e.g., 20\n", - "FILTER_SCORE_MAX = None # e.g., 80\n", - "\n", - "# Start from the scored 'gdf' produced in cell 10\n", - "render = gdf[KEEP_FIELDS].copy()\n", - "\n", - "# Optional score filters\n", - "if FILTER_SCORE_MIN is not None:\n", - " render = render[render[\"ridescore_v1\"] >= float(FILTER_SCORE_MIN)]\n", - "if FILTER_SCORE_MAX is not None:\n", - " render = render[render[\"ridescore_v1\"] <= float(FILTER_SCORE_MAX)]\n", - "\n", - "# Drop duplicate geometries\n", - "render[\"_wkb\"] = render.geometry.apply(lambda geom: geom.wkb)\n", - "render = render.drop_duplicates(\"_wkb\").drop(columns=\"_wkb\")\n", - "\n", - "# Drop very short segments\n", - "rp = render.to_crs(3857)\n", - "render = render[rp.length >= MIN_LENGTH_M].copy()\n", - "\n", - "# Simplify then return to WGS84\n", - "rp = render.to_crs(3857)\n", - "rp[\"geometry\"] = rp.geometry.simplify(SIMPLIFY_TOL_M, preserve_topology=True)\n", - "render = rp.to_crs(4326)\n", - "\n", - "# Round coordinates\n", - "from shapely.geometry import LineString\n", - "def round_linestring(ls, n=ROUND_COORDS):\n", - " #print(ls)\n", - " coords = [(round(x, n), round(y, n), z) for x, y, z in ls.coords]\n", - " return LineString(coords)\n", - "\n", - "render[\"geometry\"] = render.geometry.apply(lambda g: round_linestring(g, ROUND_COORDS))\n", - "print(\"Render features:\", len(render))\n", - "render.head(2)" - ] - }, - { - "cell_type": "code", - "execution_count": 90, - "id": "42624330-7c3b-4f76-9382-81d610adff5b", - "metadata": {}, - "outputs": [], - "source": [ - "render['parking_presence'] = render['parking_presence'].astype(int)" - ] - }, - { - "cell_type": "code", - "execution_count": 91, - "id": "58afc210-1cf7-47bb-9e20-04c1e6ef441c", - "metadata": {}, - "outputs": [], - "source": [ - "render.to_file('render_dcdata_wCrashes.geojson')" - ] - }, - { - "cell_type": "code", - "execution_count": 92, - "id": "9e0738d3-778a-412d-a37d-09fa072b1abe", - "metadata": {}, - "outputs": [], - "source": [ - "render_wkt = render.copy()\n", - "render_wkt = render_wkt.drop(columns = 'geometry')\n", - "render_wkt.to_csv('render_dc_data_wCrashes.csv')" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "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.13.9" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/mvp_map/data_processing_bespokeRidescore.ipynb b/mvp_map/data_processing_bespokeRidescore.ipynb new file mode 100644 index 0000000..0a65206 --- /dev/null +++ b/mvp_map/data_processing_bespokeRidescore.ipynb @@ -0,0 +1,2828 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3f089b9b", + "metadata": {}, + "source": [ + "# DC Bike Safety Map: Data Processing\n", + "\n", + "This notebook takes [road](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) and [crash](https://opendata.dc.gov/datasets/crashes-in-dc/about) data from the DC data website and processes it for the [DC Bike Safety Map](http://161.35.142.176/). The LTS and ridescore build on 01_lts_osm_elia_v2.ipynb.\n", + "\n", + "This is preliminary work and future work could include:\n", + "* see if same data can be extracted from OSM\n", + "* Taking directionality of road into account\n", + "* Adding bike trails\n", + "* Implement standard LTS methodology\n", + " * directionality\n", + " * get bike paths on in road block data\n", + "* Refine scaling factors to 0 to 100 scale" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ac844942", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Versions → osmnx 2.0.7 | geopandas 1.1.2\n" + ] + } + ], + "source": [ + "# 1) Imports + settings\n", + "import warnings, math, re, os, json\n", + "\n", + "import pandas as pd\n", + "import geopandas as gpd\n", + "from shapely.geometry import LineString, MultiLineString, Point\n", + "import osmnx as ox\n", + "import folium\n", + "from folium.plugins import MeasureControl\n", + "import requests\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "\n", + "import requests\n", + "\n", + "import time\n", + "from datetime import date\n", + "from dateutil.relativedelta import relativedelta\n", + "\n", + "ox.settings.use_cache = True\n", + "ox.settings.log_console = False\n", + "\n", + "print(\"Versions →\", \n", + " \"osmnx\", ox.__version__, \n", + " \"| geopandas\", gpd.__version__)" + ] + }, + { + "cell_type": "markdown", + "id": "18ebf500-b920-40ee-b3c9-7accb73c069a", + "metadata": {}, + "source": [ + "## Road Data" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "14cdcd9b-30c1-40a4-bafb-c65581692b52", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "trying website\n", + "\n", + "https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
geometryROUTEIDFROMMEASURETOMEASUREROUTENAMEROADTYPEBLOCKKEYTOTALTRAVELLANESTOTALPARKINGLANESTOTALRAISEDBUFFERS...PARKINGZONE_RPPAADT_COMBINATIONAADT_COMBINATION_YEARAADT_SINGLE_UNITAADT_SINGLE_UNIT_YEARDC_MAINTENANCE_OPERATIONSMAINTENANCE_OPERATIONSVERTICAL_DEFLECTIONOBJECTIDSHAPELEN
0LINESTRING Z (-77.01991 38.90358 0, -77.01991 ...110006021276.8725591341.9466556TH ST NW14af7e25abf59911305f2724cadc85a08420...None118.02020.0254.02020.011None41950270
1LINESTRING Z (-77.06517 38.95331 0, -77.06517 ...110032021903.8934332010.18518132ND ST NW15b3f1964647d6c0b30c8189fd594208c220...NoneNaNNaNNaNNaN11None41950280
2LINESTRING Z (-77.09076 38.92905 0, -77.09078 ...110378922905.7758793044.950439FOXHALL RD NW1fb2d4a22a88f8d4a7566a28b49aee1f9200...None32.02020.0435.02020.011None41950290
3LINESTRING Z (-77.03639 38.96543 0, -77.03639 ...110016027297.3759777377.10644516TH ST NW1a9903cf6a4ade86eb26343cd52cf1ffb401...2312.02020.01443.02020.011None41950300
4LINESTRING Z (-77.01994 38.94995 0, -77.0201 3...11033472595.138123774.214478EMERSON ST NW14cfb9ba5eb597b707b798513462ef851220...3NaNNaNNaNNaN11YES41950310
..................................................................
13833LINESTRING Z (-76.98733 38.83212 0, -76.98723 ...130815121708.8803711905.117065SOUTHERN AVE SE103ceb30917e33f51246b9427451bf29a400...None111.02020.0736.02020.011None42115000
13834LINESTRING Z (-77.00486 38.87841 0, -77.00483 ...130642821059.6279301160.749512NEW JERSEY AVE SE1f8c1e5fae8a0321753beea69ef9d88f1220...NoneNaNNaNNaNNaN11None42115010
13835LINESTRING Z (-76.98232 38.85084 0, -76.9823 3...13018522134.191696248.385300BRUCE PL SE16e06a429de20637fc25ec5ee5bdad443220...NoneNaNNaNNaNNaN11None42115020
13836LINESTRING Z (-76.9889 38.85219 0, -76.98881 3...130764420.00000051.074902ROBINSON PL SE1a476aa40bc64479559e7361d9c105d16200...NoneNaNNaNNaNNaN11None42115030
13837LINESTRING Z (-76.9956 38.8754 0, -76.9956 38....1306953215.644000213.294800PAULDING ST SE1cb8e955725acf60fbb9a51e0f8cfd753110...NoneNaNNaNNaNNaN1073None42115040
\n", + "

13838 rows × 102 columns

\n", + "
" + ], + "text/plain": [ + " geometry ROUTEID \\\n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.01991 ... 11000602 \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... 11003202 \n", + "2 LINESTRING Z (-77.09076 38.92905 0, -77.09078 ... 11037892 \n", + "3 LINESTRING Z (-77.03639 38.96543 0, -77.03639 ... 11001602 \n", + "4 LINESTRING Z (-77.01994 38.94995 0, -77.0201 3... 11033472 \n", + "... ... ... \n", + "13833 LINESTRING Z (-76.98733 38.83212 0, -76.98723 ... 13081512 \n", + "13834 LINESTRING Z (-77.00486 38.87841 0, -77.00483 ... 13064282 \n", + "13835 LINESTRING Z (-76.98232 38.85084 0, -76.9823 3... 13018522 \n", + "13836 LINESTRING Z (-76.9889 38.85219 0, -76.98881 3... 13076442 \n", + "13837 LINESTRING Z (-76.9956 38.8754 0, -76.9956 38.... 13069532 \n", + "\n", + " FROMMEASURE TOMEASURE ROUTENAME ROADTYPE \\\n", + "0 1276.872559 1341.946655 6TH ST NW 1 \n", + "1 1903.893433 2010.185181 32ND ST NW 1 \n", + "2 2905.775879 3044.950439 FOXHALL RD NW 1 \n", + "3 7297.375977 7377.106445 16TH ST NW 1 \n", + "4 595.138123 774.214478 EMERSON ST NW 1 \n", + "... ... ... ... ... \n", + "13833 1708.880371 1905.117065 SOUTHERN AVE SE 1 \n", + "13834 1059.627930 1160.749512 NEW JERSEY AVE SE 1 \n", + "13835 134.191696 248.385300 BRUCE PL SE 1 \n", + "13836 0.000000 51.074902 ROBINSON PL SE 1 \n", + "13837 15.644000 213.294800 PAULDING ST SE 1 \n", + "\n", + " BLOCKKEY TOTALTRAVELLANES TOTALPARKINGLANES \\\n", + "0 4af7e25abf59911305f2724cadc85a08 4 2 \n", + "1 5b3f1964647d6c0b30c8189fd594208c 2 2 \n", + "2 fb2d4a22a88f8d4a7566a28b49aee1f9 2 0 \n", + "3 a9903cf6a4ade86eb26343cd52cf1ffb 4 0 \n", + "4 4cfb9ba5eb597b707b798513462ef851 2 2 \n", + "... ... ... ... \n", + "13833 03ceb30917e33f51246b9427451bf29a 4 0 \n", + "13834 f8c1e5fae8a0321753beea69ef9d88f1 2 2 \n", + "13835 6e06a429de20637fc25ec5ee5bdad443 2 2 \n", + "13836 a476aa40bc64479559e7361d9c105d16 2 0 \n", + "13837 cb8e955725acf60fbb9a51e0f8cfd753 1 1 \n", + "\n", + " TOTALRAISEDBUFFERS ... PARKINGZONE_RPP AADT_COMBINATION \\\n", + "0 0 ... None 118.0 \n", + "1 0 ... None NaN \n", + "2 0 ... None 32.0 \n", + "3 1 ... 2 312.0 \n", + "4 0 ... 3 NaN \n", + "... ... ... ... ... \n", + "13833 0 ... None 111.0 \n", + "13834 0 ... None NaN \n", + "13835 0 ... None NaN \n", + "13836 0 ... None NaN \n", + "13837 0 ... None NaN \n", + "\n", + " AADT_COMBINATION_YEAR AADT_SINGLE_UNIT AADT_SINGLE_UNIT_YEAR \\\n", + "0 2020.0 254.0 2020.0 \n", + "1 NaN NaN NaN \n", + "2 2020.0 435.0 2020.0 \n", + "3 2020.0 1443.0 2020.0 \n", + "4 NaN NaN NaN \n", + "... ... ... ... \n", + "13833 2020.0 736.0 2020.0 \n", + "13834 NaN NaN NaN \n", + "13835 NaN NaN NaN \n", + "13836 NaN NaN NaN \n", + "13837 NaN NaN NaN \n", + "\n", + " DC_MAINTENANCE_OPERATIONS MAINTENANCE_OPERATIONS VERTICAL_DEFLECTION \\\n", + "0 1 1 None \n", + "1 1 1 None \n", + "2 1 1 None \n", + "3 1 1 None \n", + "4 1 1 YES \n", + "... ... ... ... \n", + "13833 1 1 None \n", + "13834 1 1 None \n", + "13835 1 1 None \n", + "13836 1 1 None \n", + "13837 10 73 None \n", + "\n", + " OBJECTID SHAPELEN \n", + "0 4195027 0 \n", + "1 4195028 0 \n", + "2 4195029 0 \n", + "3 4195030 0 \n", + "4 4195031 0 \n", + "... ... ... \n", + "13833 4211500 0 \n", + "13834 4211501 0 \n", + "13835 4211502 0 \n", + "13836 4211503 0 \n", + "13837 4211504 0 \n", + "\n", + "[13838 rows x 102 columns]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 2) Get Roadblock data from website\n", + "CRS = 'EPSG:4326'\n", + "def try_fetch_dc_roads():\n", + " url = \"https://opendata.arcgis.com/datasets/DCGIS::roadway-block.geojson\"\n", + " try:\n", + " print('trying website')\n", + " r = requests.get(url, timeout=60)\n", + " r.raise_for_status()\n", + " print(r)\n", + " print(url)\n", + " if r.ok:\n", + " gj = r.json()\n", + " roads = gpd.GeoDataFrame.from_features(gj[\"features\"], crs=CRS)\n", + " return roads\n", + " except Exception as error:\n", + " print('Error reading road data from dc gov website')\n", + "\n", + "edges = try_fetch_dc_roads()\n", + "edges.to_file('edges.geojson')\n", + "edges" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "ba1c349e-feb2-4b9f-bfa9-fa51f3d411dd", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "geometry\n", + "ROUTEID\n", + "FROMMEASURE\n", + "TOMEASURE\n", + "ROUTENAME\n", + "ROADTYPE\n", + "BLOCKKEY\n", + "TOTALTRAVELLANES\n", + "TOTALPARKINGLANES\n", + "TOTALRAISEDBUFFERS\n", + "TOTALTRAVELLANEWIDTH\n", + "TOTALCROSSSECTIONWIDTH\n", + "TOTALPARKINGLANEWIDTH\n", + "TOTALRAISEDBUFFERWIDTH\n", + "TOTALTRAVELLANESINBOUND\n", + "TOTALTRAVELLANESOUTBOUND\n", + "TOTALTRAVELLANESBIDIRECTIONAL\n", + "TOTALTRAVELLANESREVERSIBLE\n", + "SUMMARYDIRECTION\n", + "BIKELANE_PARKINGLANE_ADJACENT\n", + "BIKELANE_THROUGHLANE_ADJACENT\n", + "BIKELANE_POCKETLANE_ADJACENT\n", + "BIKELANE_CONTRAFLOW\n", + "BIKELANE_CONVENTIONAL\n", + "BIKELANE_DUAL_PROTECTED\n", + "BIKELANE_PROTECTED\n", + "BIKELANE_BUFFERED\n", + "DOUBLEYELLOW_LINE\n", + "SECTIONFLAGS\n", + "LOC_ERROR\n", + "MIDMEASURE\n", + "AADT\n", + "AADT_YEAR\n", + "FHWAFUNCTIONALCLASS\n", + "HPMSID\n", + "HPMSSECTIONTYPE\n", + "ID\n", + "IRI\n", + "IRI_DATE\n", + "NHSCODE\n", + "OWNERSHIP\n", + "PCI_CONDCATEGORY\n", + "PCI_LASTINSPECTED\n", + "PCI_SCORE\n", + "QUADRANT\n", + "SIDEWALK_IB_PAVTYPE\n", + "SIDEWALK_IB_WIDTH\n", + "SIDEWALK_OB_PAVTYPE\n", + "SIDEWALK_OB_WIDTH\n", + "SPEEDLIMITS_IB\n", + "SPEEDLIMITS_IB_ALT\n", + "SPEEDLIMITS_OB\n", + "SPEEDLIMITS_OB_ALT\n", + "STREETNAME\n", + "STREETTYPE\n", + "BLOCK_NAME\n", + "ADDRESS_RANGE_HIGH\n", + "ADDRESS_RANGE_LOW\n", + "ADDRESS_RANGE_RIGHT_HIGH\n", + "ADDRESS_RANGE_LEFT_HIGH\n", + "ADDRESS_RANGE_RIGHT_LOW\n", + "MAR_ID\n", + "ADDRESS_RANGE_LEFT_LOW\n", + "BLOCKID\n", + "DCFUNCTIONALCLASS\n", + "NHSTYPE\n", + "SNOWROUTE_DDOT\n", + "SNOWROUTE_DPW\n", + "SNOWSECTION_DDOT\n", + "SNOWZONE_DDOT\n", + "SNOWZONE_DPW\n", + "LEFTTURN_CURBLANE_EXCL\n", + "LEFTTURN_CURBLANE_EXCL_LEN\n", + "RIGHTTURN_CURBLANE_EXCL\n", + "RIGHTTURN_CURBLANE_EXCL_LEN\n", + "TOTALBIKELANES\n", + "TOTALBIKELANEWIDTH\n", + "RPPDIRECTION\n", + "RPPSIDE\n", + "SLOWSTREETINFO\n", + "BIKELANE_DUAL_BUFFERED\n", + "RIGHTTURN_EXCLUSIVE\n", + "LEFTTURN_EXCLUSIVE\n", + "BUSLANE_INBOUND\n", + "BUSLANE_OUTBOUND\n", + "FROMSTREET\n", + "TOSTREET\n", + "WARD_ID\n", + "ANC_ID\n", + "SMD_ID\n", + "SURFACE_TYPE\n", + "PARKINGZONE_ROP\n", + "PARKINGZONE_RPP\n", + "AADT_COMBINATION\n", + "AADT_COMBINATION_YEAR\n", + "AADT_SINGLE_UNIT\n", + "AADT_SINGLE_UNIT_YEAR\n", + "DC_MAINTENANCE_OPERATIONS\n", + "MAINTENANCE_OPERATIONS\n", + "VERTICAL_DEFLECTION\n", + "OBJECTID\n", + "SHAPELEN\n" + ] + } + ], + "source": [ + "#look at columns\n", + "for c in edges.columns:\n", + " print(c)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8990d5a7", + "metadata": {}, + "outputs": [], + "source": [ + "# 3) Helpers for tag parsing\n", + "def classify_facility(tags):\n", + " # standardize bike lane types into 3 categories (protected, buffered, and painted). Sharrows don't seem to be indicated in dataset\n", + " # directionality of road is not taken into account\n", + " if (tags.get(\"BIKELANE_PROTECTED\") in {\"IB\", \"OB\", \"BD\"}) or (tags.get(\"BIKELANE_DUAL_PROTECTED\") in {\"IB\", \"OB\", \"BD\"}):\n", + " return \"protected_track\"\n", + " elif (tags.get(\"BIKELANE_BUFFERED\") in {\"IB\", \"OB\", \"BD\"}):\n", + " return \"buffered_lane\"\n", + " elif (tags.get(\"BIKELANE_CONVENTIONAL\") in {\"IB\", \"OB\", \"BD\"}):\n", + " return \"painted_lane\"\n", + " else:\n", + " return \"none\"\n", + "\n", + "#replace function number with name\n", + "function_dict = {11: 'Interstate', 12: 'Other Freeway and Expressway', 14: 'Principal/Primary Arterial', 16: 'Minor Arterial', 17: 'Collector', 19:'Local'}\n", + "def name_function(tags):\n", + " if tags['DCFUNCTIONALCLASS'] in function_dict.keys():\n", + " return function_dict[tags['DCFUNCTIONALCLASS']]\n", + " else:\n", + " return 'Other'\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "083ea52e", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0\n", + "1000\n", + "2000\n", + "3000\n", + "4000\n", + "5000\n", + "6000\n", + "7000\n", + "8000\n", + "9000\n", + "10000\n", + "11000\n", + "12000\n", + "13000\n", + "Normalized segments: 13838\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presenceroad_widthslow_streetpavement_conditiongeometry
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0noneTrue56NoneExcellentLINESTRING Z (-77.01991 38.90358 0, -77.01991 ...
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0noneTrue32NoneGoodLINESTRING Z (-77.06517 38.95331 0, -77.06517 ...
\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey function \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 Minor Arterial \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c Local \n", + "\n", + " num_lanes num_lanes_raw speed_limit speed_limit_raw bike_facility_type \\\n", + "0 4 4 20.0 20.0 none \n", + "1 2 2 25.0 25.0 none \n", + "\n", + " parking_presence road_width slow_street pavement_condition \\\n", + "0 True 56 None Excellent \n", + "1 True 32 None Good \n", + "\n", + " geometry \n", + "0 LINESTRING Z (-77.01991 38.90358 0, -77.01991 ... \n", + "1 LINESTRING Z (-77.06517 38.95331 0, -77.06517 ... " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 3) simplify and impute fields as needed.\n", + "# while the safety scores my included the impute values to ensure it processes without error, the raw values are displayed on the map.\n", + "\n", + "rows = []\n", + "for i, r in edges.reset_index(drop=True).iterrows():\n", + " if (i%1000) == 0:\n", + " print(i)\n", + " tags = r.to_dict()\n", + " facility = classify_facility(tags)\n", + " function = name_function(tags)\n", + " rows.append({\n", + " \"route_id\": tags['ROUTEID'],\n", + " \"route_name\": tags['ROUTENAME'],\n", + " \"blockkey\": tags['BLOCKKEY'],\n", + " \"function\": function,\n", + " \"num_lanes\": tags['TOTALTRAVELLANES'] if tags['TOTALTRAVELLANES'] >-1 else 1, #set number of travels to 1 if no value is available \n", + " \"num_lanes_raw\": tags['TOTALTRAVELLANES'],\n", + " \"speed_limit\": tags['SPEEDLIMITS_OB'] if tags['SPEEDLIMITS_OB'] >1 else 25, #speed limit is set to 25 is no values is available\n", + " \"speed_limit_raw\": tags['SPEEDLIMITS_OB'],\n", + " \"bike_facility_type\": facility,\n", + " \"parking_presence\": True if tags[\"TOTALPARKINGLANES\"] > 0 else False,\n", + " \"road_width\": tags['TOTALCROSSSECTIONWIDTH'],\n", + " \"slow_street\": tags['SLOWSTREETINFO'],\n", + " \"pavement_condition\": tags['PCI_CONDCATEGORY'],\n", + " \"geometry\": r.geometry\n", + " })\n", + "\n", + "gdf = gpd.GeoDataFrame(rows, geometry=\"geometry\", crs=CRS)\n", + "print(\"Normalized segments:\", len(gdf))\n", + "gdf.head(2)" + ] + }, + { + "cell_type": "markdown", + "id": "75801f70-9dbd-40db-aa08-300e22c5966b", + "metadata": {}, + "source": [ + "### Modified Level of Traffic Stress score\n", + "\n", + "We use our own, modified level of traffic stress (LTS) calculator.\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Bike laneNumber of lanesSpeed limitRoad functionLTS
Protected track---1
Buffered lane or painted lane<= 2<= 25-2
None<= 2<= 25Local2
Buffered lane or painted lane>2 and <=3>25 and <= 30-3
None<=2>25 and <= 30Local3
Any other combination4
" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "86d95644", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "lts_level\n", + "1 285\n", + "2 7562\n", + "3 1611\n", + "4 4380\n", + "Name: count, dtype: int64" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 4) LTS rules (compact + tunable)\n", + "\n", + "def lts_level(facility, speed, lanes, function=\"\"):\n", + " hw = (function or \"\").lower()\n", + " if facility in {\"protected_track\"}: return 1 # or hw in {\"cycleway\",\"path\"}: return 1, also include ,\"separated_lane\" here\n", + " if facility in {\"buffered_lane\",\"painted_lane\"}:\n", + " if speed <= 25 and lanes <= 2: return 2\n", + " if speed <= 30 and lanes <= 3: return 3\n", + " return 4\n", + " if facility in {\"none\"}: #include \"shared\" here\n", + " if speed <= 20 and lanes <= 2 and hw in {\"local\"}: \n", + " return 2\n", + " if speed <= 30 and lanes <= 2 and hw in {\"local\"}: return 3\n", + " return 4\n", + " return 4\n", + "\n", + "gdf[\"lts_level\"] = gdf.apply(lambda r: lts_level(r.bike_facility_type, int(r.speed_limit), int(r.num_lanes), r.function), axis=1)\n", + "gdf[\"lts_level\"].value_counts().sort_index()" + ] + }, + { + "cell_type": "markdown", + "id": "8629f210-60d0-459c-9886-78e9985945be", + "metadata": {}, + "source": [ + "### Data exploration\n", + "Let's look at some of the columns of interest" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "d4cc6df8-ac18-475a-9ccc-448995e3db12", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAkQAAAHFCAYAAAAT5Oa6AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOlZJREFUeJzt3Q98jvX+x/HPso1hWwxDFjotEanoZ1SmxhDp34nS2dEh1EQLZyynUqdjqFD5JTmi/EnnJNWJRCV/8reV408j1WgKo9iQNs39e3y+v8d9nfu+N7M547637+v5eFztvq/7e1/3dV+72v32+X6/1x3kcrlcAgAAYLEL/L0DAAAA/kYgAgAA1iMQAQAA6xGIAACA9QhEAADAegQiAABgPQIRAACwHoEIAABYj0AEAACsRyACAtDs2bMlKChIPv/882If79mzpzRp0sRrnd6/7777yvQ6a9eulbFjx8qRI0f+q/21yZtvvilXXHGFhIWFmd/R5s2bi2336aefmsf1p9uSJUvM8S5PZ/N7P1c6depkFqAiIhABlcSiRYvkscceK3MgevLJJwlEpXTw4EFJSkqS3/3ud7J06VJZt26dXHbZZaU+3hqI9HgDCDzB/t4BAOXj6quvrnCH8uTJk6aKEhxcMf4Uff3112af//CHP0h8fLy/dwdAOaJCBFQSvl0np06dkqefflqaNWtmuncuvPBCufLKK+X55583j2vXzZ///Gdzu2nTpiaYeHbx6PMnTpwol19+uVStWlXq1asnf/zjH2Xv3r1er6vfDz1u3Dhp3LixVKtWTdq2bSvLly8v0n3i7kKaM2eOjBgxQi666CKz3W+++cZUXpKTk6VFixZSs2ZN81o33XSTrF692uu1du/ebbbxzDPPyIQJE8x71vemr+MOK6NHj5aGDRtKZGSk3H777ZKTk1Oq4/fee+9J+/btpXr16hIeHi5dunQxFSA3PbbXX3+9ud2nTx+zH2XpHtLn/+///q+57T7Wuuh7Uv/85z+lXbt2Zr91Hy655BLp37+/nI28vDwZOXKk+b2GhoaaY52SkiLHjx/3CtA33HBDkecWFhaa9nfccYezrqCgwJxL7nOhbt268qc//cn83s5k2rRp0rp1a/N71eOq23j00UfP6n0B51LF+GcZYCn9cPrtt9+KrNcQciYaZjT0/OUvf5GOHTuasLBjxw6ne+z++++Xn3/+WV588UV5++23pUGDBma9hhL14IMPyiuvvCIPPfSQGbOkH9zaJafB5osvvpA6deqYdmPGjJH09HQZNGiQ+RDNzs4229bXK647KS0tzQSPl19+WS644AITftwfrE888YTUr19fjh07ZroANXB8/PHHRYKHBgsNd/pT348GrFtuucUEipCQEHn11Vdlz549JhTovmjYKcn8+fPl3nvvlcTERHnjjTckPz/fHD/362sQ0vf+P//zPzJkyBATAG+88UaJiIiQ0tLnayB56623vIKWHne9ryFLF/2dabDU/f/kk0+krH755RdTvdLgqsFDj9P27dvl8ccfl61bt8pHH31kgpgGmocfflh27dolsbGxzvOXLVsmP/74o3ncHYxvvfVWE05TU1OlQ4cOZt/0d6XHR8e5aSgtzoIFC0zQHTp0qDz77LPm960B+Kuvvirz+wLOOReAgDNr1ixNPCUujRs39nqO3u/Xr59zv2fPnq6rrrqqxNd55plnzLaysrK81mdmZpr1ycnJXus3bNhg1j/66KPm/s8//+yqWrWqq0+fPl7t1q1bZ9rFx8c761asWGHWdezY8Yzv/7fffnOdPHnSlZCQ4Lr99tud9bqfuo3WrVu7CgsLnfVTpkwx63v16uW1nZSUFLM+Nzf3tK+l22nYsKGrVatWXts8evSoq169eq4OHToUeQ///Oc/z/ge3G31p9uQIUPMOl/PPvusWX/kyBFXWfn+3tPT010XXHCBa9OmTV7t3nrrLfMaS5YsMfcPHTrkCg0NdX6Xbr1793ZFR0eb46/eeOMN87yFCxd6tdPt6/qXXnrJWae/b8/f+UMPPeS68MILy/yeAH+gywwIYK+//rps2rSpyOLuuimJVjP+/e9/m3+hf/jhh6YbpbRWrFhhfvrOXtJtNm/e3FRN1Pr16001pXfv3l7t4uLiisyCc7vzzjuLXa8Vo2uuucZUR3RMkVZ69HUyMzOLtL355ptNtcFN90n16NHDq517/ffff3/a97pz505TEdHB0p7b1C4e3Vd9j1p1OZeuvfZa81OP4z/+8Q/54Ycfznpb77//vrRs2VKuuuoqU110L127dvXqEo2KijJVtddee81UgdThw4fl3XffNV2j7nFduj3tbtW2ntvT7Ws1z3MWnS89X7SCd88995jtHjp06KzfF3CuEYiAAKYf6Dom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FRQUyNy5c6V///6m2ywrK0v2798viYmJTpuqVatKfHy8rF271tzPyMiQkydPerXRENWyZUunzbp168yBcIchFRcXZ9a52xRHw5ceRM8FAABUTgETiN555x0zrue+++4z9zUMKa0IedL77sf0Z2hoqNSqVavENvXq1SvyerrO3aY46enpzpgjXbTqBAAAKqeACUQzZ86U7t27mwqPJ60WedIePt91vnzbFNf+TNtJS0sz5TX3kp2dXYZ3AwAAKpKACER79uyRjz76SO6//35nnQ6gVr5VnJycHKdqpG20q01nkZXU5sCBA0Ve8+DBg0WqT560e077Gj0XAABQOQVEIJo1a5bpwurR4z8DMZs2bWrCjHvmmdLws3LlSunQoYO536ZNGwkJCfFqo7PVtm3b5rTRwdNa4dm4caPTZsOGDWaduw0AALBbsL934NSpUyYQ9evXT4KD/7M72p2lM8zGjRsnsbGxZtHb1atXN9PolY7tGTBggIwYMUKioqKkdu3aMnLkSGnVqpV07tzZtGnevLl069ZNBg4cKNOnTzfrBg0aZKbml3aGGQAAqNz8Hoi0q+z77783s8t8paamyokTJyQ5Odl0i+lMsWXLlkl4eLjTZvLkySZI9e7d27RNSEiQ2bNnS5UqVZw28+bNk2HDhjmz0fTijXptIwAAgIC7DlEg4zpE8BeuQwQAFl2HCAAAwF8IRAAAwHoEIgAAYD0CEQAAsB6BCAAAWI9ABAAArEcgAgAA1iMQAQAA6xGIAACA9QhEAADAegQiAABgPQIRAACwHoEIAABYj0AEAACsRyACAADWIxABAADrEYgAAID1CEQAAMB6BCIAAGA9AhEAALAegQgAAFiPQAQAAKxHIAIAANYjEAEAAOsRiAAAgPUIRAAAwHoEIgAAYD0CEQAAsB6BCAAAWI9ABAAArEcgAgAA1iMQAQAA6xGIAACA9QhEAADAegQiAABgPb8Hoh9++EH+8Ic/SFRUlFSvXl2uuuoqycjIcB53uVwyduxYadiwoYSFhUmnTp1k+/btXtvIz8+XoUOHSp06daRGjRrSq1cv2bt3r1ebw4cPS1JSkkRGRppFbx85cuS8vU8AABC4/BqINKRcd911EhISIh988IF89dVX8txzz8mFF17otJk4caJMmjRJpk6dKps2bZL69etLly5d5OjRo06blJQUWbRokSxY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H330kXTt2lUyMzNNCFq/fr20a9fOtJkxY4a0b99edu7cKc2aNTuP7xgAAASigB1DlJWVJfv375fExERnXdWqVSU+Pl7Wrl1r7mdkZMjJkye92mj3WsuWLZ0269atM91k7jCk4uLizDp3m+JoV1xeXp7XAgAAKqeADUQahpRWhDzpffdj+jM0NFRq1apVYpt69eoV2b6uc7cpTnp6ujPmSBetOgEAgMopYAORmw629u1K813ny7dNce3PtJ20tDTTJedesrOzz2r/AQBA4AvYQKQDqJVvFScnJ8epGmmbgoICM4uspDYHDhwosv2DBw8WqT550u65iIgIrwUAAFROARuImjZtasLM8uXLnXUaflauXCkdOnQw99u0aSMhISFebfbt2yfbtm1z2ujgaa3wbNy40WmzYcMGs87dBgAA2M2vs8x0ivw333zjNZBap8TXrl1bLr74YjOlfty4cRIbG2sWvV29enUzjV7p2J4BAwbIiBEjJCoqyjxv5MiR0qpVK2fWWfPmzaVbt24ycOBAmT59ulk3aNAgMzWfGWYAAMDvgejzzz+XG2+80bk/fPhw87Nfv34ye/ZsSU1NlRMnTkhycrLpFtOZYsuWLZPw8HDnOZMnT5bg4GDp3bu3aZuQkGCeW6VKFafNvHnzZNiwYc5sNL144+mufQQAAOwT5NLRxTgjnXavFSntamM8Ec6nJqMXV7gDvnt8D3/vghU4N8C5UX6f3wE7hggAAOB8IRABAADrEYgAAID1CEQAAMB6BCIAAGA9AhEAALAegQgAAFiPQAQAAKxHIAIAANYjEAEAAOsRiAAAgPUIRAAAwHoEIgAAYD0CEQAAsB6BCAAAWI9ABAAArEcgAgAA1iMQAQAA6xGIAACA9QhEAADAegQiAABgPQIRAACwHoEIAABYj0AEAACsRyACAADWIxABAADrBVt/BAJAk9GLpaLZPb6Hv3cBAIByQ4UIAABYj0AEAACsRyACAADWIxABAADrEYgAAID1CEQAAMB6BCIAAGA9AhEAALCeVYHopZdekqZNm0q1atWkTZs2snr1an/vEgAACADWBKI333xTUlJSZMyYMfLll1/KDTfcIN27d5fvv//e37sGAAD8zJpANGnSJBkwYIDcf//90rx5c5kyZYrExMTItGnT/L1rAADAz6wIRAUFBZKRkSGJiYle6/X+2rVr/bZf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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.hist(gdf['lts_level'])\n", + "plt.xlabel('level of stress')\n", + "plt.ylabel('count')\n", + "plt.title('Histogram of lts levels')\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "a986a5be-f50b-4f52-94b4-c6363e7f9ac1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "length of road network: 1899.28km\n" + ] + } + ], + "source": [ + "#change crs to get length in meters\n", + "gdf = gdf.to_crs(gdf.estimate_utm_crs())\n", + "gdf['len'] = gdf.length\n", + "print(\"length of road network: {:.2f}km\".format(sum(gdf['len'])/1000))" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8b84b9cf-a88b-4df4-a99c-7cec7a3e184b", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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RwUnAlYN/YxqiorRRhttlI/Fr371q/y4rthmlDvOofvuuy9/NvWJilz88EaZapYvyhxNReNzCu+++27eZuxjfWIb8TmGOGfLx+Ub3/jGGn8ODRHbjjJGpaz8XuX0/HPPPTddffXV6ayzzspliuMUwdzXX399jd8njl183lEhjPM8/i6jUvS5z32uEgzec889c6AqmuDUFeuUK48hjmlUUuK8uOKKK9Lvfve7/PcbZS03JQDWb+or6ivqK9VbX2nsenBDrjfKYhtR34x+T3/605/mm3dR/3ivYFpD601Rv43tRRAp6slRF49yRZ2opoZeYzX0WMXjuJ6KuvHNN9+cLr/88rxuffWudfW1r30t38iN+lvU0yK4FMHJOB8iQBl19BEjRuRjFOuuSiQYlMv39a9/vXKexTUXjaQELdgNN9xQitN0xowZpf/85z+lRYsWlX73u9+Vttlmm1LHjh1Lc+fOLf35z3/O61xxxRW1XjtnzpxS+/btSyNGjKjMGzBgQF73nnvuqbXuxRdfnOdPnTp1lWX52c9+lte55ZZbas2fOXNmnv/DH/6wMm+HHXYobbLJJqUXX3yxMm/JkiWlLbfcsnTaaadV5v3yl7/Mr73vvvsadDz233//0rbbbpuPQ9m7775b6t27d2m77bYrrVixIs+bPXt23u7ll1/+ntuM9451Dz744FrzFy9enMt75JFH1pq/fPny0p577ln60Ic+tMptRpmWLVtW6tWrV+mcc86pzL/gggtKbdq0KT322GO11h80aFCDjsO3vvWtvN748eNrzR82bFg+3uX9X5Nz4ogjjsifV12///3v8zb+8Ic/5Oc/+clP8jkX73XIIYdU1ot9HDp06Bp/RuVz+6STTlrlfv773/8u/fjHPy5tvPHGpbPOOisf+/dywgknlHbaaafK88MOO6x06qmnlrbYYovSpEmT8rw//elPeftTpkyp9bcRU1m8d6wTZVnbz2FVTj755JWO+aabbprn1xXH7eijjy6tqfJ5XfOc+sAHPlDae++983dJTZ/4xCdK3bp1qxzf733ve/m1zzzzTGWdN954o9SuXbvSeeedV5n30Y9+NH+mCxYsqLW9M888Mx+HeE3Nv8f4zIHWSX2lNvUV9ZVqr680RT24Idcb5TrDHnvskbdT9uCDD+b5cT2yOg2pN0V9K7Z15ZVX1pp/ySWX5PkP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1+qAc8CAAWn69Omr3N7SpUvTwoULa00AAAAAtCzNGpSKVPKbbrop3X333enaa6/NQajogPP111+vjBhTd5SYeF53NJmaxo0blzp37lyZevTo0eT7AQAAAEAVBaUOP/zw9OlPfzrtscce6bDDDkt33HFHpZlezfTzus366s6rKfpXWLBgQWWaM2dOE+4BAAAAAFXZfK+mTTfdNAeooklfuZ+pullR8+bNWyl7qqZo4tepU6daEwAAAAAtS4sKSkV/UE8//XTq1q1b7mMqAlNTp06tLF+2bFmaNm1abuIHAAAAQPVq1tH3zj///HTkkUem7bffPmdAjRkzJndMfvLJJ+cmesOHD09jx45NvXr1ylM87tChQxo6dGhzFhsAAACAag5K/fOf/0zHHXdceu2119I222yT9t9//zRjxoy0ww475OUjRoxIS5YsScOGDUvz58/PHaNPmTIldezYsTmLDQAAAEA1B6Vuvvnm1S6PbKnRo0fnCQAAAIDWo0X1KQUAAADA+kFQCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAUEVGjx6d2rRpU2vq2rVrZXmpVMrrdO/ePbVv3z4NHDgwzZo1q1nLDABQH0EpAIAqs/vuu6dXXnmlMj3xxBOVZePHj08TJkxIV111VZo5c2YOWA0aNCgtWrSoWcsMAFCXoBQAQJVp27ZtDjaVp2222aaSJTVx4sQ0atSoNGTIkNS7d+80adKk9Pbbb6fJkyc3d7EBAGoRlAIAqDLPPvtsbp7Xs2fPdOyxx6bnn38+z589e3aaO3duGjx4cGXddu3apQEDBqTp06evdptLly5NCxcurDUBADQlQSkAgCrSr1+/dNNNN6W77747XXvttTkI1b9///T666/nx6FLly61XhPPy8tWZdy4calz586VqUePHk26HwAAglIAAFXk8MMPT5/+9KfTHnvskQ477LB0xx135PnRTK8sOj+vKZr11Z1X18iRI9OCBQsq05w5c5poDwAA/o+gFABAFdt0001zgCqa9JVH4aubFTVv3ryVsqfqimZ+nTp1qjUBADQlQSkAgCoWfUE9/fTTqVu3brmPqQhMTZ06tbJ82bJladq0abmJHwBAS9K2uQsAAEDDnX/++enII49M22+/fc6AGjNmTO6U/OSTT85N9IYPH57Gjh2bevXqlad43KFDhzR06FCHGQBoUQSlAACqyD//+c903HHHpddeey1ts802af/9908zZsxIO+ywQ14+YsSItGTJkjRs2LA0f/783DH6lClTUseOHZu76AAAtQhKAQBUkZtvvnm1yyNbavTo0XkCAGjJ9CkFAAAAQOEEpQAAAAAonKAUAAAAAOtvUGrcuHGVEWPKSqVS7g+he/fuqX379mngwIFp1qxZzVpOAAAAAFpJUGrmzJnpmmuuSX369Kk1f/z48WnChAnpqquuyut07do1DRo0KC1atKjZygoAAABAKwhKvfXWW+n4449P1157bdpiiy1qZUlNnDgxjRo1Kg0ZMiT17t07TZo0Kb399ttp8uTJzVpmAAAAAKo8KHXGGWekI444Ih122GG15s+ePTvNnTs3DR48uDKvXbt2acCAAWn69Omr3N7SpUvTwoULa00AAAAAtCxtm/PNb7755vTII4/kpnl1RUAqdOnSpdb8eP7iiy+utm+qiy66qAlKCwAAAEDVZ0rNmTMnnX322eknP/lJ2mSTTVa5XnR+XlM066s7r6aRI0emBQsWVKZ4HwAAAABalmbLlHr44YfTvHnz0r777luZt3z58vSHP/whd2z+zDPPVDKmunXrVlknXlM3e6qmaOIXEwAAAAAtV7NlSh166KHpiSeeSI899lhl6tu3b+70PB7vtNNOebS9qVOnVl6zbNmyNG3atNS/f//mKjYAAAAA1Zwp1bFjxzyiXk2bbrpp2mqrrSrzhw8fnsaOHZt69eqVp3jcoUOHNHTo0GYqNQAAAABV39H5exkxYkRasmRJGjZsWJo/f37q169fmjJlSg5oAQAAAFC9WlRQ6v7776/1PDo0Hz16dJ4AAAAAaD2arU8pAAAAANZfglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAKrYuHHjUps2bdLw4cMr80qlUho9enTq3r17at++fRo4cGCaNWtWs5YTAKAuQSkAgCo1c+bMdM0116Q+ffrUmj9+/Pg0YcKEdNVVV+V1unbtmgYNGpQWLVrUbGUFAKhLUAoAoAq99dZb6fjjj0/XXntt2mKLLWplSU2cODGNGjUqDRkyJPXu3TtNmjQpvf3222ny5Mmr3N7SpUvTwoULa00AAE1JUAoAoAqdccYZ6YgjjkiHHXZYrfmzZ89Oc+fOTYMHD67Ma9euXRowYECaPn36apsBdu7cuTL16NGjScsPACAoBQBQZW6++eb0yCOP5EBSXRGQCl26dKk1P56Xl9Vn5MiRacGCBZVpzpw5TVByAID/p22NxwAAtHARLDr77LPTlClT0iabbLLK9aLz85qiWV/deTVFNlVMAABFkSkFAFBFHn744TRv3ry07777prZt2+Zp2rRp6Xvf+15+XM6QqpsVFa+pmz0FANCcZEoBQAu044V3NHcRWoQXLj2iuYvQ4hx66KHpiSeeqDXv85//fPrABz6QLrjggrTTTjvl0famTp2a9t5777x82bJlOXB12WWXNVOpAQBWJigFAFBFOnbsmEfUq2nTTTdNW221VWX+8OHD09ixY1OvXr3yFI87dOiQhg4d2kylBgBYmaAUAEArM2LEiLRkyZI0bNiwNH/+/NSvX7/cB1UEtAAAWgpBKQCAKnf//ffXeh4dmo8ePTpPAAAtlY7OAQAAACicoBQAAAAA1RGUilFdXn/99ZXmv/nmm3kZAADqUAAAjR6UeuGFF9Ly5ctXmr906dL08ssvr80mAQBaPXUoAIC17Oj89ttvrzy+++67U+fOnSvPI0h1zz33pB133HFNNgkA0OqpQwEArGNQ6uijj66M6HLyySfXWrbRRhvlgNQVV1yxJpsEAGj11KEAANYxKLVixYr8f8+ePdPMmTPT1ltvvSYvBwBYL6lDAQCsY1CqbPbs2WvzMgCA9Zo6FADAOgalQvQfFdO8efMqd//Krr/++rXdLABAq6YOBQCwDqPvXXTRRWnw4MG5UvXaa6+l+fPn15oa6uqrr059+vRJnTp1ytMBBxyQ7rzzzsryUqmURo8enbp3757at2+fBg4cmGbNmrU2RQYAaHaNVYcCAFhvM6V+9KMfpRtvvDGdeOKJ6/Tm2223Xbr00kvT+9///vx80qRJ6aijjkqPPvpo2n333dP48ePThAkT8nvtsssuacyYMWnQoEHpmWeeSR07dlyn9wYAKFpj1aEAANbbTKlly5al/v37r/ObH3nkkenjH/94DjjFdMkll6TNNtsszZgxI2dJTZw4MY0aNSoNGTIk9e7dOwet3n777TR58uR1fm8AgKI1Vh0KAGC9DUp96UtfavTA0PLly9PNN9+cFi9enJvxRUegc+fOzSnuZe3atUsDBgxI06dPX+V2li5dmhYuXFhrAgBoCZqiDgUAsF4133vnnXfSNddck37/+9/nPqE22mijWsujyV1DPfHEEzkIFduMLKnbbrst7bbbbpXAU5cuXWqtH89ffPHFVW5v3Lhxub8GAICWpjHrUAAA62VQ6vHHH0977bVXfvzkk0/WWtamTZs12tauu+6aHnvssfTmm2+mW265JZ188slp2rRpq9xeNOtb3XuMHDkynXvuuZXnkSnVo0ePNSoTAEBTaMw6FADAehmUuu+++xqtABtvvHGlo/O+ffummTNnpiuvvDJdcMEFeV404evWrVtl/Xnz5q2UPVVTNPGLCQCgpWnMOhQAwHrZp1TZc889l+6+++60ZMmSShbTuoptRL9QPXv2TF27dk1Tp06t1TloZFHpIBQAqGZNUYcCAFgvMqVef/31dMwxx+S7fZFq/uyzz6addtopd965+eabpyuuuKJB2/na176WDj/88Ny8btGiRbmj8/vvvz/dddddebvDhw9PY8eOTb169cpTPO7QoUMaOnTo2hQbAKBZNVYdCgBgvc2UOuecc3LHnC+99FIOEpV97nOfywGlhnr11VfTiSeemPuVOvTQQ9Nf/vKX/PpBgwbl5SNGjMiBqWHDhuWmfS+//HKaMmVK6tix49oUGwCgWTVWHQoAYL3NlIrAUKScb7fddrXmRzbT6kbGq+u6665b7fK4gzh69Og8AQBUu8aqQwEArLeZUosXL651d6/stdde08k4AIA6FABA0wSlDj744HTTTTfVymhasWJFuvzyy9MhhxyyNpsEAGj11KEAANax+V4EnwYOHJgeeuihPCJe9P00a9as9MYbb6Q//elPa7NJAIBWTx0KAGAdM6V222239Pjjj6cPfehDuVPyaM43ZMiQ9Oijj6add955bTYJANDqqUMBAKxjplTo2rVruuiii9b25QAA6yV1KACAdciUuuGGG9Ivf/nLlebHvEmTJq3NJgEAWj11KACAdQxKXXrppWnrrbdeaf62226bxo4duzabBABo9dShAADWMSj14osvpp49e640f4cddkgvvfTS2mwSAKDVU4cCAFjHoFRkREVH53X99a9/TVtttdXabBIAoNVrjDrU1Vdfnfr06ZM6deqUpwMOOCDdeeedleWlUimNHj06de/ePbVv3z6PmByjJAMAtIqg1LHHHpvOOuusdN9996Xly5fn6d57701nn312XgYAQNPUobbbbrvcDPChhx7K00c+8pF01FFHVQJP48ePTxMmTEhXXXVVmjlzZu5YPUZLXrRokY8EAKj+0ffGjBmT088PPfTQ1Lbt/21ixYoV6aSTTtKnFABAE9ahjjzyyFrPL7nkkpw9NWPGjLTbbruliRMnplGjRqUhQ4bk5TEITZcuXdLkyZPTaaedtsrtLl26NE9lCxcu9DkCAC0rKBUp4a+88koePSYqVo899lhODd9jjz1yn1IAABRTh4pMqxj9ePHixbkZ3+zZs9PcuXPT4MGDK+u0a9cuDRgwIE2fPn21Qalx48aliy66yEcHALTsoFSvXr1yinj8HxMAAMXVoZ544okchHrnnXfSZpttlm677bacJRWBpxCZUTXF88jQWp2RI0emc889t1amVI8ePXysAEDLCUptsMEGuRL1+uuvC0gBADRDHWrXXXfNmVZvvvlmuuWWW9LJJ5+cpk2bVlnepk2blQJidefVFRlVMQEAtOiOzqMDza9+9avpySefbPwSAQC0Uo1Vh9p4443T+9///tS3b9/c7G7PPfdMV155Ze7UPEQTvprmzZu3UvYUAEBVdnR+wgknpLfffjtXgKJSFP0h1PTGG280VvkAAFqNpqpDRSZUdFLes2fPHJiaOnVq2nvvvfOyZcuW5Syqyy67rFH2AQCgWYNSMaoLAADF16G+9rWvpcMPPzz397Ro0aJ08803p/vvvz/ddddduYne8OHD80h+5X6r4nGHDh3S0KFDfVwAQPUHpaLfAgAAiq9Dvfrqq+nEE0/MI/l17tw59enTJwekBg0alJePGDEiLVmyJA0bNizNnz8/9evXL02ZMiV17NjRxwUAVH9QKvzjH//IQxrH/9GHwbbbbpsrRHHXbvfdd2/cUgIAtBLrWoe67rrrVrs8sqVGjx6dJwCAVtfRefRLsMcee6S//OUv6dZbb01vvfVWnv/444+nb33rW41dRgCAVkEdCgBg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xaNA5557br1TBA4uvfTSynNYG7fddls68MADU4cOHVL37t1Tt27d8uOY9+tf/7rFHlRBNMLMmTPT8ccfn3r27Jnat2+fz914HPMeeuihFnmQqrHMNJ1qOx+qrbysO0Gp9dQbb7yRJk2a1NzFoCB///vf0wc/+MF08MEHpz322CMNHDgwvfLKK5XlCxYsSJ///Od9HuuRu+66K+21117p/PPPT3vvvXd+HufHc889l1566aX00Y9+VGBqPTJx4sR03333pUcffbTWFM33IngZjx977LHmLiZV6L//+7/Tsccem/r06ZN+/vOf55sjf/zjH/PjmBfLrr322tSSVGMQrdou4qqlvPF5x+ce9eazzz47XX/99el//ud/8uP58+fnZb/5zW9SS1KNZa6W86Eay1tt50O1lbcaz4myyFw+8cQT8+9c27Zt04YbblhrKlKbkg4jWqXbb799tcuff/75dN5550mfX0986lOfSu+++27OinnzzTdzxsOTTz6Z7r///rT99tvnL6X4QtKcYv3Rv3//9JGPfCSNGTMm3XzzzWnYsGE5S+qSSy7Jy0eNGpV/YKdMmdLcRaUA48aNy4GBqPjFeVG20UYbpb/+9a9pt9128zmwVt7//venkSNHpi9+8Yv1Lo8Ljvje+cc//tFigmhnnXVWzhiN4HyXLl1ycDaaHN599935d/T73/9+OvXUU1NLuog75phj0qGHHrpSmeM7/J577km/+MUv0lFHHZVagmoqb+/evdMJJ5yQLrzwwnqXX3bZZTnTfNasWamlqLYyV9P5UI3lrbbzodrKW43nRNnhhx+eb0SfeeaZ+eZLmzZtUk2FljeCUrQ+bdq0KW2wwQb5/1VNsZz1w7bbblt6/PHHa80bNmxYafvtty/94x//KM2dO9f5sJ7p1KlT6dlnn82Ply9fXmrbtm3p4Ycfrix/4oknSl26dGnGElK0Bx98sLTLLruUzjvvvNKyZcvyvDgvZs2a5cNgrW2yySalv/3tb6tc/vTTT+d1Woqdd9659D//8z+rXH7dddeVdtppp1JLsvvuu5fGjRu3yuWXXnppabfddiu1FNVU3nbt2pWeeeaZVS6PczvWaUmqrczVdD5UY3mr7XyotvJW4zlRttlmm5UeffTRUkug+V4rFdHOW265Ja1YsaLe6ZFHHmnuIlJwf1KRllnTD37wg/TJT34yDRgwIDfvY/21wQYbpE022SRtvvnmlXkdO3bMzTpZf+y3337p4YcfTv/+979T37590xNPPLHSXTNYU7vvvnu65pprVrk8MvRinZbi5ZdfTgcddNBqs0z/9a9/pZYkml0PGTJklcuPPvroFpOJVm3l3XnnnVfbZDOaEe20006pJam2MlfT+VCN5a2286HayluN50RZjx49Wswoy7WvUmk19t133xx4ij+C+sSFRks5CWl6H/jAB3J75uhXqqZoghDnQQSnWL/suOOO+Uc0mtaEP//5z7kpZ83BECK4zfpls802y/0NRpPOQYMGadLLOrviiivSEUcckfutGzx4cG7WEHWQuXPnpqlTp6YXX3wx/e///m+LC6JFuashiFbzIm7EiBFVcRFXTeW9+OKLc79n06ZNq/f8jaY58X3ZklRbmavpfKjG8lbb+VBt5a3Gc6Jmf6LRTDKarcd1QXPSp1QrFZ2ILl68OH3sYx+rd3ksiyBFZMmwfvQXE+fEqir+0Z/Qj370o5xFx/ohPu+4QxIXi/WJPqWir7HoY4j10z//+c+cOXXYYYelTTfdtLmLQxV74YUX0tVXX51mzJiRLyxC165d0wEHHJBOP/30Zq8M1xQXQvG9uMMOO6w2iPbhD384tRSRGR8XcVHe1V3Ere5OfpGqrbxx0+bKK6/M/9c9f6Pz5fi/pammMlfb+VBt5a2286Eay1uN50TYYost0ttvv537HY6O2aMf0Zqis/miCEoBAEAVBtGq9SKu2spL06q286HaykvTq8ZzYtKkSatdfvLJJxdWFkEpAAAAAAqno3MAAJpF3In9yEc+4uhTlb72ta+lL3zhC6maVGOZaTrVdj5UW3mraVCshQsX1pqKJCgFAECz6N69e+6/qVpUYxCt2i7iqqm8MVpjNPesJtVW5mo6H6qxvNV2PlRbeVvyObF48eJ05plnpm233TYPdBN9TNWcimT0PaBFGjhwYNprr73yyBCN6f7770+HHHJImj9/ftp8881TEeLHs2fPnunRRx/N+wTA/xuIo9qCaBtsUF33dOMiLkZUrRbVVN736pOlJaq2MlfT+VCN5a2286HaytuSz4kRI0ak++67L/3whz9MJ510UvrBD36Qyxqj8V166aWFlkWfUkCLD0pFp7LDhw/P07oSlAIofiTH6Dh8+vTpuQPYGJUoRifq379/+vKXv5y22247HwkAFGj77bdPN910U77m6tSpU3rkkUfS+9///vTjH/84/exnP1vlqO1NQaYUAABN4oEHHkiHH3546tGjR2W47FKplObNm5d+/etfp+9///vpzjvvTAceeGCL/AQiqzbuzD/77LOpW7duufle7Avrj2jiMnny5JWCqnHOHnfccWnTTTdNLdl//vOfdMcdd1TO4U996lMtvsw0rmo+h52/TeeNN97ILTlCBKXieTjooIPyDaMiyZQCWnSm1GOPPZamTZtWa1lc0Lz44ou5HXRc8CxbtixnU11++eXp4x//+BpnSsWP9IUXXphmzpyZtt5661xhiyYl8SM9cuTInNoaQ4PX1KdPn7zeRRddlJ/fcMMNafz48Wn27Nm5LGeddVYaNmxYXqb5HrC+2m+//XIF97vf/W69y88555z8PR7fvy2led4TTzyRttpqq/x9HtlcYY899khPP/10WrRoUf49+MAHPpBaEhedTeOpp55KgwYNSm+//XYaMGBAvpAvB1WjbhL1hClTpqTddtsttRRxzkaGQ9Rx/v3vf6dDDz00PfPMM7nvtmhCFP3HRL3nfe97X2opnL9Np9rO4Wo8f6v1HO7Tp0++MRTnRdwwiuff+c530ve+9718TRNZzoUpAbRAAwYMKJ199tml119/vbTddtuVLr744tIrr7ySp3DEEUeUBg0aVHr88cdL//jHP0q//e1vS9OmTXvP7d53332l+OqbP39+fh6v32yzzUrf/e53S3//+99Lf/rTn0p777136ZRTTsnLn3jiibz+c889V9nGk08+mec988wz+fk111xT6tatW+mWW24pPf/88/n/LbfcsnTjjTfm5bNnz87rP/roo01yrABaqk022aT0t7/9bZXLn3766bxOS9GmTZvSq6++mh8fe+yxpYEDB5YWL16cn7/zzjulT3ziE6XPfOYzpZZk1qxZpe7du5c233zz0lFHHVX6r//6r9Kpp56aH8e8973vfXmdluKAAw6o/AbPmzevtMcee5Q23njjUq9evfK5sP3225f++c9/llqC+PzjPFi6dOlKy2Lecccdl9dpSWqew3Ee7LXXXpW602uvvVbq379/6Qtf+EKppXD+Nq1qO4er7fytxnO4bMKECaUrr7wyP7733ntL7du3z9/FG2ywQWnixImlIglKAS06KBV22GGHHDSqKSqxo0ePXuPt1g1KnXjiifnHo6Y//vGP+Qt5yZIl+XmfPn1yUKxs5MiRpf3226/yvEePHqXJkyfX2sa3v/3tXPEOglLA+qpnz56l66+/fpXLY1ms0xIviKJc99xzT63lM2bMyDdKWhIXnU0nLtJWdzEZN65inZak5jm8yy67lH73u9+tVA/acccdSy2F87dpVds5XG3nbzWew6vy4osv5hvrjz32WKlo+pQCqlI0j4v2zpFyfNhhh6VPf/rTOe10TT388MPpueeeSz/96U8r8yJgv2LFitx044Mf/GA6/vjj0/XXX5++8Y1v5GXR+V+50/VILY504i9+8Yvp1FNPrWzj3XffTZ07d26kvQWoTueff346/fTT83dtNCGJ5gzRrCGaN0ydOjX9z//8T6OPsrquonxh6dKlubw1xfP43m9J/vKXv6SHHnoobbzxxisti3kxHPmHPvSh1BJF86EJEyakrl275ufRbPKSSy5Jn//851NLEMOiR19Mq2raFPWHoodOX5Nz+M0336z0GVMWz1955ZXUUjh/m1Y1nsPVdP5W+zl8zz335Cmac8a1T01x7VMUQSmgKn3pS19KH/3oR3PnnRGYij6grrjiivSVr3xljbYTX8CnnXZaDnLVNypFGDp0aO5zKkalWLJkSQ5CHXvssZXXh2uvvTb169ev1us33HDDddhDgOoXfetFoCH6lIphppcvX175ftx3333zyD/HHHNMakmiD5O2bdumhQsXpr///e9p9913ryx76aWXct+DLYmLzqYTN5uic/uvf/3r9QZVx44d2ygjAze2U045JbVr1y53Eh19cNYMSMQFfblPzZbA+du0qvEcrqbzt1rP4RD94l588cWpb9++eRCEcjCwOQhKAS1e3GUoX8jUFCMgxR34mKJD8ggMrWlQap999kmzZs3KQ6CuSgxXfvDBB+dsqghKRWZW+e55/B+dLT7//PM5owqA2j73uc/lKS4wXnvttTwvAjsbbbRRiztU3/rWt2o979ChQ63nv/3tb9OHP/zh1JK46Gw6o0ePTu3bt8/ZXCNGjKhctEXWdGR3xQ2rmN+SRACi7KijjkpvvfVWreW33HJLHkimpXD+Nq1qO4er7fyt1nM4/OhHP0o33nhjOvHEE1NzM/oe0KJH34tmHTEiRPyg/vCHP8x3TuJiJr7cY5jxXXbZJY+kF035YtS7n//852s0+t7jjz+e9t9//9xUIH5UYnSMGGEpfkRiRIqyCHjFD3uM9Bd3/E844YTKsmh+EplWka0VZYomH5HGG+9x7rnnGn0PgCZ12WWXpSuvvLIy6lPNi874vWxJF511m+bFqLmf/exnK8+/+tWv5hEQ77rrrtSSRJP+OL4hjmvdZkXVIkYJi0zFTTbZJLUUzt/iz+EInOy0006pWsT3WXy3tcTzt9rO4bLIYn7wwQfTzjvvnJqboBTQ4oNSMfx2NLGLIWEj4BNf8pERdeedd+bhSjt16pQ+9rGP5WBRfMGuSVAqxFDko0aNSn/+85/ztuPLOe7qRxvwsmjXHj8s8UP46quvps0226zWdmMY2MsvvzwPvRuBrRg+PH6EPvWpTwlKAVCI1hA4aakXnTQ952+xrRD++te/5r5Tq0G1lLeazuELLrggX89En7nNTVAKAABaqegHMZolFtlpbWsqbzTbj476t9xyy5X6jHnnnXfSL37xi3TSSSellqTayhwZ6nEDsn///mnXXXdNf/vb33LWSdyIjMz0j3zkI6klqabyRsZ+faK8Udbyzdxo3tcSVFt56xM3vidNmpT7merevXv+W4suR1qas88+O/frGANFxVS3SX2Rx1hQCgAAWqnILoj+E+vrm7ElaknljY7uowuB6OA+muREf2IxAm90ChwiczouOltCWau1zNFMM/oOioyNt99+O9122235In7PPffM2esxQuPdd9/dYgI91VbeDTbYIJetbufgUc7o4Dqy++M8uffee1NLUG3lDfH3FE2OI2AWmVIHHnhgPhei1UQEMBctWpSDmB/4wAdSS3LIIYesclnRx1hQCmhVotPzn/zkJ/Uuizss0akfALQWt99++2qXx0Ac5513XosJQlRTeaMJ/rvvvptuuOGG3Iw/sjiefPLJ3BVAjNDb0gI81VjmyDaKAM6YMWPSzTffnEfsjH5CL7nkkrw8uleIbhZipOWWoNrKG/2dRr+o0f9pzUBZZMVEAHhVI8Y1l2orbzmQFk32tt1223TcccflxzE6eAyUEdlzn/nMZ3Jz5F/+8pfNXdQWS1AKaFXmzZuXh/GuT/Q9FT8YANBaxAVR3NWOO/OrEstbShCimsobnUH//ve/zxkPZWeccUb63e9+l+67776ctdGSAjzVWObOnTvnpoYxCvKKFSvygDZ/+ctfcrZciIBajHpc7qenuVVbeUMEyeLG7JFHHpmDPhHgaclBnmorb82gVHQeXzegFudHBKaiaTL122AV8wGqUvwgREWhvklACoDWJpplxTDpcYFc3/TII4+klqSayht9M7Vt27bWvB/84Afpk5/8ZBowYEBuKtfSVGOZa17cR0ZJzaZbHTt2TAsWLEgtUbWUd7/99suBtH//+9+5CVw0NSuPENcSVVt5Q7l8kRkVgeGa4nnsC6smKAUAAFVq3333XW0g572ykopWTeWNPmAeeuihleZ///vfz/0KRaCnpam2Mu+4447pueeeqzyPkZCjmWFZZJeU+8NqCaqtvGXRB1Z0vj1y5Mg0aNCgFpMp11rKe+ihh+ZsuWitUTfwG/27bb311s1WtmpQO4wOAABUja9+9atp8eLFq1wemcLRbKulqKbyRv9M0Un4iSeeuNKyq666Kmd2tbS+KqutzNEfU82AQ+/evWstv/POO1tMp+HVWN66jj322HTQQQflTKQddtghtXTVUN4YLbSm6Euqpt/+9rd5wAFWTZ9SAAAAABRO8z0AAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAABYjwwcODANHz68QevuuOOOaeLEiZXnbdq0Sb/+9a/X6f1POeWUdPTRR6/TNoDWoW1zFwAAAIDq8Morr6QttthinbZx5ZVXplKpVCtIttdee9UKfgHrB0EpAAAAGqRr167rfKQ6d+7cqEc7AlzLly9Pbdu6vIVqo/keAABAE/nVr36V9thjj9S+ffu01VZbpcMOOywtXry40oTtoosuSttuu23q1KlTOu2009KyZctqBVvGjx+fdtppp/z6PffcM2+vpqeeeip9/OMfT5tttlnq0qVLOvHEE9Nrr71WWR7vddJJJ+Xl3bp1S1dcccU67U/N5nsvvPBCfv6LX/wiffjDH85l3G+//dLf//73NHPmzNS3b9/8vh/72MfSv//973qb78XjadOm5eyp2FZMsd3Vuf/++/N6d999d36Pdu3apT/+8Y/pH//4RzrqqKPycYj3jbL8/ve/r7zu+9//fv4symI/Yjs/+MEPKvM++tGPppEjR67TMQIaTlAKAACgiZq6HXfccekLX/hCevrpp3MwZciQIZWma/fcc0+ef99996Wf/exn6bbbbstBqrKvf/3r6YYbbkhXX311mjVrVjrnnHPSCSeckIM45e0PGDAgN3176KGH0l133ZVeffXVdMwxx1S28dWvfjVvP7Y9ZcqUXIaHH364UffzW9/6Vi7rI488krOVYp9HjBiRA03lYNE3v/nNel8b6xxwwAHp1FNPzfsTU48ePRr0vvEe48aNy8ewT58+6a233soBughEPfrooznAdOSRR6aXXnqp0kwwjmM5aBfHceutt64cz3fffTdNnz49H1OgGPIbAQAAmkAEWCLQEYGoHXbYIc+rmamz8cYbp+uvvz516NAh7b777uniiy/OQaRvf/vbacmSJWnChAnp3nvvzUGbEBlTDzzwQPrv//7vHDiJYNU+++yTxo4dW9lmbC+COpGt1L1793Tdddelm266KQ0aNCgvnzRpUtpuu+0adT/PP//8HAAKZ599dg5KRcDtwAMPzPO++MUvphtvvHGVTfniOMQxWNOmgXG8yvsVIhMtssnKxowZk4Nxt99+ezrzzDNT79698zoRhPr0pz+dA3TnnXde+u53v5vXj+yud955Jx100EFrdRyANScoBQAA0AQiQHLooYfmQFQEbQYPHpw+85nPVDoKj+URjCmL4FNk+8yZMyfNmzcvB0hqBl1CNO/be++98+PIeIosqGiqVldkJ0VgK9YvB7XClltumXbddddG3c/IUiqLpnN1g28xL/ansUXTvZqiqWJkmv3ud79L//rXv3JAMI5BOVMqmuodfPDBORgVn0tkTZ1++unpO9/5TiWTLYJ89R1PoGkISgEAADSBDTfcME2dOjU3CYumc9Gn0ahRo9Jf/vKX1b4ugicrVqzIj++44470vve9r9by6EMpxDrRPO2yyy5baRvRf9Szzz6birDRRhvVKnt988r705g23XTTWs8jyyz6mYog0/vf//7cx1UEAWv20xVN+K655prcrDCCgptvvnkOVEX2VASlYjlQHEEpAACAJhIBmWjGFlP0qxTN+KJJWfjrX/+aM3kieBJmzJiRs3SieV1kU0XwKbJ8VtXHUWT13HLLLWnHHXesd+S5CMxEcCi2u/322+d58+fPz037WlK/SdF8L0bPW1cRaIqO0z/1qU/l55F1VrfT9Ag6RRPD6DC+HICKYxH9UEXwMJYBxdHROQAAQBOIjKjo7yk6IY/g0q233ppHofvgBz+Yl0cGT/S3FCPo3XnnnbnD8Oj7aIMNNkgdO3bMfTVF5+bRD1Q0x4vOu2OkuHgezjjjjPTGG2/kPpwefPDB9Pzzz+eMrOhYPYI8EeCK7UcGUfTx9OSTT+agTWy/JYmgWhyrCCBFJ+Rrm1UVQbg4xo899lgO+A0dOnSlbZX7lfrpT39aCUrF/zESXwQI9ScFxWpZ30YAAACtRKdOndIf/vCHPCLcLrvskkeou+KKK9Lhhx+el0e/Rr169crNx2LEvGiKN3r06Mrro8PzyK6KEeYikBX9Uv32t79NPXv2zMujI/M//elPOQAVyyLgEpk+0Xl4OfB0+eWX5+1/8pOfTIcddlgOuuy7776pJYngWzR13G233dI222xT6QNqTUWH5ZFh1r9//3ws45hENlndzLVyltiHP/zhSp9Yccyir674zIDitCmVxyMFAACgEJGx9Oabb+YMHYD1lUwpAAAAAAonKAUAALAeio7Bo9+pVU3N5fTTT19lmWIZ0HpovgcAALAeio69X3755dV2HN4c5s2blxYuXFjvsujzadttty28TEDTEJQCAAAAoHCa7wEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgAAAKBwglIAAAAAFE5QCgAAAIDCCUpVqRtvvDG1adOmMrVt2zZtt9126fOf/3x6+eWXU7V76qmn0ujRo9MLL7zQ6Nu+5557Ut++fdOmm26aj92vf/3r1FLdf//9uYzxf9EmT56cJk6cmFqSOCfieLz22muFvefAgQPzVPb222/nctT3mTRH+dZV/I1Fmb/zne+k1qLa9umNN95Ixx57bNp2221zuY8++ugGn49Ay6BetvbUyxpGvez/qJe1TuU69Hs55ZRT0o477lhrXjyP+Y2p7jb/9a9/5TI+9thjjfo+/J+2////VKkbbrghfeADH0hLlixJf/jDH9K4cePStGnT0hNPPJGDLtUclLrooovyD0/dL551USqV0jHHHJN22WWXdPvtt+djtOuuuzba9luTqPw8+eSTafjw4Wl99sMf/rDW8whKxbkZBAdoDN/+9rfTbbfdlq6//vq08847py233NKBhSqlXrZm1MsaTr3s/6iXUVfUoTp16tSk24ygVNT/47p0r7328iE0MkGpKte7d++c9RMOOeSQtHz58nyBE9k/xx9//DptOy6+O3TokFqT+EKJrIRPfepT6dBDD13j1//nP/+pZKZRnAi6brLJJs1yyHfbbbdmeV9avsb6PojgbwSj1vU7G2h+6mVrRr2sOqmX0ZLsvffeVbFNVk3zvVZm//33z/+/+OKLlTtQcUchIrrt27dPW2yxRfrMZz6Tnn/++Vqvi4yPqEhFtlX//v1zMOoLX/hCXvbmm2+m8847L+20006pXbt2uYnJxz/+8fS3v/2t8vply5alMWPG5KytWGebbbbJTQn//e9/13qfiC5/4hOfSHfddVfaZ599cpniNZEhUDMF/rOf/Wwl0FZuohjzV+eBBx7IgaaOHTvm8sd+3HHHHZXlkXIZTRzDBRdckLe5uiysctO5H//4x3n/3/e+9+V9e+655/Ly3//+9/n9Iooe73fggQfmFPSaYt04Dr169crrxDaOPPLInMlWVxzPj33sY3m9rbfeOp1++ulp0aJFq93nmvsWZZ01a1Y67rjjUufOnVOXLl3yZ7hgwYJa6zbknIjzIY5dnEc1m4mG/fbbLx1xxBG1trnHHnvk5TNnzqzMu/XWW/O8mvv6Xp9RzSYQU6ZMyeWPcynWXbp0ab37Hsctzs1+/fqlefPm1btOHJfY5i9/+cvKvIcffjjP23333Wut+8lPfjLtu+++tY5FOSMqmoVFeULcLSkfl7opw6+++up7fg6r0tjnVUP+fssmTJiQevbsmTbbbLN0wAEHpBkzZrxnecuf13333Ze+/OUv53N3q622SkOGDMkXGzXFenGuvleKdHmb9957bzr11FPz9uJ4nHTSSWnx4sVp7ty5OeNx8803T926dUvnn39+DhDVtWLFinTJJZek7bffPgc1I4Bf91iGZ599Ng0dOjQfmzhGH/zgB9MPfvCDNfo+qE8EwIcNG5bX3XjjjfNnMGrUqMq5XG5mGJ/5008/XTmf1rS5bpyLcf5HhlUcp/huve666/Lf+pp+/5bFMT7ttNPyd2aUPc6LeJ9333231npXX3112nPPPfM5E3/Xsb2vfe1ra1R+aM3Uy9TL1MtWpl7WdPWySCqIelG8Luo+UTeI+s/PfvazyjpR54ptxucQdc5oORL12zPPPDO/vqaGXks2tA4bou4f24v9j3Kua3cLdeuR5TpbZBfGNV/UFWN/o64cdfS4vvqv//qvXGeNKerUb7311iq3GduL658Q65bra/XVaVlLJarSDTfcEFcbpZkzZ9aaf+WVV+b511xzTX5+6qmnljbaaKPSeeedV7rrrrtKkydPLn3gAx8odenSpTR37tzK6wYMGFDacsstSz169Ch9//vfL913332ladOmlRYuXFjafffdS5tuumnp4osvLt19992lW265pXT22WeX7r333vza5cuXlz72sY/ldS666KLS1KlTS//zP/9Tet/73lfabbfdSm+//XblfXbYYYfSdtttl+ffdNNNeXuf/exnc5nj/cK8efNKY8eOzfN+8IMflP785z/nKeavyv3335/3c9999y39/Oc/L/36178uDR48uNSmTZvSzTffnNeZM2dO6dZbb83b/cpXvpK3+cgjj6xym3EMYt3Yj8985jOl22+/vfS73/2u9Prrr5d+/OMf520fffTReZu//e1vS5/4xCdKG264Yen3v/99ZRuxT3Hsf/WrX+XHt912W35N+/btS3/7298q68Vnse222+b3is/2f//3f0vHH398afvtt89liLKszre+9a28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Lmny5MnptNNOc3BpVYqsD64JdUeA9yZTCgCgitx+++2pb9++6bOf/Wzadttt0957752uvfbayvLZs2enuXPnpsGDB1fmtWvXLg0YMCBNnz59ldtdunRpWrhwYa0JAKApCUoBAFSR559/Pl199dWpV69e6e67706nn356Ouuss9JNN92Ul0dAKkRmVE3xvLysPuPGjUudO3euTJGNBQDQlASlAACqyIoVK9I+++yTxo4dm7OkojneqaeemgNVNbVp06bW82jWV3deTSNHjkwLFiyoTHPmzGmyfQAACIJSAABVpFu3bmm33XarNe+DH/xgeumll/Lj6NQ81M2Kmjdv3krZUzVFE79OnTrVmgAAmpKgFABAFYmR95555pla8/7+97+nHXbYIT/u2bNnDkxNnTq1snzZsmVp2rRpqX///oWXFwBgVYy+BwBQRc4555wcXIrme8ccc0x68MEH0zXXXJOnEE30hg8fnpdHv1MxxeMOHTqkoUOHNnfxAQAqBKUAAKrIfvvtl2677bbcB9TFF1+cM6MmTpyYjj/++Mo6I0aMSEuWLEnDhg1L8+fPT/369UtTpkxJHTt2bNayAwDUJCgFAFBlPvGJT+RpVSJbavTo0XkCAGip9CkFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAAKx/QamXX345nXDCCWmrrbZKHTp0SHvttVd6+OGHK8tLpVIeOaZ79+6pffv2aeDAgWnWrFnNWmYAAAAAqjgoNX/+/HTggQemjTbaKN15553pqaeeSldccUXafPPNK+uMHz8+TZgwIV111VVp5syZqWvXrmnQoEFp0aJFzVl0AAAAANZB29SMLrvsstSjR490ww03VObtuOOOtbKkJk6cmEaNGpWGDBmS502aNCl16dIlTZ48OZ122mnNUm4AAAAAqjhT6vbbb099+/ZNn/3sZ9O2226b9t5773TttddWls+ePTvNnTs3DR48uDKvXbt2acCAAWn69On1bnPp0qVp4cKFtSYAAAAAWpZmDUo9//zz6eqrr069evVKd999dzr99NPTWWedlW666aa8PAJSITKjaorn5WV1jRs3LnXu3LkyRSYWAAAAAC1LswalVqxYkfbZZ580duzYnCUVzfFOPfXUHKiqqU2bNrWeR7O+uvPKRo4cmRYsWFCZ5syZ06T7AAAAAECVBaW6deuWdtttt1rzPvjBD6aXXnopP45OzUPdrKh58+atlD1Vs3lfp06dak0AAAAAtCzNGpSKkfeeeeaZWvP+/ve/px122CE/7tmzZw5MTZ06tbJ82bJladq0aal///6FlxcAAACAVjD63jnnnJODS9F875hjjkkPPvhguuaaa/IUoone8OHD8/LodyqmeNyhQ4c0dOjQ5iw6AAAAANUalNpvv/3SbbfdlvuBuvjii3Nm1MSJE9Pxxx9fWWfEiBFpyZIladiwYWn+/PmpX79+acqUKaljx47NWXQAAAAAqjUoFT7xiU/kaVUiW2r06NF5AgAAAKB1aNY+pQAAAABYPwlKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAACqyOjRo1ObNm1qTV27dq0sL5VKeZ3u3bun9u3bp4EDB6ZZs2Y1a5kBAOojKAUAUGV233339Morr1SmJ554orJs/PjxacKECemqq65KM2fOzAGrQYMGpUWLFjVrmQEA6hKUAgCoMm3bts3BpvK0zTbbVLKkJk6cmEaNGpWGDBmSevfunSZNmpTefvvtNHny5OYuNgBALYJSAABV5tlnn83N83r27JmOPfbY9Pzzz+f5s2fPTnPnzk2DBw+urNuuXbs0YMCANH369NVuc+nSpWnhwoW1JgCApiQoBQBQRfr165duuummdPfdd6drr702B6H69++fXn/99fw4dOnSpdZr4nl52aqMGzcude7cuTL16NGjSfcDAEBQCgCgihx++OHp05/+dNpjjz3SYYcdlu644448P5rplUXn5zVFs7668+oaOXJkWrBgQWWaM2dOE+0BAMD/EZQCAKhim266aQ5QRZO+8ih8dbOi5s2bt1L2VF3RzK9Tp061JgCApiQoBQBQxaIvqKeffjp169Yt9zEVgampU6dWli9btixNmzYtN/EDAGhJ2jZ3AQAAaLjzzz8/HXnkkWn77bfPGVBjxozJnZKffPLJuYne8OHD09ixY1OvXr3yFI87dOiQhg4d6jADAC2KoBQAQBX55z//mY477rj02muvpW222Sbtv//+acaMGWmHHXbIy0eMGJGWLFmShg0blubPn587Rp8yZUrq2LFjcxcdAKAWQSkAgCpy8803r3Z5ZEuNHj06TwAALZk+pQAAAAAonKAUAAAAAOtXUCrSyiPFvOZUHso4lEqlvE737t1T+/bt08CBA9OsWbOas8gAAAAAtIZMqd133z298sorlemJJ56oLBs/fnyaMGFCuuqqq9LMmTNzwGrQoEFp0aJFzVpmAAAAAKo8KNW2bdscbCpPMYpMOUtq4sSJadSoUWnIkCGpd+/eadKkSentt99OkydPbu5iAwAAAFDNQalnn302N8/r2bNnOvbYY9Pzzz+f58+ePTvNnTs3DR48uLJuu3bt0oABA9L06dNXub2lS5emhQsX1poAAAAAaFmaNSjVr1+/dNNNN6W77747XXvttTkI1b9///T666/nx6FLly61XhPPy8vqM27cuNS5c+fK1KNHjybfDwAAAACqKCh1+OGHp09/+tNpjz32SIcddli644478vxoplcWnZ/XFM366s6raeTIkWnBggWVac6cOU24BwAAAABUZfO9mjbddNMcoIomfeVR+OpmRc2bN2+l7Kmaoolfp06dak0AAAAAtCwtKigV/UE9/fTTqVu3brmPqQhMTZ06tbJ82bJladq0abmJHwAAAADVq21zvvn555+fjjzyyLT99tvnDKgxY8bkjslPPvnk3ERv+PDhaezYsalXr155iscdOnRIQ4cObc5iAwAAAFDNQal//vOf6bjjjkuvvfZa2mabbdL++++fZsyYkXbYYYe8fMSIEWnJkiVp2LBhaf78+blj9ClTpqSOHTs2Z7EBAAAAqOag1M0337za5ZEtNXr06DwBAAAA0Hq0qD6lAAAAAFg/CEoBAAAAUDhBKQAAAAAKJygFAAAAQOEEpQAAAAAonKAUAAAAAIUTlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAVWzcuHGpTZs2afjw4ZV5pVIpjR49OnXv3j21b98+DRw4MM2aNatZywkAUJegFABAlZo5c2a65pprUp8+fWrNHz9+fJowYUK66qqr8jpdu3ZNgwYNSosWLWq2sgIA1CUoBQBQhd566610/PHHp2uvvTZtscUWtbKkJk6cmEaNGpWGDBmSevfunSZNmpTefvvtNHny5GYtMwBATYJSAABV6IwzzkhHHHFEOuyww2rNnz17dpo7d24aPHhwZV67du3SgAED0vTp01e5vaVLl6aFCxfWmgAAmlLbJt06AACN7uabb06PPPJIbppXVwSkQpcuXWrNj+cvvvjiavumuuiii3xaAEBhZEoBAFSROXPmpLPPPjv95Cc/SZtssskq14vOz2uKZn1159U0cuTItGDBgsoU7wMA0JRkSgEAVJGHH344zZs3L+27776VecuXL09/+MMfcsfmzzzzTCVjqlu3bpV14jV1s6dqiiZ+MQEAFEWmFABAFTn00EPTE088kR577LHK1Ldv39zpeTzeaaed8mh7U6dOrbxm2bJladq0aal///7NWnYAgJpkSgEAVJGOHTvmEfVq2nTTTdNWW21VmT98+PA0duzY1KtXrzzF4w4dOqShQ4c2U6kBAFYmKAUA0MqMGDEiLVmyJA0bNizNnz8/9evXL02ZMiUHtAAAWgpBKQCAKnf//ffXeh4dmo8ePTpPAAAtVYvpUyqGIY4KVKSb1xwlJipT3bt3T+3bt08DBw5Ms2bNatZyAgAAANBKglIzZ85M11xzTerTp0+t+ePHj08TJkzII8nEOtFp56BBg9KiRYuarawAAAAAtIKg1FtvvZVHi7n22mvTFltsUStLauLEiWnUqFFpyJAhuePOSZMmpbfffjtNnjx5ldtbunRpWrhwYa0JAAAAgFYQlIqhhl9//fWV5r/55pt52Zo444wz0hFHHJEOO+ywWvNnz56d5s6dmwYPHlyZ165duzRgwIA0ffr01TYD7Ny5c2Xq0aPHGpUHAKCpNGYdCgBgvQxKvfDCC2n58uX1Zim9/PLLDd7OzTffnB555JEcSKorAlKhS5cutebH8/Ky+owcOTItWLCgMs2ZM6fB5QEAaEqNVYcCAFjvRt+7/fbbK4/vvvvunIlUFhWse+65J+24444N2lYEi84+++w8PPEmm2yyyvWi8/Oaollf3Xk1RTZVTAAALUVj1qEAANbLoNTRRx+d/4+g0Mknn1xr2UYbbZQrU1dccUWDtvXwww+nefPmpX333bdWpewPf/hD7tj8mWeeyfMiK6pbt26VdeI1dbOnAABassasQwEArJdBqRUrVuT/e/bsmUfD23rrrdf6jQ899ND0xBNP1Jr3+c9/Pn3gAx9IF1xwQe5XIUbbmzp1atp7773z8mXLlqVp06alyy67bK3fFwCgaI1ZhwIAWC+DUjU7IV9XHTt2zCPq1bTpppumrbbaqjJ/+PDhaezYsalXr155iscdOnRIQ4cOXef3BwAoWmPUoQAA1uugVIi+D2KK5nTlu39l119/fWOULY0YMSItWbIkDRs2LM2fPz/169cv90EVAS0AgGpURB0KAKDVBqUuuuiidPHFF6e+ffvm/p5W1/H4mrj//vtrPY/tjh49Ok8AANWuqepQAADrTVDqRz/6UbrxxhvTiSee2PglAgBopdShAAD+nw3SWogOx/v37782LwUAWG+pQwEArGNQ6ktf+lKaPHny2rwUAGC9pQ4FALCOzffeeeeddM0116Tf//73qU+fPmmjjTaqtXzChAlrs1kAgFZNHQoAYB2DUo8//njaa6+98uMnn3yy1jIddgIAqEMBADRJUOq+++5bm5cBAKzX1KEAANaxT6my5557Lt19991pyZIl+XmpVFqXzQEArBfUoQAA1jIo9frrr6dDDz007bLLLunjH/94euWVVyqdd5533nmOKwCAOhQAQOMHpc4555zcuflLL72UOnToUJn/uc99Lt11111rs0kAgFZPHQoAYB37lJoyZUputrfddtvVmt+rV6/04osvrs0mAQBaPXUoAIB1zJRavHhxrQypstdeey21a9dubTYJANDqqUMBAKxjUOrggw9ON910U+V5mzZt0ooVK9Lll1+eDjnkkLXZJABAq6cOBQCwjs33Ivg0cODA9NBDD6Vly5alESNGpFmzZqU33ngj/elPf1qbTQIAtHrqUAAA65gptdtuu6XHH388fehDH0qDBg3KqehDhgxJjz76aNp5553XZpMAAK2eOhQAwDpmSoWuXbumiy66aG1fDgCwXlKHAgBYh0ypG264If3yl79caX7MmzRp0tpsEgCg1VOHAgBYx6DUpZdemrbeeuuV5m+77bZp7Nixa7NJAIBWTx0KAGAdg1Ivvvhi6tmz50rzd9hhh/TSSy+tzSYBAFq9xqhDXX311alPnz6pU6dOeTrggAPSnXfeWVleKpXS6NGjU/fu3VP79u3z4DQxIA0AQKsISkVGVHR0Xtdf//rXtNVWWzVGuQAAWp3GqENtt912OeMqRkGO6SMf+Ug66qijKoGn8ePHpwkTJqSrrroqzZw5M/dhFQPTLFq0qNH3BwCg8KDUsccem84666x03333peXLl+fp3nvvTWeffXZeBgBA09ShjjzyyPTxj3887bLLLnm65JJL0mabbZZmzJiRs6QmTpyYRo0alUdG7t27d+7v8+23306TJ0/2kQAA1T/63pgxY3L6+aGHHpratv2/TaxYsSKddNJJ+pQCACioDhVBrRhoZvHixbkZ3+zZs9PcuXPT4MGDK+u0a9cuDRgwIE2fPj2ddtppq9zW0qVL81S2cOFCnyMA0LKCUnEH7pVXXsmjx0TF6rHHHsv9Feyxxx65PwQAAJq2DvXEE0/kINQ777yTs6Ruu+22tNtuu+XAU+jSpUut9eN5BMNWZ9y4cemiiy7y0QEALTso1atXr9xvQfwfEwAAxdWhdt111xzUevPNN9Mtt9ySTj755DRt2rTK8jZt2qz03nXn1TVy5Mh07rnn1sqU6tGjx1qXEQCg0fuU2mCDDXIl6vXXX1/TlwIArLcasw618cYbp/e///2pb9++OcNpzz33TFdeeWXu1DxEE76a5s2bt1L2VF3RzK88ol95AgBocR2dx6guX/3qV9OTTz7Z+CUCAGilmqoOFZlQ0R9Uz549c2Bq6tSplWXLli3LWVT9+/dv1PcEAGiWoNQJJ5yQHnzwwXxXLvpC2HLLLWtNDXX11VenPn36VO7GRd8Id955Z60K1ujRo1P37t3z+wwcOLAy3DEAQLVpjDrU1772tfTHP/4xvfDCC7lvqRhp7/7770/HH398bqI3fPjw3Gl69DMVwa9TTjkldejQIQ0dOrTJ9w8AoMlH34uhhhvDdtttly699NKcfh5iyOKjjjoqPfroo2n33XfPdxMnTJiQbrzxxjzkcXQKOmjQoPTMM8+kjh07NkoZAACK0hh1qFdffTWdeOKJudP0zp075xt8d911V64jhREjRqQlS5akYcOGpfnz56d+/fqlKVOmqDsBAC1Om1KkI7UgcZfw8ssvT1/4whdyhlTc7bvgggvyskhLj/4QLrvsstUOaVxTdNIZFbYFCxboG6EV2vHCOwp7rxcuPaKw9wKg5Vhf6xLr635TfYqsD64JdUdgfbawgfWItWq+F/7xj3+kr3/96+m4447LnWeGuEu3ts3rli9fnm6++ea0ePHi3Ixv9uzZuZPOwYMH1+qAc8CAAZXhjusTgavY+ZoTAEBL0dh1KACAarVWQanoLHOPPfZIf/nLX9Ktt96a3nrrrTz/8ccfT9/61rfWaFvRF8Jmm22WA06nn3567v9gt912q4waU3ekmHhed0SZmmIEmojGlSdDGQMALUVj1qEAANbLoNSFF16Y+3eKkV1iSOKyQw45JP35z39eo23tuuuu6bHHHkszZsxIX/7yl9PJJ5+cnnrqqcry6LCzpmhtWHdeTSNHjszpYeVpzpw5a1QeAICm0ph1KACA9bKj88humjx58krzt9lmm/T666+v0baiQlbu6Lxv375p5syZ6corr6z0IxVZUd26dausH2nudbOnaoqMq5gAAFqaxqxDAQCsl5lSm2++eR7xpa4YNe9973vfOhUoMqGiX6iePXumrl275juJZcuWLctp7/3791+n9wAAaA5NWYcCAFgvglJDhw7NmUyRxRRN6VasWJH+9Kc/pfPPPz+ddNJJDd7O1772tfTHP/4xvfDCC/nO4ahRo9L999+fjj/++LzdGHlv7NixuZ+pJ598Mp1yyimpQ4cO+f0BAKpNY9WhAADW2+Z7l1xySQ4QxR29yGyKjsnffffdHEyK0WQa6tVXX00nnnhivmMYnZL36dMnjz4zaNCgvHzEiBFpyZIladiwYWn+/PmpX79+acqUKaljx45rU2wAgGbVWHUoAIDWoE0pakRr6fnnn08PPfRQvtO39957V/qGakkWLlyYA17R6XmnTp2auzg0sh0vvKOwY/rCpUcU9l4AtO66hDoUVGd9cE2oOwLrs4UNrD+tVaZUuO6669J3v/vd9Oyzz+bnvXr1ys3tvvSlL63tJgEAWj11KACAdQhKfeMb38gBqa985SvpgAMOyPNiGONzzjkn9w8VQx0DAKAOBQDQqEGpq6++Ol177bXpuOOOq8z75Cc/mfuEikCVoBQAgDoUAECjj763fPny1Ldv35Xm77vvvrmzTgAA1KEAABo9KHXCCSfkbKm6rrnmmjx6DAAA6lAAAKuzTh2dT5kyJe2///75+YwZM9KcOXPSSSedlM4999zKehMmTFjbtwAAaHXUoQAA1iEo9eSTT6Z99tknP/7HP/6R/99mm23yFMvK2rRpszabBwBoldShAADWMSh13333rc3LAADWa+pQAADr2KcUAAAAAKwLQSkAAAAACicoBQAAAEDhBKUAAAAAKJygFAAAAACFE5QCAAAAoHCCUgAAAAAUTlAKAAAAgMIJSgEAAABQOEEpAAAAAAonKAUAAABA4QSlAAAAACicoBQAAAAAhROUAgCoIuPGjUv77bdf6tixY9p2223T0UcfnZ555pla65RKpTR69OjUvXv31L59+zRw4MA0a9asZiszAEB9BKUAAKrItGnT0hlnnJFmzJiRpk6dmt599900ePDgtHjx4so648ePTxMmTEhXXXVVmjlzZuratWsaNGhQWrRoUbOWHQCgpra1ngEA0KLdddddtZ7fcMMNOWPq4YcfTgcffHDOkpo4cWIaNWpUGjJkSF5n0qRJqUuXLmny5MnptNNOq3e7S5cuzVPZwoULm3hPAID1nUwpAIAqtmDBgvz/lltumf+fPXt2mjt3bs6eKmvXrl0aMGBAmj59+mqbBXbu3Lky9ejRo4DSAwDrM0EpAIAqFVlR5557bjrooINS796987wISIXIjKopnpeX1WfkyJE5wFWe5syZ08SlBwDWd80alNJRJwDA2jvzzDPT448/nn72s5+ttKxNmzYrBbDqzqspsqk6depUawIAaLVBKR11AgCsna985Svp9ttvT/fdd1/abrvtKvOjU/NQNytq3rx5K2VPAQCst0Gp6KjzlFNOSbvvvnvac889c0edL730Uu6oM9TtqDPS0qOjzrfffjt31Fmf6KAzOuasOQEAtBZRP4oMqVtvvTXde++9qWfPnrWWx/MITMXIfGXLli3LNwP79+/fDCUGAKiCPqUao6NOnXQCAK3ZGWeckX7yk5/kG3QdO3bMdaWYlixZkpdHE73hw4ensWPHpttuuy09+eST+SZghw4d0tChQ5u7+AAAFW1TlXbU+eKLL66yk87YTllkShk9BgBoLa6++ur8/8CBA2vNj4zzCD6FESNG5CDVsGHD0vz581O/fv3SlClTchALAKClaDFBqXJHnQ888MA6ddQZmVQxAQC0RlEPei9RTxo9enSeAABaqhbRfE9HnQAAAADrl2YNSumoEwAAAGD91La5O+qMTjp/85vfVDrqDJ07d07t27ev1VFnr1698hSPddQJAAAAUN2aNSilo04AAACA9VOzBqV01AkAAACwfmoRHZ0DAAAAsH4RlAIAAACgcIJSAAAAABROUAoAAACAwglKAQAAAFA4QSkAAAAACicoBQAAAEDh2hb/ljSXHS+8o7D3euHSIwp7LwAAAKD6yJQCAAD+P/buA8yJ6uvj+KF3kN67WKjSREAFRLCLon9FkG6hCYgFsFGkKCqiIiAiRRGsoCiCoBQLIr0IVqSJ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iC0RXVMKAAAAAAAAsYmgFAAAAAAAAEKOoBQAAAAAAABCjqAUAAAAAAAAQo6gFICIxBwMAAAAiEYnT560CRMm2LZt28K9KlFh3rx54V4FhBGz7yXTX3/9ZSNHjrQFCxa4g02aNGmsYMGCVqdOHevQoYMVL148ZbcUkMpkzJjRVq5caZdeemm4VwUAECYnTpywiy++2D7//HMrX7482wEIsWnTpiX6ubfeeut5XZdokzVrVvv555+tZMmS4V6ViJc5c2YrWrSotW3b1lq3bs25dDx69OhhiTV06FCLJunDvQLR6LvvvrMbbrjBfVgaN27sbsrq2LFjh33yySf22muv2YwZM6xu3boWSzZv3mx9+vSxsWPHWjQ5cuSILV261PLkyROnQ3v06FH74IMPrFWrVhZN9AW3cOFCq127tl1yySX2yy+/2CuvvGLHjh2ze++916655hqL9gPsqVOn7LnnnrO8efNG5cE12J49e9wVs99//90KFy4clV+4y5cvtwsuuMBKly7tfp44caILzm/atMl1uLp06WLNmjWzaPLQQw/ZXXfdZVdddZXFEn0PLVmyxG666Sb3/t555x0bPHiwnT592po2bWr9+/e39OnpAiDyZciQwX236eIfkkd9HZ3wAclx2223Jep5+oyq74b/1KpVy1asWEFQKhH+/vtv168cP3689e3b1xo2bGjt27d3+58uVMNcPzyxn8VoQ6ZUMtSsWdOuvPJKe/nll+N9/OGHH3aBq8WLF1ssUdZKtWrVouoL57fffnNBQ5006wOqE8/Jkye7oIBs377dihQpElXvaebMmdakSRPLnj27HT582KZOneqCalWqVHHB0fnz59uXX34ZNYGptGnTunVXsMOf3keNGjUsW7ZsbtvNmTPHoon2q9WrV7ug2vr1610WpVSqVMkFFQ8cOOACiwoqRgt9/l966SVr0KCBjRkzxrp27Wr333+/y2b79ddf3TIFR9u1a2fRQvuf9q+yZcu6zo+ChYUKFbJo9uyzz9oLL7zgjn3ff/+9de/e3f2s7ya9X313dezY0fr162fR5tChQzZp0qQ4Wcq6CHTPPfe44wVijy5Q6OKLjjEEUxNHAeiBAwfaqFGjXF9H/aEyZcrY008/baVKlXLHu9SsatWqiT5xW7Zs2XlfH8SmDz/80Hr16uW+f6tXrx7nO6py5cphW7dIpkCe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1qRJE5s3b56VKVPG8uXLZ+nTpz+vf7NNmza2d+9e++STT3zLTp06Zf/8809I/j6A6MXRAQAAAABixLp166xw4cJWp06dsK5HunTprFChQmFdBwCRj+F7AAAAABADlLH00EMP2aZNm9zQuVKlSrnbsGHDAp532WWXWd++fX0/67ljxoyx22+/3bJmzWrlypWzadOmBfzOmjVr7KabbrKcOXNajhw57KqrrnIBML3OhAkT7NNPP3Wvo5uytOIbvjd//ny7/PLLLVOmTC5w1qtXLzt58qTv8fr161vXrl3t8ccfd8MPFdTyX08AsYegFAAAAADEgFdeecX69+9vxYoVs61bt9rixYsT/bv9+vWzu+66y1atWmU33nijtWjRwnbv3u0e27Jli1199dWWOXNmmzNnji1dutTatWvnAkqPPvqo+73rr7/e/U3d4svS0mvodWvWrGkrV660kSNH2ltvvWUDBgwIeJ4CXNmyZbMff/zRhgwZ4t7P7NmzU6B1AEQihu8BAAAAQAzIlSuXy2JKztA5ZVndc8897v6gQYPstddes0WLFrlg0+uvv+5e+7333rMMGTK451x00UW+382SJYsdO3bsjH9zxIgRVrx4cRs+fLjLoLrkkkvs77//tp49e9ozzzxjadP+my9RuXJl69Onj7uvjC09/+uvv7ZGjRolq00ARDYypQAAAAAglVMwyEuZSgpu7dixw/2sIXgarucNSCXHzz//bLVr13YBKa+6devawYMH7a+//op3PUTD/LzrASD2EJQCAAAAgBilDCSPxxOw7MSJE3GeFxxwUvDo9OnTvkyoc6V18A9IeZd5/1Zi1gNA7CEoBQAAAAAxKn/+/K7Ok9f+/ftt/fr1SXoNZS99++238QazJGPGjHbq1Kkzvkb58uVtwYIFAQEy/ayMrKJFiyZpfQDEDoJSAAAAABCjrrnmGnvnnXdcUOmnn36y1q1bu5pTSdGlSxcXzGrWrJktWbLEfv/9d/eav/76q3tcM/ypQLp+3rlzZ7zBq06dOtnmzZvd7IC//PKLm61PtaN69OjhqycFIPXh0w8AAAAAMap3795u5rybb77ZzX532223WdmyZZP0Gnnz5nWz7qn+U7169ax69er25ptv+oba3X///XbxxRdbjRo1XGbW999/H+c1lA31xRdfuOLpVapUsQ4dOlj79u3tqaeeSrH3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st9++81Klizp7lMXAQAAAAAAIDaFNVPq4YcfdkU3NXzvrrvuskWLFtno0aPdTfzrIqjulG66T10EAAAAAACA6BbWoFTNmjVdEU4VJ+/fv7/LjBo2bJgr1OlFXQQAAAAAAIDYE9aglNx8883ulhDqIgAAAAAAAMSesNaUAgAAAAAAQOqUrKBUmTJlbNeuXXGW79271z0GAAAA+lAAAAApHpTasGGDnTp1Ks7yY8eO2ZYtW5LzkgAAADGPPhQAAEAya0pNmzbNd//LL7+0XLly+X5WkOrrr7+2UqVKJeUlAQAAYh59KAAAgHMMSt12222+4uOtW7cOeCxDhgwuIPXSSy8l5SUBAABiHn0oAACAcwxKnT592v1funRpW7x4seXLly8pvw4AAJAq0YcCAAA4x6CU1/r165PzawAAAKkafSgAAIBzDEqJ6kfptmPHDt/VP6+xY8cm92UBAABiGn0oAACAcwhK9evXz/r37281atSwwoULuxpTAAAAoA8FAABwXoNSo0aNsvHjx1vLli2T8+sAAACpEn0oAACA/6S1ZDh+/LjVqVMnOb8KAACQatGHAgAAOMeg1H333WeTJk1Kzq8CAACkWvShAAAAznH43tGjR2306NH21VdfWeXKlS1DhgwBjw8dOjQ5LwsAABDT6EMBAACcY1Bq1apVdtlll7n7P/30U8BjFD0HAACgDwUAAHBeglJz585Nzq8BAACkavShAAAAzrGmlNcff/xhX375pR05csT97PF4zuXlAAAAUgX6UAAAAMkMSu3atcsaNmxoF110kd144422detWX/HORx55hHYFAACgDwUAAJDyQamHH37YFTfftGmTZc2a1bf87rvvtpkzZybnJQEAAGIefSgAAIBzrCk1a9YsN2yvWLFiAcvLlStnGzduTM5LAgAAxDz6UAAAAOeYKXXo0KGADCmvnTt3WqZMmZLzkgAAADGPPhQAAMA5BqWuvvpqe/vtt30/p0mTxk6fPm0vvPCCNWjQIDkvCQAAEPPoQwEAAJzj8D0Fn+rXr29Lliyx48eP2+OPP25r1qyx3bt32/fff5+clwQAAIh59KEAAADOMVOqfPnytmrVKrv88sutUaNGLhW9adOmtnz5citbtmxyXhIAACDm0YcCAAA4x0wpKVSokG/e1csAAEXYSURBVPXr1y+5vw4AAJAq0YcCAAA4h0yp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eGFg7NixYftcuXJlQB/HNm3a5Lf3798f6Ny5c6BQoUKBc889N9CgQYPAqlWrQt//+OOPBy6//PLAxIkTAyVLlgzkyZMn0LVr18CJEycCw4cP99+rnx0yZEjY70nvfqdMmRIoXbp0IF++fIEWLVoEDhw44Pe3bdvWjzPpZcuWLadds2+//TbQuHFj/51alzp16gQ2btwYWpNBgwb5uuTIkcN//wcffBD6We1fv2fWrFmB+vXrB3LlyhWoUqVKYNmyZWG/49VXX/W10P233XZb4JlnnvHnJ/ljC15P/jgWLVoU+l1fffVV6OcWL14cuPLKK/3YihYtGujbt2/g+PHjYX8P3bt3Dzz44IOB/Pnz+9pr/wD+PHpKxWij83379vl1ZUyd7uwAABw+fNibW6uXUNIL4pcanVepUsVuvPFGK126dLQPBwCyxMRaZZB+9tln9txzz9moUaNswoQJft+xY8ds8ODB3n9PpWFbtmzxUjHJnj27lz+//vrrYft74403rHbt2lauXDkvm7/55pvtp59+svfff9+nZus9vbJW9+7dG/qZTZs2eRXEhx9+aNOmTbNXXnnFf+7HH3/0Uuvhw4fbo48+aitWrPDv/zP71XGr0kIX7eupp57y+5599lk/zs6dO3uZmy4qeTuV7du3ewm4hmcoQ1u/t0OHDnbixInQPkeMGOFtRvR+44YbbrBbb73VNmzYELafRx55xEvw1O+pQoUK1rJly9A+9Dxon/fee6/fr6mxyvZNi/bTvHlz/78WfBxXX311qsfeuHFju/LKK/35HDt2rE2cODHFvvX3kCdPHj+O//znPz5g6qOPPjrlugBIRQYCWcjicubMGdi2bZtfz549O5lSANK0e/fuwM033+yvFaldEH8OHToU6NChQ+Css87yS/AMvs4IDxs2LNqHBwBRocyYSy65JJQZJcqe0bbUfP75555989tvv/ntL7/80isYgpmnweypF154wW8vWLDAM5SOHj0atp+LLrooMG7cOL+uTJzcuXOHMpjkhhtuCJQpU8b3F1SxYsXQ63VG96sMoJo1a4Y9/p49e6Z7vR5++OFA2bJlA8eOHUv1/uLFiweGDh0atk2ZSffee69fD2YvTZgwIXT/mjVrfNvatWv9trLRbrzxxrB9KMMrrUypYNZXkyZNwn4meaZU//79fQ2TPtd6npTtFVxnrYcy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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, axes = plt.subplots(3, 2, figsize=(12, 15))\n", + "\n", + "\n", + "sp = gdf.groupby('lts_level', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with lts level', ylabel = 'percent', ax=axes[0,0])\n", + "\n", + "sp = gdf.groupby('speed_limit_raw', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with each speed limit', ylabel = 'percent', ax=axes[0,1])\n", + "\n", + "sp = gdf.groupby('num_lanes_raw', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with each number of lanes', ylabel = 'percent', ax=axes[1,0])\n", + "\n", + "sp = gdf.groupby('function', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with each speed limit', ylabel = 'percent', ax=axes[1,1])\n", + "\n", + "sp = gdf.groupby('bike_facility_type', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with each bike lane type', ylabel = 'percent', ax=axes[2,0])\n", + "\n", + "sp = gdf.groupby('pavement_condition', dropna=False)['len'].sum()/gdf['len'].sum()*100\n", + "sp.plot(kind='bar', title = 'Percent of read network with each pavement condition', ylabel = 'percent', ax=axes[2,1])\n", + "\n", + "plt.tight_layout()\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "436d6335-c580-4ab5-a955-e81689e034db", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "c8f4f262-ae24-4380-b12d-6edbad307a2a", + "metadata": {}, + "outputs": [], + "source": [ + "gdf.to_file('levels.geojson')" + ] + }, + { + "cell_type": "markdown", + "id": "8c9dc7bc-22b1-4360-ac57-0cf5bb87eca2", + "metadata": {}, + "source": [ + "## Get Crash Data\n", + "\n", + "We only use crashes that resulted in a bicyclist fatality or injury from the last 5 years." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a167bd1d-ccfd-4e00-b73b-692ae8f302c1", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "2021-04-15\n", + "2026-04-15\n", + "Fetched 1000 records...\n", + "Fetched 2000 records...\n", + "2052\n" + ] + } + ], + "source": [ + "def get_crashes_df(start_date, end_date, chunk_size=1000):\n", + " base_url = \"https://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Public_Safety_WebMercator/MapServer/24/query\"\n", + "\n", + " all_rows = []\n", + " offset = 0\n", + "\n", + " while True:\n", + " params = {\n", + " \"where\": (\n", + " f\"REPORTDATE >= DATE '{start_date} 00:00:00' \"\n", + " f\"AND REPORTDATE <= DATE '{end_date} 23:59:59' \"\n", + " \"AND (MAJORINJURIES_BICYCLIST > 0 \"\n", + " \"OR MINORINJURIES_BICYCLIST > 0\"\n", + " \"OR UNKNOWNINJURIES_BICYCLIST > 0\"\n", + " \"OR FATAL_BICYCLIST > 0)\"\n", + " ),\n", + " \"outFields\": \"*\",\n", + " \"outSR\": 4326,\n", + " \"f\": \"json\",\n", + " \"orderByFields\": \"OBJECTID\",\n", + " \"resultOffset\": offset,\n", + " \"resultRecordCount\": chunk_size\n", + " }\n", + "\n", + " r = requests.get(base_url, params=params, timeout=120)\n", + " data = r.json()\n", + "\n", + " features = data.get(\"features\", [])\n", + "\n", + " #print(f\"Received {len(features)} features\")\n", + "\n", + " # Extract attribute dictionaries\n", + " for feature in features:\n", + " attrs = feature.get(\"attributes\", {})\n", + " geom = feature.get(\"geometry\")\n", + "\n", + " if geom and \"x\" in geom and \"y\" in geom:\n", + " attrs[\"geometry\"] = Point(geom[\"x\"], geom[\"y\"])\n", + " all_rows.append(attrs)\n", + "\n", + " # Stop when last page is reached\n", + " if len(features) < chunk_size:\n", + " break\n", + "\n", + " offset += chunk_size\n", + " print(f\"Fetched {offset} records...\")\n", + " time.sleep(0.05)\n", + "\n", + " # Convert to GeoDataFrame\n", + " df = pd.DataFrame(all_rows)\n", + " gdf = gpd.GeoDataFrame(df, geometry=\"geometry\", crs=\"EPSG:4326\")\n", + "\n", + " return gdf\n", + " \n", + "start_date = (date.today()-relativedelta(years=5)).isoformat()\n", + "print(start_date)\n", + "end_date = date.today().isoformat()\n", + "print(end_date)\n", + "crashes_new = get_crashes_df(start_date, end_date)\n", + "print(len(crashes_new))" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "462237b1-c63d-4e0e-9998-6e518d01852d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
geometrybbox_westbbox_southbbox_eastbbox_northplace_idosm_typeosm_idlatlonclasstypeplace_rankimportanceaddresstypenamedisplay_name
0POLYGON ((-77.11979 38.93435, -77.11977 38.934...-77.11979538.79163-76.90936638.995968394523734relation539619438.895037-77.036543placecity160.81477cityWashingtonWashington, District of Columbia, United States
\n", + "
" + ], + "text/plain": [ + " geometry bbox_west bbox_south \\\n", + "0 POLYGON ((-77.11979 38.93435, -77.11977 38.934... -77.119795 38.79163 \n", + "\n", + " bbox_east bbox_north place_id osm_type osm_id lat lon \\\n", + "0 -76.909366 38.995968 394523734 relation 5396194 38.895037 -77.036543 \n", + "\n", + " class type place_rank importance addresstype name \\\n", + "0 place city 16 0.81477 city Washington \n", + "\n", + " display_name \n", + "0 Washington, District of Columbia, United States " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# restrict crashes to DC (probably not necessary considering they are coming from DC website)\n", + "\n", + "PLACE_NAME = \"Washington, District of Columbia, USA\"\n", + "CRS = \"EPSG:4326\"\n", + "\n", + "# Crash join toggles (turn off if ArcGIS blocks)\n", + "CRASH_ENABLE = True\n", + "YEARS_BACK = 5\n", + "CRASH_BUFFER_M = 10\n", + "\n", + "# 3) Area of interest\n", + "aoi_gdf = ox.geocode_to_gdf(PLACE_NAME).to_crs(CRS)\n", + "aoi = aoi_gdf.geometry.iloc[0]\n", + "aoi_gdf" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "67d06c72-c0db-4e40-9eb9-887f73227424", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
CRIMEIDCCNREPORTDATEROUTEIDMEASUREOFFSETSTREETSEGIDROADWAYSEGIDFROMDATETODATE...SUBBLOCKKEYCORRIDORIDNEARESTINTKEYMAJORINJURIESOTHERMINORINJURIESOTHERUNKNOWNINJURIESOTHERFATALOTHEROBJECTIDgeometryREPORTDATE_
026661162614211079031627946100000110014025579.1227.280.00.01627947960000None...84073fa307bbfb12d66bc2a398381da511001402_273435d5fb8f812ed226b15ebaa9a88f00.00.00.00.0461387469POINT (-77.03273 38.94045)2021-08-02 19:15:00-04:00
126667229361211083801628019360000110036022200.3317.84NaNNaN1628019360000None...104e644e8a45e4f8f5fae8a522dfb49211003602_6a38c5c59ffe947cd9e811e4da2f8d5c20.00.00.00.0461387942POINT (-77.06985 38.94695)2021-08-03 15:36:00-04:00
22668471915921108827162809274000012061162854.3144.49NaNNaN1628109120000None...a686015e5346e258d9d532aca3fe0b96None00.00.00.00.0461388659POINT (-76.948 38.89634)2021-08-04 11:59:00-04:00
326687496038211093091628163600000110014021537.8523.44NaNNaN1628167440000None...4ee4ad33be2250ce8d95d389255b342411001402_1f63110cea700e723ffd3d38eb1b4814c0.00.00.00.0461388788POINT (-77.03196 38.90339)2021-08-05 07:40:00-04:00
42668818767621109154162812490000012050892142.6445.05NaNNaN1628178660000None...ccf5a699cde70078619692f752acad3c12050892_140736cafb4216780e39074395946fe5a0.00.00.00.0461389042POINT (-77.00742 38.90252)2021-08-04 20:55:00-04:00
..................................................................
20406965704323026048593177604662000013057852758.6921.21NaNNaN1776065994000None...8388fa359b7850a5b97c250572cbc35313057852_11c9a07f86a6d82f141a4187d76984d150.00.00.00.0461624582POINT (-77.00036 38.87649)2026-04-12 22:17:00-04:00
204169658209758251849231765049400000110013024007.1323.65NaNNaN1776076667000None...0188b11aea88a42ce1c1e00c9388dd8511001302_2621c42b3fb2be0271142a259c56891760.00.00.00.0461624584POINT (-77.02973 38.93264)2025-12-06 14:30:00-05:00
20426965830003426048407177602220000011067402685.7817.94NaNNaN1776077880000None...a5dede8358590739c5507c9e4792b91811067402_277d3cb8e0ff0a5ddb473a2c1a8903a750.00.00.00.0461624585POINT (-77.04028 38.92449)2026-04-12 15:30:00-04:00
204369659188658260486881776076200000120159920.003.84NaNNaN1776087753000None...cb351c4ccf3b8c5caee06992fe6f58e612015992_104eab17816b0ebe7fe88f4688908ed7c0.00.00.00.0461624590POINT (-76.98344 38.90014)2026-04-13 06:30:00-04:00
20446966216297926048856177610260000012061162536.2832.31NaNNaN1776106334000None...05200077c6bbd37b717fa05332a10d4bNone00.00.00.00.0461624606POINT (-76.95003 38.89397)2026-04-13 13:50:00-04:00
\n", + "

2045 rows × 66 columns

\n", + "
" + ], + "text/plain": [ + " CRIMEID CCN REPORTDATE ROUTEID MEASURE OFFSET \\\n", + "0 26661162614 21107903 1627946100000 11001402 5579.12 27.28 \n", + "1 26667229361 21108380 1628019360000 11003602 2200.33 17.84 \n", + "2 26684719159 21108827 1628092740000 12061162 854.31 44.49 \n", + "3 26687496038 21109309 1628163600000 11001402 1537.85 23.44 \n", + "4 26688187676 21109154 1628124900000 12050892 142.64 45.05 \n", + "... ... ... ... ... ... ... \n", + "2040 69657043230 26048593 1776046620000 13057852 758.69 21.21 \n", + "2041 69658209758 25184923 1765049400000 11001302 4007.13 23.65 \n", + "2042 69658300034 26048407 1776022200000 11067402 685.78 17.94 \n", + "2043 69659188658 26048688 1776076200000 12015992 0.00 3.84 \n", + "2044 69662162979 26048856 1776102600000 12061162 536.28 32.31 \n", + "\n", + " STREETSEGID ROADWAYSEGID FROMDATE TODATE ... \\\n", + "0 0.0 0.0 1627947960000 None ... \n", + "1 NaN NaN 1628019360000 None ... \n", + "2 NaN NaN 1628109120000 None ... \n", + "3 NaN NaN 1628167440000 None ... \n", + "4 NaN NaN 1628178660000 None ... \n", + "... ... ... ... ... ... \n", + "2040 NaN NaN 1776065994000 None ... \n", + "2041 NaN NaN 1776076667000 None ... \n", + "2042 NaN NaN 1776077880000 None ... \n", + "2043 NaN NaN 1776087753000 None ... \n", + "2044 NaN NaN 1776106334000 None ... \n", + "\n", + " SUBBLOCKKEY CORRIDORID \\\n", + "0 84073fa307bbfb12d66bc2a398381da5 11001402_2 \n", + "1 104e644e8a45e4f8f5fae8a522dfb492 11003602_6 \n", + "2 a686015e5346e258d9d532aca3fe0b96 None \n", + "3 4ee4ad33be2250ce8d95d389255b3424 11001402_1 \n", + "4 ccf5a699cde70078619692f752acad3c 12050892_1 \n", + "... ... ... \n", + "2040 8388fa359b7850a5b97c250572cbc353 13057852_1 \n", + "2041 0188b11aea88a42ce1c1e00c9388dd85 11001302_2 \n", + "2042 a5dede8358590739c5507c9e4792b918 11067402_2 \n", + "2043 cb351c4ccf3b8c5caee06992fe6f58e6 12015992_1 \n", + "2044 05200077c6bbd37b717fa05332a10d4b None \n", + "\n", + " NEARESTINTKEY MAJORINJURIESOTHER \\\n", + "0 73435d5fb8f812ed226b15ebaa9a88f0 0.0 \n", + "1 a38c5c59ffe947cd9e811e4da2f8d5c2 0.0 \n", + "2 0 0.0 \n", + "3 f63110cea700e723ffd3d38eb1b4814c 0.0 \n", + "4 40736cafb4216780e39074395946fe5a 0.0 \n", + "... ... ... \n", + "2040 1c9a07f86a6d82f141a4187d76984d15 0.0 \n", + "2041 621c42b3fb2be0271142a259c5689176 0.0 \n", + "2042 77d3cb8e0ff0a5ddb473a2c1a8903a75 0.0 \n", + "2043 04eab17816b0ebe7fe88f4688908ed7c 0.0 \n", + "2044 0 0.0 \n", + "\n", + " MINORINJURIESOTHER UNKNOWNINJURIESOTHER FATALOTHER OBJECTID \\\n", + "0 0.0 0.0 0.0 461387469 \n", + "1 0.0 0.0 0.0 461387942 \n", + "2 0.0 0.0 0.0 461388659 \n", + "3 0.0 0.0 0.0 461388788 \n", + "4 0.0 0.0 0.0 461389042 \n", + "... ... ... ... ... \n", + "2040 0.0 0.0 0.0 461624582 \n", + "2041 0.0 0.0 0.0 461624584 \n", + "2042 0.0 0.0 0.0 461624585 \n", + "2043 0.0 0.0 0.0 461624590 \n", + "2044 0.0 0.0 0.0 461624606 \n", + "\n", + " geometry REPORTDATE_ \n", + "0 POINT (-77.03273 38.94045) 2021-08-02 19:15:00-04:00 \n", + "1 POINT (-77.06985 38.94695) 2021-08-03 15:36:00-04:00 \n", + "2 POINT (-76.948 38.89634) 2021-08-04 11:59:00-04:00 \n", + "3 POINT (-77.03196 38.90339) 2021-08-05 07:40:00-04:00 \n", + "4 POINT (-77.00742 38.90252) 2021-08-04 20:55:00-04:00 \n", + "... ... ... \n", + "2040 POINT (-77.00036 38.87649) 2026-04-12 22:17:00-04:00 \n", + "2041 POINT (-77.02973 38.93264) 2025-12-06 14:30:00-05:00 \n", + "2042 POINT (-77.04028 38.92449) 2026-04-12 15:30:00-04:00 \n", + "2043 POINT (-76.98344 38.90014) 2026-04-13 06:30:00-04:00 \n", + "2044 POINT (-76.95003 38.89397) 2026-04-13 13:50:00-04:00 \n", + "\n", + "[2045 rows x 66 columns]" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "crashes_new = gpd.overlay(crashes_new, aoi_gdf[[\"geometry\"]], how=\"intersection\")\n", + "crashes_new['REPORTDATE_'] = pd.to_datetime(crashes_new[\"REPORTDATE\"], unit=\"ms\", utc=True).dt.tz_convert(\"America/New_York\")\n", + "crashes_new" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "fdbe963a-d6f2-4d87-8673-d05a33e57beb", + "metadata": {}, + "outputs": [], + "source": [ + "crashes_new.to_file('crashes_dcdata.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "d29d67fc-3b26-4579-a565-739cd65b9600", + "metadata": {}, + "outputs": [], + "source": [ + "keep_columns = ['REPORTDATE_', 'ADDRESS', 'MAJORINJURIES_BICYCLIST', 'MINORINJURIES_BICYCLIST', 'UNKNOWNINJURIES_BICYCLIST','FATAL_BICYCLIST', 'TOTAL_BICYCLES', 'BICYCLISTSIMPAIRED', 'TOTAL_VEHICLES', 'TOTAL_PEDESTRIANS', 'geometry']\n", + "crashes_reduced = crashes_new[keep_columns]\n", + "crashes_reduced.to_file('crashes_reduced.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "62855a0b-645e-4cd1-80d4-c66e82009737", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "number of injuries and fatalities in the last 5 years:\n", + "MAJORINJURIES_BICYCLIST: 175\n", + "MINORINJURIES_BICYCLIST: 1886\n", + "UNKNOWNINJURIES_BICYCLIST: 4\n", + "FATAL_BICYCLIST: 7\n", + "total: 2072\n" + ] + } + ], + "source": [ + "print('number of injuries and fatalities in the last 5 years:')\n", + "inj = ['MAJORINJURIES_BICYCLIST', 'MINORINJURIES_BICYCLIST', 'UNKNOWNINJURIES_BICYCLIST','FATAL_BICYCLIST']\n", + "total= 0\n", + "for i in inj:\n", + " print(i+': '+str(sum(crashes_reduced[i])))\n", + " total = total + sum(crashes_reduced[i])\n", + "print('total: '+str(total))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "59f219bf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "joined\n", + "length of joined: 2813\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
crash_count_5yr
count13838.000000
mean0.198656
std0.652594
min0.000000
25%0.000000
50%0.000000
75%0.000000
max12.000000
\n", + "
" + ], + "text/plain": [ + " crash_count_5yr\n", + "count 13838.000000\n", + "mean 0.198656\n", + "std 0.652594\n", + "min 0.000000\n", + "25% 0.000000\n", + "50% 0.000000\n", + "75% 0.000000\n", + "max 12.000000" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 9) Crash counts → segments (buffered spatial join; handles no-spatial-index case)\n", + "\n", + "def count_crashes_near_segments(segments_gdf, crashes_gdf, buffer_m=10):\n", + " if crashes_gdf.empty or segments_gdf.empty:\n", + " segments_gdf[\"crash_count_5yr\"] = 0\n", + " return segments_gdf\n", + "\n", + " proj = \"EPSG:3857\" # meters\n", + " seg_p = segments_gdf.to_crs(proj).copy()\n", + " cr_p = crashes_gdf.to_crs(proj).copy()\n", + "\n", + " seg_p[\"buf\"] = seg_p.geometry.buffer(buffer_m)\n", + " seg_p = seg_p.set_geometry(\"buf\", crs=proj)\n", + "\n", + " try:\n", + " print('joined')\n", + " joined = gpd.sjoin(cr_p[[\"geometry\"]], seg_p[[\"buf\"]], how=\"left\", predicate=\"within\") #this will create multiple matches\n", + " print('length of joined: '+str(len(joined)))\n", + " except Exception as e:\n", + " # If spatial index missing, geopandas prints an rtree/pygeos message—fallback to brute force (slow but safe for MVP)\n", + " from shapely.prepared import prep\n", + " counts = []\n", + " prepped = [prep(g) for g in seg_p[\"buf\"]]\n", + " for pt in cr_p.geometry:\n", + " hits = [i for i, pg in enumerate(prepped) if pg.contains(pt)]\n", + " counts.extend(hits)\n", + " joined = pd.Series(counts).value_counts().rename_axis(\"index_right\").rename(\"size\").to_frame()\n", + "\n", + " seg_p[\"crash_count_5yr\"] = 0\n", + " seg_p.loc[joined.index, \"crash_count_5yr\"] = joined[\"size\"].values\n", + " return seg_p.drop(columns=[\"buf\"]).set_geometry(\"geometry\").to_crs(segments_gdf.crs)\n", + "\n", + " counts = joined.groupby(joined.index_right).size().rename(\"crash_count_5yr\")\n", + " seg_p = seg_p.drop(columns=[\"buf\"]).set_geometry(\"geometry\")\n", + " seg_p[\"crash_count_5yr\"] = counts.reindex(seg_p.index).fillna(0).astype(int)\n", + " return seg_p.to_crs(segments_gdf.crs)\n", + "\n", + "gdf = count_crashes_near_segments(gdf, crashes_new, buffer_m=CRASH_BUFFER_M)\n", + "gdf[\"serious_injury_count_5yr\"] = 0\n", + "gdf[\"fatal_count_5yr\"] = 0\n", + "gdf[[\"crash_count_5yr\"]].describe()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "efbed5fc-d51b-4246-af14-4bf3da2f6eca", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "segments with most crashes\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presenceroad_widthslow_streetpavement_conditiongeometrylts_levellencrash_count_5yrserious_injury_count_5yrfatal_count_5yr
44811100140214TH ST NWf217f5fbccb8b5787492be2131bd04a7Minor Arterial3325.025.0protected_trackTrue60NoneGoodLINESTRING Z (323805.757 4310841.384 0, 323805...1158.5723121200
730612015342BENNING RD NE43a8ea2167cb67c4cc1d718205dda018Principal/Primary Arterial8830.030.0noneFalse94NoneExcellentLINESTRING Z (328001.547 4307564.869 0, 328024...4173.938964900
206811050892K ST NWaca3f6e3963be541c7b2cbb26984ec89Minor Arterial3320.020.0buffered_laneTrue57NonePoorLINESTRING Z (325255.201 4307890.163 0, 325250...386.628948800
1141110009029TH ST NWa7cf3495e3dfcf737207d6a5ebd4136fMinor Arterial3325.025.0protected_trackTrue54NoneExcellentLINESTRING Z (324504.955 4308431.516 0, 324505...1147.652490800
9811050892K ST NW4519b88e041b24532d9992f02c03d3d9Minor Arterial3320.020.0noneTrue69NoneFairLINESTRING Z (324845.041 4307899.504 0, 324833...4174.413630800
............................................................
1357512092622WEST VIRGINIA AVE NEa738fe94de86007ea4de434db6e7c010Minor Arterial2220.020.0buffered_laneTrue41NoneFairLINESTRING Z (327517.837 4308386.007 0, 327518...251.310774100
202611066752OGLETHORPE ST NW47515fa9e4a9206c30db37c63c15808eLocal2220.020.0noneTrue32NoneExcellentLINESTRING Z (324990.746 4314424.786 0, 324981...2110.886010100
1359215065322NORTH CAPITOL ST BN9942045b1d3fa70c9d6d2543aa10a3b3Principal/Primary Arterial6625.0NaNnoneFalse79NoneGoodLINESTRING Z (325807.516 4308832.594 0, 325807...482.586054100
1359314058502MAINE AVE SWc848cf3b8ebf259d8984382b8dcd8891Principal/Primary Arterial3325.0NaNnoneFalse30NoneNoneLINESTRING Z (323602.865 4305909.583 0, 323599...4397.549443100
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0noneTrue56NoneExcellentLINESTRING Z (324847.742 4308016.726 0, 324847...465.076304100
\n", + "

1777 rows × 19 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey \\\n", + "4481 11001402 14TH ST NW f217f5fbccb8b5787492be2131bd04a7 \n", + "7306 12015342 BENNING RD NE 43a8ea2167cb67c4cc1d718205dda018 \n", + "2068 11050892 K ST NW aca3f6e3963be541c7b2cbb26984ec89 \n", + "1141 11000902 9TH ST NW a7cf3495e3dfcf737207d6a5ebd4136f \n", + "98 11050892 K ST NW 4519b88e041b24532d9992f02c03d3d9 \n", + "... ... ... ... \n", + "13575 12092622 WEST VIRGINIA AVE NE a738fe94de86007ea4de434db6e7c010 \n", + "2026 11066752 OGLETHORPE ST NW 47515fa9e4a9206c30db37c63c15808e \n", + "13592 15065322 NORTH CAPITOL ST BN 9942045b1d3fa70c9d6d2543aa10a3b3 \n", + "13593 14058502 MAINE AVE SW c848cf3b8ebf259d8984382b8dcd8891 \n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 \n", + "\n", + " function num_lanes num_lanes_raw speed_limit \\\n", + "4481 Minor Arterial 3 3 25.0 \n", + "7306 Principal/Primary Arterial 8 8 30.0 \n", + "2068 Minor Arterial 3 3 20.0 \n", + "1141 Minor Arterial 3 3 25.0 \n", + "98 Minor Arterial 3 3 20.0 \n", + "... ... ... ... ... \n", + "13575 Minor Arterial 2 2 20.0 \n", + "2026 Local 2 2 20.0 \n", + "13592 Principal/Primary Arterial 6 6 25.0 \n", + "13593 Principal/Primary Arterial 3 3 25.0 \n", + "0 Minor Arterial 4 4 20.0 \n", + "\n", + " speed_limit_raw bike_facility_type parking_presence road_width \\\n", + "4481 25.0 protected_track True 60 \n", + "7306 30.0 none False 94 \n", + "2068 20.0 buffered_lane True 57 \n", + "1141 25.0 protected_track True 54 \n", + "98 20.0 none True 69 \n", + "... ... ... ... ... \n", + "13575 20.0 buffered_lane True 41 \n", + "2026 20.0 none True 32 \n", + "13592 NaN none False 79 \n", + "13593 NaN none False 30 \n", + "0 20.0 none True 56 \n", + "\n", + " slow_street pavement_condition \\\n", + "4481 None Good \n", + "7306 None Excellent \n", + "2068 None Poor \n", + "1141 None Excellent \n", + "98 None Fair \n", + "... ... ... \n", + "13575 None Fair \n", + "2026 None Excellent \n", + "13592 None Good \n", + "13593 None None \n", + "0 None Excellent \n", + "\n", + " geometry lts_level \\\n", + "4481 LINESTRING Z (323805.757 4310841.384 0, 323805... 1 \n", + "7306 LINESTRING Z (328001.547 4307564.869 0, 328024... 4 \n", + "2068 LINESTRING Z (325255.201 4307890.163 0, 325250... 3 \n", + "1141 LINESTRING Z (324504.955 4308431.516 0, 324505... 1 \n", + "98 LINESTRING Z (324845.041 4307899.504 0, 324833... 4 \n", + "... ... ... \n", + "13575 LINESTRING Z (327517.837 4308386.007 0, 327518... 2 \n", + "2026 LINESTRING Z (324990.746 4314424.786 0, 324981... 2 \n", + "13592 LINESTRING Z (325807.516 4308832.594 0, 325807... 4 \n", + "13593 LINESTRING Z (323602.865 4305909.583 0, 323599... 4 \n", + "0 LINESTRING Z (324847.742 4308016.726 0, 324847... 4 \n", + "\n", + " len crash_count_5yr serious_injury_count_5yr fatal_count_5yr \n", + "4481 158.572312 12 0 0 \n", + "7306 173.938964 9 0 0 \n", + "2068 86.628948 8 0 0 \n", + "1141 147.652490 8 0 0 \n", + "98 174.413630 8 0 0 \n", + "... ... ... ... ... \n", + "13575 51.310774 1 0 0 \n", + "2026 110.886010 1 0 0 \n", + "13592 82.586054 1 0 0 \n", + "13593 397.549443 1 0 0 \n", + "0 65.076304 1 0 0 \n", + "\n", + "[1777 rows x 19 columns]" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "print('segments with most crashes')\n", + "gdf[gdf['crash_count_5yr']>0].sort_values(by='crash_count_5yr', ascending = False)" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "2463b802", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
s_LTSs_crashs_facilityridescore_v1
count13838.013838.013838.013838.0
mean50.987.20.556.7
std30.233.51.722.0
min10.00.00.06.0
25%10.0100.00.036.0
50%75.0100.00.075.0
75%75.0100.00.075.0
max100.0100.010.091.0
\n", + "
" + ], + "text/plain": [ + " s_LTS s_crash s_facility ridescore_v1\n", + "count 13838.0 13838.0 13838.0 13838.0\n", + "mean 50.9 87.2 0.5 56.7\n", + "std 30.2 33.5 1.7 22.0\n", + "min 10.0 0.0 0.0 6.0\n", + "25% 10.0 100.0 0.0 36.0\n", + "50% 75.0 100.0 0.0 75.0\n", + "75% 75.0 100.0 0.0 75.0\n", + "max 100.0 100.0 10.0 91.0" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 10) RideScore (0–100)\n", + "\n", + "def p95(values):\n", + " s = sorted([int(v) for v in values if pd.notnull(v)])\n", + " if not s: return 1\n", + " k = int(round(0.95 * (len(s) - 1)))\n", + " return max(s[k], 1)\n", + "\n", + "def lts_to_score(x): return {1:100, 2:75, 3:40, 4:10}.get(int(x), 10)\n", + "\n", + "facility_bonus = {\"protected_track\":10, \"separated_lane\":10, \"buffered_lane\":5, \"painted_lane\":3, \"shared\":0, \"none\":0}\n", + "\n", + "P95_CRASH = p95(gdf[\"crash_count_5yr\"])\n", + "def crash_inv(n): return 100.0 * (1.0 - min(max(float(n)/float(P95_CRASH), 0.0), 1.0))\n", + "\n", + "W_LTS, W_CRASH, W_FAC = 0.6, 0.3, 0.1\n", + "\n", + "gdf[\"s_LTS\"] = gdf[\"lts_level\"].map(lts_to_score)\n", + "gdf[\"s_crash\"] = gdf[\"crash_count_5yr\"].map(crash_inv)\n", + "gdf[\"s_facility\"] = gdf[\"bike_facility_type\"].map(facility_bonus).fillna(0)\n", + "gdf[\"ridescore_v1\"] = (W_LTS*gdf.s_LTS + W_CRASH*gdf.s_crash + W_FAC*gdf.s_facility).round(1)\n", + "\n", + "gdf[[\"s_LTS\",\"s_crash\",\"s_facility\",\"ridescore_v1\"]].describe().round(1)" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "55ad5c7b-0549-45fc-8d3e-9d7a5212f305", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(array([ 933., 0., 145., 3447., 595., 1466., 104., 0., 6967.,\n", + " 181.]),\n", + " array([ 6. , 14.5, 23. , 31.5, 40. , 48.5, 57. , 65.5, 74. , 82.5, 91. ]),\n", + " )" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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AACsRIgBAABWIsQAAAArEWIAAICVCDEAAMBKhBgAAGAlQgwAALASIQYAAFjJp7tPAAAAiAxd/oZ1v4ZP1kzu1p9PTwwAALASPTHo0Wz8lwkA4MqgJwYAAFiJnhgAuEJs7Fns7jkPgNU9MX/84x8lOjpa+vXrJ6NGjZJ33323u08JAAD0AD06xLzyyiuSnp4uK1eulH/961/ys5/9TCZNmiSffvppd58aAADoZj06xGRnZ0tqaqr85je/kZiYGFm/fr0MGTJENmzY0N2nBgAAulmPnRPT2toqFRUVsnz5co/j48ePl5KSkk71LS0tprk1Njaar01NTd/L+Z1v+UJs8339Lr5PNv6egd6E/27gSv//w/2cLpfL3hDz+eefS1tbm0RERHgc1/26urpO9atXr5Ynn3yy03HtucH/F7Ke3wSAruG/G+iu/380NzdLSEiInSHGzcvLy2Nfk1nHY2rFihWyePFiZ//8+fPyv//9TwYOHHjBenz/NE1riKypqZHg4GB+5T0U18kOXCc7cJ0un/6d1wATFRX1jbU9NsSEhYWJt7d3p16X+vr6Tr0zyt/f37T2rr766u/9PPHNNMAQYno+rpMduE524Dpdnm/qgenxE3v9/PzMkurCwkKP47ofHx/fbecFAAB6hh7bE6N0eGjWrFkyevRoGTdunGzatMksr3744Ye7+9QAAEA369EhZsaMGfLf//5XnnrqKamtrZXY2FjZvXu3XHfddd19avgWdHjviSee6DTMh56F62QHrpMduE5Xlpfr26xhAgAA6GF67JwYAACAiyHEAAAAKxFiAACAlQgxAADASoQYXBb9uIfbbrtNgoKCJDw8XO6++245cuSIR43OHc/MzDR3XwwICJDExESpqqriN9/N103vZK2fEs916lk+++wzeeCBB8zdxgMDA+XWW281nyPnxvup+3311Vfyu9/9TqKjo81/066//nqzilbvFO/GdboyCDG4LEVFRbJgwQLZu3evuRGhvrn1QzrPnDnj1GRlZZlPJM/JyZHy8nKJjIyUlJQUc1tpXHl6DfSeSzfffLPHca5T9zt16pTcfvvt4uvrK2+++aYcPHhQnn32WY+7j3Odut/atWvlhRdeMP9NO3TokLkmzzzzjDz//PNODdfpCtEl1sB3pb6+Xpfsu4qKisz++fPnXZGRka41a9Y4NV9++aUrJCTE9cILL/CLv8Kam5tdw4YNcxUWFroSEhJcixYt4jr1IMuWLXPdcccdX/s476eeYfLkya6HHnrI49i0adNcDzzwgNnmOl059MTgO9XY2Gi+hoaGmq/V1dXm86+0d6b9zaASEhKkpKSE3/4Vpr1mkydPluTkZI/jXKee4bXXXjN3KL/nnnvM8OzIkSNl8+bNzuNcp57hjjvukL///e/y4Ycfmv1///vfUlxcLL/85S/NPtfpyunRd+yFXXQMWD8qQt/gendl5f4Az44f2qn7R48e7Zbz7Kvy8vLk/fffN8NJHXGdeoaPP/5YNmzYYN5Hjz/+uJSVlUlaWpoJ/r/+9a+5Tj3EsmXLzD/YbrzxRvNBxW1tbfL000/LfffdZx7n/XTlEGLwnXn00Uflgw8+MP8i6UgnkXYMPB2P4ftTU1MjixYtkoKCAunXr9/X1nGdupdODNWemFWrVpl97YnRSfAabDTEuHGdutcrr7wi27dvlx07dshNN90klZWVZpK8Ll6YPXu2U8d1+v4xnITvxMKFC01X+Ntvvy3XXHONc1wn8bb/l4lbfX19p94ZfH90dYv+zvWT4X18fEzTSdnPPfec2XZfC65T9xo8eLCMGDHC41hMTIz54FvF+6ln+O1vfyvLly+Xe++9V+Li4swHFT/22GNm1Z/iOl05hBhcFu1R0R6YnTt3yltvvWWWHLan+/qG1pVLbq2treYPaHx8PL/9KyQpKUn2799v/sXobvov/vvvv99s6xJRrlP305VJHW9RoPMu3B96y/upZ/jiiy/kqqs8/3zqsJJ7iTXX6Qq6gpOI0Qs98sgjZqXRO++846qtrXXaF1984dToyiSt2blzp2v//v2u++67zzV48GBXU1NTt557X9d+dZLiOnW/srIyl4+Pj+vpp592ffTRR67c3FxXYGCga/v27U4N16n7zZ492/XDH/7Q9frrr7uqq6vNf9vCwsJcGRkZTg3X6cogxODy/g8kcsH24osvOjW63PCJJ54wS639/f1dd955pwkz6FkhhuvUM/z1r391xcbGmvfKjTfe6Nq0aZPH41yn7qf/ANP3zrXXXuvq16+f6/rrr3etXLnS1dLS4tRwna4ML/2fK9nzAwAA8F1gTgwAALASIQYAAFiJEAMAAKxEiAEAAFYixAAAACsRYgAAgJUIMQAAwEqEGAAAYCVCDAAAsBIhBgAAWIkQAwAArESIAQAAYqP/B4jyXfmf14tXAAAAAElFTkSuQmCC", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.hist(gdf['ridescore_v1'])" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "8a695ee2-f51e-4842-a407-e5ae6b1e5839", + "metadata": {}, + "outputs": [], + "source": [ + "gdf.to_file('gdf_withScore_dcdata.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "49a6f8a7-07ab-4a58-908d-83bf6b4ce219", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
pavement_conditionpavement_condition_score
0Excellent100
1Good75
2Excellent100
3Excellent100
4Excellent100
.........
13833Good75
13834Fair50
13835Good75
13836Excellent100
13837None50
\n", + "

13838 rows × 2 columns

\n", + "
" + ], + "text/plain": [ + " pavement_condition pavement_condition_score\n", + "0 Excellent 100\n", + "1 Good 75\n", + "2 Excellent 100\n", + "3 Excellent 100\n", + "4 Excellent 100\n", + "... ... ...\n", + "13833 Good 75\n", + "13834 Fair 50\n", + "13835 Good 75\n", + "13836 Excellent 100\n", + "13837 None 50\n", + "\n", + "[13838 rows x 2 columns]" + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#value to scale\n", + "\n", + "#lts to lts_score (already done)\n", + "gdf['lts_score'] = gdf['s_LTS']\n", + "\n", + "#speed limit (if no value- speed is 25- too positive?)\n", + "def speedlimit_to_score(x):\n", + " return 100-(2*x)\n", + "gdf[\"speedlimit_score\"] = gdf[\"speed_limit\"].map(speedlimit_to_score)\n", + "\n", + "#number of lanes, blank goes to 10 score\n", + "def num_lanes_to_score(x): return {0:100, 1:100, 2:75, 3:50, 4:25, 5:25, 6:0, 7:0, 8:0, 10:0}.get(int(x), 10)\n", + "gdf[\"num_lanes_score\"] = gdf[\"num_lanes_raw\"].map(num_lanes_to_score)\n", + "\n", + "#bike lanes\n", + "def facility_to_score(x): return {'protected_track':100, 'buffered_lane':75, 'painted_lane': 50, 'none': 0}.get(x, 0)\n", + "gdf[\"facility_score\"] = gdf[\"bike_facility_type\"].map(facility_to_score)\n", + "\n", + "#road type\n", + "def function_to_score(x): return {'Local': 100, 'Collector': 75, 'Minor Arterial':50, \n", + " 'Principal/Primary Arterial':25, 'Other Freeway and Expressway': 0,\n", + " 'Interstate':0, 'Other':0}.get(x, 0)\n", + "gdf[\"function_score\"] = gdf[\"function\"].map(function_to_score)\n", + "\n", + "#road width\n", + "def road_width_to_score(x):\n", + " return 100-x\n", + "gdf[\"road_width_score\"] = gdf[\"road_width\"].map(road_width_to_score)\n", + "\n", + "#slow street- seems to have ended in 2021\n", + "\n", + "#pavement condition\n", + "def pavement_condition_to_score(x): return {'Excellent': 100, 'Good': 75, 'Fair':50, \n", + " 'Poor':25,'Very Poor': 0}.get(x, 50)\n", + "gdf[\"pavement_condition_score\"] = gdf[\"pavement_condition\"].map(pavement_condition_to_score)\n", + "\n", + "gdf[['pavement_condition', 'pavement_condition_score']]" + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "da910c7f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Render features: 13834\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
route_idroute_nameblockkeyfunctionnum_lanesnum_lanes_rawspeed_limitspeed_limit_rawbike_facility_typeparking_presence...s_crashs_facilityridescore_v1lts_scorespeedlimit_scorenum_lanes_scorefacility_scorefunction_scoreroad_width_scorepavement_condition_score
0110006026TH ST NW4af7e25abf59911305f2724cadc85a08Minor Arterial4420.020.0noneTrue...0.006.01060.02505044100
11100320232ND ST NW5b3f1964647d6c0b30c8189fd594208cLocal2225.025.0noneTrue...100.0054.04050.07501006875
\n", + "

2 rows × 30 columns

\n", + "
" + ], + "text/plain": [ + " route_id route_name blockkey function \\\n", + "0 11000602 6TH ST NW 4af7e25abf59911305f2724cadc85a08 Minor Arterial \n", + "1 11003202 32ND ST NW 5b3f1964647d6c0b30c8189fd594208c Local \n", + "\n", + " num_lanes num_lanes_raw speed_limit speed_limit_raw bike_facility_type \\\n", + "0 4 4 20.0 20.0 none \n", + "1 2 2 25.0 25.0 none \n", + "\n", + " parking_presence ... s_crash s_facility ridescore_v1 lts_score \\\n", + "0 True ... 0.0 0 6.0 10 \n", + "1 True ... 100.0 0 54.0 40 \n", + "\n", + " speedlimit_score num_lanes_score facility_score function_score \\\n", + "0 60.0 25 0 50 \n", + "1 50.0 75 0 100 \n", + "\n", + " road_width_score pavement_condition_score \n", + "0 44 100 \n", + "1 68 75 \n", + "\n", + "[2 rows x 30 columns]" + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# 10A) Build a lean render GeoDataFrame\n", + "\n", + "# === knobs you can tweak ===\n", + "SIMPLIFY_TOL_M = 4 # simplify by ~4 meters\n", + "ROUND_COORDS = 5 # round lon/lat (~1 m)\n", + "MIN_LENGTH_M = 8 # drop tiny segments\n", + "KEEP_FIELDS = gdf.columns # keep all\n", + "#[\"crash_count_5yr\",\"parking_presence\",\"num_lanes_raw\", \"speed_limit_raw\", \"bike_facility_type\", \"route_id\", \"lts_level\", \"ridescore_v1\", \"geometry\"]\n", + "#[\"segment_id\", \"lts_level\", \"ridescore_v1\", \"geometry\"]\n", + "FILTER_SCORE_MIN = None # e.g., 20\n", + "FILTER_SCORE_MAX = None # e.g., 80\n", + "\n", + "# Start from the scored 'gdf' produced in cell 10\n", + "render = gdf[KEEP_FIELDS].copy()\n", + "\n", + "# Optional score filters\n", + "if FILTER_SCORE_MIN is not None:\n", + " render = render[render[\"ridescore_v1\"] >= float(FILTER_SCORE_MIN)]\n", + "if FILTER_SCORE_MAX is not None:\n", + " render = render[render[\"ridescore_v1\"] <= float(FILTER_SCORE_MAX)]\n", + "\n", + "# Drop duplicate geometries\n", + "render[\"_wkb\"] = render.geometry.apply(lambda geom: geom.wkb)\n", + "render = render.drop_duplicates(\"_wkb\").drop(columns=\"_wkb\")\n", + "\n", + "# Drop very short segments\n", + "rp = render.to_crs(3857)\n", + "render = render[rp.length >= MIN_LENGTH_M].copy()\n", + "\n", + "# Simplify then return to WGS84\n", + "rp = render.to_crs(3857)\n", + "rp[\"geometry\"] = rp.geometry.simplify(SIMPLIFY_TOL_M, preserve_topology=True)\n", + "render = rp.to_crs(4326)\n", + "\n", + "# Round coordinates\n", + "from shapely.geometry import LineString\n", + "def round_linestring(ls, n=ROUND_COORDS):\n", + " #print(ls)\n", + " coords = [(round(x, n), round(y, n), z) for x, y, z in ls.coords]\n", + " return LineString(coords)\n", + "\n", + "render[\"geometry\"] = render.geometry.apply(lambda g: round_linestring(g, ROUND_COORDS))\n", + "print(\"Render features:\", len(render))\n", + "render.head(2)" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "42624330-7c3b-4f76-9382-81d610adff5b", + "metadata": {}, + "outputs": [], + "source": [ + "render['parking_presence'] = render['parking_presence'].astype(int)" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "58afc210-1cf7-47bb-9e20-04c1e6ef441c", + "metadata": {}, + "outputs": [], + "source": [ + "render.to_file('render_dcdata_wCrashes.geojson')" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "9e0738d3-778a-412d-a37d-09fa072b1abe", + "metadata": {}, + "outputs": [], + "source": [ + "render_wkt = render.copy()\n", + "render_wkt = render_wkt.drop(columns = 'geometry')\n", + "render_wkt.to_csv('render_dc_data_wCrashes.csv')" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "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.13.9" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/mvp_map/index.html b/mvp_map/index.html index 9fbdca7..bb0a5bc 100644 --- a/mvp_map/index.html +++ b/mvp_map/index.html @@ -124,6 +124,9 @@ } #settings-panel .close-btn:hover { background: #f1f5f9; color: #1a1a2e; } + #slider-group { + display: none; + } /* ── Mode switcher (Ridescore vs Custom) ── */ .mode-switcher { display: flex; border-radius: 6px; overflow: hidden; @@ -247,8 +250,24 @@
- - + + +
+ + +
+
+ + +
Using the pre-computed safety score. Switch to Custom to tune individual weights.
@@ -304,16 +323,25 @@ document.getElementById(spanId).textContent = LABELS[val]; } -/* ── Mode: RideScore vs Custom ── */ -let currentMode = 'ridescore'; +/* ── Mode: Precomputed vs Custom ── */ +let currentMode = 'precomputed'; +let currentPrecomputed = 'v1'; const sliderIds = ['speedlimit', 'numlanes', 'facility', 'function', 'roadwidth', 'pavement']; function setMode(mode) { currentMode = mode; - document.getElementById('mode-ridescore').classList.toggle('selected', mode === 'ridescore'); - document.getElementById('mode-custom').classList.toggle('selected', mode === 'custom'); - document.getElementById('ridescore-note').style.display = mode === 'ridescore' ? 'block' : 'none'; - + document.getElementById('mode-precomputed') + .classList.toggle('selected', mode === 'precomputed'); + document.getElementById('mode-custom') + .classList.toggle('selected', mode === 'custom'); + // Show/hide sections + document.getElementById('precomputed-options').style.display = + mode === 'precomputed' ? 'block' : 'none'; + + document.getElementById('slider-group').style.display = + mode === 'custom' ? 'flex' : 'none'; + + sliderIds.forEach(id => { const row = document.getElementById('row_' + id); const input = document.getElementById('i_' + id); @@ -364,21 +392,35 @@ const pavement_slider = document.getElementById('i_pavement'); document.getElementById('updateBtn').addEventListener('click', () => { - if (currentMode === 'ridescore') { - RefreshZone(4, 0, 0, 0, 0, 0, 0); + if (currentMode === 'precomputed') { + if (currentPrecomputed === 'v1') { + RefreshZone(4, 0, 0, 0, 0, 0, 0, 0); + } else { + RefreshZone(0, 4, 0, 0, 0, 0, 0, 0); + } } else { RefreshZone( - 0, speedlimit_slider.value, numlanes_slider.value, + 0, 0, speedlimit_slider.value, numlanes_slider.value, facility_slider.value, function_slider.value, roadwidth_slider.value, pavement_slider.value ); } }); -function RefreshZone(i_ridescore, i_speedlimit, i_numlanes, i_facility, i_function, i_roadwidth, i_pavement) { +function setPrecomputed(version) { + currentPrecomputed = version; + + document.getElementById('ridescore1Btn') + .classList.toggle('active', version === 'v1'); + + document.getElementById('ridescore2Btn') + .classList.toggle('active', version === 'v2'); +} + +function RefreshZone(i_ridescore,i_lts_original, i_speedlimit, i_numlanes, i_facility, i_function, i_roadwidth, i_pavement) { const timestamp = Date.now(); const source = map.getSource('my-vector-source'); - source.setTiles([`http://digitalocean_ip:3000/update_score/{z}/{x}/{y}?i_ridescore=${i_ridescore}&i_speedlimit=${i_speedlimit}&i_numlanes=${i_numlanes}&i_facility=${i_facility}&i_function=${i_function}&i_roadwidth=${i_roadwidth}&i_pavement=${i_pavement}&ts=${timestamp}`]); + source.setTiles([`http://digitalocean_ip:3000/update_score/{z}/{x}/{y}?i_ridescore=${i_ridescore}&i_lts_original=${i_lts_original}&i_speedlimit=${i_speedlimit}&i_numlanes=${i_numlanes}&i_facility=${i_facility}&i_function=${i_function}&i_roadwidth=${i_roadwidth}&i_pavement=${i_pavement}&ts=${timestamp}`]); console.log('Refreshed'); } @@ -404,7 +446,7 @@ map.addSource('my-vector-source', { type: 'vector', - tiles: ["http://digitalocean_ip:3000/update_score/{z}/{x}/{y}?i_ridescore=4&i_speedlimit=0&i_numlanes=0&i_facility=0&i_function=0&i_roadwidth=0&i_pavement=0"], + tiles: ["http://digitalocean_ip:3000/update_score/{z}/{x}/{y}?i_ridescore=4&i_lts_original=0&i_speedlimit=0&i_numlanes=0&i_facility=0&i_function=0&i_roadwidth=0&i_pavement=0"], minzoom: 1, maxzoom: 14 }); map.addLayer({ @@ -521,7 +563,7 @@ - + diff --git a/mvp_map/readme.md b/mvp_map/readme.md index 80f6690..b341a97 100644 --- a/mvp_map/readme.md +++ b/mvp_map/readme.md @@ -1,5 +1,7 @@ # Interactive DC Bike Safety Map +**4/20/2026 Update: Incorporated Level of Traffic Stress as a default method. See the LTS folder for more information** + This project creates a preliminary interactive bike safety map for the streets of Washington DC. You can explore it [here](http://161.35.142.176/). It does the following: * pulls [road](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) and [crash](https://opendata.dc.gov/datasets/crashes-in-dc/about) data from the Open Data DC portal. * process them and create bike safety factors and a default ridescore @@ -12,9 +14,9 @@ This project creates a preliminary interactive bike safety map for the streets o The map uses [road](https://opendata.dc.gov/datasets/DCGIS::roadway-block/about) and [crash](https://opendata.dc.gov/datasets/crashes-in-dc/about) data from the Open Data DC portal. The road data are simplified and cleaned up (see jupyter notebook for details). For the crash data, we only use crashes that resulted in a bicyclist fatality or injury from the last 5 years. -## Safety score and interactive factors +## Bespoke safety score and interactive factors -The LTS and ridescore build on 01_lts_osm_elia_v2.ipynb. +The modified LTS and ridescore build on 01_lts_osm_elia_v2.ipynb. We use our own, modified level of traffic stress (LTS) calculator. @@ -25,7 +27,7 @@ We use our own, modified level of traffic stress (LTS) calculator. - + @@ -70,7 +72,7 @@ We use our own, modified level of traffic stress (LTS) calculator. We then use it to create our own road safety score (the default on the website). It has 3 components: -1) LTS levels are translated into the score using the following dictionary: {1:100, 2:75, 3:40, 4:10, none = 10} +1) Levels are translated into the score using the following dictionary: {1:100, 2:75, 3:40, 4:10, none = 10} 2) Type of bike lane is translated into a score using the following: {"protected_track":10, "buffered_lane":5, "painted_lane":3, "none":0} 3) In short, the number of crashes is normalized to 100 \* (1- num_crash/95th_percentile of crashes). @@ -107,8 +109,9 @@ BEGIN 64, true ) AS geom, - (ridescore_v1*(query_params->>'i_ridescore')::int + speedlimit_score*(query_params->>'i_speedlimit')::int + -num_lanes_score*(query_params->>'i_numlanes')::int+ facility_score*(query_params->>'i_facility')::int+ function_score*(query_params->>'i_function')::int+ road_width_score*(query_params->>'i_roadwidth')::int+ pavement_condition_score*(query_params->>'i_pavement')::int) / ((query_params->>'i_ridescore')::int + (query_params->>'i_speedlimit')::int+ (query_params->>'i_numlanes')::int+ (query_params->>'i_facility')::int+ (query_params->>'i_function')::int+ (query_params->>'i_roadwidth')::int+ (query_params->>'i_pavement')::int) AS user_score, + (ridescore_v1*(query_params->>'i_ridescore')::int + lts_100*(query_params->>'i_lts_original')::int + speedlimit_score*(query_params->>'i_speedlimit')::int + +num_lanes_score*(query_params->>'i_numlanes')::int+ facility_score*(query_params->>'i_facility')::int+ function_score*(query_params->>'i_function')::int+ road_width_score*(query_params->>'i_roadwidth')::int+ pavement_condition_score*(query_params->>'i_pavement')::int) / ((query_params->>'i_ridescore')::int + (query_params->>'i_lts_original')::int + (query_params->>'i_speedlimit')::int+ (query_params->>'i_numlanes')::int+ (query_params->>'i_facility')::int+ (query_params->>'i_function')::int+ (query_params->>'i_roadwidth')::int+ (query_params->>'i_pavement')::int) AS user_score, + seg_id, route_name, bike_facility_type, function, @@ -117,6 +120,7 @@ num_lanes_score*(query_params->>'i_numlanes')::int+ facility_score*(query_params parking_presence, pavement_condition, ridescore_v1, + original_lts, road_width, speed_limit_raw FROM ridescoredc @@ -129,6 +133,7 @@ num_lanes_score*(query_params->>'i_numlanes')::int+ facility_score*(query_params END $$ LANGUAGE plpgsql STABLE STRICT PARALLEL SAFE; + ``` ## Backend and Frontend setup instructions (with DigitalOcean Droplet)
Safety Score${p.user_score}
RideScore${p.ridescore_v1}
LTS${p.lts_level}
LTS${p.original_lts}
Bike Lane${p.bike_facility_type}
Crashes (5yr)${p.crash_count_5yr}
Speed Limit${p.speed_limit_raw} mph
Number of lanes Speed limit Road functionLTSLevel
Protected track