I have downloaded some of the NASA SRTM elevation data, which comes in binary files. The format is described as follows:
The DEM is provided as 16-bit signed integer data in a simple binary raster. There are no header or trailer bytes embedded in the file. The data are stored in row major order (all the data for row 1, followed by all the data for row 2, etc.).
All elevations are in meters referenced to the WGS84/EGM96 geoid as documented at http:// www.NGA.mil/GandG/wgsegm/.
Byte order is Motorola ("big-endian") standard with the most significant byte first. Since they are signed integers elevations can range from -32767 to 32767 meters, encompassing the range of elevation to be found on the Earth.
These data also contain occassional voids from a number of causes such as shadowing, phase unwrapping anomalies, or other radar-specific causes. Voids are flagged with the value -32768.
I am trying to parse these values with clojure for further analysis and visualization. My current code looks like this:
;; Taken from http://stackoverflow.com/a/26372677/2345852
(defn slurp-bytes
"Slurp the bytes from a slurpable thing"
[x]
(with-open [out (java.io.ByteArrayOutputStream.)]
(clojure.java.io/copy (clojure.java.io/input-stream x) out)
(.toByteArray out)))
(defn read-elevation
"Reads elevation data stored in .hgt files as provided by the NASA
SRTM datasets"
[src]
(->> (slurp-bytes src)
(partition 2)
(map #(reduce + %))))
(read-elevation ...)
This however seems to output wrong data: I am looking at the Himalayas and the array holds numbers from -126 to 150. I suggest is because of wrong byte order (executing (java.nio.ByteOrder/nativeOrder)
returns LITTLE_ENDIAN
). How do I reverse the byte-order so that it's platform independent?