package com.revolsys.elevation.gridded.compactbinary; import java.util.Map; import com.revolsys.collection.map.LruMap; import com.revolsys.elevation.gridded.AbstractGriddedElevationModel; import com.revolsys.elevation.gridded.DirectFileElevationModel; import com.revolsys.elevation.gridded.GriddedElevationModel; import com.revolsys.elevation.gridded.GriddedElevationModelReadFactory; import com.revolsys.geometry.model.GeometryFactory; import com.revolsys.io.IoFactory; import com.revolsys.spring.resource.Resource; import com.revolsys.util.IntPair; public class TiledCompactBinaryGriddedElevationModel extends AbstractGriddedElevationModel { private int gridTileWidth; private int gridTileHeight; private Resource baseResource; private int coordinateSystemId; private final Map<IntPair, DirectFileElevationModel> models = new LruMap<>(5000); private CompactBinaryGriddedElevation factory; public TiledCompactBinaryGriddedElevationModel() { } public TiledCompactBinaryGriddedElevationModel(final Resource baseResource, final String fileExtension, final GeometryFactory geometryFactory, final double minX, final double minY, final int gridTileWidth, final int gridTileHeight, final int gridCellSize) { super(geometryFactory, minX, minY, Integer.MAX_VALUE, Integer.MAX_VALUE, gridCellSize); setFileExtension(fileExtension); this.gridTileWidth = gridTileWidth; this.gridTileHeight = gridTileHeight; this.coordinateSystemId = geometryFactory.getCoordinateSystemId(); final Resource fileExtensionDirectory = baseResource.createRelative("demcs"); final Resource coordinateSystemDirectory = fileExtensionDirectory .createRelative(Integer.toString(this.coordinateSystemId)); final Resource resolutionDirectory = coordinateSystemDirectory .createRelative(gridCellSize + "m"); this.baseResource = resolutionDirectory; } @Override public void clear() { } @Override protected double getElevationDo(final int gridX, final int gridY, final int gridWidth) { final int gridCellSize = getGridCellSize(); final int tileMinGridX = Math.floorDiv(gridX, this.gridTileWidth) * this.gridTileWidth; final int tileMinGridY = Math.floorDiv(gridY, this.gridTileHeight) * this.gridTileHeight; final IntPair key = new IntPair(tileMinGridX, tileMinGridY); DirectFileElevationModel model = this.models.get(key); if (model == null) { final int tileMinX = tileMinGridX * gridCellSize; final int tileMinY = tileMinGridY * gridCellSize; model = new CompactBinaryGriddedElevationModelFile(this.baseResource.toPath(), getGeometryFactory(), tileMinX, tileMinY, this.gridTileWidth, this.gridTileHeight, gridCellSize); this.models.put(key, model); } final int gridCellX = gridX - tileMinGridX; final int gridCellY = gridY - tileMinGridY; return model.getElevation(gridCellX, gridCellY); // final int offset = CompactBinaryGriddedElevation.HEADER_SIZE // + (gridCellY * this.gridSize + gridCellX) * this.elevationByteCount; // double elevation; // if (this.isPath) { // final Path path = resource.toPath(); // try ( // SeekableByteChannel byteChannel = Files.newByteChannel(path, // StandardOpenOption.READ)) { // byteChannel.position(offset); // if (this.floatingPoint) { // final ByteBuffer bytes = ByteBuffer.allocate(4); // byteChannel.read(bytes); // elevation = bytes.getFloat(0); // } else { // final ByteBuffer bytes = ByteBuffer.allocate(2); // byteChannel.read(bytes); // elevation = bytes.getShort(0); // } // } // } else { // try ( // DataInputStream in = // resource.newBufferedInputStream(DataInputStream::new)) { // in.skip(offset); // if (this.floatingPoint) { // elevation = in.readFloat(); // } else { // elevation = in.readShort(); // } // } catch (final IOException e) { // throw Exceptions.wrap("Unable to read: " + resource, e); // } // } // return elevation; } public int getGridTileHeight() { return this.gridTileHeight; } public int getGridTileWidth() { return this.gridTileWidth; } @Override public boolean isEmpty() { return false; } @Override public boolean isNull(final int x, final int y) { return false; } @Override public GriddedElevationModel newElevationModel(final GeometryFactory geometryFactory, final double x, final double y, final int width, final int height, final int gridCellSize) { // TODO Auto-generated method stub return null; } @Override public void setElevation(final int x, final int y, final double elevation) { } public void setFileExtension(final String fileExtension) { this.factory = (CompactBinaryGriddedElevation)IoFactory .factoryByFileExtension(GriddedElevationModelReadFactory.class, fileExtension); } public void setGridTileHeight(final int gridTileHeight) { this.gridTileHeight = gridTileHeight; } public void setGridTileWidth(final int gridTileWidth) { this.gridTileWidth = gridTileWidth; } }