Commit a6d3df6a authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Merge branch 'feature-ToponymyUpgrade' into 'dev'

Feature toponymy upgrade

See merge request redmic-project/client/web!57
parents 70f6e236 09996f3a
Loading
Loading
Loading
Loading
+61 −55
Original line number Diff line number Diff line
@@ -5,10 +5,9 @@ define([
	, "app/redmicConfig"
	, "dojo/_base/declare"
	, "dojo/_base/lang"
	, "dojo/Deferred"
	, "dojo/request"
	, "put-selector/put"
	, "templates/PlaceNamesList"
	, "redmic/store/xml2json"
	, "redmic/modules/browser/bars/Pagination"
	, "redmic/modules/browser/bars/Total"
	, "redmic/modules/map/layer/GeoJsonLayerImpl"
@@ -20,10 +19,9 @@ define([
	, redmicConfig
	, declare
	, lang
	, Deferred
	, request
	, put
	, TemplateList
	, xml2json
	, Pagination
	, Total
	, GeoJsonLayerImpl
@@ -62,7 +60,16 @@ define([
				idProperty: "id",
				title: this.i18n.placeNames,

				noFixedZoom: false
				noFixedZoom: false,

				// timeout: int
				// 	Tiempo en milisegundos de espera por la respuesta antes de dar error.
				timeout: 10000,

				// overflow: Boolean
				// 	Informa sobre si ha habido más resultados que el máximo por página.
				overflow: false

			};

			lang.mixin(this, this.config, args);
@@ -144,11 +151,6 @@ define([

			this._publish(this._buildChannel(this.mapChannel, this.actions.ADD_LAYER), this.geoJsonLayer);

			// Instanciamos el conversor
			this.conversor = new xml2json({
				url: this.target
			});

			this.clearButton = new Button({
				iconClass: "fa fa-eraser",
				'class': "warning",
@@ -164,18 +166,7 @@ define([

		_resetTarget: function() {

			var envDfd = window.env;

			if (!envDfd) {
				var dfd = new Deferred();
				dfd.resolve();

				return dfd;
			}

			envDfd.then(lang.hitch(this, function(envData) {

				var target = redmicConfig.getServiceUrl(this.baseTarget, envData);
			var target = this.baseTarget;

			if (this.numPage !== 0) {
				target += "/" + this.numPage;
@@ -188,13 +179,6 @@ define([
			target += '/';

			this.target = target;

				if (this.conversor) {
					this.conversor.url = this.target;
				}
			}));

			return envDfd;
		},

		_beforeShow: function(request) {
@@ -226,8 +210,8 @@ define([

		_drawPlaceName: function(placeName) {

			var lat = parseFloat(placeName.y),
				lng = parseFloat(placeName.x),
			var lat = parseFloat(placeName.latitud),
				lng = parseFloat(placeName.longitud),
				geoJson = {
					type: "Feature",
					geometry: {
@@ -321,9 +305,8 @@ define([
			this.numPage = (from / size) + 1,
			this.maxSize = size;

			var dfd = this._resetTarget();

			dfd.then(lang.hitch(this, this._newSearch, this._lastSearch));
			this._resetTarget();
			this._newSearch(this._lastSearch);
		},

		_newSearch: function(obj) {
@@ -332,26 +315,47 @@ define([
				return;
			}

			var value = obj.text,
				dfd;
			var value = obj.text;

			if (!this._lastSearch || this._lastSearch.text !== value) {
				this._lastSearch = obj;
				dfd = this._resetPagination();
				this._resetPagination();
			}

			if (!dfd) {
				dfd = new Deferred();
				dfd.resolve();
			}
			// Buscamos en el servicio
			this._findByText(value).then(
				lang.hitch(this, this._responseDataConversor),
				lang.hitch(this, this._errorDataConversor));
		},

			dfd.then(lang.hitch(this, function(value) {
		_findByText: function(value) {

				// Buscamos en el servicio
				this.conversor.find({
			var params = {
				texto: value
				}).then(lang.hitch(this, this._responseDataConversor), lang.hitch(this, this._errorDataConversor));
			}, value));
			};

			return request(this._generateUrl(params), {
				handleAs: "json",
				timeout: this.timeout
			});
		},

		_generateUrl: function(/*Object*/ params) {
			// summary:
			//		Prepara la url con los parámetros de búsqueda.
			// tags:
			//		private
			// params:
			//		Parámetros de búsqueda.

			var query = "";
			for (var key in params) {
				var hasSeveralQuestionMarks = this.target.indexOf("?") !== -1;
				query += hasSeveralQuestionMarks ? "&" : "?";
				query += key + "=" + params[key];
			}

			return this.target + query;
		},

		_resetPagination: function() {
@@ -362,15 +366,17 @@ define([

			this.numPage = 1;
			this._publish(this.browser.getChannel("RESET_PAGINATION"));
			return this._resetTarget();
			this._resetTarget();
		},

		_responseDataConversor: function(res) {

			var value = res.data,
				total = res.total,
				urlNext = res.urlnext,
				data = [];

			this.overflow = !!urlNext;
			this.placeNames = value;

			for (var key in value) {
+1 −1
Original line number Diff line number Diff line
@@ -124,7 +124,7 @@ define([], function() {
		baseMediastorageUploads = baseUri + 'mediastorage/uploads/';

	retObj.services = {
		'grafcan': baseUri + 'grafcan',
		'grafcan': 'https://visor.grafcan.es/busquedas/toponimo',
		'socket': baseUri + 'socket',
		'document': baseUri + 'documents',
		'accessibility': baseUri + 'accessibilities',
+0 −227
Original line number Diff line number Diff line
define([
	"dojo/_base/declare", 
	"dojo/store/util/QueryResults", 
	"redmic/store/util/SimpleQueryEngine" 
	/*=====, "./api/Store" =====*/
],
function(
	declare, 
	QueryResults, 
	SimpleQueryEngine 
	/*=====, Store =====*/
){

// module:
//		dojo/store/Memory

// No base class, but for purposes of documentation, the base class is dojo/store/api/Store
var base = null;
/*===== base = Store; =====*/

return declare("dojo.store.Memory", base, {
	idSec : 1,
	// summary:
	//		This is a basic in-memory object store. It implements dojo/store/api/Store.
	constructor: function(options){
		// summary:
		//		Creates a memory object store.
		// options: dojo/store/Memory
		//		This provides any configuration information that will be mixed into the store.
		//		This should generally include the data property to provide the starting set of data.
		for(var i in options){
			this[i] = options[i];
		}
		this.setData(this.data || []);
	},
	// data: Array
	//		The array of all the objects in the memory store
	data:null,

	// idProperty: String
	//		Indicates the property to use as the identity property. The values of this
	//		property should be unique.
	idProperty: "id",

	// index: Object
	//		An index of data indices into the data array by id
	index:null,

	// queryEngine: Function
	//		Defines the query engine to use for querying the data store
	queryEngine: SimpleQueryEngine,
	get: function(id){
		// summary:
		//		Retrieves an object by its identity
		// id: Number
		//		The identity to use to lookup the object
		// returns: Object
		//		The object in the store that matches the given id.
		return this.data[this.index[id]];
	},

	getIdentity: function(object){
		// summary:
		//		Returns an object's identity
		// object: Object
		//		The object to get the identity from
		// returns: Number

		var idObj = object && object.getId && object.getId();

		return idObj ? idObj.get ? idObj.get("value") : idObj : object[this.idProperty];
	},

	calculateId: function(){
		return this.idSec++;
	},

	put: function(object, options){
		// summary:
		//		Stores an object
		// object: Object
		//		The object to store.
		// options: dojo/store/api/Store.PutDirectives?
		//		Additional metadata for storing the data.  Includes an "id"
		//		property if a specific id is to be used.
		// returns: Number
		var data = this.data,
			index = this.index,
			idProperty = this.idProperty,
			// Comprobamos si es una instancia
			instance = object && object.get ? true : false,
			id;

		// Si es una instancia significa que estamos modificando, por lo q se realiza sobre ek modelo y no hay que hacer nada
		// En caso contrario se crea la instancia con el objeto pasado y se guarda
		if (!instance) {
			// convertimos el objeto en una instancia del modelo
			object = this.getModelInstance(object);
			id = object.getId().get("value");
			//object.set("id", id);

			if (id in index) {
				// object exists
				if (options && options.overwrite === false) {
					throw new Error("Object already exists");
				}
				// replace the entry in data
				data[index[id]] = object;
			} else {
				// add the new object
				index[id] = data.push(object) - 1;
			}
		} else {
			id = object.getId() ? object.getId().get("value") : object[idProperty];
			//object.set("id", id);
			if (index[id] === undefined){  // instancia vacia no insertada en el store
				index[id] = data.push(object) - 1;
			} else {
				data[index[id]] = object;
			}
		}

		return this.get(id);
	},

	add: function(object, options){
		// summary:
		//		Creates an object, throws an error if the object already exists
		// object: Object
		//		The object to store.
		// options: dojo/store/api/Store.PutDirectives?
		//		Additional metadata for storing the data.  Includes an "id"
		//		property if a specific id is to be used.
		// returns: Instance
		(options = options || {}).overwrite = true;
		// call put with overwrite being false
		return this.put(object, options); // retorna la instancia completa
	},

	getModelInstance: function (obj) {
		// Guarda la instancia del modelo con las propiedades pasadas
		return new this.model({
			store: this,
			initValues: obj
		});

	},

	addModelInstance: function (obj) {
		// Guarda la instancia del modelo con las propiedades a null
		var model = this.getModelInstance(obj);
		model.save();
		return model;

	},

	remove: function(id){
		// summary:
		//		Deletes an object by its identity
		// id: Number
		//		The identity to use to delete the object
		// returns: Boolean
		//		Returns true if an object was removed, falsy (undefined) if no object matched the id
		var index = this.index;
		var data = this.data;

		if(id in index){
			data.splice(index[id], 1);
			// now we have to reindex
			this.setData(data);

			return true;
		}

	},
	query: function(query, options){
		// summary:
		//		Queries the store for objects.
		// query: Object
		//		The query to use for retrieving objects from the store.
		// options: dojo/store/api/Store.QueryOptions?
		//		The optional arguments to apply to the resultset.
		// returns: dojo/store/api/Store.QueryResults
		//		The results of the query, extended with iterative methods.
		//
		// example:
		//		Given the following store:
		//
		// 	|	var store = new Memory({
		// 	|		data: [
		// 	|			{id: 1, name: "one", prime: false },
		//	|			{id: 2, name: "two", even: true, prime: true},
		//	|			{id: 3, name: "three", prime: true},
		//	|			{id: 4, name: "four", even: true, prime: false},
		//	|			{id: 5, name: "five", prime: true}
		//	|		]
		//	|	});
		//
		//	...find all items where "prime" is true:
		//
		//	|	var results = store.query({ prime: true });
		//
		//	...or find all items where "even" is true:
		//
		//	|	var results = store.query({ even: true });
		return QueryResults(this.queryEngine(query, options)(this.data));
	},
	setData: function(data){
		// summary:
		//		Sets the given data as the source for this store, and indexes it
		// data: Object[]
		//		An array of objects to use as the source of data.
		if(data.items){
			// just for convenience with the data format IFRS expects
			this.idProperty = data.identifier || this.idProperty;
			data = this.data = data.items;
		}else{
			this.data = data;
		}
		this.index = {};
		for(var i = 0, l = data.length; i < l; i++){
			this.index[data[i].getId() ? data[i].getId().get("value") : data[i][idProperty]] = i;
		}
	}
});

});
+0 −112
Original line number Diff line number Diff line
define(["dojo/_base/array" /*=====, "../api/Store" =====*/], function(arrayUtil /*=====, Store =====*/){

// module:
//		dojo/store/util/SimpleQueryEngine

return function(query, options){
	// summary:
	//		Simple query engine that matches using filter functions, named filter
	//		functions or objects by name-value on a query object hash
	//
	// description:
	//		The SimpleQueryEngine provides a way of getting a QueryResults through
	//		the use of a simple object hash as a filter.  The hash will be used to
	//		match properties on data objects with the corresponding value given. In
	//		other words, only exact matches will be returned.
	//
	//		This function can be used as a template for more complex query engines;
	//		for example, an engine can be created that accepts an object hash that
	//		contains filtering functions, or a string that gets evaluated, etc.
	//
	//		When creating a new dojo.store, simply set the store's queryEngine
	//		field as a reference to this function.
	//
	// query: Object
	//		An object hash with fields that may match fields of items in the store.
	//		Values in the hash will be compared by normal == operator, but regular expressions
	//		or any object that provides a test() method are also supported and can be
	//		used to match strings by more complex expressions
	//		(and then the regex's or object's test() method will be used to match values).
	//
	// options: dojo/store/api/Store.QueryOptions?
	//		An object that contains optional information such as sort, start, and count.
	//
	// returns: Function
	//		A function that caches the passed query under the field "matches".  See any
	//		of the "query" methods on dojo.stores.
	//
	// example:
	//		Define a store with a reference to this engine, and set up a query method.
	//
	//	|	var myStore = function(options){
	//	|		//	...more properties here
	//	|		this.queryEngine = SimpleQueryEngine;
	//	|		//	define our query method
	//	|		this.query = function(query, options){
	//	|			return QueryResults(this.queryEngine(query, options)(this.data));
	//	|		};
	//	|	};

	// create our matching query function
	switch(typeof query){
		default:
			throw new Error("Can not query with a " + typeof query);
		case "object": case "undefined":
			var queryObject = query;
			query = function(object){
				for(var key in queryObject){
					var required = queryObject[key];
					if(required && required.test){
						// an object can provide a test method, which makes it work with regex
						if(!required.test(object[key], object)){
							return false;
						}
					}/*else if(required != object[key]){
						return false;
					}*/
				}
				return true;
			};
			break;
		case "string":
			// named query
			if(!this[query]){
				throw new Error("No filter function " + query + " was found in store");
			}
			query = this[query];
			// fall through
			break;
		case "function":
			// fall through
			break;
	}
	function execute(array){
		// execute the whole query, first we filter
		var results = arrayUtil.filter(array, query);
		// next we sort
		var sortSet = options && options.sort;
		if(sortSet){
			results.sort(typeof sortSet == "function" ? sortSet : function(a, b){
				for(var sort, i=0; sort = sortSet[i]; i++){
					var aValue = a[sort.attribute];
					var bValue = b[sort.attribute];
					if (aValue != bValue) {
						return !!(sort.descending == (aValue == null || aValue > bValue) ? -1 : 1);
					}
				}
				return 0;
			});
		}
		// now we paginate
		if(options && (options.start || options.count)){
			var total = results.length;
			results = results.slice(options.start || 0, (options.start || 0) + (options.count || Infinity));
			results.total = total;
		}
		return results;
	}
	execute.matches = query;
	return execute;
};

});
+0 −141
Original line number Diff line number Diff line
define([
	"dojo/_base/declare",
	"dojo/_base/lang",
	"dojo/Deferred",
	"dojo/dom-attr",
	"dojo/request"
], function(
	declare,
	lang,
	Deferred,
	domAttr,
	request
){
	return declare(null, {
		// summary:
		// 	Widget de Dojo para consultar un XML, transformarlo y devolverlo como JSON.
		// description:
		// 	Widget de Dojo para consultar un XML, transformarlo y devolverlo como JSON.

		// url: String
		// 	Dirección o ruta donde se encuentra el XML de entrada.
		url: "",

		// timeout: int
		// 	Tiempo en milisegundos de espera por la respuesta antes de dar error.
		timeout: 10000,

		// overflow: Boolean
		// 	Informa si ha habido desbordamiento.
		overflow: false,


		constructor: function(/*Object*/ args) {

			lang.mixin(this, args);
		},

		isOverflowed: function() {
			// summary:
			//		Comprueba si hay más resultados pendientes.
			// returns:
			//		Booleano según se detecte si hay más resultados pendientes.

			return this.overflow;	// return Boolean
		},

		find: function(/*Object*/ params) {
			// summary:
			//		Busca en el servicio y espera a tener respuesta.
			// params:
			//		Atributos de búsqueda.

			// Creamos un Deferred para esperar a que termine la consulta.
			this.deferred = new Deferred();

			// Reseteamos el detector de desbordamiento
			this.overflow = false;

			// Lanzamos la petición
			request(this._generateUrl(params), {
				handleAs: "xml",
				timeout: this.timeout
			}).then(
				lang.hitch(this, this._parse),
				lang.hitch(this, this._error)
			);

			// Devolvemos el promise del Deferred para tratarlo fuera
			return this.deferred;
		},

		_parse: function(/*Object*/ data) {
			// summary:
			//		Transforma los datos del XML a JSON.
			// tags:
			//		private
			// data:
			//		Información de entrada para transformar.

			var outJson = {},
				root = data.childNodes[0],	// Nodo raíz extraído
				urlnext = domAttr.get(root, "urlnext"),	// Siguiente página de resultados
				total = domAttr.get(root, "total"),
				children = root.childNodes,	// Topónimos
				element = {};

			if (urlnext) {
				this.overflow = true;
			}

			for (var i = 0; i < children.length; i++) {
				var attributes = children[i].childNodes;

				element = {};
				for (var j = 0; j < attributes.length; j++) {
					var attribute = attributes[j].childNodes[0],
						value = attribute ? attribute.data : null,
						name = attributes[j].nodeName;
					element[name] = value;
				}
				outJson[i] = element;
			}

			// Resolvemos el Deferred
			this.deferred.resolve({
				data: outJson,
				total: parseInt(total, 10)
			});
		},

		_error: function(/*Object*/ err) {
			// summary:
			//		Informa de un error en la petición.
			// tags:
			//		private
			// err:
			//		Información del error.

			// Resolvemos el Deferred
			this.deferred.cancel(err);
		},

		_generateUrl: function(/*Object*/ params) {
			// summary:
			//		Preparamos la url con el proxy y los parámetros.
			// tags:
			//		private
			// params:
			//		Atributos de búsqueda.

			var query = "";
			for (var key in params) {
				var hasSeveralQuestionMarks = this.url.indexOf("?") !== -1;
				query += hasSeveralQuestionMarks ? "&" : "?";
				query += key + "=" + params[key];
			}

			return this.url + query;
		}
	});
});