class OGR::Feature

Attributes

c_pointer[R]

@return [FFI::Pointer] C pointer of the C Feature.

Public Class Methods

new(fd_or_pointer) click to toggle source

@param fd_or_pointer [OGR::FeatureDefinition, FFI::Pointer] Must either be

a FeatureDefinition (i.e. normal Feature creation) or a Pointer (in the
case a handle to a C OGR Feature needs to be wrapped with this object).
# File lib/ogr/feature.rb, line 22
def initialize(fd_or_pointer)
  pointer = case fd_or_pointer
            when OGR::FeatureDefinition then FFI::OGR::API.OGR_F_Create(fd_or_pointer.c_pointer)
            when FFI::Pointer
              fd_or_pointer.autorelease = false
              fd_or_pointer
            else
              raise OGR::InvalidFeature, "OGR::Feature must be instantiated with valid feature"
            end

  if !pointer.is_a?(FFI::Pointer) || pointer.null?
    raise OGR::InvalidFeature, "Unable to create Feature with #{fd_or_pointer}"
  end

  # pointer.autorelease = false

  # @c_pointer = FFI::AutoPointer.new(pointer, Feature.method(:release))
  @c_pointer = pointer
end
release(pointer) click to toggle source

@param pointer [FFI::Pointer]

# File lib/ogr/feature.rb, line 10
def self.release(pointer)
  return unless pointer && !pointer.null?

  FFI::OGR::API.OGR_F_Destroy(pointer)
end

Public Instance Methods

clone() click to toggle source

@return [OGR::Feature] @raise [OGR::Failure] If, for some reason, the clone fails.

# File lib/ogr/feature.rb, line 50
def clone
  # This new feature is owned by the caller and must be released accordingly.
  feature_ptr = FFI::OGR::API.OGR_F_Clone(@c_pointer)
  raise OGR::Failure, "Unable to clone feature" if feature_ptr.nil?

  OGR::Feature.new(feature_ptr)
end
definition() click to toggle source

@return [OGR::FeatureDefinition,nil]

# File lib/ogr/feature.rb, line 225
def definition
  feature_defn_ptr = FFI::OGR::API.OGR_F_GetDefnRef(@c_pointer)
  feature_defn_ptr.autorelease = false

  return nil if feature_defn_ptr.null?

  OGR::FeatureDefinition.new(feature_defn_ptr)
end
destroy!() click to toggle source
# File lib/ogr/feature.rb, line 42
def destroy!
  Feature.release(@c_pointer)

  @c_pointer = nil
end
dump_readable(file_path = nil) click to toggle source

Dumps the feature out to the file in human-readable form.

@param file_path [String]

# File lib/ogr/feature.rb, line 61
def dump_readable(file_path = nil)
  file_ptr = file_path ? FFI::CPL::Conv.CPLOpenShared(file_path, "w", false) : nil
  FFI::OGR::API.OGR_F_DumpReadable(@c_pointer, file_ptr)
  FFI::CPL::Conv.CPLCloseShared(file_ptr) if file_ptr
end
equal?(other) click to toggle source

@return [Boolean]

# File lib/ogr/feature.rb, line 372
def equal?(other)
  FFI::OGR::API.OGR_F_Equal(@c_pointer, c_pointer_from(other))
end
Also aliased as: equals?
equals?(other)
Alias for: equal?
fid() click to toggle source

@return [Integer]

# File lib/ogr/feature.rb, line 281
def fid
  FFI::OGR::API.OGR_F_GetFID(@c_pointer)
end
fid=(new_fid) click to toggle source

@param new_fid [Integer] @raise [OGR::Failure]

# File lib/ogr/feature.rb, line 287
def fid=(new_fid)
  OGR::ErrorHandling.handle_ogr_err("Unable to set FID") do
    FFI::OGR::API.OGR_F_SetFID(@c_pointer, new_fid)
  end
end
field_as_binary(index) click to toggle source

@param index [Integer] @return [String]

# File lib/ogr/feature.rb, line 438
def field_as_binary(index)
  byte_count_ptr = FFI::MemoryPointer.new(:int)

  # This list is internal, and should not be modified, or freed. Its lifetime may be very brief.
  binary_data_ptr = FFI::OGR::API.OGR_F_GetFieldAsBinary(@c_pointer, index, byte_count_ptr)
  binary_data_ptr.autorelease = false

  byte_count = byte_count_ptr.read_int
  string = byte_count.positive? ? binary_data_ptr.read_bytes(byte_count) : ""

  string.unpack("C*")
end
field_as_date_time(index) click to toggle source
# File lib/ogr/feature.rb, line 451
def field_as_date_time(index)
  year_ptr = FFI::MemoryPointer.new(:int)
  month_ptr = FFI::MemoryPointer.new(:int)
  day_ptr = FFI::MemoryPointer.new(:int)
  hour_ptr = FFI::MemoryPointer.new(:int)
  minute_ptr = FFI::MemoryPointer.new(:int)
  second_ptr = FFI::MemoryPointer.new(:int)
  time_zone_flag_ptr = FFI::MemoryPointer.new(:int)

  success = FFI::OGR::API.OGR_F_GetFieldAsDateTime(
    @c_pointer,
    index,
    year_ptr,
    month_ptr,
    day_ptr,
    hour_ptr,
    minute_ptr,
    second_ptr,
    time_zone_flag_ptr
  )
  return nil unless success

  formatted_tz = OGR._format_time_zone_for_ruby(time_zone_flag_ptr.read_int)

  if formatted_tz
    DateTime.new(
      year_ptr.read_int,
      month_ptr.read_int,
      day_ptr.read_int,
      hour_ptr.read_int,
      minute_ptr.read_int,
      second_ptr.read_int,
      formatted_tz
    )
  else
    DateTime.new(
      year_ptr.read_int,
      month_ptr.read_int,
      day_ptr.read_int,
      hour_ptr.read_int,
      minute_ptr.read_int,
      second_ptr.read_int
    )
  end
end
field_as_double(index) click to toggle source

@param index [Integer] @return [Float]

# File lib/ogr/feature.rb, line 398
def field_as_double(index)
  FFI::OGR::API.OGR_F_GetFieldAsDouble(@c_pointer, index)
end
field_as_double_list(index) click to toggle source

@param index [Integer] @return [Array<Float>]

# File lib/ogr/feature.rb, line 404
def field_as_double_list(index)
  list_size_ptr = FFI::MemoryPointer.new(:int)
  # This list is internal, and should not be modified, or freed. Its lifetime may be very brief.
  list_ptr = FFI::OGR::API.OGR_F_GetFieldAsDoubleList(@c_pointer, index, list_size_ptr)
  list_ptr.autorelease = false

  return [] if list_ptr.null?

  list_ptr.read_array_of_double(list_size_ptr.read_int)
end
field_as_integer(index) click to toggle source

@param index [Integer] @return [Integer]

# File lib/ogr/feature.rb, line 379
def field_as_integer(index)
  FFI::OGR::API.OGR_F_GetFieldAsInteger(@c_pointer, index)
end
field_as_integer_list(index) click to toggle source

@param index [Integer] @return [Array<Integer>]

# File lib/ogr/feature.rb, line 385
def field_as_integer_list(index)
  list_size_ptr = FFI::MemoryPointer.new(:int)
  #  This list is internal, and should not be modified, or freed. Its lifetime may be very brief.
  list_ptr = FFI::OGR::API.OGR_F_GetFieldAsIntegerList(@c_pointer, index, list_size_ptr)
  list_ptr.autorelease = false

  return [] if list_ptr.null?

  list_ptr.read_array_of_int(list_size_ptr.read_int)
end
field_as_string(index) click to toggle source

@param index [Integer] @return [String]

# File lib/ogr/feature.rb, line 417
def field_as_string(index)
  field, ptr = FFI::OGR::API.OGR_F_GetFieldAsString(@c_pointer, index)
  ptr.autorelease = false

  field.force_encoding(Encoding::UTF_8)
end
field_as_string_list(index) click to toggle source

@param index [Integer] @return [Array<String>]

# File lib/ogr/feature.rb, line 426
def field_as_string_list(index)
  # This list is internal, and should not be modified, or freed. Its lifetime may be very brief.
  list_ptr = FFI::OGR::API.OGR_F_GetFieldAsStringList(@c_pointer, index)
  list_ptr.autorelease = false

  return [] if list_ptr.null?

  list_ptr.get_array_of_string(0)
end
field_count() click to toggle source

This will always be the same as the field count for the feature definition.

@return [Integer]

# File lib/ogr/feature.rb, line 88
def field_count
  FFI::OGR::API.OGR_F_GetFieldCount(@c_pointer)
end
field_definition(index) click to toggle source

NOTE: Do not modify the FieldDefinition that’s returned here.

@param index [Integer] @return [OGR::FieldDefinition]

# File lib/ogr/feature.rb, line 195
def field_definition(index)
  # This returns an internal reference and should not be deleted or modified
  field_pointer = FFI::OGR::API.OGR_F_GetFieldDefnRef(@c_pointer, index)
  field_pointer.autorelease = false

  return nil if field_pointer.null?

  OGR::FieldDefinition.new(field_pointer, nil)
end
field_index(name) click to toggle source

@param name [String] @return [Integer, nil]

# File lib/ogr/feature.rb, line 207
def field_index(name)
  result = FFI::OGR::API.OGR_F_GetFieldIndex(@c_pointer, name)

  result.negative? ? nil : result
end
field_set?(index) click to toggle source

@param index [Integer] @return [Boolean]

# File lib/ogr/feature.rb, line 215
def field_set?(index)
  FFI::OGR::API.OGR_F_IsFieldSet(@c_pointer, index)
end
geometry() click to toggle source

NOTE: Do not modify the Geometry that’s returned here.

@return [OGR::Geometry]

# File lib/ogr/feature.rb, line 237
def geometry
  # This returns an internal reference and should not be deleted or modified
  geometry_ptr = FFI::OGR::API.OGR_F_GetGeometryRef(@c_pointer)
  geometry_ptr.autorelease = false

  return nil if geometry_ptr.null?

  OGR::Geometry.factory(geometry_ptr)
end
geometry=(new_geometry)
geometry_field(index) click to toggle source

NOTE: Do not modify the Geometry that’s returned here.

@param index [Integer] @return [OGR::Geometry, nil] A read-only OGR::Geometry.

# File lib/ogr/feature.rb, line 330
def geometry_field(index)
  # This returns an internal reference and should not be deleted or modified
  geometry_ptr = FFI::OGR::API.OGR_F_GetGeomFieldRef(@c_pointer, index)
  geometry_ptr.autorelease = false

  return nil if geometry_ptr.nil? || geometry_ptr.null?

  OGR::Geometry.factory(geometry_ptr)
end
geometry_field_count() click to toggle source

The number of Geometries in this feature.

@return [Integer]

# File lib/ogr/feature.rb, line 296
def geometry_field_count
  FFI::OGR::API.OGR_F_GetGeomFieldCount(@c_pointer)
end
geometry_field_definition(index) click to toggle source

NOTE: Do not modify the GeometryFieldDefinition that’s returned here.

@param index [Integer] @return [OGR::GeometryFieldDefinition] A read-only

OGR::GeometryFieldDefinition.

@raise [OGR::InvalidGeometryFieldDefinition] If there isn’t one at

+index+.
# File lib/ogr/feature.rb, line 307
def geometry_field_definition(index)
  # This returns an internal reference and should not be deleted or modified
  gfd_ptr = FFI::OGR::API.OGR_F_GetGeomFieldDefnRef(@c_pointer, index)
  gfd_ptr.autorelease = false

  return nil if gfd_ptr.nil?

  gfd = OGR::GeometryFieldDefinition.new(gfd_ptr)
  gfd.read_only = true

  gfd
end
geometry_field_index(name) click to toggle source

@param name [String] @return [Integer]

# File lib/ogr/feature.rb, line 322
def geometry_field_index(name)
  FFI::OGR::API.OGR_F_GetGeomFieldIndex(@c_pointer, name)
end
set_field_binary(index, value) click to toggle source

@param index [Integer] @param value [String]

# File lib/ogr/feature.rb, line 161
def set_field_binary(index, value)
  raise TypeError, "value must be a binary string" unless value.is_a? String

  value_ptr = FFI::MemoryPointer.new(:uchar, value.length)
  value_ptr.put_bytes(0, value)

  FFI::OGR::API.OGR_F_SetFieldBinary(
    @c_pointer,
    index,
    value.length,
    value_ptr
  )
end
set_field_date_time(index, value) click to toggle source

@param index [Integer] @param value [Date, Time, DateTime]

# File lib/ogr/feature.rb, line 177
def set_field_date_time(index, value)
  time = value.to_time
  zone = OGR._format_time_zone_for_ogr(value.zone)

  FFI::OGR::API.OGR_F_SetFieldDateTime(@c_pointer, index,
                                       time.year,
                                       time.month,
                                       time.day,
                                       time.hour,
                                       time.min,
                                       time.sec,
                                       zone)
end
set_field_double(index, value) click to toggle source

@param index [Integer] @param value [Float]

# File lib/ogr/feature.rb, line 106
def set_field_double(index, value)
  FFI::OGR::API.OGR_F_SetFieldDouble(@c_pointer, index, value)
end
set_field_double_list(index, values) click to toggle source

@param index [Integer] @param values [Array<Float>]

# File lib/ogr/feature.rb, line 139
def set_field_double_list(index, values)
  values_ptr = FFI::MemoryPointer.new(:double, values.size)
  values_ptr.write_array_of_double(values)

  FFI::OGR::API.OGR_F_SetFieldDoubleList(
    @c_pointer,
    index,
    values.size,
    values_ptr
  )
end
set_field_integer(index, value) click to toggle source

@param index [Integer] @param value [Integer]

# File lib/ogr/feature.rb, line 100
def set_field_integer(index, value)
  FFI::OGR::API.OGR_F_SetFieldInteger(@c_pointer, index, value)
end
set_field_integer_list(index, values) click to toggle source

@param index [Integer] @param values [Array<Integer>]

# File lib/ogr/feature.rb, line 125
def set_field_integer_list(index, values)
  values_ptr = FFI::MemoryPointer.new(:int, values.size)
  values_ptr.write_array_of_int(values)

  FFI::OGR::API.OGR_F_SetFieldIntegerList(
    @c_pointer,
    index,
    values.size,
    values_ptr
  )
end
set_field_raw(index, field) click to toggle source

@param index [Integer] @param field [OGR::Field]

# File lib/ogr/feature.rb, line 153
def set_field_raw(index, field)
  usable_raw_field = field.c_struct

  FFI::OGR::API.OGR_F_SetFieldRaw(@c_pointer, index, usable_raw_field)
end
set_field_string(index, value) click to toggle source

@param index [Integer] @param value [String]

# File lib/ogr/feature.rb, line 94
def set_field_string(index, value)
  FFI::OGR::API.OGR_F_SetFieldString(@c_pointer, index, value)
end
set_field_string_list(index, values) click to toggle source

@param index [Integer] @param values [Array<String>] @raise [GDAL::Error] If index isn’t valid

# File lib/ogr/feature.rb, line 113
def set_field_string_list(index, values)
  values_ptr = GDAL._string_array_to_pointer(values)

  FFI::OGR::API.OGR_F_SetFieldStringList(
    @c_pointer,
    index,
    values_ptr
  )
end
set_from!(_other_feature, _be_forgiving: false, with_map: nil) click to toggle source

Overwrites the contents of this feature from the geometry and attributes of the other_feature.

@param _other_feature [OGR::Feature] @param _be_forgiving [Boolean] true if the operation should continue

despite lacking output fields matching some of the source fields.

@param with_map [Array<Integer>] @raise [OGR::Failure] TODO: Implement with_map

# File lib/ogr/feature.rb, line 76
def set_from!(_other_feature, _be_forgiving: false, with_map: nil)
  raise NotImplementedError, "with_map: is not yet supported" if with_map

  OGR::ErrorHandling.handle_ogr_err("Unable to set from other feature") do
    FFI::OGR::API.OGR_F_SetFrom(@c_pointer, other_feature_ptr)
  end
end
set_geometry(new_geometry) click to toggle source

Sets the geometry of the feature by making a copy of new_geometry.

@param new_geometry [OGR::Geometry] @raise [OGR::Failure]

# File lib/ogr/feature.rb, line 251
def set_geometry(new_geometry) # rubocop:disable Naming/AccessorMethodName
  OGR::ErrorHandling.handle_ogr_err("Unable to set geometry on feature") do
    FFI::OGR::API.OGR_F_SetGeometry(@c_pointer, new_geometry.c_pointer)
  end
end
set_geometry_directly(new_geometry) click to toggle source

Sets the geometry of the feature by taking ownership of +new_geometry.

@param new_geometry [OGR::Geometry] @raise [OGR::Failure]

# File lib/ogr/feature.rb, line 261
def set_geometry_directly(new_geometry) # rubocop:disable Naming/AccessorMethodName
  new_geometry.c_pointer.autorelease = false

  OGR::ErrorHandling.handle_ogr_err("Unable to set geometry directly on feature") do
    FFI::OGR::API.OGR_F_SetGeometryDirectly(@c_pointer, new_geometry.c_pointer)
  end
end
Also aliased as: geometry=
set_geometry_field(index, geometry) click to toggle source

Sets the feature geometry of a specified geometry field by making a copy of geometry.

@param index [Integer] @param geometry [OGR::Geometry] @raise [OGR::Failure]

# File lib/ogr/feature.rb, line 346
def set_geometry_field(index, geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry)
  raise OGR::InvalidGeometry if geometry_ptr.nil?

  OGR::ErrorHandling.handle_ogr_err("Unable to set geometry field at index #{index}") do
    FFI::OGR::API.OGR_F_SetGeomField(@c_pointer, index, geometry_ptr)
  end
end
set_geometry_field_directly(index, geometry) click to toggle source

Sets the feature geometry of a specified geometry field by taking ownership of geometry.

@param index [Integer] @param geometry [OGR::Geometry] @raise [OGR::Failure]

# File lib/ogr/feature.rb, line 361
def set_geometry_field_directly(index, geometry)
  geometry_ptr = GDAL._pointer(OGR::Geometry, geometry, autorelease: false)

  raise OGR::InvalidGeometry if geometry_ptr.nil?

  OGR::ErrorHandling.handle_ogr_err("Unable to set geometry field directly at index #{index}") do
    FFI::OGR::API.OGR_F_SetGeomFieldDirectly(@c_pointer, index, geometry_ptr)
  end
end
steal_geometry() click to toggle source

Takes away ownership of the Feature’s Geometry and returns it to the caller.

@return [OGR::Geometry]

# File lib/ogr/feature.rb, line 273
def steal_geometry
  geometry_ptr = FFI::OGR::API.OGR_F_StealGeometry(@c_pointer)
  raise OGR::Failure, "Unable to steal geometry." if geometry_ptr.nil? || geometry_ptr.null?

  OGR::Geometry.factory(geometry_ptr)
end
style_string() click to toggle source

@return [String]

# File lib/ogr/feature.rb, line 498
def style_string
  style, ptr = FFI::OGR::API.OGR_F_GetStyleString(@c_pointer)
  ptr.autorelease = false

  style
end
style_string=(new_style) click to toggle source

@param new_style [String]

# File lib/ogr/feature.rb, line 506
def style_string=(new_style)
  FFI::OGR::API.OGR_F_SetStyleString(@c_pointer, new_style)
end
style_table() click to toggle source

@return [OGR::StyleTable]

# File lib/ogr/feature.rb, line 511
def style_table
  style_table_ptr = FFI::OGR::API.OGR_F_GetStyleTable(@c_pointer)
  style_table_ptr.autorelease = false

  return nil if style_table_ptr.nil? || style_table_ptr.null?

  OGR::StyleTable.new(style_table_ptr)
end
style_table=(new_style_table) click to toggle source

@param new_style_table [OGR::StyleTable]

# File lib/ogr/feature.rb, line 521
def style_table=(new_style_table)
  new_style_table_ptr = GDAL._pointer(OGR::StyleTable, new_style_table, autorelease: false)

  raise OGR::InvalidStyleTable unless new_style_table_ptr

  FFI::OGR::API.OGR_F_SetStyleTableDirectly(@c_pointer, new_style_table_ptr)
end
unset_field(index) click to toggle source

@param index [Integer]

# File lib/ogr/feature.rb, line 220
def unset_field(index)
  FFI::OGR::API.OGR_F_UnsetField(@c_pointer, index)
end

Private Instance Methods

c_pointer_from(feature) click to toggle source
# File lib/ogr/feature.rb, line 531
def c_pointer_from(feature)
  case feature
  when OGR::Feature
    feature.c_pointer
  when FFI::Pointer
    feature
  end
end