ffi-gdal 1.0.0.beta5 → 1.0.0.beta6

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -39,8 +39,8 @@ module GDAL
39
39
  output_data_type: nil, remove_negatives: false, no_data_value: -9999.0, **options)
40
40
  red = raster_band(red_band_number)
41
41
  nir = raster_band(nir_band_number)
42
- fail RequiredBandNotFound, 'Red band not found.' if red.nil?
43
- fail RequiredBandNotFound, 'Near-infrared' if nir.nil?
42
+ raise RequiredBandNotFound, 'Red band not found.' if red.nil?
43
+ raise RequiredBandNotFound, 'Near-infrared' if nir.nil?
44
44
 
45
45
  output_data_type ||= red.data_type
46
46
  the_array = calculate_ndvi(red.to_na, nir.to_na, no_data_value, remove_negatives, output_data_type)
@@ -52,7 +52,7 @@ module GDAL
52
52
  ndvi_dataset.projection = projection
53
53
 
54
54
  ndvi_band = ndvi_dataset.raster_band(1)
55
- ndvi_band.write_array(the_array)
55
+ ndvi_band.write_xy_narray(the_array)
56
56
  ndvi_band.no_data_value = no_data_value
57
57
  end
58
58
 
@@ -78,7 +78,7 @@ module GDAL
78
78
  # this object or the data may not persist!*
79
79
  def extract_nir(destination, band_number, driver_name: 'GTiff', output_data_type: nil, **options)
80
80
  original_nir_band = raster_band(band_number)
81
- fail InvalidBandNumber, "Band #{band_number} found but was nil." if original_nir_band.nil?
81
+ raise InvalidBandNumber, "Band #{band_number} found but was nil." if original_nir_band.nil?
82
82
 
83
83
  output_data_type ||= original_nir_band.data_type
84
84
  driver = GDAL::Driver.by_name(driver_name)
@@ -164,7 +164,7 @@ module GDAL
164
164
  final_array = case output_data_type
165
165
  when :GDT_Byte then calculate_ndvi_byte(ndvi)
166
166
  when :GDT_UInt16 then calculate_ndvi_uint16(ndvi)
167
- else ndvi # Already in Float32
167
+ else ndvi # Already in Float32
168
168
  end
169
169
 
170
170
  remove_negatives ? remove_negatives_from(final_array, no_data_value) : final_array
@@ -271,11 +271,16 @@ module GDAL
271
271
  spatial_ref = nil
272
272
  else
273
273
  spatial_ref = OGR::SpatialReference.new(projection)
274
- spatial_ref.auto_identify_epsg! rescue OGR::UnsupportedSRS
274
+ begin
275
+ spatial_ref.auto_identify_epsg!
276
+ rescue
277
+ OGR::UnsupportedSRS
278
+ end
275
279
  end
276
280
 
277
281
  data_source = ogr_driver.create_data_source(file_name)
278
282
 
283
+ # TODO: fasterer: each_with_index is slower than loop
279
284
  band_numbers.each_with_index do |band_number, i|
280
285
  log "Starting to polygonize raster band #{band_number}..."
281
286
  layer_name = "#{layer_name_prefix}-#{band_number}"
@@ -287,12 +292,12 @@ module GDAL
287
292
  band = raster_band(band_number)
288
293
 
289
294
  unless band
290
- fail GDAL::InvalidBandNumber, "Unknown band number: #{band_number}"
295
+ raise GDAL::InvalidBandNumber, "Unknown band number: #{band_number}"
291
296
  end
292
297
 
293
298
  pixel_value_field = layer.feature_definition.field_index(field_name)
294
299
  options = { pixel_value_field: pixel_value_field }
295
- options.merge!(mask_band: band.mask_band) if use_band_masks
300
+ options[:mask_band] = band.mask_band if use_band_masks
296
301
  band.polygonize(layer, options)
297
302
  end
298
303
 
@@ -307,10 +312,26 @@ module GDAL
307
312
  # Gets the OGR::Geometry that represents the extent of the dataset.
308
313
  #
309
314
  # @return [OGR::Polygon]
315
+ # TODO: This should return an OGR::Envelope.
310
316
  def extent
311
- raster_data_source = to_vector('memory data source', 'Memory', geometry_type: :wkbLinearRing)
312
-
313
- raster_data_source.layer(0).geometry_from_extent
317
+ ul = geo_transform.apply_geo_transform(0, 0)
318
+ ur = geo_transform.apply_geo_transform(raster_x_size, 0)
319
+ lr = geo_transform.apply_geo_transform(raster_x_size, raster_y_size)
320
+ ll = geo_transform.apply_geo_transform(0, raster_y_size)
321
+
322
+ ring = OGR::LinearRing.new
323
+ ring.point_count = 5
324
+ ring.set_point(0, ul[:x_geo], ul[:y_geo])
325
+ ring.set_point(1, ur[:x_geo], ur[:y_geo])
326
+ ring.set_point(2, lr[:x_geo], lr[:y_geo])
327
+ ring.set_point(3, ll[:x_geo], ll[:y_geo])
328
+ ring.set_point(4, ul[:x_geo], ul[:y_geo])
329
+
330
+ polygon = OGR::Polygon.new
331
+ polygon.add_geometry(ring)
332
+ polygon.spatial_reference = spatial_reference
333
+
334
+ polygon
314
335
  end
315
336
 
316
337
  # @param wkt_geometry_string [String]
@@ -328,56 +349,6 @@ module GDAL
328
349
  @raster_geometry.contains? source_geometry
329
350
  end
330
351
 
331
- def image_warp(destination_file, driver, band_numbers, **warp_options)
332
- fail NotImplementedError, '#image_warp not yet implemented.'
333
-
334
- _options_ptr = GDAL::Options.pointer(warp_options)
335
- driver = GDAL::Driver.by_name(driver)
336
- destination_dataset = driver.create_dataset(destination_file, raster_x_size, raster_y_size)
337
-
338
- band_numbers = band_numbers.is_a?(Array) ? band_numbers : [band_numbers]
339
- log "band numbers: #{band_numbers}"
340
-
341
- bands_ptr = FFI::MemoryPointer.new(:pointer, band_numbers.size)
342
- bands_ptr.write_array_of_int(band_numbers)
343
- log "band numbers ptr null? #{bands_ptr.null?}"
344
-
345
- warp_options_struct = FFI::GDAL::WarpOptions.new
346
-
347
- warp_options.each do |k, _|
348
- warp_options_struct[k] = warp_options[k]
349
- end
350
-
351
- warp_options[:source_dataset] = c_pointer
352
- warp_options[:destination_dataset] = destination_dataset.c_pointer
353
- warp_options[:band_count] = band_numbers.size
354
- warp_options[:source_bands] = bands_ptr
355
- warp_options[:transformer] = transformer
356
- warp_options[:transformer_arg] = transformer_arg
357
-
358
- log "transformer: #{transformer}"
359
- error_threshold = 0.0
360
- order = 0
361
-
362
- _transformer_ptr = FFI::GDAL::Alg.GDALCreateGenImgProjTransformer(@c_pointer,
363
- projection,
364
- destination_dataset.c_pointer,
365
- destination.projection,
366
- false,
367
- error_threshold,
368
- order)
369
-
370
- warp_operation = GDAL::WarpOperation.new(warp_options)
371
- warp_operation.chunk_and_warp_image(0, 0, raster_x_size, raster_y_size)
372
- transformer.destroy!
373
- warp_operation.destroy!
374
-
375
- destination = GDAL::Dataset.new(destination_dataset_ptr)
376
- destination.close
377
-
378
- destination
379
- end
380
-
381
352
  # Retrieves pixels from each raster band and converts this to an array of
382
353
  # points per pixel. For example:
383
354
  #
@@ -1,5 +1,3 @@
1
- require_relative '../../ffi/gdal/matching'
2
-
3
1
  module GDAL
4
2
  module DatasetMixins
5
3
  module Matching
@@ -0,0 +1,42 @@
1
+ module GDAL
2
+ module DatasetMixins
3
+ # Methods used for warping; most taken from gdalwarper.h.
4
+ module WarpMethods
5
+ # @param destination_dataset [GDAL::Dataset]
6
+ # @param resample_algorithm [Symbol] One from FFI::GDAL::Warper::GDALResampleAlg.
7
+ # @param destination_spatial_reference [OGR::SpatialReference]
8
+ # @param warp_memory_limit [Float] The amount of memory (in bytes) the API
9
+ # is allowed to use for caching. This is in addition to the amount of
10
+ # memory already allocated for caching (using GDALSetCacheMax). 0.0 uses
11
+ # default settings.
12
+ # @param max_error [Float] Maximum error, measured in input pixels that is
13
+ # allowed in approximating the transformation. Defaults to 0.0.
14
+ # @param progress_function [Proc, FFI::GDAL::GDAL::GDALProgressFunc] A
15
+ # callback for reporting progress.
16
+ # @param progress_arg [FFI::Pointer] Argument to be passed to
17
+ # +progress_function+.
18
+ # @param options [Hash] Warp options, normally empty.
19
+ def reproject_image(destination_dataset, resample_algorithm, destination_spatial_reference: nil,
20
+ warp_memory_limit: 0.0, max_error: 0.0, progress_function: nil, progress_arg: nil, **options)
21
+ destination_spatial_reference_wkt = if destination_spatial_reference
22
+ destination_spatial_reference.to_wkt
23
+ end
24
+
25
+ options_ptr = GDAL::Options.pointer(options)
26
+
27
+ FFI::GDAL::Warper.GDALReprojectImage(
28
+ @c_pointer, # hSrcDS
29
+ nil, # pszSrcWKT
30
+ destination_dataset.c_pointer, # hDstDS
31
+ destination_spatial_reference_wkt, # pszDstWKT
32
+ resample_algorithm, # eResampleAlg
33
+ warp_memory_limit, # dfWarpMemoryLimit
34
+ max_error, # dfMaxError
35
+ progress_function, # pfnProgress
36
+ progress_arg, # pProgressArg
37
+ options_ptr # psOptions
38
+ )
39
+ end
40
+ end
41
+ end
42
+ end
data/lib/gdal/driver.rb CHANGED
@@ -1,10 +1,7 @@
1
- require_relative '../ffi/gdal'
1
+ require 'multi_xml'
2
+ require_relative '../gdal'
2
3
  require_relative 'major_object'
3
- require_relative 'exceptions'
4
4
  require_relative 'driver_mixins/extensions'
5
- require_relative 'dataset'
6
- require_relative 'options'
7
- require 'multi_xml'
8
5
 
9
6
  module GDAL
10
7
  # Wrapper for GDAL drivers (aka "formats"). Useful for opening and working
@@ -14,11 +11,11 @@ module GDAL
14
11
  include GDAL::Logger
15
12
  include DriverMixins::Extensions
16
13
 
17
- GDAL_DOCS_URL = 'http://gdal.org'
14
+ GDAL_DOCS_URL = 'http://gdal.org'.freeze
18
15
 
19
16
  # @return [Fixnum]
20
17
  def self.count
21
- FFI::GDAL.GDALGetDriverCount
18
+ FFI::GDAL::GDAL.GDALGetDriverCount
22
19
  end
23
20
 
24
21
  # @param name [String] Short name of the registered GDALDriver.
@@ -26,10 +23,10 @@ module GDAL
26
23
  # @raise [GDAL::InvalidDriverName] If +name+ does not represent a valid
27
24
  # driver name.
28
25
  def self.by_name(name)
29
- driver_ptr = FFI::GDAL.GDALGetDriverByName(name)
26
+ driver_ptr = FFI::GDAL::GDAL.GDALGetDriverByName(name)
30
27
 
31
28
  if driver_ptr.null?
32
- fail InvalidDriverName, "'#{name}' is not a valid driver name."
29
+ raise InvalidDriverName, "'#{name}' is not a valid driver name."
33
30
  end
34
31
 
35
32
  new(driver_ptr)
@@ -41,10 +38,10 @@ module GDAL
41
38
  # @raise [GDAL::InvalidDriverIndex] If driver at +index+ does not exist.
42
39
  def self.at_index(index)
43
40
  if index > count
44
- fail InvalidDriverIndex, "index must be between 0 and #{count - 1}."
41
+ raise InvalidDriverIndex, "index must be between 0 and #{count - 1}."
45
42
  end
46
43
 
47
- driver_ptr = FFI::GDAL.GDALGetDriver(index)
44
+ driver_ptr = FFI::GDAL::GDAL.GDALGetDriver(index)
48
45
 
49
46
  new(driver_ptr)
50
47
  end
@@ -52,7 +49,7 @@ module GDAL
52
49
  # @param file_path [String] File to get the driver for.
53
50
  # @return [GDAL::Driver] Returns nil if the file is unsupported.
54
51
  def self.identify_driver(file_path)
55
- driver_ptr = FFI::GDAL.GDALIdentifyDriver(::File.expand_path(file_path), nil)
52
+ driver_ptr = FFI::GDAL::GDAL.GDALIdentifyDriver(::File.expand_path(file_path), nil)
56
53
  return nil if driver_ptr.null?
57
54
 
58
55
  new(driver_ptr)
@@ -67,17 +64,17 @@ module GDAL
67
64
 
68
65
  # @return [String]
69
66
  def short_name
70
- FFI::GDAL.GDALGetDriverShortName(@c_pointer)
67
+ FFI::GDAL::GDAL.GDALGetDriverShortName(@c_pointer)
71
68
  end
72
69
 
73
70
  # @return [String]
74
71
  def long_name
75
- FFI::GDAL.GDALGetDriverLongName(@c_pointer)
72
+ FFI::GDAL::GDAL.GDALGetDriverLongName(@c_pointer)
76
73
  end
77
74
 
78
75
  # @return [String]
79
76
  def help_topic
80
- "#{GDAL_DOCS_URL}/#{FFI::GDAL.GDALGetDriverHelpTopic(@c_pointer)}"
77
+ "#{GDAL_DOCS_URL}/#{FFI::GDAL::GDAL.GDALGetDriverHelpTopic(@c_pointer)}"
81
78
  end
82
79
 
83
80
  # Lists and describes the options that can be used when calling
@@ -87,7 +84,7 @@ module GDAL
87
84
  def creation_option_list
88
85
  return [] unless @c_pointer
89
86
 
90
- creation_option_list_xml = FFI::GDAL.GDALGetDriverCreationOptionList(@c_pointer)
87
+ creation_option_list_xml = FFI::GDAL::GDAL.GDALGetDriverCreationOptionList(@c_pointer)
91
88
  root = MultiXml.parse(creation_option_list_xml)
92
89
  return [] if root.nil? || root.empty?
93
90
 
@@ -106,7 +103,7 @@ module GDAL
106
103
  GDAL::Options.pointer(options)
107
104
  end
108
105
 
109
- FFI::GDAL.GDALValidateCreationOptions(@c_pointer, options_pointer).to_bool
106
+ FFI::GDAL::GDAL.GDALValidateCreationOptions(@c_pointer, options_pointer)
110
107
  end
111
108
 
112
109
  # Copy all of the associated files of a dataset from one file to another.
@@ -116,7 +113,7 @@ module GDAL
116
113
  # @return true on success, false on warning.
117
114
  # @raise [GDAL::CPLErrFailure] If failures.
118
115
  def copy_dataset_files(old_name, new_name)
119
- FFI::GDAL.GDALCopyDatasetFiles(@c_pointer, new_name, old_name)
116
+ FFI::GDAL::GDAL.GDALCopyDatasetFiles(@c_pointer, new_name, old_name)
120
117
  end
121
118
 
122
119
  # Create a new Dataset with this driver. Legal arguments depend on the
@@ -127,13 +124,14 @@ module GDAL
127
124
  # @param x_size [Fixnum] Width of created raster in pixels.
128
125
  # @param y_size [Fixnum] Height of created raster in pixels.
129
126
  # @param band_count [Fixnum]
130
- # @param data_type [FFI::GDAL::DataType]
131
- # @return [GDAL::Dataset] Returns the *open* dataset. You'll need to
132
- # close it.
127
+ # @param data_type [FFI::GDAL::GDAL::DataType]
128
+ # @return [GDAL::Dataset] If no block is given, returns the *open*
129
+ # (writable) dataset; you'll need to close it. If a block is given,
130
+ # returns the result of the block.
133
131
  def create_dataset(filename, x_size, y_size, band_count: 1, data_type: :GDT_Byte, **options)
134
132
  options_pointer = GDAL::Options.pointer(options)
135
133
 
136
- dataset_pointer = FFI::GDAL.GDALCreate(
134
+ dataset_pointer = FFI::GDAL::GDAL.GDALCreate(
137
135
  @c_pointer,
138
136
  filename,
139
137
  x_size,
@@ -143,43 +141,62 @@ module GDAL
143
141
  options_pointer
144
142
  )
145
143
 
146
- fail CreateFail if dataset_pointer.null?
144
+ raise CreateFail if dataset_pointer.null?
145
+
146
+ dataset = GDAL::Dataset.new(dataset_pointer, 'w')
147
147
 
148
- dataset = GDAL::Dataset.new(dataset_pointer, nil)
149
- yield(dataset) if block_given?
148
+ if block_given?
149
+ result = yield(dataset)
150
+ dataset.close
150
151
 
151
- dataset
152
+ result
153
+ else
154
+ dataset
155
+ end
152
156
  end
153
157
 
158
+ # Copies +source_dataset+ to +destination_path+. Will yield a writable
159
+ # {{GDAL::Dataset}} of the destination dataset then close it if a block is
160
+ # given.
161
+ #
154
162
  # @param source_dataset [GDAL::Dataset, FFI::Pointer] The dataset to copy.
155
163
  # @param destination_path [String] The name for the new dataset file.
156
164
  # @param strict [Boolean] +false+ indicates the copy may adapt as needed for
157
165
  # the output format.
158
166
  # @param options [Hash]
159
- # @param progress [Proc] For outputting copy progress. Conforms to the
160
- # FFI::GDAL::GDALProgressFunc signature.
161
- def copy_dataset(source_dataset, destination_path, strict: true, **options, &progress)
162
- options_ptr = GDAL::Options.pointer(options)
167
+ # @param progress_block [Proc, FFI::GDAL::GDAL.GDALProgressFunc] For
168
+ # outputting copy progress. Conforms to the
169
+ # FFI::GDAL::GDAL.GDALProgressFunc signature.
170
+ # @param progress_arg [Proc]
171
+ # @return [true]
172
+ # @raise [GDAL::CreateFail] if it couldn't copy the dataset.
173
+ # @yieldparam destination_dataset [GDAL::Dataset]
174
+ def copy_dataset(source_dataset, destination_path, progress_block = nil, progress_arg = nil, strict: true,
175
+ **options)
163
176
  source_dataset_ptr = make_dataset_pointer(source_dataset)
164
- fail "Source dataset couldn't be read" if source_dataset_ptr.null?
177
+ raise GDAL::OpenFailure, "Source dataset couldn't be read" if source_dataset_ptr && source_dataset_ptr.null?
178
+
179
+ options_ptr = GDAL::Options.pointer(options)
165
180
 
166
- destination_dataset_ptr = FFI::GDAL.GDALCreateCopy(
181
+ destination_dataset_ptr = FFI::GDAL::GDAL.GDALCreateCopy(
167
182
  @c_pointer,
168
183
  destination_path,
169
184
  source_dataset_ptr,
170
185
  strict,
171
186
  options_ptr,
172
- progress,
173
- nil
187
+ progress_block,
188
+ progress_arg
174
189
  )
175
190
 
176
- fail CreateFail if destination_dataset_ptr.null?
191
+ raise CreateFail if destination_dataset_ptr.nil? || destination_dataset_ptr.null?
177
192
 
178
- dataset = Dataset.new(destination_dataset_ptr, 'w')
179
- yield(dataset) if block_given?
180
- dataset.close
193
+ if block_given?
194
+ dataset = Dataset.new(destination_dataset_ptr, 'w')
195
+ yield(dataset)
196
+ dataset.close
197
+ end
181
198
 
182
- dataset
199
+ true
183
200
  end
184
201
 
185
202
  # Delete the dataset represented by +file_name+. Depending on the driver,
@@ -189,15 +206,15 @@ module GDAL
189
206
  # @return true on success, false on warning.
190
207
  # @raise [GDAL::CPLErrFailure] If failures.
191
208
  def delete_dataset(file_name)
192
- FFI::GDAL.GDALDeleteDataset(@c_pointer, file_name)
209
+ FFI::GDAL::GDAL.GDALDeleteDataset(@c_pointer, file_name)
193
210
  end
194
211
 
195
- # @param new_name [String]
196
212
  # @param old_name [String]
213
+ # @param new_name [String]
197
214
  # @return true on success, false on warning.
198
215
  # @raise [GDAL::CPLErrFailure] If failures.
199
- def rename_dataset(new_name, old_name)
200
- FFI::GDAL.GDALRenameDataset(@c_pointer, new_name, old_name)
216
+ def rename_dataset(old_name, new_name)
217
+ FFI::GDAL::GDAL.GDALRenameDataset(@c_pointer, new_name, old_name)
201
218
  end
202
219
 
203
220
  private
@@ -206,12 +223,10 @@ module GDAL
206
223
  # dataset, the pointer to another dataset, or the path to a dataset.
207
224
  # @return [GDAL::Dataset]
208
225
  def make_dataset_pointer(dataset)
209
- if dataset.is_a? GDAL::Dataset
210
- dataset.c_pointer
211
- elsif dataset.is_a? String
226
+ if dataset.is_a? String
212
227
  GDAL::Dataset.open(dataset, 'r').c_pointer
213
228
  else
214
- dataset
229
+ GDAL._pointer(GDAL::Dataset, dataset)
215
230
  end
216
231
  end
217
232
  end
@@ -8,19 +8,14 @@ module GDAL
8
8
  module ClassMethods
9
9
  # @return [Array<String>]
10
10
  def short_names
11
- names = count.times.map do |i|
12
- driver = at_index(i)
13
- driver.short_name
14
- end
11
+ names = Array.new(count) { |i| at_index(i).short_name }
15
12
 
16
13
  names.compact.sort
17
14
  end
18
15
 
19
16
  # @return [Array<String>]
20
17
  def long_names
21
- names = count.times.map do |i|
22
- at_index(i).long_name
23
- end
18
+ names = Array.new(count) { |i| at_index(i).long_name }
24
19
 
25
20
  names.compact.sort
26
21
  end
@@ -1,43 +1,46 @@
1
1
  module GDAL
2
+ # Getters and setters for the GDAL environment.
2
3
  module EnvironmentMethods
3
4
  # @return [Fixnum] The maximum cache memory.
4
5
  def cache_max
5
- FFI::GDAL.GDALGetCacheMax
6
+ FFI::GDAL::GDAL.GDALGetCacheMax
6
7
  end
7
8
 
8
9
  # @param bytes [Fixnum]
9
10
  def cache_max=(bytes)
10
- FFI::GDAL.GDALSetCacheMax(bytes)
11
+ FFI::GDAL::GDAL.GDALSetCacheMax(bytes)
11
12
  end
12
13
 
13
14
  # @return [Fixnum] The maximum cache memory.
14
15
  def cache_max64
15
- FFI::GDAL.GDALGetCacheMax64
16
+ FFI::GDAL::GDAL.GDALGetCacheMax64
16
17
  end
17
18
 
18
19
  # @param bytes [Fixnum]
19
20
  def cache_max64=(bytes)
20
- FFI::GDAL.GDALSetCacheMax64(bytes)
21
+ FFI::GDAL::GDAL.GDALSetCacheMax64(bytes)
21
22
  end
22
23
 
23
24
  # @return [Fixnum] The amount of used cache memory.
24
25
  def cache_used
25
- FFI::GDAL.GDALGetCacheUsed
26
+ FFI::GDAL::GDAL.GDALGetCacheUsed
26
27
  end
27
28
 
28
29
  # @return [Fixnum] The amount of used cache memory.
29
30
  def cache_used64
30
- FFI::GDAL.GDALGetCacheUsed64
31
+ FFI::GDAL::GDAL.GDALGetCacheUsed64
31
32
  end
32
33
 
33
34
  # @return [Boolean]
34
35
  def flush_cache_block
35
- FFI::GDAL.GDALFlushCacheBlock
36
+ FFI::GDAL::GDAL.GDALFlushCacheBlock
36
37
  end
37
38
 
38
- # @param file_name [String]
39
- def dump_open_datasets(file_name)
40
- FFI::GDAL.GDALDumpOpenDatasets(file_name)
39
+ # @param file_path [String]
40
+ def dump_open_datasets(file_path)
41
+ file_ptr = FFI::CPL::Conv.CPLOpenShared(file_path, 'w', false)
42
+ FFI::GDAL::GDAL.GDALDumpOpenDatasets(file_ptr)
43
+ FFI::CPL::Conv.CPLCloseShared(file_ptr)
41
44
  end
42
45
  end
43
46
  end
@@ -1,4 +1,7 @@
1
1
  module GDAL
2
+ class BufferTooSmall < StandardError
3
+ end
4
+
2
5
  class CreateFail < StandardError
3
6
  end
4
7
 
@@ -12,25 +15,41 @@ module GDAL
12
15
  end
13
16
  end
14
17
 
18
+ class InvalidAccessFlag < RuntimeError
19
+ end
20
+
15
21
  class InvalidBandNumber < StandardError
16
22
  end
17
23
 
18
24
  class InvalidColorTable < StandardError
19
25
  end
20
26
 
27
+ class InvalidDataType < StandardError
28
+ end
29
+
21
30
  class InvalidDriverIndex < StandardError
22
31
  end
23
32
 
24
33
  class InvalidDriverName < StandardError
25
34
  end
26
35
 
36
+ class InvalidGeoTransform < StandardError
37
+ end
38
+
27
39
  class InvalidRasterBand < StandardError
28
40
  end
29
41
 
30
- class NoWriteAccess < RuntimeError
42
+ # Used when a RasterBand erase operation can't find a value to use to set for
43
+ # values to erase.
44
+ class NoRasterEraseValue < RuntimeError
31
45
  end
32
46
 
33
- class InvalidAccessFlag < RuntimeError
47
+ # Indicates that neither field attributes were selected nor Z fields were
48
+ # provided to allow for gridding.
49
+ class NoValuesToGrid < RuntimeError
50
+ end
51
+
52
+ class NoWriteAccess < RuntimeError
34
53
  end
35
54
 
36
55
  class NullObject < TypeError
@@ -46,6 +65,9 @@ module GDAL
46
65
  end
47
66
  end
48
67
 
68
+ class UnknownRasterAttributeTableType < StandardError
69
+ end
70
+
49
71
  class UnsupportedOperation < StandardError
50
72
  end
51
73
  end
@@ -1,4 +1,4 @@
1
- require_relative '../ffi/gdal'
1
+ require_relative '../gdal'
2
2
  require_relative 'geo_transform_mixins/extensions'
3
3
 
4
4
  module GDAL
@@ -21,9 +21,9 @@ module GDAL
21
21
  gt_ptr = new_pointer
22
22
 
23
23
  result = if extension
24
- FFI::GDAL.GDALReadWorldFile(filename, extension, gt_ptr)
24
+ FFI::GDAL::GDAL.GDALReadWorldFile(filename, extension, gt_ptr)
25
25
  else
26
- FFI::GDAL.GDALLoadWorldFile(filename, gt_ptr)
26
+ FFI::GDAL::GDAL.GDALLoadWorldFile(filename, gt_ptr)
27
27
  end
28
28
 
29
29
  return nil unless result
@@ -33,13 +33,7 @@ module GDAL
33
33
 
34
34
  # @param geo_transform [FFI::Pointer]
35
35
  def initialize(geo_transform = nil)
36
- @c_pointer = if geo_transform.is_a? GDAL::GeoTransform
37
- geo_transform.c_pointer
38
- elsif geo_transform
39
- geo_transform
40
- else
41
- self.class.new_pointer
42
- end
36
+ @c_pointer = geo_transform ? GDAL._pointer(GDAL::GeoTransform, geo_transform) : self.class.new_pointer
43
37
 
44
38
  self.pixel_width ||= 1.0
45
39
  self.pixel_height ||= 1.0
@@ -160,11 +154,11 @@ module GDAL
160
154
  def apply_geo_transform(pixel, line)
161
155
  geo_x_ptr = FFI::MemoryPointer.new(:double)
162
156
  geo_y_ptr = FFI::MemoryPointer.new(:double)
163
- FFI::GDAL.GDALApplyGeoTransform(@c_pointer, pixel, line, geo_x_ptr, geo_y_ptr)
157
+ FFI::GDAL::GDAL.GDALApplyGeoTransform(@c_pointer, pixel, line, geo_x_ptr, geo_y_ptr)
164
158
 
165
159
  { x_geo: geo_x_ptr.read_double, y_geo: geo_y_ptr.read_double }
166
160
  end
167
- alias_method :pixel_to_world, :apply_geo_transform
161
+ alias pixel_to_world apply_geo_transform
168
162
 
169
163
  # Composes this and the given geo_transform. The resulting GeoTransform is
170
164
  # equivalent to applying both GeoTransforms to a point.
@@ -175,11 +169,11 @@ module GDAL
175
169
  other_ptr = GDAL._pointer(GDAL::GeoTransform, other_geo_transform)
176
170
 
177
171
  unless other_ptr
178
- fail GDAL::NullObject, "Unable to access pointer for '#{other_geo_transform}'"
172
+ raise GDAL::NullObject, "Unable to access pointer for '#{other_geo_transform}'"
179
173
  end
180
174
 
181
175
  new_gt_ptr = self.class.new_pointer
182
- FFI::GDAL.GDALComposeGeoTransforms(@c_pointer, other_ptr, new_gt_ptr)
176
+ FFI::GDAL::GDAL.GDALComposeGeoTransforms(@c_pointer, other_ptr, new_gt_ptr)
183
177
  return nil if new_gt_ptr.null?
184
178
 
185
179
  GDAL::GeoTransform.new(new_gt_ptr)
@@ -192,7 +186,7 @@ module GDAL
192
186
  # @return [GDAL::GeoTransform]
193
187
  def invert
194
188
  new_geo_transform_ptr = self.class.new_pointer
195
- success = FFI::GDAL.GDALInvGeoTransform(@c_pointer, new_geo_transform_ptr)
189
+ success = FFI::GDAL::GDAL.GDALInvGeoTransform(@c_pointer, new_geo_transform_ptr)
196
190
  return nil unless success
197
191
 
198
192
  self.class.new(new_geo_transform_ptr)
@@ -202,7 +196,7 @@ module GDAL
202
196
  # @param world_extension [String]
203
197
  # @return [Boolean]
204
198
  def to_world_file(raster_filename, world_extension)
205
- FFI::GDAL.GDALWriteWorldFile(raster_filename, world_extension, @c_pointer)
199
+ FFI::GDAL::GDAL.GDALWriteWorldFile(raster_filename, world_extension, @c_pointer)
206
200
  end
207
201
  end
208
202
  end