socib / Leaflet.TimeDimension

Add time dimension capabilities on a Leaflet map.
MIT License
435 stars 139 forks source link

TimeDimension for NASA GIBS Tiles #168

Closed DrPDash closed 5 years ago

DrPDash commented 5 years ago

date_gh.zip

Hi folks, I'm displaying tiles from NASA GIBS and the template is: var template = '//gibs-{s}.earthdata.nasa.gov/wmts/epsg4326/best/' + '{layer}/default/{time}/{tileMatrixSet}/{z}/{y}/{x}.jpg';

As such, mapping for these EPSG4326 files work fine for a constant data (e.g., "2013-11-04"). When I connect TimeDimesnion to it with "L.timeDimension.layer.wms" it does not work because of a return of "YYYY-MM-DD:T00:00:00Z" time stamp. The "template" above expects "YYYY-MM-DD".

For the display on the time-bar, I was able to change L.Control.TimeDimensionCustom to YYYY-MM-DD but the the GET function call from "L.timeDimension.layer.wms" still has the complete ISO stamp.

Chrome debugger shows (example) Bad Resuest: GET https://gibs-b.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/2013-11-03**T00:00:00.000Z**/EPSG4326_250m/4/2/2.jpg 400 (Bad Request)

If I remove "T00:00:00.000Z" the request is valid: https://gibs-b.earthdata.nasa.gov/wmts/epsg4326/best/MODIS_Terra_CorrectedReflectance_TrueColor/default/2013-11-03/EPSG4326_250m/4/2/2.jpg

The attached zip-folder has all the codes but you will need a server (or a local server). On the index.html file, if you toggle at the section, you can see the error for testTimeLayer case. // CHANGETHE DISPLAY LAYER FROM FIXED DATE TO A DATE GIVE BY TIMEDIMENSION
layerfinal = testTimeLayer; // layerfinal = layer;

Any suggestion to fix this will be very much appreciated. Many thanks

DrPDash commented 5 years ago

After trying different things, 'moment.js' helped after a small modification in the 'leaflet.timedimension.layer.wms.js' function.

I included another parameter to the options initialize: function(layer, options) as below:

/ added hack on 26 Feb 2019 return ISO timestamp w/o Thh:mm:ssZ extension / this._setDisplayDateFormat = this.options.setDisplayDateFormat || false; / end of hack on 26 Feb 2019 to tune it for daily data folders without Thh:mm:ssZ extension in time /

and modified createLayerForTime: _createLayerForTime:function(time){ var wmsParams = this._baseLayer.options; // wmsParams.time = new Date(time).toISOString(); var aa = new Date(time).toISOString(); wmsParams.time = moment(aa).format(this._setDisplayDateFormat); return new this._baseLayer.constructor(this._baseLayer.getURL(), wmsParams); },

Closing. Thank you.

gastoneb commented 5 years ago

Thanks for these hints. In my case each layer required different amounts of ISO8601 precision (rounded to the nearest hour, rounded to the nearest second, etc.) So rather than setting my _setDisplayDateFormat in the leaflet.timedimension.layer.wms initialize() function, I added a "dateFormat" option for each layer, which I could then access from the this._baseLayer object:

_createLayerForTime:function(time){
    const wmsParams = this._baseLayer.options;
    const timeIsoString = new Date(time).toISOString();
    wmsParams.time = moment(timeIsoString).utc().format(this._baseLayer.options["dateFormat"])+"Z";
    return new this._baseLayer.constructor(this._baseLayer.getURL(), wmsParams);
},

I would vote in favor of reopening this issue or creating a more generic issue. Moment is great but it's probably best to avoid adding that dependency just for this purpose.

DrPDash commented 5 years ago

Glad that you found hints useful and agree that you ought to modify the way it suits your objective, eacj layer in your case. Also, I do agree that a generic solution is preferable over an additional dependence on moment.js, but I am afraid the developers of this nice and useful plugin (time-dimension) are not proactive in responding to questions - perhaps they are caught up and the project is over leaving no time for this (I fully understand as well, if this is the case).

So, please feel free to re-open knowing this background if someone from the community solves this, it will be great.