001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.data.projection.datum;
003
004import java.io.File;
005import java.io.IOException;
006import java.io.InputStream;
007import java.nio.file.Files;
008import java.nio.file.InvalidPathException;
009import java.util.Arrays;
010import java.util.Collections;
011import java.util.List;
012
013import org.openstreetmap.josm.tools.Logging;
014import org.openstreetmap.josm.tools.Platform;
015import org.openstreetmap.josm.tools.PlatformVisitor;
016import org.openstreetmap.josm.tools.Utils;
017
018/**
019 * Shift file source that scans the common data directories of the proj4 library.
020 * @since 12777
021 */
022public final class NTV2Proj4DirGridShiftFileSource implements NTV2GridShiftFileSource, PlatformVisitor<List<File>> {
023
024    private NTV2Proj4DirGridShiftFileSource() {
025        // hide constructor
026    }
027
028    // lazy initialization
029    private static class InstanceHolder {
030        static final NTV2Proj4DirGridShiftFileSource INSTANCE = new NTV2Proj4DirGridShiftFileSource();
031    }
032
033    /**
034     * Get the singleton instance of this class.
035     * @return the singleton instance of this class
036     */
037    public static NTV2Proj4DirGridShiftFileSource getInstance() {
038        return InstanceHolder.INSTANCE;
039    }
040
041    @Override
042    public InputStream getNTV2GridShiftFile(String gridFileName) {
043        File grid = null;
044        // Check is the grid is installed in default PROJ.4 directories
045        for (File dir : Platform.determinePlatform().accept(this)) {
046            File file = new File(dir, gridFileName);
047            if (file.exists() && file.isFile()) {
048                grid = file;
049                break;
050            }
051        }
052        // If not, search into PROJ_LIB directory
053        if (grid == null) {
054            String projLib = Utils.getSystemProperty("PROJ_LIB");
055            if (projLib != null && !projLib.isEmpty()) {
056                File dir = new File(projLib);
057                if (dir.exists() && dir.isDirectory()) {
058                    File file = new File(dir, gridFileName);
059                    if (file.exists() && file.isFile()) {
060                        grid = file;
061                    }
062                }
063            }
064        }
065        if (grid != null) {
066            try {
067                return Files.newInputStream(grid.getAbsoluteFile().toPath());
068            } catch (IOException | InvalidPathException ex) {
069                Logging.warn("Unable to open NTV2 grid shift file: " + grid);
070                Logging.debug(ex);
071            }
072        }
073        return null;
074    }
075
076    @Override
077    public List<File> visitUnixoid() {
078        return Arrays.asList(new File("/usr/local/share/proj"), new File("/usr/share/proj"));
079    }
080
081    @Override
082    public List<File> visitWindows() {
083        return Arrays.asList(new File("C:\\PROJ\\NAD"));
084    }
085
086    @Override
087    public List<File> visitOsx() {
088        return Collections.emptyList();
089    }
090}