diff --git a/install.yml b/install.yml index c5c82f0..30efd9b 100644 --- a/install.yml +++ b/install.yml @@ -1,5 +1,7 @@ # This file should be committed to your app code. version: 1.0 +# This should be greater or equal to your tethys-platform in your environment +tethys_version: ">=4.0.0" # This should match the app - package name in your setup.py name: earth_engine @@ -15,4 +17,6 @@ requirements: - geojson pip: -post: + npm: + +post: \ No newline at end of file diff --git a/setup.py b/setup.py index 90a817f..7f32563 100644 --- a/setup.py +++ b/setup.py @@ -1,16 +1,16 @@ from setuptools import setup, find_namespace_packages -from tethys_apps.app_installation import find_resource_files +from tethys_apps.app_installation import find_all_resource_files +from tethys_apps.base.app_base import TethysAppBase # -- Apps Definition -- # app_package = 'earth_engine' -release_package = 'tethysapp-' + app_package +release_package = f'{TethysAppBase.package_namespace}-{app_package}' # -- Python Dependencies -- # dependencies = [] # -- Get Resource File -- # -resource_files = find_resource_files('tethysapp/' + app_package + '/templates', 'tethysapp/' + app_package) -resource_files += find_resource_files('tethysapp/' + app_package + '/public', 'tethysapp/' + app_package) +resource_files = find_all_resource_files(app_package, TethysAppBase.package_namespace) setup( diff --git a/tethysapp/earth_engine/__init__.py b/tethysapp/earth_engine/__init__.py index 8766881..c927d02 100644 --- a/tethysapp/earth_engine/__init__.py +++ b/tethysapp/earth_engine/__init__.py @@ -1 +1 @@ -# Included for native namespace package support \ No newline at end of file +# Included for native namespace package support diff --git a/tethysapp/earth_engine/app.py b/tethysapp/earth_engine/app.py index 23889dc..d368756 100644 --- a/tethysapp/earth_engine/app.py +++ b/tethysapp/earth_engine/app.py @@ -1,4 +1,4 @@ -from tethys_sdk.base import TethysAppBase, url_map_maker +from tethys_sdk.base import TethysAppBase class EarthEngine(TethysAppBase): @@ -6,49 +6,13 @@ class EarthEngine(TethysAppBase): Tethys app class for Earth Engine. """ - name = 'Earth Engine' - index = 'earth_engine:home' - icon = 'earth_engine/images/earth-engine-logo.png' - package = 'earth_engine' + name = 'Google Earth Engine Tutorial' + description = '' + package = 'earth_engine' # WARNING: Do not change this value + index = 'home' + icon = f'{package}/images/earth-engine-logo.png' root_url = 'earth-engine' color = '#524745' - description = '' tags = '' enable_feedback = False - feedback_emails = [] - - def url_maps(self): - """ - Add controllers - """ - UrlMap = url_map_maker(self.root_url) - - url_maps = ( - UrlMap( - name='home', - url='earth-engine', - controller='earth_engine.controllers.home' - ), - UrlMap( - name='viewer', - url='earth-engine/viewer', - controller='earth_engine.controllers.viewer' - ), - UrlMap( - name='get_image_collection', - url='earth-engine/viewer/get-image-collection', - controller='earth_engine.controllers.get_image_collection' - ), - UrlMap( - name='get_time_series_plot', - url='earth-engine/viewer/get-time-series-plot', - controller='earth_engine.controllers.get_time_series_plot' - ), - UrlMap( - name='about', - url='earth-engine/about', - controller='earth_engine.controllers.about' - ) - ) - - return url_maps + feedback_emails = [] \ No newline at end of file diff --git a/tethysapp/earth_engine/controllers.py b/tethysapp/earth_engine/controllers.py index 6e59a25..292a2d5 100644 --- a/tethysapp/earth_engine/controllers.py +++ b/tethysapp/earth_engine/controllers.py @@ -1,19 +1,19 @@ -import logging import datetime as dt import geojson +import logging +from simplejson.errors import JSONDecodeError from django.http import JsonResponse, HttpResponseNotAllowed from django.shortcuts import render -from simplejson.errors import JSONDecodeError +from tethys_sdk.routing import controller from tethys_sdk.gizmos import SelectInput, DatePicker, Button, MapView, MVView, PlotlyView, MVDraw -from tethys_sdk.permissions import login_required -from .helpers import generate_figure from .gee.methods import get_image_collection_asset, get_time_series_from_image_collection from .gee.products import EE_PRODUCTS +from .helpers import generate_figure log = logging.getLogger(f'tethys.apps.{__name__}') -@login_required() +@controller def home(request): """ Controller for the app home page. @@ -22,7 +22,7 @@ def home(request): return render(request, 'earth_engine/home.html', context) -@login_required() +@controller def about(request): """ Controller for the app about page. @@ -31,10 +31,10 @@ def about(request): return render(request, 'earth_engine/about.html', context) -@login_required() +@controller def viewer(request): """ - Controller for the app viewer page. + Controller for the app home page. """ default_platform = 'modis' default_sensors = EE_PRODUCTS[default_platform] @@ -138,24 +138,10 @@ def viewer(request): load_button = Button( name='load_map', display_text='Load', - style='default', + style='outline-secondary', attributes={'id': 'load_map'} ) - clear_button = Button( - name='clear_map', - display_text='Clear', - style='default', - attributes={'id': 'clear_map'} - ) - - plot_button = Button( - name='load_plot', - display_text='Plot AOI', - style='default', - attributes={'id': 'load_plot'} - ) - map_view = MapView( height='100%', width='100%', @@ -187,6 +173,21 @@ def viewer(request): ) ) + clear_button = Button( + name='clear_map', + display_text='Clear', + style='outline-secondary', + attributes={'id': 'clear_map'}, + classes='mt-2', + ) + + plot_button = Button( + name='load_plot', + display_text='Plot AOI', + style='outline-secondary', + attributes={'id': 'load_plot'}, + ) + context = { 'platform_select': platform_select, 'sensor_select': sensor_select, @@ -204,7 +205,7 @@ def viewer(request): return render(request, 'earth_engine/viewer.html', context) -@login_required() +@controller(url='viewer/get-image-collection') def get_image_collection(request): """ Controller to handle image collection requests. @@ -245,8 +246,7 @@ def get_image_collection(request): return JsonResponse(response_data) - -@login_required() +@controller(url='viewer/get-time-series-plot') def get_time_series_plot(request): context = {'success': False} diff --git a/tethysapp/earth_engine/gee/cloud_mask.py b/tethysapp/earth_engine/gee/cloud_mask.py index ac99943..6ffc3bf 100644 --- a/tethysapp/earth_engine/gee/cloud_mask.py +++ b/tethysapp/earth_engine/gee/cloud_mask.py @@ -3,7 +3,7 @@ def mask_l8_sr(image): """ - Derived From: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1_SR + Cloud Mask for Landsat 8 surface reflectance. Derived From: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1_SR """ # Bits 3 and 5 are cloud shadow and cloud, respectively. cloudShadowBitMask = (1 << 3) @@ -19,7 +19,7 @@ def mask_l8_sr(image): def cloud_mask_l457(image): """ - Derived From: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LE07_C01_T1_SR + Cloud Mask for Landsat 7 surface reflectance. Derived From: https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LE07_C01_T1_SR """ qa = image.select('pixel_qa') @@ -35,7 +35,7 @@ def cloud_mask_l457(image): def mask_s2_clouds(image): """ - Derived from: https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2 + Cloud Mask for Sentinel 2 surface reflectance. Derived from: https://developers.google.com/earth-engine/datasets/catalog/COPERNICUS_S2 """ qa = image.select('QA60') diff --git a/tethysapp/earth_engine/gee/methods.py b/tethysapp/earth_engine/gee/methods.py index 99d4fa0..ce6a9ab 100644 --- a/tethysapp/earth_engine/gee/methods.py +++ b/tethysapp/earth_engine/gee/methods.py @@ -3,10 +3,9 @@ from ee.ee_exception import EEException import geojson import pandas as pd +from .products import EE_PRODUCTS from . import params as gee_account from . import cloud_mask as cm -from .products import EE_PRODUCTS - log = logging.getLogger(f'tethys.apps.{__name__}') diff --git a/tethysapp/earth_engine/handoff.py b/tethysapp/earth_engine/handoff.py deleted file mode 100644 index 1e15fb8..0000000 --- a/tethysapp/earth_engine/handoff.py +++ /dev/null @@ -1,3 +0,0 @@ -# Define your handoff handlers here -# for more information, see: -# http://docs.tethysplatform.org/en/dev/tethys_sdk/handoff.html \ No newline at end of file diff --git a/tethysapp/earth_engine/public/css/disclaimer_modal.css b/tethysapp/earth_engine/public/css/disclaimer_modal.css deleted file mode 100644 index f5d3ff7..0000000 --- a/tethysapp/earth_engine/public/css/disclaimer_modal.css +++ /dev/null @@ -1,20 +0,0 @@ -#disclaimer-container { - height: 400px; - overflow-y: auto; -} - -#sponsors-container { - text-align: left; -} - -#sponsors-container img { - height: 50px; - width: 50px; - margin-right: 10px; - border-radius: 5px; -} - -#sponsors-container h6 { - display: inline-block; - margin-right: 10px; -} diff --git a/tethysapp/earth_engine/public/css/home.css b/tethysapp/earth_engine/public/css/home.css index f0cd423..bde0dd0 100644 --- a/tethysapp/earth_engine/public/css/home.css +++ b/tethysapp/earth_engine/public/css/home.css @@ -1,3 +1,7 @@ +#inner-app-content { + padding: 0; +} + .info-container { background-color: #0000009f; box-shadow: 3px 5px 3px rgba(0,0,0,0.35); @@ -69,4 +73,4 @@ background-color: #d2dadc; background-position: center; background-repeat: no-repeat -} +} \ No newline at end of file diff --git a/tethysapp/earth_engine/public/css/loader.css b/tethysapp/earth_engine/public/css/loader.css index d23c836..b1f287e 100644 --- a/tethysapp/earth_engine/public/css/loader.css +++ b/tethysapp/earth_engine/public/css/loader.css @@ -12,4 +12,4 @@ #loader.show { display: block; -} +} \ No newline at end of file diff --git a/tethysapp/earth_engine/public/css/main.css b/tethysapp/earth_engine/public/css/main.css index b2b732d..be9379d 100644 --- a/tethysapp/earth_engine/public/css/main.css +++ b/tethysapp/earth_engine/public/css/main.css @@ -1,4 +1,4 @@ /* Remove padding on bottom where app-actions section used to be */ #app-content-wrapper #app-content { padding-bottom: 0; -} +} \ No newline at end of file diff --git a/tethysapp/earth_engine/public/css/map.css b/tethysapp/earth_engine/public/css/map.css index 6d72cbb..7a0907e 100644 --- a/tethysapp/earth_engine/public/css/map.css +++ b/tethysapp/earth_engine/public/css/map.css @@ -6,4 +6,4 @@ #inner-app-content { height: 100%; padding: 0; -} +} \ No newline at end of file diff --git a/tethysapp/earth_engine/public/css/no_nav.css b/tethysapp/earth_engine/public/css/no_nav.css deleted file mode 100644 index f114ed9..0000000 --- a/tethysapp/earth_engine/public/css/no_nav.css +++ /dev/null @@ -1,16 +0,0 @@ -#nav-title-wrapper { - margin-left: 15px; -} - -#app-content-wrapper #app-content { - height: 100%; -} - -#app-content-wrapper.show-nav #app-content { - padding-right: 0; - transform: none; -} - -#inner-app-content { - padding: 0; -} diff --git a/tethysapp/earth_engine/public/css/plot.css b/tethysapp/earth_engine/public/css/plot.css index 0a02db7..a8d9f45 100644 --- a/tethysapp/earth_engine/public/css/plot.css +++ b/tethysapp/earth_engine/public/css/plot.css @@ -1,5 +1,9 @@ #plot-loader { - margin: 65px 84px; + display: flex; + align-items: center; + width: 100%; + justify-content: center; + flex-direction: column; } #plot-loader p { @@ -9,3 +13,8 @@ #plot-modal .modal-body { min-height: 480px; } + +.modal-dialog { + max-width: 70vw; + margin: 1.75rem auto; +} \ No newline at end of file diff --git a/tethysapp/earth_engine/public/images/icon.gif b/tethysapp/earth_engine/public/images/icon.gif deleted file mode 100644 index 5c8236e..0000000 Binary files a/tethysapp/earth_engine/public/images/icon.gif and /dev/null differ diff --git a/tethysapp/earth_engine/public/js/gee_datasets.js b/tethysapp/earth_engine/public/js/gee_datasets.js index d7063c7..4b717bd 100644 --- a/tethysapp/earth_engine/public/js/gee_datasets.js +++ b/tethysapp/earth_engine/public/js/gee_datasets.js @@ -76,7 +76,6 @@ var GEE_DATASETS = (function() { } }); - $('#start_date').on('change', function() { let start_date = $('#start_date').val(); @@ -121,10 +120,10 @@ var GEE_DATASETS = (function() { if (!m_platform in EE_PRODUCTS) { alert('Unknown platform selected.'); } - + // Clear sensor options $('#sensor').select2().empty(); - + // Set the Sensor Options let first_option = true; for (var sensor in EE_PRODUCTS[m_platform]) { @@ -133,7 +132,7 @@ var GEE_DATASETS = (function() { $('#sensor').append(new_option); first_option = false; } - + // Trigger a sensor change event to update select box $('#sensor').trigger('change'); update_date_bounds(); @@ -143,12 +142,12 @@ var GEE_DATASETS = (function() { if (!m_platform in EE_PRODUCTS || !m_sensor in EE_PRODUCTS[m_platform]) { alert('Unknown platform or sensor selected.'); } - + // Clear product options $('#product').select2().empty(); - + let first_option = true; - + // Set the Product Options for (var product in EE_PRODUCTS[m_platform][m_sensor]) { let product_display_name = EE_PRODUCTS[m_platform][m_sensor][product]['display']; @@ -156,7 +155,7 @@ var GEE_DATASETS = (function() { $('#product').append(new_option); first_option = false; } - + // Trigger a product change event to update select box $('#product').trigger('change'); update_date_bounds(); @@ -166,24 +165,24 @@ var GEE_DATASETS = (function() { // Get new date picker bounds for the current product let earliest_valid_date = EE_PRODUCTS[m_platform][m_sensor][m_product]['start_date']; let latest_valid_date = EE_PRODUCTS[m_platform][m_sensor][m_product]['end_date']; - + // Get current values of date pickers let current_start_date = $('#start_date').val(); let current_end_date = $('#end_date').val(); - + // Convert to Dates objects for comparison let date_evd = Date.parse(earliest_valid_date); let date_lvd = Date.parse(latest_valid_date) ? (latest_valid_date) : Date.now(); let date_csd = Date.parse(current_start_date); let date_ced = Date.parse(current_end_date); - + // Don't reset currently selected dates if they fall within the new date range let reset_current_dates = true; - + if (date_csd >= date_evd && date_csd <= date_lvd && date_ced >= date_evd && date_ced <= date_lvd) { reset_current_dates = false; } - + // Update start date datepicker bounds $('#start_date').datepicker('setStartDate', earliest_valid_date); $('#start_date').datepicker('setEndDate', latest_valid_date); @@ -191,7 +190,7 @@ var GEE_DATASETS = (function() { $('#start_date').datepicker('update', INITIAL_START_DATE); m_start_date = INITIAL_START_DATE; } - + // Update end date datepicker bounds $('#end_date').datepicker('setStartDate', earliest_valid_date); $('#end_date').datepicker('setEndDate', latest_valid_date); @@ -199,7 +198,7 @@ var GEE_DATASETS = (function() { $('#end_date').datepicker('update', INITIAL_END_DATE); m_end_date = INITIAL_END_DATE; } - + console.log('Date Bounds Changed To: ' + earliest_valid_date + ' - ' + latest_valid_date); }; @@ -219,14 +218,14 @@ var GEE_DATASETS = (function() { // Map Methods update_map = function() { let data = collect_data(); - + let xhr = $.ajax({ type: 'POST', url: 'get-image-collection/', dataType: 'json', data: data }); - + xhr.done(function(response) { if (response.success) { console.log(response.url); @@ -250,25 +249,25 @@ var GEE_DATASETS = (function() { url: url, attributions: 'Google Earth Engine' }); - + source.on('tileloadstart', function() { $('#loader').addClass('show'); }); - + source.on('tileloadend', function() { $('#loader').removeClass('show'); }); - + source.on('tileloaderror', function() { $('#loader').removeClass('show'); }); - + m_gee_layer = new ol.layer.Tile({ source: source, opacity: 0.7 }); - - // Insert below the draw layer (so drawn polygons and points render on top of data layer). + + // Insert below the draw layer (so drawn polygons and points render on top of the data layer). m_map.getLayers().insertAt(1, m_gee_layer); }; @@ -288,9 +287,9 @@ var GEE_DATASETS = (function() { update_plot = function() { let data = collect_data(); - + show_plot_modal(); - + $('#plot-container').load('get-time-series-plot/', data); }; @@ -332,4 +331,4 @@ var GEE_DATASETS = (function() { return public_interface; -}()); // End of package wrapper +}()); // End of package wrapper \ No newline at end of file diff --git a/tethysapp/earth_engine/public/js/main.js b/tethysapp/earth_engine/public/js/main.js index 510998b..b0f978c 100644 --- a/tethysapp/earth_engine/public/js/main.js +++ b/tethysapp/earth_engine/public/js/main.js @@ -30,4 +30,4 @@ $(function() { } } }); -}); //document ready; +}); //document ready; \ No newline at end of file diff --git a/tethysapp/earth_engine/templates/earth_engine/about.html b/tethysapp/earth_engine/templates/earth_engine/about.html index 41c383a..b2390bf 100644 --- a/tethysapp/earth_engine/templates/earth_engine/about.html +++ b/tethysapp/earth_engine/templates/earth_engine/about.html @@ -1,13 +1,13 @@ -{% extends "earth_engine/base.html" %} +{% extends "tethys_apps/app_header_content.html" %} {% load static %} {% block styles %} {{ block.super }} - {% endblock %} -{% block app_navigation_override %} +{% block header_buttons %} + {% include "earth_engine/header_buttons.html" %} {% endblock %} {% block app_content %} @@ -15,43 +15,48 @@
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Euismod nisi porta lorem mollis. Congue quisque egestas diam in arcu cursus euismod. Auctor neque vitae tempus quam pellentesque nec nam. Erat imperdiet sed euismod nisi porta lorem. Nunc eget lorem dolor sed viverra ipsum nunc aliquet bibendum. Sed blandit libero volutpat sed cras ornare. Convallis tellus id interdum velit laoreet id. Amet mauris commodo quis imperdiet massa tincidunt. Mi bibendum neque egestas congue quisque egestas diam in. Enim nec dui nunc mattis enim ut tellus elementum sagittis. Cursus mattis molestie a iaculis at erat pellentesque. Ut tellus elementum sagittis vitae et leo.
-Eu consequat ac felis donec et odio. Eget arcu dictum varius duis at consectetur lorem. Lorem ipsum dolor sit amet consectetur. Turpis egestas integer eget aliquet nibh praesent. Mattis rhoncus urna neque viverra justo nec. Iaculis urna id volutpat lacus laoreet non curabitur gravida arcu. Convallis posuere morbi leo urna molestie at elementum eu. Fermentum et sollicitudin ac orci phasellus egestas tellus. Convallis aenean et tortor at risus. Morbi tristique senectus et netus et malesuada fames ac. Sed vulputate mi sit amet mauris commodo quis. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Id venenatis a condimentum vitae sapien pellentesque habitant morbi tristique. Id cursus metus aliquam eleifend mi in nulla. Proin fermentum leo vel orci porta non pulvinar neque laoreet. Lobortis mattis aliquam faucibus purus in massa tempor. Varius vel pharetra vel turpis nunc.
-Mauris rhoncus aenean vel elit: Blandit aliquam etiam erat velit. Auctor neque vitae tempus quam pellentesque nec nam. Augue mauris augue neque gravida in fermentum et. Tempus urna et pharetra pharetra. Vel turpis nunc eget lorem. Vitae nunc sed velit dignissim. Enim tortor at auctor urna nunc id. Pellentesque habitant morbi tristique senectus et netus et. Tellus integer feugiat scelerisque varius morbi enim nunc faucibus.
-Blandit turpis cursus in hac habitasse platea: Tellus elementum sagittis vitae et leo duis ut diam quam. Amet nisl purus in mollis nunc sed. Ac feugiat sed lectus vestibulum. Suscipit adipiscing bibendum est ultricies integer quis. Tortor pretium viverra suspendisse potenti nullam ac tortor. Blandit turpis cursus in hac. Id porta nibh venenatis cras sed felis eget velit. Fermentum posuere urna nec tincidunt praesent semper feugiat nibh sed. Pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at. Sapien et ligula ullamcorper malesuada proin libero nunc consequat. Aliquet enim tortor at auctor urna nunc id. Fringilla ut morbi tincidunt augue interdum velit euismod in. In arcu cursus euismod quis viverra nibh. Vulputate ut pharetra sit amet. Purus in massa tempor nec. Pellentesque massa placerat duis ultricies lacus sed. Integer feugiat scelerisque varius morbi enim. Vitae tempus quam pellentesque nec nam.
-Sed cras ornare arcu dui vivamus arcu: Pellentesque adipiscing commodo elit at. Fusce id velit ut tortor pretium viverra. Nunc vel risus commodo viverra. Dui faucibus in ornare quam viverra orci sagittis eu volutpat. Aliquet nibh praesent tristique magna. Purus sit amet volutpat consequat. Gravida neque convallis a cras. Aenean euismod elementum nisi quis eleifend. At tellus at urna condimentum mattis pellentesque id nibh tortor. Sit amet massa vitae tortor. Volutpat lacus laoreet non curabitur gravida arcu ac. Vulputate dignissim suspendisse in est ante. Tempor commodo ullamcorper a lacus vestibulum. Quis vel eros donec ac odio tempor. Lacus sed turpis tincidunt id aliquet risus feugiat in ante. Metus aliquam eleifend mi in.
' +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Euismod nisi porta lorem mollis. Congue quisque egestas diam in arcu cursus euismod. Auctor neque vitae tempus quam pellentesque nec nam. Erat imperdiet sed euismod nisi porta lorem. Nunc eget lorem dolor sed viverra ipsum nunc aliquet bibendum. Sed blandit libero volutpat sed cras ornare. Convallis tellus id interdum velit laoreet id. Amet mauris commodo quis imperdiet massa tincidunt. Mi bibendum neque egestas congue quisque egestas diam in. Enim nec dui nunc mattis enim ut tellus elementum sagittis. Cursus mattis molestie a iaculis at erat pellentesque. Ut tellus elementum sagittis vitae et leo.
+Eu consequat ac felis donec et odio. Eget arcu dictum varius duis at consectetur lorem. Lorem ipsum dolor sit amet consectetur. Turpis egestas integer eget aliquet nibh praesent. Mattis rhoncus urna neque viverra justo nec. Iaculis urna id volutpat lacus laoreet non curabitur gravida arcu. Convallis posuere morbi leo urna molestie at elementum eu. Fermentum et sollicitudin ac orci phasellus egestas tellus. Convallis aenean et tortor at risus. Morbi tristique senectus et netus et malesuada fames ac. Sed vulputate mi sit amet mauris commodo quis. Nisi quis eleifend quam adipiscing vitae proin sagittis nisl. Id venenatis a condimentum vitae sapien pellentesque habitant morbi tristique. Id cursus metus aliquam eleifend mi in nulla. Proin fermentum leo vel orci porta non pulvinar neque laoreet. Lobortis mattis aliquam faucibus purus in massa tempor. Varius vel pharetra vel turpis nunc.
+Mauris rhoncus aenean vel elit: Blandit aliquam etiam erat velit. Auctor neque vitae tempus quam pellentesque nec nam. Augue mauris augue neque gravida in fermentum et. Tempus urna et pharetra pharetra. Vel turpis nunc eget lorem. Vitae nunc sed velit dignissim. Enim tortor at auctor urna nunc id. Pellentesque habitant morbi tristique senectus et netus et. Tellus integer feugiat scelerisque varius morbi enim nunc faucibus.
+Blandit turpis cursus in hac habitasse platea: Tellus elementum sagittis vitae et leo duis ut diam quam. Amet nisl purus in mollis nunc sed. Ac feugiat sed lectus vestibulum. Suscipit adipiscing bibendum est ultricies integer quis. Tortor pretium viverra suspendisse potenti nullam ac tortor. Blandit turpis cursus in hac. Id porta nibh venenatis cras sed felis eget velit. Fermentum posuere urna nec tincidunt praesent semper feugiat nibh sed. Pellentesque elit ullamcorper dignissim cras tincidunt lobortis feugiat vivamus at. Sapien et ligula ullamcorper malesuada proin libero nunc consequat. Aliquet enim tortor at auctor urna nunc id. Fringilla ut morbi tincidunt augue interdum velit euismod in. In arcu cursus euismod quis viverra nibh. Vulputate ut pharetra sit amet. Purus in massa tempor nec. Pellentesque massa placerat duis ultricies lacus sed. Integer feugiat scelerisque varius morbi enim. Vitae tempus quam pellentesque nec nam.
+Sed cras ornare arcu dui vivamus arcu: Pellentesque adipiscing commodo elit at. Fusce id velit ut tortor pretium viverra. Nunc vel risus commodo viverra. Dui faucibus in ornare quam viverra orci sagittis eu volutpat. Aliquet nibh praesent tristique magna. Purus sit amet volutpat consequat. Gravida neque convallis a cras. Aenean euismod elementum nisi quis eleifend. At tellus at urna condimentum mattis pellentesque id nibh tortor. Sit amet massa vitae tortor. Volutpat lacus laoreet non curabitur gravida arcu ac. Vulputate dignissim suspendisse in est ante. Tempor commodo ullamcorper a lacus vestibulum. Quis vel eros donec ac odio tempor. Lacus sed turpis tincidunt id aliquet risus feugiat in ante. Metus aliquam eleifend mi in.
' +Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Eget est lorem ipsum dolor sit amet. Morbi tincidunt augue interdum velit euismod in pellentesque.
Ac felis donec et odio pellentesque. Quis ipsum suspendisse ultrices gravida dictum fusce ut. Curabitur gravida arcu ac tortor dignissim convallis aenean et tortor. Sed euismod nisi porta lorem mollis. Nisi scelerisque eu ultrices vitae. Sit amet consectetur adipiscing elit duis. At in tellus integer feugiat scelerisque varius morbi enim.
@@ -26,35 +26,37 @@Change variables to select a data product, then press "Load" to add that product to the map.
{% gizmo load_button %} {% gizmo clear_button %} -Draw an area of interest or drop a point, the press "Plot AOI" to view a plot of the data.
+Draw an area of interest or drop a point, the press "Plot AOI" to view a plot of the data.
{% gizmo plot_button %} {% endblock %} @@ -39,8 +32,8 @@