/**
* @class
* @constructor
* @param {cercaliax.KMLOptions} options Hash table with extra options to configure the KML layer
*/
cercalia.KML = function(options) {
/**
* Class name
* @private
* @type {string}
*/
this.CLASS_NAME_ = "cercalia.KML";
/**
* Name
* @private
* @type {string}
*/
this.name_ = options.name ? options.name : "cercalia.KML_" + new Date().getTime() + Math.round((Math.random()*1000));
/**
* Map
* @private
* @type {cercalia.Map|undefined}
*/
this.map_ = options.map ? options.map : undefined;
/**
* Name
* @private
* @type {string}
*/
this.imgDefault_ = options.imgDefault ? options.imgDefault : "https://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";
/**
* MinResolution
* The minimum resolution (inclusive) at which this layer will be visible.
* @private
* @type {number|undefined}
*/
this.minResolution_ = options.minResolution ? options.minResolution : undefined;
/**
* MaxResolution
* The maximum resolution (exclusive) below which this layer will be visible.
* @private
* @type {number|undefined}
*/
this.maxResolution_ = options.maxResolution ? options.maxResolution : undefined;
/**
* Opacity
* Opacity. 0-1. Default is 1
* @private
* @type {number|undefined}
*/
this.opacity_ = options.opacity ? options.opacity : 1;
/**
* Projection
* @private
* @type {string}
*/
this.srs_ = options.projection ? options.projection : 'EPSG:3857'; // o 'EPSG:3857' ?
/**
* Draggable
* Default is false
* @private
* @type {boolean}
*/
this.draggable_ = options.draggable ? options.draggable : false;
/**
* Url
* Required.
* @private
* @type {string}
*/
this.url_ = options.url;
/**
* Visible
* @private
* @type {boolean|undefined}
*/
this.visible_ = options.visible ? options.visible : true;
/**
* KML format
* @private
* @type {ol.format.KML}
*/
this.format_ = new ol.format.KML({
'maxDepth':10,
extractStyles: true,
defaultStyle:new ol.style.Style({
image: new ol.style.Circle({
radius: 7,
fill: new ol.style.Fill({
color: '#ffcc33'
})
})
})
});
/**
* Layer
* OL Vector
* @private
* @type {ol.layer.Vector}
*
*/
this.layer_ = null;
/**
* Source
* @private
* @type {ol.source.Vector}
*
*/
this.source_ = null;
this.defaultStyle_ = {
'Point': [new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255,255,0,0.5)'
}),
radius: 5,
stroke: new ol.style.Stroke({
color: '#ff0',
width: 1
})
})
})],
'LineString': [new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#f00',
width: 3
})
})],
'Polygon': [new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0,255,255,0.5)'
}),
stroke: new ol.style.Stroke({
color: '#0ff',
width: 1
})
})],
'MultiPoint': [new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255,0,255,0.5)'
}),
radius: 5,
stroke: new ol.style.Stroke({
color: '#f0f',
width: 1
})
})
})],
'MultiLineString': [new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#0f0',
width: 3
})
})],
'MultiPolygon': [new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0,0,255,0.5)'
}),
stroke: new ol.style.Stroke({
color: '#00f',
width: 1
})
})]
};
this.initialize_();
};
/*** INITIALIZE ***/
/**
* @private
*/
cercalia.KML.prototype.initialize_ = function () {
var self = this;
//creem el source KML
this.source_ = new ol.source.Vector({
url: this.url_,
projection : ol.proj.get('EPSG:3857'),
format: this.format_
});
//creem el vector
this.layer_ = new ol.layer.Vector({
source: this.source_,
minResolution : this.minResolution_,
maxResolution : this.maxResolution_,
opacity : this.opacity_,
visible : this.visible_
});
this.layer_.typeLayer = "cercalia.KML";
this.source_.typeSource = "cercalia.KML";
this.layer_.layer = this;
this.source_.layer = this;
if(this.map_){
this.map_.addLayer(this);
}
// The snap interaction must be added after the Modify and Draw interactions
// in order for its map browser event handlers to be fired first. Its handlers
// are responsible of doing the snapping.
/*var snap = new ol.interaction.Snap({
source: this.source_
});
this.map_.getMap().addInteraction(snap);*/
}
/*** GETTERS AND SETTERS ***/
/**
* We assign a map to the object. If it's already exist, is deleted in the existing
* map and KML layer is painted on the map passed as parameter.
* If parameter is "null", it's removed from the map.
*
* @param {cercalia.Map|null} map Map.
* @param {number} position ZIndex position from layers.
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setMap = function(map, position) {
if(this.map_){
this.map_.removeLayer(this.layer_);
}
if(map == null){
this.map_ = null;
}else{
this.map_ = map;
this.map_.addLayer(this.layer_, position);
}
//Posem si es dragable
if(this.map_){
this.setDraggable(this.draggable_);
}
return this;
};
/**
* return cercalia map
* @return {cercalia.Map|undefined} map
*/
cercalia.KML.prototype.getMap = function() {
return this.map_;
}
/**
*
* @param {number} minResolution
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setMinResolution = function(minResolution) {
this.minResolution_ = minResolution;
this.layer_.setMinResolution(this.minResolution_)
return this;
}
/**
* @return {number} minResolution
*/
cercalia.KML.prototype.getMinResolution = function() {
return this.minResolution_;
}
/**
*
* @param {number} maxResolution
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setMaxResolution = function(maxResolution) {
this.maxResolution_ = maxResolution;
this.layer_.setMaxResolution(this.maxResolution_)
return this;
}
/**
* @return {number} maxResolution
*/
cercalia.KML.prototype.getMaxResolution = function() {
return this.maxResolution_;
}
/**
*
* @param {number} opacity
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setOpacity = function(opacity) {
this.opacity_ = opacity;
this.layer_.setOpacity(this.opacity_)
return this;
}
/**
* @return {number} opacity
*/
cercalia.KML.prototype.getOpacity = function() {
return this.opacity_;
}
/**
* @return {string} url
*/
cercalia.KML.prototype.getUrl = function() {
return this.url_;
}
/**
*
* @param {number} visible
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setVisible = function(visible) {
this.visible_ = visible;
this.layer_.setVisible(this.visible_)
return this;
}
/**
* @return {number} visible
*/
cercalia.KML.prototype.getVisible = function() {
return this.visible_;
}
/**
* @return {string} ClassName from `cercalia.KML` object.
*/
cercalia.KML.prototype.getClass = function() {
return this.CLASS_NAME_;
};
/**
*
* @returns {ol.layer.Vector}
*/
cercalia.KML.prototype.getLayer = function() {
return this.layer_;
};
/**
*
* @returns {ol.source.Vector}
*/
cercalia.KML.prototype.getSource = function() {
return this.source_;
};
/**
* @return {string} Projection.
*/
cercalia.KML.prototype.getProjection = function() {
return this.srs_;
};
/**
* @return {string} Projection.
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.setProjection = function(projection) {
this.srs_ = projection;
this.source_.setProjection(ol.proj.get(this.srs_));
return this;
};
/**
* Converts features to `draggable`. You can drag features.
* @param {boolean} draggable
*/
cercalia.KML.prototype.setDraggable = function(draggable) {
this.draggable_ = draggable;
if(this.draggable_){
if(this.map_){
this.map_.getInteractionDrag()
.addLayer(this);
}
}else{
if(this.map_){
this.map_.getInteractionDrag()
.removeLayer(this);
}
}
return this;
};
/**
* @return {boolean} Returns the drag status. Values: `true` or `false`.
*/
cercalia.KML.prototype.isDraggable = function() {
return this.draggable_;
};
/*** METHODS ***/
/**
* @return {Array} Array of features.
*/
cercalia.KML.prototype.getFeatures = function() {
return this.source_.getFeatures();
};
/**
* @param {Array<cercalia.Feature|ol.Feature>} features Array of features.
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.addFeatures = function(features) {
if(Array.isArray(features)){
for(index = 0; index < features.length; index++){
this.addFeature(features[index]);
}
}else this.addFeature(features);
return this;
};
/**
* @param {cercalia.Feature|cercalia.Marker|ol.Feature} feature feature.
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.addFeature = function(feature) {
if(Array.isArray(feature)){
this.addFeatures(feature);
}else{
if(feature instanceof cercalia.Feature || feature instanceof cercalia.Marker){
if(!feature.getMap()){
feature.setMap(this.map_);
}
feature = feature.getFeature();
}
if(feature instanceof ol.Feature){
this.source_.addFeature(feature);
}
}
return this;
};
/**
* @param {string} kml KML string.
* @param {string} proj Data projection.
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.addFeaturesFromKML = function(kml, proj) {
if(kml){
proj = proj ? proj : this.srs_;
var arr = this.format_.readFeatures(kml
, {dataProjection: ol.proj.get(proj), featureProjection: ol.proj.get(this.srs_)}
);
var arrFeatures = [ ];
if(this.srs_ != 'EPSG:3857') {
for(var i = 0 ; i < arr.length ; i++){
arr[ i ].getGeometry().transform(this.srs_, 'EPSG:3857');//Per defecte EPSG:3857
}
}else arrFeatures = arr;
if(arrFeatures){
this.addFeatures(arrFeatures);
}
}
return this;
};
/**
* Remove a single feature from the source. If you want to remove all features at once, use the `clear()` method instead
* @param {cercalia.Feature|cercalia.Marker|ol.Feature} feature
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.removeFeature = function(feature) {
if(feature instanceof cercalia.Feature || feature instanceof cercalia.Marker){
feature = feature.getFeature();
}
this.source_.removeFeature(feature);
return this;
};
/**
*
* @return {string} kml of features added
*/
cercalia.KML.prototype.getKML = function() {
var arr = this.getFeatures();
for(var i = 0; i < arr.length ; i++){
var feature = arr[i];
var style = feature.getStyle();
if(typeof(style)==="function"){
//style = feature.getProperties().Style[0];
}
if(style instanceof Array && style.length > 0){
style = style[0];
}
if(style !== undefined && style.getImage !== undefined){
var image = style.getImage();
if(image.getSrc === undefined){
var img = this.imgDefault_;
image.getSrc = function(){return img;};
}
}
}
return this.format_.writeFeatures(arr, {dataProjection: ol.proj.get('EPSG:4326'), featureProjection: ol.proj.get('EPSG:3857')});
};
/**
* clear all features
* @return {cercalia.KML} this
*/
cercalia.KML.prototype.clear = function() {
this.source_.clear();
return this;
};