├── .editorconfig ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ └── feature_request.md ├── dependabot.yml ├── ee_token.py └── workflows │ ├── codeql.yml │ ├── dependency-review.yml │ ├── docker-delete-pr-tags.yml │ ├── docker-image.yml │ ├── docker-publish.yml │ ├── docs-build.yml │ ├── docs.yml │ ├── installation.yml │ ├── macos.yml │ ├── pypi.yml │ ├── ubuntu.yml │ └── windows.yml ├── .gitignore ├── .pre-commit-config.yaml ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── LICENSE ├── MANIFEST.in ├── README.md ├── docs ├── CNAME ├── ai.md ├── assets │ ├── README.md │ ├── favicon.png │ └── logo.png ├── basemaps.md ├── cartoee.md ├── changelog.md ├── changelog_update.py ├── chart.md ├── cheatsheet.md ├── citations.md ├── colormaps.md ├── common.md ├── contributing.md ├── conversion.md ├── core.md ├── coreutils.md ├── datasets.md ├── deck.md ├── ee_tile_layers.md ├── examples.md ├── faq.md ├── foliumap.md ├── geemap.md ├── get-started.md ├── index.md ├── installation.md ├── kepler.md ├── legends.md ├── map_widgets.md ├── maplibregl.md ├── ml.md ├── notebooks │ ├── 00_ee_auth_colab.ipynb │ ├── 00_geemap_colab.ipynb │ ├── 00_geemap_key_features.ipynb │ ├── 01_geemap_intro.ipynb │ ├── 02_using_basemaps.ipynb │ ├── 03_inspector_tool.ipynb │ ├── 04_split_panel_map.ipynb │ ├── 05_drawing_tools.ipynb │ ├── 06_marker_cluster.ipynb │ ├── 07_geojson.ipynb │ ├── 08_ee_js_to_ipynb.ipynb │ ├── 09_plotting.ipynb │ ├── 100_numpy_to_cog.ipynb │ ├── 101_lidar.ipynb │ ├── 102_blend_hillshade.ipynb │ ├── 103_split_control.ipynb │ ├── 104_clip_image.ipynb │ ├── 105_netcdf.ipynb │ ├── 106_kepler_gl.ipynb │ ├── 107_pydeck.ipynb │ ├── 108_image_zonal_stats.ipynb │ ├── 109_coordinate_grids.ipynb │ ├── 10_shapefiles.ipynb │ ├── 110_choropleth.ipynb │ ├── 111_image_count.ipynb │ ├── 112_cartoee_basemap.ipynb │ ├── 113_image_area.ipynb │ ├── 114_dynamic_world.ipynb │ ├── 115_land_cover.ipynb │ ├── 116_land_cover_timeseries.ipynb │ ├── 117_fishnet.ipynb │ ├── 118_download_image.ipynb │ ├── 119_plot_raster.ipynb │ ├── 11_export_image.ipynb │ ├── 120_javascript.ipynb │ ├── 121_vector_style.ipynb │ ├── 122_lidar.ipynb │ ├── 123_sentinel1_timelapse.ipynb │ ├── 124_more_datasets.ipynb │ ├── 125_example_code.ipynb │ ├── 126_inspector.ipynb │ ├── 127_create_legend.ipynb │ ├── 128_add_widget.ipynb │ ├── 129_vector_to_gif.ipynb │ ├── 12_zonal_statistics.ipynb │ ├── 130_print_objects.ipynb │ ├── 131_arcgis.ipynb │ ├── 132_folium_colorbar.ipynb │ ├── 133_gradio.ipynb │ ├── 134_ee_to_geotiff.ipynb │ ├── 135_segmentation.ipynb │ ├── 136_download_parallel.ipynb │ ├── 137_create_grid.ipynb │ ├── 138_draw_control.ipynb │ ├── 139_layer_to_image.ipynb │ ├── 13_zonal_statistics_by_group.ipynb │ ├── 140_ee_to_xarray.ipynb │ ├── 141_image_array_viz.ipynb │ ├── 142_google_maps.ipynb │ ├── 143_precipitation_timelapse.ipynb │ ├── 144_chart_features.ipynb │ ├── 145_chart_image.ipynb │ ├── 146_chart_image_collection.ipynb │ ├── 147_chart_array_list.ipynb │ ├── 148_chart_data_table.ipynb │ ├── 149_gemini.ipynb │ ├── 14_legends.ipynb │ ├── 150_maplibre.ipynb │ ├── 151_dataset_explorer.ipynb │ ├── 15_convert_js_to_py.ipynb │ ├── 16_add_animated_text.ipynb │ ├── 17_add_colorbar_to_gif.ipynb │ ├── 18_create_landsat_timelapse.ipynb │ ├── 19_search_places_and_datasets.ipynb │ ├── 20_timeseries_inspector.ipynb │ ├── 21_export_map_to_html_png.ipynb │ ├── 22_import_scripts.ipynb │ ├── 23_import_assets.ipynb │ ├── 24_publish_maps.ipynb │ ├── 25_load_rasters.ipynb │ ├── 26_heroku.ipynb │ ├── 27_timelapse_app.ipynb │ ├── 28_voila.ipynb │ ├── 29_pydeck.ipynb │ ├── 30_image_props_stats.ipynb │ ├── 31_unsupervised_classification.ipynb │ ├── 32_supervised_classification.ipynb │ ├── 33_accuracy_assessment.ipynb │ ├── 34_extract_values.ipynb │ ├── 35_geemap_colab.ipynb │ ├── 36_quality_mosaic.ipynb │ ├── 37_pydeck_3d.ipynb │ ├── 38_cloud_geotiff.ipynb │ ├── 39_timelapse.ipynb │ ├── 40_ipywidgets.ipynb │ ├── 41_water_app.ipynb │ ├── 42_upload_data.ipynb │ ├── 43_extract_values_to_points.ipynb │ ├── 44_cog_stac.ipynb │ ├── 45_cog_mosaic.ipynb │ ├── 46_local_rf_training.ipynb │ ├── 47_image_thumbnails.ipynb │ ├── 48_folium_legend.ipynb │ ├── 49_colorbar.ipynb │ ├── 50_cartoee_quickstart.ipynb │ ├── 51_cartoee_projections.ipynb │ ├── 52_cartoee_gif.ipynb │ ├── 53_layer_vis.ipynb │ ├── 54_vector_vis.ipynb │ ├── 55_raster_vis.ipynb │ ├── 56_local_data.ipynb │ ├── 57_cartoee_blend.ipynb │ ├── 58_add_vector.ipynb │ ├── 59_whitebox.ipynb │ ├── 60_colormaps.ipynb │ ├── 61_cartoee_scalebar.ipynb │ ├── 62_time_slider.ipynb │ ├── 63_charts.ipynb │ ├── 64_data_catalog.ipynb │ ├── 65_vector_styling.ipynb │ ├── 66_cartoee_legend.ipynb │ ├── 67_training_samples.ipynb │ ├── 68_netcdf_to_ee.ipynb │ ├── 69_cartoee_vector.ipynb │ ├── 70_linked_maps.ipynb │ ├── 71_timelapse.ipynb │ ├── 72_time_slider_gui.ipynb │ ├── 73_transect.ipynb │ ├── 74_csv_to_points.ipynb │ ├── 75_sankee.ipynb │ ├── 76_osm_to_ee.ipynb │ ├── 77_planet_imagery.ipynb │ ├── 78_ts_inspector.ipynb │ ├── 79_chart_histogram.ipynb │ ├── 80_point_layer.ipynb │ ├── 81_goes_timelapse.ipynb │ ├── 82_contours.ipynb │ ├── 83_local_tile.ipynb │ ├── 84_openstreetmap.ipynb │ ├── 85_postgis.ipynb │ ├── 86_image_overlay.ipynb │ ├── 87_add_points_from_xy.ipynb │ ├── 88_circle_markers.ipynb │ ├── 89_add_labels.ipynb │ ├── 90_naip_timelapse.ipynb │ ├── 91_planetary_computer.ipynb │ ├── 92_plotly.ipynb │ ├── 93_cog_inspector.ipynb │ ├── 94_heremap.ipynb │ ├── 95_create_cog.ipynb │ ├── 96_image_chips.ipynb │ ├── 97_join_table.ipynb │ ├── 98_timelapse_fading.ipynb │ └── 99_landsat_9.ipynb ├── osm.md ├── overrides │ └── main.html ├── plot.md ├── plotlymap.md ├── releasing.md ├── report.md ├── search_bk.md ├── search_docs.html ├── timelapse.md ├── toolbar.md ├── tutorials.md ├── usage.md └── workshops │ ├── .jupytext.toml │ ├── AGU_2023.ipynb │ ├── AGU_2024.ipynb │ ├── Alaska_2024_Part1.ipynb │ ├── Alaska_2024_Part2.ipynb │ ├── Alaska_2024_Part3.ipynb │ ├── AmericaView_2023.ipynb │ ├── CVPR_2025.ipynb │ ├── City_Plus_2023.ipynb │ ├── Crop_Mapping_2022.ipynb │ ├── FOSS4GNA_2024.ipynb │ ├── G4G_2023.ipynb │ ├── GEE_Workshop_2021.ipynb │ ├── GEE_Workshop_2022_Part1.ipynb │ ├── GEE_Workshop_2022_Part2.ipynb │ ├── GEE_Workshop_2024.ipynb │ ├── GEE_Workshop_2025.ipynb │ ├── GeoAI_2024.ipynb │ ├── GeoPython_2021.ipynb │ ├── HGAC_2024.ipynb │ ├── IGIC_2024.ipynb │ ├── IPPN_2024.ipynb │ ├── Japan_2022.ipynb │ ├── NCSU_2023.ipynb │ ├── SRM_Workshop_2022.ipynb │ ├── SatMOC_2024.ipynb │ ├── SciPy_2023.ipynb │ ├── SciPy_2024.ipynb │ ├── TNGIC_2024.ipynb │ ├── Taiwan_2024.ipynb │ └── jupytext.toml ├── environment.yml ├── examples ├── README.md ├── batch_update.py ├── data │ ├── animation.gif │ ├── cable_geo.geojson │ ├── charts_feature_example.dbf │ ├── charts_feature_example.fix │ ├── charts_feature_example.prj │ ├── charts_feature_example.shp │ ├── charts_feature_example.shp.cpg │ ├── charts_feature_example.shx │ ├── china.geojson │ ├── cog_files.txt │ ├── countries.cpg │ ├── countries.dbf │ ├── countries.geojson │ ├── countries.gpkg │ ├── countries.prj │ ├── countries.shp │ ├── countries.shx │ ├── countries.zip │ ├── country_centroids.csv │ ├── ee_logo.png │ ├── life_exp.csv │ ├── noaa_logo.jpg │ ├── rf_example.csv │ ├── rwc_batch_input.csv │ ├── temperature.gif │ ├── us_cities.cpg │ ├── us_cities.csv │ ├── us_cities.dbf │ ├── us_cities.geojson │ ├── us_cities.json │ ├── us_cities.prj │ ├── us_cities.shp │ ├── us_cities.shx │ ├── us_regions.geojson │ ├── us_states.cpg │ ├── us_states.dbf │ ├── us_states.json │ ├── us_states.kml │ ├── us_states.kmz │ ├── us_states.prj │ ├── us_states.shp │ ├── us_states.shx │ ├── wind_global.nc │ └── world_cities.csv ├── javascripts │ ├── ClippedComposite.js │ ├── FromName.js │ ├── ModisQaBands.js │ ├── NormalizedDifference.js │ ├── QualityMosaic.js │ └── grid.js ├── python │ ├── earthengine_js_to_ipynb.py │ ├── earthengine_py_to_ipynb.py │ ├── geemap_and_earthengine.py │ └── javascript_to_python.py └── template │ ├── template.ipynb │ └── template.py ├── geemap ├── __init__.py ├── ai.py ├── basemaps.py ├── cartoee.py ├── chart.py ├── cli.py ├── colormaps.py ├── common.py ├── conversion.py ├── core.py ├── coreutils.py ├── data │ ├── census_data.json │ ├── fonts │ │ ├── alibaba.otf │ │ └── arial.ttf │ ├── gee_f.json │ ├── javascripts │ │ ├── ClippedComposite.js │ │ ├── FromName.js │ │ ├── ModisQaBands.js │ │ ├── NormalizedDifference.js │ │ └── QualityMosaic.js │ ├── python │ │ └── javascript_to_python.py │ └── template │ │ ├── NLCD.qml │ │ ├── ee_api_docs.csv │ │ ├── ee_api_docs.html │ │ ├── ee_data_catalog.csv │ │ ├── ee_legend_table.txt │ │ ├── legend.html │ │ ├── legend.txt │ │ ├── legend_style.html │ │ ├── template.ipynb │ │ ├── template.py │ │ └── toolbox.csv ├── datasets.py ├── deck.py ├── ee_tile_layers.py ├── examples │ ├── __init__.py │ └── datasets.txt ├── foliumap.py ├── geemap.py ├── kepler.py ├── legends.py ├── map_widgets.py ├── maplibregl.py ├── ml.py ├── osm.py ├── plot.py ├── plotlymap.py ├── report.py ├── timelapse.py └── toolbar.py ├── js ├── basemap_selector.ts ├── color_picker.ts ├── container.ts ├── inspector.ts ├── ipywidgets_styles.ts ├── layer_editor.ts ├── layer_manager.ts ├── layer_manager_row.ts ├── legend.ts ├── legend_customization.ts ├── lit_widget.ts ├── palette_editor.ts ├── raster_layer_editor.ts ├── search_bar.ts ├── styles.ts ├── tab_panel.ts ├── toolbar.ts ├── toolbar_item.ts ├── tree_node.ts ├── utils.ts └── vector_layer_editor.ts ├── karma.conf.cjs ├── mkdocs.yml ├── package-lock.json ├── package.json ├── paper ├── 10.21105.joss.02305.pdf ├── paper.bib └── paper.md ├── pyproject.toml ├── requirements_docs.txt ├── tests ├── __init__.py ├── basemap_selector.spec.ts ├── data │ ├── feature_tree.json │ ├── image_collection_tree.json │ └── image_tree.json ├── fake_anywidget.ts ├── fake_ee.py ├── fake_map.py ├── layer_manager.spec.ts ├── layer_manager_row.spec.ts ├── legend.spec.ts ├── search_bar.spec.ts ├── test_basemaps.py ├── test_core.py ├── test_coreutils.py ├── test_ee_tile_layers.py ├── test_geemap.py ├── test_map_widgets.py ├── test_toolbar.py └── utils.py ├── tsconfig.json ├── tsconfig.webpack.json ├── tutorials ├── FeatureCollection │ └── us_census_data.ipynb ├── Image │ ├── 01_image_overview.ipynb │ ├── 02_image_visualization.ipynb │ ├── 03_image_metadata.ipynb │ ├── 04_math_operations.ipynb │ ├── 05_conditional_operations.ipynb │ ├── 06_convolutions.ipynb │ ├── 07_morphological_operations.ipynb │ ├── 08_gradients.ipynb │ ├── 09_edge_detection.ipynb │ ├── 10_spectral_transformations.ipynb │ ├── 11_texture.ipynb │ ├── 12_object_based_methods.ipynb │ ├── 13_cumulative_cost_mapping.ipynb │ └── 14_registering_images.ipynb ├── ImageCollection │ ├── 01_image_collection_overview.ipynb │ ├── 02_image_collection_metadata.ipynb │ ├── 03_filtering_image_collection.ipynb │ └── 04_mapping_over_image_collection.ipynb ├── LICENSE ├── README.md └── Template │ ├── template.ipynb │ └── update_header.py └── uv.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | 3 | root = true 4 | 5 | [*] 6 | indent_style = space 7 | indent_size = 4 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | charset = utf-8 11 | end_of_line = lf 12 | 13 | [*.bat] 14 | indent_style = tab 15 | end_of_line = crlf 16 | 17 | [LICENSE] 18 | insert_final_newline = false 19 | 20 | [Makefile] 21 | indent_style = tab 22 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: giswqs 2 | custom: 3 | - buymeacoffee.com/giswqs 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a bug report to help us improve 4 | labels: bug 5 | --- 6 | 7 | 8 | 9 | ### Environment Information 10 | 11 | Please run the following code on your computer and share the output with us so that we can better debug your issue: 12 | 13 | ```python 14 | import geemap 15 | geemap.Report() 16 | ``` 17 | 18 | ### Description 19 | 20 | Describe what you were trying to get done. 21 | Tell us what happened, what went wrong, and what you expected to happen. 22 | 23 | ### What I Did 24 | 25 | ``` 26 | Paste the command(s) you ran and the output. 27 | If there was a crash, please include the traceback here. 28 | ``` 29 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | contact_links: 2 | - name: Ask questions 3 | url: https://github.com/gee-community/geemap/discussions/categories/q-a 4 | about: Please ask and answer questions here. 5 | - name: Ideas 6 | url: https://github.com/gee-community/geemap/discussions/categories/ideas 7 | about: Please share your ideas here. 8 | - name: Ask questions from the GEE community 9 | url: https://gis.stackexchange.com/questions/tagged/google-earth-engine 10 | about: To get answers from questions in the GEE commminuty, please ask and answer questions here. 11 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Submit a feature request to help us improve 4 | labels: Feature Request 5 | --- 6 | 7 | 8 | 9 | ### Description 10 | 11 | Describe the feature (e.g., new functions/tutorials) you would like to propose. 12 | Tell us what can be achieved with this new feature and what's the expected outcome. 13 | 14 | ### Source code 15 | 16 | ``` 17 | Paste your source code here if have sample code to share. 18 | ``` 19 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "docker" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "pip" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | - package-ecosystem: "github-actions" 17 | directory: "/" 18 | schedule: 19 | interval: "weekly" 20 | -------------------------------------------------------------------------------- /.github/ee_token.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | ee_token = os.environ["EARTHENGINE_TOKEN"] 4 | credential = '{"refresh_token":"%s"}' % ee_token 5 | credential_file_path = os.path.expanduser("~/.config/earthengine/") 6 | os.makedirs(credential_file_path, exist_ok=True) 7 | with open(credential_file_path + "credentials", "w") as file: 8 | file.write(credential) 9 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: ["master"] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: ["master"] 20 | schedule: 21 | - cron: "31 20 * * 6" 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: ["javascript", "python"] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v4 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v3 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | 52 | # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs 53 | # queries: security-extended,security-and-quality 54 | 55 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 56 | # If this step fails, then you should remove it and run the build manually (see below) 57 | - name: Autobuild 58 | uses: github/codeql-action/autobuild@v3 59 | 60 | # ℹ️ Command-line programs to run using the OS shell. 61 | # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun 62 | 63 | # If the Autobuild fails above, remove it and uncomment the following three lines. 64 | # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance. 65 | 66 | # - run: | 67 | # echo "Run, Build Application using script" 68 | # ./location_of_script_within_repo/buildscript.sh 69 | 70 | - name: Perform CodeQL Analysis 71 | uses: github/codeql-action/analyze@v3 72 | with: 73 | category: "/language:${{matrix.language}}" 74 | -------------------------------------------------------------------------------- /.github/workflows/dependency-review.yml: -------------------------------------------------------------------------------- 1 | # Dependency Review Action 2 | # 3 | # This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging. 4 | # 5 | # Source repository: https://github.com/actions/dependency-review-action 6 | # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement 7 | name: "Dependency Review" 8 | on: [pull_request] 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | dependency-review: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: "Checkout Repository" 18 | uses: actions/checkout@v4 19 | - name: "Dependency Review" 20 | uses: actions/dependency-review-action@v4 21 | -------------------------------------------------------------------------------- /.github/workflows/docker-delete-pr-tags.yml: -------------------------------------------------------------------------------- 1 | name: Delete All GHCR PR Tags 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | workflow_dispatch: 8 | 9 | jobs: 10 | delete-pr-tags: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Delete all GHCR image tags starting with "pr-" 15 | env: 16 | GHCR_TOKEN: ${{ secrets.GHCR_TOKEN }} 17 | REPO: ${{ github.event.repository.name }} 18 | OWNER: ${{ github.repository_owner }} 19 | run: | 20 | echo "Fetching GHCR container versions for ghcr.io/${OWNER}/${REPO}..." 21 | 22 | response=$(curl -s -H "Authorization: Bearer ${GHCR_TOKEN}" \ 23 | "https://api.github.com/orgs/${OWNER}/packages/container/${REPO}/versions") 24 | 25 | # Check that the response is a JSON array 26 | if ! echo "$response" | jq -e 'type == "array"' > /dev/null; then 27 | echo "❌ Unexpected response from GitHub API:" 28 | echo "$response" 29 | exit 1 30 | fi 31 | 32 | echo "$response" | jq -c '.[]' | while read -r version; do 33 | version_id=$(echo "$version" | jq -r '.id') 34 | tag_names=$(echo "$version" | jq -r '.metadata.container.tags[]?') 35 | 36 | for tag in $tag_names; do 37 | if [[ "$tag" == pr-* ]]; then 38 | echo "🗑️ Deleting tag: $tag (version ID: $version_id)" 39 | curl -s -X DELETE -H "Authorization: Bearer ${GHCR_TOKEN}" \ 40 | "https://api.github.com/orgs/${OWNER}/packages/container/${REPO}/versions/${version_id}" 41 | break # One deletion per version is sufficient 42 | fi 43 | done 44 | done 45 | -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Build Docker Image 2 | 3 | on: 4 | release: 5 | types: [published] 6 | push: 7 | branches: 8 | - master 9 | pull_request: 10 | types: [opened, synchronize, reopened] 11 | 12 | jobs: 13 | build-and-push: 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | packages: write 18 | 19 | steps: 20 | - name: Checkout code 21 | uses: actions/checkout@v4 22 | 23 | - name: Set up Docker Buildx 24 | uses: docker/setup-buildx-action@v3 25 | 26 | - name: Log in to GitHub Container Registry (ghcr.io) 27 | uses: docker/login-action@v3 28 | with: 29 | registry: ghcr.io 30 | username: ${{ github.actor }} 31 | password: ${{ secrets.GITHUB_TOKEN }} 32 | 33 | - name: Set Docker image tags 34 | id: meta 35 | run: | 36 | REPO=ghcr.io/${{ github.repository_owner }}/${{ github.event.repository.name }} 37 | 38 | if [[ "${{ github.event_name }}" == "release" ]]; then 39 | VERSION_TAG=${{ github.event.release.tag_name }} 40 | echo "tags<> $GITHUB_OUTPUT 41 | echo "${REPO}:${VERSION_TAG}" >> $GITHUB_OUTPUT 42 | echo "${REPO}:latest" >> $GITHUB_OUTPUT 43 | echo "EOF" >> $GITHUB_OUTPUT 44 | 45 | elif [[ "${{ github.event_name }}" == "pull_request" ]]; then 46 | PR_NUMBER=${{ github.event.pull_request.number }} 47 | echo "tags=${REPO}:pr-${PR_NUMBER}" >> $GITHUB_OUTPUT 48 | 49 | else 50 | echo "tags=${REPO}:dev" >> $GITHUB_OUTPUT 51 | fi 52 | 53 | - name: Build and push multi-platform image 54 | uses: docker/build-push-action@v6 55 | with: 56 | context: . 57 | platforms: linux/amd64,linux/arm64 58 | push: true 59 | tags: ${{ steps.meta.outputs.tags }} 60 | provenance: false 61 | cache-from: type=gha 62 | cache-to: type=gha,mode=max 63 | -------------------------------------------------------------------------------- /.github/workflows/docker-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker image 2 | 3 | on: 4 | release: 5 | types: [published] 6 | 7 | jobs: 8 | push_to_registries: 9 | name: Push Docker image to multiple registries 10 | runs-on: ubuntu-latest 11 | permissions: 12 | packages: write 13 | contents: read 14 | steps: 15 | - name: Check out the repo 16 | uses: actions/checkout@v4 17 | 18 | - name: Log in to Docker Hub 19 | uses: docker/login-action@v3 20 | with: 21 | username: ${{ secrets.DOCKER_USERNAME }} 22 | password: ${{ secrets.DOCKER_PASSWORD }} 23 | 24 | - name: Log in to the Container registry 25 | uses: docker/login-action@v3 26 | with: 27 | registry: ghcr.io 28 | username: ${{ github.actor }} 29 | password: ${{ secrets.GITHUB_TOKEN }} 30 | 31 | - name: Extract metadata (tags, labels) for Docker 32 | id: meta 33 | uses: docker/metadata-action@v5 34 | with: 35 | images: | 36 | giswqs/geemap 37 | ghcr.io/${{ github.repository }} 38 | 39 | - name: Build and push Docker images 40 | uses: docker/build-push-action@v6 41 | with: 42 | context: . 43 | push: true 44 | tags: ${{ steps.meta.outputs.tags }} 45 | labels: ${{ steps.meta.outputs.labels }} 46 | -------------------------------------------------------------------------------- /.github/workflows/docs-build.yml: -------------------------------------------------------------------------------- 1 | name: docs-build 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | docs-build: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | python-version: ["3.12"] 14 | 15 | env: 16 | USE_MKDOCS: ${{ secrets.USE_MKDOCS }} 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Install uv 24 | uses: astral-sh/setup-uv@v6 25 | with: 26 | version: "latest" 27 | # enable-cache: true 28 | 29 | - name: Set up Python ${{ matrix.python-version }} 30 | run: uv python install ${{ matrix.python-version }} 31 | 32 | - name: Install dependencies 33 | run: uv sync --python ${{ matrix.python-version }} 34 | 35 | - name: Install optional dependencies 36 | run: | 37 | uv cache clean 38 | uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj 39 | uv pip install -r pyproject.toml --extra all 40 | - name: Test import 41 | run: | 42 | uv run python -c "import geemap; print('geemap import successful')" 43 | uv run python -c "from osgeo import gdal; print('gdal import successful')" 44 | uv run gdalinfo --version 45 | 46 | - name: Running tests 47 | run: | 48 | uv run python -m unittest discover tests/ 49 | - name: Install mkdocs 50 | run: | 51 | uv pip install -r requirements_docs.txt 52 | uv run mkdocs build 53 | 54 | - name: Deploy to Netlify 55 | uses: nwtgck/actions-netlify@v3.0 56 | with: 57 | publish-dir: "./site" 58 | production-branch: master 59 | github-token: ${{ secrets.GITHUB_TOKEN }} 60 | deploy-message: "Deploy from GitHub Actions" 61 | enable-pull-request-comment: true 62 | enable-commit-comment: false 63 | overwrites-pull-request-comment: true 64 | env: 65 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 66 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 67 | 68 | - name: Cleanup 69 | if: always() 70 | run: | 71 | echo "Cleaning up resources." 72 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-latest 11 | strategy: 12 | matrix: 13 | python-version: ["3.12"] 14 | 15 | env: 16 | USE_MKDOCS: ${{ secrets.USE_MKDOCS }} 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 22 | 23 | - name: Install uv 24 | uses: astral-sh/setup-uv@v6 25 | with: 26 | version: "latest" 27 | # enable-cache: true 28 | 29 | - name: Set up Python ${{ matrix.python-version }} 30 | run: uv python install ${{ matrix.python-version }} 31 | 32 | - name: Install dependencies 33 | run: uv sync --python ${{ matrix.python-version }} 34 | 35 | - name: Install optional dependencies 36 | run: | 37 | uv cache clean 38 | uv pip install --find-links https://girder.github.io/large_image_wheels GDAL pyproj 39 | uv pip install -r pyproject.toml --extra all 40 | - name: Test import 41 | run: | 42 | uv run python -c "import geemap; print('geemap import successful')" 43 | uv run python -c "from osgeo import gdal; print('gdal import successful')" 44 | uv run gdalinfo --version 45 | 46 | - name: Running tests 47 | run: | 48 | uv run python -m unittest discover tests/ 49 | - name: Install mkdocs 50 | run: | 51 | uv pip install -r requirements_docs.txt 52 | uv run mkdocs gh-deploy --force 53 | -------------------------------------------------------------------------------- /.github/workflows/installation.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | name: Linux installation 10 | jobs: 11 | test-ubuntu: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | python-version: ["3.12"] 17 | steps: 18 | - uses: actions/checkout@v4 19 | 20 | - name: Install uv 21 | uses: astral-sh/setup-uv@v6 22 | with: 23 | version: "latest" 24 | enable-cache: true 25 | 26 | - name: Set up Python ${{ matrix.python-version }} 27 | run: uv python install ${{ matrix.python-version }} 28 | 29 | - name: Install dependencies 30 | run: uv sync --python ${{ matrix.python-version }} 31 | 32 | - name: Test import 33 | run: uv run python -c "import geemap; print('geemap import successful')" 34 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | 9 | name: macOS build 10 | jobs: 11 | test-macOS: 12 | runs-on: ${{ matrix.config.os }} 13 | name: ${{ matrix.config.os }} (${{ matrix.config.py }}) 14 | strategy: 15 | fail-fast: false 16 | matrix: 17 | config: 18 | - { os: macOS-latest, py: "3.12" } 19 | env: 20 | SDKROOT: /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - name: Install uv 25 | uses: astral-sh/setup-uv@v6 26 | with: 27 | version: "latest" 28 | enable-cache: true 29 | 30 | - name: Set up Python ${{ matrix.config.py }} 31 | run: uv python install ${{ matrix.config.py }} 32 | 33 | - name: Install dependencies 34 | run: uv sync --python ${{ matrix.config.py }} 35 | 36 | - name: Test import 37 | run: | 38 | uv run python -c "import geemap; print('geemap import successful')" 39 | -------------------------------------------------------------------------------- /.github/workflows/pypi.yml: -------------------------------------------------------------------------------- 1 | # This workflows will upload a Python Package using Twine when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: pypi 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | deploy: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v4 16 | - name: Set up Python 17 | uses: actions/setup-python@v5 18 | with: 19 | python-version: "3.x" 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install setuptools wheel twine 24 | - name: Build and publish 25 | env: 26 | TWINE_USERNAME: ${{ secrets.PYPI_USERS }} 27 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 28 | run: | 29 | pip install build 30 | python -m build 31 | twine upload dist/* 32 | -------------------------------------------------------------------------------- /.github/workflows/ubuntu.yml: -------------------------------------------------------------------------------- 1 | name: TestingUbuntu 2 | 3 | on: 4 | push: 5 | branches: ["master"] 6 | pull_request: 7 | branches: ["master"] 8 | 9 | jobs: 10 | test-ubuntu: 11 | runs-on: ubuntu-latest 12 | 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] 17 | 18 | env: 19 | USE_MKDOCS: ${{ secrets.USE_MKDOCS }} 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - name: Install uv 25 | uses: astral-sh/setup-uv@v6 26 | with: 27 | version: "latest" 28 | enable-cache: true 29 | 30 | - name: Set up Python ${{ matrix.python-version }} 31 | run: uv python install ${{ matrix.python-version }} 32 | 33 | - name: Install dependencies 34 | run: uv sync --python ${{ matrix.python-version }} 35 | 36 | - name: Install optional dependencies 37 | run: | 38 | uv pip install --find-links https://girder.github.io/large_image_wheels gdal pyproj 39 | - name: Test import 40 | run: | 41 | uv run python -c "import geemap; print('geemap import successful')" 42 | uv run python -c "from osgeo import gdal; print('gdal import successful')" 43 | uv run gdalinfo --version 44 | 45 | - name: Running tests 46 | run: | 47 | uv run python -m unittest discover tests/ 48 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: "TestingWindows" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | jobs: 11 | test-windows: 12 | runs-on: windows-latest 13 | strategy: 14 | matrix: 15 | python-version: ["3.12"] 16 | 17 | env: 18 | USE_FOLIUM: ${{ secrets.USE_FOLIUM }} 19 | USE_MKDOCS: ${{ secrets.USE_MKDOCS }} 20 | MAPBOX_TOKEN: ${{ secrets.MAPBOX_TOKEN }} 21 | 22 | steps: 23 | - uses: actions/checkout@v4 24 | 25 | - name: Install uv 26 | uses: astral-sh/setup-uv@v6 27 | with: 28 | version: "latest" 29 | enable-cache: true 30 | 31 | - name: Set up Python ${{ matrix.python-version }} 32 | run: uv python install ${{ matrix.python-version }} 33 | 34 | - name: Install dependencies 35 | run: uv sync --python ${{ matrix.python-version }} 36 | 37 | - name: Test import 38 | run: | 39 | uv run python -c "import geemap; print('geemap import successful')" 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | docs/data/ 6 | docs/notebooks/*.json 7 | docs/notebooks/*.js 8 | docs/notebooks/*.tif 9 | docs/notebooks/*.xml 10 | docs/notebooks/*.zip 11 | docs/notebooks/*.las 12 | docs/notebooks/*.csv 13 | docs/notebooks/*.gif 14 | docs/notebooks/*.laz 15 | docs/notebooks/*.nc 16 | docs/notebooks/*.html 17 | docs/notebooks/countries.* 18 | docs/notebooks/cache/* 19 | docs/changelog_update.md 20 | **/.DS_Store 21 | private/ 22 | 23 | # C extensions 24 | *.so 25 | 26 | # Distribution / packaging 27 | md2rst.md 28 | md2rst.rst 29 | testing/ 30 | geemap/geemap_v*.py 31 | geemap/static/ 32 | .Python 33 | env/ 34 | build/ 35 | develop-eggs/ 36 | dist/ 37 | downloads/ 38 | eggs/ 39 | .eggs/ 40 | lib/ 41 | lib64/ 42 | node_modules/ 43 | parts/ 44 | sdist/ 45 | var/ 46 | wheels/ 47 | *.egg-info/ 48 | .installed.cfg 49 | *.egg 50 | 51 | # PyInstaller 52 | # Usually these files are written by a python script from a template 53 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 54 | *.manifest 55 | *.spec 56 | 57 | # Installer logs 58 | pip-log.txt 59 | pip-delete-this-directory.txt 60 | 61 | # Unit test / coverage reports 62 | htmlcov/ 63 | .tox/ 64 | .coverage 65 | .coverage.* 66 | .cache 67 | nosetests.xml 68 | coverage.xml 69 | *.cover 70 | .hypothesis/ 71 | .pytest_cache/ 72 | 73 | # Translations 74 | *.mo 75 | *.pot 76 | 77 | # Django stuff: 78 | *.log 79 | local_settings.py 80 | 81 | # Flask stuff: 82 | instance/ 83 | .webassets-cache 84 | 85 | # Scrapy stuff: 86 | .scrapy 87 | 88 | # Sphinx documentation 89 | docs/_build/ 90 | 91 | # PyBuilder 92 | target/ 93 | 94 | # Jupyter Notebook 95 | .ipynb_checkpoints 96 | 97 | # pyenv 98 | .python-version 99 | 100 | # celery beat schedule file 101 | celerybeat-schedule 102 | 103 | # SageMath parsed files 104 | *.sage.py 105 | 106 | # dotenv 107 | .env 108 | 109 | # virtualenv 110 | .venv 111 | venv/ 112 | ENV/ 113 | 114 | # Spyder project settings 115 | .spyderproject 116 | .spyproject 117 | 118 | # Rope project settings 119 | .ropeproject 120 | 121 | # mkdocs documentation 122 | /site 123 | 124 | # mypy 125 | .mypy_cache/ 126 | 127 | # IDE settings 128 | .vscode/ 129 | docs/changelog_update.py 130 | oryx-build-commands.txt 131 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/pre-commit/pre-commit-hooks 3 | rev: v5.0.0 4 | hooks: 5 | - id: check-toml 6 | - id: check-yaml 7 | - id: end-of-file-fixer 8 | types: [python] 9 | - id: trailing-whitespace 10 | - id: requirements-txt-fixer 11 | - id: check-added-large-files 12 | args: ["--maxkb=500"] 13 | 14 | - repo: https://github.com/psf/black 15 | rev: 25.1.0 16 | hooks: 17 | - id: black-jupyter 18 | 19 | - repo: https://github.com/codespell-project/codespell 20 | rev: v2.4.1 21 | hooks: 22 | - id: codespell 23 | args: 24 | [ 25 | "--ignore-words-list=aci,acount,acounts,fallow,ges,hart,hist,nd,ned,ois,wqs,watermask,tre,assertIn", 26 | "--skip=*.csv,*.geojson,*.json,*.yml*.js,*.html,*cff,*.pdf", 27 | ] 28 | 29 | - repo: https://github.com/kynan/nbstripout 30 | rev: 0.8.1 31 | hooks: 32 | - id: nbstripout 33 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # ------------------------------ 2 | # Base image from Jupyter stack 3 | # ------------------------------ 4 | FROM quay.io/jupyter/base-notebook:latest 5 | 6 | # ------------------------------ 7 | # 1. Switch to root to install system packages 8 | # ------------------------------ 9 | USER root 10 | 11 | RUN apt-get update && \ 12 | apt-get install -y --no-install-recommends \ 13 | git \ 14 | curl \ 15 | nodejs \ 16 | npm \ 17 | && apt-get clean && rm -rf /var/lib/apt/lists/* 18 | 19 | # ------------------------------ 20 | # 2. Install conda packages into base env 21 | # ------------------------------ 22 | RUN mamba install -n base -c conda-forge -y \ 23 | gdal \ 24 | proj \ 25 | geos \ 26 | rasterio \ 27 | pyproj \ 28 | fiona \ 29 | geopandas \ 30 | rioxarray \ 31 | maplibre \ 32 | pmtiles \ 33 | flask \ 34 | flask-cors \ 35 | localtileserver \ 36 | jupyter-server-proxy \ 37 | ffmpeg-python \ 38 | gdown \ 39 | xee \ 40 | leafmap \ 41 | && mamba clean --all --yes \ 42 | && fix-permissions $CONDA_DIR 43 | 44 | # ------------------------------ 45 | # 3. Set geospatial environment variables 46 | # ------------------------------ 47 | ENV PROJ_LIB=$CONDA_DIR/share/proj \ 48 | GDAL_DATA=$CONDA_DIR/share/gdal \ 49 | LOCALTILESERVER_CLIENT_PREFIX='proxy/{port}' 50 | 51 | # ------------------------------ 52 | # 4. Copy source code after env setup 53 | # ------------------------------ 54 | COPY . /home/jovyan/geemap 55 | WORKDIR /home/jovyan/geemap 56 | 57 | # ------------------------------ 58 | # 5. Install geemap from source 59 | # ------------------------------ 60 | # Prevent version resolution errors in CI 61 | ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_GEEMAP=0.0.0 62 | 63 | RUN pip install . && \ 64 | rm -rf ./build ./dist *.egg-info && \ 65 | mkdir -p /home/jovyan/work && \ 66 | fix-permissions /home/jovyan 67 | 68 | # ------------------------------ 69 | # 6. Switch back to default user 70 | # ------------------------------ 71 | USER $NB_UID 72 | WORKDIR /home/jovyan 73 | 74 | # ------------------------------ 75 | # Usage: 76 | # docker pull ghcr.io/gee-community/geemap:latest 77 | # docker run -it -p 8888:8888 -v $(pwd):/home/jovyan/work ghcr.io/gee-community/geemap:latest 78 | # ------------------------------ 79 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020-2024, Qiusheng Wu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.md 3 | include requirements.txt 4 | include requirements_docs.txt 5 | 6 | recursive-include geemap/data * 7 | recursive-include geemap/examples * 8 | recursive-include tests * 9 | recursive-exclude * __pycache__ 10 | recursive-exclude * *.py[co] 11 | recursive-exclude * *.ipynb 12 | recursive-exclude examples * 13 | 14 | recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif 15 | -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | geemap.org 2 | -------------------------------------------------------------------------------- /docs/ai.md: -------------------------------------------------------------------------------- 1 | # ai module 2 | 3 | ::: geemap.ai 4 | -------------------------------------------------------------------------------- /docs/assets/README.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | 3 | Credits to [Khalil Misbah](https://www.linkedin.com/in/khalil-misbah/) for the original design of the geemap logo. 4 | 5 | ![logo](https://raw.githubusercontent.com/gee-community/geemap/master/docs/assets/logo.png) 6 | -------------------------------------------------------------------------------- /docs/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/docs/assets/favicon.png -------------------------------------------------------------------------------- /docs/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/docs/assets/logo.png -------------------------------------------------------------------------------- /docs/basemaps.md: -------------------------------------------------------------------------------- 1 | # basemaps module 2 | 3 | ::: geemap.basemaps -------------------------------------------------------------------------------- /docs/cartoee.md: -------------------------------------------------------------------------------- 1 | # cartoee module 2 | 3 | ::: geemap.cartoee -------------------------------------------------------------------------------- /docs/changelog_update.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # Copy the release notes from the GitHub release page 4 | markdown_text = """ 5 | ## What's Changed 6 | * Add installation CI by @giswqs in https://github.com/gee-community/geemap/pull/1656 7 | * Fix vis control error by @giswqs in https://github.com/gee-community/geemap/pull/1660 8 | 9 | ## New Contributors 10 | * @bengalin made their first contribution in https://github.com/gee-community/geemap/pull/1664 11 | * @sufyanAbbasi made their first contribution in https://github.com/gee-community/geemap/pull/1666 12 | * @kirimaru-jp made their first contribution in https://github.com/gee-community/geemap/pull/1669 13 | * @schwehr made their first contribution in https://github.com/gee-community/geemap/pull/1673 14 | 15 | **Full Changelog**: https://github.com/gee-community/geemap/compare/v0.25.0...v0.26.0 16 | """ 17 | 18 | # Regular expression pattern to match the Markdown hyperlinks 19 | pattern = r"https://github\.com/gee-community/geemap/pull/(\d+)" 20 | 21 | 22 | # Function to replace matched URLs with the desired format 23 | def replace_url(match): 24 | pr_number = match.group(1) 25 | return f"[#{pr_number}](https://github.com/gee-community/geemap/pull/{pr_number})" 26 | 27 | 28 | # Use re.sub to replace URLs with the desired format 29 | formatted_text = re.sub(pattern, replace_url, markdown_text) 30 | 31 | for line in formatted_text.splitlines(): 32 | if "Full Changelog" in line: 33 | prefix = line.split(": ")[0] 34 | link = line.split(": ")[1] 35 | version = line.split("/")[-1] 36 | formatted_text = ( 37 | formatted_text.replace(line, f"{prefix}: [{version}]({link})") 38 | .replace("## What's Changed", "**What's Changed**") 39 | .replace("## New Contributors", "**New Contributors**") 40 | ) 41 | 42 | 43 | with open("docs/changelog_update.md", "w") as f: 44 | f.write(formatted_text) 45 | 46 | # Print the formatted text 47 | print(formatted_text) 48 | 49 | # Copy the formatted text and paste it to the CHANGELOG.md file 50 | -------------------------------------------------------------------------------- /docs/chart.md: -------------------------------------------------------------------------------- 1 | # chart module 2 | 3 | ::: geemap.chart 4 | -------------------------------------------------------------------------------- /docs/cheatsheet.md: -------------------------------------------------------------------------------- 1 | # geemap cheat sheet 2 | 3 | ## Installation 4 | 5 | ### Install from PyPI 6 | 7 | ```console 8 | pip install geemap 9 | ``` 10 | 11 | ### Install from conda-forge 12 | 13 | ```console 14 | conda install geemap -c conda-forge 15 | ``` 16 | 17 | ### Create a new conda env 18 | 19 | ```console 20 | conda create -n gee python=3.9 21 | conda activate gee 22 | conda install geemap -c conda-forge 23 | ``` 24 | 25 | ## Upgrade 26 | 27 | ### Upgrade from PyPI 28 | 29 | ```console 30 | pip install -U geemap 31 | ``` 32 | 33 | ### Upgrade from conda-forge 34 | 35 | ```console 36 | conda update geemap -c conda-forge 37 | ``` 38 | 39 | ### Upgrade from GitHub 40 | 41 | ```console 42 | import geemap 43 | geemap.update_package() 44 | ``` 45 | 46 | ## Map 47 | 48 | ### Create an interactive map 49 | 50 | ```python 51 | Map = geemap.Map(center=(lat, lon), zoom=4) 52 | Map 53 | ``` 54 | 55 | ### Change the default basemap 56 | 57 | ```python 58 | Map = geemap.Map(basemap='HYBRID') 59 | ``` 60 | 61 | ### Add basemaps 62 | 63 | ```python 64 | Map.add_basemap('OpenTopoMap') 65 | ``` 66 | 67 | ### Add XYZ layers 68 | 69 | ```python 70 | url = 'https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}' 71 | Map.add_tile_layer(url, name='Google Satellite', attribution='Google') 72 | ``` 73 | 74 | ### Add WMS layers 75 | 76 | ```python 77 | url = 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer?' 78 | Map.add_wms_layer(url=url, layers='0', name='NAIP Imagery', format='image/png', shown=True) 79 | ``` 80 | 81 | ### Add Earth Engine layers 82 | 83 | ```python 84 | image = ee.Image('USGS/SRTMGL1_003') 85 | vis_params = { 86 | 'min': 0, 87 | 'max': 4000, 88 | 'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5'] 89 | } 90 | Map.addLayer(image, vis_params, 'SRTM DEM', True, 0.5) 91 | ``` 92 | 93 | ### Set map center 94 | 95 | ```python 96 | Map.setCenter(lon, lat, zoom) 97 | ``` 98 | 99 | ### Center map around an object 100 | 101 | ```python 102 | Map.centerObject(ee_object, zoom) 103 | ``` 104 | 105 | ### Add built-in legends 106 | 107 | ```python 108 | Map.add_legend(builtin_legend='NLCD') 109 | ``` 110 | 111 | ### Add custom legends 112 | 113 | ```python 114 | Map.add_legend(legend_title, legend_dict, layer_name) 115 | ``` 116 | 117 | ## Export data 118 | 119 | ### Export vector to local 120 | 121 | ```python 122 | geemap.ee_to_shp(ee_object, filename) 123 | geemap.ee_export_geojson(ee_object, filename) 124 | geemap.ee_export_vector(ee_object, filename) 125 | ``` 126 | 127 | ### Export vector to Google Drive 128 | 129 | ```python 130 | ee_export_vector_to_drive(ee_object, description, folder, file_format='shp', selectors=None) 131 | ``` 132 | 133 | ### Export image to local 134 | 135 | ```python 136 | ee_export_image(ee_object, filename, scale=None, crs=None, region=None, file_per_band=False) 137 | ``` 138 | 139 | ### Export image collection to local 140 | 141 | ```python 142 | ee_export_image_collection(ee_object, out_dir, scale=None, crs=None, region=None, file_per_band=False) 143 | ``` 144 | 145 | ### Export image to Google Drive 146 | 147 | ```python 148 | ee_export_image_to_drive(ee_object, description, folder=None, region=None, scale=None, crs=None, file_format='GeoTIFF') 149 | ``` 150 | 151 | ### Export image collection to Google Drive 152 | 153 | ```python 154 | ee_export_image_collection_to_drive(ee_object, descriptions=None, folder=None, region=None, scale=None, crs=None, file_format='GeoTIFF') 155 | ``` 156 | -------------------------------------------------------------------------------- /docs/citations.md: -------------------------------------------------------------------------------- 1 | # Citations 2 | 3 | If you find **geemap** useful in your research, please consider citing the following papers to support my work. Thank you for your support. 4 | 5 | * Wu, Q., (2020). geemap: A Python package for interactive mapping with Google Earth Engine. The Journal of Open Source Software, 5(51), 2305. 6 | * 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. ([pdf](https://gishub.org/2019_rse) | [source code](https://doi.org/10.6084/m9.figshare.8864921)) -------------------------------------------------------------------------------- /docs/colormaps.md: -------------------------------------------------------------------------------- 1 | # colormaps module 2 | 3 | ::: geemap.colormaps -------------------------------------------------------------------------------- /docs/common.md: -------------------------------------------------------------------------------- 1 | # common module 2 | 3 | ::: geemap.common -------------------------------------------------------------------------------- /docs/conversion.md: -------------------------------------------------------------------------------- 1 | # conversion module 2 | 3 | ::: geemap.conversion -------------------------------------------------------------------------------- /docs/core.md: -------------------------------------------------------------------------------- 1 | # core module 2 | 3 | ::: geemap.core 4 | -------------------------------------------------------------------------------- /docs/coreutils.md: -------------------------------------------------------------------------------- 1 | # coreutils module 2 | 3 | ::: geemap.coreutils 4 | -------------------------------------------------------------------------------- /docs/datasets.md: -------------------------------------------------------------------------------- 1 | # datasets module 2 | 3 | ::: geemap.datasets 4 | -------------------------------------------------------------------------------- /docs/deck.md: -------------------------------------------------------------------------------- 1 | # deck module 2 | 3 | ::: geemap.deck -------------------------------------------------------------------------------- /docs/ee_tile_layers.md: -------------------------------------------------------------------------------- 1 | # ee_tile_layers module 2 | 3 | ::: geemap.ee_tile_layers 4 | -------------------------------------------------------------------------------- /docs/examples.md: -------------------------------------------------------------------------------- 1 | # examples module 2 | 3 | ::: geemap.examples 4 | -------------------------------------------------------------------------------- /docs/faq.md: -------------------------------------------------------------------------------- 1 | # FAQ 2 | 3 | ## How do I report an issue or make a feature request 4 | 5 | Please go to . 6 | 7 | ## How do I cite geemap in publications 8 | 9 | Wu, Q., (2020). geemap: A Python package for interactive mapping with Google Earth Engine. _The Journal of Open Source Software_, 5(51), 2305. 10 | 11 | ``` 12 | Bibtex: 13 | @article{wu2020geemap, 14 | title={geemap: A Python package for interactive mapping with Google Earth Engine}, 15 | author={Wu, Qiusheng}, 16 | journal={Journal of Open Source Software}, 17 | volume={5}, 18 | number={51}, 19 | pages={2305}, 20 | year={2020} 21 | } 22 | ``` 23 | 24 | ## Why the interactive map does not show up 25 | 26 | If the interactive map does not show up on Jupyter notebook and JupyterLab, it is probably because the ipyleaflet extentsion is not installed properly. 27 | For Jupyter notebook, try running the following two commands within your geemap conda environment: 28 | 29 | ``` 30 | jupyter nbextension install --py --symlink --sys-prefix ipyleaflet 31 | jupyter nbextension enable --py --sys-prefix ipyleaflet 32 | ``` 33 | 34 | For JupyterLab, try running the following command within your geemap conda environment: 35 | 36 | ``` 37 | jupyter labextension install @jupyter-widgets/jupyterlab-manager jupyter-leaflet 38 | 39 | ``` 40 | 41 | ## How to use geemap in countries where Google Services are blocked 42 | 43 | If you are trying to use geemap in a country where Google Services are blocked (e.g., China), you will need a VPN. Use `geemap.set_proxy(port=your-port-number)` to connect to Earth Engine servers. Otherwise, you might encounter a connection timeout issue. 44 | 45 | ``` 46 | import geemap 47 | geemap.set_proxy(port=your-port-number) 48 | Map = geemap.Map() 49 | Map 50 | ``` 51 | 52 | ![](https://i.imgur.com/AHY9rT2.png) 53 | -------------------------------------------------------------------------------- /docs/foliumap.md: -------------------------------------------------------------------------------- 1 | # foliumap module 2 | 3 | ::: geemap.foliumap 4 | -------------------------------------------------------------------------------- /docs/geemap.md: -------------------------------------------------------------------------------- 1 | # geemap module 2 | 3 | ::: geemap.geemap -------------------------------------------------------------------------------- /docs/kepler.md: -------------------------------------------------------------------------------- 1 | # kepler module 2 | 3 | ::: geemap.kepler -------------------------------------------------------------------------------- /docs/legends.md: -------------------------------------------------------------------------------- 1 | # legends module 2 | 3 | ::: geemap.legends -------------------------------------------------------------------------------- /docs/map_widgets.md: -------------------------------------------------------------------------------- 1 | # map_widgets module 2 | 3 | ::: geemap.map_widgets 4 | -------------------------------------------------------------------------------- /docs/maplibregl.md: -------------------------------------------------------------------------------- 1 | # maplibregl module 2 | 3 | ::: geemap.maplibregl 4 | -------------------------------------------------------------------------------- /docs/ml.md: -------------------------------------------------------------------------------- 1 | # ml module 2 | 3 | ::: geemap.ml -------------------------------------------------------------------------------- /docs/notebooks/00_ee_auth_colab.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "\n", 11 | "## Earth Engine Automatic Authentication on Google Colab\n", 12 | "\n", 13 | "### Step 1: Locating the Earth Engine Token\n", 14 | "\n", 15 | "1. Locate the Earth Engine token on your computer by navigating to the following file path based on your operating system:\n", 16 | "\n", 17 | " - Windows: C:\\\\Users\\\\USERNAME\\\\.config\\\\earthengine\\\\credentials\n", 18 | " - Linux: /home/USERNAME/.config/earthengine/credentials\n", 19 | " - MacOS: /Users/USERNAME/.config/earthengine/credentials\n", 20 | "\n", 21 | "2. Open the credentials file and copy the entire content to the clipboard.\n", 22 | "\n", 23 | " **Note:** Ensure that you do not share the content of the credentials file with others to prevent unauthorized access to your Earth Engine account.\n", 24 | "\n", 25 | "### Step 2: Creating the Secret in Google Colab\n", 26 | "\n", 27 | "1. Open your Google Colab notebook and click on the `secrets` tab.\n", 28 | "2. Create a new secret with the name `EARTHENGINE_TOKEN`.\n", 29 | "3. Paste the content from the clipboard into the `Value` input box of the created secret.\n", 30 | "4. Toggle the button on the left to allow notebook access to the secret.\n", 31 | "\n", 32 | "![](https://i.imgur.com/Z9R08uU.png)\n", 33 | "\n", 34 | "### Step 3: Installing the Required Version of geemap\n", 35 | "\n", 36 | "Ensure that you have installed geemap version 0.29.3 or later, as only these versions support the automatic authentication feature." 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "1", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "%pip install -U geemap" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "id": "2", 52 | "metadata": {}, 53 | "source": [ 54 | "### Step 4: Automatic Authentication with geemap\n", 55 | "\n", 56 | "To automatically authenticate Earth Engine using the EARTHENGINE_TOKEN in your Google Colab notebook, run the following code:" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "id": "3", 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "import geemap" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "4", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "m = geemap.Map()\n", 77 | "m" 78 | ] 79 | } 80 | ], 81 | "metadata": { 82 | "kernelspec": { 83 | "display_name": "Python 3", 84 | "name": "python3" 85 | } 86 | }, 87 | "nbformat": 4, 88 | "nbformat_minor": 5 89 | } 90 | -------------------------------------------------------------------------------- /docs/notebooks/01_geemap_intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": { 7 | "toc": true 8 | }, 9 | "source": [ 10 | "

Table of Contents

\n", 11 | "
    " 12 | ] 13 | }, 14 | { 15 | "cell_type": "markdown", 16 | "id": "1", 17 | "metadata": {}, 18 | "source": [ 19 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "id": "2", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "# !pip install geemap" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "id": "3", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "import geemap" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "id": "4", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "geemap.show_youtube(\"h0pz3S6Tvx0\")" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "5", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "Map = geemap.Map(center=(40, -100), zoom=4)\n", 60 | "Map" 61 | ] 62 | }, 63 | { 64 | "cell_type": "code", 65 | "execution_count": null, 66 | "id": "6", 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "Map.add_basemap(\"HYBRID\")" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "id": "7", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "basemaps = geemap.basemaps\n", 81 | "for basemap in basemaps:\n", 82 | " print(basemap)" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "id": "8", 89 | "metadata": {}, 90 | "outputs": [], 91 | "source": [ 92 | "Map.add_basemap(\"OpenTopoMap\")" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Python 3", 99 | "language": "python", 100 | "name": "python3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /docs/notebooks/02_using_basemaps.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "1", 14 | "metadata": {}, 15 | "source": [ 16 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "id": "2", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# !pip install geemap" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "3", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import geemap" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "4", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "geemap.show_youtube(\"6J5ZCIUPXfI\")" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "id": "5", 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "Map = geemap.Map(center=[40, -100], zoom=4)\n", 57 | "Map" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "id": "6", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "Map.add_basemap(\"HYBRID\")" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "id": "7", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "naip_url = \"https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer?\"\n", 78 | "Map.add_wms_layer(\n", 79 | " url=naip_url, layers=\"0\", name=\"NAIP Imagery\", format=\"image/png\", shown=True\n", 80 | ")" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "id": "8", 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "url = \"https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}\"\n", 91 | "Map.add_tile_layer(url, name=\"Google Map\", attribution=\"Google\")" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "id": "9", 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "m = geemap.Map()\n", 102 | "m.basemap_demo()\n", 103 | "m" 104 | ] 105 | } 106 | ], 107 | "metadata": { 108 | "kernelspec": { 109 | "display_name": "Python 3", 110 | "language": "python", 111 | "name": "python3" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 5 116 | } 117 | -------------------------------------------------------------------------------- /docs/notebooks/03_inspector_tool.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "1", 14 | "metadata": {}, 15 | "source": [ 16 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "id": "2", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# !pip install geemap" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "3", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "import ee\n", 37 | "import geemap" 38 | ] 39 | }, 40 | { 41 | "cell_type": "code", 42 | "execution_count": null, 43 | "id": "4", 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "geemap.show_youtube(\"k477ksjkaXw\")" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "id": "5", 53 | "metadata": {}, 54 | "source": [ 55 | "## Create an interactive map" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "id": "6", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "Map = geemap.Map(center=(40, -100), zoom=4)" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "id": "7", 71 | "metadata": {}, 72 | "source": [ 73 | "## Add Earth Engine Python script" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "execution_count": null, 79 | "id": "8", 80 | "metadata": {}, 81 | "outputs": [], 82 | "source": [ 83 | "# Add Earth Engine dataset\n", 84 | "dem = ee.Image(\"USGS/SRTMGL1_003\")\n", 85 | "landcover = ee.Image(\"ESA/GLOBCOVER_L4_200901_200912_V2_3\").select(\"landcover\")\n", 86 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\").select(\n", 87 | " [\"B1\", \"B2\", \"B3\", \"B4\", \"B5\", \"B7\"]\n", 88 | ")\n", 89 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 90 | "\n", 91 | "# Set visualization parameters.\n", 92 | "vis_params = {\n", 93 | " \"min\": 0,\n", 94 | " \"max\": 4000,\n", 95 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 96 | "}\n", 97 | "\n", 98 | "# Add Earth Engine layers to Map\n", 99 | "Map.addLayer(dem, vis_params, \"SRTM DEM\", True, 0.5)\n", 100 | "Map.addLayer(landcover, {}, \"Land cover\")\n", 101 | "Map.addLayer(\n", 102 | " landsat7,\n", 103 | " {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2.0},\n", 104 | " \"Landsat 7\",\n", 105 | ")\n", 106 | "Map.addLayer(states, {}, \"US States\")\n", 107 | "\n", 108 | "Map" 109 | ] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 5 121 | } 122 | -------------------------------------------------------------------------------- /docs/notebooks/05_drawing_tools.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "geemap.show_youtube(\"N7rK2aV1R4c\")" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "4", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "Map = geemap.Map()\n", 52 | "Map" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "5", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "# Add Earth Engine dataset\n", 63 | "image = ee.Image(\"USGS/SRTMGL1_003\")\n", 64 | "\n", 65 | "# Set visualization parameters.\n", 66 | "vis_params = {\n", 67 | " \"min\": 0,\n", 68 | " \"max\": 4000,\n", 69 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 70 | "}\n", 71 | "\n", 72 | "# Add Earth Engine DEM to map\n", 73 | "Map.addLayer(image, vis_params, \"SRTM DEM\")\n", 74 | "\n", 75 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 76 | "Map.addLayer(states, {}, \"US States\")" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": null, 82 | "id": "6", 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "Map.draw_features" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "id": "7", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "Map.draw_last_feature" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "id": "8", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "roi = ee.FeatureCollection(Map.draw_features)\n", 107 | "selected_states = states.filterBounds(roi)\n", 108 | "Map.addLayer(selected_states, {}, \"Selected states\")" 109 | ] 110 | }, 111 | { 112 | "cell_type": "code", 113 | "execution_count": null, 114 | "id": "9", 115 | "metadata": {}, 116 | "outputs": [], 117 | "source": [ 118 | "clipped_image = image.clip(selected_states)\n", 119 | "Map.addLayer(clipped_image, vis_params, \"Clipped image\")" 120 | ] 121 | } 122 | ], 123 | "metadata": { 124 | "kernelspec": { 125 | "display_name": "Python 3", 126 | "language": "python", 127 | "name": "python3" 128 | } 129 | }, 130 | "nbformat": 4, 131 | "nbformat_minor": 5 132 | } 133 | -------------------------------------------------------------------------------- /docs/notebooks/06_marker_cluster.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import geemap\n", 31 | "import json\n", 32 | "import os\n", 33 | "import requests\n", 34 | "from geemap import geojson_to_ee, ee_to_geojson\n", 35 | "from ipyleaflet import GeoJSON, Marker, MarkerCluster" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "id": "3", 42 | "metadata": {}, 43 | "outputs": [], 44 | "source": [ 45 | "geemap.show_youtube(\"4HycJPrwpuo\")" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "4", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "Map = geemap.Map()\n", 56 | "Map" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "id": "5", 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "file_path = os.path.abspath(\"../data/us_cities.json\")\n", 67 | "\n", 68 | "if not os.path.exists(file_path):\n", 69 | " url = \"https://github.com/gee-community/geemap/raw/master/examples/data/us_cities.json\"\n", 70 | " r = requests.get(url)\n", 71 | " with open(file_path, \"w\") as f:\n", 72 | " f.write(r.content.decode(\"utf-8\"))\n", 73 | "\n", 74 | "with open(file_path) as f:\n", 75 | " json_data = json.load(f)" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "id": "6", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "maker_cluster = MarkerCluster(\n", 86 | " markers=[\n", 87 | " Marker(location=feature[\"geometry\"][\"coordinates\"][::-1])\n", 88 | " for feature in json_data[\"features\"]\n", 89 | " ],\n", 90 | " name=\"Markers\",\n", 91 | ")" 92 | ] 93 | }, 94 | { 95 | "cell_type": "code", 96 | "execution_count": null, 97 | "id": "7", 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "Map.add_layer(maker_cluster)" 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": null, 107 | "id": "8", 108 | "metadata": {}, 109 | "outputs": [], 110 | "source": [ 111 | "ee_fc = geojson_to_ee(json_data)\n", 112 | "Map.addLayer(ee_fc, {}, \"US Cities EE\")" 113 | ] 114 | } 115 | ], 116 | "metadata": { 117 | "kernelspec": { 118 | "display_name": "Python 3", 119 | "language": "python", 120 | "name": "python3" 121 | } 122 | }, 123 | "nbformat": 4, 124 | "nbformat_minor": 5 125 | } 126 | -------------------------------------------------------------------------------- /docs/notebooks/09_plotting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "geemap.show_youtube(\"PDab8mkAFL0\")" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "4", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "Map = geemap.Map()\n", 52 | "Map" 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "5", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\").select([0, 1, 2, 3, 4, 6])\n", 63 | "landsat_vis = {\"bands\": [\"B4\", \"B3\", \"B2\"], \"gamma\": 1.4}\n", 64 | "Map.addLayer(landsat7, landsat_vis, \"LE7_TOA_5YEAR/1999_2003\")\n", 65 | "\n", 66 | "hyperion = ee.ImageCollection(\"EO1/HYPERION\").filter(\n", 67 | " ee.Filter.date(\"2016-01-01\", \"2017-03-01\")\n", 68 | ")\n", 69 | "hyperion_vis = {\n", 70 | " \"min\": 1000.0,\n", 71 | " \"max\": 14000.0,\n", 72 | " \"gamma\": 2.5,\n", 73 | "}\n", 74 | "Map.addLayer(hyperion, hyperion_vis, \"EO1/HYPERION\");" 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "execution_count": null, 80 | "id": "6", 81 | "metadata": {}, 82 | "outputs": [], 83 | "source": [ 84 | "Map.set_plot_options(plot_type=\"bar\", add_marker_cluster=True)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "code", 89 | "execution_count": null, 90 | "id": "7", 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "m = geemap.Map()\n", 95 | "m" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "id": "8", 102 | "metadata": {}, 103 | "outputs": [], 104 | "source": [ 105 | "# m.plot_demo()" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 5 118 | } 119 | -------------------------------------------------------------------------------- /docs/notebooks/119_plot_raster.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/gee-community/geemap/blob/master/docs/notebooks/119_plot_raster.ipynb)\n", 9 | "[![image](https://mybinder.org/badge_logo.svg)](https://gishub.org/geemap-binder)\n", 10 | "\n", 11 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "id": "1", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "# !pip install -U geemap" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "import os\n", 32 | "import geemap" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "3", 38 | "metadata": {}, 39 | "source": [ 40 | "Download a sample dataset." 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "4", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "url = \"https://github.com/giswqs/data/raw/main/raster/srtm90.tif\"" 51 | ] 52 | }, 53 | { 54 | "cell_type": "code", 55 | "execution_count": null, 56 | "id": "5", 57 | "metadata": {}, 58 | "outputs": [], 59 | "source": [ 60 | "image = \"srtm90.tif\"\n", 61 | "if not os.path.exists(image):\n", 62 | " geemap.download_file(url, image)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "id": "6", 68 | "metadata": {}, 69 | "source": [ 70 | "Plot the raster image in 2D." 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "id": "7", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "geemap.plot_raster(image, cmap=\"terrain\", figsize=(15, 10))" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "id": "8", 86 | "metadata": {}, 87 | "source": [ 88 | "![](https://i.imgur.com/oDoivba.png)" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "id": "9", 94 | "metadata": {}, 95 | "source": [ 96 | "Plot the raster image in 3D." 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "id": "10", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "geemap.plot_raster_3d(\"srtm90.tif\", factor=2, cmap=\"terrain\", background=\"gray\")" 107 | ] 108 | }, 109 | { 110 | "cell_type": "markdown", 111 | "id": "11", 112 | "metadata": {}, 113 | "source": [ 114 | "![](https://i.imgur.com/UQDbV2G.gif)" 115 | ] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | } 124 | }, 125 | "nbformat": 4, 126 | "nbformat_minor": 5 127 | } 128 | -------------------------------------------------------------------------------- /docs/notebooks/123_sentinel1_timelapse.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "**Creating Sentinel-1 SAR imagery timelapse**\n", 11 | "\n", 12 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "id": "1", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "# !pip install -U geemap" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "id": "2", 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import ee\n", 33 | "import geemap" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "id": "3", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "Map = geemap.Map()\n", 44 | "Map" 45 | ] 46 | }, 47 | { 48 | "cell_type": "markdown", 49 | "id": "4", 50 | "metadata": {}, 51 | "source": [ 52 | "Pan and zoom to an area of interest and draw a rectangle on the map." 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "5", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "roi = Map.user_roi\n", 63 | "if roi is None:\n", 64 | " roi = ee.Geometry.BBox(117.1132, 3.5227, 117.2214, 3.5843)\n", 65 | " Map.addLayer(roi)\n", 66 | " Map.centerObject(roi)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "6", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "timelapse = geemap.sentinel1_timelapse(\n", 77 | " roi,\n", 78 | " out_gif=\"sentinel1.gif\",\n", 79 | " start_year=2019,\n", 80 | " end_year=2019,\n", 81 | " start_date=\"04-01\",\n", 82 | " end_date=\"08-01\",\n", 83 | " frequency=\"day\",\n", 84 | " vis_params={\"min\": -30, \"max\": 0},\n", 85 | " palette=\"Greys\",\n", 86 | " frames_per_second=3,\n", 87 | " title=\"Sentinel-1 Timelapse\",\n", 88 | " add_colorbar=True,\n", 89 | " colorbar_bg_color=\"gray\",\n", 90 | ")" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "id": "7", 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "geemap.show_image(timelapse)" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "id": "8", 106 | "metadata": {}, 107 | "source": [ 108 | "![](https://i.imgur.com/FlhvI46.gif)" 109 | ] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 5 121 | } 122 | -------------------------------------------------------------------------------- /docs/notebooks/126_inspector.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "**Using the improved Inspector GUI**" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install -U geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "Map = geemap.Map(center=[40, -100], zoom=4)\n", 42 | "\n", 43 | "dem = ee.Image(\"USGS/SRTMGL1_003\")\n", 44 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\").select(\"B[1-7]\")\n", 45 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 46 | "\n", 47 | "vis_params = {\n", 48 | " \"min\": 0,\n", 49 | " \"max\": 4000,\n", 50 | " \"palette\": \"terrain\",\n", 51 | "}\n", 52 | "Map.addLayer(dem, vis_params, \"SRTM DEM\")\n", 53 | "Map.addLayer(\n", 54 | " landsat7,\n", 55 | " {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2.0},\n", 56 | " \"Landsat 7\",\n", 57 | ")\n", 58 | "Map.addLayer(states, {}, \"US States\")\n", 59 | "Map" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "id": "4", 66 | "metadata": {}, 67 | "outputs": [], 68 | "source": [ 69 | "image = ee.Image(\"LANDSAT/LC09/C02/T1_L2/LC09_023031_20220617\")\n", 70 | "geemap.get_info(image)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "id": "5", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "geemap.get_info(states.first(), opened=True)" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "id": "6", 86 | "metadata": {}, 87 | "source": [ 88 | "![](https://i.imgur.com/8OR5BNe.gif)" 89 | ] 90 | } 91 | ], 92 | "metadata": { 93 | "kernelspec": { 94 | "display_name": "Python 3", 95 | "language": "python", 96 | "name": "python3" 97 | } 98 | }, 99 | "nbformat": 4, 100 | "nbformat_minor": 5 101 | } 102 | -------------------------------------------------------------------------------- /docs/notebooks/134_ee_to_geotiff.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "**Download Earth Engine map tiles as a GeoTIFF**\n", 11 | "\n", 12 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "id": "1", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "# !pip install -U geemap" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "id": "2", 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "import ee\n", 33 | "import geemap" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "id": "3", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "Map = geemap.Map()\n", 44 | "point = ee.Geometry.Point(-99.2222, 46.7816)\n", 45 | "collection = (\n", 46 | " ee.ImageCollection(\"USDA/NAIP/DOQQ\")\n", 47 | " .filterBounds(point)\n", 48 | " .filterDate(\"2008-01-01\", \"2018-01-01\")\n", 49 | " .filter(ee.Filter.listContains(\"system:band_names\", \"N\"))\n", 50 | ")\n", 51 | "image = collection.first()\n", 52 | "Map.addLayer(image, {}, \"NAIP\")\n", 53 | "Map.centerObject(image)\n", 54 | "Map" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "id": "4", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "geemap.ee_to_geotiff(\n", 65 | " image, \"naip.tif\", resolution=5, vis_params={\"bands\": [\"N\", \"R\", \"G\"]}\n", 66 | ")" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "5", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "Map = geemap.Map()\n", 77 | "\n", 78 | "image = ee.Image(\"LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318\").select(\n", 79 | " [\"B5\", \"B4\", \"B3\"]\n", 80 | ")\n", 81 | "\n", 82 | "vis_params = {\"min\": 0, \"max\": 0.5, \"gamma\": [0.95, 1.1, 1]}\n", 83 | "\n", 84 | "Map.centerObject(image)\n", 85 | "Map.addLayer(image, vis_params, \"Landsat\")\n", 86 | "Map" 87 | ] 88 | }, 89 | { 90 | "cell_type": "code", 91 | "execution_count": null, 92 | "id": "6", 93 | "metadata": {}, 94 | "outputs": [], 95 | "source": [ 96 | "bbox = Map.user_roi_coords()\n", 97 | "if bbox is None:\n", 98 | " bbox = [-122.5955, 37.5339, -122.0982, 37.8252]" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "id": "7", 105 | "metadata": {}, 106 | "outputs": [], 107 | "source": [ 108 | "geemap.ee_to_geotiff(image, \"landsat.tif\", bbox, vis_params, resolution=30)" 109 | ] 110 | } 111 | ], 112 | "metadata": { 113 | "kernelspec": { 114 | "display_name": "Python 3", 115 | "language": "python", 116 | "name": "python3" 117 | } 118 | }, 119 | "nbformat": 4, 120 | "nbformat_minor": 5 121 | } 122 | -------------------------------------------------------------------------------- /docs/notebooks/19_search_places_and_datasets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "geemap.show_youtube(\"lwtgzrHrXj8\")" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "4", 47 | "metadata": {}, 48 | "source": [ 49 | "## Update the geemap package\n", 50 | "\n", 51 | "If you run into errors with this notebook, please uncomment the line below to update the [geemap](https://github.com/gee-community/geemap#installation) package to the latest version from GitHub. \n", 52 | "Restart the Kernel (Menu -> Kernel -> Restart) to take effect." 53 | ] 54 | }, 55 | { 56 | "cell_type": "code", 57 | "execution_count": null, 58 | "id": "5", 59 | "metadata": {}, 60 | "outputs": [], 61 | "source": [ 62 | "# geemap.update_package()" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "id": "6", 68 | "metadata": {}, 69 | "source": [ 70 | "## Create an interactive map" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "id": "7", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "Map = geemap.Map()\n", 81 | "Map" 82 | ] 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "id": "8", 87 | "metadata": {}, 88 | "source": [ 89 | "## Convert marker to ee.Geometry" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "id": "9", 96 | "metadata": {}, 97 | "outputs": [], 98 | "source": [ 99 | "Map.search_locations" 100 | ] 101 | }, 102 | { 103 | "cell_type": "code", 104 | "execution_count": null, 105 | "id": "10", 106 | "metadata": {}, 107 | "outputs": [], 108 | "source": [ 109 | "Map.search_loc_geom" 110 | ] 111 | }, 112 | { 113 | "cell_type": "code", 114 | "execution_count": null, 115 | "id": "11", 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [ 119 | "location = Map.search_loc_geom\n", 120 | "# print(location.getInfo())" 121 | ] 122 | } 123 | ], 124 | "metadata": { 125 | "kernelspec": { 126 | "display_name": "Python 3", 127 | "language": "python", 128 | "name": "python3" 129 | } 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 5 133 | } 134 | -------------------------------------------------------------------------------- /docs/notebooks/22_import_scripts.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "Map = geemap.Map()\n", 42 | "Map" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "id": "4", 49 | "metadata": {}, 50 | "outputs": [], 51 | "source": [ 52 | "geemap.ee_search()" 53 | ] 54 | } 55 | ], 56 | "metadata": { 57 | "kernelspec": { 58 | "display_name": "Python 3", 59 | "language": "python", 60 | "name": "python3" 61 | } 62 | }, 63 | "nbformat": 4, 64 | "nbformat_minor": 5 65 | } 66 | -------------------------------------------------------------------------------- /docs/notebooks/23_import_assets.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import os\n", 31 | "import ee\n", 32 | "import geemap" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "id": "3", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "Map = geemap.Map()\n", 43 | "Map" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "id": "4", 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "out_dir = os.path.join(os.path.expanduser(\"~\"), \"Downloads\")\n", 54 | "if not os.path.exists(out_dir):\n", 55 | " os.makedirs(out_dir)" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "id": "5", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "out_csv = os.path.join(out_dir, \"ee_api.csv\")\n", 66 | "geemap.ee_api_to_csv(out_csv)" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "6", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "geemap.ee_search()" 77 | ] 78 | } 79 | ], 80 | "metadata": { 81 | "kernelspec": { 82 | "display_name": "Python 3", 83 | "language": "python", 84 | "name": "python3" 85 | } 86 | }, 87 | "nbformat": 4, 88 | "nbformat_minor": 5 89 | } 90 | -------------------------------------------------------------------------------- /docs/notebooks/26_heroku.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import ee\n", 31 | "import geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "3", 37 | "metadata": {}, 38 | "source": [ 39 | "## Earth Engine App" 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "id": "4", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "Map = geemap.Map(center=(40, -100), zoom=4)" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "5", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "# Add Earth Engine dataset\n", 60 | "dem = ee.Image(\"USGS/SRTMGL1_003\")\n", 61 | "landcover = ee.Image(\"ESA/GLOBCOVER_L4_200901_200912_V2_3\").select(\"landcover\")\n", 62 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\")\n", 63 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 64 | "\n", 65 | "# Set visualization parameters.\n", 66 | "vis_params = {\n", 67 | " \"min\": 0,\n", 68 | " \"max\": 4000,\n", 69 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 70 | "}\n", 71 | "\n", 72 | "# Add Earth Engine layers to Map\n", 73 | "Map.addLayer(\n", 74 | " landsat7, {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200}, \"Landsat 7\"\n", 75 | ")\n", 76 | "Map.addLayer(landcover, {}, \"Land cover\")\n", 77 | "Map.addLayer(dem, vis_params, \"SRTM DEM\", True, 1)\n", 78 | "Map.addLayer(states, {}, \"US States\")\n", 79 | "\n", 80 | "Map" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "id": "6", 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "print(\"Change layer opacity:\")\n", 91 | "dem_layer = Map.layers[-2]\n", 92 | "dem_layer.interact(opacity=(0, 1, 0.1))" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Python 3", 99 | "language": "python", 100 | "name": "python3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /docs/notebooks/53_layer_vis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "1", 14 | "metadata": {}, 15 | "source": [ 16 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "id": "2", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# !pip install geemap" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "3", 32 | "metadata": {}, 33 | "source": [ 34 | "# How to change layer visualization interactively with a GUI" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "id": "4", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "import ee\n", 45 | "import geemap" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "5", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# geemap.update_package()" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "id": "6", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "Map = geemap.Map(center=(40, -100), zoom=4)\n", 66 | "\n", 67 | "# Add Earth Engine dataset\n", 68 | "dem = ee.Image(\"USGS/SRTMGL1_003\")\n", 69 | "landcover = ee.Image(\"ESA/GLOBCOVER_L4_200901_200912_V2_3\").select(\"landcover\")\n", 70 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\").select(\n", 71 | " [\"B1\", \"B2\", \"B3\", \"B4\", \"B5\", \"B7\"]\n", 72 | ")\n", 73 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 74 | "\n", 75 | "# Set visualization parameters.\n", 76 | "vis_params = {\n", 77 | " \"min\": 0,\n", 78 | " \"max\": 4000,\n", 79 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 80 | "}\n", 81 | "\n", 82 | "# Add Earth Engine layers to Map\n", 83 | "Map.addLayer(dem, vis_params, \"SRTM DEM\", True, 0.5)\n", 84 | "Map.addLayer(landcover, {}, \"Land cover\")\n", 85 | "Map.addLayer(\n", 86 | " landsat7,\n", 87 | " {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 1.5},\n", 88 | " \"Landsat 7\",\n", 89 | ")\n", 90 | "Map.addLayer(states, {}, \"US States\", False)\n", 91 | "\n", 92 | "Map" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Python 3", 99 | "language": "python", 100 | "name": "python3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /docs/notebooks/55_raster_vis.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "1", 14 | "metadata": {}, 15 | "source": [ 16 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "id": "2", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "# !pip install geemap" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "id": "3", 32 | "metadata": {}, 33 | "source": [ 34 | "# How to visualize Earth Engine raster data interactively with a GUI" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "id": "4", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "import ee\n", 45 | "import geemap" 46 | ] 47 | }, 48 | { 49 | "cell_type": "code", 50 | "execution_count": null, 51 | "id": "5", 52 | "metadata": {}, 53 | "outputs": [], 54 | "source": [ 55 | "# geemap.update_package()" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "execution_count": null, 61 | "id": "6", 62 | "metadata": {}, 63 | "outputs": [], 64 | "source": [ 65 | "Map = geemap.Map(center=(40, -100), zoom=4)\n", 66 | "\n", 67 | "# Add Earth Engine dataset\n", 68 | "dem = ee.Image(\"USGS/SRTMGL1_003\")\n", 69 | "# landcover = ee.Image(\"ESA/GLOBCOVER_L4_200901_200912_V2_3\").select('landcover')\n", 70 | "landsat7 = ee.Image(\"LANDSAT/LE7_TOA_5YEAR/1999_2003\").select(\n", 71 | " [\"B1\", \"B2\", \"B3\", \"B4\", \"B5\", \"B7\"]\n", 72 | ")\n", 73 | "states = ee.FeatureCollection(\"TIGER/2018/States\")\n", 74 | "\n", 75 | "# Set visualization parameters.\n", 76 | "vis_params = {\n", 77 | " \"min\": 0,\n", 78 | " \"max\": 4000,\n", 79 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 80 | "}\n", 81 | "\n", 82 | "# Add Earth Engine layers to Map\n", 83 | "Map.addLayer(dem, vis_params, \"SRTM DEM\", True, 1)\n", 84 | "# Map.addLayer(landcover, {}, 'Land cover')\n", 85 | "Map.addLayer(\n", 86 | " landsat7,\n", 87 | " {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 20, \"max\": 200, \"gamma\": 2},\n", 88 | " \"Landsat 7\",\n", 89 | ")\n", 90 | "Map.addLayer(states, {}, \"US States\", False)\n", 91 | "\n", 92 | "Map" 93 | ] 94 | } 95 | ], 96 | "metadata": { 97 | "kernelspec": { 98 | "display_name": "Python 3", 99 | "language": "python", 100 | "name": "python3" 101 | } 102 | }, 103 | "nbformat": 4, 104 | "nbformat_minor": 5 105 | } 106 | -------------------------------------------------------------------------------- /docs/notebooks/59_whitebox.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import os\n", 31 | "import geemap\n", 32 | "import whiteboxgui" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "id": "3", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "out_dir = os.path.expanduser(\"~/Downloads\")\n", 43 | "dem = os.path.join(out_dir, \"dem.tif\")\n", 44 | "\n", 45 | "if not os.path.exists(dem):\n", 46 | " dem_url = \"https://drive.google.com/file/d/1vRkAWQYsLWCi6vcTMk8vLxoXMFbdMFn8/view?usp=sharing\"\n", 47 | " geemap.download_file(dem_url, \"dem.tif\", out_dir, unzip=False)" 48 | ] 49 | }, 50 | { 51 | "cell_type": "code", 52 | "execution_count": null, 53 | "id": "4", 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "Map = geemap.Map()\n", 58 | "Map" 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": null, 64 | "id": "5", 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "whiteboxgui.show()" 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": null, 74 | "id": "6", 75 | "metadata": {}, 76 | "outputs": [], 77 | "source": [ 78 | "whiteboxgui.show(tree=True)" 79 | ] 80 | } 81 | ], 82 | "metadata": { 83 | "kernelspec": { 84 | "display_name": "Python 3", 85 | "language": "python", 86 | "name": "python3" 87 | } 88 | }, 89 | "nbformat": 4, 90 | "nbformat_minor": 5 91 | } 92 | -------------------------------------------------------------------------------- /docs/notebooks/67_training_samples.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import ee\n", 11 | "import geemap" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "id": "1", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "geemap.show_youtube(\"https://youtu.be/VWh5PxXPZw0\")" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "Map = geemap.Map()\n", 32 | "Map" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "execution_count": null, 38 | "id": "3", 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "if Map.user_rois is not None:\n", 43 | " training_samples = Map.user_rois\n", 44 | " print(training_samples.getInfo())" 45 | ] 46 | } 47 | ], 48 | "metadata": { 49 | "kernelspec": { 50 | "display_name": "Python 3", 51 | "language": "python", 52 | "name": "python3" 53 | } 54 | }, 55 | "nbformat": 4, 56 | "nbformat_minor": 5 57 | } 58 | -------------------------------------------------------------------------------- /docs/notebooks/68_netcdf_to_ee.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "Uncomment the following line to install [geemap](https://geemap.org) if needed.\n", 9 | "\n", 10 | "You will also need to install the following package:\n", 11 | "- `xarray`" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "id": "1", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "# !pip install geemap" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "import os\n", 32 | "import ee\n", 33 | "import geemap\n", 34 | "import geemap.colormaps as cm" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "execution_count": null, 40 | "id": "3", 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "geemap.ee_initialize()" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "id": "4", 51 | "metadata": {}, 52 | "outputs": [], 53 | "source": [ 54 | "nc_file = \"../data/wind_global.nc\"" 55 | ] 56 | }, 57 | { 58 | "cell_type": "code", 59 | "execution_count": null, 60 | "id": "5", 61 | "metadata": {}, 62 | "outputs": [], 63 | "source": [ 64 | "if not os.path.exists(nc_file):\n", 65 | " url = \"https://github.com/gee-community/geemap/blob/master/examples/data/wind_global.nc\"\n", 66 | " import requests\n", 67 | "\n", 68 | " r = requests.get(url)\n", 69 | " wind_data = r.content\n", 70 | " with open(\"wind_global.nc\", \"wb\") as f:\n", 71 | " f.write(wind_data)" 72 | ] 73 | }, 74 | { 75 | "cell_type": "code", 76 | "execution_count": null, 77 | "id": "6", 78 | "metadata": {}, 79 | "outputs": [], 80 | "source": [ 81 | "# Test with only one variable\n", 82 | "img = geemap.netcdf_to_ee(nc_file=nc_file, var_names=\"u_wind\")\n", 83 | "palette = cm.palettes.YlOrRd\n", 84 | "\n", 85 | "Map = geemap.Map()\n", 86 | "Map.addLayer(img, {\"min\": -20, \"max\": 25, \"palette\": palette, \"opacity\": 0.6}, \"u_wind\")\n", 87 | "Map" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": null, 93 | "id": "7", 94 | "metadata": {}, 95 | "outputs": [], 96 | "source": [ 97 | "# Test with two variables\n", 98 | "img2 = geemap.netcdf_to_ee(nc_file=nc_file, var_names=[\"u_wind\", \"v_wind\"])\n", 99 | "Map2 = geemap.Map()\n", 100 | "Map2.addLayer(\n", 101 | " img2,\n", 102 | " {\"bands\": [\"u_wind\"], \"min\": -20, \"max\": 25, \"palette\": palette, \"opacity\": 0.6},\n", 103 | " \"uv_wind\",\n", 104 | ")\n", 105 | "Map2" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 5 118 | } 119 | -------------------------------------------------------------------------------- /docs/notebooks/70_linked_maps.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# !pip install geemap" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import ee\n", 21 | "import geemap" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "# geemap.update_package()" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "geemap.ee_initialize()" 42 | ] 43 | }, 44 | { 45 | "cell_type": "code", 46 | "execution_count": null, 47 | "id": "4", 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "geemap.linked_maps(rows=1, cols=2, height=\"400px\", center=[38.4151, 21.2712], zoom=12)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "id": "5", 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [ 61 | "image = (\n", 62 | " ee.ImageCollection(\"COPERNICUS/S2\")\n", 63 | " .filterDate(\"2018-09-01\", \"2018-09-30\")\n", 64 | " .map(lambda img: img.divide(10000))\n", 65 | " .median()\n", 66 | ")" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": null, 72 | "id": "6", 73 | "metadata": {}, 74 | "outputs": [], 75 | "source": [ 76 | "vis_params = [\n", 77 | " {\"bands\": [\"B4\", \"B3\", \"B2\"], \"min\": 0, \"max\": 0.3, \"gamma\": 1.3},\n", 78 | " {\"bands\": [\"B8\", \"B11\", \"B4\"], \"min\": 0, \"max\": 0.3, \"gamma\": 1.3},\n", 79 | " {\"bands\": [\"B8\", \"B4\", \"B3\"], \"min\": 0, \"max\": 0.3, \"gamma\": 1.3},\n", 80 | " {\"bands\": [\"B12\", \"B12\", \"B4\"], \"min\": 0, \"max\": 0.3, \"gamma\": 1.3},\n", 81 | "]" 82 | ] 83 | }, 84 | { 85 | "cell_type": "code", 86 | "execution_count": null, 87 | "id": "7", 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "labels = [\n", 92 | " \"Natural Color (B4/B3/B2)\",\n", 93 | " \"Land/Water (B8/B11/B4)\",\n", 94 | " \"Color Infrared (B8/B4/B3)\",\n", 95 | " \"Vegetation (B12/B11/B4)\",\n", 96 | "]" 97 | ] 98 | }, 99 | { 100 | "cell_type": "code", 101 | "execution_count": null, 102 | "id": "8", 103 | "metadata": {}, 104 | "outputs": [], 105 | "source": [ 106 | "geemap.linked_maps(\n", 107 | " rows=2,\n", 108 | " cols=2,\n", 109 | " height=\"400px\",\n", 110 | " center=[38.4151, 21.2712],\n", 111 | " zoom=12,\n", 112 | " ee_objects=[image],\n", 113 | " vis_params=vis_params,\n", 114 | " labels=labels,\n", 115 | " label_position=\"topright\",\n", 116 | ")" 117 | ] 118 | } 119 | ], 120 | "metadata": { 121 | "kernelspec": { 122 | "display_name": "Python 3", 123 | "language": "python", 124 | "name": "python3" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 5 129 | } 130 | -------------------------------------------------------------------------------- /docs/notebooks/71_timelapse.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "Try it out: " 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "id": "1", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "import ee\n", 19 | "import geemap" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "id": "2", 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "# geemap.update_package()" 30 | ] 31 | }, 32 | { 33 | "cell_type": "code", 34 | "execution_count": null, 35 | "id": "3", 36 | "metadata": {}, 37 | "outputs": [], 38 | "source": [ 39 | "Map = geemap.Map()\n", 40 | "Map" 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "id": "4", 46 | "metadata": {}, 47 | "source": [ 48 | "![](https://i.imgur.com/adwTxEo.png)" 49 | ] 50 | } 51 | ], 52 | "metadata": { 53 | "kernelspec": { 54 | "display_name": "Python 3", 55 | "language": "python", 56 | "name": "python3" 57 | } 58 | }, 59 | "nbformat": 4, 60 | "nbformat_minor": 5 61 | } 62 | -------------------------------------------------------------------------------- /docs/notebooks/72_time_slider_gui.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import ee\n", 11 | "import geemap" 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "id": "1", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "# geemap.update_package()" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "Map = geemap.Map(center=[37.75, -122.45], zoom=12)\n", 32 | "\n", 33 | "S2 = (\n", 34 | " ee.ImageCollection(\"COPERNICUS/S2_SR\")\n", 35 | " .filterBounds(ee.Geometry.Point([-122.45, 37.75]))\n", 36 | " .filterMetadata(\"CLOUDY_PIXEL_PERCENTAGE\", \"less_than\", 10)\n", 37 | ")\n", 38 | "\n", 39 | "vis_params = {\"min\": 0, \"max\": 4000, \"bands\": [\"B8\", \"B4\", \"B3\"]}\n", 40 | "\n", 41 | "Map.addLayer(S2, {}, \"Sentinel-2\", False)\n", 42 | "Map.add_time_slider(S2, vis_params)\n", 43 | "Map" 44 | ] 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "id": "3", 49 | "metadata": {}, 50 | "source": [ 51 | "![](https://i.imgur.com/UTVk9EJ.png)" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "id": "4", 58 | "metadata": {}, 59 | "outputs": [], 60 | "source": [] 61 | } 62 | ], 63 | "metadata": { 64 | "kernelspec": { 65 | "display_name": "Python 3", 66 | "language": "python", 67 | "name": "python3" 68 | } 69 | }, 70 | "nbformat": 4, 71 | "nbformat_minor": 5 72 | } 73 | -------------------------------------------------------------------------------- /docs/notebooks/73_transect.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import ee\n", 11 | "import geemap\n", 12 | "from bqplot import pyplot as plt" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "id": "1", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "Map = geemap.Map()\n", 23 | "Map.add_basemap(\"TERRAIN\")\n", 24 | "Map" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "id": "2", 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "image = ee.Image(\"USGS/SRTMGL1_003\")\n", 35 | "vis_params = {\n", 36 | " \"min\": 0,\n", 37 | " \"max\": 4000,\n", 38 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 39 | "}\n", 40 | "Map.addLayer(image, vis_params, \"SRTM DEM\", True, 0.5)" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "id": "3", 47 | "metadata": {}, 48 | "outputs": [], 49 | "source": [ 50 | "# Use the drawing tool to draw any line on the map.\n", 51 | "line = Map.user_roi\n", 52 | "if line is None:\n", 53 | " line = ee.Geometry.LineString(\n", 54 | " [[-120.223279, 36.314849], [-118.926969, 36.712192], [-117.202217, 36.756215]]\n", 55 | " )\n", 56 | " Map.addLayer(line, {}, \"ROI\")\n", 57 | "Map.centerObject(line)" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "id": "4", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "line.getInfo()" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "id": "5", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [ 77 | "reducer = \"mean\" # Any ee.Reducer, e.g., mean, median, min, max, stdDev\n", 78 | "transect = geemap.extract_transect(\n", 79 | " image, line, n_segments=100, reducer=reducer, to_pandas=True\n", 80 | ")" 81 | ] 82 | }, 83 | { 84 | "cell_type": "code", 85 | "execution_count": null, 86 | "id": "6", 87 | "metadata": {}, 88 | "outputs": [], 89 | "source": [ 90 | "transect" 91 | ] 92 | }, 93 | { 94 | "cell_type": "code", 95 | "execution_count": null, 96 | "id": "7", 97 | "metadata": {}, 98 | "outputs": [], 99 | "source": [ 100 | "fig = plt.figure()\n", 101 | "plt.plot(transect[\"distance\"], transect[reducer])\n", 102 | "plt.xlabel(\"Distance\")\n", 103 | "plt.ylabel(\"Elevation\")\n", 104 | "plt.show()" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python 3", 111 | "language": "python", 112 | "name": "python3" 113 | } 114 | }, 115 | "nbformat": 4, 116 | "nbformat_minor": 5 117 | } 118 | -------------------------------------------------------------------------------- /docs/notebooks/75_sankee.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "# !pip install geemap" 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "import ee\n", 21 | "import geemap" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "Map = geemap.Map()\n", 32 | "Map" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "id": "3", 38 | "metadata": {}, 39 | "source": [ 40 | "![](https://i.imgur.com/N7ah30J.png)" 41 | ] 42 | } 43 | ], 44 | "metadata": { 45 | "kernelspec": { 46 | "display_name": "Python 3", 47 | "language": "python", 48 | "name": "python3" 49 | } 50 | }, 51 | "nbformat": 4, 52 | "nbformat_minor": 5 53 | } 54 | -------------------------------------------------------------------------------- /docs/notebooks/80_point_layer.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/gee-community/geemap/blob/master/docs/notebooks/80_point_layer.ipynb)" 9 | ] 10 | }, 11 | { 12 | "cell_type": "markdown", 13 | "id": "1", 14 | "metadata": {}, 15 | "source": [ 16 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 17 | ] 18 | }, 19 | { 20 | "cell_type": "code", 21 | "execution_count": null, 22 | "id": "2", 23 | "metadata": {}, 24 | "outputs": [], 25 | "source": [ 26 | "import geemap" 27 | ] 28 | }, 29 | { 30 | "cell_type": "code", 31 | "execution_count": null, 32 | "id": "3", 33 | "metadata": {}, 34 | "outputs": [], 35 | "source": [ 36 | "# geemap.update_package()" 37 | ] 38 | }, 39 | { 40 | "cell_type": "code", 41 | "execution_count": null, 42 | "id": "4", 43 | "metadata": {}, 44 | "outputs": [], 45 | "source": [ 46 | "m = geemap.Map()" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "execution_count": null, 52 | "id": "5", 53 | "metadata": {}, 54 | "outputs": [], 55 | "source": [ 56 | "url = \"https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/us_cities.geojson\"" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "execution_count": null, 62 | "id": "6", 63 | "metadata": {}, 64 | "outputs": [], 65 | "source": [ 66 | "m.add_point_layer(url, popup=[\"name\", \"pop_max\"], layer_name=\"US Cities\")\n", 67 | "m" 68 | ] 69 | } 70 | ], 71 | "metadata": { 72 | "kernelspec": { 73 | "display_name": "Python 3", 74 | "language": "python", 75 | "name": "python3" 76 | } 77 | }, 78 | "nbformat": 4, 79 | "nbformat_minor": 5 80 | } 81 | -------------------------------------------------------------------------------- /docs/notebooks/82_contours.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": null, 6 | "id": "0", 7 | "metadata": {}, 8 | "outputs": [], 9 | "source": [ 10 | "import ee\n", 11 | "import geemap\n", 12 | "import geemap.colormaps as cm" 13 | ] 14 | }, 15 | { 16 | "cell_type": "code", 17 | "execution_count": null, 18 | "id": "1", 19 | "metadata": {}, 20 | "outputs": [], 21 | "source": [ 22 | "# geemap.update_package()" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "execution_count": null, 28 | "id": "2", 29 | "metadata": {}, 30 | "outputs": [], 31 | "source": [ 32 | "Map = geemap.Map()\n", 33 | "Map" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": null, 39 | "id": "3", 40 | "metadata": {}, 41 | "outputs": [], 42 | "source": [ 43 | "image = ee.Image(\"USGS/SRTMGL1_003\")" 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": null, 49 | "id": "4", 50 | "metadata": {}, 51 | "outputs": [], 52 | "source": [ 53 | "hillshade = ee.Terrain.hillshade(image)" 54 | ] 55 | }, 56 | { 57 | "cell_type": "code", 58 | "execution_count": null, 59 | "id": "5", 60 | "metadata": {}, 61 | "outputs": [], 62 | "source": [ 63 | "Map.addLayer(hillshade, {}, \"Hillshade\")" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": null, 69 | "id": "6", 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "Map.addLayer(\n", 74 | " image, {\"min\": 0, \"max\": 5000, \"palette\": cm.palettes.dem}, \"dem\", True, 0.5\n", 75 | ")" 76 | ] 77 | }, 78 | { 79 | "cell_type": "code", 80 | "execution_count": null, 81 | "id": "7", 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "contours = geemap.create_contours(image, 0, 5000, 100, region=None)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "id": "8", 92 | "metadata": {}, 93 | "outputs": [], 94 | "source": [ 95 | "Map.addLayer(\n", 96 | " contours, {\"min\": 0, \"max\": 5000, \"palette\": cm.palettes.terrain}, \"contours\"\n", 97 | ")" 98 | ] 99 | }, 100 | { 101 | "cell_type": "markdown", 102 | "id": "9", 103 | "metadata": {}, 104 | "source": [ 105 | "![](https://i.imgur.com/c9UZ9HP.png)" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | } 115 | }, 116 | "nbformat": 4, 117 | "nbformat_minor": 5 118 | } 119 | -------------------------------------------------------------------------------- /docs/notebooks/87_add_points_from_xy.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "\"Open\n", 9 | "\n", 10 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 11 | ] 12 | }, 13 | { 14 | "cell_type": "code", 15 | "execution_count": null, 16 | "id": "1", 17 | "metadata": {}, 18 | "outputs": [], 19 | "source": [ 20 | "# !pip install geemap" 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": null, 26 | "id": "2", 27 | "metadata": {}, 28 | "outputs": [], 29 | "source": [ 30 | "import geemap\n", 31 | "import pandas as pd" 32 | ] 33 | }, 34 | { 35 | "cell_type": "code", 36 | "execution_count": null, 37 | "id": "3", 38 | "metadata": {}, 39 | "outputs": [], 40 | "source": [ 41 | "# geemap.update_package()" 42 | ] 43 | }, 44 | { 45 | "cell_type": "markdown", 46 | "id": "4", 47 | "metadata": {}, 48 | "source": [ 49 | "Using a CSV file containing xy coordinates" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": null, 55 | "id": "5", 56 | "metadata": {}, 57 | "outputs": [], 58 | "source": [ 59 | "m = geemap.Map()\n", 60 | "data = \"https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/us_cities.csv\"\n", 61 | "m.add_points_from_xy(data, x=\"longitude\", y=\"latitude\")\n", 62 | "m" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "id": "6", 68 | "metadata": {}, 69 | "source": [ 70 | "Using a Pandas DataFrame containing xy coordinates." 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "execution_count": null, 76 | "id": "7", 77 | "metadata": {}, 78 | "outputs": [], 79 | "source": [ 80 | "m = geemap.Map()\n", 81 | "data = \"https://raw.githubusercontent.com/giswqs/leafmap/master/examples/data/us_cities.csv\"\n", 82 | "df = pd.read_csv(data)\n", 83 | "m.add_points_from_xy(df, x=\"longitude\", y=\"latitude\")\n", 84 | "m" 85 | ] 86 | } 87 | ], 88 | "metadata": { 89 | "kernelspec": { 90 | "display_name": "Python 3", 91 | "language": "python", 92 | "name": "python3" 93 | } 94 | }, 95 | "nbformat": 4, 96 | "nbformat_minor": 5 97 | } 98 | -------------------------------------------------------------------------------- /docs/notebooks/88_circle_markers.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "0", 6 | "metadata": {}, 7 | "source": [ 8 | "[![image](https://colab.research.google.com/assets/colab-badge.svg)](https://githubtocolab.com/gee-community/geemap/blob/master/docs/notebooks/88_circle_markers.ipynb)\n", 9 | "[![image](https://mybinder.org/badge_logo.svg)](https://gishub.org/geemap-binder)\n", 10 | "\n", 11 | "Uncomment the following line to install [geemap](https://geemap.org) if needed." 12 | ] 13 | }, 14 | { 15 | "cell_type": "code", 16 | "execution_count": null, 17 | "id": "1", 18 | "metadata": {}, 19 | "outputs": [], 20 | "source": [ 21 | "# !pip install geemap" 22 | ] 23 | }, 24 | { 25 | "cell_type": "code", 26 | "execution_count": null, 27 | "id": "2", 28 | "metadata": {}, 29 | "outputs": [], 30 | "source": [ 31 | "import geemap.foliumap as geemap" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "id": "3", 37 | "metadata": {}, 38 | "source": [ 39 | "If you are using a recently implemented geemap feature that has not yet been released to PyPI or conda-forge, you can uncomment the following line to install the development version from GitHub." 40 | ] 41 | }, 42 | { 43 | "cell_type": "code", 44 | "execution_count": null, 45 | "id": "4", 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "# geemap.update_package()" 50 | ] 51 | }, 52 | { 53 | "cell_type": "markdown", 54 | "id": "5", 55 | "metadata": {}, 56 | "source": [ 57 | "For a list of options for circle markers, see https://ipyleaflet.readthedocs.io/en/latest/api_reference/circle_marker.html" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "id": "6", 64 | "metadata": {}, 65 | "outputs": [], 66 | "source": [ 67 | "m = geemap.Map()\n", 68 | "data = \"https://raw.githubusercontent.com/gee-community/geemap/master/examples/data/us_cities.csv\"\n", 69 | "m.add_circle_markers_from_xy(\n", 70 | " data, x=\"longitude\", y=\"latitude\", radius=10, color=\"blue\", fill_color=\"black\"\n", 71 | ")\n", 72 | "m" 73 | ] 74 | } 75 | ], 76 | "metadata": { 77 | "kernelspec": { 78 | "display_name": "Python 3", 79 | "language": "python", 80 | "name": "python3" 81 | } 82 | }, 83 | "nbformat": 4, 84 | "nbformat_minor": 5 85 | } 86 | -------------------------------------------------------------------------------- /docs/osm.md: -------------------------------------------------------------------------------- 1 | # osm module 2 | 3 | ::: geemap.osm 4 | -------------------------------------------------------------------------------- /docs/overrides/main.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | 3 | {% block content %} 4 | {% if page.nb_url %} 5 | 6 | {% include ".icons/material/download.svg" %} 7 | 8 | {% endif %} 9 | 10 | {{ super() }} 11 | {% endblock content %} 12 | -------------------------------------------------------------------------------- /docs/plot.md: -------------------------------------------------------------------------------- 1 | # plot module 2 | 3 | ::: geemap.plot 4 | -------------------------------------------------------------------------------- /docs/plotlymap.md: -------------------------------------------------------------------------------- 1 | # plotlymap module 2 | 3 | ::: geemap.plotlymap -------------------------------------------------------------------------------- /docs/report.md: -------------------------------------------------------------------------------- 1 | # report module 2 | 3 | ::: geemap.report 4 | -------------------------------------------------------------------------------- /docs/search_bk.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Search 5 | 6 | 7 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /docs/search_docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Search 5 | 6 | 7 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/timelapse.md: -------------------------------------------------------------------------------- 1 | # timelapse module 2 | 3 | ::: geemap.timelapse 4 | -------------------------------------------------------------------------------- /docs/toolbar.md: -------------------------------------------------------------------------------- 1 | # toolbar module 2 | 3 | ::: geemap.toolbar 4 | -------------------------------------------------------------------------------- /docs/workshops/.jupytext.toml: -------------------------------------------------------------------------------- 1 | # Install jupytext using: conda install jupytext -c conda-forge 2 | # Always pair ipynb notebooks to md files. 3 | # formats = "ipynb,md" 4 | formats = "ipynb,myst" 5 | 6 | # jupytext --to ipynb *.md # convert all .md files to notebooks with no outputs 7 | # jupytext --to ipynb --execute *.md # convert all .md files to notebooks and execute them 8 | # jupytext --set-formats ipynb,md --execute *.md # convert all .md files to paired notebooks and execute them 9 | # jupytext --to md *.ipynb # convert all .ipynb files to .md files 10 | # jupytext --to myst *.ipynb # convert all .ipynb files to myst files 11 | 12 | # convert notebooks to rst https://nbconvert.readthedocs.io/en/latest/usage.html#convert-rst 13 | # jupyter nbconvert *.ipynb --to rst 14 | # convert md to rst: m2r *.md 15 | -------------------------------------------------------------------------------- /docs/workshops/jupytext.toml: -------------------------------------------------------------------------------- 1 | # Install jupytext using: conda install jupytext -c conda-forge 2 | # Always pair ipynb notebooks to md files. 3 | # formats = "ipynb,md" 4 | formats = "ipynb,myst" 5 | 6 | # jupytext --to ipynb *.md # convert all .md files to notebooks with no outputs 7 | # jupytext --to ipynb --execute *.md # convert all .md files to notebooks and execute them 8 | # jupytext --set-formats ipynb,md --execute *.md # convert all .md files to paired notebooks and execute them 9 | # jupytext --to md *.ipynb # convert all .ipynb files to .md files 10 | # jupytext --to myst *.ipynb # convert all .ipynb files to myst files 11 | 12 | # convert notebooks to rst https://nbconvert.readthedocs.io/en/latest/usage.html#convert-rst 13 | # jupyter nbconvert *.ipynb --to rst 14 | # convert md to rst: m2r *.md 15 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: geo-env 2 | channels: 3 | - conda-forge 4 | dependencies: 5 | - cartopy 6 | - datapane 7 | - flask>=2.0.0 8 | - flask-caching 9 | - gdal 10 | - geemap>=0.20.0 11 | - geopandas 12 | - imageio 13 | - ipyvtklink 14 | - keplergl 15 | - laspy 16 | - leafmap>=0.18.0 17 | - localtileserver>=0.4.0 18 | - osmnx 19 | - pip 20 | - pydeck 21 | - pyntcloud 22 | - python>=3.9 23 | - pyvista 24 | - requests 25 | - rio-cogeo 26 | - tifffile 27 | -------------------------------------------------------------------------------- /examples/data/animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/animation.gif -------------------------------------------------------------------------------- /examples/data/charts_feature_example.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/charts_feature_example.dbf -------------------------------------------------------------------------------- /examples/data/charts_feature_example.fix: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /examples/data/charts_feature_example.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["WGS 84", DATUM["World Geodetic System 1984", SPHEROID["WGS 84", 6378137.0, 298.257223563, AUTHORITY["EPSG","7030"]], AUTHORITY["EPSG","6326"]], PRIMEM["Greenwich", 0.0, AUTHORITY["EPSG","8901"]], UNIT["degree", 0.017453292519943295], AXIS["Geodetic longitude", EAST], AXIS["Geodetic latitude", NORTH], AUTHORITY["EPSG","4326"]] -------------------------------------------------------------------------------- /examples/data/charts_feature_example.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/charts_feature_example.shp -------------------------------------------------------------------------------- /examples/data/charts_feature_example.shp.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /examples/data/charts_feature_example.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/charts_feature_example.shx -------------------------------------------------------------------------------- /examples/data/countries.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /examples/data/countries.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/countries.dbf -------------------------------------------------------------------------------- /examples/data/countries.gpkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/countries.gpkg -------------------------------------------------------------------------------- /examples/data/countries.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]] -------------------------------------------------------------------------------- /examples/data/countries.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/countries.shp -------------------------------------------------------------------------------- /examples/data/countries.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/countries.shx -------------------------------------------------------------------------------- /examples/data/countries.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/countries.zip -------------------------------------------------------------------------------- /examples/data/ee_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/ee_logo.png -------------------------------------------------------------------------------- /examples/data/noaa_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/noaa_logo.jpg -------------------------------------------------------------------------------- /examples/data/rwc_batch_input.csv: -------------------------------------------------------------------------------- 1 | LANDSAT_ID,Point_ID,Latitude,Longitude 2 | LT05_L1TP_017036_20060502_20160910_01_T1,2166501,34.16763036,-81.9078923 3 | LT05_L1TP_017036_20060502_20160910_01_T1,2167000,34.17457619,-81.864002 4 | LT05_L1TP_017036_20061212_20160908_01_T1,2148000,34.24459385,-80.6539697 -------------------------------------------------------------------------------- /examples/data/temperature.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/temperature.gif -------------------------------------------------------------------------------- /examples/data/us_cities.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /examples/data/us_cities.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_cities.dbf -------------------------------------------------------------------------------- /examples/data/us_cities.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /examples/data/us_cities.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_cities.shp -------------------------------------------------------------------------------- /examples/data/us_cities.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_cities.shx -------------------------------------------------------------------------------- /examples/data/us_states.cpg: -------------------------------------------------------------------------------- 1 | UTF-8 -------------------------------------------------------------------------------- /examples/data/us_states.dbf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_states.dbf -------------------------------------------------------------------------------- /examples/data/us_states.kmz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_states.kmz -------------------------------------------------------------------------------- /examples/data/us_states.prj: -------------------------------------------------------------------------------- 1 | GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]] -------------------------------------------------------------------------------- /examples/data/us_states.shp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_states.shp -------------------------------------------------------------------------------- /examples/data/us_states.shx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/us_states.shx -------------------------------------------------------------------------------- /examples/data/wind_global.nc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/examples/data/wind_global.nc -------------------------------------------------------------------------------- /examples/javascripts/ClippedComposite.js: -------------------------------------------------------------------------------- 1 | // Composite an image collection and clip it to a boundary. 2 | 3 | // Load Landsat 7 raw imagery and filter it to April-July 2000. 4 | var collection = ee.ImageCollection('LANDSAT/LE07/C01/T1') 5 | .filterDate('2000-04-01', '2000-07-01'); 6 | 7 | // Reduce the collection by taking the median. 8 | var median = collection.median(); 9 | 10 | // Load a table of state boundaries and filter. 11 | var fc = ee.FeatureCollection('TIGER/2016/States') 12 | .filter(ee.Filter.or( 13 | ee.Filter.eq('NAME', 'Nevada'), 14 | ee.Filter.eq('NAME', 'Arizona'))); 15 | 16 | // Clip to the output image to the Nevada and Arizona state boundaries. 17 | var clipped = median.clipToCollection(fc); 18 | 19 | // Display the result. 20 | Map.setCenter(-110, 40, 5); 21 | var visParams = {bands: ['B3', 'B2', 'B1'], gain: [1.4, 1.4, 1.1]}; 22 | Map.addLayer(clipped, visParams, 'clipped composite'); 23 | -------------------------------------------------------------------------------- /examples/javascripts/FromName.js: -------------------------------------------------------------------------------- 1 | // Display an image given its ID. 2 | 3 | var image = ee.Image('CGIAR/SRTM90_V4'); 4 | // Center the Map. 5 | Map.setCenter(-110, 40, 5); 6 | // Display the image. 7 | Map.addLayer(image, {min: 0, max: 3000}, 'SRTM'); 8 | -------------------------------------------------------------------------------- /examples/javascripts/ModisQaBands.js: -------------------------------------------------------------------------------- 1 | // Extract MODIS QA information from the "state_1km" QA band 2 | // and use it to mask out cloudy and deep ocean areas. 3 | // 4 | // QA Band information is available at: 5 | // https://lpdaac.usgs.gov/products/modis_products_table/mod09ga 6 | // Table 1: 1-kilometer State QA Descriptions (16-bit) 7 | 8 | 9 | /** 10 | * Returns an image containing just the specified QA bits. 11 | * 12 | * Args: 13 | * image - The QA Image to get bits from. 14 | * start - The first bit position, 0-based. 15 | * end - The last bit position, inclusive. 16 | * name - A name for the output image. 17 | */ 18 | var getQABits = function(image, start, end, newName) { 19 | // Compute the bits we need to extract. 20 | var pattern = 0; 21 | for (var i = start; i <= end; i++) { 22 | pattern += Math.pow(2, i); 23 | } 24 | return image.select([0], [newName]) 25 | .bitwiseAnd(pattern) 26 | .rightShift(start); 27 | }; 28 | 29 | // Reference a single MODIS MOD09GA image. 30 | var image = ee.Image('MODIS/006/MOD09GA/2012_10_11'); 31 | 32 | // Select the QA band 33 | var QA = image.select('state_1km'); 34 | 35 | // Get the cloud_state bits and find cloudy areas. 36 | var cloud = getQABits(QA, 0, 1, 'cloud_state') 37 | .expression("b(0) == 1 || b(0) == 2"); 38 | 39 | // Get the land_water_flag bits. 40 | var landWaterFlag = getQABits(QA, 3, 5, 'land_water_flag'); 41 | 42 | // Create a mask that filters out deep ocean and cloudy areas. 43 | var mask = landWaterFlag.neq(7).and(cloud.not()); 44 | 45 | // Add a map layer with the deep ocean and clouds areas masked out. 46 | Map.addLayer(image.updateMask(mask), 47 | { 48 | bands: ['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03'], 49 | min: -100, 50 | max: 2000 51 | }, 'MOD09GA 143' 52 | ); 53 | 54 | // Add a semi-transparent map layer that displays the clouds. 55 | Map.addLayer( 56 | cloud.updateMask(cloud), 57 | {palette: 'FFFFFF', opacity: 0.8}, 58 | 'clouds' 59 | ); 60 | -------------------------------------------------------------------------------- /examples/javascripts/NormalizedDifference.js: -------------------------------------------------------------------------------- 1 | // NormalizedDifference example. 2 | // 3 | // Compute Normalized Difference Vegetation Index over MOD09GA product. 4 | // NDVI = (NIR - RED) / (NIR + RED), where 5 | // RED is sur_refl_b01, 620-670nm 6 | // NIR is sur_refl_b02, 841-876nm 7 | 8 | // Load a MODIS image. 9 | var img = ee.Image('MODIS/006/MOD09GA/2012_03_09'); 10 | 11 | // Use the normalizedDifference(A, B) to compute (A - B) / (A + B) 12 | var ndvi = img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']); 13 | 14 | // Make a palette: a list of hex strings. 15 | var palette = ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', 16 | '74A901', '66A000', '529400', '3E8601', '207401', '056201', 17 | '004C00', '023B01', '012E01', '011D01', '011301']; 18 | 19 | // Center the map 20 | Map.setCenter(-94.84497, 39.01918, 8); 21 | 22 | // Display the input image and the NDVI derived from it. 23 | Map.addLayer(img.select(['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03']), 24 | {gain: [0.1, 0.1, 0.1]}, 'MODIS bands 1/4/3'); 25 | Map.addLayer(ndvi, {min: 0, max: 1, palette: palette}, 'NDVI'); 26 | -------------------------------------------------------------------------------- /examples/javascripts/QualityMosaic.js: -------------------------------------------------------------------------------- 1 | // Array-based quality mosaic. 2 | 3 | // Returns a mosaic built by sorting each stack of pixels by the first band 4 | // in descending order, and taking the highest quality pixel. 5 | function qualityMosaic(bands) { 6 | // Convert to an array, and declare names for the axes and indices along the 7 | // band axis. 8 | var array = bands.toArray(); 9 | var imageAxis = 0; 10 | var bandAxis = 1; 11 | var qualityIndex = 0; 12 | var valuesIndex = 1; 13 | 14 | // Slice the quality and values off the main array, and sort the values by the 15 | // quality in descending order. 16 | var quality = array.arraySlice(bandAxis, qualityIndex, qualityIndex + 1); 17 | var values = array.arraySlice(bandAxis, valuesIndex); 18 | var valuesByQuality = values.arraySort(quality.multiply(-1)); 19 | 20 | // Get an image where each pixel is the array of band values where the quality 21 | // band is greatest. Note that while the array is 2-D, the first axis is 22 | // length one. 23 | var best = valuesByQuality.arraySlice(imageAxis, 0, 1); 24 | 25 | // Project the best 2D array down to a single dimension, and convert it back 26 | // to a regular scalar image by naming each position along the axis. Note we 27 | // provide the original band names, but slice off the first band since the 28 | // quality band is not part of the result. Also note to get at the band names, 29 | // we have to do some kind of reduction, but it won't really calculate pixels 30 | // if we only access the band names. 31 | var bandNames = bands.min().bandNames().slice(1); 32 | return best.arrayProject([bandAxis]).arrayFlatten([bandNames]); 33 | } 34 | 35 | // Load the l7_l1t collection for the year 2000, and make sure the first band 36 | // is our quality measure, in this case the normalized difference values. 37 | var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1') 38 | .filterDate('2000-01-01', '2001-01-01'); 39 | var withNd = l7.map(function(image) { 40 | return image.normalizedDifference(['B4', 'B3']).addBands(image); 41 | }); 42 | 43 | // Build a mosaic using the NDVI of bands 4 and 3, essentially showing the 44 | // greenest pixels from the year 2000. 45 | var greenest = qualityMosaic(withNd); 46 | 47 | // Select out the color bands to visualize. An interesting artifact of this 48 | // approach is that clouds are greener than water. So all the water is white. 49 | var rgb = greenest.select(['B3', 'B2', 'B1']); 50 | 51 | Map.addLayer(rgb, {gain: [1.4, 1.4, 1.1]}, 'Greenest'); 52 | Map.setCenter(-90.08789, 16.38339, 11); 53 | 54 | -------------------------------------------------------------------------------- /examples/javascripts/grid.js: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | A sample Earth Engine JavaScript library. 4 | The script is adapted from https://code.earthengine.google.com/2bca4e5f36d5a2d642475a98fa421fa9 5 | Credits to Gennadii Donchyts. 6 | 7 | */ 8 | 9 | var generateRasterGrid= function(origin, dx, dy, proj) { 10 | var coords = origin.transform(proj).coordinates(); 11 | origin = ee.Image.constant(coords.get(0)).addBands(ee.Image.constant(coords.get(1))); 12 | 13 | var pixelCoords = ee.Image.pixelCoordinates(proj); 14 | 15 | var grid = pixelCoords 16 | .subtract(origin) 17 | .divide([dx, dy]).floor() 18 | .toInt().reduce(ee.Reducer.sum()).bitwiseAnd(1).rename('grid'); 19 | 20 | var xy = pixelCoords.reproject(proj.translate(coords.get(0), coords.get(1)).scale(dx, dy)); 21 | 22 | var id = xy.multiply(ee.Image.constant([1, 1000000])).reduce(ee.Reducer.sum()).rename('id'); 23 | 24 | return grid 25 | .addBands(id) 26 | .addBands(xy); 27 | } 28 | 29 | 30 | /*** 31 | * Generates a regular grid using given bounds, specified as geometry. 32 | */ 33 | var generateGrid = function(xmin, ymin, xmax, ymax, dx, dy, marginx, marginy, opt_proj) { 34 | var proj = opt_proj || 'EPSG:4326'; 35 | 36 | dx = ee.Number(dx); 37 | dy = ee.Number(dy); 38 | 39 | var xx = ee.List.sequence(xmin, ee.Number(xmax).subtract(ee.Number(dx).multiply(0.1)), dx); 40 | var yy = ee.List.sequence(ymin, ee.Number(ymax).subtract(ee.Number(dy).multiply(0.1)), dy); 41 | 42 | var cells = xx.map(function(x) { 43 | return yy.map(function(y) { 44 | var x1 = ee.Number(x).subtract(marginx); 45 | var x2 = ee.Number(x).add(ee.Number(dx)).add(marginx); 46 | var y1 = ee.Number(y).subtract(marginy); 47 | var y2 = ee.Number(y).add(ee.Number(dy)).add(marginy); 48 | 49 | var coords = ee.List([x1, y1, x2, y2]); 50 | var rect = ee.Algorithms.GeometryConstructors.Rectangle(coords, proj, false); 51 | 52 | var nx = x1.add(dx.multiply(0.5)).subtract(xmin).divide(dx).floor(); 53 | var ny = y1.add(dy.multiply(0.5)).subtract(ymin).divide(dy).floor(); 54 | 55 | return ee.Feature(rect) 56 | .set({ 57 | nx: nx.format('%d'), 58 | ny: ny.format('%d'), 59 | }); 60 | // .set({cell_id: x1.format('%.3f').cat('_').cat(y1.format('%.3f')) }) 61 | }); 62 | }).flatten(); 63 | 64 | return ee.FeatureCollection(cells); 65 | }; 66 | 67 | 68 | var grid_test = function() { 69 | 70 | var gridRaster = generateRasterGrid(ee.Geometry.Point(0, 0), 10, 10, ee.Projection('EPSG:4326')); 71 | Map.addLayer(gridRaster.select('id').randomVisualizer(), {}, 'Grid raster', true, 0.5); 72 | 73 | var gridVector = generateGrid(-180, -70, 180, 70, 10, 10, 0, 0); 74 | style = {'fillColor': '00000000'}; 75 | Map.addLayer(gridVector.style(style), {}, 'Grid vector'); 76 | 77 | } 78 | 79 | exports.generateGrid = generateGrid; 80 | exports.generateRasterGrid = generateRasterGrid; 81 | exports.grid_test = grid_test; 82 | -------------------------------------------------------------------------------- /examples/python/earthengine_js_to_ipynb.py: -------------------------------------------------------------------------------- 1 | import os 2 | from geemap.conversion import * 3 | 4 | # Create a temporary working directory 5 | work_dir = os.path.join(os.path.expanduser("~"), "geemap") 6 | # Get Earth Engine JavaScript examples. There are five examples in the geemap package folder. 7 | # Change js_dir to your own folder containing your Earth Engine JavaScripts, such as js_dir = '/path/to/your/js/folder' 8 | js_dir = get_js_examples(out_dir=work_dir) 9 | 10 | # Convert all Earth Engine JavaScripts in a folder recursively to Python scripts. 11 | js_to_python_dir(in_dir=js_dir, out_dir=js_dir, use_qgis=True) 12 | print("Python scripts saved at: {}".format(js_dir)) 13 | 14 | # Convert all Earth Engine Python scripts in a folder recursively to Jupyter notebooks. 15 | nb_template = get_nb_template() # Get the notebook template from the package folder. 16 | py_to_ipynb_dir(js_dir, nb_template) 17 | 18 | # Execute all Jupyter notebooks in a folder recursively and save the output cells. 19 | execute_notebook_dir(in_dir=js_dir) 20 | -------------------------------------------------------------------------------- /examples/python/earthengine_py_to_ipynb.py: -------------------------------------------------------------------------------- 1 | """The example shows you how to convert all Earth Engine Python scripts in a GitHub repo to Jupyter notebooks.""" 2 | 3 | import os 4 | from geemap.conversion import * 5 | 6 | import subprocess 7 | 8 | try: 9 | from git import Repo 10 | except ImportError: 11 | print("gitpython package is not installed. Installing ...") 12 | subprocess.check_call(["python", "-m", "pip", "install", "gitpython"]) 13 | from git import Repo 14 | 15 | 16 | git_url = "https://github.com/giswqs/qgis-earthengine-examples" 17 | out_repo_name = "earthengine-py-notebooks" 18 | 19 | # Create a temporary working directory 20 | work_dir = os.path.join(os.path.expanduser("~"), "geemap") 21 | if not os.path.exists(work_dir): 22 | os.makedirs(work_dir) 23 | 24 | out_dir = os.path.join(work_dir, out_repo_name) 25 | 26 | repo_name = git_url.split("/")[-1] 27 | repo_dir = os.path.join(work_dir, repo_name) 28 | 29 | if not os.path.exists(repo_dir): 30 | Repo.clone_from(git_url, repo_dir) 31 | 32 | # # Convert all Earth Engine Python scripts in a folder recursively to Jupyter notebooks. 33 | nb_template = get_nb_template() # Get the notebook template from the package folder. 34 | py_to_ipynb_dir( 35 | repo_dir, 36 | nb_template, 37 | out_dir, 38 | github_username="giswqs", 39 | github_repo=out_repo_name, 40 | ) 41 | 42 | # execute_notebook_dir(out_dir) 43 | -------------------------------------------------------------------------------- /examples/python/geemap_and_earthengine.py: -------------------------------------------------------------------------------- 1 | import ee 2 | import geemap 3 | 4 | try: 5 | ee.Initialize() 6 | except Exception as e: 7 | ee.Authenticate() 8 | ee.Initialize() 9 | 10 | # Create an interactive map 11 | Map = geemap.Map(center=(40, -100), zoom=4) 12 | Map 13 | 14 | # Add Earth Engine dataset 15 | image = ee.Image("USGS/SRTMGL1_003") 16 | 17 | # Set visualization parameters. 18 | vis_params = { 19 | "min": 0, 20 | "max": 4000, 21 | "palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"], 22 | } 23 | 24 | # Print the elevation of Mount Everest. 25 | xy = ee.Geometry.Point([86.9250, 27.9881]) 26 | elev = image.sample(xy, 30).first().get("elevation").getInfo() 27 | print("Mount Everest elevation (m):", elev) 28 | 29 | # Add Earth Engine layers to Map 30 | Map.addLayer(image, vis_params, "SRTM DEM", True, 0.5) 31 | Map.addLayer(xy, {"color": "red"}, "Mount Everest") 32 | 33 | # Set center of the map 34 | Map.centerObject(ee_object=xy, zoom=13) 35 | Map.setCenter(lon=-100, lat=40, zoom=4) 36 | -------------------------------------------------------------------------------- /examples/python/javascript_to_python.py: -------------------------------------------------------------------------------- 1 | import os 2 | from geemap.conversion import * 3 | 4 | # Create a temporary working directory 5 | work_dir = os.path.join(os.path.expanduser("~"), "geemap") 6 | # Get Earth Engine JavaScript examples. There are five examples in the geemap package folder. 7 | # Change js_dir to your own folder containing your Earth Engine JavaScripts, such as js_dir = '/path/to/your/js/folder' 8 | js_dir = get_js_examples(out_dir=work_dir) 9 | 10 | # Convert all Earth Engine JavaScripts in a folder recursively to Python scripts. 11 | js_to_python_dir(in_dir=js_dir, out_dir=js_dir, use_qgis=True) 12 | print("Python scripts saved at: {}".format(js_dir)) 13 | 14 | # Convert all Earth Engine Python scripts in a folder recursively to Jupyter notebooks. 15 | nb_template = get_nb_template() # Get the notebook template from the package folder. 16 | py_to_ipynb_dir(js_dir, nb_template) 17 | 18 | # Execute all Jupyter notebooks in a folder recursively and save the output cells. 19 | execute_notebook_dir(in_dir=js_dir) 20 | -------------------------------------------------------------------------------- /examples/template/template.py: -------------------------------------------------------------------------------- 1 | # %% 2 | """ 3 | 4 | 5 | 6 | 7 |
    View source on GitHubNotebook Viewer Run in Google Colab
    8 | """ 9 | 10 | # %% 11 | """ 12 | ## Install Earth Engine API and geemap 13 | Install the [Earth Engine Python API](https://developers.google.com/earth-engine/python_install) and [geemap](https://geemap.org). The **geemap** Python package is built upon the [ipyleaflet](https://github.com/jupyter-widgets/ipyleaflet) and [folium](https://github.com/python-visualization/folium) packages and implements several methods for interacting with Earth Engine data layers, such as `Map.addLayer()`, `Map.setCenter()`, and `Map.centerObject()`. 14 | The following script checks if the geemap package has been installed. If not, it will install geemap, which automatically installs its [dependencies](https://github.com/gee-community/geemap#dependencies), including earthengine-api, folium, and ipyleaflet. 15 | """ 16 | 17 | # %% 18 | # Installs geemap package 19 | import subprocess 20 | 21 | try: 22 | import geemap 23 | except ImportError: 24 | print("Installing geemap ...") 25 | subprocess.check_call(["python", "-m", "pip", "install", "geemap"]) 26 | 27 | # %% 28 | import ee 29 | import geemap 30 | 31 | # %% 32 | """ 33 | ## Create an interactive map 34 | The default basemap is `Google Maps`. [Additional basemaps](https://github.com/gee-community/geemap/blob/master/geemap/basemaps.py) can be added using the `Map.add_basemap()` function. 35 | """ 36 | 37 | # %% 38 | Map = geemap.Map(center=[40, -100], zoom=4) 39 | Map 40 | 41 | # %% 42 | """ 43 | ## Add Earth Engine Python script 44 | """ 45 | 46 | # %% 47 | # Add Earth Engine dataset 48 | image = ee.Image("USGS/SRTMGL1_003") 49 | 50 | # Set visualization parameters. 51 | vis_params = { 52 | "min": 0, 53 | "max": 4000, 54 | "palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"], 55 | } 56 | 57 | # Print the elevation of Mount Everest. 58 | xy = ee.Geometry.Point([86.9250, 27.9881]) 59 | elev = image.sample(xy, 30).first().get("elevation").getInfo() 60 | print("Mount Everest elevation (m):", elev) 61 | 62 | # Add Earth Engine layers to Map 63 | Map.addLayer(image, vis_params, "DEM") 64 | Map.addLayer(xy, {"color": "red"}, "Mount Everest") 65 | 66 | # Center the map based on an Earth Engine object or coordinates (longitude, latitude) 67 | # Map.centerObject(xy, 4) 68 | Map.setCenter(86.9250, 27.9881, 4) 69 | 70 | # %% 71 | """ 72 | ## Display Earth Engine data layers 73 | """ 74 | 75 | # %% 76 | Map.addLayerControl() # This line is not needed for ipyleaflet-based Map. 77 | Map 78 | -------------------------------------------------------------------------------- /geemap/__init__.py: -------------------------------------------------------------------------------- 1 | """Top-level package for geemap.""" 2 | 3 | __author__ = """Qiusheng Wu""" 4 | __email__ = "giswqs@gmail.com" 5 | __version__ = "0.35.1" 6 | 7 | import os 8 | 9 | 10 | def in_colab_shell(): 11 | """Tests if the code is being executed within Google Colab.""" 12 | import sys 13 | 14 | if "google.colab" in sys.modules: 15 | return True 16 | else: 17 | return False 18 | 19 | 20 | def use_folium(): 21 | """Whether to use the folium or ipyleaflet plotting backend.""" 22 | if os.environ.get("USE_FOLIUM") is not None: 23 | return True 24 | else: 25 | return False 26 | 27 | 28 | def _use_eerepr(token="USE_EEREPR"): 29 | """Whether to use eerepr for printing Earth Engine objects. 30 | 31 | Returns: 32 | bool: True if eerepr is used for printing Earth Engine objects. 33 | """ 34 | 35 | if os.environ.get(token) is None: 36 | return True 37 | else: 38 | return False 39 | 40 | 41 | if use_folium(): 42 | from .foliumap import * 43 | else: 44 | try: 45 | from .geemap import * 46 | except Exception as e: 47 | if in_colab_shell(): 48 | print( 49 | "Please restart Colab runtime after installation if you encounter any errors when importing geemap." 50 | ) 51 | else: 52 | print( 53 | "Please restart Jupyter kernel after installation if you encounter any errors when importing geemap." 54 | ) 55 | raise e 56 | 57 | if _use_eerepr(): 58 | import eerepr 59 | 60 | eerepr.initialize() 61 | 62 | from .report import Report 63 | -------------------------------------------------------------------------------- /geemap/cli.py: -------------------------------------------------------------------------------- 1 | """Console script for geemap.""" 2 | 3 | import sys 4 | import click 5 | 6 | 7 | @click.command() 8 | def main(args=None): 9 | """Console script for geemap.""" 10 | click.echo("Replace this message by putting your code into " "geemap.cli.main") 11 | click.echo("See click documentation at https://click.palletsprojects.com/") 12 | return 0 13 | 14 | 15 | if __name__ == "__main__": 16 | sys.exit(main()) # pragma: no cover 17 | -------------------------------------------------------------------------------- /geemap/data/fonts/alibaba.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/geemap/data/fonts/alibaba.otf -------------------------------------------------------------------------------- /geemap/data/fonts/arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/geemap/data/fonts/arial.ttf -------------------------------------------------------------------------------- /geemap/data/javascripts/ClippedComposite.js: -------------------------------------------------------------------------------- 1 | // Composite an image collection and clip it to a boundary. 2 | 3 | // Load Landsat 7 raw imagery and filter it to April-July 2000. 4 | var collection = ee.ImageCollection('LANDSAT/LE07/C01/T1') 5 | .filterDate('2000-04-01', '2000-07-01'); 6 | 7 | // Reduce the collection by taking the median. 8 | var median = collection.median(); 9 | 10 | // Load a table of state boundaries and filter. 11 | var fc = ee.FeatureCollection('TIGER/2016/States') 12 | .filter(ee.Filter.or( 13 | ee.Filter.eq('NAME', 'Nevada'), 14 | ee.Filter.eq('NAME', 'Arizona'))); 15 | 16 | // Clip to the output image to the Nevada and Arizona state boundaries. 17 | var clipped = median.clipToCollection(fc); 18 | 19 | // Display the result. 20 | Map.setCenter(-110, 40, 5); 21 | var visParams = {bands: ['B3', 'B2', 'B1'], gain: [1.4, 1.4, 1.1]}; 22 | Map.addLayer(clipped, visParams, 'clipped composite'); 23 | -------------------------------------------------------------------------------- /geemap/data/javascripts/FromName.js: -------------------------------------------------------------------------------- 1 | // Display an image given its ID. 2 | 3 | var image = ee.Image('CGIAR/SRTM90_V4'); 4 | // Center the Map. 5 | Map.setCenter(-110, 40, 5); 6 | // Display the image. 7 | Map.addLayer(image, {min: 0, max: 3000}, 'SRTM'); 8 | -------------------------------------------------------------------------------- /geemap/data/javascripts/ModisQaBands.js: -------------------------------------------------------------------------------- 1 | // Extract MODIS QA information from the "state_1km" QA band 2 | // and use it to mask out cloudy and deep ocean areas. 3 | // 4 | // QA Band information is available at: 5 | // https://lpdaac.usgs.gov/products/modis_products_table/mod09ga 6 | // Table 1: 1-kilometer State QA Descriptions (16-bit) 7 | 8 | 9 | /** 10 | * Returns an image containing just the specified QA bits. 11 | * 12 | * Args: 13 | * image - The QA Image to get bits from. 14 | * start - The first bit position, 0-based. 15 | * end - The last bit position, inclusive. 16 | * name - A name for the output image. 17 | */ 18 | var getQABits = function(image, start, end, newName) { 19 | // Compute the bits we need to extract. 20 | var pattern = 0; 21 | for (var i = start; i <= end; i++) { 22 | pattern += Math.pow(2, i); 23 | } 24 | return image.select([0], [newName]) 25 | .bitwiseAnd(pattern) 26 | .rightShift(start); 27 | }; 28 | 29 | // Reference a single MODIS MOD09GA image. 30 | var image = ee.Image('MODIS/006/MOD09GA/2012_10_11'); 31 | 32 | // Select the QA band 33 | var QA = image.select('state_1km'); 34 | 35 | // Get the cloud_state bits and find cloudy areas. 36 | var cloud = getQABits(QA, 0, 1, 'cloud_state') 37 | .expression("b(0) == 1 || b(0) == 2"); 38 | 39 | // Get the land_water_flag bits. 40 | var landWaterFlag = getQABits(QA, 3, 5, 'land_water_flag'); 41 | 42 | // Create a mask that filters out deep ocean and cloudy areas. 43 | var mask = landWaterFlag.neq(7).and(cloud.not()); 44 | 45 | // Add a map layer with the deep ocean and clouds areas masked out. 46 | Map.addLayer(image.updateMask(mask), 47 | { 48 | bands: ['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03'], 49 | min: -100, 50 | max: 2000 51 | }, 'MOD09GA 143' 52 | ); 53 | 54 | // Add a semi-transparent map layer that displays the clouds. 55 | Map.addLayer( 56 | cloud.updateMask(cloud), 57 | {palette: 'FFFFFF', opacity: 0.8}, 58 | 'clouds' 59 | ); 60 | -------------------------------------------------------------------------------- /geemap/data/javascripts/NormalizedDifference.js: -------------------------------------------------------------------------------- 1 | // NormalizedDifference example. 2 | // 3 | // Compute Normalized Difference Vegetation Index over MOD09GA product. 4 | // NDVI = (NIR - RED) / (NIR + RED), where 5 | // RED is sur_refl_b01, 620-670nm 6 | // NIR is sur_refl_b02, 841-876nm 7 | 8 | // Load a MODIS image. 9 | var img = ee.Image('MODIS/006/MOD09GA/2012_03_09'); 10 | 11 | // Use the normalizedDifference(A, B) to compute (A - B) / (A + B) 12 | var ndvi = img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']); 13 | 14 | // Make a palette: a list of hex strings. 15 | var palette = ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', 16 | '74A901', '66A000', '529400', '3E8601', '207401', '056201', 17 | '004C00', '023B01', '012E01', '011D01', '011301']; 18 | 19 | // Center the map 20 | Map.setCenter(-94.84497, 39.01918, 8); 21 | 22 | // Display the input image and the NDVI derived from it. 23 | Map.addLayer(img.select(['sur_refl_b01', 'sur_refl_b04', 'sur_refl_b03']), 24 | {gain: [0.1, 0.1, 0.1]}, 'MODIS bands 1/4/3'); 25 | Map.addLayer(ndvi, {min: 0, max: 1, palette: palette}, 'NDVI'); 26 | -------------------------------------------------------------------------------- /geemap/data/javascripts/QualityMosaic.js: -------------------------------------------------------------------------------- 1 | // Array-based quality mosaic. 2 | 3 | // Returns a mosaic built by sorting each stack of pixels by the first band 4 | // in descending order, and taking the highest quality pixel. 5 | function qualityMosaic(bands) { 6 | // Convert to an array, and declare names for the axes and indices along the 7 | // band axis. 8 | var array = bands.toArray(); 9 | var imageAxis = 0; 10 | var bandAxis = 1; 11 | var qualityIndex = 0; 12 | var valuesIndex = 1; 13 | 14 | // Slice the quality and values off the main array, and sort the values by the 15 | // quality in descending order. 16 | var quality = array.arraySlice(bandAxis, qualityIndex, qualityIndex + 1); 17 | var values = array.arraySlice(bandAxis, valuesIndex); 18 | var valuesByQuality = values.arraySort(quality.multiply(-1)); 19 | 20 | // Get an image where each pixel is the array of band values where the quality 21 | // band is greatest. Note that while the array is 2-D, the first axis is 22 | // length one. 23 | var best = valuesByQuality.arraySlice(imageAxis, 0, 1); 24 | 25 | // Project the best 2D array down to a single dimension, and convert it back 26 | // to a regular scalar image by naming each position along the axis. Note we 27 | // provide the original band names, but slice off the first band since the 28 | // quality band is not part of the result. Also note to get at the band names, 29 | // we have to do some kind of reduction, but it won't really calculate pixels 30 | // if we only access the band names. 31 | var bandNames = bands.min().bandNames().slice(1); 32 | return best.arrayProject([bandAxis]).arrayFlatten([bandNames]); 33 | } 34 | 35 | // Load the l7_l1t collection for the year 2000, and make sure the first band 36 | // is our quality measure, in this case the normalized difference values. 37 | var l7 = ee.ImageCollection('LANDSAT/LE07/C01/T1') 38 | .filterDate('2000-01-01', '2001-01-01'); 39 | var withNd = l7.map(function(image) { 40 | return image.normalizedDifference(['B4', 'B3']).addBands(image); 41 | }); 42 | 43 | // Build a mosaic using the NDVI of bands 4 and 3, essentially showing the 44 | // greenest pixels from the year 2000. 45 | var greenest = qualityMosaic(withNd); 46 | 47 | // Select out the color bands to visualize. An interesting artifact of this 48 | // approach is that clouds are greener than water. So all the water is white. 49 | var rgb = greenest.select(['B3', 'B2', 'B1']); 50 | 51 | Map.addLayer(rgb, {gain: [1.4, 1.4, 1.1]}, 'Greenest'); 52 | Map.setCenter(-90.08789, 16.38339, 11); 53 | 54 | -------------------------------------------------------------------------------- /geemap/data/python/javascript_to_python.py: -------------------------------------------------------------------------------- 1 | import os 2 | from geemap.conversion import * 3 | 4 | # Create a temporary working directory 5 | work_dir = os.path.join(os.path.expanduser("~"), "geemap") 6 | # Get Earth Engine JavaScript examples. There are five examples in the geemap package folder. 7 | # Change js_dir to your own folder containing your Earth Engine JavaScripts, such as js_dir = '/path/to/your/js/folder' 8 | js_dir = get_js_examples(out_dir=work_dir) 9 | 10 | # Convert all Earth Engine JavaScripts in a folder recursively to Python scripts. 11 | js_to_python_dir(in_dir=js_dir, out_dir=js_dir, use_qgis=True) 12 | print("Python scripts saved at: {}".format(js_dir)) 13 | 14 | # Convert all Earth Engine Python scripts in a folder recursively to Jupyter notebooks. 15 | nb_template = get_nb_template() # Get the notebook template from the package folder. 16 | py_to_ipynb_dir(js_dir, nb_template) 17 | 18 | # Execute all Jupyter notebooks in a folder recursively and save the output cells. 19 | execute_notebook_dir(in_dir=js_dir) 20 | -------------------------------------------------------------------------------- /geemap/data/template/NLCD.qml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1 5 | 1 6 | 1 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | None 25 | WholeRaster 26 | Estimated 27 | 0.02 28 | 0.98 29 | 2 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | resamplingFilter 58 | 59 | 0 60 | 61 | -------------------------------------------------------------------------------- /geemap/data/template/ee_api_docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 62 | 63 | 64 | 65 | 66 |

    function_name

    67 |

    function_description


    68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 |
    UsageReturns
    function_usagefunction_returns
    79 | 80 |
    81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
    ArgumentTypeDetails
    function_argumentfunction_typefunction_details
    94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /geemap/data/template/ee_legend_table.txt: -------------------------------------------------------------------------------- 1 | Value Color Description 2 | 0 1c0dff Water 3 | 1 05450a Evergreen needleleaf forest 4 | 2 086a10 Evergreen broadleaf forest 5 | 3 54a708 Deciduous needleleaf forest 6 | 4 78d203 Deciduous broadleaf forest 7 | 5 009900 Mixed forest 8 | 6 c6b044 Closed shrublands 9 | 7 dcd159 Open shrublands 10 | 8 dade48 Woody savannas 11 | 9 fbff13 Savannas 12 | 10 b6ff05 Grasslands 13 | 11 27ff87 Permanent wetlands 14 | 12 c24f44 Croplands 15 | 13 a5a5a5 Urban and built-up 16 | 14 ff6d4c Cropland/natural vegetation mosaic 17 | 15 69fff8 Snow and ice 18 | 16 f9ffa4 Barren or sparsely vegetated 19 | 254 ffffff Unclassified -------------------------------------------------------------------------------- /geemap/data/template/legend.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
    4 |
    Legend
    5 |
    6 |
      7 |
    • One
    • 8 |
    • Two
    • 9 |
    • Three
    • 10 |
    • Four
    • 11 |
    • etc
    • 12 |
    13 |
    14 |
    15 | 16 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /geemap/data/template/legend.txt: -------------------------------------------------------------------------------- 1 | """ 2 | {% macro html(this, kwargs) %} 3 | 4 | 5 | 6 | 7 | 8 | 9 | jQuery UI Draggable - Default functionality 10 | 11 | 12 | 13 | 14 | 15 | 29 | 30 | 31 | 32 | 33 |
    36 | 37 |
    Legend
    38 |
    39 |
      40 |
    • Big
    • 41 |
    • Medium
    • 42 |
    • Small
    • 43 |
    44 |
    45 |
    46 | 47 | 48 | 49 | 50 | 89 | {% endmacro %}""" 90 | -------------------------------------------------------------------------------- /geemap/data/template/legend_style.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
    20 |
    Legend
    21 |
    22 |
      23 |
    • 24 | Big 25 |
    • 26 |
    • 27 | Medium 29 |
    • 30 |
    • 31 | Small 33 |
    • 34 |
    35 |
    36 |
    37 | 38 | 39 | 40 | 79 | -------------------------------------------------------------------------------- /geemap/data/template/template.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Import libraries" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import ee\n", 17 | "import geemap" 18 | ] 19 | }, 20 | { 21 | "cell_type": "markdown", 22 | "metadata": {}, 23 | "source": [ 24 | "## Create an interactive map" 25 | ] 26 | }, 27 | { 28 | "cell_type": "code", 29 | "execution_count": null, 30 | "metadata": {}, 31 | "outputs": [], 32 | "source": [ 33 | "Map = geemap.Map(center=[40, -100], zoom=4)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "## Add Earth Engine Python script" 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "execution_count": null, 46 | "metadata": {}, 47 | "outputs": [], 48 | "source": [ 49 | "# Add Earth Engine dataset\n", 50 | "image = ee.Image(\"USGS/SRTMGL1_003\")\n", 51 | "\n", 52 | "# Set visualization parameters.\n", 53 | "vis_params = {\n", 54 | " \"min\": 0,\n", 55 | " \"max\": 4000,\n", 56 | " \"palette\": [\"006633\", \"E5FFCC\", \"662A00\", \"D8D8D8\", \"F5F5F5\"],\n", 57 | "}\n", 58 | "\n", 59 | "# Print the elevation of Mount Everest.\n", 60 | "xy = ee.Geometry.Point([86.9250, 27.9881])\n", 61 | "elev = image.sample(xy, 30).first().get(\"elevation\").getInfo()\n", 62 | "print(\"Mount Everest elevation (m):\", elev)\n", 63 | "\n", 64 | "# Add Earth Engine layers to Map\n", 65 | "Map.addLayer(image, vis_params, \"DEM\")\n", 66 | "Map.addLayer(xy, {\"color\": \"red\"}, \"Mount Everest\")\n", 67 | "\n", 68 | "# Center the map based on an Earth Engine object or coordinates (longitude, latitude)\n", 69 | "# Map.centerObject(xy, 4)\n", 70 | "Map.setCenter(86.9250, 27.9881, 4)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "markdown", 75 | "metadata": {}, 76 | "source": [ 77 | "## Display the interactive map" 78 | ] 79 | }, 80 | { 81 | "cell_type": "code", 82 | "execution_count": null, 83 | "metadata": {}, 84 | "outputs": [], 85 | "source": [ 86 | "Map" 87 | ] 88 | } 89 | ], 90 | "metadata": { 91 | "anaconda-cloud": {}, 92 | "kernelspec": { 93 | "display_name": "Python 3", 94 | "language": "python", 95 | "name": "python3" 96 | }, 97 | "language_info": { 98 | "codemirror_mode": { 99 | "name": "ipython", 100 | "version": 3 101 | }, 102 | "file_extension": ".py", 103 | "mimetype": "text/x-python", 104 | "name": "python", 105 | "nbconvert_exporter": "python", 106 | "pygments_lexer": "ipython3", 107 | "version": "3.6.1" 108 | } 109 | }, 110 | "nbformat": 4, 111 | "nbformat_minor": 4 112 | } 113 | -------------------------------------------------------------------------------- /geemap/data/template/template.py: -------------------------------------------------------------------------------- 1 | # %% 2 | """ 3 | ## Import libraries 4 | """ 5 | 6 | # %% 7 | import ee 8 | import geemap 9 | 10 | # %% 11 | """ 12 | ## Create an interactive map 13 | """ 14 | 15 | # %% 16 | Map = geemap.Map(center=[40, -100], zoom=4) 17 | 18 | # %% 19 | """ 20 | ## Add Earth Engine Python script 21 | """ 22 | 23 | # %% 24 | # Add Earth Engine dataset 25 | image = ee.Image("USGS/SRTMGL1_003") 26 | 27 | # Set visualization parameters. 28 | vis_params = { 29 | "min": 0, 30 | "max": 4000, 31 | "palette": ["006633", "E5FFCC", "662A00", "D8D8D8", "F5F5F5"], 32 | } 33 | 34 | # Print the elevation of Mount Everest. 35 | xy = ee.Geometry.Point([86.9250, 27.9881]) 36 | elev = image.sample(xy, 30).first().get("elevation").getInfo() 37 | print("Mount Everest elevation (m):", elev) 38 | 39 | # Add Earth Engine layers to Map 40 | Map.addLayer(image, vis_params, "DEM") 41 | Map.addLayer(xy, {"color": "red"}, "Mount Everest") 42 | 43 | # Center the map based on an Earth Engine object or coordinates (longitude, latitude) 44 | # Map.centerObject(xy, 4) 45 | Map.setCenter(86.9250, 27.9881, 4) 46 | 47 | # %% 48 | """ 49 | ## Display the interactive map 50 | """ 51 | 52 | # %% 53 | Map 54 | -------------------------------------------------------------------------------- /geemap/data/template/toolbox.csv: -------------------------------------------------------------------------------- 1 | index,name,category,label,description,link,definition,parameters 2 | DecisionTree,DecisionTree,Image Classification,Decision Tree,Creates a classifier that applies the given decision tree.,https://developers.google.com/earth-engine/apidocs/ee-classifier-decisiontree,ee.Classifier.decisionTree, 3 | DecisionTreeEnsemble,DecisionTreeEnsemble,Image Classification,Decision Tree Ensemble,Creates a classifier that applies the given decision trees.,https://developers.google.com/earth-engine/apidocs/ee-classifier-decisiontreeensemble,ee.Classifier.decisionTreeEnsemble, 4 | RandomForest,RandomForest,Image Classification,Random Forest,Creates an empty Random Forest classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-smilerandomforest,ee.Classifier.smileRandomForest, 5 | AmnhMaxent,AmnhMaxent,Image Classification,Maximum Entropy,Creates a Maximum Entropy classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-amnhmaxent,ee.Classifier.amnhMaxent, 6 | GmoMaxEnt,GmoMaxEnt,Image Classification,GMO Maximum Entropy ,Creates an empty GMO Maximum Entropy classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-gmomaxent,ee.Classifier.gmoMaxEnt, 7 | SupportVectorMachine,SupportVectorMachine,Image Classification,Support Vector Machine,Creates an empty Support Vector Machine classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-libsvm,ee.Classifier.libsvm, 8 | CART,CART,Image Classification,Classification and Regression Trees,Creates an empty CART classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-smilecart,ee.Classifier.smileCart, 9 | GradientTreeBoost,GradientTreeBoost,Image Classification,Gradient Tree Boost,Creates an empty Gradient Tree Boost classifier.,https://developers.google.com/earth-engine/apidocs/ee-classifier-smilegradienttreeboost,ee.Classifier.smileGradientTreeBoost, 10 | NaiveBayes,NaiveBayes,Image Classification,Naive Bayes,Creates an empty Naive Bayes classifier. ,https://developers.google.com/earth-engine/apidocs/ee-classifier-smilenaivebayes,ee.Classifier.smileNaiveBayes, 11 | WekaXMeans,WekaXMeans,Image Clustering,Weka X-means,X-Means is K-Means with an efficient estimation of the number of clusters.,https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekaxmeans,ee.Clusterer.wekaXMeans, 12 | WekaCascadeKMeans,WekaCascadeKMeans,Image Clustering,Weka Cascade KMeans,Cascade simple k-means,https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekacascadekmeans,ee.Clusterer.wekaCascadeKMeans, 13 | WekaCobweb,WekaCobweb,Image Clustering,Weka Cobweb,Implementation of the Cobweb clustering algorithm.,https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekacobweb,ee.Clusterer.wekaCobweb, 14 | WekaKMeans,WekaKMeans,Image Clustering,Weka K-means,Cluster data using the k means algorithm. ,https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekakmeans,ee.Clusterer.wekaKMeans, 15 | WekaLVQ,WekaLVQ,Image Clustering,Weka LVQ,A Clusterer that implements the Learning Vector Quantization algorithm.,https://developers.google.com/earth-engine/apidocs/ee-clusterer-wekalvq,ee.Clusterer.wekaLVQ, 16 | -------------------------------------------------------------------------------- /geemap/examples/__init__.py: -------------------------------------------------------------------------------- 1 | import box 2 | import os 3 | import importlib.resources 4 | 5 | _pkg_dir = str(importlib.resources.files("geemap").joinpath("geemap.py").parent) 6 | _datasets_path = os.path.join(_pkg_dir, "examples/datasets.txt") 7 | _baseurl = ( 8 | "https://raw.githubusercontent.com/gee-community/geemap/master/examples/data/" 9 | ) 10 | 11 | with open(_datasets_path) as f: 12 | _names = [line.strip() for line in f.readlines()] 13 | 14 | _links = [f"{_baseurl}{_name}" for _name in _names] 15 | datasets = box.Box(dict(zip(_names, _links)), frozen_box=True) 16 | 17 | 18 | def get_path(name): 19 | """Get the HTTP URL to an example dataset. 20 | 21 | Args: 22 | name (str): The name of the dataset. 23 | 24 | Raises: 25 | ValueError: If the dataset name is not found. 26 | 27 | Returns: 28 | str: The HTTP URL to the dataset. 29 | """ 30 | if name in datasets: 31 | return datasets[name] 32 | else: 33 | raise ValueError( 34 | f"{name} not found in example datasets. It must be one of {list(datasets.keys())}" 35 | ) 36 | 37 | 38 | def get_ee_path(name): 39 | """Get the Earth Engine asset ID of an example dataset. 40 | 41 | Args: 42 | name (str): The name of the dataset, such as contents, countries, us_cities, us_states, 43 | china, CONUS_HU8, chn_admin_level0, chn_admin_level1, chn_admin_level2, chn_admin_line 44 | 45 | Returns: 46 | str: The Earth Engine asset ID of the dataset. 47 | """ 48 | return f"{'users/giswqs/public/'}{name}" 49 | 50 | 51 | def get_names(): 52 | """Get a list of names of the example datasets. 53 | 54 | Returns: 55 | list: A list of names of the example datasets. 56 | """ 57 | 58 | return list(datasets.keys()) 59 | 60 | 61 | def get_links(): 62 | """Get a list of HTTP URLs to the example datasets. 63 | 64 | Returns: 65 | list: A list of HTTP URLs to the example datasets. 66 | """ 67 | 68 | return list(datasets.values()) 69 | -------------------------------------------------------------------------------- /geemap/examples/datasets.txt: -------------------------------------------------------------------------------- 1 | animation.gif 2 | cable_geo.geojson 3 | charts_feature_example.dbf 4 | charts_feature_example.fix 5 | charts_feature_example.prj 6 | charts_feature_example.shp 7 | charts_feature_example.shp.cpg 8 | charts_feature_example.shx 9 | china.geojson 10 | cog_files.txt 11 | countries.cpg 12 | countries.dbf 13 | countries.geojson 14 | countries.gpkg 15 | countries.prj 16 | countries.shp 17 | countries.shx 18 | countries.zip 19 | country_centroids.csv 20 | datasets.txt 21 | ee_logo.png 22 | life_exp.csv 23 | noaa_logo.jpg 24 | rf_example.csv 25 | rwc_batch_input.csv 26 | temperature.gif 27 | us_cities.cpg 28 | us_cities.csv 29 | us_cities.dbf 30 | us_cities.geojson 31 | us_cities.json 32 | us_cities.prj 33 | us_cities.shp 34 | us_cities.shx 35 | us_regions.geojson 36 | us_states.cpg 37 | us_states.dbf 38 | us_states.json 39 | us_states.kml 40 | us_states.kmz 41 | us_states.prj 42 | us_states.shp 43 | us_states.shx 44 | wind_global.nc 45 | world_cities.csv 46 | -------------------------------------------------------------------------------- /geemap/report.py: -------------------------------------------------------------------------------- 1 | """Module for reporting issues with geemap.""" 2 | 3 | # *******************************************************************************# 4 | # This module contains extra features of the geemap package. # 5 | # The geemap community will maintain the extra features. # 6 | # *******************************************************************************# 7 | 8 | import scooby 9 | from typing import Optional 10 | 11 | 12 | class Report(scooby.Report): 13 | def __init__( 14 | self, 15 | additional: Optional[dict] = None, 16 | ncol: int = 3, 17 | text_width: int = 80, 18 | sort: bool = False, 19 | ): 20 | """Initiate a scooby.Report instance.""" 21 | core = [ 22 | "geemap", 23 | "ee", 24 | "ipyleaflet", 25 | "folium", 26 | "jupyterlab", 27 | "notebook", 28 | "ipyevents", 29 | ] 30 | optional = ["geopandas", "localtileserver"] 31 | 32 | scooby.Report.__init__( 33 | self, 34 | additional=additional, 35 | core=core, 36 | optional=optional, 37 | ncol=ncol, 38 | text_width=text_width, 39 | sort=sort, 40 | ) 41 | -------------------------------------------------------------------------------- /js/color_picker.ts: -------------------------------------------------------------------------------- 1 | import { css, html, LitElement } from "lit"; 2 | import { property } from "lit/decorators.js"; 3 | 4 | import { legacyStyles } from "./ipywidgets_styles"; 5 | 6 | export class ColorPicker extends LitElement { 7 | static get componentName() { 8 | return `color-picker`; 9 | } 10 | 11 | static override styles = [ 12 | legacyStyles, 13 | css` 14 | .color-swatch { 15 | border-radius: 0; 16 | height: 28px; 17 | padding: 0 2px; 18 | width: 28px; 19 | } 20 | 21 | .color-text { 22 | width: 80px; 23 | } 24 | 25 | .widget-inline-hbox { 26 | align-items: baseline; 27 | box-sizing: border-box; 28 | display: flex; 29 | flex-direction: row; 30 | line-height: 28px; 31 | } 32 | `, 33 | ]; 34 | 35 | @property({ type: String }) value: string = "#000000"; 36 | 37 | override render() { 38 | return html` 39 |
    40 | 46 | 52 |
    53 | `; 54 | } 55 | 56 | private onValueChanged(event: Event): void { 57 | this.value = (event.target as HTMLInputElement).value; 58 | this.dispatchEvent(new CustomEvent("change", {})); 59 | } 60 | } 61 | 62 | // Without this check, there's a component registry issue when developing locally. 63 | if (!customElements.get(ColorPicker.componentName)) { 64 | customElements.define(ColorPicker.componentName, ColorPicker); 65 | } -------------------------------------------------------------------------------- /js/lit_widget.ts: -------------------------------------------------------------------------------- 1 | import { LitElement, PropertyValues } from "lit"; 2 | 3 | import { reverseMap } from "./utils"; 4 | 5 | export abstract class LitWidget< 6 | ModelType, 7 | SubclassType extends LitWidget 8 | > extends LitElement { 9 | private _model: any | undefined = undefined; // AnyModel 10 | 11 | abstract modelNameToViewName(): Map< 12 | keyof ModelType, 13 | keyof SubclassType | null 14 | >; 15 | 16 | onCustomMessage?(_msg: any): void {} 17 | 18 | viewNameToModelName(): Map { 19 | return reverseMap(this.modelNameToViewName()); 20 | } 21 | 22 | set model(model: any) { 23 | // TODO(naschmitz): model should be of type AnyModel. AnyModel 24 | // requires a type that conforms to a non-exported member of anywidget. 25 | this._model = model; 26 | for (const [modelKey, widgetKey] of this.modelNameToViewName()) { 27 | if (widgetKey) { 28 | // Get initial values from the Python model. 29 | (this as any)[widgetKey] = model.get(modelKey); 30 | // Listen for updates to the model. 31 | model.on(`change:${String(modelKey)}`, () => { 32 | (this as any)[widgetKey] = model.get(modelKey); 33 | }); 34 | } 35 | } 36 | model.on("msg:custom", (msg: any) => { 37 | this.onCustomMessage?.(msg); 38 | }); 39 | } 40 | 41 | get model(): any { 42 | // TODO(naschmitz): model should be of type AnyModel. AnyModel 43 | // requires a type that conforms to a non-exported member of anywidget. 44 | return this._model; 45 | } 46 | 47 | override updated(changedProperties: PropertyValues): void { 48 | // Update the model properties so they're reflected in Python. 49 | const viewToModelMap = this.viewNameToModelName(); 50 | for (const [viewProp, _] of changedProperties) { 51 | const castViewProp = viewProp as keyof SubclassType; 52 | if (viewToModelMap.has(castViewProp)) { 53 | const modelProp = viewToModelMap.get(castViewProp); 54 | this._model?.set( 55 | modelProp as any, 56 | this[castViewProp as keyof this] as any 57 | ); 58 | } 59 | } 60 | this._model?.save_changes(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /js/styles.ts: -------------------------------------------------------------------------------- 1 | import { css } from "lit"; 2 | 3 | export const materialStyles = css` 4 | @font-face { 5 | font-family: "Material Symbols Outlined"; 6 | font-style: normal; 7 | font-weight: 400; 8 | src: url(https://fonts.gstatic.com/s/materialsymbolsoutlined/v205/kJF1BvYX7BgnkSrUwT8OhrdQw4oELdPIeeII9v6oDMzByHX9rA6RzaxHMPdY43zj-jCxv3fzvRNU22ZXGJpEpjC_1v-p_4MrImHCIJIZrDCvHOejbd5zrDAt.woff2) 9 | format("woff2"); 10 | } 11 | 12 | .material-symbols-outlined { 13 | -webkit-font-feature-settings: "liga"; 14 | -webkit-font-smoothing: antialiased; 15 | direction: ltr; 16 | display: inline-block; 17 | font-family: "Material Symbols Outlined"; 18 | font-style: normal; 19 | font-weight: normal; 20 | letter-spacing: normal; 21 | line-height: 1; 22 | text-transform: none; 23 | white-space: nowrap; 24 | word-wrap: normal; 25 | } 26 | `; 27 | 28 | export const flexStyles = css` 29 | .vertical-flex { 30 | display: flex; 31 | flex-direction: column; 32 | gap: 4px; 33 | } 34 | 35 | .horizontal-flex { 36 | align-items: center; 37 | display: flex; 38 | flex-wrap: nowrap; 39 | gap: 8px; 40 | } 41 | 42 | input:not([type="radio"]):not([type="checkbox"]) { 43 | width: 100%; 44 | } 45 | 46 | select { 47 | width: 100%; 48 | } 49 | 50 | .horizontal-flex .legacy-text { 51 | flex-shrink: 0; 52 | } 53 | `; 54 | -------------------------------------------------------------------------------- /js/toolbar_item.ts: -------------------------------------------------------------------------------- 1 | import type { RenderProps } from "@anywidget/types"; 2 | import { html, css } from "lit"; 3 | import { property } from "lit/decorators.js"; 4 | import { classMap } from 'lit/directives/class-map.js'; 5 | 6 | import { legacyStyles } from './ipywidgets_styles'; 7 | import { LitWidget } from "./lit_widget"; 8 | import { materialStyles } from "./styles"; 9 | import { loadFonts } from "./utils"; 10 | 11 | export interface ToolbarItemModel { 12 | active: boolean; 13 | primary: boolean; 14 | icon: string; 15 | // Note: "tooltip" is already used by ipywidgets. 16 | tooltip_text: string; 17 | } 18 | 19 | export class ToolbarItem extends LitWidget { 20 | static get componentName() { 21 | return `tool-button`; 22 | } 23 | 24 | static override styles = [ 25 | legacyStyles, 26 | materialStyles, 27 | css` 28 | button { 29 | font-size: 16px !important; 30 | height: 32px; 31 | padding: 0px 0px 0px 4px; 32 | width: 32px; 33 | } 34 | `, 35 | ]; 36 | 37 | modelNameToViewName(): Map { 38 | return new Map([ 39 | ["active", "active"], 40 | ["primary", "primary"], 41 | ["icon", "icon"], 42 | ["tooltip_text", "tooltip_text"], 43 | ]); 44 | } 45 | 46 | @property({ type: Boolean }) 47 | active: boolean = false; 48 | 49 | @property({ type: Boolean }) 50 | primary: boolean = true; 51 | 52 | @property({ type: String }) 53 | icon: string = ''; 54 | 55 | @property({ type: String }) 56 | tooltip_text: string = ''; 57 | 58 | override render() { 59 | return html` 60 | `; 70 | } 71 | 72 | private onClick(_: Event) { 73 | this.active = !this.active; 74 | } 75 | } 76 | 77 | // Without this check, there's a component registry issue when developing locally. 78 | if (!customElements.get(ToolbarItem.componentName)) { 79 | customElements.define(ToolbarItem.componentName, ToolbarItem); 80 | } 81 | 82 | async function render({ model, el }: RenderProps) { 83 | loadFonts(); 84 | const manager = document.createElement(ToolbarItem.componentName); 85 | manager.model = model; 86 | el.appendChild(manager); 87 | } 88 | 89 | export default { render }; 90 | -------------------------------------------------------------------------------- /js/utils.ts: -------------------------------------------------------------------------------- 1 | // TODO(sufyanAbbasi): Write tests for this file. 2 | 3 | import type { AnyModel } from "@anywidget/types"; 4 | import { IWidgetManager, WidgetModel } from "@jupyter-widgets/base"; 5 | import { html, TemplateResult } from "lit"; 6 | 7 | async function unpackModels( 8 | modelIds: Array, 9 | manager: IWidgetManager 10 | ): Promise> { 11 | return Promise.all( 12 | modelIds.map((id) => manager.get_model(id.slice("IPY_MODEL_".length))) 13 | ); 14 | } 15 | 16 | export function loadFonts() { 17 | if (!document.querySelector(".custom-fonts")) { 18 | const styleElement = document.createElement("style"); 19 | styleElement.classList.add("custom-fonts"); 20 | styleElement.textContent = 21 | '@import "https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined";'; 22 | document.body.appendChild(styleElement); 23 | } 24 | } 25 | 26 | export async function updateChildren( 27 | container: HTMLElement, 28 | model: AnyModel, 29 | property = "children" 30 | ) { 31 | let children = model.get(property); 32 | if (!Array.isArray(children)) { 33 | children = [children]; 34 | } 35 | const child_models = await unpackModels(children, model.widget_manager); 36 | const child_views = await Promise.all( 37 | child_models.map((model) => model.widget_manager.create_view(model)) 38 | ); 39 | container.innerHTML = ``; 40 | for (const child_view of child_views) { 41 | container.appendChild(child_view.el); 42 | } 43 | } 44 | 45 | export function reverseMap(map: Map): Map { 46 | const reversedMap = new Map(); 47 | for (const [key, value] of map.entries()) { 48 | if (value != null) { 49 | reversedMap.set(value, key); 50 | } 51 | } 52 | return reversedMap; 53 | } 54 | 55 | export interface SelectOption { 56 | label: string; 57 | value: string; 58 | } 59 | 60 | export function renderSelect( 61 | options: Array | Array, 62 | value: string, 63 | callback: (event: Event) => void 64 | ): TemplateResult { 65 | const emptyOptions = options.length === 0; 66 | const newOptions = (emptyOptions ? ["---"] : options).map((option) => { 67 | const isObject = typeof option === "object"; 68 | const optValue = `${isObject ? option.value : option}`; 69 | const optLabel = `${isObject ? option.label : option}`; 70 | return html` 71 | 74 | `; 75 | }); 76 | return html` 77 | 84 | `; 85 | } 86 | -------------------------------------------------------------------------------- /karma.conf.cjs: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | process.env.CHROME_BIN = require('puppeteer').executablePath(); 4 | 5 | // test/karma.conf.js 6 | module.exports = config => { 7 | config.set({ 8 | frameworks: ['jasmine', 'webpack'], 9 | basePath: '', 10 | type: 'module', 11 | files: [ 12 | {pattern: 'js/*.ts', type:'module'}, 13 | {pattern: 'tests/*.spec.ts', type:'module'}, 14 | ], 15 | exclude: [], 16 | client: { 17 | clearContext: false, // leave Jasmine Spec Runner output visible in browser 18 | }, 19 | preprocessors: { 20 | '**/*.ts': ['webpack'], 21 | }, 22 | webpack: { 23 | mode: 'development', 24 | devtool: 'inline-source-map', 25 | module: { 26 | rules: [ 27 | { 28 | test: /\.ts$/, 29 | loader: "ts-loader", 30 | exclude: /node_modules/, 31 | options: { 32 | configFile: "tsconfig.webpack.json" 33 | } 34 | }, 35 | ], 36 | }, 37 | resolve: { 38 | extensions: ['.ts'], 39 | }, 40 | stats: { 41 | colors: true, 42 | modules: true, 43 | reasons: true, 44 | errorDetails: true 45 | }, 46 | }, 47 | reporters: ['spec', 'progress', 'kjhtml'], 48 | port: 9876, 49 | colors: true, 50 | logLevel: config.LOG_INFO, 51 | autoWatch: true, 52 | browsers: ['Chrome'], 53 | singleRun: false, 54 | restartOnFileChange: true, 55 | customLaunchers: { 56 | ChromeHeadlessNoSandbox: { 57 | base: 'ChromeHeadless', 58 | flags: ['--no-sandbox'], 59 | }, 60 | }, 61 | }); 62 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "dev": "npm run build -- --sourcemap=inline --watch", 4 | "build": "esbuild js/*.ts --format=esm --bundle --outdir=geemap/static", 5 | "typecheck": "tsc --noEmit", 6 | "pretest": "npm run build", 7 | "test": "karma start karma.conf.cjs --single-run --watch=false", 8 | "test:watch": "karma start karma.conf.cjs" 9 | }, 10 | "type": "module", 11 | "dependencies": { 12 | "lit": "^3.2.1" 13 | }, 14 | "devDependencies": { 15 | "@anywidget/types": "^0.1.9", 16 | "@types/jasmine": "^5.1.4", 17 | "@types/jasmine-expect": "^3.8.1", 18 | "esbuild": "^0.25.0", 19 | "jasmine": "^5.4.0", 20 | "jasmine-core": "^5.4.0", 21 | "jasmine-spec-reporter": "^7.0.0", 22 | "karma": "^6.4.4", 23 | "karma-chrome-launcher": "^3.2.0", 24 | "karma-jasmine": "^5.1.0", 25 | "karma-jasmine-html-reporter": "^2.1.0", 26 | "karma-spec-reporter": "^0.0.36", 27 | "karma-webpack": "^5.0.1", 28 | "puppeteer": "^23.5.3", 29 | "puppeteer-core": "^23.5.3", 30 | "ts-loader": "^9.5.1", 31 | "typescript": "^5.5.3", 32 | "webpack": "^5.95.0", 33 | "webpack-cli": "^5.1.4" 34 | } 35 | } -------------------------------------------------------------------------------- /paper/10.21105.joss.02305.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gee-community/geemap/0dbec7e4e9ccc385ddd6eae05a5be30615406ec6/paper/10.21105.joss.02305.pdf -------------------------------------------------------------------------------- /requirements_docs.txt: -------------------------------------------------------------------------------- 1 | black 2 | black[jupyter] 3 | bump-my-version 4 | codespell 5 | coverage 6 | deadlink 7 | ipykernel 8 | livereload 9 | mkdocs 10 | mkdocs-git-revision-date-localized-plugin 11 | mkdocs-git-revision-date-plugin 12 | mkdocs-jupyter>=0.24.0 13 | mkdocs-material>=9.1.3 14 | mkdocs-pdf-export-plugin 15 | mkdocstrings 16 | mkdocstrings-crystal 17 | mkdocstrings-python 18 | nbconvert 19 | nbformat 20 | pip 21 | pre-commit 22 | pygments 23 | pymdown-extensions 24 | pyproject-flake8 25 | sphinx 26 | tox 27 | twine 28 | watchdog 29 | wheel 30 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """Unit test package for geemap.""" 2 | -------------------------------------------------------------------------------- /tests/data/feature_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Feature", 3 | "children": [ 4 | { 5 | "label": "type: Feature", 6 | "children": [], 7 | "expanded": false, 8 | "topLevel": false 9 | }, 10 | { 11 | "label": "id: 00000000000000000001", 12 | "children": [], 13 | "expanded": false, 14 | "topLevel": false 15 | }, 16 | { 17 | "label": "properties: Object (4 properties)", 18 | "children": [ 19 | { 20 | "label": "fullname: some-full-name", 21 | "children": [], 22 | "expanded": false, 23 | "topLevel": false 24 | }, 25 | { 26 | "label": "linearid: 110469267091", 27 | "children": [], 28 | "expanded": false, 29 | "topLevel": false 30 | }, 31 | { 32 | "label": "mtfcc: S1400", 33 | "children": [], 34 | "expanded": false, 35 | "topLevel": false 36 | }, 37 | { 38 | "label": "rttyp: some-rttyp", 39 | "children": [], 40 | "expanded": false, 41 | "topLevel": false 42 | } 43 | ], 44 | "expanded": false, 45 | "topLevel": false 46 | } 47 | ], 48 | "expanded": false, 49 | "topLevel": false 50 | } 51 | -------------------------------------------------------------------------------- /tests/fake_anywidget.ts: -------------------------------------------------------------------------------- 1 | import type { AnyModel } from "@anywidget/types"; 2 | import type { IWidgetManager } from "@jupyter-widgets/base"; 3 | 4 | type ObjectHash = Record; 5 | 6 | export class FakeAnyModel implements AnyModel { 7 | public widget_manager: IWidgetManager = new Object() as IWidgetManager; 8 | 9 | constructor(private model: T) { } 10 | 11 | get(key: K) { 12 | return this.model[key]; 13 | } 14 | set(key: K, value: T[K]) { 15 | this.model[key] = value; 16 | } 17 | off() { } 18 | on() { } 19 | save_changes() { } 20 | send(_: Object) { }; 21 | } -------------------------------------------------------------------------------- /tests/layer_manager.spec.ts: -------------------------------------------------------------------------------- 1 | import { AnyModel } from "@anywidget/types"; 2 | import "../js/layer_manager"; 3 | 4 | import { default as layerManagerRender, LayerManager, LayerManagerModel } from "../js/layer_manager"; 5 | import { FakeAnyModel } from "./fake_anywidget"; 6 | 7 | describe("", () => { 8 | let layerManager: LayerManager; 9 | 10 | async function makeManager(model: AnyModel) { 11 | const container = document.createElement("div"); 12 | layerManagerRender.render({ 13 | model, el: container, experimental: { 14 | invoke: () => new Promise(() => [model, []]), 15 | } 16 | }); 17 | const element = container.firstElementChild as LayerManager; 18 | document.body.appendChild(element); 19 | await element.updateComplete; 20 | return element; 21 | } 22 | 23 | beforeEach(async () => { 24 | layerManager = await makeManager(new FakeAnyModel({ 25 | visible: true, 26 | children: [], 27 | })); 28 | }); 29 | 30 | afterEach(() => { 31 | Array.from(document.querySelectorAll("layer-manager")).forEach((el) => { 32 | el.remove(); 33 | }) 34 | }); 35 | 36 | it("can be instantiated.", async () => { 37 | expect(layerManager.shadowRoot?.querySelector(".all-layers-text")).toBeDefined(); 38 | }); 39 | 40 | it("sets model properties on property change.", async () => { 41 | const setSpy = spyOn(FakeAnyModel.prototype, "set"); 42 | const saveSpy = spyOn(FakeAnyModel.prototype, "save_changes"); 43 | layerManager.visible = false; 44 | await layerManager.updateComplete; 45 | expect(setSpy).toHaveBeenCalledOnceWith("visible", false); 46 | expect(saveSpy).toHaveBeenCalledTimes(1); 47 | }); 48 | }); -------------------------------------------------------------------------------- /tests/layer_manager_row.spec.ts: -------------------------------------------------------------------------------- 1 | import { AnyModel } from "@anywidget/types"; 2 | import "../js/layer_manager_row"; 3 | import { default as rowRender, LayerManagerRow, LayerManagerRowModel } from "../js/layer_manager_row"; 4 | import { FakeAnyModel } from "./fake_anywidget"; 5 | 6 | describe("", () => { 7 | let row: LayerManagerRow; 8 | 9 | async function makeRow(model: AnyModel) { 10 | const container = document.createElement("div"); 11 | rowRender.render({ 12 | model, el: container, experimental: { 13 | invoke: () => new Promise(() => [model, []]), 14 | } 15 | }); 16 | const element = container.firstElementChild as LayerManagerRow; 17 | document.body.appendChild(element); 18 | await element.updateComplete; 19 | return element; 20 | } 21 | 22 | beforeEach(async () => { 23 | row = await makeRow(new FakeAnyModel({ 24 | name: "Test Layer", 25 | visible: true, 26 | opacity: 1, 27 | is_loading: false, 28 | })); 29 | }); 30 | 31 | afterEach(() => { 32 | Array.from(document.querySelectorAll("layer-manager-row")).forEach((el) => { 33 | el.remove(); 34 | }) 35 | }); 36 | 37 | it("can be instantiated.", () => { 38 | expect(row.shadowRoot?.querySelector(".layer-name")?.textContent).toContain("Test Layer"); 39 | }); 40 | 41 | it("sets model properties on property change.", async () => { 42 | const setSpy = spyOn(FakeAnyModel.prototype, "set"); 43 | const saveSpy = spyOn(FakeAnyModel.prototype, "save_changes"); 44 | row.opacity = 0.5; 45 | await row.updateComplete; 46 | expect(setSpy).toHaveBeenCalledOnceWith("opacity", 0.5); 47 | expect(saveSpy).toHaveBeenCalledTimes(1); 48 | }); 49 | 50 | it("emits model events when clicked.", async () => { 51 | // Settings button emits an event. 52 | const sendSpy = spyOn(FakeAnyModel.prototype, "send"); 53 | (row.shadowRoot?.querySelector(".settings-button") as HTMLButtonElement).click(); 54 | expect(FakeAnyModel.prototype.send).toHaveBeenCalledOnceWith({ 55 | type: "click", 56 | id: "settings" 57 | }); 58 | 59 | sendSpy.calls.reset(); 60 | 61 | // Deletion button emits an event. 62 | (row.shadowRoot?.querySelector(".delete-button") as HTMLButtonElement).click(); 63 | await row.updateComplete; 64 | (row.shadowRoot?.querySelector(".confirm-deletion-button") as HTMLButtonElement).click(); 65 | expect(sendSpy).toHaveBeenCalledOnceWith({ 66 | type: "click", 67 | id: "delete" 68 | }); 69 | }); 70 | }); -------------------------------------------------------------------------------- /tests/legend.spec.ts: -------------------------------------------------------------------------------- 1 | import { AnyModel } from "@anywidget/types"; 2 | import { default as legendRender, Legend, LegendModel } from "../js/legend"; 3 | import { FakeAnyModel } from "./fake_anywidget"; 4 | 5 | import "../js/legend"; 6 | import { Container } from "../js/container"; 7 | 8 | describe("", () => { 9 | let legend: Legend; 10 | 11 | async function makeLegend(model: AnyModel) { 12 | const container = document.createElement("div"); 13 | legendRender.render({ 14 | model, el: container, experimental: { 15 | invoke: () => new Promise(() => [model, []]), 16 | } 17 | }); 18 | const element = container.firstElementChild as Legend; 19 | document.body.appendChild(element); 20 | await element.updateComplete; 21 | return element; 22 | } 23 | 24 | beforeEach(async () => { 25 | legend = await makeLegend(new FakeAnyModel({ 26 | title: "My Legend", 27 | legend_keys: ["fire", "grass", "water"], 28 | legend_colors: ["#ff0000", "#00ff00", "#0000ff"], 29 | add_header: true, 30 | show_close_button: true, 31 | })); 32 | }); 33 | 34 | afterEach(() => { 35 | Array.from(document.querySelectorAll("legend-widget")).forEach((el) => { 36 | el.remove(); 37 | }) 38 | }); 39 | 40 | it("can be instantiated.", () => { 41 | expect(legend.shadowRoot?.querySelector("widget-container")).toBeDefined(); 42 | }); 43 | 44 | it("renders a header with title and close button", () => { 45 | const header = legend.shadowRoot?.querySelector("widget-container")!! as Container 46 | expect(header.title).toBe("My Legend"); 47 | expect(header.hideCloseButton).toBeFalse(); 48 | }); 49 | 50 | 51 | it("does not render a header when add_header is false", async () => { 52 | legend.addHeader = false 53 | await legend.updateComplete; 54 | expect(legend.shadowRoot?.querySelector("widget-container")).toBeNull(); 55 | expect(legend.shadowRoot?.textContent).toContain("My Legend"); 56 | }); 57 | 58 | it("renders the legend", async () => { 59 | const legendItems = legend.shadowRoot?.querySelectorAll('li')!; 60 | expect(Array.from(legendItems) 61 | .map((el) => el.textContent?.trim())) 62 | .toEqual(["fire", "grass", "water"]); 63 | expect(Array.from(legendItems) 64 | .map((el) => el.querySelector('span')?.style.background)) 65 | .toEqual(["rgb(255, 0, 0)", "rgb(0, 255, 0)", "rgb(0, 0, 255)"]); 66 | }); 67 | 68 | it("handles mismatched key/color size", async () => { 69 | legend.legendKeys = ["fire", "grass", "water", "electricity"] 70 | const legendItems = legend.shadowRoot?.querySelectorAll('li')!; 71 | expect(Array.from(legendItems) 72 | .map((el) => el.textContent?.trim())) 73 | .toEqual(["fire", "grass", "water"]); 74 | }); 75 | }); -------------------------------------------------------------------------------- /tests/test_geemap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | """Tests for `geemap` package.""" 4 | 5 | 6 | import unittest 7 | import geemap 8 | import ipyleaflet 9 | 10 | 11 | class TestGeemap(unittest.TestCase): 12 | """Tests for `geemap` package.""" 13 | 14 | def setUp(self): 15 | """Set up test fixtures, if any.""" 16 | # geemap.ee_initialize() 17 | 18 | def tearDown(self): 19 | """Tear down test fixtures, if any.""" 20 | 21 | def test_map(self): 22 | m = geemap.Map(ee_initialize=False) 23 | self.assertIsInstance(m, ipyleaflet.Map) 24 | -------------------------------------------------------------------------------- /tests/utils.py: -------------------------------------------------------------------------------- 1 | """Helpers for unit tests.""" 2 | 3 | 4 | def query_widget(node, type_matcher, matcher=None): 5 | """Recursively searches the widget hierarchy for the widget.""" 6 | if matcher is None: 7 | matcher = lambda c: True 8 | 9 | if hasattr(node, "layout"): 10 | if hasattr(node.layout, "display"): 11 | if node.layout.display == "none": 12 | return None 13 | if hasattr(node, "style"): 14 | if hasattr(node.style, "display"): 15 | if node.style.display == "none": 16 | return None 17 | 18 | children = getattr(node, "children", getattr(node, "nodes", None)) 19 | if children is not None: 20 | for child in children: 21 | result = query_widget(child, type_matcher, matcher) 22 | if result: 23 | return result 24 | if isinstance(node, type_matcher) and matcher(node): 25 | return node 26 | return None 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "js" 4 | ], 5 | "compilerOptions": { 6 | "target": "ES2020", 7 | "module": "ESNext", 8 | "lib": [ 9 | "ES2020", 10 | "DOM", 11 | "DOM.Iterable" 12 | ], 13 | "skipLibCheck": true, 14 | "moduleResolution": "bundler", 15 | "allowImportingTsExtensions": true, 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "noEmit": true, 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "downlevelIteration": true, 24 | "experimentalDecorators": true, 25 | "emitDecoratorMetadata": true 26 | } 27 | } -------------------------------------------------------------------------------- /tsconfig.webpack.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "js", 4 | "tests" 5 | ], 6 | "compilerOptions": { 7 | "target": "ES2020", 8 | "module": "ESNext", 9 | "lib": [ 10 | "ES2020", 11 | "DOM", 12 | "DOM.Iterable" 13 | ], 14 | "skipLibCheck": true, 15 | "moduleResolution": "bundler", 16 | "allowImportingTsExtensions": false, 17 | "resolveJsonModule": true, 18 | "isolatedModules": true, 19 | "noEmit": false, 20 | "strict": true, 21 | "sourceMap": true, 22 | "noUnusedLocals": true, 23 | "noUnusedParameters": true, 24 | "noFallthroughCasesInSwitch": true, 25 | "downlevelIteration": true, 26 | "experimentalDecorators": true, 27 | "emitDecoratorMetadata": true, 28 | } 29 | } -------------------------------------------------------------------------------- /tutorials/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Qiusheng Wu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tutorials/README.md: -------------------------------------------------------------------------------- 1 | # earthengine-py-documentation 2 | Unofficial Google Earth Engine Python Documentation 3 | -------------------------------------------------------------------------------- /tutorials/Template/update_header.py: -------------------------------------------------------------------------------- 1 | import os 2 | from geemap.conversion import * 3 | 4 | work_dir = os.path.dirname(os.path.dirname(__file__)) 5 | update_nb_header_dir(work_dir, github_username="giswqs", github_repo="geemap") 6 | --------------------------------------------------------------------------------