Class: Proj4::Projection
- Inherits:
-
Object
- Object
- Proj4::Projection
- Defined in:
- lib/proj4.rb,
ext/projrb.c
Overview
The Projection class represents a geographical projection.
Creating a new projection object
Projection objects are created through the new method as usual. Depending on the kind of projection, many different parameters are needed. Please consult the documentation of the Proj.4 C library at trac.osgeo.org/proj/ for details.
There are several ways of specifying the parameters:
- as a String:
-
A string with the parameters in ‘[+]key=value’ format concatenated together. This is the format used by the
proj
andcs2cs
command line tool.
proj = Projection.new "+proj=utm +zone=21 +units=m"
- as an Array:
-
An array with each parameter as a member in the array in ‘[+]key=value’ format.
proj = Projection.new [ "proj=utm", "zone=21", "units=m" ]
- as a Hash:
-
A hash with strings or symbols as keys.
proj = Projection.new( "proj" => "utm", "zone" => "21", "units" => "m" )
proj = Projection.new( :proj => "utm", :zone => "21", :units => "m" )
With all variants the plus sign in front of the keys is optional.
Using a projection object to project points
There are two ways a projection can be used: Through the forward
and inverse
methods (with all their variants) you can do projection from longitudes and latitudes into the coordinate system used by the projection and back. These projections are always 2D, i.e. you need and get lon/lat or x/y coordinates.
The alternative is the transform
method (with all its variants) which is used to transform 3D points from one projection and datum to another. In addition to the x/y coordinates the transform method also reads and returns a z coordinate.
Versions of the projection methods
All three projection methods (forward
, inverse
, and transform
) work on points. Every method has an in-place version (with a name ending in !) which changes the given point and a normal version which first creates a copy of the point object and changes and returns that. All methods use radians when reading or returning points. For convenience there are also forwardDeg
and inverseDeg
methods (and in-place versions forwardDeg!
and inverseDeg!
) that will work with degrees.
Points
All projection method project points to other points. You can use objects of the Proj4::Point class for this or any other object which supports the x, y, z read and write accessor methods. (In fact you don’t even need the z accessor methods, 0 is assumed if they don’t exist.)
Some projection methods act on the given point in-place, other return a copy of the point object. But in any case all other attributes of the point object are retained.
Projection collections
The methods forward_all, inverse_all, and transform_all (and their in-place versions forward_all!, inverse_all!, and transform_all! work just like their simple counterparts, but instead of a single point they convert a collection of points in one go.
These methods all take an array as an argument or any object responding to the each
method (for the in-place versions) or each
, clear
, and <<
methods (for the normal version).
Some projection methods act on the given collection in-place, i.e. the collection is not touched and all points in the collection will be projected in-place. The other methods act on a copy of the collection and on copies of each point in the collection. So you’ll get back a brand new copy of the collection with new copies of the points with the projected coordinates. In any case all other attributes of the collection and points are retained.
Instance Method Summary collapse
-
#datum ⇒ Object
Get the ID of the datum used in this projection.
-
#forward(point) ⇒ Object
Forward projection of a point.
-
#forward!(point) ⇒ Object
Transforms a point in WGS84 LonLat in radians to projected coordinates.
-
#forward_all(collection) ⇒ Object
Projects all points in a collection.
-
#forward_all!(collection) ⇒ Object
Project all points in a collection ‘in place’.
-
#forwardDeg(point) ⇒ Object
Convenience function for calculating a forward projection with degrees instead of radians.
-
#forwardDeg!(point) ⇒ Object
Convenience function for calculating a forward projection with degrees instead of radians.
-
#getDef ⇒ Object
Get the expanded definition of this projection as a string.
-
#hasInverse? ⇒ Boolean
Has this projection an inverse?.
-
#initialize(params) ⇒ Object
constructor
Creates a new projection object.
-
#inverse(point) ⇒ Object
Inverse projection of a point.
-
#inverse!(point) ⇒ Object
Transforms a point in the coordinate system defined at initialization of the Projection object to WGS84 LonLat in radians.
-
#inverse_all(collection) ⇒ Object
Projects all points in a collection.
-
#inverse_all!(collection) ⇒ Object
Project all points in a collection ‘in place’.
-
#inverseDeg(point) ⇒ Object
Convenience function for calculating an inverse projection with the result in degrees instead of radians.
-
#inverseDeg!(point) ⇒ Object
Convenience function for calculating an inverse projection with the result in degrees instead of radians.
-
#isGeocent? ⇒ Boolean
(also: #isGeocentric?)
Is this projection a geocentric projection?.
-
#isLatLong? ⇒ Boolean
Is this projection a latlong projection?.
-
#projection ⇒ Object
Get the ID of this projection.
-
#to_s ⇒ Object
Get definition of projection in typical inspect format (#<Proj4::Projection init=… proj=… …>).
-
#transform(otherProjection, point) ⇒ Object
Transforms a point from one projection to another.
-
#transform!(dst, point) ⇒ Object
Transforms a point from one projection to another.
-
#transform_all(otherProjection, collection) ⇒ Object
Transforms all points in a collection from one projection to another.
-
#transform_all!(otherProjection, collection) ⇒ Object
Transforms all points in a collection ‘in place’ from one projection to another.
Constructor Details
#initialize(params) ⇒ Object
Creates a new projection object. See the intro for details.
call-seq: new(String) -> Proj4::Projection
new(Array) -> Proj4::Projection
new(Hash) -> Proj4::Projection
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'ext/projrb.c', line 77
static VALUE proj_initialize(VALUE self, VALUE params){
_wrap_pj* wpj;
VALUE proj_params = rb_funcall(cProjection, idParseInitParameters, 1, params);
int size = RARRAY_LEN(proj_params);
char** c_params = (char **) malloc(size*sizeof(char *));
int i;
for (i=0; i < size; i++)
{
VALUE item = rb_ary_entry(proj_params, i);
c_params[i]= StringValuePtr(item);
}
Data_Get_Struct(self,_wrap_pj,wpj);
wpj->pj = pj_init(size,c_params);
free(c_params);
if(wpj->pj == 0) {
int pj_errno_ref = *pj_get_errno_ref();
if (pj_errno_ref > 0) {
rb_raise(rb_eSystemCallError, "Unknown system call error");
} else {
raise_error(pj_errno_ref);
}
}
return self;
}
|
Instance Method Details
#datum ⇒ Object
Get the ID of the datum used in this projection.
call-seq: datum -> String
163 164 165 |
# File 'lib/proj4.rb', line 163 def datum getDef =~ /\+datum=(.+?) / ? $1 : nil end |
#forward(point) ⇒ Object
Forward projection of a point. Returns a copy of the point object with coordinates projected.
call-seq: forward(point) -> point
179 180 181 |
# File 'lib/proj4.rb', line 179 def forward(point) forward!(point.dup) end |
#forward!(point) ⇒ Object
Transforms a point in WGS84 LonLat in radians to projected coordinates.
This version of the method changes the point in-place.
call-seq: forward!(point) -> point
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'ext/projrb.c', line 156
static VALUE proj_forward(VALUE self,VALUE point){
_wrap_pj* wpj;
int pj_errno_ref;
projLP pj_point;
projXY pj_result;
Data_Get_Struct(self,_wrap_pj,wpj);
pj_point.u = NUM2DBL( rb_funcall(point, idGetX, 0) );
pj_point.v = NUM2DBL( rb_funcall(point, idGetY, 0) );
pj_result = pj_fwd(pj_point, wpj->pj);
pj_errno_ref = *pj_get_errno_ref();
if (pj_errno_ref == 0) {
rb_funcall(point, idSetX, 1, rb_float_new(pj_result.u) );
rb_funcall(point, idSetY, 1, rb_float_new(pj_result.v) );
return point;
} else if (pj_errno_ref > 0) {
rb_raise(rb_eSystemCallError, "Unknown system call error");
} else {
raise_error(pj_errno_ref);
}
return self; /* Makes gcc happy */
}
|
#forward_all(collection) ⇒ Object
Projects all points in a collection. The collection
object must implement the each
, clear
, and << methods (just like an Array) for this to work.
call-seq: forward_all(collection) -> collection
221 222 223 224 225 226 227 |
# File 'lib/proj4.rb', line 221 def forward_all(collection) newcollection = collection.dup.clear collection.each do |point| newcollection << forward(point) end newcollection end |
#forward_all!(collection) ⇒ Object
Project all points in a collection ‘in place’. The collection
object must implement the each
method for this to work.
call-seq: forward_all!(collection) -> collection
208 209 210 211 212 213 |
# File 'lib/proj4.rb', line 208 def forward_all!(collection) collection.each do |point| forward!(point) end collection end |
#forwardDeg(point) ⇒ Object
Convenience function for calculating a forward projection with degrees instead of radians.
call-seq: forwardDeg(point) -> point
187 188 189 |
# File 'lib/proj4.rb', line 187 def forwardDeg(point) forwardDeg!(point.dup) end |
#forwardDeg!(point) ⇒ Object
Convenience function for calculating a forward projection with degrees instead of radians. This version works in-place, i.e. the point objects content is overwritten.
call-seq: forwardDeg!(point) -> point
196 197 198 199 200 |
# File 'lib/proj4.rb', line 196 def forwardDeg!(point) point.x *= Proj4::DEG_TO_RAD point.y *= Proj4::DEG_TO_RAD forward!(point) end |
#getDef ⇒ Object
Get the expanded definition of this projection as a string.
call-seq: getDef -> String
144 145 146 147 148 |
# File 'ext/projrb.c', line 144
static VALUE proj_get_def(VALUE self){
_wrap_pj* wpj;
Data_Get_Struct(self,_wrap_pj,wpj);
return rb_str_new2(pj_get_def(wpj->pj, 0));
}
|
#hasInverse? ⇒ Boolean
Has this projection an inverse?
call-seq: hasInverse? -> true or false
110 111 112 113 114 |
# File 'ext/projrb.c', line 110
static VALUE proj_has_inverse(VALUE self){
_wrap_pj* wpj;
Data_Get_Struct(self,_wrap_pj,wpj);
return wpj->pj->inv ? Qtrue : Qfalse;
}
|
#inverse(point) ⇒ Object
Inverse projection of a point. Returns a copy of the point object with coordinates projected.
call-seq: inverse(point) -> point
233 234 235 |
# File 'lib/proj4.rb', line 233 def inverse(point) inverse!(point.dup) end |
#inverse!(point) ⇒ Object
Transforms a point in the coordinate system defined at initialization of the Projection object to WGS84 LonLat in radians.
This version of the method changes the point in-place.
call-seq: inverse!(point) -> point
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'ext/projrb.c', line 186
static VALUE proj_inverse(VALUE self,VALUE point){
_wrap_pj* wpj;
int pj_errno_ref;
projXY pj_point;
projLP pj_result;
Data_Get_Struct(self,_wrap_pj,wpj);
pj_point.u = NUM2DBL( rb_funcall(point, idGetX, 0) );
pj_point.v = NUM2DBL( rb_funcall(point, idGetY, 0) );
pj_result = pj_inv(pj_point, wpj->pj);
pj_errno_ref = *pj_get_errno_ref();
if (pj_errno_ref == 0) {
rb_funcall(point, idSetX, 1, rb_float_new(pj_result.u) );
rb_funcall(point, idSetY, 1, rb_float_new(pj_result.v) );
return point;
} else if (pj_errno_ref > 0) {
rb_raise(rb_eSystemCallError, "Unknown system call error");
} else {
raise_error(pj_errno_ref);
}
return self; /* Makes gcc happy */
}
|
#inverse_all(collection) ⇒ Object
Projects all points in a collection. The collection
object must implement the each
, clear
, and << methods (just like an Array) for this to work.
call-seq: inverse_all(collection) -> collection
276 277 278 279 280 281 282 |
# File 'lib/proj4.rb', line 276 def inverse_all(collection) newcollection = collection.dup.clear collection.each do |point| newcollection << inverse(point) end newcollection end |
#inverse_all!(collection) ⇒ Object
Project all points in a collection ‘in place’. The collection
object must implement the each
method for this to work.
call-seq: inverse_all!(collection) -> collection
263 264 265 266 267 268 |
# File 'lib/proj4.rb', line 263 def inverse_all!(collection) collection.each do |point| inverse!(point) end collection end |
#inverseDeg(point) ⇒ Object
Convenience function for calculating an inverse projection with the result in degrees instead of radians.
call-seq: inverseDeg(point) -> point
241 242 243 |
# File 'lib/proj4.rb', line 241 def inverseDeg(point) inverseDeg!(point.dup) end |
#inverseDeg!(point) ⇒ Object
Convenience function for calculating an inverse projection with the result in degrees instead of radians. This version works in-place, i.e. the point objects content is overwritten.
call-seq: inverseDeg!(point) -> point
250 251 252 253 254 255 |
# File 'lib/proj4.rb', line 250 def inverseDeg!(point) inverse!(point) point.x *= Proj4::RAD_TO_DEG point.y *= Proj4::RAD_TO_DEG point end |
#isGeocent? ⇒ Boolean Also known as: isGeocentric?
Is this projection a geocentric projection?
call-seq: isGeocentric? -> true or false
133 134 135 136 137 |
# File 'ext/projrb.c', line 133
static VALUE proj_is_geocent(VALUE self){
_wrap_pj* wpj;
Data_Get_Struct(self,_wrap_pj,wpj);
return pj_is_geocent(wpj->pj) ? Qtrue : Qfalse;
}
|
#isLatLong? ⇒ Boolean
Is this projection a latlong projection?
call-seq: isLatLong? -> true or false
122 123 124 125 126 |
# File 'ext/projrb.c', line 122
static VALUE proj_is_latlong(VALUE self){
_wrap_pj* wpj;
Data_Get_Struct(self,_wrap_pj,wpj);
return pj_is_latlong(wpj->pj) ? Qtrue : Qfalse;
}
|
#projection ⇒ Object
Get the ID of this projection.
call-seq: projection -> String
155 156 157 |
# File 'lib/proj4.rb', line 155 def projection getDef =~ /\+proj=(.+?) / ? $1 : nil end |
#to_s ⇒ Object
Get definition of projection in typical inspect format (#<Proj4::Projection init=… proj=… …>).
call-seq: to_s -> String
171 172 173 |
# File 'lib/proj4.rb', line 171 def to_s "#<Proj4::Projection#{ getDef }>" end |
#transform(otherProjection, point) ⇒ Object
Transforms a point from one projection to another.
call-seq: transform(destinationProjection, point) -> point
288 289 290 |
# File 'lib/proj4.rb', line 288 def transform(otherProjection, point) transform!(otherProjection, point.dup) end |
#transform!(dst, point) ⇒ Object
Transforms a point from one projection to another. The second parameter is
either a Proj4::Point object or you can use any object which
responds to the x, y, z read and write accessor methods. (In fact you
don't even need the z accessor methods, 0 is assumed if they don't exist).
This is the destructive variant of the method, i.e. it will overwrite your
existing point coordinates but otherwise leave the point object alone.
call-seq: transform!(destinationProjection, point) -> point
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'ext/projrb.c', line 221
static VALUE proj_transform(VALUE self, VALUE dst, VALUE point){
_wrap_pj* wpjsrc;
_wrap_pj* wpjdst;
double array_x[1];
double array_y[1];
double array_z[1];
int result;
Data_Get_Struct(self,_wrap_pj,wpjsrc);
Data_Get_Struct(dst,_wrap_pj,wpjdst);
array_x[0] = NUM2DBL( rb_funcall(point, idGetX, 0) );
array_y[0] = NUM2DBL( rb_funcall(point, idGetY, 0) );
/* if point objects has a method 'z' we get the z coordinate, otherwise we just assume 0 */
if ( rb_respond_to(point, idGetZ) ) {
array_z[0] = NUM2DBL( rb_funcall(point, idGetZ, 0) );
} else {
array_z[0] = 0.0;
}
result = pj_transform(wpjsrc->pj, wpjdst->pj, 1, 1, array_x, array_y, array_z);
if (! result) {
rb_funcall(point, idSetX, 1, rb_float_new(array_x[0]) );
rb_funcall(point, idSetY, 1, rb_float_new(array_y[0]) );
/* if point objects has a method 'z=' we set the z coordinate, otherwise we ignore it */
if ( rb_respond_to(point, idSetZ) ) {
rb_funcall(point, idSetZ, 1, rb_float_new(array_z[0]) );
}
return point;
} else if (result > 0) {
rb_raise(rb_eSystemCallError, "Unknown system call error");
} else {
raise_error(result);
}
return self; /* Makes gcc happy */
}
|
#transform_all(otherProjection, collection) ⇒ Object
Transforms all points in a collection from one projection to another. The collection
object must implement the each
, clear
, and << methods (just like an Array) for this to work.
call-seq: transform_all(destinationProjection, collection) -> collection
311 312 313 314 315 316 317 |
# File 'lib/proj4.rb', line 311 def transform_all(otherProjection, collection) newcollection = collection.dup.clear collection.each do |point| newcollection << transform(otherProjection, point) end newcollection end |
#transform_all!(otherProjection, collection) ⇒ Object
Transforms all points in a collection ‘in place’ from one projection to another. The collection
object must implement the each
method for this to work.
call-seq: transform_all!(destinationProjection, collection) -> collection
298 299 300 301 302 303 |
# File 'lib/proj4.rb', line 298 def transform_all!(otherProjection, collection) collection.each do |point| transform!(otherProjection, point) end collection end |