|
| 1 | +{ |
| 2 | + "cells": [ |
| 3 | + { |
| 4 | + "cell_type": "markdown", |
| 5 | + "metadata": {}, |
| 6 | + "source": [ |
| 7 | + "# Constructing drive time based service areas\n", |
| 8 | + "This sample shows how the `network` module of the ArcGIS API for Python can be used to construct service areas. In this sample, we generate service areas for two of the fire stations in central Tokyo, Japan. We later observe how the service area varies by time of day for a fire station in the city of Los Angeles." |
| 9 | + ] |
| 10 | + }, |
| 11 | + { |
| 12 | + "cell_type": "markdown", |
| 13 | + "metadata": { |
| 14 | + "heading_collapsed": true |
| 15 | + }, |
| 16 | + "source": [ |
| 17 | + "### Service areas\n", |
| 18 | + "A network service area is a region that encompasses all accessible streets (that is, streets that are within a specified impedance). For instance, the 5-minute service area for a point on a network includes all the streets that can be reached within five minutes from that point.\n", |
| 19 | + "\n", |
| 20 | + "Service areas also help evaluate accessibility. Concentric service areas show how accessibility varies. Once service areas are created, you can use them to identify how much land, how many people, or how much of anything else is within the neighborhood or region.\n", |
| 21 | + "\n", |
| 22 | + "\n", |
| 23 | + "\n", |
| 24 | + "Service area solver provides functionality for finding out how far a vehicle could go within a specified time or distance limit. \n", |
| 25 | + "\n", |
| 26 | + "## Connect to the GIS\n", |
| 27 | + "Establish a connection to your organization which could be an ArcGIS Online organization or an ArcGIS Enterprise. To be able to run the code in this sample notebook, you would need to provide credentials of a user within an ArcGIS Online organization." |
| 28 | + ] |
| 29 | + }, |
| 30 | + { |
| 31 | + "cell_type": "code", |
| 32 | + "execution_count": null, |
| 33 | + "metadata": { |
| 34 | + "collapsed": true, |
| 35 | + "hidden": true |
| 36 | + }, |
| 37 | + "outputs": [], |
| 38 | + "source": [ |
| 39 | + "from datetime import datetime\n", |
| 40 | + "from IPython.display import HTML\n", |
| 41 | + "import pandas as pd\n", |
| 42 | + "from arcgis.gis import GIS\n", |
| 43 | + "\n", |
| 44 | + "user_name = 'arcgis_python'\n", |
| 45 | + "password = 'P@ssword123'\n", |
| 46 | + "my_gis = GIS('https://www.arcgis.com', user_name, password)" |
| 47 | + ] |
| 48 | + }, |
| 49 | + { |
| 50 | + "cell_type": "markdown", |
| 51 | + "metadata": { |
| 52 | + "heading_collapsed": true |
| 53 | + }, |
| 54 | + "source": [ |
| 55 | + "### Create a Network Layer" |
| 56 | + ] |
| 57 | + }, |
| 58 | + { |
| 59 | + "cell_type": "code", |
| 60 | + "execution_count": null, |
| 61 | + "metadata": { |
| 62 | + "collapsed": true, |
| 63 | + "hidden": true |
| 64 | + }, |
| 65 | + "outputs": [], |
| 66 | + "source": [ |
| 67 | + "import arcgis.network as network" |
| 68 | + ] |
| 69 | + }, |
| 70 | + { |
| 71 | + "cell_type": "code", |
| 72 | + "execution_count": null, |
| 73 | + "metadata": { |
| 74 | + "hidden": true |
| 75 | + }, |
| 76 | + "outputs": [], |
| 77 | + "source": [ |
| 78 | + "service_area_url = my_gis.properties.helperServices.serviceArea.url\n", |
| 79 | + "service_area_url" |
| 80 | + ] |
| 81 | + }, |
| 82 | + { |
| 83 | + "cell_type": "code", |
| 84 | + "execution_count": null, |
| 85 | + "metadata": { |
| 86 | + "collapsed": true, |
| 87 | + "hidden": true |
| 88 | + }, |
| 89 | + "outputs": [], |
| 90 | + "source": [ |
| 91 | + "sa_layer = network.ServiceAreaLayer(service_area_url, gis=my_gis)" |
| 92 | + ] |
| 93 | + }, |
| 94 | + { |
| 95 | + "cell_type": "markdown", |
| 96 | + "metadata": { |
| 97 | + "heading_collapsed": true |
| 98 | + }, |
| 99 | + "source": [ |
| 100 | + "## Create fire station facility layer" |
| 101 | + ] |
| 102 | + }, |
| 103 | + { |
| 104 | + "cell_type": "markdown", |
| 105 | + "metadata": { |
| 106 | + "hidden": true |
| 107 | + }, |
| 108 | + "source": [ |
| 109 | + "We obtained the coordinates of two fire stations in Tokyo. We construct `Feature` and `FeatureSet` objects to represent them." |
| 110 | + ] |
| 111 | + }, |
| 112 | + { |
| 113 | + "cell_type": "code", |
| 114 | + "execution_count": null, |
| 115 | + "metadata": { |
| 116 | + "collapsed": true, |
| 117 | + "hidden": true |
| 118 | + }, |
| 119 | + "outputs": [], |
| 120 | + "source": [ |
| 121 | + "fire_station_1_coord = '139.546910,35.695729'\n", |
| 122 | + "fire_station_2_coord = '139.673726,35.697988'\n", |
| 123 | + "\n", |
| 124 | + "from arcgis.features import Feature, FeatureSet\n", |
| 125 | + "\n", |
| 126 | + "f1 = Feature(geometry={'x':float(fire_station_1_coord.split(',')[0]),\n", |
| 127 | + " 'y':float(fire_station_1_coord.split(',')[1])})\n", |
| 128 | + "\n", |
| 129 | + "f2 = Feature(geometry={'x':float(fire_station_2_coord.split(',')[0]),\n", |
| 130 | + " 'y':float(fire_station_2_coord.split(',')[1])})\n", |
| 131 | + "\n", |
| 132 | + "fire_station_fset = FeatureSet([f1,f2], geometry_type='esriGeometryPoint', \n", |
| 133 | + " spatial_reference={'latestWkid': 4326})" |
| 134 | + ] |
| 135 | + }, |
| 136 | + { |
| 137 | + "cell_type": "markdown", |
| 138 | + "metadata": { |
| 139 | + "hidden": true |
| 140 | + }, |
| 141 | + "source": [ |
| 142 | + "Let us display the fire stations on a map" |
| 143 | + ] |
| 144 | + }, |
| 145 | + { |
| 146 | + "cell_type": "code", |
| 147 | + "execution_count": null, |
| 148 | + "metadata": { |
| 149 | + "hidden": true |
| 150 | + }, |
| 151 | + "outputs": [], |
| 152 | + "source": [ |
| 153 | + "map1 = my_gis.map('Tokyo', zoomlevel=12)\n", |
| 154 | + "map1" |
| 155 | + ] |
| 156 | + }, |
| 157 | + { |
| 158 | + "cell_type": "code", |
| 159 | + "execution_count": null, |
| 160 | + "metadata": { |
| 161 | + "collapsed": true, |
| 162 | + "hidden": true |
| 163 | + }, |
| 164 | + "outputs": [], |
| 165 | + "source": [ |
| 166 | + "fire_truck_symbol = {\"type\":\"esriPMS\",\n", |
| 167 | + " \"url\":\"http://static.arcgis.com/images/Symbols/SafetyHealth/FireTruck.png\",\n", |
| 168 | + " \"contentType\": \"image/png\", \"width\":20, \"height\":20}\n", |
| 169 | + "\n", |
| 170 | + "map1.draw(fire_station_fset, symbol=fire_truck_symbol)" |
| 171 | + ] |
| 172 | + }, |
| 173 | + { |
| 174 | + "cell_type": "markdown", |
| 175 | + "metadata": { |
| 176 | + "heading_collapsed": true |
| 177 | + }, |
| 178 | + "source": [ |
| 179 | + "## Compute the service area" |
| 180 | + ] |
| 181 | + }, |
| 182 | + { |
| 183 | + "cell_type": "code", |
| 184 | + "execution_count": null, |
| 185 | + "metadata": { |
| 186 | + "collapsed": true, |
| 187 | + "hidden": true |
| 188 | + }, |
| 189 | + "outputs": [], |
| 190 | + "source": [ |
| 191 | + "travel_modes = sa_layer.retrieve_travel_modes()\n", |
| 192 | + "truck_mode = [t for t in travel_modes['supportedTravelModes'] if t['name'] == 'Trucking Time'][0]\n", |
| 193 | + "\n", |
| 194 | + "result = sa_layer.solve_service_area(fire_station_fset, default_breaks=[5,10,15], \n", |
| 195 | + " travel_direction='esriNATravelDirectionFromFacility',\n", |
| 196 | + " travel_mode=truck_mode)" |
| 197 | + ] |
| 198 | + }, |
| 199 | + { |
| 200 | + "cell_type": "markdown", |
| 201 | + "metadata": { |
| 202 | + "hidden": true |
| 203 | + }, |
| 204 | + "source": [ |
| 205 | + "#### Read the result back as a `FeatureSet`\n", |
| 206 | + "The `result` variable contains the service area as a dictionary. We inspect its keys and construct `Feature` and `FeatureSet` objects out of it to display in the map" |
| 207 | + ] |
| 208 | + }, |
| 209 | + { |
| 210 | + "cell_type": "code", |
| 211 | + "execution_count": null, |
| 212 | + "metadata": { |
| 213 | + "hidden": true |
| 214 | + }, |
| 215 | + "outputs": [], |
| 216 | + "source": [ |
| 217 | + "result.keys()" |
| 218 | + ] |
| 219 | + }, |
| 220 | + { |
| 221 | + "cell_type": "code", |
| 222 | + "execution_count": null, |
| 223 | + "metadata": { |
| 224 | + "hidden": true |
| 225 | + }, |
| 226 | + "outputs": [], |
| 227 | + "source": [ |
| 228 | + "result['saPolygons'].keys()" |
| 229 | + ] |
| 230 | + }, |
| 231 | + { |
| 232 | + "cell_type": "code", |
| 233 | + "execution_count": null, |
| 234 | + "metadata": { |
| 235 | + "collapsed": true, |
| 236 | + "hidden": true |
| 237 | + }, |
| 238 | + "outputs": [], |
| 239 | + "source": [ |
| 240 | + "poly_feat_list = []\n", |
| 241 | + "for polygon_dict in result['saPolygons']['features']:\n", |
| 242 | + " f1 = Feature(polygon_dict['geometry'], polygon_dict['attributes'])\n", |
| 243 | + " poly_feat_list.append(f1)" |
| 244 | + ] |
| 245 | + }, |
| 246 | + { |
| 247 | + "cell_type": "code", |
| 248 | + "execution_count": null, |
| 249 | + "metadata": { |
| 250 | + "collapsed": true, |
| 251 | + "hidden": true |
| 252 | + }, |
| 253 | + "outputs": [], |
| 254 | + "source": [ |
| 255 | + "service_area_fset = FeatureSet(poly_feat_list, \n", |
| 256 | + " geometry_type=result['saPolygons']['geometryType'],\n", |
| 257 | + " spatial_reference= result['saPolygons']['spatialReference'])" |
| 258 | + ] |
| 259 | + }, |
| 260 | + { |
| 261 | + "cell_type": "markdown", |
| 262 | + "metadata": { |
| 263 | + "hidden": true |
| 264 | + }, |
| 265 | + "source": [ |
| 266 | + "Let us inspect the service area as a Pandas `DataFrame` to understand the attribute information" |
| 267 | + ] |
| 268 | + }, |
| 269 | + { |
| 270 | + "cell_type": "code", |
| 271 | + "execution_count": null, |
| 272 | + "metadata": { |
| 273 | + "hidden": true |
| 274 | + }, |
| 275 | + "outputs": [], |
| 276 | + "source": [ |
| 277 | + "service_area_fset.df" |
| 278 | + ] |
| 279 | + }, |
| 280 | + { |
| 281 | + "cell_type": "markdown", |
| 282 | + "metadata": { |
| 283 | + "hidden": true |
| 284 | + }, |
| 285 | + "source": [ |
| 286 | + "### Visualize the service area on the map\n", |
| 287 | + "From the DataFrame above, we know, there are 3 service area polygons for each fire station. The drive times are given as a range between `FromBreak` and `ToBreak` columns. Let us use this information to visualize the polygons with different colors and appropriate popup messags on the map" |
| 288 | + ] |
| 289 | + }, |
| 290 | + { |
| 291 | + "cell_type": "code", |
| 292 | + "execution_count": null, |
| 293 | + "metadata": { |
| 294 | + "collapsed": true, |
| 295 | + "hidden": true |
| 296 | + }, |
| 297 | + "outputs": [], |
| 298 | + "source": [ |
| 299 | + "colors = {5: [0, 128, 0, 90], \n", |
| 300 | + " 10: [255, 255, 0, 90], \n", |
| 301 | + " 15: [255, 0, 0, 90]}\n", |
| 302 | + "\n", |
| 303 | + "fill_symbol = {\"type\": \"esriSFS\",\"style\": \"esriSFSSolid\",\n", |
| 304 | + " \"color\": [115,76,0,255]}" |
| 305 | + ] |
| 306 | + }, |
| 307 | + { |
| 308 | + "cell_type": "code", |
| 309 | + "execution_count": null, |
| 310 | + "metadata": { |
| 311 | + "collapsed": true, |
| 312 | + "hidden": true |
| 313 | + }, |
| 314 | + "outputs": [], |
| 315 | + "source": [ |
| 316 | + "for service_area in service_area_fset.features:\n", |
| 317 | + " \n", |
| 318 | + " #set color based on drive time\n", |
| 319 | + " fill_symbol['color'] = colors[service_area.attributes['ToBreak']]\n", |
| 320 | + " \n", |
| 321 | + " #set popup\n", |
| 322 | + " popup={\"title\": \"Service area\", \n", |
| 323 | + " \"content\": \"{} minutes\".format(service_area.attributes['ToBreak'])}\n", |
| 324 | + " \n", |
| 325 | + " map1.draw(service_area.geometry, symbol=fill_symbol, popup=popup)" |
| 326 | + ] |
| 327 | + }, |
| 328 | + { |
| 329 | + "cell_type": "markdown", |
| 330 | + "metadata": { |
| 331 | + "hidden": true |
| 332 | + }, |
| 333 | + "source": [ |
| 334 | + "Click the drive time areas to explore their attributes. Because the content of the pop-ups may include HTML source code, it is also possible to have the pop-up windows include other resources such as tables and images." |
| 335 | + ] |
| 336 | + } |
| 337 | + ], |
| 338 | + "metadata": { |
| 339 | + "kernelspec": { |
| 340 | + "display_name": "Python 3", |
| 341 | + "language": "python", |
| 342 | + "name": "python3" |
| 343 | + }, |
| 344 | + "language_info": { |
| 345 | + "codemirror_mode": { |
| 346 | + "name": "ipython", |
| 347 | + "version": 3 |
| 348 | + }, |
| 349 | + "file_extension": ".py", |
| 350 | + "mimetype": "text/x-python", |
| 351 | + "name": "python", |
| 352 | + "nbconvert_exporter": "python", |
| 353 | + "pygments_lexer": "ipython3", |
| 354 | + "version": "3.6.1" |
| 355 | + } |
| 356 | + }, |
| 357 | + "nbformat": 4, |
| 358 | + "nbformat_minor": 2 |
| 359 | +} |
0 commit comments