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:
- EE Python Install -> Map Visualization -> Interactive Map
- Sentinel-1 Algorithms -> Metadata and Filtering (JavaScript)
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:
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'
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.