Skip To Content ArcGIS for Developers Sign In Dashboard

ArcGIS API for Python

Download the samples Try it live

How much green is Delhi as on 15 Oct 2017?

Introduction

The India State of Forests Report (ISFR) 2017, showed that the green cover of Delhi has increased from 20.08% in 2015 to 20.22% in 2017, as observed from satellite imageries of Delhi for the month of October and November [1]. This was a welcome news for the city struggling with severe pollution and rising population, which makes it necessary to monitor the city's green cover and keep the city liveable.

This sample shows the capabilities of spectral indices such as Normalized Difference Vegetation index (NDVI) for the calculation of green cover in Delhi, India on 15 October 2017 using Landsat 8 imagery.

Necessary Imports

In [1]:
%matplotlib inline

import pandas as pd
from datetime import datetime
from IPython.display import Image
from IPython.display import HTML
import matplotlib.pyplot as plt

import arcgis
from arcgis.gis import GIS
from arcgis.raster.functions import apply, clip, remap, colormap
from arcgis.geocoding import geocode

Connect to your GIS

In [2]:
gis = GIS(url='https://pythonapi.playground.esri.com/portal', username='arcgis_python', password='amazing_arcgis_123')

Get the data for analysis

Search for Multispectral Landsat layer in ArcGIS Online.

In [3]:
landsat_item = gis.content.search('title:Multispectral Landsat', 'Imagery Layer', outside_org=True)[0]
landsat = landsat_item.layers[0]
landsat_item
Out[3]:
Multispectral Landsat
Landsat multispectral and multitemporal imagery with on-the-fly renderings and indices for visualization and analysis. The Landsat 8 imagery in this layer is updated daily and is directly sourced from the Landsat on AWS collection.Imagery Layer by esri
Last Modified: December 19, 2019
0 comments, 2,10,398 views

Search for India State Boundaries 2018 layer in ArcGIS Online. This layer has all the state boundaries for India. The boundary of Delhi can be filtered from the layer, as this notebook focuses on the city's green cover.

In [4]:
boundaries = gis.content.search('India State Boundaries 2018', 'Feature Layer', outside_org=True)[0]
state_boundaries = boundaries.layers[1]

Extracting Landsat imagery for New Delhi Region

In [5]:
area = geocode("New Delhi, India", out_sr=landsat.properties.spatialReference)[0]
landsat.extent = area['extent']

In State Boundary layer, OBJECTID for Delhi is 7 which is used below. Also, it is important to add extent to the geometry of selected boundary.

In [6]:
delhi = state_boundaries.query(where='OBJECTID=7')
delhi_geom = delhi.features[0].geometry
delhi_geom['spatialReference'] = {'wkid':4326}
delhi.features[0].extent = area['extent']

Filter imageries based on cloud cover and Acquisition Date

In order to have good result, it is important to select cloud free imagery from the image collection for a specified time duration. In this example we have selected all the imageries captured between 1 October, 2017 to 31 December, 2017 with cloud cover less than or equal to 5% for Delhi.

In [8]:
selected = landsat.filter_by(where="(Category = 1) AND (cloudcover <=0.05)",
                             time=[datetime(2017, 10, 1), datetime(2017, 12, 31)],
                             geometry=arcgis.geometry.filters.intersects(area['extent']))

df = selected.query(out_fields="AcquisitionDate, GroupName, CloudCover, DayOfYear", 
                    order_by_fields="AcquisitionDate").sdf
df['AcquisitionDate'] = pd.to_datetime(df['AcquisitionDate'], unit='ms')
df
Out[8]:
OBJECTID AcquisitionDate GroupName CloudCover DayOfYear Shape_Length Shape_Area SHAPE
0 2096408 2017-10-06 05:25:18 LC81470402017279LGN00_MTL 0.0000 279 852147.705738 4.534369e+10 {'rings': [[[8625624.2331, 3442812.7971], [857...
1 2095521 2017-10-15 05:19:09 LC81460402017288LGN00_MTL 0.0011 288 852002.482986 4.532785e+10 {'rings': [[[8796766.063900001, 3442853.641099...
2 2095533 2017-10-15 05:19:32 LC81460412017288LGN00_MTL 0.0001 288 840538.454365 4.411500e+10 {'rings': [[[8754232.399300002, 3260266.637200...
3 2095534 2017-10-31 05:19:33 LC81460412017304LGN00_MTL 0.0335 304 840790.091989 4.414146e+10 {'rings': [[[8754361.912, 3260262.332699999], ...
4 2203649 2017-11-23 05:25:14 LC81470402017327LGN00_MTL 0.0333 327 852242.226027 4.535328e+10 {'rings': [[[8627133.4597, 3442780.260499999],...
5 2206118 2017-12-02 05:19:00 LC81460402017336LGN00_MTL 0.0015 336 851555.400431 4.528033e+10 {'rings': [[[8800038.6758, 3442628.6884000003]...
6 2211732 2017-12-09 05:25:11 LC81470402017343LGN00_MTL 0.0099 343 852179.154208 4.532813e+10 {'rings': [[[8626952.113400001, 3442914.852600...
7 2214288 2017-12-18 05:19:26 LC81460412017352LGN00_MTL 0.0030 352 840946.176659 4.415843e+10 {'rings': [[[8754656.32, 3260315.098700002], [...

Selecting imagery dated 15 October, 2017 from the collection using its OBJECTID.

In [9]:
delhi_image = landsat.filter_by('OBJECTID=2095521') # 2017-10-15 

Applying Natural color to verify the quality of image

In [10]:
apply(delhi_image, 'Natural Color with DRA')
Out[10]: