Files
openlayers/build/OpenLayers.js
euzuro 42277961da working version of singlefile.
git-svn-id: http://svn.openlayers.org/trunk/openlayers@475 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2006-05-31 16:49:37 +00:00

6456 lines
180 KiB
JavaScript
Raw Blame History

////
/// This blob sucks in all the files in uncompressed form for ease of use
///
OpenLayers = new Object();
OpenLayers._scriptName = "lib/OpenLayers.js";
OpenLayers._getScriptLocation = function () {
var scriptLocation = "";
var SCRIPT_NAME = OpenLayers._scriptName;
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var src = scripts[i].getAttribute('src');
if (src) {
var index = src.lastIndexOf(SCRIPT_NAME);
// is it found, at the end of the URL?
if ((index > -1) && (index + SCRIPT_NAME.length == src.length)) {
scriptLocation = src.slice(0, -SCRIPT_NAME.length);
break;
}
}
}
return scriptLocation;
}
/* Prototype JavaScript framework, version 1.4.0
* (c) 2005 Sam Stephenson <sam@conio.net>
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://prototype.conio.net/
*
/*--------------------------------------------------------------------------*/
var Prototype = {
Version: '1.4.0',
ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
emptyFunction: function() {},
K: function(x) {return x}
}
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
var Abstract = new Object();
Object.extend = function(destination, source) {
for (property in source) {
destination[property] = source[property];
}
return destination;
}
Object.inspect = function(object) {
try {
if (object == undefined) return 'undefined';
if (object == null) return 'null';
return object.inspect ? object.inspect() : object.toString();
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
}
Function.prototype.bind = function() {
var __method = this, args = $A(arguments), object = args.shift();
return function() {
return __method.apply(object, args.concat($A(arguments)));
}
}
Function.prototype.bindAsEventListener = function(object) {
var __method = this;
return function(event) {
return __method.call(object, event || window.event);
}
}
Object.extend(Number.prototype, {
toColorPart: function() {
var digits = this.toString(16);
if (this < 16) return '0' + digits;
return digits;
},
succ: function() {
return this + 1;
},
times: function(iterator) {
$R(0, this, true).each(iterator);
return this;
}
});
var Try = {
these: function() {
var returnValue;
for (var i = 0; i < arguments.length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) {}
}
return returnValue;
}
}
/*--------------------------------------------------------------------------*/
var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.callback();
} finally {
this.currentlyExecuting = false;
}
}
}
}
/*--------------------------------------------------------------------------*/
function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}
Object.extend(String.prototype, {
stripTags: function() {
return this.replace(/<\/?[^>]+>/gi, '');
},
stripScripts: function() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
},
extractScripts: function() {
var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
},
evalScripts: function() {
return this.extractScripts().map(eval);
},
escapeHTML: function() {
var div = document.createElement('div');
var text = document.createTextNode(this);
div.appendChild(text);
return div.innerHTML;
},
unescapeHTML: function() {
var div = document.createElement('div');
div.innerHTML = this.stripTags();
return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
},
toQueryParams: function() {
var pairs = this.match(/^\??(.*)$/)[1].split('&');
return pairs.inject({}, function(params, pairString) {
var pair = pairString.split('=');
params[pair[0]] = pair[1];
return params;
});
},
toArray: function() {
return this.split('');
},
camelize: function() {
var oStringList = this.split('-');
if (oStringList.length == 1) return oStringList[0];
var camelizedString = this.indexOf('-') == 0
? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
: oStringList[0];
for (var i = 1, len = oStringList.length; i < len; i++) {
var s = oStringList[i];
camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
}
return camelizedString;
},
inspect: function() {
return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
}
});
String.prototype.parseQuery = String.prototype.toQueryParams;
var $break = new Object();
var $continue = new Object();
var Enumerable = {
each: function(iterator) {
var index = 0;
try {
this._each(function(value) {
try {
iterator(value, index++);
} catch (e) {
if (e != $continue) throw e;
}
});
} catch (e) {
if (e != $break) throw e;
}
},
all: function(iterator) {
var result = true;
this.each(function(value, index) {
result = result && !!(iterator || Prototype.K)(value, index);
if (!result) throw $break;
});
return result;
},
any: function(iterator) {
var result = true;
this.each(function(value, index) {
if (result = !!(iterator || Prototype.K)(value, index))
throw $break;
});
return result;
},
collect: function(iterator) {
var results = [];
this.each(function(value, index) {
results.push(iterator(value, index));
});
return results;
},
detect: function (iterator) {
var result;
this.each(function(value, index) {
if (iterator(value, index)) {
result = value;
throw $break;
}
});
return result;
},
findAll: function(iterator) {
var results = [];
this.each(function(value, index) {
if (iterator(value, index))
results.push(value);
});
return results;
},
grep: function(pattern, iterator) {
var results = [];
this.each(function(value, index) {
var stringValue = value.toString();
if (stringValue.match(pattern))
results.push((iterator || Prototype.K)(value, index));
})
return results;
},
include: function(object) {
var found = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $break;
}
});
return found;
},
inject: function(memo, iterator) {
this.each(function(value, index) {
memo = iterator(memo, value, index);
});
return memo;
},
invoke: function(method) {
var args = $A(arguments).slice(1);
return this.collect(function(value) {
return value[method].apply(value, args);
});
},
max: function(iterator) {
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
if (value >= (result || value))
result = value;
});
return result;
},
min: function(iterator) {
var result;
this.each(function(value, index) {
value = (iterator || Prototype.K)(value, index);
if (value <= (result || value))
result = value;
});
return result;
},
partition: function(iterator) {
var trues = [], falses = [];
this.each(function(value, index) {
((iterator || Prototype.K)(value, index) ?
trues : falses).push(value);
});
return [trues, falses];
},
pluck: function(property) {
var results = [];
this.each(function(value, index) {
results.push(value[property]);
});
return results;
},
reject: function(iterator) {
var results = [];
this.each(function(value, index) {
if (!iterator(value, index))
results.push(value);
});
return results;
},
sortBy: function(iterator) {
return this.collect(function(value, index) {
return {value: value, criteria: iterator(value, index)};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
},
toArray: function() {
return this.collect(Prototype.K);
},
zip: function() {
var iterator = Prototype.K, args = $A(arguments);
if (typeof args.last() == 'function')
iterator = args.pop();
var collections = [this].concat(args).map($A);
return this.map(function(value, index) {
iterator(value = collections.pluck(index));
return value;
});
},
inspect: function() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
}
Object.extend(Enumerable, {
map: Enumerable.collect,
find: Enumerable.detect,
select: Enumerable.findAll,
member: Enumerable.include,
entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
if (!iterable) return [];
if (iterable.toArray) {
return iterable.toArray();
} else {
var results = [];
for (var i = 0; i < iterable.length; i++)
results.push(iterable[i]);
return results;
}
}
Object.extend(Array.prototype, Enumerable);
Array.prototype._reverse = Array.prototype.reverse;
Object.extend(Array.prototype, {
_each: function(iterator) {
for (var i = 0; i < this.length; i++)
iterator(this[i]);
},
clear: function() {
this.length = 0;
return this;
},
first: function() {
return this[0];
},
last: function() {
return this[this.length - 1];
},
compact: function() {
return this.select(function(value) {
return value != undefined || value != null;
});
},
flatten: function() {
return this.inject([], function(array, value) {
return array.concat(value.constructor == Array ?
value.flatten() : [value]);
});
},
without: function() {
var values = $A(arguments);
return this.select(function(value) {
return !values.include(value);
});
},
indexOf: function(object) {
for (var i = 0; i < this.length; i++)
if (this[i] == object) return i;
return -1;
},
reverse: function(inline) {
return (inline !== false ? this : this.toArray())._reverse();
},
shift: function() {
var result = this[0];
for (var i = 0; i < this.length - 1; i++)
this[i] = this[i + 1];
this.length--;
return result;
},
inspect: function() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
});
var Hash = {
_each: function(iterator) {
for (key in this) {
var value = this[key];
if (typeof value == 'function') continue;
var pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
},
keys: function() {
return this.pluck('key');
},
values: function() {
return this.pluck('value');
},
merge: function(hash) {
return $H(hash).inject($H(this), function(mergedHash, pair) {
mergedHash[pair.key] = pair.value;
return mergedHash;
});
},
toQueryString: function() {
return this.map(function(pair) {
return pair.map(encodeURIComponent).join('=');
}).join('&');
},
inspect: function() {
return '#<Hash:{' + this.map(function(pair) {
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}
}
function $H(object) {
var hash = Object.extend({}, object || {});
Object.extend(hash, Enumerable);
Object.extend(hash, Hash);
return hash;
}
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
initialize: function(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
},
_each: function(iterator) {
var value = this.start;
do {
iterator(value);
value = value.succ();
} while (this.include(value));
},
include: function(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
});
var $R = function(start, end, exclusive) {
return new ObjectRange(start, end, exclusive);
}
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')},
function() {return new XMLHttpRequest()}
) || false;
},
activeRequestCount: 0
}
Ajax.Responders = {
responders: [],
_each: function(iterator) {
this.responders._each(iterator);
},
register: function(responderToAdd) {
if (!this.include(responderToAdd))
this.responders.push(responderToAdd);
},
unregister: function(responderToRemove) {
this.responders = this.responders.without(responderToRemove);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
if (responder[callback] && typeof responder[callback] == 'function') {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) {}
}
});
}
};
Object.extend(Ajax.Responders, Enumerable);
Ajax.Responders.register({
onCreate: function() {
Ajax.activeRequestCount++;
},
onComplete: function() {
Ajax.activeRequestCount--;
}
});
Ajax.Base = function() {};
Ajax.Base.prototype = {
setOptions: function(options) {
this.options = {
method: 'post',
asynchronous: true,
parameters: ''
}
Object.extend(this.options, options || {});
},
responseIsSuccess: function() {
return this.transport.status == undefined
|| this.transport.status == 0
|| (this.transport.status >= 200 && this.transport.status < 300);
},
responseIsFailure: function() {
return !this.responseIsSuccess();
}
}
Ajax.Request = Class.create();
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
initialize: function(url, options) {
this.transport = Ajax.getTransport();
this.setOptions(options);
this.request(url);
},
request: function(url) {
var parameters = this.options.parameters || '';
if (parameters.length > 0) parameters += '&_=';
try {
this.url = url;
if (this.options.method == 'get' && parameters.length > 0)
this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;
Ajax.Responders.dispatch('onCreate', this, this.transport);
this.transport.open(this.options.method, this.url,
this.options.asynchronous);
if (this.options.asynchronous) {
this.transport.onreadystatechange = this.onStateChange.bind(this);
setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
}
this.setRequestHeaders();
var body = this.options.postBody ? this.options.postBody : parameters;
this.transport.send(this.options.method == 'post' ? body : null);
} catch (e) {
this.dispatchException(e);
}
},
setRequestHeaders: function() {
var requestHeaders =
['X-Requested-With', 'XMLHttpRequest',
'X-Prototype-Version', Prototype.Version];
if (this.options.method == 'post') {
requestHeaders.push('Content-type',
'application/x-www-form-urlencoded');
/* Force "Connection: close" for Mozilla browsers to work around
* a bug where XMLHttpReqeuest sends an incorrect Content-length
* header. See Mozilla Bugzilla #246651.
*/
if (this.transport.overrideMimeType)
requestHeaders.push('Connection', 'close');
}
if (this.options.requestHeaders)
requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
for (var i = 0; i < requestHeaders.length; i += 2)
this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
},
onStateChange: function() {
var readyState = this.transport.readyState;
if (readyState != 1)
this.respondToReadyState(this.transport.readyState);
},
header: function(name) {
try {
return this.transport.getResponseHeader(name);
} catch (e) {}
},
evalJSON: function() {
try {
return eval(this.header('X-JSON'));
} catch (e) {}
},
evalResponse: function() {
try {
return eval(this.transport.responseText);
} catch (e) {
this.dispatchException(e);
}
},
respondToReadyState: function(readyState) {
var event = Ajax.Request.Events[readyState];
var transport = this.transport, json = this.evalJSON();
if (event == 'Complete') {
try {
(this.options['on' + this.transport.status]
|| this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(transport, json);
} catch (e) {
this.dispatchException(e);
}
if ((this.header('Content-type') || '').match(/^text\/javascript/i))
this.evalResponse();
}
try {
(this.options['on' + event] || Prototype.emptyFunction)(transport, json);
Ajax.Responders.dispatch('on' + event, this, transport, json);
} catch (e) {
this.dispatchException(e);
}
/* Avoid memory leak in MSIE: clean up the oncomplete event handler */
if (event == 'Complete')
this.transport.onreadystatechange = Prototype.emptyFunction;
},
dispatchException: function(exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
}
});
Ajax.Updater = Class.create();
Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
initialize: function(container, url, options) {
this.containers = {
success: container.success ? $(container.success) : $(container),
failure: container.failure ? $(container.failure) :
(container.success ? null : $(container))
}
this.transport = Ajax.getTransport();
this.setOptions(options);
var onComplete = this.options.onComplete || Prototype.emptyFunction;
this.options.onComplete = (function(transport, object) {
this.updateContent();
onComplete(transport, object);
}).bind(this);
this.request(url);
},
updateContent: function() {
var receiver = this.responseIsSuccess() ?
this.containers.success : this.containers.failure;
var response = this.transport.responseText;
if (!this.options.evalScripts)
response = response.stripScripts();
if (receiver) {
if (this.options.insertion) {
new this.options.insertion(receiver, response);
} else {
Element.update(receiver, response);
}
}
if (this.responseIsSuccess()) {
if (this.onComplete)
setTimeout(this.onComplete.bind(this), 10);
}
}
});
Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
initialize: function(container, url, options) {
this.setOptions(options);
this.onComplete = this.options.onComplete;
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
this.updater = {};
this.container = container;
this.url = url;
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(request) {
if (this.options.decay) {
this.decay = (request.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = request.responseText;
}
this.timer = setTimeout(this.onTimerEvent.bind(this),
this.decay * this.frequency * 1000);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
document.getElementsByClassName = function(className, parentElement) {
var children = ($(parentElement) || document.body).getElementsByTagName('*');
return $A(children).inject([], function(elements, child) {
if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
elements.push(child);
return elements;
});
}
/*--------------------------------------------------------------------------*/
if (!window.Element) {
var Element = new Object();
}
Object.extend(Element, {
visible: function(element) {
return $(element).style.display != 'none';
},
toggle: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);
Element[Element.visible(element) ? 'hide' : 'show'](element);
}
},
hide: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);
element.style.display = 'none';
}
},
show: function() {
for (var i = 0; i < arguments.length; i++) {
var element = $(arguments[i]);
element.style.display = '';
}
},
remove: function(element) {
element = $(element);
element.parentNode.removeChild(element);
},
update: function(element, html) {
$(element).innerHTML = html.stripScripts();
setTimeout(function() {html.evalScripts()}, 10);
},
getHeight: function(element) {
element = $(element);
return element.offsetHeight;
},
classNames: function(element) {
return new Element.ClassNames(element);
},
hasClassName: function(element, className) {
if (!(element = $(element))) return;
return Element.classNames(element).include(className);
},
addClassName: function(element, className) {
if (!(element = $(element))) return;
return Element.classNames(element).add(className);
},
removeClassName: function(element, className) {
if (!(element = $(element))) return;
return Element.classNames(element).remove(className);
},
// removes whitespace-only text node children
cleanWhitespace: function(element) {
element = $(element);
for (var i = 0; i < element.childNodes.length; i++) {
var node = element.childNodes[i];
if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
Element.remove(node);
}
},
empty: function(element) {
return $(element).innerHTML.match(/^\s*$/);
},
scrollTo: function(element) {
element = $(element);
var x = element.x ? element.x : element.offsetLeft,
y = element.y ? element.y : element.offsetTop;
window.scrollTo(x, y);
},
getStyle: function(element, style) {
element = $(element);
var value = element.style[style.camelize()];
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
var css = document.defaultView.getComputedStyle(element, null);
value = css ? css.getPropertyValue(style) : null;
} else if (element.currentStyle) {
value = element.currentStyle[style.camelize()];
}
}
if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
if (Element.getStyle(element, 'position') == 'static') value = 'auto';
return value == 'auto' ? null : value;
},
setStyle: function(element, style) {
element = $(element);
for (name in style)
element.style[name.camelize()] = style[name];
},
getDimensions: function(element) {
element = $(element);
if (Element.getStyle(element, 'display') != 'none')
return {width: element.offsetWidth, height: element.offsetHeight};
// All *Width and *Height properties give 0 on elements with display none,
// so enable the element temporarily
var els = element.style;
var originalVisibility = els.visibility;
var originalPosition = els.position;
els.visibility = 'hidden';
els.position = 'absolute';
els.display = '';
var originalWidth = element.clientWidth;
var originalHeight = element.clientHeight;
els.display = 'none';
els.position = originalPosition;
els.visibility = originalVisibility;
return {width: originalWidth, height: originalHeight};
},
makePositioned: function(element) {
element = $(element);
var pos = Element.getStyle(element, 'position');
if (pos == 'static' || !pos) {
element._madePositioned = true;
element.style.position = 'relative';
// Opera returns the offset relative to the positioning context, when an
// element is position relative but top and left have not been defined
if (window.opera) {
element.style.top = 0;
element.style.left = 0;
}
}
},
undoPositioned: function(element) {
element = $(element);
if (element._madePositioned) {
element._madePositioned = undefined;
element.style.position =
element.style.top =
element.style.left =
element.style.bottom =
element.style.right = '';
}
},
makeClipping: function(element) {
element = $(element);
if (element._overflow) return;
element._overflow = element.style.overflow;
if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
element.style.overflow = 'hidden';
},
undoClipping: function(element) {
element = $(element);
if (element._overflow) return;
element.style.overflow = element._overflow;
element._overflow = undefined;
}
});
var Toggle = new Object();
Toggle.display = Element.toggle;
/*--------------------------------------------------------------------------*/
Abstract.Insertion = function(adjacency) {
this.adjacency = adjacency;
}
Abstract.Insertion.prototype = {
initialize: function(element, content) {
this.element = $(element);
this.content = content.stripScripts();
if (this.adjacency && this.element.insertAdjacentHTML) {
try {
this.element.insertAdjacentHTML(this.adjacency, this.content);
} catch (e) {
if (this.element.tagName.toLowerCase() == 'tbody') {
this.insertContent(this.contentFromAnonymousTable());
} else {
throw e;
}
}
} else {
this.range = this.element.ownerDocument.createRange();
if (this.initializeRange) this.initializeRange();
this.insertContent([this.range.createContextualFragment(this.content)]);
}
setTimeout(function() {content.evalScripts()}, 10);
},
contentFromAnonymousTable: function() {
var div = document.createElement('div');
div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
return $A(div.childNodes[0].childNodes[0].childNodes);
}
}
var Insertion = new Object();
Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
initializeRange: function() {
this.range.setStartBefore(this.element);
},
insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment, this.element);
}).bind(this));
}
});
Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(true);
},
insertContent: function(fragments) {
fragments.reverse(false).each((function(fragment) {
this.element.insertBefore(fragment, this.element.firstChild);
}).bind(this));
}
});
Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
initializeRange: function() {
this.range.selectNodeContents(this.element);
this.range.collapse(this.element);
},
insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.appendChild(fragment);
}).bind(this));
}
});
Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
initializeRange: function() {
this.range.setStartAfter(this.element);
},
insertContent: function(fragments) {
fragments.each((function(fragment) {
this.element.parentNode.insertBefore(fragment,
this.element.nextSibling);
}).bind(this));
}
});
/*--------------------------------------------------------------------------*/
Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
initialize: function(element) {
this.element = $(element);
},
_each: function(iterator) {
this.element.className.split(/\s+/).select(function(name) {
return name.length > 0;
})._each(iterator);
},
set: function(className) {
this.element.className = className;
},
add: function(classNameToAdd) {
if (this.include(classNameToAdd)) return;
this.set(this.toArray().concat(classNameToAdd).join(' '));
},
remove: function(classNameToRemove) {
if (!this.include(classNameToRemove)) return;
this.set(this.select(function(className) {
return className != classNameToRemove;
}).join(' '));
},
toString: function() {
return this.toArray().join(' ');
}
}
Object.extend(Element.ClassNames.prototype, Enumerable);
var Field = {
clear: function() {
for (var i = 0; i < arguments.length; i++)
$(arguments[i]).value = '';
},
focus: function(element) {
$(element).focus();
},
present: function() {
for (var i = 0; i < arguments.length; i++)
if ($(arguments[i]).value == '') return false;
return true;
},
select: function(element) {
$(element).select();
},
activate: function(element) {
element = $(element);
element.focus();
if (element.select)
element.select();
}
}
/*--------------------------------------------------------------------------*/
var Form = {
serialize: function(form) {
var elements = Form.getElements($(form));
var queryComponents = new Array();
for (var i = 0; i < elements.length; i++) {
var queryComponent = Form.Element.serialize(elements[i]);
if (queryComponent)
queryComponents.push(queryComponent);
}
return queryComponents.join('&');
},
getElements: function(form) {
form = $(form);
var elements = new Array();
for (tagName in Form.Element.Serializers) {
var tagElements = form.getElementsByTagName(tagName);
for (var j = 0; j < tagElements.length; j++)
elements.push(tagElements[j]);
}
return elements;
},
getInputs: function(form, typeName, name) {
form = $(form);
var inputs = form.getElementsByTagName('input');
if (!typeName && !name)
return inputs;
var matchingInputs = new Array();
for (var i = 0; i < inputs.length; i++) {
var input = inputs[i];
if ((typeName && input.type != typeName) ||
(name && input.name != name))
continue;
matchingInputs.push(input);
}
return matchingInputs;
},
disable: function(form) {
var elements = Form.getElements(form);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.blur();
element.disabled = 'true';
}
},
enable: function(form) {
var elements = Form.getElements(form);
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
element.disabled = '';
}
},
findFirstElement: function(form) {
return Form.getElements(form).find(function(element) {
return element.type != 'hidden' && !element.disabled &&
['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
});
},
focusFirstElement: function(form) {
Field.activate(Form.findFirstElement(form));
},
reset: function(form) {
$(form).reset();
}
}
Form.Element = {
serialize: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
if (parameter) {
var key = encodeURIComponent(parameter[0]);
if (key.length == 0) return;
if (parameter[1].constructor != Array)
parameter[1] = [parameter[1]];
return parameter[1].map(function(value) {
return key + '=' + encodeURIComponent(value);
}).join('&');
}
},
getValue: function(element) {
element = $(element);
var method = element.tagName.toLowerCase();
var parameter = Form.Element.Serializers[method](element);
if (parameter)
return parameter[1];
}
}
Form.Element.Serializers = {
input: function(element) {
switch (element.type.toLowerCase()) {
case 'submit':
case 'hidden':
case 'password':
case 'text':
return Form.Element.Serializers.textarea(element);
case 'checkbox':
case 'radio':
return Form.Element.Serializers.inputSelector(element);
}
return false;
},
inputSelector: function(element) {
if (element.checked)
return [element.name, element.value];
},
textarea: function(element) {
return [element.name, element.value];
},
select: function(element) {
return Form.Element.Serializers[element.type == 'select-one' ?
'selectOne' : 'selectMany'](element);
},
selectOne: function(element) {
var value = '', opt, index = element.selectedIndex;
if (index >= 0) {
opt = element.options[index];
value = opt.value;
if (!value && !('value' in opt))
value = opt.text;
}
return [element.name, value];
},
selectMany: function(element) {
var value = new Array();
for (var i = 0; i < element.length; i++) {
var opt = element.options[i];
if (opt.selected) {
var optValue = opt.value;
if (!optValue && !('value' in opt))
optValue = opt.text;
value.push(optValue);
}
}
return [element.name, value];
}
}
/*--------------------------------------------------------------------------*/
var $F = Form.Element.getValue;
/*--------------------------------------------------------------------------*/
Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
initialize: function(element, frequency, callback) {
this.frequency = frequency;
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
this.registerCallback();
},
registerCallback: function() {
setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
onTimerEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
}
}
Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
getValue: function() {
return Form.serialize(this.element);
}
});
/*--------------------------------------------------------------------------*/
Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
initialize: function(element, callback) {
this.element = $(element);
this.callback = callback;
this.lastValue = this.getValue();
if (this.element.tagName.toLowerCase() == 'form')
this.registerFormCallbacks();
else
this.registerCallback(this.element);
},
onElementEvent: function() {
var value = this.getValue();
if (this.lastValue != value) {
this.callback(this.element, value);
this.lastValue = value;
}
},
registerFormCallbacks: function() {
var elements = Form.getElements(this.element);
for (var i = 0; i < elements.length; i++)
this.registerCallback(elements[i]);
},
registerCallback: function(element) {
if (element.type) {
switch (element.type.toLowerCase()) {
case 'checkbox':
case 'radio':
Event.observe(element, 'click', this.onElementEvent.bind(this));
break;
case 'password':
case 'text':
case 'textarea':
case 'select-one':
case 'select-multiple':
Event.observe(element, 'change', this.onElementEvent.bind(this));
break;
}
}
}
}
Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
getValue: function() {
return Form.Element.getValue(this.element);
}
});
Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
getValue: function() {
return Form.serialize(this.element);
}
});
if (!window.Event) {
var Event = new Object();
}
Object.extend(Event, {
KEY_BACKSPACE: 8,
KEY_TAB: 9,
KEY_RETURN: 13,
KEY_ESC: 27,
KEY_LEFT: 37,
KEY_UP: 38,
KEY_RIGHT: 39,
KEY_DOWN: 40,
KEY_DELETE: 46,
element: function(event) {
return event.target || event.srcElement;
},
isLeftClick: function(event) {
return (((event.which) && (event.which == 1)) ||
((event.button) && (event.button == 1)));
},
pointerX: function(event) {
return event.pageX || (event.clientX +
(document.documentElement.scrollLeft || document.body.scrollLeft));
},
pointerY: function(event) {
return event.pageY || (event.clientY +
(document.documentElement.scrollTop || document.body.scrollTop));
},
stop: function(event) {
if (event.preventDefault) {
event.preventDefault();
event.stopPropagation();
} else {
event.returnValue = false;
event.cancelBubble = true;
}
},
// find the first node with the given tagName, starting from the
// node the event was triggered on; traverses the DOM upwards
findElement: function(event, tagName) {
var element = Event.element(event);
while (element.parentNode && (!element.tagName ||
(element.tagName.toUpperCase() != tagName.toUpperCase())))
element = element.parentNode;
return element;
},
observers: false,
_observeAndCache: function(element, name, observer, useCapture) {
if (!this.observers) this.observers = [];
if (element.addEventListener) {
this.observers.push([element, name, observer, useCapture]);
element.addEventListener(name, observer, useCapture);
} else if (element.attachEvent) {
this.observers.push([element, name, observer, useCapture]);
element.attachEvent('on' + name, observer);
}
},
unloadCache: function() {
if (!Event.observers) return;
for (var i = 0; i < Event.observers.length; i++) {
Event.stopObserving.apply(this, Event.observers[i]);
Event.observers[i][0] = null;
}
Event.observers = false;
},
observe: function(elementParam, name, observer, useCapture) {
var element = $(elementParam);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.attachEvent))
name = 'keydown';
this._observeAndCache(element, name, observer, useCapture);
},
stopObserving: function(elementParam, name, observer, useCapture) {
var element = $(elementParam);
useCapture = useCapture || false;
if (name == 'keypress' &&
(navigator.appVersion.match(/Konqueror|Safari|KHTML/)
|| element.detachEvent))
name = 'keydown';
if (element.removeEventListener) {
element.removeEventListener(name, observer, useCapture);
} else if (element.detachEvent) {
element.detachEvent('on' + name, observer);
}
}
});
/* prevent memory leaks in IE */
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
// set to true if needed, warning: firefox performance problems
// NOT neeeded for page scrolling, only if draggable contained in
// scrollable elements
includeScrollOffsets: false,
// must be called before calling withinIncludingScrolloffset, every time the
// page is scrolled
prepare: function() {
this.deltaX = window.pageXOffset
|| document.documentElement.scrollLeft
|| document.body.scrollLeft
|| 0;
this.deltaY = window.pageYOffset
|| document.documentElement.scrollTop
|| document.body.scrollTop
|| 0;
},
realOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.scrollTop || 0;
valueL += element.scrollLeft || 0;
element = element.parentNode;
} while (element);
return [valueL, valueT];
},
cumulativeOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
} while (element);
return [valueL, valueT];
},
positionedOffset: function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
element = element.offsetParent;
if (element) {
p = Element.getStyle(element, 'position');
if (p == 'relative' || p == 'absolute') break;
}
} while (element);
return [valueL, valueT];
},
offsetParent: function(element) {
if (element.offsetParent) return element.offsetParent;
if (element == document.body) return element;
while ((element = element.parentNode) && element != document.body)
if (Element.getStyle(element, 'position') != 'static')
return element;
return document.body;
},
// caches x/y coordinate pair to use with overlap
within: function(element, x, y) {
if (this.includeScrollOffsets)
return this.withinIncludingScrolloffsets(element, x, y);
this.xcomp = x;
this.ycomp = y;
this.offset = this.cumulativeOffset(element);
return (y >= this.offset[1] &&
y < this.offset[1] + element.offsetHeight &&
x >= this.offset[0] &&
x < this.offset[0] + element.offsetWidth);
},
withinIncludingScrolloffsets: function(element, x, y) {
var offsetcache = this.realOffset(element);
this.xcomp = x + offsetcache[0] - this.deltaX;
this.ycomp = y + offsetcache[1] - this.deltaY;
this.offset = this.cumulativeOffset(element);
return (this.ycomp >= this.offset[1] &&
this.ycomp < this.offset[1] + element.offsetHeight &&
this.xcomp >= this.offset[0] &&
this.xcomp < this.offset[0] + element.offsetWidth);
},
// within must be called directly before
overlap: function(mode, element) {
if (!mode) return 0;
if (mode == 'vertical')
return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
element.offsetHeight;
if (mode == 'horizontal')
return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
element.offsetWidth;
},
clone: function(source, target) {
source = $(source);
target = $(target);
target.style.position = 'absolute';
var offsets = this.cumulativeOffset(source);
target.style.top = offsets[1] + 'px';
target.style.left = offsets[0] + 'px';
target.style.width = source.offsetWidth + 'px';
target.style.height = source.offsetHeight + 'px';
},
page: function(forElement) {
var valueT = 0, valueL = 0;
var element = forElement;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
// Safari fix
if (element.offsetParent==document.body)
if (Element.getStyle(element,'position')=='absolute') break;
} while (element = element.offsetParent);
element = forElement;
do {
valueT -= element.scrollTop || 0;
valueL -= element.scrollLeft || 0;
} while (element = element.parentNode);
return [valueL, valueT];
},
clone: function(source, target) {
var options = Object.extend({
setLeft: true,
setTop: true,
setWidth: true,
setHeight: true,
offsetTop: 0,
offsetLeft: 0
}, arguments[2] || {})
// find page position of source
source = $(source);
var p = Position.page(source);
// find coordinate system to use
target = $(target);
var delta = [0, 0];
var parent = null;
// delta [0,0] will do fine with position: fixed elements,
// position:absolute needs offsetParent deltas
if (Element.getStyle(target,'position') == 'absolute') {
parent = Position.offsetParent(target);
delta = Position.page(parent);
}
// correct by body offsets (fixes Safari)
if (parent == document.body) {
delta[0] -= document.body.offsetLeft;
delta[1] -= document.body.offsetTop;
}
// set position
if(options.setLeft) target.style.left = (p[0] - delta[0] + options.offsetLeft) + 'px';
if(options.setTop) target.style.top = (p[1] - delta[1] + options.offsetTop) + 'px';
if(options.setWidth) target.style.width = source.offsetWidth + 'px';
if(options.setHeight) target.style.height = source.offsetHeight + 'px';
},
absolutize: function(element) {
element = $(element);
if (element.style.position == 'absolute') return;
Position.prepare();
var offsets = Position.positionedOffset(element);
var top = offsets[1];
var left = offsets[0];
var width = element.clientWidth;
var height = element.clientHeight;
element._originalLeft = left - parseFloat(element.style.left || 0);
element._originalTop = top - parseFloat(element.style.top || 0);
element._originalWidth = element.style.width;
element._originalHeight = element.style.height;
element.style.position = 'absolute';
element.style.top = top + 'px';;
element.style.left = left + 'px';;
element.style.width = width + 'px';;
element.style.height = height + 'px';;
},
relativize: function(element) {
element = $(element);
if (element.style.position == 'relative') return;
Position.prepare();
element.style.position = 'relative';
var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
element.style.top = top + 'px';
element.style.left = left + 'px';
element.style.height = element._originalHeight;
element.style.width = element._originalWidth;
}
}
// Safari returns margins on body which is incorrect if the child is absolutely
// positioned. For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
Position.cumulativeOffset = function(element) {
var valueT = 0, valueL = 0;
do {
valueT += element.offsetTop || 0;
valueL += element.offsetLeft || 0;
if (element.offsetParent == document.body)
if (Element.getStyle(element, 'position') == 'absolute') break;
element = element.offsetParent;
} while (element);
return [valueL, valueT];
}
}
/**
*
* Copyright 2005 Sabre Airline Solutions
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific language governing permissions
* and limitations under the License.
**/
var Rico = new Object();
Rico.Corner = {
round: function(e, options) {
var e = $(e);
this._setOptions(options);
var color = this.options.color;
if ( this.options.color == "fromElement" )
color = this._background(e);
var bgColor = this.options.bgColor;
if ( this.options.bgColor == "fromParent" )
bgColor = this._background(e.offsetParent);
this._roundCornersImpl(e, color, bgColor);
},
/** This is a helper function to change the background
* color of <div> that has had Rico rounded corners added.
*
* It seems we cannot just set the background color for the
* outer <div> so each <span> element used to create the
* corners must have its background color set individually.
*
* @param {DOM} theDiv - A child of the outer <div> that was
* supplied to the `round` method.
*
* @param {str} newColor - The new background color to use.
*/
changeColor: function(theDiv, newColor) {
theDiv.style.backgroundColor = newColor;
var spanElements = theDiv.parentNode.getElementsByTagName("span");
for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
spanElements[currIdx].style.backgroundColor = newColor;
}
},
/** This is a helper function to change the background
* opacity of <div> that has had Rico rounded corners added.
*
* See changeColor (above) for algorithm explanation
*
* @param {DOM} theDiv A child of the outer <div> that was
* supplied to the `round` method.
*
* @param {int} newOpacity The new opacity to use (0-1).
*/
changeOpacity: function(theDiv, newOpacity) {
var mozillaOpacity = newOpacity;
var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';
theDiv.style.opacity = mozillaOpacity;
theDiv.style.filter = ieOpacity;
var spanElements = theDiv.parentNode.getElementsByTagName("span");
for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {
spanElements[currIdx].style.opacity = mozillaOpacity;
spanElements[currIdx].style.filter = ieOpacity;
}
},
/** this function takes care of redoing the rico cornering
*
* you can't just call updateRicoCorners() again and pass it a
* new options string. you have to first remove the divs that
* rico puts on top and below the content div.
*
* @param {DOM} theDiv - A child of the outer <div> that was
* supplied to the `round` method.
*
* @param {Array} options - list of options
*/
reRound: function(theDiv, options) {
var topRico = theDiv.parentNode.childNodes[0];
//theDiv would be theDiv.parentNode.childNodes[1]
var bottomRico = theDiv.parentNode.childNodes[2];
theDiv.parentNode.removeChild(topRico);
theDiv.parentNode.removeChild(bottomRico);
this.round(theDiv.parentNode, options);
},
_roundCornersImpl: function(e, color, bgColor) {
if(this.options.border)
this._renderBorder(e,bgColor);
if(this._isTopRounded())
this._roundTopCorners(e,color,bgColor);
if(this._isBottomRounded())
this._roundBottomCorners(e,color,bgColor);
},
_renderBorder: function(el,bgColor) {
var borderValue = "1px solid " + this._borderColor(bgColor);
var borderL = "border-left: " + borderValue;
var borderR = "border-right: " + borderValue;
var style = "style='" + borderL + ";" + borderR + "'";
el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
},
_roundTopCorners: function(el, color, bgColor) {
var corner = this._createCorner(bgColor);
for(var i=0 ; i < this.options.numSlices ; i++ )
corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
el.style.paddingTop = 0;
el.insertBefore(corner,el.firstChild);
},
_roundBottomCorners: function(el, color, bgColor) {
var corner = this._createCorner(bgColor);
for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
el.style.paddingBottom = 0;
el.appendChild(corner);
},
_createCorner: function(bgColor) {
var corner = document.createElement("div");
corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
return corner;
},
_createCornerSlice: function(color,bgColor, n, position) {
var slice = document.createElement("span");
var inStyle = slice.style;
inStyle.backgroundColor = color;
inStyle.display = "block";
inStyle.height = "1px";
inStyle.overflow = "hidden";
inStyle.fontSize = "1px";
var borderColor = this._borderColor(color,bgColor);
if ( this.options.border && n == 0 ) {
inStyle.borderTopStyle = "solid";
inStyle.borderTopWidth = "1px";
inStyle.borderLeftWidth = "0px";
inStyle.borderRightWidth = "0px";
inStyle.borderBottomWidth = "0px";
inStyle.height = "0px"; // assumes css compliant box model
inStyle.borderColor = borderColor;
}
else if(borderColor) {
inStyle.borderColor = borderColor;
inStyle.borderStyle = "solid";
inStyle.borderWidth = "0px 1px";
}
if ( !this.options.compact && (n == (this.options.numSlices-1)) )
inStyle.height = "2px";
this._setMargin(slice, n, position);
this._setBorder(slice, n, position);
return slice;
},
_setOptions: function(options) {
this.options = {
corners : "all",
color : "fromElement",
bgColor : "fromParent",
blend : true,
border : false,
compact : false
}
Object.extend(this.options, options || {});
this.options.numSlices = this.options.compact ? 2 : 4;
if ( this._isTransparent() )
this.options.blend = false;
},
_whichSideTop: function() {
if ( this._hasString(this.options.corners, "all", "top") )
return "";
if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
return "";
if (this.options.corners.indexOf("tl") >= 0)
return "left";
else if (this.options.corners.indexOf("tr") >= 0)
return "right";
return "";
},
_whichSideBottom: function() {
if ( this._hasString(this.options.corners, "all", "bottom") )
return "";
if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
return "";
if(this.options.corners.indexOf("bl") >=0)
return "left";
else if(this.options.corners.indexOf("br")>=0)
return "right";
return "";
},
_borderColor : function(color,bgColor) {
if ( color == "transparent" )
return bgColor;
else if ( this.options.border )
return this.options.border;
else if ( this.options.blend )
return this._blend( bgColor, color );
else
return "";
},
_setMargin: function(el, n, corners) {
var marginSize = this._marginSize(n);
var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
if ( whichSide == "left" ) {
el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
}
else if ( whichSide == "right" ) {
el.style.marginRight = marginSize + "px"; el.style.marginLeft = "0px";
}
else {
el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
}
},
_setBorder: function(el,n,corners) {
var borderSize = this._borderSize(n);
var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
if ( whichSide == "left" ) {
el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
}
else if ( whichSide == "right" ) {
el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth = "0px";
}
else {
el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
}
if (this.options.border != false)
el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
},
_marginSize: function(n) {
if ( this._isTransparent() )
return 0;
var marginSizes = [ 5, 3, 2, 1 ];
var blendedMarginSizes = [ 3, 2, 1, 0 ];
var compactMarginSizes = [ 2, 1 ];
var smBlendedMarginSizes = [ 1, 0 ];
if ( this.options.compact && this.options.blend )
return smBlendedMarginSizes[n];
else if ( this.options.compact )
return compactMarginSizes[n];
else if ( this.options.blend )
return blendedMarginSizes[n];
else
return marginSizes[n];
},
_borderSize: function(n) {
var transparentBorderSizes = [ 5, 3, 2, 1 ];
var blendedBorderSizes = [ 2, 1, 1, 1 ];
var compactBorderSizes = [ 1, 0 ];
var actualBorderSizes = [ 0, 2, 0, 0 ];
if ( this.options.compact && (this.options.blend || this._isTransparent()) )
return 1;
else if ( this.options.compact )
return compactBorderSizes[n];
else if ( this.options.blend )
return blendedBorderSizes[n];
else if ( this.options.border )
return actualBorderSizes[n];
else if ( this._isTransparent() )
return transparentBorderSizes[n];
return 0;
},
_hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
_blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
_background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
_isTransparent: function() { return this.options.color == "transparent"; },
_isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
_isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
_hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
}
Rico.Color = Class.create();
Rico.Color.prototype = {
initialize: function(red, green, blue) {
this.rgb = { r: red, g : green, b : blue };
},
setRed: function(r) {
this.rgb.r = r;
},
setGreen: function(g) {
this.rgb.g = g;
},
setBlue: function(b) {
this.rgb.b = b;
},
setHue: function(h) {
// get an HSB model, and set the new hue...
var hsb = this.asHSB();
hsb.h = h;
// convert back to RGB...
this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
},
setSaturation: function(s) {
// get an HSB model, and set the new hue...
var hsb = this.asHSB();
hsb.s = s;
// convert back to RGB and set values...
this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
},
setBrightness: function(b) {
// get an HSB model, and set the new hue...
var hsb = this.asHSB();
hsb.b = b;
// convert back to RGB and set values...
this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
},
darken: function(percent) {
var hsb = this.asHSB();
this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
},
brighten: function(percent) {
var hsb = this.asHSB();
this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
},
blend: function(other) {
this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
},
isBright: function() {
var hsb = this.asHSB();
return this.asHSB().b > 0.5;
},
isDark: function() {
return ! this.isBright();
},
asRGB: function() {
return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
},
asHex: function() {
return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
},
asHSB: function() {
return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
},
toString: function() {
return this.asHex();
}
};
Rico.Color.createFromHex = function(hexCode) {
if(hexCode.length==4) {
var shortHexCode = hexCode;
var hexCode = '#';
for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) +
shortHexCode.charAt(i));
}
if ( hexCode.indexOf('#') == 0 )
hexCode = hexCode.substring(1);
var red = hexCode.substring(0,2);
var green = hexCode.substring(2,4);
var blue = hexCode.substring(4,6);
return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
}
/**
* Factory method for creating a color from the background of
* an HTML element.
*/
Rico.Color.createColorFromBackground = function(elem) {
var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");
if ( actualColor == "transparent" && elem.parentNode )
return Rico.Color.createColorFromBackground(elem.parentNode);
if ( actualColor == null )
return new Rico.Color(255,255,255);
if ( actualColor.indexOf("rgb(") == 0 ) {
var colors = actualColor.substring(4, actualColor.length - 1 );
var colorArray = colors.split(",");
return new Rico.Color( parseInt( colorArray[0] ),
parseInt( colorArray[1] ),
parseInt( colorArray[2] ) );
}
else if ( actualColor.indexOf("#") == 0 ) {
return Rico.Color.createFromHex(actualColor);
}
else
return new Rico.Color(255,255,255);
}
Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {
var red = 0;
var green = 0;
var blue = 0;
if (saturation == 0) {
red = parseInt(brightness * 255.0 + 0.5);
green = red;
blue = red;
}
else {
var h = (hue - Math.floor(hue)) * 6.0;
var f = h - Math.floor(h);
var p = brightness * (1.0 - saturation);
var q = brightness * (1.0 - saturation * f);
var t = brightness * (1.0 - (saturation * (1.0 - f)));
switch (parseInt(h)) {
case 0:
red = (brightness * 255.0 + 0.5);
green = (t * 255.0 + 0.5);
blue = (p * 255.0 + 0.5);
break;
case 1:
red = (q * 255.0 + 0.5);
green = (brightness * 255.0 + 0.5);
blue = (p * 255.0 + 0.5);
break;
case 2:
red = (p * 255.0 + 0.5);
green = (brightness * 255.0 + 0.5);
blue = (t * 255.0 + 0.5);
break;
case 3:
red = (p * 255.0 + 0.5);
green = (q * 255.0 + 0.5);
blue = (brightness * 255.0 + 0.5);
break;
case 4:
red = (t * 255.0 + 0.5);
green = (p * 255.0 + 0.5);
blue = (brightness * 255.0 + 0.5);
break;
case 5:
red = (brightness * 255.0 + 0.5);
green = (p * 255.0 + 0.5);
blue = (q * 255.0 + 0.5);
break;
}
}
return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
}
Rico.Color.RGBtoHSB = function(r, g, b) {
var hue;
var saturation;
var brightness;
var cmax = (r > g) ? r : g;
if (b > cmax)
cmax = b;
var cmin = (r < g) ? r : g;
if (b < cmin)
cmin = b;
brightness = cmax / 255.0;
if (cmax != 0)
saturation = (cmax - cmin)/cmax;
else
saturation = 0;
if (saturation == 0)
hue = 0;
else {
var redc = (cmax - r)/(cmax - cmin);
var greenc = (cmax - g)/(cmax - cmin);
var bluec = (cmax - b)/(cmax - cmin);
if (r == cmax)
hue = bluec - greenc;
else if (g == cmax)
hue = 2.0 + redc - bluec;
else
hue = 4.0 + greenc - redc;
hue = hue / 6.0;
if (hue < 0)
hue = hue + 1.0;
}
return { h : hue, s : saturation, b : brightness };
}
/**
* @class
*/
OpenLayers.Util = new Object();
/**
* @class This class represents a screen coordinate, in x and y coordinates
*/
OpenLayers.Pixel = Class.create();
OpenLayers.Pixel.prototype = {
/** @type float */
x: 0.0,
/** @type float */
y: 0.0,
/**
* @constructor
*
* @param {float} x
* @param {float} y
*/
initialize: function(x, y) {
this.x = x;
this.y = y;
},
/**
* @return string representation of Pixel. ex: "x=200.4,y=242.2"
* @type str
*/
toString:function() {
return ("x=" + this.x + ",y=" + this.y);
},
/**
* @type OpenLayers.Pixel
*/
copyOf:function() {
return new OpenLayers.Pixel(this.x, this.y);
},
/**
* @param {OpenLayers.Pixel} px
*
* @return whether or not the point passed in as parameter is equal to this
* @type bool
*/
equals:function(px) {
return ((this.x == px.x) && (this.y == px.y));
},
/**
* @param {int} x
* @param {int} y
*
* @return a new Pixel with this pixel's x&y augmented by the
* values passed in.
* @type OpenLayers.Pixel
*/
add:function(x, y) {
return new OpenLayers.Pixel(this.x + x, this.y + y);
},
/**
* @param {OpenLayers.Pixel} px
*
* @return a new Pixel with this pixel's x&y augmented by the
* x&y values of the pixel passed in.
* @type OpenLayers.Pixel
*/
offset:function(px) {
return this.add(px.x, px.y);
},
/** @final @type str */
CLASS_NAME: "OpenLayers.Pixel"
};
/**
* @class This class represents a width and height pair
*/
OpenLayers.Size = Class.create();
OpenLayers.Size.prototype = {
/** @type float */
w: 0.0,
/** @type float */
h: 0.0,
/**
* @constructor
*
* @param {float} w
* @param {float} h
*/
initialize: function(w, h) {
this.w = w;
this.h = h;
},
/**
* @return String representation of OpenLayers.Size object.
* (ex. <i>"w=55,h=66"</i>)
* @type String
*/
toString:function() {
return ("w=" + this.w + ",h=" + this.h);
},
/**
* @return New OpenLayers.Size object with the same w and h values
* @type OpenLayers.Size
*/
copyOf:function() {
return new OpenLayers.Size(this.w, this.h);
},
/**
* @param {OpenLayers.Size} sz
* @returns Boolean value indicating whether the passed-in OpenLayers.Size
* object has the same w and h components as this
*
* @type bool
*/
equals:function(sz) {
return ((this.w == sz.w) && (this.h == sz.h));
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Size"
};
/**
* @class This class represents a longitude and latitude pair
*/
OpenLayers.LonLat = Class.create();
OpenLayers.LonLat.prototype = {
/** @type float */
lon: 0.0,
/** @type float */
lat: 0.0,
/**
* @constructor
*
* @param {float} lon
* @param {float} lat
*/
initialize: function(lon, lat) {
this.lon = lon;
this.lat = lat;
},
/**
* @return String representation of OpenLayers.LonLat object.
* (ex. <i>"lon=5,lat=42"</i>)
* @type String
*/
toString:function() {
return ("lon=" + this.lon + ",lat=" + this.lat);
},
/**
* @return Shortened String representation of OpenLayers.LonLat object.
* (ex. <i>"5, 42"</i>)
* @type String
*/
toShortString:function() {
return (this.lon + ", " + this.lat);
},
/**
* @return New OpenLayers.LonLat object with the same lon and lat values
* @type OpenLayers.LonLat
*/
copyOf:function() {
return new OpenLayers.LonLat(this.lon, this.lat);
},
/**
* @param {float} lon
* @param {float} lat
*
* @return A new OpenLayers.LonLat object with the lon and lat passed-in
* added to this's.
* @type OpenLayers.Pixel
*/
add:function(lon, lat) {
return new OpenLayers.LonLat(this.lon + lon, this.lat + lat);
},
/**
* @param {OpenLayers.LonLat} ll
* @returns Boolean value indicating whether the passed-in OpenLayers.LonLat
* object has the same lon and lat components as this
*
* @type bool
*/
equals:function(ll) {
return ((this.lon == ll.lon) && (this.lat == ll.lat));
},
/** @final @type String */
CLASS_NAME: "OpenLayers.LonLat"
};
/** Alternative constructor that builds a new OpenLayers.LonLat from a
* parameter string
*
* @constructor
*
* @param {String} str Comma-separated Lon,Lat coordinate string.
* (ex. <i>"5,40"</i>)
*
* @returns New OpenLayers.LonLat object built from the passed-in String.
* @type OpenLayers.LonLat
*/
OpenLayers.LonLat.fromString = function(str) {
var pair = str.split(",");
return new OpenLayers.LonLat(parseFloat(pair[0]),
parseFloat(pair[1]));
};
/**
* @class This class represents a bounding box.
* Data stored as left, bottom, right, top floats
*/
OpenLayers.Bounds = Class.create();
OpenLayers.Bounds.prototype = {
/** @type float */
left: 0.0,
/** @type float */
bottom: 0.0,
/** @type float */
right: 0.0,
/** @type float */
top: 0.0,
/**
* @constructor
*
* @param {float} left
* @param {float} bottom
* @param {float} right
* @param {float} top
*
*/
initialize: function(left, bottom, right, top) {
this.left = left;
this.bottom = bottom;
this.right = right;
this.top = top;
},
/**
* @returns A fresh copy of the bounds
* @type OpenLayers.Bounds
*/
copyOf:function() {
return new OpenLayers.Bounds(this.left, this.bottom,
this.right, this.top);
},
/**
* @param {OpenLayers.Bounds} bounds
* @returns Boolean value indicating whether the passed-in OpenLayers.Bounds
* object has the same left, right, top, bottom components as this
*
* @type bool
*/
equals:function(bounds) {
return ((this.left == bounds.left) && (this.right == bounds.right) &&
(this.top == bounds.top) && (this.bottom == bounds.bottom));
},
/**
* @return String representation of OpenLayers.Bounds object.
* (ex.<i>"left-bottom=(5,42) right-top=(10,45)"</i>)
* @type String
*/
toString:function(){
return ( "left-bottom=(" + this.left + "," + this.bottom + ")"
+ " right-top=(" + this.right + "," + this.top + ")" );
},
/**
* @return Simple String representation of OpenLayers.Bounds object.
* (ex. <i>"5,42,10,45"</i>)
* @type String
*/
toBBOX:function() {
return (this.left + "," + this.bottom + ","
+ this.right + "," + this.top);
},
/**
* @returns The width of the bounds
* @type float
*/
getWidth:function() {
return (this.right - this.left);
},
/**
* @returns The height of the bounds
* @type float
*/
getHeight:function() {
return (this.top - this.bottom);
},
/**
* @returns An OpenLayers.Size which represents the size of the box
* @type OpenLayers.Size
*/
getSize:function() {
return new OpenLayers.Size(this.getWidth(), this.getHeight());
},
/**
* @returns An OpenLayers.Pixel which represents the center of the bounds
* @type OpenLayers.Pixel
*/
getCenterPixel:function() {
return new OpenLayers.Pixel(this.left + (this.getWidth() / 2),
this.bottom + (this.getHeight() / 2));
},
/**
* @returns An OpenLayers.LonLat which represents the center of the bounds
* @type OpenLayers.LonLat
*/
getCenterLonLat:function() {
return new OpenLayers.LonLat(this.left + (this.getWidth() / 2),
this.bottom + (this.getHeight() / 2));
},
/**
* @param {float} x
* @param {float} y
*
* @returns A new OpenLayers.Bounds whose coordinates are the same as this,
* but shifted by the passed-in x and y values
* @type OpenLayers.Bounds
*/
add:function(x, y){
return new OpenLayers.Box(this.left + x, this.bottom + y,
this.right + x, this.top + y);
},
/**
* @param {float} x
* @param {float} y
* @param {Boolean} inclusive Whether or not to include the border.
* Default is true
*
* @return Whether or not the passed-in coordinates are within this bounds
* @type Boolean
*/
contains:function(x, y, inclusive) {
//set default
if (inclusive == null) {
inclusive = true;
}
var contains = false;
if (inclusive) {
contains = ((x >= this.left) && (x <= this.right) &&
(y >= this.bottom) && (y <= this.top));
} else {
contains = ((x > this.left) && (x < this.right) &&
(y > this.bottom) && (y < this.top));
}
return contains;
},
/**
* @param {OpenLayers.Bounds} bounds
* @param {Boolean} partial If true, only part of passed-in
* OpenLayers.Bounds needs be within this bounds.
* If false, the entire passed-in bounds must be
* within. Default is false
* @param {Boolean} inclusive Whether or not to include the border.
* Default is true
*
* @return Whether or not the passed-in OpenLayers.Bounds object is
* contained within this bounds.
* @type Boolean
*/
containsBounds:function(bounds, partial, inclusive) {
//set defaults
if (partial == null) {
partial = false;
}
if (inclusive == null) {
inclusive = true;
}
var inLeft;
var inTop;
var inRight;
var inBottom;
if (inclusive) {
inLeft = (bounds.left >= this.left) && (bounds.left <= this.right);
inTop = (bounds.top >= this.bottom) && (bounds.top <= this.top);
inRight= (bounds.right >= this.left) && (bounds.right <= this.right);
inBottom = (bounds.bottom >= this.bottom) && (bounds.bottom <= this.top);
} else {
inLeft = (bounds.left > this.left) && (bounds.left < this.right);
inTop = (bounds.top > this.bottom) && (bounds.top < this.top);
inRight= (bounds.right > this.left) && (bounds.right < this.right);
inBottom = (bounds.bottom > this.bottom) && (bounds.bottom < this.top);
}
return (partial) ? (inTop || inBottom) && (inLeft || inRight )
: (inTop && inLeft && inBottom && inRight);
},
/**
* @param {OpenLayers.LonLat} lonlat
*
* @returns The quadrant ("br" "tr" "tl" "bl") of the bounds in which
* the coordinate lies.
* @type String
*/
determineQuadrant: function(lonlat) {
var quadrant = "";
var center = this.getCenterLonLat();
quadrant += (lonlat.lat < center.lat) ? "b" : "t";
quadrant += (lonlat.lon < center.lon) ? "l" : "r";
return quadrant;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Bounds"
};
/** Alternative constructor that builds a new OpenLayers.Bounds from a
* parameter string
*
* @constructor
*
* @param {String} str Comma-separated bounds string. (ex. <i>"5,42,10,45"</i>)
*
* @returns New OpenLayers.Bounds object built from the passed-in String.
* @type OpenLayers.Bounds
*/
OpenLayers.Bounds.fromString = function(str) {
var bounds = str.split(",");
return new OpenLayers.Bounds(parseFloat(bounds[0]),
parseFloat(bounds[1]),
parseFloat(bounds[2]),
parseFloat(bounds[3]));
};
/**
* @param {String} quadrant
*
* @returns The opposing quadrant ("br" "tr" "tl" "bl"). For Example, if
* you pass in "bl" it returns "tr", if you pass in "br" it
* returns "tl", etc.
* @type String
*/
OpenLayers.Bounds.oppositeQuadrant = function(quadrant) {
var opp = "";
opp += (quadrant.charAt(0) == 't') ? 'b' : 't';
opp += (quadrant.charAt(1) == 'l') ? 'r' : 'l';
return opp;
};
// Some other helpful things
/**
* @param {String} sStart
*
* @returns Whether or not this string starts with the string passed in.
* @type Boolean
*/
String.prototype.startsWith = function(sStart){
return (this.substr(0,sStart.length) == sStart);
};
/**
* @returns A trimmed version of the string - all leading and
* trailing spaces removed
* @type String
*/
String.prototype.trim = function() {
var b = 0;
while(this.substr(b,1) == " ") {
b++;
}
var e = this.length - 1;
while(this.substr(e,1) == " ") {
e--;
}
return this.substring(b, e+1);
};
/** Remove an object from an array. Iterates through the array
* to find the item, then removes it.
*
* @param {Object} item
*
* @returns A reference to the array
* @type Array
*/
Array.prototype.remove = function(item) {
for(var i=0; i < this.length; i++) {
if(this[i] == item) {
this.splice(i,1);
//break;more than once??
}
}
return this;
}
/**
* @returns A fresh copy of the array
* @type Array
*/
Array.prototype.copyOf = function() {
var copy = new Array();
for (var i = 0; i < this.length; i++) {
copy[i] = this[i];
}
return copy;
};
/**
* @param {Object} item
*/
Array.prototype.prepend = function(item) {
this.splice(0, 0, item);
};
/**
* @param {Object} item
*/
Array.prototype.append = function(item){
this[this.length] = item;
};
/**
*/
Array.prototype.clear = function() {
this.length = 0;
};
/**
* @param {Object} element
*
* @returns The first index of the element in the array if found. Else returns -1
* @type int
*/
Array.prototype.indexOf = function(element) {
var index = -1;
for(var i=0; i < this.length; i++) {
if (this[i] == element) {
index = i;
break;
}
}
return index;
}
/**
* @param {String} id
* @param {OpenLayers.Pixel} px
* @param {OpenLayers.Size} sz
* @param {String} position
* @param {String} border
* @param {String} overflow
*/
OpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position,
border, overflow) {
if (id) {
element.id = id;
}
if (px) {
element.style.left = px.x;
element.style.top = px.y;
}
if (sz) {
element.style.width = sz.w + "px";
element.style.height = sz.h + "px";
}
if (position) {
element.style.position = position;
}
if (border) {
element.style.border = border;
}
if (overflow) {
element.style.overflow = overflow;
}
};
/**
* zIndex is NOT set
*
* @param {String} id
* @param {OpenLayers.Pixel} px
* @param {OpenLayers.Size} sz
* @param {String} imgURL
* @param {String} position
* @param {String} border
* @param {String} overflow
*
* @returns A DOM Div created with the specified attributes.
* @type DOMElement
*/
OpenLayers.Util.createDiv = function(id, px, sz, imgURL, position,
border, overflow) {
var dom = document.createElement('div');
//set specific properties
dom.style.padding = "0";
dom.style.margin = "0";
dom.style.cursor = "inherit";
if (imgURL) {
dom.style.backgroundImage = 'url(' + imgURL + ')';
}
//set generic properties
if (!id) {
id = "OpenLayersDiv" + (Math.random() * 10000 % 10000);
}
if (!position) {
position = "absolute";
}
OpenLayers.Util.modifyDOMElement(dom, id, px, sz,
position, border, overflow);
return dom;
};
/**
* @param {String} id
* @param {OpenLayers.Pixel} px
* @param {OpenLayers.Size} sz
* @param {String} imgURL
* @param {String} position
* @param {String} border
*
* @returns A DOM Image created with the specified attributes.
* @type DOMElement
*/
OpenLayers.Util.createImage = function(id, px, sz, imgURL, position, border) {
image = document.createElement("img");
//set special properties
image.style.alt = id;
image.style.cursor = "inherit";
image.galleryImg = "no";
if (imgURL) {
image.src = imgURL;
}
//set generic properties
if (!id) {
id = "OpenLayersDiv" + (Math.random() * 10000 % 10000);
}
if (!position) {
position = "relative";
}
OpenLayers.Util.modifyDOMElement(image, id, px, sz, position, border);
return image;
};
OpenLayers.Util.alphaHack = function() {
var arVersion = navigator.appVersion.split("MSIE");
var version = parseFloat(arVersion[1]);
return ( (document.body.filters) &&
(version >= 5.5) && (version < 7) );
}
/**
* @param {DOMElement} div Div containing Alpha-adjusted Image
* @param {String} id
* @param {OpenLayers.Pixel} px
* @param {OpenLayers.Size} sz
* @param {String} imgURL
* @param {String} position
* @param {String} border
* @param {String} sizing 'crop', 'scale', or 'image'. Default is "scale"
*/
OpenLayers.Util.modifyAlphaImageDiv = function(div, id, px, sz, imgURL,
position, border, sizing) {
OpenLayers.Util.modifyDOMElement(div, id, px, sz);
var img = div.childNodes[0];
if (imgURL) {
img.src = imgURL;
}
OpenLayers.Util.modifyDOMElement(img, div.id + "_innerImage", null, sz,
"relative", border);
if (OpenLayers.Util.alphaHack()) {
div.style.display = "inline-block";
if (sizing == null) {
sizing = "scale";
}
div.style.filter = "progid:DXImageTransform.Microsoft" +
".AlphaImageLoader(src='" + img.src + "', " +
"sizingMethod='" + sizing + "')";
img.style.filter = "progid:DXImageTransform.Microsoft" +
".Alpha(opacity=0)";
}
};
/**
* @param {String} id
* @param {OpenLayers.Pixel} px
* @param {OpenLayers.Size} sz
* @param {String} imgURL
* @param {String} position
* @param {String} border
* @param {String} sizing 'crop', 'scale', or 'image'. Default is "scale"
*
* @returns A DOM Div created with a DOM Image inside it. If the hack is
* needed for transparency in IE, it is added.
* @type DOMElement
*/
OpenLayers.Util.createAlphaImageDiv = function(id, px, sz, imgURL,
position, border, sizing) {
var div = OpenLayers.Util.createDiv();
var img = OpenLayers.Util.createImage();
div.appendChild(img);
OpenLayers.Util.modifyAlphaImageDiv(div, id, px, sz, imgURL,
position, border, sizing);
return div;
};
/**
* @param {Object} params
*
* @returns a concatenation of the properties of an object in
* http parameter notation.
* (ex. <i>"key1=value1&key2=value2&key3=value3"</i>)
* @type String
*/
OpenLayers.Util.getParameterString = function(params) {
paramsArray = new Array();
for (var key in params) {
var value = params[key];
//skip functions
if (typeof value == 'function') continue;
paramsArray.push(key + "=" + value);
}
return paramsArray.join("&");
};
/**
* @returns The fully formatted image location string
* @type String
*/
OpenLayers.Util.getImagesLocation = function() {
return OpenLayers._getScriptLocation() + "img/";
};
/** Takes a hash and copies any keys that don't exist from
* another hash, by analogy with Object.extend() from
* Prototype.js.
*
* @param {Object} to
* @param {Object} from
*
* @type Object
*/
OpenLayers.Util.applyDefaults = function (to, from) {
for (var key in from) {
if (to[key] == null) {
to[key] = from[key];
}
}
return to;
};
/** These could/should be made namespace aware?
*
* @param {} p
* @param {str} tagName
*
* @return {Array}
*/
OpenLayers.Util.getNodes=function(p, tagName) {
var nodes = Try.these(
function () {
return OpenLayers.Util._getNodes(p.documentElement.childNodes,
tagName);
},
function () {
return OpenLayers.Util._getNodes(p.childNodes, tagName);
}
);
return nodes;
};
/**
* @param {Array} nodes
* @param {str} tagName
*
* @return {Array}
*/
OpenLayers.Util._getNodes=function(nodes, tagName) {
var retArray = new Array();
for (var i=0;i<nodes.length;i++) {
if (nodes[i].nodeName==tagName) {
retArray.push(nodes[i]);
}
}
return retArray;
};
/**
* @param {} parent
* @param {str} item
* @param {int} index
*
* @return {str}
*/
OpenLayers.Util.getTagText = function (parent, item, index) {
var result = OpenLayers.Util.getNodes(parent, item);
if (result && (result.length > 0))
{
if (!index) {
index=0;
}
if (result[index].childNodes.length > 1) {
return result.childNodes[1].nodeValue;
}
else if (result[index].childNodes.length == 1) {
return result[index].firstChild.nodeValue;
}
} else {
return "";
}
};
/**
* @param {Event} evt
* @param {HTMLDivElement} div
*
* @return {boolean}
*/
OpenLayers.Util.mouseLeft = function (evt, div) {
// start with the element to which the mouse has moved
var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement;
// walk up the DOM tree.
while (target != div && target != null) {
target = target.parentNode;
}
// if the target we stop at isn't the div, then we've left the div.
return (target != div);
};
OpenLayers.ProxyHost = "/viewer/Crossbrowser/blindproxy.py?url=";
//OpenLayers.ProxyHost = "examples/proxy.cgi?url=";
/**
* Ajax reader for OpenLayers
*
* Pay close attention to how this works:
*
*@uri url to do remote XML http get
*@param 'get' format params (x=y&a=b...)
*@who object which is providing a specific callbacks for this request
*@complete the name of the function which must be defined in the callers.handler[] array
*@failure the name of the function which must be defined in the callers.handler[] array
*
* example usage from a caller:
*
* this.handlers["caps"] = function(request){..}
* OpenLayers.loadURL(url,params,this,"caps");
*
* Notice the above example does not provide an error handler; a default empty
* handler is provided which merely logs the error if a failure handler is not supplied
*
*/
/**
* @param {} request
*/
OpenLayers.nullHandler = function(request) {
// ol.Log.warn("Unhandled request return " + request.statusText);
};
/** Background load a document
*
* @param {String} uri URI of source doc
* @param {String} params Params on get (doesnt seem to work)
* @param {Object} caller object which gets callbacks
* @param {Function} onComplete callback for success
* @param {Function} onFailure callback for failure
*
* Both callbacks optional (though silly)
*/
OpenLayers.loadURL = function(uri, params, caller,
onComplete, onFailure) {
if (OpenLayers.ProxyHost && uri.startsWith("http")) {
uri = OpenLayers.ProxyHost + escape(uri);
if (!params) {
params="";
}
params += "&cachehack=" + new Date().getTime();
}
// ol.Log.debug("loadURL [" + uri + "]");
var successx;
var failurex;
var bind1 = null;
var bind2 = null;
if (onComplete) {
successx = caller.handlers[onComplete];
bind1 = caller;
} else {
successx = OpenLayers.nullHandler;
}
if (onFailure) {
failurex = caller.handlers[onFailure];
bind2=caller;
} else {
failurex = OpenLayers.nullHandler;
}
// from prototype.js
new Ajax.Request(uri,
{ method: 'get',
parameters: params,
onComplete: successx.bind(bind1),
onFailure: failurex.bind(bind2)
}
);
};
/** Parse XML into a doc structure
* @param {String} text
*
* @returns Parsed Ajax Response ??
* @type ?
*/
OpenLayers.parseXMLString = function(text) {
//MS sucks, if the server is bad it dies
var index = text.indexOf('<');
if (index > 0) {
text = text.substring(index);
}
var ajaxResponse = Try.these(
function() {
var xmldom = new ActiveXObject('Microsoft.XMLDOM');
xmldom.loadXML(text);
return xmldom;
},
function() {
return new DOMParser().parseFromString(text, 'text/xml');
},
function() {
var req = new XMLHttpRequest();
req.open("GET", "data:" + "text/xml" +
";charset=utf-8," + encodeURIComponent(text), false);
if (req.overrideMimeType) {
req.overrideMimeType("text/xml");
}
req.send(null);
return req.responseXML;
}
);
return ajaxResponse;
};OpenLayers.Events = Class.create();
OpenLayers.Events.prototype = {
// Array: supported events
BROWSER_EVENTS: [
"mouseover", "mouseout",
"mousedown", "mouseup", "mousemove",
"click", "dblclick",
"resize", "focus", "blur"
],
// hash of Array(Function): events listener functions
listeners: null,
// Object: the code object issuing application events
object: null,
// DOMElement: the DOM element receiving browser events
div: null,
// Array: list of support application events
eventTypes: null,
/**
* @param {OpenLayers.Map} map
* @param {DOMElement} div
*/
initialize: function (object, div, eventTypes) {
this.listeners = {};
this.object = object;
this.div = div;
this.eventTypes = eventTypes;
if (eventTypes) {
for (var i = 0; i < this.eventTypes.length; i++) {
// create a listener list for every custom application event
this.listeners[ this.eventTypes[i] ] = [];
}
}
for (var i = 0; i < this.BROWSER_EVENTS.length; i++) {
var eventType = this.BROWSER_EVENTS[i];
// every browser event has a corresponding application event
// (whether it's listened for or not).
this.listeners[ eventType ] = [];
Event.observe(div, eventType,
this.handleBrowserEvent.bindAsEventListener(this));
}
// disable dragstart in IE so that mousedown/move/up works normally
Event.observe(div, "dragstart", Event.stop);
},
/**
* @param {str} type
* @param {Object} obj
* @param {Function} func
*/
register: function (type, obj, func) {
var listeners = this.listeners[type];
listeners.push( func.bindAsEventListener(obj) );
},
remove: function(type) {
this.listeners[type].pop();
},
/**
* @param {event} evt
*/
handleBrowserEvent: function (evt) {
evt.xy = this.getMousePosition(evt);
this.triggerEvent(evt.type, evt)
},
/**
* @param {event} evt
*
* @return {OpenLayers.Pixel}
*/
getMousePosition: function (evt) {
if (!this.div.offsets) {
this.div.offsets = Position.page(this.div);
}
return new OpenLayers.Pixel(
evt.clientX - this.div.offsets[0],
evt.clientY - this.div.offsets[1]);
},
/**
* @param {str} type
* @param {event} evt
*/
triggerEvent: function (type, evt) {
if (evt == null) {
evt = {};
}
evt.object = this.object;
var listeners = this.listeners[type];
for (var i = 0; i < listeners.length; i++) {
var callback = listeners[i];
callback(evt);
}
}
};
// @require: OpenLayers/Util.js
/**
* @class
*
*
*/
OpenLayers.Map = Class.create();
OpenLayers.Map.prototype = {
// Hash: base z-indexes for different classes of thing
Z_INDEX_BASE: { Layer: 100, Popup: 200, Control: 1000 },
// Array: supported application event types
EVENT_TYPES: [
"addlayer", "removelayer", "movestart", "move", "moveend",
"zoomend", "layerchanged", "popupopen", "popupclose",
"addmarker", "removemarker", "clearmarkers", "mouseover",
"mouseout", "mousemove", "dragstart", "drag", "dragend" ],
// int: zoom levels, used to draw zoom dragging control and limit zooming
maxZoomLevel: 16,
// OpenLayers.Bounds
maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),
/* projection */
projection: "EPSG:4326",
// float
maxResolution: null, // degrees per pixel
// DOMElement: the div that our map lives in
div: null,
// HTMLDivElement: the map's view port
viewPortDiv: null,
// HTMLDivElement: the map's layer container
layerContainerDiv: null,
// Array(OpenLayers.Layer): ordered list of layers in the map
layers: null,
// Array(OpenLayers.Control)
controls: null,
// Array(OpenLayers.Popup)
popups: null,
// OpenLayers.LonLat
center: null,
// int
zoom: null,
// OpenLayers.Events
events: null,
// OpenLayers.Pixel
mouseDragStart: null,
/**
* @param {DOMElement} div
*/
initialize: function (div, options) {
Object.extend(this, options);
this.div = div = $(div);
// the viewPortDiv is the outermost div we modify
var id = div.id + "_OpenLayers_ViewPort";
this.viewPortDiv = OpenLayers.Util.createDiv(id, null, null, null,
"relative", null,
"hidden");
this.viewPortDiv.style.width = "100%";
this.viewPortDiv.style.height = "100%";
this.div.appendChild(this.viewPortDiv);
// the layerContainerDiv is the one that holds all the layers
id = div.id + "_OpenLayers_Container";
this.layerContainerDiv = OpenLayers.Util.createDiv(id);
this.viewPortDiv.appendChild(this.layerContainerDiv);
this.events = new OpenLayers.Events(this, div, this.EVENT_TYPES);
this.updateSize();
// make the entire maxExtent fix in zoom level 0 by default
if (this.maxResolution == null) {
this.maxResolution = Math.max(
this.maxExtent.getWidth() / this.size.w,
this.maxExtent.getHeight() / this.size.h );
}
// update the internal size register whenever the div is resized
this.events.register("resize", this, this.updateSize);
this.layers = [];
if (!this.controls) {
this.controls = [];
this.addControl(new OpenLayers.Control.MouseDefaults());
this.addControl(new OpenLayers.Control.PanZoom());
}
this.popups = new Array();
// always call map.destroy()
Event.observe(window, 'unload',
this.destroy.bindAsEventListener(this));
},
/**
*/
destroy:function() {
if (this.layers != null) {
for(var i=0; i< this.layers.length; i++) {
this.layers[i].destroy();
}
this.layers = null;
}
if (this.controls != null) {
for(var i=0; i< this.controls.length; i++) {
this.controls[i].destroy();
}
this.controls = null;
}
},
/**
* @param {OpenLayers.Layer} layer
*/
addLayer: function (layer, zIndex) {
layer.map = this;
layer.projection = this.projection;
layer.div.style.overflow = "";
if (zIndex) {
layer.div.style.zIndex = zIndex;
} else {
layer.div.style.zIndex = this.Z_INDEX_BASE['Layer'] + this.layers.length;
}
this.layerContainerDiv.appendChild(layer.div);
this.layers.push(layer);
this.events.triggerEvent("addlayer");
},
/**
* @param {Array(OpenLayers.Layer)} layers
*/
addLayers: function (layers) {
for (var i = 0; i < layers.length; i++) {
this.addLayer(layers[i]);
}
},
/**
* @param {OpenLayers.Control} control
* @param {OpenLayers.Pixel} px
*/
addControl: function (control, px) {
control.map = this;
this.controls.push(control);
var div = control.draw(px);
if (div) {
div.style.zIndex = this.Z_INDEX_BASE['Control'] +
this.controls.length;
this.viewPortDiv.appendChild( div );
}
},
/**
* @param {OpenLayers.Popup} popup
*/
addPopup: function(popup) {
popup.map = this;
this.popups.push(popup);
var popupDiv = popup.draw();
if (popupDiv) {
popupDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] +
this.popups.length;
this.layerContainerDiv.appendChild(popupDiv);
}
},
/**
* @param {OpenLayers.Popup} popup
*/
removePopup: function(popup) {
this.popups.remove(popup);
if (popup.div) {
this.layerContainerDiv.removeChild(popup.div);
}
},
/**
* @return {float}
*/
getResolution: function () {
// return degrees per pixel
return this.maxResolution / Math.pow(2, this.zoom);
},
/**
* @return {int}
*/
getZoom: function () {
return this.zoom;
},
/**
* @returns {OpenLayers.Size}
*/
getSize: function () {
return this.size;
},
updateSize: function() {
this.size = new OpenLayers.Size(
this.div.clientWidth, this.div.clientHeight);
this.events.div.offsets = null;
// Workaround for the fact that hidden elements return 0 for size.
if (this.size.w == 0 && this.size.h == 0) {
this.size.w = parseInt(this.div.style.width);
this.size.h = parseInt(this.div.style.height);
}
},
/**
* @return {OpenLayers.LonLat}
*/
getCenter: function () {
return this.center;
},
/**
* @return {OpenLayers.Bounds}
*/
getExtent: function () {
if (this.center) {
var res = this.getResolution();
var size = this.getSize();
var w_deg = size.w * res;
var h_deg = size.h * res;
return new OpenLayers.Bounds(
this.center.lon - w_deg / 2,
this.center.lat - h_deg / 2,
this.center.lon + w_deg / 2,
this.center.lat + h_deg / 2);
} else {
return null;
}
},
/**
* @return {OpenLayers.Bounds}
*/
getFullExtent: function () {
return this.maxExtent;
},
getZoomLevels: function() {
return this.maxZoomLevel;
},
/**
* @param {OpenLayers.Bounds} bounds
*
* @return {int}
*/
getZoomForExtent: function (bounds) {
var size = this.getSize();
var width = bounds.getWidth();
var height = bounds.getHeight();
var deg_per_pixel = (width > height ? width / size.w : height / size.h);
var zoom = Math.log(this.maxResolution / deg_per_pixel) / Math.log(2);
return Math.floor(Math.max(zoom, 0));
},
/**
* @param {OpenLayers.Pixel} layerPx
*
* @returns px translated into screen pixel coordinates
* @type OpenLayers.Pixel
*/
getScreenPxFromLayerPx:function(layerPx) {
var screenPx = layerPx.copyOf();
screenPx.x += parseInt(this.layerContainerDiv.style.left);
screenPx.y += parseInt(this.layerContainerDiv.style.top);
return screenPx;
},
/**
* @param {OpenLayers.Pixel} screenPx
*
* @returns px translated into screen pixel coordinates
* @type OpenLayers.Pixel
*/
getLayerPxFromScreenPx:function(screenPx) {
var layerPx = screenPx.copyOf();
layerPx.x -= parseInt(this.layerContainerDiv.style.left);
layerPx.y -= parseInt(this.layerContainerDiv.style.top);
return layerPx;
},
/**
* @param {OpenLayers.Pixel} px
*
* @return {OpenLayers.LonLat}
*/
getLonLatFromLayerPx: function (px) {
//adjust for displacement of layerContainerDiv
px = this.getScreenPxFromLayerPx(px);
return this.getLonLatFromScreenPx(px);
},
/**
* @param {OpenLayers.Pixel} screenPx
*
* @returns An OpenLayers.LonLat which is the passed-in screen
* OpenLayers.Pixel, translated into lon/lat given the
* current extent and resolution
* @type OpenLayers.LonLat
*/
getLonLatFromScreenPx: function (screenPx) {
var center = this.getCenter(); //map center lon/lat
var res = this.getResolution();
var size = this.getSize();
var delta_x = screenPx.x - (size.w / 2);
var delta_y = screenPx.y - (size.h / 2);
return new OpenLayers.LonLat(center.lon + delta_x * res ,
center.lat - delta_y * res);
},
/**
* @param {OpenLayers.LonLat} lonlat
*
* @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
* translated into layer pixels given the current extent
* and resolution
* @type OpenLayers.Pixel
*/
getLayerPxFromLonLat: function (lonlat) {
//adjust for displacement of layerContainerDiv
var px = this.getScreenPxFromLonLat(lonlat);
return this.getLayerPxFromScreenPx(px);
},
/**
* @param {OpenLayers.LonLat} lonlat
*
* @returns An OpenLayers.Pixel which is the passed-in OpenLayers.LonLat,
* translated into screen pixels given the current extent
* and resolution
* @type OpenLayers.Pixel
*/
getScreenPxFromLonLat: function (lonlat) {
var resolution = this.getResolution();
var extent = this.getExtent();
return new OpenLayers.Pixel(
Math.round(1/resolution * (lonlat.lon - extent.left)),
Math.round(1/resolution * (extent.top - lonlat.lat))
);
},
/**
* @param {OpenLayers.LonLat} lonlat
* @param {int} zoom
*/
setCenter: function (lonlat, zoom) {
if (this.center) { // otherwise there's nothing to move yet
this.moveLayerContainer(lonlat);
}
this.center = lonlat.copyOf();
var zoomChanged = null;
if (zoom != null && zoom != this.zoom
&& zoom >= 0 && zoom <= this.getZoomLevels()) {
zoomChanged = (this.zoom == null ? 0 : this.zoom);
this.zoom = zoom;
}
this.events.triggerEvent("movestart");
this.moveToNewExtent(zoomChanged);
this.events.triggerEvent("moveend");
},
moveToNewExtent: function (zoomChanged) {
if (zoomChanged != null) { // reset the layerContainerDiv's location
this.layerContainerDiv.style.left = "0px";
this.layerContainerDiv.style.top = "0px";
//redraw popups
for (var i = 0; i < this.popups.length; i++) {
this.popups[i].updatePosition();
}
}
var bounds = this.getExtent();
for (var i = 0; i < this.layers.length; i++) {
this.layers[i].moveTo(bounds, (zoomChanged != null));
}
this.events.triggerEvent("move");
if (zoomChanged != null)
this.events.triggerEvent("zoomend",
{oldZoom: zoomChanged, newZoom: this.zoom});
},
/**
* zoomIn
* Increase zoom level by one.
*/
zoomIn: function() {
if (this.zoom != null && this.zoom <= this.getZoomLevels()) {
this.zoomTo( this.zoom += 1 );
}
},
/**
* zoomTo
* Set Zoom To int
*/
zoomTo: function(zoom) {
if (zoom >= 0 && zoom <= this.getZoomLevels()) {
var oldZoom = this.zoom;
this.zoom = zoom;
this.moveToNewExtent(oldZoom);
}
},
/**
* zoomOut
* Decrease zoom level by one.
*/
zoomOut: function() {
if (this.zoom != null && this.zoom > 0) {
this.zoomTo( this.zoom - 1 );
}
},
zoomExtent: function() {
var fullExtent = this.getFullExtent();
var oldZoom = this.zoom;
this.setCenter(
new OpenLayers.LonLat((fullExtent.left+fullExtent.right)/2,
(fullExtent.bottom+fullExtent.top)/2),
0
);
},
/**
* @param {OpenLayers.LonLat} lonlat
*/
moveLayerContainer: function (lonlat) {
var container = this.layerContainerDiv;
var resolution = this.getResolution();
var deltaX = Math.round((this.center.lon - lonlat.lon) / resolution);
var deltaY = Math.round((this.center.lat - lonlat.lat) / resolution);
var offsetLeft = parseInt(container.style.left);
var offsetTop = parseInt(container.style.top);
container.style.left = (offsetLeft + deltaX) + "px";
container.style.top = (offsetTop - deltaY) + "px";
},
CLASS_NAME: "OpenLayers.Map"
};
OpenLayers.Layer = Class.create();
OpenLayers.Layer.prototype = {
// str
name: null,
// DOMElement
div: null,
/** This variable is set in map.addLayer, not within the layer itself
* @type OpenLayers.Map */
map: null,
// str -- projection for use in WFS, WMS, etc.
projection: null,
/**
* @param {str} name
*/
initialize: function(name) {
if (arguments.length > 0) {
this.name = name;
if (this.div == null) {
this.div = OpenLayers.Util.createDiv();
this.div.style.width = "100%";
this.div.style.height = "100%";
}
}
},
/**
* Destroy is a destructor: this is to alleviate cyclic references which
* the Javascript garbage cleaner can not take care of on its own.
*/
destroy: function() {
this.map = null;
},
/**
* @params {OpenLayers.Bounds} bound
* @params {bool} zoomChanged tells when zoom has changed, as layers have to do some init work in that case.
*/
moveTo: function (bound,zoomChanged) {
// not implemented here
return;
},
/**
* @return {bool}
*/
getVisibility: function() {
return (this.div.style.display != "none");
},
/**
* @param {bool} visible
*/
setVisibility: function(visible) {
this.div.style.display = (visible) ? "block" : "none";
if ((visible) && (this.map != null)) {
this.moveTo(this.map.getExtent());
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer"
};
/**
* @class
*/
OpenLayers.Icon = Class.create();
OpenLayers.Icon.prototype = {
/** image url
* @type String */
url: null,
/** @type OpenLayers.Size */
size:null,
/** distance in pixels to offset the image when being rendered
* @type OpenLayers.Pixel */
offset: null,
/** Function to calculate the offset (based on the size)
* @type OpenLayers.Pixel */
calculateOffset: null,
/** @type DOMElement */
imageDiv: null,
/** @type OpenLayers.Pixel */
px: null,
/**
* @constructor
*
* @param {String} url
* @param {OpenLayers.Size} size
* @param {Function} calculateOffset
*/
initialize: function(url, size, offset, calculateOffset) {
this.url = url;
this.size = (size) ? size : new OpenLayers.Size(20,20);
this.offset = (offset) ? offset : new OpenLayers.Pixel(0,0);
this.calculateOffset = calculateOffset;
this.imageDiv = OpenLayers.Util.createAlphaImageDiv();
},
/**
* @returns A fresh copy of the icon.
* @type OpenLayers.Icon
*/
clone: function() {
return new OpenLayers.Icon(this.size, this.url, this.offset);
},
/**
* @param {OpenLayers.Size} size
*/
setSize: function(size) {
if (size != null) {
this.size = size;
}
this.draw();
},
/**
* @param {OpenLayers.Pixel} px
*
* @return A new DOM Image of this icon set at the location passed-in
* @type DOMElement
*/
draw: function(px) {
OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv,
null,
null,
this.size,
this.url,
"absolute");
this.moveTo(px);
return this.imageDiv;
},
/**
* @param {OpenLayers.Pixel} px
*/
moveTo: function (px) {
//if no px passed in, use stored location
if (px != null) {
this.px = px;
}
if ((this.px != null) && (this.imageDiv != null)) {
if (this.calculateOffset) {
this.offset = this.calculateOffset(this.size);
}
var offsetPx = this.px.offset(this.offset);
OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, offsetPx);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Icon"
};/**
* @class
*/
OpenLayers.Marker = Class.create();
OpenLayers.Marker.prototype = {
/** @type OpenLayers.Icon */
icon: null,
/** location of object
* @type OpenLayers.LonLat */
lonlat: null,
/** @type OpenLayers.Events*/
events: null,
/** @type OpenLayers.Map */
map: null,
/**
* @constructor
*
* @param {OpenLayers.Icon} icon
* @param {OpenLayers.LonLat lonlat
*/
initialize: function(lonlat, icon) {
this.lonlat = lonlat;
this.icon = (icon) ? icon : OpenLayers.Marker.defaultIcon();
this.events = new OpenLayers.Events(this, this.icon.imageDiv, null);
},
/**
* @param {OpenLayers.Pixel} px
*
* @return A new DOM Image with this marker<65>s icon set at the
* location passed-in
* @type DOMElement
*/
draw: function(px) {
return this.icon.draw(px);
},
/**
* @param {OpenLayers.Pixel} px
*/
moveTo: function (px) {
if ((px != null) && (this.icon != null)) {
this.icon.moveTo(px);
}
},
/**
* @param {float} inflate
*/
inflate: function(inflate) {
if (this.icon) {
var newSize = new OpenLayers.Size(this.icon.size.w * inflate,
this.icon.size.h * inflate);
this.icon.setSize(newSize);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Marker"
};
/**
* @returns A default OpenLayers.Icon to use for a marker
* @type OpenLayers.Icon
*/
OpenLayers.Marker.defaultIcon = function() {
var url = OpenLayers.Util.getImagesLocation() + "marker.png";
var size = new OpenLayers.Size(21, 25);
var calculateOffset = function(size) {
return new OpenLayers.Pixel(-(size.w/2), -size.h);
};
return new OpenLayers.Icon(url, size, null, calculateOffset);
};
/**
* @class
*/
OpenLayers.Popup = Class.create();
OpenLayers.Popup.count = 0;
OpenLayers.Popup.WIDTH = 200;
OpenLayers.Popup.HEIGHT = 200;
OpenLayers.Popup.COLOR = "white";
OpenLayers.Popup.OPACITY = 1;
OpenLayers.Popup.BORDER = "0px";
OpenLayers.Popup.prototype = {
/** @type OpenLayers.Events*/
events: null,
/** @type String */
id: "",
/** @type OpenLayers.LonLat */
lonlat: null,
/** @type DOMElement */
div: null,
/** @type OpenLayers.Size*/
size: null,
/** @type String */
contentHTML: "",
/** @type String */
backgroundColor: "",
/** @type float */
opacity: "",
/** @type String */
border: "",
/** this gets set in Map.js when the popup is added to the map
* @type OpenLayers.Map */
map: null,
/**
* @constructor
*
* @param {String} id
* @param {OpenLayers.LonLat} lonlat
* @param {OpenLayers.Size} size
* @param {String} contentHTML
*/
initialize:function(id, lonlat, size, contentHTML) {
OpenLayers.Popup.count += 1;
this.id = (id != null) ? id : "Popup" + OpenLayers.Popup.count;
this.lonlat = lonlat;
this.size = (size != null) ? size
: new OpenLayers.Size(
OpenLayers.Popup.WIDTH,
OpenLayers.Popup.HEIGHT);
if (contentHTML != null) {
this.contentHTML = contentHTML;
}
this.backgroundColor = OpenLayers.Popup.COLOR;
this.opacity = OpenLayers.Popup.OPACITY;
this.border = OpenLayers.Popup.BORDER;
this.div = OpenLayers.Util.createDiv(this.id + "_div", null, null,
null, null, null, "hidden");
this.events = new OpenLayers.Events(this, this.div, null);
},
/**
*/
destroy: function() {
if ((this.div) && (this.div.parentNode)) {
this.div.parentNode.removeChild(this.div);
}
this.div = null;
this.map = null;
},
/**
* @param {OpenLayers.Pixel} px
*
* @returns Reference to a div that contains the drawn popup
* @type DOMElement
*/
draw: function(px) {
if (px == null) {
if ((this.lonlat != null) && (this.map != null)) {
px = this.map.getLayerPxFromLonLat(this.lonlat);
}
}
this.setSize();
this.setBackgroundColor();
this.setOpacity();
this.setBorder();
this.setContentHTML();
this.moveTo(px);
return this.div;
},
/**
* if the popup has a lonlat and its map members set,
* then have it move itself to its proper position
*/
updatePosition: function() {
if ((this.lonlat) && (this.map)) {
var px = this.map.getLayerPxFromLonLat(this.lonlat);
this.moveTo(px);
}
},
/**
* @param {OpenLayers.Pixel} px
*/
moveTo: function(px) {
if ((px != null) && (this.div != null)) {
this.div.style.left = px.x + "px";
this.div.style.top = px.y + "px";
}
},
/**
* @returns Boolean indicating whether or not the popup is visible
* @type Boolean
*/
visible: function() {
return Element.visible(this.div);
},
/**
*
*/
toggle: function() {
Element.toggle(this.div);
},
/**
*
*/
show: function() {
Element.show(this.div);
},
/**
*
*/
hide: function() {
Element.hide(this.div);
},
/**
* @param {OpenLayers.Size} size
*/
setSize:function(size) {
if (size != undefined) {
this.size = size;
}
if (this.div != null) {
this.div.style.width = this.size.w;
this.div.style.height = this.size.h;
}
},
/**
* @param {String} color
*/
setBackgroundColor:function(color) {
if (color != undefined) {
this.backgroundColor = color;
}
if (this.div != null) {
this.div.style.backgroundColor = this.backgroundColor;
}
},
/**
* @param {float} opacity
*/
setOpacity:function(opacity) {
if (opacity != undefined) {
this.opacity = opacity;
}
if (this.div != null) {
// for Mozilla and Safari
this.div.style.opacity = this.opacity;
// for IE
this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')';
}
},
/**
* @param {int} border
*/
setBorder:function(border) {
if (border != undefined) {
this.border = border;
}
if (this.div != null) {
this.div.style.border = this.border;
}
},
/**
* @param {String} contentHTML
*/
setContentHTML:function(contentHTML) {
if (contentHTML != null) {
this.contentHTML = contentHTML;
}
if (this.div != null) {
this.div.innerHTML = this.contentHTML;
}
},
CLASS_NAME: "OpenLayers.Popup"
};
/*
* OpenLayers.Tile
*
* @class This is a class designed to designate a single tile, however
* it is explicitly designed to do relatively little. Tiles store information
* about themselves -- such as the URL that they are related to, and their
* size - but do not add themselves to the layer div automatically, for
* example.
*/
OpenLayers.Tile = Class.create();
OpenLayers.Tile.prototype = {
/** @type OpenLayers.Layer */
layer: null,
/** @type String url of the request */
url:null,
/** @type OpenLayers.Bounds */
bounds:null,
/** @type OpenLayers.Size */
size:null,
/** Top Left pixel of the tile
* @type OpenLayers.Pixel */
position:null,
/**
* @constructor
*
* @param {OpenLayers.Layer} layer
* @param {OpenLayers.Pixel} position
* @param {OpenLayers.Bounds} bounds
* @param {String} url
* @param {OpenLayers.Size} size
*/
initialize: function(layer, position, bounds, url, size) {
if (arguments.length > 0) {
this.layer = layer;
this.position = position;
this.bounds = bounds;
this.url = url;
this.size = size;
}
},
/** nullify references to prevent circular references and memory leaks
*/
destroy:function() {
this.layer = null;
this.bounds = null;
this.size = null;
},
/**
*/
draw:function() {
// HACK HACK - should we make it a standard to put this sort of warning
// message in functions that are supposed to be overridden?
//
// ol.Log.warn(this.CLASS_NAME + ": draw() not implemented");
},
/** remove this tile from the ds
*/
remove:function() {
},
/**
* @type OpenLayers.Pixel
*/
getPosition: function() {
return this.position;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Tile"
};
/**
* @class
*/
OpenLayers.Feature = Class.create();
OpenLayers.Feature.prototype= {
/** @type OpenLayers.Events */
events:null,
/** @type OpenLayers.Layer */
layer: null,
/** @type String */
id: null,
/** @type OpenLayers.LonLat */
lonlat:null,
/** @type Object */
data:null,
/** @type OpenLayers.Marker */
marker: null,
/** @type OpenLayers.Popup */
popup: null,
/**
* @constructor
*
* @param {OpenLayers.Layer} layer
* @param {String} id
* @param {OpenLayers.LonLat} lonlat
* @param {Object} data
*/
initialize: function(layer, lonlat, data, id) {
this.layer = layer;
this.lonlat = lonlat;
this.data = (data != null) ? data : new Object();
this.id = (id ? id : 'f' + Math.random());
},
/**
*
*/
destroy: function() {
this.layer = null;
},
/**
* @returns A Marker Object created from the 'lonlat' and 'icon' properties
* set in this.data. If no 'lonlat' is set, returns null. If no
* 'icon' is set, OpenLayers.Marker() will load the default image
* @type OpenLayers.Marker
*/
createMarker: function() {
var marker = null;
if (this.lonlat != null) {
this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);
}
return this.marker;
},
/**
*
*/
createPopup: function() {
if (this.lonlat != null) {
var id = this.id + "_popup";
var anchor = (this.marker) ? this.marker.icon : null;
this.popup = new OpenLayers.Popup.AnchoredBubble(id,
this.lonlat,
this.data.popupSize,
this.data.popupContentHTML,
anchor);
}
return this.popup;
},
CLASS_NAME: "OpenLayers.Feature"
};
/**
* @class
*/
OpenLayers.Feature.WFS = Class.create();
OpenLayers.Feature.WFS.prototype =
Object.extend( new OpenLayers.Feature(), {
/**
* @constructor
*
* @param {OpenLayers.Layer} layer
* @param {XMLNode} xmlNode
*/
initialize: function(layer, xmlNode) {
var newArguments = arguments;
if (arguments.length > 0) {
var data = this.processXMLNode(xmlNode);
newArguments = new Array(layer, data.lonlat, data, data.id)
}
OpenLayers.Feature.prototype.initialize.apply(this, newArguments);
if (arguments.length > 0) {
this.createMarker();
this.layer.addMarker(this.marker);
}
},
/**
* @param {XMLNode} xmlNode
*
* @returns Data Object with 'id', 'lonlat', and private properties set
* @type Object
*/
processXMLNode: function(xmlNode) {
//this should be overridden by subclasses
// must return an Object with 'id' and 'lonlat' values set
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Feature.WFS"
});
// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.Image = Class.create();
OpenLayers.Tile.Image.prototype =
Object.extend( new OpenLayers.Tile(), {
/** @type DOMElement img */
img:null,
/**
* @constructor
*
* @param {OpenLayers.Grid} layer
* @param {OpenLayers.Pixel} position
* @param {OpenLayers.Bounds} bounds
* @param {String} url
* @param {OpenLayers.Size} size
*/
initialize: function(layer, position, bounds, url, size) {
OpenLayers.Tile.prototype.initialize.apply(this, arguments);
},
/**
*/
draw:function() {
OpenLayers.Tile.prototype.draw.apply(this, arguments);
this.img = OpenLayers.Util.createImage(null,
this.position,
this.size,
this.url,
"absolute");
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Tile.Image"
}
);
// @require: OpenLayers/Tile.js
/**
* @class
*/
OpenLayers.Tile.WFS = Class.create();
OpenLayers.Tile.WFS.prototype =
Object.extend( new OpenLayers.Tile(), {
/** @type Array of Function */
handlers: null,
/** @type Array(OpenLayers.Feature)*/
features: null,
/**
* @constructor
*
* @param {OpenLayers.Layer} layer
* @param {OpenLayers.Pixel} position
* @param {OpenLayers.Bounds} bounds
* @param {String} url
* @param {OpenLayers.Size} size
*/
initialize: function(layer, position, bounds, url, size) {
OpenLayers.Tile.prototype.initialize.apply(this, arguments);
this.features = new Array();
this.handlers = new Array();
this.handlers["requestSuccess"] = this.requestSuccess;
},
/**
*/
draw:function() {
OpenLayers.Tile.prototype.draw.apply(this, arguments);
this.loadFeaturesForRegion("requestSuccess");
},
/** get the full request string from the ds and the tile params
* and call the AJAX loadURL().
*
* input are function pointers for what to do on success and failure.
*
* @param {function} success
* @param {function} failure
*/
loadFeaturesForRegion:function(success, failure) {
if (!this.loaded) {
if (this.url != "") {
// TODO: Hmmm, this stops multiple loads of the data when a
// result isn't immediately retrieved, but it's hacky.
// Do it better.
this.loaded = true;
// ol.Log.info("request string: " + this.url);
OpenLayers.loadURL(this.url, null, this, success, failure);
}
}
},
/** Return from AJAX request
*
* @param {} request
*/
requestSuccess:function(request) {
var doc = request.responseXML;
if (!doc || request.fileType!="XML") {
doc = OpenLayers.parseXMLString(request.responseText);
}
var resultFeatures = OpenLayers.Util.getNodes(doc, "gml:featureMember");
// ol.Log.info(this.layer.name + " found " +
// resultFeatures.length + " features");
//clear old featureList
this.features = new Array();
for (var i=0; i < resultFeatures.length; i++) {
var feature = new this.layer.featureClass(this.layer,
resultFeatures[i]);
this.features.append(feature);
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Tile.WFS"
}
);
// @require: OpenLayers/Layer.js
OpenLayers.Layer.Google = Class.create();
OpenLayers.Layer.Google.prototype = Object.extend( new OpenLayers.Layer(), {
// gmap stores the Google Map element
gmap:null,
initialize: function(name) {
OpenLayers.Layer.prototype.initialize.apply(this, [name]);
this.gmap = new GMap2(this.div);
},
moveTo: function() {
center = this.map.getCenter();
this.gmap.setCenter(
new GLatLng(center.lat, center.lon),
this.map.getZoom()
);
}
});
// @require: OpenLayers/Layer.js
// @require: OpenLayers/Util.js
OpenLayers.Layer.Grid = Class.create();
OpenLayers.Layer.Grid.TILE_WIDTH = 256;
OpenLayers.Layer.Grid.TILE_HEIGHT = 256;
OpenLayers.Layer.Grid.prototype = Object.extend( new OpenLayers.Layer(), {
// str: url
url: null,
// hash: params
params: null,
// tileSize: OpenLayers.Size
tileSize: null,
// grid: Array(Array())
// this is an array of rows, each row is an array of tiles
grid: null,
/**
* @param {str} name
* @param {str} url
* @param {hash} params
*/
initialize: function(name, url, params) {
var newArguments = arguments;
if (arguments.length > 0) {
newArguments = [name];
}
OpenLayers.Layer.prototype.initialize.apply(this, newArguments);
this.url = url;
this.params = params;
this.tileSize = new OpenLayers.Size(OpenLayers.Layer.Grid.TILE_WIDTH,
OpenLayers.Layer.Grid.TILE_HEIGHT);
},
setTileSize: function (size) {
this.tileSize = size.copyOf();
},
/**
* moveTo
* moveTo is a function called whenever the map is moved. All the moving
* of actual 'tiles' is done by the map, but moveTo's role is to accept
* a bounds and make sure the data that that bounds requires is pre-loaded.
* @param {OpenLayers.Bounds}
*/
moveTo:function(bounds,zoomChanged) {
if (!this.getVisibility()) {
if (zoomChanged) {
this.grid = null;
}
return;
}
if (!this.grid || zoomChanged) {
this._initTiles();
} else {
var i = 0;
while (this.getGridBounds().bottom > bounds.bottom) {
this.insertRow(false);
}
while (this.getGridBounds().left > bounds.left) {
this.insertColumn(true);
}
while (this.getGridBounds().top < bounds.top) {
this.insertRow(true);
}
while (this.getGridBounds().right < bounds.right) {
this.insertColumn(false);
}
}
},
getGridBounds:function() {
var topLeftTile = this.grid[0][0];
var bottomRightTile = this.grid[this.grid.length-1][this.grid[0].length-1];
return new OpenLayers.Bounds(topLeftTile.bounds.left,
bottomRightTile.bounds.bottom,
bottomRightTile.bounds.right,
topLeftTile.bounds.top);
},
/**
*/
_initTiles:function() {
//first of all, clear out the main div
this.div.innerHTML = "";
//now clear out the old grid and start a new one
this.clearGrid();
this.grid = new Array();
var viewSize = this.map.getSize();
var bounds = this.map.getExtent();
var extent = this.map.getFullExtent();
var resolution = this.map.getResolution();
var tilelon = resolution*this.tileSize.w;
var tilelat = resolution*this.tileSize.h;
var offsetlon = bounds.left - extent.left;
var tilecol = Math.floor(offsetlon/tilelon);
var tilecolremain = offsetlon/tilelon - tilecol;
var tileoffsetx = -tilecolremain * this.tileSize.w;
var tileoffsetlon = extent.left + tilecol * tilelon;
var offsetlat = bounds.top - (extent.bottom + tilelat);
var tilerow = Math.ceil(offsetlat/tilelat);
var tilerowremain = tilerow - offsetlat/tilelat;
var tileoffsety = -tilerowremain * this.tileSize.h;
var tileoffsetlat = extent.bottom + tilerow * tilelat;
tileoffsetx = Math.round(tileoffsetx); // heaven help us
tileoffsety = Math.round(tileoffsety);
this.origin = new OpenLayers.Pixel(tileoffsetx,tileoffsety);
var startX = tileoffsetx;
var startLon = tileoffsetlon;
do {
var row = new Array();
this.grid.append(row);
tileoffsetlon = startLon;
tileoffsetx = startX;
do {
var tileBounds = new OpenLayers.Bounds(tileoffsetlon,
tileoffsetlat,
tileoffsetlon+tilelon,
tileoffsetlat+tilelat);
var tile = this.addTile(tileBounds,
new OpenLayers.Pixel(tileoffsetx,
tileoffsety)
);
row.append(tile);
tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w;
} while (tileoffsetlon < bounds.right)
tileoffsetlat -= tilelat;
tileoffsety += this.tileSize.h;
} while(tileoffsetlat > bounds.bottom - tilelat)
},
/**
* @param {bool} prepend - if true, prepend to beginning.
* if false, then append to end
*/
insertRow:function(prepend) {
var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1);
var modelRow = this.grid[modelRowIndex];
var newRow = new Array();
var resolution = this.map.getResolution();
var deltaY = (prepend) ? -this.tileSize.h : this.tileSize.h;
var deltaLat = resolution * -deltaY;
for (var i=0; i < modelRow.length; i++) {
var modelTile = modelRow[i];
var bounds = modelTile.bounds.copyOf();
var position = modelTile.position.copyOf();
bounds.bottom = bounds.bottom + deltaLat;
bounds.top = bounds.top + deltaLat;
position.y = position.y + deltaY;
var newTile = this.addTile(bounds, position);
newRow.append(newTile);
}
if (newRow.length>0){
if (prepend) {
this.grid.prepend(newRow);
} else {
this.grid.append(newRow);
}
}
},
/**
* @param {bool} prepend - if true, prepend to beginning.
* if false, then append to end
*/
insertColumn:function(prepend) {
var modelCellIndex;
var deltaX = (prepend) ? -this.tileSize.w : this.tileSize.w;
var resolution = this.map.getResolution();
var deltaLon = resolution * deltaX;
for (var i=0; i<this.grid.length; i++) {
var row = this.grid[i];
modelTileIndex = (prepend) ? 0 : (row.length - 1);
var modelTile = row[modelTileIndex];
var bounds = modelTile.bounds.copyOf();
var position = modelTile.position.copyOf();
bounds.left = bounds.left + deltaLon;
bounds.right = bounds.right + deltaLon;
position.x = position.x + deltaX;
var newTile = this.addTile(bounds, position);
if (prepend) {
row = row.prepend(newTile);
} else {
row = row.append(newTile);
}
}
},
/** combine the ds's serverPath with its params and the tile's params.
*
* 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"
*
* @return {str}
*/
getFullRequestString:function(params) {
var requestString = "";
this.params.srs = this.projection;
// concat tile params with layer params and convert to string
var allParams = Object.extend(params, this.params);
var paramsString = OpenLayers.Util.getParameterString(allParams);
var server = this.url;
var lastServerChar = server.charAt(server.length - 1);
if ((lastServerChar == "&") || (lastServerChar == "?")) {
requestString = server + paramsString;
} else {
if (server.indexOf('?') == -1) {
//serverPath has no ? -- add one
requestString = server + '?' + paramsString;
} else {
//serverPath contains ?, so must already have paramsString at the end
requestString = server + '&' + paramsString;
}
}
return requestString;
},
/** go through and remove all tiles from the grid, calling
* destroy() on each of them to kill circular references
*
* @private
*/
clearGrid:function() {
if (this.grid) {
while(this.grid.length > 0) {
var row = this.grid[0];
while(row.length > 0) {
var tile = row[0];
tile.destroy();
row.remove(tile);
}
this.grid.remove(row);
}
}
}
});
// @require: OpenLayers/Layer.js
/**
* @class
*/
OpenLayers.Layer.Markers = Class.create();
OpenLayers.Layer.Markers.prototype =
Object.extend( new OpenLayers.Layer(), {
/** internal marker list
* @type Array(OpenLayers.Marker) */
markers: null,
/**
* @constructor
*
* @param {String} name
*/
initialize: function(name) {
OpenLayers.Layer.prototype.initialize.apply(this, arguments);
this.markers = new Array();
},
/**
* @param {OpenLayers.Bounds} bounds
* @param {Boolean} zoomChanged
*/
moveTo: function(bounds, zoomChanged) {
if (zoomChanged) {
this.redraw();
}
},
/**
* @param {OpenLayers.Marker} marker
*/
addMarker: function(marker) {
this.markers.append(marker);
if (this.map && this.map.getExtent()) {
this.drawMarker(marker);
}
},
/** clear all the marker div's from the layer and then redraw all of them.
* Use the map to recalculate new placement of markers.
*/
redraw: function() {
for(i=0; i < this.markers.length; i++) {
this.drawMarker(this.markers[i]);
}
},
/** Calculate the screen pixel location for the marker, create it, and
* add it to the layer's div
*
* @private
*
* @param {OpenLayers.Marker} marker
*/
drawMarker: function(marker) {
var px = this.map.getLayerPxFromLonLat(marker.lonlat);
var markerImg = marker.draw(px);
if (!marker.drawn) {
this.div.appendChild(markerImg);
marker.drawn = true;
}
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.Markers"
});
// @require: OpenLayers/Layer/Markers.js
/**
* @class
*/
OpenLayers.Layer.Text = Class.create();
OpenLayers.Layer.Text.prototype =
Object.extend( new OpenLayers.Layer.Markers(), {
/** store url of text file
* @type str */
location:null,
/** @type OpenLayers.Feature */
selectedFeature: null,
/**
* @constructor
*
* @param {String} name
* @param {String} location
*/
initialize: function(name, location) {
OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name]);
this.location = location;
new Ajax.Request(location,
{ method: 'get', onComplete:this.parseData.bind(this) } );
},
/**
* @param {?} ajaxRequest
*/
parseData: function(ajaxRequest) {
var text = ajaxRequest.responseText;
var lines = text.split('\n');
var columns;
// length - 1 to allow for trailing new line
for (var lcv = 0; lcv < (lines.length - 1); lcv++) {
var currLine = lines[lcv].replace(/^\s*/,'').replace(/\s*$/,'');
if (currLine.charAt(0) != '#') { /* not a comment */
if (!columns) {
//First line is columns
columns = currLine.split('\t');
} else {
var vals = currLine.split('\t');
var location = new OpenLayers.LonLat(0,0);
var title; var url;
var icon, iconSize, iconOffset;
var set = false;
for (var valIndex = 0; valIndex < vals.length; valIndex++) {
if (vals[valIndex]) {
if (columns[valIndex] == 'point') {
var coords = vals[valIndex].split(',');
location.lat = parseFloat(coords[0]);
location.lon = parseFloat(coords[1]);
set = true;
} else if (columns[valIndex] == 'lat') {
location.lat = parseFloat(vals[valIndex]);
set = true;
} else if (columns[valIndex] == 'lon') {
location.lon = parseFloat(vals[valIndex]);
set = true;
} else if (columns[valIndex] == 'title')
title = vals[valIndex];
else if (columns[valIndex] == 'image' ||
columns[valIndex] == 'icon')
url = vals[valIndex];
else if (columns[valIndex] == 'iconSize') {
var size = vals[valIndex].split(',');
iconSize = new OpenLayers.Size(parseFloat(size[0]),
parseFloat(size[1]));
} else if (columns[valIndex] == 'iconOffset') {
var offset = vals[valIndex].split(',');
iconOffset = new OpenLayers.Pixel(parseFloat(offset[0]),
parseFloat(offset[1]));
} else if (columns[valIndex] == 'title') {
title = vals[valIndex];
} else if (columns[valIndex] == 'description') {
description = vals[valIndex];
}
}
}
if (set) {
var data = new Object();
if (url != null) {
data.icon = new OpenLayers.Icon(url,
iconSize,
iconOffset);
} else {
data.icon = OpenLayers.Marker.defaultIcon();
//allows for the case where the image url is not
// specified but the size is. use a default icon
// but change the size
if (iconSize != null) {
data.icon.setSize(iconSize);
}
}
if ((title != null) && (description != null)) {
data['popupContentHTML'] = '<h2>'+title+'</h2><p>'+description+'</p>';
}
var feature = new OpenLayers.Feature(this, location, data);
var marker = feature.createMarker();
marker.events.register('click', feature, this.markerClick);
this.addMarker(marker);
}
}
}
}
},
/**
* @param {Event} evt
*/
markerClick: function(evt) {
sameMarkerClicked = (this == this.layer.selectedFeature);
this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;
for(var i=0; i < this.layer.map.popups.length; i++) {
this.layer.map.removePopup(this.layer.map.popups[i]);
}
if (!sameMarkerClicked) {
this.layer.map.addPopup(this.createPopup());
}
Event.stop(evt);
}
});
// @require: OpenLayers/Layer/Grid.js
/**
* @class
*/
OpenLayers.Layer.WMS = Class.create();
OpenLayers.Layer.WMS.prototype =
Object.extend( new OpenLayers.Layer.Grid(), {
/** @final @type hash */
DEFAULT_PARAMS: { service: "WMS",
version: "1.1.1",
request: "GetMap",
styles: "",
exceptions: "application/vnd.ogc.se_inimage",
format: "image/jpeg"
},
/**
* @constructor
*
* @param {str} name
* @param {str} url
* @param {hash} params
*/
initialize: function(name, url, params) {
OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);
OpenLayers.Util.applyDefaults(this.params, this.DEFAULT_PARAMS);
},
/**
* @param {String} name
* @param {hash} params
*
* @returns A clone of this OpenLayers.Layer.WMS, with the passed-in
* parameters merged in.
* @type OpenLayers.Layer.WMS
*/
clone: function (name, params) {
var mergedParams = {};
Object.extend(mergedParams, this.params);
Object.extend(mergedParams, params);
var obj = new OpenLayers.Layer.WMS(name, this.url, mergedParams);
obj.setTileSize(this.tileSize);
return obj;
},
/**
* addTile creates a tile, initializes it (via 'draw' in this case), and
* adds it to the layer div.
*
* @param {OpenLayers.Bounds} bounds
*
* @returns The added OpenLayers.Tile.Image
* @type OpenLayers.Tile.Image
*/
addTile:function(bounds,position) {
url = this.getFullRequestString(
{bbox:bounds.toBBOX(),
width:this.tileSize.w,
height:this.tileSize.h});
var tile = new OpenLayers.Tile.Image(this, position, bounds,
url, this.tileSize);
tile.draw();
this.div.appendChild(tile.img);
return tile;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.WMS"
});
// @require: OpenLayers/Layer/Grid.js
// @require: OpenLayers/Layer/Markers.js
/**
* @class
*/
OpenLayers.Layer.WFS = Class.create();
OpenLayers.Layer.WFS.prototype =
Object.extend(new OpenLayers.Layer.Grid(),
Object.extend(new OpenLayers.Layer.Markers(), {
/** @type Object */
featureClass: null,
/** @final @type hash */
DEFAULT_PARAMS: { service: "WFS",
version: "1.0.0",
request: "GetFeature",
typename: "docpoint"
},
/**
* @constructor
*
* @param {str} name
* @param {str} url
* @param {hash} params
* @param {Object} featureClass
*/
initialize: function(name, url, params, featureClass) {
this.featureClass = featureClass;
var newArguments = new Array();
if (arguments.length > 0) {
newArguments.push(name, url, params);
}
OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);
OpenLayers.Layer.Markers.prototype.initialize.apply(this, newArguments);
if (arguments.length > 0) {
OpenLayers.Util.applyDefaults(this.params, this.DEFAULT_PARAMS);
}
},
/**
* @param {OpenLayers.Bounds} bounds
* @param {Boolean} zoomChanged
*/
moveTo: function(bounds, zoomChanged) {
OpenLayers.Layer.Grid.prototype.moveTo.apply(this, arguments);
OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);
},
/**
* @param {String} name
* @param {hash} params
*
* @returns A clone of this OpenLayers.Layer.WMS, with the passed-in
* parameters merged in.
* @type OpenLayers.Layer.WMS
*/
clone: function (name, params) {
var mergedParams = {}
Object.extend(mergedParams, this.params);
Object.extend(mergedParams, params);
var obj = new OpenLayers.Layer.WFS(name, this.url, mergedParams);
obj.setTileSize(this.tileSize);
return obj;
},
/**
* addTile creates a tile, initializes it (via 'draw' in this case), and
* adds it to the layer div.
*
* @param {OpenLayers.Bounds} bounds
*
* @returns The added OpenLayers.Tile.WFS
* @type OpenLayers.Tile.WFS
*/
addTile:function(bounds, position) {
url = this.getFullRequestString(
{ bbox:bounds.toBBOX() });
var tile = new OpenLayers.Tile.WFS(this, position, bounds,
url, this.tileSize);
tile.draw();
return tile;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Layer.WFS"
}
)
);
// @require: OpenLayers/Popup.js
/**
* @class
*/
OpenLayers.Popup.Anchored = Class.create();
OpenLayers.Popup.Anchored.prototype =
Object.extend( new OpenLayers.Popup(), {
/** "lr", "ll", "tr", "tl" - relative position of the popup.
* @type String */
relativePosition: null,
/** Object which must have expose a 'size' (OpenLayers.Size) and
* 'offset' (OpenLayers.Pixel)
* @type Object */
anchor: null,
/**
* @constructor
*
* @param {String} id
* @param {OpenLayers.LonLat} lonlat
* @param {OpenLayers.Size} size
* @param {String} contentHTML
* @param {Object} anchor Object which must expose a
* - 'size' (OpenLayers.Size) and
* - 'offset' (OpenLayers.Pixel)
* (this is generally an OpenLayers.Icon)
*/
initialize:function(id, lonlat, size, contentHTML, anchor) {
var newArguments = new Array(id, lonlat, size, contentHTML);
OpenLayers.Popup.prototype.initialize.apply(this, newArguments);
this.anchor = (anchor != null) ? anchor
: { size: new OpenLayers.Size(0,0),
offset: new OpenLayers.Pixel(0,0)};
},
/**
* @param {OpenLayers.Pixel} px
*
* @returns Reference to a div that contains the drawn popup
* @type DOMElement
*/
draw: function(px) {
if (px == null) {
if ((this.lonlat != null) && (this.map != null)) {
px = this.map.getLayerPxFromLonLat(this.lonlat);
}
}
//calculate relative position
this.relativePosition = this.calculateRelativePosition(px);
return OpenLayers.Popup.prototype.draw.apply(this, arguments);
},
/**
* @private
*
* @param {OpenLayers.Pixel} px
*
* @returns The relative position ("br" "tr" "tl "bl") at which the popup
* should be placed
* @type String
*/
calculateRelativePosition:function(px) {
var lonlat = this.map.getLonLatFromLayerPx(px);
var extent = this.map.getExtent();
var quadrant = extent.determineQuadrant(lonlat);
return OpenLayers.Bounds.oppositeQuadrant(quadrant);
},
/**
* @param {OpenLayers.Pixel} px
*/
moveTo: function(px) {
var newPx = this.calculateNewPx(px);
var newArguments = new Array(newPx);
OpenLayers.Popup.prototype.moveTo.apply(this, newArguments);
},
/**
* @param {OpenLayers.Size} size
*/
setSize:function(size) {
OpenLayers.Popup.prototype.setSize.apply(this, arguments);
if ((this.lonlat) && (this.map)) {
var px = this.map.getLayerPxFromLonLat(this.lonlat);
this.moveTo(px);
}
},
/**
* @private
*
* @param {OpenLayers.Pixel} px
*
* @returns The the new px position of the popup on the screen
* relative to the passed-in px
* @type OpenLayers.Pixel
*/
calculateNewPx:function(px) {
var newPx = px.offset(this.anchor.offset);
var top = (this.relativePosition.charAt(0) == 't');
newPx.y += (top) ? -this.size.h : this.anchor.size.h;
var left = (this.relativePosition.charAt(1) == 'l');
newPx.x += (left) ? -this.size.w : this.anchor.size.w;
return newPx;
},
CLASS_NAME: "OpenLayers.Popup.Anchored"
});
// @require: OpenLayers/Popup/Anchored.js
/**
* @class
*/
OpenLayers.Popup.AnchoredBubble = Class.create();
//Border space for the rico corners
OpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5;
OpenLayers.Popup.AnchoredBubble.prototype =
Object.extend( new OpenLayers.Popup.Anchored(), {
/** @type DOMElement */
contentDiv:null,
/**
* @constructor
*
* @param {String} id
* @param {OpenLayers.LonLat} lonlat
* @param {OpenLayers.Size} size
* @param {String} contentHTML
* @param {Object} anchor Object which must expose a
* - 'size' (OpenLayers.Size) and
* - 'offset' (OpenLayers.Pixel)
* (this is generally an OpenLayers.Icon)
*/
initialize:function(id, lonlat, size, contentHTML, anchor) {
OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);
},
/**
* @param {OpenLayers.Pixel} px
*
* @returns Reference to a div that contains the drawn popup
* @type DOMElement
*/
draw: function(px) {
OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments);
// make the content Div
var contentSize = this.size.copyOf();
contentSize.h -= (2 * OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);
var id = this.div.id + "-contentDiv";
this.contentDiv = OpenLayers.Util.createDiv(id, null, contentSize,
null, "relative", null,
"auto");
this.div.appendChild(this.contentDiv);
this.setContentHTML();
this.setRicoCorners(true);
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
return this.div;
},
/**
* @param {OpenLayers.Size} size
*/
setSize:function(size) {
OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);
if (this.contentDiv != null) {
var contentSize = this.size.copyOf();
contentSize.h -= (2 * OpenLayers.Popup.AnchoredBubble.CORNER_SIZE);
this.contentDiv.style.height = contentSize.h + "px";
//size has changed - must redo corners
this.setRicoCorners(false);
}
},
/**
* @param {String} color
*/
setBackgroundColor:function(color) {
if (color != undefined) {
this.backgroundColor = color;
}
if (this.div != null) {
if (this.contentDiv != null) {
this.div.style.background = "transparent";
Rico.Corner.changeColor(this.contentDiv, this.backgroundColor);
}
}
},
/**
* @param {float} opacity
*/
setOpacity:function(opacity) {
if (opacity != undefined) {
this.opacity = opacity;
}
if (this.div != null) {
if (this.contentDiv != null) {
Rico.Corner.changeOpacity(this.contentDiv, this.opacity);
}
}
},
/** Bubble Popups can not have a border
*
* @param {int} border
*/
setBorder:function(border) {
this.border = 0;
},
/**
* @param {String} contentHTML
*/
setContentHTML:function(contentHTML) {
if (contentHTML != null) {
this.contentHTML = contentHTML;
}
if (this.contentDiv != null) {
this.contentDiv.innerHTML = this.contentHTML;
}
},
/**
* @private
*
* @param {Boolean} firstTime Is this the first time the corners are being
* rounded?
*
* update the rico corners according to the popup's
* current relative postion
*/
setRicoCorners:function(firstTime) {
var corners = this.getCornersToRound(this.relativePosition);
var options = {corners: corners,
color: this.backgroundColor,
bgColor: "transparent",
blend: false};
if (firstTime) {
Rico.Corner.round(this.div, options);
} else {
Rico.Corner.reRound(this.contentDiv, options);
//set the popup color and opacity
this.setBackgroundColor();
this.setOpacity();
}
},
/**
* @private
*
* @returns The proper corners string ("tr tl bl br") for rico
* to round
* @type String
*/
getCornersToRound:function() {
var corners = ['tl', 'tr', 'bl', 'br'];
//we want to round all the corners _except_ the opposite one.
var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);
corners.remove(corner);
return corners.join(" ");
},
CLASS_NAME: "OpenLayers.Popup.AnchoredBubble"
});
/**
* @class
*/
OpenLayers.Control = Class.create();
OpenLayers.Control.prototype = {
/** this gets set in the addControl() function in OpenLayers.Map
* @type OpenLayers.Map */
map: null,
/** @type DOMElement */
div: null,
/** @type OpenLayers.Pixel */
position: null,
/**
* @constructor
*/
initialize: function (options) {
Object.extend(this, options);
},
/**
* @param {OpenLayers.Pixel} px
*
* @returns A reference to the DIV DOMElement containing the control
* @type DOMElement
*/
draw: function (px) {
if (this.div == null) {
this.div = OpenLayers.Util.createDiv();
}
if (px != null) {
this.position = px.copyOf();
}
this.moveTo(this.position);
return this.div;
},
/**
* @param {OpenLayers.Pixel} px
*/
moveTo: function (px) {
if ((px != null) && (this.div != null)) {
this.div.style.left = px.x + "px";
this.div.style.top = px.x + "px";
}
},
/**
*/
destroy: function () {
// eliminate circular references
this.map = null;
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control"
};
// @require: OpenLayers/Control.js
OpenLayers.Control.MouseDefaults = Class.create();
OpenLayers.Control.MouseDefaults.prototype =
Object.extend( new OpenLayers.Control(), {
initialize: function() {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
},
draw: function() {
this.map.events.register( "dblclick", this, this.defaultDblClick );
this.map.events.register( "mousedown", this, this.defaultMouseDown );
this.map.events.register( "mouseup", this, this.defaultMouseUp );
this.map.events.register( "mousemove", this, this.defaultMouseMove );
this.map.events.register( "mouseout", this, this.defaultMouseOut );
},
/**
* @param {Event} evt
*/
defaultDblClick: function (evt) {
var newCenter = this.map.getLonLatFromScreenPx( evt.xy );
this.map.setCenter(newCenter, this.map.zoom + 1);
},
/**
* @param {Event} evt
*/
defaultMouseDown: function (evt) {
this.mouseDragStart = evt.xy.copyOf();
if (evt.shiftKey) {
this.map.div.style.cursor = "crosshair";
this.zoomBox = OpenLayers.Util.createDiv('zoomBox',
this.mouseDragStart,
null,
null,
"absolute",
"2px solid red");
this.zoomBox.style.backgroundColor = "white";
this.zoomBox.style.filter = "alpha(opacity=50)"; // IE
this.zoomBox.style.opacity = "0.50";
this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
this.map.viewPortDiv.appendChild(this.zoomBox);
} else {
this.map.div.style.cursor = "move";
}
Event.stop(evt);
},
/**
* @param {Event} evt
*/
defaultMouseMove: function (evt) {
if (this.mouseDragStart != null) {
if (this.zoomBox) {
var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x);
var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y);
this.zoomBox.style.width = deltaX+"px";
this.zoomBox.style.height = deltaY+"px";
if (evt.xy.x < this.mouseDragStart.x) {
this.zoomBox.style.left = evt.xy.x+"px";
}
if (evt.xy.y < this.mouseDragStart.y) {
this.zoomBox.style.top = evt.xy.y+"px";
}
} else {
var deltaX = this.mouseDragStart.x - evt.xy.x;
var deltaY = this.mouseDragStart.y - evt.xy.y;
var size = this.map.getSize();
var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,
size.h / 2 + deltaY);
var newCenter = this.map.getLonLatFromScreenPx( newXY );
this.map.setCenter(newCenter);
this.mouseDragStart = evt.xy.copyOf();
}
}
},
/**
* @param {Event} evt
*/
defaultMouseUp: function (evt) {
if (this.zoomBox) {
var start = this.map.getLonLatFromScreenPx( this.mouseDragStart );
var end = this.map.getLonLatFromScreenPx( evt.xy );
var top = Math.max(start.lat, end.lat);
var bottom = Math.min(start.lat, end.lat);
var left = Math.min(start.lon, end.lon);
var right = Math.max(start.lon, end.lon);
var bounds = new OpenLayers.Bounds(left, bottom, right, top);
var zoom = this.map.getZoomForExtent(bounds);
this.map.setCenter(new OpenLayers.LonLat(
(start.lon + end.lon) / 2,
(start.lat + end.lat) / 2
), zoom);
this.map.viewPortDiv.removeChild(document.getElementById("zoomBox"));
this.zoomBox = null;
}
this.mouseDragStart = null;
this.map.div.style.cursor = "default";
},
defaultMouseOut: function (evt) {
if (this.mouseDragStart != null
&& OpenLayers.Util.mouseLeft(evt, this.map.div)) {
this.defaultMouseUp(evt);
}
}
});
// @require: OpenLayers/Control.js
OpenLayers.Control.KeyboardDefaults = Class.create();
OpenLayers.Control.KeyboardDefaults.prototype =
Object.extend( new OpenLayers.Control(), {
initialize: function() {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
},
draw: function() {
Event.observe(document, 'keypress', this.defaultKeyDown.bind(this.map));
},
/**
* @param {Event} evt
*/
defaultKeyDown: function (evt) {
var i = 0;
switch(evt.keyCode) {
case Event.KEY_LEFT:
var resolution = this.getResolution();
var center = this.getCenter();
this.setCenter(
new OpenLayers.LonLat(center.lon - (resolution * 50),
center.lat)
);
Event.stop(evt);
break;
case Event.KEY_RIGHT:
var resolution = this.getResolution();
var center = this.getCenter();
this.setCenter(
new OpenLayers.LonLat(center.lon + (resolution * 50),
center.lat)
);
Event.stop(evt);
break;
case Event.KEY_UP:
var resolution = this.getResolution();
var center = this.getCenter();
this.setCenter(
new OpenLayers.LonLat(center.lon,
center.lat + (resolution * 50))
);
Event.stop(evt);
break;
case Event.KEY_DOWN:
var resolution = this.getResolution();
var center = this.getCenter();
this.setCenter(
new OpenLayers.LonLat(center.lon,
center.lat - (resolution * 50))
);
Event.stop(evt);
break;
}
}
});
// @require: OpenLayers/Control.js
//
// default zoom/pan controls
//
OpenLayers.Control.PanZoom = Class.create();
OpenLayers.Control.PanZoom.X = 4;
OpenLayers.Control.PanZoom.Y = 4;
OpenLayers.Control.PanZoom.prototype =
Object.extend( new OpenLayers.Control(), {
/** @type Array(...) */
buttons: null,
initialize: function() {
OpenLayers.Control.prototype.initialize.apply(this, arguments);
this.position = new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,
OpenLayers.Control.PanZoom.Y);
},
/**
* @param {OpenLayers.Pixel} px
*/
draw: function(px) {
// initialize our internal div
OpenLayers.Control.prototype.draw.apply(this, arguments);
px = this.position;
// place the controls
this.buttons = new Array();
var sz = new OpenLayers.Size(18,18);
var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);
this._addButton("panup", "north-mini.png", centered, sz);
px.y = centered.y+sz.h;
this._addButton("panleft", "west-mini.png", px, sz);
this._addButton("panright", "east-mini.png", px.add(sz.w, 0), sz);
this._addButton("pandown", "south-mini.png", centered.add(0, sz.h*2), sz);
this._addButton("zoomin", "zoom-plus-mini.png", centered.add(0, sz.h*3+5), sz);
this._addButton("zoomworld", "zoom-world-mini.png", centered.add(0, sz.h*4+5), sz);
this._addButton("zoomout", "zoom-minus-mini.png", centered.add(0, sz.h*5+5), sz);
return this.div;
},
_addButton:function(id, img, xy, sz) {
var imgLocation = OpenLayers.Util.getImagesLocation() + img;
// var btn = new ol.AlphaImage("_"+id, imgLocation, xy, sz);
var btn = OpenLayers.Util.createAlphaImageDiv(
"OpenLayers_Control_PanZoom_" + id,
xy, sz, imgLocation, "absolute");
//we want to add the outer div
this.div.appendChild(btn);
btn.onmousedown = this.buttonDown.bindAsEventListener(btn);
btn.ondblclick = this.doubleClick.bindAsEventListener(btn);
btn.action = id;
btn.map = this.map;
//we want to remember/reference the outer div
this.buttons.push(btn);
return btn;
},
doubleClick: function (evt) {
Event.stop(evt);
},
buttonDown: function (evt) {
switch (this.action) {
case "panup":
var resolution = this.map.getResolution();
var center = this.map.getCenter();
this.map.setCenter(
new OpenLayers.LonLat(center.lon,
center.lat + (resolution * 50))
);
break;
case "pandown":
var resolution = this.map.getResolution();
var center = this.map.getCenter();
this.map.setCenter(
new OpenLayers.LonLat(center.lon,
center.lat - (resolution * 50))
);
break;
case "panleft":
var resolution = this.map.getResolution();
var center = this.map.getCenter();
this.map.setCenter(
new OpenLayers.LonLat(center.lon - (resolution * 50),
center.lat)
);
break;
case "panright":
var resolution = this.map.getResolution();
var center = this.map.getCenter();
this.map.setCenter(
new OpenLayers.LonLat(center.lon + (resolution * 50),
center.lat)
);
break;
case "zoomin": this.map.zoomIn(); break;
case "zoomout": this.map.zoomOut(); break;
case "zoomworld": this.map.zoomExtent(); break;
}
Event.stop(evt);
},
destroy: function() {
OpenLayers.Control.prototype.destroy.apply(this, arguments);
for(i=0; i<this.buttons.length; i++) {
this.buttons[i].map = null;
}
}
});
// @require: OpenLayers/Control/PanZoom.js
//
// default zoom/pan controls
//
OpenLayers.Control.PanZoomBar = Class.create();
OpenLayers.Control.PanZoomBar.X = 4;
OpenLayers.Control.PanZoomBar.Y = 4;
OpenLayers.Control.PanZoomBar.prototype =
Object.extend( new OpenLayers.Control.PanZoom(), {
/** @type Array(...) */
buttons: null,
/** @type int */
zoomStopWidth: 18,
/** @type int */
zoomStopHeight: 11,
initialize: function() {
OpenLayers.Control.PanZoom.prototype.initialize.apply(this, arguments);
this.position = new OpenLayers.Pixel(OpenLayers.Control.PanZoomBar.X,
OpenLayers.Control.PanZoomBar.Y);
},
/**
* @param {OpenLayers.Pixel} px
*/
draw: function(px) {
// initialize our internal div
OpenLayers.Control.prototype.draw.apply(this, arguments);
px = this.position;
// place the controls
this.buttons = new Array();
var sz = new OpenLayers.Size(18,18);
var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);
this._addButton("panup", "north-mini.png", centered, sz);
px.y = centered.y+sz.h;
this._addButton("panleft", "west-mini.png", px, sz);
this._addButton("panright", "east-mini.png", px.add(sz.w, 0), sz);
this._addButton("pandown", "south-mini.png", centered.add(0, sz.h*2), sz);
this._addButton("zoomin", "zoom-plus-mini.png", centered.add(0, sz.h*3+5), sz);
centered = this._addZoomBar(centered.add(0, sz.h*4 + 5));
this._addButton("zoomout", "zoom-minus-mini.png", centered, sz);
return this.div;
},
/**
* @param {OpenLayers.Pixel} location where zoombar drawing is to start.
*/
_addZoomBar:function(centered) {
var imgLocation = OpenLayers.Util.getImagesLocation();
var id = "OpenLayers_Control_PanZoomBar_Slider" + this.map.id;
var slider = OpenLayers.Util.createAlphaImageDiv(id,
centered.add(-1,
(this.map.getZoomLevels())*this.zoomStopHeight),
new OpenLayers.Size(20,9),
imgLocation+"slider.png",
"absolute");
slider.style.zIndex = this.div.zIndex + 5;
this.slider = slider;
this.sliderEvents = new OpenLayers.Events(this, slider);
this.sliderEvents.register("mousedown", this, this.zoomBarDown);
this.sliderEvents.register("mousemove", this, this.zoomBarDrag);
this.sliderEvents.register("mouseup", this, this.zoomBarUp);
this.sliderEvents.register("dblclick", this, this.doubleClick);
sz = new OpenLayers.Size();
sz.h = this.zoomStopHeight*(this.map.getZoomLevels()+1);
sz.w = this.zoomStopWidth;
var div = null
if (OpenLayers.Util.alphaHack()) {
var id = "OpenLayers_Control_PanZoomBar" + this.map.id;
div = OpenLayers.Util.createAlphaImageDiv(id, centered,
new OpenLayers.Size(sz.w,
this.zoomStopHeight),
imgLocation + "zoombar.png",
"absolute", null, "crop");
div.style.height = sz.h;
} else {
div = OpenLayers.Util.createDiv(
'OpenLayers_Control_PanZoomBar_Zoombar' + this.map.id,
centered,
sz,
imgLocation+"zoombar.png");
}
this.zoombarDiv = div;
this.divEvents = new OpenLayers.Events(this, div);
this.divEvents.register("mousedown", this, this.divClick);
this.divEvents.register("mousemove", this, this.passEventToSlider);
this.divEvents.register("dblclick", this, this.doubleClick);
this.div.appendChild(div);
this.startTop = parseInt(div.style.top);
this.div.appendChild(slider);
this.map.events.register("zoomend", this, this.moveZoomBar);
centered = centered.add(0,
this.zoomStopHeight*(this.map.getZoomLevels()+1));
return centered;
},
/*
* @param evt
* This function is used to pass events that happen on the div, or the map,
* through to the slider, which then does its moving thing.
*/
passEventToSlider:function(evt) {
this.sliderEvents.handleBrowserEvent(evt);
},
/*
* divClick: Picks up on clicks directly on the zoombar div
* and sets the zoom level appropriately.
*/
divClick: function (evt) {
var y = evt.xy.y;
var top = Position.page(evt.object)[1];
var levels = Math.floor((y - top)/this.zoomStopHeight);
this.map.zoomTo(this.map.getZoomLevels() - levels);
Event.stop(evt);
},
/*
* @param evt
* event listener for clicks on the slider
*/
zoomBarDown:function(evt) {
this.map.events.register("mousemove", this, this.passEventToSlider);
this.map.events.register("mouseup", this, this.passEventToSlider);
this.mouseDragStart = evt.xy.copyOf();
this.zoomStart = evt.xy.copyOf();
this.div.style.cursor = "move";
Event.stop(evt);
},
/*
* @param evt
* This is what happens when a click has occurred, and the client is dragging.
* Here we must ensure that the slider doesn't go beyond the bottom/top of the
* zoombar div, as well as moving the slider to its new visual location
*/
zoomBarDrag:function(evt) {
if (this.mouseDragStart != null) {
var deltaY = this.mouseDragStart.y - evt.xy.y
var offsets = Position.page(this.zoombarDiv);
if ((evt.clientY - offsets[1]) > 0 &&
(evt.clientY - offsets[1]) < parseInt(this.zoombarDiv.style.height) - 2) {
var newTop = parseInt(this.slider.style.top) - deltaY;
this.slider.style.top = newTop+"px";
}
this.mouseDragStart = evt.xy.copyOf();
}
Event.stop(evt);
},
/*
* @param evt
* Perform cleanup when a mouseup event is received -- discover new zoom level
* and switch to it.
*/
zoomBarUp:function(evt) {
if (this.zoomStart) {
this.div.style.cursor="default";
this.map.events.remove("mousemove");
this.map.events.remove("mouseup");
var deltaY = this.zoomStart.y - evt.xy.y
this.map.zoomTo(this.map.zoom + Math.round(deltaY/this.zoomStopHeight));
this.moveZoomBar();
this.mouseDragStart = null;
Event.stop(evt);
}
},
/*
* Change the location of the slider to match the current zoom level.
*/
moveZoomBar:function() {
var newTop =
(this.map.getZoomLevels() - this.map.getZoom()) * this.zoomStopHeight
+ this.startTop + 1;
this.slider.style.top = newTop + "px";
},
CLASS_NAME: "OpenLayers.Control.PanZoomBar"
});
// @require: OpenLayers/Control.js
/**
* @class
*/
OpenLayers.Control.LayerSwitcher = Class.create();
/** color used in the UI to show a layer is active/displayed
*
* @final
* @type String
*/
OpenLayers.Control.LayerSwitcher.ACTIVE_COLOR = "darkblue";
/** color used in the UI to show a layer is deactivated/hidden
*
* @final
* @type String
*/
OpenLayers.Control.LayerSwitcher.NONACTIVE_COLOR = "lightblue";
OpenLayers.Control.LayerSwitcher.prototype =
Object.extend( new OpenLayers.Control(), {
/** @type String */
activeColor: "",
/** @type String */
nonActiveColor: "",
/** @type String */
mode: "checkbox",
/**
* @constructor
*/
initialize: function(options) {
this.activeColor = OpenLayers.Control.LayerSwitcher.ACTIVE_COLOR;
this.nonActiveColor = OpenLayers.Control.LayerSwitcher.NONACTIVE_COLOR;
this.backdrops = [];
OpenLayers.Control.prototype.initialize.apply(this, arguments);
},
/**
* @returns A reference to the DIV DOMElement containing the switcher tabs
* @type DOMElement
*/
draw: function() {
// initialize our internal div
OpenLayers.Control.prototype.draw.apply(this);
this.div.style.position = "absolute";
this.div.style.top = "10px";
this.div.style.right = "0px";
this.div.style.left = "";
this.div.style.fontFamily = "sans-serif";
this.div.style.color = "white";
this.div.style.fontWeight = "bold";
this.div.style.marginTop = "3px";
this.div.style.marginLeft = "3px";
this.div.style.marginBottom = "3px";
this.div.style.fontSize="smaller";
this.div.style.width = "10em";
this.map.events.register("addlayer", this, this.redraw);
return this.redraw();
},
/**
* @returns A reference to the DIV DOMElement containing the switcher tabs
* @type DOMElement
*/
redraw: function() {
//clear out previous incarnation of LayerSwitcher tabs
this.div.innerHTML = "";
var visible = false;
for( var i = 0; i < this.map.layers.length; i++) {
if (visible && this.mode == "radio") {
this.map.layers[i].setVisibility(false);
} else {
visible = this.map.layers[i].getVisibility();
}
this.addTab(this.map.layers[i]);
}
return this.div;
},
/**
* @param {event} evt
*/
singleClick: function(evt) {
var div = Event.element(evt);
var layer = div.layer;
if (this.mode == "radio") {
for(var i=0; i < this.backdrops.length; i++) {
this.setTabActivation(this.backdrops[i], false);
this.backdrops[i].layer.setVisibility(false);
}
this.setTabActivation(div, true);
layer.setVisibility(true);
} else {
var visible = layer.getVisibility();
this.setTabActivation(div, !visible);
layer.setVisibility(!visible);
}
Event.stop(evt);
},
/**
* @param {event} evt
*/
doubleClick: function(evt) {
Event.stop(evt);
},
/**
* @private
*
* @param {OpenLayers.Layer} layer
*/
addTab: function(layer) {
// Outer DIV - for Rico Corners
//
var backdropLabelOuter = document.createElement('div');
backdropLabelOuter.id = "LayerSwitcher_" + layer.name + "_Tab";
backdropLabelOuter.style.marginTop = "4px";
backdropLabelOuter.style.marginBottom = "4px";
// Inner Label - for Rico Corners
//
var backdropLabel = document.createElement('p');
backdropLabel.innerHTML = layer.name;
backdropLabel.style.marginTop = "0px";
backdropLabel.style.marginBottom = "0px";
backdropLabel.style.paddingLeft = "10px";
backdropLabel.style.paddingRight = "10px";
// add reference to layer onto the div for use in event handlers
backdropLabel.layer = layer;
// set event handlers
backdropLabel.ondblclick = this.doubleClick.bindAsEventListener(this);
backdropLabel.onmousedown = this.singleClick.bindAsEventListener(this);
// add label to div
backdropLabelOuter.appendChild(backdropLabel);
this.backdrops.append(backdropLabel);
// add div to main LayerSwitcher Div
this.div.appendChild(backdropLabelOuter);
Rico.Corner.round(backdropLabelOuter, {corners: "tl bl",
bgColor: "transparent",
color: "white",
blend: false});
this.setTabActivation(backdropLabel, layer.getVisibility());
},
/**
* @private
*
* @param {DOMElement} div
* @param {Boolean} activate
*/
setTabActivation:function(div, activate) {
var color = (activate) ? this.activeColor : this.nonActiveColor;
Rico.Corner.changeColor(div, color);
},
/** @final @type String */
CLASS_NAME: "OpenLayers.Control.LayerSwitcher"
});