Class: Proj4::Projection

Inherits:
Object
  • Object
show all
Includes:
Tools
Defined in:
lib/ffi-proj4/projection.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Tools

#bool_result, #deg_to_rad, #rad_to_deg

Constructor Details

#initialize(arg, auto_free = true) ⇒ Projection

Returns a new instance of Projection.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/ffi-proj4/projection.rb', line 11

def initialize(arg, auto_free = true)
  args = case arg
    when Array
      arg.collect { |a| a.sub(/^\+/, '') }
    when String
      arg.strip.split(/ /).collect { |a| a.sub(/^\+/, '') }
    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?
    errno = FFIProj4.pj_get_errno_ref.read_int
    raise ProjectionParseError.new(FFIProj4.pj_strerrno(errno))
  else
    @ptr = FFI::AutoPointer.new(
      ptr,
      auto_free ? self.class.method(:release) : self.class.method(:no_release)
    )
  end
end

Instance Attribute Details

#ptrObject (readonly)

Returns the value of attribute ptr.



9
10
11
# File 'lib/ffi-proj4/projection.rb', line 9

def ptr
  @ptr
end

Class Method Details

.no_release(ptr) ⇒ Object

:nodoc:



52
53
# File 'lib/ffi-proj4/projection.rb', line 52

def self.no_release(ptr) #:nodoc:
end

.release(ptr) ⇒ Object

:nodoc:



55
56
57
# File 'lib/ffi-proj4/projection.rb', line 55

def self.release(ptr) #:nodoc:
  FFIProj4.pj_free(ptr)
end

Instance Method Details

#datum_transform(proj, x, y, z = nil) ⇒ Object Also known as: datum_transform_rad



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/ffi-proj4/projection.rb', line 154

def datum_transform(proj, x, y, z = nil)
  if !proj.is_a?(Proj4::Projection)
    raise ArgumentError.new("Expected a Proj4::Projection")
  end

  x_ptr = FFI::MemoryPointer.new(:double)
  y_ptr = FFI::MemoryPointer.new(:double)
  z_ptr = FFI::MemoryPointer.new(:double) unless z.nil?

  x_ptr.write_double(x)
  y_ptr.write_double(y)
  z_ptr.write_double(z) unless z.nil?

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

  if result >= 0 && !bool_result(result)
    Point.new(
      x_ptr.read_double,
      y_ptr.read_double,
      z_ptr.read_double
    )
  else
    raise TransformError.new(FFIProj4.pj_strerrno(result))
  end
end

#datum_transform_deg(proj, x, y, z = nil) ⇒ Object



181
182
183
184
185
186
187
# File 'lib/ffi-proj4/projection.rb', line 181

def datum_transform_deg(proj, x, y, z = nil)
  self.datum_transform(proj, x, y, z).tap { |ret|
    ret.x = rad_to_deg(ret.x)
    ret.y = rad_to_deg(ret.y)
    ret.z = rad_to_deg(ret.z)
  }
end

#definitionObject



67
68
69
# File 'lib/ffi-proj4/projection.rb', line 67

def definition
  @definition ||= FFIProj4.pj_get_def(self.ptr, 0).strip
end

#definition_as_hashObject



71
72
73
74
75
76
77
78
79
80
# File 'lib/ffi-proj4/projection.rb', line 71

def definition_as_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

#forward(x, y) ⇒ Object Also known as: forward_deg

end alias :inspect :to_s



87
88
89
90
91
92
93
94
95
96
# File 'lib/ffi-proj4/projection.rb', line 87

def forward(x, y)
  xy = ProjXY.new(x, y)
  ret = FFIProj4.pj_fwd(xy, self.ptr)
  errno = FFIProj4.pj_get_errno_ref.read_int
  if errno == 0
    Point.new(ret[:x], ret[:y])
  else
    raise TransformError.new(FFIProj4.pj_strerrno(errno))
  end
end

#forward_rad(x, y) ⇒ Object



99
100
101
# File 'lib/ffi-proj4/projection.rb', line 99

def forward_rad(x, y)
  self.forward(deg_to_rad(x), deg_to_rad(y))
end

#geocentric?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/ffi-proj4/projection.rb', line 63

def geocentric?
  bool_result(FFIProj4.pj_is_geocent(self.ptr))
end

#inverse(x, y) ⇒ Object Also known as: inverse_deg



103
104
105
106
107
108
109
110
111
112
# File 'lib/ffi-proj4/projection.rb', line 103

def inverse(x, y)
  xy = ProjXY.new(x, y)
  ret = FFIProj4.pj_inv(xy, self.ptr)
  errno = FFIProj4.pj_get_errno_ref.read_int
  if errno == 0
    Point.new(ret.x, ret.y)
  else
    raise TransformError.new(FFIProj4.pj_strerrno(errno))
  end
end

#inverse_rad(x, y) ⇒ Object



115
116
117
# File 'lib/ffi-proj4/projection.rb', line 115

def inverse_rad(x, y)
  self.inverse(deg_to_rad(x), deg_to_rad(y))
end

#lat_long?Boolean

Returns:

  • (Boolean)


59
60
61
# File 'lib/ffi-proj4/projection.rb', line 59

def lat_long?
  bool_result(FFIProj4.pj_is_latlong(self.ptr))
end

#transform(proj, x, y, z = nil) ⇒ Object Also known as: transform_rad



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/ffi-proj4/projection.rb', line 119

def transform(proj, x, y, z = nil)
  if !proj.is_a?(Proj4::Projection)
    raise ArgumentError.new("Expected a Proj4::Projection")
  end

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

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

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

  if result >= 0 && !bool_result(result)
    Point.new(
      x_ptr.read_double,
      y_ptr.read_double,
      z_ptr.read_double
    )
  else
    raise TransformError.new(FFIProj4.pj_strerrno(result))
  end
end

#transform_deg(proj, x, y, z = nil) ⇒ Object



146
147
148
149
150
151
152
# File 'lib/ffi-proj4/projection.rb', line 146

def transform_deg(proj, x, y, z = nil)
  self.transform(proj, x, y, z).tap { |ret|
    ret.x = rad_to_deg(ret.x)
    ret.y = rad_to_deg(ret.y)
    ret.z = rad_to_deg(ret.z)
  }
end