/**
* @classdesc
* Measure control. This control measure:<br/>
* `cercalia.MapControls.MeasureControlOptions.LINE`: The length, painting a line on the map <br/>
* `cercalia.MapControls.MeasureControlOptions.ROAD`: The length, painting a route on the map: <br/>
* `cercalia.MapControls.MeasureControlOptions.AREA`: The area, painting a polygon on the map. <br/>
*
* @constructor
* @param {cercaliax.Control.MeasureControlOptions|undefined} options
* @extends {ol.control.Control}
*/
cercalia.Control.Measure = function(options){
options = options || {};
/**
* @private
* @type {string}
*/
this.name_ = cercalia.MapControls.MeasureControl;
/**
* Class name
* @private
* @type {string}
*/
this.CLASS_NAME_ = "cercalia.Control.Measure";
/**
* Id of topBar.
* @private
* @type {string}
*/
this.topBar_ = null;
/**
* Dialog element jQuery
* @private
* @type {Object}
*/
this.dialog_ = null;
/**
* @private
* @type {string|undefined}
*/
this.scaleUnits_ = options.scaleUnits && ['metric','imperial'].indexOf(options.scaleUnits)!==-1 > 0 ? options.scaleUnits : 'metric';
/**
* @private
* @type {ol.interaction.Draw}
*/
this.measureInteractionActive_ = null;
this.wgs84Sphere = new ol.Sphere(6378137);
/**
* @private
* @type {Array.<ol.Feature>}
*/
this.features_ = [];
/**
* Button
* @private
* @type {Object}
*/
this.element_ = document.createElement('div');
this.element_.className = "cercalia-big-icon cercalia-control cercalia-control-measureControl";
cercalia.jQuery(this.element_).button({icons: {primary:"cercalia-big-icon cercalia-big-icon-rule", secondary: "" }, text: false }).attr("title", cercalia.i18n._("TOOLTIP_MEASURE"));
cercalia.jQuery(this.element_).addClass("cercalia-tool-button");
var self = this;
var distanceControlFn = 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;
}
self.getMap().getCercalia().deactivateControls();
e.preventDefault();
if ( ! self.dialog_ ){
self.dialog_ =
cercalia.jQuery('<div />')
.append(
cercalia.jQuery('<ul />').addClass("ui-corner-all ui-widget ui-state-default")
.append(
cercalia.jQuery('<li />')
.html('<span>'+cercalia.i18n._('Line')+'</span>')
.addClass("cercalia-box-sizing ui-corner-top ui-no-corner-bottom")
.click(function(){
self.disableMeasureInteraction();
self.enableMeasureInteraction(cercalia.MapControls.MeasureControlOptions.LINE);
self.dialog_.dialog('close');
cercalia.jQuery(self.element_).removeClass("cercalia-tool-button-open");
})
.button()
)
.append(
cercalia.jQuery('<li />')
.html('<span>'+cercalia.i18n._('Road')+'</span>')
.addClass("cercalia-box-sizing ui-no-corner-all")
.click(function(){
self.disableMeasureInteraction();
self.enableMeasureInteraction(cercalia.MapControls.MeasureControlOptions.ROAD);
self.dialog_.dialog('close');
cercalia.jQuery(self.element_).removeClass("cercalia-tool-button-open");
})
.button()
)
.append(
cercalia.jQuery('<li />')
.html('<span>'+cercalia.i18n._('Area')+'</span>')
.addClass("cercalia-box-sizing ui-corner-bottom ui-no-corner-top")
.click(function(){
self.disableMeasureInteraction();
self.enableMeasureInteraction(cercalia.MapControls.MeasureControlOptions.AREA);
self.dialog_.dialog('close');
cercalia.jQuery(self.element_).removeClass("cercalia-tool-button-open");
})
.button()
)
)
.dialog({
dialogClass: 'measureDialogControl',
width: "125px",
height: "auto",
resizable: false,
draggable: false,
position: { my: "left top", at: "left bottom+4px", of: ".cercalia-control-measureControl" },
appendTo: self.topBar_ ? "#" + self.topBar_ : "body"
});
} else {
//Ya existe
isOpen ? self.dialog_.dialog('close') : self.dialog_.dialog('open');
}
};
this.element_.addEventListener('click', distanceControlFn, false);
};
ol.inherits(cercalia.Control.Measure, ol.control.Control);
/**
* Create the button in the tools topbar
* @private
* @param {string} idTopBar Div element ID where the control will be embedded
*/
cercalia.Control.Measure.prototype.setTopBar = function (idTopBar) {
var self = this;
this.topBar_ = idTopBar;
ol.control.Control.call(this, {
element: self.element_,
target: document.getElementById(idTopBar)
});
};
/**
* Enable the distance measure control
* @param {string|boolean|undefined} type
*/
cercalia.Control.Measure.prototype.enableMeasureInteraction = function(type) {
var self = this;
var typeDraw = null, weight = null;
var map = self.getMap().getCercalia();
var drawLayer = map.getLayerByName("DrawLayer");
switch(type){
case cercalia.MapControls.MeasureControlOptions.LINE:
typeDraw = "LineString";
weight = "line";
break;
case cercalia.MapControls.MeasureControlOptions.ROAD:
typeDraw = "LineString";
weight = "distance";
break;
case cercalia.MapControls.MeasureControlOptions.AREA:
typeDraw = "Polygon";
weight = 'area';
break;
}
this.disableMeasureInteraction();
if(type){
var sourceLayer = drawLayer.getSource();
this.measureInteractionActive_ = new ol.interaction.Draw({
source: sourceLayer,
type: typeDraw
//type: 'LineString'
});
this.getMap().addInteraction(this.measureInteractionActive_);
this.measureInteractionActive_.on('drawstart',function(evt) {
self.measureInteractionActive_.distanceService = new cercalia.service.Distance({
weight:weight,
calculateGeometry: true
});
});
this.measureInteractionActive_.on('drawend', function(evt) {
var projectionCode = map.getProjectionCode();
//Para linea y distancia usamos el servicio 'cercalia.service.distance'
if(weight == "line") {
var geometryMerc = evt.feature.getGeometry();
var numPoints = geometryMerc.getCoordinates().length;
// Origen
var origin = ol.proj.transform(geometryMerc.getFirstCoordinate(), projectionCode,'EPSG:4326');
var marker = new cercalia.Marker({
icon: new cercalia.Icon({
src : cercaliaGlobals.img + '/cercalia-little-marker.png',
anchor : [8, 20]
}),
position: new cercalia.LonLat(origin[0], origin[1])
});
self.features_.push(marker);
map.addMarker(marker);
// Contamos los km
var countMeters = 0;
if(numPoints > 0) {
var steps = [];
for(var i = 1 ; i < numPoints; i++){
// Nuevo punto
var coordGeo = ol.proj.transform(geometryMerc.getCoordinates()[i], projectionCode, 'EPSG:4326');
countMeters += self.wgs84Sphere.haversineDistance(origin, coordGeo);
origin = coordGeo;
var textLabel;
if(self.scaleUnits_ === 'metric') {
if(countMeters < 1000){
textLabel = parseInt(countMeters) + ' m';
} else {
textLabel = (countMeters/1000).toFixed(2) + ' km';
}
} else{
textLabel = cercalia.Util.distanceMetricToImperial(countMeters);
}
// Add marker
marker = new cercalia.Marker({
icon: new cercalia.Icon({
src : cercaliaGlobals.img + '/cercalia-little-marker.png',
anchor : [8, 20]
}),
position: new cercalia.LonLat(coordGeo[0], coordGeo[1]),
label : new cercalia.Label({text: textLabel})
});
map.addMarker(marker);
self.features_.push(marker);
}
}
//Borramos nada mas añadirlo
sourceLayer.once('addfeature',function(vectorEvent) {
this.removeFeature(vectorEvent.feature);
var feature = new cercalia.Feature({geometry: geometryMerc, draggable: false});
map.addFeature(feature, drawLayer);
self.features_.push(feature);
});
self.disableMeasureInteraction();
} else if(weight == "distance") {
var geometryMerc = evt.feature.getGeometry();
var numPoints = geometryMerc.getCoordinates().length;
var origin = ol.proj.transform(geometryMerc.getFirstCoordinate(), projectionCode, 'EPSG:4326');
var destination = ol.proj.transform(geometryMerc.getLastCoordinate(), projectionCode, 'EPSG:4326');
self.measureInteractionActive_.distanceService.setOrigin(new cercalia.LonLat(origin[0], origin[1]));
self.measureInteractionActive_.distanceService.setDestination(new cercalia.LonLat(destination[0], destination[1]));
if( numPoints >0 ) {
var steps = [];
for(var i = 1 ; i < numPoints-1 ; i++ ){
var coordGeo = ol.proj.transform(geometryMerc.getCoordinates()[i], projectionCode, 'EPSG:4326');
steps.push(new cercalia.LonLat(coordGeo[0], coordGeo[1]));
}
self.measureInteractionActive_.distanceService.setSteps(steps);
}
self.measureInteractionActive_.distanceService.calculate(function(data){
map = self.getMap().getCercalia();
//Pintar ruta
var listStops = data.cercalia.route.stoplist.stop;
var stages = data.cercalia.route.stages.stage;
var wkt = data.cercalia.geometry.route[0].wkt.value;
var feature = new cercalia.Feature({wkt: wkt});
sourceLayer.removeFeature(evt.feature);//borramos la linea que ha pintado el usuario antes de pintar la ruta
map.addFeature(feature, drawLayer);
self.features_.push(feature);
var countKm = 0;
for(var i = 0 ; i<listStops.length; i++){
var marker;
if(i==0) {
marker = new cercalia.Marker({
icon: new cercalia.Icon({
src : cercaliaGlobals.img + '/cercalia-little-marker.png',
anchor : [8, 20]
}),
position: new cercalia.LonLat(listStops[i].mo.coord.x,listStops[i].mo.coord.y)
});
} else {
countKm += parseFloat(stages[i-1].dist);
var textLabel = self.scaleUnits_ === 'metric' ? countKm.toFixed(2) + " km" : cercalia.Util.distanceMetricToImperial(countKm*1000);
marker = new cercalia.Marker({
icon: new cercalia.Icon({
src : cercaliaGlobals.img + '/cercalia-little-marker.png',
anchor : [8, 20]
}),
position: new cercalia.LonLat(listStops[i].mo.coord.x,listStops[i].mo.coord.y),
label : new cercalia.Label({
text: textLabel
})
});
}
self.features_.push(marker);
map.addMarker(marker);
}
self.disableMeasureInteraction();
});
} else if ( weight == "area" ) {
var geometryMerc = evt.feature.getGeometry();
var coordinates = geometryMerc.getLinearRing(0).getCoordinates();
var transformedCoordinates = [];
for(var index = 0; index < coordinates.length; index++) {
transformedCoordinates.push(ol.proj.transform(coordinates[index], projectionCode, 'EPSG:4326'));
}
var area = Math.abs(self.wgs84Sphere.geodesicArea(transformedCoordinates));
var extent = ol.proj.transformExtent(geometryMerc.getExtent(), projectionCode, 'EPSG:4326');
var bounds = new cercalia.Bounds(extent);
var center = bounds.getCenterLonLat();//Obtenemos el centro del poligono dibujado
var areaHa = (area/10000).toFixed(2);
var marker = new cercalia.Marker({
icon: new cercalia.Icon({
src : cercaliaGlobals.img + '/cercalia-little-marker.png',
anchor : [8, 20]
}),
position: center,
label : new cercalia.Label({
text: self.scaleUnits_ == 'metric' ? areaHa + "ha" : cercalia.Util.areaMetricToImperial(areaHa)
})
});
self.features_.push(marker);
map.addMarker(marker);
//Borramos nada mas añadirlo
sourceLayer.once('addfeature',function(vectorEvent) {
this.removeFeature(vectorEvent.feature);
var feature = new cercalia.Feature({geometry: geometryMerc, draggable: false});
map.addFeature(feature, drawLayer);
self.features_.push(feature);
});
self.disableMeasureInteraction();
}
});
}
};
/**
* Disable the measure interaction.
*/
cercalia.Control.Measure.prototype.disableMeasureInteraction = function() {
//Al clickar siempre al icono si esta activo lo desactivamos
if(this.measureInteractionActive_){
this.getMap().removeInteraction(this.measureInteractionActive_);
this.measureInteractionActive_ = null;
}
};
/**
*
*/
cercalia.Control.Measure.prototype.removeFeatures = function() {
var map = this.getMap().getCercalia();
var drawLayer = map.getLayerByName("DrawLayer");
for(var i = 0; i < this.features_.length ; i++ ) {
if(this.features_[i] instanceof cercalia.Feature){
map.removeFeatures(this.features_[i], drawLayer);
} else if(this.features_[i] instanceof cercalia.Marker){
map.removeMarkers(this.features_[i], drawLayer);
} else {
alert('tipo no controlado');
}
}
this.features_ = [];
};
/**
* Get menu dialog element
* @return {jQuery} jQueryElement
*/
cercalia.Control.Measure.prototype.getDialog = function() {
return this.dialog_;
};