0

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?

2

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.

| improve this answer | |
  • Thanks! Beginner question if you have the time: I'm not sure if I understand the date ranges. If I put a start/end date range for the SAR imagery, then what actually gets displayed? Averaged values over the specified period? – Austin Feb 17 at 18:09
  • 1
    Just visualizing an image collection without any additional parameters will display one image from the collection. You can specify if you want the first image by using .first() or it will default to the last in the list (by default, chronological order), or you can use .sort() to choose some other argument to sort by. If you want an average values over the specified period, you can use a reducer: .reducer(ee.Reducer.mean()) – Masjo Feb 18 at 13:32
2

I think your request is simply too large for an interactive session in Python or the JS Code Editor. You may need to do this as a batch task - export the result as an asset and when it completes, import it and then explore it.

Additionally, you may want to break up the analysis by region and date range to make the computation and interpretation of the result more manageable. Also, .focal_median is likely going to be a computationally expensive operation globally. You may have better success using .resample() with 'bilinear' or 'bicubic'.

| improve this answer | |
  • Thanks for your answer. Would you happen to know how I can further specify lat/lon min/max bounds and date ranges to reduce the size of my request? I actually only need a small region for a two week period, but didn't know how to specify this. – Austin Feb 13 at 0:44
1

I have a script working with this content.

DV-COPERNICUS/SENTINAL-1

the city of SF, Ca USA

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# enable debugging
import cgitb
cgitb.enable()
import cgi

import ee; ee.Initialize()
import folium
import geehydro

## Create an interactive map 

Map = folium.Map(location=[40, -100], zoom_start=4)
Map.setOptions('HYBRID')

# %%
'''
## Add Earth Engine Python script 

'''

# %%
# Load the Sentinel-1 ImageCollection.
sentinel1 = ee.ImageCollection('COPERNICUS/S1_GRD') \
    .filterBounds(ee.Geometry.Point(-122.37383, 37.6193))

# Filter by metadata properties.
vh = sentinel1 \
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV')) \
  .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH')) \
  .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.
Map.setCenter(-122.37383, 37.6193, 10)
Map.addLayer(composite, {'min': [-25, -20, -25], 'max': [0, 10, 0]}, 'composite')


# %%
'''
## Display Earth Engine data layers 

'''

# %%
Map.setControlVisibility(layerControl=True, fullscreenControl=True, latLngPopup=True)
Map
outHtml = '/var/www/map2.html' # temporary file path, change if needed
Map.save(outHtml)
###


#html in python
print ('''Content-Type: text/html''') # HTML is following print 
print #12 returns in the next bracket
print ('''
<html><head>
  <title>J^2</title>
  <meta name="description" content="=100jay" />
  <meta name="keywords" content="Music, Art, Forum" />
  <meta http-equiv="content-type" content="text/html" />
  <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
body {background: #1339de;}
div#container
{        background: black;
 width: 50%;
  margin: 100px auto;
        color: white;
        border-radius: 1em;
        width: 1400px;
    height: 1000px;
    overflow:hidden;     /* if you don't want a scrollbar, set to hidden */
    overflow-x:hidden;   /* hides horizontal scrollbar on newer browsers */
    /* resize and min-height are optional, allows user to resize viewable area */
    -webkit-resize:vertical;
    -moz-resize:vertical;
    resize:vertical;
 //   min-height:1600px;
}
iframe#embed
{
    width:1400px;       /* set this to approximate width of entire page you're embedding */
    height:1200px;      /* determines where the bottom of the page cuts off */
    margin-left:0px; /* clipping left side of page */
    margin-top:0px;  /* clipping top of page */
    overflow:hidden;
    /* resize seems to inherit in at least Firefox */
    -webkit-resize:none;
    -moz-resize:none;
    resize:none;
}
</style>
<body>
  <div id="main">
    <div id="site_content">
      <div id="content">
        <h1>Google Earth Engine with Folium</h1>''')


print ('''<section>
<div id="container">
<iframe id="embed" scrolling="no" src="/map2.html"></iframe>
</div>
</section>
</div></div></div>''')
gis
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.