Source: temp/jsdocinputdirs/cercalia.control.measure.js

/**
 * @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_;
};