0

I'm trying to read the elevation data stored in HGT files. As far as I know they can be read as binary files.

I found this thread:
How do I access .HGT SRTM files in C++?

Based on that post, my sample code is:

#include <iostream>
#include <fstream>

int main(int argc, const char * argv[])
{

std::ifstream::pos_type size;
char * memblock;

std::ifstream file ("N45W066.hgt", std::ios::in|std::ios::binary|std::ios::ate);

if (file.is_open())
{
    size = 2;
    memblock = new char [size];

    file.seekg(0, std::ios::beg);
    file.read(memblock, size);

    int srtm_ver = 1201;
    int height[1201][1021];

    for (int i = 0; i<srtm_ver; ++i){
        for (int j = 0; j < srtm_ver; ++j) {

            height[i][j] = (memblock[0] << 8 | memblock[1]);
            std::cout<<height[i][j]<<" ";
        }
        std::cout<<std::endl;
    }
}


return 0;
}

After the first run, it gives me a bunch of zeros, and nothing else :| The hgt file is good, i've tested it with an application that can read several type of map files, and it contains the elevation data what i need.

Community
  • 1
  • 1
Fulop Barna
  • 13
  • 1
  • 6
  • You're only reading 2 bytes from the file in total. You need to read 2 bytes for each location in the array. You also have a typo in the second dimension of the array size. – Retired Ninja Apr 30 '13 at 10:33
  • i was guessing the same thing, but could you please help me out how to read the whole file? or how to read a specific line/pixel location? – Fulop Barna Apr 30 '13 at 10:35

1 Answers1

3

This will read the file and populate the array correctly. Reading 2 bytes at a time generally isn't the most efficient way to do it, but it is simple. The alternative would be to read the whole file and then swap the bytes afterward.

I moved the height array outside main to avoid a stack overflow issue with the default stack size in Visual Studio. If your stack is large enough you could move it back, or dynamically allocate the memory on the heap.

#include <iostream>
#include <fstream>

const int SRTM_SIZE = 1201;
short height[SRTM_SIZE][SRTM_SIZE] = {0};

int main(int argc, const char * argv[])
{
    std::ifstream file("N45W066.hgt", std::ios::in|std::ios::binary);
    if(!file)
    {
        std::cout << "Error opening file!" << std::endl;
        return -1;
    }

    unsigned char buffer[2];
    for (int i = 0; i < SRTM_SIZE; ++i)
    {
        for (int j = 0; j < SRTM_SIZE; ++j) 
        {
            if(!file.read( reinterpret_cast<char*>(buffer), sizeof(buffer) ))
            {
                std::cout << "Error reading file!" << std::endl;
                return -1;
            }
            height[i][j] = (buffer[0] << 8) | buffer[1];
        }
    }

    //Read single value from file at row,col
    const int row = 500;
    const int col = 1000;
    size_t offset = sizeof(buffer) * ((row * SRTM_SIZE) + col);
    file.seekg(offset, std::ios::beg);
    file.read( reinterpret_cast<char*>(buffer), sizeof(buffer) );
    short single_value = (buffer[0] << 8) | buffer[1];
    std::cout << "values at " << row << "," << col << ":" << std::endl;
    std::cout << "  height array: " << height[row][col] << ", file: " << single_value << std::endl;

    return 0;
}
Retired Ninja
  • 4,785
  • 3
  • 25
  • 35
  • I added an example of that to the answer as well. The file is basically just an array on disk, so you seek to the proper row, col and read the value here. – Retired Ninja Apr 30 '13 at 23:55
  • please what does it mean this line (buffer[0] << 8) | buffer[1] i mean why we put this line to extract elvation – DINA TAKLIT Apr 21 '18 at 17:07
  • The data in the file is stored in big endian format. In order to use it on a little endian computer the bytes need to be swapped. That is what that line does. – Retired Ninja Apr 21 '18 at 18:32