diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 7b59c293..7b460af7 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -26,7 +26,8 @@ jobs: # NOTE: # - ubuntu-20.04 has GDAL 3.0.4, PROJ 6.3.1, GEOS 3.8.0 # - ubuntu-22.04 has GDAL 3.4.1, PROJ 8.2.1, GEOS 3.10.2 - os: ["ubuntu-20.04", "ubuntu-22.04"] + # - ubuntu-24.04 has GDAL 3.8.4, PROJ 9.4.0, GEOS 3.12.1 + os: ["ubuntu-20.04", "ubuntu-22.04", "ubuntu-24.04"] ruby-version: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3"] name: "Ruby ${{ matrix.ruby-version }} on ${{ matrix.os }}" runs-on: ${{ matrix.os }} diff --git a/README.md b/README.md index e7386006..a6b5cd5c 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,8 @@ FFI::CPL::Conv.CPLSetConfigOption('CPL_LOG_ERRORS', 'ON') ## Compatibility CI is run against: +- Ruby 2.6, 2.7, 3.0, 3.1, 3.2, 3.3 for Ubuntu 24.04 + (**GDAL 3.8.4**, PROJ 9.4.0, GEOS 3.12.1) - Ruby 2.6, 2.7, 3.0, 3.1, 3.2, 3.3 for Ubuntu 22.04 (**GDAL 3.4.1**, PROJ 8.2.1, GEOS 3.10.2) - Ruby 2.6, 2.7, 3.0, 3.1, 3.2, 3.3 for Ubuntu 20.04 diff --git a/lib/ffi/gdal.rb b/lib/ffi/gdal.rb index a7c767fc..78ac0814 100644 --- a/lib/ffi/gdal.rb +++ b/lib/ffi/gdal.rb @@ -19,6 +19,7 @@ module GDAL File.expand_path("gdal/grid_inverse_distance_to_a_power_options.rb", __dir__) autoload :GridMovingAverageOptions, File.expand_path("gdal/grid_moving_average_options.rb", __dir__) autoload :GridNearestNeighborOptions, File.expand_path("gdal/grid_nearest_neighbor_options.rb", __dir__) + autoload :InternalHelpers, File.expand_path("gdal/internal_helpers.rb", __dir__) autoload :Matching, File.expand_path("gdal/matching.rb", __dir__) autoload :RPCInfo, File.expand_path("gdal/rpc_info.rb", __dir__) autoload :TransformerInfo, File.expand_path("gdal/transformer_info.rb", __dir__) diff --git a/lib/ffi/gdal/grid_data_metrics_options.rb b/lib/ffi/gdal/grid_data_metrics_options.rb index 26115d6c..845855dc 100644 --- a/lib/ffi/gdal/grid_data_metrics_options.rb +++ b/lib/ffi/gdal/grid_data_metrics_options.rb @@ -4,12 +4,34 @@ module FFI module GDAL + # FFI structure for GDALGridDataMetricsOptions. + # @see https://gdal.org/api/gdal_alg.html#_CPPv426GDALGridDataMetricsOptions class GridDataMetricsOptions < FFI::Struct - layout :radius1, :double, - :radius2, :double, - :angle, :double, - :min_points, CPL::Port.find_type(:GUInt32), - :no_data_value, :double + DEFAULT_LAYOUT = [ + :radius1, :double, + :radius2, :double, + :angle, :double, + :min_points, CPL::Port.find_type(:GUInt32), + :no_data_value, :double + ].freeze + + LAYOUT_VERSIONS = [ + InternalHelpers::LayoutVersion.new( + version: "0000000", # Any old GDAL + layout: DEFAULT_LAYOUT + ), + InternalHelpers::LayoutVersion.new( + version: "3060000", # GDAL 3.6.0 + layout: [ + :n_size_of_structure, :size_t, + *DEFAULT_LAYOUT, + :max_points_per_quadrant, CPL::Port.find_type(:GUInt32), + :min_points_per_quadrant, CPL::Port.find_type(:GUInt32) + ] + ) + ].freeze + + layout(*InternalHelpers::LayoutVersionResolver.resolve(versions: LAYOUT_VERSIONS)) end end end diff --git a/lib/ffi/gdal/grid_inverse_distance_to_a_power_options.rb b/lib/ffi/gdal/grid_inverse_distance_to_a_power_options.rb index e20cc366..83253e16 100644 --- a/lib/ffi/gdal/grid_inverse_distance_to_a_power_options.rb +++ b/lib/ffi/gdal/grid_inverse_distance_to_a_power_options.rb @@ -4,17 +4,37 @@ module FFI module GDAL + # FFI structure for GDALGridInverseDistanceToAPowerOptions. + # @see https://gdal.org/api/gdal_alg.html#_CPPv438GDALGridInverseDistanceToAPowerOptions class GridInverseDistanceToAPowerOptions < FFI::Struct - layout :power, :double, - :smoothing, :double, - :anisotropy_ratio, :double, - :anisotropy_angle, :double, - :radius1, :double, - :radius2, :double, - :angle, :double, - :max_points, CPL::Port.find_type(:GUInt32), - :min_points, CPL::Port.find_type(:GUInt32), - :no_data_value, :double + DEFAULT_LAYOUT = [ + :power, :double, + :smoothing, :double, + :anisotropy_ratio, :double, + :anisotropy_angle, :double, + :radius1, :double, + :radius2, :double, + :angle, :double, + :max_points, CPL::Port.find_type(:GUInt32), + :min_points, CPL::Port.find_type(:GUInt32), + :no_data_value, :double + ].freeze + + LAYOUT_VERSIONS = [ + InternalHelpers::LayoutVersion.new( + version: "0000000", # Any old GDAL + layout: DEFAULT_LAYOUT + ), + InternalHelpers::LayoutVersion.new( + version: "3060000", # GDAL 3.6.0 + layout: [ + :n_size_of_structure, :size_t, + *DEFAULT_LAYOUT + ] + ) + ].freeze + + layout(*InternalHelpers::LayoutVersionResolver.resolve(versions: LAYOUT_VERSIONS)) end end end diff --git a/lib/ffi/gdal/grid_moving_average_options.rb b/lib/ffi/gdal/grid_moving_average_options.rb index a84a1ee6..cae14a1b 100644 --- a/lib/ffi/gdal/grid_moving_average_options.rb +++ b/lib/ffi/gdal/grid_moving_average_options.rb @@ -4,12 +4,37 @@ module FFI module GDAL + # FFI structure for GDALGridMovingAverageOptions. + # @see https://gdal.org/api/gdal_alg.html#_CPPv428GDALGridMovingAverageOptions class GridMovingAverageOptions < FFI::Struct - layout :radius1, :double, - :radius2, :double, - :angle, :double, - :min_points, CPL::Port.find_type(:GUInt32), - :no_data_value, :double + LAYOUT_VERSIONS = [ + InternalHelpers::LayoutVersion.new( + version: "0000000", # Any old GDAL + layout: [ + :radius1, :double, + :radius2, :double, + :angle, :double, + :min_points, CPL::Port.find_type(:GUInt32), + :no_data_value, :double + ] + ), + InternalHelpers::LayoutVersion.new( + version: "3060000", # GDAL 3.6.0 + layout: [ + :n_size_of_structure, :size_t, + :radius1, :double, + :radius2, :double, + :angle, :double, + :max_points, CPL::Port.find_type(:GUInt32), + :min_points, CPL::Port.find_type(:GUInt32), + :no_data_value, :double, + :max_points_per_quadrant, CPL::Port.find_type(:GUInt32), + :min_points_per_quadrant, CPL::Port.find_type(:GUInt32) + ] + ) + ].freeze + + layout(*InternalHelpers::LayoutVersionResolver.resolve(versions: LAYOUT_VERSIONS)) end end end diff --git a/lib/ffi/gdal/grid_nearest_neighbor_options.rb b/lib/ffi/gdal/grid_nearest_neighbor_options.rb index 07f61295..1355224c 100644 --- a/lib/ffi/gdal/grid_nearest_neighbor_options.rb +++ b/lib/ffi/gdal/grid_nearest_neighbor_options.rb @@ -4,11 +4,31 @@ module FFI module GDAL + # FFI structure for GDALGridNearestNeighborOptions. + # @see https://gdal.org/api/gdal_alg.html#_CPPv430GDALGridNearestNeighborOptions class GridNearestNeighborOptions < FFI::Struct - layout :radius1, :double, - :radius2, :double, - :angle, :double, - :no_data_value, :double + DEFAULT_LAYOUT = %i[ + radius1 double + radius2 double + angle double + no_data_value double + ].freeze + + LAYOUT_VERSIONS = [ + InternalHelpers::LayoutVersion.new( + version: "0000000", # Any old GDAL + layout: DEFAULT_LAYOUT + ), + InternalHelpers::LayoutVersion.new( + version: "3060000", # GDAL 3.6.0 + layout: [ + :n_size_of_structure, :size_t, + *DEFAULT_LAYOUT + ] + ) + ].freeze + + layout(*InternalHelpers::LayoutVersionResolver.resolve(versions: LAYOUT_VERSIONS)) end end end diff --git a/lib/ffi/gdal/internal_helpers.rb b/lib/ffi/gdal/internal_helpers.rb new file mode 100644 index 00000000..c8e972a0 --- /dev/null +++ b/lib/ffi/gdal/internal_helpers.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module FFI + module GDAL + module InternalHelpers + autoload :GDALVersion, File.expand_path("internal_helpers/gdal_version", __dir__) + autoload :LayoutVersion, File.expand_path("internal_helpers/layout_version", __dir__) + autoload :LayoutVersionResolver, File.expand_path("internal_helpers/layout_version_resolver", __dir__) + end + end +end diff --git a/lib/ffi/gdal/internal_helpers/gdal_version.rb b/lib/ffi/gdal/internal_helpers/gdal_version.rb new file mode 100644 index 00000000..941c38d1 --- /dev/null +++ b/lib/ffi/gdal/internal_helpers/gdal_version.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module FFI + module GDAL + module InternalHelpers + # Version information for GDAL. + class GDALVersion + # @return [String] GDAL Version. + def self.version + ::FFI::GDAL.GDALVersionInfo("VERSION_NUM") + end + end + end + end +end diff --git a/lib/ffi/gdal/internal_helpers/layout_version.rb b/lib/ffi/gdal/internal_helpers/layout_version.rb new file mode 100644 index 00000000..90e1fd73 --- /dev/null +++ b/lib/ffi/gdal/internal_helpers/layout_version.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module FFI + module GDAL + module InternalHelpers + LayoutVersion = ::Struct.new(:version, :layout, keyword_init: true) + end + end +end diff --git a/lib/ffi/gdal/internal_helpers/layout_version_resolver.rb b/lib/ffi/gdal/internal_helpers/layout_version_resolver.rb new file mode 100644 index 00000000..532563fc --- /dev/null +++ b/lib/ffi/gdal/internal_helpers/layout_version_resolver.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +module FFI + module GDAL + module InternalHelpers + # Resolve the layout version based on the GDAL version. + class LayoutVersionResolver + # Resolve the layout version based on the GDAL version. + # @param versions [Array] The versions to resolve. + # @return [Array] The resolved layout. + def self.resolve(versions: []) + gdal_version = GDALVersion.version + + versions + .sort_by(&:version) + .reverse_each + .find { |layout_version| gdal_version >= layout_version.version } + .layout + .freeze + end + end + end + end +end diff --git a/lib/gdal/extensions/gridder.rb b/lib/gdal/extensions/gridder.rb index ba174847..d7850680 100644 --- a/lib/gdal/extensions/gridder.rb +++ b/lib/gdal/extensions/gridder.rb @@ -4,6 +4,10 @@ require "gdal" require "gdal/options" require "ogr" +require "ogr/extensions/envelope/extensions" +require "ogr/extensions/layer/extensions" +require "gdal/extensions/geo_transform/extensions" + require_relative "gridder_options" require_relative "gridder/point_extracting" diff --git a/lib/gdal/grid_algorithms.rb b/lib/gdal/grid_algorithms.rb index ca2dbe75..1e7de60c 100644 --- a/lib/gdal/grid_algorithms.rb +++ b/lib/gdal/grid_algorithms.rb @@ -2,6 +2,8 @@ module GDAL module GridAlgorithms + autoload :AlgorithmBase, + File.expand_path("grid_algorithms/algorithm_base", __dir__) autoload :InverseDistanceToAPower, File.expand_path("grid_algorithms/inverse_distance_to_a_power", __dir__) autoload :MetricAverageDistance, diff --git a/lib/gdal/grid_algorithms/algorithm_base.rb b/lib/gdal/grid_algorithms/algorithm_base.rb new file mode 100644 index 00000000..ce70be55 --- /dev/null +++ b/lib/gdal/grid_algorithms/algorithm_base.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module GDAL + module GridAlgorithms + # Base abstract class for all grid algorithms. + class AlgorithmBase + # @return Options object. + attr_reader :options + + def initialize + @options = options_class.new + assign_size_of_structure + end + + # @return [Class] Options class. + def options_class + # This method must be overridden in subclasses. + end + + # @return [Symbol] C identifier for the algorithm. + def c_identifier + # This method must be overridden in subclasses. + end + + private + + def assign_size_of_structure + # Starting GDAL 3.6.0 we must assign nSizeOfStructure to the size of the structure. + return unless @options.members.include?(:n_size_of_structure) + + @options[:n_size_of_structure] = @options.size + end + end + end +end diff --git a/lib/gdal/grid_algorithms/data_metrics_base.rb b/lib/gdal/grid_algorithms/data_metrics_base.rb deleted file mode 100644 index e2622dc9..00000000 --- a/lib/gdal/grid_algorithms/data_metrics_base.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -module GDAL - module GridAlgorithms - class DataMetricsBase - # @return [FFI::GDAL::GridDataMetricsOptions] - attr_reader :options - - def initialize - @options = FFI::GDAL::GridDataMetricsOptions.new - end - end - end -end diff --git a/lib/gdal/grid_algorithms/inverse_distance_to_a_power.rb b/lib/gdal/grid_algorithms/inverse_distance_to_a_power.rb index 43c74f50..77b7dc33 100644 --- a/lib/gdal/grid_algorithms/inverse_distance_to_a_power.rb +++ b/lib/gdal/grid_algorithms/inverse_distance_to_a_power.rb @@ -2,15 +2,11 @@ module GDAL module GridAlgorithms - class InverseDistanceToAPower - # @return [FFI::GDAL::GridInverseDistanceToAPowerOptions] - attr_reader :options - - def initialize - @options = FFI::GDAL::GridInverseDistanceToAPowerOptions.new + class InverseDistanceToAPower < AlgorithmBase + def options_class + ::FFI::GDAL::GridInverseDistanceToAPowerOptions end - # @return [Symbol] def c_identifier :GGA_InverseDistanceToAPower end diff --git a/lib/gdal/grid_algorithms/metric_average_distance.rb b/lib/gdal/grid_algorithms/metric_average_distance.rb index 33c0a516..e16f97be 100644 --- a/lib/gdal/grid_algorithms/metric_average_distance.rb +++ b/lib/gdal/grid_algorithms/metric_average_distance.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricAverageDistance < DataMetricsBase - # @return [Symbol] + class MetricAverageDistance < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricAverageDistance end diff --git a/lib/gdal/grid_algorithms/metric_average_distance_pts.rb b/lib/gdal/grid_algorithms/metric_average_distance_pts.rb index 5a7067dc..b40d628b 100644 --- a/lib/gdal/grid_algorithms/metric_average_distance_pts.rb +++ b/lib/gdal/grid_algorithms/metric_average_distance_pts.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricAverageDistancePts < DataMetricsBase - # @return [Symbol] + class MetricAverageDistancePts < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricAverageDistancePts end diff --git a/lib/gdal/grid_algorithms/metric_count.rb b/lib/gdal/grid_algorithms/metric_count.rb index 9cf0c0db..4bc25b22 100644 --- a/lib/gdal/grid_algorithms/metric_count.rb +++ b/lib/gdal/grid_algorithms/metric_count.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricCount < DataMetricsBase - # @return [Symbol] + class MetricCount < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricCount end diff --git a/lib/gdal/grid_algorithms/metric_maximum.rb b/lib/gdal/grid_algorithms/metric_maximum.rb index 8f1995b7..f2c36bcc 100644 --- a/lib/gdal/grid_algorithms/metric_maximum.rb +++ b/lib/gdal/grid_algorithms/metric_maximum.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricMaximum < DataMetricsBase - # @return [Symbol] + class MetricMaximum < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricMaximum end diff --git a/lib/gdal/grid_algorithms/metric_minimum.rb b/lib/gdal/grid_algorithms/metric_minimum.rb index d0c9a31a..aacd8626 100644 --- a/lib/gdal/grid_algorithms/metric_minimum.rb +++ b/lib/gdal/grid_algorithms/metric_minimum.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricMinimum < DataMetricsBase - # @return [Symbol] + class MetricMinimum < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricMinimum end diff --git a/lib/gdal/grid_algorithms/metric_range.rb b/lib/gdal/grid_algorithms/metric_range.rb index d97cbab0..541bfbae 100644 --- a/lib/gdal/grid_algorithms/metric_range.rb +++ b/lib/gdal/grid_algorithms/metric_range.rb @@ -1,11 +1,12 @@ # frozen_string_literal: true -require_relative "data_metrics_base" - module GDAL module GridAlgorithms - class MetricRange < DataMetricsBase - # @return [Symbol] + class MetricRange < AlgorithmBase + def options_class + ::FFI::GDAL::GridDataMetricsOptions + end + def c_identifier :GGA_MetricRange end diff --git a/lib/gdal/grid_algorithms/moving_average.rb b/lib/gdal/grid_algorithms/moving_average.rb index 52e9cfd3..03a46408 100644 --- a/lib/gdal/grid_algorithms/moving_average.rb +++ b/lib/gdal/grid_algorithms/moving_average.rb @@ -2,15 +2,11 @@ module GDAL module GridAlgorithms - class MovingAverage - # @return [FFI::GDAL::GridMovingAverageOptions] - attr_reader :options - - def initialize - @options = FFI::GDAL::GridMovingAverageOptions.new + class MovingAverage < AlgorithmBase + def options_class + ::FFI::GDAL::GridMovingAverageOptions end - # @return [Symbol] def c_identifier :GGA_MovingAverage end diff --git a/lib/gdal/grid_algorithms/nearest_neighbor.rb b/lib/gdal/grid_algorithms/nearest_neighbor.rb index a70b499a..8b37377c 100644 --- a/lib/gdal/grid_algorithms/nearest_neighbor.rb +++ b/lib/gdal/grid_algorithms/nearest_neighbor.rb @@ -2,15 +2,11 @@ module GDAL module GridAlgorithms - class NearestNeighbor - # @return [FFI::GDAL::GridNearestNeighborOptions] - attr_reader :options - - def initialize - @options = FFI::GDAL::GridNearestNeighborOptions.new + class NearestNeighbor < AlgorithmBase + def options_class + ::FFI::GDAL::GridNearestNeighborOptions end - # @return [Symbol] def c_identifier :GGA_NearestNeighbor end diff --git a/spec/integration/gdal/raster_band_info_spec.rb b/spec/integration/gdal/raster_band_info_spec.rb index 6416c23c..62c80114 100644 --- a/spec/integration/gdal/raster_band_info_spec.rb +++ b/spec/integration/gdal/raster_band_info_spec.rb @@ -101,9 +101,24 @@ describe "#no_data_value" do it "is a Hash with :value and :is_associated keys" do expect(subject.no_data_value).to be_an Hash + expect(subject.no_data_value).to have_key(:value) + expect(subject.no_data_value).to have_key(:is_associated) + end - expect(subject.no_data_value[:value]).to be_nil - expect(subject.no_data_value[:is_associated]).to_not be_nil + it "is a `false` value for :is_associated key" do + expect(subject.no_data_value.fetch(:is_associated)).to eq(false) + end + + it "has `nil` value for :value" do + skip "This spec only for GDAL before 3.6" if GDAL.version_num >= "3060000" + + expect(subject.no_data_value.fetch(:value)).to be_nil + end + + it "has `0` value for :value" do + skip "This spec only for GDAL 3.6+" if GDAL.version_num < "3060000" + + expect(subject.no_data_value.fetch(:value)).to eq(0) end end end diff --git a/spec/unit/ffi/gdal/internal_helpers/gdal_version_spec.rb b/spec/unit/ffi/gdal/internal_helpers/gdal_version_spec.rb new file mode 100644 index 00000000..caedcb12 --- /dev/null +++ b/spec/unit/ffi/gdal/internal_helpers/gdal_version_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require "ffi/gdal" + +RSpec.describe FFI::GDAL::InternalHelpers::GDALVersion do + describe "#version" do + subject(:version) { described_class.version } + + it "returns string from FFI::GDAL::GDALVersionInfo" do + allow(FFI::GDAL).to receive(:GDALVersionInfo).with("VERSION_NUM").and_return("3020123") + + expect(version).to eq("3020123") + + expect(FFI::GDAL).to have_received(:GDALVersionInfo).with("VERSION_NUM") + end + + it "returns string of current GDAL version" do + expect(version).to be_a(String) + end + end +end diff --git a/spec/unit/ffi/gdal/internal_helpers/layout_version_resolver_spec.rb b/spec/unit/ffi/gdal/internal_helpers/layout_version_resolver_spec.rb new file mode 100644 index 00000000..d7a3eaf2 --- /dev/null +++ b/spec/unit/ffi/gdal/internal_helpers/layout_version_resolver_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require "ffi/gdal" + +RSpec.describe FFI::GDAL::InternalHelpers::LayoutVersionResolver do + describe "#resolve" do + subject(:layout) { described_class.resolve(versions: versions) } + + let(:versions) do + [ + FFI::GDAL::InternalHelpers::LayoutVersion.new( + version: "0000000", + layout: %i[radius1 double] + ), + FFI::GDAL::InternalHelpers::LayoutVersion.new( + version: "3060000", + layout: %i[radius2 double] + ), + FFI::GDAL::InternalHelpers::LayoutVersion.new( + version: "3080000", + layout: %i[radius3 double] + ) + ] + end + + context "when GDAL is version 3.2.0" do + it "returns layout for old versions (0000000)" do + allow(FFI::GDAL::InternalHelpers::GDALVersion).to receive(:version).and_return("3020000") + + expect(layout).to eq(%i[radius1 double]) + + expect(FFI::GDAL::InternalHelpers::GDALVersion).to have_received(:version) + end + end + + context "when GDAL is version 3.6.0" do + it "returns layout for version 3060000" do + allow(FFI::GDAL::InternalHelpers::GDALVersion).to receive(:version).and_return("3060000") + + expect(layout).to eq(%i[radius2 double]) + + expect(FFI::GDAL::InternalHelpers::GDALVersion).to have_received(:version) + end + end + + context "when GDAL is version 3.6.1" do + it "returns layout for version 3060000" do + allow(FFI::GDAL::InternalHelpers::GDALVersion).to receive(:version).and_return("3060100") + + expect(layout).to eq(%i[radius2 double]) + + expect(FFI::GDAL::InternalHelpers::GDALVersion).to have_received(:version) + end + end + + context "when GDAL is version 3.9.0" do + it "returns layout for version 3080000" do + allow(FFI::GDAL::InternalHelpers::GDALVersion).to receive(:version).and_return("3080000") + + expect(layout).to eq(%i[radius3 double]) + + expect(FFI::GDAL::InternalHelpers::GDALVersion).to have_received(:version) + end + end + end +end diff --git a/spec/unit/gdal/extensions/raster_band/io_extensions_spec.rb b/spec/unit/gdal/extensions/raster_band/io_extensions_spec.rb index 88b401e3..317804fe 100644 --- a/spec/unit/gdal/extensions/raster_band/io_extensions_spec.rb +++ b/spec/unit/gdal/extensions/raster_band/io_extensions_spec.rb @@ -41,6 +41,8 @@ describe "#set_pixel_value/#pixel_value" do context "valid values, GDT_Byte" do + subject { dataset_byte.raster_band(1) } + it "sets and gets the value successfully" do subject.set_pixel_value(0, 0, 123) expect(subject.pixel_value(0, 0)).to eq(123) @@ -48,6 +50,8 @@ end context "valid values, GDT_Int8" do + subject { dataset_int8.raster_band(1) } + it "sets and gets the value successfully" do skip "This spec only for GDAL 3.7+" if GDAL.version_num < "3070000" diff --git a/spec/unit/ogr/data_source_spec.rb b/spec/unit/ogr/data_source_spec.rb index f48cb3b6..870d3ca0 100644 --- a/spec/unit/ogr/data_source_spec.rb +++ b/spec/unit/ogr/data_source_spec.rb @@ -216,15 +216,15 @@ describe "#sync_to_disk" do # NOTE: We redefine driver, as we should use file-based format to test #sync_to_disk. - let(:driver) { OGR::Driver.by_name("CSV") } - let(:tmpfile) { Tempfile.new(["spec", ".csv"]) } + let(:driver) { OGR::Driver.by_name("GML") } + let(:tmpfile) { Tempfile.new(["spec", ".gml"]) } subject(:data_source) do driver.create_data_source(tmpfile.path) end it do - expect(subject.sync_to_disk).to be_nil + expect(data_source.sync_to_disk).to be_nil end end end diff --git a/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb b/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb index a9273c6c..6a56cb93 100644 --- a/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb +++ b/spec/unit/ogr/geometries/geometry_collection_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbGeometryCollection" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbGeometryCollection end + + it "returns :wkbGeometryCollection25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbGeometryCollection25D + end end end end diff --git a/spec/unit/ogr/geometries/line_string_25d_spec.rb b/spec/unit/ogr/geometries/line_string_25d_spec.rb index bc555779..947b732e 100644 --- a/spec/unit/ogr/geometries/line_string_25d_spec.rb +++ b/spec/unit/ogr/geometries/line_string_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbLineString" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbLineString end + + it "returns :wkbLineString25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbLineString25D + end end end end diff --git a/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb b/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb index 82317a97..569efd28 100644 --- a/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb +++ b/spec/unit/ogr/geometries/multi_line_string_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbMultiLineString" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbMultiLineString end + + it "returns :wkbMultiLineString25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbMultiLineString25D + end end end end diff --git a/spec/unit/ogr/geometries/multi_point_25d_spec.rb b/spec/unit/ogr/geometries/multi_point_25d_spec.rb index dbe25ead..db9a1e90 100644 --- a/spec/unit/ogr/geometries/multi_point_25d_spec.rb +++ b/spec/unit/ogr/geometries/multi_point_25d_spec.rb @@ -16,9 +16,17 @@ context "when created without data" do subject { described_class.new } - it "returns :wkbPoint" do + it "returns :wkbMultiPoint" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbMultiPoint end + + it "returns :wkbMultiPoint25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbMultiPoint25D + end end end end diff --git a/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb b/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb index 831ca284..8cf8f3bf 100644 --- a/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb +++ b/spec/unit/ogr/geometries/multi_polygon_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbMultiPolygon" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbMultiPolygon end + + it "returns :wkbMultiPolygon25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbMultiPolygon25D + end end end end diff --git a/spec/unit/ogr/geometries/point_25d_spec.rb b/spec/unit/ogr/geometries/point_25d_spec.rb index df98c042..a1363dde 100644 --- a/spec/unit/ogr/geometries/point_25d_spec.rb +++ b/spec/unit/ogr/geometries/point_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbPoint" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbPoint end + + it "returns :wkbPoint25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbPoint25D + end end end end diff --git a/spec/unit/ogr/geometries/polygon_25d_spec.rb b/spec/unit/ogr/geometries/polygon_25d_spec.rb index b850a128..49404dbc 100644 --- a/spec/unit/ogr/geometries/polygon_25d_spec.rb +++ b/spec/unit/ogr/geometries/polygon_25d_spec.rb @@ -17,8 +17,16 @@ subject { described_class.new } it "returns :wkbPolygon" do + skip "This spec only for GDAL before 3.8" if GDAL.version_num >= "3080000" + expect(subject.type).to eq :wkbPolygon end + + it "returns :wkbPolygon25D" do + skip "This spec only for GDAL 3.8+" if GDAL.version_num < "3080000" + + expect(subject.type).to eq :wkbPolygon25D + end end end end