Class GeoRuby::SimpleFeatures::Point
In: lib/geo_ruby/simple_features/point.rb
Parent: Geometry

Represents a point. It is in 3D if the Z coordinate is not nil.

Methods

External Aliases

x -> lon
  if you prefer calling the coordinates lat and lon (or lng, for GeoKit compatibility)
x -> lng
y -> lat
from_x_y -> from_lon_lat
from_x_y_z -> from_lon_lat_z
from_x_y_m -> from_lon_lat_m
from_x_y_z_m -> from_lon_lat_z_m

Attributes

m  [RW] 
x  [RW] 
y  [RW] 
z  [RW] 

Public Class methods

creates a point from an array of coordinates

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 188
188:       def self.from_coordinates(coords,srid=DEFAULT_SRID,with_z=false,with_m=false)
189:         if ! (with_z or with_m)
190:           from_x_y(coords[0],coords[1],srid)
191:         elsif with_z and with_m
192:           from_x_y_z_m(coords[0],coords[1],coords[2],coords[3],srid)
193:         elsif with_z
194:           from_x_y_z(coords[0],coords[1],coords[2],srid)
195:         else
196:           from_x_y_m(coords[0],coords[1],coords[2],srid) 
197:         end
198:       end

creates a point from the X and Y coordinates

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 201
201:       def self.from_x_y(x,y,srid=DEFAULT_SRID)
202:         point= new(srid)
203:         point.set_x_y(x,y)
204:       end

creates a point from the X, Y and M coordinates

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 214
214:       def self.from_x_y_m(x,y,m,srid=DEFAULT_SRID)
215:         point= new(srid,false,true)
216:         point.m=m
217:         point.set_x_y(x,y)
218:       end

creates a point from the X, Y and Z coordinates

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 207
207:       def self.from_x_y_z(x,y,z,srid=DEFAULT_SRID)
208:         point= new(srid,true)
209:         point.set_x_y_z(x,y,z)
210:       end

creates a point from the X, Y, Z and M coordinates

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 221
221:       def self.from_x_y_z_m(x,y,z,m,srid=DEFAULT_SRID)
222:         point= new(srid,true,true)
223:         point.m=m
224:         point.set_x_y_z(x,y,z)
225:       end

[Source]

    # File lib/geo_ruby/simple_features/point.rb, line 14
14:       def initialize(srid=DEFAULT_SRID,with_z=false,with_m=false)
15:         super(srid,with_z,with_m)
16:         @x=0.0
17:         @y=0.0
18:         @z=0.0 #default value : meaningful if with_z
19:         @m=0.0 #default value : meaningful if with_m
20:       end

Public Instance methods

tests the equality of the position of points + m

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 123
123:       def ==(other_point)
124:         if other_point.class != self.class
125:           false
126:         else
127:           @x == other_point.x and @y == other_point.y and @z == other_point.z and @m == other_point.m
128:         end
129:       end

Bounding box in 2D/3D. Returns an array of 2 points

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 110
110:       def bounding_box
111:         unless with_z
112:           [Point.from_x_y(@x,@y),Point.from_x_y(@x,@y)]
113:         else
114:           [Point.from_x_y_z(@x,@y,@z),Point.from_x_y_z(@x,@y,@z)]
115:         end
116:       end

Ellipsoidal distance in m using Vincenty’s formula. Lifted entirely from Chris Veness’s code at www.movable-type.co.uk/scripts/LatLongVincenty.html and adapted for Ruby. Assumes the x and y are the lon and lat in degrees. a is the semi-major axis (equatorial radius) of the ellipsoid b is the semi-minor axis (polar radius) of the ellipsoid Their values by default are set to the ones of the WGS84 ellipsoid

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 62
 62:       def ellipsoidal_distance(point, a = 6378137.0, b = 6356752.3142)
 63:         deg_to_rad = 0.0174532925199433
 64:         
 65:         f = (a-b) / a
 66:         l = (point.lon - lon) * deg_to_rad
 67:         
 68:         u1 = Math.atan((1-f) * Math.tan(lat * deg_to_rad ))
 69:         u2 = Math.atan((1-f) * Math.tan(point.lat * deg_to_rad))
 70:         sinU1 = Math.sin(u1)
 71:         cosU1 = Math.cos(u1)
 72:         sinU2 = Math.sin(u2)
 73:         cosU2 = Math.cos(u2)
 74:   
 75:         lambda = l
 76:         lambdaP = 2 * Math::PI
 77:         iterLimit = 20
 78:         
 79:         while (lambda-lambdaP).abs > 1e-12 && --iterLimit>0
 80:           sinLambda = Math.sin(lambda)
 81:           cosLambda = Math.cos(lambda)
 82:           sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) + (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda))
 83:           
 84:           return 0 if sinSigma == 0 #coincident points
 85:           
 86:           cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda
 87:           sigma = Math.atan2(sinSigma, cosSigma)
 88:           sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma
 89:           cosSqAlpha = 1 - sinAlpha*sinAlpha
 90:           cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha
 91:           
 92:           cos2SigmaM = 0 if (cos2SigmaM.nan?) #equatorial line: cosSqAlpha=0
 93: 
 94:           c = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha))
 95:           lambdaP = lambda
 96:           lambda = l + (1-c) * f * sinAlpha * (sigma + c * sinSigma * (cos2SigmaM + c * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM)))
 97:         end
 98:         return NaN if iterLimit==0 #formula failed to converge
 99: 
100:         uSq = cosSqAlpha * (a*a - b*b) / (b*b)
101:         a_bis = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
102:         b_bis = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)))
103:         deltaSigma = b_bis * sinSigma*(cos2SigmaM + b_bis/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)- b_bis/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)))
104:       
105:         b*a_bis*(sigma-deltaSigma)
106:       end

Return the distance between the 2D points (ie taking care only of the x and y coordinates), assuming the points are in projected coordinates. Euclidian distance in whatever unit the x and y ordinates are.

[Source]

    # File lib/geo_ruby/simple_features/point.rb, line 39
39:       def euclidian_distance(point)
40:         Math.sqrt((point.x - x)**2 + (point.y - y)**2)
41:       end

[Source]

     # File lib/geo_ruby/simple_features/point.rb, line 118
118:       def m_range
119:         [@m,@m]
120:       end
set_lon_lat(x,y)

Alias for set_x_y

set_lon_lat_z(x,y,z)

Alias for set_x_y_z

sets all coordinates of a 2D point in one call

[Source]

    # File lib/geo_ruby/simple_features/point.rb, line 31
31:       def set_x_y(x,y)
32:         @x=x
33:         @y=y
34:         self
35:       end

sets all coordinates in one call. Use the m accessor to set the m.

[Source]

    # File lib/geo_ruby/simple_features/point.rb, line 22
22:       def set_x_y_z(x,y,z)
23:         @x=x
24:         @y=y
25:         @z=z
26:         self
27:       end

Returns the sperical distance in m, with a radius of 6471000m, with the haversine law. Assumes x is the lon and y the lat, in degrees (Changed in version 1.1). The user has to make sure using this distance makes sense (ie she should be in latlon coordinates)

[Source]

    # File lib/geo_ruby/simple_features/point.rb, line 44
44:       def spherical_distance(point,radius=6370997.0)
45:         deg_to_rad = 0.0174532925199433
46:         
47:         radlat_from = lat * deg_to_rad
48:         radlat_to = point.lat * deg_to_rad
49:         
50:         dlat = (point.lat - lat) * deg_to_rad
51:         dlon = (point.lon - lon) * deg_to_rad
52:  
53:         a = Math.sin(dlat/2)**2 + Math.cos(radlat_from) * Math.cos(radlat_to) * Math.sin(dlon/2)**2
54:         c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
55:         radius * c
56:       end

[Validate]