GeoPackageReader extends AbstractGridCoverage2DReader { @Override public GridCoverage2D read(String coverageName, GeneralParameterValue[] parameters) throws IllegalArgumentException, IOException { TileEntry entry = tiles.get(coverageName); BufferedImage image = null; ReferencedEnvelope resultEnvelope = null; GeoPackage file = new GeoPackage(sourceFile); try { CoordinateReferenceSystem crs = getCoordinateReferenceSystem(coverageName); ReferencedEnvelope requestedEnvelope = null; Rectangle dim = null; if (parameters != null) { for (int i = 0; i < parameters.length; i++) { final ParameterValue param = (ParameterValue) parameters[i]; final ReferenceIdentifier name = param.getDescriptor().getName(); if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName())) { final GridGeometry2D gg = (GridGeometry2D) param.getValue(); try { requestedEnvelope = ReferencedEnvelope.create(gg.getEnvelope(), gg.getCoordinateReferenceSystem()).transform(crs, true);; } catch (Exception e) { requestedEnvelope = null; } dim = gg.getGridRange2D().getBounds(); continue; } } } int leftTile, topTile, rightTile, bottomTile; TileMatrix bestMatrix = null; if (requestedEnvelope != null && dim != null) { double horRes = requestedEnvelope.getSpan(0) / dim.getWidth(); double worldSpan = crs.getCoordinateSystem().getAxis(0).getMaximumValue() - crs.getCoordinateSystem().getAxis(0).getMinimumValue(); double difference = Double.MAX_VALUE; for (TileMatrix matrix : entry.getTileMatricies()) { double newRes = worldSpan / (matrix.getMatrixWidth() * matrix.getTileWidth()); double newDifference = Math.abs(horRes - newRes); if (newDifference < difference) { difference = newDifference; bestMatrix = matrix; } } } if (bestMatrix == null) { bestMatrix = entry.getTileMatricies().get(0); } leftTile = file.getTileBound(entry, bestMatrix.getZoomLevel(), false, false); rightTile = file.getTileBound(entry, bestMatrix.getZoomLevel(), true, false); bottomTile = file.getTileBound(entry, bestMatrix.getZoomLevel(), false, true); topTile = file.getTileBound(entry, bestMatrix.getZoomLevel(), true, true); double resX = (crs.getCoordinateSystem().getAxis(0).getMaximumValue() - crs.getCoordinateSystem().getAxis(0).getMinimumValue()) / bestMatrix.getMatrixWidth(); double resY = (crs.getCoordinateSystem().getAxis(1).getMaximumValue() - crs.getCoordinateSystem().getAxis(1).getMinimumValue()) / bestMatrix.getMatrixHeight(); double offsetX = crs.getCoordinateSystem().getAxis(0).getMinimumValue(); double offsetY = crs.getCoordinateSystem().getAxis(1).getMinimumValue(); if (requestedEnvelope != null) { leftTile = Math.max(leftTile, (int) Math.round(Math.floor((requestedEnvelope.getMinimum(0) - offsetX) / resX ))); bottomTile = Math.max(bottomTile, (int) Math.round(Math.floor((requestedEnvelope.getMinimum(1) - offsetY) / resY ))); rightTile = Math.max(leftTile, (int) Math.min(rightTile, Math.round(Math.floor((requestedEnvelope.getMaximum(0) - offsetX) / resX )))); topTile = Math.max(bottomTile, (int) Math.min(topTile, Math.round(Math.floor((requestedEnvelope.getMaximum(1) - offsetY) / resY )))); } int width = (int) (rightTile - leftTile + 1) * DEFAULT_TILE_SIZE; int height = (int) (topTile - bottomTile + 1) * DEFAULT_TILE_SIZE; resultEnvelope = new ReferencedEnvelope(offsetX + leftTile * resX, offsetX + (rightTile+1) * resX, offsetY + bottomTile * resY, offsetY + (topTile+1) * resY, crs); TileReader it; it = file.reader(entry, bestMatrix.getZoomLevel(), bestMatrix.getZoomLevel(), leftTile, rightTile, bottomTile, topTile); while (it.hasNext()) { Tile tile = it.next(); BufferedImage tileImage = readImage(tile.getData()); if (image == null) { image = getStartImage(tileImage, width, height); } int posx = (int) (tile.getColumn() - leftTile) * DEFAULT_TILE_SIZE; int posy = (int) (topTile - tile.getRow()) * DEFAULT_TILE_SIZE; image.getRaster().setRect(posx, posy, tileImage.getData() ); } it.close(); if (image == null){ image = getStartImage(width, height); } } finally { file.close(); } return coverageFactory.create(entry.getTableName(), image, resultEnvelope); } GeoPackageReader(Object source, Hints hints); @Override Format getFormat(); @Override GeneralEnvelope getOriginalEnvelope(String coverageName); @Override GridEnvelope getOriginalGridRange(String coverageName); @Override CoordinateReferenceSystem getCoordinateReferenceSystem(String coverageName); @Override String[] getGridCoverageNames(); @Override int getGridCoverageCount(); @Override GridCoverage2D read(String coverageName, GeneralParameterValue[] parameters); @Override GridCoverage2D read(GeneralParameterValue[] parameters);  }
@Test public void testZoomlevel2() throws IOException { GeoPackageReader reader = new GeoPackageReader(getClass().getResource("world_lakes.gpkg"), null); GeneralParameterValue[] parameters = new GeneralParameterValue[1]; GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(new Rectangle(500,500)), new ReferencedEnvelope(0,180.0,-85.0,0,WGS_84)); parameters[0] = new Parameter<GridGeometry2D>(AbstractGridFormat.READ_GRIDGEOMETRY2D, gg); GridCoverage2D gc = reader.read("World_Lakes", parameters); RenderedImage img = gc.getRenderedImage(); assertEquals(0, gc.getEnvelope().getMinimum(0),0.01); assertEquals(-90, gc.getEnvelope().getMinimum(1),0.01); assertEquals(180, gc.getEnvelope().getMaximum(0),0.01); assertEquals(0, gc.getEnvelope().getMaximum(1),0.01); assertEquals(1024, img.getWidth()); assertEquals(512, img.getHeight()); ImageAssert.assertEquals(DataUtilities.urlToFile(getClass().getResource("world_lakes.png")), img, 250); }
@Test public void testZoomlevel3() throws IOException { GeoPackageReader reader = new GeoPackageReader(getClass().getResource("world_lakes.gpkg"), null); GeneralParameterValue[] parameters = new GeneralParameterValue[1]; GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(new Rectangle(500,500)), new ReferencedEnvelope(0,45.0,-85.0,0,WGS_84)); parameters[0] = new Parameter<GridGeometry2D>(AbstractGridFormat.READ_GRIDGEOMETRY2D, gg); GridCoverage2D gc = reader.read("World_Lakes", parameters); RenderedImage img = gc.getRenderedImage(); assertEquals(0, gc.getEnvelope().getMinimum(0),0.01); assertEquals(-90, gc.getEnvelope().getMinimum(1),0.01); assertEquals(67.5, gc.getEnvelope().getMaximum(0),0.01); assertEquals(0, gc.getEnvelope().getMaximum(1),0.01); assertEquals(768, img.getWidth()); assertEquals(1024, img.getHeight()); }
@Test public void testZoomlevel4() throws IOException { GeoPackageReader reader = new GeoPackageReader(getClass().getResource("world_lakes.gpkg"), null); GeneralParameterValue[] parameters = new GeneralParameterValue[1]; GridGeometry2D gg = new GridGeometry2D(new GridEnvelope2D(new Rectangle(500,500)), new ReferencedEnvelope(0,22.0,-85.0,0,WGS_84)); parameters[0] = new Parameter<GridGeometry2D>(AbstractGridFormat.READ_GRIDGEOMETRY2D, gg); GridCoverage2D gc = reader.read("World_Lakes", parameters); RenderedImage img = gc.getRenderedImage(); assertEquals(0, gc.getEnvelope().getMinimum(0),0.01); assertEquals(-90, gc.getEnvelope().getMinimum(1),0.01); assertEquals(22.5, gc.getEnvelope().getMaximum(0),0.01); assertEquals(0, gc.getEnvelope().getMaximum(1),0.01); assertEquals(512, img.getWidth()); assertEquals(2048, img.getHeight()); }