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