TilesCache.java
- /* Copyright 2013-2022 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.rugged.raster;
- import org.hipparchus.util.FastMath;
- import java.lang.reflect.Array;
- import org.orekit.rugged.errors.DumpManager;
- import org.orekit.rugged.errors.RuggedException;
- import org.orekit.rugged.errors.RuggedMessages;
- /** Cache for Digital Elevation Model {@link Tile tiles}.
- * <p>
- * Beware, this cache is <em>not</em> thread-safe!
- * </p>
- * @param <T> Type of tiles.
- * @author Luc Maisonobe
- */
- public class TilesCache<T extends Tile> {
- /** Factory for empty tiles. */
- private final TileFactory<T> factory;
- /** Updater for retrieving tiles data. */
- private final TileUpdater updater;
- /** Cache. */
- private final T[] tiles;
- /** Simple constructor.
- * @param factory factory for creating empty tiles
- * @param updater updater for retrieving tiles data
- * @param maxTiles maximum number of tiles stored simultaneously in the cache
- */
- public TilesCache(final TileFactory<T> factory, final TileUpdater updater, final int maxTiles) {
- this.factory = factory;
- this.updater = updater;
- @SuppressWarnings("unchecked")
- final T[] array = (T[]) Array.newInstance(Tile.class, maxTiles);
- this.tiles = array;
- }
- /** Get the tile covering a ground point.
- * @param latitude ground point latitude
- * @param longitude ground point longitude
- * @return tile covering the ground point
- */
- public T getTile(final double latitude, final double longitude) {
- for (int i = 0; i < tiles.length; ++i) {
- final T tile = tiles[i];
- if (tile != null && tile.getLocation(latitude, longitude) == Tile.Location.HAS_INTERPOLATION_NEIGHBORS) {
- // we have found the tile in the cache
- // put it on the front as it becomes the most recently used
- while (i > 0) {
- tiles[i] = tiles[i - 1];
- --i;
- }
- tiles[0] = tile;
- return tile;
- }
- }
- // none of the tiles in the cache covers the specified points
- // make some room in the cache, possibly evicting the least recently used one
- for (int i = tiles.length - 1; i > 0; --i) {
- tiles[i] = tiles[i - 1];
- }
- // create the tile and retrieve its data
- final T tile = factory.createTile();
- // In case dump is asked for, suspend the dump manager as we don't need to dump anything here
- // For instance for SRTM DEM, the user needs to read Geoid data that are not useful in the dump
- final Boolean wasSuspended = DumpManager.suspend();
- updater.updateTile(latitude, longitude, tile);
- // Resume the dump manager if necessary
- DumpManager.resume(wasSuspended);
- tile.tileUpdateCompleted();
- if (tile.getLocation(latitude, longitude) != Tile.Location.HAS_INTERPOLATION_NEIGHBORS) {
- // this should happen only if user set up an inconsistent TileUpdater
- throw new RuggedException(RuggedMessages.TILE_WITHOUT_REQUIRED_NEIGHBORS_SELECTED,
- FastMath.toDegrees(latitude),
- FastMath.toDegrees(longitude));
- }
- tiles[0] = tile;
- return tile;
- }
- }