module Proj::CoordinateOperationMixin

Coordinate Operations convert {Coordinate coordinates} to a new value. In Proj they are can either by {Conversion conversions} that do not exert a change in reference frame or {Transformation transformations} which do.

Public Instance Methods

accuracy() click to toggle source

Returns the accuracy (in meters) of a coordinate operation.

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_accuracy

@return [Float] The accuracy, or a negative value if unknown or in case of error.

# File lib/proj/coordinate_operation_mixin.rb, line 288
def accuracy
  Api.proj_coordoperation_get_accuracy(self.context, self)
end
ballpark_transformation?() click to toggle source

Return whether a coordinate operation has a “ballpark” transformation

@see proj.org/development/reference/functions.html#c.proj_coordoperation_has_ballpark_transformation

@return [Boolean]

# File lib/proj/coordinate_operation_mixin.rb, line 278
def ballpark_transformation?
  result = Api.proj_coordoperation_has_ballpark_transformation(Context.current, self)
  result == 1 ? true : false
end
create_inverse() click to toggle source

Returns a coordinate operation that represents the inverse operation of this operation

@return [Conversion, Transformation] Returns nil on error

# File lib/proj/coordinate_operation_mixin.rb, line 26
def create_inverse
  ptr = Api.proj_coordoperation_create_inverse(self.context, self)
  self.class.create_object(ptr, self.context)
end
forward(coord) click to toggle source

Transforms a {Coordinate} from the source {Crs} to the target {Crs}. Coordinates should be expressed in the units and axis order of the definition of the source CRS. The returned transformed coordinate will be in the units and axis order of the definition of the target CRS.

@see proj.org/development/reference/functions.html#c.proj_trans

@param coord [Coordinate]

@return [Coordinate]

# File lib/proj/coordinate_operation_mixin.rb, line 154
def forward(coord)
  self.transform(coord, :PJ_FWD)
end
grid(index) click to toggle source

Returns information about a Grid

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_grid_used

@param index [Integer] Grid index

@return [Integer]

# File lib/proj/coordinate_operation_mixin.rb, line 308
def grid(index)
  out_short_name = FFI::MemoryPointer.new(:string)
  out_full_name = FFI::MemoryPointer.new(:string)
  out_package_name = FFI::MemoryPointer.new(:string)
  out_url = FFI::MemoryPointer.new(:string)
  out_direct_download  = FFI::MemoryPointer.new(:int)
  out_open_license = FFI::MemoryPointer.new(:int)
  out_available = FFI::MemoryPointer.new(:int)

  result = Api.proj_coordoperation_get_grid_used(self.context, self, index,
                                                 out_short_name, out_full_name, out_package_name,
                                                 out_url, out_direct_download ,
                                                 out_open_license, out_available)

  if result != 1
    Error.check_object(self)
  end

  name_ptr = out_short_name.read_pointer
  full_name_ptr = out_full_name.read_pointer
  package_name_ptr = out_package_name.read_pointer
  url_ptr = out_url.read_pointer
  downloadable_ptr = out_direct_download 
  open_license_ptr = out_open_license
  available_ptr = out_available

  unless name_ptr.null?
    Grid.new(name_ptr.read_string_to_null, self.context,
             full_name: full_name_ptr.null? ? nil : full_name_ptr.read_string_to_null,
             package_name: package_name_ptr.null? ? nil : package_name_ptr.read_string_to_null,
             url: url_ptr.null? ? nil : url_ptr.read_string_to_null,
             downloadable: downloadable_ptr.null? ? nil : downloadable_ptr.read_int == 1 ? true : false,
             open_license: open_license_ptr.null? ? nil : open_license_ptr.read_int == 1 ? true : false,
             available: available_ptr.null? ? nil : available_ptr.read_int == 1 ? true : false)
  end
end
grid_count() click to toggle source

Returns the number of grids used by a CoordinateOperation

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_grid_used_count

@return [Integer]

# File lib/proj/coordinate_operation_mixin.rb, line 297
def grid_count
  Api.proj_coordoperation_get_grid_used_count(self.context, self)
end
instantiable?() click to toggle source

Return whether a coordinate operation can be instantiated as a PROJ pipeline, checking in particular that referenced grids are available.

@see proj.org/development/reference/functions.html#c.proj_coordoperation_is_instantiable

@return [Boolean]

# File lib/proj/coordinate_operation_mixin.rb, line 18
def instantiable?
  result = Api.proj_coordoperation_is_instantiable(self.context, self)
  result == 1 ? true : false
end
inverse(coord) click to toggle source

Transforms a {Coordinate} from the target {Crs} to the source {Crs}. Coordinates should be expressed in the units and axis order of the definition of the source CRS. The returned transformed coordinate will be in the units and axis order of the definition of the target CRS.

@see proj.org/development/reference/functions.html#c.proj_trans

@param coord [Coordinate]

@return [Coordinate]

# File lib/proj/coordinate_operation_mixin.rb, line 167
def inverse(coord)
  self.transform(coord, :PJ_INV)
end
last_used_operation() click to toggle source

Return the operation used during the last invocation of Transformation#forward or Transformation#inverse

@see }proj.org/development/reference/functions.html#c.proj_trans_get_last_used_operation proj_trans_get_last_used_operation

@return [CoordinateOperationMixin] The last used operation

# File lib/proj/coordinate_operation_mixin.rb, line 268
def last_used_operation
  ptr = Api.proj_trans_get_last_used_operation(self)
  self.class.create_object(ptr, self.context)
end
method_auth_name() click to toggle source

Returns the operation authority name

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info

@return [String]

# File lib/proj/coordinate_operation_mixin.rb, line 62
def method_auth_name
  method_info[:method_auth_name]
end
method_code() click to toggle source

Returns the operation code

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info

@return [String]

# File lib/proj/coordinate_operation_mixin.rb, line 71
def method_code
  method_info[:method_code]
end
method_info() click to toggle source

@!visibility private

# File lib/proj/coordinate_operation_mixin.rb, line 32
def method_info
  out_method_name = FFI::MemoryPointer.new(:string)
  out_method_auth_name = FFI::MemoryPointer.new(:string)
  out_method_code = FFI::MemoryPointer.new(:string)

  result = Api.proj_coordoperation_get_method_info(self.context, self, out_method_name, out_method_auth_name, out_method_code)

  if result != 1
    Error.check_object(self)
  end

  {:method_name => out_method_name.read_pointer.read_string_to_null,
   :method_auth_name => out_method_auth_name.read_pointer.read_string_to_null,
   :method_code => out_method_code.read_pointer.read_string_to_null}
end
method_name() click to toggle source

Returns the operation name

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_method_info

@return [String]

# File lib/proj/coordinate_operation_mixin.rb, line 53
def method_name
  method_info[:method_name]
end
normalize_for_visualization() click to toggle source

Returns a new PJ object whose axis order is the one expected for visualization purposes

@see proj.org/development/reference/functions.html#c.proj_normalize_for_visualization

@return [CoordinateOperationMixin] A new CoordinateOperation or nil in case of error

# File lib/proj/coordinate_operation_mixin.rb, line 258
def normalize_for_visualization
  ptr = Api.proj_normalize_for_visualization(self.context, self)
  self.class.create_object(ptr, self.context)
end
param(index) click to toggle source

Returns a parameter of a SingleOperation

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_param

@param index [Integer] Parameter index

@return [Param]

# File lib/proj/coordinate_operation_mixin.rb, line 102
def param(index)
  out_name = FFI::MemoryPointer.new(:string)
  out_auth_name = FFI::MemoryPointer.new(:string)
  out_code = FFI::MemoryPointer.new(:string)
  out_value = FFI::MemoryPointer.new(:double)
  out_value_string = FFI::MemoryPointer.new(:string)
  out_unit_conv_factor = FFI::MemoryPointer.new(:double)
  out_unit_name = FFI::MemoryPointer.new(:string)
  out_unit_auth_name = FFI::MemoryPointer.new(:string)
  out_unit_code = FFI::MemoryPointer.new(:string)
  out_unit_category = FFI::MemoryPointer.new(:string)

  result = Api.proj_coordoperation_get_param(self.context, self, index,
                                             out_name, out_auth_name, out_code,
                                             out_value, out_value_string,
                                             out_unit_conv_factor,
                                             out_unit_name, out_unit_auth_name,out_unit_code,
                                             out_unit_category)
  if result != 1
    Error.check_object(self)
  end

  name_ptr = out_name.read_pointer
  auth_name_ptr = out_auth_name.read_pointer
  code_ptr = out_code.read_pointer
  value_string_ptr = out_value_string.read_pointer
  unit_name_ptr = out_unit_name.read_pointer
  unit_auth_name_ptr = out_unit_auth_name.read_pointer
  unit_code_ptr = out_unit_code.read_pointer
  unit_category_ptr = out_unit_category.read_pointer

  Param.new(name: name_ptr.null? ? nil : name_ptr.read_string_to_null,
            auth_name: auth_name_ptr.null? ? nil : auth_name_ptr.read_string_to_null,
            code: code_ptr.null? ? nil : code_ptr.read_string_to_null,
            value: out_value.null? ? nil : out_value.read_double,
            value_string: value_string_ptr.null? ? nil : value_string_ptr.read_string_to_null,
            unit_conv_factor: out_unit_conv_factor.null? ? nil : out_unit_conv_factor.read_double,
            unit_name: unit_name_ptr.null? ? nil : unit_name_ptr.read_string_to_null,
            unit_auth_name: unit_auth_name_ptr.null? ? nil : unit_auth_name_ptr.read_string_to_null,
            unit_code: unit_code_ptr.null? ? nil : unit_code_ptr.read_string_to_null,
            unit_category: unit_category_ptr.null? ? nil : unit_category_ptr.read_string_to_null)
end
param_count() click to toggle source

Returns the number of parameters of a SingleOperation

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_param_count

@return [Integer]

# File lib/proj/coordinate_operation_mixin.rb, line 80
def param_count
  Api.proj_coordoperation_get_param_count(self.context, self)
end
param_index(name) click to toggle source

Returns the index of a parameter of a SingleOperation

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_param_index

@param name [String] Name of the parameter. Must not be nil

@return [Integer] Index of the parameter or -1 in case of error.

# File lib/proj/coordinate_operation_mixin.rb, line 91
def param_index(name)
  Api.proj_coordoperation_get_param_index(self.context, self, name)
end
roundtrip(direction, iterations, coordinate) click to toggle source

Measure the internal consistency of a given transformation. The function performs n round trip transformations starting in either the forward or reverse direction.

@see proj.org/development/reference/functions.html#c.proj_roundtrip

@param direction [PJ_DIRECTION] The starting direction of transformation @param iterations [Integer] The number of roundtrip transformations @param coordinate [Coordinate] The input coordinate

@return [Float] The euclidean distance of the starting point coordinate and the last coordinate after n iterations back and forth.

# File lib/proj/coordinate_operation_mixin.rb, line 249
def roundtrip(direction, iterations, coordinate)
  Api.proj_roundtrip(self, direction, iterations, coordinate.pj_coord)
end
step(index) click to toggle source

Returns a step of a concatenated operation

@see proj.org/development/reference/functions.html#c.proj_concatoperation_get_step

@param index [Integer] Index of the step

@return [PjObject]

# File lib/proj/coordinate_operation_mixin.rb, line 376
def step(index)
  ptr = Api.proj_concatoperation_get_step(self.context, self, index)
  self.class.create_object(ptr, self.context)
end
step_count() click to toggle source

Returns the number of steps in a concatenated operation

@see proj.org/development/reference/functions.html#c.proj_concatoperation_get_step_count

@return [Integer] The number of steps

# File lib/proj/coordinate_operation_mixin.rb, line 365
def step_count
  Api.proj_concatoperation_get_step_count(self.context, self)
end
to_wgs84(error_if_incompatible = false) click to toggle source

Return the parameters of a Helmert transformation as WKT1 TOWGS84 values

@see proj.org/development/reference/functions.html#c.proj_coordoperation_get_towgs84_values

@param error_if_incompatible [Boolean] If true an exception is thrown if the coordinate operation is not compatible with a WKT1 TOWGS84 representation

@return [Array<Float>]] Array of 7 numbers that represent translation, rotation and scale parameters.

Rotation and scale difference terms might be zero if the transformation only includes translation parameters
# File lib/proj/coordinate_operation_mixin.rb, line 353
def to_wgs84(error_if_incompatible = false)
  parameter_count = 7
  out_values = FFI::MemoryPointer.new(:double, parameter_count)
  Api.proj_coordoperation_get_towgs84_values(self.context, self, out_values, parameter_count, error_if_incompatible ? 1 : 0)
  out_values.read_array_of_double(parameter_count)
end
transform(coord, direction) click to toggle source

Transforms a {Coordinate} in the specified direction. See {CoordinateOperationMixin#forward forward} and {CoordinateOperationMixin#inverse inverse}

@see proj.org/development/reference/functions.html#c.proj_trans

@param direction [PJ_DIRECTION] Direction of transformation (:PJ_FWD or :PJ_INV) @param coord [Coordinate]

@return [Coordinate]

# File lib/proj/coordinate_operation_mixin.rb, line 180
def transform(coord, direction)
  struct = Api.proj_trans(self, direction, coord)
  Coordinate.from_coord(struct)
end
transform_array(coordinates, direction) click to toggle source

Transforms an array of {Coordinate coordinates}. Individual points that fail to transform will have their components set to Infinity.

@param coordinates [Array<Coordinate>] Coordinates to transform @param direction [PJ_DIRECTION] The direction of the transformation

@return [Array<Coordinate>] Array of transformed coordinates

# File lib/proj/coordinate_operation_mixin.rb, line 219
def transform_array(coordinates, direction)
  coords_ptr = FFI::MemoryPointer.new(Api::PJ_COORD, coordinates.size)
  coordinates.each_with_index do |coordinate, i|
    pj_coord = Api::PJ_COORD.new(coords_ptr[i])
    pj_coord.to_ptr.__copy_from__(coordinate.to_ptr, Api::PJ_COORD.size)
  end

  int = Api.proj_trans_array(self, direction, coordinates.size, coords_ptr)
  unless int == 0
    Error.check_object(self)
  end

  result = Array.new(coordinates.size)
  0.upto(coordinates.size) do |i|
    pj_coord = Api::PJ_COORD.new(coords_ptr[i])
    result[i] = Coordinate.from_coord(pj_coord)
  end
  result
end
transform_bounds(bounds, direction, densify_points = 21) click to toggle source

Transform boundary densifying the edges to account for nonlinear transformations along these edges and extracting the outermost bounds.

@see proj.org/development/reference/functions.html#c.proj_trans_bounds

@param bounds [Area] Bounding box in source CRS (target CRS if direction is inverse). @param direction [PJ_DIRECTION] The direction of the transformation. @param densify_points [Integer] Recommended to use 21. This is the number of points to use to densify the bounding polygon in the transformation.

@return [Area] Bounding box in target CRS (target CRS if direction is inverse).

# File lib/proj/coordinate_operation_mixin.rb, line 195
def transform_bounds(bounds, direction, densify_points = 21)
  out_xmin = FFI::MemoryPointer.new(:double)
  out_ymin = FFI::MemoryPointer.new(:double)
  out_xmax = FFI::MemoryPointer.new(:double)
  out_ymax = FFI::MemoryPointer.new(:double)

  result = Api.proj_trans_bounds(self.context, self, direction,
                                 bounds.xmin, bounds.ymin, bounds.xmax, bounds.ymax,
                                 out_xmin, out_ymin, out_xmax, out_ymax, densify_points)

  unless result == 0
    Error.check_object(self)
  end

  Bounds.new(out_xmin.read_double, out_ymin.read_double, out_xmax.read_double, out_ymax.read_double)
end