├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── hgt ├── N27E086.hgt ├── N27E088.hgt └── place_hgt_files_here ├── requirements.txt ├── srtm.py └── tests.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # PyCharm IDE 60 | .idea/ 61 | 62 | # SRTM data files 63 | *.hgt 64 | *.zip 65 | venv 66 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.2" 5 | - "3.3" 6 | - "3.6" 7 | before_install: 8 | - sudo apt-get -qq update 9 | - sudo apt-get install -y gdal-bin 10 | 11 | install: 12 | - pip install -r requirements.txt 13 | script: 14 | - python tests.py 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Aatish Neupane 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # srtm-python 2 | [![Build Status](https://travis-ci.org/aatishnn/srtm-python.svg?branch=master)](https://travis-ci.org/aatishnn/srtm-python) 3 | 4 | A python program that reads SRTM1 and SRTM3 Digital Elevation Model files. 5 | 6 | Read on how this works: [https://librenepal.com/article/reading-srtm-data-with-python/](https://librenepal.com/article/reading-srtm-data-with-python/) 7 | 8 | # Usage 9 | 1. Put uncompressed *.hgt files on hgt/ directory or redefine the location of this 10 | directory with `HGT_DIR` environment variable. 11 | 2. By default, the code will assume SRTM3 as the data format. You can also 12 | change it with `SRTM_TYPE` environment variable. 13 | 3. Enjoy 14 | ```python 15 | from srtm import get_elevation 16 | print('Mt. Everest's Elevation: %d' % get_elevation(27.988056, 86.925278)) 17 | ``` 18 | # Contributors 19 | - [@blebo](https://github.com/blebo) 20 | - [@hilsonshrestha](https://github.com/hilsonshrestha) 21 | - [@gamb](https://github.com/gamb) 22 | - [@23pointsNorth](https://github.com/23pointsNorth) 23 | -------------------------------------------------------------------------------- /hgt/N27E086.hgt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aatishnn/srtm-python/e81bfef37df74d9fd51c5a40d22be928df85a920/hgt/N27E086.hgt -------------------------------------------------------------------------------- /hgt/N27E088.hgt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aatishnn/srtm-python/e81bfef37df74d9fd51c5a40d22be928df85a920/hgt/N27E088.hgt -------------------------------------------------------------------------------- /hgt/place_hgt_files_here: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aatishnn/srtm-python/e81bfef37df74d9fd51c5a40d22be928df85a920/hgt/place_hgt_files_here -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy 2 | -------------------------------------------------------------------------------- /srtm.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | import os 3 | import numpy as np 4 | 5 | SRTM_DICT = {'SRTM1': 3601, 'SRTM3': 1201} 6 | 7 | # Get the type of SRTM files or use SRTM3 by default 8 | SRTM_TYPE = os.getenv('SRTM_TYPE', 'SRTM3') 9 | SAMPLES = SRTM_DICT[SRTM_TYPE] 10 | 11 | # put uncompressed hgt files in HGT_DIR, defaults to 'hgt' 12 | HGTDIR = os.getenv('HGT_DIR', 'hgt') 13 | 14 | 15 | def get_elevation(lat, lon): 16 | hgt_file = get_file_name(lat, lon) 17 | if hgt_file: 18 | return read_elevation_from_file(hgt_file, lat, lon) 19 | # Treat it as data void as in SRTM documentation 20 | # if file is absent 21 | return -32768 22 | 23 | 24 | def read_elevation_from_file(hgt_file, lat, lon): 25 | with open(hgt_file, 'rb') as hgt_data: 26 | # HGT is 16bit signed integer(i2) - big endian(>) 27 | elevations = np.fromfile( 28 | hgt_data, # binary data 29 | np.dtype('>i2'), # data type 30 | SAMPLES * SAMPLES # length 31 | ).reshape((SAMPLES, SAMPLES)) 32 | 33 | lat_row = int(round((lat - int(lat)) * (SAMPLES - 1), 0)) 34 | lon_row = int(round((lon - int(lon)) * (SAMPLES - 1), 0)) 35 | 36 | return elevations[SAMPLES - 1 - lat_row, lon_row].astype(int) 37 | 38 | 39 | def get_file_name(lat, lon): 40 | """ 41 | Returns filename such as N27E086.hgt, concatenated 42 | with HGTDIR where these 'hgt' files are kept 43 | """ 44 | if lat >= 0: 45 | ns = 'N' 46 | elif lat < 0: 47 | ns = 'S' 48 | 49 | if lon >= 0: 50 | ew = 'E' 51 | elif lon < 0: 52 | ew = 'W' 53 | 54 | hgt_file = "%(ns)s%(lat)02d%(ew)s%(lon)03d.hgt" % \ 55 | {'lat': abs(lat), 'lon': abs(lon), 'ns': ns, 'ew': ew} 56 | hgt_file_path = os.path.join(HGTDIR, hgt_file) 57 | if os.path.isfile(hgt_file_path): 58 | return hgt_file_path 59 | else: 60 | return None 61 | 62 | 63 | if __name__ == '__main__': 64 | # Mt. Everest 65 | print('Mt. Everest: %d' % get_elevation(27.988056, 86.925278)) 66 | # Kanchanjunga 67 | print('Kanchanjunga: %d' % get_elevation(27.7025, 88.146667)) 68 | -------------------------------------------------------------------------------- /tests.py: -------------------------------------------------------------------------------- 1 | import re 2 | import unittest 3 | import subprocess 4 | from srtm import get_elevation, get_file_name 5 | 6 | 7 | ''' 8 | These elevation values were taken using gdallocationinfo command which is 9 | a part of gdal-bin package. You can install it in Ubuntu (or derivatives) 10 | using: 11 | sudo apt-get install gdal-bin 12 | ''' 13 | 14 | TEST_DATA = [ 15 | { 16 | 'name': 'Mt. Everest', 17 | 'lat': 27.988056, 18 | 'lon': 86.925278, 19 | 'filename': 'hgt/N27E086.hgt', 20 | # gdallocationinfo N27E086.hgt -wgs84 86.925278 27.988056 21 | 'alt': 8840 22 | }, 23 | { 24 | 'name': 'Mt. Kanchanjunga', 25 | 'lat': 27.7025, 26 | 'lon': 88.146667, 27 | 'filename': 'hgt/N27E088.hgt', 28 | # gdallocationinfo N27E088.hgt -wgs84 88.146667 27.7025 29 | 'alt': 8464 30 | } 31 | ] 32 | 33 | 34 | def get_elevation_from_gdallocationinfo(filename, lat, lon): 35 | output = subprocess.check_output([ 36 | 'gdallocationinfo', filename, '-wgs84', str(lon), str(lat) 37 | ]) 38 | return int(re.search('Value: (\d+)', str(output)).group(1)) 39 | 40 | 41 | class TestSRTMMethods(unittest.TestCase): 42 | 43 | def test_get_elevation(self): 44 | for mountain in TEST_DATA: 45 | elevation = get_elevation(mountain['lat'], mountain['lon']) 46 | gdal_elevation = get_elevation_from_gdallocationinfo( 47 | mountain['filename'], mountain['lat'], mountain['lon'] 48 | ) 49 | self.assertEqual(elevation, gdal_elevation) 50 | 51 | def test_get_file_name(self): 52 | for mountain in TEST_DATA: 53 | filename = get_file_name(mountain['lat'], mountain['lon']) 54 | self.assertEqual(filename, mountain['filename']) 55 | 56 | 57 | if __name__ == '__main__': 58 | unittest.main() 59 | --------------------------------------------------------------------------------