class GeoElevation::SrtmFile

Public Class Methods

new(local_file_name) click to toggle source
# File lib/geoelevation.rb, line 93
def initialize(local_file_name)
    @local_file_name = local_file_name
    @file = open(@local_file_name)
    size = File.size?(@local_file_name)
    @square_side = Math.sqrt(size / 2)

    if @square_side != @square_side.to_i
        raise "Invalid file size #{size}"
    end
    
    parse_file_name_starting_position()
end

Public Instance Methods

get_elevation(latitude, longitude) click to toggle source

If approximate is True then only the points from SRTM grid will be used, otherwise a basic aproximation of nearby points will be calculated.

# File lib/geoelevation.rb, line 128
def get_elevation(latitude, longitude)
    if ! (@latitude <= latitude && latitude < @latitude + 1)
        raise "Invalid latitude #{latitude} for file #{@file_name}"
    end
    if ! (@longitude <= longitude && longitude < @longitude + 1)
        raise "Invalid longitude #{longitude} for file #{@file_name}"
    end

    row, column = get_row_and_column(latitude, longitude)

    #points = self.square_side ** 2

    get_elevation_from_row_and_column(row.to_i, column.to_i)
end
get_elevation_from_row_and_column(row, column) click to toggle source
# File lib/geoelevation.rb, line 144
def get_elevation_from_row_and_column(row, column)
    i = row * (@square_side) + column

    i < @square_side ** 2 or raise "Invalid i=#{i}"

    @file.seek(i * 2)
    bytes = @file.read(2)
    byte_1 = bytes[0].ord
    byte_2 = bytes[1].ord

    result = byte_1 * 256 + byte_2

    if result > 9000
        # TODO(TK) try to detect the elevation from neighbour point:
        return nil
    end

    result
end
get_row_and_column(latitude, longitude) click to toggle source
# File lib/geoelevation.rb, line 118
def get_row_and_column(latitude, longitude)
    if latitude == nil || longitude == nil
        return nil
    end

    [ ((@latitude + 1 - latitude) * (@square_side - 1).to_f).floor, ((longitude - @longitude) * (@square_side - 1).to_f).floor ]
end
parse_file_name_starting_position() click to toggle source

Returns (latitude, longitude) of lower left point of the file

# File lib/geoelevation.rb, line 107
def parse_file_name_starting_position()
    groups = @local_file_name.scan(/([NS])(\d+)([EW])(\d+)\.hgt/)[0]

    if groups.length != 4
        raise "Invalid file name #{@file_name}"
    end

    @latitude = groups[1].to_i * (groups[0] == 'N' ? 1 : -1)
    @longitude = groups[3].to_i * (groups[2] == 'E' ? 1 : -1)
end