diff --git a/app/assets/javascripts/helpers/fallbackDataHelper.js b/app/assets/javascripts/helpers/fallbackDataHelper.js index 93b9279d56..ef2746d09d 100644 --- a/app/assets/javascripts/helpers/fallbackDataHelper.js +++ b/app/assets/javascripts/helpers/fallbackDataHelper.js @@ -283,4 +283,4 @@ define([], function() { }; return fallbackDataHelper; -}); +}); \ No newline at end of file diff --git a/app/assets/javascripts/map.js b/app/assets/javascripts/map.js index ee31f81ba2..c20063c758 100644 --- a/app/assets/javascripts/map.js +++ b/app/assets/javascripts/map.js @@ -1,3 +1,4 @@ +/* eslint-disable */ /** * Application entry point. */ @@ -29,6 +30,7 @@ require([ 'map/views/NavMobileView', 'map/views/GuideView', 'map/views/controls/GuideButtonView', + 'map/views/ReactMapMiddleView', 'views/HeaderView', 'views/FooterView', 'views/NotificationsView', @@ -56,6 +58,7 @@ require([ NavMobileView, GuideView, GuideButtonView, + ReactMapMiddleView, HeaderView, FooterView, NotificationsView, @@ -65,6 +68,9 @@ require([ $el: $('body'), init: function() { + window.App = { + Views: {} + }; var router = new Router(this); this._cartodbHack(); this._handlebarsPlugins(); @@ -80,6 +86,7 @@ require([ if (!Backbone.History.started) { Backbone.history.start({ pushState: true }); } + window.dispatchEvent(new Event('mapLoaded')); }, _fetchData: function() { @@ -87,16 +94,20 @@ require([ // we shouldn't create any view. countryService .getCountries() - .then(function(results) { - this.countries = results; - this._initViews(); - }.bind(this)) - .catch(function(e) { - console.warn(e); - // Fallback when request is timing out - this.countries = FallbackDataHelper.getCountryNames(); - this._initViews(); - }.bind(this)); + .then( + function(results) { + this.countries = results; + this._initViews(); + }.bind(this) + ) + .catch( + function(e) { + console.warn(e); + // Fallback when request is timing out + this.countries = FallbackDataHelper.getCountryNames(); + this._initViews(); + }.bind(this) + ); }, /** * Initialize Application Views. @@ -122,6 +133,7 @@ require([ new NotificationsView(this.map, this.countries); new GuideView(this.map, this.countries); new GuideButtonView(this.map, this.countries); + window.App.Views.ReactMapMiddleView = new ReactMapMiddleView(this.map); this._initApp(); }, @@ -137,14 +149,11 @@ require([ }, _handlebarsPlugins: function() { - Handlebars.registerHelper( - 'firstLetter', - function(text) { - return text.charAt(0).toUpperCase(); - } - ); + Handlebars.registerHelper('firstLetter', function(text) { + return text.charAt(0).toUpperCase(); + }); - Handlebars.registerHelper('ifCond', function (v1, operator, v2, options) { + Handlebars.registerHelper('ifCond', function(v1, operator, v2, options) { switch (operator) { case '==': return v1 == v2 ? options.fn(this) : options.inverse(this); @@ -172,7 +181,7 @@ require([ _googleMapsHelper: function() { if (!google.maps.Polygon.prototype.getBounds) { - google.maps.Polygon.prototype.getBounds = function () { + google.maps.Polygon.prototype.getBounds = function() { var bounds = new google.maps.LatLngBounds(); var paths = this.getPaths(); var path; diff --git a/app/assets/javascripts/map/helpers/layersHelper.js b/app/assets/javascripts/map/helpers/layersHelper.js index 632d1d9c7a..cfdc191d55 100644 --- a/app/assets/javascripts/map/helpers/layersHelper.js +++ b/app/assets/javascripts/map/helpers/layersHelper.js @@ -177,9 +177,7 @@ define( 'map/views/layers/HaitiWatershedLayer', 'map/views/layers/EcuUserProtectedAreasLayer', 'map/views/layers/BolUserFireFrequencyLayer', - // high resolution maps - 'map/views/layers/SentinelLayer', - 'map/views/layers/SentinelTilesLayer', + 'map/views/layers/RecentImageryLayer', // Layer dialog templates // 'text!templates/dialogs/loss_dialog.handlebars', // Layers timelines @@ -366,9 +364,7 @@ define( HaitiWatershedLayer, EcuUserProtectedAreasLayer, BolUserFireFrequencyLayer, - // highres layers - SentinelLayer, - SentinelTilesLayer, + RecentImageryLayer, // Layer dialog templates // loss_dialog, // Layer timelines @@ -777,11 +773,8 @@ define( usa_forest_ownership: { view: UsaForestOwnershipLayer }, - highres: { - view: SentinelLayer - }, sentinel_tiles: { - view: SentinelTilesLayer + view: RecentImageryLayer }, guyra: { view: GuyraLayer, diff --git a/app/assets/javascripts/map/models/LayerSpecModel.js b/app/assets/javascripts/map/models/LayerSpecModel.js index 81f41fadab..44f8275e66 100644 --- a/app/assets/javascripts/map/models/LayerSpecModel.js +++ b/app/assets/javascripts/map/models/LayerSpecModel.js @@ -207,10 +207,7 @@ define(['underscore', 'backbone'], function(_, Backbone) { * @return {object} layers */ positionizer: function(layers) { - var layerOrder = _.intersection( - this.layerOrder, - _.pluck(layers, 'slug') - ); + var layerOrder = _.intersection(this.layerOrder, _.pluck(layers, 'slug')); _.each( layerOrder, _.bind(function(slug, i) { @@ -293,10 +290,9 @@ define(['underscore', 'backbone'], function(_, Backbone) { var category = this.get(categoryName); if (category) { categories.push( - _.sortBy( - this.positionizer(category), - function(layer){ return layer.position; } - ).reverse() + _.sortBy(this.positionizer(category), function(layer) { + return layer.position; + }).reverse() ); } }, this) diff --git a/app/assets/javascripts/map/presenters/ReactMapMiddlePresenter.js b/app/assets/javascripts/map/presenters/ReactMapMiddlePresenter.js new file mode 100644 index 0000000000..c207767aa0 --- /dev/null +++ b/app/assets/javascripts/map/presenters/ReactMapMiddlePresenter.js @@ -0,0 +1,113 @@ +/* eslint-disable */ +define( + [ + 'underscore', + 'mps', + 'map/presenters/PresenterClass', + 'map/services/LayerSpecService' + ], + function(_, mps, PresenterClass, layerSpecService) { + 'use strict'; + + var StatusModel = Backbone.Model.extend({ + defaults: { + layers: [], + recentImagery: null + } + }); + + var ReactMapMiddlePresenter = PresenterClass.extend({ + init: function(view) { + this.view = view; + this.status = new StatusModel(); + this._super(); + mps.publish('Place/register', [this]); + }, + + _subscriptions: [ + { + 'Place/go': function(place) { + this.status.set('layerSpec', place.layerSpec); + this.status.set('recentImagery', place.params.recentImagery); + var isRecentImageryActivated = !!this.status + .get('layerSpec') + .getLayer({ slug: 'sentinel_tiles' }); + if ( + isRecentImageryActivated && + !!this.status.get('recentImagery') + ) { + this.view.fillParams( + JSON.parse(atob(place.params.recentImagery)) + ); + } + } + }, + { + 'LayerNav/change': function(layerSpec) { + this.status.set('layerSpec', layerSpec); + var isRecentImageryActivated = !!this.status + .get('layerSpec') + .getLayer({ slug: 'sentinel_tiles' }); + + if (isRecentImageryActivated) { + this.setRecentImagery(this.view.getParams()); + } + } + }, + { + 'Layer/add': function(slug) { + if (slug === 'sentinel_tiles') { + window.dispatchEvent(new Event('isRecentImageryActivated')); + } + } + }, + { + 'ReactMap/zoom-go-back': function(slug) { + mps.publish('Map/set-zoom', [this.view.previousZoom]); + } + } + ], + + toggleLayer: function(layerSlug) { + var where = [{ slug: layerSlug }]; + layerSpecService.toggle( + where, + _.bind(function(layerSpec) { + mps.publish('LayerNav/change', [layerSpec]); + mps.publish('Place/update', [{ go: false }]); + }, this) + ); + }, + + updateLayer: function(name, params) { + this.setRecentImagery(this.view.getParams()); + mps.publish('Layer/update', [name]); + }, + + setRecentImagery: function(value) { + if (!!value) { + value = btoa(JSON.stringify(value)); + } + + this.status.set('recentImagery', value); + this.publishRecentImagery(); + }, + + publishRecentImagery: function() { + mps.publish('Place/update', [{ go: false }]); + }, + + getPlaceParams: function() { + return { + recentImagery: this.status.get('recentImagery') + }; + }, + + notificate: function(id) { + mps.publish('Notification/open', [id]); + } + }); + + return ReactMapMiddlePresenter; + } +); diff --git a/app/assets/javascripts/map/presenters/SentinelTilesLayerPresenter.js b/app/assets/javascripts/map/presenters/SentinelTilesLayerPresenter.js deleted file mode 100644 index 9c848b11e8..0000000000 --- a/app/assets/javascripts/map/presenters/SentinelTilesLayerPresenter.js +++ /dev/null @@ -1,35 +0,0 @@ -define([ - 'mps', 'backbone', 'moment', 'map/presenters/PresenterClass' -], function(mps, Backbone, moment, PresenterClass) { - - 'use strict'; - - var StatusModel = Backbone.Model.extend({}); - - var SentinelTilesLayerPresenter = PresenterClass.extend({ - - init: function(view) { - this.view = view; - this._super(); - - this.status = new StatusModel(); - }, - - _subscriptions: [{ - 'SentinelTiles/update': function(params) { - if (params !== null) { - params = JSON.parse(atob(params)); - - this.view.setCurrentDate([ - moment.utc(params.mindate), - moment.utc(params.maxdate) - ]); - } - } - }] - - }); - - return SentinelTilesLayerPresenter; - -}); diff --git a/app/assets/javascripts/map/presenters/analysis/AnalysisResultsNewPresenter.js b/app/assets/javascripts/map/presenters/analysis/AnalysisResultsNewPresenter.js index 5ea4c78f6f..e47315bdb4 100644 --- a/app/assets/javascripts/map/presenters/analysis/AnalysisResultsNewPresenter.js +++ b/app/assets/javascripts/map/presenters/analysis/AnalysisResultsNewPresenter.js @@ -94,13 +94,14 @@ define( getRegions: function() { var iso = this.status.get('iso'); - CountryService.getRegionsList({ iso: iso.country }) - .then(function(results) { + CountryService.getRegionsList({ iso: iso.country }).then( + function(results) { this.status.set({ regions: results }); this.view.render(); - }.bind(this)); + }.bind(this) + ); }, getSubRegions: function() { @@ -109,12 +110,14 @@ define( CountryService.getSubRegionsList({ iso: iso.country, region: iso.region - }).then(function(results) { - this.status.set({ - subRegions: results - }); - this.view.render(); - }.bind(this)); + }).then( + function(results) { + this.status.set({ + subRegions: results + }); + this.view.render(); + }.bind(this) + ); }, /** diff --git a/app/assets/javascripts/map/presenters/analysis/AnalysisResultsPresenter.js b/app/assets/javascripts/map/presenters/analysis/AnalysisResultsPresenter.js index fe7ac32190..2a2600d07c 100644 --- a/app/assets/javascripts/map/presenters/analysis/AnalysisResultsPresenter.js +++ b/app/assets/javascripts/map/presenters/analysis/AnalysisResultsPresenter.js @@ -435,4 +435,4 @@ define( return AnalysisResultsPresenter; } -); +); \ No newline at end of file diff --git a/app/assets/javascripts/map/presenters/layers/BiodiversityCompletenessLayerPresenter.js b/app/assets/javascripts/map/presenters/layers/BiodiversityCompletenessLayerPresenter.js index 35f2c33173..9780fb96a0 100644 --- a/app/assets/javascripts/map/presenters/layers/BiodiversityCompletenessLayerPresenter.js +++ b/app/assets/javascripts/map/presenters/layers/BiodiversityCompletenessLayerPresenter.js @@ -27,4 +27,4 @@ define( return BiodiversityCompletenessLayerPresenter; } -); +); \ No newline at end of file diff --git a/app/assets/javascripts/map/presenters/layers/BiodiversityIntactnessLayerPresenter.js b/app/assets/javascripts/map/presenters/layers/BiodiversityIntactnessLayerPresenter.js index c85ee37768..21e728dd03 100644 --- a/app/assets/javascripts/map/presenters/layers/BiodiversityIntactnessLayerPresenter.js +++ b/app/assets/javascripts/map/presenters/layers/BiodiversityIntactnessLayerPresenter.js @@ -27,4 +27,4 @@ define( return BiodiversityIntactnessLayerPresenter; } -); +); \ No newline at end of file diff --git a/app/assets/javascripts/map/presenters/tabs/AnalysisNewPresenter.js b/app/assets/javascripts/map/presenters/tabs/AnalysisNewPresenter.js index 4e9ec8d5aa..b2a1e5a390 100644 --- a/app/assets/javascripts/map/presenters/tabs/AnalysisNewPresenter.js +++ b/app/assets/javascripts/map/presenters/tabs/AnalysisNewPresenter.js @@ -936,4 +936,4 @@ define( return AnalysisNewPresenter; } -); +); \ No newline at end of file diff --git a/app/assets/javascripts/map/services/PlaceService.js b/app/assets/javascripts/map/services/PlaceService.js index 451b293e1d..41353f25ea 100644 --- a/app/assets/javascripts/map/services/PlaceService.js +++ b/app/assets/javascripts/map/services/PlaceService.js @@ -68,7 +68,7 @@ define( var PlaceService = PresenterClass.extend({ _uriTemplate: - '{name}{/zoom}{/lat}{/lng}{/iso}{/maptype}{/baselayers}{/sublayers}{?tab,fit_to_geom,geojson,geostore,wdpaid,begin,end,threshold,dont_analyze,hresolution,tour,subscribe,use,useid,layer_options,lang}', + '{name}{/zoom}{/lat}{/lng}{/iso}{/maptype}{/baselayers}{/sublayers}{?tab,fit_to_geom,geojson,geostore,wdpaid,begin,end,threshold,dont_analyze,hresolution,recentImagery,tour,subscribe,use,useid,layer_options,lang}', /** * Create new PlaceService with supplied Backbone.Router. @@ -157,6 +157,102 @@ define( return decodeURIComponent(url); }, + /** + * Return standardized representation of supplied params object. + * + * @param {Object} params The params to standardize + * @return {Object} The standardized params. + */ + _standardizeParams: function(params) { + var p = _.extendNonNull({}, urlDefaultsParams, params); + p.name = this._name; + + p.baselayers = _.map(p.baselayers.split(','), function(slug) { + return { slug: slug }; + }); + + p.sublayers = p.sublayers + ? _.map(p.sublayers.split(','), function(id) { + return { id: _.toNumber(id) }; + }) + : []; + + p.zoom = _.toNumber(p.zoom); + p.lat = _.toNumber(p.lat); + p.lng = _.toNumber(p.lng); + p.iso = _.object(['country', 'region'], p.iso.split('-')); + p.begin = p.begin ? p.begin.format('YYYY-MM-DD') : null; + p.end = p.end ? p.end.format('YYYY-MM-DD') : null; + p.geostore = p.geostore ? p.geostore : null; + p.wdpaid = p.wdpaid ? _.toNumber(p.wdpaid) : null; + p.threshold = p.threshold ? _.toNumber(p.threshold) : null; + p.dont_analyze = p.dont_analyze ? p.dont_analyze : null; + p.subscribe_alerts = p.subscribe_alerts === 'subscribe' ? true : null; + p.referral = p.referral; + p.hresolution = p.hresolution; + p.recentImagery = p.recentImagery; + p.tour = p.tour; + + if (p.layer_options) { + p.layer_options = p.layer_options.split(','); + } + + return p; + }, + + /** + * Return formated URL representation of supplied params object based on + * a route name. + * + * @param {Object} params Place to standardize + * @return {Object} Params ready for URL + */ + _destandardizeParams: function(params) { + var p = _.extendNonNull({}, urlDefaultsParams, params); + var baselayers = _.pluck(p.baselayers, 'slug'); + p.name = this._name; + p.baselayers = baselayers.length > 0 ? baselayers : 'none'; + p.sublayers = p.sublayers ? p.sublayers.join(',') : null; + p.zoom = String(p.zoom); + p.lat = p.lat.toFixed(2); + p.lng = p.lng.toFixed(2); + p.iso = _.compact(_.values(p.iso)).join('-') || 'ALL'; + p.begin = p.begin ? p.begin.format('YYYY-MM-DD') : null; + p.end = p.end ? p.end.format('YYYY-MM-DD') : null; + p.geostore = p.geostore ? p.geostore : null; + p.wdpaid = p.wdpaid ? String(p.wdpaid) : null; + p.threshold = p.threshold ? String(p.threshold) : null; + p.dont_analyze = p.dont_analyze ? p.dont_analyze : null; + p.hresolution = p.hresolution; + p.recentImagery = p.recentImagery; + p.tour = p.tour; + + if (p.layer_options) { + p.layer_options = p.layer_options.join(','); + } + + where = _.union(place.params.baselayers, place.params.sublayers); + + layerSpecService.toggle( + where, + _.bind(function(layerSpec) { + place.layerSpec = layerSpec; + mps.publish('Place/go', [place]); + }, this) + ); + }, + + /** + * Return route URL for supplied route name and route params. + * + * @param {Object} params The route params + * @return {string} The route URL + */ + _getRoute: function(params) { + var url = new UriTemplate(this._uriTemplate).fillFromObject(params); + return decodeURIComponent(url); + }, + /** * Return standardized representation of supplied params object. * diff --git a/app/assets/javascripts/map/services/SentinelService.js b/app/assets/javascripts/map/services/SentinelService.js deleted file mode 100644 index 352233cdb0..0000000000 --- a/app/assets/javascripts/map/services/SentinelService.js +++ /dev/null @@ -1,83 +0,0 @@ -define([ - 'Class', - 'uri', - 'bluebird', - 'map/services/DataService' -], function(Class, UriTemplate, Promise, ds) { - - 'use strict'; - - var GET_REQUEST_SENTINEL_TILES_ID = 'SentinelService:getTiles'; - - var APIURL = 'https://staging-api.globalforestwatch.org/v1'; - - var APIURLS = { - 'getTiles': '/sentinel-tiles?lat={lat}&lon={lon}&start={start}&end={end}' - }; - - var SentinelService = Class.extend({ - init: function() { - this.currentRequest = []; - }, - - getTiles: function(lat, lon, start, end) { - return new Promise(function(resolve, reject) { - var url = new UriTemplate(APIURLS.getTiles).fillFromObject({ - lat: lat, - lon: lon, - start: start, - end: end - }); - - var requestId = GET_REQUEST_SENTINEL_TILES_ID + '_' + lat + '_' + lon; - this.defineRequest( - requestId, - APIURL + url, - { type: 'persist', duration: 1, unit: 'days' } - ); - - var requestConfig = { - resourceId: requestId, - success: function(res, status) { - resolve(res.data, status); - }, - error: function(errors) { - reject(errors); - } - }; - - this.abortRequest(requestId); - this.currentRequest[requestId] = ds.request(requestConfig); - }.bind(this)); - }, - - defineRequest: function (id, url, cache) { - ds.define(id, { - cache: cache, - url: url, - type: 'GET', - dataType: 'json', - contentType: 'application/json; charset=utf-8', - decoder: function ( data, status, xhr, success, error ) { - if ( status === "success" ) { - success( data, xhr ); - } - } - }); - }, - - /** - * Abort the current request if it exists. - */ - abortRequest: function(request) { - if (this.currentRequest && this.currentRequest[request]) { - this.currentRequest[request].abort(); - this.currentRequest[request] = null; - } - } - - }); - - return new SentinelService(); - -}); diff --git a/app/assets/javascripts/map/templates/legend/sentinel_tiles.handlebars b/app/assets/javascripts/map/templates/legend/sentinel_tiles.handlebars index d483535473..0366dab3a9 100644 --- a/app/assets/javascripts/map/templates/legend/sentinel_tiles.handlebars +++ b/app/assets/javascripts/map/templates/legend/sentinel_tiles.handlebars @@ -1,3 +1 @@ -
-
Refresh tile
-
\ No newline at end of file +
diff --git a/app/assets/javascripts/map/templates/tabs-mobile.handlebars b/app/assets/javascripts/map/templates/tabs-mobile.handlebars index 706eafbeb3..a3e3e5327a 100644 --- a/app/assets/javascripts/map/templates/tabs-mobile.handlebars +++ b/app/assets/javascripts/map/templates/tabs-mobile.handlebars @@ -9,7 +9,6 @@
  • Global data
  • Country data
  • Basemaps
  • -
  • High Resolution Imagery