001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.data.projection.datum; 003 004import java.io.IOException; 005import java.io.InputStream; 006import java.util.Collections; 007import java.util.Map; 008import java.util.Objects; 009import java.util.TreeMap; 010 011import org.openstreetmap.josm.tools.Logging; 012 013/** 014 * Wrapper for {@link NTV2GridShiftFile}. 015 * 016 * Loads the shift file from disk, when it is first accessed. 017 * @since 5226 018 */ 019public class NTV2GridShiftFileWrapper { 020 021 private NTV2GridShiftFile instance; 022 private final String gridFileName; 023 024 /** Priority for local NTV2 grid files */ 025 public static final float NTV2_SOURCE_PRIORITY_LOCAL = 10f; 026 /** Priority for downloaded NTV2 grid files */ 027 public static final float NTV2_SOURCE_PRIORITY_DOWNLOAD = 5f; 028 029 private static Map<Float, NTV2GridShiftFileSource> sources = new TreeMap<>(Collections.reverseOrder()); 030 031 /** 032 * Register a source for NTV2 grid files. 033 * @param priority the priority, sources with higher priority are checked first; 034 * use {@link #NTV2_SOURCE_PRIORITY_LOCAL} for local files and 035 * {@link #NTV2_SOURCE_PRIORITY_DOWNLOAD} for remote downloads 036 * @param source the NTV2 grid file source 037 * @since 12777 038 */ 039 public static void registerNTV2GridShiftFileSource(float priority, NTV2GridShiftFileSource source) { 040 sources.put(priority, source); 041 } 042 043 /** 044 * Constructs a new {@code NTV2GridShiftFileWrapper}. 045 * @param filename Path to the grid file (GSB format) 046 */ 047 public NTV2GridShiftFileWrapper(String filename) { 048 this.gridFileName = Objects.requireNonNull(filename); 049 } 050 051 /** 052 * Returns the actual {@link NTV2GridShiftFile} behind this wrapper. 053 * The grid file is only loaded once, when first accessed. 054 * @return The NTv2 grid file 055 * @throws IOException if the grid file cannot be found/loaded 056 */ 057 public synchronized NTV2GridShiftFile getShiftFile() throws IOException { 058 if (instance == null) { 059 for (Map.Entry<Float, NTV2GridShiftFileSource> entry : sources.entrySet()) { 060 NTV2GridShiftFileSource source = entry.getValue(); 061 try (InputStream is = source.getNTV2GridShiftFile(gridFileName)) { 062 if (is != null) { 063 NTV2GridShiftFile ntv2 = new NTV2GridShiftFile(); 064 ntv2.loadGridShiftFile(is, false); 065 instance = ntv2; 066 break; 067 } 068 } 069 } 070 if (instance == null) { 071 Logging.error("Unable to find NTV2 grid shift file for {0}", gridFileName); 072 } 073 } 074 return instance; 075 } 076}