/** * Download srtm files for a specific latitude and longitude. * @param int $lat * @param int $lng */ function download_srtm_for($lat, $lon) { global $config; $base_url = 'http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/'; $srtm_directory = get_srtm_directory() . "/"; $fname = srtm::get_filename($lat, $lon); $zip_fname = $fname . '.zip'; $regions = array('Africa', 'Australia', 'Eurasia', 'Islands', 'North_America', 'South_America'); /* * Search file in all regions */ foreach ($regions as $region) { if (!($srtm_data = @file_get_contents($base_url . '/' . $region . '/' . $zip_fname))) { continue; } file_put_contents($srtm_directory . $zip_fname, $srtm_data); if (!($zip = zip_open($srtm_directory . $zip_fname))) { die("Cannot unzip file \"" . $srtm_directory . $zip_fname . "\"\n"); } while ($e = zip_read($zip)) { if (zip_entry_name($e) !== $fname) { continue; } zip_entry_open($zip, $e, "r"); $uncompressed = zip_entry_read($e, zip_entry_filesize($e)); file_put_contents($srtm_directory . $fname, $uncompressed); zip_close($zip); unlink($srtm_directory . $zip_fname); return true; } } die("Cannot find tile for {$lat},{$lon}\" in any region.\n"); }
public static function get_filename($lat, $lon) { $ll = srtm::get_lat_long_adjustments($lat, $lon); //print_R($ll); //always return filename with positive numbers (eg S-33 -> S33) return $ll['lat_dir'] . sprintf("%02.0f", abs((int) ($lat + $ll['lat_adj']))) . $ll['lon_dir'] . sprintf("%03.0f", abs((int) ($lon + $ll['lon_adj']))) . '.hgt'; }
public static function get_filename($lat, $lon) { $ll = srtm::get_lat_long_adjustments($lat, $lon); //print_R($ll); $n_lat = $lat + $ll['lat_adj']; $n_lon = $lon + $ll['lon_adj']; return $ll['lat_dir'] . sprintf("%02.0f", abs((int) ($lat + $ll['lat_adj']))) . $ll['lon_dir'] . sprintf("%03.0f", abs((int) ($lon + $ll['lon_adj']))) . '.hgt'; }
function get_elevation($lat, $lon, $round = TRUE) { $filename = $this->data_path . $this->get_filename($lat, $lon); if ($lat === '' || $lon === '' || !file_exists($filename)) { return FALSE; } $file = fopen($filename, 'r'); $ll = $this->get_lat_long_adjustments($lat, $lon); $lat_dir = $ll['lat_dir']; $lat_adj = $ll['lat_adj']; $lon_dir = $ll['lon_dir']; $lon_adj = $ll['lon_adj']; $y = $lat; $x = $lon; /* Exracting data from NASA .hgt files? Here is a description from www2.jpl.nasa.gov/srtm/faq.html: * The SRTM data files have names like "N34W119.hgt". What do the letters and numbers refer to, and what is ".hgt" format? * * Each data file covers a one-degree-of-latitude by one-degree-of-longitude block of Earth's surface. * The first seven characters indicate the southwest corner of the block, with N, S, E, and W referring * to north, south, east, and west. Thus, the "N34W119.hgt" file covers * latitudes 34 to 35 North and * longitudes 118-119 West * (this file includes downtown Los Angeles, California). * The filename extension ".hgt" simply stands for the word "height", meaning elevation. * It is NOT a format type. These files are in "raw" format (no headers and not compressed), * 16-bit signed integers, elevation measured in meters above sea level, in a * "geographic" (latitude and longitude array) projection, with data voids indicated by -32768. * * International 3-arc-second files have 1201 columns and 1201 rows of data, with a total filesize * of 2,884,802 bytes ( = 1201 x 1201 x 2). * * United States 1-arc-second files have 3601 columns and 3601 rows of data, with a total filesize * of 25,934,402 bytes ( = 3601 x 3601 x 2). * * For more information read the text file "SRTM_Topo.txt" at http://dds.cr.usgs.gov/srtm/version1/Documentation/SRTM_Topo.txt *** S-WiND *** Due to the nature of HGT files, we must read the HGT differently depending if the location is North or South of the equator. - We read them as 2 byte binary - check against http://www.heywhatsthat.com/profiler.html A HGT file records elevations within a square. Data is stored from the upper left corner. --> +----+ | | | | The File is named from its lower left corner --> +----+ *** Not implimented until required *** USA has 1-arc-second files (its like HD for HGT files) * These require 3601 rows + colums, * so if it is ever needed, the calcs below need adjusting and testing for that. jammin - 31/1/2016 */ if ($lat_dir == "S") { //South of the equator offset //Round ensures a whole number for pixel $line = (int) (((int) $lat - $lat) * 1201) * 1201; $pixel = round(($lon - (int) $lon) * 1201); $offset = ($line + $pixel) * 2; } else { //North of the equator offset /* (un-modified WiND version) $offset = ( (integer)(($x - (integer)$x + $lon_adj) * 1200) * 2 + (1200 - (integer)(($y - (integer)$y + $lat_adj) * 1200)) * 2402 ); */ $line = 1200 - (int) (($y - (int) $y + $lat_adj) * 1200); $pixel = (int) (($x - (int) $x + $lon_adj) * 1200) * 2; $offset = $pixel + $line * 2402; } //Debug if (isset($main->userdata->privileges['admin']) && $main->userdata->privileges['admin'] === TRUE && $vars['debug']['enabled'] == TRUE) { echo "DEBUG - SRTM.php - filename:{$filename},\n lat:{$lat}, lat_dir:{$lat_dir}\n lon:{$lon}, lon_dir:{$lon_dir}\n Line:{$line}, pixel:{$pixel}, offset:{$offset}<br />\n"; } fseek($file, $offset); //reverse string - file read (handle, length) $h1 = $h2 = srtm::bytes2int(strrev(fread($file, 2))); fseek($file, $offset - 2402); $h3 = $h4 = srtm::bytes2int(strrev(fread($file, 2))); fclose($file); $m = max($h1, $h2, $h3, $h4); for ($i = 1; $i <= 4; $i++) { $c = 'h' . $i; if (${$c} == -32768) { ${$c} = $m; } } $fx = ($lon - (int) ($lon * 1200) / 1200) * 1200; $fy = ($lat - (int) ($lat * 1200) / 1200) * 1200; // normalizing data (smooths landscape from jutting out) $elevation = ($h1 * (1 - $fx) + $h2 * $fx) * (1 - $fy) + ($h3 * (1 - $fx) + $h4 * $fx) * $fy; if ($round) { $elevation = round($elevation); } return $elevation; }
<?php require_once dirname(__FILE__) . '/../../globals/classes/srtm.php'; // Calculate needed files $needed_files = array(); $bounds = $_SESSION['config']['map']['bounds']; for ($lat = floor($bounds['min_latitude']); $lat <= ceil($bounds['max_latitude']); $lat += 1) { // Clamp if ($lat > 90) { $lat = -90; } for ($lng = floor($bounds['min_longitude']); $lng <= ceil($bounds['max_longitude']); $lng += 1) { // clamp if ($lng > 180) { $lng = -180; } $fname = srtm::get_filename($lat, $lng); $needed_files[$fname] = array('exists' => file_exists(dirname(__FILE__) . '/../../files/srtm/' . $fname), 'lat' => $lat, 'lng' => $lng); } } $web_folders = array('Africa', 'Australia', 'Eurasia', 'Islands', 'North_America', 'South_America'); if (!extension_loaded('zip') || !function_exists('zip_open')) { show_error('You need <strong>"zip"</strong> extension to download srtm files.'); return true; } echo '<ul class="srtm">'; foreach ($needed_files as $fname => $data) { echo '<li data-lat="' . $data['lat'] . '" data-lng="' . $data['lng'] . '" class="' . ($data['exists'] ? 'existing' : 'missing') . '">' . '<span>' . $fname . '</span></li>'; } echo '</ul>'; echo '<div style="clear: both;"> </div>'; ?>
* but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ ini_set('max_execution_time', 300); header('Content-Type: application/json'); require_once dirname(__FILE__) . '/../globals/classes/srtm.php'; if (!isset($_GET['lat']) || !isset($_GET['lng'])) { return; } $base_url = 'http://dds.cr.usgs.gov/srtm/version2_1/SRTM3/'; $srtm_directory = dirname(__FILE__) . '/../files/srtm/'; $fname = srtm::get_filename((int) $_GET['lat'], (int) $_GET['lng']); $zip_fname = $fname . '.zip'; $regions = array('Africa', 'Australia', 'Eurasia', 'Islands', 'North_America', 'South_America'); /* * Search file in all regions */ foreach ($regions as $region) { if (!($srtm_data = @file_get_contents($base_url . '/' . $region . '/' . $zip_fname))) { continue; } file_put_contents($srtm_directory . $zip_fname, $srtm_data); if (!($zip = zip_open($srtm_directory . $zip_fname))) { echo json_encode(array('result' => '500', 'error' => 'cannot unzip')); return; } while ($e = zip_read($zip)) {