/*
* Copyright (c) 2013 Bundesamt by Kartographie und Geodäsie.
* See license.txt in the BKG WebMap distribution or repository for the
* full text of the license.
*
* Author: Dirk Thalheim
*/
/**
* @namespace BKGWebMap.Util
*/
BKGWebMap.Util = BKGWebMap.Util || {};
/**
* Funktion zur Filterung von Elementen aus einer Liste.
* @param {Array} elements - die zu durchsuchenden Elemente
* @param {function} filter - die Filterfunktion
*/
BKGWebMap.Util.grep = function(elements, filter) {
var results = [];
if(!elements || !elements.length) {
return results;
}
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if(filter(element, i)) results.push(element);
}
return results;
};
/**
* Hilfsfunktion für die Iteration durch Elemente einer Liste.
* @param {Array} elements - die zu durchsuchenden Elemente
* @param {function} method - Funktion für jeden Iterationsschritt
*/
BKGWebMap.Util.each = function(elements, method) {
if(!elements || !elements.length) {
return;
}
for (var i = 0; i < elements.length; i++) {
method( i, elements[i] );
}
};
/**
* Hilfsfunktion um Elemente einer Liste zu 'mappen'. Es können weitere statische Argumente übergeben werden, die an
* die Methode übergeben werden.
*
* @param {function} method - Funktion für jeden Iterationsschritt
* @param {Array} elements - die zu durchsuchenden Elemente
* @return {Array}
*/
BKGWebMap.Util.map = function(method, elements) {
if(!elements || !elements.length) {
return [];
}
// weitere optionale Argumente ermitteln
var staticArgs = (arguments.length == 2) ? [] : Array.prototype.slice.call(arguments, 2, arguments.length);
var result = [];
for (var i = 0; i < elements.length; i++) {
var args = [elements[i]];
args = args.concat(staticArgs);
result.push( method.apply( this, args ) );
}
return result;
};
/**
* Kapitalisiert den gegebenen String.
* @param {string} str - Der zu kapitalisierende String
* @returns {string}
*/
BKGWebMap.Util.capitalize = function(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
};
BKGWebMap.Util.getEventTarget = function (e) {
var target;
if (e.target) target = e.target;
else if (e.srcElement) target = e.srcElement;
if (target.nodeType == 3) // defeat Safari bug
target = targ.parentNode;
return target;
};
/**
* Gibt den Index des elements innerhalb seiner DOM-Ebene an.
*
* @param {node} element
* @returns {number}
*/
BKGWebMap.Util.getIndex = function(element) {
var k=0, e=element;
while (e = e.previousSibling) { k++;}
return k;
};
/**
* Berechnet die Datenausdehnung für eine Featurecollection. Über geometry kann eine alternative
* Geometrie aus den Attributen verwendet werden.
*
* @param {Array<OpenLayers.Feature>} features - Die FeatureCollection
* @param {string} geometry - Attributname der alternativen Geometrie
* @return OpenLayers.Bounds oder <code>null</code> wenn keine Features gegeben sind
*/
BKGWebMap.Util.getDataExtent = function (features, geometry) {
var bounds = new OpenLayers.Bounds();
var g = geometry;
BKGWebMap.Util.each(
features,
function(index, feature) {
var geometry = g ? feature.attributes[g] : feature.geometry;
bounds.extend(geometry.getBounds());
}
);
return bounds;
};
BKGWebMap.Util.getSize = function(element) {
var cStyle = element.ownerDocument && element.ownerDocument.defaultView &&
element.ownerDocument.defaultView.getComputedStyle &&
element.ownerDocument.defaultView.getComputedStyle(element, null);
var w = cStyle && cStyle.getPropertyValue('width') || '';
var h = cStyle && cStyle.getPropertyValue('height') || '';
if (w && w.indexOf('.') > -1) {
w = parseFloat(w) +
parseInt(cStyle.getPropertyValue('padding-left')) +
parseInt(cStyle.getPropertyValue('padding-right')) +
parseInt(cStyle.getPropertyValue('border-left-width')) +
parseInt(cStyle.getPropertyValue('border-right-width'));
} else {
w = element.offsetWidth;
}
if (h && h.indexOf('.') > -1) {
h = parseFloat(w) +
parseInt(cStyle.getPropertyValue('padding-top')) +
parseInt(cStyle.getPropertyValue('padding-bottom')) +
parseInt(cStyle.getPropertyValue('border-top-width')) +
parseInt(cStyle.getPropertyValue('border-bottom-width'));
} else {
h = element.offsetWidth;
}
return new OpenLayers.Size(w, h);
};
/**
* Hilfsfunktion zum Stoppen eines Events
* @param {Event} evt - Der zu stoppende Event
*/
BKGWebMap.Util.stopEvent = function(evt) {
OpenLayers.Event.stop(evt, true);
};
/**
* Hilfsmethode zum ermitteln von berechneten Style-Eigenschaften
* @param {HTMLElement} element - das zu untersuchende Element
* @param {string} property - der Name für die CSS-Eigenschaft
* @return {string}
*/
BKGWebMap.Util.getStyle = function(element, property) {
if(window.getComputedStyle) {
// Non IE
return getComputedStyle(element, null)[property];
} else {
// IE < 9
return element.currentStyle[property];
}
};
/**
* Testet ob eine Variable leer ist.
* @param obj {*} das zu testende Objekt
* @return {boolean}
*/
BKGWebMap.Util.isEmpty = function(obj) {
if (obj === undefined) return true;
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and toValue enumeration bugs in IE < 9
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) return false;
}
return true;
};
/**
* Ermittelt die Projektion, die per URL-Parameter übergeben wurde
* @param def {string} Default Projektion
* @param key {string} Name des Parameters
* @return {string}
*/
BKGWebMap.Util.getProjection = function(def, key) {
def = def || BKGWebMap.PROJECTION;
key = key || 'CRS';
var parameters = OpenLayers.Util.getParameters();
return (key in parameters) ? parameters[key] : def;
};
/**
* Ermittelt den zur Projektion passenden Extent.
* @param projection {string} Name der Projektion
* @param extents {object} Map mit Extents
* @return {Array}
*/
BKGWebMap.Util.getMaxExtent = function(projection, extents) {
projection = projection || BKGWebMap.PROJECTION;
return (projection in extents) ? extents[projection] : null;
};
/**
* Erstellt die BKG Service-URL für den angegebenen Dienst. Hierbei wird das Protokoll der Webanwendung (HTTP/HTTPS).
*
* Wenn BKGWebMap.UUID gesetzt ist, wird diese zur Authentifizierung des Dienstes verwendet.
*
* Wenn BKGWebMap.APP_ID und BKGWebMap.APP_DOMAIN gesetzt sind, wird ein Session-Token generiert, der zur
* Authentifizierung des Dienstes verwendet.
*
* @param {string} service - Name des Dienstet (z.B. wmts_webatlasde)
* @param {string} [path=null] - Pfad des Dienstes (z.B. tile/1.0.0), default: null
* @param {boolean} [ignoreUuid=false] - soll UUID ignoriert werden, default: false
* @param {boolean} [useSgx=false] - soll sgx Subdomain für Zugriff verwendet werden, default: false
* @return {string}
*/
BKGWebMap.Util.getServiceUrl = function(service , path, ignoreUuid, useSgx) {
var path = (path) ? '/' + path : '';
var ignoreUuid = ignoreUuid || false;
var useSgx = useSgx || false;
var base = BKGWebMap.BASE_URL;
if(useSgx)
base = base.replace("/sg.", "/sgx.");
// Damit Cookies bei XHR gesendet werden, muss das Protokoll der Seite übereinstimmen
var useHttps = window.location.protocol.toLowerCase() == 'https:';
if (BKGWebMap.UUID && !ignoreUuid) {
// UUID bevorzugen
service = service + '__' + BKGWebMap.UUID;
// bei Verwendung des UUID darf nur HTTPS verwendet werden
useHttps = true;
} else if (BKGWebMap.APP_ID && BKGWebMap.APP_DOMAIN) {
if(!BKGWebMap._SESSION_TOKEN) {
BKGWebMap._SESSION_TOKEN = BKGWebMap.Util.getSessionToken(BKGWebMap.APP_ID, BKGWebMap.APP_DOMAIN);
}
if(BKGWebMap._SESSION_TOKEN.startsWith("sess-")) {
service = service + '__' + BKGWebMap._SESSION_TOKEN;
// bei Verwendung des SESSION_TOKEN darf nur HTTPS verwendet werden
useHttps = true;
}
}
// Protokoll anpassen
if(useHttps)
base = base.replace('http://', 'https://');
return base + service + path;
};
/**
* Generiert den Session-Token zur Authentifizierung von Zugriffsgeschützten Diensten.
*
* @param {string} appId - Applikationsschlüssel
* @param {string} appDomain - Applikationsdomain
* @return {string}
*/
BKGWebMap.Util.getSessionToken = function(appId , appDomain) {
try {
var baseURL = BKGWebMap.BASE_URL.replace('http://', 'https://');
var request = OpenLayers.Request.GET({
url: baseURL + "gdz_getSession",
params: {bkg_appid: appId, domain: appDomain},
async: false
});
if (request.status !== 200) {
console.log("Problem bei der Session-Initialisierung: " + request.responseText);
return "n.a.";
}
return request.responseText;
} catch (err) {
console.log(err);
return "n.a.";
}
};
/**
* Ermittelt die UUID aus einer URL. Die UUID UUID ist der erste URL-Bestandtteil der mit "__" eingeleitet wird.
*
* @param url {string} Die URL aus der die UUID ermittelt werden soll
* @return {string}
*/
BKGWebMap.Util.getUuidFromUrl = function(url) {
var pattern = /__([\w\d\-]+)/g;
var match = pattern.exec(url);
return (match == null) ? null : match[1];
};
// IE7 Fix
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (obj, start) {
for (var i = (start || 0), j = this.length; i < j; i++) {
if (this[i] === obj) {
return i;
}
}
return -1;
}
};
(function(fn){
if (!fn.map) fn.map=function(f){var r=[];for(var i=0;i<this.length;i++)r.push(f(this[i]));return r}
if (!fn.filter) fn.filter=function(f){var r=[];for(var i=0;i<this.length;i++)if(f(this[i]))r.push(this[i]);return r}
})(Array.prototype);