Skip to content

Commit

Permalink
Added geojson to ee geometry
Browse files Browse the repository at this point in the history
  • Loading branch information
giswqs committed Mar 24, 2020
1 parent f8a608c commit 838c268
Show file tree
Hide file tree
Showing 3 changed files with 224 additions and 4 deletions.
3 changes: 3 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ geemap
.. image:: https://readthedocs.org/projects/geemap/badge/?version=latest
:target: https://geemap.readthedocs.io/en/latest/?badge=latest

.. image:: https://img.shields.io/twitter/follow/giswqs?style=social
:target: https://twitter.com/giswqs

.. image:: https://img.shields.io/badge/License-MIT-yellow.svg
:target: https://opensource.org/licenses/MIT

Expand Down
173 changes: 173 additions & 0 deletions examples/notebooks/ipyleaflet_draw_control.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<table class=\"ee-notebook-buttons\" align=\"left\">\n",
" <td><a target=\"_blank\" href=\"https://github.com/giswqs/geemap/tree/master/examples/notebooks/ipyleaflet_draw_control.ipynb\"><img width=32px src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" /> View source on GitHub</a></td>\n",
" <td><a target=\"_blank\" href=\"https://nbviewer.jupyter.org/github/giswqs/geemap/blob/master/examples/notebooks/ipyleaflet_draw_control.ipynb\"><img width=26px src=\"https://upload.wikimedia.org/wikipedia/commons/thumb/3/38/Jupyter_logo.svg/883px-Jupyter_logo.svg.png\" />Notebook Viewer</a></td>\n",
" <td><a target=\"_blank\" href=\"https://mybinder.org/v2/gh/giswqs/geemap/master?filepath=examples/notebooks/ipyleaflet_draw_control.ipynb\"><img width=56px src=\"https://mybinder.org/static/images/logo_social.png\" />Run in mybinder.org</a></td>\n",
" <td><a target=\"_blank\" href=\"https://binder.pangeo.io/v2/gh/giswqs/geemap/master?filepath=examples/notebooks/ipyleaflet_draw_control.ipynb\"><img width=60px src=\"https://i.imgur.com/NiV7heh.png\" />Run in binder.pangeo.io</a></td>\n",
" <td><a target=\"_blank\" href=\"https://colab.research.google.com/github/giswqs/geemap/blob/master/examples/notebooks/ipyleaflet_draw_control.ipynb\"><img width=26px src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" /> Run in Google Colab</a></td>\n",
"</table>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Using ipyleaflet drawing tools to interact with Earth Engine data\n",
"\n",
"* [Video demo](https://i.imgur.com/SzauIsZ.gifv)\n",
"\n",
"## Install Earth Engine API and geemap\n",
"Install the [Earth Engine Python API](https://developers.google.com/earth-engine/python_install) and [geemap](https://github.com/giswqs/geemap). 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()`.\n",
"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/giswqs/geemap#dependencies), including earthengine-api, folium, and ipyleaflet.\n",
"\n",
"**Important note**: A key difference between folium and ipyleaflet is that ipyleaflet is built upon ipywidgets and allows bidirectional communication between the front-end and the backend enabling the use of the map to capture user input, while folium is meant for displaying static data only ([source](https://blog.jupyter.org/interactive-gis-in-jupyter-with-ipyleaflet-52f9657fa7a)). Note that [Google Colab](https://colab.research.google.com/) currently does not support ipyleaflet ([source](https://github.com/googlecolab/colabtools/issues/60#issuecomment-596225619)). Therefore, if you are using geemap with Google Colab, you should use [`import geemap.eefolium`](https://github.com/giswqs/geemap/blob/master/geemap/eefolium.py). If you are using geemap with [binder](https://mybinder.org/) or a local Jupyter notebook server, you can use [`import geemap`](https://github.com/giswqs/geemap/blob/master/geemap/geemap.py), which provides more functionalities for capturing user input (e.g., mouse-clicking and moving)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Installs geemap package\n",
"import subprocess\n",
"\n",
"try:\n",
" import geemap\n",
"except ImportError:\n",
" print('geemap package not installed. Installing ...')\n",
" subprocess.check_call([\"python\", '-m', 'pip', 'install', '-U', 'geemap'])\n",
"\n",
"# Checks whether this notebook is running on Google Colab\n",
"try:\n",
" import google.colab\n",
" import geemap.eefolium as emap\n",
"except:\n",
" import geemap as emap\n",
"\n",
"# Authenticates and initializes Earth Engine\n",
"import ee\n",
"\n",
"try:\n",
" ee.Initialize()\n",
"except Exception as e:\n",
" ee.Authenticate()\n",
" ee.Initialize() "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create an interactive map \n",
"The default basemap is `Google Satellite`. [Additional basemaps](https://github.com/giswqs/geemap/blob/master/geemap/geemap.py#L13) can be added using the `Map.add_basemap()` function. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Map = emap.Map(center=[40,-100], zoom=4)\n",
"Map.add_basemap('ROADMAP') # Add Google Map\n",
"Map"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import ipywidgets as widgets\n",
"from ipyleaflet import WidgetControl\n",
"from geemap import geojson_to_eegeometry\n",
"\n",
"# Add Earth Engine dataset\n",
"image = ee.Image('USGS/SRTMGL1_003')\n",
"\n",
"# Set visualization parameters.\n",
"vis_params = {\n",
" 'min': 0,\n",
" 'max': 4000,\n",
" 'palette': ['006633', 'E5FFCC', '662A00', 'D8D8D8', 'F5F5F5']}\n",
"\n",
"# Get basemap layers\n",
"base_layers = Map.layers\n",
"\n",
"# Add Earth Engine DEM to map\n",
"Map.addLayer(image, vis_params, 'EE DEM')\n",
"\n",
"# An empty list for storing drawing geometries\n",
"feat_list = []\n",
"\n",
"# Get the DrawControl\n",
"dc = Map.draw_control\n",
"\n",
"# Handle draw events\n",
"def handle_draw(self, action, geo_json):\n",
"\n",
" geom = geojson_to_eegeometry(geo_json, False)\n",
" feature = ee.Feature(geom)\n",
" feat_list.append(feature)\n",
" collection = ee.FeatureCollection(feat_list)\n",
" clip_image = image.clipToCollection(collection)\n",
" \n",
" Map.layers = base_layers[:3]\n",
" Map.addLayer(clip_image, vis_params, 'EE DEM')\n",
" Map.addLayer(ee.Image().paint(collection, 0, 2), {'palette': 'red'}, 'EE Geometry')\n",
"\n",
"dc.on_draw(handle_draw)\n",
"\n",
"# Add a button to the map\n",
"button = widgets.Button(description=\"Clear drawings\")\n",
"btn_control = WidgetControl(widget=button, position='bottomright')\n",
"Map.add_control(btn_control)\n",
"\n",
"# Handle click event\n",
"def on_button_clicked(b):\n",
" dc.clear()\n",
"\n",
"button.on_click(on_button_clicked)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Print out the geojson of the last drawing object\n",
"dc.last_draw"
]
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.2"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
52 changes: 48 additions & 4 deletions geemap/geemap.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,35 @@ def __init__(self, **kwargs):

super().__init__(**kwargs)
self.scroll_wheel_zoom= True
self.add_control(LayersControl(position='topright'))
self.add_control(ScaleControl(position='bottomleft'))
self.add_control(FullScreenControl())
self.add_control(DrawControl())

layers = LayersControl(position='topright')
self.add_control(layers)
self.layer_control = layers

scale =ScaleControl(position='bottomleft')
self.add_control(scale)
self.scale_control = scale

fullscreen = FullScreenControl()
self.add_control(fullscreen)
self.fullscreen_control = fullscreen

draw = DrawControl(marker={'shapeOptions': {'color': '#0000FF'}},
rectangle={'shapeOptions': {'color': '#0000FF'}},
circle={'shapeOptions': {'color': '#0000FF'}},
circlemarker={},
)

self.add_control(draw)
self.draw_control = draw

measure = MeasureControl(
position='bottomleft',
active_color='orange',
primary_length_unit='kilometers'
)
self.add_control(measure)
self.measure_control = measure

self.add_layer(ee_basemaps['HYBRID'])

Expand Down Expand Up @@ -483,3 +501,29 @@ def ee_tile_layer(ee_object, vis_params={}, name='Layer untitled', shown=True, o
)
return tile_layer


def geojson_to_eegeometry(geo_json, geodesic=True):
"""Converts a geojson to ee.Geometry()
Args:
geo_json (dict): A geojson geometry dictionary.
Returns:
ee_object: An ee.Geometry object
"""
try:

keys = geo_json['properties']['style'].keys()
if 'radius' in keys:
geom = ee.Geometry(geo_json['geometry'])
radius = geo_json['properties']['style']['radius']
geom = geom.buffer(radius)
# return geom
else:
geom = ee.Geometry(geo_json['geometry'], "", geodesic)
# if 'radius' in keys: # Checks whether it is a circle
return geom

except:
print("Could not convert the geojson to ee.Geometry()")

0 comments on commit 838c268

Please sign in to comment.