updated from GitHub

Kilian Vos 6 years ago
parent a0b49c7dcf
commit 33a1d63b05

6
.gitignore vendored

@ -2,8 +2,10 @@
*.mat *.mat
*.tif *.tif
*.png *.png
*.PNG
*.jpeg
*.mp4 *.mp4
*.gif
*.jpg *.jpg
*.pkl *.pkl
*.xml *.kml
*checkpoint.ipynb

@ -1,59 +1,186 @@
# CoastSat # CoastSat
Python code to extract shorelines at sub-pixel resolution from publicly available satellite imagery. The shoreline detection algorithm is described in *Vos K., Harley M.D., Splinter K.D., Simmons J.A., Turner I.L. (in review). Capturing intra-annual to multi-decadal shoreline variability from publicly available satellite imagery, Coastal Engineering*. Google Earth Engine's Python API is used to access the archive of publicly available satellite imagery (Landsat series and Sentinel-2). This software enables the users to extract time-series of shoreline change over the last 30+ years at their site of interest.
Written by *Kilian Vos*. ![Alt text](https://github.com/kvos/CoastSat/blob/development/classifiers/doc/example.gif)
## Description The algorithms used in this software are described in:
Satellite remote sensing can provide low-cost long-term shoreline data capable of resolving the temporal scales of interest to coastal scientists and engineers at sites where no in-situ measurements are available. Satellite imagery spannig the last 30 years with constant revisit periods is publicly available and suitable to extract repeated measurements of the shoreline positon. *Vos K., Splinter K.D., Harley M.D., Simmons J.A., Turner I.L. (submitted). CoastSat: a Google Earth Engine-enabled software to extract shorelines from publicly available satellite imagery, Environmental Modelling and Software*.
*coastsat* is an open-source Python module that allows to extract shorelines from Landsat 5, Landsat 7, Landsat 8 and Sentinel-2 images.
The shoreline detection algorithm proposed here combines a sub-pixel border segmentation and an image classification component, which refines the segmentation into four distinct categories such that the shoreline detection is specific to the sand/water interface.
## Requirements There are two main steps:
- retrieval of the satellite images of the region of interest from Google Earth Engine
- extraction of the shorelines from the images using a sub-pixel resolution technique
In this section instructions on how to install all the necessary Python packages using *Anaconda* are provided.
Best practice is to create a new environment that will contain all the packages. To do this open the *Anaconda prompt* and run the following command:
- *conda create -n coastsat python=3.6* (it will create a new Python 3.6 environment called *coastsat*)
Then activate the new environment run: ### Description
- *conda activate coastsat*
Now you need to install **Google Earth Engine's Python API** module. Satellite remote sensing can provide low-cost long-term shoreline data capable of resolving the temporal scales of interest to coastal scientists and engineers at sites where no in-situ measurements are available. Satellite imagery spanning the last 30 years with constant revisit periods is publicly available and suitable to extract repeated measurements of the shoreline position.
Follow these steps to install the *earthengine-api* package: CoastSat is an open-source Python module that allows the user to extract shorelines from Landsat 5, Landsat 7, Landsat 8 and Sentinel-2 images.
- go to https://earthengine.google.com and go to signup The shoreline detection algorithm implemented in CoastSat combines a sub-pixel border segmentation and an image classification component, which refines the segmentation into four distinct categories such that the shoreline detection is specific to the sand/water interface.
Go back to the *Anaconda prompt* where the *coastsat* environment is active and run the following commands:
- *conda install -c conda-forge earthengine-api*
- *earthengine authenticate* (this will open a web browser where you will have login with your Google Earth Engine credentials)
Once you have installed the *earthengine-api*, you need to install the other Python packages that are used in this toolbox (*scikit-image*, *scikit-learn* etc...). ## 1. Installation
If on *win-64*, use the *Anaconda prompt* to navigate to the directory where you downloaded the repository and run: CoastSat requires the following Python packages to run:
- *conda install --name coastsat --file environment.txt* (this will install all the necessary packages) ```
conda-forge: python=3.6 | matplotlib | scikit-image | scikit-learn | gdal | earthengine-api | oauth2client | spyder | jupyter | simplekml
PyPi: shapely
```
If you are not a regular Python user and are not sure how to install these packages from *conda-forge* and *PyPi*, the section below shows how to install them step-by-step using Anaconda. Otherwise, install the packages and go directly to section **1.2 Activating Google Earth Engine Python API**.
Now you are ready to start using the toolbox! ### 1.1 Installing the packages (Anaconda)
If on *linux* or *osx*, you can create the *coastsat* environment with the following command: If Anaconda is not already installed on your PC, you can get it at https://www.anaconda.com/download/.
- *conda env create -f environment.yml* Open the *Anaconda prompt* (in Mac and Linux, open a terminal window) and drive to the folder where you have downloaded/cloned this repository.
Then, follow the instructions above to install *earthengine-api* in your environment. Create a new environment named *coastsat*:
## Use ```
conda create -n coastsat
```
A demonstration of the use of *coastsat* is provided in the Jupyter Notebook *shoreline_extraction.ipynb*. The code can also be run in Spyder with *main_spyder.py*. Activate the new environment:
The first step is to retrieve the satellite images of the region of interest from Google Earth Engine servers by calling *SDS_download.get_images(sitename, polygon, dates, sat_list)*: ```
- *sitename* is a string which will define the name of the folder where the files will be stored conda activate coastsat
- *polygon* contains the coordinates of the region of interest (longitude/latitude pairs) ```
- *dates* defines the dates over which the images will be retrieved (e.g., *dates = ['2017-12-01', '2018-01-01']*)
- *sat_list* indicates which satellite missions to consider (e.g., *sat_list = ['L5', 'L7', 'L8', 'S2']* will download images from Landsat 5, 7, 8 and Sentinel-2 collections).
The images are cropped on the Google Earth Engine servers and only the region of interest is downloaded resulting in low memory allocation (~ 1 megabyte/image for a 5km-long beach). The relevant image metadata (time of acquisition, geometric accuracy...etc) is stored in a file named *sitename_metadata.pkl*. On Linux systems, type `source activate coastsat` instead.
Once the images have been downloaded, the shorelines are extracted from the multispectral images using the sub-pixel resolution technique described in *Vos K., Harley M.D., Splinter K.D., Simmons J.A., Turner I.L. (in review). Capturing intra-annual to multi-decadal shoreline variability from publicly available satellite imagery, Coastal Engineering*. To know if you have activated coastsat, your terminal command line prompt should now start with (coastsat) when it is activated.
The shoreline extraction is performed by the function SDS_shoreline.extract_shorelines(metadata, settings). The user must define the settings in a Python dictionary. To ensure maximum robustness of the algorithm the user can optionally digitize a reference shoreline (byc calling *SDS_preprocess.get_reference_sl(metadata, settings)*) that will then be used to identify obvious outliers and minimize false detections. Since the cloud mask is not perfect (especially in Sentinel-2 images) the user has the option to manually validate each detection by setting the *'check_detection'* parameter to *True*.
The shoreline coordinates (in the coordinate system defined by the user in *'output_epsg'* are stored in a file named *sitename_out.pkl*. Now you need to populate the environment with the packages needed to run CoastSat. All the necessary packages are contained in three platform specific files: `requirements_win64.txt`, `requirements_osx64.txt`, `requirements_linux64.txt`. To install the packages, run one of the following commands, depending on which platform you are operating:
#### Windows 64 bits (win64)
```
conda install --name coastsat --file requirements_win64.txt
```
#### Mac 64 bits (osx64)
```
conda install --name coastsat --file requirements_osx64.txt
```
#### Linux 64 bits (linux64)
```
conda install --name coastsat --file requirements_linux64.txt
```
This might take a few minutes... once it is finished run the following command:
```
pip install shapely
```
All the packages have now been install in an environment called `coastsat`.
### 1.2 Activating Google Earth Engine Python API
Go to https://earthengine.google.com and sign up to Google Earth Engine.
![gee_capture](https://user-images.githubusercontent.com/7217258/49348457-a9271300-f6f9-11e8-8c0b-407383940e94.jpg)
Once you have created a Google Earth Engine account, go back to Anaconda and link your GEE credentials to the Python API:
```
earthengine authenticate
```
A web browser will open, login with your GEE credentials, accept the terms and conditions and copy the authorization code into the Anaconda terminal.
Now you are ready to start using the CoastSat toolbox!
## 2. Usage
**Note**: remeber to always activate the `coastsat` environment with `conda activate coastsat` each time you wish to use it.
Your terminal command line prompt should start with (coastsat) when it is activated.
An example of how to run the software in a Jupyter Notebook is provided in the repository (`example_jupyter.ipynb`). To run it, first activate your `coastsat` environment with `conda activate coastsat` (if not already active), and then type:
```
jupyter notebook
```
A web browser window will open, drive to the directory where you downloaded/cloned this repository and click on `example_jupyter.ipynb`.
The following sections guide the reader through the different functionalities of CoastSat with an example at Narrabeen beach (Australia).
To run a Jupyter Notebook, put your cursor inside one of the code sections and then hit the 'run' button up in the top menu to run that section and progress forward (as shown in the animation below).
![example_jupyter](https://user-images.githubusercontent.com/7217258/49705486-8dc88480-fc72-11e8-8300-c342baaf54eb.gif)
### 2.1 Retrieval of the satellite images
To retrieve the satellite images cropped around the the region of interest from Google Earth Engine servers the following user-defined variables are needed:
- `polygon`: the coordinates of the region of interest (longitude/latitude pairs)
- `dates`: dates over which the images will be retrieved (e.g., `dates = ['2017-12-01', '2018-01-01']`)
- `sat_list`: satellite missions to consider (e.g., `sat_list = ['L5', 'L7', 'L8', 'S2']` for Landsat 5, 7, 8 and Sentinel-2 collections).
- `sitename`: name of the site (defines the name of the subfolder where the files will be stored)
The call `metadata = SDS_download.retrieve_images(inputs)` will launch the retrieval of the images and store them as .TIF files (under *.data\sitename*). The metadata contains the exact time of acquisition (UTC) and geometric accuracy of each downloaded image and is saved as `metadata_sitename.pkl`. If the images have already been downloaded previously and the user only wants to run the shoreline detection, the metadata can be loaded directly from this file. The screenshot below shows an example where all the images of Narrabeen-Collaroy (Australia) acquired in December 2017 are retrieved.
![retrieval](https://user-images.githubusercontent.com/7217258/49353105-0037e280-f710-11e8-9454-c03ce6116c54.PNG)
### 2.2 Shoreline detection
It is finally time to map shorelines!
The following user-defined settings are required:
- `cloud_thresh`: threshold on maximum cloud cover that is acceptable on the images (value between 0 and 1)
- `output_epsg`: epsg code defining the spatial reference system of the shoreline coordinates
- `check_detection`: if set to `True` allows the user to quality control each shoreline detection
See http://spatialreference.org/ to find the EPSG number corresponding to your local coordinate system. If the user wants to quality control the mapped shorelines and manually validate each detection, the parameter `check_detection` should be set to `True`.
In addition, there are extra parameters (`min_beach_size`, `buffer_size`, `min_length_sl`) that can be tuned to optimise the shoreline detection (for Advanced users only). For the moment leave those parameters to their default values, we will see later how they can be modified.
An example of settings is provided here:
![settings](https://user-images.githubusercontent.com/7217258/49565578-ba7f5200-f97b-11e8-9bb4-8d933329b625.PNG)
Once all the settings have been defined, the batch shoreline detection can be launched by calling:
```
output = SDS_shoreline.extract_shorelines(metadata, settings)
```
When `check_detection` is set to `True`, a figure like the one below appears and asks the user to manually accept/reject each detection by clicking on `keep` or `skip`.
![Alt text](https://github.com/kvos/CoastSat/blob/development/classifiers/doc/batch_detection.gif)
Once all the shorelines have been mapped, the output is available in two different formats (saved under *.\data\sitename*):
- `sitename_output.pkl`: contains a list with the shoreline coordinates and the exact timestamp at which the image was captured (UTC time) as well as the geometric accuracy and the cloud cover of the image. The list can be manipulated with Python, a snippet of code to plot the results is provided in the main script.
- `sitename_output.kml`: this output can be visualised in a GIS software (e.g., QGIS, ArcGIS).
The figure below shows how the satellite-derived shorelines can be opened in GIS software using the `.kml` output.
![gis_output](https://user-images.githubusercontent.com/7217258/49361401-15bd0480-f730-11e8-88a8-a127f87ca64a.jpeg)
### Advanced shoreline detection parameters
As mentioned above, there are extra parameters that can be modified to optimise the shoreline detection:
- `min_beach_area`: minimum allowable object area (in metres^2) for the class sand. During the image classification, some building roofs may be incorrectly labelled as sand. To correct this, all the objects classified as sand containing less than a certain number of connected pixels are removed from the sand class. The default value of `min_beach_area` is 4500 m^2, which corresponds to 20 connected pixels of 15 m^2. If you are looking at a very small beach (<20 connected pixels on the images), decrease the value of this parameter.
- `buffer_size`: radius (in metres) that defines the buffer around sandy pixels that is considered for the shoreline detection. The default value of `buffer_size` is 150 m. This parameter should be increased if you have a very wide (>150 m) surf zone or inter-tidal zone.
- `min_length_sl`: minimum length (in metres) of shoreline perimeter to be valid. This allows to discard small contours that are detected but do not correspond to the actual shoreline. The default value is 200 m. If the shoreline that you are trying to map is shorter than 200 m, decrease the value of this parameter.
### Reference shoreline
There is also an option to manually digitize a reference shoreline before running the batch shoreline detection on all the images. This reference shoreline helps to reject outliers and false detections when mapping shorelines as it only considers as valid shorelines the points that are within a distance from this reference shoreline.
The user can manually digitize a reference shoreline on one of the images by calling:
```
settings['reference_shoreline'] = SDS_preprocess.get_reference_sl_manual(metadata, settings)
settings['max_dist_ref'] = 100 # max distance (in meters) allowed from the reference shoreline
```
This function allows the user to click points along the shoreline on one of the satellite images, as shown in the animation below.
![ref_shoreline](https://user-images.githubusercontent.com/7217258/49710753-94b1c000-fc8f-11e8-9b6c-b5e96aadc5c9.gif)
The maximum distance (in metres) allowed from the reference shoreline is defined by the parameter `max_dist_ref`. This parameter is set to a default value of 100 m. If you think that your shoreline will move more than 100 m, please change this parameter to an appropriate distance. This may be the case for large nourishments or eroding/accreting coastlines.
## Issues and Contributions ## Issues and Contributions
Looking to contribute to the code? Please see the [Issues page](https://github.com/kvos/coastsat/issues). Having a problem or looking to contribute to the code? Please see the [Issues page](https://github.com/kvos/coastsat/issues).

@ -61,7 +61,7 @@ def download_tif(image, polygon, bandsId, filepath):
return local_zipfile.extract('data.tif', filepath) return local_zipfile.extract('data.tif', filepath)
def get_images(inputs): def retrieve_images(inputs):
""" """
Downloads all images from Landsat 5, Landsat 7, Landsat 8 and Sentinel-2 covering the area of Downloads all images from Landsat 5, Landsat 7, Landsat 8 and Sentinel-2 covering the area of
interest and acquired between the specified dates. interest and acquired between the specified dates.

@ -616,7 +616,7 @@ def get_reference_sl_manual(metadata, settings):
Returns: Returns:
----------- -----------
ref_sl: np.array reference_shoreline: np.array
coordinates of the reference shoreline that was manually digitized coordinates of the reference shoreline that was manually digitized
""" """
@ -625,10 +625,10 @@ def get_reference_sl_manual(metadata, settings):
# check if reference shoreline already exists in the corresponding folder # check if reference shoreline already exists in the corresponding folder
filepath = os.path.join(os.getcwd(), 'data', sitename) filepath = os.path.join(os.getcwd(), 'data', sitename)
filename = sitename + '_ref_sl.pkl' filename = sitename + '_reference_shoreline.pkl'
if filename in os.listdir(filepath): if filename in os.listdir(filepath):
print('Reference shoreline already exists and was loaded') print('Reference shoreline already exists and was loaded')
with open(os.path.join(filepath, sitename + '_ref_sl.pkl'), 'rb') as f: with open(os.path.join(filepath, sitename + '_reference_shoreline.pkl'), 'rb') as f:
refsl = pickle.load(f) refsl = pickle.load(f)
return refsl return refsl
@ -695,22 +695,42 @@ def get_reference_sl_manual(metadata, settings):
keep_button.set_visible(False) keep_button.set_visible(False)
skip_button.set_visible(False) skip_button.set_visible(False)
# update title (instructions) # update title (instructions)
plt.title('Digitize the shoreline on this image by clicking on it.\n' + plt.title('Click points along the shoreline every ~500 m.\n' +
'When finished digitizing the shoreline click on the scroll wheel ' + 'Start at one end of the beach.\n' + 'When finished digitizing, click <ENTER>',
'(middle click).', fontsize=14) fontsize=14)
plt.draw() plt.draw()
# let user click on the shoreline # let user click on the shoreline
pts = ginput(n=50000, timeout=100000, show_clicks=True) pts = ginput(n=50000, timeout=1e9, show_clicks=True)
pts_pix = np.array(pts) pts_pix = np.array(pts)
# interpolate between points and show the output to the user
pts_pix_interp = np.expand_dims(np.array([np.nan, np.nan]),axis=0)
for k in range(len(pts_pix)-1):
if pts_pix[k,0] < pts_pix[k+1,0]:
x = pts_pix[[k,k+1],0]
y = pts_pix[[k,k+1],1]
else:
x = pts_pix[[k+1,k],0]
y = pts_pix[[k+1,k],1]
xvals = np.linspace(x[0],x[1],50)
yinterp = np.interp(xvals,x,y)
pts_pix_interp = np.append(pts_pix_interp,
np.transpose(np.array([xvals,yinterp])), axis=0)
pts_pix_interp = np.delete(pts_pix_interp,0,axis=0)
plt.plot(pts_pix_interp[:,0], pts_pix_interp[:,1], 'r.', markersize=5)
plt.title('Saving reference shoreline as ' + sitename + '_reference_shoreline.pkl ...')
plt.draw()
ginput(n=1, timeout=5, show_clicks=True)
plt.close() plt.close()
# convert image coordinates to world coordinates # convert image coordinates to world coordinates
pts_world = SDS_tools.convert_pix2world(pts_pix[:,[1,0]], georef) pts_world = SDS_tools.convert_pix2world(pts_pix_interp[:,[1,0]], georef)
image_epsg = metadata[satname]['epsg'][i] image_epsg = metadata[satname]['epsg'][i]
pts_coords = SDS_tools.convert_epsg(pts_world, image_epsg, settings['output_epsg']) pts_coords = SDS_tools.convert_epsg(pts_world, image_epsg, settings['output_epsg'])
# save the reference shoreline # save the reference shoreline
filepath = os.path.join(os.getcwd(), 'data', sitename) filepath = os.path.join(os.getcwd(), 'data', sitename)
with open(os.path.join(filepath, sitename + '_ref_sl.pkl'), 'wb') as f: with open(os.path.join(filepath, sitename + '_reference_shoreline.pkl'), 'wb') as f:
pickle.dump(pts_coords, f) pickle.dump(pts_coords, f)
print('Reference shoreline has been saved') print('Reference shoreline has been saved')
break break

@ -31,6 +31,7 @@ import matplotlib.cm as cm
from matplotlib import gridspec from matplotlib import gridspec
from pylab import ginput from pylab import ginput
import pickle import pickle
import simplekml
# own modules # own modules
import SDS_tools, SDS_preprocess import SDS_tools, SDS_preprocess
@ -132,7 +133,7 @@ def calculate_features(im_ms, cloud_mask, im_bool):
return features return features
def classify_image_NN(im_ms, im_extra, cloud_mask, min_beach_size, satname): def classify_image_NN(im_ms, im_extra, cloud_mask, min_beach_area, satname):
""" """
Classifies every pixel in the image in one of 4 classes: Classifies every pixel in the image in one of 4 classes:
- sand --> label = 1 - sand --> label = 1
@ -152,7 +153,7 @@ def classify_image_NN(im_ms, im_extra, cloud_mask, min_beach_size, satname):
only used for Landsat 7 and 8 where im_extra is the panchromatic band only used for Landsat 7 and 8 where im_extra is the panchromatic band
cloud_mask: np.array cloud_mask: np.array
2D cloud mask with True where cloud pixels are 2D cloud mask with True where cloud pixels are
min_beach_size: int min_beach_area: int
minimum number of pixels that have to be connected in the SAND class minimum number of pixels that have to be connected in the SAND class
Returns: ----------- Returns: -----------
@ -216,8 +217,8 @@ def classify_image_NN(im_ms, im_extra, cloud_mask, min_beach_size, satname):
im_swash = im_classif == 2 im_swash = im_classif == 2
im_water = im_classif == 3 im_water = im_classif == 3
# remove small patches of sand or water that could be around the image (usually noise) # remove small patches of sand or water that could be around the image (usually noise)
im_sand = morphology.remove_small_objects(im_sand, min_size=min_beach_size, connectivity=2) im_sand = morphology.remove_small_objects(im_sand, min_size=min_beach_area, connectivity=2)
im_water = morphology.remove_small_objects(im_water, min_size=min_beach_size, connectivity=2) im_water = morphology.remove_small_objects(im_water, min_size=min_beach_area, connectivity=2)
im_labels = np.stack((im_sand,im_swash,im_water), axis=-1) im_labels = np.stack((im_sand,im_swash,im_water), axis=-1)
@ -339,7 +340,7 @@ def find_wl_contours2(im_ms, im_labels, cloud_mask, buffer_size):
im_mwi_buffer = np.copy(im_mwi) im_mwi_buffer = np.copy(im_mwi)
im_mwi_buffer[~im_buffer] = np.nan im_mwi_buffer[~im_buffer] = np.nan
contours_wi = measure.find_contours(im_wi_buffer, t_wi) contours_wi = measure.find_contours(im_wi_buffer, t_wi)
contours_mwi = measure.find_contours(im_mwi, t_mwi) contours_mwi = measure.find_contours(im_mwi_buffer, t_mwi)
# remove contour points that are NaNs (around clouds) # remove contour points that are NaNs (around clouds)
contours = contours_wi contours = contours_wi
@ -418,12 +419,12 @@ def process_shoreline(contours, georef, image_epsg, settings):
contours_array = np.transpose(np.array([x_points,y_points])) contours_array = np.transpose(np.array([x_points,y_points]))
# if reference shoreline has been manually digitised # if reference shoreline has been manually digitised
if 'refsl' in settings.keys(): if 'reference_shoreline' in settings.keys():
# only keep the points that are at a certain distance (define in settings) from the # only keep the points that are at a certain distance (define in settings) from the
# reference shoreline, enables to avoid false detections and remove obvious outliers # reference shoreline, enables to avoid false detections and remove obvious outliers
temp = np.zeros((len(contours_array))).astype(bool) temp = np.zeros((len(contours_array))).astype(bool)
for k in range(len(settings['refsl'])): for k in range(len(settings['reference_shoreline'])):
temp = np.logical_or(np.linalg.norm(contours_array - settings['refsl'][k,[0,1]], temp = np.logical_or(np.linalg.norm(contours_array - settings['reference_shoreline'][k,[0,1]],
axis=1) < settings['max_dist_ref'], temp) axis=1) < settings['max_dist_ref'], temp)
shoreline = contours_array[temp] shoreline = contours_array[temp]
else: else:
@ -536,9 +537,9 @@ def show_detection(im_ms, cloud_mask, im_labels, shoreline,image_epsg, georef,
orange_patch = mpatches.Patch(color=colours[0,:], label='sand') orange_patch = mpatches.Patch(color=colours[0,:], label='sand')
white_patch = mpatches.Patch(color=colours[1,:], label='whitewater') white_patch = mpatches.Patch(color=colours[1,:], label='whitewater')
blue_patch = mpatches.Patch(color=colours[2,:], label='water') blue_patch = mpatches.Patch(color=colours[2,:], label='water')
black_line = mlines.Line2D([],[],color='k',linestyle='--', label='shoreline') black_line = mlines.Line2D([],[],color='k',linestyle='-', label='shoreline')
ax2.legend(handles=[orange_patch,white_patch,blue_patch, black_line], ax2.legend(handles=[orange_patch,white_patch,blue_patch, black_line],
bbox_to_anchor=(1, 0.5), fontsize=9) bbox_to_anchor=(1, 0.5), fontsize=10)
# create image 3 (MNDWI) # create image 3 (MNDWI)
ax3.imshow(im_mwi, cmap='bwr') ax3.imshow(im_mwi, cmap='bwr')
ax3.plot(sl_pix[:,0], sl_pix[:,1], 'k.', markersize=3) ax3.plot(sl_pix[:,0], sl_pix[:,1], 'k.', markersize=3)
@ -616,6 +617,8 @@ def extract_shorelines(metadata, settings):
except: except:
print('') print('')
# loop through satellite list # loop through satellite list
for satname in metadata.keys(): for satname in metadata.keys():
@ -631,6 +634,14 @@ def extract_shorelines(metadata, settings):
output_geoaccuracy = []# georeferencing accuracy of the images output_geoaccuracy = []# georeferencing accuracy of the images
output_idxkeep = [] # index that were kept during the analysis (cloudy images are skipped) output_idxkeep = [] # index that were kept during the analysis (cloudy images are skipped)
# convert settings['min_beach_area'] and settings['buffer_size'] from metres to pixels
if satname in ['L5','L7','L8']:
pixel_size = 15
elif satname == 'S2':
pixel_size = 10
buffer_size_pixels = np.ceil(settings['buffer_size']/pixel_size)
min_beach_area_pixels = np.ceil(settings['min_beach_area']/pixel_size**2)
# loop through the images # loop through the images
for i in range(len(filenames)): for i in range(len(filenames)):
@ -649,7 +660,7 @@ def extract_shorelines(metadata, settings):
# classify image in 4 classes (sand, whitewater, water, other) with NN classifier # classify image in 4 classes (sand, whitewater, water, other) with NN classifier
im_classif, im_labels = classify_image_NN(im_ms, im_extra, cloud_mask, im_classif, im_labels = classify_image_NN(im_ms, im_extra, cloud_mask,
settings['min_beach_size'], satname) min_beach_area_pixels, satname)
# extract water line contours # extract water line contours
# if there aren't any sandy pixels, use find_wl_contours1 (traditional method), # if there aren't any sandy pixels, use find_wl_contours1 (traditional method),
@ -663,7 +674,7 @@ def extract_shorelines(metadata, settings):
else: else:
# use classification to refine threshold and extract sand/water interface # use classification to refine threshold and extract sand/water interface
contours_wi, contours_mwi = find_wl_contours2(im_ms, im_labels, contours_wi, contours_mwi = find_wl_contours2(im_ms, im_labels,
cloud_mask, settings['buffer_size']) cloud_mask, buffer_size_pixels)
except: except:
continue continue
@ -708,4 +719,19 @@ def extract_shorelines(metadata, settings):
with open(os.path.join(filepath, sitename + '_output.pkl'), 'wb') as f: with open(os.path.join(filepath, sitename + '_output.pkl'), 'wb') as f:
pickle.dump(output, f) pickle.dump(output, f)
# save output as kml for GIS applications
kml = simplekml.Kml()
for satname in metadata.keys():
for i in range(len(output[satname]['shoreline'])):
if len(output[satname]['shoreline'][i]) == 0:
continue
sl = output[satname]['shoreline'][i]
date = output[satname]['timestamp'][i]
newline = kml.newlinestring(name= date.strftime('%Y-%m-%d'))
newline.coords = sl
newline.description = satname + ' shoreline' + '\n' + 'acquired at ' + date.strftime('%H:%M:%S') + ' UTC'
kml.save(os.path.join(filepath, sitename + '_shorelines.kml'))
return output return output

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 MiB

@ -1,203 +0,0 @@
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: win-64
@EXPLICIT
https://conda.anaconda.org/anaconda/win-64/ca-certificates-2018.03.07-0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/icc_rt-2017.0.4-h97af966_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/intel-openmp-2018.0.0-hd92c6cd_8.tar.bz2
https://repo.anaconda.com/pkgs/free/win-64/libgdal-1.11.2-1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pandoc-1.19.2.1-hb2460c7_1.tar.bz2
https://conda.anaconda.org/anaconda/win-64/vs2015_runtime-15.5.2-3.tar.bz2
https://conda.anaconda.org/anaconda/win-64/winpty-0.4.3-4.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/mkl-2018.0.1-h2108138_4.tar.bz2
https://conda.anaconda.org/anaconda/win-64/vc-14.1-h21ff451_3.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/bzip2-1.0.6-hfa6e2cd_5.tar.bz2
https://conda.anaconda.org/anaconda/win-64/expat-2.2.5-he025d50_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/geos-3.6.2-h9ef7328_2.tar.bz2
https://conda.anaconda.org/anaconda/win-64/icu-58.2-ha66f8fd_1.tar.bz2
https://conda.anaconda.org/anaconda/win-64/jpeg-9b-hb83a4c4_2.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libiconv-1.15-h1df5818_7.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libwebp-1.0.0-hfa6e2cd_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/nodejs-8.9.3-hd6b2f15_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/openssl-1.0.2p-hfa6e2cd_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/proj4-4.9.3-hcf24537_7.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/python-3.6.4-h6538335_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sqlite-3.24.0-h7602738_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/tk-8.6.8-hfa6e2cd_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/xerces-c-3.2.1-h27bfe9a_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/xz-5.2.3-h7c615d8_2.tar.bz2
https://conda.anaconda.org/anaconda/win-64/yaml-0.1.7-hc54c509_2.tar.bz2
https://conda.anaconda.org/anaconda/win-64/zlib-1.2.11-h8395fce_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/affine-2.2.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/alabaster-0.7.10-py36hcd07829_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/asn1crypto-0.24.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/attrs-17.4.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/backports-1.0-py36h81696a8_1.tar.bz2
https://conda.anaconda.org/anaconda/win-64/certifi-2018.8.24-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/chardet-3.0.4-py36h420ce6e_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/click-6.7-py36hec8c647_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/cloudpickle-0.5.2-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/colorama-0.3.9-py36h029ae33_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cssselect-1.0.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/dask-core-0.17.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/decorator-4.2.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/docutils-0.14-py36h6012d8f_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/entrypoints-0.2.3-py36hfd66bb0_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/freexl-1.0.5-hfa6e2cd_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/hdf4-4.2.13-h712560f_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/hdf5-1.10.2-hac2f561_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/heapdict-1.0.0-py36_2.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/idna-2.6-py36h148d497_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/imagesize-0.7.1-py36he29f638_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/ipython_genutils-0.2.0-py36h3c5d0ee_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jmespath-0.9.3-py36h0745840_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/kiwisolver-1.0.1-py36h12c3424_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/krb5-1.16.1-h038dc86_6.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/lazy-object-proxy-1.3.1-py36hd1c21d2_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libboost-1.65.1-he51fdeb_4.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libpng-1.6.34-h79bbb47_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libprotobuf-3.6.0-h1a1b453_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libssh2-1.8.0-hd619d38_4.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libtiff-4.0.9-h36446d0_2.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libxml2-2.9.8-hadb2253_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/locket-0.2.0-py36hfed976d_1.tar.bz2
https://repo.continuum.io/pkgs/free/win-64/markdown-2.6.9-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/markupsafe-1.0-py36h0e26971_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/mccabe-0.6.1-py36hb41005a_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/mistune-0.8.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/msgpack-python-0.5.1-py36he980bc4_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/numpy-1.14.1-py36hb69e940_2.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/olefile-0.45.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pandocfilters-1.4.2-py36h3ef6317_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/parso-0.1.1-py36hae3edee_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pickleshare-0.7.4-py36h9de030f_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/psutil-5.4.3-py36hfa6e2cd_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pycodestyle-2.3.1-py36h7cc55cd_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pycparser-2.18-py36hd053e01_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pyparsing-2.2.0-py36h785a196_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyshp-1.2.12-py36h9b5cf0b_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pytz-2018.3-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/pywin32-223-py36hfa6e2cd_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pywinpty-0.5-py36h6538335_1.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/pyyaml-3.12-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pyzmq-16.0.3-py36he714bf5_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/qtpy-1.3.1-py36hb8717c5_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/rope-0.10.7-py36had63a69_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/send2trash-1.4.2-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/simplegeneric-0.8.1-py36_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sip-4.19.8-py36h6538335_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/six-1.11.0-py36h4db2310_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/snowballstemmer-1.2.1-py36h763602f_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/sortedcontainers-1.5.9-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/sphinxcontrib-1.0-py36hbbac3d2_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/tblib-1.3.2-py36h30f5020_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/testpath-0.3.1-py36h2698cfe_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/toolz-0.9.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/tornado-4.5.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/typing-3.6.2-py36hb035bda_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wcwidth-0.1.7-py36h3d5aa90_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/webencodings-0.5.1-py36h67c50ae_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/werkzeug-0.14.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/win_inet_pton-1.0.1-py36he67d7fd_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wincertstore-0.2-py36h7fe50ca_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wrapt-1.10.11-py36he5f5981_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/babel-2.5.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/free/win-64/backports.weakref-1.0rc1-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/boost-cpp-1.65.1-hfa6e2cd_4.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/cffi-1.11.4-py36hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cftime-1.0.0b1-py36h452e1ab_0.tar.bz2
https://repo.anaconda.com/pkgs/free/win-64/click-plugins-1.0.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/free/win-64/cligj-0.4.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/cycler-0.10.0-py36h009560c_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/freetype-2.8-h51f8f2c_1.tar.bz2
https://conda.anaconda.org/anaconda/win-64/geotiff-1.4.2-hd5bfa41_0.tar.bz2
https://repo.continuum.io/pkgs/free/win-64/html5lib-0.9999999-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jedi-0.11.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/kealib-1.4.7-hf7dd379_6.tar.bz2
https://conda.anaconda.org/anaconda/win-64/keyring-13.2.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libcurl-7.60.0-hc4dcbb0_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libpq-10.5-h5fe2233_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libspatialite-4.3.0a-h383548d_18.tar.bz2
https://conda.anaconda.org/anaconda/win-64/libxslt-1.1.32-hf6f1972_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/networkx-2.1-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/openjpeg-2.3.0-h5ec785f_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/packaging-16.8-py36ha0986f6_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/partd-0.3.8-py36hc8e763b_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/protobuf-3.6.0-py36he025d50_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pysocks-1.6.7-py36h698d350_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/python-dateutil-2.6.1-py36h509ddcb_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pywavelets-0.5.2-py36hc649158_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/qt-5.9.6-vc14h62aca36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/qtawesome-0.4.4-py36h5aa48f6_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/scipy-1.0.0-py36h1260518_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/setuptools-38.4.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/shapely-1.6.4-py36h2a969d5_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/snuggs-1.4.1-py36hd271b8d_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/sphinxcontrib-websupport-1.0.1-py36hb5e5916_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/terminado-0.8.1-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/traitlets-4.3.2-py36h096827d_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/zict-0.1.3-py36h2d8e73e_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/astroid-1.6.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/free/win-64/bleach-1.5.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/boost-1.66.0-py36_vc14_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/botocore-1.10.4-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/cryptography-2.1.4-py36he1d7878_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/curl-7.60.0-h7602738_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/distributed-1.21.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/isort-4.2.15-py36h6198cc5_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jinja2-2.10-py36h292fed1_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jsonschema-2.6.0-py36h7636477_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jupyter_core-4.4.0-py36h56e9d50_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/lxml-4.1.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pandas-0.22.0-py36h6538335_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/patsy-0.5.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pillow-5.0.0-py36h0738816_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pyflakes-1.6.0-py36h0b975d6_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pygments-2.2.0-py36hb010967_0.tar.bz2
https://repo.anaconda.com/pkgs/free/win-64/pyproj-1.9.5.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyqt-5.9.2-py36h1aa27d4_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/scikit-learn-0.19.1-py36h53aea1b_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wheel-0.30.0-py36h6c3ec14_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/bokeh-0.12.14-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/imageio-2.3.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jupyter_client-5.2.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-vc14_6.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libnetcdf-4.6.1-h62daf8c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/matplotlib-2.2.2-py36h153e9ff_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/nbformat-4.4.0-py36h3a5bc1b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pip-9.0.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/prompt_toolkit-1.0.15-py36h60b8f86_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pylint-1.8.2-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pyopenssl-17.5.0-py36h5b7d817_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/s3transfer-0.1.13-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/statsmodels-0.8.0-py36h6189b4c_0.tar.bz2
https://repo.continuum.io/pkgs/free/win-64/tensorflow-1.2.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/boto3-1.7.4-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/dask-0.17.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/ipython-6.2.1-py36h9cf0123_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/nbconvert-5.3.1-py36h8dc0fde_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/netcdf4-1.4.0-py36hbfe741f_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/urllib3-1.22-py36h276f60a_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/ipykernel-4.8.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/requests-2.18.4-py36h4371aae_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/scikit-image-0.13.1-py36hfa6e2cd_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jupyter_console-5.2.0-py36h6d89b47_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/notebook-5.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/owslib-0.16.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyepsg-0.3.2-py36h6c744c8_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/qtconsole-4.3.1-py36h99a29a9_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/sphinx-1.6.6-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/win-64/spyder-kernels-0.2.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cartopy-0.16.0-py36hbd42bde_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyter_contrib_core-0.3.3-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyterlab_launcher-0.10.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/numpydoc-0.7.0-py36ha25429e_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/widgetsnbextension-3.1.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/ipywidgets-7.1.1-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyter_highlight_selected_word-0.1.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyter_latex_envs-1.3.8.2-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyter_nbextensions_configurator-0.4.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyterlab-0.31.5-py36_1.tar.bz2
https://conda.anaconda.org/anaconda/win-64/spyder-3.3.1-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jupyter-1.0.0-py36_4.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/jupyter_contrib_nbextensions-0.4.0-py36_0.tar.bz2

@ -1,207 +0,0 @@
name: coastsat
channels:
- conda-forge
- anaconda
- defaults
dependencies:
- boost-cpp=1.65.1=hfa6e2cd_4
- ca-certificates=2018.03.07=0
- certifi=2018.8.24=py36_1
- curl=7.60.0=h7602738_0
- expat=2.2.5=he025d50_0
- freetype=2.8=h51f8f2c_1
- geos=3.6.2=h9ef7328_2
- geotiff=1.4.2=hd5bfa41_0
- hdf4=4.2.13=h712560f_2
- icu=58.2=ha66f8fd_1
- jpeg=9b=hb83a4c4_2
- keyring=13.2.1=py36_0
- krb5=1.16.1=h038dc86_6
- libpng=1.6.34=h79bbb47_0
- libpq=10.5=h5fe2233_0
- libprotobuf=3.6.0=h1a1b453_0
- libssh2=1.8.0=hd619d38_4
- libtiff=4.0.9=h36446d0_2
- libwebp=1.0.0=hfa6e2cd_1
- libxml2=2.9.8=hadb2253_1
- libxslt=1.1.32=hf6f1972_0
- openjpeg=2.3.0=h5ec785f_1
- openssl=1.0.2p=hfa6e2cd_0
- proj4=4.9.3=hcf24537_7
- protobuf=3.6.0=py36he025d50_0
- pywin32=223=py36hfa6e2cd_1
- spyder=3.3.1=py36_1
- spyder-kernels=0.2.4=py36_0
- tk=8.6.8=hfa6e2cd_0
- vc=14.1=h21ff451_3
- vs2015_runtime=15.5.2=3
- winpty=0.4.3=4
- xerces-c=3.2.1=h27bfe9a_0
- yaml=0.1.7=hc54c509_2
- zlib=1.2.11=h8395fce_2
- boost=1.66.0=py36_vc14_1
- ipywidgets=7.1.1=py36_0
- jupyter_contrib_core=0.3.3=py36_1
- jupyter_contrib_nbextensions=0.4.0=py36_0
- jupyter_highlight_selected_word=0.1.0=py36_0
- jupyter_latex_envs=1.3.8.2=py36_1
- jupyter_nbextensions_configurator=0.4.0=py36_0
- jupyterlab=0.31.5=py36_1
- jupyterlab_launcher=0.10.3=py36_0
- libkml=1.3.0=vc14_6
- lxml=4.1.1=py36_0
- pyyaml=3.12=py36_1
- affine=2.2.0=py36_0
- alabaster=0.7.10=py36hcd07829_0
- asn1crypto=0.24.0=py36_0
- astroid=1.6.1=py36_0
- attrs=17.4.0=py36_0
- babel=2.5.3=py36_0
- backports=1.0=py36h81696a8_1
- backports.weakref=1.0rc1=py36_0
- bleach=1.5.0=py36_0
- bokeh=0.12.14=py36_0
- boto3=1.7.4=py36_0
- botocore=1.10.4=py36_0
- bzip2=1.0.6=hfa6e2cd_5
- cartopy=0.16.0=py36hbd42bde_0
- cffi=1.11.4=py36hfa6e2cd_0
- cftime=1.0.0b1=py36h452e1ab_0
- chardet=3.0.4=py36h420ce6e_1
- click=6.7=py36hec8c647_0
- click-plugins=1.0.3=py36_0
- cligj=0.4.0=py36_0
- cloudpickle=0.5.2=py36_1
- colorama=0.3.9=py36h029ae33_0
- cryptography=2.1.4=py36he1d7878_0
- cssselect=1.0.3=py36_0
- cycler=0.10.0=py36h009560c_0
- dask=0.17.0=py36_0
- dask-core=0.17.0=py36_0
- decorator=4.2.1=py36_0
- distributed=1.21.0=py36_0
- docutils=0.14=py36h6012d8f_0
- entrypoints=0.2.3=py36hfd66bb0_2
- freexl=1.0.5=hfa6e2cd_0
- hdf5=1.10.2=hac2f561_1
- heapdict=1.0.0=py36_2
- html5lib=0.9999999=py36_0
- icc_rt=2017.0.4=h97af966_0
- idna=2.6=py36h148d497_1
- imageio=2.3.0=py36_0
- imagesize=0.7.1=py36he29f638_0
- intel-openmp=2018.0.0=hd92c6cd_8
- ipykernel=4.8.0=py36_0
- ipython=6.2.1=py36h9cf0123_1
- ipython_genutils=0.2.0=py36h3c5d0ee_0
- isort=4.2.15=py36h6198cc5_0
- jedi=0.11.1=py36_0
- jinja2=2.10=py36h292fed1_0
- jmespath=0.9.3=py36h0745840_0
- jsonschema=2.6.0=py36h7636477_0
- jupyter=1.0.0=py36_4
- jupyter_client=5.2.2=py36_0
- jupyter_console=5.2.0=py36h6d89b47_1
- jupyter_core=4.4.0=py36h56e9d50_0
- kealib=1.4.7=hf7dd379_6
- kiwisolver=1.0.1=py36h12c3424_0
- lazy-object-proxy=1.3.1=py36hd1c21d2_0
- libboost=1.65.1=he51fdeb_4
- libcurl=7.60.0=hc4dcbb0_0
- libgdal=1.11.2=1
- libiconv=1.15=h1df5818_7
- libnetcdf=4.6.1=h62daf8c_0
- libspatialite=4.3.0a=h383548d_18
- locket=0.2.0=py36hfed976d_1
- markdown=2.6.9=py36_0
- markupsafe=1.0=py36h0e26971_1
- matplotlib=2.2.2=py36h153e9ff_1
- mccabe=0.6.1=py36hb41005a_1
- mistune=0.8.3=py36_0
- mkl=2018.0.1=h2108138_4
- msgpack-python=0.5.1=py36he980bc4_0
- nbconvert=5.3.1=py36h8dc0fde_0
- nbformat=4.4.0=py36h3a5bc1b_0
- netcdf4=1.4.0=py36hbfe741f_1
- networkx=2.1=py36_0
- nodejs=8.9.3=hd6b2f15_0
- notebook=5.4.0=py36_0
- numpy=1.14.1=py36hb69e940_2
- numpydoc=0.7.0=py36ha25429e_0
- olefile=0.45.1=py36_0
- owslib=0.16.0=py36_0
- packaging=16.8=py36ha0986f6_1
- pandas=0.22.0=py36h6538335_0
- pandoc=1.19.2.1=hb2460c7_1
- pandocfilters=1.4.2=py36h3ef6317_1
- parso=0.1.1=py36hae3edee_0
- partd=0.3.8=py36hc8e763b_0
- patsy=0.5.0=py36_0
- pickleshare=0.7.4=py36h9de030f_0
- pillow=5.0.0=py36h0738816_0
- pip=9.0.3=py36_0
- prompt_toolkit=1.0.15=py36h60b8f86_0
- psutil=5.4.3=py36hfa6e2cd_0
- pycodestyle=2.3.1=py36h7cc55cd_0
- pycparser=2.18=py36hd053e01_1
- pyepsg=0.3.2=py36h6c744c8_0
- pyflakes=1.6.0=py36h0b975d6_0
- pygments=2.2.0=py36hb010967_0
- pylint=1.8.2=py36_0
- pyopenssl=17.5.0=py36h5b7d817_0
- pyparsing=2.2.0=py36h785a196_1
- pyproj=1.9.5.1=py36_0
- pyqt=5.9.2=py36h1aa27d4_0
- pyshp=1.2.12=py36h9b5cf0b_0
- pysocks=1.6.7=py36h698d350_1
- python=3.6.4=h6538335_1
- python-dateutil=2.6.1=py36h509ddcb_1
- pytz=2018.3=py36_0
- pywavelets=0.5.2=py36hc649158_0
- pywinpty=0.5=py36h6538335_1
- pyzmq=16.0.3=py36he714bf5_0
- qt=5.9.6=vc14h62aca36_0
- qtawesome=0.4.4=py36h5aa48f6_0
- qtconsole=4.3.1=py36h99a29a9_0
- qtpy=1.3.1=py36hb8717c5_0
- requests=2.18.4=py36h4371aae_1
- rope=0.10.7=py36had63a69_0
- s3transfer=0.1.13=py36_0
- scikit-image=0.13.1=py36hfa6e2cd_1
- scikit-learn=0.19.1=py36h53aea1b_0
- scipy=1.0.0=py36h1260518_0
- send2trash=1.4.2=py36_0
- setuptools=38.4.0=py36_0
- shapely=1.6.4=py36h2a969d5_0
- simplegeneric=0.8.1=py36_2
- sip=4.19.8=py36h6538335_0
- six=1.11.0=py36h4db2310_1
- snowballstemmer=1.2.1=py36h763602f_0
- snuggs=1.4.1=py36hd271b8d_0
- sortedcontainers=1.5.9=py36_0
- sphinx=1.6.6=py36_0
- sphinxcontrib=1.0=py36hbbac3d2_1
- sphinxcontrib-websupport=1.0.1=py36hb5e5916_1
- sqlite=3.24.0=h7602738_0
- statsmodels=0.8.0=py36h6189b4c_0
- tblib=1.3.2=py36h30f5020_0
- tensorflow=1.2.1=py36_0
- terminado=0.8.1=py36_1
- testpath=0.3.1=py36h2698cfe_0
- toolz=0.9.0=py36_0
- tornado=4.5.3=py36_0
- traitlets=4.3.2=py36h096827d_0
- typing=3.6.2=py36hb035bda_0
- urllib3=1.22=py36h276f60a_0
- wcwidth=0.1.7=py36h3d5aa90_0
- webencodings=0.5.1=py36h67c50ae_1
- werkzeug=0.14.1=py36_0
- wheel=0.30.0=py36h6c3ec14_1
- widgetsnbextension=3.1.0=py36_0
- win_inet_pton=1.0.1=py36he67d7fd_1
- wincertstore=0.2=py36h7fe50ca_0
- wrapt=1.10.11=py36he5f5981_0
- xz=5.2.3=h7c615d8_2
- zict=0.1.3=py36h2d8e73e_0
prefix: C:Anaconda\envs\coastsat

@ -0,0 +1,294 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# *CoastSat*: example at Narrabeen-Collaroy, Australia\n",
"\n",
"This software is described in *Vos K., Splinter K.D., Harley M.D., Simmons J.A., Turner I.L. (submitted). CoastSat: a Google Earth Engine-enabled software to extract shorelines from publicly available satellite imagery, Environmental Modelling and Software*. It enables the users to extract time-series of shoreline change over the last 30+ years at their site of interest.\n",
"\n",
"There are two main steps:\n",
"- retrieval of the satellite images of the region of interest from Google Earth Engine\n",
"- extraction of the shorelines from the images using a sub-pixel resolution technique\n",
"\n",
"## 1. Initial settings\n",
"\n",
"Refer to the **Installation** section of the README for instructions on how to install the Python packages necessary to run the software, including Google Earth Engine Python API. If that step has been completed correctly, the following packages should be imported without any problem."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import pickle\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"import matplotlib.pyplot as plt\n",
"import SDS_download, SDS_preprocess, SDS_shoreline, SDS_tools"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Retrieval of the images from GEE\n",
"\n",
"Define the region of interest (`polygon`), the date range (`dates`) and the satellite missions (`sat_list`) from which you wish to retrieve the satellite images. The images will be cropped on the Google Earth Engine server and only the region of interest will be downloaded as a .TIF file. The files will be organised in the local directory under *.\\data\\sitename*."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"# region of interest (longitude, latitude)\n",
"polygon = [[[151.2957545, -33.7012561],\n",
" [151.297557, -33.7388075],\n",
" [151.312234, -33.7390216],\n",
" [151.311204, -33.701399],\n",
" [151.2957545, -33.7012561]]] \n",
"# date range\n",
"dates = ['2017-12-01', '2018-01-01']\n",
"# satellite missions\n",
"sat_list = ['S2']\n",
"# name of the site\n",
"sitename = 'NARRA'\n",
"# put all the inputs into a dictionnary\n",
"inputs = {'polygon': polygon, 'dates': dates, 'sat_list': sat_list, 'sitename': sitename}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Retrieve satellite images from GEE"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"metadata = SDS_download.retrieve_images(inputs)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**If you have already retrieved the images**, just load the metadata file by only running the section below"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"filepath = os.path.join(os.getcwd(), 'data', sitename)\n",
"with open(os.path.join(filepath, sitename + '_metadata' + '.pkl'), 'rb') as f:\n",
" metadata = pickle.load(f) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Shoreline extraction\n",
"\n",
"Maps the position of the shoreline on the satellite images. The user can define the cloud threhold (`cloud_thresh`) and select the spatial reference system in which he would like to output the coordinates of the mapped shorelines (`output_epsg`). See http://spatialreference.org/ to find the EPSG number corresponding to your local coordinate system. To quality control each shoreline detection and manually validate the mapped shorelines, the user has the option to set the parameter `check_detection` to **True**. The other parameters are for advanced users only and are described in the last section of the README."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"settings = { \n",
" # general parameters:\n",
" 'cloud_thresh': 0.2, # threshold on maximum cloud cover\n",
" 'output_epsg': 28356, # epsg code of spatial reference system desired for the output \n",
" # quality control:\n",
" 'check_detection': True, # if True, shows each shoreline detection to the user for validation\n",
"\n",
" # add the inputs defined previously\n",
" 'inputs': inputs,\n",
" \n",
" # [ONLY FOR ADVANCED USERS] shoreline detection parameters:\n",
" 'min_beach_area': 4500, # minimum area (in metres^2) for an object to be labelled as a beach\n",
" 'buffer_size': 150, # radius (in metres) of the buffer around sandy pixels considered in the shoreline detection\n",
" 'min_length_sl': 200, # minimum length (in metres) of shoreline perimeter to be valid \n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### [OPTIONAL] Save .jpg of the satellite images \n",
"Saves .jpg files of the preprocessed satellite images (cloud masking + pansharpening/down-sampling) under *./data/sitename/jpeg_files\\preprocessed*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"SDS_preprocess.save_jpg(metadata, settings)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### [OPTIONAL] Digitize a reference shoreline\n",
"Creates a reference shoreline which helps to identify outliers and false detections. The reference shoreline is manually digitised by the user on one of the images. The parameter `max_dist_ref` defines the maximum distance from the reference shoreline (in metres) at which a valid detected shoreline can be. If you think that you shoreline will move more than the default value of 100 m, please change this parameter to an appropriate distance."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Reference shoreline already exists and was loaded\n"
]
}
],
"source": [
"%matplotlib qt\n",
"settings['reference_shoreline'] = SDS_preprocess.get_reference_sl_manual(metadata, settings)\n",
"settings['max_dist_ref'] = 100 # max distance (in meters) allowed from the reference shoreline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Batch shoreline detection\n",
"Extracts the shorelines from the images. The mapped shorelines are saved into `output.pkl` (under *./data/sitename*) which contains the shoreline coordinates for each date in the spatial reference system specified by the user in `'output_epsg'`."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n"
]
}
],
"source": [
"%matplotlib qt\n",
"output = SDS_shoreline.extract_shorelines(metadata, settings)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 4. Plot the shorelines\n",
"\n",
"Simple plot of the mapped shorelines"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.legend.Legend at 0x23a4f91b6a0>"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plt.figure()\n",
"plt.axis('equal')\n",
"plt.xlabel('Eastings')\n",
"plt.ylabel('Northings')\n",
"for satname in output.keys():\n",
" if satname == 'meta':\n",
" continue\n",
" for i in range(len(output[satname]['shoreline'])):\n",
" sl = output[satname]['shoreline'][i]\n",
" date = output[satname]['timestamp'][i]\n",
" plt.plot(sl[:,0], sl[:,1], '.', label=date.strftime('%d-%m-%Y'))\n",
"plt.legend()"
]
}
],
"metadata": {
"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.6.7"
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}

@ -8,19 +8,23 @@ import pickle
import warnings import warnings
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import SDS_download, SDS_preprocess, SDS_shoreline, SDS_tools import SDS_download, SDS_preprocess, SDS_shoreline, SDS_tools
# define the area of interest (longitude, latitude) # region of interest (longitude, latitude), can also be loaded from a .kml polygon
polygon = SDS_tools.coords_from_kml('NARRA.kml') polygon = SDS_tools.coords_from_kml('NARRA.kml')
#polygon = [[[151.301454, -33.700754],
# [151.311453, -33.702075],
# [151.307237, -33.739761],
# [151.294220, -33.736329],
# [151.301454, -33.700754]]]
# define dates of interest # date range
dates = ['2015-01-01', '2019-01-01'] dates = ['2017-12-01', '2018-01-01']
# define satellite missions # satellite missions
sat_list = ['S2'] sat_list = ['S2']
# give a name to the site # name of the site
sitename = 'NARRA' sitename = 'NARRA'
# put all the inputs into a dictionnary # put all the inputs into a dictionnary
@ -31,48 +35,48 @@ inputs = {
'sitename': sitename 'sitename': sitename
} }
# download satellite images (also saves metadata.pkl) # retrieve satellite images from GEE
metadata = SDS_download.get_images(inputs) metadata = SDS_download.retrieve_images(inputs)
# if you have already downloaded the images, just load the metadata file # if you have already downloaded the images, just load the metadata file
filepath = os.path.join(os.getcwd(), 'data', sitename) filepath = os.path.join(os.getcwd(), 'data', sitename)
with open(os.path.join(filepath, sitename + '_metadata' + '.pkl'), 'rb') as f: with open(os.path.join(filepath, sitename + '_metadata' + '.pkl'), 'rb') as f:
metadata = pickle.load(f) metadata = pickle.load(f)
#%% #%%
# settings needed to run the shoreline extraction # settings for the shoreline extraction
settings = { settings = {
# general parameters: # general parameters:
'cloud_thresh': 0.2, # threshold on maximum cloud cover 'cloud_thresh': 0.2, # threshold on maximum cloud cover
'output_epsg': 28356, # epsg code of spatial reference system desired for the output 'output_epsg': 28356, # epsg code of spatial reference system desired for the output
# shoreline detection parameters: # [ONLY FOR ADVANCED USERS] shoreline detection parameters:
'min_beach_size': 20, # minimum number of connected pixels for a beach 'min_beach_area': 4500, # minimum area (in metres^2) for an object to be labelled as a beach
'buffer_size': 7, # radius (in pixels) of disk for buffer around sandy pixels 'buffer_size': 150, # radius (in pixels) of disk for buffer around sandy pixels
'min_length_sl': 200, # minimum length of shoreline perimeter to be kept 'min_length_sl': 200, # minimum length of shoreline perimeter to be kept
'max_dist_ref': 100, # max distance (in meters) allowed from a reference shoreline
# quality control: # quality control:
'check_detection': True, # if True, shows each shoreline detection and lets the user 'check_detection': True, # if True, shows each shoreline detection and lets the user
# decide which ones are correct and which ones are false due to # decide which ones are correct and which ones are false due to
# the presence of clouds # the presence of clouds
# also add the inputs # add the inputs
'inputs': inputs 'inputs': inputs
} }
# preprocess images (cloud masking, pansharpening/down-sampling) # [OPTIONAL] preprocess images (cloud masking, pansharpening/down-sampling)
#SDS_preprocess.save_jpg(metadata, settings) SDS_preprocess.save_jpg(metadata, settings)
# create a reference shoreline (helps to identify outliers and false detections) # [OPTIONAL] create a reference shoreline (helps to identify outliers and false detections)
settings['refsl'] = SDS_preprocess.get_reference_sl_manual(metadata, settings) settings['reference_shoreline'] = SDS_preprocess.get_reference_sl_manual(metadata, settings)
#settings['refsl'] = SDS_preprocess.get_reference_sl_Australia(settings) # set the max distance (in meters) allowed from the reference shoreline for a detected shoreline to be valid
settings['max_dist_ref'] = 100
# extract shorelines from all images (also saves output.pkl) # extract shorelines from all images (also saves output.pkl and output.kml)
output = SDS_shoreline.extract_shorelines(metadata, settings) output = SDS_shoreline.extract_shorelines(metadata, settings)
# plot shorelines #%%
# basic figure plotting the mapped shorelines
plt.figure() plt.figure()
plt.axis('equal') plt.axis('equal')
plt.xlabel('Eastings [m]') plt.xlabel('Eastings [m]')
@ -85,3 +89,5 @@ for satname in output.keys():
date = output[satname]['timestamp'][i] date = output[satname]['timestamp'][i]
plt.plot(sl[:, 0], sl[:, 1], '.', label=date.strftime('%d-%m-%Y')) plt.plot(sl[:, 0], sl[:, 1], '.', label=date.strftime('%d-%m-%Y'))
plt.legend() plt.legend()

@ -1,285 +0,0 @@
#==========================================================#
# Create a classifier for satellite images
#==========================================================#
# load modules
import os
import pickle
import warnings
import numpy as np
import matplotlib.cm as cm
warnings.filterwarnings("ignore")
import matplotlib.pyplot as plt
from pylab import ginput
import SDS_download, SDS_preprocess, SDS_shoreline, SDS_tools, SDS_classification
filepath_sites = os.path.join(os.getcwd(), 'polygons')
sites = os.listdir(filepath_sites)
for site in sites:
polygon = SDS_tools.coords_from_kml(os.path.join(filepath_sites,site))
# load Sentinel-2 images
inputs = {
'polygon': polygon,
'dates': ['2016-10-01', '2016-11-01'],
'sat_list': ['S2'],
'sitename': site[:site.find('.')]
}
satname = inputs['sat_list'][0]
metadata = SDS_download.get_images(inputs)
metadata = SDS_download.remove_cloudy_images(metadata,inputs,0.2)
filepath = os.path.join(os.getcwd(), 'data', inputs['sitename'])
with open(os.path.join(filepath, inputs['sitename'] + '_metadata_' + satname + '.pkl'), 'wb') as f:
pickle.dump(metadata, f)
#with open(os.path.join(filepath, inputs['sitename'] + '_metadata_' + satname + '.pkl'), 'rb') as f:
# metadata = pickle.load(f)
# settings needed to run the shoreline extraction
settings = {
# general parameters:
'cloud_thresh': 0.1, # threshold on maximum cloud cover
'output_epsg': 28356, # epsg code of spatial reference system desired for the output
# shoreline detection parameters:
'min_beach_size': 20, # minimum number of connected pixels for a beach
'buffer_size': 7, # radius (in pixels) of disk for buffer around sandy pixels
'min_length_sl': 200, # minimum length of shoreline perimeter to be kept
'max_dist_ref': 100, # max distance (in meters) allowed from a reference shoreline
# quality control:
'check_detection': True, # if True, shows each shoreline detection and lets the user
# decide which ones are correct and which ones are false due to
# the presence of clouds
# also add the inputs
'inputs': inputs
}
# preprocess images (cloud masking, pansharpening/down-sampling)
SDS_preprocess.preprocess_all_images(metadata, settings)
training_data = dict([])
training_data['sand'] = dict([])
training_data['swash'] = dict([])
training_data['water'] = dict([])
training_data['land'] = dict([])
# read images
filepath = SDS_tools.get_filepath(inputs,satname)
filenames = metadata[satname]['filenames']
for i in range(len(filenames)):
fn = SDS_tools.get_filenames(filenames[i],filepath,satname)
im_ms, georef, cloud_mask, im20, imQA = SDS_preprocess.preprocess_single(fn,satname)
nrow = im_ms.shape[0]
ncol = im_ms.shape[1]
im_RGB = SDS_preprocess.rescale_image_intensity(im_ms[:,:,[2,1,0]], cloud_mask, 99.9)
plt.figure()
mng = plt.get_current_fig_manager()
mng.window.showMaximized()
plt.imshow(im_RGB)
plt.axis('off')
# Digitize sandy pixels
plt.title('Digitize SAND pixels', fontweight='bold', fontsize=15)
pt = ginput(n=1000, timeout=100000, show_clicks=True)
if len(pt) > 0:
pt = np.round(pt).astype(int)
im_sand = np.zeros((nrow,ncol))
for k in range(len(pt)):
im_sand[pt[k,1],pt[k,0]] = 1
im_RGB[pt[k,1],pt[k,0],0] = 1
im_RGB[pt[k,1],pt[k,0],1] = 0
im_RGB[pt[k,1],pt[k,0],2] = 0
im_sand = im_sand.astype(bool)
features = SDS_classification.calculate_features(im_ms, cloud_mask, im_sand)
else:
im_sand = np.zeros((nrow,ncol)).astype(bool)
features = []
training_data['sand'][filenames[i]] = {'pixels':im_sand,'features':features}
# Digitize swash pixels
plt.title('Digitize SWASH pixels', fontweight='bold', fontsize=15)
plt.draw()
pt = ginput(n=1000, timeout=100000, show_clicks=True)
if len(pt) > 0:
pt = np.round(pt).astype(int)
im_swash = np.zeros((nrow,ncol))
for k in range(len(pt)):
im_swash[pt[k,1],pt[k,0]] = 1
im_RGB[pt[k,1],pt[k,0],0] = 0
im_RGB[pt[k,1],pt[k,0],1] = 1
im_RGB[pt[k,1],pt[k,0],2] = 0
im_swash = im_swash.astype(bool)
features = SDS_classification.calculate_features(im_ms, cloud_mask, im_swash)
else:
im_swash = np.zeros((nrow,ncol)).astype(bool)
features = []
training_data['swash'][filenames[i]] = {'pixels':im_swash,'features':features}
# Digitize rectangle containig water pixels
plt.title('Click 2 points to draw a rectange in the WATER', fontweight='bold', fontsize=15)
plt.draw()
pt = ginput(n=2, timeout=100000, show_clicks=True)
if len(pt) > 0:
pt = np.round(pt).astype(int)
idx_row = np.arange(np.min(pt[:,1]),np.max(pt[:,1])+1,1)
idx_col = np.arange(np.min(pt[:,0]),np.max(pt[:,0])+1,1)
xx, yy = np.meshgrid(idx_row,idx_col, indexing='ij')
rows = xx.reshape(xx.shape[0]*xx.shape[1])
cols = yy.reshape(yy.shape[0]*yy.shape[1])
im_water = np.zeros((nrow,ncol)).astype(bool)
for k in range(len(rows)):
im_water[rows[k],cols[k]] = 1
im_RGB[rows[k],cols[k],0] = 0
im_RGB[rows[k],cols[k],1] = 0
im_RGB[rows[k],cols[k],2] = 1
im_water = im_water.astype(bool)
features = SDS_classification.calculate_features(im_ms, cloud_mask, im_water)
else:
im_water = np.zeros((nrow,ncol)).astype(bool)
features = []
training_data['water'][filenames[i]] = {'pixels':im_water,'features':features}
# Digitize rectangle containig land pixels
plt.title('Click 2 points to draw a rectange in the LAND', fontweight='bold', fontsize=15)
plt.draw()
pt = ginput(n=2, timeout=100000, show_clicks=True)
plt.close()
if len(pt) > 0:
pt = np.round(pt).astype(int)
idx_row = np.arange(np.min(pt[:,1]),np.max(pt[:,1])+1,1)
idx_col = np.arange(np.min(pt[:,0]),np.max(pt[:,0])+1,1)
xx, yy = np.meshgrid(idx_row,idx_col, indexing='ij')
rows = xx.reshape(xx.shape[0]*xx.shape[1])
cols = yy.reshape(yy.shape[0]*yy.shape[1])
im_land = np.zeros((nrow,ncol)).astype(bool)
for k in range(len(rows)):
im_land[rows[k],cols[k]] = 1
im_RGB[rows[k],cols[k],0] = 1
im_RGB[rows[k],cols[k],1] = 1
im_RGB[rows[k],cols[k],2] = 0
im_land = im_land.astype(bool)
features = SDS_classification.calculate_features(im_ms, cloud_mask, im_land)
else:
im_land = np.zeros((nrow,ncol)).astype(bool)
features = []
training_data['land'][filenames[i]] = {'pixels':im_land,'features':features}
plt.figure()
plt.title('Classified image')
plt.imshow(im_RGB)
# save training data for each site
filepath = os.path.join(os.getcwd(), 'data', inputs['sitename'])
with open(os.path.join(filepath, inputs['sitename'] + '_training_' + satname + '.pkl'), 'wb') as f:
pickle.dump(training_data, f)
#%%
## load Landsat 5 images
#inputs = {
# 'polygon': polygon,
# 'dates': ['1987-01-01', '1988-01-01'],
# 'sat_list': ['L5'],
# 'sitename': site[:site.find('.')]
# }
#metadata = SDS_download.get_images(inputs)
#
## load Landsat 7 images
#inputs = {
# 'polygon': polygon,
# 'dates': ['2001-01-01', '2002-01-01'],
# 'sat_list': ['L7'],
# 'sitename': site[:site.find('.')]
# }
#metadata = SDS_download.get_images(inputs)
#
## load Landsat 8 images
#inputs = {
# 'polygon': polygon,
# 'dates': ['2014-01-01', '2015-01-01'],
# 'sat_list': ['L8'],
# 'sitename': site[:site.find('.')]
# }
#metadata = SDS_download.get_images(inputs)
#%% clean the Landsat collections
#import ee
#from datetime import datetime, timedelta
#import pytz
#import copy
#ee.Initialize()
#site = sites[0]
#dates = ['2017-12-01', '2017-12-25']
#polygon = SDS_tools.coords_from_kml(os.path.join(filepath_sites,site))
## Landsat collection
#input_col = ee.ImageCollection('LANDSAT/LC08/C01/T1_RT_TOA')
## filter by location and dates
#flt_col = input_col.filterBounds(ee.Geometry.Polygon(polygon)).filterDate(inputs['dates'][0],inputs['dates'][1])
## get all images in the filtered collection
#im_all = flt_col.getInfo().get('features')
#cloud_cover = [_['properties']['CLOUD_COVER'] for _ in im_all]
#if np.any([_ > 90 for _ in cloud_cover]):
# idx_delete = np.where([_ > 90 for _ in cloud_cover])[0]
# im_all_cloud = [x for k,x in enumerate(im_all) if k not in idx_delete]
#%% clean the S2 collection
#import ee
#from datetime import datetime, timedelta
#import pytz
#import copy
#ee.Initialize()
## Sentinel2 collection
#input_col = ee.ImageCollection('COPERNICUS/S2')
## filter by location and dates
#flt_col = input_col.filterBounds(ee.Geometry.Polygon(polygon)).filterDate(inputs['dates'][0],inputs['dates'][1])
## get all images in the filtered collection
#im_all = flt_col.getInfo().get('features')
#
## remove duplicates (there are many in S2 collection)
## timestamps
#timestamps = [datetime.fromtimestamp(_['properties']['system:time_start']/1000, tz=pytz.utc) for _ in im_all]
## utm zones
#utm_zones = np.array([int(_['bands'][0]['crs'][5:]) for _ in im_all])
#utm_zone_selected = np.max(np.unique(utm_zones))
#idx_all = np.arange(0,len(im_all),1)
#idx_covered = np.ones(len(im_all)).astype(bool)
#idx_delete = []
#i = 0
#while 1:
# same_time = np.abs([(timestamps[i]-_).total_seconds() for _ in timestamps]) < 60*60*24
# idx_same_time = np.where(same_time)[0]
# same_utm = utm_zones == utm_zone_selected
# idx_temp = np.where([same_time[j] == True and same_utm[j] == False for j in idx_all])[0]
# idx_keep = idx_same_time[[_ not in idx_temp for _ in idx_same_time ]]
# if len(idx_keep) > 2: # if more than 2 images with same date and same utm, drop the last one
# idx_temp = np.append(idx_temp,idx_keep[-1])
# for j in idx_temp:
# idx_delete.append(j)
# idx_covered[idx_same_time] = False
# if np.any(idx_covered):
# i = np.where(idx_covered)[0][0]
# else:
# break
#im_all_updated = [x for k,x in enumerate(im_all) if k not in idx_delete]
#
## remove very cloudy images (>90% cloud)
#cloud_cover = [_['properties']['CLOUDY_PIXEL_PERCENTAGE'] for _ in im_all_updated]
#if np.any([_ > 90 for _ in cloud_cover]):
# idx_delete = np.where([_ > 90 for _ in cloud_cover])[0]
# im_all_cloud = [x for k,x in enumerate(im_all_updated) if k not in idx_delete]

@ -0,0 +1,167 @@
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: linux-64
@EXPLICIT
https://repo.anaconda.com/pkgs/main/linux-64/blas-1.0-mkl.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ca-certificates-2018.03.07-0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/intel-openmp-2019.1-144.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libgcc-ng-8.2.0-hdf63c60_1.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libgfortran-3.0.0-1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libgfortran-ng-7.3.0-hdf63c60_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libstdcxx-ng-8.2.0-hdf63c60_1.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/poppler-data-0.4.9-0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.6-h470a237_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/expat-2.2.6-he6710b0_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/freexl-1.0.5-h470a237_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/geos-3.6.2-heeff764_2.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/giflib-5.1.4-h470a237_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/gmp-6.1.2-h6c8ec71_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/icu-58.2-h9c2bf20_1.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/jpeg-9c-h470a237_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/json-c-0.13.1-h1bed415_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libffi-3.2.1-hd88cf55_4.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libgcc-7.2.0-h69d50b8_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libsodium-1.0.16-h1bed415_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.32.1-h470a237_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libxcb-1.13-h1bed415_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/mkl-2018.0.3-1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ncurses-6.1-he6710b0_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/openssl-1.0.2p-h14c3975_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pcre-8.42-h439df22_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/pixman-0.34.0-h470a237_3.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/proj4-4.9.3-hc8507d1_7.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h470a237_2.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.0.9-h470a237_4.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-renderproto-0.11.1-h470a237_2.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h470a237_2.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h470a237_7.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/xz-5.2.4-h14c3975_4.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/zlib-1.2.11-h7b6447c_3.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/boost-cpp-1.68.0-h3a22d5f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/glib-2.56.2-hd408876_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.13-h951d187_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/hdf5-1.10.1-h9caa474_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libedit-3.1.20170329-h6b74fdf_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libpng-1.6.35-hbc83047_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.8.0-h5b517e9_3.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/libtiff-4.0.9-he85c1e1_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libxml2-2.9.8-h26e45fe_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pandoc-2.2.3.2-0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/readline-7.0-h7b6447c_5.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/tk-8.6.8-hbc83047_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.2-h5d6a6da_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-libsm-1.2.3-h8c8a85c_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-libx11-1.6.6-h470a237_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/zeromq-4.2.5-hf484d3e_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/dbus-1.13.2-h714fa37_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/freetype-2.8-hab7d2ae_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/geotiff-1.4.2-h8e81d37_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/gstreamer-1.14.0-hb453b48_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/kealib-1.4.7-h79811e5_5.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/krb5-1.16.2-hbb41f41_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libkml-1.3.0-he469717_9.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.3.0-h0e734dc_3.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.26.0-hb1c47c0_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-libxext-1.3.3-h470a237_4.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/xorg-libxrender-0.9.10-h470a237_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/fontconfig-2.12.6-h49f89f6_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/gst-plugins-base-1.14.0-hbbd80ab_1.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libcurl-7.62.0-hbdb9355_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libpq-10.5-he29860b_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libspatialite-4.3.0a-h72746d6_18.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/python-3.6.6-h5001a0f_3.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/asn1crypto-0.24.0-py36_1003.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/backcall-0.1.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/cachetools-2.1.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/cairo-1.14.12-h7636065_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/certifi-2018.10.15-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/cloudpickle-0.6.1-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/cryptography-vectors-2.3.1-py36_1000.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/curl-7.62.0-h74213dd_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/dask-core-1.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/decorator-4.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/entrypoints-0.2.3-py36_2.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/httplib2-0.12.0-py36_1000.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/idna-2.8-py36_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ipython_genutils-0.2.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/kiwisolver-1.0.1-py36hf484d3e_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/markupsafe-1.1.0-py36h7b6447c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/mistune-0.8.4-py36h7b6447c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/numpy-base-1.15.4-py36h81de0dd_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/olefile-0.46-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pandocfilters-1.4.2-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/parso-0.3.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pickleshare-0.7.5-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/postgresql-10.5-h66035e0_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/prometheus_client-0.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ptyprocess-0.6.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.4.4-py_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pycparser-2.19-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pyparsing-2.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pytz-2018.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pyzmq-17.1.2-py36h14c3975_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/qt-5.9.5-h7e424d6_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/send2trash-1.5.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/simplejson-3.16.1-py36h470a237_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/simplekml-1.3.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/sip-4.19.8-py36hf484d3e_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/six-1.11.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/testpath-0.4.2-py36_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/toolz-0.9.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/tornado-5.1.1-py36h7b6447c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/wcwidth-0.1.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/webencodings-0.5.1-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/cffi-1.11.5-py36h5e8e0c9_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/cycler-0.10.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jedi-0.13.1-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/libdap4-3.19.1-h8fe5423_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libnetcdf-4.4.1.1-h816af47_8.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pexpect-4.6.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pillow-5.1.0-py36h3deb7b8_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/poppler-0.65.0-ha54bb34_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.2.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pyqt-5.9.2-py36h751905a_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/python-dateutil-2.7.5-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/rsa-3.4.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/setuptools-40.6.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/terminado-0.8.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/traitlets-4.3.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/uritemplate-3.0.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/bleach-3.0.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/cryptography-2.3.1-py36hdffb7b8_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-1.6.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jinja2-2.10-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jsonschema-2.6.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_core-4.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/libgdal-2.2.4-hc8d23f9_1.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/networkx-2.2-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/oauth2client-4.1.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pygments-2.2.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/wheel-0.32.3-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-httplib2-0.0.3-py_2.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_client-5.2.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/nbformat-4.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/pip-18.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/prompt_toolkit-2.0.7-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/linux-64/pyopenssl-18.0.0-py36_1000.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-api-python-client-1.7.5-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ipython-7.2.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/nbconvert-5.3.1-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/earthengine-api-0.1.152-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ipykernel-5.1.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jupyter_console-6.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/notebook-5.7.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/qtconsole-4.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/widgetsnbextension-3.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/ipywidgets-7.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/jupyter-1.0.0-py36_7.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/gdal-2.2.4-py36h637b7d7_1.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/imageio-2.4.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/matplotlib-2.2.2-py36h0e671d2_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/mkl_fft-1.0.6-py36h7dd41cf_0.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/mkl_random-1.0.1-py36h4414c95_1.tar.bz2
https://repo.anaconda.com/pkgs/main/linux-64/numpy-1.15.4-py36h1d66e8a_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/pywavelets-1.0.1-py36hdd07704_0.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/scipy-1.1.0-py36hfa4b5c9_1.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/scikit-image-0.14.0-py36hf484d3e_1.tar.bz2
https://conda.anaconda.org/anaconda/linux-64/scikit-learn-0.20.1-py36h4989274_0.tar.bz2

@ -0,0 +1,184 @@
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: osx-64
@EXPLICIT
https://repo.anaconda.com/pkgs/main/osx-64/blas-1.0-mkl.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.6-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ca-certificates-2018.03.07-0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/expat-2.2.5-hfc679d8_2.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/freexl-1.0.5-h470a237_2.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/geos-3.7.0-hfc679d8_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/gettext-0.19.8.1-h1f1d5ed_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/giflib-5.1.4-h470a237_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/icu-58.2-hfc679d8_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/intel-openmp-2019.1-144.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/jpeg-9c-h470a237_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/json-c-0.13.1-h470a237_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libcxxabi-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libgfortran-3.0.1-h93005f0_2.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libiconv-1.15-h470a237_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libsodium-1.0.16-h3efe00b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pandoc-2.2.3.2-0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/pcre-8.41-hfc679d8_3.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/pixman-0.34.0-h470a237_3.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/poppler-data-0.4.9-0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/proj4-5.2.0-h470a237_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/xz-5.2.4-h1de35cc_4.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/zlib-1.2.11-h1de35cc_3.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/boost-cpp-1.68.0-h3a22d5f_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/hdf4-4.2.13-h951d187_2.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.10.4-nompi_h5598ddc_1003.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libcxx-4.0.1-hcfea43d_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libpng-1.6.35-ha441bb4_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.0.10-he6b73bb_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.9.8-h422b904_5.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mkl-2018.0.3-1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/openssl-1.0.2p-h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/tk-8.6.8-ha441bb4_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/xerces-c-3.2.2-h5d6a6da_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/freetype-2.9.1-hb4e5f40_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/geotiff-1.4.2-h9c44c65_7.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/kealib-1.4.10-heffcb4b_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libffi-3.2.1-h475c297_4.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libkml-1.3.0-he469717_9.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.8.0-h5b517e9_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ncurses-6.1-h0a44026_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.3.0-h316dc23_3.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/zeromq-4.2.5-h0a44026_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.13.1-hce039c3_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/glib-2.56.2-h464dc38_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/libedit-3.1.20170329-hb402a30_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/readline-7.0-h1de35cc_5.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/cairo-1.14.12-h276e583_5.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/dbus-1.13.2-h760590f_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/krb5-1.16.2-hbb41f41_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libpq-10.5-hf16a0db_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.26.0-hb1c47c0_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libcurl-7.62.0-hbdb9355_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libspatialite-4.3.0a-h201a3a7_25.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/postgresql-10.5-ha408888_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/python-3.6.6-h5001a0f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/qt-5.9.6-h45cd832_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/alabaster-0.7.12-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/appnope-0.1.0-py36hf537a9a_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/asn1crypto-0.24.0-py36_1003.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/backcall-0.1.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/cachetools-2.1.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/certifi-2018.10.15-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/chardet-3.0.4-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/cloudpickle-0.6.1-py_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/cryptography-vectors-2.3.1-py36_1000.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/curl-7.62.0-h74213dd_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/dask-core-1.0.0-py_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/decorator-4.3.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/docutils-0.14-py36hbfde631_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/entrypoints-0.2.3-py36_2.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/httplib2-0.12.0-py36_1000.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/idna-2.8-py36_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/imagesize-1.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipython_genutils-0.2.0-py36h241746c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/kiwisolver-1.0.1-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/lazy-object-proxy-1.3.1-py36h1de35cc_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/markupsafe-1.1.0-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mccabe-0.6.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mistune-0.8.4-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numpy-base-1.15.4-py36h8a80b8c_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/olefile-0.46-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pandocfilters-1.4.2-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/parso-0.3.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pickleshare-0.7.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/prometheus_client-0.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/psutil-5.4.8-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ptyprocess-0.6.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.4.4-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pycodestyle-2.4.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pycparser-2.19-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyflakes-2.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyparsing-2.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/python.app-2-py36_9.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pytz-2018.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyzmq-17.1.2-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/qtpy-1.5.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/free/osx-64/requests-2.14.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/rope-0.11.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/send2trash-1.5.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/simplejson-3.16.1-py36h470a237_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/simplekml-1.3.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sip-4.19.8-py36h0a44026_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/six-1.11.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/snowballstemmer-1.2.1-py36h6c7b616_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sphinxcontrib-1.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/testpath-0.4.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/toolz-0.9.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/tornado-5.1.1-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/typed-ast-1.1.0-py36h1de35cc_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wcwidth-0.1.7-py36h8c6ec74_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/webencodings-0.5.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wrapt-1.10.11-py36h1de35cc_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wurlitzer-1.0.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/astroid-2.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/babel-2.6.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/cffi-1.11.5-py36h5e8e0c9_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/cycler-0.10.0-py36hfc81398_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/cytoolz-0.9.0.1-py36h470a237_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jedi-0.13.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/keyring-16.1.1-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libdap4-3.19.1-h18059cb_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.6.2-h45f6246_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/packaging-18.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pexpect-4.6.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/pillow-5.3.0-py36hc736899_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/poppler-0.67.0-hdf8a1b3_2.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.2.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pyqt-5.9.2-py36h655552a_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/python-dateutil-2.7.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/qtawesome-0.5.3-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/rsa-3.4.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/setuptools-40.6.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sphinxcontrib-websupport-1.1.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/terminado-0.8.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/traitlets-4.3.2-py36h65bd3ce_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/uritemplate-3.0.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/bleach-3.0.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/cryptography-2.3.1-py36hdffb7b8_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-1.6.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/isort-4.3.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jinja2-2.10-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jsonschema-2.6.0-py36hb385e00_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter_core-4.4.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/libgdal-2.3.2-h42efa9e_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/networkx-2.2-py_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/oauth2client-4.1.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pygments-2.2.0-py36h240cd3f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/wheel-0.32.3-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-httplib2-0.0.3-py_2.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter_client-5.2.3-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/nbformat-4.4.0-py36h827af21_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pip-18.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/prompt_toolkit-2.0.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/pylint-2.2.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/pyopenssl-18.0.0-py36_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/sphinx-1.8.2-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-api-python-client-1.7.5-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipython-7.2.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/nbconvert-5.3.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numpydoc-0.8.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/earthengine-api-0.1.152-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipykernel-5.1.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter_console-6.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/notebook-5.7.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/qtconsole-4.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/spyder-kernels-0.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/widgetsnbextension-3.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/ipywidgets-7.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/jupyter-1.0.0-py36_7.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/gdal-2.3.2-py36hfc77a4a_1.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/imageio-2.4.1-py36_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/matplotlib-3.0.1-py36h54f8f79_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mkl_fft-1.0.6-py36hb8a8100_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/mkl_random-1.0.1-py36h5d10147_1.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/numpy-1.15.4-py36h6a91979_0.tar.bz2
https://conda.anaconda.org/conda-forge/osx-64/pywavelets-1.0.1-py36h7eb728f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/osx-64/scipy-1.1.0-py36h28f7352_1.tar.bz2
https://conda.anaconda.org/anaconda/osx-64/scikit-image-0.14.0-py36h0a44026_1.tar.bz2
https://conda.anaconda.org/anaconda/osx-64/scikit-learn-0.20.1-py36h4f467ca_0.tar.bz2

@ -0,0 +1,174 @@
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: win-64
@EXPLICIT
https://repo.anaconda.com/pkgs/main/win-64/blas-1.0-mkl.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/ca-certificates-2018.03.07-0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/icc_rt-2017.0.4-h97af966_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/intel-openmp-2019.1-144.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/msys2-conda-epoch-20160418-1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pandoc-2.2.3.2-0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/vs2015_runtime-14.15.26706-h3a45250_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/winpty-0.4.3-4.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/m2w64-gmp-6.1.0-2.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/m2w64-libwinpthread-git-5.0.0.4634.697f757-2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/mkl-2018.0.3-1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/vc-14.1-h0510ff6_4.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/expat-2.2.5-he025d50_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/geos-3.6.2-h9ef7328_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/icu-58.2-ha66f8fd_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jpeg-9b-hb83a4c4_2.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libiconv-1.15-h1df5818_7.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libsodium-1.0.16-h9d3ae62_0.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/m2w64-gcc-libs-core-5.3.0-7.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/openssl-1.0.2p-hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/proj4-4.9.3-hcf24537_7.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/python-3.6.7-h33f27b4_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sqlite-3.25.3-he774522_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/tk-8.6.8-hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/xerces-c-3.2.2-ha925a31_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/xz-5.2.4-h2fa13f4_4.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/zlib-1.2.11-h62dcd97_3.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/alabaster-0.7.12-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/asn1crypto-0.24.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/backcall-0.1.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/cachetools-2.1.0-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/certifi-2018.10.15-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/chardet-3.0.4-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cloudpickle-0.6.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/colorama-0.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/dask-core-1.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/decorator-4.3.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/docutils-0.14-py36h6012d8f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/entrypoints-0.2.3-py36_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/freexl-1.0.5-hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/hdf4-4.2.13-h712560f_2.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/hdf5-1.10.1-h98b8871_1.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/httplib2-0.12.0-py36_1000.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/idna-2.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/imagesize-1.1.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/ipython_genutils-0.2.0-py36h3c5d0ee_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/kiwisolver-1.0.1-py36h6538335_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/krb5-1.16.1-h038dc86_6.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/lazy-object-proxy-1.3.1-py36hfa6e2cd_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libboost-1.67.0-hd9e427e_4.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libpng-1.6.35-h2a8f88b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libssh2-1.8.0-hd619d38_4.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libtiff-4.0.9-h36446d0_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libxml2-2.9.8-hadb2253_1.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/m2w64-gcc-libgfortran-5.3.0-6.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/markupsafe-1.1.0-py36he774522_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/mccabe-0.6.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/mistune-0.8.4-py36he774522_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/numpy-base-1.15.4-py36h8128ebf_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/olefile-0.46-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pandocfilters-1.4.2-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/parso-0.3.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pickleshare-0.7.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/prometheus_client-0.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/psutil-5.4.8-py36he774522_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-0.4.4-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pycodestyle-2.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pycparser-2.19-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyflakes-2.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyparsing-2.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pytz-2018.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pywin32-223-py36hfa6e2cd_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/qtpy-1.5.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/rope-0.11.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/send2trash-1.5.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/win-64/simplejson-3.16.1-py36hfa6e2cd_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/simplekml-1.3.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sip-4.19.8-py36h6538335_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/six-1.11.0-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/snowballstemmer-1.2.1-py36h763602f_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sphinxcontrib-1.0-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/testpath-0.4.2-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/toolz-0.9.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/tornado-5.1.1-py36hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/typed-ast-1.1.0-py36hfa6e2cd_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wcwidth-0.1.7-py36h3d5aa90_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/webencodings-0.5.1-py36_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/win_inet_pton-1.0.1-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/wincertstore-0.2-py36h7fe50ca_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/wrapt-1.10.11-py36hfa6e2cd_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/zeromq-4.2.5-he025d50_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/astroid-2.1.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/babel-2.6.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cffi-1.11.5-py36h74b6da3_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/cycler-0.10.0-py36h009560c_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/freetype-2.9.1-ha9979f8_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jedi-0.13.1-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/kealib-1.4.7-ha5b336b_5.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/keyring-16.1.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libcurl-7.62.0-h2a8f88b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libkml-1.3.0-he5f2a48_4.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/libpq-10.5-h5fe2233_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libspatialite-4.3.0a-h383548d_18.tar.bz2
https://repo.anaconda.com/pkgs/msys2/win-64/m2w64-gcc-libs-5.3.0-7.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/openjpeg-2.3.0-h5ec785f_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/packaging-18.0-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/pyasn1-modules-0.2.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pysocks-1.6.8-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/python-dateutil-2.7.5-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyzmq-17.1.2-py36hfa6e2cd_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/qt-5.9.6-vc14h1e9a669_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/qtawesome-0.5.3-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/rsa-3.4.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/setuptools-40.6.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sphinxcontrib-websupport-1.1.0-py36_1.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/traitlets-4.3.2-py36h096827d_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/uritemplate-3.0.0-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/bleach-3.0.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/cryptography-2.3.1-py36h74b6da3_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/curl-7.62.0-h2a8f88b_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-1.6.1-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/isort-4.3.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jinja2-2.10-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/jsonschema-2.6.0-py36h7636477_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jupyter_core-4.4.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/networkx-2.2-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/oauth2client-4.1.2-py_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pillow-5.3.0-py36hdc69c19_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/pygments-2.2.0-py36hb010967_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyqt-5.9.2-py36h6538335_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pywinpty-0.5.4-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/wheel-0.32.3-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-auth-httplib2-0.0.3-py_2.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jupyter_client-5.2.3-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libnetcdf-4.4.1.1-h825a56a_8.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/nbformat-4.4.0-py36h3a5bc1b_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pip-18.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/prompt_toolkit-2.0.7-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pylint-2.2.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pyopenssl-18.0.0-py36_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/terminado-0.8.1-py36_1.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/google-api-python-client-1.7.5-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/ipython-7.2.0-py36h39e3cac_0.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/libgdal-2.2.2-h2727f2b_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/nbconvert-5.3.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/urllib3-1.23-py36_0.tar.bz2
https://conda.anaconda.org/conda-forge/noarch/earthengine-api-0.1.152-py_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/ipykernel-5.1.0-py36h39e3cac_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/requests-2.20.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jupyter_console-6.0.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/notebook-5.7.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/qtconsole-4.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/sphinx-1.8.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/spyder-kernels-0.3.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/numpydoc-0.8.0-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/widgetsnbextension-3.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/ipywidgets-7.4.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/spyder-3.3.2-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/jupyter-1.0.0-py36_7.tar.bz2
https://repo.continuum.io/pkgs/main/win-64/gdal-2.2.2-py36hcebd033_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/imageio-2.4.1-py36_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/matplotlib-3.0.1-py36hc8f65d3_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/mkl_fft-1.0.6-py36hdbbee80_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/mkl_random-1.0.1-py36h77b88f5_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/numpy-1.15.4-py36ha559c80_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/pywavelets-1.0.1-py36h8c2d366_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/scipy-1.1.0-py36h4f6bf74_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/shapely-1.6.4-py36hc90234e_0.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/scikit-image-0.14.0-py36h6538335_1.tar.bz2
https://repo.anaconda.com/pkgs/main/win-64/scikit-learn-0.20.1-py36hb854c30_0.tar.bz2

@ -1,199 +0,0 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Shoreline extraction from satellite images"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This notebook shows how to download satellite images (Landsat 5,7,8 and Sentinel-2) from Google Earth Engine and apply the shoreline detection algorithm described in *Vos K., Harley M.D., Splinter K.D., Simmons J.A., Turner I.L. (in review). Capturing intra-annual to multi-decadal shoreline variability from publicly available satellite imagery, Coastal Engineering*. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Initial settings"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The Python packages required to run this notebook can be installed by running the following anaconda command:\n",
"*\"conda env create -f environment.yml\"*. This will create a new enviroment with all the relevant packages installed. You will also need to sign up for Google Earth Engine (https://earthengine.google.com and go to signup) and authenticate on the computer so that python can access via your login."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"import pickle\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import warnings\n",
"warnings.filterwarnings(\"ignore\")\n",
"# load modules from directory\n",
"import SDS_download, SDS_preprocess, SDS_tools, SDS_shoreline"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Download images"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Define the region of interest, the dates and the satellite missions from which you want to download images. The image will be cropped on the Google Earth Engine server and only the region of interest will be downloaded resulting in low memory allocation (~ 1 megabyte/image for 5 km of beach)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# define the area of interest (longitude, latitude)\n",
"polygon = [[[151.301454, -33.700754],\n",
" [151.311453, -33.702075], \n",
" [151.307237, -33.739761],\n",
" [151.294220, -33.736329],\n",
" [151.301454, -33.700754]]]\n",
" \n",
"# define dates of interest\n",
"dates = ['2017-12-01','2018-01-01']\n",
"\n",
"# define satellite missions ('L5' --> landsat 5 , 'S2' --> Sentinel-2)\n",
"sat_list = ['L5', 'L7', 'L8', 'S2']\n",
"\n",
"# give a name to the site\n",
"sitename = 'NARRA'\n",
"\n",
"# download satellite images. The cropped images are saved in a '/data' subfolder. The image information is stored\n",
"# into 'metadata.pkl'.\n",
"# SDS_download.get_images(sitename, polygon, dates, sat_list)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Shoreline extraction"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Performs a sub-pixel resolution shoreline detection method integrating a supervised classification component that allows to map the boundary between water and sand."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# parameters and settings\n",
"%matplotlib qt\n",
"settings = { \n",
" 'sitename': sitename,\n",
" \n",
" # general parameters:\n",
" 'cloud_thresh': 0.5, # threshold on maximum cloud cover\n",
" 'output_epsg': 28356, # epsg code of the desired output spatial reference system\n",
" \n",
" # shoreline detection parameters:\n",
" 'min_beach_size': 20, # minimum number of connected pixels for a beach\n",
" 'buffer_size': 7, # radius (in pixels) of disk for buffer around sandy pixels\n",
" 'min_length_sl': 200, # minimum length of shoreline perimeter to be kept \n",
" 'max_dist_ref': 100 , # max distance (in meters) allowed from a reference shoreline\n",
" \n",
" # quality control:\n",
" 'check_detection': True # if True, shows each shoreline detection and lets the user \n",
" # decide which shorleines are correct and which ones are false due to\n",
" # the presence of clouds and other artefacts. \n",
" # If set to False, shorelines are extracted from all images.\n",
" }\n",
"\n",
"# load metadata structure (contains information on the downloaded satellite images and is created\n",
"# after all images have been successfully downloaded)\n",
"filepath = os.path.join(os.getcwd(), 'data', settings['sitename'])\n",
"with open(os.path.join(filepath, settings['sitename'] + '_metadata' + '.pkl'), 'rb') as f:\n",
" metadata = pickle.load(f)\n",
" \n",
"# [OPTIONAL] saves .jpg files of the preprocessed images (cloud mask and pansharpening/down-sampling) \n",
"#SDS_preprocess.save_jpg(metadata, settings)\n",
"\n",
"# [OPTIONAL] to avoid false detections and identify obvious outliers there is the option to\n",
"# create a reference shoreline position (manually clicking on a satellite image)\n",
"settings['refsl'] = SDS_preprocess.get_reference_sl(metadata, settings)\n",
"\n",
"# extract shorelines from all images. Saves out.pkl which contains the shoreline coordinates for each date in the spatial\n",
"# reference system specified in settings['output_epsg']. Save the output in a file called 'out.pkl'.\n",
"out = SDS_shoreline.extract_shorelines(metadata, settings)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Plot the shorelines"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"plt.figure()\n",
"plt.axis('equal')\n",
"plt.xlabel('Eastings [m]')\n",
"plt.ylabel('Northings [m]')\n",
"plt.title('Shorelines')\n",
"for satname in out.keys():\n",
" if satname == 'meta':\n",
" continue\n",
" for i in range(len(out[satname]['shoreline'])):\n",
" sl = out[satname]['shoreline'][i]\n",
" date = out[satname]['timestamp'][i]\n",
" plt.plot(sl[:,0], sl[:,1], '-', label=date.strftime('%d-%m-%Y'))\n",
"plt.legend()"
]
}
],
"metadata": {
"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.6.4"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading…
Cancel
Save