So I was using Google Earth Engine and working through some of the example code in their repo. I am using Python 3.6. Looks like Google will not support the mapping functionality in Python 3 through their ee.mapclient()
anymore. I was wondering if anyone has found a suitable workaround? Let me outline the problem.
I tried to load the ee.mapclient
to plot a map.
import ee
import ee.mapclient
ee.Initialize()
But I got an error:
ModuleNotFoundError Traceback (most recent call last)
<ipython-input-13-6d4860410653> in <module>()
1 import ee
----> 2 import ee.mapclient
3 ee.Initialize()
/media/krishnab/lakshmi/anaconda3/envs/pMining/lib/python3.6/site-packages/ee/mapclient.py in <module>()
29
30 import collections
---> 31 import cStringIO
32 import functools
33 import math
ModuleNotFoundError: No module named 'cStringIO'
The cStringIO
problem is easy enough to resolve as per:
python 3.4.0 email package install: ImportError: No module named 'cStringIO'
So I went to post an issue on the Google Earth Engine Repo, but found a preexisting issue:
https://github.com/google/earthengine-api/issues/16
In the issue the developers acknowledge the problem, but indicate that they will not fix it due to limitations with the underlying Tk
package.
Here is a quote from the issue:
We have not been actively maintaining the mapclient object, because it depends on Tk, a graphical user interface toolkit, which behaves differently on different machines. Could you describe your use case that requires mapclient? We may be able to suggest an alternative approach.
The google developers offered to submit a workaround, but so far no workaround has been posted.
Hence, I was wondering if anyone else had found a suitable workaround in Python3.6 for this problem?
By way of a genuine code example, I can offer the code below from the Google examples repo:
import datetime
import ee
import ee.mapclient
ee.Initialize()
ee.mapclient.centerMap(-95.738, 18.453, 9)
# Filter the LE7 collection to a single date.
collection = (ee.ImageCollection('LE7_L1T')
.filterDate(datetime.datetime(2002, 11, 8),
datetime.datetime(2002, 11, 9)))
image = collection.mosaic().select('B3', 'B2', 'B1')
# Display the image normally.
ee.mapclient.addToMap(image, {'gain': '1.6, 1.4, 1.1'}, 'Land')
# Add and stretch the water. Once where the elevation is masked,
# and again where the elevation is zero.
elev = ee.Image('srtm90_v4')
mask1 = elev.mask().eq(0).And(image.mask())
mask2 = elev.eq(0).And(image.mask())
ee.mapclient.addToMap(
image.mask(mask1), {'gain': 6.0, 'bias': -200}, 'Water: Masked')
ee.mapclient.addToMap(
image.mask(mask2), {'gain': 6.0, 'bias': -200}, 'Water: Elev 0')
In addition to the web-based IDE Google Earth Engine also provides a Python API that can be used on your local machine without the need to utilize a browser, although the capabilities of this API are reduced compared to the Code Editor/IDE.
The Earth Engine API is available in Python and JavaScript, making it easy to harness the power of Google's cloud for your own geospatial analysis.
The Google Earth Engine uses the programming language JavaScript. Similarly to other programming languages, there is support online - you can google JavaScript and Earth Engine tutorials.
Not sure if there is still an issue with import ee.mapclient in Python 3 but here is a work around using the folium package that can have similar methods to the ee.mapclient. However, this was will render the result in your web browser and not as a popup window (unless using a Jupyter notebook, then you can just call the folium map object to render).
import ee
import folium
import datetime
import webbrowser
ee.Initialize()
class eeMapHack(object):
def __init__(self,center=[0, 0],zoom=3):
self._map = folium.Map(location=center,zoom_start=zoom)
return
def addToMap(self,img,vizParams,name):
map_id = ee.Image(img.visualize(**vizParams)).getMapId()
tile_url_template = "https://earthengine.googleapis.com/map/{mapid}/{{z}}/{{x}}/{{y}}?token={token}"
mapurl = tile_url_template.format(**map_id)
folium.WmsTileLayer(mapurl,name=name).add_to(self._map)
return
def addLayerControl(self):
self._map.add_child(folium.map.LayerControl())
return
# initialize map object
eeMap = eeMapHack(center=[18.453,-95.738],zoom=9)
# Filter the LE7 collection to a single date.
collection = (ee.ImageCollection('LE7_L1T')
.filterDate(datetime.datetime(2002, 11, 8),
datetime.datetime(2002, 11, 9)))
image = collection.mosaic().select('B3', 'B2', 'B1')
eeMap.addToMap(image, {'gain': '1.6, 1.4, 1.1'}, 'Land')
# Add and stretch the water. Once where the elevation is masked,
# and again where the elevation is zero.
elev = ee.Image('srtm90_v4')
mask1 = elev.mask().eq(0).And(image.mask())
mask2 = elev.eq(0).And(image.mask())
eeMap.addToMap(image.mask(mask1), {'gain': 6.0, 'bias': -200}, 'Water: Masked')
eeMap.addToMap(image.mask(mask2), {'gain': 6.0, 'bias': -200}, 'Water: Elev 0')
# add layer control to map
eeMap.addLayerControl()
outHtml = 'map.html' # temporary file path, change if needed
eeMap._map.save(outHtml)
webbrowser.open('file://'+outHtml)
You should get an interactive web map in your browser with your analysis results that looks like this:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With