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