Fighting California forest fires using spatial analysis

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
LA County Emergency Management

Summary: Group providing data relevant to emergencies in Los Angeles, California, USA.
Description: None
Owner: api_data_owner
Created: August 08, 2019
# list items in the group
items = group.content()
for item in items: 
    display(item)
Active California Fires
Fires in Southern California active during 2016-2017.Feature Layer Collection by api_data_owner
Last Modified: August 08, 2019
0 comments, 253 views
Critical Infrastructure in Southern California
Essential facilities to public health and safety in Southern California.Feature Layer Collection by api_data_owner
Last Modified: August 08, 2019
0 comments, 69 views
LA County Infrastructure At Risk
A Web Map with critical infrastructure at risk from fires.Web Map by arcgis_python
Last Modified: December 14, 2023
0 comments, 30 views

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', 9)
m

fighting-1.png

# add the active fires layer
fires = items[0]
m.add_layer(fires)
# add our critical infrastructure layer
infra = items[1]
m.add_layer(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', 9)
m1

fighting-2.png

#add the active fires layer to the map
m1.add_layer(fires)
#add the critical infrastructure layer to the map
m1.add_layer(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.share() method. The code below shares it to everyone (public):

# share the layer with public
firebuffers.share(everyone=True)
{'notSharedWith': [], 'itemId': '2d2f20cf99664d47ac4a1c2020a250ae'}

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.add_layer(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.share(everyone=True)
{'notSharedWith': [], 'itemId': '70e60df19f24459aa784fc9a55b5dedd'}

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_2023_12_15_08_49_38/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_1citylatitudeaddrln2linkaddrln1phonessourceshape_lenguse_type...date_updatnameinfo1analysisareaperimeter_acresobjectidinfo2statusSHAPE
0Fish Fire34.176673http://egis3.lacounty.gov/lms/?p=24626HSIP Freedom Gnis_cultural_fe24948.867757publish...2010-11-01Azusa Powerplant Conduit112.454712016-06-261085040242905Active{"x": -117.87199392276113, "y": 34.17666797642...
1Pony Fire34.157505http://egis3.lacounty.gov/lms/?p=26620HSIP Freedom Gnis_structures3787.741971publish...2010-11-01Motion Picture And Television Fund Hospital57.42822016-06-26108040244777Active{"x": -118.63618579426031, "y": 34.15750062135...
2Wheaton Fire34.280934http://egis3.lacounty.gov/lms/?p=27055HSIP Freedom Gnis_structures6262.26394publish...2011-05-03Pacoima Memorial Hospital60.1300132016-06-26894040280838Active{"x": -118.38329528379319, "y": 34.28092898174...
3Wheaton FirePacoima34.259185http://egis3.lacounty.gov/lms/?p=1355912653 Osborne St.818) 896-5271 (Primary)Current Services Locator6262.26394publish...2011-06-10Whiteman Airport60.1300132016-06-26894040281293Active{"x": -118.41329310645722, "y": 34.25918012113...
4Pony FireWoodland Hills34.170993http://egis3.lacounty.gov/lms/?p=7305601 De Soto Ave.Current Services Locator3787.741971publish...2011-06-27Kaiser Permanente - Woodland Hills Medical Center57.42822016-06-26108040281296Active{"x": -118.58972710110294, "y": 34.17098795728...
5Wheaton FireSun Valley34.240153http://egis3.lacounty.gov/lms/?p=6379449 San Fernando Rd.Mental Health Resource - 24 hours Service/Inta...2116262.26394publish...2013-05-30Pacifica Hospital Of The Valley60.1300132016-06-26894040283163Active{"x": -118.39619134564362, "y": 34.24014857730...
6Wheaton FirePacoima34.274168http://egis3.lacounty.gov/lms/?p=7059912756 Van Nuys BlvdAdministrative (818) 898-1388 Ext.51115, WIC S...2116262.26394publish...2010-11-01Northeast Valley Health Corporation - Pacoima ...60.1300132016-06-26894040284438Active{"x": -118.41070642294858, "y": 34.27416334584...

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
namecat1post_id
0Azusa Powerplant ConduitPhysical Features24626.0
1Motion Picture And Television Fund HospitalHealth and Mental Health26620.0
2Pacoima Memorial HospitalHealth and Mental Health27055.0
3Whiteman AirportTransportation13559.0
4Kaiser Permanente - Woodland Hills Medical CenterHealth and Mental Health730.0
5Pacifica Hospital Of The ValleyHealth and Mental Health637.0
6Northeast Valley Health Corporation - Pacoima ...Health and Mental Health70599.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', 9)
m2

fighting-3.png

#add the critical infrastructure layer to the map
m2.add_layer(infra)
# add at risk facilities layer to fresh map
m2.add_layer(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 webmap from the item
webmap = arcgis.mapping.WebMap(webmapitem)
# read the operational layers in our webmap
for lyr in webmap.layers:
    if lyr['id'].startswith('At_Risk_Infrastructure'):
        print(lyr['url'])
https://pythonapi.playground.esri.com/server/rest/services/Hosted/At_Risk_Infrastructure_2023_12_14_12_09_08/FeatureServer/0
new_url = at_risk_facilities.url
new_url
'https://pythonapi.playground.esri.com/server/rest/services/Hosted/At_Risk_Infrastructure_2023_12_15_08_49_38/FeatureServer/0'
# update the url of the 'At Risk Infrastructure' layer in the web map

for lyr in webmap.layers:
    if lyr['id'].startswith('At_Risk_Infrastructure'):
        lyr['url'] = new_url
# save the updates back to the GIS
webmap.update()
True

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', 9)
m3

fighting-4.png

feature_layer_id = webmap.layers[0].itemId
flayer = gis.content.get(feature_layer_id)
flayer
At_Risk_Infrastructure_source
Feature Layer Collection by api_data_owner
Last Modified: November 30, 2023
0 comments, 56 views
featurelayer = flayer.layers[0]
m3.add_layer(featurelayer)

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.