Revision 4272 org.gvsig.raster.wmts/trunk/org.gvsig.raster.wmts/org.gvsig.raster.wmts.io/src/main/java/org/gvsig/raster/wmts/io/WMTSProvider.java

View differences:

WMTSProvider.java
31 31
import java.io.IOException;
32 32
import java.net.ConnectException;
33 33
import java.net.MalformedURLException;
34
import java.net.URI;
35
import java.net.URISyntaxException;
34 36
import java.net.URL;
35 37
import java.util.List;
36 38

  
......
51 53
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
52 54
import org.gvsig.fmap.dal.coverage.exception.InfoByPointException;
53 55
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
56
import org.gvsig.fmap.dal.coverage.exception.InvalidSourceException;
54 57
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
55 58
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
56 59
import org.gvsig.fmap.dal.coverage.exception.QueryException;
......
64 67
import org.gvsig.fmap.dal.coverage.util.MathUtils;
65 68
import org.gvsig.fmap.dal.exception.CloseException;
66 69
import org.gvsig.fmap.dal.exception.InitializeException;
70
import org.gvsig.fmap.dal.exception.OpenException;
67 71
import org.gvsig.fmap.dal.exception.ProviderNotRegisteredException;
68 72
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
69 73
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
......
103 107
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSet;
104 108
import org.gvsig.raster.wmts.ogc.struct.WMTSTileMatrixSetLink;
105 109
import org.gvsig.tools.ToolsLocator;
110

  
111
import org.apache.commons.io.FilenameUtils;
112
import org.cresques.cts.IProjection;
106 113
import org.slf4j.Logger;
107 114
import org.slf4j.LoggerFactory;
108 115
/**
......
116 123
	public static final String          METADATA_DEFINITION_NAME = "WmtsStore";
117 124
	private static Logger               logger                   = LoggerFactory.getLogger(WMTSProvider.class);
118 125
	public static boolean               TILED                    = true;
119
	
126

  
120 127
	//Los tiles se piden de forma secuencial y sin lanzar threads para ello (+Lento)
121 128
	public static int                   SEQUENTIAL               = 0;
122 129
	//Los tiles se piden en threads y hay un thread manager para gestionar que no se pidan m?s de cierto n?mero
......
124 131
	//Los tiles se piden en threads y se lanzan tantos threads como tiles haya
125 132
	public static int                   UNLIMITED_THREADS        = 2;
126 133
	private int                         requestType              = LIMITED_THREADS;
127
	
134

  
128 135
	private static final double         MTS_X_GRADO              = 111319.490793274;
129
	
136

  
130 137
	private Extent                      viewRequest              = null;
131 138
	private WMTSClient                  ogcClient                = null;
132
	//private static Hashtable<URL, WMTSConnector>    
139
	//private static Hashtable<URL, WMTSConnector>
133 140
	//                                    drivers                  = new Hashtable<URL, WMTSConnector> ();
134 141
	private boolean                     open                     = false;
135 142
	private File                        lastRequest              = null;
......
141 148
	private Extent[]                    extentByLevel            = null; //Only for layers without gridSubsets
142 149
	private Extent                      bbox                     = null;
143 150
	private MathUtils                   math                     = RasterLocator.getManager().getMathUtils();
144
	
151

  
145 152
	/**
146 153
	 * This thread manages the number of tiles that have been thrown.
147 154
	 * This number is controlled by the NTHREADS_QUEUE variable.
148
	 * 
155
	 *
149 156
	 * @author Nacho Brodin (nachobrodin@gmail.com)
150 157
	 */
151 158
	public class RequestThreadManager extends Thread {
152 159
		private TilePipe               pipe           = null;
153 160
		private List<WMTSTile>         tiles          = null;
154 161
		private WMTSStatus             status         = null;
155
		
162

  
156 163
		public RequestThreadManager(TilePipe pipe, List<WMTSTile> tiles, WMTSStatus status) {
157 164
			this.pipe = pipe;
158 165
			this.tiles = tiles;
159 166
			this.status = status;
160 167
		}
161
		
168

  
162 169
		public void run() {
163 170
			for (int i = 0; i < tiles.size(); i++) {
164 171
				WMTSTile tile = tiles.get(i);
......
168 175
				if (pipe.getSize() > TilePipe.NTHREADS_QUEUE) {
169 176
					try {
170 177
						synchronized (this) {
171
							wait();							
178
							wait();
172 179
						}
173 180
					} catch( InterruptedException e ) {
174 181
					}
......
177 184
			}
178 185
		}
179 186
	}
180
	
187

  
181 188
	/**
182 189
	 * Thread to download a tile
183 190
	 * @author Nacho Brodin (nachobrodin@gmail.com)
......
208 215
			}
209 216
		}
210 217
	}
211
	
218

  
212 219
	/**
213
	 * Point information 
220
	 * Point information
214 221
	 * @author Nacho Brodin (nachobrodin@gmail.com)
215 222
	 */
216 223
	public class PointInfo {
......
218 225
		public Point2D tile;
219 226
		public Point2D pixelInTile;
220 227
		public int     level;
221
		
228

  
222 229
		public PointInfo(Point2D worldCoord) {
223 230
			this.worldCoord = worldCoord;
224 231
		}
......
236 243
		}
237 244
		dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
238 245
	}
239
	
246

  
240 247
	public WMTSProvider() throws NotSupportedExtensionException {
241 248
		super();
242 249
	}
243
	
250

  
244 251
	/**
245 252
	 * Constructor. Abre el dataset.
246 253
	 * @param proj Proyecci?n
247 254
	 * @param fName Nombre del fichero
248 255
	 * @throws NotSupportedExtensionException
256
	 * @throws OpenException
257
     * @deprecated use {@link #WMTSProvider(URI)}, this constructor will be removed in gvSIG 2.5
249 258
	 */
250
	public WMTSProvider(String params) throws NotSupportedExtensionException {
259
	public WMTSProvider(String params) throws NotSupportedExtensionException, OpenException {
251 260
		super(params);
261
        logger.info("Deprecated use of WMTSProvider constructor");
252 262
		if(params instanceof String) {
253 263
			WMTSDataParameters p = new WMTSDataParametersImpl();
254
			p.setURI((String)params);
264
            try {
265
                p.setURI(new URI((String) params));
266
            } catch (URISyntaxException e) {
267
                throw new OpenException("Can't create URI from" + (String) params, e);
268
            }
255 269
			super.init(p, null, ToolsLocator.getDynObjectManager()
256 270
					.createDynObject(
257 271
							MetadataLocator.getMetadataManager().getDefinition(
......
259 273
			init(p, null);
260 274
		}
261 275
	}
262
	
263
	public WMTSProvider(WMTSDataParameters params,
276

  
277
	 /**
278
     * Constructor. Abre el dataset.
279
     * @param uri URI del fichero
280
     * @throws NotSupportedExtensionException
281
     */
282
    public WMTSProvider(URI uri) throws NotSupportedExtensionException {
283
        super(uri);
284
        WMTSDataParameters p = new WMTSDataParametersImpl();
285
        p.setURI(uri);
286
        super.init(
287
            p,
288
            null,
289
            ToolsLocator.getDynObjectManager().createDynObject(
290
                MetadataLocator.getMetadataManager().getDefinition(DataStore.METADATA_DEFINITION_NAME)));
291
        init(p, null);
292
    }
293

  
294
    public WMTSProvider(WMTSDataParameters params,
264 295
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
265 296
		super(params, storeServices, ToolsLocator.getDynObjectManager()
266 297
				.createDynObject(
......
268 299
								DataStore.METADATA_DEFINITION_NAME)));
269 300
		init(params, storeServices);
270 301
	}
271
	
302

  
272 303
	/**
273 304
	 * Gets the connector from the URL
274 305
	 * @return
......
280 311
			ogcClient = p.getOGCClient();
281 312
			if(ogcClient != null)
282 313
				return ogcClient;
283
			
314

  
284 315
			URL url = null;
285 316
			try {
286
				url = new URL(p.getURI());
317
				url = p.getURI().toURL();
287 318
			} catch (Exception e) {
288 319
				throw new WMTSException("Malformed URL",e);
289 320
			}
290 321
			try {
291 322
				ogcClient = WMTSOGCLocator.getManager().createWMTSClient(url.toString());
292 323
				ogcClient.connect(true, new ICancellable() {
293
					
324

  
294 325
					public boolean isCanceled() {
295 326
						return false;
296 327
					}
297
					
328

  
298 329
					public Object getID() {
299 330
						return null;
300 331
					}
......
325 356
			setDataType(new int[]{Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE});
326 357
			bandCount = 4;
327 358
		}
328
		
359

  
329 360
		if(!(param instanceof WMTSDataParameters))
330 361
			return;
331
		
362

  
332 363
		gridSubsets = hasGridSubsets((WMTSDataParameters)param);
333 364
		open = true;
334 365
	}
335
	
366

  
336 367
	/**
337 368
	 * Returns true if this layer has grid subsets
338 369
	 * @return
......
340 371
	public boolean hasGridSubsets() {
341 372
		return gridSubsets;
342 373
	}
343
	
374

  
344 375
	/**
345 376
	 * Checks if this layer has grid subsets or doesn't
346 377
	 * @param p
......
359 390
				tileMatrixSetLimits = tmsl;
360 391
			}
361 392
		}
362
		
363
		return (tileMatrixSetLimits == null || tileMatrixSetLimits.size() <= 0) ? false : true; 
393

  
394
		return (tileMatrixSetLimits == null || tileMatrixSetLimits.size() <= 0) ? false : true;
364 395
	}
365
	
396

  
366 397
	private boolean areSrsEquals(String sourceSrs, String appSrs) {
367 398
		if(sourceSrs.compareTo(appSrs) == 0)
368 399
			return true;
369
		if(sourceSrs.contains("CRS:84") || sourceSrs.contains("CRS84")) { 
400
		if(sourceSrs.contains("CRS:84") || sourceSrs.contains("CRS84")) {
370 401
			if(appSrs.equals("EPSG:4326"))
371 402
				return true;
372 403
		}
373 404
		return false;
374 405
	}
375
	
406

  
376 407
	/*public static final WMTSConnector getConnectorFromURL(URL url) throws IOException {
377 408
		WMTSConnector drv = (WMTSConnector) drivers.get(url);
378 409
		if (drv == null) {
......
381 412
		}
382 413
		return drv;
383 414
	}*/
384
	
415

  
385 416
	/**
386 417
	 * Obtiene el objeto que contiene que contiene la interpretaci?n de
387 418
	 * color por banda
......
390 421
	public ColorInterpretation getColorInterpretation() {
391 422
		if(super.getColorInterpretation() == null) {
392 423
			ColorInterpretation colorInterpretation = new DataStoreColorInterpretation(getBandCount());
393
			
394
			if(getBandCount() == 1) 
424

  
425
			if(getBandCount() == 1)
395 426
				colorInterpretation = DataStoreColorInterpretation.createGrayInterpretation();
396
			
397
			if(getBandCount() == 3) 
427

  
428
			if(getBandCount() == 3)
398 429
				colorInterpretation = DataStoreColorInterpretation.createRGBInterpretation();
399
			
430

  
400 431
			if(getBandCount() == 4)
401 432
				colorInterpretation = DataStoreColorInterpretation.createRGBAInterpretation();
402
			
433

  
403 434
			if(getBandCount() > 4 || getBandCount() == 2) {
404 435
				for (int i = 0; i < getBandCount(); i++) {
405 436
					colorInterpretation.setColorInterpValue(i, DataStoreColorInterpretation.UNDEF_BAND);
......
409 440
		}
410 441
		return super.getColorInterpretation();
411 442
	}
412
	
443

  
413 444
	public boolean isTiled() {
414 445
		return true;
415 446
	}
416
	
447

  
417 448
	public AffineTransform getAffineTransform() {
418 449
		WMTSDataParameters p = (WMTSDataParameters)parameters;
419 450
		Extent e = getExtent();
420 451
		double psX = e.width() / (lastWidthRequest <= 0 ? p.getWidth() : lastWidthRequest);
421 452
		double psY = -(e.height() / (lastHeightRequest <= 0 ? p.getHeight() : lastHeightRequest));
422 453
		ownTransformation = new AffineTransform(
423
				psX, 
424
				0, 
425
				0, 
426
				psY, 
454
				psX,
455
				0,
456
				0,
457
				psY,
427 458
				e.getULX() - (psX / 2),
428 459
				e.getULY() - (psY / 2));
429 460
		externalTransformation = (AffineTransform) ownTransformation.clone();
430 461
		return ownTransformation;
431 462
	}
432
	
463

  
433 464
	/**
434 465
	 * <p>
435
	 * Gets the bounding box in world coordinates. 
436
	 * If the layer has defined the BoundingBox tag, we will take this bounding box as entire 
466
	 * Gets the bounding box in world coordinates.
467
	 * If the layer has defined the BoundingBox tag, we will take this bounding box as entire
437 468
	 * extension of this layer, else we'll see if the tag WGS84BoundingBox is defined (it can be approximated).
438 469
	 * In this case we'll take WGS84BoundingBox as entire extension.
439 470
	 * </p>
440 471
	 * <br>
441
	 * Note: 
472
	 * Note:
442 473
	 * <br>
443 474
	 * <p>
444 475
	 * If the layer has grid subsets (TileMatrixLimits) then
......
453 484

  
454 485
		if(layer.getBBox() != null)
455 486
			return new ExtentImpl(layer.getBBox().toRectangle2D());
456
		
487

  
457 488
		if(layer.getWGS84BBox() != null) {
458 489
			String crsCode = p.getSRSCode();
459 490
			Rectangle2D r = layer.getWGS84BBoxTransformed(crsCode);
460 491
			if(r != null)
461 492
				return new ExtentImpl(r);
462 493
		}
463
			
494

  
464 495
		if(bbox == null)
465 496
			getExtentByResolutionLevel();
466 497
		return bbox;
467
		
498

  
468 499
		/*if(gridSubsets) {
469 500
			WMTSBoundingBox bbox = layer.getWGS84BBox();
470 501
			return new ExtentImpl(bbox.toRectangle2D());
......
474 505
			return bbox;
475 506
		}*/
476 507
	}
477
	
508

  
478 509
	/**
479 510
	 * Gets the suffix of the downloaded image
480 511
	 * @return
......
487 518
		}
488 519
		if (format.indexOf("png") >= 0){
489 520
	        return "png";
490
		}	
521
		}
491 522
	    if (format.indexOf("xml") >= 0){
492 523
	        return "xml";
493
	    }	
524
	    }
494 525
	    if (format.indexOf("gif") >= 0){
495 526
	        return "gif";
496 527
	    }
......
502 533
	    }
503 534
	    if (format.indexOf("jpg") >= 0
504 535
	        || format.indexOf("jpeg") >= 0){
505
	        return "jpg";			 
536
	        return "jpg";
506 537
	    }
507 538
		return "xml";
508 539
	}
......
518 549
			WMTSDataParameters p = (WMTSDataParameters)parameters;
519 550
			WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
520 551
			WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
521
			
552

  
522 553
	    	double widthMtsTile = 0;
523 554
	    	double heightMtsTile = 0;
524 555
			List<WMTSTileMatrix> tileMatrixList = tileMatrixSet.getTileMatrix();
......
536 567
		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000;
537 568
		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileHeight() * 0.28) / 1000;
538 569
		    	}
539
		    	
570

  
540 571
		    	//TODO: Revisar!!! Creo que el top left sale al rev?s en el de la nasa
541
		    	
572

  
542 573
		    	double h = Math.abs(tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getMatrixHeight() * heightMtsTile)));
543 574
		    	Rectangle2D r = new Rectangle2D.Double(
544
		    			tileMatrix.getTopLeftCorner()[0], 
575
		    			tileMatrix.getTopLeftCorner()[0],
545 576
		    			tileMatrix.getTopLeftCorner()[1] - h,
546 577
		    			Math.abs(tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getTopLeftCorner()[0] + (tileMatrix.getMatrixWidth() * widthMtsTile))),
547 578
		    			h);
......
562 593
		}
563 594
		return extentByLevel;
564 595
	}
565
	
596

  
566 597
	public Rectangle2D getLayerExtent(String layerName, String srs) throws RemoteServiceException {
567 598
		return null;
568 599
	}
......
570 601
	public RasterProvider load() {
571 602
		return this;
572 603
	}
573
	
604

  
574 605
	public boolean isOpen() {
575 606
		return open;
576 607
	}
......
578 609
	public void close() {
579 610
		open = false;
580 611
	}
581
	
612

  
582 613
	public Transparency getTransparency() {
583 614
		if(lastFileTransparency == null) {
584 615
			lastFileTransparency = new DataStoreTransparency(getColorInterpretation());
......
586 617
		}
587 618
		return lastFileTransparency;
588 619
	}
589
	
620

  
590 621
	public NoData getNoDataValue() {
591 622
		NoData nodata = super.getNoDataValue();
592 623
		if(nodata != null)
......
594 625
		return noData;
595 626
	}
596 627

  
597
	public String translateFileName(String fileName) {
598
		return fileName;
628
	public URI translateURI(URI uri) {
629
		return uri;
599 630
	}
600 631

  
601 632
	public void setView(Extent e) {
......
608 639

  
609 640
	public double getWidth() {
610 641
		WMTSDataParameters p = (WMTSDataParameters)parameters;
611
		if (lastWidthRequest <= 0) 
642
		if (lastWidthRequest <= 0)
612 643
			return p.getWidth();
613 644
		return lastWidthRequest;
614 645
	}
615 646

  
616 647
	public double getHeight() {
617 648
		WMTSDataParameters p = (WMTSDataParameters)parameters;
618
		if (lastHeightRequest <= 0) 
649
		if (lastHeightRequest <= 0)
619 650
			return p.getHeight();
620 651
		return lastHeightRequest;
621 652
	}
......
624 655
		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
625 656
		return null;
626 657
	}
627
	
658

  
628 659
	/**
629
	 * When the remote layer has fixed size this method downloads the file and return its reference. 
660
	 * When the remote layer has fixed size this method downloads the file and return its reference.
630 661
	 * File layer has in the long side FIXED_SIZE pixels and the bounding box is complete. This file could be
631 662
	 * useful to build an histogram or calculate statistics. This represents a sample of data.
632 663
	 * @return
......
640 671
	 * Reads a complete block of data and returns an tridimensional array of the right type. This function is useful
641 672
	 * to read a file very fast without setting a view. In a WMTS service when the size is fixed then it will read the
642 673
	 * entire image but when the source hasn't pixel size it will read a sample of data. This set of data will have
643
	 * the size defined in FIXED_SIZE. 
644
	 * 
674
	 * the size defined in FIXED_SIZE.
675
	 *
645 676
	 * @param pos Posici?n donde se empieza  a leer
646 677
	 * @param blockHeight Altura m?xima del bloque leido
647 678
	 * @return Object que es un array tridimendional del tipo de datos del raster. (Bandas X Filas X Columnas)
......
649 680
	 * @throws FileNotOpenException
650 681
	 * @throws RasterDriverException
651 682
	 */
652
	public Object readBlock(int pos, int blockHeight, double scale) 
683
	public Object readBlock(int pos, int blockHeight, double scale)
653 684
	throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
654 685
		return null;
655 686
	}
656
	
687

  
657 688
	public Object getData(int x, int y, int band)
658 689
		throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
659 690
		return null;
660 691
	}
661
	
692

  
662 693
	/**
663 694
	 * Assigns the list of bands RGB and read a window of data
664 695
	 * @param rasterBuf
......
672 703
	 * @throws RasterDriverException
673 704
	 * @throws ProcessInterruptedException
674 705
	 */
675
	public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile, 
706
	public Buffer getBuffer(Buffer rasterBuf, BandList bandList, File lastFile,
676 707
			double ulx, double uly, double lrx, double lry) throws RasterDriverException, ProcessInterruptedException {
677 708
		return null;
678 709
	}
679
	
710

  
680 711
	/**
681 712
	 * Gets the tile matrix from the selected level
682 713
	 * @param level
......
684 715
	 */
685 716
	private WMTSTileMatrix getTileMatrixByLevel(int level) {
686 717
		level = adjustLevel(level);
687
		
718

  
688 719
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
689 720
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
690 721
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
691
		
722

  
692 723
		WMTSTileMatrixLimits tileMatrixLimits = null;
693 724
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level);
694 725
		if(hasGridSubsets()) {
......
697 728
		}
698 729
		return tileMatrix;
699 730
	}
700
	
731

  
701 732
	/**
702 733
	 * Returns the number of levels
703 734
	 * @return
......
710 741
			return Math.min(tileMatrixSet.getTileMatrix().size(), tileMatrixSetLimits.size());
711 742
		}
712 743
		return tileMatrixSet.getTileMatrix().size();
713
		
744

  
714 745
	}
715
	
746

  
716 747
	public Extent getCoordsInTheNearestLevel(Extent extent, int w, int h) {
717 748
		double[] pixelSizes = getPixelSizeByLevel();
718 749
		double currentPixelSize = extent.width() / (double)w;
719
		
750

  
720 751
		int level = 0;
721 752
		for (int i = 0; i < (pixelSizes.length - 1); i++) {
722 753
			if(currentPixelSize < pixelSizes[i] && currentPixelSize >= pixelSizes[i + 1]) {
......
724 755
				break;
725 756
			}
726 757
		}
727
		
758

  
728 759
		return getZoomLevelCoordinates(level, extent, w, h);
729 760
	}
730
	
761

  
731 762
	public Extent getCoordsInLevel(Point2D viewCenter, int level, int w, int h) {
732 763
		WMTSDataParameters p = (WMTSDataParameters)param;
733 764
		level = adjustLevel(level);
734 765
		WMTSTileMatrix tileMatrix = getTileMatrixByLevel(level);
735
		
766

  
736 767
		boolean proj = p.isProjected();
737
		
768

  
738 769
		double psX = tileMatrix.getWidthWCTile(proj) / tileMatrix.getTileWidth();
739 770
		double psY = tileMatrix.getHeightWCTile(proj) / tileMatrix.getTileHeight();
740
		
771

  
741 772
		double ulx = viewCenter.getX() - ((w / 2) * psX);
742 773
		double uly = viewCenter.getY() - ((h / 2) * psY);
743 774
		double lrx = ulx + (w * psX);
744 775
		double lry = uly + (h * psY);
745 776
		return new ExtentImpl(ulx, uly, lrx, lry);
746 777
	}
747
	
778

  
748 779
	/**
749
	 * Calculates the extent of a zoom level using other extent as a reference. The new extent is 
750
	 * calculated with the same coordinate at the center. 
780
	 * Calculates the extent of a zoom level using other extent as a reference. The new extent is
781
	 * calculated with the same coordinate at the center.
751 782
	 * @param level
752 783
	 * @param extent
753 784
	 * @param w
......
759 790
		double centerY = extent.getCenterY();
760 791
		return getCoordsInLevel(new Point2D.Double(centerX, centerY), level, w, h);
761 792
	}
762
	
793

  
763 794
	/**
764 795
	 * Returns a list of pixel sizes by level
765 796
	 * @return
......
767 798
	public double[] getPixelSizeByLevel() {
768 799
		WMTSDataParameters p = (WMTSDataParameters)param;
769 800
		double[] list = new double[getZoomLevels()];
770
		
801

  
771 802
		for (int i = 0; i < getZoomLevels(); i++) {
772 803
			WMTSTileMatrix tileMatrix = getTileMatrixByLevel(i);
773 804
			list[i] = math.adjustDouble(tileMatrix.getWidthWCTile(p.isProjected()) / tileMatrix.getTileWidth());
774 805
		}
775 806
		return list;
776 807
	}
777
	
808

  
778 809
	/**
779 810
	 * Adjust de level to the range
780 811
	 * @param level
......
787 818
			level = getZoomLevels();
788 819
		return level;
789 820
	}
790
	
821

  
791 822
	public org.gvsig.raster.cache.tile.Tile getTile(SpiRasterQuery q) throws TileGettingException {
792 823
		//q.getResolutionLevel(), q.getTileCol(), q.getTileRow(), q.getBBox(), q.getCacheStruct()!
793
		
824

  
794 825
		CacheStruct str = getTileServer().getStruct();
795
		
826

  
796 827
		//1-Selecci?n de WMTSTileMatrixSet por srs
797 828
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
798 829
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
799 830
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
800
		
831

  
801 832
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(q.getResolutionLevel());
802 833
		if(gridSubsets) {
803 834
			WMTSTileMatrixLimits tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(q.getResolutionLevel());
......
805 836
		}
806 837
		int bufWidth = tileMatrix.getTileWidth();
807 838
		int bufHeight = tileMatrix.getTileHeight();
808
		
839

  
809 840
		try {
810 841
			Extent adjBbox = q.getAdjustedRequestBoundingBox();
811 842
			Rectangle2D r = adjBbox.toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
812 843
			WMTSStatus status = buildWMTSStatus(r, bufWidth , bufHeight);
813
			
844

  
814 845
			int[] size = str.getTileSizeByLevel(q.getResolutionLevel());
815 846
			WMTSTile tile = WMTSOGCLocator.getManager().createTile(
816
					size, 
817
					new int[]{q.getTileRow(), q.getTileCol()}, 
847
					size,
848
					new int[]{q.getTileRow(), q.getTileCol()},
818 849
					new double[]{adjBbox.getULX(), adjBbox.getULY(), adjBbox.getLRX(), adjBbox.getLRY()});
819
			
850

  
820 851
			File file = getOGCClient().getTile(status, null);
821 852
			tile.setFile(file);
822 853
			//Creamos un BandList con todas las bandas del fichero
823 854
			BandList bandList = new BandListImpl();
824 855
			for(int i = 0; i < getBandCount(); i++) {
825 856
				try {
826
					DatasetBand band = new DatasetBandImpl(getURIOfFirstProvider(), i, getDataType()[i], getBandCount());
857
					DatasetBand band = new DatasetBandImpl(getURIOfFirstProvider().getPath(), i, getDataType()[i], getBandCount());
827 858
					bandList.addBand(band);
828 859
				} catch(BandNotFoundInListException e) {
829 860
					//No a?adimos la banda
......
838 869
			throw new TileGettingException("Error getting tiles", e);
839 870
		}
840 871
	}
841
	
872

  
842 873
	@Override
843
	public void loadBuffer(SpiRasterQuery q) 
874
	public void loadBuffer(SpiRasterQuery q)
844 875
			throws ProcessInterruptedException, RasterDriverException {
845 876
		Rectangle2D r = q.getAdjustedRequestBoundingBox().toRectangle2D();//new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
846 877
		WMTSStatus status = buildWMTSStatus(r, q.getAdjustedWidth(), q.getAdjustedBufHeight());
......
850 881
		Buffer b = matrixBuffer.getWindow(q.getAdjustedRequestBoundingBox(), q.getBufWidth(), q.getBufHeight(), q.getBandList().getDrawableBandsCount());
851 882
		q.setBufferResult(b);
852 883
	}
853
	
884

  
854 885
	/**
855
	 * Gets the information from a point 
886
	 * Gets the information from a point
856 887
	 * @param wcx
857 888
	 * @param wcy
858 889
	 * @param level
......
863 894
		PointInfo pointInfo = new PointInfo(new Point2D.Double(wcx, wcy));
864 895
		pointInfo.level = level;
865 896
		getTileInfo(pointInfo);
866
		
897

  
867 898
		WMTSClient ogcClient = null;
868 899
		try {
869 900
			ogcClient = getOGCClient();
870 901
			lastStatus.setTileRow((int)pointInfo.tile.getX());
871 902
			lastStatus.setTileCol((int)pointInfo.tile.getY());
872
			
903

  
873 904
			String fi = ogcClient.getFeatureInfo(lastStatus, (int)pointInfo.pixelInTile.getX(), (int)pointInfo.pixelInTile.getY(), null);
874 905
			return fi;
875 906
		} catch (WMTSException e) {
876 907
			throw new RasterDriverException("Error getting the connector object", e);
877
		} 
908
		}
878 909
	}
879
	
910

  
880 911
	/**
881 912
	 * Gets a tile position from a world coordinates point and a resolution level
882 913
	 * @param point
......
886 917
	 */
887 918
	private void getTileInfo(PointInfo pointInfo) {
888 919
		WMTSDataParameters p = (WMTSDataParameters)param;
889
		
920

  
890 921
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
891 922
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
892 923
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
893
		
924

  
894 925
		WMTSTileMatrixLimits tileMatrixLimits = null;
895 926
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(pointInfo.level);
896 927
		if(hasGridSubsets()) {
897 928
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(pointInfo.level);
898 929
			tileMatrix = tileMatrixLimits.getTileMatrix();
899 930
		}
900
		
931

  
901 932
		List<WMTSTile> tiles = null;
902 933
		if(hasGridSubsets())
903 934
			tiles = tileMatrix.contains(p.isProjected(), tileMatrixLimits, pointInfo.worldCoord, getExtent().toRectangle2D());
904 935
		else
905 936
			tiles = tileMatrix.contains(p.isProjected(), pointInfo.worldCoord, getExtent().toRectangle2D());
906
		
937

  
907 938
		//Tile row and column
908 939
		pointInfo.tile = new Point2D.Double(tiles.get(0).getRow(), tiles.get(0).getCol());
909
		
940

  
910 941
		//Desplazamiento en pixels dentro del tile
911 942
		Point2D rasterPoint = tiles.get(0).worldToRaster(pointInfo.worldCoord);
912 943
		pointInfo.pixelInTile = new Point2D.Double(rasterPoint.getX(), rasterPoint.getY());
913 944
	}
914
	
945

  
915 946
	/**
916
	 * Builds the WMTSStatus object using the parameters and the request bounding box. 
947
	 * Builds the WMTSStatus object using the parameters and the request bounding box.
917 948
	 * @param r
918 949
	 * @param bufWidth
919 950
	 * @return
......
921 952
	 */
922 953
	public WMTSStatus buildWMTSStatus(Rectangle2D r, int bufWidth, int bufHeight) throws RasterDriverException {
923 954
		WMTSDataParameters p = (WMTSDataParameters)param;
924
		
955

  
925 956
		//Mantiene actualizados los par?metros del WMTSStoreParameters con la ?ltima petici?n hecha
926 957
		p.setExtent(r);
927 958
		p.setWidth(bufWidth);
928 959
		p.setHeight(bufHeight);
929
		
960

  
930 961
		lastWidthRequest = bufWidth;
931 962
		lastHeightRequest = bufHeight;
932
		
963

  
933 964
		//1-Selecci?n de WMTSTileMatrixSet por srs
934 965
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
935 966
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
936 967
		List<WMTSTileMatrixLimits> tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
937 968
		int initialLevel = p.getLayer().getInitialLevel(tileMatrixSet.getIdentifier());
938
		
969

  
939 970
		//Esto hace lo mismo que getScale y getLevelFromScale
940 971
		/*int level = 0;
941 972
		double[] pixelSizes = getPixelSizeByLevel();
......
946 977
				break;
947 978
			}
948 979
		}*/
949
		
980

  
950 981
		//2-Calculo de la escala
951 982
		double scale = getScale(r, bufWidth);
952
		
983

  
953 984
		//3-Selecci?n del nivel a partir de la escala
954 985
		int level = getLevelFromScale(scale, tileMatrixSet);
955
		
986

  
956 987
		//Para evitar que se salga del array si la capa tiene menos niveles que el tilematrixset
957 988
		int dif = 0;
958 989
		if(gridSubsets)
959 990
			dif = (level - initialLevel) >= tileMatrixSetLimits.size() ?  (level - initialLevel) - tileMatrixSetLimits.size() + 1 : 0;
960
		
991

  
961 992
		//4-Obtenemos la matriz de tiles y los l?mites si tiene subsets
962 993
		@SuppressWarnings("unused")
963 994
		WMTSTileMatrixLimits tileMatrixLimits = null;
964 995
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level - dif);
965 996
		if(gridSubsets)
966 997
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level - initialLevel - dif);
967
		
998

  
968 999
		//5-Selecci?n de tiles que entran en esta bounding box
969 1000
		List<WMTSTile> tiles = null;
970 1001
		/*if(gridSubsets)
......
972 1003
		else*/
973 1004
		Extent[] extList = getExtentByResolutionLevel();
974 1005
		tiles = tileMatrix.intersects(p.isProjected(), r, extList[level].toRectangle2D());
975
		
1006

  
976 1007
		//6-Petici?n
977 1008
		WMTSStatus status = null;
978 1009
		try {
......
983 1014
		WMTSLayer wmtsLayer = p.getLayer();
984 1015
		status.setTileList(tiles);
985 1016
		status.setLayer(wmtsLayer.getIdentifier());//.substring(p.getLayer().getIdentifier().indexOf("_") + 1));
986
		
1017

  
987 1018
		status.setFormat(p.getImageFormat());
988 1019
		status.setInfoFormat(p.getInfoFormat());
989 1020
		status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : "");
......
992 1023
		status.setLevel(level - dif);
993 1024
		status.setDimension(p.getDimension());
994 1025
		status.setValueForDimension(p.getDimensionSelectedValue());
995
		
1026

  
996 1027
		wmtsLayer.buildResourceURLListFromTemplate(status);
997 1028
		this.lastStatus = status;
998
		
1029

  
999 1030
		return status;
1000 1031
	}
1001
	
1032

  
1002 1033
	/**
1003 1034
	 * Gets the resolution level from the real coordinates
1004 1035
	 * @param r
1005
	 * @param 
1036
	 * @param
1006 1037
	 * @return
1007 1038
	 * @throws RasterDriverException
1008 1039
	 */
......
1012 1043
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
1013 1044
		return getLevelFromScale(scale, tileMatrixSet);
1014 1045
	}
1015
	
1046

  
1016 1047
	/**
1017 1048
	 * Gets the resolution level from the scale
1018 1049
	 * @param scale
......
1037 1068
		}
1038 1069
		return 0;
1039 1070
	}
1040
	
1071

  
1041 1072
	/**
1042 1073
	 * Get the tile matrix set using the crs
1043 1074
	 * @param srs
......
1057 1088
			return (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(0);
1058 1089
		return null;
1059 1090
	}
1060
	
1091

  
1061 1092
	/**
1062 1093
	 * Gets the scale using the extent and the width in pixels.
1063 1094
	 * @param r
......
1071 1102
		} else
1072 1103
			return (r.getWidth()) / (width * 0.00028);
1073 1104
	}
1074
	
1105

  
1075 1106
	/**
1076 1107
	 * Throw a request
1077 1108
	 * @param status
1078 1109
	 * @param bandList
1079 1110
	 * @param listener
1080
	 * @param alphaBandNumber 
1111
	 * @param alphaBandNumber
1081 1112
	 * @return returns a buffer if the listener is null. In any other case it return null.
1082
	 * @throws RasterDriverException 
1083
	 * @throws ProcessInterruptedException 
1113
	 * @throws RasterDriverException
1114
	 * @throws ProcessInterruptedException
1084 1115
	 */
1085 1116
	private synchronized org.gvsig.raster.cache.tile.Tile[] request(
1086 1117
			WMTSStatus status, BandList bandList, TileListener listener, int requestType) throws RasterDriverException, ProcessInterruptedException {
......
1091 1122
		} catch (WMTSException e) {
1092 1123
			throw new RasterDriverException("Error getting the connector object", e);
1093 1124
		}
1094
		
1125

  
1095 1126
		if(ogcClient == null)
1096 1127
			throw new RasterDriverException("Error getting the connector object");
1097
		
1128

  
1098 1129
		List<WMTSTile> tiles = status.getTileList();
1099
		
1130

  
1100 1131
		TilePipe pipe = new TilePipe();
1101 1132
		//TilePipe2 pipe = new TilePipe2();
1102 1133
		//TileThreadPool pool = null;
1103
		
1134

  
1104 1135
		//Caso 1: Lanza un thread que gestiona que no se lancen muchos threads a la vez
1105 1136
		if(requestType == LIMITED_THREADS) {
1106 1137
			RequestThreadManager threadManager = new RequestThreadManager(pipe, tiles, status);
......
1116 1147
				new RequestTileLauncher(pipe, statusCopy, tile).start();
1117 1148
			}
1118 1149
		}
1119
		
1120
		org.gvsig.raster.cache.tile.Tile[] tileList = new org.gvsig.raster.cache.tile.Tile[tiles.size()]; 
1121
		
1150

  
1151
		org.gvsig.raster.cache.tile.Tile[] tileList = new org.gvsig.raster.cache.tile.Tile[tiles.size()];
1152

  
1122 1153
		if(requestType == LIMITED_THREADS || requestType == UNLIMITED_THREADS) {
1123 1154
			int nCollected = 0;
1124 1155
			while (nCollected < tiles.size()) {
......
1127 1158
				nCollected ++;
1128 1159
			}
1129 1160
		}
1130
		
1161

  
1131 1162
		if(requestType == SEQUENTIAL) {
1132 1163
			for (int i = 0; i < tiles.size(); i++) {
1133 1164
				WMTSTile tile = tiles.get(i);
......
1145 1176
				}
1146 1177
			}
1147 1178
		}
1148
		if(listener != null) 
1179
		if(listener != null)
1149 1180
			listener.endReading();
1150
		
1181

  
1151 1182
		return tileList;
1152 1183
	}
1153
	
1184

  
1154 1185
	/**
1155 1186
	 * Reads a tile with gdal and calls the method nextBuffer
1156 1187
	 * @param tile
......
1166 1197
			colorTable = driver.getColorTable();
1167 1198
			bandCount = driver.getBandCount();
1168 1199
			lastFileTransparency = (DataStoreTransparency)driver.getTransparency();
1169
			
1200

  
1170 1201
			RasterQuery q = RasterLocator.getManager().createQuery();
1171 1202
			q.setAreaOfInterest(new Rectangle(0, 0, tile.getWidthPx(), tile.getHeightPx()));
1172 1203
			int[] drawableBands = bandList.getDrawableBands();
......
1176 1207
			RasterDataStore store = new DefaultRasterStore();
1177 1208
			store.setProvider(driver);
1178 1209
			Buffer buf = store.query(q);
1179
			
1210

  
1180 1211
			buf.setDataExtent(new Rectangle2D.Double(
1181
					Math.min(tile.getULX(), tile.getLRX()), 
1182
					Math.min(tile.getULY(), tile.getLRY()), 
1183
					Math.abs(tile.getULX() - tile.getLRX()), 
1212
					Math.min(tile.getULX(), tile.getLRX()),
1213
					Math.min(tile.getULY(), tile.getLRY()),
1214
					Math.abs(tile.getULX() - tile.getLRX()),
1184 1215
					Math.abs(tile.getULY() - tile.getLRY())));
1185
			
1216

  
1186 1217
			Buffer alphaBand = null;
1187 1218
			if(p.getAlphaBand() != -1 && listener != null && p.getAlphaBand() < bandCount) {
1188 1219
				q = RasterLocator.getManager().createQuery();
......
1205 1236
			t.setLr(new Point2D.Double(tile.getLRX(), tile.getLRY()));
1206 1237
			t.setDownloaderParams("AffineTransform", getAffineTransform());
1207 1238
			t.setDownloaderParams("Tiling", new Boolean(true));
1208
			if(listener != null) 
1239
			if(listener != null)
1209 1240
				listener.tileReady(t);
1210
			else 
1241
			else
1211 1242
				return t;
1212 1243

  
1213 1244
		} catch (ProcessInterruptedException e) {
......
1222 1253
		}
1223 1254
		return null;
1224 1255
	}
1225
	
1256

  
1226 1257
	public Image getImageLegend() {
1227 1258
		try {
1228 1259
			File file = getOGCClient().getLegendGraphic(
1229 1260
					((WMTSDataParameters)param).getLayer(),
1230
					((WMTSDataParameters)param).getStyle(), 
1261
					((WMTSDataParameters)param).getStyle(),
1231 1262
					new ICancellable() {
1232 1263
						public boolean isCanceled() {
1233 1264
							return false;
1234 1265
						}
1235
						
1266

  
1236 1267
						public Object getID() {
1237 1268
							return null;
1238 1269
						}
......
1253 1284
	}
1254 1285

  
1255 1286
	public void setAffineTransform(AffineTransform t){
1256
		
1287

  
1257 1288
	}
1258 1289

  
1259 1290
	public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
......
1287 1318
        public WMTSDataParameters getParameters() {
1288 1319
		return (WMTSDataParameters)this.param;
1289 1320
	}
1290
        
1321

  
1291 1322
	/**
1292 1323
	 * Convierte un punto desde coordenadas pixel a coordenadas del mundo.
1293 1324
	 * @param pt Punto a transformar
......
1313 1344
		}
1314 1345
		return p;
1315 1346
	}
1316
	
1347

  
1317 1348
	public void setStatus(RasterProvider provider) {
1318 1349
		if(provider instanceof WMTSProvider) {
1319 1350
		}
1320 1351
	}
1321
	
1352

  
1322 1353
	public File getLastRequest() {
1323 1354
		return lastRequest;
1324 1355
	}
1325
	
1356

  
1326 1357
	/**
1327 1358
	 * ASigna el par?metro de inicializaci?n del driver.
1328 1359
	 */
......
1333 1364
		this.param = param;
1334 1365
		this.storeServices = storeServices;
1335 1366
	}
1336
	
1367

  
1337 1368
	public String getInfoByPoint(int x, int y, Extent bbox, int w, int h, ICancellable cancellable) throws InfoByPointException {
1338 1369
		int level;
1339 1370
		try {
......
1343 1374
			throw new InfoByPointException("Error in getFeatureInfo", e);
1344 1375
		}
1345 1376
	}
1346
	
1377

  
1347 1378
	public int getNearestLevel(double pixelSize) {
1348 1379
		double[] pixelSizes = getPixelSizeByLevel();
1349 1380
		for (int i = 0; i < pixelSizes.length - 1; i++) {
......
1355 1386
			return getZoomLevels() - 1;
1356 1387
		return 0;
1357 1388
	}
1358
	
1389

  
1359 1390
	public TileServer getTileServer() {
1360 1391
		if(tileServer == null) {
1361 1392
			DefaultRasterStore store = new DefaultRasterStore();
......
1364 1395
		}
1365 1396
		return tileServer;
1366 1397
	}
1367
	
1398

  
1368 1399
	public int[] getTileSize(int level) {
1369 1400
		return getTileServer().getStruct().getTileSizeByLevel(level);
1370 1401
	}
......
1372 1403
	public boolean isRasterEnclosed() {
1373 1404
		return true;
1374 1405
	}
1375
	
1406

  
1376 1407
	public Buffer getBufferLastRequest() throws ProcessInterruptedException, RasterDriverException {
1377 1408
		return null;
1378 1409
	}
1379
	
1410

  
1380 1411
	/**
1381 1412
	 * Gets the srs code
1382 1413
	 * @return
......
1389 1420
	public RasterProvider getInternalProvider() {
1390 1421
		return this;
1391 1422
	}
1392
	
1423

  
1393 1424
	public HistogramComputer getHistogramComputer() {
1394 1425
		if (histogram == null)
1395 1426
			histogram = new RemoteStoreHistogram(this);
1396 1427
		return histogram;
1397 1428
	}
1429

  
1430
    /* (non-Javadoc)
1431
     * @see org.gvsig.raster.impl.provider.RasterProvider#addFile(java.io.File)
1432
     */
1433
    @Override
1434
    public void addFile(File file) throws InvalidSourceException {
1435
        // Do nothing
1436

  
1437
    }
1438

  
1439
    /* (non-Javadoc)
1440
     * @see org.gvsig.raster.impl.provider.RasterProvider#removeFile(java.io.File)
1441
     */
1442
    @Override
1443
    public void removeFile(File file) {
1444
        // Do nothing
1445

  
1446
    }
1447

  
1448
    /* (non-Javadoc)
1449
     * @see org.gvsig.raster.impl.provider.AbstractRasterProvider#getProjection()
1450
     */
1451
    @Override
1452
    public IProjection getProjection() {
1453
        if(proj==null){
1454
            proj = ((WMTSDataParameters)param).getSRS();
1455
        }
1456
        return proj;
1457
    }
1458

  
1398 1459
}

Also available in: Unified diff