proj4rb 0.2.0-i486-linux
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +8 -0
- data/README +151 -0
- data/example/basic.rb +18 -0
- data/example/list-datums.rb +17 -0
- data/example/list-ellipsoids.rb +17 -0
- data/example/list-errors.rb +11 -0
- data/example/list-prime-meridians.rb +17 -0
- data/example/list-projection-types.rb +17 -0
- data/example/list-units.rb +17 -0
- data/example/version.rb +9 -0
- data/lib/proj4.rb +518 -0
- data/lib/projrb.so +0 -0
- data/rakefile.rb +72 -0
- data/src/extconf.rb +8 -0
- data/src/projrb.c +532 -0
- data/test/test_constants.rb +20 -0
- data/test/test_create_projection.rb +63 -0
- data/test/test_datums.rb +44 -0
- data/test/test_ellipsoids.rb +45 -0
- data/test/test_errors.rb +70 -0
- data/test/test_init_projection.rb +108 -0
- data/test/test_prime_meridians.rb +44 -0
- data/test/test_projection_type.rb +43 -0
- data/test/test_simple_projection.rb +64 -0
- data/test/test_transform.rb +114 -0
- data/test/test_units.rb +45 -0
- data/test/test_uv.rb +53 -0
- metadata +84 -0
data/lib/proj4.rb
ADDED
@@ -0,0 +1,518 @@
|
|
1
|
+
ENV['PROJ_LIB'] = File.dirname(__FILE__) + '/../data'
|
2
|
+
require 'projrb'
|
3
|
+
|
4
|
+
# Ruby bindings for the Proj.4 cartographic projection library (http://proj.maptools.org).
|
5
|
+
module Proj4
|
6
|
+
|
7
|
+
# Base class for all Proj.4 exceptions. Subclasses with the name <errorname>Error are available for each exception.
|
8
|
+
class Error < StandardError
|
9
|
+
|
10
|
+
# List of all Proj.4 errors.
|
11
|
+
#--
|
12
|
+
# (This list is created from the one in pj_strerrno.c in the Proj.4 distribution.)
|
13
|
+
#++
|
14
|
+
ERRORS = %w{Unknown NoArgsInInitList NoOptionsInInitFile NoColonInInitString ProjectionNotNamed UnknownProjectionId EffectiveEccentricityEq1 UnknownUnitConversionId InvalidBooleanParamArgument UnknownEllipticalParameterName ReciprocalFlatteningIsZero RadiusReferenceLatitudeGt90 SquaredEccentricityLessThanZero MajorAxisOrRadiusIsZeroOrNotGiven LatitudeOrLongitudeExceededLimits InvalidXOrY ImproperlyFormedDMSValue NonConvergentInverseMeridinalDist NonConvergentInversePhi2 AcosOrAsinArgTooBig ToleranceCondition ConicLat1EqMinusLat2 Lat1GreaterThan90 Lat1IsZero LatTsGreater90 NoDistanceBetweenControlPoints ProjectionNotSelectedToBeRotated WSmallerZeroOrMSmallerZero LsatNotInRange PathNotInRange HSmallerZero KSmallerZero Lat0IsZeroOr90OrAlphaIsZero Lat1EqLat2OrLat1IsZeroOrLat2Is90 EllipticalUsageRequired InvalidUTMZoneNumber ArgsOutOfRangeForTchebyEval NoProjectionToBeRotated FailedToLoadNAD2783CorrectionFile BothNAndMMustBeSpecdAndGreaterZero NSmallerZeroOrNGreaterOneOrNotSpecified Lat1OrLat2NotSpecified AbsoluteLat1EqLat2 Lat0IsHalfPiFromMeanLat UnparseableCoordinateSystemDefinition GeocentricTransformationMissingZOrEllps UnknownPrimeMeridianConversionId}
|
15
|
+
|
16
|
+
# Return list of all errors.
|
17
|
+
#
|
18
|
+
# call-seq: list -> Array
|
19
|
+
#
|
20
|
+
def self.list
|
21
|
+
ERRORS
|
22
|
+
end
|
23
|
+
|
24
|
+
# Return name of error with given number.
|
25
|
+
#
|
26
|
+
# call-seq: error(errnum) -> String
|
27
|
+
#
|
28
|
+
def self.error(errnum)
|
29
|
+
ERRORS[errnum.abs] || 'Unknown'
|
30
|
+
end
|
31
|
+
|
32
|
+
# Raise an error with error number +errnum+.
|
33
|
+
def self.raise_error(errnum)
|
34
|
+
raise eval("#{error(errnum.abs)}Error"), strerrno(-(errnum.abs)), caller[0..-1]
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return error number of this error.
|
38
|
+
def errnum
|
39
|
+
self.class.errnum
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
Error.list.each_with_index do |err, index|
|
45
|
+
eval "class #{err}Error < Error;
|
46
|
+
def self.errnum;
|
47
|
+
#{index};
|
48
|
+
end;
|
49
|
+
end"
|
50
|
+
end
|
51
|
+
|
52
|
+
# The Projection class represents a geographical projection.
|
53
|
+
#
|
54
|
+
# = Creating a new projection object
|
55
|
+
#
|
56
|
+
# Projection objects are created through the new method as usual. Depending on the kind of projection, many
|
57
|
+
# different parameters are needed. Please consult the documentation of the Proj.4 C library at http://proj.maptools.org
|
58
|
+
# for details.
|
59
|
+
#
|
60
|
+
# There are several ways of specifying the parameters:
|
61
|
+
#
|
62
|
+
# [<b>as a String:</b>] A string with the parameters in '[+]key=value' format concatenated together. This is the format used by the <tt>proj</tt> and <tt>cs2cs</tt> command line tool.
|
63
|
+
#
|
64
|
+
# proj = Projection.new "+proj=utm +zone=21 +units=m"
|
65
|
+
#
|
66
|
+
# [<b>as an Array:</b>] An array with each parameter as a member in the array in '[+]key=value' format.
|
67
|
+
#
|
68
|
+
# proj = Projection.new [ "proj=utm", "zone=21", "units=m" ]
|
69
|
+
#
|
70
|
+
# [<b>as a Hash:</b>] A hash with strings or symbols as keys.
|
71
|
+
#
|
72
|
+
# proj = Projection.new( "proj" => "utm", "zone" => "21", "units" => "m" )
|
73
|
+
# proj = Projection.new( :proj => "utm", :zone => "21", :units => "m" )
|
74
|
+
#
|
75
|
+
# With all variants the plus sign in front of the keys is optional.
|
76
|
+
#
|
77
|
+
# = Using a projection object to project points
|
78
|
+
#
|
79
|
+
# There are two ways a projection can be used: Through the +forward+ and +inverse+ methods (with all their variants)
|
80
|
+
# you can do projection from longitudes and latitudes into the coordinate system used by the projection and back.
|
81
|
+
# These projections are always 2D, i.e. you need and get lon/lat or x/y coordinates.
|
82
|
+
#
|
83
|
+
# The alternative is the +transform+ method (with all its variants) which is used to transform 3D points from one
|
84
|
+
# projection and datum to another. In addition to the x/y coordinates the transform method also reads and returns
|
85
|
+
# a z coordinate.
|
86
|
+
#
|
87
|
+
# = Versions of the projection methods
|
88
|
+
#
|
89
|
+
# All three projection methods (+forward+, +inverse+, and +transform+) work on points. Every method has an in-place
|
90
|
+
# version (with a name ending in !) which changes the given point and a normal version which first creates a copy of
|
91
|
+
# the point object and changes and returns that. All methods use radians when reading or returning points. For
|
92
|
+
# convenience there are also +forwardDeg+ and +inverseDeg+ methods (and in-place versions <tt>forwardDeg!</tt>
|
93
|
+
# and <tt>inverseDeg!</tt>) that will work with degrees.
|
94
|
+
#
|
95
|
+
# = Points
|
96
|
+
#
|
97
|
+
# All projection method project points to other points. You can use objects of the Proj4::Point class for this or
|
98
|
+
# any other object which supports the x, y, z read and write accessor methods. (In fact you don't even need the
|
99
|
+
# z accessor methods, 0 is assumed if they don't exist.)
|
100
|
+
#
|
101
|
+
# Some projection methods act on the given point in-place, other return a copy of the point object. But in any case
|
102
|
+
# all other attributes of the point object are retained.
|
103
|
+
#
|
104
|
+
# = Projection collections
|
105
|
+
#
|
106
|
+
# The methods forward_all, inverse_all, and transform_all (and their in-place versions forward_all!,
|
107
|
+
# inverse_all!, and transform_all! work just like their simple counterparts, but instead of a single
|
108
|
+
# point they convert a collection of points in one go.
|
109
|
+
#
|
110
|
+
# These methods all take an array as an argument or any object responding to the +each+ method (for the in-place versions)
|
111
|
+
# or +each+, +clear+, and <tt><<</tt> methods (for the normal version).
|
112
|
+
#
|
113
|
+
# Some projection methods act on the given collection in-place, i.e. the collection is not touched and all points
|
114
|
+
# in the collection will be projected in-place. The other methods act on a copy of the collection and on copies
|
115
|
+
# of each point in the collection. So you'll get back a brand new copy of the collection with new copies of the
|
116
|
+
# points with the projected coordinates. In any case all other attributes of the collection and points are retained.
|
117
|
+
#
|
118
|
+
class Projection
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def self._parse_init_parameters(args)
|
123
|
+
case args
|
124
|
+
when Array
|
125
|
+
args.collect{ |a| a.sub(/^\+/, '') }
|
126
|
+
when String
|
127
|
+
args.strip.split(' ').collect{ |a| a.sub(/^\+/, '')}
|
128
|
+
when Hash
|
129
|
+
array = []
|
130
|
+
args.each_pair{ | key, value | array << (value.nil? ? key.to_s : "#{key}=#{value}") }
|
131
|
+
array
|
132
|
+
when Proj4::Projection
|
133
|
+
args.getDef.strip.split(' ').collect{ |a| a.sub(/^\+/, '')}
|
134
|
+
else
|
135
|
+
raise ArgumentError, "Unknown type #{args.class} for projection definition"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
public
|
140
|
+
|
141
|
+
# Get the ID of this projection.
|
142
|
+
#
|
143
|
+
# call-seq: projection -> String
|
144
|
+
#
|
145
|
+
def projection
|
146
|
+
getDef =~ /\+proj=(.+?) / ? $1 : nil
|
147
|
+
end
|
148
|
+
|
149
|
+
# Get the ID of the datum used in this projection.
|
150
|
+
#
|
151
|
+
# call-seq: datum -> String
|
152
|
+
#
|
153
|
+
def datum
|
154
|
+
getDef =~ /\+datum=(.+?) / ? $1 : nil
|
155
|
+
end
|
156
|
+
|
157
|
+
# Get definition of projection in typical inspect format (#<Proj4::Projection +init=... +proj=... ...>).
|
158
|
+
#
|
159
|
+
# call-seq: to_s -> String
|
160
|
+
#
|
161
|
+
def to_s
|
162
|
+
"#<Proj4::Projection#{ getDef }>"
|
163
|
+
end
|
164
|
+
|
165
|
+
# Forward projection of a point. Returns a copy of the point object with coordinates projected.
|
166
|
+
#
|
167
|
+
# call-seq: forward(point) -> point
|
168
|
+
#
|
169
|
+
def forward(point)
|
170
|
+
forward!(point.dup)
|
171
|
+
end
|
172
|
+
|
173
|
+
# Convenience function for calculating a forward projection with degrees instead of radians.
|
174
|
+
#
|
175
|
+
# call-seq: forwardDeg(point) -> point
|
176
|
+
#
|
177
|
+
def forwardDeg(point)
|
178
|
+
forwardDeg!(point.dup)
|
179
|
+
end
|
180
|
+
|
181
|
+
# Convenience function for calculating a forward projection with degrees instead of radians.
|
182
|
+
# This version works in-place, i.e. the point objects content is overwritten.
|
183
|
+
#
|
184
|
+
# call-seq: forwardDeg!(point) -> point
|
185
|
+
#
|
186
|
+
def forwardDeg!(point)
|
187
|
+
point.x *= Proj4::DEG_TO_RAD
|
188
|
+
point.y *= Proj4::DEG_TO_RAD
|
189
|
+
forward!(point)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Project all points in a collection 'in place'.
|
193
|
+
# The +collection+ object must implement the +each+
|
194
|
+
# method for this to work.
|
195
|
+
#
|
196
|
+
# call-seq: forward_all!(collection) -> collection
|
197
|
+
#
|
198
|
+
def forward_all!(collection)
|
199
|
+
collection.each do |point|
|
200
|
+
forward!(point)
|
201
|
+
end
|
202
|
+
collection
|
203
|
+
end
|
204
|
+
|
205
|
+
# Projects all points in a collection.
|
206
|
+
# The +collection+ object must implement the +each+,
|
207
|
+
# +clear+, and << methods (just like an Array) for this to work.
|
208
|
+
#
|
209
|
+
# call-seq: forward_all(collection) -> collection
|
210
|
+
#
|
211
|
+
def forward_all(collection)
|
212
|
+
newcollection = collection.dup.clear
|
213
|
+
collection.each do |point|
|
214
|
+
newcollection << forward(point)
|
215
|
+
end
|
216
|
+
newcollection
|
217
|
+
end
|
218
|
+
|
219
|
+
# Inverse projection of a point. Returns a copy of the point object with coordinates projected.
|
220
|
+
#
|
221
|
+
# call-seq: inverse(point) -> point
|
222
|
+
#
|
223
|
+
def inverse(point)
|
224
|
+
inverse!(point.dup)
|
225
|
+
end
|
226
|
+
|
227
|
+
# Convenience function for calculating an inverse projection with the result in degrees instead of radians.
|
228
|
+
#
|
229
|
+
# call-seq: inverseDeg(point) -> point
|
230
|
+
#
|
231
|
+
def inverseDeg(point)
|
232
|
+
inverseDeg!(point.dup)
|
233
|
+
end
|
234
|
+
|
235
|
+
# Convenience function for calculating an inverse projection with the result in degrees instead of radians.
|
236
|
+
# This version works in-place, i.e. the point objects content is overwritten.
|
237
|
+
#
|
238
|
+
# call-seq: inverseDeg!(point) -> point
|
239
|
+
#
|
240
|
+
def inverseDeg!(point)
|
241
|
+
inverse!(point)
|
242
|
+
point.x *= Proj4::RAD_TO_DEG
|
243
|
+
point.y *= Proj4::RAD_TO_DEG
|
244
|
+
point
|
245
|
+
end
|
246
|
+
|
247
|
+
# Project all points in a collection 'in place'.
|
248
|
+
# The +collection+ object must implement the +each+
|
249
|
+
# method for this to work.
|
250
|
+
#
|
251
|
+
# call-seq: inverse_all!(collection) -> collection
|
252
|
+
#
|
253
|
+
def inverse_all!(collection)
|
254
|
+
collection.each do |point|
|
255
|
+
inverse!(point)
|
256
|
+
end
|
257
|
+
collection
|
258
|
+
end
|
259
|
+
|
260
|
+
# Projects all points in a collection.
|
261
|
+
# The +collection+ object must implement the +each+,
|
262
|
+
# +clear+, and << methods (just like an Array) for this to work.
|
263
|
+
#
|
264
|
+
# call-seq: inverse_all(collection) -> collection
|
265
|
+
#
|
266
|
+
def inverse_all(collection)
|
267
|
+
newcollection = collection.dup.clear
|
268
|
+
collection.each do |point|
|
269
|
+
newcollection << inverse(point)
|
270
|
+
end
|
271
|
+
newcollection
|
272
|
+
end
|
273
|
+
|
274
|
+
# Transforms a point from one projection to another.
|
275
|
+
#
|
276
|
+
# call-seq: transform(destinationProjection, point) -> point
|
277
|
+
#
|
278
|
+
def transform(otherProjection, point)
|
279
|
+
transform!(otherProjection, point.dup)
|
280
|
+
end
|
281
|
+
|
282
|
+
# Transforms all points in a collection 'in place' from one projection
|
283
|
+
# to another. The +collection+ object must implement the +each+
|
284
|
+
# method for this to work.
|
285
|
+
#
|
286
|
+
# call-seq: transform_all!(destinationProjection, collection) -> collection
|
287
|
+
#
|
288
|
+
def transform_all!(otherProjection, collection)
|
289
|
+
collection.each do |point|
|
290
|
+
transform!(otherProjection, point)
|
291
|
+
end
|
292
|
+
collection
|
293
|
+
end
|
294
|
+
|
295
|
+
# Transforms all points in a collection from one projection to
|
296
|
+
# another. The +collection+ object must implement the +each+,
|
297
|
+
# +clear+, and << methods (just like an Array) for this to work.
|
298
|
+
#
|
299
|
+
# call-seq: transform_all(destinationProjection, collection) -> collection
|
300
|
+
#
|
301
|
+
def transform_all(otherProjection, collection)
|
302
|
+
newcollection = collection.dup.clear
|
303
|
+
collection.each do |point|
|
304
|
+
newcollection << transform(otherProjection, point)
|
305
|
+
end
|
306
|
+
newcollection
|
307
|
+
end
|
308
|
+
|
309
|
+
end
|
310
|
+
|
311
|
+
# This class represents a point in either lon/lat or projected x/y coordinates.
|
312
|
+
class Point
|
313
|
+
|
314
|
+
# X coordinate or longitude
|
315
|
+
attr_accessor :x
|
316
|
+
|
317
|
+
# Y coordinate or latitude
|
318
|
+
attr_accessor :y
|
319
|
+
|
320
|
+
# Z coordinate (height)
|
321
|
+
attr_accessor :z
|
322
|
+
|
323
|
+
# Create new Proj4::Point object from coordinates.
|
324
|
+
def initialize(x, y, z=0)
|
325
|
+
@x = x
|
326
|
+
@y = y
|
327
|
+
@z = z
|
328
|
+
end
|
329
|
+
|
330
|
+
# Get longitude/x coordinate.
|
331
|
+
def lon
|
332
|
+
x
|
333
|
+
end
|
334
|
+
|
335
|
+
# Get latitude/y coordinate.
|
336
|
+
def lat
|
337
|
+
y
|
338
|
+
end
|
339
|
+
|
340
|
+
# Set longitude/x coordinate.
|
341
|
+
def lon=(lon)
|
342
|
+
@x = lon
|
343
|
+
end
|
344
|
+
|
345
|
+
# Set latitude/y coordinate.
|
346
|
+
def lat=(lat)
|
347
|
+
@y = lat
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
# Abstract base class for several types of definitions: Proj4::Datum, Proj4::Ellipsoid, Proj4::PrimeMeridian, Proj4::ProjectionType, Proj4::Unit.
|
353
|
+
#
|
354
|
+
# Note that these classes only work if the version of the Proj.4 C library used is at least 449.
|
355
|
+
class Def
|
356
|
+
|
357
|
+
# Initialize function raises error. Definitions are always defined by the underlying Proj.4 library, you can't create them yourself.
|
358
|
+
def initialize # :nodoc:
|
359
|
+
raise TypeError, "You can't created objects of this type yourself."
|
360
|
+
end
|
361
|
+
|
362
|
+
# Get the definition with given id.
|
363
|
+
def self.get(id)
|
364
|
+
self.list.select{ |u| u.id == id }.first
|
365
|
+
end
|
366
|
+
|
367
|
+
# Compares definitions by comparing ids.
|
368
|
+
#
|
369
|
+
# call-seq: one == other -> true or false
|
370
|
+
#
|
371
|
+
def ==(other)
|
372
|
+
self.id == other.id
|
373
|
+
end
|
374
|
+
|
375
|
+
# Compares definitions by comparing ids.
|
376
|
+
#
|
377
|
+
# call-seq: one <=> other -> -1, 0, 1
|
378
|
+
#
|
379
|
+
def <=>(other)
|
380
|
+
self.id <=> other.id
|
381
|
+
end
|
382
|
+
|
383
|
+
# Stringify definition. Returns ID of this definition.
|
384
|
+
#
|
385
|
+
# call-seq: to_s -> String
|
386
|
+
#
|
387
|
+
def to_s
|
388
|
+
id
|
389
|
+
end
|
390
|
+
|
391
|
+
end
|
392
|
+
|
393
|
+
class Datum < Def
|
394
|
+
|
395
|
+
# Returns datum definition as string in format '#<Proj4::Datum id="...", ellipse_id="...", defn="...", comments="...">'.
|
396
|
+
#
|
397
|
+
# call-seq: inspect -> String
|
398
|
+
#
|
399
|
+
def inspect
|
400
|
+
"#<Proj4::Datum id=\"#{id}\", ellipse_id=\"#{ellipse_id}\", defn=\"#{defn}\", comments=\"#{comments}\">"
|
401
|
+
end
|
402
|
+
|
403
|
+
end
|
404
|
+
|
405
|
+
class Ellipsoid < Def
|
406
|
+
|
407
|
+
# Returns ellipsoid definition as string in format '#<Proj4::Ellipsoid id="...", major="...", ell="...", name="...">'.
|
408
|
+
#
|
409
|
+
# call-seq: inspect -> String
|
410
|
+
#
|
411
|
+
def inspect
|
412
|
+
"#<Proj4::Ellipsoid id=\"#{id}\", major=\"#{major}\", ell=\"#{ell}\", name=\"#{name}\">"
|
413
|
+
end
|
414
|
+
|
415
|
+
end
|
416
|
+
|
417
|
+
class PrimeMeridian < Def
|
418
|
+
|
419
|
+
# Returns a prime meridian definition as string in format '#<Proj4::PrimeMeridian id="...", defn="...">'.
|
420
|
+
#
|
421
|
+
# call-seq: inspect -> String
|
422
|
+
#
|
423
|
+
def inspect
|
424
|
+
"#<Proj4::PrimeMeridian id=\"#{id}\", defn=\"#{defn}\">"
|
425
|
+
end
|
426
|
+
|
427
|
+
end
|
428
|
+
|
429
|
+
class ProjectionType < Def
|
430
|
+
|
431
|
+
# Returns a projection type as string in format '#<Proj4::PrimeMeridian id="...", name="...">'.
|
432
|
+
#
|
433
|
+
# call-seq: inspect -> String
|
434
|
+
#
|
435
|
+
def inspect
|
436
|
+
"#<Proj4::ProjectionType id=\"#{id}\", name=\"#{name}\">"
|
437
|
+
end
|
438
|
+
|
439
|
+
# Gets name of this projection type.
|
440
|
+
#
|
441
|
+
# call-seq: name -> String
|
442
|
+
#
|
443
|
+
def name
|
444
|
+
descr.sub(/\n.*/m, '')
|
445
|
+
end
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
class Unit < Def
|
450
|
+
|
451
|
+
# Returns unit definition as string in format '#<Proj4::Unit id="...", to_meter="...", name="...">'.
|
452
|
+
#
|
453
|
+
# call-seq: inspect -> String
|
454
|
+
#
|
455
|
+
def inspect
|
456
|
+
"#<Proj4::Unit id=\"#{id}\", to_meter=\"#{to_meter}\", name=\"#{name}\">"
|
457
|
+
end
|
458
|
+
|
459
|
+
end
|
460
|
+
|
461
|
+
# The UV class holds one coordinate pair. Can be either lon/lat or x/y.
|
462
|
+
#
|
463
|
+
# This class is deprecated and it will disappear in a later version of this
|
464
|
+
# library. Use Proj4::Point instead (or any other class supporting x, y read and
|
465
|
+
# write accessor method.
|
466
|
+
class UV
|
467
|
+
|
468
|
+
attr_accessor :x, :y
|
469
|
+
|
470
|
+
def initialize(x, y)
|
471
|
+
warn 'Use of class Proj4::UV is deprecated. Please use Proj4::Point instead. See documentation for details.'
|
472
|
+
if ! x.kind_of?(Float) or ! y.kind_of?(Float)
|
473
|
+
raise TypeError
|
474
|
+
end
|
475
|
+
@x = x
|
476
|
+
@y = y
|
477
|
+
end
|
478
|
+
|
479
|
+
# get u(x) coordinate
|
480
|
+
def u
|
481
|
+
x
|
482
|
+
end
|
483
|
+
|
484
|
+
# get v(y) coordinate
|
485
|
+
def v
|
486
|
+
y
|
487
|
+
end
|
488
|
+
|
489
|
+
# set u(x) coordinate
|
490
|
+
def u=(u)
|
491
|
+
@x = u
|
492
|
+
end
|
493
|
+
|
494
|
+
# set v(y) coordinate
|
495
|
+
def v=(v)
|
496
|
+
@y = v
|
497
|
+
end
|
498
|
+
|
499
|
+
# Compare to UV instances, they are equal if both coordinates are equal, respectively.
|
500
|
+
#
|
501
|
+
# call-seq: uv == other -> true or false
|
502
|
+
#
|
503
|
+
def ==(uv)
|
504
|
+
self.u == uv.u && self.v == uv.v
|
505
|
+
end
|
506
|
+
|
507
|
+
# Create string in format 'x,y'.
|
508
|
+
#
|
509
|
+
# call-seq: to_s -> String
|
510
|
+
#
|
511
|
+
def to_s
|
512
|
+
"#{u},#{v}"
|
513
|
+
end
|
514
|
+
|
515
|
+
end
|
516
|
+
|
517
|
+
end
|
518
|
+
|
data/lib/projrb.so
ADDED
Binary file
|
data/rakefile.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/testtask'
|
3
|
+
require 'rake/rdoctask'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/clean'
|
6
|
+
|
7
|
+
task :default => :test
|
8
|
+
|
9
|
+
CLOBBER.include('pkg/*', 'proj4rb-doc/**/*', 'lib/*.so', 'lib/*.bundle', 'lib/*.dll', 'src/*.o', 'src/*.so', 'src/*.bundle', 'src/*.dll', 'src/Makefile', 'src/mkmf.log')
|
10
|
+
|
11
|
+
desc "Create Makefile"
|
12
|
+
file 'src/Makefile' => ['src/extconf.rb'] do
|
13
|
+
sh 'cd src; ruby extconf.rb'
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Build from C library"
|
17
|
+
task :build => ['src/Makefile', 'src/projrb.c'] do
|
18
|
+
sh 'cd src; make'
|
19
|
+
# Try the different suffixes for Linux, Mac OS X, or Windows shared libraries and put the one found into lib dir
|
20
|
+
['so', 'bundle', 'dll'].each do |suffix|
|
21
|
+
if File.exists?('src/projrb.' + suffix)
|
22
|
+
puts "Copying 'src/projrb.#{suffix}' to lib/"
|
23
|
+
File.copy('src/projrb.' + suffix, 'lib/projrb.' + suffix)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Run the tests"
|
29
|
+
Rake::TestTask::new do |t|
|
30
|
+
t.test_files = FileList['test/test*.rb']
|
31
|
+
t.verbose = true
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Generate the documentation"
|
35
|
+
Rake::RDocTask::new do |rdoc|
|
36
|
+
rdoc.rdoc_dir = 'proj4rb-doc/'
|
37
|
+
rdoc.title = "Proj4rb Documentation"
|
38
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
39
|
+
rdoc.rdoc_files.include('README')
|
40
|
+
rdoc.rdoc_files.include('src/**/*.c', 'lib/proj4.rb')
|
41
|
+
end
|
42
|
+
|
43
|
+
spec = Gem::Specification::new do |s|
|
44
|
+
s.platform = Gem::Platform::CURRENT
|
45
|
+
|
46
|
+
s.name = 'proj4rb'
|
47
|
+
s.version = "0.2.0"
|
48
|
+
s.summary = "Ruby bindings for the Proj.4 Carthographic Projection library"
|
49
|
+
s.description = <<EOF
|
50
|
+
Proj4rb is a ruby binding for the Proj.4 Carthographic Projection library, that supports conversions between a very large number of geographic coordinate systems and datums.
|
51
|
+
EOF
|
52
|
+
s.author = 'Guilhem Vellut'
|
53
|
+
s.email = 'guilhem.vellut@gmail.com'
|
54
|
+
s.homepage = 'http://thepochisuperstarmegashow.com'
|
55
|
+
s.rubyforge_project = 'proj4rb'
|
56
|
+
|
57
|
+
s.requirements << 'Proj.4 C library'
|
58
|
+
s.require_path = 'lib'
|
59
|
+
s.files = FileList["lib/**/*.rb", "lib/**/*.dll","lib/**/*.so","lib/**/*.bundle","example/**/*.rb","src/extconf.rb","src/**/*.h","src/**/*.c","test/**/*.rb", "README","MIT-LICENSE","rakefile.rb"]
|
60
|
+
s.test_files = FileList['test/test*.rb']
|
61
|
+
|
62
|
+
s.has_rdoc = true
|
63
|
+
s.extra_rdoc_files = ["README"]
|
64
|
+
s.rdoc_options.concat ['--main', 'README']
|
65
|
+
end
|
66
|
+
|
67
|
+
desc "Package the library as a gem"
|
68
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
69
|
+
pkg.need_zip = true
|
70
|
+
pkg.need_tar = true
|
71
|
+
end
|
72
|
+
|