Index: WMTSProvider.java
===================================================================
--- WMTSProvider.java	(revision 4271)
+++ WMTSProvider.java	(revision 4272)
@@ -31,6 +31,8 @@
 import java.io.IOException;
 import java.net.ConnectException;
 import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.List;
 
@@ -51,6 +53,7 @@
 import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
 import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
 import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
+import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
 import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
 import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
 import org.gvsig.fmap.dal.coverage.exception.QueryException;
@@ -64,6 +67,7 @@
 import org.gvsig.fmap.dal.coverage.util.MathUtils;
 import org.gvsig.fmap.dal.exception.CloseException;
 import org.gvsig.fmap.dal.exception.InitializeException;
+import org.gvsig.fmap.dal.exception.OpenException;
 import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
 import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
 import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
@@ -103,6 +107,9 @@
 import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSet;
 import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSetLink;
 import org.gvsig.tools.ToolsLocator;
+
+import org.apache.commons.io.FilenameUtils;
+import org.cresques.cts.IProjection;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 /**
@@ -116,7 +123,7 @@
 	public static final String          METADATA_DEFINITION_NAME = "WmtsStore";
 	private static Logger               logger                   = LoggerFactory.getLogger(WMTSProvider.class);
 	public static boolean               TILED                    = true;
-	
+
 	//Los tiles se piden de forma secuencial y sin lanzar threads para ello (+Lento)
 	public static int                   SEQUENTIAL               = 0;
 	//Los tiles se piden en threads y hay un thread manager para gestionar que no se pidan más de cierto número
@@ -124,12 +131,12 @@
 	//Los tiles se piden en threads y se lanzan tantos threads como tiles haya
 	public static int                   UNLIMITED_THREADS        = 2;
 	private int                         requestType              = LIMITED_THREADS;
-	
+
 	private static final double         MTS_X_GRADO              = 111319.490793274;
-	
+
 	private Extent                      viewRequest              = null;
 	private WMTSClient                  ogcClient                = null;
-	//private static Hashtable<URL, WMTSConnector>    
+	//private static Hashtable<URL, WMTSConnector>
 	//                                    drivers                  = new Hashtable<URL, WMTSConnector> ();
 	private boolean                     open                     = false;
 	private File                        lastRequest              = null;
@@ -141,24 +148,24 @@
 	private Extent[]                    extentByLevel            = null; //Only for layers without gridSubsets
 	private Extent                      bbox                     = null;
 	private MathUtils                   math                     = RasterLocator.getManager().getMathUtils();
-	
+
 	/**
 	 * This thread manages the number of tiles that have been thrown.
 	 * This number is controlled by the NTHREADS_QUEUE variable.
-	 * 
+	 *
 	 * @author Nacho Brodin (nachobrodin@gmail.com)
 	 */
 	public class RequestThreadManager extends Thread {
 		private TilePipe               pipe           = null;
 		private List<WMTSTile>         tiles          = null;
 		private WMTSStatus             status         = null;
-		
+
 		public RequestThreadManager(TilePipe pipe, List<WMTSTile> tiles, WMTSStatus status) {
 			this.pipe = pipe;
 			this.tiles = tiles;
 			this.status = status;
 		}
-		
+
 		public void run() {
 			for (int i = 0; i < tiles.size(); i++) {
 				WMTSTile tile = tiles.get(i);
@@ -168,7 +175,7 @@
 				if (pipe.getSize() > TilePipe.NTHREADS_QUEUE) {
 					try {
 						synchronized (this) {
-							wait();							
+							wait();
 						}
 					} catch( InterruptedException e ) {
 					}
@@ -177,7 +184,7 @@
 			}
 		}
 	}
-	
+
 	/**
 	 * Thread to download a tile
 	 * @author Nacho Brodin (nachobrodin@gmail.com)
@@ -208,9 +215,9 @@
 			}
 		}
 	}
-	
+
 	/**
-	 * Point information 
+	 * Point information
 	 * @author Nacho Brodin (nachobrodin@gmail.com)
 	 */
 	public class PointInfo {
@@ -218,7 +225,7 @@
 		public Point2D tile;
 		public Point2D pixelInTile;
 		public int     level;
-		
+
 		public PointInfo(Point2D worldCoord) {
 			this.worldCoord = worldCoord;
 		}
@@ -236,22 +243,29 @@
 		}
 		dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
 	}
-	
+
 	public WMTSProvider() throws NotSupportedExtensionException {
 		super();
 	}
-	
+
 	/**
 	 * Constructor. Abre el dataset.
 	 * @param proj Proyección
 	 * @param fName Nombre del fichero
 	 * @throws NotSupportedExtensionException
+	 * @throws OpenException
+     * @deprecated use {@link #WMTSProvider(URI)}, this constructor will be removed in gvSIG 2.5
 	 */
-	public WMTSProvider(String params) throws NotSupportedExtensionException {
+	public WMTSProvider(String params) throws NotSupportedExtensionException, OpenException {
 		super(params);
+        logger.info("Deprecated use of WMTSProvider constructor");
 		if(params instanceof String) {
 			WMTSDataParameters p = new WMTSDataParametersImpl();
-			p.setURI((String)params);
+            try {
+                p.setURI(new URI((String) params));
+            } catch (URISyntaxException e) {
+                throw new OpenException("Can't create URI from" + (String) params, e);
+            }
 			super.init(p, null, ToolsLocator.getDynObjectManager()
 					.createDynObject(
 							MetadataLocator.getMetadataManager().getDefinition(
@@ -259,8 +273,25 @@
 			init(p, null);
 		}
 	}
-	
-	public WMTSProvider(WMTSDataParameters params,
+
+	 /**
+     * Constructor. Abre el dataset.
+     * @param uri URI del fichero
+     * @throws NotSupportedExtensionException
+     */
+    public WMTSProvider(URI uri) throws NotSupportedExtensionException {
+        super(uri);
+        WMTSDataParameters p = new WMTSDataParametersImpl();
+        p.setURI(uri);
+        super.init(
+            p,
+            null,
+            ToolsLocator.getDynObjectManager().createDynObject(
+                MetadataLocator.getMetadataManager().getDefinition(DataStore.METADATA_DEFINITION_NAME)));
+        init(p, null);
+    }
+
+    public WMTSProvider(WMTSDataParameters params,
 			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
 		super(params, storeServices, ToolsLocator.getDynObjectManager()
 				.createDynObject(
@@ -268,7 +299,7 @@
 								DataStore.METADATA_DEFINITION_NAME)));
 		init(params, storeServices);
 	}
-	
+
 	/**
 	 * Gets the connector from the URL
 	 * @return
@@ -280,21 +311,21 @@
 			ogcClient = p.getOGCClient();
 			if(ogcClient != null)
 				return ogcClient;
-			
+
 			URL url = null;
 			try {
-				url = new URL(p.getURI());
+				url = p.getURI().toURL();
 			} catch (Exception e) {
 				throw new WMTSException("Malformed URL",e);
 			}
 			try {
 				ogcClient = WMTSOGCLocator.getManager().createWMTSClient(url.toString());
 				ogcClient.connect(true, new ICancellable() {
-					
+
 					public boolean isCanceled() {
 						return false;
 					}
-					
+
 					public Object getID() {
 						return null;
 					}
@@ -325,14 +356,14 @@
 			setDataType(new int[]{Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE});
 			bandCount = 4;
 		}
-		
+
 		if(!(param instanceof WMTSDataParameters))
 			return;
-		
+
 		gridSubsets = hasGridSubsets((WMTSDataParameters)param);
 		open = true;
 	}
-	
+
 	/**
 	 * Returns true if this layer has grid subsets
 	 * @return
@@ -340,7 +371,7 @@
 	public boolean hasGridSubsets() {
 		return gridSubsets;
 	}
-	
+
 	/**
 	 * Checks if this layer has grid subsets or doesn't
 	 * @param p
@@ -359,20 +390,20 @@
 				tileMatrixSetLimits = tmsl;
 			}
 		}
-		
-		return (tileMatrixSetLimits == null || tileMatrixSetLimits.size() <= 0) ? false : true; 
+
+		return (tileMatrixSetLimits == null || tileMatrixSetLimits.size() <= 0) ? false : true;
 	}
-	
+
 	private boolean areSrsEquals(String sourceSrs, String appSrs) {
 		if(sourceSrs.compareTo(appSrs) == 0)
 			return true;
-		if(sourceSrs.contains("CRS:84") || sourceSrs.contains("CRS84")) { 
+		if(sourceSrs.contains("CRS:84") || sourceSrs.contains("CRS84")) {
 			if(appSrs.equals("EPSG:4326"))
 				return true;
 		}
 		return false;
 	}
-	
+
 	/*public static final WMTSConnector getConnectorFromURL(URL url) throws IOException {
 		WMTSConnector drv = (WMTSConnector) drivers.get(url);
 		if (drv == null) {
@@ -381,7 +412,7 @@
 		}
 		return drv;
 	}*/
-	
+
 	/**
 	 * Obtiene el objeto que contiene que contiene la interpretación de
 	 * color por banda
@@ -390,16 +421,16 @@
 	public ColorInterpretation getColorInterpretation() {
 		if(super.getColorInterpretation() == null) {
 			ColorInterpretation colorInterpretation = new DataStoreColorInterpretation(getBandCount());
-			
-			if(getBandCount() == 1) 
+
+			if(getBandCount() == 1)
 				colorInterpretation = DataStoreColorInterpretation.createGrayInterpretation();
-			
-			if(getBandCount() == 3) 
+
+			if(getBandCount() == 3)
 				colorInterpretation = DataStoreColorInterpretation.createRGBInterpretation();
-			
+
 			if(getBandCount() == 4)
 				colorInterpretation = DataStoreColorInterpretation.createRGBAInterpretation();
-			
+
 			if(getBandCount() > 4 || getBandCount() == 2) {
 				for (int i = 0; i < getBandCount(); i++) {
 					colorInterpretation.setColorInterpValue(i, DataStoreColorInterpretation.UNDEF_BAND);
@@ -409,36 +440,36 @@
 		}
 		return super.getColorInterpretation();
 	}
-	
+
 	public boolean isTiled() {
 		return true;
 	}
-	
+
 	public AffineTransform getAffineTransform() {
 		WMTSDataParameters p = (WMTSDataParameters)parameters;
 		Extent e = getExtent();
 		double psX = e.width() / (lastWidthRequest <= 0 ? p.getWidth() : lastWidthRequest);
 		double psY = -(e.height() / (lastHeightRequest <= 0 ? p.getHeight() : lastHeightRequest));
 		ownTransformation = new AffineTransform(
-				psX, 
-				0, 
-				0, 
-				psY, 
+				psX,
+				0,
+				0,
+				psY,
 				e.getULX() - (psX / 2),
 				e.getULY() - (psY / 2));
 		externalTransformation = (AffineTransform) ownTransformation.clone();
 		return ownTransformation;
 	}
-	
+
 	/**
 	 * <p>
-	 * Gets the bounding box in world coordinates. 
-	 * If the layer has defined the BoundingBox tag, we will take this bounding box as entire 
+	 * Gets the bounding box in world coordinates.
+	 * If the layer has defined the BoundingBox tag, we will take this bounding box as entire
 	 * extension of this layer, else we'll see if the tag WGS84BoundingBox is defined (it can be approximated).
 	 * In this case we'll take WGS84BoundingBox as entire extension.
 	 * </p>
 	 * <br>
-	 * Note: 
+	 * Note:
 	 * <br>
 	 * <p>
 	 * If the layer has grid subsets (TileMatrixLimits) then
@@ -453,18 +484,18 @@
 
 		if(layer.getBBox() != null)
 			return new ExtentImpl(layer.getBBox().toRectangle2D());
-		
+
 		if(layer.getWGS84BBox() != null) {
 			String crsCode = p.getSRSCode();
 			Rectangle2D r = layer.getWGS84BBoxTransformed(crsCode);
 			if(r != null)
 				return new ExtentImpl(r);
 		}
-			
+
 		if(bbox == null)
 			getExtentByResolutionLevel();
 		return bbox;
-		
+
 		/*if(gridSubsets) {
 			WMTSBoundingBox bbox = layer.getWGS84BBox();
 			return new ExtentImpl(bbox.toRectangle2D());
@@ -474,7 +505,7 @@
 			return bbox;
 		}*/
 	}
-	
+
 	/**
 	 * Gets the suffix of the downloaded image
 	 * @return
@@ -487,10 +518,10 @@
 		}
 		if (format.indexOf("png") >= 0){
 	        return "png";
-		}	
+		}
 	    if (format.indexOf("xml") >= 0){
 	        return "xml";
-	    }	
+	    }
 	    if (format.indexOf("gif") >= 0){
 	        return "gif";
 	    }
@@ -502,7 +533,7 @@
 	    }
 	    if (format.indexOf("jpg") >= 0
 	        || format.indexOf("jpeg") >= 0){
-	        return "jpg";			 
+	        return "jpg";
 	    }
 		return "xml";
 	}
@@ -518,7 +549,7 @@
 			WMTSDataParameters p = (WMTSDataParameters)parameters;
 			WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
 			WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
-			
+
 	    	double widthMtsTile = 0;
 	    	double heightMtsTile = 0;
 			List<WMTSTileMatrix> tileMatrixList = tileMatrixSet.getTileMatrix();
@@ -536,12 +567,12 @@
 		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000;
 		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileHeight() * 0.28) / 1000;
 		    	}
-		    	
+
 		    	//TODO: Revisar!!! Creo que el top left sale al revés en el de la nasa
-		    	
+
 		    	double h = Math.abs(tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getMatrixHeight() * heightMtsTile)));
 		    	Rectangle2D r = new Rectangle2D.Double(
-		    			tileMatrix.getTopLeftCorner()[0], 
+		    			tileMatrix.getTopLeftCorner()[0],
 		    			tileMatrix.getTopLeftCorner()[1] - h,
 		    			Math.abs(tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getTopLeftCorner()[0] + (tileMatrix.getMatrixWidth() * widthMtsTile))),
 		    			h);
@@ -562,7 +593,7 @@
 		}
 		return extentByLevel;
 	}
-	
+
 	public Rectangle2D getLayerExtent(String layerName, String srs) throws RemoteServiceException {
 		return null;
 	}
@@ -570,7 +601,7 @@
 	public RasterProvider load() {
 		return this;
 	}
-	
+
 	public boolean isOpen() {
 		return open;
 	}
@@ -578,7 +609,7 @@
 	public void close() {
 		open = false;
 	}
-	
+
 	public Transparency getTransparency() {
 		if(lastFileTransparency == null) {
 			lastFileTransparency = new DataStoreTransparency(getColorInterpretation());
@@ -586,7 +617,7 @@
 		}
 		return lastFileTransparency;
 	}
-	
+
 	public NoData getNoDataValue() {
 		NoData nodata = super.getNoDataValue();
 		if(nodata != null)
@@ -594,8 +625,8 @@
 		return noData;
 	}
 
-	public String translateFileName(String fileName) {
-		return fileName;
+	public URI translateURI(URI uri) {
+		return uri;
 	}
 
 	public void setView(Extent e) {
@@ -608,14 +639,14 @@
 
 	public double getWidth() {
 		WMTSDataParameters p = (WMTSDataParameters)parameters;
-		if (lastWidthRequest <= 0) 
+		if (lastWidthRequest <= 0)
 			return p.getWidth();
 		return lastWidthRequest;
 	}
 
 	public double getHeight() {
 		WMTSDataParameters p = (WMTSDataParameters)parameters;
-		if (lastHeightRequest <= 0) 
+		if (lastHeightRequest <= 0)
 			return p.getHeight();
 		return lastHeightRequest;
 	}
@@ -624,9 +655,9 @@
 		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
 		return null;
 	}
-	
+
 	/**
-	 * When the remote layer has fixed size this method downloads the file and return its reference. 
+	 * When the remote layer has fixed size this method downloads the file and return its reference.
 	 * File layer has in the long side FIXED_SIZE pixels and the bounding box is complete. This file could be
 	 * useful to build an histogram or calculate statistics. This represents a sample of data.
 	 * @return
@@ -640,8 +671,8 @@
 	 * Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
 	 * to read a file very fast without setting a view. In a WMTS service when the size is fixed then it will read the
 	 * entire image but when the source hasn't pixel size it will read a sample of data. This set of data will have
-	 * the size defined in FIXED_SIZE. 
-	 * 
+	 * the size defined in FIXED_SIZE.
+	 *
 	 * @param pos Posición donde se empieza  a leer
 	 * @param blockHeight Altura máxima del bloque leido
 	 * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
@@ -649,16 +680,16 @@
 	 * @throws FileNotOpenException
 	 * @throws RasterDriverException
 	 */
-	public Object readBlock(int pos, int blockHeight, double scale) 
+	public Object readBlock(int pos, int blockHeight, double scale)
 	throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
 		return null;
 	}
-	
+
 	public Object getData(int x, int y, int band)
 		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
 		return null;
 	}
-	
+
 	/**
 	 * Assigns the list of bands RGB and read a window of data
 	 * @param rasterBuf
@@ -672,11 +703,11 @@
 	 * @throws RasterDriverException
 	 * @throws ProcessInterruptedException
 	 */
-	public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, 
+	public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile,
 			double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
 		return null;
 	}
-	
+
 	/**
 	 * Gets the tile matrix from the selected level
 	 * @param level
@@ -684,11 +715,11 @@
 	 */
 	private WMTSTileMatrix getTileMatrixByLevel(int level) {
 		level = adjustLevel(level);
-		
+
 		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
 		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
 		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
-		
+
 		WMTSTileMatrixLimits tileMatrixLimits = null;
 		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level);
 		if(hasGridSubsets()) {
@@ -697,7 +728,7 @@
 		}
 		return tileMatrix;
 	}
-	
+
 	/**
 	 * Returns the number of levels
 	 * @return
@@ -710,13 +741,13 @@
 			return Math.min(tileMatrixSet.getTileMatrix().size(), tileMatrixSetLimits.size());
 		}
 		return tileMatrixSet.getTileMatrix().size();
-		
+
 	}
-	
+
 	public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
 		double[] pixelSizes = getPixelSizeByLevel();
 		double currentPixelSize = extent.width() / (double)w;
-		
+
 		int level = 0;
 		for (int i = 0; i < (pixelSizes.length - 1); i++) {
 			if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
@@ -724,30 +755,30 @@
 				break;
 			}
 		}
-		
+
 		return getZoomLevelCoordinates(level, extent, w, h);
 	}
-	
+
 	public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
 		WMTSDataParameters p = (WMTSDataParameters)param;
 		level = adjustLevel(level);
 		WMTSTileMatrix tileMatrix = getTileMatrixByLevel(level);
-		
+
 		boolean proj = p.isProjected();
-		
+
 		double psX = tileMatrix.getWidthWCTile(proj) / tileMatrix.getTileWidth();
 		double psY = tileMatrix.getHeightWCTile(proj) / tileMatrix.getTileHeight();
-		
+
 		double ulx = viewCenter.getX() - ((w / 2) * psX);
 		double uly = viewCenter.getY() - ((h / 2) * psY);
 		double lrx = ulx + (w * psX);
 		double lry = uly + (h * psY);
 		return new ExtentImpl(ulx, uly, lrx, lry);
 	}
-	
+
 	/**
-	 * Calculates the extent of a zoom level using other extent as a reference. The new extent is 
-	 * calculated with the same coordinate at the center. 
+	 * Calculates the extent of a zoom level using other extent as a reference. The new extent is
+	 * calculated with the same coordinate at the center.
 	 * @param level
 	 * @param extent
 	 * @param w
@@ -759,7 +790,7 @@
 		double centerY = extent.getCenterY();
 		return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
 	}
-	
+
 	/**
 	 * Returns a list of pixel sizes by level
 	 * @return
@@ -767,14 +798,14 @@
 	public double[] getPixelSizeByLevel() {
 		WMTSDataParameters p = (WMTSDataParameters)param;
 		double[] list = new double[getZoomLevels()];
-		
+
 		for (int i = 0; i < getZoomLevels(); i++) {
 			WMTSTileMatrix tileMatrix = getTileMatrixByLevel(i);
 			list[i] = math.adjustDouble(tileMatrix.getWidthWCTile(p.isProjected()) / tileMatrix.getTileWidth());
 		}
 		return list;
 	}
-	
+
 	/**
 	 * Adjust de level to the range
 	 * @param level
@@ -787,17 +818,17 @@
 			level = getZoomLevels();
 		return level;
 	}
-	
+
 	public org.gvsig.raster.cache.tile.Tile getTile(SpiRasterQuery q) throws TileGettingException {
 		//q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), q.getBBox(), q.getCacheStruct()!
-		
+
 		CacheStruct str = getTileServer().getStruct();
-		
+
 		//1-Selección de WMTSTileMatrixSet por srs
 		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
 		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
 		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
-		
+
 		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(q.getResolutionLevel());
 		if(gridSubsets) {
 			WMTSTileMatrixLimits tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(q.getResolutionLevel());
@@ -805,25 +836,25 @@
 		}
 		int bufWidth = tileMatrix.getTileWidth();
 		int bufHeight = tileMatrix.getTileHeight();
-		
+
 		try {
 			Extent adjBbox = q.getAdjustedRequestBoundingBox();
 			Rectangle2D r = adjBbox.toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
 			WMTSStatus status = buildWMTSStatus(r, bufWidth , bufHeight);
-			
+
 			int[] size = str.getTileSizeByLevel(q.getResolutionLevel());
 			WMTSTile tile = WMTSOGCLocator.getManager().createTile(
-					size, 
-					new int[]{q.getTileRow(), q.getTileCol()}, 
+					size,
+					new int[]{q.getTileRow(), q.getTileCol()},
 					new double[]{adjBbox.getULX(), adjBbox.getULY(), adjBbox.getLRX(), adjBbox.getLRY()});
-			
+
 			File file = getOGCClient().getTile(status, null);
 			tile.setFile(file);
 			//Creamos un BandList con todas las bandas del fichero
 			BandList bandList = new BandListImpl();
 			for(int i = 0; i < getBandCount(); i++) {
 				try {
-					DatasetBand band = new DatasetBandImpl(getURIOfFirstProvider(), i, getDataType()[i], getBandCount());
+					DatasetBand band = new DatasetBandImpl(getURIOfFirstProvider().getPath(), i, getDataType()[i], getBandCount());
 					bandList.addBand(band);
 				} catch(BandNotFoundInListException e) {
 					//No añadimos la banda
@@ -838,9 +869,9 @@
 			throw new TileGettingException("Error getting tiles", e);
 		}
 	}
-	
+
 	@Override
-	public void loadBuffer(SpiRasterQuery q) 
+	public void loadBuffer(SpiRasterQuery q)
 			throws ProcessInterruptedException, RasterDriverException {
 		Rectangle2D r = q.getAdjustedRequestBoundingBox().toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
 		WMTSStatus status = buildWMTSStatus(r, q.getAdjustedWidth(), q.getAdjustedBufHeight());
@@ -850,9 +881,9 @@
 		Buffer b = matrixBuffer.getWindow(q.getAdjustedRequestBoundingBox(), q.getBufWidth(), q.getBufHeight(), q.getBandList().getDrawableBandsCount());
 		q.setBufferResult(b);
 	}
-	
+
 	/**
-	 * Gets the information from a point 
+	 * Gets the information from a point
 	 * @param wcx
 	 * @param wcy
 	 * @param level
@@ -863,20 +894,20 @@
 		PointInfo pointInfo = new PointInfo(new Point2D.Double(wcx, wcy));
 		pointInfo.level = level;
 		getTileInfo(pointInfo);
-		
+
 		WMTSClient ogcClient = null;
 		try {
 			ogcClient = getOGCClient();
 			lastStatus.setTileRow((int)pointInfo.tile.getX());
 			lastStatus.setTileCol((int)pointInfo.tile.getY());
-			
+
 			String fi = ogcClient.getFeatureInfo(lastStatus, (int)pointInfo.pixelInTile.getX(), (int)pointInfo.pixelInTile.getY(), null);
 			return fi;
 		} catch (WMTSException e) {
 			throw new RasterDriverException("Error getting the connector object", e);
-		} 
+		}
 	}
-	
+
 	/**
 	 * Gets a tile position from a world coordinates point and a resolution level
 	 * @param point
@@ -886,34 +917,34 @@
 	 */
 	private void getTileInfo(PointInfo pointInfo) {
 		WMTSDataParameters p = (WMTSDataParameters)param;
-		
+
 		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
 		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
 		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
-		
+
 		WMTSTileMatrixLimits tileMatrixLimits = null;
 		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(pointInfo.level);
 		if(hasGridSubsets()) {
 			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(pointInfo.level);
 			tileMatrix = tileMatrixLimits.getTileMatrix();
 		}
-		
+
 		List<WMTSTile> tiles = null;
 		if(hasGridSubsets())
 			tiles = tileMatrix.contains(p.isProjected(), tileMatrixLimits, pointInfo.worldCoord, getExtent().toRectangle2D());
 		else
 			tiles = tileMatrix.contains(p.isProjected(), pointInfo.worldCoord, getExtent().toRectangle2D());
-		
+
 		//Tile row and column
 		pointInfo.tile = new Point2D.Double(tiles.get(0).getRow(), tiles.get(0).getCol());
-		
+
 		//Desplazamiento en pixels dentro del tile
 		Point2D rasterPoint = tiles.get(0).worldToRaster(pointInfo.worldCoord);
 		pointInfo.pixelInTile = new Point2D.Double(rasterPoint.getX(), rasterPoint.getY());
 	}
-	
+
 	/**
-	 * Builds the WMTSStatus object using the parameters and the request bounding box. 
+	 * Builds the WMTSStatus object using the parameters and the request bounding box.
 	 * @param r
 	 * @param bufWidth
 	 * @return
@@ -921,21 +952,21 @@
 	 */
 	public WMTSStatus buildWMTSStatus(Rectangle2D r, int bufWidth, int bufHeight) throws RasterDriverException {
 		WMTSDataParameters p = (WMTSDataParameters)param;
-		
+
 		//Mantiene actualizados los parámetros del WMTSStoreParameters con la última petición hecha
 		p.setExtent(r);
 		p.setWidth(bufWidth);
 		p.setHeight(bufHeight);
-		
+
 		lastWidthRequest = bufWidth;
 		lastHeightRequest = bufHeight;
-		
+
 		//1-Selección de WMTSTileMatrixSet por srs
 		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
 		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
 		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
 		int initialLevel = p.getLayer().getInitialLevel(tileMatrixSet.getIdentifier());
-		
+
 		//Esto hace lo mismo que getScale y getLevelFromScale
 		/*int level = 0;
 		double[] pixelSizes = getPixelSizeByLevel();
@@ -946,25 +977,25 @@
 				break;
 			}
 		}*/
-		
+
 		//2-Calculo de la escala
 		double scale = getScale(r, bufWidth);
-		
+
 		//3-Selección del nivel a partir de la escala
 		int level = getLevelFromScale(scale, tileMatrixSet);
-		
+
 		//Para evitar que se salga del array si la capa tiene menos niveles que el tilematrixset
 		int dif = 0;
 		if(gridSubsets)
 			dif = (level - initialLevel) >= tileMatrixSetLimits.size() ?  (level - initialLevel) - tileMatrixSetLimits.size() + 1 : 0;
-		
+
 		//4-Obtenemos la matriz de tiles y los límites si tiene subsets
 		@SuppressWarnings("unused")
 		WMTSTileMatrixLimits tileMatrixLimits = null;
 		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level - dif);
 		if(gridSubsets)
 			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level - initialLevel - dif);
-		
+
 		//5-Selección de tiles que entran en esta bounding box
 		List<WMTSTile> tiles = null;
 		/*if(gridSubsets)
@@ -972,7 +1003,7 @@
 		else*/
 		Extent[] extList = getExtentByResolutionLevel();
 		tiles = tileMatrix.intersects(p.isProjected(), r, extList[level].toRectangle2D());
-		
+
 		//6-Petición
 		WMTSStatus status = null;
 		try {
@@ -983,7 +1014,7 @@
 		WMTSLayer wmtsLayer = p.getLayer();
 		status.setTileList(tiles);
 		status.setLayer(wmtsLayer.getIdentifier());//.substring(p.getLayer().getIdentifier().indexOf("_") + 1));
-		
+
 		status.setFormat(p.getImageFormat());
 		status.setInfoFormat(p.getInfoFormat());
 		status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : "");
@@ -992,17 +1023,17 @@
 		status.setLevel(level - dif);
 		status.setDimension(p.getDimension());
 		status.setValueForDimension(p.getDimensionSelectedValue());
-		
+
 		wmtsLayer.buildResourceURLListFromTemplate(status);
 		this.lastStatus = status;
-		
+
 		return status;
 	}
-	
+
 	/**
 	 * Gets the resolution level from the real coordinates
 	 * @param r
-	 * @param 
+	 * @param
 	 * @return
 	 * @throws RasterDriverException
 	 */
@@ -1012,7 +1043,7 @@
 		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
 		return getLevelFromScale(scale, tileMatrixSet);
 	}
-	
+
 	/**
 	 * Gets the resolution level from the scale
 	 * @param scale
@@ -1037,7 +1068,7 @@
 		}
 		return 0;
 	}
-	
+
 	/**
 	 * Get the tile matrix set using the crs
 	 * @param srs
@@ -1057,7 +1088,7 @@
 			return (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(0);
 		return null;
 	}
-	
+
 	/**
 	 * Gets the scale using the extent and the width in pixels.
 	 * @param r
@@ -1071,16 +1102,16 @@
 		} else
 			return (r.getWidth()) / (width * 0.00028);
 	}
-	
+
 	/**
 	 * Throw a request
 	 * @param status
 	 * @param bandList
 	 * @param listener
-	 * @param alphaBandNumber 
+	 * @param alphaBandNumber
 	 * @return returns a buffer if the listener is null. In any other case it return null.
-	 * @throws RasterDriverException 
-	 * @throws ProcessInterruptedException 
+	 * @throws RasterDriverException
+	 * @throws ProcessInterruptedException
 	 */
 	private synchronized org.gvsig.raster.cache.tile.Tile[] request(
 			WMTSStatus status, BandList bandList, TileListener listener, int requestType) throws RasterDriverException, ProcessInterruptedException {
@@ -1091,16 +1122,16 @@
 		} catch (WMTSException e) {
 			throw new RasterDriverException("Error getting the connector object", e);
 		}
-		
+
 		if(ogcClient == null)
 			throw new RasterDriverException("Error getting the connector object");
-		
+
 		List<WMTSTile> tiles = status.getTileList();
-		
+
 		TilePipe pipe = new TilePipe();
 		//TilePipe2 pipe = new TilePipe2();
 		//TileThreadPool pool = null;
-		
+
 		//Caso 1: Lanza un thread que gestiona que no se lancen muchos threads a la vez
 		if(requestType == LIMITED_THREADS) {
 			RequestThreadManager threadManager = new RequestThreadManager(pipe, tiles, status);
@@ -1116,9 +1147,9 @@
 				new RequestTileLauncher(pipe, statusCopy, tile).start();
 			}
 		}
-		
-		org.gvsig.raster.cache.tile.Tile[] tileList = new org.gvsig.raster.cache.tile.Tile[tiles.size()]; 
-		
+
+		org.gvsig.raster.cache.tile.Tile[] tileList = new org.gvsig.raster.cache.tile.Tile[tiles.size()];
+
 		if(requestType == LIMITED_THREADS || requestType == UNLIMITED_THREADS) {
 			int nCollected = 0;
 			while (nCollected < tiles.size()) {
@@ -1127,7 +1158,7 @@
 				nCollected ++;
 			}
 		}
-		
+
 		if(requestType == SEQUENTIAL) {
 			for (int i = 0; i < tiles.size(); i++) {
 				WMTSTile tile = tiles.get(i);
@@ -1145,12 +1176,12 @@
 				}
 			}
 		}
-		if(listener != null) 
+		if(listener != null)
 			listener.endReading();
-		
+
 		return tileList;
 	}
-	
+
 	/**
 	 * Reads a tile with gdal and calls the method nextBuffer
 	 * @param tile
@@ -1166,7 +1197,7 @@
 			colorTable = driver.getColorTable();
 			bandCount = driver.getBandCount();
 			lastFileTransparency = (DataStoreTransparency)driver.getTransparency();
-			
+
 			RasterQuery q = RasterLocator.getManager().createQuery();
 			q.setAreaOfInterest(new Rectangle(0, 0, tile.getWidthPx(), tile.getHeightPx()));
 			int[] drawableBands = bandList.getDrawableBands();
@@ -1176,13 +1207,13 @@
 			RasterDataStore store = new DefaultRasterStore();
 			store.setProvider(driver);
 			Buffer buf = store.query(q);
-			
+
 			buf.setDataExtent(new Rectangle2D.Double(
-					Math.min(tile.getULX(), tile.getLRX()), 
-					Math.min(tile.getULY(), tile.getLRY()), 
-					Math.abs(tile.getULX() - tile.getLRX()), 
+					Math.min(tile.getULX(), tile.getLRX()),
+					Math.min(tile.getULY(), tile.getLRY()),
+					Math.abs(tile.getULX() - tile.getLRX()),
 					Math.abs(tile.getULY() - tile.getLRY())));
-			
+
 			Buffer alphaBand = null;
 			if(p.getAlphaBand() != -1 && listener != null && p.getAlphaBand() < bandCount) {
 				q = RasterLocator.getManager().createQuery();
@@ -1205,9 +1236,9 @@
 			t.setLr(new Point2D.Double(tile.getLRX(), tile.getLRY()));
 			t.setDownloaderParams("AffineTransform", getAffineTransform());
 			t.setDownloaderParams("Tiling", new Boolean(true));
-			if(listener != null) 
+			if(listener != null)
 				listener.tileReady(t);
-			else 
+			else
 				return t;
 
 		} catch (ProcessInterruptedException e) {
@@ -1222,17 +1253,17 @@
 		}
 		return null;
 	}
-	
+
 	public Image getImageLegend() {
 		try {
 			File file = getOGCClient().getLegendGraphic(
 					((WMTSDataParameters)param).getLayer(),
-					((WMTSDataParameters)param).getStyle(), 
+					((WMTSDataParameters)param).getStyle(),
 					new ICancellable() {
 						public boolean isCanceled() {
 							return false;
 						}
-						
+
 						public Object getID() {
 							return null;
 						}
@@ -1253,7 +1284,7 @@
 	}
 
 	public void setAffineTransform(AffineTransform t){
-		
+
 	}
 
 	public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
@@ -1287,7 +1318,7 @@
         public WMTSDataParameters getParameters() {
 		return (WMTSDataParameters)this.param;
 	}
-        
+
 	/**
 	 * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
 	 * @param pt Punto a transformar
@@ -1313,16 +1344,16 @@
 		}
 		return p;
 	}
-	
+
 	public void setStatus(RasterProvider provider) {
 		if(provider instanceof WMTSProvider) {
 		}
 	}
-	
+
 	public File getLastRequest() {
 		return lastRequest;
 	}
-	
+
 	/**
 	 * ASigna el parámetro de inicialización del driver.
 	 */
@@ -1333,7 +1364,7 @@
 		this.param = param;
 		this.storeServices = storeServices;
 	}
-	
+
 	public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
 		int level;
 		try {
@@ -1343,7 +1374,7 @@
 			throw new InfoByPointException("Error in getFeatureInfo", e);
 		}
 	}
-	
+
 	public int getNearestLevel(double pixelSize) {
 		double[] pixelSizes = getPixelSizeByLevel();
 		for (int i = 0; i < pixelSizes.length - 1; i++) {
@@ -1355,7 +1386,7 @@
 			return getZoomLevels() - 1;
 		return 0;
 	}
-	
+
 	public TileServer getTileServer() {
 		if(tileServer == null) {
 			DefaultRasterStore store = new DefaultRasterStore();
@@ -1364,7 +1395,7 @@
 		}
 		return tileServer;
 	}
-	
+
 	public int[] getTileSize(int level) {
 		return getTileServer().getStruct().getTileSizeByLevel(level);
 	}
@@ -1372,11 +1403,11 @@
 	public boolean isRasterEnclosed() {
 		return true;
 	}
-	
+
 	public Buffer getBufferLastRequest() throws ProcessInterruptedException, RasterDriverException {
 		return null;
 	}
-	
+
 	/**
 	 * Gets the srs code
 	 * @return
@@ -1389,10 +1420,40 @@
 	public RasterProvider getInternalProvider() {
 		return this;
 	}
-	
+
 	public HistogramComputer getHistogramComputer() {
 		if (histogram == null)
 			histogram = new RemoteStoreHistogram(this);
 		return histogram;
 	}
+
+    /* (non-Javadoc)
+     * @see org.gvsig.raster.impl.provider.RasterProvider#addFile(java.io.File)
+     */
+    @Override
+    public void addFile(File file) throws InvalidSourceException {
+        // Do nothing
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.gvsig.raster.impl.provider.RasterProvider#removeFile(java.io.File)
+     */
+    @Override
+    public void removeFile(File file) {
+        // Do nothing
+
+    }
+
+    /* (non-Javadoc)
+     * @see org.gvsig.raster.impl.provider.AbstractRasterProvider#getProjection()
+     */
+    @Override
+    public IProjection getProjection() {
+        if(proj==null){
+            proj = ((WMTSDataParameters)param).getSRS();
+        }
+        return proj;
+    }
+
 }
\ No newline at end of file
