Package net.sourceforge.gpstools.dem

Source Code of net.sourceforge.gpstools.dem.HgtElevationModel

package net.sourceforge.gpstools.dem;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;

import net.sourceforge.gpstools.gpx.Wpt;
import net.sourceforge.gpstools.gpx.WptType;
import net.sourceforge.gpstools.utils.GPXUtils;
import net.sourceforge.gpstools.utils.GPXUtils.GeonamesException;

public class HgtElevationModel implements ElevationModel {
    private final static int MAX_OPEN_FILES = 10;
    private Map<Integer, HgtFile> fileMap = new HashMap<Integer, HgtFile>();
    private String baseURI = "http://dds.cr.usgs.gov/srtm/version2_1/";
    private Map<Integer, String> uriMap = new HashMap<Integer, String>();
    private HgtFile last1;
    private HgtFile last2;
    private File cacheDir = new File(System.getProperty("java.io.tmpdir"));

    public HgtElevationModel() throws IOException {
        this.loadSrtm3();
        this.loadSrtm1();
    }

    @Override
    public void close() throws IOException {
        this.closeCore();
    }

    private void closeCore() throws IOException {
        Collection<Integer> keys = fileMap.keySet();
        IOException lastEx = null;
        for (Integer cell : keys.toArray(new Integer[keys.size()])) {
            HgtFile hgt = fileMap.get(cell);
            fileMap.remove(cell);
            if (hgt != null) {
                try {
                    hgt.close();
                } catch (IOException ioex) {
                    lastEx = ioex;
                }
            }
        }

        if (lastEx != null) {
            throw lastEx;
        }
    }

    @Override
    public BigDecimal getElevation(BigDecimal lat, BigDecimal lon)
            throws DEMException {
        if (this.last1 != null) {
            try {
                return this.last1.getElevation(lat, lon);
            } catch (DEMException ex) {
                if (this.last2 != null) {
                    try {
                        BigDecimal result = this.last2.getElevation(lat, lon);
                        HgtFile tmp = this.last1;
                        this.last1 = this.last2;
                        this.last2 = tmp;
                        return result;
                    } catch (DEMException ex2) {
                        // ignore
                    }
                }
            }
        }

        int cellLat = (int) Math.floor(lat.floatValue());
        int cellLon = (int) Math.floor(lon.floatValue());
        Integer cellKey = getCellKey(cellLat, cellLon);

        HgtFile hgt = this.fileMap.get(cellKey);
        if (hgt == null) {
            try {
                String key = this.uriMap.get(cellKey);
                if (key == null) {
                    throw new DEMException(lat, lon,
                            "No hgt URL for this location.");
                }

                URI uri = new URI(getBaseURI() + key);
                hgt = new HgtFile(uri, this.getCacheDir());
                if (this.fileMap.size() >= MAX_OPEN_FILES) {
                    try {
                        this.closeCore();
                    } catch (IOException ex) {
                        // ignore
                    }
                }

                this.fileMap.put(cellKey, hgt);
            } catch (IOException e) {
                throw new DEMException(lat, lon, e.getMessage(), e);
            } catch (URISyntaxException e) {
                // Should never happen.
                throw new Error(e);
            }
        }

        BigDecimal result = hgt.getElevation(lat, lon);
        this.last2 = this.last1;
        this.last1 = hgt;
        return result;
    }

    /**
     * @param cacheDir
     *            the cacheDir to set
     */
    public void setCacheDir(File cacheDir) {
        if (!cacheDir.isDirectory()) {
            throw new IllegalArgumentException(cacheDir
                    + " is not a directory.");
        }

        this.cacheDir = cacheDir;
    }

    /**
     * @return the cacheDir
     */
    public File getCacheDir() {
        return cacheDir;
    }

    /**
     * Sets the base URI relative to which relative URIs are resolved.
     *
     * @param baseURI
     *            the base URI.
     */
    public void setBaseURI(String baseURI) {
        this.baseURI = baseURI;
    }

    /**
     * Gets the base URI relative to which relative URIs are resolved.
     *
     * @return the base URI.
     */
    public String getBaseURI() {
        return this.baseURI;
    }

    public String getRelativeTileURI(int lat, int lon) {
        return this.uriMap.get(getCellKey(lat, lon));
    }

    public void setRelativeTileURI(int lat, int lon, String relativeURI) {
        this.uriMap.put(getCellKey(lat, lon), relativeURI);
    }

    public URI getAbsoluteTileURI(int lat, int lon) throws URISyntaxException {
        String relative = this.getRelativeTileURI(lat, lon);
        return (relative == null) ? null
                : new URI(this.getBaseURI() + relative);
    }

    private void loadSrtm1() throws IOException {
        String[] dirs = new String[] { "Region_01", "Region_02", "Region_03",
                "Region_04", "Region_05", "Region_06", "Region_07" };

        for (String dir : dirs) {
            loadURLs("SRTM1", dir);
        }
    }

    private void loadSrtm3() throws IOException {
        String[] dirs = new String[] { "Africa", "Australia", "Eurasia",
                "Islands", "North_America", "South_America" };

        for (String dir : dirs) {
            loadURLs("SRTM3", dir);
        }
    }

    private void loadURLs(String prefix, String dir) throws IOException {
        String resourceName = prefix + "/" + dir + ".url";
        InputStream in = HgtElevationModel.class.getResourceAsStream(resourceName);
        try {
            Reader reader = new InputStreamReader(in, "UTF-8");
            BufferedReader lineReader = new BufferedReader(reader);

            Matcher m;
            String longPrefix = prefix + "/" + dir + "/";
            for (String name = lineReader.readLine(); name != null; name = lineReader
                    .readLine()) {
                m = HgtFile.fileNamePattern.matcher(name);
                if (m.matches()) {
                    int lat = Integer.parseInt(m.group(2));
                    if (m.group(1).charAt(0) == 'S') {
                        lat = -lat;
                    }

                    int lon = Integer.parseInt(m.group(4));
                    if (m.group(3).charAt(0) == 'W') {
                        lon = -lon;
                    }

                    this.setRelativeTileURI(lat, lon, longPrefix + name);
                }
            }
        } finally {
            in.close();
        }
    }

    private static Integer getCellKey(int cellLat, int cellLon) {
        return ((cellLat + 90) << 16) + (cellLon + 180);
    }

    /**
     * Prints the elevation for a coordinate pair, evaluated with this class and
     * with the geonames srtm3 web service.
     *
     * @param argv
     *            the command line parameters
     * @throws Exception
     */
    public static void main(String[] argv) throws Exception {
        double lat0 = Double.parseDouble(argv[0]);
        double lon0 = Double.parseDouble(argv[1]);

        BigDecimal lat = new BigDecimal(lat0);
        BigDecimal lon = new BigDecimal(lon0);

        HgtElevationModel hgt = new HgtElevationModel();
        try {
            System.out.println(hgt.getElevation(lat, lon));
        } finally {
            hgt.close();
        }

        WptType pt = new Wpt();
        pt.setLat(lat);
        pt.setLon(lon);
        WptType[] wpts = new WptType[] { pt };
        try {
            GPXUtils.getInstance().setEle(wpts);
            System.out.println(pt.getEle());
        } catch (GeonamesException ex) {
            System.out.println(ex.getMessage());
        }
    }

    @Override
    public String getInfo() {
        return this.getBaseURI();
    }
}
TOP

Related Classes of net.sourceforge.gpstools.dem.HgtElevationModel

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.