/*
* 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
*/
/**
* @requires OpenLayers/Feature.js
* @requires OpenLayers/Layer/Markers.js
* @requires BKGWebMap/Util.js
* @requires BKGWebMap/Popup.js
* @requires BKGWebMap/Layer.js
*/
/**
* @classdesc Klasse für Layer zum Hinzufügen von Markern mit Popupfunktion
*
* @constructor BKGWebMap.Layer.MarkerLayer
* @param {string} name - Der Layername
* @param {object} options - weitere Optionen für den Layer
**/
BKGWebMap.Layer.MarkerLayer = OpenLayers.Class(OpenLayers.Layer.Markers, {
/**
* @memberOf BKGWebMap.Layer.MarkerLayer
* @type Array<OpenLayers.Feature.Vector>
*/
features: null,
initialize:function(name, options) {
OpenLayers.Layer.Markers.prototype.initialize.apply(this, arguments);
this.features = [];
// Touch Event für Mobilgeräte registrieren
this.events.register("touchstart", this, function(e) { /* ??? */ });
},
destroy: function() {
this.removeAllFeatures();
this.features = null;
OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);
},
clearMarkers: function() {
this.removeAllFeatures();
OpenLayers.Layer.Markers.prototype.clearMarkers.apply(this, arguments);
},
/**
* Erzeugt ein OpenLayers.Marker Objekt zum Einfügen in den Layer.
* @memberOf BKGWebMap.Layer.MarkerLayer
* @param {Array|OpenLayers.LonLat} coords - Die Koordinaten des Markers
* @param {string} contentHTML - HTML-Inhalt für das Popup
* @param {Object} options - weitere Eigenschaften für das Popup.
* @param {boolean} options.closeBox - <code>true</code> wenn Icon zum Schließen des Popups angezeigt werden soll.
* @param {OpenLayers.Size} options.popupSize - Größe für Popup
* @param {string} options.overflow - CSS-Wert für Overflow verhalten.
* @return {OpenLayers.Marker}
*/
createMarker: function(coords, contentHTML, options) {
if( !(coords instanceof OpenLayers.LonLat) ) {
coords = new OpenLayers.LonLat(coords);
}
options = options ? options : {overflow: 'auto', closeBox: 'true'};
options.popupContentHTML = contentHTML;
var feature = new OpenLayers.Feature(this, coords, options);
return this.createFeatureMarker(feature);
},
/**
* Generiert einen Marker für ein Feature.
*
* @memberOf BKGWebMap.Layer.MarkerLayer
* @param {OpenLayers.Feature} feature - Das Feature, für das der Marker generiert werden soll
* @param {OpenLayers.Class} popupClass - Klasse für Popup, das geöffnet werden soll, wenn der Marker geklickt wird.
* @returns {OpenLayers.Marker}
*/
createFeatureMarker: function(feature, popupClass) {
feature.popupClass = popupClass || BKGWebMap.Popup;
var marker = feature.createMarker();
// Fallback für OpenLayers.Feature.Vector
if(!marker) {
// Mitte der Geometrie ermitteln:
var center = feature.geometry.getCentroid();
feature.lonlat = new OpenLayers.LonLat(center.x, center.y);
marker = new OpenLayers.Marker(feature.lonlat, feature.data.icon);
}
if(!marker) return null;
marker.feature = feature;
feature.marker = marker;
marker.events.register("mousedown", feature, function(evt) {
BKGWebMap.Layer.MarkerLayer.togglePopup(this);
OpenLayers.Event.stop(evt);
});
return marker;
},
/**
* Fügt einen Marker in den Layer ein.
*
* Im Gegensatz zu addMarker wird hier ein neues OpenLayers.Marker Objekt dynamisch erzeugt.
*
* @memberOf BKGWebMap.Layer.MarkerLayer
*
* @param {Array|OpenLayers.LonLat} coords - Die Koordinaten des Markers
* @param {string} contentHTML - HTML-Inhalt für das Popup
* @param {Object} options - weitere Eigenschaften für das Popup.
* @param {boolean} options.closeBox - <code>true</code> wenn Icon zum Schließen des Popups angezeigt werden soll.
* @param {OpenLayers.Size} options.popupSize - Größe für Popup
* @param {string} options.overflow - CSS-Wert für Overflow verhalten.
*/
mark: function(coords, contentHTML, options) {
var marker = this.createMarker(coords, contentHTML, options);
this.addMarker(marker);
},
/**
* Markiert alle Features mit einem Marker. Verwendet dazu die Mitte der Geometrie.
*
* @memberOf BKGWebMap.Layer.MarkerLayer
* @param {Array<OpenLayers.Feature.Vector>} features - die hinzuzufügenden Features
* @param {function} getContent - optionale Funktion zur Generierung des HTML-Inhalts für ein Popup
*/
addFeatures: function(features, getContent) {
if (!(OpenLayers.Util.isArray(features))) {
features = [features];
}
for (var i=0, len=features.length; i<len; i++) {
var feature = features[i];
// Gib Feature Referenz zu diesem Layer
// TODO: sollte hier anderer Propertyname verwendet werden, falls Features in mehrere Layer eingefügt wird?
feature.layer = this;
var marker = this.createFeatureMarker(feature);
if(!marker) {
continue;
}
// zusätzliche Popup-Optionen setzen falls nötig
feature.data = OpenLayers.Util.applyDefaults(feature.data, {overflow: 'auto', closeBox: 'true'});
// generiere Popup-Inhalt
if(!feature.data.popupContentHTML && getContent) {
feature.data.popupContentHTML = getContent(feature, i);
}
this.features.push(feature);
this.addMarker(marker);
}
},
/**
* Löscht alle Features und deren Marker
* @memberOf BKGWebMap.Layer.MarkerLayer
*/
removeAllFeatures: function() {
if(!this.features) return;
var features = this.features;
var feature;
for (var i = features.length-1; i >= 0; i--) {
feature = features[i];
feature.layer = null;
this.removeMarker(feature.marker);
feature.marker = null;
if(this.map && feature.popup) {
this.map.removePopup(feature.popup);
}
feature.popup = null;
}
this.features = [];
},
CLASS_NAME: "BKGWebMap.Layer.MarkerLayer"
});
/**
* Blended das Popup eines Markers ein oder aus.
*
* @memberOf BKGWebMap.Layer.MarkerLayer
* @param {Event} evt - der Mousedown-Event
*/
BKGWebMap.Layer.MarkerLayer.togglePopup = function (feature) {
if (feature.popup == null) {
feature.popup = feature.createPopup(feature.data.closeBox);
// Fallback für OpenLayers.Feature.Vector
if (!feature.popup) {
feature.popup = OpenLayers.Feature.prototype.createPopup.apply(feature, [feature.data.closeBox]);
}
if (!feature.popup) return;
// autoSize abstellen falls explizit Größe übergeben wurde.
if (feature.data.popupSize) {
feature.popup.autoSize = false;
}
feature.layer.map.addPopup(feature.popup);
feature.popup.show();
} else {
feature.popup.toggle();
}
};