mirror of
https://github.com/medialab-prado/poblados-colonizacion-colonias-penitenciarias.git
synced 2024-12-27 21:11:22 +01:00
479 lines
16 KiB
JavaScript
479 lines
16 KiB
JavaScript
/*
|
|
* L.TimeDimension.Layer.WMS: wms Layer associated to a TimeDimension
|
|
*/
|
|
|
|
L.TimeDimension.Layer.WMS = L.TimeDimension.Layer.extend({
|
|
|
|
initialize: function(layer, options) {
|
|
L.TimeDimension.Layer.prototype.initialize.call(this, layer, options);
|
|
this._timeCacheBackward = this.options.cacheBackward || this.options.cache || 0;
|
|
this._timeCacheForward = this.options.cacheForward || this.options.cache || 0;
|
|
this._wmsVersion = this.options.wmsVersion || this.options.version || layer.options.version || "1.1.1";
|
|
this._getCapabilitiesParams = this.options.getCapabilitiesParams || {};
|
|
this._getCapabilitiesAlternateUrl = this.options.getCapabilitiesUrl || null;
|
|
this._getCapabilitiesAlternateLayerName = this.options.getCapabilitiesLayerName || null;
|
|
this._proxy = this.options.proxy || null;
|
|
this._updateTimeDimension = this.options.updateTimeDimension || false;
|
|
this._setDefaultTime = this.options.setDefaultTime || false;
|
|
this._updateTimeDimensionMode = this.options.updateTimeDimensionMode || 'intersect'; // 'union' or 'replace'
|
|
this._layers = {};
|
|
this._defaultTime = 0;
|
|
this._availableTimes = [];
|
|
this._capabilitiesRequested = false;
|
|
if (this._updateTimeDimension || this.options.requestTimeFromCapabilities) {
|
|
this._requestTimeDimensionFromCapabilities();
|
|
}
|
|
|
|
this._baseLayer.on('load', (function() {
|
|
this._baseLayer.setLoaded(true);
|
|
this.fire('timeload', {
|
|
time: this._defaultTime
|
|
});
|
|
}).bind(this));
|
|
},
|
|
|
|
getEvents: function() {
|
|
var clearCache = L.bind(this._unvalidateCache, this);
|
|
return {
|
|
moveend: clearCache,
|
|
zoomend: clearCache
|
|
}
|
|
},
|
|
|
|
eachLayer: function(method, context) {
|
|
for (var prop in this._layers) {
|
|
if (this._layers.hasOwnProperty(prop)) {
|
|
method.call(context, this._layers[prop]);
|
|
}
|
|
}
|
|
return L.TimeDimension.Layer.prototype.eachLayer.call(this, method, context);
|
|
},
|
|
|
|
_onNewTimeLoading: function(ev) {
|
|
// console.log('Layer._onNewTimeLoading: ' + this._baseLayer.wmsParams.layers + ' with time: ' + new Date(ev.time).toISOString());
|
|
var layer = this._getLayerForTime(ev.time);
|
|
if (!this._map.hasLayer(layer)) {
|
|
this._map.addLayer(layer);
|
|
// console.log('Layer._onNewTimeLoading: layer added to map');
|
|
}
|
|
},
|
|
|
|
isReady: function(time) {
|
|
var layer = this._getLayerForTime(time);
|
|
return layer.isLoaded();
|
|
},
|
|
|
|
onAdd: function(map) {
|
|
L.TimeDimension.Layer.prototype.onAdd.call(this, map);
|
|
if (this._availableTimes.length == 0) {
|
|
this._requestTimeDimensionFromCapabilities();
|
|
} else {
|
|
this._updateTimeDimensionAvailableTimes();
|
|
}
|
|
},
|
|
|
|
_update: function() {
|
|
if (!this._map)
|
|
return;
|
|
var time = this._timeDimension.getCurrentTime();
|
|
// It will get the layer for this time (create or get)
|
|
// Then, the layer will be loaded if necessary, adding it to the map (and show it after loading).
|
|
// If it already on the map (but probably hidden), it will be shown
|
|
var layer = this._getLayerForTime(time);
|
|
if (this._currentLayer == null) {
|
|
this._currentLayer = layer;
|
|
}
|
|
if (!this._map.hasLayer(layer)) {
|
|
this._map.addLayer(layer);
|
|
} else {
|
|
this._showLayer(layer, time);
|
|
}
|
|
},
|
|
|
|
setOpacity: function(opacity) {
|
|
L.TimeDimension.Layer.prototype.setOpacity.apply(this, arguments);
|
|
// apply to all preloaded caches
|
|
for (var prop in this._layers) {
|
|
if (this._layers.hasOwnProperty(prop) && this._layers[prop].setOpacity) {
|
|
this._layers[prop].setOpacity(opacity);
|
|
}
|
|
}
|
|
},
|
|
|
|
setZIndex: function(zIndex){
|
|
L.TimeDimension.Layer.prototype.setZIndex.apply(this, arguments);
|
|
// apply to all preloaded caches
|
|
for (var prop in this._layers) {
|
|
if (this._layers.hasOwnProperty(prop) && this._layers[prop].setZIndex) {
|
|
this._layers[prop].setZIndex(zIndex);
|
|
}
|
|
}
|
|
},
|
|
|
|
setParams: function(params, noRedraw) {
|
|
L.extend(this._baseLayer.options, params);
|
|
if (this._baseLayer.setParams) {
|
|
this._baseLayer.setParams(params, noRedraw);
|
|
}
|
|
for (var prop in this._layers) {
|
|
if (this._layers.hasOwnProperty(prop) && this._layers[prop].setParams) {
|
|
this._layers[prop].setLoaded(false); // mark it as unloaded
|
|
this._layers[prop].setParams(params, noRedraw);
|
|
}
|
|
}
|
|
return this;
|
|
},
|
|
|
|
_unvalidateCache: function() {
|
|
var time = this._timeDimension.getCurrentTime();
|
|
for (var prop in this._layers) {
|
|
if (time != prop && this._layers.hasOwnProperty(prop)) {
|
|
this._layers[prop].setLoaded(false); // mark it as unloaded
|
|
this._layers[prop].redraw();
|
|
}
|
|
}
|
|
},
|
|
|
|
_evictCachedTimes: function(keepforward, keepbackward) {
|
|
// Cache management
|
|
var times = this._getLoadedTimes();
|
|
var strTime = String(this._currentTime);
|
|
var index = times.indexOf(strTime);
|
|
var remove = [];
|
|
// remove times before current time
|
|
if (keepbackward > -1) {
|
|
var objectsToRemove = index - keepbackward;
|
|
if (objectsToRemove > 0) {
|
|
remove = times.splice(0, objectsToRemove);
|
|
this._removeLayers(remove);
|
|
}
|
|
}
|
|
if (keepforward > -1) {
|
|
index = times.indexOf(strTime);
|
|
var objectsToRemove = times.length - index - keepforward - 1;
|
|
if (objectsToRemove > 0) {
|
|
remove = times.splice(index + keepforward + 1, objectsToRemove);
|
|
this._removeLayers(remove);
|
|
}
|
|
}
|
|
},
|
|
_showLayer: function(layer, time) {
|
|
if (this._currentLayer && this._currentLayer !== layer) {
|
|
this._currentLayer.hide();
|
|
}
|
|
layer.show();
|
|
if (this._currentLayer && this._currentLayer === layer) {
|
|
return;
|
|
}
|
|
this._currentLayer = layer;
|
|
this._currentTime = time;
|
|
console.log('Show layer ' + layer.wmsParams.layers + ' with time: ' + new Date(time).toISOString());
|
|
|
|
this._evictCachedTimes(this._timeCacheForward, this._timeCacheBackward);
|
|
},
|
|
|
|
_getLayerForTime: function(time) {
|
|
if (time == 0 || time == this._defaultTime || time == null) {
|
|
return this._baseLayer;
|
|
}
|
|
if (this._layers.hasOwnProperty(time)) {
|
|
return this._layers[time];
|
|
}
|
|
var nearestTime = this._getNearestTime(time);
|
|
if (this._layers.hasOwnProperty(nearestTime)) {
|
|
return this._layers[nearestTime];
|
|
}
|
|
|
|
var newLayer = this._createLayerForTime(nearestTime);
|
|
|
|
this._layers[time] = newLayer;
|
|
|
|
newLayer.on('load', (function(layer, time) {
|
|
layer.setLoaded(true);
|
|
// this time entry should exists inside _layers
|
|
// but it might be deleted by cache management
|
|
if (!this._layers[time]) {
|
|
this._layers[time] = layer;
|
|
}
|
|
if (this._timeDimension && time == this._timeDimension.getCurrentTime() && !this._timeDimension.isLoading()) {
|
|
this._showLayer(layer, time);
|
|
}
|
|
// console.log('Loaded layer ' + layer.wmsParams.layers + ' with time: ' + new Date(time).toISOString());
|
|
this.fire('timeload', {
|
|
time: time
|
|
});
|
|
}).bind(this, newLayer, time));
|
|
|
|
// Hack to hide the layer when added to the map.
|
|
// It will be shown when timeload event is fired from the map (after all layers are loaded)
|
|
newLayer.onAdd = (function(map) {
|
|
Object.getPrototypeOf(this).onAdd.call(this, map);
|
|
this.hide();
|
|
}).bind(newLayer);
|
|
return newLayer;
|
|
},
|
|
|
|
_createLayerForTime:function(time){
|
|
var wmsParams = this._baseLayer.options;
|
|
wmsParams.time = new Date(time).toISOString();
|
|
return new this._baseLayer.constructor(this._baseLayer.getURL(), wmsParams);
|
|
},
|
|
|
|
_getLoadedTimes: function() {
|
|
var result = [];
|
|
for (var prop in this._layers) {
|
|
if (this._layers.hasOwnProperty(prop)) {
|
|
result.push(prop);
|
|
}
|
|
}
|
|
return result.sort(function(a, b) {
|
|
return a - b;
|
|
});
|
|
},
|
|
|
|
_removeLayers: function(times) {
|
|
for (var i = 0, l = times.length; i < l; i++) {
|
|
if (this._map)
|
|
this._map.removeLayer(this._layers[times[i]]);
|
|
delete this._layers[times[i]];
|
|
}
|
|
},
|
|
|
|
setMinimumForwardCache: function(value) {
|
|
if (value > this._timeCacheForward) {
|
|
this._timeCacheForward = value;
|
|
}
|
|
},
|
|
|
|
_requestTimeDimensionFromCapabilities: function() {
|
|
if (this._capabilitiesRequested) {
|
|
return;
|
|
}
|
|
this._capabilitiesRequested = true;
|
|
var url = this._getCapabilitiesUrl();
|
|
if (this._proxy) {
|
|
url = this._proxy + '?url=' + encodeURIComponent(url);
|
|
}
|
|
$.get(url, (function(data) {
|
|
this._defaultTime = Date.parse(this._getDefaultTimeFromCapabilities(data));
|
|
this._setDefaultTime = this._setDefaultTime || (this._timeDimension && this._timeDimension.getAvailableTimes().length == 0);
|
|
this.setAvailableTimes(this._parseTimeDimensionFromCapabilities(data));
|
|
if (this._setDefaultTime && this._timeDimension) {
|
|
this._timeDimension.setCurrentTime(this._defaultTime);
|
|
}
|
|
}).bind(this));
|
|
},
|
|
|
|
_getCapabilitiesUrl: function() {
|
|
var url = this._baseLayer.getURL();
|
|
if (this._getCapabilitiesAlternateUrl)
|
|
url = this._getCapabilitiesAlternateUrl;
|
|
var params = L.extend({}, this._getCapabilitiesParams, {
|
|
'request': 'GetCapabilities',
|
|
'service': 'WMS',
|
|
'version': this._wmsVersion
|
|
});
|
|
url = url + L.Util.getParamString(params, url, params.uppercase);
|
|
return url;
|
|
},
|
|
|
|
_parseTimeDimensionFromCapabilities: function(xml) {
|
|
var layers = $(xml).find('Layer[queryable="1"]');
|
|
var layerName = this._baseLayer.wmsParams.layers;
|
|
if (this._getCapabilitiesAlternateLayerName)
|
|
layerName = this._getCapabilitiesAlternateLayerName;
|
|
var layerNameElement = layers.find("Name").filter(function(index) {
|
|
return $(this).text() === layerName;
|
|
});
|
|
var times = null;
|
|
if (layerNameElement) {
|
|
var layer = layerNameElement.parent();
|
|
times = this._getTimesFromLayerCapabilities(layer);
|
|
if (!times) {
|
|
times = this._getTimesFromLayerCapabilities(layer.parent());
|
|
}
|
|
}
|
|
return times;
|
|
},
|
|
|
|
_getTimesFromLayerCapabilities: function(layer) {
|
|
var times = null;
|
|
var dimension = layer.find("Dimension[name='time']");
|
|
if (dimension && dimension.length && dimension[0].textContent.length) {
|
|
times = dimension[0].textContent.trim();
|
|
} else {
|
|
var extent = layer.find("Extent[name='time']");
|
|
if (extent && extent.length && extent[0].textContent.length) {
|
|
times = extent[0].textContent.trim();
|
|
}
|
|
}
|
|
return times;
|
|
},
|
|
|
|
_getDefaultTimeFromCapabilities: function(xml) {
|
|
var layers = $(xml).find('Layer[queryable="1"]');
|
|
var layerName = this._baseLayer.wmsParams.layers;
|
|
if (this._getCapabilitiesAlternateLayerName)
|
|
layerName = this._getCapabilitiesAlternateLayerName;
|
|
var layerNameElement = layers.find("Name").filter(function(index) {
|
|
return $(this).text() === layerName;
|
|
});
|
|
var defaultTime = 0;
|
|
if (layerNameElement) {
|
|
var layer = layerNameElement.parent();
|
|
defaultTime = this._getDefaultTimeFromLayerCapabilities(layer);
|
|
if (defaultTime == 0) {
|
|
defaultTime = this._getDefaultTimeFromLayerCapabilities(layer.parent());
|
|
}
|
|
}
|
|
return defaultTime;
|
|
},
|
|
|
|
_getDefaultTimeFromLayerCapabilities: function(layer) {
|
|
var defaultTime = 0;
|
|
var dimension = layer.find("Dimension[name='time']");
|
|
if (dimension && dimension.attr("default")) {
|
|
defaultTime = dimension.attr("default");
|
|
} else {
|
|
var extent = layer.find("Extent[name='time']");
|
|
if (extent && extent.attr("default")) {
|
|
defaultTime = extent.attr("default");
|
|
}
|
|
}
|
|
return defaultTime;
|
|
},
|
|
|
|
|
|
setAvailableTimes: function(times) {
|
|
this._availableTimes = L.TimeDimension.Util.parseTimesExpression(times);
|
|
this._updateTimeDimensionAvailableTimes();
|
|
},
|
|
|
|
_updateTimeDimensionAvailableTimes: function() {
|
|
if ((this._timeDimension && this._updateTimeDimension) ||
|
|
(this._timeDimension && this._timeDimension.getAvailableTimes().length == 0)) {
|
|
this._timeDimension.setAvailableTimes(this._availableTimes, this._updateTimeDimensionMode);
|
|
if (this._setDefaultTime && this._defaultTime > 0) {
|
|
this._timeDimension.setCurrentTime(this._defaultTime);
|
|
}
|
|
}
|
|
},
|
|
|
|
_getNearestTime: function(time) {
|
|
if (this._layers.hasOwnProperty(time)) {
|
|
return time;
|
|
}
|
|
if (this._availableTimes.length == 0) {
|
|
return time;
|
|
}
|
|
var index = 0;
|
|
var len = this._availableTimes.length;
|
|
for (; index < len; index++) {
|
|
if (time < this._availableTimes[index]) {
|
|
break;
|
|
}
|
|
}
|
|
// We've found the first index greater than the time. Get the previous
|
|
if (index > 0) {
|
|
index--;
|
|
}
|
|
if (time != this._availableTimes[index]) {
|
|
console.log('Search layer time: ' + new Date(time).toISOString());
|
|
console.log('Return layer time: ' + new Date(this._availableTimes[index]).toISOString());
|
|
}
|
|
return this._availableTimes[index];
|
|
},
|
|
|
|
});
|
|
|
|
if (!L.NonTiledLayer) {
|
|
L.NonTiledLayer = (L.Layer || L.Class).extend({});
|
|
}
|
|
|
|
L.NonTiledLayer.include({
|
|
_visible: true,
|
|
_loaded: false,
|
|
|
|
_originalUpdate: L.NonTiledLayer.prototype._update,
|
|
_originalOnRemove: L.NonTiledLayer.prototype.onRemove,
|
|
|
|
_update: function() {
|
|
if (!this._visible && this._loaded) {
|
|
return;
|
|
}
|
|
this._originalUpdate();
|
|
},
|
|
|
|
onRemove: function(map) {
|
|
this._loaded = false;
|
|
this._originalOnRemove(map);
|
|
},
|
|
|
|
setLoaded: function(loaded) {
|
|
this._loaded = loaded;
|
|
},
|
|
|
|
isLoaded: function() {
|
|
return this._loaded;
|
|
},
|
|
|
|
hide: function() {
|
|
this._visible = false;
|
|
this._div.style.display = 'none';
|
|
},
|
|
|
|
show: function() {
|
|
this._visible = true;
|
|
this._div.style.display = 'block';
|
|
},
|
|
|
|
getURL: function() {
|
|
return this._wmsUrl;
|
|
}
|
|
|
|
});
|
|
|
|
L.TileLayer.include({
|
|
_visible: true,
|
|
_loaded: false,
|
|
|
|
_originalUpdate: L.TileLayer.prototype._update,
|
|
|
|
_update: function() {
|
|
if (!this._visible && this._loaded) {
|
|
return;
|
|
}
|
|
this._originalUpdate();
|
|
},
|
|
|
|
setLoaded: function(loaded) {
|
|
this._loaded = loaded;
|
|
},
|
|
|
|
isLoaded: function() {
|
|
return this._loaded;
|
|
},
|
|
|
|
hide: function() {
|
|
this._visible = false;
|
|
if (this._container) {
|
|
this._container.style.display = 'none';
|
|
}
|
|
},
|
|
|
|
show: function() {
|
|
this._visible = true;
|
|
if (this._container) {
|
|
this._container.style.display = 'block';
|
|
}
|
|
},
|
|
|
|
getURL: function() {
|
|
return this._url;
|
|
}
|
|
|
|
});
|
|
|
|
L.timeDimension.layer.wms = function(layer, options) {
|
|
return new L.TimeDimension.Layer.WMS(layer, options);
|
|
};
|