ffi-gdal 0.0.4 → 1.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -1
  3. data/Rakefile +12 -1
  4. data/TODO.md +11 -0
  5. data/ffi-gdal.gemspec +2 -2
  6. data/lib/ext/error_symbols.rb +59 -0
  7. data/lib/ext/float_ext.rb +15 -0
  8. data/lib/ext/narray_ext.rb +16 -0
  9. data/lib/ext/to_bool.rb +2 -0
  10. data/lib/ffi-gdal.rb +139 -4
  11. data/lib/ffi/{gdal/cpl_conv.rb → cpl/conv_h.rb} +2 -3
  12. data/lib/ffi/{gdal/cpl_error.rb → cpl/error_h.rb} +1 -25
  13. data/lib/ffi/cpl/minixml_h.rb +14 -0
  14. data/lib/ffi/{gdal/cpl_string.rb → cpl/string_h.rb} +0 -25
  15. data/lib/ffi/{gdal/cpl_vsi.rb → cpl/vsi_h.rb} +0 -0
  16. data/lib/ffi/cpl/xml_node.rb +13 -0
  17. data/lib/ffi/gdal.rb +57 -593
  18. data/lib/ffi/gdal/alg_h.rb +127 -0
  19. data/lib/ffi/gdal/gdal_grid_data_metrics_options.rb +14 -0
  20. data/lib/ffi/gdal/gdal_grid_inverse_distance_to_a_power_options.rb +19 -0
  21. data/lib/ffi/gdal/gdal_grid_moving_average_options.rb +14 -0
  22. data/lib/ffi/gdal/gdal_grid_nearest_neighbor_options.rb +13 -0
  23. data/lib/ffi/gdal/gdal_h.rb +683 -0
  24. data/lib/ffi/gdal/gdal_rpc_info.rb +27 -0
  25. data/lib/ffi/gdal/gdal_transformer_info.rb +14 -0
  26. data/lib/ffi/gdal/gdal_warp_options.rb +43 -0
  27. data/lib/ffi/gdal/grid_h.rb +51 -0
  28. data/lib/ffi/gdal/version.rb +1 -1
  29. data/lib/ffi/gdal/warper_h.rb +48 -0
  30. data/lib/ffi/ogr.rb +12 -0
  31. data/lib/ffi/ogr/api_h.rb +553 -0
  32. data/lib/ffi/ogr/core_h.rb +148 -0
  33. data/lib/ffi/ogr/featurestyle_h.rb +22 -0
  34. data/lib/ffi/ogr/geocoding_h.rb +21 -0
  35. data/lib/ffi/ogr/ogr_contour_writer_info.rb +14 -0
  36. data/lib/ffi/ogr/ogr_envelope.rb +12 -0
  37. data/lib/ffi/ogr/ogr_envelope_3d.rb +14 -0
  38. data/lib/ffi/ogr/ogr_field.rb +50 -0
  39. data/lib/ffi/ogr/ogr_style_param.rb +12 -0
  40. data/lib/ffi/ogr/ogr_style_value.rb +13 -0
  41. data/lib/ffi/ogr/srs_api_h.rb +325 -0
  42. data/lib/gdal/color_entry.rb +47 -0
  43. data/lib/gdal/color_entry_extensions.rb +30 -0
  44. data/lib/gdal/color_interpretation.rb +15 -0
  45. data/lib/gdal/color_table.rb +146 -0
  46. data/lib/gdal/color_table_extensions.rb +47 -0
  47. data/lib/gdal/color_table_types/cmyk.rb +25 -0
  48. data/lib/gdal/color_table_types/gray.rb +9 -0
  49. data/lib/gdal/color_table_types/hls.rb +21 -0
  50. data/lib/gdal/color_table_types/rgb.rb +25 -0
  51. data/lib/gdal/data_type.rb +38 -0
  52. data/lib/gdal/dataset.rb +437 -0
  53. data/lib/gdal/dataset_extensions.rb +496 -0
  54. data/lib/gdal/driver.rb +244 -0
  55. data/lib/gdal/driver_extensions.rb +56 -0
  56. data/lib/gdal/environment_methods.rb +43 -0
  57. data/lib/{ffi-gdal → gdal}/exceptions.rb +4 -1
  58. data/lib/gdal/geo_transform.rb +188 -0
  59. data/lib/gdal/geo_transform_extensions.rb +90 -0
  60. data/lib/gdal/logger.rb +7 -0
  61. data/lib/{ffi-gdal → gdal}/major_object.rb +15 -14
  62. data/lib/gdal/options.rb +49 -0
  63. data/lib/gdal/raster_attribute_table.rb +185 -0
  64. data/lib/gdal/raster_attribute_table_extensions.rb +40 -0
  65. data/lib/{ffi-gdal → gdal}/raster_band.rb +227 -99
  66. data/lib/gdal/raster_band_extensions.rb +198 -0
  67. data/lib/{ffi-gdal → gdal}/version_info.rb +8 -0
  68. data/lib/gdal/warp_operation.rb +96 -0
  69. data/lib/ogr/coordinate_transformation.rb +108 -0
  70. data/lib/ogr/data_source.rb +172 -0
  71. data/lib/ogr/data_source_extensions.rb +32 -0
  72. data/lib/ogr/driver.rb +119 -0
  73. data/lib/ogr/envelope.rb +80 -0
  74. data/lib/ogr/envelope_extensions.rb +92 -0
  75. data/lib/ogr/exceptions.rb +35 -0
  76. data/lib/ogr/feature.rb +212 -0
  77. data/lib/ogr/feature_definition.rb +120 -0
  78. data/lib/ogr/feature_definition_extensions.rb +36 -0
  79. data/lib/ogr/feature_extensions.rb +31 -0
  80. data/lib/ogr/field.rb +91 -0
  81. data/lib/ogr/field_extensions.rb +23 -0
  82. data/lib/ogr/geocoding_session.rb +84 -0
  83. data/lib/ogr/geometry.rb +617 -0
  84. data/lib/ogr/geometry_extensions.rb +60 -0
  85. data/lib/ogr/geometry_types/collection.rb +45 -0
  86. data/lib/ogr/geometry_types/curve.rb +120 -0
  87. data/lib/ogr/geometry_types/surface.rb +20 -0
  88. data/lib/ogr/layer.rb +226 -0
  89. data/lib/ogr/layer_extensions.rb +55 -0
  90. data/lib/ogr/line_string.rb +7 -0
  91. data/lib/ogr/linear_ring.rb +6 -0
  92. data/lib/ogr/multi_line_string.rb +9 -0
  93. data/lib/ogr/multi_point.rb +7 -0
  94. data/lib/ogr/multi_polygon.rb +14 -0
  95. data/lib/ogr/point.rb +89 -0
  96. data/lib/ogr/polygon.rb +9 -0
  97. data/lib/ogr/spatial_reference.rb +723 -0
  98. data/lib/ogr/spatial_reference_extensions.rb +32 -0
  99. data/lib/ogr/style_table.rb +17 -0
  100. data/lib/ogr/style_table_extensions.rb +16 -0
  101. data/spec/{ffi-gdal/integration → integration}/color_table_info_spec.rb +1 -1
  102. data/spec/{ffi-gdal/integration → integration}/dataset_info_spec.rb +0 -0
  103. data/spec/{ffi-gdal/integration → integration}/driver_info_spec.rb +1 -1
  104. data/spec/{ffi-gdal/integration → integration}/geo_transform_info_spec.rb +0 -0
  105. data/spec/{ffi-gdal/integration → integration}/raster_attribute_table_info_spec.rb +1 -1
  106. data/spec/{ffi-gdal/integration → integration}/raster_band_info_spec.rb +5 -5
  107. data/spec/spec_helper.rb +4 -1
  108. data/spec/support/shapefiles/states_21basic/states.prj +1 -0
  109. data/spec/support/shapefiles/states_21basic/states.sbn +0 -0
  110. data/spec/support/shapefiles/states_21basic/states.sbx +0 -0
  111. data/spec/support/shapefiles/states_21basic/states.shp +0 -0
  112. data/spec/support/worldfiles/SR_50M/SR_50M.VERSION.txt +1 -0
  113. data/spec/support/worldfiles/SR_50M/SR_50M.prj +1 -0
  114. data/spec/support/worldfiles/SR_50M/SR_50M.tfw +6 -0
  115. data/spec/{ext/cpl_error_symbols_spec.rb → unit/ext/error_symbols_spec.rb} +1 -1
  116. data/spec/unit/gdal/color_table_spec.rb +146 -0
  117. data/spec/unit/ogr/layer_spec.rb +97 -0
  118. data/spec/unit/ogr/linear_ring_spec.rb +111 -0
  119. data/spec/unit/ogr/point_spec.rb +321 -0
  120. data/spec/{ffi-gdal/unit → unit}/version_info_spec.rb +1 -1
  121. data/testing_gdal.rb +168 -0
  122. data/testing_gdalwarp.rb +91 -0
  123. data/testing_layer_to_layer.rb +35 -0
  124. data/testing_ndvi.rb +76 -0
  125. data/testing_nir.rb +77 -0
  126. data/testing_ogr.rb +63 -0
  127. metadata +167 -59
  128. data/lib/ext/cpl_error_symbols.rb +0 -37
  129. data/lib/ffi-gdal/color_table.rb +0 -59
  130. data/lib/ffi-gdal/dataset.rb +0 -359
  131. data/lib/ffi-gdal/driver.rb +0 -151
  132. data/lib/ffi-gdal/geo_transform.rb +0 -137
  133. data/lib/ffi-gdal/raster_attribute_table.rb +0 -78
  134. data/lib/ffi/gdal/ogr_api.rb +0 -21
  135. data/lib/ffi/gdal/ogr_core.rb +0 -195
  136. data/lib/ffi/gdal/ogr_srs_api.rb +0 -44
  137. data/meow.rb +0 -144
  138. data/rubby.rb +0 -224
@@ -0,0 +1,90 @@
1
+ require 'json'
2
+
3
+ module GDAL
4
+ module GeoTransformExtensions
5
+
6
+ # The calculated UTM easting of the pixel on the map.
7
+ #
8
+ # @return [Float]
9
+ def x_projection(x_pixel, y_pixel)
10
+ return nil if null?
11
+
12
+ apply_geo_transform(x_pixel, y_pixel)[:x_location]
13
+ end
14
+
15
+ # The calculated UTM northing of the pixel on the map.
16
+ #
17
+ # @return [Float]
18
+ def y_projection(x_pixel, y_pixel)
19
+ return nil if null?
20
+
21
+ apply_geo_transform(x_pixel, y_pixel)[:y_location]
22
+ end
23
+
24
+ # The algorithm per http://www.gdal.org/gdal_datamodel.html.
25
+ def pixel_to_world(pixel, line)
26
+ x_geo = x_origin + (pixel * pixel_width) + (line * x_rotation)
27
+ y_geo = y_origin + (pixel * pixel_height) + (line * y_rotation)
28
+
29
+ { longitude: y_geo, latitude: x_geo }
30
+ end
31
+
32
+ # Adapted from "Advanced Geospatial Python Modeling". Calculates the
33
+ # pixel location of a geospatial coordinate.
34
+ #
35
+ # @param lon [Fixnum]
36
+ # @param lat [Fixnum]
37
+ # @param value_type [Symbol] Data type to return: :float or :integer.
38
+ # @return [Hash<x, y>] [pixel, line]
39
+ def world_to_pixel(lon, lat, value_type=:float)
40
+ pixel = (lon - x_origin) / pixel_width
41
+ line = (y_origin - lat) / pixel_height
42
+
43
+ case value_type
44
+ when :float
45
+ { x: pixel.to_f, y: line.to_f }
46
+ when :integer
47
+ { x: pixel.to_i, y: line.to_i }
48
+ else
49
+ { x: pixel, y: line }
50
+ end
51
+ end
52
+
53
+ # All attributes as an Array, in the order:
54
+ # * x_origin
55
+ # * pixel_width
56
+ # * x_rotation
57
+ # * y_origin
58
+ # * y_rotation
59
+ # * pixel_height
60
+ #
61
+ # @return [Array]
62
+ def to_a
63
+ [
64
+ x_origin,
65
+ pixel_width,
66
+ x_rotation,
67
+ y_origin,
68
+ y_rotation,
69
+ pixel_height
70
+ ]
71
+ end
72
+
73
+ # @return [Hash]
74
+ def as_json
75
+ {
76
+ x_origin: x_origin,
77
+ x_rotation: x_rotation,
78
+ pixel_width: pixel_width,
79
+ y_origin: y_origin,
80
+ y_rotation: y_rotation,
81
+ pixel_height: pixel_height
82
+ }
83
+ end
84
+
85
+ # @return [String]
86
+ def to_json
87
+ as_json.to_json
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,7 @@
1
+ require 'log_switch'
2
+
3
+ module GDAL
4
+ module Logger
5
+ include LogSwitch
6
+ end
7
+ end
@@ -3,19 +3,14 @@ require_relative '../ffi/gdal'
3
3
 
4
4
  module GDAL
5
5
  module MajorObject
6
- include FFI::GDAL
7
-
8
6
  # @return [Array<String>]
9
7
  def metadata_domain_list
10
- unless defined? FFI::GDAL::GDALGetMetadataDomainList
8
+ unless defined? FFI::GDAL.GDALGetMetadataDomainList
11
9
  warn "GDALGetMetadataDomainList is't defined. GDAL::MajorObject#metadata_domain_list disabled."
12
10
  return []
13
11
  end
14
12
 
15
- # I don't quite get it, but if #GDALGetMetadataDomainList isn't called
16
- # twice, the last domain in the list sometimes doesn't get read.
17
- GDALGetMetadataDomainList(c_pointer)
18
- list_pointer = GDALGetMetadataDomainList(c_pointer)
13
+ list_pointer = FFI::GDAL.GDALGetMetadataDomainList(c_pointer)
19
14
  return [] if list_pointer.null?
20
15
 
21
16
  strings = list_pointer.get_array_of_string(0)
@@ -25,8 +20,8 @@ module GDAL
25
20
 
26
21
  # @param domain [String] Name of the domain to get metadata for.
27
22
  # @return [Hash]
28
- def metadata_for_domain(domain='')
29
- m = GDALGetMetadata(c_pointer, domain)
23
+ def metadata(domain='')
24
+ m = FFI::GDAL.GDALGetMetadata(c_pointer, domain)
30
25
  return {} if m.null?
31
26
 
32
27
  data_array = m.get_array_of_string(0)
@@ -46,27 +41,33 @@ module GDAL
46
41
  # @param domain [String]
47
42
  # @return [String]
48
43
  def metadata_item(name, domain='')
49
- GDALGetMetadataItem(c_pointer, name, domain)
44
+ FFI::GDAL.GDALGetMetadataItem(c_pointer, name, domain)
45
+ end
46
+
47
+ def set_metadata_item(name, value, domain='')
48
+ cpl_err = FFI::GDAL.GDALSetMetadataItem(c_pointer, name, value.to_s, domain)
49
+
50
+ cpl_err.to_bool
50
51
  end
51
52
 
52
53
  # @return [Hash{domain => Array<String>}]
53
54
  def all_metadata
54
55
  sub_metadata = metadata_domain_list.each_with_object({}) do |subdomain, obj|
55
- metadata_array = metadata_for_domain(subdomain)
56
+ metadata_array = metadata(subdomain)
56
57
  obj[subdomain] = metadata_array
57
58
  end
58
59
 
59
- { DEFAULT: metadata_for_domain }.merge(sub_metadata)
60
+ { DEFAULT: metadata }.merge(sub_metadata)
60
61
  end
61
62
 
62
63
  # @return [String]
63
64
  def description
64
- GDALGetDescription(c_pointer)
65
+ FFI::GDAL.GDALGetDescription(c_pointer)
65
66
  end
66
67
 
67
68
  # @param new_description [String]
68
69
  def description=(new_description)
69
- GDALSetDescription(c_pointer, new_description.to_s)
70
+ FFI::GDAL.GDALSetDescription(c_pointer, new_description.to_s)
70
71
  end
71
72
 
72
73
  def null?
@@ -0,0 +1,49 @@
1
+ require 'ffi'
2
+
3
+
4
+ module GDAL
5
+ # A wrapper for the way GDAL does key/value pair options for methods.
6
+ class Options < Hash
7
+ # Shortcut for if you just want to build the options and get the pointer to
8
+ # them.
9
+ #
10
+ # @param hash [Hash]
11
+ # @return [FFI::MemoryPointer, nil]
12
+ def self.pointer(hash)
13
+ hash.empty? ? nil : new(hash).c_pointer
14
+ end
15
+
16
+ def initialize(hash={})
17
+ super()
18
+ capitalize_keys!(hash)
19
+ end
20
+
21
+ # @return [FFI::MemoryPointer] The double-char pointer that contains the
22
+ # options for GDAL to use.
23
+ def c_pointer
24
+ options_ptr = FFI::MemoryPointer.new(:pointer, self.size)
25
+
26
+ self.each do |key, value|
27
+ options_ptr = FFI::GDAL.CSLSetNameValue(options_ptr, key, value)
28
+ end
29
+
30
+ options_ptr
31
+ end
32
+
33
+ # def to_s
34
+ # options_ptr = to_gdal
35
+ # options_array = options_ptr.read_array_of_pointer(self.size)
36
+ #
37
+ # 0.upto(self.size).map do |i|
38
+ # options_array[i].first.read_string
39
+ # end
40
+ # end
41
+ private
42
+
43
+ def capitalize_keys!(hash)
44
+ hash.each_with_object(self) do |(key, value), obj|
45
+ obj[key.to_s.upcase] = value
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,185 @@
1
+ require_relative '../ffi/gdal'
2
+ require_relative 'raster_attribute_table_extensions'
3
+
4
+
5
+ module GDAL
6
+ class RasterAttributeTable
7
+ include RasterAttributeTableExtensions
8
+
9
+ # @return [GDAL::RasterAttributeTable]
10
+ def self.create
11
+ raster_attribute_table_ptr = FFI::GDAL.GDALCreateRasterAttributeTable
12
+
13
+ new(raster_attribute_table_ptr)
14
+ end
15
+
16
+ # Create an object from a ColorTable.
17
+ #
18
+ # @param color_table [GDAL::ColorTable, FFI::Pointer]
19
+ # @return [GDAL::RasterAttributeTable]
20
+ def self.from_color_table(color_table)
21
+ color_table_ptr = GDAL._pointer(GDAL::ColorTable, color_table)
22
+ rat_ptr = FFI::GDAL.GDALCreateRasterAttributeTable
23
+ cpl_err = FFI::GDAL.GDALRATInitializeFromColorTable(rat_ptr, color_table_ptr)
24
+ cpl_err.to_bool
25
+
26
+ new(rat_ptr)
27
+ end
28
+
29
+ # @param raster_attribute_table [GDAL::RasterAttributeTable, FFI::Pointer]
30
+ def initialize(raster_attribute_table=nil)
31
+ @rat_pointer = GDAL._pointer(GDAL::RasterAttributeTable, raster_attribute_table)
32
+ end
33
+
34
+ def destroy!
35
+ FFI::GDAL.GDALDestroyRasterAttributeTable(@rat_pointer)
36
+ end
37
+
38
+ def c_pointer
39
+ @rat_pointer
40
+ end
41
+
42
+ # Clone using the C API.
43
+ #
44
+ # @return [GDAL::RasterAttributeTable]
45
+ def clone
46
+ rat_ptr = FFI::GDAL.GDALRATClone(@rat_pointer)
47
+ return nil if rat_ptr.null?
48
+
49
+ self.class.new(rat_ptr)
50
+ end
51
+
52
+ # +true+ if the changes made to this RAT have been written to the associated
53
+ # dataset.
54
+ #
55
+ # @return [Boolean]
56
+ def changes_written_to_file?
57
+ FFI::GDAL.GDALRATChangesAreWrittenToFile(@rat_pointer)
58
+ end
59
+
60
+ # @return [Fixnum]
61
+ def column_count
62
+ FFI::GDAL.GDALRATGetColumnCount(@rat_pointer)
63
+ end
64
+
65
+ # @param index [Fixnum] The column number.
66
+ # @return [String]
67
+ def column_name(index)
68
+ FFI::GDAL.GDALRATGetNameOfCol(@rat_pointer, index)
69
+ end
70
+
71
+ # @param index [Fixnum] The column number.
72
+ # @return [GDALRATFieldUsage]
73
+ def column_usage(index)
74
+ FFI::GDAL.GDALRATGetUsageOfCol(@rat_pointer, index)
75
+ end
76
+
77
+ # @param index [Fixnum] The column number.
78
+ # @return [GDALRATFieldType]
79
+ def column_type(index)
80
+ FFI::GDAL.GDALRATGetTypeOfCol(@rat_pointer, index)
81
+ end
82
+
83
+ # @param field_usage [GDALRATFieldUsage]
84
+ # @return [Fixnum] The column number.
85
+ def column_of_usage(field_usage)
86
+ FFI::GDAL.GDALRATGetColOfUsage(@rat_pointer, field_usage)
87
+ end
88
+
89
+ # @param name [String]
90
+ # @param type [FFI::GDALRATFieldType]
91
+ # @param usage [FFI::GDALRATFieldUsage]
92
+ # @return [Boolean]
93
+ def create_column(name, type, usage)
94
+ cpl_err = FFI::GDAL.GDALRATCreateColumn(@rat_pointer, name, type, usage)
95
+
96
+ cpl_err.to_bool
97
+ end
98
+
99
+ # @return [Fixnum] The number of rows.
100
+ def row_count
101
+ FFI::GDAL.GDALRATGetRowCount(@rat_pointer)
102
+ end
103
+
104
+ # @return [Fixnum] The number of rows.
105
+ def row_count=(count)
106
+ FFI::GDAL.GDALRATSetRowCount(@rat_pointer, count)
107
+ end
108
+
109
+ # Get the row for a pixel value.
110
+ #
111
+ # @param value [Float]
112
+ # @return [Fixnum]
113
+ def row_of_value(value)
114
+ FFI::GDAL.GDALRATGetRowOfValue(@rat_pointer, value)
115
+ end
116
+
117
+ # @param row [Fixnum]
118
+ # @param field [Fixnum]
119
+ # @return [String]
120
+ def value_to_s(row, field)
121
+ FFI::GDAL.GDALRATGetValueAsString(@rat_pointer, row, field)
122
+ end
123
+
124
+ # @param row [Fixnum]
125
+ # @param field [Fixnum]
126
+ # @return [Fixnum]
127
+ def value_to_i(row, field)
128
+ FFI::GDAL.GDALRATGetValueAsInt(@rat_pointer, row, field)
129
+ end
130
+
131
+ # @param row [Fixnum]
132
+ # @param field [Fixnum]
133
+ # @return [Float]
134
+ def value_to_f(row, field)
135
+ FFI::GDAL.GDALRATGetValueAsDouble(@rat_pointer, row, field)
136
+ end
137
+
138
+ # @param row [Fixnum]
139
+ # @param field [Fixnum]
140
+ # @param value [String, Float, Fixnum]
141
+ def add_value(row, field, value)
142
+ case value.class.name
143
+ when 'String'
144
+ FFI::GDAL.GDALRATSetValueAsString(@rat_pointer, row, field, value)
145
+ when 'Float'
146
+ FFI::GDAL.GDALRATSetValueAsDouble(@rat_pointer, row, field, value)
147
+ when 'Fixnum'
148
+ FFI::GDAL.GDALRATSetValueAsInt(@rat_pointer, row, field, value)
149
+ else
150
+ raise "Unknown value type for value '#{value}'"
151
+ end
152
+ end
153
+
154
+ # @return [Hash{row_0_minimum => Float, bin_size => Float}]
155
+ def linear_binning
156
+ row_0_min_ptr = FFI::MemoryPointer.new(:double)
157
+ bin_size_ptr = FFI::MemoryPointer.new(:double)
158
+ FFI::GDAL.GDALRATGetLinearBinning(@rat_pointer, row_0_min_ptr, bin_size_ptr)
159
+
160
+ {
161
+ row_0_minimum: row_0_min_ptr.read_double,
162
+ bin_size: bin_size_ptr.read_double
163
+ }
164
+ end
165
+
166
+ # @param entry_count [Fixnum] The number of entries to produce. The default
167
+ # will try to auto-determine the number.
168
+ # @return [GDAL::ColorTable]
169
+ def to_color_table(entry_count = -1)
170
+ color_table_pointer = FFI::GDAL.GDALRATTranslateToColorTable(@rat_pointer, entry_count)
171
+
172
+ GDAL::ColorTable.new(color_table_pointer)
173
+ end
174
+
175
+ # @param file_path [String]
176
+ def dump_readable(file_path=nil)
177
+ file = if file_path
178
+ File.open(file_path, 'r')
179
+ else
180
+ file_path
181
+ end
182
+ FFI::GDAL.GDALRATDumpReadable(@rat_pointer, file)
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,40 @@
1
+ require 'json'
2
+
3
+ module GDAL
4
+ module RasterAttributeTableExtensions
5
+
6
+ # Get +column_name+, +column_usage+, +column_type+ as a Hash.
7
+ #
8
+ # @param index [Fixnum]
9
+ # @return [Hash]
10
+ def column(index)
11
+ {
12
+ name: column_name(index),
13
+ usage: column_usage(index),
14
+ type: column_type(index)
15
+ }
16
+ end
17
+
18
+ # @return [Array<Hash>]
19
+ def columns
20
+ 0.upto(column_count - 1).map do |i|
21
+ column(i)
22
+ end
23
+ end
24
+
25
+ # @return [Hash]
26
+ def as_json
27
+ {
28
+ column_count: column_count,
29
+ columns: columns,
30
+ linear_binning: linear_binning,
31
+ row_count: row_count
32
+ }
33
+ end
34
+
35
+ # @return [String]
36
+ def to_json
37
+ as_json.to_json
38
+ end
39
+ end
40
+ end