class Proj4::Projection

Attributes

ptr[R]

Public Class Methods

new(arg, auto_free = true) click to toggle source
# File lib/ffi-proj4/projection.rb, line 10
def initialize(arg, auto_free = true)
  args = case arg
    when Array
      arg.collect { |a| a.sub(/^\+/, '') }
    when String
      if arg =~ /^(epsg|esri):/i
        [ "+init=#{arg}" ]
      else
        arg.strip.split(/ /).collect { |a| a.sub(/^\+/, '') }
      end
    when Hash
      arg.collect { |k, v|
        if v.nil?
          k.to_s
        else
          "#{k.to_s.strip}=#{v.to_s.strip}"
        end
      }
    when Proj4::Projection
      arg.definition.strip.split(/ /).collect { |a| a.sub(/^\+/, '') }
    else
      raise ArgumentError.new("Unknown type #{arg.class} for projection definition")
  end

  params = args.collect(&:strip).collect { |a|
    if !(a =~ /^\+/)
      "+#{a}"
    else
      a
    end
  }.join(' ')

  ptr = FFIProj4.pj_init_plus(params)

  if ptr.null?
    result = FFIProj4.pj_get_errno_ref.read_int
    raise ProjectionParseError.new(FFIProj4.pj_strerrno(result))
  else
    @ptr = FFI::AutoPointer.new(
      ptr,
      self.class.method(:release)
    )
  end

  self.ptr.autorelease = auto_free
end

Public Instance Methods

datum() click to toggle source
# File lib/ffi-proj4/projection.rb, line 229
def datum
  self.to_hash[:datum]
end
datum_transform(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 200
def datum_transform(proj, *args)
  self.datum_transform!(proj, *(dup_args(*args)))
end
datum_transform!(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 195
def datum_transform!(proj, *args)
  perform_transform(:pj_datum_transform, proj, *args)
end
Also aliased as: datum_transform_rad!
datum_transform_deg(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 208
def datum_transform_deg(proj, *args)
  self.datum_transform_deg!(proj, *(dup_args(*args)))
end
datum_transform_deg!(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 204
def datum_transform_deg!(proj, *args)
  self.datum_transform!(proj, *args).to_deg!
end
datum_transform_rad!(proj, *args)
Alias for: datum_transform!
definition() click to toggle source
# File lib/ffi-proj4/projection.rb, line 72
def definition
  @definition ||= FFIProj4.pj_get_def(self.ptr, 0).strip
end
Also aliased as: getDef
definition_as_hash()
Alias for: to_hash
forward(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 112
def forward(*args)
  self.forward!(*dup_args(*args))
end
Also aliased as: forward_rad, forwardRad
forward!(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 94
def forward!(*args)
  xy, point = xy_and_point_from_args(*args)

  ret = FFIProj4.pj_fwd(xy, self.ptr)
  result = FFIProj4.pj_get_errno_ref.read_int

  if result == 0
    point.x = ret[:x]
    point.y = ret[:y]
    point.z = 0 if point.respond_to?(:z=)
    point
  else
    raise Proj4::Error.instantiate_error(result)
  end
end
Also aliased as: forward_rad!, forwardRad!
forwardDeg(*args)
Alias for: forward_deg
forwardDeg!(*args)
Alias for: forward_deg!
forwardRad(*args)
Alias for: forward
forwardRad!(*args)
Alias for: forward!
forward_all(proj, collection) click to toggle source
# File lib/ffi-proj4/projection.rb, line 135
def forward_all(proj, collection)
  collection.collect do |args|
    self.forward!(proj, *(dup_args(*args)))
  end
end
forward_all!(collection) click to toggle source
# File lib/ffi-proj4/projection.rb, line 128
def forward_all!(collection)
  collection.each do |args|
    self.forward_all!(proj, *args)
  end
  collection
end
forward_deg(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 123
def forward_deg(*args)
  self.forward_deg!(*dup_args(*args))
end
Also aliased as: forwardDeg
forward_deg!(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 118
def forward_deg!(*args)
  self.forward!(*args_deg_to_rad(*args))
end
Also aliased as: forwardDeg!
forward_rad(*args)
Alias for: forward
forward_rad!(*args)
Alias for: forward!
geocentric?() click to toggle source
# File lib/ffi-proj4/projection.rb, line 66
def geocentric?
  bool_result(FFIProj4.pj_is_geocent(self.ptr))
end
Also aliased as: isGeocent?, isGeocentric?
getDef()
Alias for: definition
inspect()
Alias for: to_s
inverse(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 159
def inverse(*args)
  self.inverse!(*dup_args(*args))
end
Also aliased as: inverse_rad, inverseRad
inverse!(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 141
def inverse!(*args)
  xy, point = xy_and_point_from_args(*args)

  ret = FFIProj4.pj_inv(xy, self.ptr)
  result = FFIProj4.pj_get_errno_ref.read_int

  if result == 0
    point.x = ret[:x]
    point.y = ret[:y]
    point.z = 0 if point.respond_to?(:z=)
    point
  else
    raise Proj4::Error.instantiate_error(result)
  end
end
Also aliased as: inverse_rad!, inverseRad!
inverseDeg(*args)
Alias for: inverse_deg
inverseDeg!(*args)
Alias for: inverse_deg!
inverseRad(*args)
Alias for: inverse
inverseRad!(*args)
Alias for: inverse!
inverse_deg(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 170
def inverse_deg(*args)
  self.inverse_deg!(*dup_args(*args))
end
Also aliased as: inverseDeg
inverse_deg!(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 165
def inverse_deg!(*args)
  self.inverse!(*args).to_deg!
end
Also aliased as: inverseDeg!
inverse_rad(*args)
Alias for: inverse
inverse_rad!(*args)
Alias for: inverse!
isGeocent?()
Alias for: geocentric?
isGeocentric?()
Alias for: geocentric?
isLatLong?()
Alias for: lat_long?
lat_long?() click to toggle source
# File lib/ffi-proj4/projection.rb, line 61
def lat_long?
  bool_result(FFIProj4.pj_is_latlong(self.ptr))
end
Also aliased as: isLatLong?
projection() click to toggle source
# File lib/ffi-proj4/projection.rb, line 225
def projection
  self.to_hash[:proj]
end
to_hash() click to toggle source
# File lib/ffi-proj4/projection.rb, line 77
def to_hash
  @hash ||= self.definition.split(/ /).inject({}) { |memo, opt|
    memo.tap {
      k, v = opt.split('=')
      k.sub!(/^\+/, '')
      v = true if v.nil?
      memo[k.to_sym] = v
    }
  }
end
Also aliased as: definition_as_hash
to_s() click to toggle source
# File lib/ffi-proj4/projection.rb, line 89
def to_s
  "#<Proj4::Projection #{definition}>"
end
Also aliased as: inspect
transform(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 181
def transform(proj, *args)
  self.transform!(proj, *(dup_args(*args)))
end
Also aliased as: transform_rad, transformRad
transform!(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 175
def transform!(proj, *args)
  perform_transform(:pj_transform, proj, *args)
end
Also aliased as: transform_rad!, transformRad!
transformRad(proj, *args)
Alias for: transform
transformRad!(proj, *args)
Alias for: transform!
transform_all(proj, collection) click to toggle source
# File lib/ffi-proj4/projection.rb, line 219
def transform_all(proj, collection)
  collection.collect do |args|
    self.transform!(proj, *(dup_args(*args)))
  end
end
transform_all!(proj, collection) click to toggle source
# File lib/ffi-proj4/projection.rb, line 212
def transform_all!(proj, collection)
  collection.each do |args|
    self.transform!(proj, *args)
  end
  collection
end
transform_deg(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 191
def transform_deg(proj, *args)
  self.transform_deg!(proj, *(dup_args(*args)))
end
transform_deg!(proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 187
def transform_deg!(proj, *args)
  self.transform!(proj, *args_deg_to_rad(*args)).to_deg!
end
transform_rad(proj, *args)
Alias for: transform
transform_rad!(proj, *args)
Alias for: transform!

Private Instance Methods

args_deg_to_rad(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 261
def args_deg_to_rad(*args)
  args.collect { |value|
    deg_to_rad!(value)
  }
end
args_rad_to_deg(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 267
def args_rad_to_deg(*args)
  args.collect { |value|
    rad_to_deg!(value)
  }
end
dup_args(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 273
def dup_args(*args)
  args.collect { |value|
    if !value.is_a?(Numeric) && value.respond_to?(:dup)
      value.dup
    else
      value
    end
  }
end
perform_transform(transform_method, proj, *args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 283
def perform_transform(transform_method, proj, *args)
  if !proj.is_a?(Proj4::Projection)
    raise TypeError.new("Expected a Proj4::Projection")
  end

  point = point_from_args(*args)

  x_ptr = FFI::MemoryPointer.new(:double)
  y_ptr = FFI::MemoryPointer.new(:double)
  z_ptr = FFI::MemoryPointer.new(:double)

  x_ptr.write_double(point.x)
  y_ptr.write_double(point.y)
  z_ptr.write_double(point.z.nil? ? 0 : point.z) if point.respond_to?(:z)

  result = FFIProj4.send(transform_method, self.ptr, proj.ptr, 1, 1, x_ptr, y_ptr, z_ptr)

  if result >= 0 && !bool_result(result)
    point.x = x_ptr.read_double
    point.y = y_ptr.read_double
    point.z = z_ptr.read_double if point.respond_to?(:z=)
    point
  else
    raise Proj4::Error.instantiate_error(result)
  end
end
point_from_args(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 251
def point_from_args(*args)
  if args.length >= 2
    Proj4::Point.new(*args)
  elsif args.length == 1 && args.first.respond_to?(:x) && args.first.respond_to?(:y)
    args.first
  else
    raise ArgumentError.new("Expected either coordinates, a Proj4::Point or an object that responds to x and y methods.")
  end
end
xy_and_point_from_args(*args) click to toggle source
# File lib/ffi-proj4/projection.rb, line 234
def xy_and_point_from_args(*args)
  if args.length == 1
    point = args.first
    if point.is_a?(Proj4::ProjXY)
      [ point, Proj4::Point.new(point.x, point.y) ]
    elsif point.respond_to?(:x) && point.respond_to?(:y)
      [ Proj4::ProjXY.alloc_in.init(point.x, point.y), point ]
    else
      raise ArgumentError.new("Expected a Proj4::ProjXY, a Proj4::Point or an object that responds to x and y methods.")
    end
  elsif args.length == 2
    [ Proj4::ProjXY.alloc_in.init(args[0], args[1]), Proj4::Point.new(args[0], args[1]) ]
  else
    raise ArgumentError.new("Wrong number of arguments #{args.length} for 1-2")
  end
end