The state of California has had a dangerous fire season in 2015 and 2016. A standard procedure while fighting these fires is identifying facilities that are at risk and evacuating them. Tasks such as this can be accomplished easily using spatial analysis tools available on your GIS. Spatial analysis tools allow overlaying the extent of fire and the locations of the facilities on a map and identifying the ones that fall within the fire's extent.
Thus, this sample demonstrates the application of spatial analysis tools such as buffer and overlay.
This notebook describes a scenario wherein an analyst automates the process of identifying facilities at risk from forest fires and sharing this information with other departments such as the fire department, etc.
Note: To run this sample, you need the pandas
library in your conda environment. If you don't have the library, install it by running the following command from cmd.exe or your shell
conda install pandas
import datetime
import arcgis
from arcgis.gis import GIS
from IPython.display import display
import pandas as pd
# create a Web GIS object
gis = GIS(profile="your_enterprise_profile")
Using groups to share items and collaborate
A group effort spanning several professionals and teams is required to meet challenges such as forest fires. Members of a web GIS can collaborate with each other by sharing web maps, layers, applications, etc. with each other. This sharing is accomplished by creating groups in the GIS and items shared to a group can be used by members of the group.
The code below lists the items shared with the 'LA County Emergency Management' group. This group contains a collection of maps, apps and layers that are published as the authoritative common map for the county of Los Angeles.
# get our group
group = gis.groups.search('LA County Emergency Management')[0]
group
# list items in the group
items = group.content()
for item in items:
display(item)
Visualize the fire data
Let us create a map widget to see the fire related information in it's geographic context:
# create a map of our area of interest
m = gis.map('Los Angeles')
m
m.zoom = 9
# add the active fires layer
fires = items[0]
m.content.add(fires)
# add our critical infrastructure layer
infra = items[1]
m.content.add(infra)
#we shall use this webmap item in the last section of the notebook.
webmapitem = items[2]
# create a map of our area of interest
m1 = gis.map('Los Angeles')
m1
m1.zoom = 9
#add the active fires layer to the map
m1.content.add(fires)
#add the critical infrastructure layer to the map
m1.content.add(infra)
from arcgis.features.use_proximity import create_buffers
# buffer the active fire boundaries and add as new content
timestamp = '{:%Y_%m_%d_%H_%M_%S}'.format(datetime.datetime.now())
firebuffers = create_buffers(fires, [4], None, 'Miles', output_name="Fire_Buffers_" + timestamp )
The output layer is private by default. To share it with particular groups, members within the org, or everyone, we can use the Item.sharing.sharing_level
property. The code below shares it to 'EVERYONE'
(public):
# share the layer with public
firebuffers.sharing.sharing_level = 'EVERYONE'
Since the output_name
parameter was specified, the tool created a new feature layer item as output. We can visualize this by adding it to the map above. Now we can observe more facilities falling within the buffered area.
# add risk areas to map
m1.content.add(firebuffers)
Perform overlay analysis to extract facilities that fall within the fire buffers
To programmatically extract the locations that fall within the fire buffers, we use overlay_layers
tool under FeatureAnalysisTools
class just like we did for create_buffers
tool earlier. The overlay_layers
tool supports a few overlay types, here we use Intersect
as we need to perform a spatial intersection to identify the facilities that are located within the fire boundaries. To learn more about this operation, refer to the documentation.
We specify an output name (with a timestamp) for the service as we want to keep a record of the critical infrastructure within the risk boundaries and share it with others as feature layers or in web maps:
from arcgis.features.manage_data import overlay_layers
# run analysis to determine critical infrastructure within the risk boundaries
riskinfra = overlay_layers(firebuffers, infra,
overlay_type="Intersect",
output_name="At_Risk_Infrastructure_" + timestamp)
# set sharing on new analysis layer
riskinfra.sharing.sharing_level = 'EVERYONE'
The output of the overlay analysis is a Feature Layer Item. We can access the layers and tables in an Item represing GIS services using the layers
and tables
attributes.
riskinfra.layers
[<FeatureLayer url:'https://pythonapi.playground.esri.com/server/rest/services/Hosted/At_Risk_Infrastructure_2024_05_07_18_41_36/FeatureServer/0'>]
Read analysis results as a pandas dataframe for analysis
Let us read this results of the overlay analysis by querying it's layer for attribute data, and display the attribute table to get a sense of the results. Layers can be queried for attributes and geometry using the query()
method.
The query we ran in the previous step returned a list of dictionaries representing the features. For further analysis or for visualizing the output data as a table, let us convert it into a pandas dataframe.
at_risk_facilities = riskinfra.layers[0]
df = at_risk_facilities.query(as_df=True) # read the returned features as a Pandas dataframe
df
name_1 | city | latitude | addrln2 | link | addrln1 | phones | source | shape_leng | use_type | ... | date_updat | name | info1 | analysisarea | perimeter_ | acres | objectid | info2 | status | SHAPE | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | Fish Fire | 34.176673 | http://egis3.lacounty.gov/lms/?p=24626 | HSIP Freedom Gnis_cultural_fe | 24948.867757 | publish | ... | 2010-11-01 | Azusa Powerplant Conduit | 112.45471 | 2016-06-26 | 10850 | 40242905 | Active | {"x": -117.87199392299999, "y": 34.17666797600... | ||||||
1 | Pony Fire | 34.157505 | http://egis3.lacounty.gov/lms/?p=26620 | HSIP Freedom Gnis_structures | 3787.741971 | publish | ... | 2010-11-01 | Motion Picture And Television Fund Hospital | 57.4282 | 2016-06-26 | 1080 | 40244777 | Active | {"x": -118.63618579399997, "y": 34.15750062100... | ||||||
2 | Wheaton Fire | 34.280934 | http://egis3.lacounty.gov/lms/?p=27055 | HSIP Freedom Gnis_structures | 6262.26394 | publish | ... | 2011-05-03 | Pacoima Memorial Hospital | 60.130013 | 2016-06-26 | 8940 | 40280838 | Active | {"x": -118.38329528399998, "y": 34.28092898200... | ||||||
3 | Wheaton Fire | Pacoima | 34.259185 | http://egis3.lacounty.gov/lms/?p=13559 | 12653 Osborne St. | 818) 896-5271 (Primary) | Current Services Locator | 6262.26394 | publish | ... | 2011-06-10 | Whiteman Airport | 60.130013 | 2016-06-26 | 8940 | 40281293 | Active | {"x": -118.41329310599997, "y": 34.25918012100... | |||
4 | Pony Fire | Woodland Hills | 34.170993 | http://egis3.lacounty.gov/lms/?p=730 | 5601 De Soto Ave. | Current Services Locator | 3787.741971 | publish | ... | 2011-06-27 | Kaiser Permanente - Woodland Hills Medical Center | 57.4282 | 2016-06-26 | 1080 | 40281296 | Active | {"x": -118.589727101, "y": 34.17098795700008, ... | ||||
5 | Wheaton Fire | Sun Valley | 34.240153 | http://egis3.lacounty.gov/lms/?p=637 | 9449 San Fernando Rd. | Mental Health Resource - 24 hours Service/Inta... | 211 | 6262.26394 | publish | ... | 2013-05-30 | Pacifica Hospital Of The Valley | 60.130013 | 2016-06-26 | 8940 | 40283163 | Active | {"x": -118.39619134599997, "y": 34.24014857700... | |||
6 | Wheaton Fire | Pacoima | 34.274168 | http://egis3.lacounty.gov/lms/?p=70599 | 12756 Van Nuys Blvd | Administrative (818) 898-1388 Ext.51115, WIC S... | 211 | 6262.26394 | publish | ... | 2010-11-01 | Northeast Valley Health Corporation - Pacoima ... | 60.130013 | 2016-06-26 | 8940 | 40284438 | Active | {"x": -118.41070642299997, "y": 34.27416334600... |
7 rows × 43 columns
From the data frame, we can see there are 7 features which fell within the fire buffers. To make this result usable, let us export a CSV with only the facility name and other critical details. This CSV can be considered as a valuable information product as a result of this analysis and can be shared with the teams assisting in organizing the firefighting efforts, evacuations, etc.
# view simplified risk facilities table
df1_simplified = df[['name', 'cat1', 'post_id']]
df1_simplified
name | cat1 | post_id | |
---|---|---|---|
0 | Azusa Powerplant Conduit | Physical Features | 24626.0 |
1 | Motion Picture And Television Fund Hospital | Health and Mental Health | 26620.0 |
2 | Pacoima Memorial Hospital | Health and Mental Health | 27055.0 |
3 | Whiteman Airport | Transportation | 13559.0 |
4 | Kaiser Permanente - Woodland Hills Medical Center | Health and Mental Health | 730.0 |
5 | Pacifica Hospital Of The Valley | Health and Mental Health | 637.0 |
6 | Northeast Valley Health Corporation - Pacoima ... | Health and Mental Health | 70599.0 |
# Export this to a csv file. This CSV can then be shared with fire fighters.
csv_file = r'at_risk_facilities.csv'
df1_simplified.to_csv(csv_file)
Mapping the infrastructure at risk
Tables and charts aren't enough to convey the information gathered from this analysis. By plotting the locations of the critical infrastructure at risk from the forest fires, we are able to identify patterns that can be of great value in fighting a catastrophe of this scale and prevent or minimize human, infrastructural and environmental loss:
# create new map over aoi
m2 = gis.map('Los Angeles')
m2
m2.zoom = 9
#add the critical infrastructure layer to the map
m2.content.add(infra)
# add at risk facilities layer to fresh map
m2.content.add(riskinfra)
Sharing the result of the analysis as a web map
The different teams working on the firefighting, relief and rescue efforts need a current and updated web map of the critical infrastruture at risk from the fires. The code below fetches the web-map from the GIS and updates it's operational layer to the one from the analysis above. This enables all interested parties to refer to one common, constantly updated web-map for planning firefighting, rescue and relief efforts.
#display the webmap item that we had obtained as part of the 'LA County Emergency Management' group's content in the first section of this notebook.
webmapitem
# create a web map from the item
webmap = gis.map(webmapitem)
# read the operational layers in our webmap
for lyr in webmap.content.layers:
if lyr.properties['name'].startswith('At_Risk_Infrastructure'):
print(lyr.url)
https://pythonapi.playground.esri.com/server/rest/services/Hosted/At_Risk_Infrastructure_2020_07_07_13_26_50/FeatureServer/0
new_url = at_risk_facilities.url
new_url
https://pythonapi.playground.esri.com/server/rest/services/Hosted/At_Risk_Infrastructure_2024_05_07_18_41_36/FeatureServer/0
# update the url of the 'At Risk Infrastructure' layer in the web map
for lyr in webmap.content.layers:
if lyr.properties['name'].startswith('At_Risk_Infrastructure'):
lyr.url = new_url
# save the updates back to the GIS
webmap.update()
Web map items can also be visualized in the Jupyter Notebook as shown below. This enables use of web-maps for analysis and visualization within the notebook environment.
m3 = gis.map('Los Angeles')
m3
m3.zoom = 9
feature_layer_id = webmap.content.layers[0].properties['serviceItemId']
flayer = gis.content.get(feature_layer_id)
flayer
featurelayer = flayer.layers[0]
m3.content.add(featurelayer)