ArcGIS Developer

ArcGIS API for Python

Download the samples Try it live

Hey GIS, Give me a map of the recent natural disasters

Local, State, National or even foreign governments need support to implement short-term emergency response, and long-term hazard mitigation measures at the occurrence of natural disasters. The sample notebook takes advantage of NASA's Earth Observatory Natural Event Tracker (EONET) API to collect a curated and continuously updated set of natural event metadata, and transform them into ArcGIS FeatureCollection(s) and save them into Web Maps in your GIS.

Using the temporal and location information of the event occurrence, this notebook queries the before- and after- disaster satellite images of the prone areas, and adds as overlay layers along with the FeatureCollection generated at the first step. The differences between the two fore and aft images can be used to build a training dataset. Thus when there are sufficient numbers of these images (or labels), you can build a model to predict, from the satellite images, if there was a natural disaster (e.g. tropical cyclone) or not.

With the sample notebook run in a scheduled fashion, you can produce a web map that contains the up-to-date list of natural disasters at any given time. For example, the eruption of Karymsky Volcano in Russia on Feb 15th, 2019 appears as one of the recent events in the EONET API Feed, and it would be represented in three forms - as an event vector, a pre-disaster satellite imagery, and a post-disaster satellite image (as shown in Figs 1, 2 and 3), in the resulting web map.

A Volcano eruption event in Russia Fig 1. A Volcano eruption event in Russia

Satellite Image of the area before the volcano eruption event Fig 2. Satellite Image of the area before the volcano eruption event

Satellite Image of the area after the volcano eruption event Fig 3. Satellite Image of the area after the volcano eruption event

Step 1. Preparation

In order to access the Land Remote-Sensing Satellite (System) (in short, Landsat) dataset, the first step is to connect to ArcGIS Online organization. The esri livingatlas account publishes a series of good-to-use Landsat products in forms of imagery layers ready that you can query, visualize and analyze. You can do so via an existing online profile, or just enter username/password as in gis = GIS('',"arcgis_python","P@ssword123").

Create another GIS connection to your ArcGIS Enterprise deployment to save the target web map. Same here, the GIS connection can be created via a profile, or using u/p (portal_gis = GIS('','arcgis_python','amazing_arcgis_123')).

In [1]:
from arcgis.gis import GIS

gis = GIS(profile = 'your_online_profile', verify_cert = False)

portal_gis = GIS(profile = 'your_enterprise_profile', verify_cert = False)

The exact_search function below extends the generic search method and returns you a single match instead of a list. It uses fields such as title, owner and item type, to loop through all the query results and gets an exact match. As seen here, the output of the exact_search is a Imagery Layer item titled "Multispectral Landsat".

In [2]:
def exact_search(my_gis, title, owner_value, item_type_value):
    final_match = None
    search_result = title + ' AND owner:' + owner_value, item_type=item_type_value, outside_org=True)
    if "Imagery Layer" in item_type_value:
        item_type_value = item_type_value.replace("Imagery Layer", "Image Service")
    elif "Layer" in item_type_value:
        item_type_value = item_type_value.replace("Layer", "Service")
    for result in search_result:
        if result.title == title and result.type == item_type_value :
            final_match = result
    return final_match

landsat_item = exact_search(gis, 'Multispectral Landsat', 'esri', 'Imagery Layer')
landsat = landsat_item.layers[0]
Multispectral Landsat
Landsat 8 OLI, 30m multispectral and multitemporal 8-band imagery, with on-the-fly renderings and indices. This imagery layer is sourced from the Landsat on AWS collections and is updated daily with new imagery.Imagery Layer by esri
Last Modified: May 03, 2018
0 comments, 143,954 views

Step 2. Understanding the data structure of EONET Feed

Carefully studying the geodata feed at, we notice the JSON feed does not strictly follow the GeoJSON standard, which requires a tree structure of FeatureCollection > features > Feature > geometry. In order to make the EONET feed easier for parsing, we rewrite the JSON feed to conform to the GeoJSON standard.

We can then use from_geojson() of the ArcGIS API for Python to create a FeatureSet object, and eventually a FeatureCollection object to save into the Web Map.

In [3]:
import json
from arcgis.geometry import Geometry
import requests
import pandas as pd
from arcgis.features import Feature, FeatureSet, FeatureCollection, GeoAccessor
In [4]:
""" read the response from HTTP request, and load as JSON object;
    all "events" in original JSON will be stored as "features"
response = requests.get("")  
obj = json.loads(response.text)
features = obj['events']
obj['features'] = features

Preview the feed data:

In [18]:
from pprint import pprint
print(len(obj['features']), "\n")
dict_keys(['title', 'description', 'link', 'events', 'features'])

{'categories': [{'id': 8, 'title': 'Wildfires'}],
 'description': '',
 'geometries': [{'coordinates': [34.99872, 31.41316],
                 'date': '2019-05-24T13:41:00Z',
                 'type': 'Point'}],
 'id': 'EONET_4196',
 'link': '',
 'sources': [{'id': 'PDC',
              'url': ''}],
 'title': 'Wildfires - Central Israel'}

We have obtained 124 events from the EO feed.

Note: The number of events may vary depending on the time you execute this sample and the number of disasters detected at that time.

Each "event" shall be stored as "Feature", and its geometry will be rewritten here based on its geometry type.

In [20]:
for feature in features:
    feature['type'] = "Feature"
    feature['objectIdFieldName'] = feature['id']
    feature["properties"] = {}
    feature["properties"]["id"] = feature["id"]
    feature["properties"]["title"] = feature["title"]
    feature["properties"]["date"] = feature["geometries"][0]['date']
    feature["properties"]["link"] = feature["link"]
    if len(feature["sources"]) > 0:
        feature["properties"]["source_id"] = feature["sources"][0]["id"]
        feature["properties"]["source_url"] = feature["sources"][0]["url"]
    feature["name"] = feature["title"]
    feature['geometry'] = {}
    if len(feature["geometries"]) == 1 and feature["geometries"][0]["type"] == "Point":
        feature["geometryType"] = "esriGeometryPoint"
        feature['geometry']['type'] = "Point"
        feature['geometry']['coordinates'] = feature["geometries"][0]['coordinates']
        feature['geometry']['date'] = feature["geometries"][0]['date']
    elif len(feature["geometries"]) > 1 and feature["geometries"][0]["type"] == "Point":
        feature["geometryType"] = "esriGeometryPolyline"
        feature['geometry']['type'] = "LineString"
        feature['geometry']['coordinates'] = []
        feature['geometry']['date'] = []
        for g in feature["geometries"]:
    elif len(feature["geometries"]) > 1 and feature["geometries"][0]["type"] == "Point":
        feature["geometryType"] = "esriGeometryMultiPoint" 
        feature['geometry']['type'] = "MultiPoint" 
        feature['geometry']['points'] = []
        feature['geometry']['date'] = []
        for g in feature["geometries"]:
            tmp = {'type': 'Point',
                   'coordinates': None}
            tmp['coordinates'] = g['coordinates']
    elif feature["geometries"][0]["type"] == "Polygon":
        feature["geometryType"] = "esriGeometryPolygon"
        feature['geometry']['type'] = "Polygon"
        feature['geometry']['coordinates'] = []
        feature['geometry']['date'] = []
        for g in feature["geometries"]:

Next, give the JSON object a root node called features and set the type to FeatureCollection

In [21]:
obj['features'] = features
obj['type'] = "FeatureCollection"

Now that we standardized the GeoJSON, we can use from_geojson method directly to create the FeatureSet object, which can be later be used as input as to create a FeatureCollection object using the from_featureset() method.

In [22]:
fset = FeatureSet.from_geojson(obj)
fc = FeatureCollection.from_featureset(fset, symbol=None, 
                                       name="Natural Disaster Feed Events Feature Collection")
<FeatureSet> 124 features

Read the data as a spatially enabled data frame (SeDF)

In [23]:
df = fc.query().sdf

# Visualize the top 5 records
OBJECTID SHAPE date id link source_id source_url title
0 1 {"x": 34.99872, "y": 31.41316, "spatialReferen... 2019-05-24T13:41:00Z EONET_4196 PDC Wildfires - Central Israel
1 2 {"x": -68.7, "y": 28.8, "spatialReference": {"... 2019-05-21T00:00:00Z EONET_4192 NOAA_NHC Subtropical Storm Andrea
2 3 {"x": -120.4293365, "y": 58.204834, "spatialRe... 2019-05-21T00:00:00Z EONET_4195 BCWILDFIRE Fontas River Fire, British Columbia, Canada
3 4 {"x": -114.40635, "y": 55.716367, "spatialRefe... 2019-05-18T14:46:00Z EONET_4190 ABFIRE Wildfire SWF049-2019 Slave Lake, Alberta, Canada
4 5 {"x": -114.544067, "y": 55.655167, "spatialRef... 2019-05-18T14:46:00Z EONET_4191 ABFIRE Wildfire SWF050-2019 Slave Lake, Alberta, Canada

Make URLs clickable

The columns link and source_url both contain HTTP URLs. Users will understand the data and source of the feed better if they are made into clickable links. The cells below demonstrate how to display these two columns in clickable hyperlink texts. Further, we split the DataFrame based on the disaster type.

In [5]:
def make_clickable(val):
    return '<a href="{}">{}</a>'.format(val,val)

# query for rows with "Fire" or "Wildfire" in its "title" column
df1 = df[df['title'].str.contains("Fire|Wildfire") == True]
# drop unnecessary columns
cols = [col for col in df.columns if col not in ['OBJECTID', 'SHAPE', 'index']]
df1 = df1[cols]
# attach the two columns with clickable hyperlinks
df1.reset_index().style.format({'link': make_clickable, 'source_url': make_clickable})
index date id link source_id source_url title
0 0 2019-05-13T15:40:00Z EONET_4182 PDC Wildfires - Southern Switzerland
1 1 2019-05-13T00:00:00Z EONET_4183 MBFIRE Wildfire MB-CE038, Manitoba, Canada
2 2 2019-05-13T00:00:00Z EONET_4184 MBFIRE Wildfire MB-CE039, Manitoba, Canada
3 3 2019-05-13T00:00:00Z EONET_4185 BCWILDFIRE Richter Creek Fire, British Columbia, Canada
4 4 2019-05-11T22:18:00Z EONET_4181 ABFIRE Wildfire PWF052-2019 Peace River, Alberta, Canada
5 6 2019-05-10T15:47:00Z EONET_4179 PDC Wildfires - Mexico
6 7 2019-05-07T16:27:00Z EONET_4178 PDC Wildfires - Lithuania and Latvia
7 8 2019-05-03T00:00:00Z EONET_4174 MBFIRE Wildfire MB-CE018, Manitoba, Canada
8 9 2019-04-30T14:22:00Z EONET_4170 PDC Wildfires - Mexico
9 10 2019-04-30T13:00:00Z EONET_4173 InciWeb Oregon Lakes Fire
10 11 2019-04-30T00:00:00Z EONET_4172 MBFIRE Wildfire MB-CE015, Manitoba, Canada
11 12 2019-04-29T00:00:00Z EONET_4171 MBFIRE Wildfire MB-CE013, Manitoba, Canada
12 13 2019-04-26T15:51:00Z EONET_4168 PDC Wildfires - Southern Uruguay
13 14 2019-04-25T17:27:00Z EONET_4167 PDC Wildfires - Southern Sweden
14 15 2019-04-24T17:25:00Z EONET_4165 PDC Wildfires - Southern Norway
15 16 2019-04-22T15:40:00Z EONET_4161 PDC Wildfires - Switzerland
16 18 2019-04-12T16:48:00Z EONET_4159 PDC Wildfires - Macarao National Park, Venezuela
17 20 2019-03-29T16:21:00Z EONET_4155 PDC Wildfires - Central and Northern Portugal
18 22 2019-03-21T14:30:00Z EONET_4154 PDC Wildfires - Paredones, Chile
19 23 2019-03-18T16:24:00Z EONET_4149 PDC Wildfires - Southern Switzerland
20 24 2019-03-18T16:00:00Z EONET_4150 PDC Wildfires - Northwestern South Africa
21 52 2019-03-11T17:02:00Z EONET_4118 PDC Wildfires - Traiguén, Chile
22 53 2019-03-11T16:56:00Z EONET_4117 PDC Wildfire - Cautín, Chile
23 54 2019-03-11T16:48:00Z EONET_4116 PDC Wildfire - Ercilla, Chile
24 55 2019-03-11T16:14:00Z EONET_4119 PDC Wildfire - Woodgate, Queensland, Australia
25 56 2019-03-07T15:34:00Z EONET_4114 PDC Wildfires - Sierra Nevada de Santa Marta, Colombia
26 57 2019-03-05T15:44:00Z EONET_4113 PDC Wildfires - Southeastern Victoria, Australia
27 58 2019-03-05T15:41:00Z EONET_4112 PDC Wildfires - Western Basque Country, Cantabria and Asturias, Spain
28 59 2019-03-04T15:40:00Z EONET_4111 PDC Wildfire - Bullsbrook, Western Australia, Australia
29 60 2019-03-04T15:23:00Z EONET_4110 PDC Wildfire - Mount Kenya, Kenya
30 61 2019-03-01T18:39:00Z EONET_4108 PDC Wildfires - Ercilla and Collipulli, Chile
31 62 2019-03-01T18:34:00Z EONET_4107 PDC Wildfires - Esperance, Western Australia
32 63 2019-03-01T18:27:00Z EONET_4106 PDC Wildfires - Slovenia
33 64 2019-03-01T18:24:00Z EONET_4105 PDC Wildfires - South Africa
34 65 2019-02-27T15:41:00Z EONET_4103 PDC Wildfires - Saddleworth Moor, United Kingdom
35 66 2019-02-25T16:29:00Z EONET_4101 PDC Wildfires - Corsica, France
36 68 2019-02-20T15:26:00Z EONET_4097 PDC Wildfire - Southampton, Western Australia, Australia
37 69 2019-02-19T17:44:00Z EONET_4096 PDC Wildfire - Nelson Tasman Region (Pigeon Valley Fire), New Zealand
38 73 2019-02-15T16:47:00Z EONET_4094 PDC Wildfires - Southern Switzerland
39 74 2019-02-14T16:38:00Z EONET_4093 PDC Wildfire - Laingsburg, South Africa
40 75 2019-02-11T16:42:00Z EONET_4090 PDC Wildfires - Galvarino, Chile
41 78 2019-02-07T19:43:00Z EONET_4088 PDC Wildfire - Cochamo, Chile
42 79 2019-02-06T16:51:00Z EONET_4086 PDC Wildfires - Nelson - Tasman, New Zealand
43 80 2019-02-06T16:37:00Z EONET_4087 PDC Wildfires - Southwestern, South Africa
44 81 2019-02-05T15:42:00Z EONET_4081 PDC Wildfires - Southern Chile
45 87 2019-01-07T04:20:00Z EONET_4072 PDC Wildfire - Wailea, Hawaii, United States
In [6]:
df2 = df[df['title'].str.contains("Cyclone") == True]
df2 = df2[cols]
df2.reset_index().style.format({'link': make_clickable, 'source_url': make_clickable})
index date id link source_id source_url title
0 5 2019-05-11T00:00:00Z EONET_4180 JTWC Tropical Cyclone Ann
In [7]:
df3 = df[df['title'].str.contains("Volcano") == True]
df3 = df3[cols]
df3.reset_index().style.format({'link': make_clickable, 'source_url': make_clickable})
index date id link source_id source_url title
0 17 2019-04-16T10:12:29Z EONET_4160 SIVolcano Asosan Volcano, Japan
1 19 2019-04-09T00:00:00Z EONET_4158 SIVolcano Klyuchevskoy Volcano, Russia
2 21 2019-03-26T09:19:10Z EONET_4156 SIVolcano Sangay Volcano, Ecuador
3 25 2019-03-17T00:00:00Z EONET_4152 nan nan Villarica Volcano, Chile
4 67 2019-02-24T10:58:37Z EONET_4104 SIVolcano Semeru Volcano, Indonesia
5 70 2019-02-18T00:00:00Z EONET_4098 SIVolcano Tengger Caldera Volcano, Indonesia
6 71 2019-02-16T00:00:00Z EONET_4099 SIVolcano Karymsky Volcano, Russia
7 72 2019-02-16T00:00:00Z EONET_4100 SIVolcano Piton de la Fournaise Volcano, Réunion (France)
8 76 2019-02-11T09:50:08Z EONET_4092 SIVolcano Poas Volcano, Costa Rica
9 82 2019-01-29T00:00:00Z EONET_4085 SIVolcano Merapi Volcano, Indonesia
10 83 2019-01-20T00:00:00Z EONET_4075 SIVolcano Bezymianny Volcano, Russia
11 84 2019-01-19T08:49:43Z EONET_4074 SIVolcano Kerinci Volcano, Indonesia
12 85 2019-01-11T00:00:00Z EONET_4079 SIVolcano San Cristobal Volcano
13 86 2019-01-10T00:00:00Z EONET_4073 SIVolcano Agung Volcano, Indonesia
14 88 2019-01-06T08:15:24Z EONET_4069 SIVolcano Reventador Volcano, Ecuador
15 89 2019-01-05T00:00:00Z EONET_4070 SIVolcano Planchón-Peteroa Volcano, Chile
16 90 2019-01-02T09:05:32Z EONET_4071 SIVolcano Stromboli Volcano, Italy
17 91 2018-12-02T00:00:00Z EONET_4049 SIVolcano Popocatepetl Volcano, Mexico
18 92 2018-11-25T00:00:00Z EONET_4044 SIVolcano Karangetang Volcano, Indonesia
19 94 2018-11-09T00:00:00Z EONET_4048 SIVolcano Suwanosejima Volcano, Japan
20 95 2018-09-28T00:00:00Z EONET_3999 SIVolcano Kadovar Volcano, Papua New Guinea
21 96 2018-08-25T06:00:00Z EONET_3934 NASA_DISP Manam Volcano, Papua New Guinea
22 97 2018-08-01T00:00:00Z EONET_3867 EO Etna Volcano, Italy
23 98 2018-07-23T00:00:00Z EONET_3871 SIVolcano Turrialba Volcano, Costa Rica
24 99 2018-07-11T00:00:00Z EONET_3868 SIVolcano Nevados de Chillan Volcano, Chile
25 100 2018-06-18T00:00:00Z EONET_3618 SIVolcano Krakatau Volcano, Indonesia
26 101 2018-05-01T00:00:00Z EONET_3674 SIVolcano Santa Maria Volcano, Guatemala
27 102 2018-03-07T00:00:00Z EONET_3491 SIVolcano Ibu Volcano, Indonesia
28 103 2017-08-12T00:00:00Z EONET_3390 SIVolcano Pacaya Volcano, Guatemala
29 109 2017-03-25T00:00:00Z EONET_2761 SIVolcano Aira Volcano, Japan
30 110 2016-12-08T00:00:00Z EONET_2693 SIVolcano Ebeko Volcano, Russia
31 111 2016-11-07T00:00:00Z EONET_2654 EO Sabancaya Volcano, Peru
32 112 2016-09-18T00:00:00Z EONET_2632 EO Sheveluch Volcano, Russia
33 113 2016-03-16T00:00:00Z EONET_354 EO Dukono Volcano, Indonesia
34 126 2002-01-04T00:00:00Z EONET_980 CEMS Fuego Volcano, Guatemala
In [8]:
df4 = df[df['title'].str.contains("Iceberg") == True]
df4 = df4[cols]
df4.reset_index().style.format({'link': make_clickable, 'source_url': make_clickable})
index date id link source_id source_url title
0 26 2019-03-13T00:00:00Z EONET_4129 NATICE Iceberg B38
1 27 2019-03-13T00:00:00Z EONET_4130 NATICE Iceberg B39
2 28 2019-03-13T00:00:00Z EONET_4131 NATICE Iceberg B40
3 29 2019-03-13T00:00:00Z EONET_4132 NATICE Iceberg B45
4 30 2019-03-13T00:00:00Z EONET_4133 NATICE Iceberg C18B
5 31 2019-03-13T00:00:00Z EONET_4134 NATICE Iceberg C24
6 32 2019-03-13T00:00:00Z EONET_4135 NATICE Iceberg C29
7 33 2019-03-13T00:00:00Z EONET_4136 NATICE Iceberg C30
8 34 2019-03-13T00:00:00Z EONET_4137 NATICE Iceberg C31
9 35 2019-03-13T00:00:00Z EONET_4138 NATICE Iceberg C32
10 36 2019-03-13T00:00:00Z EONET_4139 NATICE Iceberg C33
11 37 2019-03-13T00:00:00Z EONET_4140 NATICE Iceberg C35
12 38 2019-03-13T00:00:00Z EONET_4141 NATICE Iceberg D21B
13 39 2019-03-13T00:00:00Z EONET_4142 NATICE Iceberg D22
14 40 2019-03-13T00:00:00Z EONET_4143 NATICE Iceberg D23
15 41 2019-03-13T00:00:00Z EONET_4144 NATICE Iceberg D26
16 42 2019-03-13T00:00:00Z EONET_4145 NATICE Iceberg D27
17 43 2019-03-12T00:00:00Z EONET_4120 NATICE Iceberg A57A
18 44 2019-03-12T00:00:00Z EONET_4121 NATICE Iceberg A63
19 45 2019-03-12T00:00:00Z EONET_4122 NATICE Iceberg B09G
20 46 2019-03-12T00:00:00Z EONET_4123 NATICE Iceberg B09I
21 47 2019-03-12T00:00:00Z EONET_4124 NATICE Iceberg B15AA
22 48 2019-03-12T00:00:00Z EONET_4125 NATICE Iceberg B15AB
23 49 2019-03-12T00:00:00Z EONET_4126 NATICE Iceberg B28
24 50 2019-03-12T00:00:00Z EONET_4127 NATICE Iceberg B29
25 51 2019-03-12T00:00:00Z EONET_4128 NATICE Iceberg B37
26 77 2019-02-11T00:00:00Z EONET_4089 NATICE Iceberg C36
27 93 2018-11-09T00:00:00Z EONET_4031 EO Iceberg B46
28 104 2017-07-21T00:00:00Z EONET_2998 NATICE Iceberg A68B
29 105 2017-07-12T00:00:00Z EONET_2934 EO Iceberg A68A
30 106 2017-05-19T00:00:00Z EONET_2883 NATICE Iceberg C34
31 107 2017-04-21T00:00:00Z EONET_2881 NATICE Iceberg B42
32 108 2017-04-21T00:00:00Z EONET_2882 NATICE Iceberg B43
33 114 2016-02-01T00:00:00Z EONET_2871 BYU_ICE Iceberg D15B
34 115 2016-01-31T00:00:00Z EONET_2870 BYU_ICE Iceberg D15A
35 116 2014-07-23T00:00:00Z EONET_2880 BYU_ICE Iceberg A64
36 117 2012-05-24T00:00:00Z EONET_2733 BYU_ICE Iceberg B30
37 118 2012-02-03T00:00:00Z EONET_2874 BYU_ICE Iceberg B09F
38 119 2011-08-30T00:00:00Z EONET_2734 BYU_ICE Iceberg A23A
39 120 2011-08-30T00:00:00Z EONET_2736 BYU_ICE Iceberg B22A
40 121 2011-08-30T00:00:00Z EONET_2876 BYU_ICE Iceberg C15
41 122 2011-08-30T00:00:00Z EONET_2878 BYU_ICE Iceberg B09B
42 123 2011-08-30T00:00:00Z EONET_2879 BYU_ICE Iceberg D20A
43 124 2011-08-30T00:00:00Z EONET_2996 BYU_ICE Iceberg B16
44 125 2011-08-30T00:00:00Z EONET_2997 BYU_ICE Iceberg C21B

Step 3. Plot the features

So far, we have transformed and read the EONet feed into a Spatially Enabled DataFrame object. We noticed that features of different disaster types have different geometry types, properties, and data structures. We can use these properties to symbolize these disasters and draw them on a map.

Before plotting on a map, let's take a look at the built-in symbol styles that comes with the arcgis.mapping module. Symbol styles come in different sets for Points, Lines and Polygons as shown below.

In [9]:
from arcgis.mapping import show_styles

for idx, style in show_styles('Point').iterrows():
    print(style['ESRI_STYLE'] + " : " + style['MARKER'])
    style_volcano = style['MARKER']
for idx, style in show_styles('Line').iterrows():
    print(style['ESRI_STYLE'] + " : " + style['MARKER'])
    style_cyclone = style['MARKER']
for idx, style in show_styles('Polygon').iterrows():
    print(style['ESRI_STYLE'] + " : " + style['MARKER'])
    style_iceburg = style['MARKER']
Circle (default) : o
Cross : +
Diamond : d
Square : s
X : x
Solid (default) : s
Dash : -
Dash Dot : -.
Dash Dot Dot : -..
Dot : .
Long Dash : --
Long Dash Dot : --.
Null : n
Short Dash : s-
Short Dash Dot : s-.
Short Dash Dot Dot : s-..
Short Dot : s.
Backward Diagonal : \
Forward Diagonal : /
Vertical Bar : |
Horizontal Bar : -
Diagonal Cross : x
Cross : +
Solid Fill (default) : s

Create a temporary map object.

In [10]:
map_g =

The EONet takes liberty in varying the geometry type used to record events of the same type. Thus an Iceburg could be a point or a polygon. The cell below handles this uncertainity. It also picks an appropriate symbol for each geometry type.

The boolean variable if_Changed is used to represent if the geometry of the features inside the FeatureSet has been changed during the parsing or execution process. A hint here: If you are interested to find out the details of each feature stored in the FeatureSet Class object, use print(ea.get_value('title'), " - ", ea.geometry_type, " - ", ea.geometry) to display information of each entry.

In [11]:
if_Changed = False

# Filter based on disaster type, and each type is assigned a different symbology
for ea in fc.query():
    title = ea.get_value('title')
    obj_id = ea.attributes['OBJECTID']
    obj_type = ea.geometry_type
    if "Cyclone" in title:
        df_sel = df[df['OBJECTID']==obj_id]
                            symbol_type = 'simple',
                            symbol_style = style_cyclone)
    elif "Volcano" in title:
        if obj_type == 'Point':
            df_sel = df[df['OBJECTID']==obj_id]
            df_sel.spatial.plot(map_widget= map_g,
                                symbol_type = 'simple',
                                symbol_style = style_volcano)
        else: # Polygon
            if not if_Changed and 'rings' in ea.geometry:
                tmp = ea.geometry['rings']
                ea.geometry['rings'] = tmp[0]
                if_Changed = True
            df_sel = df[df['OBJECTID']==obj_id]
            df_sel.spatial.plot(map_widget= map_g,
                                symbol_type = 'simple',
                                symbol_style = style_volcano,
    elif "Wildfire" in title or "Fire" in title:
        df_sel = df[df['OBJECTID']==obj_id]
        df_sel.spatial.plot(map_widget= map_g,
                            symbol_type = 'simple',
                            symbol_style = 'd')
    elif "Iceberg" in title:
        if obj_type == 'Point':
            df_sel = df[df['OBJECTID']==obj_id]
            df_sel.spatial.plot(map_widget= map_g,
                                symbol_type = 'simple',
                                symbol_style = style_iceburg)
        else: # Polyline
            df_sel = df[df['OBJECTID']==obj_id]
            df_sel.spatial.plot(map_widget= map_g,
                                symbol_type = 'simple',
                                symbol_style = style_iceburg)
        print(" - Not recognized - ", title)
In [12]:
# map_g
map_g1 =
for lyr in map_g.layers: