ooRexx logo
   1: /* ---------------------------------------------------------------- */
   2: /* Transforms a GeoTiff file as produced by ASTER GDEM, see:        */
   3: /*                                                                  */
   4: /* http://gdem.ersdac.jspacesystems.or.jp                           */
   5: /*                                                                  */
   6: /* to 'hgt' format as used by SRTM, see:                            */
   7: /*                                                                  */
   8: /* https://lpdaac.usgs.gov/products/measures_products_table/srtmgl3 */
   9: /*                                                                  */
  10: /* Foa a nice explanation of the (geo)tiff format see:              */
  11: /*                                                                  */
  12: /* http://www.awaresystems.be/imaging/tiff.html                     */
  13: /*                                                                  */
  14: /* ---------------------------------------------------------------- */
  15: /*                                                                  */
  16: /* Originally by Ruurd J. Idenburg                                  */                                                             
  17: /*                                                                  */
  18: /* No copyright, no licence, no guarantees or warrantees, be it     */
  19: /* explicit, implicit or whatever. Usage is totally and completely  */
  20: /* at the users own risk, the author shall not be liable for any    */ 
  21: /* damages whatsoever, for any reason whatsoever.                   */
  22: /*                                                                  */
  23: /* Please keep this comment block intact when modifying this code   */
  24: /* and add a note with date and a description.                      */
  25: /*                                                                  */
  26: /* ---------------------------------------------------------------- */
  27: /*  Parameter(s):                                                   */ 
  28: /*                                                                  */
  29: /*    file - the (geo)tiff path and filename to be converted        */
  30: /*                                                                  */
  31: /*                                                                  */
  32: /*  Result:                                                         */
  33: /*                                                                  */
  34: /*    A file on the same path and filename as the input tiff file   */
  35: /*    but with file extension 'hgt' and in the SRTM format          */
  36: /*                                                                  */
  37: /* ---------------------------------------------------------------- */
  38: /* 2014/02/01 - Initial version                                     */
  39: /* ---------------------------------------------------------------- */
  40: 
  41: use arg geoTiffFile
  42: geoTiff = .stream~new(geoTiffFile)
  43: geoTiff~open("read")
  44: /* ---------------------------------------------------------------- */
  45: /* The Image File Directory(IFD) is always at offset 4 in the file. */
  46: /* ---------------------------------------------------------------- */
  47: ifdOffset = (geoTiff~charin(5,4)~reverse~c2d)+1   -- cater for base 1 
  48: say "Found the IFD at offset" ifdOffset "('"ifdOffset~d2x(8)"'X)."
  49: /* ---------------------------------------------------------------- */
  50: /* Get the number of tags present in this IFD.                      */
  51: /* ---------------------------------------------------------------- */
  52: tagCount = geoTiff~charin(ifdOffset,2)~reverse~c2d
  53: say "IFD contains" tagCount "tags."
  54: /* ---------------------------------------------------------------- */
  55: /* The tags follow directly after the count and each 12 bytes long. */
  56: /* ---------------------------------------------------------------- */
  57: tags = geoTiff~charin(ifdOffset+2,tagCount*12)
  58: nextIfdOffset = geoTiff~charin(ifdOffset+2+tagCount*12,4)~reverse~c2d
  59: -- say nextIfdOffset  -- for now assume no following IFD's
  60: tagDir = .directory~new
  61: /* ---------------------------------------------------------------- */
  62: /* Each tag consists of Key, Datatype, Valuecount and Value(s).     */
  63: /* If the values don't fit in 4 bytes, the value is an offset to    */
  64: /* where the values can be found.                                   */
  65: /* ---------------------------------------------------------------- */
  66: do t=0 to tagCount-1  --cater for base 1
  67:   aTag = tags~substr(1+12*t,12)
  68:   tagKey = aTag~substr(1,2)~reverse~c2x
  69:   dataType = aTag~substr(3,2)~reverse~c2x
  70:   valueCount = aTag~substr(5,4)~reverse~c2d
  71:   valuePointer = aTag~substr(9,4)~reverse~c2d -- can be a value only
  72:   tag = .directory~new
  73:   tagDir~put(dataType valueCount valuePointer,tagKey)
  74: end
  75: columns = tagDir~0100~word(3)
  76: say "The elevation information is" columns "columns wide."
  77: rows = tagDir~0101~word(3)
  78: say "The elevation information is" rows "rows deep."
  79: --rowsPerStrip = tagDir~0116~word(3) -- not needed for further processing
  80: --say rowsPerStrip
  81: stripByteCountValues = tagDir~0117~word(2)
  82: say "There are" stripByteCountValues "byte counts for the row strips to read." 
  83: stripByteCountsOffset = tagDir~0117~word(3)+1 -- cater for base 1
  84: --say stripByteCountsOffset
  85: stripByteCounts = geoTiff~charin(stripByteCountsOffset,stripByteCountValues*4)
  86: --say stripByteCounts~c2x
  87: stripCount = tagDir~0111~word(2)
  88: say "The strip count" stripCount "should be equal to previous value."
  89: stripOffsetsPointer = tagDir~0111~word(3)+1 -- cater for base 1
  90: --say stripOffsetsPointer
  91: stripPointers = geoTiff~charin(stripOffsetsPointer,stripCount*4)
  92: heightFile = geoTiffFile~substr(1,geoTiffFile~lastPos(".")-1)".hgt"
  93: srtm = .stream~new(heightFile)
  94: srtm~open("write" "replace")
  95: do a=0 to stripCount-1  -- cater for base 1
  96:   charinLength = stripByteCounts~substr(1+4*a,4)~reverse~c2d 
  97:   stripOffset = stripPointers~substr(1+4*a,4)~reverse~c2d+1
  98:   strip = geoTiff~charin(stripOffset,charinLength)
  99:   -- make strip contents big-endian from little-endian
 100:   test = makeBigEndian(strip)
 101:   --say test~length
 102:   srtm~charout(test)
 103: end
 104: geoTiff~close
 105: srtm~close
 106: exit
 107:    
 108: ::routine makeBigEndian
 109:   use arg string
 110:   big = .mutablebuffer~new(,string~length)
 111:   do i=1 by 2 to string~length
 112:     big~append(string~substr(i,2)~reverse)
 113:   end
 114:   return big
 115: exit
 116: 
 117:  
If you feel inclined to make corrections, suggestions etc., please mail me any.
All content © Ruurd Idenburg, 2007–, except where marked otherwise. All rights reserved. This page is primarily for non-commercial use only. The Idenburg website records no personal information and sets no ‘cookies’. This site is hosted on a VPS(Virtual Private System) rented from Transip.nl, a Dutch company, falling under Dutch (privacy) laws (I think).

This page updated on by Ruurd Idenburg.