1 /***************************************
  2  * Copyright 2011, 2012 GlobWeb contributors.
  3  *
  4  * This file is part of GlobWeb.
  5  *
  6  * GlobWeb is free software: you can redistribute it and/or modify
  7  * it under the terms of the GNU Lesser General Public License as published by
  8  * the Free Software Foundation, version 3 of the License, or
  9  * (at your option) any later version.
 10  *
 11  * GlobWeb is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 14  * GNU Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU General Public License
 17  * along with GlobWeb. If not, see <http://www.gnu.org/licenses/>.
 18  ***************************************/
 19  
 20 define(['./Utils', './RasterLayer', './GeoTiling'], 
 21 	function(Utils, RasterLayer, GeoTiling) {
 22 
 23 /**************************************************************************************************************/
 24 
 25 
 26 /** @name WCSElevationLayer
 27 	@class
 28 	Create a layer for elevation data using WCS protocol.
 29 	The only supported format is right now image/x-aaigrid. It is an ASCII format that is easily parsed in Javascript.
 30 	@augments RasterLayer
 31 	@param options Configuration properties for the WCSElevationLayer. See {@link RasterLayer} for base properties :
 32 		<ul>
 33 			<li>baseUrl : the base Url to access the WCS server</li>
 34 			<li>coverage : the name of the coverage to use (WCS parameter)</li>
 35 			<li>crs : the coordinate reference system to use (WCS parameter)</li>
 36 			<li>version : 2.0.x or 1.0.x is supported</li>
 37 		</ul>
 38  */
 39 var WCSElevationLayer = function( options )
 40 {
 41 	RasterLayer.prototype.constructor.call( this, options );
 42 	
 43 	this.baseUrl = options['baseUrl'];
 44 	this.tilePixelSize = options['tilePixelSize'] || 33;
 45 	this.tiling = new GeoTiling( 4, 2 );
 46 	this.numberOfLevels = options['numberOfLevels'] || 21;
 47 	this.version = options['version'] || '2.0.0';
 48 	this.format = options['format'] || 'image/x-aaigrid';
 49 	this.minElevation = options['minElevation'] || 0;
 50 	
 51 	// Build the base GetMap URL
 52 	var url = this.baseUrl;
 53 	if ( url.indexOf('?',0) == -1 )
 54 	{
 55 		url += '?service=wcs';
 56 	}
 57 	else
 58 	{
 59 		url += '&service=wcs';
 60 	}
 61 	url += "&version=" + this.version;
 62 	url += "&request=GetCoverage";
 63 
 64 	switch (this.version.substring(0,3)) 
 65 	{
 66 		case '2.0':
 67 			this.crs = options['outputCRS'] || options['crs'] || 'http://www.opengis.net/def/crs/EPSG/0/4326';
 68 			url += '&outputCRS=' + this.crs;
 69 			url += "&size=x(" + this.tilePixelSize + ")";
 70 			url += "&size=y(" + this.tilePixelSize + ")";
 71 			url += "&coverageid=" + options['coverage'];
 72 			break;
 73 		case '1.0':
 74 			url += "&width=" + this.tilePixelSize;
 75 			url += "&height=" + this.tilePixelSize;
 76 			url += '&crs=' + (options['crs'] || 'EPSG:4326');
 77 			url += "&coverage=" + options['coverage'];
 78 			break;
 79 	}
 80 	url += '&format=' + this.format;
 81 	
 82 	this.getCoverageBaseUrl = url;
 83 }
 84 
 85 Utils.inherits(RasterLayer,WCSElevationLayer);
 86 
 87 
 88 /**************************************************************************************************************/
 89 
 90 /**
 91 	Parse a elevation response
 92  */
 93 WCSElevationLayer.prototype.parseElevations = function(text)
 94 {
 95 	if (text == null) {
 96 		return this._returnZeroElevations();
 97 	}
 98 	switch(this.format) {
 99 	case "image/x-aaigrid":
100 		return this._parseAAIGrid(text);
101 	default:
102 		console.log("Format '" + this.format + "' could not be parsed.");
103 		return this._returnZeroElevations();
104 	}
105 }
106 
107 /**************************************************************************************************************/
108 
109 
110 /**
111 	Fallback elevations when no data was returned
112  */
113 WCSElevationLayer.prototype._returnZeroElevations = function()
114 {
115 	var elevations = [];
116 	for( var i = 0; i < this.tilePixelSize * this.tilePixelSize; ++i ) {
117 		elevations.push(0);
118 	}
119 	return elevations;
120 }
121 
122 
123 /**************************************************************************************************************/
124 
125 
126 /**
127 	Parse a elevation response from AAIGrid
128  */
129 WCSElevationLayer.prototype._parseAAIGrid = function(text)
130 {
131 	var elevations = [];
132 	var lines = text.trim().split('\n');
133 
134 	var dataLinesStart = 0;
135 	for ( var i = 0; i < lines.length; ++i ) {
136 		if (lines[i].substring(0, 1) === " ") {
137 			dataLinesStart = i;
138 			break;
139 		}
140 	}
141 
142 	for ( var i = dataLinesStart; i < lines.length; i++ )
143 	{
144 		var elts = lines[i].trim().split(/\s+/);
145 		for ( var n=0; n < elts.length; n++ )
146 		{
147 			var elevation = parseInt(elts[n]);
148 			if ( elevation < this.minElevation ) 
149 				elevation = this.minElevation;
150 			elevations.push( elevation );
151 		}
152 	}
153 
154 	return elevations;
155 }
156 
157 
158 /**************************************************************************************************************/
159 
160 /**
161 	Get an url for the given tile
162  */
163 WCSElevationLayer.prototype.getUrl = function(tile)
164 {
165 	var geoBound = tile.geoBound;
166 	var url = this.getCoverageBaseUrl;
167 
168 	if (this.version.substring(0,3) === '2.0') 
169 	{
170 		url += '&subset=x,' + this.crs + '(' + geoBound.west + ',' + geoBound.east + ')';
171 		url += '&subset=y,' + this.crs + '(' + geoBound.south + ',' + geoBound.north + ')';
172 	}
173 	else if (this.version.substring(0,3) === '1.0') 
174 	{
175 		url += "&bbox=";	
176 		url += geoBound.west;
177 		url += ",";
178 		url += geoBound.south;
179 		url += ",";
180 		url += geoBound.east;
181 		url += ",";
182 		url += geoBound.north;
183 	}
184 	
185 	return url;
186 }
187 
188 /**************************************************************************************************************/
189 
190 return WCSElevationLayer;
191 
192 });
193