[GIS] Code to read elevation data from HGT file

javasrtm

I'm trying to read elevation data from NASA HGT file. I've started from Extracting elevation from .HGT file? and have changed this code a little to keep it simple and to use 1-ARCSEC (30-meter) data from http://dwtkns.com/srtm30m/ instead the original old data files.

After change the code, I can check it here, but the values are wrong.

I only changed these values but I'm not very sure what I'm doing:

public static final int HGT_RES = 1;  // <<- The new SRTM is 1-ARCSEC
public static final int HGT_ROW_LENGTH = 3601; <<-- New file resolution is 3601x3601

This is the code I'm using ( credits to don-vip from openstreetmap )

//  https://gis.stackexchange.com/questions/43743/extracting-elevation-from-hgt-file
private static final int SECONDS_PER_MINUTE = 60;

// alter these values for different SRTM resolutions
public static final int HGT_RES = 1; // resolution in arc seconds
public static final int HGT_ROW_LENGTH = 3601; // number of elevation values per line
public static final int HGT_VOID = -32768; // magic number which indicates 'void data' in HGT file  


public static void main(String[] args)  throws Exception {
    double coorLat = -22.352951806595854;
    double coorLon = -42.43121349392618;

    String filePath = "C:/Magno/DEMRJ/";
    String fileName = getHgtFileName(coorLat, coorLon);

    String htgFile = filePath + fileName;

    System.out.println( htgFile );

    //File f = new File( htgFile );

    ShortBuffer data = readHgtFile( htgFile );

    double fLat = frac( Math.abs(coorLat) ) * SECONDS_PER_MINUTE;
    double fLon = frac( Math.abs(coorLon) ) * SECONDS_PER_MINUTE;       

    System.out.println("fLat: " + fLat + "   fLon: " + fLon);

    int row = (int) Math.round(fLat * SECONDS_PER_MINUTE / HGT_RES);
    int col = (int) Math.round(fLon * SECONDS_PER_MINUTE / HGT_RES);        


    row = HGT_ROW_LENGTH - row;
    int cell = (HGT_ROW_LENGTH * (row - 1)) + col;

    System.out.println("Read SRTM elevation data from row/col/cell " + row + "," + col + ", " + cell + " == " + data.limit() );

    // valid position in buffer?
    if ( cell < data.limit() ) {

        short ele = data.get(cell);
        System.out.println("==> Read SRTM elevation data from row/col/cell " + row + "," + col + ", " + cell + " = " + ele);

        // check for data voids
        if (ele == HGT_VOID) {
            System.out.println("No Elevation - VOID");
        } else {
            System.out.println("Elevation : " + ele );
        }

    } else {
        System.out.println("No Elevation - Out of Range");
    }        


}


private static ShortBuffer readHgtFile(String file) throws Exception {

    FileChannel fc = null;
    ShortBuffer sb = null;
    try {
        // Eclipse complains here about resource leak on 'fc' - even with 'finally' clause???
        fc = new FileInputStream(file).getChannel();
        // choose the right endianness

        ByteBuffer bb = ByteBuffer.allocateDirect((int) fc.size());
        while (bb.remaining() > 0) fc.read(bb);

        bb.flip();
        //sb = bb.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
        sb = bb.order(ByteOrder.BIG_ENDIAN).asShortBuffer();
    } finally {
        if (fc != null) fc.close();
    }

    return sb;
}   




public static String getHgtFileName(double latD, double lonD) {
    int lat = (int) latD;
    int lon = (int) lonD;
    String latPref = "N";
    if (lat < 0) latPref = "S";

    String lonPref = "E";
    if (lon < 0) {
        lonPref = "W";
    }
    String lonT = String.valueOf(lon).replace("-", "");
    if ( lonT.length() == 2 ) {
        lonT = "0" + lonT;
    }
    String ret = latPref + lat + lonPref + lonT + ".hgt";
    return ret.replace("-", "");
}   


public static double frac(double d) {
    long iPart;
    double fPart;
    iPart = (long) d;
    fPart = d - iPart;
    return fPart;
}    

What I'm doing wrong?

The output is:

C:/Magno/DEMRJ/S22W042.hgt
fLat: 21.177108395751247   fLon: 25.872809635570775
Read SRTM elevation data from row/col/cell 2330,1552, 8388281 == 12967201
==> Read SRTM elevation data from row/col/cell 2330,1552, 8388281 = 129
Elevation : 129

But if you check the coordinates you can see the elevation value is 1222m or 4011ft ( not 129 – what unit? ).

Best Answer

I think I made some mistake in X,Y order. All seems fine now and I'm able to:

1) Open a HGT file.
2) Get the elevation value at a given Lat,Lon
3) Get the elevation profile from a path (red bars).

enter image description here

Related Question