ffi-gdal 1.0.2 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (191) hide show
  1. checksums.yaml +4 -4
  2. data/.prettierrc.yml +4 -0
  3. data/.rubocop.yml +9 -5
  4. data/.rubocop_todo.yml +5 -11
  5. data/.solargraph.yml +13 -0
  6. data/Changelog-0.x.md +229 -174
  7. data/Changelog.md +15 -5
  8. data/Dockerfile.gdal2 +1 -1
  9. data/Gemfile +12 -2
  10. data/README.md +13 -10
  11. data/Rakefile +6 -6
  12. data/bin/bundle +12 -12
  13. data/bin/rake +6 -6
  14. data/bin/rspec +6 -6
  15. data/bin/rubocop +6 -6
  16. data/examples/extract_and_colorize.rb +15 -15
  17. data/examples/geometries.rb +12 -12
  18. data/examples/gridding.rb +17 -17
  19. data/examples/ogr_layer_to_layer.rb +3 -3
  20. data/examples/raster_erasing.rb +9 -9
  21. data/examples/remove_small_polygons.rb +11 -11
  22. data/examples/testing_gdal.rb +20 -20
  23. data/examples/warping.rb +13 -13
  24. data/ffi-gdal.gemspec +15 -26
  25. data/lib/ext/ffi_library_function_checks.rb +3 -3
  26. data/lib/ext/narray_ext.rb +1 -1
  27. data/lib/ext/to_bool.rb +2 -2
  28. data/lib/ffi/cpl/conv.rb +2 -2
  29. data/lib/ffi/cpl/error.rb +1 -1
  30. data/lib/ffi/cpl/hash_set.rb +2 -2
  31. data/lib/ffi/cpl/http.rb +3 -3
  32. data/lib/ffi/cpl/http_result.rb +2 -2
  33. data/lib/ffi/cpl/list.rb +1 -1
  34. data/lib/ffi/cpl/mime_part.rb +1 -1
  35. data/lib/ffi/cpl/minixml.rb +2 -2
  36. data/lib/ffi/cpl/port.rb +1 -1
  37. data/lib/ffi/cpl/progress.rb +2 -2
  38. data/lib/ffi/cpl/quad_tree.rb +3 -3
  39. data/lib/ffi/cpl/rect_obj.rb +1 -1
  40. data/lib/ffi/cpl/string.rb +1 -1
  41. data/lib/ffi/cpl/vsi.rb +2 -2
  42. data/lib/ffi/cpl/xml_node.rb +1 -1
  43. data/lib/ffi/cpl.rb +11 -11
  44. data/lib/ffi/extensions/gdal/extensions/all.rb +2 -2
  45. data/lib/ffi/extensions/gdal/extensions.rb +2 -2
  46. data/lib/ffi/extensions/rttopo/gbox.rb +1 -1
  47. data/lib/ffi/extensions/rttopo/geom.rb +2 -2
  48. data/lib/ffi/extensions/rttopo.rb +3 -3
  49. data/lib/ffi/gdal/alg.rb +2 -2
  50. data/lib/ffi/gdal/color_entry.rb +1 -1
  51. data/lib/ffi/gdal/gcp.rb +1 -1
  52. data/lib/ffi/gdal/gdal.rb +3 -3
  53. data/lib/ffi/gdal/grid.rb +2 -2
  54. data/lib/ffi/gdal/grid_data_metrics_options.rb +1 -1
  55. data/lib/ffi/gdal/grid_inverse_distance_to_a_power_options.rb +1 -1
  56. data/lib/ffi/gdal/grid_moving_average_options.rb +1 -1
  57. data/lib/ffi/gdal/grid_nearest_neighbor_options.rb +1 -1
  58. data/lib/ffi/gdal/matching.rb +2 -2
  59. data/lib/ffi/gdal/rpc_info.rb +1 -1
  60. data/lib/ffi/gdal/transformer_info.rb +1 -1
  61. data/lib/ffi/gdal/version.rb +1 -1
  62. data/lib/ffi/gdal/vrt.rb +2 -2
  63. data/lib/ffi/gdal/warp_options.rb +1 -1
  64. data/lib/ffi/gdal/warper.rb +2 -2
  65. data/lib/ffi/gdal.rb +22 -22
  66. data/lib/ffi/ogr/api.rb +3 -3
  67. data/lib/ffi/ogr/contour_writer_info.rb +1 -1
  68. data/lib/ffi/ogr/core.rb +9 -9
  69. data/lib/ffi/ogr/envelope.rb +1 -1
  70. data/lib/ffi/ogr/envelope_3d.rb +1 -1
  71. data/lib/ffi/ogr/featurestyle.rb +1 -1
  72. data/lib/ffi/ogr/field.rb +1 -1
  73. data/lib/ffi/ogr/geocoding.rb +2 -2
  74. data/lib/ffi/ogr/srs_api.rb +63 -63
  75. data/lib/ffi/ogr/style_param.rb +2 -2
  76. data/lib/ffi/ogr/style_value.rb +1 -1
  77. data/lib/ffi/ogr.rb +11 -11
  78. data/lib/ffi-gdal.rb +8 -8
  79. data/lib/gdal/color_table.rb +6 -6
  80. data/lib/gdal/dataset/accessors.rb +101 -0
  81. data/lib/gdal/{dataset_mixins → dataset}/algorithm_methods.rb +1 -1
  82. data/lib/gdal/dataset/class_methods.rb +69 -0
  83. data/lib/gdal/dataset/internal_functions.rb +22 -0
  84. data/lib/gdal/{dataset_mixins → dataset}/matching.rb +1 -1
  85. data/lib/gdal/dataset/raster_band_methods.rb +181 -0
  86. data/lib/gdal/{dataset_mixins → dataset}/warp_methods.rb +1 -1
  87. data/lib/gdal/dataset.rb +21 -359
  88. data/lib/gdal/driver.rb +10 -10
  89. data/lib/gdal/environment_methods.rb +1 -1
  90. data/lib/gdal/extensions/all.rb +1 -1
  91. data/lib/gdal/extensions/color_entry/extensions.rb +2 -2
  92. data/lib/gdal/extensions/color_table/extensions.rb +2 -2
  93. data/lib/gdal/extensions/dataset/extensions.rb +11 -11
  94. data/lib/gdal/extensions/driver/extensions.rb +7 -7
  95. data/lib/gdal/extensions/geo_transform/extensions.rb +2 -2
  96. data/lib/gdal/extensions/gridder.rb +8 -8
  97. data/lib/gdal/extensions/gridder_options.rb +6 -6
  98. data/lib/gdal/extensions/raster_attribute_table/extensions.rb +1 -1
  99. data/lib/gdal/extensions/raster_band/algorithm_extensions.rb +4 -4
  100. data/lib/gdal/extensions/raster_band/coloring_extensions.rb +1 -1
  101. data/lib/gdal/extensions/raster_band/extensions.rb +3 -3
  102. data/lib/gdal/extensions/raster_band/io_extensions.rb +4 -4
  103. data/lib/gdal/extensions/raster_band_classifier.rb +3 -3
  104. data/lib/gdal/geo_transform.rb +1 -1
  105. data/lib/gdal/grid.rb +6 -6
  106. data/lib/gdal/grid_algorithms/metric_average_distance.rb +1 -1
  107. data/lib/gdal/grid_algorithms/metric_average_distance_pts.rb +1 -1
  108. data/lib/gdal/grid_algorithms/metric_count.rb +1 -1
  109. data/lib/gdal/grid_algorithms/metric_maximum.rb +1 -1
  110. data/lib/gdal/grid_algorithms/metric_minimum.rb +1 -1
  111. data/lib/gdal/grid_algorithms/metric_range.rb +1 -1
  112. data/lib/gdal/grid_algorithms.rb +9 -9
  113. data/lib/gdal/internal_helpers.rb +3 -3
  114. data/lib/gdal/logger.rb +1 -1
  115. data/lib/gdal/major_object.rb +6 -6
  116. data/lib/gdal/options.rb +2 -2
  117. data/lib/gdal/raster_attribute_table.rb +5 -5
  118. data/lib/gdal/raster_band.rb +24 -24
  119. data/lib/gdal/rpc_info.rb +2 -2
  120. data/lib/gdal/transformer.rb +1 -1
  121. data/lib/gdal/transformers/general_image_projection_transformer.rb +1 -1
  122. data/lib/gdal/transformers/general_image_projection_transformer2.rb +1 -1
  123. data/lib/gdal/transformers/general_image_projection_transformer3.rb +1 -1
  124. data/lib/gdal/version_info.rb +9 -9
  125. data/lib/gdal/virtual_dataset.rb +4 -4
  126. data/lib/gdal/warp_operation.rb +2 -2
  127. data/lib/gdal/warp_options.rb +2 -2
  128. data/lib/gdal.rb +17 -17
  129. data/lib/ogr/coordinate_transformation.rb +5 -5
  130. data/lib/ogr/data_source.rb +9 -9
  131. data/lib/ogr/driver.rb +9 -9
  132. data/lib/ogr/envelope.rb +1 -1
  133. data/lib/ogr/error_handling.rb +1 -1
  134. data/lib/ogr/extensions/all.rb +1 -1
  135. data/lib/ogr/extensions/data_source/capability_methods.rb +4 -4
  136. data/lib/ogr/extensions/data_source/data_source_extensions.rb +1 -1
  137. data/lib/ogr/extensions/driver/capability_methods.rb +3 -3
  138. data/lib/ogr/extensions/envelope/extensions.rb +1 -1
  139. data/lib/ogr/extensions/feature/extensions.rb +1 -1
  140. data/lib/ogr/extensions/feature_definition/extensions.rb +1 -1
  141. data/lib/ogr/extensions/geometries/point/extensions.rb +1 -1
  142. data/lib/ogr/extensions/geometry/container_mixins.rb +10 -10
  143. data/lib/ogr/extensions/geometry/ewkb_io_extensions.rb +3 -3
  144. data/lib/ogr/extensions/geometry/ewkb_record.rb +4 -4
  145. data/lib/ogr/extensions/geometry/extensions.rb +4 -7
  146. data/lib/ogr/extensions/geometry/rttopo_extensions.rb +2 -2
  147. data/lib/ogr/extensions/geometry/wkb_record.rb +3 -3
  148. data/lib/ogr/extensions/geometry_types/curve/extensions.rb +2 -2
  149. data/lib/ogr/extensions/layer/capability_methods.rb +17 -17
  150. data/lib/ogr/extensions/layer/extensions.rb +1 -1
  151. data/lib/ogr/extensions/spatial_reference/extensions.rb +1 -1
  152. data/lib/ogr/extensions/spatial_reference/initializers.rb +2 -2
  153. data/lib/ogr/extensions/style_table/extensions.rb +1 -1
  154. data/lib/ogr/feature.rb +15 -15
  155. data/lib/ogr/feature_definition.rb +2 -2
  156. data/lib/ogr/field.rb +5 -5
  157. data/lib/ogr/field_definition.rb +1 -1
  158. data/lib/ogr/geocoder.rb +1 -1
  159. data/lib/ogr/geometries/geometry_collection.rb +2 -2
  160. data/lib/ogr/geometries/geometry_collection_25d.rb +1 -1
  161. data/lib/ogr/geometries/line_string.rb +1 -1
  162. data/lib/ogr/geometries/line_string_25d.rb +1 -1
  163. data/lib/ogr/geometries/linear_ring.rb +2 -2
  164. data/lib/ogr/geometries/multi_line_string.rb +2 -2
  165. data/lib/ogr/geometries/multi_line_string_25d.rb +1 -1
  166. data/lib/ogr/geometries/multi_point.rb +1 -1
  167. data/lib/ogr/geometries/multi_point_25d.rb +1 -1
  168. data/lib/ogr/geometries/multi_polygon.rb +2 -2
  169. data/lib/ogr/geometries/multi_polygon_25d.rb +1 -1
  170. data/lib/ogr/geometries/point_25d.rb +1 -1
  171. data/lib/ogr/geometries/polygon.rb +2 -2
  172. data/lib/ogr/geometries/polygon_25d.rb +1 -1
  173. data/lib/ogr/geometry.rb +11 -11
  174. data/lib/ogr/geometry_types/container.rb +1 -1
  175. data/lib/ogr/geometry_types/curve.rb +1 -1
  176. data/lib/ogr/internal_helpers.rb +4 -4
  177. data/lib/ogr/layer.rb +8 -8
  178. data/lib/ogr/layer_mixins/ogr_feature_methods.rb +9 -9
  179. data/lib/ogr/layer_mixins/ogr_field_methods.rb +15 -15
  180. data/lib/ogr/layer_mixins/ogr_sql_methods.rb +2 -2
  181. data/lib/ogr/spatial_reference.rb +19 -19
  182. data/lib/ogr/spatial_reference_mixins/coordinate_system_getter_setters.rb +4 -4
  183. data/lib/ogr/spatial_reference_mixins/exporters.rb +9 -9
  184. data/lib/ogr/spatial_reference_mixins/importers.rb +2 -2
  185. data/lib/ogr/spatial_reference_mixins/morphers.rb +2 -2
  186. data/lib/ogr/spatial_reference_mixins/parameter_getter_setters.rb +1 -1
  187. data/lib/ogr/style_table.rb +3 -3
  188. data/lib/ogr/style_tool.rb +1 -1
  189. data/lib/ogr.rb +33 -33
  190. data/rakelib/docker.rake +2 -2
  191. metadata +11 -145
@@ -0,0 +1,181 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../dataset/internal_functions"
4
+
5
+ module GDAL
6
+ class Dataset
7
+ module RasterBandMethods
8
+ # Lets you pass in :GMF_ symbols that represent mask band flags and bitwise
9
+ # ors them.
10
+ #
11
+ # @param flags [Symbol]
12
+ # @return [Integer]
13
+ def self.parse_mask_flag_symbols(*flags)
14
+ flags.reduce(0) do |result, flag|
15
+ result | case flag
16
+ when :GMF_ALL_VALID then 0x01
17
+ when :GMF_PER_DATASET then 0x02
18
+ when :GMF_PER_ALPHA then 0x04
19
+ when :GMF_NODATA then 0x08
20
+ else 0
21
+ end
22
+ end
23
+ end
24
+
25
+ # @param buffer_data_type [FFI::GDAL::GDAL::DataType]
26
+ # @param x_buffer_size [Integer]
27
+ # @param y_buffer_size [Integer]
28
+ # @return [Integer]
29
+ def self.valid_min_buffer_size(buffer_data_type, x_buffer_size, y_buffer_size)
30
+ data_type_bytes = GDAL::DataType.size(buffer_data_type) / 8
31
+
32
+ data_type_bytes * x_buffer_size * y_buffer_size
33
+ end
34
+
35
+ # @return [Integer, nil]
36
+ def raster_x_size
37
+ return nil if null?
38
+
39
+ FFI::GDAL::GDAL.GDALGetRasterXSize(@c_pointer)
40
+ end
41
+
42
+ # @return [Integer, nil]
43
+ def raster_y_size
44
+ return nil if null?
45
+
46
+ FFI::GDAL::GDAL.GDALGetRasterYSize(@c_pointer)
47
+ end
48
+
49
+ # @return [Integer]
50
+ def raster_count
51
+ return 0 if null?
52
+
53
+ FFI::GDAL::GDAL.GDALGetRasterCount(@c_pointer)
54
+ end
55
+
56
+ # @param raster_index [Integer]
57
+ # @return [GDAL::RasterBand]
58
+ def raster_band(raster_index)
59
+ if raster_index > raster_count
60
+ raise GDAL::InvalidRasterBand, "Invalid raster band number '#{raster_index}'. Must be <= #{raster_count}"
61
+ end
62
+
63
+ raster_band_ptr = FFI::GDAL::GDAL.GDALGetRasterBand(@c_pointer, raster_index)
64
+ raster_band_ptr.autorelease = false
65
+
66
+ GDAL::RasterBand.new(raster_band_ptr, self)
67
+ end
68
+
69
+ # @param type [FFI::GDAL::GDAL::DataType]
70
+ # @param options [Hash]
71
+ # @raise [GDAL::Error]
72
+ # @return [GDAL::RasterBand, nil]
73
+ def add_band(type, **options)
74
+ options_ptr = GDAL::Options.pointer(options)
75
+
76
+ GDAL::CPLErrorHandler.manually_handle("Unable to add band") do
77
+ FFI::GDAL::GDAL.GDALAddBand(@c_pointer, type, options_ptr)
78
+ end
79
+
80
+ raster_band(raster_count)
81
+ end
82
+
83
+ # Adds a mask band to the dataset.
84
+ #
85
+ # @param flags [Array<Symbol>, Symbol] Any of the :GMF symbols.
86
+ # @raise [GDAL::Error]
87
+ def create_mask_band(*flags)
88
+ flag_value = RasterBandMethods.parse_mask_flag_symbols(flags)
89
+
90
+ GDAL::CPLErrorHandler.manually_handle("Unable to create Dataset mask band") do
91
+ FFI::GDAL::GDAL.GDALCreateDatasetMaskBand(@c_pointer, flag_value)
92
+ end
93
+ end
94
+
95
+ # @param access_flag [String] 'r' or 'w'.
96
+ # @param buffer [FFI::MemoryPointer] The pointer to the data to read/write
97
+ # to the dataset.
98
+ # @param x_size [Integer] If not given, uses {{#raster_x_size}}.
99
+ # @param y_size [Integer] If not given, uses {{#raster_y_size}}.
100
+ # @param x_offset [Integer] The pixel number in the line to start operating
101
+ # on. Note that when using this, +x_size+ - +x_offset+ should be >= 0,
102
+ # otherwise this means you're telling the method to read past the end of
103
+ # the line. Defaults to 0.
104
+ # @param y_offset [Integer] The line number to start operating on. Note that
105
+ # when using this, +y_size+ - +y_offset+ should be >= 0, otherwise this
106
+ # means you're telling the method to read more lines than the raster has.
107
+ # Defaults to 0.
108
+ # @param buffer_x_size [Integer] The width of the buffer image in which to
109
+ # read/write the raster data into/from. Typically this should be the same
110
+ # size as +x_size+; if it's different, GDAL will resample accordingly.
111
+ # @param buffer_y_size [Integer] The height of the buffer image in which to
112
+ # read/write the raster data into/from. Typically this should be the same
113
+ # size as +y_size+; if it's different, GDAL will resample accordingly.
114
+ # @param buffer_data_type [FFI::GDAL::GDAL::DataType] Can be used to convert the
115
+ # data to a different type. You must account for this when reading/writing
116
+ # to/from your buffer--your buffer size must be +buffer_x_size+ *
117
+ # +buffer_y_size+.
118
+ # @param band_numbers [Array<Integer>] The numbers of the bands to do IO on.
119
+ # Pass +nil+ defaults to choose the first band.
120
+ # @param pixel_space [Integer] The byte offset from the start of one pixel
121
+ # value in the buffer to the start of the next pixel value within a line.
122
+ # If defaulted (0), the size of +buffer_data_type+ is used.
123
+ # @param line_space [Integer] The byte offset from the start of one line in
124
+ # the buffer to the start of the next. If defaulted (0), the size of
125
+ # +buffer_data_type+ * +buffer_x_size* is used.
126
+ # @param band_space [Integer] The byte offset from the start of one band's
127
+ # data to the start of the next. If defaulted (0), the size of
128
+ # +line_space+ * +buffer_y_size* is used.
129
+ # @return [FFI::MemoryPointer] The buffer that was passed in.
130
+ # @raise [GDAL::Error] On failure.
131
+ # rubocop:disable Metrics/ParameterLists
132
+ def raster_io(access_flag, buffer = nil,
133
+ x_size: nil, y_size: nil, x_offset: 0, y_offset: 0,
134
+ buffer_x_size: nil, buffer_y_size: nil, buffer_data_type: nil,
135
+ band_numbers: nil,
136
+ pixel_space: 0, line_space: 0, band_space: 0)
137
+ x_size ||= raster_x_size
138
+ y_size ||= raster_y_size
139
+ buffer_x_size ||= x_size
140
+ buffer_y_size ||= y_size
141
+ buffer_data_type ||= raster_band(1).data_type
142
+
143
+ band_numbers_ptr, band_count = InternalFunctions.band_numbers_args(band_numbers)
144
+ band_count = raster_count if band_count.zero?
145
+
146
+ buffer ||= GDAL._pointer_from_data_type(buffer_data_type, buffer_x_size * buffer_y_size * band_count)
147
+
148
+ gdal_access_flag = GDAL._gdal_access_flag(access_flag)
149
+
150
+ min_buffer_size = RasterBandMethods.valid_min_buffer_size(buffer_data_type, buffer_x_size, buffer_y_size)
151
+
152
+ unless buffer.size >= min_buffer_size
153
+ raise GDAL::BufferTooSmall, "Buffer size (#{buffer.size}) too small (#{min_buffer_size})"
154
+ end
155
+
156
+ GDAL::CPLErrorHandler.manually_handle("Unable to perform raster band IO") do
157
+ FFI::GDAL::GDAL::GDALDatasetRasterIO(
158
+ @c_pointer, # hDS
159
+ gdal_access_flag, # eRWFlag
160
+ x_offset, # nXOff
161
+ y_offset, # nYOff
162
+ x_size, # nXSize
163
+ y_size, # nYSize
164
+ buffer, # pData
165
+ buffer_x_size, # nBufXSize
166
+ buffer_y_size, # nBufYSize
167
+ buffer_data_type, # eBufType
168
+ band_count, # nBandCount
169
+ band_numbers_ptr, # panBandMap (WTH is this?)
170
+ pixel_space, # nPixelSpace
171
+ line_space, # nLineSpace
172
+ band_space # nBandSpace
173
+ )
174
+ end
175
+
176
+ buffer
177
+ end
178
+ # rubocop:enable Metrics/ParameterLists
179
+ end
180
+ end
181
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GDAL
4
- module DatasetMixins
4
+ class Dataset
5
5
  # Methods used for warping; most taken from gdalwarper.h.
6
6
  module WarpMethods
7
7
  # @param destination_dataset [GDAL::Dataset]
data/lib/gdal/dataset.rb CHANGED
@@ -1,90 +1,36 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../gdal'
4
- require_relative '../ogr'
5
- require_relative 'major_object'
6
- require_relative 'dataset_mixins/matching'
7
- require_relative 'dataset_mixins/algorithm_methods'
8
- require_relative 'dataset_mixins/warp_methods'
3
+ require_relative "../gdal"
4
+ require_relative "../ogr"
5
+ require_relative "major_object"
6
+ require_relative "dataset/internal_functions"
7
+ require_relative "dataset/class_methods"
8
+ require_relative "dataset/accessors"
9
+ require_relative "dataset/raster_band_methods"
10
+ require_relative "dataset/matching"
11
+ require_relative "dataset/algorithm_methods"
12
+ require_relative "dataset/warp_methods"
9
13
 
10
14
  module GDAL
11
15
  # A set of associated raster bands and info common to them all. It's also
12
16
  # responsible for the georeferencing transform and coordinate system
13
17
  # definition of all bands.
14
18
  class Dataset
19
+ extend Dataset::ClassMethods
20
+
15
21
  include MajorObject
16
- include DatasetMixins::Matching
17
- include DatasetMixins::AlgorithmMethods
18
- include DatasetMixins::WarpMethods
22
+ include Dataset::Accessors
23
+ include Dataset::RasterBandMethods
24
+ include Dataset::Matching
25
+ include Dataset::AlgorithmMethods
26
+ include Dataset::WarpMethods
19
27
  include GDAL::Logger
20
28
 
21
29
  ACCESS_FLAGS = {
22
- 'r' => :GA_ReadOnly,
23
- 'w' => :GA_Update
30
+ "r" => :GA_ReadOnly,
31
+ "w" => :GA_Update
24
32
  }.freeze
25
33
 
26
- # @param path [String] Path to the file that contains the dataset. Can be
27
- # a local file or a URL.
28
- # @param access_flag [String] 'r' or 'w'.
29
- # @param shared [Boolean] Whether or not to open using GDALOpenShared
30
- # vs GDALOpen. Defaults to +true+.
31
- def self.open(path, access_flag, shared: true)
32
- ds = new(path, access_flag, shared_open: shared)
33
-
34
- if block_given?
35
- result = yield ds
36
- ds.close
37
- result
38
- else
39
- ds
40
- end
41
- end
42
-
43
- # Copy all dataset raster data.
44
- #
45
- # This function copies the complete raster contents of one dataset to
46
- # another similarly configured dataset. The source and destination dataset
47
- # must have the same number of bands, and the same width and height. The
48
- # bands do not have to have the same data type.
49
- #
50
- # This function is primarily intended to support implementation of driver
51
- # specific CreateCopy() functions. It implements efficient copying, in
52
- # particular "chunking" the copy in substantial blocks and, if appropriate,
53
- # performing the transfer in a pixel interleaved fashion.
54
- #
55
- # @param source [GDAL::Dataset, FFI::Pointer]
56
- # @param destination [GDAL::Dataset, FFI::Pointer]
57
- # @param options [Hash]
58
- # @option options interleave: 'pixel'
59
- # @option options compressed: true
60
- # @option options skip_holes: true
61
- # @param progress_function [Proc]
62
- # @raise [GDAL::Error]
63
- def self.copy_whole_raster(source, destination, options = {}, progress_function = nil)
64
- source_ptr = GDAL._pointer(GDAL::Dataset, source, autorelease: false)
65
- dest_ptr = GDAL._pointer(GDAL::Dataset, destination, autorelease: false)
66
- options_ptr = GDAL::Options.pointer(options)
67
-
68
- GDAL::CPLErrorHandler.manually_handle('Unable to copy whole raster') do
69
- FFI::GDAL::GDAL.GDALDatasetCopyWholeRaster(source_ptr, dest_ptr, options_ptr, progress_function, nil)
70
- end
71
- end
72
-
73
- # @param dataset [GDAL::Dataset]
74
- # @return [FFI::AutoPointer]
75
- def self.new_pointer(dataset, warn_on_nil: true)
76
- ptr = GDAL._pointer(GDAL::Dataset, dataset, warn_on_nil: warn_on_nil, autorelease: false)
77
-
78
- FFI::AutoPointer.new(ptr, Dataset.method(:release))
79
- end
80
-
81
- # @param pointer [FFI::Pointer]
82
- def self.release(pointer)
83
- return unless pointer && !pointer.null?
84
-
85
- FFI::GDAL::GDAL.GDALClose(pointer)
86
- end
87
-
88
34
  #---------------------------------------------------------------------------
89
35
  # Instance methods
90
36
  #---------------------------------------------------------------------------
@@ -115,7 +61,6 @@ module GDAL
115
61
 
116
62
  @geo_transform = nil
117
63
  @spatial_reference = nil
118
- @raster_bands = Array.new(raster_count)
119
64
  end
120
65
 
121
66
  # Close the dataset.
@@ -132,14 +77,6 @@ module GDAL
132
77
  FFI::GDAL::GDAL::Access[flag]
133
78
  end
134
79
 
135
- # @return [GDAL::Driver] The driver to be used for working with this
136
- # dataset.
137
- def driver
138
- driver_ptr = FFI::GDAL::GDAL.GDALGetDatasetDriver(@c_pointer)
139
-
140
- Driver.new(driver_ptr)
141
- end
142
-
143
80
  # Fetches all files that form the dataset.
144
81
  # @return [Array<String>]
145
82
  def file_list
@@ -157,141 +94,6 @@ module GDAL
157
94
  FFI::GDAL::GDAL.GDALFlushCache(@c_pointer)
158
95
  end
159
96
 
160
- # @return [Integer]
161
- def raster_x_size
162
- return nil if null?
163
-
164
- FFI::GDAL::GDAL.GDALGetRasterXSize(@c_pointer)
165
- end
166
-
167
- # @return [Integer]
168
- def raster_y_size
169
- return nil if null?
170
-
171
- FFI::GDAL::GDAL.GDALGetRasterYSize(@c_pointer)
172
- end
173
-
174
- # @return [Integer]
175
- def raster_count
176
- return 0 if null?
177
-
178
- FFI::GDAL::GDAL.GDALGetRasterCount(@c_pointer)
179
- end
180
-
181
- # @param raster_index [Integer]
182
- # @return [GDAL::RasterBand]
183
- def raster_band(raster_index)
184
- if raster_index > raster_count
185
- raise GDAL::InvalidRasterBand, "Invalid raster band number '#{raster_index}'. Must be <= #{raster_count}"
186
- end
187
-
188
- raster_band_ptr = FFI::GDAL::GDAL.GDALGetRasterBand(@c_pointer, raster_index)
189
- raster_band_ptr.autorelease = false
190
-
191
- GDAL::RasterBand.new(raster_band_ptr, self)
192
- end
193
-
194
- # @param type [FFI::GDAL::GDAL::DataType]
195
- # @param options [Hash]
196
- # @raise [GDAL::Error]
197
- # @return [GDAL::RasterBand, nil]
198
- def add_band(type, **options)
199
- options_ptr = GDAL::Options.pointer(options)
200
-
201
- GDAL::CPLErrorHandler.manually_handle('Unable to add band') do
202
- FFI::GDAL::GDAL.GDALAddBand(@c_pointer, type, options_ptr)
203
- end
204
-
205
- raster_band(raster_count)
206
- end
207
-
208
- # Adds a mask band to the dataset.
209
- #
210
- # @param flags [Array<Symbol>, Symbol] Any of the :GMF symbols.
211
- # @raise [GDAL::Error]
212
- def create_mask_band(*flags)
213
- flag_value = parse_mask_flag_symbols(flags)
214
-
215
- GDAL::CPLErrorHandler.manually_handle('Unable to create Dataset mask band') do
216
- FFI::GDAL::GDAL.GDALCreateDatasetMaskBand(@c_pointer, flag_value)
217
- end
218
- end
219
-
220
- # @return [String]
221
- def projection
222
- # Returns a pointer to an internal projection reference string. It should
223
- # not be altered, freed or expected to last for long.
224
- proj, ptr = FFI::GDAL::GDAL.GDALGetProjectionRef(@c_pointer)
225
- ptr.autorelease = false
226
-
227
- proj || ''
228
- end
229
-
230
- # @param new_projection [String] Should be in WKT or PROJ.4 format.
231
- # @raise [GDAL::Error]
232
- def projection=(new_projection)
233
- GDAL::CPLErrorHandler.manually_handle('Unable to set projection') do
234
- FFI::GDAL::GDAL.GDALSetProjection(@c_pointer, new_projection.to_s)
235
- end
236
- end
237
-
238
- # @return [GDAL::GeoTransform]
239
- # @raise [GDAL::Error]
240
- def geo_transform
241
- return @geo_transform if @geo_transform
242
-
243
- geo_transform_pointer = GDAL::GeoTransform.new_pointer
244
-
245
- GDAL::CPLErrorHandler.manually_handle('Unable to get geo_transform') do
246
- FFI::GDAL::GDAL.GDALGetGeoTransform(@c_pointer, geo_transform_pointer)
247
- end
248
-
249
- @geo_transform = GeoTransform.new(geo_transform_pointer)
250
- end
251
-
252
- # @param new_transform [GDAL::GeoTransform, FFI::Pointer]
253
- # @return [GDAL::GeoTransform]
254
- # @raise [GDAL::Error]
255
- def geo_transform=(new_transform)
256
- new_pointer = GDAL._pointer(GDAL::GeoTransform, new_transform)
257
-
258
- GDAL::CPLErrorHandler.manually_handle('Unable to set geo_transform') do
259
- FFI::GDAL::GDAL.GDALSetGeoTransform(@c_pointer, new_pointer)
260
- end
261
-
262
- @geo_transform = new_transform.is_a?(FFI::Pointer) ? GeoTransform.new(new_pointer) : new_transform
263
- end
264
-
265
- # @return [Integer]
266
- def gcp_count
267
- return 0 if null?
268
-
269
- FFI::GDAL::GDAL.GDALGetGCPCount(@c_pointer)
270
- end
271
-
272
- # @return [String]
273
- def gcp_projection
274
- return '' if null?
275
-
276
- proj, ptr = FFI::GDAL::GDAL.GDALGetGCPProjection(@c_pointer)
277
- ptr.autorelease = false
278
-
279
- proj
280
- end
281
-
282
- # @return [FFI::GDAL::GCP]
283
- def gcps
284
- return FFI::GDAL::GCP.new if null?
285
-
286
- gcp_array_pointer = FFI::GDAL::GDAL.GDALGetGCPs(@c_pointer)
287
-
288
- if gcp_array_pointer.null?
289
- FFI::GDAL::GCP.new
290
- else
291
- FFI::GDAL::GCP.new(gcp_array_pointer)
292
- end
293
- end
294
-
295
97
  # @param resampling [String, Symbol] One of:
296
98
  # * :nearest - Nearest neighbor resampling
297
99
  # * :gauss - Gaussian kernel resampling
@@ -316,9 +118,9 @@ module GDAL
316
118
 
317
119
  overview_levels_ptr = FFI::MemoryPointer.new(:int, overview_levels.size)
318
120
  overview_levels_ptr.write_array_of_int(overview_levels)
319
- band_numbers_ptr, band_count = band_numbers_args(band_numbers)
121
+ band_numbers_ptr, band_count = InternalFunctions.band_numbers_args(band_numbers)
320
122
 
321
- GDAL::CPLErrorHandler.manually_handle('Unable to build overviews') do
123
+ GDAL::CPLErrorHandler.manually_handle("Unable to build overviews") do
322
124
  FFI::GDAL::GDAL.GDALBuildOverviews(
323
125
  @c_pointer,
324
126
  resampling_string,
@@ -331,145 +133,5 @@ module GDAL
331
133
  )
332
134
  end
333
135
  end
334
-
335
- # @param access_flag [String] 'r' or 'w'.
336
- # @param buffer [FFI::MemoryPointer] The pointer to the data to read/write
337
- # to the dataset.
338
- # @param x_size [Integer] If not given, uses {{#raster_x_size}}.
339
- # @param y_size [Integer] If not given, uses {{#raster_y_size}}.
340
- # @param x_offset [Integer] The pixel number in the line to start operating
341
- # on. Note that when using this, +x_size+ - +x_offset+ should be >= 0,
342
- # otherwise this means you're telling the method to read past the end of
343
- # the line. Defaults to 0.
344
- # @param y_offset [Integer] The line number to start operating on. Note that
345
- # when using this, +y_size+ - +y_offset+ should be >= 0, otherwise this
346
- # means you're telling the method to read more lines than the raster has.
347
- # Defaults to 0.
348
- # @param buffer_x_size [Integer] The width of the buffer image in which to
349
- # read/write the raster data into/from. Typically this should be the same
350
- # size as +x_size+; if it's different, GDAL will resample accordingly.
351
- # @param buffer_y_size [Integer] The height of the buffer image in which to
352
- # read/write the raster data into/from. Typically this should be the same
353
- # size as +y_size+; if it's different, GDAL will resample accordingly.
354
- # @param buffer_data_type [FFI::GDAL::GDAL::DataType] Can be used to convert the
355
- # data to a different type. You must account for this when reading/writing
356
- # to/from your buffer--your buffer size must be +buffer_x_size+ *
357
- # +buffer_y_size+.
358
- # @param band_numbers [Array<Integer>] The numbers of the bands to do IO on.
359
- # Pass +nil+ defaults to choose the first band.
360
- # @param pixel_space [Integer] The byte offset from the start of one pixel
361
- # value in the buffer to the start of the next pixel value within a line.
362
- # If defaulted (0), the size of +buffer_data_type+ is used.
363
- # @param line_space [Integer] The byte offset from the start of one line in
364
- # the buffer to the start of the next. If defaulted (0), the size of
365
- # +buffer_data_type+ * +buffer_x_size* is used.
366
- # @param band_space [Integer] The byte offset from the start of one band's
367
- # data to the start of the next. If defaulted (0), the size of
368
- # +line_space+ * +buffer_y_size* is used.
369
- # @return [FFI::MemoryPointer] The buffer that was passed in.
370
- # @raise [GDAL::Error] On failure.
371
- # rubocop:disable Metrics/ParameterLists
372
- def raster_io(access_flag, buffer = nil,
373
- x_size: nil, y_size: nil, x_offset: 0, y_offset: 0,
374
- buffer_x_size: nil, buffer_y_size: nil, buffer_data_type: nil,
375
- band_numbers: nil,
376
- pixel_space: 0, line_space: 0, band_space: 0)
377
- x_size ||= raster_x_size
378
- y_size ||= raster_y_size
379
- buffer_x_size ||= x_size
380
- buffer_y_size ||= y_size
381
- buffer_data_type ||= raster_band(1).data_type
382
-
383
- band_numbers_ptr, band_count = band_numbers_args(band_numbers)
384
- band_count = raster_count if band_count.zero?
385
-
386
- buffer ||= GDAL._pointer_from_data_type(buffer_data_type, buffer_x_size * buffer_y_size * band_count)
387
-
388
- gdal_access_flag = GDAL._gdal_access_flag(access_flag)
389
-
390
- min_buffer_size = valid_min_buffer_size(buffer_data_type, buffer_x_size, buffer_y_size)
391
-
392
- unless buffer.size >= min_buffer_size
393
- raise GDAL::BufferTooSmall, "Buffer size (#{buffer.size}) too small (#{min_buffer_size})"
394
- end
395
-
396
- GDAL::CPLErrorHandler.manually_handle('Unable to perform raster band IO') do
397
- FFI::GDAL::GDAL::GDALDatasetRasterIO(
398
- @c_pointer, # hDS
399
- gdal_access_flag, # eRWFlag
400
- x_offset, # nXOff
401
- y_offset, # nYOff
402
- x_size, # nXSize
403
- y_size, # nYSize
404
- buffer, # pData
405
- buffer_x_size, # nBufXSize
406
- buffer_y_size, # nBufYSize
407
- buffer_data_type, # eBufType
408
- band_count, # nBandCount
409
- band_numbers_ptr, # panBandMap (WTH is this?)
410
- pixel_space, # nPixelSpace
411
- line_space, # nLineSpace
412
- band_space # nBandSpace
413
- )
414
- end
415
-
416
- buffer
417
- end
418
- # rubocop:enable Metrics/ParameterLists
419
-
420
- # Creates a OGR::SpatialReference object from the dataset's projection.
421
- #
422
- # @return [OGR::SpatialReference]
423
- def spatial_reference
424
- return @spatial_reference if @spatial_reference
425
-
426
- return nil if projection.empty?
427
-
428
- @spatial_reference = OGR::SpatialReference.new(projection)
429
- end
430
-
431
- private
432
-
433
- # Lets you pass in :GMF_ symbols that represent mask band flags and bitwise
434
- # ors them.
435
- #
436
- # @param flags [Symbol]
437
- # @return [Integer]
438
- def parse_mask_flag_symbols(*flags)
439
- flags.reduce(0) do |result, flag|
440
- result | case flag
441
- when :GMF_ALL_VALID then 0x01
442
- when :GMF_PER_DATASET then 0x02
443
- when :GMF_PER_ALPHA then 0x04
444
- when :GMF_NODATA then 0x08
445
- else 0
446
- end
447
- end
448
- end
449
-
450
- # @param buffer_data_type [FFI::GDAL::GDAL::DataType]
451
- # @param x_buffer_size [Integer]
452
- # @param y_buffer_size [Integer]
453
- # @return [Integer]
454
- def valid_min_buffer_size(buffer_data_type, x_buffer_size, y_buffer_size)
455
- data_type_bytes = GDAL::DataType.size(buffer_data_type) / 8
456
-
457
- data_type_bytes * x_buffer_size * y_buffer_size
458
- end
459
-
460
- # Makes a pointer of +band_numbers+.
461
- #
462
- # @param band_numbers [Array<Integer>]
463
- # @return [Array<FFI::MemoryPointer, Integer>]
464
- def band_numbers_args(band_numbers)
465
- band_count = band_numbers&.size || 0
466
- ptr = FFI::MemoryPointer.new(:int, band_count)
467
-
468
- ptr.write_array_of_int(band_numbers) if band_numbers
469
-
470
- ptr.autorelease = false
471
-
472
- [ptr, band_count]
473
- end
474
136
  end
475
137
  end
data/lib/gdal/driver.rb CHANGED
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'multi_xml'
4
- require_relative '../gdal'
5
- require_relative 'major_object'
3
+ require "multi_xml"
4
+ require_relative "../gdal"
5
+ require_relative "major_object"
6
6
 
7
7
  module GDAL
8
8
  # Wrapper for GDAL drivers (aka "formats"). Useful for opening and working
@@ -11,7 +11,7 @@ module GDAL
11
11
  include MajorObject
12
12
  include GDAL::Logger
13
13
 
14
- GDAL_DOCS_URL = 'http://gdal.org'
14
+ GDAL_DOCS_URL = "http://gdal.org"
15
15
 
16
16
  # @return [Integer]
17
17
  def self.count
@@ -99,10 +99,10 @@ module GDAL
99
99
 
100
100
  return [] if root.nil? || root.empty?
101
101
 
102
- list = root['CreationOptionList']
102
+ list = root["CreationOptionList"]
103
103
  return [] if list.nil? || list.empty?
104
104
 
105
- list['Option']
105
+ list["Option"]
106
106
  end
107
107
 
108
108
  # @param options [Hash]
@@ -156,7 +156,7 @@ module GDAL
156
156
 
157
157
  raise CreateFail if dataset_pointer.null?
158
158
 
159
- dataset = GDAL::Dataset.new(dataset_pointer, 'w')
159
+ dataset = GDAL::Dataset.new(dataset_pointer, "w")
160
160
 
161
161
  if block_given?
162
162
  result = yield(dataset)
@@ -204,7 +204,7 @@ module GDAL
204
204
  raise CreateFail if destination_dataset_ptr.nil? || destination_dataset_ptr.null?
205
205
 
206
206
  if block_given?
207
- dataset = Dataset.new(destination_dataset_ptr, 'w')
207
+ dataset = Dataset.new(destination_dataset_ptr, "w")
208
208
  yield(dataset)
209
209
  dataset.close
210
210
  end
@@ -239,7 +239,7 @@ module GDAL
239
239
  # @return [GDAL::Dataset]
240
240
  def make_dataset_pointer(dataset)
241
241
  if dataset.is_a? String
242
- GDAL::Dataset.open(dataset, 'r').c_pointer
242
+ GDAL::Dataset.open(dataset, "r").c_pointer
243
243
  else
244
244
  GDAL._pointer(GDAL::Dataset, dataset, autorelease: false)
245
245
  end
@@ -247,4 +247,4 @@ module GDAL
247
247
  end
248
248
  end
249
249
 
250
- require_relative 'dataset'
250
+ require_relative "dataset"
@@ -40,7 +40,7 @@ module GDAL
40
40
 
41
41
  # @param file_path [String]
42
42
  def dump_open_datasets(file_path)
43
- file_ptr = FFI::CPL::Conv.CPLOpenShared(file_path, 'w', false)
43
+ file_ptr = FFI::CPL::Conv.CPLOpenShared(file_path, "w", false)
44
44
  FFI::GDAL::GDAL.GDALDumpOpenDatasets(file_ptr)
45
45
  FFI::CPL::Conv.CPLCloseShared(file_ptr)
46
46
  end