/*
* Copyright (c) 2014 Bundesamt für Kartographie und Geodäsie.
* See license.txt in the BKG WebMap distribution or repository for the
* full text of the license.
*
* Author: Dirk Thalheim
*/
/**
* @requires OpenLayers/BaseTypes/Class.js
* @requires OpenLayers/Control/WMSGetFeatureInfo.js
* @requires BKGWebMap/Control.js
* @requires BKGWebMap/Util.js
*/
/**
* WMSGetFeatureInfo stellt ein Tool bereit, mit welchem GetFeatureInfo abfragen auf die Layer in der Karte durchgeführt
* werden können. Standardmäßig werden alle aktiven WMS-Layer abgefragt. Über den Einstellungs-Button können explizit
* einzelne Layer ausgewählt werden.
* <br/>
* Das Ergebnis wird in einem PopUp an der Stelle des Clicks angezeigt.
*
* TODO: ein einzelner Layer -> url setzen
* TODO: alle Layer (mehrere URLs) -> drillDown = true & InfoFormat parseable
*
* @classdesc Erweiterte WMSGetFeatureInfo für BKG-Dienste
*
* @constructor BKGWebMap.Control.WMSGetFeatureInfo
* @param {object} options - Optionen für das Controlelement
**/
BKGWebMap.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control.WMSGetFeatureInfo, {
title: 'FeatureInfo',
queryVisible: true,
textHandler: null,
popupSize: new OpenLayers.Size(200, 150),
popupAutoSize: false,
emptyMessage: 'Die Abfrage lieferte keine Ergebnisse!',
initialize:function(options) {
if(!options.eventListeners) {
options.eventListeners = { getfeatureinfo: this.handleFeatureInfoResponse }
}
OpenLayers.Control.WMSGetFeatureInfo.prototype.initialize.apply(this, [options]);
if (this.infoFormat == 'application/geojson') {
this.format = new OpenLayers.Format.GeoJSON();
this.textHandler = this.textHandler || new BKGWebMap.Control.WMSGetFeatureInfo.GeoJSONTextTransformer();
} else {
this.textHandler = this.textHandler || new BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer();
}
},
/**
* Bugfix: Baselayers, die nicht aktiv sind, sollen nicht mit angefragt werden.
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo
*/
request: function (clickPosition, options) {
this._text = null;
this._requestCount = 0;
OpenLayers.Control.WMSGetFeatureInfo.prototype.request.apply(this, [clickPosition, options]);
},
/**
* Bugfix: Baselayers, die nicht aktiv sind, sollen nicht mit angefragt werden.
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo
*/
findLayers: function () {
var layers = OpenLayers.Control.WMSGetFeatureInfo.prototype.findLayers.apply(this);
var map = this.map;
layers = BKGWebMap.Util.grep(layers, function(layer) {
if(!(layer instanceof OpenLayers.Layer.WMS))
return true;
return !layer.isBaseLayer || layer==map.baseLayer;
});
return layers;
},
/**
* Überschreibt das Standardverhalten des WMSGetFeatureInfo, damit auch bei dirllDown Texte ergänzt werden.
*
* @param xy {OpenLayers.Pixel} - The position on the map where the
* @param request {XMLHttpRequest} - The request object
* @param url {String} - The url which was used for this request.
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo
*/
handleResponse: function (xy, request, url) {
var doc = request.responseXML;
if (!doc || !doc.documentElement) {
doc = request.responseText;
}
var features = this.format.read(doc);
if (this.drillDown === false) {
this.triggerGetFeatureInfo(request, xy, features);
} else {
this._requestCount++;
if (this.output === "object") {
this._features = (this._features || []).concat( {url: url, features: features} );
} else {
this._features = (this._features || []).concat(features);
}
this._text = (this._text || '');
this._text += '<h2>' + url + '</h2>';
this._text += request.responseText;
this._text += '<hr/><p/>';
if (this._requestCount === this._numRequests) {
// modify request object
request.responseText = this._text;
this.triggerGetFeatureInfo(request, xy, this._features.concat());
delete this._features;
delete this.text;
delete this._requestCount;
delete this._numRequests;
}
}
},
/**
* Standard-Eventhandler für GetFeature-Response
* @param event - Event-Objekt mit GetFeatureInfo Response
* @param event.text - Antwort des Servers
* @param event.object - diese Control-Instanz
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo
*/
handleFeatureInfoResponse: function(event) {
var text = event.object.parseText(event.text, event.features, event.xy);
var popup = new BKGWebMap.Popup (
null,
event.object.map.getLonLatFromPixel(event.xy),
this.popupSize,
text,
null,
true
);
popup.autoSize = event.object.popupAutoSize;
map.addPopup(popup);
},
/**
* Methode zur Anpassung der Serverantwort für Darstellung im Popup
* @param text {string} - Die GetFeatureInfo-Antwort
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo
*/
parseText: function(text, features, xy) {
text = this.textHandler.handle(text, features, xy);
return (!text) ? this.emptyMessage : text;
},
CLASS_NAME: "BKGWebMap.Control.WMSGetFeatureInfo"
});
/**
* @classdesc Hilfsklasse zur Transformation von WMSGetFeatureInfo-Responses in Text für das Info-PopUp.
*
* @constructor BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer
**/
BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer = OpenLayers.Class({
initialize: function(options) {
OpenLayers.Util.extend(this, options);
},
/**
* Wandelt den Text für das PopUp. Für diese Implementierung wird nichts getan.
* @param text {string}
* @returns {string}
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer
*/
handle: function(text, features, xy) {
return text;
}
});
/**
* @classdesc Hilfklasse zur Transformation von WMSGetFeatureInfo-Responses in Text für das Info-PopUp
*
* @constructor BKGWebMap.Control.WMSGetFeatureInfo.GeoJSONTextTransformer
**/
BKGWebMap.Control.WMSGetFeatureInfo.GeoJSONTextTransformer =
OpenLayers.Class(BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer, {
initialize: function(options) {
OpenLayers.Util.extend(this, options);
},
/**
* Wandelt den Text für das PopUp in GeoJSON und gibt alle Attribute aus.
* @param text {string}
* @returns {string}
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo.GeoJSONTextTransformer
*/
handle: function(text, features, xy) {
var content = '';
BKGWebMap.Util.each(features, function(index, feature) {
content += '<div class="feature">';
for(var key in feature.attributes) {
if(!feature.attributes.hasOwnProperty(key)) continue;
content += '<label>' + key + ':</label> ' + feature.attributes[key] + '<br/>'
}
content += '</div>';
});
return content;
}
});
/**
* @classdesc Hilfklasse zur Transformation von WMSGetFeatureInfo-Responses in Text für das Info-PopUp
*
* @constructor BKGWebMap.Control.WMSGetFeatureInfo.TextTransformer
**/
BKGWebMap.Control.WMSGetFeatureInfo.DOPInfoTextTransformer =
OpenLayers.Class(BKGWebMap.Control.WMSGetFeatureInfo.GeoJSONTextTransformer, {
/**
* Wandelt den Text für das PopUp. Für diese Implementierung wird nichts getan.
* @param text {string}
* @returns {string}
* @memberOf BKGWebMap.Control.WMSGetFeatureInfo.DOPInfoTextTransformer
*/
handle: function(text, features, xy) {
var content = '';
BKGWebMap.Util.each(features, function(index, feature) {
if(feature == null) return;
content +=
'<div class="feature">' +
'<h2>Kachel ' + feature.attributes['ID'] + '</h2>' +
'<label>Bundesland:</label> ' + feature.attributes['LAND'].toUpperCase() + '<br/>' +
'<label>Bildflug:</label> ' + feature.attributes['BILDFLUG'] + '<br/>' +
'</div>';
});
return content;
}
});
/**
* Fügt FeatureInfo der Control-Liste hinzu.
* @param {Array<OpenLayers.Control>} controls - Liste der Steuerelemente, in die die neue erzeugten Steuerelemente
* eingefügt werden sollen.
* @param {object} config - Konfiguration für das FeatureInfo-Steuerelement (s. Konstruktor OpenLayers.Control.WMSGetFeatureInfo).
*/
BKGWebMap.Control.FACTORIES['featureInfo'] = function(controls, config) {
if (!config) return;
controls.push(new BKGWebMap.Control.WMSGetFeatureInfo(config));
};