Revision 231 org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.io/org.gvsig.raster.io.base/src/main/java/org/gvsig/fmap/dal/coverage/dataset/io/wmts/WMTSProvider.java

View differences:

WMTSProvider.java
97 97
	private DataStoreTransparency       fileTransparency         = null;
98 98
	private int                         lastWidthRequest         = 0;
99 99
	private int                         lastHeightRequest        = 0;
100
	private boolean                     gridSubsets              = true;
101
	private Extent[]                    extentByLevel            = null; //Only for layers without gridSubsets
100 102
	
101 103
	public static void register() {
102 104
		ExtensionPointManager extensionPoints = ToolsLocator.getExtensionPointManager();
......
179 181
		setParam(params);
180 182
		setDataType(new int[]{Buffer.TYPE_BYTE, Buffer.TYPE_BYTE, Buffer.TYPE_BYTE});
181 183
		bandCount = 3;
184
		
185
		if(!(param instanceof WMTSStoreParameters))
186
			return;
187
		
188
		gridSubsets = hasGridSubsets((WMTSStoreParameters)param);
182 189
	}
183 190
	
191
	/**
192
	 * Checks if this layer has grid subsets or doesn't
193
	 * @param p
194
	 * @return
195
	 */
196
	@SuppressWarnings("unchecked")
197
	private boolean hasGridSubsets(WMTSStoreParameters p) {
198
		ArrayList tileMatrixSetLimits = null;
199
		ArrayList<?> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
200
		String srs = p.getSRSCode();
201
		for (int i = 0; i < tileMatrixSetLinkList.size(); i++) {
202
			WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i);
203
			WMTSTileMatrixSet tms = tileMatrixSetLink.getTileMatrixSet();
204
			ArrayList tmsl = tileMatrixSetLink.getTileMatrixLimits();
205
			String srsTileSet = tms.getSupportedCRS();
206
			if(srsTileSet.compareTo(srs) == 0) {
207
				tileMatrixSetLimits = tmsl;
208
			}
209
		}
210
		
211
		return tileMatrixSetLimits.size() <= 0 ? false : true; 
212
	}
213
	
184 214
	public static final WMTSConnector getConnectorFromURL(URL url) throws IOException {
185 215
		WMTSConnector drv = (WMTSConnector) drivers.get(url);
186 216
		if (drv == null) {
......
235 265
	}
236 266
	
237 267
	/**
238
	 * Calcula el extent en coordenadas del mundo real
268
	 * Gets the bounding box in world coordinates. If the layer has grid subsets (TileMatrixLimits) then
269
	 * this will have a only extent but if the layer doesn't have grid subsets then this will have a different
270
	 * extent in each level resolution. In this case we need to know the extent for each level.
239 271
	 * @return Extent
240 272
	 */
241 273
	public Extent getExtent() {
242 274
		WMTSStoreParametersImpl p = (WMTSStoreParametersImpl)parameters;
243
		WMTSLayer layer = p.getLayer();
244
		WMTSBoundingBox bbox = layer.getWGS84BBox();
245
		return new ExtentImpl(bbox.toRectangle2D());
275
		if(gridSubsets) {
276
			WMTSLayer layer = p.getLayer();
277
			WMTSBoundingBox bbox = layer.getWGS84BBox();
278
			return new ExtentImpl(bbox.toRectangle2D());
279
		} else {
280
			WMTSTileMatrixSet tileMatrixSet = getTileMatrixSetLink().getTileMatrixSet();
281
			
282
			//Si ya se han calculado los niveles es q el extent es v?lido sino el nivel ser? el 0
283
			double scale = 0D;
284
			int level = 0;
285
			if(extentByLevel != null && p.getExtent() != null) {
286
				scale = getScale(p.getExtent(), p.getWidth());
287
				try {
288
					level = getLevelFromScale(scale, tileMatrixSet);
289
				} catch (RasterDriverException e) {
290
					e.printStackTrace();
291
				}				
292
			}
293
			
294
			Extent[] ext = getExtentByResolutionLevel();
295
			
296
			if(ext != null && level >= 0 && level < ext.length)
297
				return ext[level];
298
		}
299
		return null;
246 300
	}
247 301

  
302
	/**
303
	 * When a layer doesn't have grid subsets this will have a different bounding
304
	 * box by resolution level. This function calculates and returns the array of
305
	 * extents, one by resolution level.
306
	 * @return
307
	 */
308
	private Extent[] getExtentByResolutionLevel() {
309
		if(extentByLevel == null) {
310
			WMTSStoreParametersImpl p = (WMTSStoreParametersImpl)parameters;
311
			WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
312
			WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
313
			
314
	    	double widthMtsTile = 0;
315
	    	double heightMtsTile = 0;
316
			ArrayList<?> tileMatrixList = tileMatrixSet.getTileMatrix();
317
			extentByLevel = new ExtentImpl[tileMatrixList.size()];
318
			for (int i = 0; i < tileMatrixList.size(); i++) {
319
				WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixList.get(i);
320
		    	if(!p.getSRS().isProjected()) {
321
		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / (MTS_X_GRADO * 1000);
322
		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / (MTS_X_GRADO * 1000);
323
		    	} else {
324
		    		widthMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000;
325
		    		heightMtsTile = (tileMatrix.getScaleDenominator() * tileMatrix.getTileWidth() * 0.28) / 1000;
326
		    	}
327
		    	
328
		    	double h = Math.abs(tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getTopLeftCorner()[0] - (tileMatrix.getMatrixHeight() * heightMtsTile)));
329
		    	Rectangle2D r = new Rectangle2D.Double(
330
		    			tileMatrix.getTopLeftCorner()[1], 
331
		    			tileMatrix.getTopLeftCorner()[0] - h,
332
		    			Math.abs(tileMatrix.getTopLeftCorner()[1] - (tileMatrix.getTopLeftCorner()[1] + (tileMatrix.getMatrixWidth() * widthMtsTile))),
333
		    			h);
334
		    	extentByLevel[i] = new ExtentImpl(r);
335
			}
336
			
337
		}
338
		return extentByLevel;
339
	}
248 340
	
249 341
	/*
250 342
	 * (non-Javadoc)
......
407 499
	public void getWindowRaster(double minX, double minY, double maxX, double maxY, 
408 500
			int bufWidth, int bufHeight, BandList bandList, TileListener listener, int frameInPx)throws ProcessInterruptedException, RasterDriverException {
409 501
		WMTSStoreParameters p = (WMTSStoreParameters)param;
410
		WMTSTileMatrixSet tileMatrixSet = null;
411
		WMTSTileMatrixLimits tileMatrixLimits = null;
412
		WMTSTileMatrix tileMatrix = null;
413
		ArrayList tileMatrixSetLimits = null;
502
		Rectangle2D r = new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
503
		
504
		//Mantiene actualizados los par?metros del WMTSStoreParameters con la ?ltima petici?n hecha
505
		p.setExtent(r);
506
		p.setWidth(bufWidth);
507
		p.setHeight(bufHeight);
508
		
414 509
		lastWidthRequest = bufWidth;
415 510
		lastHeightRequest = bufHeight;
416 511
		
417
		ArrayList<?> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
418
		
419 512
		//1-Selecci?n de WMTSTileMatrixSet por srs
513
		WMTSTileMatrixSetLink tileMatrixSetLink = getTileMatrixSetLink();
514
		WMTSTileMatrixSet tileMatrixSet = tileMatrixSetLink.getTileMatrixSet();
515
		ArrayList tileMatrixSetLimits = tileMatrixSetLink.getTileMatrixLimits();
420 516
		
421
		String srs = p.getSRSCode();
422
		for (int i = 0; i < tileMatrixSetLinkList.size(); i++) {
423
			WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i);
424
			WMTSTileMatrixSet tms = tileMatrixSetLink.getTileMatrixSet();
425
			ArrayList tmsl = tileMatrixSetLink.getTileMatrixLimits();
426
			String srsTileSet = tms.getSupportedCRS();
427
			if(srsTileSet.compareTo(srs) == 0) {
428
				tileMatrixSet = tms;
429
				tileMatrixSetLimits = tmsl;
430
			}
431
		}
517
		//2-Calculo de la escala
518
		double scale = getScale(r, bufWidth);
432 519
		
433
		if(tileMatrixSet == null)
434
			return;
520
		//3-Selecci?n del nivel a partir de la escala
521
		int level = getLevelFromScale(scale, tileMatrixSet);
522

  
523
		//4-Obtenemos la matriz de tiles y los l?mites si tiene subsets
524
		WMTSTileMatrixLimits tileMatrixLimits = null;
525
		WMTSTileMatrix tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(level);
526
		if(gridSubsets)
527
			tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(level);
435 528
		
436
		Rectangle2D r = new Rectangle2D.Double(Math.min(minX, maxX), Math.min(minY, maxY), Math.abs(maxX - minX), Math.abs(maxY - minY));
437
		double scale = 0;
529
		//5-Selecci?n de tiles que entran en esta bounding box
530
		ArrayList<Tile> tiles = null;
531
		if(gridSubsets)
532
			tiles = tileMatrix.intersects(p.getSRS().isProjected(), tileMatrixLimits, r, getExtent().toRectangle2D());
533
		else
534
			tiles = tileMatrix.intersects(p.getSRS().isProjected(), r, getExtent().toRectangle2D());
438 535
		
439
		//Calculo de la escala en geogr?ficas
440
		if(!p.getSRS().isProjected()) {
441
			scale = (1000 * r.getWidth() * MTS_X_GRADO) / (bufWidth * 0.28);
442
		} else
443
			scale = (1000 * r.getWidth()) / (bufWidth * 0.28);
536
		//6-Petici?n
537
		WMTSStatus status = new WMTSStatus();
538
		status.setLayer(p.getLayer().getIdentifier());
539
		status.setFormat(p.getImageFormat());
540
		status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : "");
541
		status.setTileMatrixSet(tileMatrixSet.getIdentifier());
542
		status.setTileMatrix(tileMatrix.getIdentifier());
444 543
		
445
		
446
		tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(0);
447
		
448
		//2-Selecci?n de WMTSTileMatrix
449
		
544
		request(status, tiles, bandList, listener);
545
	}
546
	
547
	/**
548
	 * Gets the resolution level from the scale
549
	 * @param scale
550
	 * @param tileMatrixSet
551
	 * @return
552
	 * @throws RasterDriverException
553
	 */
554
	public int getLevelFromScale(double scale, WMTSTileMatrixSet tileMatrixSet) throws RasterDriverException {
450 555
		//Recorremos los tileMatrix para obtener la escala m?s aproximada
451
		//Con la escala obtenemos el WMTSTileMatrix que corresponde
452 556
		int levelModifier = 0;
453 557
		try {
454 558
			for (int resolutionLevel = 0; resolutionLevel < tileMatrixSet.getTileMatrix().size(); resolutionLevel++) {
455 559
				WMTSTileMatrix tm = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(resolutionLevel);
456
				WMTSTileMatrixLimits tml = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(resolutionLevel);
457 560
				double scaleDenominator = tm.getScaleDenominator();
458 561
				if(scale >= scaleDenominator) {
459
					tileMatrix = (WMTSTileMatrix)tileMatrixSet.getTileMatrix().get(Math.max(resolutionLevel + levelModifier, 0));
460
					tileMatrixLimits = (WMTSTileMatrixLimits)tileMatrixSetLimits.get(Math.max(resolutionLevel + levelModifier, 0));
461
					break;
562
					return Math.max(resolutionLevel + levelModifier, 0);
462 563
				}
463 564
			}
464
		}catch (IndexOutOfBoundsException e) {
565
		} catch (IndexOutOfBoundsException e) {
465 566
			throw new RasterDriverException("Error in this resolution level", e);
466 567
		}
467
		
468
		//3-Selecci?n de fila y columna
469
		ArrayList<Tile> tiles = tileMatrix.intersects(p.getSRS().isProjected(), tileMatrixLimits, r, getExtent().toRectangle2D());
470
		
568
		return 0;
569
	}
570
	
571
	/**
572
	 * Get the tile matrix set using the crs
573
	 * @param srs
574
	 * @return
575
	 */
576
	private WMTSTileMatrixSetLink getTileMatrixSetLink() {
577
		WMTSStoreParameters p = (WMTSStoreParameters)param;
578
		ArrayList<?> tileMatrixSetLinkList = p.getLayer().getTileMatrixSetLink();
579
		for (int i = 0; i < tileMatrixSetLinkList.size(); i++) {
580
			WMTSTileMatrixSetLink tileMatrixSetLink = (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(i);
581
			String srsTileSet = tileMatrixSetLink.getTileMatrixSet().getSupportedCRS();
582
			if(srsTileSet.compareTo(p.getSRSCode()) == 0) {
583
				return tileMatrixSetLink;
584
			}
585
		}
586
		if(tileMatrixSetLinkList != null && tileMatrixSetLinkList.size() > 0)
587
			return (WMTSTileMatrixSetLink)tileMatrixSetLinkList.get(0);
588
		return null;
589
	}
590
	
591
	/**
592
	 * Gets the scale using the extent and the width in pixels.
593
	 * @param r
594
	 * @param width
595
	 * @return
596
	 */
597
	private double getScale(Rectangle2D r, int width) {
598
		WMTSStoreParameters p = (WMTSStoreParameters)param;
599
		if(!p.getSRS().isProjected()) {
600
			return (1000 * r.getWidth() * MTS_X_GRADO) / (width * 0.28);
601
		} else
602
			return (1000 * r.getWidth()) / (width * 0.28);
603
	}
604
	
605
	/**
606
	 * Throw a request
607
	 * @param status
608
	 * @param tiles
609
	 * @param bandList
610
	 * @param listener
611
	 * @throws RasterDriverException 
612
	 * @throws ProcessInterruptedException 
613
	 */
614
	private void request(WMTSStatus status, ArrayList<Tile> tiles, BandList bandList, TileListener listener) throws RasterDriverException, ProcessInterruptedException {
471 615
		WMTSConnector connector = null;
472 616
		try {
473 617
			connector = getConnector();
......
478 622
		if(connector == null)
479 623
			throw new RasterDriverException("Error getting the connector object");
480 624
		
481
		//4-Petici?n
482
		
483
		WMTSStatus status = new WMTSStatus();
484
		status.setLayer(p.getLayer().getIdentifier());
485
		status.setFormat(p.getImageFormat());
486
		status.setStyle(p.getStyle() != null ? p.getStyle().getIdentifier() : "");
487
		status.setTileMatrixSet(tileMatrixSet.getIdentifier());
488
		status.setTileMatrix(tileMatrix.getIdentifier());
489
		
490 625
		for (int i = 0; i < tiles.size(); i++) {
491 626
			Tile tile = tiles.get(i);
492 627
			status.setTileRow(tile.row);
......
501 636
				}
502 637
				
503 638
				GdalProvider driver = new GdalProvider(file.getPath());
504
				Buffer rasterBuf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tileMatrix.getTileWidth(), tileMatrix.getTileHeight(), 3, true);
505
				Buffer buf = driver.getWindowRaster(0, 0, tileMatrix.getTileWidth(), tileMatrix.getTileHeight(), bandList, rasterBuf);
639
				Buffer rasterBuf = DefaultRasterManager.getInstance().createBuffer(getDataType()[0], tile.wPx, tile.hPx, 3, true);
640
				Buffer buf = driver.getWindowRaster(0, 0, tile.wPx, tile.hPx, bandList, rasterBuf);
506 641
				
507 642
				for (int j = 0; j < bandList.getBandCount(); j++) {
508 643
					bandList.getBand(j).setFileName(serverName);

Also available in: Unified diff