Python – Using Google Earth Engine with Folium and Sentinel-1 for Advanced Plotting

foliumgoogle-earth-engineplotpythonsentinel-1

I'm attempting to plot Google Earth Engine Sentinel-1 SAR data in a Jupyter notebook with Python and Folium. To do this I'm trying to combine two pieces of documentation:

What I've pieced together is currently freezing at the getMapId(vis_params) stage:

import ee
import folium
ee.Initialize()

# Load the Sentinel-1 ImageCollection
sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD')

               # Filter to get images with VV and VH dual polarization.
vh = (sentinel1.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
               .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
               # Filter to get images collected in interferometric wide swath mode.
               .filter(ee.Filter.eq('instrumentMode', 'IW')))

# Filter to get images from different look angles.
vhAscending = vh.filter(ee.Filter.eq('orbitProperties_pass', 'ASCENDING'))
vhDescending = vh.filter(ee.Filter.eq('orbitProperties_pass', 'DESCENDING'))

# Create a composite from means at different polarizations and look angles.
composite = ee.Image.cat([
  vhAscending.select('VH').mean(),
  ee.ImageCollection(vhAscending.select('VV').merge(vhDescending.select('VV'))).mean(),
  vhDescending.select('VH').mean()
]).focal_median()

# Display as a composite of polarization and backscattering characteristics.

# Define a method for displaying Earth Engine image tiles to folium map.
def add_ee_layer(self, ee_image_object, vis_params, name):
  map_id_dict = ee.Image(ee_image_object).getMapId(vis_params) # STUCK
  folium.raster_layers.TileLayer(
    tiles = map_id_dict['tile_fetcher'].url_format,
    attr = "Map Data © Google Earth Engine",
    name = name,
    overlay = True,
    control = True
  ).add_to(self)

# Add EE drawing method to folium.
folium.Map.add_ee_layer = add_ee_layer

# Fetch an elevation model.
dem = ee.Image('COPERNICUS/S1_GRD')

# Create a folium map object.
my_map = folium.Map(location=[20, 0], zoom_start=3, height=500)

# Add the elevation model to the map object.
my_map.add_ee_layer(composite, {'min': [-25, -20, -25], 'max': [0, 10, 0]}, 'composite')

# Add a layer control panel to the map.
my_map.add_child(folium.LayerControl())

# Display the map.
display(my_map)

Would anyone who has experience with this be able to point out what I'm doing wrong?

Best Answer

As noted, reducing the amount of data being called is probably a good idea. To reduce the area you can use a polygon or point geometry. A polygon would use the following:

    .filterBounds(ee.Geometry.Polygon([insert coordinate list here ]))

Documentation about how to fill that in can be found at https://developers.google.com/maps/documentation/javascript/shape Sub in ee.Geometry.Point(longitude, latitude) if you want to simply use a point.

To reduce date, you can use filterDate(), which takes ISO date strings 'year-mm-dd'

    .filterDate('ISO-date-stringStart', 'ISO-date-stringEnd')

To slightly speed up your code, you can also get rid of the filter for 'VV' data. Sentinel-1 only operates in cross-polarization mode when in dual-polarization mode with the like-polarized data, so all images with 'VH' data must have 'VV' data. Note that the reverse is not true as S1 sometimes operates in single-polarization modes.

Related Question