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
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
Rasterio reads and writes geospatial raster datasets

Rasterio Rasterio reads and writes geospatial raster data. Geographic information systems use GeoTIFF and other formats to organize and store gridded,

Mapbox 1.9k Jan 07, 2023
Geographic add-ons for Django REST Framework. Maintained by the OpenWISP Project.

Geographic add-ons for Django REST Framework. Maintained by the OpenWISP Project.

OpenWISP 982 Jan 06, 2023
A light-weight, versatile XYZ tile server, built with Flask and Rasterio :earth_africa:

Terracotta is a pure Python tile server that runs as a WSGI app on a dedicated webserver or as a serverless app on AWS Lambda. It is built on a modern

DHI GRAS 531 Dec 28, 2022
Interactive Maps with Geopandas

Create Interactive maps πŸ—ΊοΈ with your geodataframe Geopatra extends geopandas for interactive mapping and attempts to wrap the goodness of amazing map

sangarshanan 46 Aug 16, 2022
Python module to access the OpenCage geocoding API

OpenCage Geocoding Module for Python A Python module to access the OpenCage Geocoder. Build Status / Code Quality / etc Usage Supports Python 3.6 or n

OpenCage GmbH 57 Nov 01, 2022
Geocoding library for Python.

geopy geopy is a Python client for several popular geocoding web services. geopy makes it easy for Python developers to locate the coordinates of addr

geopy 3.8k Dec 30, 2022
pure-Python (Numpy optional) 3D coordinate conversions for geospace ecef enu eci

Python 3-D coordinate conversions Pure Python (no prerequistes beyond Python itself) 3-D geographic coordinate conversions and geodesy. API similar to

Geospace code 292 Dec 29, 2022
How to use COG's (Cloud optimized GeoTIFFs) with Rasterio

How to use COG's (Cloud optimized GeoTIFFs) with Rasterio According to Cogeo.org: A Cloud Opdtimized GeoTIFF (COG) is a regular GeoTIFF file, aimed at

Marvin Gabler 8 Jul 29, 2022
A compilation of several single-beam bathymetry surveys of the Caribbean

Caribbean - Single-beam bathymetry This dataset is a compilation of several single-beam bathymetry surveys of the Caribbean ocean displaying a wide ra

Fatiando a Terra Datasets 0 Jan 20, 2022
Platform for building statistical models of cities and regions

UrbanSim UrbanSim is a platform for building statistical models of cities and regions. These models help forecast long-range patterns in real estate d

Urban Data Science Toolkit 419 Dec 30, 2022
Zora is a python program that searches for GeoLocation info for given CIDR networks , with options to search with API or without API

Zora Zora is a python program that searches for GeoLocation info for given CIDR networks , with options to search with API or without API Installing a

z3r0day 1 Oct 26, 2021
a Geolocator made in python

Geolocator A Geolocator made in python ✨ Features locates ur location using ur ip thats it! πŸ’β€β™€οΈ How to use first download the locator.py file instal

Portgas D Ace 1 Oct 27, 2021
WIP: extracting Geometry utilities from datacube-core

odc.geo This is still work in progress. This repository contains geometry related code extracted from Open Datacube. For details and motivation see OD

Open Data Cube 34 Jan 09, 2023
A trivia questions about Europe

EUROPE TRIVIA QUIZ IN PYTHON Project Outline Ask user if he / she knows more about Europe. If yes show the Trivia main screen, else show the end Trivi

David Danso 1 Nov 17, 2021
This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

This app displays interesting statistical weather records and trends which can be used in climate related research including study of global warming.

0 Dec 27, 2021
Record railway train route profile with GNSS tools

Train route profile recording with GNSS technology based on ARDUINO platform Project target Develop GNSS recording tools based on the ARDUINO platform

tomcom 1 Jan 01, 2022
Introduction to Geospatial Analysis in Python

Introduction to Geospatial Analysis in Python This repository is in support of a talk on geospatial data. Data To recreate all of the examples, the da

Dillon Gardner 6 Oct 19, 2022
LEOGPS - Satellite Navigation with GPS on Python!

LEOGPS is an open-source Python software which performs relative satellite navigation between two formation flying satellites, with the objective of high accuracy relative positioning. Specifically,

Samuel Low 50 Dec 13, 2022
QLUSTER is a relative orbit design tool for formation flying satellite missions and space rendezvous scenarios

QLUSTER is a relative orbit design tool for formation flying satellite missions and space rendezvous scenarios, that I wrote in Python 3 for my own research and visualisation. It is currently unfinis

Samuel Low 9 Aug 23, 2022