Source: temp/jsdocinputdirs/cercalia.widget.geocoding.js

/**
 * Geocoding widget constructor
 * @class
 * @constructor
 * @param {cercaliax.widget.GeocodingOptions} options Geocoding options
 */
cercalia.widget.Geocoding = function (options) {

	/**
	 * Class name
	 * @private
	 * @type {string}
	 */
	this.CLASS_NAME_ = 'cercalia.widget.Geocoding';

	/* OPTIONS */

	/**
	 * DIV container ID.
	 * @private
	 * @type {string}
	 */
	this.divId_ = options.div ? options.div : null;

	/**
	 * Geocode type. Posible values: cp,
	 * @private
	 * @type {string}
	 */
	this.type_ = options.type ? options.type : 'cp';

	/**
	 * @private
	 * @type {Function}
	 */
	this.completeCallback_ = options.complete ? options.complete : null;

	/**
	 * @private
	 * @type {Function}
	 */
	this.errorCallback_ = options.error ? options.error : null;

	/**
	 * Map
	 * @private
	 * @type {cercalia.Map}
	 */
	this.map_ = null;

	/**
	 * Markers list painted on map.
	 * @private
	 * @type {Array.<cercalia.Marker>}
	 */
	this.listMarkers_ = null;

	/**
	 * Geocoding service
	 * @private
	 * @type {cercalia.service.Geocoding}
	 */
	this.geocoding_ = null;

	/**
	 * Countries
	 * @private
	 * @type {cercalia.service.Data}
	 */
	this.data_ = null;

	/**
	 * @private
	 * @type {cercalia.service.GeometryEntity}
	 */
	this.geomEntService_ = new cercalia.service.GeometryEntity();

	/**
	 * @private
	 * @type {cercalia.Feature|null}
	 */
	this.featureGeomEnt_ = null;

	// Inicializamos
	this.initialize_();
};

/**
 * Initializes element.
 * @private
 */
cercalia.widget.Geocoding.prototype.initialize_ = function () {

	if( ! this.divId_ ) {
		cercalia.Exception(cercalia.i18n._('WIDGET_ERR_NO_DIV "%"', this.CLASS_NAME_));
	} else {

		this.data_ = new cercalia.service.Data();
		this.geocoding_ = new cercalia.service.Geocoding();
		this.listMarkers_ = [];

		switch (this.type_) {
			case 'cp':
				this.createCPType_();
				break;

			default:
				this.createCPType_();
				break;
		}
	}
};

/**
 * Creates the postal code geocoding
 * @private
 */
cercalia.widget.Geocoding.prototype.createCPType_ = function () {

	// Buscamos div
	var element = cercalia.jQuery('#' + this.divId_).addClass('cercalia-widget cercalia-widget-geocoding');

	var divInput = cercalia.jQuery('<div />').addClass('deleteicon').appendTo(element);

	// Creamos input, br y select de pais
	var inputCP = cercalia.jQuery('<input />')
		.attr('type', 'text')
		.attr('placeholder', cercalia.i18n._('GEOCODING_TYPECP_PLACEHOLDER'))
		.attr('id', this.divId_ + '_postalcode')
		.addClass('cercalia-widget-geocoding-postalcode')
		.appendTo(divInput);

		//icona per borrar l'input
		jQuery('<span/>').addClass('icon').click(function() {
				jQuery(this).prev('input').val('').focus();
				self.autocomplete_.close();
				input.parent().find('span').hide();
	    }).appendTo(divInput);

	inputCP.keyup(function() {
		if(jQuery(this).val().length > 0) inputCP.parent().find('span').show();
		else inputCP.parent().find('span').hide();
	});
	inputCP.parent().find('span').hide();

	cercalia.jQuery('<br />').appendTo(element);

	var paisCP = cercalia.jQuery('<select />')
		.attr('id', this.divId_ + '_country')
		.addClass('cercalia-widget-geocoding-country')
	.appendTo(element);

	cercalia.jQuery('<br />').appendTo(element);

	var buttonCP = cercalia.jQuery('<button />')
		.attr('id', this.divId_ + '_find')
		.addClass('cercalia-widget-geocoding-find')
		.html(cercalia.i18n._('GEOCODING_TYPECP_FIND'))
		.button()
	.appendTo(element);

	// Llenamos el select
	this.data_.getCountries(function(listCountries){

		cercalia.jQuery('<option />')
			.html(cercalia.i18n._('All'))
			.attr('value', 'all')
		.appendTo(paisCP);

		for(var index in listCountries) {
			var keyValue = listCountries[index];
			cercalia.jQuery('<option />').html(keyValue[1]).attr('value', keyValue[0]).appendTo(paisCP);
		}
		paisCP.val('ESP'); // Valor por defecto del select
	});


	//Postal code candidates
	var elemCandidates = cercalia.jQuery('<div />')
		.addClass('pcCandidates')
	.appendTo(element);


	// Añadimos función al hacer click.
	buttonCP.click(function () {

		var cp = inputCP.val();
		var pais = paisCP.val();
		pais = pais === 'all' ? null : pais;

		// Limpiamos busdqueda anterior
		this.geocoding_.clear();

		// Añadimos parámetros de la nueva busqueda
		this.geocoding_.setSearch({
			postalCode: cp,
			countryId: pais
		});

		// Buscamos i tratamos el resultado
		this.geocoding_.geocode(function (result) {
			if(typeof(result.cercalia.error) !== 'undefined' && result.cercalia.error !== null) {
				if(this.errorCallback_ != null) {
					this.errorCallback_(result);
				} else {
					this.callbackErrorfunction_(result);
				}
			} else {
				if(this.completeCallback_ != null) {
					this.completeCallback_(result);
				} else if(this.map_ != null) {
					if (result.cercalia.candidates && result.cercalia.candidates.candidate && result.cercalia.candidates.candidate.length > 1) {
						this.showPcodeCandidates_(elemCandidates, result);
					} else {
						this.callbackfunction_(result);
					}
				} else {
					cercalia.Exception(cercalia.i18n._('WIDGET_ERR_NO_MAP_NO_FUNCTION '%'', [this.CLASS_NAME_]));
				}
			}
		}.bind(this));

		//En paralelo obtenemos la geometria del codigo postal
		if (pais !== 'all') {
			this.geomEntService_.getPostalCodeGeometry(pais, cp, this.handleDrawGeometryEntity_.bind(this, false));
		}

	}.bind(this));
};

/**
 * @private
 * @param {Element} elemCandidates Element HTML container.
 * @param {Object} result Candidates result
 */
cercalia.widget.Geocoding.prototype.showPcodeCandidates_ = function(elemCandidates, result) {
	var candidates = result.cercalia.candidates.candidate;
	var ulCandidates =
		cercalia.jQuery('<ul />')
			.addClass('ui-autocomplete ui-front ui-menu ui-widget ui-widget-content ui-corner-all');

	ulCandidates.appendTo(elemCandidates);

	for (var i = 0; i < candidates.length; i++) {
		var candidate = candidates[i];

		cercalia.jQuery('<li />')
			.addClass('cercalia-suggest-item ui-menu-item')
			.append(
				cercalia.jQuery('<a />')
					.addClass('ui-corner-all')
					.append(
						cercalia.jQuery('<span />')
							.addClass('cercalia-suggest address')
					)
					.append(
						cercalia.jQuery('<span />').text(candidate.desc)
					)
					.data('index', i)
					.click(function() {
						var index = cercalia.jQuery(this).data('index');
						//Borrem la resta de candidats
						var candidateAct = result.cercalia.candidates.candidate[index];
						result.cercalia.candidates.candidate = [candidateAct];
						this.callbackfunction_(result);
						elemCandidates.empty();
						elemCandidates.hide();
					}.bind(this))
					.mouseover(function(){
						cercalia.jQuery(this).addClass('ui-state-focus')
					})
					.mouseout(function(){
						cercalia.jQuery(this).removeClass('ui-state-focus')
					})
			)
		.appendTo(ulCandidates);
	}

	elemCandidates.show();

};


/**
 * Clean input and select
 */
cercalia.widget.Geocoding.prototype.clean = function () {

	switch (this.type_) {
		case 'cp':
			cercalia.jQuery('#' + this.divId_ + '_postalcode').val('');
			break;
		default:
			cercalia.jQuery('#' + this.divId_ + '_postalcode').val('');
			break;
	}

	cercalia.jQuery('#' + this.divId_ + '_country').val('ESP');
	this.cleanMarkers();
};

/**
 * Clean current geocoding search.
 */
cercalia.widget.Geocoding.prototype.cleanMarkers = function () {
	for(var index in this.listMarkers_) {
		var marker = this.listMarkers_[index];
		marker.destroy();
	}

	this.listMarkers_ = [];
};

/**
 * Modify the map which interacts with the Widget.
 * @param {cercalia.Map} map Map which interacts with the widget.
 */
cercalia.widget.Geocoding.prototype.setMap = function (map) {
	this.map_ = map;
};

/**
 * Default callback function.
 * Create a popup and market at the position returned.
 * @private
 * @param {Object} result
 */
cercalia.widget.Geocoding.prototype.callbackfunction_ = function (result) {
	// Función que genera el contenido del popup
	var popupContent = function (ge) {
		var content = cercalia.jQuery('<div />');
		var table = cercalia.jQuery('<table />').appendTo(content);

		if(ge.city) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('City')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.city.value).appendTo(tr);
		}

		if(ge.postalcode) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Postal code')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.postalcode.id).appendTo(tr);
		}

		if(ge.municipality) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Municipality')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.municipality.value).appendTo(tr);
		}

		if(ge.subregion) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Subregion')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.subregion.value).appendTo(tr);
		}

		if(ge.region) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Region')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.region.value).appendTo(tr);
		}

		if(ge.country) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Country')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.country.value).appendTo(tr);
		}

		if(ge.coord) {
			var tr = cercalia.jQuery('<tr />').appendTo(table);
			cercalia.jQuery('<td />').css('font-weight', 'bold').html(cercalia.i18n._('Coords')).appendTo(tr);
			cercalia.jQuery('<td />').html(ge.coord.x +', ' + ge.coord.y).appendTo(tr);
		}

		return content.html();
	};

	var candidates = result.cercalia.candidates.candidate;
	if(candidates && candidates.length > 0) {
		var ge = candidates[0].ge;
		var popup = new cercalia.Popup({
			visible: true,
			title: cercalia.i18n._('GEOCODING_TYPECP_POPUP_TITLE'),
			content: popupContent(ge)
		});

		var marker = new cercalia.Marker({
			position: new cercalia.LonLat(ge.coord.x, ge.coord.y),
			popup: popup
		});

		this.map_.addMarker(marker);
		this.listMarkers_.push(marker);

		this.map_.panTo(marker.getPosition(), cercalia.MapAnimation.PAN);
		this.map_.setZoom(12, true);

	} else {
		cercalia.Exception(cercalia.i18n._('WIDGET_WARN_NO_CANDIDATES "%"', this.CLASS_NAME_));
	}
};

/**
 * Default error callback function.
 * @private
 * @param {Object} result
 */
cercalia.widget.Geocoding.prototype.callbackErrorfunction_ = function (result) {
	cercalia.Exception(cercalia.i18n._('WIDGET_ERR_CERCALIA "%" "%" "%"', this.CLASS_NAME_, result.cercalia.error.id, result.cercalia.error.value));
};

/**
 * @private
 * @param {boolean} panTo Optional pan to location.
 * @param {cercaliax.GeometryEntityResult} data Geocoding result.
 */
cercalia.widget.Geocoding.prototype.handleDrawGeometryEntity_ = function(panTo, data) {

	if (!data.cercalia.error) {
		var geometry = data.cercalia.ge.geometry;
		var wkt = geometry.wkt.value;

		if (this.featureGeomEnt_) {
			this.map_.removeFeatures(this.featureGeomEnt_);
		}

		this.featureGeomEnt_ = new cercalia.Feature({
			wkt: wkt,
			fillOpacity: 0.1,
			fillColor: '#ff4d4d',
			strokeColor: '#ff4d4d',
			strokeWidth: 1.5,
			strokeOpacity: 1,
			outlineWidth: 0
		});

		this.map_.addFeature(this.featureGeomEnt_);

		if (panTo) {
			this.map_.fitBounds(this.featureGeomEnt_.getBounds());
		}
	}
};

/**
 * Retuns the object type.
 * @return {string}
 */
cercalia.widget.Geocoding.prototype.getClass = function(){
	return this.CLASS_NAME_;
};