gdal-helper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "pp"
4
+ require "gdal_helper"
5
+
6
+ #basic plan - open a 256 by 256 image, write some data, set the projection and geo_trans, then quit, job done.
7
+ image_size = 256
8
+ # Open a tiff to write to, with default create options (TILED=YES, COMPRESS=LZW) to write to..
9
+ outfile = Gdal_File.new(ARGV[0], "w", image_size ,image_size,3,"GTiff", String, ["COMPRESS=DEFLATE", "TILED=YES"])
10
+ 0.upto(image_size-1) do |y|
11
+ #Read a single line, line y
12
+ bands = outfile.read_bands(0,y,image_size,1)
13
+ y_value = ((256.0/image_size)*y).to_i
14
+ 0.upto(image_size-1) do |x|
15
+ bands[0][x]=((256.0/image_size)*x).to_i;
16
+ bands[1][x]= y_value
17
+ end
18
+ outfile.write_bands(0,y,image_size,1,bands)
19
+ end
20
+ # Set the projection
21
+ outfile.set_projection_epsg(102006)
22
+ # set the geo transform (world file)
23
+ outfile.set_geo_transform([1497254.72218513,17.6750396474176,0.0,971470.96496574,0.0,-17.6750396474176])
24
+
25
+
26
+
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "gdal_helper"
4
+
5
+ ## Open input file
6
+ infile = Gdal_File.new(ARGV[0])
7
+ puts ("#{ARGV[0]} -> #{infile}")
8
+ # Read the upper left hand quarter
9
+ bands = infile.read_bands(0,0,infile.xsize/4,infile.ysize/4)
10
+ # Open a file to write to..
11
+ outfile = Gdal_File.new(ARGV[1], "w", infile.xsize/4 , infile.ysize/4,infile.number_of_bands,"GTiff", infile.data_type )
12
+ # write the upper left hand quarter..
13
+ outfile.write_bands(0,0,infile.xsize/4,infile.ysize/4,bands)
14
+ # Set the projection
15
+ outfile.set_projection_epsg(102006)
16
+
17
+
18
+
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ # Basic example - opens the files in argv and prints some info on them..
3
+ require "rubygems"
4
+ require "gdal_helper"
5
+
6
+ ARGV.each do |item|
7
+ gdal_file = Gdal_File.new(item) #open the file..
8
+ size = gdal_file.size() #get the size hash..
9
+ puts("#{item}: #{size["x"]}x#{size["y"]}")
10
+ puts("#{item}: #{size["bands"]} bands of type #{size["data_type"]}")
11
+ puts("#{item}: projection -> '#{gdal_file.get_projection}'")
12
+ puts("#{item}: geo_transform -> [#{gdal_file.get_geo_transform.join(",")}]")
13
+ end
14
+
@@ -0,0 +1,408 @@
1
+ #!/usr/bin/env ruby
2
+ # A simple wrapper class for gdal - the goal is to provide a very simple and easy interface to gdal in ruby.
3
+ # Ruby's gdal bindings, and ruby's ogr bindings are required.
4
+ # blame for this work goes to jay@spruceboy.net
5
+ # Feel free to fork/revamp/whatever - credit would be nice, but not required.
6
+ # I am hoping some more qualified folks will take this on and make it gleam with super goodness - Have at it folks!
7
+ require "gdal/gdal"
8
+ require "gdal/gdalconst"
9
+ require 'gdal/osr'
10
+
11
+
12
+ ###
13
+ # Helper class for gdal.
14
+
15
+ # class with constants and bits that will be used by all gdal-helper classes
16
+ class Gdal_Stuff
17
+ # Does type mappings from gdal to ruby - pretty basic, and needs to be expanded so other types can be done, like for example
18
+ # 32 bit integer types, 16 bit types, double floating bit types, unsigned int types, etc..
19
+ def data_type_from_gdal(data_type)
20
+ case (data_type)
21
+ when Gdal::Gdalconst::GDT_UNKNOWN; return null
22
+ when Gdal::Gdalconst::GDT_BYTE; return String
23
+ when Gdal::Gdalconst::GDT_UINT16 ; return Integer
24
+ when Gdal::Gdalconst::GDT_INT16; return Integer
25
+ when Gdal::Gdalconst::GDT_UINT32; return Integer
26
+ when Gdal::Gdalconst::GDT_INT32; return Integer
27
+ when Gdal::Gdalconst::GDT_FLOAT32; return Float
28
+ when Gdal::Gdalconst::GDT_FLOAT64; return Float
29
+ when Gdal::Gdalconst::GDT_CINT16; return Integer
30
+ when Gdal::Gdalconst::GDT_CINT32; return Float
31
+ when Gdal::Gdalconst::GDT_CFLOAT32; return Float
32
+ when Gdal::Gdalconst::GDT_CFLOAT64; return Float
33
+ end
34
+ end
35
+
36
+ # Does type mappings from ruby to gdal - pretty basic, and needs to be expanded so other types can be done, like for example
37
+ # 32 bit integer types, 16 bit types, double floating bit types, unsigned int types, etc..
38
+ def data_type_to_gdal ( data_type )
39
+ #puts("DEBUG: data_type_to_gdal(#{data_type})")
40
+ # Does not work, something is wrong with my understanding of the case statement and class compares..
41
+ #case (data_type)
42
+ # when String; return Gdal::Gdalconst::GDT_BYTE
43
+ # when Integer; return Gdal::Gdalconst::GDT_INT16
44
+ # when Float; return Gdal::Gdalconst::GDT_FLOAT32
45
+ #end
46
+ return Gdal::Gdalconst::GDT_BYTE if (data_type == String )
47
+ return Gdal::Gdalconst::GDT_INT16 if (data_type == Integer )
48
+ return Gdal::Gdalconst::GDT_FLOAT32 if (data_type == Float )
49
+ raise ArgumentError, "#{data_type} is not a valid (String|Integer|Float) data type.. not sure what to do here folks", caller
50
+ end
51
+
52
+ end
53
+
54
+ ##
55
+ # Class wrapping up a gdal band.
56
+ class Gdal_Band < Gdal_Stuff
57
+
58
+ def initialize( band)
59
+ @band = band
60
+ end
61
+ #Reads data
62
+ def read(start_x, start_y, width_x, width_y)
63
+ return unpack(width_y*width_x, @band.read_raster(start_x,start_y,width_x,width_y))
64
+ end
65
+
66
+ #Writes data
67
+ def write(start_x, start_y, width_x, width_y, data)
68
+ return @band.write_raster(start_x,start_y,width_x,width_y, pack(data))
69
+ end
70
+
71
+ #returns the datatype
72
+ def data_type()
73
+ data_type_from_gdal(@band.DataType)
74
+ end
75
+
76
+ #returns the datatype as a string in a gdal like manner
77
+ def data_type_pretty()
78
+ type_string = case(@band.DataType)
79
+ when Gdal::Gdalconst::GDT_UNKNOWN; 'GDT_UNKNOWN'
80
+ when Gdal::Gdalconst::GDT_BYTE; 'GDT_BYTE'
81
+ when Gdal::Gdalconst::GDT_UINT16;'GDT_UINT16'
82
+ when Gdal::Gdalconst::GDT_INT16;'GDT_INT16'
83
+ when Gdal::Gdalconst::GDT_UINT32; 'GDT_UINT32'
84
+ when Gdal::Gdalconst::GDT_INT32; 'GDT_INT32'
85
+ when Gdal::Gdalconst::GDT_FLOAT32; 'IDT_FLOAT32'
86
+ when Gdal::Gdalconst::GDT_FLOAT64; 'GDT_FLOAT64'
87
+ when Gdal::Gdalconst::GDT_CINT16; 'GDT_CINT16'
88
+ when Gdal::Gdalconst::GDT_CINT32; 'GDT_CINT32'
89
+ when Gdal::Gdalconst::GDT_CFLOAT32; 'GDT_CFLOAT32'
90
+ when Gdal::Gdalconst::GDT_CFLOAT64; 'GDT_CFLOAT64'
91
+ end
92
+ type_string
93
+ end
94
+
95
+ #converts to a string for display/print/other .to_s action
96
+ def to_s
97
+ "#{data_type_pretty}"
98
+ end
99
+
100
+ private
101
+
102
+ # string.pack notes - for refrence for the function below.
103
+ # Format | Returns | Function
104
+ #-------+---------+-----------------------------------------
105
+ # A | String | with trailing nulls and spaces removed
106
+ #-------+---------+-----------------------------------------
107
+ # a | String | string
108
+ #-------+---------+-----------------------------------------
109
+ # B | String | extract bits from each character (msb first)
110
+ #-------+---------+-----------------------------------------
111
+ # b | String | extract bits from each character (lsb first)
112
+ #-------+---------+-----------------------------------------
113
+ # C | Fixnum | extract a character as an unsigned integer
114
+ #-------+---------+-----------------------------------------
115
+ # c | Fixnum | extract a character as an integer
116
+ #-------+---------+-----------------------------------------
117
+ # d,D | Float | treat sizeof(double) characters as
118
+ # | | a native double
119
+ #-------+---------+-----------------------------------------
120
+ # E | Float | treat sizeof(double) characters as
121
+ # | | a double in little-endian byte order
122
+ #-------+---------+-----------------------------------------
123
+ # e | Float | treat sizeof(float) characters as
124
+ # | | a float in little-endian byte order
125
+ #-------+---------+-----------------------------------------
126
+ # f,F | Float | treat sizeof(float) characters as
127
+ # | | a native float
128
+ #-------+---------+-----------------------------------------
129
+ # G | Float | treat sizeof(double) characters as
130
+ # | | a double in network byte order
131
+ #-------+---------+-----------------------------------------
132
+ # g | Float | treat sizeof(float) characters as a
133
+ # | | float in network byte order
134
+ #-------+---------+-----------------------------------------
135
+ # H | String | extract hex nibbles from each character
136
+ # | | (most significant first)
137
+ #-------+---------+-----------------------------------------
138
+ # h | String | extract hex nibbles from each character
139
+ # | | (least significant first)
140
+ #-------+---------+-----------------------------------------
141
+ # I | Integer | treat sizeof(int) (modified by _)
142
+ # | | successive characters as an unsigned
143
+ # | | native integer
144
+ #-------+---------+-----------------------------------------
145
+ # i | Integer | treat sizeof(int) (modified by _)
146
+ # | | successive characters as a signed
147
+ # | | native integer
148
+ #-------+---------+-----------------------------------------
149
+ # L | Integer | treat four (modified by _) successive
150
+ # | | characters as an unsigned native
151
+ # | | long integer
152
+ #-------+---------+-----------------------------------------
153
+ # l | Integer | treat four (modified by _) successive
154
+ # | | characters as a signed native
155
+ # | | long integer
156
+ #-------+---------+-----------------------------------------
157
+ # M | String | quoted-printable
158
+ #-------+---------+-----------------------------------------
159
+ # m | String | base64-encoded
160
+ #-------+---------+-----------------------------------------
161
+ # N | Integer | treat four characters as an unsigned
162
+ # | | long in network byte order
163
+ #-------+---------+-----------------------------------------
164
+ # n | Fixnum | treat two characters as an unsigned
165
+ # | | short in network byte order
166
+ #-------+---------+-----------------------------------------
167
+ # P | String | treat sizeof(char *) characters as a
168
+ # | | pointer, and return \emph{len} characters
169
+ # | | from the referenced location
170
+ #-------+---------+-----------------------------------------
171
+ # p | String | treat sizeof(char *) characters as a
172
+ # | | pointer to a null-terminated string
173
+ #-------+---------+-----------------------------------------
174
+ # Q | Integer | treat 8 characters as an unsigned
175
+ # | | quad word (64 bits)
176
+ #-------+---------+-----------------------------------------
177
+ # q | Integer | treat 8 characters as a signed
178
+ # | | quad word (64 bits)
179
+ #-------+---------+-----------------------------------------
180
+ # S | Fixnum | treat two (different if _ used)
181
+ # | | successive characters as an unsigned
182
+ # | | short in native byte order
183
+ #-------+---------+-----------------------------------------
184
+ # s | Fixnum | Treat two (different if _ used)
185
+ # | | successive characters as a signed short
186
+ # | | in native byte order
187
+ #-------+---------+-----------------------------------------
188
+ # U | Integer | UTF-8 characters as unsigned integers
189
+ #-------+---------+-----------------------------------------
190
+ # u | String | UU-encoded
191
+ #-------+---------+-----------------------------------------
192
+ # V | Fixnum | treat four characters as an unsigned
193
+ # | | long in little-endian byte order
194
+ #-------+---------+-----------------------------------------
195
+ # v | Fixnum | treat two characters as an unsigned
196
+ # | | short in little-endian byte order
197
+ #-------+---------+-----------------------------------------
198
+ # w | Integer | BER-compressed integer (see Array.pack)
199
+ #-------+---------+-----------------------------------------
200
+ # X | --- | skip backward one character
201
+ #-------+---------+-----------------------------------------
202
+ # x | --- | skip forward one character
203
+ #-------+---------+-----------------------------------------
204
+ # Z | String | with trailing nulls removed
205
+ # | | upto first null with *
206
+ #-------+---------+-----------------------------------------
207
+ # @ | --- | skip to the offset given by the
208
+ # | | length argument
209
+ #-------+---------+-----------------------------------------
210
+ #unpacks the data
211
+ def unpack ( items, data)
212
+ pack_template = case (@band.DataType)
213
+ when Gdal::Gdalconst::GDT_UNKNOWN;raise ArgumentError, "GDT_UNKNOWN has no storage template.. not sure what to do here folks", caller
214
+ when Gdal::Gdalconst::GDT_BYTE; 'C'
215
+ when Gdal::Gdalconst::GDT_UINT16;'S'
216
+ when Gdal::Gdalconst::GDT_INT16;'s'
217
+ when Gdal::Gdalconst::GDT_UINT32; 'I'
218
+ when Gdal::Gdalconst::GDT_INT32; 'i'
219
+ when Gdal::Gdalconst::GDT_FLOAT32; 'f'
220
+ when Gdal::Gdalconst::GDT_FLOAT64; 'D'
221
+ when Gdal::Gdalconst::GDT_CINT16; '' #What are these?
222
+ when Gdal::Gdalconst::GDT_CINT32; '' #What are these?
223
+ when Gdal::Gdalconst::GDT_CFLOAT32; '' #What are these?
224
+ when Gdal::Gdalconst::GDT_CFLOAT64; '' #What are these?
225
+ end
226
+ return data.unpack(pack_template*data.length)
227
+ end
228
+
229
+ #Notes for pack..
230
+ # #Directives for pack.
231
+ #
232
+ #Directive Meaning
233
+ #---------------------------------------------------------------
234
+ # @ | Moves to absolute position
235
+ # A | ASCII string (space padded, count is width)
236
+ # a | ASCII string (null padded, count is width)
237
+ # B | Bit string (descending bit order)
238
+ # b | Bit string (ascending bit order)
239
+ # C | Unsigned char
240
+ # c | Char
241
+ # D, d | Double-precision float, native format
242
+ # E | Double-precision float, little-endian byte order
243
+ # e | Single-precision float, little-endian byte order
244
+ # F, f | Single-precision float, native format
245
+ # G | Double-precision float, network (big-endian) byte order
246
+ # g | Single-precision float, network (big-endian) byte order
247
+ # H | Hex string (high nibble first)
248
+ # h | Hex string (low nibble first)
249
+ # I | Unsigned integer
250
+ # i | Integer
251
+ # L | Unsigned long
252
+ # l | Long
253
+ # M | Quoted printable, MIME encoding (see RFC2045)
254
+ # m | Base64 encoded string
255
+ # N | Long, network (big-endian) byte order
256
+ # n | Short, network (big-endian) byte-order
257
+ # P | Pointer to a structure (fixed-length string)
258
+ # p | Pointer to a null-terminated string
259
+ # Q, q | 64-bit number
260
+ # S | Unsigned short
261
+ # s | Short
262
+ # U | UTF-8
263
+ # u | UU-encoded string
264
+ # V | Long, little-endian byte order
265
+ # v | Short, little-endian byte order
266
+ # w | BER-compressed integer\fnm
267
+ # X | Back up a byte
268
+ # x | Null byte
269
+ # Z | Same as ``a'', except that null is added with *
270
+ # packs data in prep to write to gdal..
271
+ def pack(data)
272
+ pack_template = case(@band.DataType)
273
+ when Gdal::Gdalconst::GDT_UNKNOWN;raise ArgumentError, "GDT_UNKNOWN has no storage template.. not sure what to do here folks", caller
274
+ when Gdal::Gdalconst::GDT_BYTE; 'c'
275
+ when Gdal::Gdalconst::GDT_UINT16;'S'
276
+ when Gdal::Gdalconst::GDT_INT16;'s'
277
+ when Gdal::Gdalconst::GDT_UINT32; 'I'
278
+ when Gdal::Gdalconst::GDT_INT32; 'i'
279
+ when Gdal::Gdalconst::GDT_FLOAT32; 'f'
280
+ when Gdal::Gdalconst::GDT_FLOAT64; 'D'
281
+ when Gdal::Gdalconst::GDT_CINT16; '' #What are these? Complex types?
282
+ when Gdal::Gdalconst::GDT_CINT32; '' #What are these?
283
+ when Gdal::Gdalconst::GDT_CFLOAT32; '' #What are these?
284
+ when Gdal::Gdalconst::GDT_CFLOAT64; '' #What are these?
285
+ end
286
+ raise(ArgumentError, "Complex type requested, but no complex type handling.. not sure what to do here folks", caller) if ( pack_template == '')
287
+ return data.pack(pack_template*data.length)
288
+ end
289
+
290
+ end
291
+
292
+ ##
293
+ # Class for a file - this is what most folks want
294
+ # Use like:
295
+ #infile = Gdal_File.new("foo.tif")
296
+ #bands = infile.read_bands(0,0,infile.xsize/4,infile.ysize/4)
297
+ #..do something..
298
+ class Gdal_File < Gdal_Stuff
299
+ def initialize ( name, mode="r", xsize=nil, ysize=nil,bands=3, driver="GTiff", data_type=String, options=['TILED=YES','COMPRESS=DEFLATE'] )
300
+ if ( mode == "r" )
301
+ @gdal_file = Gdal::Gdal.open(name)
302
+ else
303
+ if ( mode == "w")
304
+ if (File.exists?(name))
305
+ @gdal_file = Gdal::Gdal.open(name,Gdal::Gdalconst::GA_UPDATE )
306
+ else
307
+ driver = Gdal::Gdal.get_driver_by_name(driver)
308
+ puts(driver.class)
309
+ puts("Creating create(#{name}, #{xsize}, #{ysize}, #{bands}, #{data_type_to_gdal(data_type).to_s})")
310
+ @gdal_file = driver.create(name, xsize, ysize, bands, data_type_to_gdal(data_type), options)
311
+ end
312
+ else
313
+ raise ArgumentError, "mode of \"#{mode}\" is not useful (not r|w) not sure what to do here folks", caller
314
+ end
315
+ end
316
+
317
+ @bands=[]
318
+ #1 is not a mistake - the raster bands start at 1 no 0. just a fyi.
319
+ 1.upto(@gdal_file.RasterCount).each {|x| @bands << Gdal_Band.new(@gdal_file.get_raster_band(x))}
320
+ end
321
+
322
+ ###
323
+ # methods for Reading and writing data..
324
+
325
+ #reads bands
326
+ def read_bands(start_x, start_y, width_x, width_y)
327
+ data = []
328
+ @bands.each_index {|x| data[x] = @bands[x].read(start_x, start_y, width_x, width_y)}
329
+ data
330
+ end
331
+ #reads a band
332
+ def read_band(bandno,start_x, start_y,width_x, width_y )
333
+ @bands[bandno].read(start_x, start_y, width_x, width_y)
334
+ end
335
+ #writes bands
336
+ def write_bands(start_x, start_y, width_x, width_y, bands)
337
+ bands.each_index {|x| @bands[x].write(start_x, start_y, width_x, width_y, bands[x])}
338
+ end
339
+ #writes a band
340
+ def write_band(bandno,start_x, start_y, end_x, end_y, band )
341
+ @bands[bandno].write(start_x, start_y, end_x, end_y, band)
342
+ end
343
+
344
+
345
+ ###
346
+ # getting info about the data..
347
+
348
+ #returns basic size info as a hash
349
+ def size()
350
+ { "x"=> @gdal_file.RasterXSize,
351
+ "y" => @gdal_file.RasterYSize,
352
+ "bands" => @bands.length,
353
+ "data_type" => @bands[0].data_type()}
354
+ end
355
+
356
+ #x dimention size
357
+ def xsize()
358
+ @gdal_file.RasterXSize
359
+ end
360
+
361
+ #y dim size
362
+ def ysize()
363
+ @gdal_file.RasterYSize
364
+ end
365
+
366
+ #number of bands
367
+ def number_of_bands()
368
+ @bands.length
369
+ end
370
+
371
+ #types of bands
372
+ def data_type()
373
+ @bands.first.data_type
374
+ end
375
+
376
+ #for pping or other .to_s action..
377
+ def to_s
378
+ "#{xsize}x#{ysize} with #{number_of_bands} #{@bands[0].to_s} bands"
379
+ end
380
+
381
+ # gets the projection
382
+ def get_projection
383
+ @gdal_file.get_projection
384
+ end
385
+
386
+ #sets the projection
387
+ def set_projection(proj_str)
388
+ @gdal_file.set_projection(proj_str)
389
+ end
390
+
391
+ #looks up the projection in the epsg database, give it a number like 102006.
392
+ def set_projection_epsg(epsg)
393
+ srs = Gdal::Osr::SpatialReference.new()
394
+ srs.import_from_epsg(epsg)
395
+ @gdal_file.set_projection(srs.export_to_wkt)
396
+ end
397
+
398
+ #sets the geo_transform, the wld file generally.
399
+ def set_geo_transform(srs)
400
+ @gdal_file.set_geo_transform(srs)
401
+ end
402
+
403
+ #gets the geo transform (wld file traditionally)
404
+ def get_geo_transform()
405
+ @gdal_file.get_geo_transform
406
+ end
407
+
408
+ end
@@ -0,0 +1,4 @@
1
+ module Gdal_Helper
2
+ Version = "0.0.1"
3
+ end
4
+
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require "rubygems"
3
+ require "gdal_helper"
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gdal-helper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - JC
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-04-20 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: A helper library for the ruby bindings to gdal (http://gdal.org)
17
+ email: JC@alaska.edu
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - lib/version.rb
26
+ - lib/gdal_helper.rb
27
+ - test/ruby_gem_test.rb
28
+ - examples/basic_example.rb
29
+ - examples/print_info_example.rb
30
+ - examples/gdal_helper_test.rb
31
+ has_rdoc: true
32
+ homepage: http://www.gina.alaska.edu
33
+ licenses: []
34
+
35
+ post_install_message:
36
+ rdoc_options: []
37
+
38
+ require_paths:
39
+ - lib
40
+ required_ruby_version: !ruby/object:Gem::Requirement
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: "0"
45
+ version:
46
+ required_rubygems_version: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: "0"
51
+ version:
52
+ requirements:
53
+ - PostgreSQL >= 7.4
54
+ rubyforge_project:
55
+ rubygems_version: 1.3.4
56
+ signing_key:
57
+ specification_version: 3
58
+ summary: A helper library for the ruby bindings to gdal (http://gdal.org)
59
+ test_files: []
60
+