geemap - A Python package for interactive mapping with Google Earth Engine, ipyleaflet, and ipywidgets.

Overview

geemap

https://pepy.tech/badge/geemap https://img.shields.io/badge/YouTube-Channel-red https://img.shields.io/lgtm/grade/python/g/giswqs/geemap.svg?logo=lgtm&logoWidth=18 https://img.shields.io/twitter/follow/giswqs?style=social

A Python package for interactive mapping with Google Earth Engine, ipyleaflet, and ipywidgets.

Contents

Introduction

geemap is a Python package for interactive mapping with Google Earth Engine (GEE), which is a cloud computing platform with a multi-petabyte catalog of satellite imagery and geospatial datasets. During the past few years, GEE has become very popular in the geospatial community and it has empowered numerous environmental applications at local, regional, and global scales. GEE provides both JavaScript and Python APIs for making computational requests to the Earth Engine servers. Compared with the comprehensive documentation and interactive IDE (i.e., GEE JavaScript Code Editor) of the GEE JavaScript API, the GEE Python API has relatively little documentation and limited functionality for visualizing results interactively. The geemap Python package was created to fill this gap. It is built upon ipyleaflet and ipywidgets, and enables users to analyze and visualize Earth Engine datasets interactively within a Jupyter-based environment.

geemap is intended for students and researchers, who would like to utilize the Python ecosystem of diverse libraries and tools to explore Google Earth Engine. It is also designed for existing GEE users who would like to transition from the GEE JavaScript API to Python API. The automated JavaScript-to-Python conversion module of the geemap package can greatly reduce the time needed to convert existing GEE JavaScripts to Python scripts and Jupyter notebooks.

For video tutorials and notebook examples, please visit https://github.com/giswqs/geemap/tree/master/examples. For complete documentation on geemap modules and methods, please visit https://geemap.org/geemap.

If you find geemap useful in your research, please consider citing the following papers to support my work. Thank you for your support.

  • Wu, Q., (2020). geemap: A Python package for interactive mapping with Google Earth Engine. The Journal of Open Source Software, 5(51), 2305. https://doi.org/10.21105/joss.02305
  • Wu, Q., Lane, C. R., Li, X., Zhao, K., Zhou, Y., Clinton, N., DeVries, B., Golden, H. E., & Lang, M. W. (2019). Integrating LiDAR data and multi-temporal aerial imagery to map wetland inundation dynamics using Google Earth Engine. Remote Sensing of Environment, 228, 1-13. https://doi.org/10.1016/j.rse.2019.04.015 (pdf | source code)

Features

Below is a partial list of features available for the geemap package. Please check the examples page for notebook examples, GIF animations, and video tutorials.

  • Convert Earth Engine JavaScripts to Python scripts and Jupyter notebooks.
  • Display Earth Engine data layers for interactive mapping.
  • Support Earth Engine JavaScript API-styled functions in Python, such as Map.addLayer(), Map.setCenter(), Map.centerObject(), Map.setOptions().
  • Create split-panel maps with Earth Engine data.
  • Retrieve Earth Engine data interactively using the Inspector Tool.
  • Interactive plotting of Earth Engine data by simply clicking on the map.
  • Convert data format between GeoJSON and Earth Engine.
  • Use drawing tools to interact with Earth Engine data.
  • Use shapefiles with Earth Engine without having to upload data to one's GEE account.
  • Export Earth Engine FeatureCollection to other formats (i.e., shp, csv, json, kml, kmz).
  • Export Earth Engine Image and ImageCollection as GeoTIFF.
  • Extract pixels from an Earth Engine Image into a 3D numpy array.
  • Calculate zonal statistics by group.
  • Add a customized legend for Earth Engine data.
  • Convert Earth Engine JavaScripts to Python code directly within Jupyter notebook.
  • Add animated text to GIF images generated from Earth Engine data.
  • Add colorbar and images to GIF animations generated from Earth Engine data.
  • Create Landsat timelapse animations with animated text using Earth Engine.
  • Search places and datasets from Earth Engine Data Catalog.
  • Use timeseries inspector to visualize landscape changes over time.
  • Export Earth Engine maps as HTML files and PNG images.
  • Search Earth Engine API documentation within Jupyter notebooks.
  • Import Earth Engine assets from personal account.
  • Publish interactive GEE maps directly within Jupyter notebook.
  • Add local raster datasets (e.g., GeoTIFF) to the map.
  • Perform image classification and accuracy assessment.
  • Extract pixel values interactively and export as shapefile and csv.

Installation

To use geemap, you must first sign up for a Google Earth Engine account.

https://i.imgur.com/ng0FzUT.png

geemap is available on PyPI. To install geemap, run this command in your terminal:

pip install geemap

geemap is also available on conda-forge. If you have Anaconda or Miniconda installed on your computer, you can create a conda Python environment to install geemap:

conda create -n gee python
conda activate gee
conda install mamba -c conda-forge
mamba install geemap -c conda-forge

Optionally, you can install Jupyter notebook extensions, which can improve your productivity in the notebook environment. Some useful extensions include Table of Contents, Gist-it, Autopep8, Variable Inspector, etc. See this post for more information.

mamba install jupyter_contrib_nbextensions -c conda-forge

If you have installed geemap before and want to upgrade to the latest version, you can run the following command in your terminal:

pip install -U geemap

If you use conda, you can update geemap to the latest version by running the following command in your terminal:

mamba update -c conda-forge geemap

To install the development version from GitHub using Git, run the following command in your terminal:

pip install git+https://github.com/giswqs/geemap

To install the development version from GitHub directly within Jupyter notebook without using Git, run the following code:

import geemap
geemap.update_package()

To use geemap in a Docker container, check out the following docker containers with geemap installed.

To use geemap in a Docker container, check out ee-jupyter-contrib or this page.

Usage

Important note: A key difference between ipyleaflet and folium is that ipyleaflet is built upon ipywidgets and allows bidirectional communication between the front-end and the backend enabling the use of the map to capture user input, while folium is meant for displaying static data only (source). Note that Google Colab currently does not support ipyleaflet (source). Therefore, if you are using geemap with Google Colab, you should use import geemap.eefolium. If you are using geemap with binder or a local Jupyter notebook server, you can use import geemap, which provides more functionalities for capturing user input (e.g., mouse-clicking and moving).

More GEE Tutorials are available on my YouTube channel.

YouTube

To create an ipyleaflet-based interactive map:

import geemap
Map = geemap.Map(center=[40,-100], zoom=4)
Map

To create a folium-based interactive map:

import geemap.eefolium as geemap
Map = geemap.Map(center=[40,-100], zoom=4)
Map

To add an Earth Engine data layer to the Map:

Map.addLayer(ee_object, vis_params, name, shown, opacity)

To center the map view at a given coordinates with the given zoom level:

Map.setCenter(lon, lat, zoom)

To center the map view around an Earth Engine object:

Map.centerObject(ee_object, zoom)

To add LayerControl to a folium-based Map:

Map.addLayerControl()

To add a minimap (overview) to an ipyleaflet-based Map:

Map.add_minimap()

To add additional basemaps to the Map:

Map.add_basemap('Esri Ocean')
Map.add_basemap('Esri National Geographic')

To add an XYZ tile layer to the Map:

url = 'https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}'
Map.add_tile_layer(url, name='Google Map', attribution='Google')

To add a WMS layer to the Map:

naip_url = 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer?'
Map.add_wms_layer(url=naip_url, layers='0', name='NAIP Imagery', format='image/png', shown=True)

To convert a shapefile to Earth Engine object and add it to the Map:

ee_object = geemap.shp_to_ee(shp_file_path)
Map.addLayer(ee_object, {}, 'Layer name')

To convert a GeoJSON file to Earth Engine object and add it to the Map:

ee_object = geemap.geojson_to_ee(geojson_file_path)
Map.addLayer(ee_object, {}, 'Layer name')

To download an ee.FeatureCollection as a shapefile:

geemap.ee_to_csv(ee_object, filename, selectors)

To export an ee.FeatureCollection to other formats, including shp, csv, json, kml, and kmz:

geemap.ee_export_vector(ee_object, filename, selectors)

To export an ee.Image as a GeoTIFF file:

geemap.ee_export_image(ee_object, filename, scale, crs, region, file_per_band)

To export an ee.ImageCollection as GeoTIFF files:

geemap.ee_export_image_collection(ee_object, output, scale, crs, region, file_per_band)

To extract pixels from an ee.Image into a 3D numpy array:

geemap.ee_to_numpy(ee_object, bands, region, properties, default_value)

To import a 2D or 3D numpy array to an ee.Image using a given base coordinate reference system (crs) and transform between projected coordinates and the base:

geemap.numpy_to_ee(np_array, crs, transform, transformWkt, band_names)

To import one or more variables from a netCDF file with a regular grid in EPSG:4326 to an ee.Image:

geemap.netcdf_to_ee(nc_file, var_names, band_names, lon='lon', lat='lat')

To calculate zonal statistics:

geemap.zonal_statistics(in_value_raster, in_zone_vector, out_file_path, statistics_type='MEAN')

To calculate zonal statistics by group:

geemap.zonal_statistics_by_group(in_value_raster, in_zone_vector, out_file_path, statistics_type='SUM')

To create a split-panel Map:

Map.split_map(left_layer='HYBRID', right_layer='ESRI')

To add a marker cluster to the Map:

Map.marker_cluster()
feature_collection = ee.FeatureCollection(Map.ee_markers)

To add a customized legend to the Map:

legend_dict = {
    'one': (0, 0, 0),
    'two': (255,255,0),
    'three': (127, 0, 127)
}
Map.add_legend(legend_title='Legend', legend_dict=legend_dict, position='bottomright')
Map.add_legend(builtin_legend='NLCD')

To download a GIF from an Earth Engine ImageCollection:

geemap.download_ee_video(tempCol, videoArgs, saved_gif)

To add animated text to an existing GIF image:

geemap.add_text_to_gif(in_gif, out_gif, xy=('5%', '5%'), text_sequence=1984, font_size=30, font_color='#0000ff', duration=100)

To create a colorbar for an Earth Engine image:

palette = ['blue', 'purple', 'cyan', 'green', 'yellow', 'red']
create_colorbar(width=250, height=30, palette=palette, vertical=False,add_labels=True, font_size=20, labels=[-40, 35])

To create a Landsat timelapse animation and add it to the Map:

Map.add_landsat_ts_gif(label='Place name', start_year=1985, bands=['NIR', 'Red', 'Green'], frames_per_second=5)

To convert all GEE JavaScripts in a folder recursively to Python scripts:

from geemap.conversion import *
js_to_python_dir(in_dir, out_dir)

To convert all GEE Python scripts in a folder recursively to Jupyter notebooks:

from geemap.conversion import *
template_file = get_nb_template()
py_to_ipynb_dir(in_dir, template_file, out_dir)

To execute all Jupyter notebooks in a folder recursively and save output cells:

from geemap.conversion import *
execute_notebook_dir(in_dir)

To search Earth Engine API documentation with Jupyter notebooks:

import geemap
geemap.ee_search()

To publish an interactive GEE map with Jupyter notebooks:

Map.publish(name, headline, visibility)

To add a local raster dataset to the map:

Map.add_raster(image, bands, colormap, layer_name)

To get image basic properties:

geemap.image_props(image).getInfo()

To get image descriptive statistics:

geemap.image_stats(image, region, scale)

To remove all user-drawn geometries:

geemap.remove_drawn_features()

To extract pixel values based on user-drawn geometries:

geemap.extract_values_to_points(out_shp)

To load a Cloud Optimized GeoTIFF as an ee.Image:

image = geemap.load_GeoTIFF(URL)

To load a list of Cloud Optimized GeoTIFFs as an ee.ImageCollection:

collection = geemap.load_GeoTIFFs(URLs)

Examples

The following examples require the geemap package, which can be installed using pip install geemap. Check the Installation section for more information. More examples can be found at another repo: A collection of 300+ Jupyter Python notebook examples for using Google Earth Engine with interactive mapping.

Converting GEE JavaScripts to Python scripts and Jupyter notebooks

Launch an interactive notebook with Google Colab. Keep in mind that the conversion might not always work perfectly. Additional manual changes might still be needed. ui and chart are not supported. The source code for this automated conversion module can be found at conversion.py.

import os
from geemap.conversion import *

# Create a temporary working directory
work_dir = os.path.join(os.path.expanduser('~'), 'geemap')
# Get Earth Engine JavaScript examples. There are five examples in the geemap package folder.
# Change js_dir to your own folder containing your Earth Engine JavaScripts, such as js_dir = '/path/to/your/js/folder'
js_dir = get_js_examples(out_dir=work_dir)

# Convert all Earth Engine JavaScripts in a folder recursively to Python scripts.
js_to_python_dir(in_dir=js_dir, out_dir=js_dir, use_qgis=True)
print("Python scripts saved at: {}".format(js_dir))

# Convert all Earth Engine Python scripts in a folder recursively to Jupyter notebooks.
nb_template = get_nb_template()  # Get the notebook template from the package folder.
py_to_ipynb_dir(js_dir, nb_template)

# Execute all Jupyter notebooks in a folder recursively and save the output cells.
execute_notebook_dir(in_dir=js_dir)

https://i.imgur.com/8bedWtl.gif

Interactive mapping using GEE Python API and geemap

Launch an interactive notebook with Google Colab. Note that Google Colab currently does not support ipyleaflet. Therefore, you should use import geemap.eefolium instead of import geemap.

# Installs geemap package
import subprocess

try:
        import geemap
except ImportError:
        print('geemap package not installed. Installing ...')
        subprocess.check_call(["python", '-m', 'pip', 'install', 'geemap'])

# Checks whether this notebook is running on Google Colab
try:
        import google.colab
        import geemap.eefolium as emap
except:
        import geemap as emap

# Authenticates and initializes Earth Engine
import ee

try:
        ee.Initialize()
except Exception as e:
        ee.Authenticate()
        ee.Initialize()

# Creates an interactive map
Map = emap.Map(center=[40,-100], zoom=4)

# Adds Earth Engine dataset
image = ee.Image('USGS/SRTMGL1_003')

# Sets visualization parameters.
vis_params = {
        'min': 0,
        'max': 4000,
        'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5']}

# Prints the elevation of Mount Everest.
xy = ee.Geometry.Point([86.9250, 27.9881])
elev = image.sample(xy, 30).first().get('elevation').getInfo()
print('Mount Everest elevation (m):', elev)

# Adds Earth Engine layers to Map
Map.addLayer(image, vis_params, 'SRTM DEM', True, 0.5)
Map.addLayer(xy, {'color': 'red'}, 'Mount Everest')
Map.setCenter(100, 40, 4)
# Map.centerObject(xy, 13)

# Display the Map
Map.addLayerControl()
Map

https://i.imgur.com/7NMQw6I.gif

Dependencies

Contributing

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

You can contribute in many ways:

Report Bugs

Report bugs at https://github.com/giswqs/geemap/issues.

If you are reporting a bug, please include:

  • Your operating system name and version.
  • Any details about your local setup that might be helpful in troubleshooting.
  • Detailed steps to reproduce the bug.

Fix Bugs

Look through the GitHub issues for bugs. Anything tagged with "bug" and "help wanted" is open to whoever wants to implement it.

Implement Features

Look through the GitHub issues for features. Anything tagged with "enhancement" and "help wanted" is open to whoever wants to implement it.

Write Documentation

geemap could always use more documentation, whether as part of the official geemap docs, in docstrings, or even on the web in blog posts, articles, and such.

Submit Feedback

The best way to send feedback is to file an issue at https://github.com/giswqs/geemap/issues.

If you are proposing a feature:

  • Explain in detail how it would work.
  • Keep the scope as narrow as possible, to make it easier to implement.
  • Remember that this is a volunteer-driven project, and that contributions are welcome :)

Get Started!

Ready to contribute? Here's how to set up geemap for local development.

  1. Fork the geemap repo on GitHub.

  2. Clone your fork locally:

    $ git clone [email protected]:your_name_here/geemap.git
    
  3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:

    $ mkvirtualenv geemap
    $ cd geemap/
    $ python setup.py develop
    
  4. Create a branch for local development:

    $ git checkout -b name-of-your-bugfix-or-feature
    

    Now you can make your changes locally.

  5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:

    $ flake8 geemap tests
    $ python setup.py test or pytest
    $ tox
    

    To get flake8 and tox, just pip install them into your virtualenv.

  6. Commit your changes and push your branch to GitHub:

    $ git add .
    $ git commit -m "Your detailed description of your changes."
    $ git push origin name-of-your-bugfix-or-feature
    
  7. Submit a pull request through the GitHub website.

Pull Request Guidelines

Before you submit a pull request, check that it meets these guidelines:

  1. The pull request should include tests.
  2. If the pull request adds functionality, the docs should be updated. Put your new functionality into a function with a docstring, and add the feature to the list in README.rst.
  3. The pull request should work for Python 3.6, 3.7 and 3.8, and for PyPy. Check https://travis-ci.com/giswqs/geemap/pull_requests and make sure that the tests pass for all supported Python versions.

Tips

To run a subset of tests:

$ python -m unittest tests.test_geemap

Deploying

A reminder for the maintainers on how to deploy. Make sure all your changes are committed (including an entry in HISTORY.rst). Then run:

$ bump2version patch # possible: major / minor / patch
$ git push
$ git push --tags

Travis will then deploy to PyPI if tests pass.

References

To support my work, please consider citing the following articles:

  • Wu, Q., (2020). geemap: A Python package for interactive mapping with Google Earth Engine. The Journal of Open Source Software, 5(51), 2305. https://doi.org/10.21105/joss.02305
  • Wu, Q., Lane, C. R., Li, X., Zhao, K., Zhou, Y., Clinton, N., DeVries, B., Golden, H. E., & Lang, M. W. (2019). Integrating LiDAR data and multi-temporal aerial imagery to map wetland inundation dynamics using Google Earth Engine. Remote Sensing of Environment, 228, 1-13. https://doi.org/10.1016/j.rse.2019.04.015 (pdf | source code)

Credits

This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.

Comments
  • Map does not display in jupyterlab,

    Map does not display in jupyterlab, "Loading widget..." or "Error displaying widget: model not found"

    I am betting this is rather an ipyleaflet plus jupyter-lab issue, but I open this ticket hoping to provide workarounds/fixes for other users as this may be one of the first experience (i.e. impression) for newcomers.

    • geemap version: 0.6.10 from conda-forge
    • Python version: 3.8.2
    • Operating System: Linux 4.19.0-8-amd64 #1 SMP Debian 4.19.98-1+deb10u1 (2020-04-27) x86_64 GNU/Linux

    Description

    example notebook 01_geemap_intro Map does not display in the cell output in jupyterlab, instead "Loading widget..." or "Error displaying widget: model not found" Display works if accessed/run from jupyter-notebook however. I think I previously similar symptoms with upyleaflet

    What I Did

    Updated an existing conda env which had ipyleaflet working. conda update -c conda-forge python=3.8, then conda install -c conda-forge geemap

    jupyter-lab opened and requested a rebuild of the extensions:

    [W 12:30:43.793 LabApp] Build recommended
    [W 12:30:43.793 LabApp] jupyter-leaflet needs to be included in build
    [W 12:30:43.793 LabApp] @jupyter-widgets/jupyterlab-manager needs to be included in build
    

    Once done, Map resulted in "Loading widget..." , but I think this was because I should have restarted jupyter-lab. Using the script

    #!/bin/bash
    source ${HOME}/anaconda3/bin/activate sv
    jupyter-nbextension list
    cd ${HOME}/src/github/geemap
    jupyter-lab --browser=/usr/bin/google-chrome
    
    Known nbextensions:
      config dir: /home/xxxyyy/anaconda3/envs/sv/etc/jupyter/nbconfig
        notebook section
          bqplot/extension  enabled 
          - Validating: OK
          jupyter-leaflet/extension  enabled 
          - Validating: OK
          jupyter-js-widgets/extension  enabled 
          - Validating: OK
      config dir: /etc/jupyter/nbconfig
        notebook section
          jupyter-js-widgets/extension  enabled 
          - Validating: OK
    

    but upon re-execution of the notebook 01_geemap_intro Map then leads to "Error displaying widget: model not found"

    good solution 
    opened by jmp75 24
  • substring not found - Search and Import GEE data

    substring not found - Search and Import GEE data

    This happened when I was trying to use the search and import data button. Can you kindly help? Many thanks, Daniel

    substring not found

    TypeError Traceback (most recent call last) e:\dropbox\py\projects\spatial\spatialvenv\lib\site-packages\geemap\geemap.py in search_box_callback(text) 357 ee_assets = search_ee_data(text.value) 358 self.search_datasets = ee_assets --> 359 asset_titles = [x["title"] for x in ee_assets] 360 assets_dropdown.options = asset_titles 361 search_output.clear_output()

    TypeError: 'NoneType' object is not iterable

    image

    bug 
    opened by Daniel-Trung-Nguyen 19
  • geemap installation issue

    geemap installation issue

    • geemap version:
    • Python version:
    • Operating System:

    Description

    I have followed the steps on the video 8 about conversion from earth engine to jupyter notebook after the conversion done I open the script but the notebook can't run I got this message: A connection to the notebook server could not be established. The notebook will continue trying to reconnect. Check your network connection or notebook server configuration

    What I Did

    Paste the command(s) you ran and the output.
    If there was a crash, please include the traceback here.
    
    opened by alabbaci 19
  • issue in Map.add_raster function

    issue in Map.add_raster function

    • geemap version: 0.8.4
    • Python version: 3.8.6
    • Operating System: Window 10 Pro

    Description

    When I tried to run tutorial 25_load_rasters, this line of code `Map.add_raster(landsat, bands=[5,4,3], layer_name='Landsat') raised an TypeError, as detailed below.

    image where da = rioxarray.open_rasterio(image, masked=True)

    What I Did

    This tutorial ipynb file is intact, and I haven't edited it. According to the error message, the 'rgb_dim' parameter is not expected in da.leaflet.plot function and should be deleted. Is this bug caused by the updated dependency of rioxarray (version 0.1.1 in my case)?

    Paste the command(s) you ran and the output.
    If there was a crash, please include the traceback here.
    
    bug 
    opened by NickCarraway96 18
  • Impossible to display a raster .tiff file on the map

    Impossible to display a raster .tiff file on the map

    setup

    rasterio==1.1.5 python==3.6 geemap==0.7.9 gdal==3.0.4

    description

    I'm using geemap to display a raster on a created map. It uses xarray_leaflet to display the raster and this lib will end up using rasterio to manipulate the .tif file.

    When I launch my display :

    m = geemap.Map()
    m.add_raster(clip_map, colormap='terrain', layer_name='gfc')
    

    I get the following error :

    CRSError: Unable to open EPSG support file gcs.csv. Try setting the GDAL_DATA environment variable to point to the directory containing EPSG csv files.

    This error is everywhere on SO so I tried to verify if my GDAL_DATA env variable was coorectly set :

    import os
    import stat
    gdal_data = os.environ['GDAL_DATA']
    print('is dir: ' + str(os.path.isdir(gdal_data)))
    gcs_csv = os.path.join(gdal_data, 'gcs.csv')
    print('is file: ' + str(os.path.isfile(gcs_csv)))
    st = os.stat(gcs_csv)
    print('is readable: ' + str(bool(st.st_mode & stat.S_IRGRP)))
    
    # out 
    # is dir: True
    #is file: False
    #FileNotFoundError: [Errno 2] No such file or directory: '/usr/share/gdal/gcs.csv'
    

    going to the glad distrib inb the NEWS file, I read that they removed lots of file in 3.0 including gcs.csv. So it's no longer included in my folder.

    It's the first time I'm having a compatibility problem between rasterio and gdal so I'm very surprised.

    Having the feeling to be dum I try to reproduce your example. It raised the same error (I also verified the files that display perfectly in Qgis).

    Is this function still working ? Did you see anything wrong in the way I'm using it ?

    opened by 12rambau 14
  • Merging cartoee features into geemap

    Merging cartoee features into geemap

    cartoee is a Python package meant to assist Earth Engine users in creating publication quality maps. This was a project started over two years ago and was developed primarily to support a small group in figure creation. This package is admittedly not so well maintained... I feel that geemap and cartoee have a similar broad goal in aiding visualization of EE data but with slightly different end target visualizations (one for creating publication figures the other for interactive mapping).

    Gauging interest here on taking functionality from cartotee and merging it into geemap so that geemap becomes the one-stop shop for EE visualization using the Python API.

    I imagine that we can have another module with optional dependencies where users can call from geemap import cartoee (or whatever we want to name the module) and create the figure. This module would have to be somewhat isolated given that cartoee dependencies (cython and cartopy) can make installation complex. Users should be able to install the optional dependencies to use the cartoee module if they want but it will not be needed for the majority of users.

    @giswqs what are your thoughts on this?

    Feature Request enhancement 
    opened by KMarkert 13
  • geemap.ee_export_image problem.

    geemap.ee_export_image problem.

    Hi! Thanks for the great package and awsome work. I have a problem with ee_export_image that I will explain it below.

    Environment Information

    • geemap version: 0.11.0
    • Python version: 3.9.8
    • Operating System: Windows 10 x64

    Description

    I want to download a decadal mvc for NDSI (1-10, 11-20, and 20 the last day of the month), MOD10A1 product. When I visualize the first image of the final collection of images is the correct one (filtered to take in account NDSI with more than 2 observations per the decadal period, clipped, etc.). When I export the images from the collection they are wrong, respectively the images before filtering out the miminum number of observations.

    What I Did

    import os
    import ee
    import datetime
    from datetime import datetime, timedelta
    import geemap
    
    Map=geemap.Map()
    
    pol3=ee.FeatureCollection('geometry of interest')
    
    ## a function to extract values from specific bits 
    def bitwiseExtract(input, fromBit, toBit):
        maskSize=ee.Number(1).add(toBit).subtract(fromBit)
        mask=ee.Number(1).leftShift(maskSize).subtract(1)
        return input.rightShift(fromBit).bitwiseAnd(mask)
    
    # A function to mask out low quality zones 
    def qa_mask(image):
        # Select the QA band.
        QA = image.select('NDSI_Snow_Cover_Basic_QA')
        qaMask=bitwiseExtract(QA, 0, 15).lte(2)
        mask=qaMask
        return image.updateMask(mask)
    
    ## a function to keep values for count gte 2
    
    def mask_count(image):
        maskCount=image.select('NDSI_count').gte(2)
        image=image.updateMask(maskCount)
        return image.select('NDSI_max')
    
    
    ###function to count the number of bands to omit images with 0 bands
    def nb_bands(image):
        return image.set('numar',image.bandNames().size())
    
    ###GLS water dataset to filter out all regions that are covered with lakes, pond, big rivers etc.
    water_dataset_orig = ee.ImageCollection('GLCF/GLS_WATER').select('water').min()
    # Remap values.
    water_dataset = ee.Image(1)\
              .where(water_dataset_orig.lte(1), 0)\
              .where(water_dataset_orig.eq(2), 1)\
              .where(water_dataset_orig.gte(3),0);
    ###Mask for NDSI values greater than 30 
    def masker(image):
        test=water_dataset.select('constant').eq(0)
        test2=image.updateMask(test)
        mask1 = test2.select('NDSI_Snow_Cover').gt(30)
        return image.updateMask(mask1)
    
    #Create NDSI
    
    def func_dko(image):
          return image.select('NDSI_Snow_Cover').rename('NDSI').clip(pol3).copyProperties(image,['system:time_start','system:time_end'])
    
    col1 = ee.ImageCollection('MODIS/006/MOD10A1').map(qa_mask)
    NDSI = col1.map(masker).map(func_dko)
    
    ###variables for the decadal composite image
    #define starting and ending dates
    startyear = 2002
    endyear = 2003
    mapYears = ee.List.sequence(startyear, endyear)
    startmonth = 6
    endmonth =1
    mapMonths = ee.List.sequence(1, 12)
    start = ee.Date.fromYMD(startyear, startmonth, 1)
    end = ee.Date.fromYMD(endyear, endmonth+1, 1); # end date is always exclusive
    
    # define list of dates to filter on
    startdays = ee.List([1, 11, 21])
    enddays = ee.List([11, 21, 1])
    # Create a sequence of numbers, one for each time interval.
    sequence = ee.List.sequence(0, 2)
    
    def collect(collection, start, end, mapYears, mapMonths):
            def func_years(year):
                def func_months(month):
                    def func_sequence(dayRange):
                        startDate = ee.Date.fromYMD(year, month, startdays.get(dayRange))
                                        # the end date needs some if statements to be well formatted
                        endDate = ee.Date(ee.Algorithms.If( ee.Number(dayRange).eq(2), \
                                                            ee.Algorithms.If(ee.Number(month).eq(12), \
                                                                             ee.Date.fromYMD(ee.Number(year).add(1), 1, enddays.get(dayRange)),\
                                                                             ee.Date.fromYMD(year, ee.Number(month).add(1), enddays.get(dayRange))),\
                                                             ee.Date.fromYMD(year, month, enddays.get(dayRange))))
                                                             
                        return collection.filterDate(startDate, endDate).reduce(ee.Reducer.max().combine(reducer2=ee.Reducer.count(), sharedInputs=True)).set('system:time_start', startDate.millis()).set('system:time_end', endDate.millis()).set('numbImages',collection.size())
                    images2 = sequence.map(func_sequence)
                    return images2
                images1 = mapMonths.map(func_months)
                return images1
            images=mapYears.map(func_years).flatten()
            collection = ee.ImageCollection.fromImages(images)
            return collection.filterDate(start, end).set('system:time_start', start.millis()).set('system:time_end', end.millis())
    
    
    ##applying the fucntion defined above 
    
    colectie_decad_init=collect(NDSI,start,end,mapYears,mapMonths)
    colectie_decad_number=colectie_decad_init.map(nb_bands)
    colectie_decad=colectie_decad_number.filter(ee.Filter.gte("numar",2))
    
    colectie_final=colectie_decad.map(mask_count)
    
    ##visualize data for confirmation
    
    final_list=colectie_final.toList(200)
    image_1=ee.Image(final_list.get(0))
    date_image_1 = image_1.date().format('dd-MM-yyyy').getInfo()
    print(date_image_1 )
    ndviParams = {'min': -1, 'max':100, 'palette': ['8B0000','FF0000', 'FF4500', 'FFFF00', '00FF00','008000', '006400']}
    Map.addLayer(ee.Image(viz_list.get(0)), ndviParams, 'NDSI image')
    Map
    
    ##final step, export your images 
    out_dir = os.path.expanduser("Downloads_new")
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)
    
    
    for i in range(0, 200, 1):
            image_2=ee.Image(final_list.get(i))
            date = image_2.date().format('dd-MM-yyyy').getInfo()
            name1= 'SnowDecad'+'_'+date+'.tif'
            filename1 = os.path.join(out_dir, name1)
            print(name1)
            geemap.ee_export_image(image_2, filename=filename1, scale=500,region=pol3.geometry(), crs='EPSG:3035')
    
    
    

    I think it is something wrong here, at export of the images. I checked and rechecked the variables and the code. I also test the code in EarthEngine web platform and with ee.batch.Export.image.toDrive and the results are correct.

    Thank u for everything!

    bug 
    opened by georgeboldeanu 12
  • Exporting Landcover image .tif only appears in b&w

    Exporting Landcover image .tif only appears in b&w

    • geemap version: 0.7.13
    • Python version: 3.6.12
    • Operating System: ubuntu

    Description

    Using the stock #32 .ipynb, I export the classified image, but find that upon opening it only appears in b&w. Is there a way to change export settings to retain land cover colorization?

    Feature Request 
    opened by albertlarson 12
  • geemap.ee_to_numpy() Does not work

    geemap.ee_to_numpy() Does not work

    • geemap version: 0.8.1
    • Python version: 3.8
    • Operating System: windows 10

    Description

    Dear profesor Qiusheng Wu. I am trying to extract a cloud masked image as numpy array but it does not work. The output message is the following:

    <<Image.sampleRectangle: Fully masked pixels / pixels outside of the image footprint when sampling band 'B4' with no default value set. Note that calling sampleRectangle() on an image after ee.Image.clip() may result in a sampling bounding box outside the geometry passed to clip().>>

    GEE cloud masked image to numpy array error

    Thank you very much for your hep.

    What I Did

    Paste the command(s) you ran and the output.
    If there was a crash, please include the traceback here.
    
    opened by PERCY-ESCOBAR 12
  • Multiple broken URLs/links in the example Jupyter notebooks

    Multiple broken URLs/links in the example Jupyter notebooks

    Environment Information

    • geemap version: 0.11.7
    • Python version: 3.9.10
    • Operating System: Windows 11

    Description

    I was trying the 13_zonal_statistic_by_group.ipynb and noticed the https://developers.google.com/earth-engine/datasets/catalog/MODIS_051_MCD12Q1 link no longer works

    What I Did

    I tried checking the Earth Engine catalog, searching for that ID only returns this URL now: https://developers.google.com/earth-engine/datasets/catalog/MODIS_006_MCD12Q1 I'm not sure if this supersedes the one with the missing link.

    bug 
    opened by owenlamont 11
  • Bug in ROI creation error in Asia

    Bug in ROI creation error in Asia

    Environment Information

    • geemap version:0.8.18
    • Python version:3.9.6
    • Operating System:Windows

    Description

    Describe what you were trying to get done.---Creating Landsat timelapse animations with animated text using Earth Engine Tell us what happened, what went wrong, and what you expected to happen.--- I am having problems with selecting ROI in Asia and then running it unsuccessfully. After trying geemap.update_package() as mentioned in (https://github.com/giswqs/geemap/issues/134) it still doesn't work, display and download. The downloaded GIF is black. I don't know what the problem is, but I would appreciate it if you could answer my questions.

    What I Did

    ee.Feature({ "functionInvocationValue": { "functionName": "Feature", "arguments": { "geometry": { "functionInvocationValue": { "functionName": "GeometryConstructors.Polygon", "arguments": { "coordinates": { "constantValue": [ [ [ -246.842215, 40.786488 ], [ -246.842215, 40.902842 ], [ -246.551129, 40.902842 ], [ -246.551129, 40.786488 ], [ -246.842215, 40.786488 ] ] ] }, "geodesic": { "constantValue": false } } } } } } })

    Paste the command(s) you ran and the output.
    If there was a crash, please include the traceback here.---https://earthengine.googleapis.com/v1alpha/projects/earthengine-legacy/videoThumbnails/f9f8c47117d98fd8f7b277a8a3fa24e0-07ad235cfe3d2c62b4bf3323b2a307f8:getPixels
    
    bug 
    opened by Guoliang940242695 10
  • Markers with different shapes

    Markers with different shapes

    Is it possible to add markers to the map with different shapes (square, triangle, star, ...), not only circle?

    It would be interesting to have a function like add_markers_from_xy(..., shape='square')

    Or even include HTML icons.

    Feature Request 
    opened by EmanuelCastanho 6
  • Addition of add_legend to plotlymap module

    Addition of add_legend to plotlymap module

    Description

    Hello, I would like to make a feature request. The addition of add_legend to plotlymap module. I have read the different features in the module but the addition of a legend isn't one of them. I'm currently developing a dashboard with Dash in Python and I use plotlymap from geemap to visualize some maps and I really would appreciate if you could add it.

    Thank you and good day.

    Feature Request help wanted 
    opened by alexacanche 1
  • Fix issues hindering use of geemap with Panel

    Fix issues hindering use of geemap with Panel

    I would like to enable people to use geemap in their data apps via Panel. Panel supports ipywidgets in general via ipywidgets_bokeh. See https://panel.holoviz.org/reference/panes/IPyWidget.html#panes-gallery-ipywidget.

    I can see geemap is built upon ipywidgets, so I was hoping it would work out of the box. But when I run a minimal example I get errors in the browser console and in the terminal.

    I've seen this with other ipywidgets. Sometimes the issue has been on ipywidgets_bokeh side, sometimes on the ipywidget side. So I'm positing here because I don't know where the issue is.

    Reproducible example

    pip install geemap==0.13.10 ipywidgets_bokeh==1.2.1 panel==0.13.1
    

    Then panel serve script.py --autoreload --show where script.py contains

    import geemap
    
    map = geemap.Map(center=[40,-100], zoom=4)
    
    import panel as pn
    
    pn.extension("ipywidgets", template="fast")
    pn.state.template.param.update(
      site="Awesome Panel", title="Panel + Geemap - Google Earth Engine Data Apps"
    )
    
    pn.panel(map).servable()
    

    Then I see the errors

    ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2 
            
           Error: Could not create a view for model id b97b1de12b934e639c9b914f53f0985f
        at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2087124
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.catch (async)
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.then (async)
    e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    t.create_child_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    add_control_model @ Map.js:194
    e.update @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    (anonymous) @ Map.js:233
    Promise.then (async)
    render_leaflet @ Map.js:231
    Promise.then (async)
    render @ Map.js:227
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.then (async)
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.then (async)
    e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    e.display_model @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    await in render (async)
    _render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    build @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    renderTo @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    f @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
    await in f (async)
    t.add_document_standalone @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
    await in t.add_document_standalone (async)
    t.add_document_from_session @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:586
    await in t.add_document_from_session (async)
    w @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
    t.embed_items @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
    await in t.embed_items (async)
    embed_document @ script?theme=dark:286
    (anonymous) @ script?theme=dark:289
    (anonymous) @ script?theme=dark:305
    o.safely @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:595
    fn @ script?theme=dark:281
    ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2 
            
           Error: Could not create child view
        at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2087124
        at async Promise.all (:5006/index 0)
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.catch (async)
    t.create_child_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    add_control_model @ Map.js:194
    e.update @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    (anonymous) @ Map.js:233
    Promise.then (async)
    render_leaflet @ Map.js:231
    Promise.then (async)
    render @ Map.js:227
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.then (async)
    (anonymous) @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    Promise.then (async)
    e.create_view @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    e.display_model @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    await in render (async)
    _render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2
    render @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    build @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    renderTo @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:496
    f @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
    await in f (async)
    t.add_document_standalone @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:584
    await in t.add_document_standalone (async)
    t.add_document_from_session @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:586
    await in t.add_document_from_session (async)
    w @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
    t.embed_items @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:163
    await in t.embed_items (async)
    embed_document @ script?theme=dark:286
    (anonymous) @ script?theme=dark:289
    (anonymous) @ script?theme=dark:305
    o.safely @ bokeh.min.js?v=3c61e952b808bb7e346ce828a565a5f23aaf7708d034fa9d0906403813355d45bb4e8d8b0b23a93f032c76831d4f0221846f28699c7f5147caa62e0d31668314:595
    fn @ script?theme=dark:281
    ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2 
            
           Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'indexOf')
        at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2459037
        at gg.Bl [as loader] (ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2459166)
        at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2741052
        at new Promise (<anonymous>)
        at gg.loadClass (ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2740898)
        at ipywidgets_bokeh.js?v=206620a657f1ccc8af72b866fdcef20e641c48f39ce27f338ce8313949c63e53:2:2091629
    

    image

    and in the terminal

    $ panel serve 'script.py' --autoreload --show
    2022-06-12 11:07:23,557 Starting Bokeh server version 2.4.3 (running on Tornado 6.1)
    2022-06-12 11:07:23,559 User authentication hooks NOT provided (default user enabled)
    2022-06-12 11:07:23,560 Bokeh app running at: http://localhost:5006/script
    2022-06-12 11:07:23,561 Starting Bokeh server with process id: 32072
    2022-06-12 11:07:27,280 WebSocket connection opened
    2022-06-12 11:07:27,281 ServerConnection created
    2022-06-12 11:07:27,305 WebSocket connection opened
    2022-06-12 11:07:27,306 ServerConnection created
    2022-06-12 11:07:28,329 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    2022-06-12 11:07:28,591 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    2022-06-12 11:07:28,597 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    2022-06-12 11:07:29,826 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    2022-06-12 11:07:29,926 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    2022-06-12 11:07:29,931 No such comm: 32d8eaaf587145428eaf87cde1e9eda1
    
    Feature Request help wanted 
    opened by MarcSkovMadsen 4
  • How to convert ee.ImageCollection to xarray.Dataset for phenology analysis?

    How to convert ee.ImageCollection to xarray.Dataset for phenology analysis?

    Dear Dr. Wu,

    The DEA Sandbox has some APIs abouth phenology analysis. For example, xr_phenology and Tutorials. However, one of the input parameter [ds] is a xarray.Dataset object. I want to konw how to convert an ee.ImageCollection object that generated by geemap to xarry. How about develop such an API in geemap?

    Feature Request help wanted 
    opened by Jack-ee 5
Releases(v0.19.1)
  • v0.19.1(Dec 23, 2022)

  • v0.19.0(Dec 5, 2022)

  • v0.18.3(Dec 2, 2022)

  • v0.18.2(Dec 1, 2022)

  • v0.18.1(Nov 29, 2022)

  • v0.18.0(Nov 27, 2022)

    New Features

    • Added functions for creating legends and adding widgets to the map (#1345)(#1346)
    • New functions include create_legend(), add_legend(), add_text(), add_image(), add_html(), and add_widget()
    • Added two notebook examples for using newly added functions
    • Split-map now supports adding multiple legends
    • Added ESA World Cover 2021 basemaps
    • Added mkdocs dark mode (#1338)

    Improvement

    • Removed misc notebook to reduce mkdocs size
    Source code(tar.gz)
    Source code(zip)
  • v0.17.3(Nov 19, 2022)

  • v0.17.2(Nov 1, 2022)

    Improvement:

    • Added NASA funding acknowledgment
    • Added unmask_value parameter to download image #1270
    • Added Japan GEE workshop notebook
    • Improved Colab error message
    • Added support for Python 3.11
    • Added asset type to search result
    • zonal_stats: additions to allowed_statistics #1308
    • Fixed max zoom bug
    • Improved split control
    • Improved local tile
    Source code(tar.gz)
    Source code(zip)
  • v0.17.1(Sep 19, 2022)

  • v0.17.0(Sep 11, 2022)

  • v0.16.9(Sep 7, 2022)

  • v0.16.8(Sep 7, 2022)

  • v0.16.7(Aug 20, 2022)

  • v0.16.6(Aug 19, 2022)

    New Features:

    • Added auth support for ee service account #1220
    • Added a mosaic function #1219
    • Added download_ned function #1218

    API References:

    • ee_initialize(): https://geemap.org/common/#geemap.common.ee_initialize
    • mosaic(): https://geemap.org/common/#geemap.common.mosaic
    • download_ned(): https://geemap.org/common/#geemap.common.download_ned
    Source code(tar.gz)
    Source code(zip)
  • v0.16.5(Aug 16, 2022)

    Improvement:

    • Add band param for image_count #1209
    • Improved exporting image to asset #1208
    • Fixed Sentinel-1 timelapse bug #1210
    • Fixed pie chart Windows bug
    • Added popup fields for add_geojson
    • Updated zonal stats function
    Source code(tar.gz)
    Source code(zip)
  • v0.16.4(Aug 11, 2022)

    Special thanks to @karelvancamp for his many contributions to this new version.

    New Features:

    • Added support for searching Awesome GEE Community Datasets #1197 #1201 #1202
    • Added support for retrieving GEE JS code examples and converting to Python
    • Added colorbar background color and image convolution
    • Added html_to_streamlit function

    Improvement:

    • Improved the search data GUI

    https://user-images.githubusercontent.com/5016453/184171214-49e58375-196f-4349-9ec1-ae143b63eb42.mp4

    Source code(tar.gz)
    Source code(zip)
  • v0.16.3(Aug 9, 2022)

  • v0.16.2(Aug 4, 2022)

  • v0.16.1(Jul 31, 2022)

  • v0.16.0(Jul 30, 2022)

    New Features:

    • Added support for creating S1 timelapse #752 #1168
    • Added cloud_pct option for dynamic world ts #1165
    • Added get_ee_path function

    Improvement:

    • Renamed region to roi for timelapse func
    • Added lidar tutorial
    • Improved support for Colab
    • Fixed js py conversion bug
    • Improved COG and STAC for short URL
    • Improved requireJS function
    • Added book link
    • Added vector_styling explicit args #1155
    Source code(tar.gz)
    Source code(zip)
  • v0.15.5(Jul 22, 2022)

    New Features:

    • Added get_direct_url function
    • Added more lidar functions #1149

    Improvement:

    • Improved load_GeoTIFF function
    • Fixed image palette bug
    • Updated vector styling notebook
    Source code(tar.gz)
    Source code(zip)
  • v0.15.4(Jul 16, 2022)

    New Features:

    • Added support for vector styling #1148
    • Added csv_to_vector function #1144

    Improvement:

    • Improved add_legend and points_from_xy
    • Updated data conversion functions
    • Renamed datasets from hyphen to underscore
    • Updated sample datasets
    • Fixed folium split map bug
    Source code(tar.gz)
    Source code(zip)
  • v0.15.3(Jul 11, 2022)

  • v0.15.2(Jul 10, 2022)

  • v0.15.1(Jul 9, 2022)

    New Features:

    • Added support for the Open Earth Engine Library (OEEL) #1137. Now can you can call functions in third-party Earth Engine JavaScript libraries directly from Python.
    Source code(tar.gz)
    Source code(zip)
  • v0.15.0(Jul 8, 2022)

  • v0.14.3(Jul 1, 2022)

  • v0.14.2(Jun 28, 2022)

  • v0.14.1(Jun 27, 2022)

  • v0.14.0(Jun 18, 2022)

Owner
Qiusheng Wu
Assistant Professor of Geography at the University of Tennessee, Knoxville
Qiusheng Wu
Global topography (referenced to sea-level) in a 10 arcminute resolution grid

Earth - Topography grid at 10 arc-minute resolution Global 10 arc-minute resolution grids of topography (ETOPO1 ice-surface) referenced to mean sea-le

Fatiando a Terra Datasets 1 Jan 20, 2022
Using SQLAlchemy with spatial databases

GeoAlchemy GIS Support for SQLAlchemy. Introduction GeoAlchemy is an extension of SQLAlchemy. It provides support for Geospatial data types at the ORM

109 Dec 01, 2022
Constraint-based geometry sketcher for blender

Geometry Sketcher Constraint-based sketcher addon for Blender that allows to create precise 2d shapes by defining a set of geometric constraints like

1.7k Jan 02, 2023
Python module and script to interact with the Tractive GPS tracker.

pyTractive GPS Python module and script to interact with the Tractive GPS tracker. Requirements Python 3 geopy folium pandas pillow usage: main.py [-h

Dr. Usman Kayani 3 Nov 16, 2022
Search and download Copernicus Sentinel satellite images

sentinelsat Sentinelsat makes searching, downloading and retrieving the metadata of Sentinel satellite images from the Copernicus Open Access Hub easy

837 Dec 28, 2022
Geodata extensions for Django REST Framework

Django-Spillway Django and Django REST Framework integration of raster and feature based geodata. Spillway builds on the immensely marvelous Django RE

Brian Galey 62 Jan 04, 2023
Satellite imagery for dummies.

felicette Satellite imagery for dummies. What can you do with this tool? TL;DR: Generate JPEG earth imagery from coordinates/location name with public

Shivashis Padhi 1.8k Jan 03, 2023
Tile Map Service and OGC Tiles API for QGIS Server

Tiles API Add tiles API to QGIS Server Tiles Map Service API OGC Tiles API Tile Map Service API - TMS The TMS API provides these URLs: /tms/? to get i

3Liz 6 Dec 01, 2021
Xarray backend to Copernicus Sentinel-1 satellite data products

xarray-sentinel WARNING: this product is a "technology preview" / pre-Alpha Xarray backend to explore and load Copernicus Sentinel-1 satellite data pr

B-Open 191 Dec 15, 2022
Python interface to PROJ (cartographic projections and coordinate transformations library)

pyproj Python interface to PROJ (cartographic projections and coordinate transformations library). Documentation Stable: http://pyproj4.github.io/pypr

832 Dec 31, 2022
gjf: A tool for fixing invalid GeoJSON objects

gjf: A tool for fixing invalid GeoJSON objects The goal of this tool is to make it as easy as possible to fix invalid GeoJSON objects through Python o

Yazeed Almuqwishi 91 Dec 06, 2022
iNaturalist observations along hiking trails

This tool reads the route of a hike and generates a table of iNaturalist observations along the trails. It also shows the observations and the route of the hike on a map. Moreover, it saves waypoints

7 Nov 11, 2022
Imports VZD (Latvian State Land Service) open data into postgis enabled database

Python script main.py downloads and imports Latvian addresses into PostgreSQL database. Data contains parishes, counties, cities, towns, and streets.

Kaspars Foigts 7 Oct 26, 2022
A python package that extends Google Earth Engine.

A python package that extends Google Earth Engine GitHub: https://github.com/davemlz/eemont Documentation: https://eemont.readthedocs.io/ PyPI: https:

David Montero Loaiza 307 Jan 01, 2023
Geospatial Image Processing for Python

GIPPY Gippy is a Python library for image processing of geospatial raster data. The core of the library is implemented as a C++ library, libgip, with

GIPIT 83 Aug 19, 2022
GeoNode is an open source platform that facilitates the creation, sharing, and collaborative use of geospatial data.

Table of Contents What is GeoNode? Try out GeoNode Install Learn GeoNode Development Contributing Roadmap Showcase Most useful links Licensing What is

GeoNode Development Team 1.2k Dec 26, 2022
Cloud Optimized GeoTIFF creation and validation plugin for rasterio

rio-cogeo Cloud Optimized GeoTIFF (COG) creation and validation plugin for Rasterio. Documentation: https://cogeotiff.github.io/rio-cogeo/ Source Code

216 Dec 31, 2022
Map Ookla server locations as a Kernel Density Estimation (KDE) geographic map plot.

Ookla Server KDE Plotting This notebook was created to map Ookla server locations as a Kernel Density Estimation (KDE) geographic map plot. Currently,

Jonathan Lo 1 Feb 12, 2022
Focal Statistics

Focal-Statistics The Focal statistics tool in many GIS applications like ArcGIS, QGIS and GRASS GIS is a standard method to gain a local overview of r

Ifeanyi Nwasolu 1 Oct 21, 2021
Location field and widget for Django. It supports Google Maps, OpenStreetMap and Mapbox

django-location-field Let users pick locations using a map widget and store its latitude and longitude. Stable version: django-location-field==2.1.0 D

Caio Ariede 481 Dec 29, 2022