Raster Analytics
ArcGIS Enterprise at 10.5 provides you with the ability to perform large raster analysis using distributed computing. This capability is provided in the arcgis.raster.analytics
module and includes functionality to summarize data, analyze patterns, images, terrain and manage data. This sample show the capabilities of imagery layers and raster analytics.
Imagery layers
import arcgis
from arcgis.gis import GIS
from IPython.display import display
gis = GIS(profile="your_enterprise_profile")
Here we're getting the multispectral landsat imagery item:
imglyr = arcgis.raster.ImageryLayer('https://landsat2.arcgis.com/arcgis/rest/services/Landsat8_Views/ImageServer')
imglyr
The code below cycles through and lists the Raster Functions published with the imglyr
:
for fn in imglyr.properties['rasterFunctionInfos']:
print (fn['name'])
Agriculture with DRA Bathymetric with DRA Color Infrared with DRA Geology with DRA Natural Color with DRA Short-wave Infrared with DRA Agriculture Bathymetric Color Infrared Geology Natural Color Short-wave Infrared NDVI Colorized Normalized Difference Moisture Index Colorized NDVI Raw NBR Raw Band 10 Surface Temperature in Fahrenheit Band 11 Surface Temperature in Fahrenheit Band 10 Surface Temperature in Celsius Band 11 Surface Temperature in Celsius None
Let us create a map widget and load this layer
marthasbasin = arcgis.geocoding.geocode("Marthas Basin, Montana")[0]
map1 = gis.map(marthasbasin, zoomlevel=12)
map1
map1.add_layer(imglyr)
The utility of raster functions is better seen when we interactively cycle through these raster functions and apply them to the map. The code below cycles through the first 6 raster functions stored with the Imagery Layer and a small time delay to illustrate. The image processing occurs on-the-fly at display resolution to show how the layer can be visualized using these different raster functions published with the layer.
import time
from arcgis.raster.functions import apply
for fn in imglyr.properties['rasterFunctionInfos'][:6]:
print(fn['name'])
map1.remove_layers()
map1.add_layer(apply(imglyr, fn['name']))
time.sleep(4)
Agriculture with DRA Bathymetric with DRA Color Infrared with DRA Geology with DRA Natural Color with DRA Short-wave Infrared with DRA
Raster functions
Developers can create their own raster functions, by chaining different raster functions. For instance, the code below is doing an Extract Band and extracting out the [4,5,3] band combination, and applying a Stretch to get the land-water boundary visualization that makes it easy to see where land is and where water is. Its worth noting that the raster function is applied at display resolution and only for the visible extent using on the fly image processing.
from arcgis.raster.functions import stretch, extract_band
def process_bands(layer, bands):
return stretch(extract_band(layer, bands),
stretch_type='percentclip', min_percent=0.1, max_percent=0.1, gamma=[1, 1, 1], dra=True)
Let us apply this raster function to the image layer to visualize the results.
map2 = gis.map(marthasbasin, zoomlevel=12)
map2
map2.add_layer(process_bands(imglyr, [4, 5, 3]))
Creating a Raster Information Product using Landsat 8 imagery
This part of the notebook shows how Raster Analytics (in ArcGIS Enterprise 10.5) can be used to generate a raster information product, by applying the same raster function across the extent of an image service on the portal. The raster function is applied at source resolution and creates an Information Product, that can be used for further analysis and visualization.
montana_landsat = gis.content.get('09a4edaefae74ec6a2cb114f155091e3')
montana_landsat
In the code below, we use extract and stretch the [7, 5, 2] band combination. This improves visibility of fire and burn scars by pushing further into the SWIR range of the electromagnetic spectrum, as there is less susceptibility to smoke and haze generated by a burning fire.
montana_lyr = montana_landsat.layers[0]
fire_viz = process_bands(montana_lyr, [7, 5, 2])
fire_viz
We can use the save
method to apply the raster function across the entire extext of the input image layer at source resolution, and presist the result in an output image layer. This creates a raster product similar that can be used for further analysis and visualization.
arcgis.env.verbose = True
from datetime import datetime as dt
montana_fires_lyr = fire_viz.save('Montana_Burn_scars'+str(dt.now().microsecond))
Submitted. Executing... Start Time: Tuesday, August 8, 2023 9:07:32 AM Raster Analytics helper service: https://pythonapi.playground.esri.com/ra Running on ArcGIS Image Server. Image service {'name': 'Montana_Burn_scars189998', 'serviceUrl': 'https://pythonapi.playground.esri.com/ra/rest/services/Hosted/Montana_Burn_scars189998/ImageServer'} already existed. Output item id is: c9d5f6fed85445909b05079ceb2ab830 Output image service url is: https://pythonapi.playground.esri.com/ra/rest/services/Hosted/Montana_Burn_scars189998/ImageServer Output cloud raster name is: Hosted_Montana_Burn_scars189998.crf {"rasterFunction": "Stretch", "rasterFunctionArguments": {"Raster": {"rasterFunction": "ExtractBand", "rasterFunctionArguments": {"Raster": "https://pythonapi.playground.esri.com/server/rest/services/ImgSrv_Landsat_Montana_2015/ImageServer?token=SSec3-zNyNZ5RaQLxr1tssCr8mSw4RURxAjnP5oFmx7NCnWyrT6jGXxzcSdEfYdCeSYwS8BY52kdikDpz9bV2OegjVeMr_Ur9PMFL3LsOXsf6zoX4zVgxKBo1mMa6efpd9h87wdO-iNluoxXDkqpn7BqgAofkiyC3ZG6l87paAIlM523_XbBTT1Jo81lReklZS2MADUTpJEv8Ywow_WAA-SIcntgSFdz77csXtTNwD4.", "BandIDs": [6, 4, 1]}, "variableName": "Raster"}, "StretchType": 6, "DRA": true, "MinPercent": 0.1, "MaxPercent": 0.1, "Gamma": [1, 1, 1], "UseGamma": true}, "variableName": "Raster"} Hosted_Montana_Burn_scars189998.crf Updating service with data store URI. Getting image service info... Updating service: https://pythonapi.playground.esri.com/ra/admin/services/Hosted/Montana_Burn_scars189998.ImageServer/edit Update item service: https://pythonapi.playground.esri.com/ra/admin/services/Hosted/Montana_Burn_scars189998.ImageServer successfully. Portal item refreshed. Succeeded at Tuesday, August 8, 2023 9:07:44 AM (Elapsed Time: 11.26 seconds) GenerateRaster GP Job: jd9dbf5e8e48d47b4a5e6a69956f71f73 finished successfully.
montana_fires_lyr
base_map = gis.map(marthasbasin, 12)
natural_color_map = gis.map(marthasbasin, 12)
natural_color_map.add_layer(montana_landsat)
false_color_map = gis.map(marthasbasin, 12)
false_color_map.add_layer(montana_fires_lyr)
We can compare the natural color and false color images uaing a tabbed widget.
In the false color image the red and brownish pixels correspond to burn scars of the fire:
import ipywidgets as widgets
tab = widgets.Tab([base_map, natural_color_map, false_color_map])
tab.set_title(0, 'Basemap')
tab.set_title(1, 'Natural Color')
tab.set_title(2, 'False Color')
tab
Thus using the same raster function, we were able to both visualize on the fly and derive a persisted image service using distributed raster analysis.