/* Copyright (c) 2006-2010 by OpenLayers Contributors (see authors.txt for
* full list of contributors). Published under the Clear BSD license.
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Layer.js
*/
/**
* Class: OpenLayers.Layer.HTTPRequest
*
* Inherits from:
* - <OpenLayers.Layer>
*/
OpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, {
/**
* Constant: URL_HASH_FACTOR
* {Float} Used to hash URL param strings for multi-WMS server selection.
* Set to the Golden Ratio per Knuth's recommendation.
*/
URL_HASH_FACTOR: (Math.sqrt(5) - 1) / 2,
/**
* Property: url
* {Array(String) or String} This is either an array of url strings or
* a single url string.
*/
url: null,
/**
* Property: params
* {Object} Hashtable of key/value parameters
*/
params: null,
/**
* APIProperty: reproject
* *Deprecated*. See http://trac.openlayers.org/wiki/SpatialMercator
* for information on the replacement for this functionality.
* {Boolean} Whether layer should reproject itself based on base layer
* locations. This allows reprojection onto commercial layers.
* Default is false: Most layers can't reproject, but layers
* which can create non-square geographic pixels can, like WMS.
*
*/
reproject: false,
/**
* Constructor: OpenLayers.Layer.HTTPRequest
*
* Parameters:
* name - {String}
* url - {Array(String) or String}
* params - {Object}
* options - {Object} Hashtable of extra options to tag onto the layer
*/
initialize: function(name, url, params, options) {
var newArguments = arguments;
newArguments = [name, options];
OpenLayers.Layer.prototype.initialize.apply(this, newArguments);
this.url = url;
this.params = OpenLayers.Util.extend( {}, params);
},
/**
* APIMethod: destroy
*/
destroy: function() {
this.url = null;
this.params = null;
OpenLayers.Layer.prototype.destroy.apply(this, arguments);
},
/**
* APIMethod: clone
*
* Parameters:
* obj - {Object}
*
* Returns:
* {<OpenLayers.Layer.HTTPRequest>} An exact clone of this
* <OpenLayers.Layer.HTTPRequest>
*/
clone: function (obj) {
if (obj == null) {
obj = new OpenLayers.Layer.HTTPRequest(this.name,
this.url,
this.params,
this.getOptions());
}
//get all additions from superclasses
obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);
// copy/set any non-init, non-simple values here
return obj;
},
/**
* APIMethod: setUrl
*
* Parameters:
* newUrl - {String}
*/
setUrl: function(newUrl) {
this.url = newUrl;
},
/**
* APIMethod: mergeNewParams
*
* Parameters:
* newParams - {Object}
*
* Returns:
* redrawn: {Boolean} whether the layer was actually redrawn.
*/
mergeNewParams:function(newParams) {
this.params = OpenLayers.Util.extend(this.params, newParams);
var ret = this.redraw();
if(this.map != null) {
this.map.events.triggerEvent("changelayer", {
layer: this,
property: "params"
});
}
return ret;
},
/**
* APIMethod: redraw
* Redraws the layer. Returns true if the layer was redrawn, false if not.
*
* Parameters:
* force - {Boolean} Force redraw by adding random parameter.
*
* Returns:
* {Boolean} The layer was redrawn.
*/
redraw: function(force) {
if (force) {
return this.mergeNewParams({"_olSalt": Math.random()});
} else {
return OpenLayers.Layer.prototype.redraw.apply(this, []);
}
},
/**
* Method: selectUrl
* selectUrl() implements the standard floating-point multiplicative
* hash function described by Knuth, and hashes the contents of the
* given param string into a float between 0 and 1. This float is then
* scaled to the size of the provided urls array, and used to select
* a URL.
*
* Parameters:
* paramString - {String}
* urls - {Array(String)}
*
* Returns:
* {String} An entry from the urls array, deterministically selected based
* on the paramString.
*/
selectUrl: function(paramString, urls) {
var product = 1;
for (var i=0, len=paramString.length; i<len; i++) {
product *= paramString.charCodeAt(i) * this.URL_HASH_FACTOR;
product -= Math.floor(product);
}
return urls[Math.floor(product * urls.length)];
},
/**
* Method: getFullRequestString
* Combine url with layer's params and these newParams.
*
* does checking on the serverPath variable, allowing for cases when it
* is supplied with trailing ? or &, as well as cases where not.
*
* return in formatted string like this:
* "server?key1=value1&key2=value2&key3=value3"
*
* WARNING: The altUrl parameter is deprecated and will be removed in 3.0.
*
* Parameters:
* newParams - {Object}
* altUrl - {String} Use this as the url instead of the layer's url
*
* Returns:
* {String}
*/
getFullRequestString:function(newParams, altUrl) {
// if not altUrl passed in, use layer's url
var url = altUrl || this.url;
// create a new params hashtable with all the layer params and the
// new params together. then convert to string
var allParams = OpenLayers.Util.extend({}, this.params);
allParams = OpenLayers.Util.extend(allParams, newParams);
var paramsString = OpenLayers.Util.getParameterString(allParams);
// if url is not a string, it should be an array of strings,
// in which case we will deterministically select one of them in
// order to evenly distribute requests to different urls.
//
if (url instanceof Array) {
url = this.selectUrl(paramsString, url);
}
// ignore parameters that are already in the url search string
var urlParams =
OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));
for(var key in allParams) {
if(key.toUpperCase() in urlParams) {
delete allParams[key];
}
}
paramsString = OpenLayers.Util.getParameterString(allParams);
return OpenLayers.Util.urlAppend(url, paramsString);
},
CLASS_NAME: "OpenLayers.Layer.HTTPRequest"
});