Skip To Content ArcGIS for Developers Sign In Dashboard
Download the samples Try it live

Finding suitable spots for placing heart defibrillator equipments in public

In this sample, we will observe how site suitability analyses can be performed using the ArcGIS API for Python. The objective of this sample is to find locations in the city of Philadelphia that are suitable for placing AED (Automated External Defibrillator) for public emergencies.

The criteria for a suitable place are those that have high incidence of OHCA (Out of Hospital Cardiac Arrests) and be accessible to public, such as commercial areas.

As inputs, we start with geocoded OCHA (Out-of-Hospital Cardiac Arrest) point data, along with a few base layers for the city of Pittsburgh published as feature layers. As output, we need to generate a list of locations that have a high incidence of heart-attacks and located within commercial areas, allowing easy access at times of emergencies.

Connect to the GIS

In [10]:
from arcgis.gis import *
gis = GIS("https://python.playground.esri.com/portal","arcgis_python","amazing_arcgis_123")

Preview the input datasets

In [2]:
ohca_item = gis.content.search("Pittsburgh_heart_attacks", "Feature Layer")[0]
ohca_item
Out[2]:
Pittsburgh_heart_attacks
OHCA in PittsburghFeature Layer Collection by arcgis_python
Last Modified: June 23, 2017
0 comments, 0 views
In [1]:
map1 = gis.map("Pittsburgh, PA", zoomlevel=12)
map1
Out[1]:
In [98]:
map1.add_layer(ohca_item)

Let us take a look at the layers available in this item

In [3]:
for lyr in ohca_item.layers:
    print(lyr.properties.name)
Heart attack incidence
Streets
Zoning
Rivers
Pittsburgh boundary

Outline of the analysis

For the rest of this analysis, we will use the Zoning polygon layer and build a 600-foot buffers around it to represent areas that are accessible to commercial zones. Next, we will use the Heart attack incidence point layer to build a density raster. This raster depicts those areas that have a higher incidence of cardiac arrests. Finally, we will overlay the buffers on the density raster to pick places that are suitable to place new AED devices.

Create a 600 feet buffer around commercial areas

The Zoning feature layer contains polygon features that represent different zones such as commercial, residential etc. We need to select those features that correspond to commercial zones and create a buffer of 600 feet around them. The 600 feet area roughly corresponds to two-blocks, a walk able distance in case of an emergency.

Select commercial zones

To select the commercial zones using a query, we need to know what columns and values are available. Hence, let us construct a small query that gives the first few rows / features.

In [3]:
zoning_flayer = ohca_item.layers[2]
zoning_fset = zoning_flayer.query(result_record_count=10, return_all_records=False)
In [4]:
zoning_fset.sdf
Out[4]:
acres area code code_2 name objectid perimeter sqmiles symbol x y zon_new zoning_ zoning_grouped zoning_id SHAPE
0 370.108 1.591398e+07 R1D-L R1D-L Single-Unit Detached Residential/Low Density 1 52563.176 0.576 80 1.340082e+06 429618.202356 R1D-L 2 Residential 5521 {'rings': [[[-80.01772016299998, 40.4977767210...
1 370.108 8.107219e+04 R2-L R2-L Two-Unit Residential/Low Density 2 1524.910 0.576 80 1.338226e+06 432380.904671 R2-L 3 Non Commercial 5522 {'rings': [[[-80.01757926499994, 40.4981592720...
2 60.461 2.591469e+06 R2-L R2-L Two-Unit Residential/Low Density 3 14071.084 0.094 83 1.335954e+06 430498.618340 R2-L 4 Non Commercial 5526 {'rings': [[[-80.02201914599993, 40.4938213470...
3 19.306 8.370962e+05 RP RP Residential Planned Unit Development 4 5395.625 0.030 85 1.340037e+06 431409.546743 RP 5 Residential 5517 {'rings': [[[-80.01117829099985, 40.4967724760...
4 0.223 9.650762e+03 RM-M RM-M Multi-Unit Residential/Low Density 5 441.323 0.000 84 1.339642e+06 431798.332613 RM-M 6 Residential 5519 {'rings': [[[-80.01130567899997, 40.4967769370...
5 0.682 2.956994e+04 RM-M RM-M Multi-Unit Residential/Low Density 6 694.941 0.001 84 1.339795e+06 431772.596200 RM-M 7 Residential 5518 {'rings': [[[-80.01056552699987, 40.4966935830...
6 370.108 1.301243e+05 R2-L R2-L Two-Unit Residential/Low Density 7 1882.449 0.576 80 1.337204e+06 431420.364326 R2-L 8 Non Commercial 5523 {'rings': [[[-80.02005998699991, 40.4963623440...
7 14.709 6.377810e+05 PO PO Parks and Open Space 8 4160.470 0.023 73 1.337574e+06 430975.826537 PO 9 Non Commercial 5524 {'rings': [[[-80.01961748999992, 40.4955720630...
8 4.975 2.080350e+05 UI UI Urban Industrial District 9 2329.875 0.008 128 1.341530e+06 431299.784705 UI 10 Commercial 5520 {'rings': [[[-80.00390870399991, 40.4945575660...
9 60.461 2.625691e+07 PO PO Parks and Open Space 10 67658.258 0.094 83 1.336595e+06 425033.974710 PO 11 Non Commercial 5537 {'rings': [[[-80.02087123699982, 40.4914294070...

The column zoning_grouped contains zoning categories. We are intersted in those polygons that correspond to the Commercial category.

In [5]:
zoning_commercial_fset = zoning_flayer.query("zoning_grouped = 'Commercial'")
commercial_zone_df = zoning_commercial_fset.sdf
commercial_zone_df.head(5)[['name','zoning_grouped']] #display the first 5 results
Out[5]:
name zoning_grouped
0 Urban Industrial District Commercial
1 Local Neighborhood Commercial Commercial
2 Neighborhood Industrial Commercial
3 Local Neighborhood Commercial Commercial
4 General Industrial Commercial
In [6]:
commercial_zone_df.shape
Out[6]:
(317, 16)

Let us draw the selected polygons on a map

In [2]:
zone_map = gis.map("Pittsburgh, PA")
zone_map
Out[2]: