ffi-gdal 1.0.0.beta6 → 1.0.0.beta7

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/History.md +40 -0
  3. data/bitbucket-pipelines.yml +16 -0
  4. data/lib/ffi/gdal/version.rb +1 -1
  5. data/lib/ffi/gdal/warp_options.rb +18 -4
  6. data/lib/ffi/gdal/warper.rb +17 -1
  7. data/lib/ffi/gdal.rb +1 -1
  8. data/lib/gdal/color_entry_mixins/extensions.rb +0 -14
  9. data/lib/gdal/color_table_mixins/extensions.rb +0 -14
  10. data/lib/gdal/dataset_mixins/algorithm_methods.rb +2 -2
  11. data/lib/gdal/dataset_mixins/extensions.rb +3 -43
  12. data/lib/gdal/dataset_mixins/warp_methods.rb +50 -11
  13. data/lib/gdal/geo_transform_mixins/extensions.rb +0 -17
  14. data/lib/gdal/grid.rb +2 -1
  15. data/lib/gdal/gridder/point_extracting.rb +1 -2
  16. data/lib/gdal/gridder.rb +7 -2
  17. data/lib/gdal/options.rb +14 -13
  18. data/lib/gdal/raster_attribute_table_mixins/extensions.rb +0 -15
  19. data/lib/gdal/raster_band.rb +5 -3
  20. data/lib/gdal/raster_band_classifier.rb +5 -3
  21. data/lib/gdal/raster_band_mixins/extensions.rb +0 -35
  22. data/lib/gdal/raster_band_mixins/io_extensions.rb +4 -3
  23. data/lib/gdal/warp_options.rb +99 -35
  24. data/lib/gdal.rb +1 -0
  25. data/lib/ogr/data_source_extensions.rb +0 -19
  26. data/lib/ogr/envelope_extensions.rb +0 -22
  27. data/lib/ogr/feature_definition_extensions.rb +0 -18
  28. data/lib/ogr/feature_extensions.rb +0 -27
  29. data/lib/ogr/field_definition.rb +0 -3
  30. data/lib/ogr/geometry.rb +0 -1
  31. data/lib/ogr/geometry_field_definition.rb +0 -4
  32. data/lib/ogr/geometry_mixins/extensions.rb +0 -29
  33. data/lib/ogr/geometry_types/curve.rb +1 -1
  34. data/lib/ogr/layer.rb +3 -1
  35. data/lib/ogr/layer_mixins/extensions.rb +1 -25
  36. data/lib/ogr/spatial_reference.rb +10 -2
  37. data/lib/ogr/spatial_reference_extensions.rb +0 -26
  38. data/lib/ogr/style_table_extensions.rb +0 -10
  39. data/spec/integration/gdal/raster_band_info_spec.rb +27 -5
  40. data/spec/integration/ogr/layer_spec.rb +0 -6
  41. data/spec/support/images/123.tiff +0 -0
  42. data/spec/unit/ffi/gdal_spec.rb +1 -0
  43. data/spec/unit/gdal/dataset_mixins/warp_methods_spec.rb +52 -0
  44. data/spec/unit/gdal/geo_transform_spec.rb +0 -13
  45. data/spec/unit/gdal/grid_spec.rb +8 -0
  46. data/spec/unit/gdal/gridder_spec.rb +40 -0
  47. data/spec/unit/gdal/options_spec.rb +26 -1
  48. data/spec/unit/gdal/warp_options_spec.rb +336 -0
  49. data/spec/unit/ogr/feature_definition_spec.rb +0 -19
  50. data/spec/unit/ogr/feature_extensions_spec.rb +1 -1
  51. data/spec/unit/ogr/field_definition_spec.rb +0 -19
  52. data/spec/unit/ogr/geometry_field_definition_spec.rb +0 -16
  53. data/spec/unit/ogr/style_table_spec.rb +0 -26
  54. metadata +10 -5
  55. data/lib/ogr/field_definition_extensions.rb +0 -22
  56. data/lib/ogr/geometry_field_definition_extensions.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 82ca64b9a92e057bf506f537804b6e26aee42281
4
- data.tar.gz: 96ce8a17293f28885113c73df4f06b53780a518d
3
+ metadata.gz: d67e9f4bf5c35dd5b8fd8bc6661eb1e4d6d3ae26
4
+ data.tar.gz: bc17e333a2f17d7da911db39cdbfd7494dc620d2
5
5
  SHA512:
6
- metadata.gz: 0c44973c096820715f5c8860c5ac55f85fa90b94f06a88fec64e257e78478c64f192d4938ec25b38efbac6e74f29289b5ff7cf93a229864c0416365bb058a33c
7
- data.tar.gz: f9a8fba2bdcbe83bb2359c48c4559e257b9fed4d30667eb8e878e7bdb0ac1e5afde35fce330636377f5ef7b1fec2bea6436fdd4b3a6088fed5cbb5014557ec52
6
+ metadata.gz: d6014e176cca5ba88ba825f4eaa2cc41f0117b70c402a622606e463ab21aa3c2a1d41b207edb0e5d1223ecfb95c7644d3a612d6ae265d680f737bd35a5104102
7
+ data.tar.gz: d88dd91735e49e182793c2bee36b78ab79dc761bec8ac89cecd01e453afb1f4ac30e5124025fcf474f9fae27e92043355981d2994c9123993c2de6e3b13421bd
data/History.md CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  Format for this file derived from [http://keepachangelog.com](http://keepachangelog.com).
4
4
 
5
+ ## 1.0.0.beta7 / 2016-09-21
6
+
7
+ ### Improvements
8
+
9
+ * Removed all `#as_json` and `#to_json` definitions. They were out of date, not
10
+ used, and sometimes confusing (ex OGR::Geometries#to_json vs #to_geo_json).
11
+
12
+ #### GDAL
13
+
14
+ * Added wrapper for GDALCreateAndReprojectImage in
15
+ `gdal/dataset_mixins/warp_methods.rb`.
16
+ * (BREAKING CHANGE) Additionally, changed
17
+ `GDAL::DatasetMixins::WarpMethods#reproject_image`'s
18
+ `destination_spatial_reference` named param to `destination_projection` which
19
+ takes a String of WKT for a projection instead of an `OGR::SpatialReference`.
20
+ * Added `GDAL::Options.to_hash` to convert a pointer of options to a Ruby Hash.
21
+ * Return `nil` for missing NODATA values in `GDAL::RasterBand#no_data_value` and
22
+ `#no_data_value=`.
23
+
24
+ ### Bug Fixes
25
+
26
+ #### Core
27
+
28
+ * Fixed specifying an alternate GDAL library using the `GDAL_LIBRARY_PATH`.
29
+
30
+ #### GDAL
31
+
32
+ * `GDAL::RasterBandMixins::IOExtensions#write_xy_narray` no longer duplicates
33
+ data when blocks have a remainder.
34
+ * `GDAL::WarpOptions` should properly act as a wrapper for `FFI::GDAL::WarpOptions`.
35
+ * `Updated extract methods to be compatible with latest `GDAL::Driver#create_dataset`.
36
+ * `GDAL::MajorObject` now gets autoloaded.
37
+ * Fix `GDAL::DatasetMixins::AlgorithmMethods` to use the right `FFI` module for
38
+ `#rasterize_geometries` and `#rasterize_layers`.
39
+
40
+ #### OGR
41
+
42
+ * [AGDEV-17357] Define constants from C using `const_set` instead of `class_eval`.
43
+ * Fixed `OGR::GeometryTypes::Curve#points` (missing local variable).
44
+
5
45
  ## 1.0.0.beta6 / 2016-04-18
6
46
 
7
47
  ### New Features
@@ -0,0 +1,16 @@
1
+ # You can use a Docker image from Docker Hub or your own container
2
+ # registry for your build environment.
3
+ image: agrian/ubuntugis-ruby:latest
4
+
5
+ pipelines:
6
+ default:
7
+ - step:
8
+ script: # Modify the commands below to build your repository.
9
+ - ruby --version
10
+ - gem install bundler
11
+ - gem sources -a http://$AGRIAN_GEMS_USERNAME:$AGRIAN_GEMS_PASSWORD@gems.agrian.com/
12
+ - bundle config gems.agrian.com $AGRIAN_GEMS_USERNAME:$AGRIAN_GEMS_PASSWORD
13
+ - bundler --version
14
+ - bundle install
15
+ - bundle exec rake spec
16
+ # - bundle exec rubocop
@@ -1,5 +1,5 @@
1
1
  module FFI
2
2
  module GDAL
3
- VERSION = '1.0.0.beta6'.freeze
3
+ VERSION = '1.0.0.beta7'.freeze
4
4
  end
5
5
  end
@@ -5,41 +5,55 @@ module FFI
5
5
  class WarpOptions < FFI::Struct
6
6
  layout :warp_operation_options, :pointer,
7
7
  :warp_memory_limit, :double,
8
+
8
9
  :resample_alg, FFI::GDAL::Warper::ResampleAlg,
9
10
  :working_data_type, FFI::GDAL::GDAL::DataType,
10
11
  :source_dataset, GDAL.find_type(:GDALDatasetH),
11
12
  :destination_dataset, GDAL.find_type(:GDALDatasetH),
13
+
12
14
  :band_count, :int,
13
15
  :source_bands, :pointer,
14
16
  :destination_bands, :pointer,
15
17
  :source_alpha_band, :int,
16
18
  :destination_alpha_band, :int,
19
+
17
20
  :source_no_data_real, :pointer,
18
21
  :source_no_data_imaginary, :pointer,
19
22
  :destination_no_data_real, :pointer,
20
23
  :destination_no_data_imaginary, :pointer,
24
+
21
25
  :progress, GDAL.find_type(:GDALProgressFunc),
22
26
  :progress_arg, :pointer,
23
27
  :transformer, Alg.find_type(:GDALTransformerFunc),
24
28
  :transformer_arg, :pointer,
29
+
25
30
  :source_per_band_validity_mask_function, :pointer,
26
31
  :source_per_band_validity_mask_function_arg, :pointer,
32
+
27
33
  :source_validity_mask_function, Warper.find_type(:GDALMaskFunc),
28
34
  :source_validity_mask_function_arg, :pointer,
35
+
29
36
  :source_density_mask_function, Warper.find_type(:GDALMaskFunc),
30
37
  :source_density_mask_function_arg, :pointer,
38
+
31
39
  :destination_density_mask_function, Warper.find_type(:GDALMaskFunc),
32
40
  :destination_density_mask_function_arg, :pointer,
41
+
33
42
  :destination_validity_mask_function, Warper.find_type(:GDALMaskFunc),
34
43
  :destination_validity_mask_function_arg, :pointer,
35
- # :pre_warp_chunk_processor, CPL::Error::CPLErr,
36
- :pre_warp_chunk_processor, :pointer,
44
+
45
+ :pre_warp_chunk_processor, callback(%i[pointer pointer], CPL::Error::CPLErr),
37
46
  :pre_warp_processor_arg, :pointer,
38
- # :post_warp_chunk_processor, CPL::Error::CPLErr,
39
- :post_warp_chunk_processor, :pointer,
47
+ :post_warp_chunk_processor, callback(%i[pointer pointer], CPL::Error::CPLErr),
40
48
  :post_warp_processor_arg, :pointer,
49
+
41
50
  :cutline, :pointer,
42
51
  :cutline_blend_distance, :double
52
+
53
+ def initialize
54
+ super
55
+ self[:progress] = proc { true } if self[:progress].null?
56
+ end
43
57
  end
44
58
  end
45
59
  end
@@ -11,7 +11,7 @@ module FFI
11
11
  # Typedefs
12
12
  #------------------------------------------------------------------------
13
13
  typedef :pointer, :GDALWarpOperationH
14
- callback :GDALMaskFunc,
14
+ MaskFunc = callback :GDALMaskFunc,
15
15
  [
16
16
  :pointer,
17
17
  :int,
@@ -85,6 +85,22 @@ module FFI
85
85
  FFI::GDAL::WarpOptions.ptr
86
86
  ],
87
87
  CPL::Error::CPLErr
88
+ attach_function :GDALCreateAndReprojectImage,
89
+ [
90
+ FFI::GDAL::GDAL.find_type(:GDALDatasetH),
91
+ :string,
92
+ :string,
93
+ :string,
94
+ FFI::GDAL::GDAL.find_type(:GDALDriverH),
95
+ :pointer,
96
+ ResampleAlg,
97
+ :double,
98
+ :double,
99
+ FFI::GDAL::GDAL.find_type(:GDALProgressFunc),
100
+ :pointer,
101
+ FFI::GDAL::WarpOptions.ptr
102
+ ],
103
+ CPL::Error::CPLErr
88
104
  attach_function :GDALAutoCreateWarpedVRT,
89
105
  [
90
106
  FFI::GDAL::GDAL.find_type(:GDALDatasetH),
data/lib/ffi/gdal.rb CHANGED
@@ -35,7 +35,7 @@ module FFI
35
35
  lib_file_name = "#{lib}.#{FFI::Platform::LIBSUFFIX}*"
36
36
 
37
37
  if ENV['GDAL_LIBRARY_PATH']
38
- return File.join(ENV['GDAL_LIBRARY_PATH'], lib_file_name)
38
+ return Dir[File.join(ENV['GDAL_LIBRARY_PATH'], lib_file_name)]
39
39
  end
40
40
 
41
41
  search_paths.map do |search_path|
@@ -13,20 +13,6 @@ module GDAL
13
13
  [color1, color2, color3]
14
14
  end
15
15
  end
16
-
17
- def as_json(_options = nil)
18
- {
19
- color1: color1,
20
- color2: color2,
21
- color3: color3,
22
- color4: color4
23
- }
24
- end
25
-
26
- # @return [String]
27
- def to_json(options = nil)
28
- as_json(options).to_json
29
- end
30
16
  end
31
17
  end
32
18
  end
@@ -29,20 +29,6 @@ module GDAL
29
29
  color_entry_as_rgb(i)
30
30
  end
31
31
  end
32
-
33
- # @return [Hash]
34
- def as_json(_options = nil)
35
- {
36
- color_entry_count: color_entry_count,
37
- color_entries: color_entries.map(&:as_json),
38
- palette_interpretation: palette_interpretation
39
- }
40
- end
41
-
42
- # @return [String]
43
- def to_json(options = nil)
44
- as_json(options).to_json
45
- end
46
32
  end
47
33
  end
48
34
  end
@@ -40,7 +40,7 @@ module GDAL
40
40
  burn_values_ptr = FFI::MemoryPointer.new(:pointer, burn_values.size)
41
41
  burn_values_ptr.write_array_of_double(burn_values)
42
42
 
43
- FFI::GDAL::GDAL.GDALRasterizeGeometries(@c_pointer,
43
+ FFI::GDAL::Alg.GDALRasterizeGeometries(@c_pointer,
44
44
  band_numbers.size,
45
45
  band_numbers_ptr,
46
46
  geometries.size,
@@ -94,7 +94,7 @@ module GDAL
94
94
  burn_values_ptr.write_array_of_double(burn_values)
95
95
  log "burn value ptr null? #{burn_values_ptr.null?}"
96
96
 
97
- FFI::GDAL::GDAL.GDALRasterizeLayers(@c_pointer, # hDS
97
+ FFI::GDAL::Alg.GDALRasterizeLayers(@c_pointer, # hDS
98
98
  band_numbers.size, # nBandCount
99
99
  band_numbers_ptr, # panBandList
100
100
  layers.size, # nLayerCount
@@ -33,8 +33,6 @@ module GDAL
33
33
  # Defaults to -9999.0.
34
34
  # @param options [Hash] Options that get used for creating the new NDVI
35
35
  # dataset. See docs for GDAL::Driver#create_dataset.
36
- # @return [GDAL::Dataset] The new NDVI dataset. *Be sure to call #close on
37
- # this object or the data may not persist!*
38
36
  def extract_ndvi(destination, red_band_number, nir_band_number, driver_name: 'GTiff',
39
37
  output_data_type: nil, remove_negatives: false, no_data_value: -9999.0, **options)
40
38
  red = raster_band(red_band_number)
@@ -46,7 +44,7 @@ module GDAL
46
44
  the_array = calculate_ndvi(red.to_na, nir.to_na, no_data_value, remove_negatives, output_data_type)
47
45
  driver = GDAL::Driver.by_name(driver_name)
48
46
 
49
- ndvi = driver.create_dataset(destination, raster_x_size, raster_y_size,
47
+ driver.create_dataset(destination, raster_x_size, raster_y_size,
50
48
  data_type: output_data_type, **options) do |ndvi_dataset|
51
49
  ndvi_dataset.geo_transform = geo_transform
52
50
  ndvi_dataset.projection = projection
@@ -55,10 +53,6 @@ module GDAL
55
53
  ndvi_band.write_xy_narray(the_array)
56
54
  ndvi_band.no_data_value = no_data_value
57
55
  end
58
-
59
- ndvi.close
60
-
61
- ndvi
62
56
  end
63
57
 
64
58
  # Extracts the NIR band and writes to a new file. NOTE: be sure to close
@@ -74,8 +68,6 @@ module GDAL
74
68
  # in this data type. Defaults to use the current data type.
75
69
  # @param options [Hash] Options that get used for creating the new NDVI
76
70
  # dataset. See docs for GDAL::Driver#create_dataset.
77
- # @return [GDAL::Dataset] The new NIR dataset. *Be sure to call #close on
78
- # this object or the data may not persist!*
79
71
  def extract_nir(destination, band_number, driver_name: 'GTiff', output_data_type: nil, **options)
80
72
  original_nir_band = raster_band(band_number)
81
73
  raise InvalidBandNumber, "Band #{band_number} found but was nil." if original_nir_band.nil?
@@ -83,7 +75,7 @@ module GDAL
83
75
  output_data_type ||= original_nir_band.data_type
84
76
  driver = GDAL::Driver.by_name(driver_name)
85
77
 
86
- nir = driver.create_dataset(destination, raster_x_size, raster_y_size,
78
+ driver.create_dataset(destination, raster_x_size, raster_y_size,
87
79
  data_type: output_data_type, **options) do |nir_dataset|
88
80
  nir_dataset.geo_transform = geo_transform
89
81
  nir_dataset.projection = projection
@@ -91,10 +83,6 @@ module GDAL
91
83
  nir_band = nir_dataset.raster_band(1)
92
84
  original_nir_band.copy_whole_raster(nir_band)
93
85
  end
94
-
95
- nir.close
96
-
97
- nir
98
86
  end
99
87
 
100
88
  # Extracts the RGB bands and writes to a new file. NOTE: this closes the
@@ -111,7 +99,6 @@ module GDAL
111
99
  # in this data type. Defaults to use the current data type.
112
100
  # @param options [Hash] Options that get used for creating the new NDVI
113
101
  # dataset. See docs for GDAL::Driver#create_dataset.
114
- # @return [GDAL::Dataset]
115
102
  def extract_natural_color(destination, red_band_number, green_band_number, blue_band_number,
116
103
  driver_name: 'GTiff', output_data_type: nil, **options)
117
104
  original_bands = {
@@ -123,7 +110,7 @@ module GDAL
123
110
  output_data_type ||= raster_band(1).data_type
124
111
  driver = GDAL::Driver.by_name(driver_name)
125
112
 
126
- natural_color = driver.create_dataset(destination, raster_x_size, raster_y_size,
113
+ driver.create_dataset(destination, raster_x_size, raster_y_size,
127
114
  band_count: 3, data_type: output_data_type, **options) do |new_dataset|
128
115
  new_dataset.geo_transform = geo_transform
129
116
  new_dataset.projection = projection
@@ -137,10 +124,6 @@ module GDAL
137
124
  new_blue_band = new_dataset.raster_band(3)
138
125
  original_bands[:blue].copy_whole_raster(new_blue_band)
139
126
  end
140
-
141
- natural_color.close
142
-
143
- natural_color
144
127
  end
145
128
 
146
129
  # @param red_band_array [NArray]
@@ -367,29 +350,6 @@ module GDAL
367
350
  NArray[*na.transpose]
368
351
  end
369
352
 
370
- # @return [Hash]
371
- def as_json(options = nil)
372
- {
373
- dataset: {
374
- driver: driver.long_name,
375
- file_list: file_list,
376
- gcp_count: gcp_count,
377
- gcp_projection: gcp_projection,
378
- geo_transform: geo_transform.as_json(options),
379
- projection: projection,
380
- raster_count: raster_count,
381
- raster_bands: raster_bands.map(&:as_json),
382
- spatial_reference: spatial_reference.as_json(options)
383
- },
384
- metadata: all_metadata
385
- }
386
- end
387
-
388
- # @return [String]
389
- def to_json(options = nil)
390
- as_json(options).to_json
391
- end
392
-
393
353
  private
394
354
 
395
355
  # @param ndvi [NArray]
@@ -4,7 +4,7 @@ module GDAL
4
4
  module WarpMethods
5
5
  # @param destination_dataset [GDAL::Dataset]
6
6
  # @param resample_algorithm [Symbol] One from FFI::GDAL::Warper::GDALResampleAlg.
7
- # @param destination_spatial_reference [OGR::SpatialReference]
7
+ # @param destination_spatial_reference [String]
8
8
  # @param warp_memory_limit [Float] The amount of memory (in bytes) the API
9
9
  # is allowed to use for caching. This is in addition to the amount of
10
10
  # memory already allocated for caching (using GDALSetCacheMax). 0.0 uses
@@ -15,26 +15,65 @@ module GDAL
15
15
  # callback for reporting progress.
16
16
  # @param progress_arg [FFI::Pointer] Argument to be passed to
17
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)
18
+ # @param warp_options [GDAL::WarpOptions] Warp options, normally empty.
19
+ def reproject_image(destination_dataset, resample_algorithm, destination_projection: nil,
20
+ warp_memory_limit: 0.0, max_error: 0.0, progress_function: nil, progress_arg: nil, warp_options: nil)
21
+ warp_options_struct = warp_options ? warp_options.c_struct : nil
26
22
 
27
23
  FFI::GDAL::Warper.GDALReprojectImage(
28
24
  @c_pointer, # hSrcDS
29
25
  nil, # pszSrcWKT
30
26
  destination_dataset.c_pointer, # hDstDS
31
- destination_spatial_reference_wkt, # pszDstWKT
27
+ destination_projection, # pszDstWKT
28
+ resample_algorithm, # eResampleAlg
29
+ warp_memory_limit, # dfWarpMemoryLimit
30
+ max_error, # dfMaxError
31
+ progress_function, # pfnProgress
32
+ progress_arg, # pProgressArg
33
+ warp_options_struct # psOptions
34
+ )
35
+ end
36
+
37
+ # @param destination_file_name [String] Path to the output dataset.
38
+ # @param resample_algorithm [Symbol] One from FFI::GDAL::Warper::GDALResampleAlg.
39
+ # @param destination_projection [String] WKT of the projection to
40
+ # be used for the destination dataset.
41
+ # @param destination_driver [GDAL::Driver] Driver to use for the
42
+ # destination dataset.
43
+ # @param creation_options [Hash] Driver-specific options to use during
44
+ # creation.
45
+ # @param warp_memory_limit [Float] The amount of memory (in bytes) the API
46
+ # is allowed to use for caching. This is in addition to the amount of
47
+ # memory already allocated for caching (using GDALSetCacheMax). 0.0 uses
48
+ # default settings.
49
+ # @param max_error [Float] Maximum error, measured in input pixels that is
50
+ # allowed in approximating the transformation. Defaults to 0.0.
51
+ # @param progress_function [Proc, FFI::GDAL::GDAL::GDALProgressFunc] A
52
+ # callback for reporting progress.
53
+ # @param progress_arg [FFI::Pointer] Argument to be passed to
54
+ # +progress_function+.
55
+ # @param warp_options [GDAL::WarpOptions] Warp options, normally empty.
56
+ def create_and_reproject_image(destination_file_name, resample_algorithm, destination_projection,
57
+ destination_driver, creation_options: {},
58
+ warp_memory_limit: 0.0, max_error: 0.0,
59
+ progress_function: nil, progress_arg: nil,
60
+ warp_options: nil)
61
+ creation_options_ptr = GDAL::Options.pointer(creation_options)
62
+ warp_options_struct = warp_options ? warp_options.c_struct : nil
63
+
64
+ FFI::GDAL::Warper.GDALCreateAndReprojectImage(
65
+ @c_pointer, # hSrcDS
66
+ nil, # pszSrcWKT
67
+ destination_file_name, # pszDstFilename
68
+ destination_projection, # pszDstWKT
69
+ destination_driver.c_pointer, # hDstDriver
70
+ creation_options_ptr, # papszCreateOptions
32
71
  resample_algorithm, # eResampleAlg
33
72
  warp_memory_limit, # dfWarpMemoryLimit
34
73
  max_error, # dfMaxError
35
74
  progress_function, # pfnProgress
36
75
  progress_arg, # pProgressArg
37
- options_ptr # psOptions
76
+ warp_options_struct # psOptions
38
77
  )
39
78
  end
40
79
  end
@@ -90,23 +90,6 @@ module GDAL
90
90
  pixel_height
91
91
  ]
92
92
  end
93
-
94
- # @return [Hash]
95
- def as_json(_options = nil)
96
- {
97
- x_origin: x_origin,
98
- x_rotation: x_rotation,
99
- pixel_width: pixel_width,
100
- y_origin: y_origin,
101
- y_rotation: y_rotation,
102
- pixel_height: pixel_height
103
- }
104
- end
105
-
106
- # @return [String]
107
- def to_json(options = nil)
108
- as_json(options).to_json
109
- end
110
93
  end
111
94
  end
112
95
  end
data/lib/gdal/grid.rb CHANGED
@@ -36,8 +36,9 @@ module GDAL
36
36
  points = points.to_a if points.is_a? NArray
37
37
  point_count = points.length
38
38
  log "Number of points: #{point_count}"
39
- points = points.transpose
39
+ raise GDAL::NoValuesToGrid, 'No points to grid' if point_count.zero?
40
40
 
41
+ points = points.transpose
41
42
  x_input_coordinates_ptr = make_points_pointer(points[0])
42
43
  y_input_coordinates_ptr = make_points_pointer(points[1])
43
44
  z_input_coordinates_ptr = make_points_pointer(points[2])
@@ -39,8 +39,7 @@ module GDAL
39
39
  # set and the layer has no Z values.
40
40
  def ensure_z_values
41
41
  if layer_missing_specified_field?
42
- raise OGR::InvalidFieldName,
43
- "Field name not found in layer: '#{@options.input_field_name}'"
42
+ raise OGR::InvalidFieldName, "Field name not found in layer: '#{@options.input_field_name}'"
44
43
  elsif !@options.input_field_name && !@source_layer.any_geometries_with_z?
45
44
  raise GDAL::NoValuesToGrid,
46
45
  "No input_field_name option given and source layer #{@source_layer.name} has no Z values."
data/lib/gdal/gridder.rb CHANGED
@@ -287,8 +287,13 @@ module GDAL
287
287
  # @return [Fixnum] The total number of blocks that should be iterated
288
288
  # through during the grid+rasterize process.
289
289
  def build_block_count(block_x_size, block_y_size, raster_width, raster_height)
290
- ((raster_width + block_x_size - 1) / block_x_size) *
291
- ((raster_height + block_y_size - 1) / block_y_size)
290
+ build_block_size(raster_width, block_x_size) * build_block_size(raster_height, block_y_size)
291
+ end
292
+
293
+ # @param total_pixels [Fixnum] Number of pixels in the width or height.
294
+ # @param block_size [Fixnum] Size of the reported block.
295
+ def build_block_size(total_pixels, block_size)
296
+ (total_pixels + block_size - 1) / block_size
292
297
  end
293
298
  end
294
299
  end
data/lib/gdal/options.rb CHANGED
@@ -11,10 +11,20 @@ module GDAL
11
11
  # +nil+. If +false+, creates a 0-size pointer.
12
12
  # @return [FFI::MemoryPointer, nil]
13
13
  def self.pointer(hash, nil_on_empty: true)
14
- if nil_on_empty
15
- hash.empty? ? nil : new(hash).c_pointer
16
- else
17
- new(hash).c_pointer
14
+ return if nil_on_empty && hash.empty?
15
+
16
+ new(hash).c_pointer
17
+ end
18
+
19
+ # Takes a GDAL options pointer and turns it into a Ruby Hash.
20
+ #
21
+ # @param pointer [FFI::Pointer]
22
+ # @return [Hash]
23
+ def self.to_hash(pointer)
24
+ FFI::CPL::String.CSLCount(pointer).times.each_with_object({}) do |i, o|
25
+ key_and_value = FFI::CPL::String.CSLGetField(pointer, i)
26
+ key, value = key_and_value.split('=')
27
+ o[key.downcase.to_sym] = value
18
28
  end
19
29
  end
20
30
 
@@ -37,15 +47,6 @@ module GDAL
37
47
  options_ptr
38
48
  end
39
49
 
40
- # def to_s
41
- # options_ptr = to_gdal
42
- # options_array = options_ptr.read_array_of_pointer(self.size)
43
- #
44
- # 0.upto(self.size).map do |i|
45
- # options_array[i].first.read_string
46
- # end
47
- # end
48
-
49
50
  private
50
51
 
51
52
  def capitalize_keys!(hash)
@@ -39,21 +39,6 @@ module GDAL
39
39
 
40
40
  column_count.times { |i| yield column(i) }
41
41
  end
42
-
43
- # @return [Hash]
44
- def as_json(_options = nil)
45
- {
46
- column_count: column_count,
47
- columns: columns,
48
- linear_binning: linear_binning,
49
- row_count: row_count
50
- }
51
- end
52
-
53
- # @return [String]
54
- def to_json(options = nil)
55
- as_json(options).to_json
56
- end
57
42
  end
58
43
  end
59
44
  end
@@ -149,16 +149,18 @@ module GDAL
149
149
  def no_data_value
150
150
  associated = FFI::MemoryPointer.new(:bool)
151
151
  value = FFI::GDAL::GDAL.GDALGetRasterNoDataValue(@c_pointer, associated)
152
+ value = nil if value == -10_000_000_000.0
152
153
 
153
154
  { value: value, is_associated: associated.read_bytes(1).to_bool }
154
155
  end
155
156
 
156
- # Sets the no data value for this band.
157
+ # Sets the no data value for this band. Do nothing if attempting to set to nil, because removing a no data value
158
+ # is impossible until GDAL 2.1.
157
159
  #
158
- # @param value [Float]
160
+ # @param value [Float, nil]
159
161
  # @return [Boolean]
160
162
  def no_data_value=(value)
161
- !!FFI::GDAL::GDAL.GDALSetRasterNoDataValue(@c_pointer, value)
163
+ !!FFI::GDAL::GDAL.GDALSetRasterNoDataValue(@c_pointer, value) if value
162
164
  end
163
165
 
164
166
  # @return [Fixnum]
@@ -50,7 +50,8 @@ module GDAL
50
50
  # @return [Array<Hash>, nil]
51
51
  def equal_count_ranges(range_count)
52
52
  sorted_pixels = @raster_band.to_na.sort
53
- sorted_and_masked_pixels = sorted_pixels[sorted_pixels.ne(@raster_band.no_data_value[:value])]
53
+ no_data = @raster_band.no_data_value[:value]
54
+ sorted_and_masked_pixels = no_data ? sorted_pixels[sorted_pixels.ne(no_data)] : sorted_pixels
54
55
  return [] if sorted_and_masked_pixels.empty?
55
56
 
56
57
  range_size = (sorted_and_masked_pixels.size / range_count).to_i
@@ -89,11 +90,12 @@ module GDAL
89
90
  nodata_value = @raster_band.no_data_value[:value]
90
91
  band_pixels = @raster_band.to_na
91
92
  new_band_pixels = GDAL._narray_from_data_type(@raster_band.data_type, @raster_band.x_size, @raster_band.y_size)
92
- new_band_pixels[band_pixels.eq(nodata_value)] = nodata_value
93
+ new_band_pixels[band_pixels.eq(nodata_value)] = nodata_value if nodata_value
94
+ data_pixels = nodata_value ? band_pixels.ne(nodata_value) : band_pixels
93
95
 
94
96
  @ranges.each do |r|
95
97
  new_band_pixels[
96
- band_pixels.ne(nodata_value).
98
+ data_pixels.
97
99
  and(band_pixels.le(r[:range].max)).
98
100
  and(band_pixels.ge(r[:range].min))
99
101
  ] = r[:map_to]
@@ -62,41 +62,6 @@ module GDAL
62
62
  def pixel_count
63
63
  x_size * y_size
64
64
  end
65
-
66
- # @return [Hash]
67
- def as_json(_options = nil)
68
- {
69
- raster_band: {
70
- block_size: block_size,
71
- category_names: category_names,
72
- color_interpretation: color_interpretation,
73
- color_table: color_table,
74
- data_type: data_type,
75
- default_histogram: default_histogram(true),
76
- default_raster_attribute_table: default_raster_attribute_table,
77
- has_arbitrary_overviews: arbitrary_overviews?,
78
- mask_flags: mask_flags,
79
- maximum_value: maximum_value,
80
- minimum_value: minimum_value,
81
- no_data_value: no_data_value,
82
- number: number,
83
- offset: offset,
84
- overview_count: overview_count,
85
- overviews: overviews,
86
- scale: scale,
87
- statistics: statistics,
88
- unit_type: unit_type,
89
- x_size: x_size,
90
- y_size: y_size
91
- },
92
- metadata: all_metadata
93
- }
94
- end
95
-
96
- # @return [String]
97
- def to_json(options = nil)
98
- as_json(options).to_json
99
- end
100
65
  end
101
66
  end
102
67
  end