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
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