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
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+ require 'gdal/gridder_options'
3
+
4
+ RSpec.describe GDAL::GridderOptions do
5
+ subject(:gridder_options) { described_class.new(:metric_count) }
6
+
7
+ describe 'attributes' do
8
+ it { is_expected.to respond_to :input_clipping_geometry }
9
+ it { is_expected.to respond_to :input_clipping_geometry= }
10
+ it { is_expected.to respond_to :input_field_name }
11
+ it { is_expected.to respond_to :input_field_name= }
12
+
13
+ it { is_expected.to respond_to :progress_formatter }
14
+ it { is_expected.to respond_to :progress_formatter= }
15
+ it { is_expected.to respond_to :grid }
16
+ it { is_expected.to respond_to :algorithm_options }
17
+
18
+ it { is_expected.to respond_to :output_creation_options }
19
+ it { is_expected.to respond_to :output_creation_options= }
20
+ it { is_expected.to respond_to :output_format }
21
+ it { is_expected.to respond_to :output_format= }
22
+ it { is_expected.to respond_to :output_x_extent }
23
+ it { is_expected.to respond_to :output_x_extent= }
24
+ it { is_expected.to respond_to :output_y_extent }
25
+ it { is_expected.to respond_to :output_y_extent= }
26
+ it { is_expected.to respond_to :output_projection }
27
+ it { is_expected.to respond_to :output_projection= }
28
+ it { is_expected.to respond_to :output_size }
29
+ it { is_expected.to respond_to :output_size= }
30
+ it { is_expected.to respond_to :output_data_type }
31
+ it { is_expected.to respond_to :output_data_type= }
32
+ end
33
+
34
+ describe 'default values' do
35
+ describe '#output_data_type' do
36
+ subject { gridder_options.output_data_type }
37
+ it { is_expected.to eq :GDT_Float64 }
38
+ end
39
+
40
+ describe '#output_format' do
41
+ subject { gridder_options.output_format }
42
+ it { is_expected.to eq 'GTiff' }
43
+ end
44
+
45
+ describe '#output_size' do
46
+ subject { gridder_options.output_size }
47
+ it { is_expected.to eq(width: 256, height: 256) }
48
+ end
49
+ end
50
+
51
+ describe '#input_clipping_geometry=' do
52
+ context 'param is a OGR::Geometry' do
53
+ it 'sets the attribute' do
54
+ geom = OGR::Point.new
55
+ subject.input_clipping_geometry = geom
56
+ expect(subject.input_clipping_geometry).to eq geom
57
+ end
58
+ end
59
+
60
+ context 'param is not a OGR::Geometry' do
61
+ it 'raises a OGR::InvalidGeometry exception' do
62
+ expect { subject.input_clipping_geometry = 'meow' }.
63
+ to raise_exception OGR::InvalidGeometry
64
+ end
65
+ end
66
+ end
67
+
68
+ describe '#output_data_type=' do
69
+ context 'param is a FFI::GDAL::GDAL::DataType' do
70
+ it 'sets the attribute and the grid data type' do
71
+ subject.output_data_type = :GDT_Byte
72
+ expect(subject.output_data_type).to eq :GDT_Byte
73
+ expect(subject.grid.data_type).to eq :GDT_Byte
74
+ end
75
+ end
76
+
77
+ context 'param is not a FFI::GDAL::GDAL::DataType' do
78
+ it 'raises a OGR::InvalidGeometry exception' do
79
+ expect { subject.output_data_type = 'meow' }.
80
+ to raise_exception GDAL::InvalidDataType
81
+ end
82
+ end
83
+ end
84
+
85
+ describe '#output_format=' do
86
+ context 'param is a GDAL::Driver short name' do
87
+ it 'sets the attribute' do
88
+ subject.output_format = 'SAGA'
89
+ expect(subject.output_format).to eq 'SAGA'
90
+ end
91
+ end
92
+
93
+ context 'param is not a GDAL::Driver short name' do
94
+ it 'raises a GDAL::InvalidDriverName exception' do
95
+ expect { subject.output_format = 'meow' }.
96
+ to raise_exception GDAL::InvalidDriverName
97
+ end
98
+ end
99
+ end
100
+
101
+ describe '#output_x_extent=' do
102
+ it 'returns a Hash with min and max keys' do
103
+ expect(subject).to receive(:extract_min_max).with(%w[some values], :min, :max).
104
+ and_return(%w[some values])
105
+ subject.output_x_extent = %w[some values]
106
+ expect(subject.output_x_extent).to eq(min: 'some', max: 'values')
107
+ end
108
+ end
109
+
110
+ describe '#output_y_extent=' do
111
+ it 'returns a Hash with min and max keys' do
112
+ expect(subject).to receive(:extract_min_max).with(%w[some values], :min, :max).
113
+ and_return(%w[some values])
114
+ subject.output_y_extent = %w[some values]
115
+ expect(subject.output_y_extent).to eq(min: 'some', max: 'values')
116
+ end
117
+ end
118
+
119
+ describe '#output_size=' do
120
+ it 'returns a Hash with min and max keys' do
121
+ expect(subject).to receive(:extract_min_max).with(%w[some values], :width, :height).
122
+ and_return(%w[some values])
123
+ subject.output_size = %w[some values]
124
+ expect(subject.output_size).to eq(width: 'some', height: 'values')
125
+ end
126
+ end
127
+
128
+ describe '#output_projection=' do
129
+ context 'param is a OGR::SpatialReference' do
130
+ it 'sets the attribute' do
131
+ projection = OGR::SpatialReference.new_from_epsg(4326)
132
+ subject.output_projection = projection
133
+ expect(subject.output_projection).to eq projection
134
+ end
135
+ end
136
+
137
+ context 'param is not a OGR::SpatialReference' do
138
+ it 'raises a OGR::InvalidSpatialReference exception' do
139
+ expect { subject.output_projection = 'meow' }.
140
+ to raise_exception OGR::InvalidSpatialReference
141
+ end
142
+ end
143
+ end
144
+
145
+ describe '#extract_min_max_from_array' do
146
+ context 'param is a 2-element Array' do
147
+ it 'sets the attribute' do
148
+ expect(subject.send(:extract_min_max_from_array, [1, 20], :foo, :bar)).
149
+ to eq([1, 20])
150
+ end
151
+ end
152
+
153
+ context 'param is an Array with not 2 elements' do
154
+ it 'raises an ArgumentError' do
155
+ expect { subject.send(:extract_min_max_from_array, [1, 20, 30], :foo, :bar) }.
156
+ to raise_exception ArgumentError
157
+ end
158
+ end
159
+ end
160
+
161
+ describe '#extract_min_max_from_hash' do
162
+ context 'param is a Hash with :min and :max keys' do
163
+ it 'sets the attribute' do
164
+ expect(subject.send(:extract_min_max_from_hash, { min: 1, max: 20 }, :min, :max)).
165
+ to eq([1, 20])
166
+ end
167
+ end
168
+
169
+ context 'param is a Hash with :min, :max, and :other' do
170
+ it 'raises an ArgumentError' do
171
+ expect { subject.send(:extract_min_max_from_hash, { min: 1, max: 20, other: 30 }, :min, :max) }.
172
+ to raise_exception ArgumentError
173
+ end
174
+ end
175
+
176
+ context 'param is a Hash without :min and :max' do
177
+ it 'raises an ArgumentError' do
178
+ expect { subject.send(:extract_min_max_from_hash, { things: 1, stuff: 20 }, :min, :max) }.
179
+ to raise_exception ArgumentError
180
+ end
181
+ end
182
+ end
183
+ end
@@ -0,0 +1,140 @@
1
+ require 'spec_helper'
2
+ require 'gdal/gridder'
3
+
4
+ RSpec.describe GDAL::Gridder do
5
+ let(:source_layer) { instance_double 'OGR::Layer' }
6
+ let(:dest_file_name) { 'blah.docx' }
7
+ let(:gridder_options) { instance_double 'GDAL::GridderOptions' }
8
+
9
+ subject(:gridder) { described_class.new(source_layer, dest_file_name, gridder_options) }
10
+
11
+ describe '#build_output_spatial_reference' do
12
+ let(:spatial_reference) { instance_double 'OGR::SpatialRefernce' }
13
+
14
+ context 'no output_projection given, source layer has one set' do
15
+ before do
16
+ allow(gridder_options).to receive(:output_projection).and_return nil
17
+ allow(source_layer).to receive(:spatial_reference).and_return spatial_reference
18
+ allow(spatial_reference).to receive(:to_wkt).and_return 'BLAH'
19
+ end
20
+
21
+ it "returns WKT of the source layer's SpatialReference" do
22
+ expect(subject.send(:build_output_spatial_reference)).to eq 'BLAH'
23
+ end
24
+ end
25
+
26
+ context 'output_projection given' do
27
+ before do
28
+ allow(gridder_options).to receive(:output_projection).and_return spatial_reference
29
+ allow(spatial_reference).to receive(:to_wkt).and_return 'MEOW'
30
+ end
31
+
32
+ it "returns WKT of the source layer's SpatialReference" do
33
+ expect(subject.send(:build_output_spatial_reference)).to eq 'MEOW'
34
+ end
35
+ end
36
+
37
+ context 'no output_projection given, source layer does not have one set' do
38
+ before do
39
+ allow(gridder_options).to receive(:output_projection).and_return nil
40
+ allow(source_layer).to receive(:spatial_reference).and_return nil
41
+ end
42
+
43
+ it 'returns nil' do
44
+ expect(subject.send(:build_output_spatial_reference)).to eq nil
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#x_min' do
50
+ context 'output_x_extent is set' do
51
+ before { allow(gridder_options).to receive(:output_x_extent).and_return(min: 123) }
52
+
53
+ it 'sets x_min to that value' do
54
+ expect(subject.send(:x_min)).to eq 123
55
+ end
56
+ end
57
+
58
+ context 'output_x_extent is not set' do
59
+ let(:extent) { instance_double 'OGR::Envelope', x_min: 456 }
60
+
61
+ before do
62
+ allow(gridder_options).to receive(:output_x_extent).and_return({})
63
+ allow(source_layer).to receive(:extent).and_return extent
64
+ end
65
+
66
+ it "sets x_min to the source layer's extent's x_min value" do
67
+ expect(subject.send(:x_min)).to eq 456
68
+ end
69
+ end
70
+ end
71
+
72
+ describe '#x_max' do
73
+ context 'output_x_extent is set' do
74
+ before { allow(gridder_options).to receive(:output_x_extent).and_return(max: 321) }
75
+
76
+ it 'sets x_max to that value' do
77
+ expect(subject.send(:x_max)).to eq 321
78
+ end
79
+ end
80
+
81
+ context 'output_x_extent is not set' do
82
+ let(:extent) { instance_double 'OGR::Envelope', x_max: 654 }
83
+
84
+ before do
85
+ allow(gridder_options).to receive(:output_x_extent).and_return({})
86
+ allow(source_layer).to receive(:extent).and_return extent
87
+ end
88
+
89
+ it "sets x_max to the source layer's extent's x_max value" do
90
+ expect(subject.send(:x_max)).to eq 654
91
+ end
92
+ end
93
+ end
94
+
95
+ describe '#y_min' do
96
+ context 'output_y_extent is set' do
97
+ before { allow(gridder_options).to receive(:output_y_extent).and_return(min: 123) }
98
+
99
+ it 'sets y_min to that value' do
100
+ expect(subject.send(:y_min)).to eq 123
101
+ end
102
+ end
103
+
104
+ context 'output_y_extent is not set' do
105
+ let(:extent) { instance_double 'OGR::Envelope', y_min: 456 }
106
+
107
+ before do
108
+ allow(gridder_options).to receive(:output_y_extent).and_return({})
109
+ allow(source_layer).to receive(:extent).and_return extent
110
+ end
111
+
112
+ it "sets y_min to the source layer's extent's y_min value" do
113
+ expect(subject.send(:y_min)).to eq 456
114
+ end
115
+ end
116
+ end
117
+
118
+ describe '#y_max' do
119
+ context 'output_y_extent is set' do
120
+ before { allow(gridder_options).to receive(:output_y_extent).and_return(max: 321) }
121
+
122
+ it 'sets y_max to that value' do
123
+ expect(subject.send(:y_max)).to eq 321
124
+ end
125
+ end
126
+
127
+ context 'output_y_extent is not set' do
128
+ let(:extent) { instance_double 'OGR::Envelope', y_max: 654 }
129
+
130
+ before do
131
+ allow(gridder_options).to receive(:output_y_extent).and_return({})
132
+ allow(source_layer).to receive(:extent).and_return extent
133
+ end
134
+
135
+ it "sets y_max to the source layer's extent's y_max value" do
136
+ expect(subject.send(:y_max)).to eq 654
137
+ end
138
+ end
139
+ end
140
+ end
@@ -93,8 +93,58 @@ RSpec.describe GDAL::InternalHelpers do
93
93
  end
94
94
 
95
95
  context 'data type is not one listed' do
96
- subject { tester._gdal_data_type_to_ffi(:blargh) }
97
- it { is_expected.to eq :float }
96
+ it 'raises a GDAL::InvalidDataType' do
97
+ expect { tester._gdal_data_type_to_ffi(:blargh) }.
98
+ to raise_exception(GDAL::InvalidDataType)
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '._read_pointer' do
104
+ context 'length is 1' do
105
+ let(:pointer) do
106
+ p = FFI::MemoryPointer.new(:int16)
107
+ p.write_int16(12_345)
108
+
109
+ p
110
+ end
111
+
112
+ it 'returns the data value' do
113
+ expect(GDAL._read_pointer(pointer, :GDT_Int16)).to eq(12_345)
114
+ end
115
+ end
116
+
117
+ context 'length is > 1' do
118
+ let(:pointer) do
119
+ p = FFI::MemoryPointer.new(:int16, 2)
120
+ p.write_array_of_int16([12_345, 222])
121
+
122
+ p
123
+ end
124
+
125
+ it 'returns the data value' do
126
+ expect(GDAL._read_pointer(pointer, :GDT_Int16, 2)).to eq([12_345, 222])
127
+ end
128
+ end
129
+ end
130
+
131
+ describe '._write_pointer' do
132
+ context 'data is not an Array' do
133
+ let(:pointer) { FFI::MemoryPointer.new(:int16) }
134
+
135
+ it 'writes the single value to the pointer' do
136
+ expect(pointer).to receive(:write_int16).with(12_345)
137
+ GDAL._write_pointer(pointer, :GDT_Int16, 12_345)
138
+ end
139
+ end
140
+
141
+ context 'data is an Array' do
142
+ let(:pointer) { FFI::MemoryPointer.new(:int16, 2) }
143
+
144
+ it 'writes the values to the pointer' do
145
+ expect(pointer).to receive(:write_array_of_int16).with([12_345, 222])
146
+ GDAL._write_pointer(pointer, :GDT_Int16, [12_345, 222])
147
+ end
98
148
  end
99
149
  end
100
150
 
@@ -109,4 +159,118 @@ RSpec.describe GDAL::InternalHelpers do
109
159
  it { is_expected.to eq false }
110
160
  end
111
161
  end
162
+
163
+ describe '._gdal_data_type_to_narray' do
164
+ subject { GDAL._gdal_data_type_to_narray(data_type) }
165
+
166
+ context 'data_type is :GDT_Byte' do
167
+ let(:data_type) { :GDT_Byte }
168
+ it { is_expected.to eq(:byte) }
169
+ end
170
+
171
+ context 'data_type is :GDT_Int16' do
172
+ let(:data_type) { :GDT_Int16 }
173
+ it { is_expected.to eq(:sint) }
174
+ end
175
+
176
+ context 'data_type is :GDT_UInt16' do
177
+ let(:data_type) { :GDT_UInt16 }
178
+ it { is_expected.to eq(:int) }
179
+ end
180
+
181
+ context 'data_type is :GDT_Int32' do
182
+ let(:data_type) { :GDT_Int32 }
183
+ it { is_expected.to eq(:int) }
184
+ end
185
+
186
+ context 'data_type is :GDT_UInt32' do
187
+ let(:data_type) { :GDT_UInt32 }
188
+ it { is_expected.to eq(:int) }
189
+ end
190
+
191
+ context 'data_type is :GDT_Float32' do
192
+ let(:data_type) { :GDT_Float32 }
193
+ it { is_expected.to eq(:float) }
194
+ end
195
+
196
+ context 'data_type is :GDT_Float64' do
197
+ let(:data_type) { :GDT_Float64 }
198
+ it { is_expected.to eq(:dfloat) }
199
+ end
200
+
201
+ context 'data_type is :GDT_CInt16' do
202
+ let(:data_type) { :GDT_CInt16 }
203
+ it { is_expected.to eq(:scomplex) }
204
+ end
205
+
206
+ context 'data_type is :GDT_CInt32' do
207
+ let(:data_type) { :GDT_CInt32 }
208
+ it { is_expected.to eq(:scomplex) }
209
+ end
210
+
211
+ context 'data_type is :GDT_CFloat32' do
212
+ let(:data_type) { :GDT_CFloat32 }
213
+ it { is_expected.to eq(:complex) }
214
+ end
215
+
216
+ context 'data_type is :GDT_CFloat64' do
217
+ let(:data_type) { :GDT_CFloat64 }
218
+ it { is_expected.to eq(:dcomplex) }
219
+ end
220
+
221
+ context 'unknown data_type' do
222
+ it 'raises a GDAL::InvalidDataType exception' do
223
+ expect { GDAL._gdal_data_type_to_narray(:meow) }.
224
+ to raise_exception(GDAL::InvalidDataType)
225
+ end
226
+ end
227
+ end
228
+
229
+ describe '._narray_from_data_type' do
230
+ context '0 narray_args and known GDAL data_type' do
231
+ subject { GDAL._narray_from_data_type(:GDT_Byte) }
232
+ it { is_expected.to be_a NArray }
233
+
234
+ it 'has size 0' do
235
+ expect(subject.size).to be_zero
236
+ end
237
+
238
+ it 'has shape []' do
239
+ expect(subject.shape).to eq([])
240
+ end
241
+ end
242
+
243
+ context '1 narray_args and known GDAL data_type' do
244
+ subject { GDAL._narray_from_data_type(:GDT_Byte, 2) }
245
+ it { is_expected.to be_a NArray }
246
+
247
+ it 'has size of the 2nd param' do
248
+ expect(subject.size).to eq(2)
249
+ end
250
+
251
+ it 'has 1D shape with size of the 2nd param' do
252
+ expect(subject.shape).to eq([2])
253
+ end
254
+ end
255
+
256
+ context '2 narray_args and known GDAL data_type' do
257
+ subject { GDAL._narray_from_data_type(:GDT_Byte, 2, 3) }
258
+ it { is_expected.to be_a NArray }
259
+
260
+ it 'has size of the 2nd param * 3rd param' do
261
+ expect(subject.size).to eq(6)
262
+ end
263
+
264
+ it 'has 2D shape with size of each of the params' do
265
+ expect(subject.shape).to eq([2, 3])
266
+ end
267
+ end
268
+
269
+ context 'unknown GDAL data_type' do
270
+ it 'raises a GDAL::InvalidDataType exception' do
271
+ expect { GDAL._narray_from_data_type(:bobo) }.
272
+ to raise_exception(GDAL::InvalidDataType)
273
+ end
274
+ end
275
+ end
112
276
  end
@@ -3,4 +3,6 @@ require 'gdal/major_object'
3
3
 
4
4
  RSpec.describe GDAL::MajorObject do
5
5
  subject { Object.new.extend(described_class) }
6
+
7
+ pending 'Add some tests!'
6
8
  end
@@ -2,4 +2,5 @@ require 'spec_helper'
2
2
  require 'gdal/options'
3
3
 
4
4
  RSpec.describe GDAL::Options do
5
+ pending 'Add some tests!'
5
6
  end
@@ -6,16 +6,15 @@ RSpec.describe GDAL::RasterBandClassifier do
6
6
  let(:driver) { GDAL::Driver.by_name('MEM') }
7
7
 
8
8
  let(:dataset) do
9
- driver.create_dataset 'test dataset', 640, 480
10
- end
11
-
12
- let(:raster_band) do
13
- band = dataset.raster_band 1
9
+ d = driver.create_dataset('test dataset', 640, 480)
10
+ band = d.raster_band 1
14
11
  new_values = band.to_na.indgen!
15
- band.write_array(new_values)
16
- band
12
+ band.write_xy_narray(new_values)
13
+
14
+ d
17
15
  end
18
16
 
17
+ let(:raster_band) { dataset.raster_band 1 }
19
18
  subject(:classifier) { described_class.new(raster_band) }
20
19
 
21
20
  describe '#add_range' do
@@ -70,7 +69,7 @@ RSpec.describe GDAL::RasterBandClassifier do
70
69
  let(:raster_band) do
71
70
  band = float_dataset.raster_band 1
72
71
  new_values = band.to_na.indgen!
73
- band.write_array(new_values)
72
+ band.write_xy_narray(new_values)
74
73
  band
75
74
  end
76
75
 
@@ -95,6 +94,15 @@ RSpec.describe GDAL::RasterBandClassifier do
95
94
  subject { classifier.equal_count_ranges(1_000) }
96
95
  it { is_expected.to be_nil }
97
96
  end
97
+
98
+ context 'all nodata pixels' do
99
+ let(:band_narray) { NArray.byte(0) }
100
+ before { allow(raster_band).to receive(:to_na).and_return(band_narray) }
101
+
102
+ it 'returns an empty Array' do
103
+ expect(subject.equal_count_ranges(10)).to eq([])
104
+ end
105
+ end
98
106
  end
99
107
 
100
108
  describe '#classify!' do
@@ -103,37 +111,87 @@ RSpec.describe GDAL::RasterBandClassifier do
103
111
  subject.add_ranges(ranges)
104
112
  end
105
113
 
106
- context 'no_data_value is set' do
114
+ context 'no_data_value is set to 0' do
107
115
  before do
108
116
  raster_band.no_data_value = 0
109
- subject.classify!
110
117
  end
111
118
 
112
119
  it 'has a max value equal to the number of ranges' do
120
+ subject.classify!
113
121
  min_max = raster_band.min_max
114
122
  expect(min_max[:max]).to eq 10
115
123
  end
116
124
 
117
125
  it 'has a min value of 1' do
126
+ subject.classify!
118
127
  min_max = raster_band.min_max
119
128
  expect(min_max[:min]).to eq 1
120
129
  end
130
+
131
+ it 'retains its NODATA pixels' do
132
+ expect { subject.classify! }.to_not change { raster_band.to_na.eq(-9999.0).count_true }
133
+ end
121
134
  end
122
135
 
123
- context 'no_data_value is not set' do
124
- before do
136
+ # Relevant because NArray inits its arrays to 0.
137
+ context 'no_data_value is set to non-0' do
138
+ let(:dataset) do
139
+ d = driver.create_dataset('test dataset', 640, 480, data_type: :GDT_Float32)
140
+ band = d.raster_band 1
141
+ band.no_data_value = -9999.0
142
+ new_values = band.to_na.indgen!
143
+ new_values[true, 0] = -9999.0
144
+ band.write_xy_narray(new_values)
145
+
146
+ d
147
+ end
148
+
149
+ it 'has a max value equal to the number of ranges' do
125
150
  subject.classify!
151
+ min_max = raster_band.min_max
152
+ expect(min_max[:max]).to eq 10
153
+ end
154
+
155
+ it 'has a min value of 1' do
156
+ subject.classify!
157
+ min_max = raster_band.min_max
158
+ expect(min_max[:min]).to eq 1
126
159
  end
127
160
 
161
+ it 'retains its NODATA pixels' do
162
+ expect { subject.classify! }.to_not change { raster_band.to_na.eq(-9999.0).count_true }
163
+ pixels = raster_band.to_na
164
+ expect(pixels.eq(-9999).count_true).to eq 640
165
+ expect(pixels.eq(0).count_true).to eq 0
166
+ expect(pixels.eq(1).count_true).to eq 30_656
167
+ expect(pixels.eq(2).count_true).to eq 30_656
168
+ expect(pixels.eq(3).count_true).to eq 30_656
169
+ expect(pixels.eq(4).count_true).to eq 30_656
170
+ expect(pixels.eq(5).count_true).to eq 30_656
171
+ expect(pixels.eq(6).count_true).to eq 30_656
172
+ expect(pixels.eq(7).count_true).to eq 30_656
173
+ expect(pixels.eq(8).count_true).to eq 30_656
174
+ expect(pixels.eq(9).count_true).to eq 30_656
175
+ expect(pixels.eq(10).count_true).to eq 30_656
176
+ end
177
+ end
178
+
179
+ context 'no_data_value is not set' do
128
180
  it 'has a max value equal to the number of ranges' do
181
+ subject.classify!
129
182
  min_max = raster_band.min_max
130
183
  expect(min_max[:max]).to eq 10
131
184
  end
132
185
 
133
186
  it 'has a min value of 0' do
187
+ subject.classify!
134
188
  min_max = raster_band.min_max
135
189
  expect(min_max[:min]).to eq 0
136
190
  end
191
+
192
+ it 'retains its NODATA pixels' do
193
+ expect { subject.classify! }.to_not change { raster_band.to_na.eq(-9999.0).count_true }
194
+ end
137
195
  end
138
196
  end
139
197
  end