proj4rb 0.2.0-i486-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/src/projrb.c
ADDED
@@ -0,0 +1,532 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "projects.h"
|
3
|
+
#include "proj_api.h"
|
4
|
+
|
5
|
+
static VALUE mProjrb;
|
6
|
+
|
7
|
+
static VALUE cDef;
|
8
|
+
static VALUE cDatum;
|
9
|
+
static VALUE cEllipsoid;
|
10
|
+
static VALUE cPrimeMeridian;
|
11
|
+
static VALUE cProjectionType;
|
12
|
+
static VALUE cUnit;
|
13
|
+
|
14
|
+
static VALUE cError;
|
15
|
+
static VALUE cProjection;
|
16
|
+
|
17
|
+
static ID idRaise;
|
18
|
+
static ID idGetX;
|
19
|
+
static ID idSetX;
|
20
|
+
static ID idGetY;
|
21
|
+
static ID idSetY;
|
22
|
+
static ID idGetZ;
|
23
|
+
static ID idSetZ;
|
24
|
+
static ID idParseInitParameters;
|
25
|
+
|
26
|
+
typedef struct {projPJ pj;} _wrap_pj;
|
27
|
+
|
28
|
+
static void proj_free(void* p){
|
29
|
+
_wrap_pj * wpj = (_wrap_pj*) p;
|
30
|
+
if(wpj->pj != 0)
|
31
|
+
pj_free(wpj->pj);
|
32
|
+
free(p);
|
33
|
+
}
|
34
|
+
|
35
|
+
static VALUE proj_alloc(VALUE klass){
|
36
|
+
_wrap_pj* wpj;
|
37
|
+
VALUE obj;
|
38
|
+
wpj = (_wrap_pj*) malloc(sizeof(_wrap_pj));
|
39
|
+
wpj->pj = 0; //at init the projection has not been defined
|
40
|
+
obj = Data_Wrap_Struct(klass, 0, proj_free, wpj);
|
41
|
+
return obj;
|
42
|
+
}
|
43
|
+
|
44
|
+
/**Creates a new projection object. See the intro for details.
|
45
|
+
|
46
|
+
call-seq: new(String) -> Proj4::Projection
|
47
|
+
new(Array) -> Proj4::Projection
|
48
|
+
new(Hash) -> Proj4::Projection
|
49
|
+
|
50
|
+
*/
|
51
|
+
static VALUE proj_initialize(VALUE self, VALUE params){
|
52
|
+
_wrap_pj* wpj;
|
53
|
+
VALUE proj_params = rb_funcall(cProjection, idParseInitParameters, 1, params);
|
54
|
+
int size = RARRAY(proj_params)->len;
|
55
|
+
char** c_params = (char **) malloc(size*sizeof(char *));
|
56
|
+
VALUE *ptr = RARRAY(proj_params)->ptr;
|
57
|
+
int i;
|
58
|
+
for (i=0; i < size; i++, ptr++)
|
59
|
+
c_params[i]= STR2CSTR(*ptr);
|
60
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
61
|
+
wpj->pj = pj_init(size,c_params);
|
62
|
+
free(c_params);
|
63
|
+
if(wpj->pj == 0) {
|
64
|
+
if (pj_errno > 0) {
|
65
|
+
rb_raise(rb_eSystemCallError, "Unknown system call error");
|
66
|
+
} else {
|
67
|
+
rb_funcall(cError, idRaise, 1, INT2FIX(pj_errno) );
|
68
|
+
}
|
69
|
+
}
|
70
|
+
return self;
|
71
|
+
}
|
72
|
+
|
73
|
+
/**Has this projection an inverse?
|
74
|
+
|
75
|
+
call-seq: hasInverse? -> true or false
|
76
|
+
|
77
|
+
*/
|
78
|
+
static VALUE proj_has_inverse(VALUE self){
|
79
|
+
_wrap_pj* wpj;
|
80
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
81
|
+
return wpj->pj->inv ? Qtrue : Qfalse;
|
82
|
+
}
|
83
|
+
|
84
|
+
/**Is this projection a latlong projection?
|
85
|
+
|
86
|
+
call-seq: isLatLong? -> true or false
|
87
|
+
|
88
|
+
*/
|
89
|
+
static VALUE proj_is_latlong(VALUE self){
|
90
|
+
_wrap_pj* wpj;
|
91
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
92
|
+
return pj_is_latlong(wpj->pj) ? Qtrue : Qfalse;
|
93
|
+
}
|
94
|
+
|
95
|
+
/**Is this projection a geocentric projection?
|
96
|
+
|
97
|
+
call-seq: isGeocentric? -> true or false
|
98
|
+
|
99
|
+
*/
|
100
|
+
static VALUE proj_is_geocent(VALUE self){
|
101
|
+
_wrap_pj* wpj;
|
102
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
103
|
+
return pj_is_geocent(wpj->pj) ? Qtrue : Qfalse;
|
104
|
+
}
|
105
|
+
|
106
|
+
/**Get the expanded definition of this projection as a string.
|
107
|
+
|
108
|
+
call-seq: getDef -> String
|
109
|
+
|
110
|
+
*/
|
111
|
+
static VALUE proj_get_def(VALUE self){
|
112
|
+
_wrap_pj* wpj;
|
113
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
114
|
+
return rb_str_new2(pj_get_def(wpj->pj, 0));
|
115
|
+
}
|
116
|
+
|
117
|
+
/**Transforms a point in WGS84 LonLat in radians to projected coordinates.
|
118
|
+
This version of the method changes the point in-place.
|
119
|
+
|
120
|
+
call-seq: forward!(point) -> point
|
121
|
+
|
122
|
+
*/
|
123
|
+
static VALUE proj_forward(VALUE self,VALUE point){
|
124
|
+
_wrap_pj* wpj;
|
125
|
+
projUV* pResult = (projUV*) malloc(sizeof(projUV));
|
126
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
127
|
+
|
128
|
+
pResult->u = NUM2DBL( rb_funcall(point, idGetX, 0) );
|
129
|
+
pResult->v = NUM2DBL( rb_funcall(point, idGetY, 0) );
|
130
|
+
*pResult = pj_fwd(*pResult,wpj->pj);
|
131
|
+
|
132
|
+
if (pj_errno == 0) {
|
133
|
+
rb_funcall(point, idSetX, 1, rb_float_new(pResult->u) );
|
134
|
+
rb_funcall(point, idSetY, 1, rb_float_new(pResult->v) );
|
135
|
+
return point;
|
136
|
+
} else if (pj_errno > 0) {
|
137
|
+
rb_raise(rb_eSystemCallError, "Unknown system call error");
|
138
|
+
} else {
|
139
|
+
rb_funcall(cError, idRaise, 1, INT2FIX(pj_errno) );
|
140
|
+
}
|
141
|
+
}
|
142
|
+
|
143
|
+
/**Transforms a point in the coordinate system defined at initialization of the Projection object to WGS84 LonLat in radians.
|
144
|
+
This version of the method changes the point in-place.
|
145
|
+
|
146
|
+
call-seq: inverse!(point) -> point
|
147
|
+
|
148
|
+
*/
|
149
|
+
static VALUE proj_inverse(VALUE self,VALUE point){
|
150
|
+
_wrap_pj* wpj;
|
151
|
+
projUV* pResult = (projUV*) malloc(sizeof(projUV));
|
152
|
+
Data_Get_Struct(self,_wrap_pj,wpj);
|
153
|
+
|
154
|
+
pResult->u = NUM2DBL( rb_funcall(point, idGetX, 0) );
|
155
|
+
pResult->v = NUM2DBL( rb_funcall(point, idGetY, 0) );
|
156
|
+
*pResult = pj_inv(*pResult,wpj->pj);
|
157
|
+
|
158
|
+
if (pj_errno == 0) {
|
159
|
+
rb_funcall(point, idSetX, 1, rb_float_new(pResult->u) );
|
160
|
+
rb_funcall(point, idSetY, 1, rb_float_new(pResult->v) );
|
161
|
+
return point;
|
162
|
+
} else if (pj_errno > 0) {
|
163
|
+
rb_raise(rb_eSystemCallError, "Unknown system call error");
|
164
|
+
} else {
|
165
|
+
rb_funcall(cError, idRaise, 1, INT2FIX(pj_errno) );
|
166
|
+
}
|
167
|
+
}
|
168
|
+
|
169
|
+
/**Transforms a point from one projection to another. The second parameter is
|
170
|
+
either a Proj4::Point object or you can use any object which
|
171
|
+
responds to the x, y, z read and write accessor methods. (In fact you
|
172
|
+
don't even need the z accessor methods, 0 is assumed if they don't exist).
|
173
|
+
This is the destructive variant of the method, i.e. it will overwrite your
|
174
|
+
existing point coordinates but otherwise leave the point object alone.
|
175
|
+
|
176
|
+
call-seq: transform!(destinationProjection, point) -> point
|
177
|
+
|
178
|
+
*/
|
179
|
+
static VALUE proj_transform(VALUE self, VALUE dst, VALUE point){
|
180
|
+
_wrap_pj* wpjsrc;
|
181
|
+
_wrap_pj* wpjdst;
|
182
|
+
double array_x[1];
|
183
|
+
double array_y[1];
|
184
|
+
double array_z[1];
|
185
|
+
int result;
|
186
|
+
|
187
|
+
Data_Get_Struct(self,_wrap_pj,wpjsrc);
|
188
|
+
Data_Get_Struct(dst,_wrap_pj,wpjdst);
|
189
|
+
|
190
|
+
array_x[0] = NUM2DBL( rb_funcall(point, idGetX, 0) );
|
191
|
+
array_y[0] = NUM2DBL( rb_funcall(point, idGetY, 0) );
|
192
|
+
|
193
|
+
/* if point objects has a method 'z' we get the z coordinate, otherwise we just assume 0 */
|
194
|
+
if ( rb_respond_to(point, idGetZ) ) {
|
195
|
+
array_z[0] = NUM2DBL( rb_funcall(point, idGetZ, 0) );
|
196
|
+
} else {
|
197
|
+
array_z[0] = 0.0;
|
198
|
+
}
|
199
|
+
|
200
|
+
result = pj_transform(wpjsrc->pj, wpjdst->pj, 1, 1, array_x, array_y, array_z);
|
201
|
+
if (! result) {
|
202
|
+
rb_funcall(point, idSetX, 1, rb_float_new(array_x[0]) );
|
203
|
+
rb_funcall(point, idSetY, 1, rb_float_new(array_y[0]) );
|
204
|
+
/* if point objects has a method 'z=' we set the z coordinate, otherwise we ignore it */
|
205
|
+
if ( rb_respond_to(point, idSetZ) ) {
|
206
|
+
rb_funcall(point, idSetZ, 1, rb_float_new(array_z[0]) );
|
207
|
+
}
|
208
|
+
return point;
|
209
|
+
} else {
|
210
|
+
if (result > 0) {
|
211
|
+
rb_raise(rb_eSystemCallError, "Unknown system call error");
|
212
|
+
} else {
|
213
|
+
rb_funcall(cError, idRaise, 1, INT2FIX(result) );
|
214
|
+
}
|
215
|
+
}
|
216
|
+
}
|
217
|
+
|
218
|
+
static VALUE projerr_strerrno(VALUE self, VALUE errno){
|
219
|
+
char *errmsg = pj_strerrno(NUM2INT(errno));
|
220
|
+
if (errmsg) {
|
221
|
+
return rb_str_new2(errmsg);
|
222
|
+
} else {
|
223
|
+
return rb_str_new2("unknown error");
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
#if PJ_VERSION >= 449
|
228
|
+
/**Return list of all datums we know about.
|
229
|
+
|
230
|
+
call-seq: list -> Array of Proj4::Datum
|
231
|
+
|
232
|
+
*/
|
233
|
+
static VALUE datum_list(VALUE self){
|
234
|
+
struct PJ_DATUMS *datum;
|
235
|
+
VALUE list = rb_ary_new();
|
236
|
+
for (datum = pj_get_datums_ref(); datum->id; datum++){
|
237
|
+
rb_ary_push(list, Data_Wrap_Struct(cDatum, 0, 0, datum));
|
238
|
+
}
|
239
|
+
return list;
|
240
|
+
}
|
241
|
+
/**Get ID of the datum.
|
242
|
+
|
243
|
+
call-seq: id -> String
|
244
|
+
|
245
|
+
*/
|
246
|
+
static VALUE datum_get_id(VALUE self){
|
247
|
+
struct PJ_DATUMS *datum;
|
248
|
+
Data_Get_Struct(self,struct PJ_DATUMS,datum);
|
249
|
+
return rb_str_new2(datum->id);
|
250
|
+
}
|
251
|
+
/**Get ID of the ellipse used by the datum.
|
252
|
+
|
253
|
+
call-seq: ellipse_id -> String
|
254
|
+
|
255
|
+
*/
|
256
|
+
static VALUE datum_get_ellipse_id(VALUE self){
|
257
|
+
struct PJ_DATUMS *datum;
|
258
|
+
Data_Get_Struct(self,struct PJ_DATUMS,datum);
|
259
|
+
return rb_str_new2(datum->ellipse_id);
|
260
|
+
}
|
261
|
+
/**Get definition of the datum.
|
262
|
+
|
263
|
+
call-seq: defn -> String
|
264
|
+
|
265
|
+
*/
|
266
|
+
static VALUE datum_get_defn(VALUE self){
|
267
|
+
struct PJ_DATUMS *datum;
|
268
|
+
Data_Get_Struct(self,struct PJ_DATUMS,datum);
|
269
|
+
return rb_str_new2(datum->defn);
|
270
|
+
}
|
271
|
+
/**Get comments about the datum.
|
272
|
+
|
273
|
+
call-seq: comments -> String
|
274
|
+
|
275
|
+
*/
|
276
|
+
static VALUE datum_get_comments(VALUE self){
|
277
|
+
struct PJ_DATUMS *datum;
|
278
|
+
Data_Get_Struct(self,struct PJ_DATUMS,datum);
|
279
|
+
return rb_str_new2(datum->comments);
|
280
|
+
}
|
281
|
+
|
282
|
+
/**Return list of all reference ellipsoids we know about.
|
283
|
+
|
284
|
+
call-seq: list -> Array of Proj4::Ellipsoid
|
285
|
+
|
286
|
+
*/
|
287
|
+
static VALUE ellipsoid_list(VALUE self){
|
288
|
+
struct PJ_ELLPS *el;
|
289
|
+
VALUE list = rb_ary_new();
|
290
|
+
for (el = pj_get_ellps_ref(); el->id; el++){
|
291
|
+
rb_ary_push(list, Data_Wrap_Struct(cEllipsoid, 0, 0, el));
|
292
|
+
}
|
293
|
+
return list;
|
294
|
+
}
|
295
|
+
/**Get ID of the reference ellipsoid.
|
296
|
+
|
297
|
+
call-seq: id -> String
|
298
|
+
|
299
|
+
*/
|
300
|
+
static VALUE ellipsoid_get_id(VALUE self){
|
301
|
+
struct PJ_ELLPS *el;
|
302
|
+
Data_Get_Struct(self,struct PJ_ELLPS,el);
|
303
|
+
return rb_str_new2(el->id);
|
304
|
+
}
|
305
|
+
/**Get equatorial radius (semi-major axis, a value) of the reference ellipsoid.
|
306
|
+
|
307
|
+
call-seq: major -> String
|
308
|
+
|
309
|
+
*/
|
310
|
+
static VALUE ellipsoid_get_major(VALUE self){
|
311
|
+
struct PJ_ELLPS *el;
|
312
|
+
Data_Get_Struct(self,struct PJ_ELLPS,el);
|
313
|
+
return rb_str_new2(el->major);
|
314
|
+
}
|
315
|
+
/**Get elliptical parameter of the reference ellipsoid. This is either the polar radius (semi-minor axis, b value) or the inverse flattening (1/f, rf).
|
316
|
+
|
317
|
+
call-seq: ell -> String
|
318
|
+
|
319
|
+
*/
|
320
|
+
static VALUE ellipsoid_get_ell(VALUE self){
|
321
|
+
struct PJ_ELLPS *el;
|
322
|
+
Data_Get_Struct(self,struct PJ_ELLPS,el);
|
323
|
+
return rb_str_new2(el->ell);
|
324
|
+
}
|
325
|
+
/**Get name of the reference ellipsoid.
|
326
|
+
|
327
|
+
call-seq: name -> String
|
328
|
+
|
329
|
+
*/
|
330
|
+
static VALUE ellipsoid_get_name(VALUE self){
|
331
|
+
struct PJ_ELLPS *el;
|
332
|
+
Data_Get_Struct(self,struct PJ_ELLPS,el);
|
333
|
+
return rb_str_new2(el->name);
|
334
|
+
}
|
335
|
+
|
336
|
+
/**Return list of all prime meridians we know about.
|
337
|
+
|
338
|
+
call-seq: list -> Array of Proj4::PrimeMeridian
|
339
|
+
|
340
|
+
*/
|
341
|
+
static VALUE prime_meridian_list(VALUE self){
|
342
|
+
struct PJ_PRIME_MERIDIANS *prime_meridian;
|
343
|
+
VALUE list = rb_ary_new();
|
344
|
+
for (prime_meridian = pj_get_prime_meridians_ref(); prime_meridian->id; prime_meridian++){
|
345
|
+
rb_ary_push(list, Data_Wrap_Struct(cPrimeMeridian, 0, 0, prime_meridian));
|
346
|
+
}
|
347
|
+
return list;
|
348
|
+
}
|
349
|
+
/**Get ID of this prime_meridian.
|
350
|
+
|
351
|
+
call-seq: id -> String
|
352
|
+
|
353
|
+
*/
|
354
|
+
static VALUE prime_meridian_get_id(VALUE self){
|
355
|
+
struct PJ_PRIME_MERIDIANS *prime_meridian;
|
356
|
+
Data_Get_Struct(self,struct PJ_PRIME_MERIDIANS,prime_meridian);
|
357
|
+
return rb_str_new2(prime_meridian->id);
|
358
|
+
}
|
359
|
+
/**Get definition of this prime_meridian.
|
360
|
+
|
361
|
+
call-seq: defn -> String
|
362
|
+
|
363
|
+
*/
|
364
|
+
static VALUE prime_meridian_get_defn(VALUE self){
|
365
|
+
struct PJ_PRIME_MERIDIANS *prime_meridian;
|
366
|
+
Data_Get_Struct(self,struct PJ_PRIME_MERIDIANS,prime_meridian);
|
367
|
+
return rb_str_new2(prime_meridian->defn);
|
368
|
+
}
|
369
|
+
|
370
|
+
/**Return list of all projection types we know about.
|
371
|
+
|
372
|
+
call-seq: list -> Array of Proj4::ProjectionType
|
373
|
+
|
374
|
+
*/
|
375
|
+
static VALUE projection_type_list(VALUE self){
|
376
|
+
struct PJ_LIST *pt;
|
377
|
+
VALUE list = rb_ary_new();
|
378
|
+
for (pt = pj_get_list_ref(); pt->id; pt++){
|
379
|
+
rb_ary_push(list, Data_Wrap_Struct(cProjectionType, 0, 0, pt));
|
380
|
+
}
|
381
|
+
return list;
|
382
|
+
}
|
383
|
+
/**Get ID of this projection type.
|
384
|
+
|
385
|
+
call-seq: id -> String
|
386
|
+
|
387
|
+
*/
|
388
|
+
static VALUE projection_type_get_id(VALUE self){
|
389
|
+
struct PJ_LIST *pt;
|
390
|
+
Data_Get_Struct(self,struct PJ_LIST,pt);
|
391
|
+
return rb_str_new2(pt->id);
|
392
|
+
}
|
393
|
+
/**Get description of this projection type as a multiline string.
|
394
|
+
|
395
|
+
call-seq: descr -> String
|
396
|
+
|
397
|
+
*/
|
398
|
+
static VALUE projection_type_get_descr(VALUE self){
|
399
|
+
struct PJ_LIST *pt;
|
400
|
+
Data_Get_Struct(self,struct PJ_LIST,pt);
|
401
|
+
return rb_str_new2(*(pt->descr));
|
402
|
+
}
|
403
|
+
|
404
|
+
/**Return list of all units we know about.
|
405
|
+
|
406
|
+
call-seq: list -> Array of Proj4::Unit
|
407
|
+
|
408
|
+
*/
|
409
|
+
static VALUE unit_list(VALUE self){
|
410
|
+
struct PJ_UNITS *unit;
|
411
|
+
VALUE list = rb_ary_new();
|
412
|
+
for (unit = pj_get_units_ref(); unit->id; unit++){
|
413
|
+
rb_ary_push(list, Data_Wrap_Struct(cUnit, 0, 0, unit));
|
414
|
+
}
|
415
|
+
return list;
|
416
|
+
}
|
417
|
+
/**Get ID of the unit.
|
418
|
+
|
419
|
+
call-seq: id -> String
|
420
|
+
|
421
|
+
*/
|
422
|
+
static VALUE unit_get_id(VALUE self){
|
423
|
+
struct PJ_UNITS *unit;
|
424
|
+
Data_Get_Struct(self,struct PJ_UNITS,unit);
|
425
|
+
return rb_str_new2(unit->id);
|
426
|
+
}
|
427
|
+
/**Get conversion factor of this unit to a meter. Note that this is a string, it can either contain a floating point number or it can be in the form numerator/denominator.
|
428
|
+
|
429
|
+
call-seq: to_meter -> String
|
430
|
+
|
431
|
+
*/
|
432
|
+
static VALUE unit_get_to_meter(VALUE self){
|
433
|
+
struct PJ_UNITS *unit;
|
434
|
+
Data_Get_Struct(self,struct PJ_UNITS,unit);
|
435
|
+
return rb_str_new2(unit->to_meter);
|
436
|
+
}
|
437
|
+
/**Get name (description) of the unit.
|
438
|
+
|
439
|
+
call-seq: name -> String
|
440
|
+
|
441
|
+
*/
|
442
|
+
static VALUE unit_get_name(VALUE self){
|
443
|
+
struct PJ_UNITS *unit;
|
444
|
+
Data_Get_Struct(self,struct PJ_UNITS,unit);
|
445
|
+
return rb_str_new2(unit->name);
|
446
|
+
}
|
447
|
+
|
448
|
+
#endif
|
449
|
+
|
450
|
+
void Init_projrb(void) {
|
451
|
+
|
452
|
+
idRaise = rb_intern("raise_error");
|
453
|
+
idGetX = rb_intern("x");
|
454
|
+
idSetX = rb_intern("x=");
|
455
|
+
idGetY = rb_intern("y");
|
456
|
+
idSetY = rb_intern("y=");
|
457
|
+
idGetZ = rb_intern("z");
|
458
|
+
idSetZ = rb_intern("z=");
|
459
|
+
idParseInitParameters = rb_intern("_parse_init_parameters");
|
460
|
+
|
461
|
+
mProjrb = rb_define_module("Proj4");
|
462
|
+
|
463
|
+
/**
|
464
|
+
Radians per degree
|
465
|
+
*/
|
466
|
+
rb_define_const(mProjrb,"DEG_TO_RAD", rb_float_new(DEG_TO_RAD));
|
467
|
+
/**
|
468
|
+
Degrees per radian
|
469
|
+
*/
|
470
|
+
rb_define_const(mProjrb,"RAD_TO_DEG", rb_float_new(RAD_TO_DEG));
|
471
|
+
/**
|
472
|
+
Version of C libproj
|
473
|
+
*/
|
474
|
+
rb_define_const(mProjrb,"LIBVERSION", rb_float_new(PJ_VERSION));
|
475
|
+
|
476
|
+
cError = rb_define_class_under(mProjrb,"Error",rb_path2class("StandardError"));
|
477
|
+
rb_define_singleton_method(cError,"strerrno",projerr_strerrno,1);
|
478
|
+
|
479
|
+
cProjection = rb_define_class_under(mProjrb,"Projection",rb_cObject);
|
480
|
+
rb_define_alloc_func(cProjection,proj_alloc);
|
481
|
+
rb_define_method(cProjection,"initialize",proj_initialize,1);
|
482
|
+
rb_define_method(cProjection,"hasInverse?",proj_has_inverse,0);
|
483
|
+
rb_define_method(cProjection,"isLatLong?",proj_is_latlong,0);
|
484
|
+
rb_define_method(cProjection,"isGeocent?",proj_is_geocent,0);
|
485
|
+
rb_define_alias(cProjection,"isGeocentric?","isGeocent?");
|
486
|
+
rb_define_method(cProjection,"getDef",proj_get_def,0);
|
487
|
+
rb_define_method(cProjection,"forward!",proj_forward,1);
|
488
|
+
rb_define_method(cProjection,"inverse!",proj_inverse,1);
|
489
|
+
rb_define_method(cProjection,"transform!",proj_transform,2);
|
490
|
+
|
491
|
+
#if PJ_VERSION >= 449
|
492
|
+
cDef = rb_define_class_under(mProjrb,"Def",rb_cObject);
|
493
|
+
|
494
|
+
/* The Datum class holds information about datums ('WGS84', 'potsdam', ...) known to Proj.4. */
|
495
|
+
cDatum = rb_define_class_under(mProjrb,"Datum",cDef);
|
496
|
+
rb_define_singleton_method(cDatum,"list",datum_list,0);
|
497
|
+
rb_define_method(cDatum,"id",datum_get_id,0);
|
498
|
+
rb_define_method(cDatum,"ellipse_id",datum_get_ellipse_id,0);
|
499
|
+
rb_define_method(cDatum,"defn",datum_get_defn,0);
|
500
|
+
rb_define_method(cDatum,"comments",datum_get_comments,0);
|
501
|
+
|
502
|
+
/* The Ellipsoid class holds information about ellipsoids ('WGS84', 'bessel', ...) known to Proj.4. */
|
503
|
+
cEllipsoid = rb_define_class_under(mProjrb,"Ellipsoid",cDef);
|
504
|
+
rb_define_singleton_method(cEllipsoid,"list",ellipsoid_list,0);
|
505
|
+
rb_define_method(cEllipsoid,"id",ellipsoid_get_id,0);
|
506
|
+
rb_define_method(cEllipsoid,"major",ellipsoid_get_major,0);
|
507
|
+
rb_define_method(cEllipsoid,"ell",ellipsoid_get_ell,0);
|
508
|
+
rb_define_method(cEllipsoid,"name",ellipsoid_get_name,0);
|
509
|
+
|
510
|
+
/* The PrimeMeridian class holds information about prime meridians ('greenwich', 'lisbon', ...) known to Proj.4. */
|
511
|
+
cPrimeMeridian = rb_define_class_under(mProjrb,"PrimeMeridian",cDef);
|
512
|
+
rb_define_singleton_method(cPrimeMeridian,"list",prime_meridian_list,0);
|
513
|
+
rb_define_method(cPrimeMeridian,"id",prime_meridian_get_id,0);
|
514
|
+
rb_define_method(cPrimeMeridian,"defn",prime_meridian_get_defn,0);
|
515
|
+
|
516
|
+
/* The ProjectionType class holds information about projections types ('merc', 'aea', ...) known to Proj.4. */
|
517
|
+
cProjectionType = rb_define_class_under(mProjrb,"ProjectionType",cDef);
|
518
|
+
rb_define_singleton_method(cProjectionType,"list",projection_type_list,0);
|
519
|
+
rb_define_method(cProjectionType,"id",projection_type_get_id,0);
|
520
|
+
rb_define_method(cProjectionType,"descr",projection_type_get_descr,0);
|
521
|
+
|
522
|
+
/* The Unit class holds information about the units ('m', 'km', 'mi', ...) known to Proj.4. */
|
523
|
+
cUnit = rb_define_class_under(mProjrb,"Unit",cDef);
|
524
|
+
rb_define_singleton_method(cUnit,"list",unit_list,0);
|
525
|
+
rb_define_method(cUnit,"id",unit_get_id,0);
|
526
|
+
rb_define_method(cUnit,"to_meter",unit_get_to_meter,0);
|
527
|
+
rb_define_method(cUnit,"name",unit_get_name,0);
|
528
|
+
|
529
|
+
#endif
|
530
|
+
|
531
|
+
}
|
532
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
$: << 'lib'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'proj4')
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class ConstantsTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_version
|
8
|
+
assert 440 < Proj4::LIBVERSION
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_deg
|
12
|
+
assert_equal Math::PI/180, Proj4::DEG_TO_RAD
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_rad
|
16
|
+
assert_equal 180/Math::PI, Proj4::RAD_TO_DEG
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
$: << 'lib'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'proj4')
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
class CreateProjectionTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@proj_wgs84 = Proj4::Projection.new(["init=epsg:4326"]) # WGS84
|
9
|
+
@proj_gk = Proj4::Projection.new(["init=epsg:31467"]) # Gauss-Kruger Zone 3
|
10
|
+
@proj_conakry = Proj4::Projection.new(["init=epsg:31528"]) # Conakry 1905 / UTM zone 28N
|
11
|
+
@proj_ortel = Proj4::Projection.new(["proj=ortel", "lon_0=90w"]) # Ortelius Oval Projection
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_has_inverse
|
15
|
+
assert @proj_wgs84.hasInverse?
|
16
|
+
assert @proj_gk.hasInverse?
|
17
|
+
assert @proj_conakry.hasInverse?
|
18
|
+
assert ! @proj_ortel.hasInverse?
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_is_latlong
|
22
|
+
assert @proj_wgs84.isLatLong?
|
23
|
+
assert ! @proj_gk.isLatLong?
|
24
|
+
assert ! @proj_conakry.isLatLong?
|
25
|
+
assert ! @proj_ortel.isLatLong?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_is_geocent
|
29
|
+
assert_equal @proj_gk.isGeocent?, @proj_gk.isGeocentric? # two names for same method
|
30
|
+
assert ! @proj_wgs84.isGeocent?
|
31
|
+
assert ! @proj_gk.isGeocent?
|
32
|
+
assert ! @proj_conakry.isGeocent?
|
33
|
+
assert ! @proj_ortel.isGeocent?
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_get_def
|
37
|
+
assert_equal '+init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0', @proj_wgs84.getDef.strip
|
38
|
+
assert_equal '+init=epsg:31467 +proj=tmerc +lat_0=0 +lon_0=9 +k=1.000000 +x_0=3500000 +y_0=0 +ellps=bessel +datum=potsdam +units=m +no_defs +towgs84=606.0,23.0,413.0', @proj_gk.getDef.strip
|
39
|
+
assert_equal '+init=epsg:31528 +proj=utm +zone=28 +a=6378249.2 +b=6356515 +towgs84=-23,259,-9,0,0,0,0 +units=m +no_defs', @proj_conakry.getDef.strip
|
40
|
+
assert_equal '+proj=ortel +lon_0=90w +ellps=WGS84', @proj_ortel.getDef.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_inspect
|
44
|
+
assert_equal '#<Proj4::Projection +init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0>', @proj_wgs84.to_s
|
45
|
+
assert_equal '#<Proj4::Projection +init=epsg:4326 +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0>', @proj_wgs84.inspect
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_projection
|
49
|
+
assert_equal 'longlat', @proj_wgs84.projection
|
50
|
+
assert_equal 'tmerc', @proj_gk.projection
|
51
|
+
assert_equal 'utm', @proj_conakry.projection
|
52
|
+
assert_equal 'ortel', @proj_ortel.projection
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_datum
|
56
|
+
assert_equal 'WGS84', @proj_wgs84.datum
|
57
|
+
assert_equal 'potsdam', @proj_gk.datum
|
58
|
+
assert_nil @proj_conakry.datum
|
59
|
+
assert_nil @proj_ortel.datum
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
data/test/test_datums.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
$: << 'lib'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'proj4')
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
if Proj4::LIBVERSION >= 449
|
6
|
+
class DatumsTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_get_all
|
9
|
+
datums = Proj4::Datum.list.sort.collect{ |u| u.id }
|
10
|
+
assert datums.index('WGS84')
|
11
|
+
assert datums.index('potsdam')
|
12
|
+
assert datums.index('ire65')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_one
|
16
|
+
datum = Proj4::Datum.get('potsdam')
|
17
|
+
assert_kind_of Proj4::Datum, datum
|
18
|
+
assert_equal 'potsdam', datum.id
|
19
|
+
assert_equal 'potsdam', datum.to_s
|
20
|
+
assert_equal 'bessel', datum.ellipse_id
|
21
|
+
assert_equal 'towgs84=606.0,23.0,413.0', datum.defn
|
22
|
+
assert_equal 'Potsdam Rauenberg 1950 DHDN', datum.comments
|
23
|
+
assert_equal '#<Proj4::Datum id="potsdam", ellipse_id="bessel", defn="towgs84=606.0,23.0,413.0", comments="Potsdam Rauenberg 1950 DHDN">', datum.inspect
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_compare
|
27
|
+
u1 = Proj4::Datum.get('potsdam')
|
28
|
+
u2 = Proj4::Datum.get('potsdam')
|
29
|
+
assert u1 == u2
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_failed_get
|
33
|
+
datum = Proj4::Datum.get('foo')
|
34
|
+
assert_nil datum
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_new
|
38
|
+
assert_raise TypeError do
|
39
|
+
Proj4::Datum.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
$: << 'lib'
|
2
|
+
require File.join(File.dirname(__FILE__), '..', 'lib', 'proj4')
|
3
|
+
require 'test/unit'
|
4
|
+
|
5
|
+
if Proj4::LIBVERSION >= 449
|
6
|
+
class EllipsoidsTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_get_all
|
9
|
+
ellipsoids = Proj4::Ellipsoid.list.sort.collect{ |u| u.id }
|
10
|
+
assert ellipsoids.index('WGS84')
|
11
|
+
assert ellipsoids.index('bessel')
|
12
|
+
assert ellipsoids.index('lerch')
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_one
|
16
|
+
ellipsoid = Proj4::Ellipsoid.get('bessel')
|
17
|
+
assert_kind_of Proj4::Ellipsoid, ellipsoid
|
18
|
+
assert_equal 'bessel', ellipsoid.id
|
19
|
+
assert_equal 'a=6377397.155', ellipsoid.major
|
20
|
+
assert_equal 'rf=299.1528128', ellipsoid.ell
|
21
|
+
assert_equal 'Bessel 1841', ellipsoid.name
|
22
|
+
assert_equal 'bessel', ellipsoid.to_s
|
23
|
+
assert_equal '#<Proj4::Ellipsoid id="bessel", major="a=6377397.155", ell="rf=299.1528128", name="Bessel 1841">', ellipsoid.inspect
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_compare
|
27
|
+
e1 = Proj4::Ellipsoid.get('bessel')
|
28
|
+
e2 = Proj4::Ellipsoid.get('bessel')
|
29
|
+
assert e1 == e2
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_failed_get
|
33
|
+
ellipsoid = Proj4::Ellipsoid.get('foo')
|
34
|
+
assert_nil ellipsoid
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_new
|
38
|
+
assert_raise TypeError do
|
39
|
+
Proj4::Ellipsoid.new
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|