/**
* @classdesc
* This control let you draw several shapes on the map.
*
*
* @constructor
* @extends {ol.control.Control}
*/
cercalia.Control.Isochrones = function() {
/**
* @private
* @type {string}
*/
this.name_ = cercalia.MapControls.Isochrones;
/**
* Class name
* @private
* @type {string}
*/
this.CLASS_NAME_ = "cercalia.Control.Isochrones";
/**
* @private
* @type {Object}
*/
this.dialog_ = null;
/**
* Button
* @private
* @type {Object}
*/
this.element_ = null;
/**
* @private
* @type {string}
*/
this.weight_ = "distance";
/**
* @private
* @type {boolean}
*/
this.inverse_ = false;
/**
* @private
* @type {string}
*/
this.method_ = "concavehull";
/**
* @private
* @type {number}
*/
this.isolevels_ = null;
/**
* @private
* @type {cercalia.service.Isochrone}
*/
this.isochroneService_ = new cercalia.service.Isochrone();
/**
* @private
* @type {ol.interaction.Draw}
*/
this.isochroneInteraction_ = null;
/**
* @private
* @type {Array.<cercalia.Feature>}
*/
this.features_ = [];
/**
* @private
* @type {Array.<cercalia.Marker>}
*/
this.markers_ = [];
var self = this;
this.element_ = document.createElement('div');
this.element_.className = "cercalia-big-icon cercalia-control cercalia-control-isochronesControl";
cercalia.jQuery(this.element_).button({icons: {primary:"cercalia-big-icon cercalia-big-icon-isochrone", secondary: "" }, text: false }).attr("title", cercalia.i18n._("TOOLTIP_ISOCHRONE"));
cercalia.jQuery(this.element_).addClass("cercalia-tool-button");
this.element_.addEventListener('click', function(e) {
var isOpen;
if(cercalia.jQuery(self.element_).hasClass("cercalia-tool-button-open")) {
cercalia.jQuery(self.element_).removeClass("cercalia-tool-button-open");
cercalia.jQuery(".cercalia-tool-button.cercalia-tool-button-open").click().removeClass("cercalia-tool-button-open").button("refresh")
isOpen = true;
} else {
cercalia.jQuery(".cercalia-tool-button.cercalia-tool-button-open").click().removeClass("cercalia-tool-button-open").button("refresh");
cercalia.jQuery(self.element_).addClass("cercalia-tool-button-open");
isOpen = false;
}
var cercaliaMap = self.getMap().getCercalia();
cercaliaMap.deactivateControls();
//Si no existe la primera vez lo creamos
if ( ! self.dialog_ ) {
self.dialog_ =
cercalia.jQuery('<div />')
.addClass('dialogIsochronesBox')
.append(
cercalia.jQuery('<div />')
.addClass('container-buttons')
.append(
cercalia.jQuery(
'<div class="method">' +
'<span class="icon simplified-icon"></span>' +
'<label class="text" for="isoc-radio-1">' + cercalia.i18n._("Simplified isochrone") + '</label>' +
'<input type="radio" name="method" id="isoc-radio-1" value="convexhull">' +
'<span class="icon detailed-icon"></span>' +
'<label class="text" for="isoc-radio-2">' + cercalia.i18n._("Detailed isochrone") + '</label>' +
'<input type="radio" name="method" id="isoc-radio-2" value="concavehull" checked>' +
'</div>' +
'<div class="weight">' +
'<label class="time-icon" for="isoc-radio-3"></label>' +
'<input type="radio" name="weight" id="isoc-radio-3" value="time" >' +
'<label class="distance-icon" for="isoc-radio-4"></label>' +
'<input type="radio" name="weight" id="isoc-radio-4" value="distance" checked>' +
'</div>'
)
)
)
.append(
cercalia.jQuery('<div />')
.addClass('container-slider')
.append(
cercalia.jQuery('<div />')
.addClass('slider')
.append(
cercalia.jQuery('<div />').attr('id', 'slider-isolevels')
)
)
.append(
cercalia.jQuery('<div />')
.addClass('container-slider-value')
.append(
cercalia.jQuery('<a><span id="container-slider-id"/></a>')
)
)
)
.append(
cercalia.jQuery('<div />')
.addClass('container-button')
.append(
cercalia.jQuery('<select />')
.addClass('inverse')
.append(
cercalia.jQuery('<option />').val("0").text( cercalia.i18n._("Isochrone origin") )
)
.append(
cercalia.jQuery('<option />').val("1").text( cercalia.i18n._("Isochrone arrival") )
)
)
.append(
cercalia.jQuery('<button />')
.addClass('marker')
.click(function(){
self.drawIsochrone();
})
.button()
)
.append(
cercalia.jQuery('<button />')
.addClass('save')
.hide()
.click(function(){
self.saveKml();
})
.button()
)
.append(
cercalia.jQuery('<button />')
.addClass('clean')
.hide()
.click(function(){
self.clearAll();
})
.button()
)
)
.dialog({
title: cercalia.i18n._("Calculate isochrone"),
height: 240,
width: 306,
draggable: true,
resizable: false,
position: {
my: "left top",
at: "left top+54px",
of: self.element_
},
appendTo: "#" + cercaliaMap.getContainerId()
});
self.initializeDialogEvents_();
} else { //Ya existe
isOpen ? self.dialog_.dialog('close') : self.dialog_.dialog('open');
self.dialog_.children().removeClass('active');
}
e.preventDefault();
}, false);
};
ol.inherits(cercalia.Control.Isochrones, ol.control.Control);
/**
* Delete all features
*/
cercalia.Control.Isochrones.prototype.drawIsochrone = function() {
var olMap = this.getMap();
if( !this.isochroneInteraction_ ) {
var self = this;
var cercaliaMap = olMap.getCercalia();
var drawLayer = cercaliaMap.getLayerByName("DrawLayer");
var projectionCode = cercaliaMap.getProjectionCode();
var sourceLayer = drawLayer.getSource();
this.isochroneInteraction_ = new ol.interaction.Draw({
source: sourceLayer,
type: 'Point'
});
//Borramos nada mas añadirlo
sourceLayer.once('addfeature',function(vectorEvent) {
var featureDrawn = vectorEvent.feature;
var geometry = featureDrawn.getGeometry();
this.removeFeature(featureDrawn);
olMap.removeInteraction(self.isochroneInteraction_);
self.isochroneInteraction_ = null;
var coord = geometry.getCoordinates();
var coordGeo = ol.proj.transform(coord, projectionCode, 'EPSG:4326');
var lonLat = new cercalia.LonLat(coordGeo[0], coordGeo[1]);
self.doIsochroneCall_(lonLat);
self.dialog_.find('button.save').show();
self.dialog_.find('button.clean').show();
});
olMap.addInteraction(this.isochroneInteraction_);
} else {
olMap.removeInteraction(this.isochroneInteraction_);
this.isochroneInteraction_ = null;
}
};
/**
* Delete all features
*/
cercalia.Control.Isochrones.prototype.clearAll = function() {
var cercaliaMap = this.getMap().getCercalia();
cercaliaMap.removeFeatures(this.features_);
cercaliaMap.removeMarkers(this.markers_);
this.dialog_.find('button.save').hide();
this.dialog_.find('button.clean').hide();
this.features_ = [];
this.markers_ = [];
};
/**
* Delete all features
*/
cercalia.Control.Isochrones.prototype.saveKml = function() {
if(this.features_.length > 0 ) {
var filename = "cercalia_isochrones" + Date.now() + ".kml";
var kmlFormat = new ol.format.KML();
var arrFeaturesOL = [];
for(var i = 0; i < this.features_.length; i++) {
var wkt = this.features_[i].getWKT();
var featureOL = new ol.format.WKT().readFeature(wkt);
arrFeaturesOL.push(featureOL);
}
var kml = kmlFormat.writeFeatures(arrFeaturesOL);
cercalia.Util.downloadXmlToFile(kml, filename);
} else {
alert("No features to download");
}
};
/**
* @private
*/
cercalia.Control.Isochrones.prototype.initializeDialogEvents_ = function() {
var self = this;
this.dialog_.find('.method')
.buttonset()
.change(function(e){
self.method_ = e.target.value;
self.initializeSlider_();
});
this.dialog_.find('.weight')
.buttonset()
.change(function(e){
self.weight_ = e.target.value;
self.initializeSlider_();
});
this.dialog_.find('select.inverse').change(function(e){
self.inverse_ = e.target.value;
});
self.initializeSlider_();
};
/**
* @private
*/
cercalia.Control.Isochrones.prototype.initializeSlider_ = function() {
var self = this;
var minValue, maxValue, defaultValue;
if(self.weight_ == "distance") {
minValue = 500; //500m
defaultValue = 10000; //10km
maxValue = (self.method_ == "concavehull" ? 50000: 100000 ); //50km i 100km
cercalia.jQuery('#container-slider-id').text( (defaultValue/1000) + "km"); //default value
this.isolevels_ = defaultValue;
} else { //time
minValue = 5; //<0.1h (5min)
defaultValue = 30; //30min
maxValue = (self.method_ == "concavehull" ? 60: 150 ); //1h i 2.5h
cercalia.jQuery('#container-slider-id').text( defaultValue + "min"); //default value
this.isolevels_ = defaultValue*60000;
}
cercalia.jQuery('#slider-isolevels')
.slider({
range: "min",
min: minValue,
max: maxValue,
value: defaultValue,
slide: function( event, ui ) {
var isolevelAct = ui.value;
if(self.weight_ == "distance") {
self.isolevels_ = isolevelAct;
isolevelAct = (isolevelAct/1000).toFixed(1) + "km";
cercalia.jQuery('#container-slider-id').text(isolevelAct);
} else {
self.isolevels_ = isolevelAct * 60000; //tiempo en milisegundos
if(isolevelAct<60){
isolevelAct = isolevelAct + "min";
} else {
isolevelAct = (isolevelAct/60).toFixed(1) + "h";
}
cercalia.jQuery('#container-slider-id').text(isolevelAct);
}
}
});
};
/**
* @private
* @param {cercalia.LonLat}
*/
cercalia.Control.Isochrones.prototype.doIsochroneCall_ = function(lonLat) {
var self = this;
var mapOL = this.getMap();
var cercaliaMap = mapOL.getCercalia();
this.isochroneService_.clear();
this.isochroneService_.setSearch({
position: lonLat,
weight: this.weight_,
isolevels: this.isolevels_,
method: this.method_,
inverse: this.inverse_
});
cercaliaMap.showLoading();
this.isochroneService_.calculate(function(data) {
var wkt = data.cercalia.isochrones.isochrone.value;
var feature = new cercalia.Feature({
wkt: wkt
});
cercaliaMap.addFeature(feature);
self.features_.push(feature);
var marker = new cercalia.Marker({
position: lonLat
});
self.markers_.push(marker);
cercaliaMap.addMarker(marker);
cercaliaMap.centerToFeatures(self.features_);
cercaliaMap.hideLoading();
}, function() {//callback error function
cercaliaMap.hideLoading();
});
};
/**
* Create the button in the tools topbar
* @param {string} idTopBar Div element ID where the control will be embedded
*/
cercalia.Control.Isochrones.prototype.setTopBar = function (idTopBar) {
var self = this;
ol.control.Control.call(this, {
element: self.element_,
target: document.getElementById(idTopBar)
});
};
/**
* Disable control and close dialog.
*/
cercalia.Control.Isochrones.prototype.disable = function() {
var olMap = this.getMap();
if(this.isochroneInteraction_){
olMap.removeInteraction(this.isochroneInteraction_);
}
if(this.dialog_){
this.dialog_.dialog('close');
}
};
/**
* Get menu dialog element
* @return {jQuery} jQueryElement
*/
cercalia.Control.Isochrones.prototype.getDialog = function() {
return this.dialog_;
};