ffi-gdal 1.0.0.beta5 → 1.0.0.beta6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +7 -3
  3. data/.rubocop.yml +7 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +1 -1
  6. data/History.md +143 -1
  7. data/README.md +5 -11
  8. data/Rakefile +2 -60
  9. data/TODO.md +10 -0
  10. data/examples/geometries.rb +4 -6
  11. data/examples/gridding.rb +99 -98
  12. data/examples/ogr_layer_to_layer.rb +0 -2
  13. data/examples/raster_erasing.rb +47 -0
  14. data/examples/remove_small_polygons.rb +62 -0
  15. data/examples/testing_gdal.rb +0 -3
  16. data/examples/warping.rb +140 -0
  17. data/ffi-gdal.gemspec +5 -2
  18. data/lib/ext/error_symbols.rb +1 -1
  19. data/lib/ext/ffi_library_function_checks.rb +3 -2
  20. data/lib/ext/float_ext.rb +2 -2
  21. data/lib/ext/narray_ext.rb +1 -1
  22. data/lib/ext/numeric_as_data_type.rb +1 -1
  23. data/lib/ext/to_bool.rb +2 -2
  24. data/lib/ffi/cpl/conv.rb +1 -3
  25. data/lib/ffi/cpl/error.rb +0 -3
  26. data/lib/ffi/cpl/minixml.rb +17 -21
  27. data/lib/ffi/cpl/progress.rb +27 -0
  28. data/lib/ffi/cpl/string.rb +0 -8
  29. data/lib/ffi/cpl/vsi.rb +0 -1
  30. data/lib/ffi/cpl/xml_node.rb +0 -1
  31. data/lib/ffi/cpl.rb +15 -0
  32. data/lib/ffi/gdal/alg.rb +72 -54
  33. data/lib/ffi/gdal/gdal.rb +669 -672
  34. data/lib/ffi/gdal/grid.rb +141 -24
  35. data/lib/ffi/gdal/grid_data_metrics_options.rb +1 -1
  36. data/lib/ffi/gdal/grid_moving_average_options.rb +1 -1
  37. data/lib/ffi/gdal/matching.rb +0 -2
  38. data/lib/ffi/gdal/transformer_info.rb +1 -1
  39. data/lib/ffi/gdal/version.rb +1 -1
  40. data/lib/ffi/gdal/vrt.rb +0 -2
  41. data/lib/ffi/gdal/warp_options.rb +12 -14
  42. data/lib/ffi/gdal/warper.rb +61 -6
  43. data/lib/ffi/gdal.rb +18 -3
  44. data/lib/ffi/ogr/api.rb +10 -21
  45. data/lib/ffi/ogr/core.rb +9 -12
  46. data/lib/ffi/ogr/featurestyle.rb +0 -5
  47. data/lib/ffi/ogr/geocoding.rb +0 -1
  48. data/lib/ffi/ogr/srs_api.rb +0 -4
  49. data/lib/ffi/ogr/style_value.rb +1 -2
  50. data/lib/ffi/ogr.rb +15 -12
  51. data/lib/ffi-gdal.rb +5 -3
  52. data/lib/gdal/color_entry.rb +1 -0
  53. data/lib/gdal/color_interpretation.rb +2 -2
  54. data/lib/gdal/color_table.rb +14 -14
  55. data/lib/gdal/color_table_mixins/extensions.rb +4 -4
  56. data/lib/gdal/cpl_error_handler.rb +12 -14
  57. data/lib/gdal/data_type.rb +13 -12
  58. data/lib/gdal/dataset.rb +170 -94
  59. data/lib/gdal/dataset_mixins/algorithm_methods.rb +47 -21
  60. data/lib/gdal/dataset_mixins/extensions.rb +32 -61
  61. data/lib/gdal/dataset_mixins/matching.rb +0 -2
  62. data/lib/gdal/dataset_mixins/warp_methods.rb +42 -0
  63. data/lib/gdal/driver.rb +62 -47
  64. data/lib/gdal/driver_mixins/extensions.rb +2 -7
  65. data/lib/gdal/environment_methods.rb +13 -10
  66. data/lib/gdal/exceptions.rb +24 -2
  67. data/lib/gdal/geo_transform.rb +10 -16
  68. data/lib/gdal/geo_transform_mixins/extensions.rb +58 -3
  69. data/lib/gdal/grid.rb +62 -109
  70. data/lib/gdal/{grid_types → grid_algorithms}/data_metrics_base.rb +1 -3
  71. data/lib/gdal/{grid_types → grid_algorithms}/inverse_distance_to_a_power.rb +2 -4
  72. data/lib/gdal/{grid_types → grid_algorithms}/metric_average_distance.rb +2 -2
  73. data/lib/gdal/{grid_types → grid_algorithms}/metric_average_distance_pts.rb +2 -2
  74. data/lib/gdal/{grid_types → grid_algorithms}/metric_count.rb +2 -2
  75. data/lib/gdal/{grid_types → grid_algorithms}/metric_maximum.rb +2 -2
  76. data/lib/gdal/{grid_types → grid_algorithms}/metric_minimum.rb +2 -2
  77. data/lib/gdal/{grid_types → grid_algorithms}/metric_range.rb +2 -2
  78. data/lib/gdal/{grid_types → grid_algorithms}/moving_average.rb +2 -4
  79. data/lib/gdal/{grid_types → grid_algorithms}/nearest_neighbor.rb +2 -4
  80. data/lib/gdal/grid_algorithms.rb +22 -0
  81. data/lib/gdal/gridder/point_extracting.rb +89 -0
  82. data/lib/gdal/gridder.rb +294 -0
  83. data/lib/gdal/gridder_options.rb +273 -0
  84. data/lib/gdal/internal_helpers.rb +132 -23
  85. data/lib/gdal/major_object.rb +13 -10
  86. data/lib/gdal/merger.rb +130 -0
  87. data/lib/gdal/options.rb +3 -2
  88. data/lib/gdal/raster_attribute_table.rb +74 -51
  89. data/lib/gdal/raster_attribute_table_mixins/extensions.rb +21 -3
  90. data/lib/gdal/raster_band.rb +139 -167
  91. data/lib/gdal/raster_band_classifier.rb +19 -18
  92. data/lib/gdal/raster_band_mixins/algorithm_extensions.rb +107 -0
  93. data/lib/gdal/raster_band_mixins/algorithm_methods.rb +79 -40
  94. data/lib/gdal/raster_band_mixins/coloring_extensions.rb +84 -0
  95. data/lib/gdal/raster_band_mixins/extensions.rb +34 -169
  96. data/lib/gdal/raster_band_mixins/io_extensions.rb +180 -0
  97. data/lib/gdal/rpc_info.rb +1 -2
  98. data/lib/gdal/transformer.rb +1 -6
  99. data/lib/gdal/transformers/approximate_transformer.rb +0 -4
  100. data/lib/gdal/transformers/base_general_image_projection_transformer.rb +0 -6
  101. data/lib/gdal/transformers/gcp_transformer.rb +2 -6
  102. data/lib/gdal/transformers/general_image_projection_transformer.rb +8 -7
  103. data/lib/gdal/transformers/general_image_projection_transformer2.rb +1 -1
  104. data/lib/gdal/transformers/geolocation_transformer.rb +0 -4
  105. data/lib/gdal/transformers/reprojection_transformer.rb +0 -8
  106. data/lib/gdal/transformers/rpc_transformer.rb +0 -4
  107. data/lib/gdal/transformers/tps_transformer.rb +1 -3
  108. data/lib/gdal/version_info.rb +7 -8
  109. data/lib/gdal/virtual_dataset.rb +2 -4
  110. data/lib/gdal/warp_operation.rb +17 -14
  111. data/lib/gdal/warp_options.rb +132 -0
  112. data/lib/gdal.rb +41 -2
  113. data/lib/ogr/coordinate_transformation.rb +79 -32
  114. data/lib/ogr/data_source.rb +17 -14
  115. data/lib/ogr/data_source_extensions.rb +1 -5
  116. data/lib/ogr/driver.rb +11 -14
  117. data/lib/ogr/envelope.rb +1 -1
  118. data/lib/ogr/envelope_extensions.rb +23 -6
  119. data/lib/ogr/error_handling.rb +3 -3
  120. data/lib/ogr/exceptions.rb +6 -0
  121. data/lib/ogr/feature.rb +25 -38
  122. data/lib/ogr/feature_definition.rb +6 -8
  123. data/lib/ogr/feature_definition_extensions.rb +2 -6
  124. data/lib/ogr/feature_extensions.rb +71 -41
  125. data/lib/ogr/field.rb +16 -15
  126. data/lib/ogr/field_definition.rb +4 -4
  127. data/lib/ogr/geocoder.rb +5 -5
  128. data/lib/ogr/geometries/geometry_collection.rb +4 -1
  129. data/lib/ogr/geometries/geometry_collection_25d.rb +12 -0
  130. data/lib/ogr/geometries/line_string.rb +30 -8
  131. data/lib/ogr/geometries/line_string_25d.rb +21 -0
  132. data/lib/ogr/geometries/linear_ring.rb +10 -1
  133. data/lib/ogr/geometries/multi_line_string.rb +2 -1
  134. data/lib/ogr/geometries/multi_line_string_25d.rb +13 -0
  135. data/lib/ogr/geometries/multi_point.rb +2 -1
  136. data/lib/ogr/geometries/multi_point_25d.rb +14 -0
  137. data/lib/ogr/geometries/multi_polygon.rb +3 -2
  138. data/lib/ogr/geometries/multi_polygon_25d.rb +13 -0
  139. data/lib/ogr/geometries/point.rb +20 -23
  140. data/lib/ogr/geometries/point_25d.rb +48 -0
  141. data/lib/ogr/geometries/polygon.rb +4 -1
  142. data/lib/ogr/geometries/polygon_25d.rb +14 -0
  143. data/lib/ogr/geometry.rb +125 -93
  144. data/lib/ogr/geometry_field_definition.rb +7 -5
  145. data/lib/ogr/geometry_mixins/container_mixins.rb +23 -0
  146. data/lib/ogr/geometry_mixins/extensions.rb +111 -0
  147. data/lib/ogr/geometry_types/container.rb +10 -3
  148. data/lib/ogr/geometry_types/curve.rb +68 -23
  149. data/lib/ogr/geometry_types/surface.rb +0 -9
  150. data/lib/ogr/internal_helpers.rb +3 -3
  151. data/lib/ogr/layer.rb +4 -5
  152. data/lib/ogr/layer_mixins/extensions.rb +242 -17
  153. data/lib/ogr/layer_mixins/ogr_feature_methods.rb +11 -11
  154. data/lib/ogr/layer_mixins/ogr_field_methods.rb +6 -11
  155. data/lib/ogr/layer_mixins/ogr_layer_method_methods.rb +18 -18
  156. data/lib/ogr/layer_mixins/ogr_query_filter_methods.rb +0 -2
  157. data/lib/ogr/layer_mixins/ogr_sql_methods.rb +1 -1
  158. data/lib/ogr/spatial_reference.rb +12 -37
  159. data/lib/ogr/spatial_reference_mixins/coordinate_system_getter_setters.rb +53 -55
  160. data/lib/ogr/spatial_reference_mixins/exporters.rb +18 -49
  161. data/lib/ogr/spatial_reference_mixins/parameter_getter_setters.rb +10 -29
  162. data/lib/ogr/style_table.rb +2 -2
  163. data/lib/ogr/style_table_extensions.rb +3 -1
  164. data/lib/ogr/style_tool.rb +8 -14
  165. data/lib/ogr.rb +39 -1
  166. data/spec/ffi-gdal_spec.rb +18 -1
  167. data/spec/integration/gdal/color_table_info_spec.rb +49 -33
  168. data/spec/integration/gdal/dataset_info_spec.rb +294 -45
  169. data/spec/integration/gdal/driver_info_spec.rb +139 -31
  170. data/spec/integration/gdal/geo_transform_info_spec.rb +197 -26
  171. data/spec/integration/gdal/gridder_spec.rb +329 -0
  172. data/spec/integration/gdal/raster_attribute_table_info_spec.rb +216 -11
  173. data/spec/integration/gdal/raster_band_algorithms_spec.rb +33 -0
  174. data/spec/integration/gdal/raster_band_info_spec.rb +240 -271
  175. data/spec/integration/ogr/layer_spec.rb +3 -1
  176. data/spec/spec_helper.rb +15 -6
  177. data/spec/support/images/osgeo/gdal/data/hfa/float-rle.img +0 -0
  178. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.lgo +31 -0
  179. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.tif +0 -0
  180. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.tif.msk +0 -0
  181. data/spec/support/images/osgeo/geotiff/GeogToWGS84GeoKey/GeogToWGS84GeoKey5.txt +10 -0
  182. data/spec/support/images/osgeo/geotiff/gdal_eg/cea.tif +0 -0
  183. data/spec/support/images/osgeo/geotiff/gdal_eg/cea.txt +84 -0
  184. data/spec/support/images/osgeo/geotiff/zi_imaging/image0.lgo +45 -0
  185. data/spec/support/images/osgeo/geotiff/zi_imaging/image0.tif +0 -0
  186. data/spec/support/integration_help.rb +32 -2
  187. data/spec/support/shared_examples/gdal/major_object_examples.rb +0 -6
  188. data/spec/support/shared_examples/ogr/a_geometry.rb +1 -1
  189. data/spec/unit/ffi/gdal_spec.rb +1 -1
  190. data/spec/unit/gdal/color_entry_spec.rb +1 -0
  191. data/spec/unit/gdal/color_interpretation_spec.rb +1 -0
  192. data/spec/unit/gdal/dataset_spec.rb +53 -2
  193. data/spec/unit/gdal/geo_transform_mixins/extensions_spec.rb +67 -0
  194. data/spec/unit/gdal/geo_transform_spec.rb +1 -1
  195. data/spec/unit/gdal/grid_spec.rb +83 -0
  196. data/spec/unit/gdal/gridder/point_extracting_spec.rb +99 -0
  197. data/spec/unit/gdal/gridder_options_spec.rb +183 -0
  198. data/spec/unit/gdal/gridder_spec.rb +140 -0
  199. data/spec/unit/gdal/internal_helpers_spec.rb +166 -2
  200. data/spec/unit/gdal/major_object_spec.rb +2 -0
  201. data/spec/unit/gdal/options_spec.rb +1 -0
  202. data/spec/unit/gdal/raster_band_classifier_spec.rb +70 -12
  203. data/spec/unit/gdal/raster_band_mixins/extensions_spec.rb +71 -0
  204. data/spec/unit/gdal/raster_band_mixins/io_extensions_spec.rb +133 -0
  205. data/spec/unit/gdal/raster_band_spec.rb +1 -0
  206. data/spec/unit/gdal/rpc_info_spec.rb +1 -0
  207. data/spec/unit/gdal/version_info_spec.rb +2 -0
  208. data/spec/unit/gdal/warp_operation_spec.rb +1 -0
  209. data/spec/unit/ogr/coordinate_transformation_spec.rb +102 -0
  210. data/spec/unit/ogr/data_source_spec.rb +12 -0
  211. data/spec/unit/ogr/feature_extensions_spec.rb +88 -0
  212. data/spec/unit/ogr/feature_spec.rb +30 -46
  213. data/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb +23 -0
  214. data/spec/unit/ogr/geometries/geometry_collection_spec.rb +3 -3
  215. data/spec/unit/ogr/geometries/line_string_25d_spec.rb +23 -0
  216. data/spec/unit/ogr/geometries/line_string_spec.rb +2 -2
  217. data/spec/unit/ogr/geometries/linear_ring_spec.rb +2 -2
  218. data/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb +23 -0
  219. data/spec/unit/ogr/geometries/multi_point_25d_spec.rb +23 -0
  220. data/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb +23 -0
  221. data/spec/unit/ogr/geometries/point_25d_spec.rb +23 -0
  222. data/spec/unit/ogr/geometries/point_spec.rb +14 -24
  223. data/spec/unit/ogr/geometries/polygon_25d_spec.rb +23 -0
  224. data/spec/unit/ogr/geometries/polygon_spec.rb +1 -1
  225. data/spec/unit/ogr/geometry_field_definition_spec.rb +1 -1
  226. data/spec/unit/ogr/geometry_spec.rb +196 -30
  227. data/spec/unit/ogr/internal_helpers_spec.rb +20 -9
  228. data/spec/unit/ogr/layer_mixins/ogr_feature_methods_spec.rb +14 -6
  229. data/spec/unit/ogr/spatial_reference_mixins/exporters_spec.rb +9 -1
  230. data/spec/unit/ogr/spatial_reference_mixins/parameter_getter_setters_spec.rb +2 -1
  231. data/spec/unit/ogr/style_table_spec.rb +1 -1
  232. data/tmp/.keep +0 -0
  233. metadata +121 -19
  234. data/examples/points.txt +0 -127
  235. data/lib/gdal/grid_types.rb +0 -22
  236. data/lib/ogr/geometries/point_extensions.rb +0 -32
  237. data/lib/ogr/geometry_extensions.rb +0 -59
data/lib/gdal/dataset.rb CHANGED
@@ -1,16 +1,11 @@
1
1
  require 'uri'
2
- require_relative '../ffi/gdal'
3
- require_relative '../ffi/cpl/string'
4
- require_relative '../ogr/spatial_reference'
5
- require_relative 'driver'
6
- require_relative 'geo_transform'
7
- require_relative 'raster_band'
8
- require_relative 'exceptions'
2
+ require_relative '../gdal'
3
+ require_relative '../ogr'
9
4
  require_relative 'major_object'
10
5
  require_relative 'dataset_mixins/extensions'
11
6
  require_relative 'dataset_mixins/matching'
12
7
  require_relative 'dataset_mixins/algorithm_methods'
13
- require_relative 'options'
8
+ require_relative 'dataset_mixins/warp_methods'
14
9
 
15
10
  module GDAL
16
11
  # A set of associated raster bands and info common to them all. It's also
@@ -21,18 +16,29 @@ module GDAL
21
16
  include DatasetMixins::Extensions
22
17
  include DatasetMixins::Matching
23
18
  include DatasetMixins::AlgorithmMethods
19
+ include DatasetMixins::WarpMethods
24
20
  include GDAL::Logger
25
21
 
26
22
  ACCESS_FLAGS = {
27
23
  'r' => :GA_ReadOnly,
28
24
  'w' => :GA_Update
29
- }
25
+ }.freeze
30
26
 
31
27
  # @param path [String] Path to the file that contains the dataset. Can be
32
28
  # a local file or a URL.
33
29
  # @param access_flag [String] 'r' or 'w'.
34
- def self.open(path, access_flag)
35
- new(path, access_flag)
30
+ # @param shared_open [Boolean] Whether or not to open using GDALOpenShared
31
+ # vs GDALOpen. Defaults to +true+.
32
+ def self.open(path, access_flag, shared_open = true)
33
+ ds = new(path, access_flag, shared_open)
34
+
35
+ if block_given?
36
+ result = yield ds
37
+ ds.close
38
+ result
39
+ else
40
+ ds
41
+ end
36
42
  end
37
43
 
38
44
  #---------------------------------------------------------------------------
@@ -47,7 +53,9 @@ module GDAL
47
53
  # contains the dataset or a pointer to the dataset. If it's a path, it can
48
54
  # be a local file or a URL.
49
55
  # @param access_flag [String] 'r' or 'w'.
50
- def initialize(path_or_pointer, access_flag)
56
+ # @param shared_open [Boolean] Whether or not to open using GDALOpenShared
57
+ # vs GDALOpen. Defaults to +true+.
58
+ def initialize(path_or_pointer, access_flag, shared_open = true)
51
59
  @c_pointer =
52
60
  if path_or_pointer.is_a? String
53
61
  file_path = begin
@@ -57,15 +65,19 @@ module GDAL
57
65
  path_or_pointer
58
66
  end
59
67
 
60
- FFI::GDAL.GDALOpen(file_path, ACCESS_FLAGS[access_flag])
68
+ if shared_open
69
+ FFI::GDAL::GDAL.GDALOpenShared(file_path, ACCESS_FLAGS[access_flag])
70
+ else
71
+ FFI::GDAL::GDAL.GDALOpen(file_path, ACCESS_FLAGS[access_flag])
72
+ end
61
73
  else
62
74
  path_or_pointer
63
75
  end
64
76
 
65
- fail OpenFailure, path_or_pointer if @c_pointer.null?
66
- ObjectSpace.define_finalizer self, -> { close }
77
+ raise OpenFailure, path_or_pointer if @c_pointer.null?
67
78
 
68
79
  @geo_transform = nil
80
+ @spatial_reference = nil
69
81
  @raster_bands = Array.new(raster_count)
70
82
  end
71
83
 
@@ -73,23 +85,21 @@ module GDAL
73
85
  def close
74
86
  return unless @c_pointer
75
87
 
76
- FFI::GDAL.GDALClose(@c_pointer)
88
+ FFI::GDAL::GDAL.GDALClose(@c_pointer)
77
89
  @c_pointer = nil
78
90
  end
79
91
 
80
92
  # @return [Symbol]
81
93
  def access_flag
82
- return nil if null?
83
-
84
- flag = FFI::GDAL.GDALGetAccess(@c_pointer)
94
+ flag = FFI::GDAL::GDAL.GDALGetAccess(@c_pointer)
85
95
 
86
- FFI::GDAL::Access[flag]
96
+ FFI::GDAL::GDAL::Access[flag]
87
97
  end
88
98
 
89
99
  # @return [GDAL::Driver] The driver to be used for working with this
90
100
  # dataset.
91
101
  def driver
92
- driver_ptr = FFI::GDAL.GDALGetDatasetDriver(@c_pointer)
102
+ driver_ptr = FFI::GDAL::GDAL.GDALGetDatasetDriver(@c_pointer)
93
103
 
94
104
  Driver.new(driver_ptr)
95
105
  end
@@ -97,7 +107,7 @@ module GDAL
97
107
  # Fetches all files that form the dataset.
98
108
  # @return [Array<String>]
99
109
  def file_list
100
- list_pointer = FFI::GDAL.GDALGetFileList(@c_pointer)
110
+ list_pointer = FFI::GDAL::GDAL.GDALGetFileList(@c_pointer)
101
111
  return [] if list_pointer.null?
102
112
  file_list = list_pointer.get_array_of_string(0)
103
113
  FFI::CPL::String.CSLDestroy(list_pointer)
@@ -107,69 +117,71 @@ module GDAL
107
117
 
108
118
  # Flushes all write-cached data to disk.
109
119
  def flush_cache
110
- FFI::GDAL.GDALFlushCache(@c_pointer)
120
+ FFI::GDAL::GDAL.GDALFlushCache(@c_pointer)
111
121
  end
112
122
 
113
123
  # @return [Fixnum]
114
124
  def raster_x_size
115
125
  return nil if null?
116
126
 
117
- FFI::GDAL.GDALGetRasterXSize(@c_pointer)
127
+ FFI::GDAL::GDAL.GDALGetRasterXSize(@c_pointer)
118
128
  end
119
129
 
120
130
  # @return [Fixnum]
121
131
  def raster_y_size
122
132
  return nil if null?
123
133
 
124
- FFI::GDAL.GDALGetRasterYSize(@c_pointer)
134
+ FFI::GDAL::GDAL.GDALGetRasterYSize(@c_pointer)
125
135
  end
126
136
 
127
137
  # @return [Fixnum]
128
138
  def raster_count
129
139
  return 0 if null?
130
140
 
131
- FFI::GDAL.GDALGetRasterCount(@c_pointer)
141
+ FFI::GDAL::GDAL.GDALGetRasterCount(@c_pointer)
132
142
  end
133
143
 
134
144
  # @param raster_index [Fixnum]
135
145
  # @return [GDAL::RasterBand]
136
146
  def raster_band(raster_index)
137
147
  if raster_index > raster_count
138
- fail GDAL::InvalidRasterBand, "Invalid raster band number '#{raster_index}'. Must be <= #{raster_count}"
148
+ raise GDAL::InvalidRasterBand, "Invalid raster band number '#{raster_index}'. Must be <= #{raster_count}"
139
149
  end
140
150
 
141
- raster_band_ptr = FFI::GDAL.GDALGetRasterBand(@c_pointer, raster_index)
151
+ raster_band_ptr = FFI::GDAL::GDAL.GDALGetRasterBand(@c_pointer, raster_index)
142
152
 
143
153
  GDAL::RasterBand.new(raster_band_ptr)
144
154
  end
145
155
 
146
- # @param type [FFI::GDAL::DataType]
156
+ # @param type [FFI::GDAL::GDAL::DataType]
147
157
  # @param options [Hash]
148
158
  # @return [GDAL::RasterBand, nil]
149
159
  def add_band(type, **options)
150
160
  options_ptr = GDAL::Options.pointer(options)
151
- FFI::GDAL.GDALAddBand(@c_pointer, type, options_ptr)
161
+ FFI::GDAL::GDAL.GDALAddBand(@c_pointer, type, options_ptr)
152
162
 
153
163
  raster_band(raster_count)
154
164
  end
155
165
 
156
166
  # Adds a mask band to the dataset.
157
167
  #
158
- # @param flags [Fixnum] Any of of the GDAL::RasterBand flags.
168
+ # @param flags [Array<Symbol>, Symbol] Any of the :GMF symbols.
159
169
  # @return [Boolean]
160
- def create_mask_band(flags)
161
- !!FFI::GDAL.GDALCreateDatasetMaskBand(@c_pointer, flags)
170
+ def create_mask_band(*flags)
171
+ flag_value = parse_mask_flag_symbols(flags)
172
+
173
+ !!FFI::GDAL::GDAL.GDALCreateDatasetMaskBand(@c_pointer, flag_value)
162
174
  end
163
175
 
164
176
  # @return [String]
165
177
  def projection
166
- FFI::GDAL.GDALGetProjectionRef(@c_pointer) || ''
178
+ FFI::GDAL::GDAL.GDALGetProjectionRef(@c_pointer) || ''
167
179
  end
168
180
 
169
181
  # @param new_projection [String]
170
182
  # @return [Boolean]
171
183
  def projection=(new_projection)
172
- FFI::GDAL.GDALSetProjection(@c_pointer, new_projection.to_s)
184
+ FFI::GDAL::GDAL.GDALSetProjection(@c_pointer, new_projection.to_s)
173
185
  end
174
186
 
175
187
  # @return [GDAL::GeoTransform]
@@ -177,39 +189,40 @@ module GDAL
177
189
  return @geo_transform if @geo_transform
178
190
 
179
191
  geo_transform_pointer = GDAL::GeoTransform.new_pointer
180
- FFI::GDAL.GDALGetGeoTransform(@c_pointer, geo_transform_pointer)
192
+ geo_transform_pointer.autorelease = false
193
+ FFI::GDAL::GDAL.GDALGetGeoTransform(@c_pointer, geo_transform_pointer)
181
194
 
182
195
  @geo_transform = GeoTransform.new(geo_transform_pointer)
183
196
  end
184
197
 
185
- # @param new_transform [GDAL::GeoTransform]
198
+ # @param new_transform [GDAL::GeoTransform, FFI::Pointer]
186
199
  # @return [GDAL::GeoTransform]
187
200
  def geo_transform=(new_transform)
188
201
  new_pointer = GDAL._pointer(GDAL::GeoTransform, new_transform)
189
- FFI::GDAL.GDALSetGeoTransform(@c_pointer, new_pointer)
202
+ FFI::GDAL::GDAL.GDALSetGeoTransform(@c_pointer, new_pointer)
190
203
 
191
- @geo_transform = GeoTransform.new(new_pointer)
204
+ @geo_transform = new_transform.is_a?(FFI::Pointer) ? GeoTransform.new(new_pointer) : new_transform
192
205
  end
193
206
 
194
207
  # @return [Fixnum]
195
208
  def gcp_count
196
209
  return 0 if null?
197
210
 
198
- FFI::GDAL.GDALGetGCPCount(@c_pointer)
211
+ FFI::GDAL::GDAL.GDALGetGCPCount(@c_pointer)
199
212
  end
200
213
 
201
214
  # @return [String]
202
215
  def gcp_projection
203
216
  return '' if null?
204
217
 
205
- FFI::GDAL.GDALGetGCPProjection(@c_pointer)
218
+ FFI::GDAL::GDAL.GDALGetGCPProjection(@c_pointer)
206
219
  end
207
220
 
208
221
  # @return [FFI::GDAL::GCP]
209
222
  def gcps
210
223
  return FFI::GDAL::GCP.new if null?
211
224
 
212
- gcp_array_pointer = FFI::GDAL.GDALGetGCPs(@c_pointer)
225
+ gcp_array_pointer = FFI::GDAL::GDAL.GDALGetGCPs(@c_pointer)
213
226
 
214
227
  if gcp_array_pointer.null?
215
228
  FFI::GDAL::GCP.new
@@ -218,26 +231,20 @@ module GDAL
218
231
  end
219
232
  end
220
233
 
221
- # @return [Fixnum]
222
- def layer_count
223
- fail GDAL::UnsupportedOperation unless GDAL._supported?(:GDALDatasetGetLayerCount)
224
-
225
- FFI::GDAL.GDALDatasetGetLayerCount(@c_pointer)
226
- end
227
-
228
234
  # @param resampling [String, Symbol] One of:
229
- # * :nearest
230
- # * :gauss
231
- # * :cubic
232
- # * :average
233
- # * :mode
234
- # * :average_magphase
235
+ # * :nearest - Nearest neighbor resampling
236
+ # * :gauss - Gaussian kernel resampling
237
+ # * :cubic - Cubic convolution resampling
238
+ # * :average - Average of all non-NODATA
239
+ # * :mode - Selects the value that occurs most often
240
+ # * :average_magphase - Averages complex data in mag/phase space
235
241
  # * :none
236
242
  # @param overview_levels [Array<Fixnum>] The list of overview decimation
237
243
  # factors to build.
238
244
  # @param band_numbers [Array<Fixnum>] The numbers of the bands to build
239
245
  # overviews from.
240
- def build_overviews(resampling, overview_levels, band_numbers = nil, &progress)
246
+ # @see http://www.gdal.org/gdaladdo.html
247
+ def build_overviews(resampling, overview_levels, band_numbers: nil, &progress)
241
248
  resampling_string = if resampling.is_a? String
242
249
  resampling.upcase
243
250
  elsif resampling.is_a? Symbol
@@ -246,17 +253,9 @@ module GDAL
246
253
 
247
254
  overview_levels_ptr = FFI::MemoryPointer.new(:int, overview_levels.size)
248
255
  overview_levels_ptr.write_array_of_int(overview_levels)
256
+ band_numbers_ptr, band_count = band_numbers_args(band_numbers)
249
257
 
250
- if band_numbers
251
- band_count = band_numbers.size
252
- band_numbers_ptr = FFI::MemoryPointer.new(:int, band_count)
253
- band_numbers_ptr.write_array_of_int(band_numbers)
254
- else
255
- band_numbers_ptr = nil
256
- band_count = nil
257
- end
258
-
259
- !!FFI::GDAL.GDALBuildOverviews(
258
+ !!FFI::GDAL::GDAL.GDALBuildOverviews(
260
259
  @c_pointer,
261
260
  resampling_string,
262
261
  overview_levels.size,
@@ -268,50 +267,127 @@ module GDAL
268
267
  )
269
268
  end
270
269
 
271
- # @param access_flag [String] 'r' or 'w'
272
- # @param data_ptr [FFI::MemoryPointer] The pointer to the data to write to
273
- # the dataset.
274
- # @param x_size [Fixnum] If not given, uses #raster_x_size.
275
- # @param y_size [Fixnum] If not given, uses #raster_y_size.
276
- # @param data_type [FFI::GDAL::DataType]
277
- # @param band_count [Fixnum] The number of bands to create in the raster.
278
- # @param pixel_space
279
- def raster_io(access_flag, data_ptr,
280
- x_size: nil,
281
- y_size: nil,
282
- x_offset: 0,
283
- y_offset: 0,
284
- data_type: :GDT_Byte,
285
- band_count: 1,
286
- pixel_space: 0,
287
- line_space: 0,
288
- band_space: 0
289
- )
290
-
270
+ # @param access_flag [String] 'r' or 'w'.
271
+ # @param buffer [FFI::MemoryPointer] The pointer to the data to read/write
272
+ # to the dataset.
273
+ # @param x_size [Fixnum] If not given, uses {{#raster_x_size}}.
274
+ # @param y_size [Fixnum] If not given, uses {{#raster_y_size}}.
275
+ # @param x_offset [Fixnum] The pixel number in the line to start operating
276
+ # on. Note that when using this, {#x_size} - +x_offset+ should be >= 0,
277
+ # otherwise this means you're telling the method to read past the end of
278
+ # the line. Defaults to 0.
279
+ # @param y_offset [Fixnum] The line number to start operating on. Note that
280
+ # when using this, {#y_size} - +y_offset+ should be >= 0, otherwise this
281
+ # means you're telling the method to read more lines than the raster has.
282
+ # Defaults to 0.
283
+ # @param buffer_x_size [Fixnum] The width of the buffer image in which to
284
+ # read/write the raster data into/from. Typically this should be the same
285
+ # size as +x_size+; if it's different, GDAL will resample accordingly.
286
+ # @param buffer_y_size [Fixnum] The height of the buffer image in which to
287
+ # read/write the raster data into/from. Typically this should be the same
288
+ # size as +y_size+; if it's different, GDAL will resample accordingly.
289
+ # @param buffer_data_type [FFI::GDAL::GDAL::DataType] Can be used to convert the
290
+ # data to a different type. You must account for this when reading/writing
291
+ # to/from your buffer--your buffer size must be +buffer_x_size+ *
292
+ # +buffer_y_size+.
293
+ # @param band_numbers [Array<Fixnum>] The numbers of the bands to do IO on.
294
+ # @param pixel_space [Fixnum] The byte offset from the start of one pixel
295
+ # value in the buffer to the start of the next pixel value within a line.
296
+ # If defaulted (0), the size of +buffer_data_type+ is used.
297
+ # @param line_space [Fixnum] The byte offset from the start of one line in
298
+ # the buffer to the start of the next. If defaulted (0), the size of
299
+ # +buffer_data_type+ * +buffer_x_size* is used.
300
+ # @param band_space [Fixnum] The byte offset from the start of one band's
301
+ # data to the start of the next. If defaulted (0), the size of
302
+ # +line_space+ * +buffer_y_size* is used.
303
+ def raster_io(access_flag, buffer = nil,
304
+ x_size: nil, y_size: nil, x_offset: 0, y_offset: 0,
305
+ buffer_x_size: nil, buffer_y_size: nil, buffer_data_type: nil,
306
+ band_numbers: nil,
307
+ pixel_space: 0, line_space: 0, band_space: 0)
291
308
  x_size ||= raster_x_size
292
309
  y_size ||= raster_y_size
310
+ buffer_x_size ||= x_size
311
+ buffer_y_size ||= y_size
312
+ buffer_data_type ||= raster_band(1).data_type
313
+ band_numbers_ptr, band_count = band_numbers_args(band_numbers)
314
+ band_count = raster_count if band_count.zero?
315
+
316
+ buffer ||= GDAL._pointer_from_data_type(buffer_data_type, buffer_x_size * buffer_y_size * band_count)
293
317
 
294
318
  gdal_access_flag = GDAL._gdal_access_flag(access_flag)
295
- x_buffer_size = x_size
296
- y_buffer_size = y_size
297
319
 
298
- !!FFI::GDAL::GDALDatasetRasterIO(
320
+ min_buffer_size = valid_min_buffer_size(buffer_data_type, buffer_x_size, buffer_y_size)
321
+
322
+ unless buffer.size >= min_buffer_size
323
+ raise GDAL::BufferTooSmall, "Buffer size (#{buffer.size}) too small (#{min_buffer_size})"
324
+ end
325
+
326
+ FFI::GDAL::GDAL::GDALDatasetRasterIO(
299
327
  @c_pointer, # hDS
300
328
  gdal_access_flag, # eRWFlag
301
329
  x_offset, # nXOff
302
330
  y_offset, # nYOff
303
331
  x_size, # nXSize
304
332
  y_size, # nYSize
305
- data_ptr, # pData
306
- x_buffer_size, # nBufXSize
307
- y_buffer_size, # nBufYSize
308
- data_type, # eBufType
333
+ buffer, # pData
334
+ buffer_x_size, # nBufXSize
335
+ buffer_y_size, # nBufYSize
336
+ buffer_data_type, # eBufType
309
337
  band_count, # nBandCount
310
- nil, # panBandMap (WTH is this?)
338
+ band_numbers_ptr, # panBandMap (WTH is this?)
311
339
  pixel_space, # nPixelSpace
312
340
  line_space, # nLineSpace
313
341
  band_space # nBandSpace
314
342
  )
343
+
344
+ buffer
345
+ end
346
+
347
+ private
348
+
349
+ # Lets you pass in :GMF_ symbols that represent mask band flags and bitwise
350
+ # ors them.
351
+ #
352
+ # @param flags [Symbol]
353
+ # @return [Fixnum]
354
+ def parse_mask_flag_symbols(*flags)
355
+ flags.reduce(0) do |result, flag|
356
+ result |= case flag
357
+ when :GMF_ALL_VALID then 0x01
358
+ when :GMF_PER_DATASET then 0x02
359
+ when :GMF_PER_ALPHA then 0x04
360
+ when :GMF_NODATA then 0x08
361
+ else 0
362
+ end
363
+ end
364
+ end
365
+
366
+ # @param buffer_data_type [FFI::GDAL::GDAL::DataType]
367
+ # @param x_buffer_size [Fixnum]
368
+ # @param y_buffer_size [Fixnum]
369
+ # @return [Fixnum]
370
+ def valid_min_buffer_size(buffer_data_type, x_buffer_size, y_buffer_size)
371
+ data_type_bytes = GDAL::DataType.size(buffer_data_type) / 8
372
+
373
+ data_type_bytes * x_buffer_size * y_buffer_size
374
+ end
375
+
376
+ # Makes a pointer of +band_numbers+.
377
+ #
378
+ # @param band_numbers [Array<Fixnum>]
379
+ # @return [Array<FFI::Pointer, Fixnum>]
380
+ def band_numbers_args(band_numbers)
381
+ if band_numbers
382
+ band_count = band_numbers.size
383
+ band_numbers_ptr = FFI::MemoryPointer.new(:int, band_count)
384
+ band_numbers_ptr.write_array_of_int(band_numbers)
385
+ else
386
+ band_numbers_ptr = nil
387
+ band_count = 0
388
+ end
389
+
390
+ [band_numbers_ptr, band_count]
315
391
  end
316
392
  end
317
393
  end
@@ -1,5 +1,6 @@
1
1
  module GDAL
2
2
  module DatasetMixins
3
+ # Wrappers for Warp algorithm methods defined in gdal_alg.h.
3
4
  module AlgorithmMethods
4
5
  # Rasterizes the geometric objects +geometries+ into this raster dataset.
5
6
  # +transformer+ can be nil as long as the +geometries+ are within the
@@ -22,7 +23,7 @@ module GDAL
22
23
  transformer: nil, transform_arg: nil, **options, &progress_block)
23
24
 
24
25
  if geo_transform.nil? && gcp_count.zero?
25
- fail "Can't rasterize geometries--no geo_transform or GCPs have been defined on the dataset."
26
+ raise "Can't rasterize geometries--no geo_transform or GCPs have been defined on the dataset."
26
27
  end
27
28
 
28
29
  gdal_options = GDAL::Options.pointer(options)
@@ -39,7 +40,7 @@ module GDAL
39
40
  burn_values_ptr = FFI::MemoryPointer.new(:pointer, burn_values.size)
40
41
  burn_values_ptr.write_array_of_double(burn_values)
41
42
 
42
- FFI::GDAL.GDALRasterizeGeometries(@c_pointer,
43
+ FFI::GDAL::GDAL.GDALRasterizeGeometries(@c_pointer,
43
44
  band_numbers.size,
44
45
  band_numbers_ptr,
45
46
  geometries.size,
@@ -93,7 +94,7 @@ module GDAL
93
94
  burn_values_ptr.write_array_of_double(burn_values)
94
95
  log "burn value ptr null? #{burn_values_ptr.null?}"
95
96
 
96
- FFI::GDAL.GDALRasterizeLayers(@c_pointer, # hDS
97
+ FFI::GDAL::GDAL.GDALRasterizeLayers(@c_pointer, # hDS
97
98
  band_numbers.size, # nBandCount
98
99
  band_numbers_ptr, # panBandList
99
100
  layers.size, # nLayerCount
@@ -106,23 +107,21 @@ module GDAL
106
107
  nil) # pProgressArg
107
108
  end
108
109
 
109
- # @param destination_file [String]
110
- # @param driver [String] Name of the driver to use for outputing the new
111
- # image.
112
- # @param transformer [Proc]
113
- # @param transformer_arg_ptr [FFI::Pointer]
114
- # @param band_numbers [Fixnum, Array<Fixnum>] Raster bands to include in the
115
- # warping. 0 indicates all bands.
116
- # @param options [Hash]
117
- # @option options [String] init Indicates that the output dataset should be
110
+ # @param destination_dataset [String]
111
+ # @param transformer [Proc, FFI::Function]
112
+ # @param transformer_arg_ptr [FFI::Pointer] The pointer created from one
113
+ # of the GDAL::Transformers.
114
+ # @param warp_options [Hash]
115
+ # @option warp_options [String] init Indicates that the output dataset should be
118
116
  # initialized to the given value in any area where valid data isn't
119
117
  # written. In form: "v[,v...]"
118
+ # @param band_numbers [Fixnum, Array<Fixnum>] Raster bands to include in the
119
+ # warping. 0 indicates all bands.
120
+ # @param progress [Proc]
120
121
  # @return [GDAL::Dataset, nil] The new dataset or nil if the warping failed.
121
- def simple_image_warp(destination_file, driver, transformer,
122
- transformer_arg_ptr, band_numbers = 0, **options, &progress)
123
- options_ptr = GDAL::Options.pointer(options)
124
- driver = GDAL::Driver.by_name(driver)
125
- destination_dataset_ptr = driver.open(destination_file, 'w')
122
+ def simple_image_warp(destination_dataset, transformer, transformer_arg_ptr,
123
+ warp_options, band_numbers = 0, progress = nil)
124
+ destination_dataset_ptr = destination_dataset.c_pointer
126
125
 
127
126
  band_numbers = band_numbers.is_a?(Array) ? band_numbers : [band_numbers]
128
127
  log "band numbers: #{band_numbers}"
@@ -131,7 +130,7 @@ module GDAL
131
130
  bands_ptr.write_array_of_int(band_numbers)
132
131
  log "band numbers ptr null? #{bands_ptr.null?}"
133
132
 
134
- success = FFI::GDAL.GDALSimpleImageWarp(@c_pointer,
133
+ success = FFI::GDAL::Alg.GDALSimpleImageWarp(@c_pointer,
135
134
  destination_dataset_ptr,
136
135
  band_numbers.size,
137
136
  bands_ptr,
@@ -139,17 +138,44 @@ module GDAL
139
138
  transformer_arg_ptr,
140
139
  progress,
141
140
  nil,
142
- options_ptr)
141
+ warp_options.c_pointer)
143
142
 
144
- success ? GDAL::Dataset.new(destination_dataset_ptr) : nil
143
+ success ? destination_dataset : nil
145
144
  end
146
145
 
146
+ # @param transformer [GDAL::Transformers]
147
+ # @return [Hash{geo_transform: GDAL::GeoTransform, lines: Fixnum, pixels: Fixnum}]
147
148
  def suggested_warp_output(transformer)
148
149
  geo_transform = GDAL::GeoTransform.new
149
150
  pixels_ptr = FFI::MemoryPointer.new(:int)
150
151
  lines_ptr = FFI::MemoryPointer.new(:int)
152
+
153
+ FFI::GDAL::Alg.GDALSuggestedWarpOutput(
154
+ @c_pointer,
155
+ transformer.function,
156
+ transformer.c_pointer,
157
+ geo_transform.c_pointer,
158
+ pixels_ptr,
159
+ lines_ptr
160
+ )
161
+
162
+ {
163
+ geo_transform: geo_transform,
164
+ lines: lines_ptr.read_int,
165
+ pixels: pixels_ptr.read_int
166
+ }
167
+ end
168
+
169
+ # @param transformer [GDAL::Transformers]
170
+ # @return [Hash{extents: Hash{ min_x: Fixnum, min_y: Fixnum, max_x: Fixnum,
171
+ # max_y: Fixnum }, geo_transform: GDAL::GeoTransform, lines: Fixnum,
172
+ # pixels: Fixnum}]
173
+ def suggested_warp_output2(transformer)
174
+ geo_transform = GDAL::GeoTransform.new
175
+ pixels_ptr = FFI::MemoryPointer.new(:int)
176
+ lines_ptr = FFI::MemoryPointer.new(:int)
151
177
  extents_ptr = FFI::MemoryPointer.new(:double, 4)
152
- options = 0 # C code says this isn't used yet.
178
+ options = 0 # C code says this isn't used yet.
153
179
 
154
180
  FFI::GDAL::Alg.GDALSuggestedWarpOutput2(
155
181
  @c_pointer,