/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2011, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotoolkit.wmts.model; import java.awt.*; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.UUID; import java.util.concurrent.BlockingQueue; import org.geotoolkit.storage.coverage.GridMosaic; import org.geotoolkit.storage.coverage.TileReference; import org.apache.sis.geometry.GeneralDirectPosition; import org.apache.sis.geometry.GeneralEnvelope; import org.apache.sis.storage.DataStoreException; import org.apache.sis.util.Classes; import org.geotoolkit.storage.coverage.PyramidSet; import org.geotoolkit.wmts.WMTSUtilities; import org.geotoolkit.wmts.xml.v100.TileMatrix; import org.geotoolkit.wmts.xml.v100.TileMatrixLimits; import org.opengis.coverage.PointOutsideCoverageException; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.Envelope; /** * * @author Johann Sorel (Geomatys) * @module */ public class WMTSMosaic implements GridMosaic{ private final String id = UUID.randomUUID().toString(); private final WMTSPyramid pyramid; private final TileMatrix matrix; private final TileMatrixLimits limit; private final double scale; public WMTSMosaic(final WMTSPyramid pyramid, final TileMatrix matrix, final TileMatrixLimits limits) { this.pyramid = pyramid; this.matrix = matrix; this.limit = limits; this.scale = WMTSUtilities.unitsByPixel(pyramid.getMatrixset(), pyramid.getCoordinateReferenceSystem(), matrix); } public TileMatrix getMatrix() { return matrix; } @Override public String getId() { return id; } @Override public WMTSPyramid getPyramid() { return pyramid; } @Override public DirectPosition getUpperLeftCorner() { final GeneralDirectPosition ul = new GeneralDirectPosition(getPyramid().getCoordinateReferenceSystem()); ul.setOrdinate(0, matrix.getTopLeftCorner().get(0)); ul.setOrdinate(1, matrix.getTopLeftCorner().get(1)); return ul; } @Override public Dimension getGridSize() { return new Dimension( matrix.getMatrixWidth(), matrix.getMatrixHeight()); } @Override public double getScale() { return scale; } @Override public Dimension getTileSize() { return new Dimension( matrix.getTileWidth(), matrix.getTileHeight()); } @Override public Envelope getEnvelope(int row, int col) { final DirectPosition ul = getUpperLeftCorner(); final double minX = ul.getOrdinate(0); final double maxY = ul.getOrdinate(1); final Dimension tileSize = getTileSize(); final double scale = getScale(); final double spanX = tileSize.width * scale; final double spanY = tileSize.height * scale; final GeneralEnvelope envelope = new GeneralEnvelope( getPyramid().getCoordinateReferenceSystem()); envelope.setRange(0, minX + col*spanX, minX + (col+1)*spanX); envelope.setRange(1, maxY - (row+1)*spanY, maxY - row*spanY); return envelope; } @Override public Envelope getEnvelope() { final DirectPosition ul = getUpperLeftCorner(); final double minX = ul.getOrdinate(0); final double maxY = ul.getOrdinate(1); final double spanX = getTileSize().width * getGridSize().width * getScale(); final double spanY = getTileSize().height* getGridSize().height* getScale(); final GeneralEnvelope envelope = new GeneralEnvelope( getPyramid().getCoordinateReferenceSystem()); envelope.setRange(0, minX, minX + spanX); envelope.setRange(1, maxY - spanY, maxY ); return envelope; } @Override public boolean isMissing(int col, int row) throws PointOutsideCoverageException { if (col < 0 || row < 0 || col > matrix.getMatrixWidth() || row > matrix.getMatrixHeight()) { throw new PointOutsideCoverageException("Queried tile position is outside matrix dimension.", new GeneralDirectPosition(col, row)); } if(limit == null) return false; //limits are exclusive return col < limit.getMinTileCol() || col > limit.getMaxTileCol() || row < limit.getMinTileRow() || row > limit.getMaxTileRow(); } @Override public TileReference getTile(int col, int row, Map hints) throws DataStoreException { if(hints==null) hints = new HashMap(); if(!hints.containsKey(PyramidSet.HINT_FORMAT)) hints.put(PyramidSet.HINT_FORMAT,"image/png"); return ((WMTSPyramidSet)getPyramid().getPyramidSet()).getTile(this, col, row, hints); } @Override public String toString() { final StringBuilder sb = new StringBuilder(Classes.getShortClassName(this)); sb.append(" scale = ").append(getScale()); sb.append(" gridSize[").append(getGridSize().width).append(',').append(getGridSize().height).append(']'); sb.append(" tileSize[").append(getTileSize().width).append(',').append(getTileSize().height).append(']'); sb.append(" ").append(getEnvelope()); return sb.toString(); } @Override public BlockingQueue<Object> getTiles(Collection<? extends Point> positions, Map hints) throws DataStoreException { if(hints==null) hints = new HashMap(); if(!hints.containsKey(PyramidSet.HINT_FORMAT)){ hints = new HashMap(hints); hints.put(PyramidSet.HINT_FORMAT,"image/png"); } return ((WMTSPyramidSet)getPyramid().getPyramidSet()).getTiles(this, positions, hints); } @Override public Rectangle getDataArea() { return new Rectangle(0,0, getGridSize().width, getGridSize().height); } }