Commit 9c6da9d3 authored by Pedro Eduardo Trujillo's avatar Pedro Eduardo Trujillo
Browse files

Pide info por capa alternativa, prueba tiles

Mejora el soporte de GetFeatureInfo, soportando capas tileadas que
también definan un protocolo WMS alternativo para hacer estas peticiones
de datos.

Prueba a optimizar peticiones haciendo consultas a nivel de tiles
(WMS-C), pero faltan detalles para que sea funcional (punto en píxeles a
nivel del tile concreto).
parent 648b2dad
Loading
Loading
Loading
Loading
+152 −13
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ define([

		_requestLayerInfo: function(obj) {

			this.infoTarget = this._chkUrlAndAddParams(this.layer._url + '?', this._obtainGetParams(obj));
			this.infoTarget = this._obtainLayerInfoTarget(obj);

			this._emitEvt('GET', {
				target: this.infoTarget,
@@ -139,16 +139,87 @@ define([
			});
		},

		_processLayerInfo: function(data) {
		_obtainLayerInfoTarget: function(data) {

			this._emitEvt('LAYER_INFO', {
				layerId: this.layerId,
				layerLabel: this.layerLabel,
				info: data
			var protocol = this.layerDefinition.protocol,
				mustUseAlternativeDefinition = protocol === 'WMTS' || protocol === 'TMS' || protocol === 'WMS-C';

			if (mustUseAlternativeDefinition) {
				return this._obtainLayerAlternativeDefinitionTarget(data);
			}

			return this._obtainLayerMainDefinitionTarget(data);
		},

		_obtainLayerMainDefinitionTarget: function(data) {

			return this._chkUrlAndAddParams(this._obtainMainGetUrl(), this._obtainMainGetParams(data));
		},

		_obtainLayerAlternativeDefinitionTarget: function(data) {

			var alternativeDefinitions = this.layerDefinition.alternativeDefinitions,
				alternativeDefinition;

			for (var i = 0; i < alternativeDefinitions.length; i++) {
				var altDef = alternativeDefinitions[i];
				if (altDef.protocol === 'WMS') {
					alternativeDefinition = altDef;
					break;
				}
			}

			if (!alternativeDefinition) {
				console.error('Alternative protocol not found for GetFeatureInfo at layer:', this.layerDefinition);
				return;
			}

			return this._chkUrlAndAddParams(this._obtainAltGetUrl(alternativeDefinition),
				this._obtainAltGetParams(alternativeDefinition, data));
		},

		_obtainAltGetUrl: function(altDef) {

			// TODO
			return altDef.url + '?';
		},

		_obtainAltGetParams: function(altDef, data) {

			// TODO
			var layerProtocol = altDef.protocol,
				layerProps = altDef.props,
				layerName = layerProps.layers,
				layerFormat = layerProps.format,
				layerTransparent = layerProps.transparent;

			return L.Util.getParamString({
				request: 'GetFeatureInfo',
				srs: 'EPSG:4326',
				info_format: 'application/json',
				service: layerProtocol,
				version: '1.1.1',
				layers: layerName,
				query_layers: layerName,
				//styles: this.layer.wmsParams.styles,
				format: layerFormat,
				transparent: layerTransparent,
				feature_count: 100,

				width: data.size.x,
				height: data.size.y,
				bbox: data.bbox.toBBoxString(),
				x: parseInt(data.containerPoint.x, 10),
				y: parseInt(data.containerPoint.y, 10)
			});
		},

		_obtainGetParams: function(data) {
		_obtainMainGetUrl: function() {

			return this.layer._url + '?';
		},

		_obtainMainGetParams: function(data) {

			var params = {
				request: 'GetFeatureInfo',
@@ -161,17 +232,76 @@ define([
				styles: this.layer.wmsParams.styles,
				format: this.layer.wmsParams.format,
				transparent: this.layer.wmsParams.transparent,
				feature_count: 100,
				width: data.size.x,
				height: data.size.y,
				bbox: data.bbox.toBBoxString()
				feature_count: 100
			};
			params[params.version === '1.3.0' ? 'i' : 'x'] = parseInt(data.containerPoint.x, 10);
			params[params.version === '1.3.0' ? 'j' : 'y'] = parseInt(data.containerPoint.y, 10);

			var lngParam, latParam;
			if (params.version === '1.3.0') {
				lngParam = 'i';
				latParam = 'j';
			} else {
				lngParam = 'x';
				latParam = 'y';
			}

			var isTiled = this.layerDefinition.protocol === 'WMS-C';
			if (!isTiled) {
				params.width = data.size.x;
				params.height = data.size.y;
				params.bbox = data.bbox.toBBoxString();
				params[lngParam] = parseInt(data.containerPoint.x, 10);
				params[latParam] = parseInt(data.containerPoint.y, 10);
			} else {
				var tile = this._getClickedTile(data.latLng, data.zoom),
					tileSize = this.layer.getTileSize(),
					tilePoint = this._getClickedTilePoint(data.containerPoint, tile);

				params.width = tileSize.x;
				params.height = tileSize.y;
				params.bbox = this._getTileBbox(tile);
				// TODO falla el punto
				params[lngParam] = parseInt(tilePoint.x, 10);
				params[latParam] = parseInt(tilePoint.y, 10);
			}

			return L.Util.getParamString(params);
		},

		_getClickedTile: function(clickLatLng, currZoom) {

			var clickedTileKey = this._getTileKey(clickLatLng, currZoom);

			return this.layer._tiles[clickedTileKey];
		},

		_getTileKey: function(clickLatLng, currZoom) {

			var tileSize = this.layer.getTileSize(),
				pixelPoint = this.layer._map.project(clickLatLng, currZoom).floor(),
				coords = pixelPoint.unscaleBy(tileSize).floor();

			return coords.x + ':' + coords.y + ':' + currZoom;
		},

		_getClickedTilePoint: function(containerPoint, tile) {
			// TODO no funciona, va bien en zoom alejado solamente

			var tilePosition = tile.el._leaflet_pos,
				tileOffsetX = containerPoint.x - tilePosition.x,
				tileOffsetY = containerPoint.y - tilePosition.y;

			return { x: tileOffsetX, y: tileOffsetY };
		},

		_getTileBbox: function(tile) {

			var tileSrc = tile.el.src,
				bboxExpr = /.+bbox=([-.,\d]+).*/gi,
				exprMatches = new RegExp(bboxExpr).exec(tileSrc);

			return exprMatches[1];
		},

		_chkLayerIsMe: function(response) {

			var layerAddedId = response.layer._leaflet_id;
@@ -179,6 +309,15 @@ define([
			return layerAddedId === this.layerId;
		},

		_processLayerInfo: function(data) {

			this._emitEvt('LAYER_INFO', {
				layerId: this.layerId,
				layerLabel: this.layerLabel,
				info: data
			});
		},

		_onMapShown: function(response) {

			this._setRefreshInterval();