georuby 2.3.0 → 2.5.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +16 -9
  3. data/Rakefile +13 -14
  4. data/lib/geo_ruby/ewk.rb +2 -0
  5. data/lib/geo_ruby/{simple_features → ewk}/ewkb_parser.rb +206 -218
  6. data/lib/geo_ruby/ewk/ewkt_parser.rb +321 -0
  7. data/lib/geo_ruby/geojson.rb +27 -32
  8. data/lib/geo_ruby/georss.rb +88 -66
  9. data/lib/geo_ruby/gpx.rb +113 -1
  10. data/lib/geo_ruby/kml.rb +43 -31
  11. data/lib/geo_ruby/shp.rb +1 -0
  12. data/lib/geo_ruby/shp4r/dbf.rb +7 -3
  13. data/lib/geo_ruby/shp4r/shp.rb +297 -284
  14. data/lib/geo_ruby/simple_features.rb +2 -6
  15. data/lib/geo_ruby/simple_features/circle.rb +15 -13
  16. data/lib/geo_ruby/simple_features/envelope.rb +84 -77
  17. data/lib/geo_ruby/simple_features/geometry.rb +89 -69
  18. data/lib/geo_ruby/simple_features/geometry_collection.rb +46 -43
  19. data/lib/geo_ruby/simple_features/geometry_factory.rb +50 -47
  20. data/lib/geo_ruby/simple_features/helper.rb +14 -14
  21. data/lib/geo_ruby/simple_features/line_string.rb +94 -97
  22. data/lib/geo_ruby/simple_features/linear_ring.rb +4 -9
  23. data/lib/geo_ruby/simple_features/multi_line_string.rb +18 -21
  24. data/lib/geo_ruby/simple_features/multi_point.rb +18 -20
  25. data/lib/geo_ruby/simple_features/multi_polygon.rb +19 -25
  26. data/lib/geo_ruby/simple_features/point.rb +134 -128
  27. data/lib/geo_ruby/simple_features/polygon.rb +60 -59
  28. data/lib/geo_ruby/version.rb +1 -1
  29. data/spec/data/geojson/feature.json +9 -0
  30. data/spec/data/geojson/feature_collection.json +3 -4
  31. data/spec/geo_ruby/{simple_features → ewk}/ewkb_parser_spec.rb +56 -57
  32. data/spec/geo_ruby/{simple_features → ewk}/ewkt_parser_spec.rb +62 -63
  33. data/spec/geo_ruby/geojson_spec.rb +34 -17
  34. data/spec/geo_ruby/georss_spec.rb +76 -64
  35. data/spec/geo_ruby/{gpx4r/gpx_spec.rb → gpx_spec.rb} +25 -25
  36. data/spec/geo_ruby/kml_spec.rb +40 -36
  37. data/spec/geo_ruby/shp4r/shp_spec.rb +51 -51
  38. data/spec/geo_ruby/simple_features/circle_spec.rb +2 -2
  39. data/spec/geo_ruby/simple_features/envelope_spec.rb +8 -8
  40. data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +26 -26
  41. data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +5 -5
  42. data/spec/geo_ruby/simple_features/geometry_spec.rb +8 -8
  43. data/spec/geo_ruby/simple_features/line_string_spec.rb +102 -102
  44. data/spec/geo_ruby/simple_features/linear_ring_spec.rb +7 -7
  45. data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +20 -20
  46. data/spec/geo_ruby/simple_features/multi_point_spec.rb +16 -16
  47. data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +19 -19
  48. data/spec/geo_ruby/simple_features/point_spec.rb +180 -174
  49. data/spec/geo_ruby/simple_features/polygon_spec.rb +55 -56
  50. data/spec/geo_ruby_spec.rb +4 -4
  51. data/spec/spec_helper.rb +19 -13
  52. metadata +10 -9
  53. data/lib/geo_ruby/gpx4r/gpx.rb +0 -118
  54. data/lib/geo_ruby/simple_features/ewkt_parser.rb +0 -336
@@ -1,15 +1,12 @@
1
1
  require 'geo_ruby/simple_features/line_string'
2
2
 
3
3
  module GeoRuby
4
-
5
4
  module SimpleFeatures
6
-
7
- #Represents a linear ring, which is a closed line string (see LineString).
8
- #Currently, no check is performed to verify if the linear ring is really closed.
5
+ # Represents a linear ring, which is a closed line string (see LineString).
6
+ # Currently, no check is performed to verify if the linear ring is really closed.
9
7
  class LinearRing < LineString
10
-
11
- def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
12
- super(srid,with_z,with_m)
8
+ def initialize(srid = DEFAULT_SRID, with_z = false, with_m = false)
9
+ super(srid, with_z, with_m)
13
10
  end
14
11
 
15
12
  # fix kml export
@@ -33,7 +30,5 @@ module GeoRuby
33
30
  crossings.size % 2 == 1
34
31
  end
35
32
  end
36
-
37
33
  end
38
-
39
34
  end
@@ -1,13 +1,10 @@
1
1
  require 'geo_ruby/simple_features/geometry_collection'
2
2
 
3
3
  module GeoRuby
4
-
5
4
  module SimpleFeatures
6
-
7
- #Represents a group of line strings (see LineString).
5
+ # Represents a group of line strings (see LineString).
8
6
  class MultiLineString < GeometryCollection
9
-
10
- def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
7
+ def initialize(srid = DEFAULT_SRID, _with_z = false, _with_m = false)
11
8
  super(srid)
12
9
  end
13
10
 
@@ -19,39 +16,39 @@ module GeoRuby
19
16
  geometries.map(&:points).flatten
20
17
  end
21
18
 
22
- #Text representation of a multi line string
23
- def text_representation(allow_z=true,allow_m=true) #:nodoc:
24
- @geometries.collect{|line_string| "(" + line_string.text_representation(allow_z,allow_m) + ")" }.join(",")
19
+ # Text representation of a multi line string
20
+ def text_representation(allow_z = true, allow_m = true) #:nodoc:
21
+ @geometries.collect { |line_string| '(' + line_string.text_representation(allow_z, allow_m) + ')' }.join(',')
25
22
  end
26
23
 
27
- #WKT geometry type
24
+ # WKT geometry type
28
25
  def text_geometry_type #:nodoc:
29
- "MULTILINESTRING"
26
+ 'MULTILINESTRING'
30
27
  end
31
28
 
32
- def to_line_string(join = true)
29
+ def to_line_string(_join = true)
33
30
  LineString.from_points(points)
34
31
  end
35
32
 
36
33
  def to_coordinates
37
- geometries.map{|ls| ls.to_coordinates}
34
+ geometries.map(&:to_coordinates)
38
35
  end
39
36
 
40
- def as_json(options = {})
41
- {:type => 'MultiLineString', :coordinates => self.to_coordinates}
37
+ def as_json(_options = {})
38
+ { type: 'MultiLineString', coordinates: to_coordinates }
42
39
  end
43
40
 
44
- #Creates a new multi line string from an array of line strings
45
- def self.from_line_strings(line_strings,srid=DEFAULT_SRID,with_z=false,with_m=false)
46
- multi_line_string = new(srid,with_z,with_m)
41
+ # Creates a new multi line string from an array of line strings
42
+ def self.from_line_strings(line_strings, srid = DEFAULT_SRID, with_z = false, with_m = false)
43
+ multi_line_string = new(srid, with_z, with_m)
47
44
  multi_line_string.concat(line_strings)
48
45
  multi_line_string
49
46
  end
50
47
 
51
- #Creates a new multi line string from sequences of points : (((x,y)...(x,y)),((x,y)...(x,y)))
52
- def self.from_coordinates(point_sequences,srid=DEFAULT_SRID,with_z=false,with_m=false)
53
- multi_line_string = new(srid,with_z,with_m)
54
- multi_line_string.concat(point_sequences.collect {|points| LineString.from_coordinates(points,srid,with_z,with_m) })
48
+ # Creates a new multi line string from sequences of points : (((x,y)...(x,y)),((x,y)...(x,y)))
49
+ def self.from_coordinates(point_sequences, srid = DEFAULT_SRID, with_z = false, with_m = false)
50
+ multi_line_string = new(srid, with_z, with_m)
51
+ multi_line_string.concat(point_sequences.collect { |points| LineString.from_coordinates(points, srid, with_z, with_m) })
55
52
  multi_line_string
56
53
  end
57
54
  end
@@ -2,11 +2,10 @@ require 'geo_ruby/simple_features/geometry_collection'
2
2
 
3
3
  module GeoRuby
4
4
  module SimpleFeatures
5
- #Represents a group of points (see Point).
5
+ # Represents a group of points (see Point).
6
6
  class MultiPoint < GeometryCollection
7
-
8
- def initialize(srid= DEFAULT_SRID,with_z=false,with_m=false)
9
- super(srid,with_z,with_m)
7
+ def initialize(srid = DEFAULT_SRID, with_z = false, with_m = false)
8
+ super(srid, with_z, with_m)
10
9
  end
11
10
 
12
11
  def binary_geometry_type #:nodoc:
@@ -17,38 +16,37 @@ module GeoRuby
17
16
  @geometries
18
17
  end
19
18
 
20
- #Text representation of a MultiPoint
21
- def text_representation(allow_z=true,allow_m=true) #:nodoc:
22
- "(" + @geometries.collect{|point| point.text_representation(allow_z,allow_m)}.join("),(") + ")"
19
+ # Text representation of a MultiPoint
20
+ def text_representation(allow_z = true, allow_m = true) #:nodoc:
21
+ '(' + @geometries.collect { |point| point.text_representation(allow_z, allow_m) }.join('),(') + ')'
23
22
  end
24
23
 
25
- #WKT geoemtry type
24
+ # WKT geoemtry type
26
25
  def text_geometry_type #:nodoc:
27
- "MULTIPOINT"
26
+ 'MULTIPOINT'
28
27
  end
29
28
 
30
29
  def to_coordinates
31
- points.map{|p| p.to_coordinates }
30
+ points.map(&:to_coordinates)
32
31
  end
33
32
 
34
- def as_json(options = {})
35
- {:type => 'MultiPoint', :coordinates => self.to_coordinates}
33
+ def as_json(_options = {})
34
+ { type: 'MultiPoint', coordinates: to_coordinates }
36
35
  end
37
36
 
38
- #Creates a new multi point from an array of points
39
- def self.from_points(points,srid= DEFAULT_SRID,with_z=false,with_m=false)
40
- multi_point= new(srid,with_z,with_m)
37
+ # Creates a new multi point from an array of points
38
+ def self.from_points(points, srid = DEFAULT_SRID, with_z = false, with_m = false)
39
+ multi_point = new(srid, with_z, with_m)
41
40
  multi_point.concat(points)
42
41
  multi_point
43
42
  end
44
43
 
45
- #Creates a new multi point from a list of point coordinates : ((x,y)...(x,y))
46
- def self.from_coordinates(points,srid= DEFAULT_SRID,with_z=false,with_m=false)
47
- multi_point= new(srid,with_z,with_m)
48
- multi_point.concat(points.collect {|point| Point.from_coordinates(point,srid,with_z,with_m)})
44
+ # Creates a new multi point from a list of point coordinates : ((x,y)...(x,y))
45
+ def self.from_coordinates(points, srid = DEFAULT_SRID, with_z = false, with_m = false)
46
+ multi_point = new(srid, with_z, with_m)
47
+ multi_point.concat(points.collect { |point| Point.from_coordinates(point, srid, with_z, with_m) })
49
48
  multi_point
50
49
  end
51
-
52
50
  end
53
51
  end
54
52
  end
@@ -1,13 +1,10 @@
1
1
  require 'geo_ruby/simple_features/geometry_collection'
2
2
 
3
3
  module GeoRuby
4
-
5
4
  module SimpleFeatures
6
-
7
- #Represents a group of polygons (see Polygon).
5
+ # Represents a group of polygons (see Polygon).
8
6
  class MultiPolygon < GeometryCollection
9
-
10
- def initialize(srid = DEFAULT_SRID,with_z=false,with_m=false)
7
+ def initialize(srid = DEFAULT_SRID, _with_z = false, _with_m = false)
11
8
  super(srid)
12
9
  end
13
10
 
@@ -16,46 +13,43 @@ module GeoRuby
16
13
  end
17
14
 
18
15
  def points
19
- @points ||= geometries.inject([]) do |arr, r|
16
+ @points ||= geometries.reduce([]) do |arr, r|
20
17
  arr.concat(r.rings.map(&:points).flatten)
21
18
  end
22
19
  end
23
20
 
24
- #Text representation of a MultiPolygon
25
- def text_representation(allow_z=true,allow_m=true) #:nodoc:
26
- @geometries.map {|polygon| "(" + polygon.text_representation(allow_z,allow_m) + ")"}.join(",")
21
+ # Text representation of a MultiPolygon
22
+ def text_representation(allow_z = true, allow_m = true) #:nodoc:
23
+ @geometries.map { |polygon| '(' + polygon.text_representation(allow_z, allow_m) + ')' }.join(',')
27
24
  end
28
25
 
29
- #WKT geometry type
26
+ # WKT geometry type
30
27
  def text_geometry_type #:nodoc:
31
- "MULTIPOLYGON"
28
+ 'MULTIPOLYGON'
32
29
  end
33
30
 
34
31
  def to_coordinates
35
- geometries.map{|polygon| polygon.to_coordinates}
32
+ geometries.map(&:to_coordinates)
36
33
  end
37
34
 
38
- def as_json(options = {})
39
- {:type => 'MultiPolygon',
40
- :coordinates => self.to_coordinates}
35
+ def as_json(_options = {})
36
+ { type: 'MultiPolygon',
37
+ coordinates: to_coordinates }
41
38
  end
42
39
 
43
- #Creates a multi polygon from an array of polygons
44
- def self.from_polygons(polygons,srid=DEFAULT_SRID,with_z=false,with_m=false)
45
- multi_polygon = new(srid,with_z,with_m)
40
+ # Creates a multi polygon from an array of polygons
41
+ def self.from_polygons(polygons, srid = DEFAULT_SRID, with_z = false, with_m = false)
42
+ multi_polygon = new(srid, with_z, with_m)
46
43
  multi_polygon.concat(polygons)
47
44
  multi_polygon
48
45
  end
49
46
 
50
- #Creates a multi polygon from sequences of points : ((((x,y)...(x,y)),((x,y)...(x,y)),((x,y)...(x,y)))
51
- def self.from_coordinates(point_sequence_sequences,srid= DEFAULT_SRID,with_z=false,with_m=false)
52
- multi_polygon = new(srid,with_z,with_m)
53
- multi_polygon.concat( point_sequence_sequences.collect {|point_sequences| Polygon.from_coordinates(point_sequences,srid,with_z,with_m) } )
47
+ # Creates a multi polygon from sequences of points : ((((x,y)...(x,y)),((x,y)...(x,y)),((x,y)...(x,y)))
48
+ def self.from_coordinates(point_sequence_sequences, srid = DEFAULT_SRID, with_z = false, with_m = false)
49
+ multi_polygon = new(srid, with_z, with_m)
50
+ multi_polygon.concat(point_sequence_sequences.collect { |point_sequences| Polygon.from_coordinates(point_sequences, srid, with_z, with_m) })
54
51
  multi_polygon
55
52
  end
56
-
57
53
  end
58
-
59
54
  end
60
-
61
55
  end
@@ -7,23 +7,23 @@ module GeoRuby
7
7
  class Point < Geometry
8
8
  DEG2RAD = 0.0174532925199433
9
9
  HALFPI = 1.5707963267948966
10
- attr_accessor :x,:y,:z,:m
10
+ attr_accessor :x, :y, :z, :m
11
11
  attr_reader :r, :t # radium and theta
12
12
 
13
13
  # If you prefer calling the coordinates lat and lon
14
14
  # (or lng, for GeoKit compatibility)
15
- alias :lon :x
16
- alias :lng :x
17
- alias :lat :y
18
- alias :rad :r
19
- alias :tet :t
20
- alias :tetha :t
15
+ alias_method :lon, :x
16
+ alias_method :lng, :x
17
+ alias_method :lat, :y
18
+ alias_method :rad, :r
19
+ alias_method :tet, :t
20
+ alias_method :tetha, :t
21
21
 
22
22
  def initialize(srid = DEFAULT_SRID, with_z = false, with_m = false)
23
23
  super(srid, with_z, with_m)
24
24
  @x = @y = 0.0
25
- @z = 0.0 #default value : meaningful if with_z
26
- @m = 0.0 #default value : meaningful if with_m
25
+ @z = 0.0 # default value : meaningful if with_z
26
+ @m = 0.0 # default value : meaningful if with_m
27
27
  end
28
28
 
29
29
  # Sets all coordinates in one call.
@@ -34,7 +34,7 @@ module GeoRuby
34
34
  @z = z && !z.is_a?(Numeric) ? z.to_f : z
35
35
  self
36
36
  end
37
- alias :set_lon_lat_z :set_x_y_z
37
+ alias_method :set_lon_lat_z, :set_x_y_z
38
38
 
39
39
  # Sets all coordinates of a 2D point in one call
40
40
  def set_x_y(x, y)
@@ -42,7 +42,7 @@ module GeoRuby
42
42
  @y = y && !y.is_a?(Numeric) ? y.to_f : y
43
43
  self
44
44
  end
45
- alias :set_lon_lat :set_x_y
45
+ alias_method :set_lon_lat, :set_x_y
46
46
 
47
47
  # Return the distance between the 2D points (ie taking care only
48
48
  # of the x and y coordinates), assuming the points are in
@@ -58,72 +58,79 @@ module GeoRuby
58
58
  # Assumes x is the lon and y the lat, in degrees.
59
59
  # The user has to make sure using this distance makes sense
60
60
  # (ie she should be in latlon coordinates)
61
- def spherical_distance(point, r = 6370997.0)
61
+ def spherical_distance(point, r = 6_370_997.0)
62
62
  dlat = (point.lat - lat) * DEG2RAD / 2
63
63
  dlon = (point.lon - lon) * DEG2RAD / 2
64
64
 
65
65
  a = Math.sin(dlat)**2 + Math.cos(lat * DEG2RAD) *
66
- Math.cos(point.lat * DEG2RAD) * Math.sin(dlon)**2
67
- c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
66
+ Math.cos(point.lat * DEG2RAD) * Math.sin(dlon)**2
67
+ c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
68
68
  r * c
69
69
  end
70
70
 
71
- # Ellipsoidal distance in m using Vincenty's formula. Lifted entirely from Chris Veness's code at http://www.movable-type.co.uk/scripts/LatLongVincenty.html and adapted for Ruby. Assumes the x and y are the lon and lat in degrees.
71
+ #
72
+ # Ellipsoidal distance in m using Vincenty's formula.
73
+ # Lifted entirely from Chris Veness's code at
74
+ # http://www.movable-type.co.uk/scripts/LatLongVincenty.html
75
+ # and adapted for Ruby.
76
+ #
77
+ # Assumes the x and y are the lon and lat in degrees.
72
78
  # a is the semi-major axis (equatorial radius) of the ellipsoid
73
79
  # b is the semi-minor axis (polar radius) of the ellipsoid
74
- # Their values by default are set to the ones of the WGS84 ellipsoid
75
- def ellipsoidal_distance(point, a = 6378137.0, b = 6356752.3142)
80
+ # Their values by default are set to the WGS84 ellipsoid.
81
+ #
82
+ def ellipsoidal_distance(point, a = 6_378_137.0, b = 6_356_752.3142)
76
83
  f = (a - b) / a
77
84
  l = (point.lon - lon) * DEG2RAD
78
85
 
79
- u1 = Math.atan((1-f) * Math.tan(lat * DEG2RAD ))
80
- u2 = Math.atan((1-f) * Math.tan(point.lat * DEG2RAD))
81
- sinU1 = Math.sin(u1)
82
- cosU1 = Math.cos(u1)
83
- sinU2 = Math.sin(u2)
84
- cosU2 = Math.cos(u2)
86
+ u1 = Math.atan((1 - f) * Math.tan(lat * DEG2RAD))
87
+ u2 = Math.atan((1 - f) * Math.tan(point.lat * DEG2RAD))
88
+ sin_u1 = Math.sin(u1)
89
+ cos_u1 = Math.cos(u1)
90
+ sin_u2 = Math.sin(u2)
91
+ cos_u2 = Math.cos(u2)
85
92
 
86
93
  lambda = l
87
- lambdaP = 2 * Math::PI
88
- iterLimit = 20
89
-
90
- while (lambda - lambdaP).abs > 1e-12 && --iterLimit > 0
91
- sinLambda = Math.sin(lambda)
92
- cosLambda = Math.cos(lambda)
93
- sinSigma =\
94
- Math.sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) +
95
- (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) *
96
- (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda))
97
-
98
- return 0 if sinSigma == 0 # coincident points
99
-
100
- cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda
101
- sigma = Math.atan2(sinSigma, cosSigma)
102
- sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma
103
- cosSqAlpha = 1 - sinAlpha * sinAlpha
104
- cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha
105
-
106
- # equatorial line: cosSqAlpha=0
107
- cos2SigmaM = 0 if (cos2SigmaM.nan?)
108
-
109
- c = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha))
110
- lambdaP = lambda
111
- lambda = l + (1 - c) * f * sinAlpha * (sigma + c * sinSigma *
112
- (cos2SigmaM + c * cosSigma * (-1 + 2 * cos2SigmaM *
113
- cos2SigmaM)))
94
+ lambda_p = 2 * Math::PI
95
+ iter_limit = 20
96
+
97
+ while (lambda - lambda_p).abs > 1e-12 && --iter_limit > 0
98
+ sin_lambda = Math.sin(lambda)
99
+ cos_lambda = Math.cos(lambda)
100
+ sin_sigma = \
101
+ Math.sqrt((cos_u2 * sin_lambda) * (cos_u2 * sin_lambda) +
102
+ (cos_u1 * sin_u2 - sin_u1 * cos_u2 * cos_lambda) *
103
+ (cos_u1 * sin_u2 - sin_u1 * cos_u2 * cos_lambda))
104
+
105
+ return 0 if sin_sigma == 0 # coincident points
106
+
107
+ cos_sigma = sin_u1 * sin_u2 + cos_u1 * cos_u2 * cos_lambda
108
+ sigma = Math.atan2(sin_sigma, cos_sigma)
109
+ sin_alpha = cos_u1 * cos_u2 * sin_lambda / sin_sigma
110
+ cos_sq_alpha = 1 - sin_alpha * sin_alpha
111
+ cos2_sigma_m = cos_sigma - 2 * sin_u1 * sin_u2 / cos_sq_alpha
112
+
113
+ # equatorial line: cos_sq_alpha=0
114
+ cos2_sigma_m = 0 if cos2_sigma_m.nan?
115
+
116
+ c = f / 16 * cos_sq_alpha * (4 + f * (4 - 3 * cos_sq_alpha))
117
+ lambda_p = lambda
118
+ lambda = l + (1 - c) * f * sin_alpha * (sigma + c * sin_sigma *
119
+ (cos2_sigma_m + c * cos_sigma * (-1 + 2 * cos2_sigma_m *
120
+ cos2_sigma_m)))
114
121
  end
115
122
 
116
- return NaN if iterLimit==0 #formula failed to converge
123
+ return NaN if iter_limit == 0 # formula failed to converge
117
124
 
118
- uSq = cosSqAlpha * (a*a - b*b) / (b*b)
119
- a_bis = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)))
120
- b_bis = uSq/1024 * (256+uSq*(-128 + uSq * (74 - 47 * uSq)))
121
- deltaSigma = b_bis * sinSigma * (cos2SigmaM + b_bis / 4 *
122
- (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - b_bis / 6 *
123
- cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 *
124
- cos2SigmaM * cos2SigmaM)))
125
+ usq = cos_sq_alpha * (a * a - b * b) / (b * b)
126
+ a_bis = 1 + usq / 16_384 * (4096 + usq * (-768 + usq * (320 - 175 * usq)))
127
+ b_bis = usq / 1024 * (256 + usq * (-128 + usq * (74 - 47 * usq)))
128
+ delta_sigma = b_bis * sin_sigma * (cos2_sigma_m + b_bis / 4 *
129
+ (cos_sigma * (-1 + 2 * cos2_sigma_m * cos2_sigma_m) - b_bis / 6 *
130
+ cos2_sigma_m * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 *
131
+ cos2_sigma_m * cos2_sigma_m)))
125
132
 
126
- b * a_bis * (sigma - deltaSigma)
133
+ b * a_bis * (sigma - delta_sigma)
127
134
  end
128
135
 
129
136
  # Orthogonal Distance
@@ -138,7 +145,7 @@ module GeoRuby
138
145
  return 0.0 if len.zero?
139
146
  res = dot / len
140
147
 
141
- xx, yy =\
148
+ xx, yy = \
142
149
  if res < 0
143
150
  [head.x, head.y]
144
151
  elsif res > 1
@@ -146,16 +153,16 @@ module GeoRuby
146
153
  else
147
154
  [head.x + res * c, head.y + res * d]
148
155
  end
149
- # todo benchmark if worth creating an instance
156
+ # TODO: benchmark if worth creating an instance
150
157
  # euclidian_distance(Point.from_x_y(xx, yy))
151
- Math.sqrt((@x - xx) ** 2 + (@y - yy) ** 2)
158
+ Math.sqrt((@x - xx)**2 + (@y - yy)**2)
152
159
  end
153
160
 
154
161
  # Bearing from a point to another, in degrees.
155
162
  def bearing_to(other)
156
163
  return 0 if self == other
157
- a,b = other.x - self.x, other.y - self.y
158
- res = Math.acos(b / Math.sqrt(a*a+b*b)) / Math::PI * 180;
164
+ a, b = other.x - x, other.y - y
165
+ res = Math.acos(b / Math.sqrt(a * a + b * b)) / Math::PI * 180
159
166
  a < 0 ? 360 - res : res
160
167
  end
161
168
 
@@ -178,37 +185,38 @@ module GeoRuby
178
185
  # Bounding box in 2D/3D. Returns an array of 2 points
179
186
  def bounding_box
180
187
  if with_z
181
- [Point.from_x_y_z(@x,@y,@z),Point.from_x_y_z(@x,@y,@z)]
188
+ [Point.from_x_y_z(@x, @y, @z), Point.from_x_y_z(@x, @y, @z)]
182
189
  else
183
- [Point.from_x_y(@x,@y),Point.from_x_y(@x,@y)]
190
+ [Point.from_x_y(@x, @y), Point.from_x_y(@x, @y)]
184
191
  end
185
192
  end
186
193
 
187
194
  def m_range
188
- [@m,@m]
195
+ [@m, @m]
189
196
  end
190
197
 
191
198
  # Tests the equality of the position of points + m
192
199
  def ==(other)
193
- return false unless other.kind_of?(Point)
200
+ return false unless other.is_a?(Point)
194
201
  @x == other.x && @y == other.y && @z == other.z && @m == other.m
195
202
  end
196
203
 
197
- # Binary representation of a point. It lacks some headers to be a valid EWKB representation.
198
- def binary_representation(allow_z=true,allow_m=true) #:nodoc:
199
- bin_rep = [@x.to_f,@y.to_f].pack('EE')
200
- bin_rep += [@z.to_f].pack('E') if @with_z && allow_z #Default value so no crash
201
- bin_rep += [@m.to_f].pack('E') if @with_m && allow_m #idem
204
+ # Binary representation of a point.
205
+ # It lacks some headers to be a valid EWKB representation.
206
+ def binary_representation(allow_z = true, allow_m = true) #:nodoc:
207
+ bin_rep = [@x.to_f, @y.to_f].pack('EE')
208
+ bin_rep += [@z.to_f].pack('E') if @with_z && allow_z # Default value so no crash
209
+ bin_rep += [@m.to_f].pack('E') if @with_m && allow_m # idem
202
210
  bin_rep
203
211
  end
204
212
 
205
213
  # WKB geometry type of a point
206
- def binary_geometry_type#:nodoc:
214
+ def binary_geometry_type #:nodoc:
207
215
  1
208
216
  end
209
217
 
210
218
  # Text representation of a point
211
- def text_representation(allow_z=true,allow_m=true) #:nodoc:
219
+ def text_representation(allow_z = true, allow_m = true) #:nodoc:
212
220
  tex_rep = "#{@x} #{@y}"
213
221
  tex_rep += " #{@z}" if @with_z && allow_z
214
222
  tex_rep += " #{@m}" if @with_m && allow_m
@@ -222,24 +230,23 @@ module GeoRuby
222
230
 
223
231
  # georss simple representation
224
232
  def georss_simple_representation(options) #:nodoc:
225
- georss_ns = options[:georss_ns] || "georss"
233
+ georss_ns = options[:georss_ns] || 'georss'
226
234
  geom_attr = options[:geom_attr]
227
235
  "<#{georss_ns}:point#{geom_attr}>#{y} #{x}</#{georss_ns}:point>\n"
228
236
  end
229
237
 
230
238
  # georss w3c representation
231
239
  def georss_w3cgeo_representation(options) #:nodoc:
232
- w3cgeo_ns = options[:w3cgeo_ns] || "geo"
240
+ w3cgeo_ns = options[:w3cgeo_ns] || 'geo'
233
241
  "<#{w3cgeo_ns}:lat>#{y}</#{w3cgeo_ns}:lat>\n<#{w3cgeo_ns}:long>#{x}</#{w3cgeo_ns}:long>\n"
234
242
  end
235
243
 
236
244
  # georss gml representation
237
245
  def georss_gml_representation(options) #:nodoc:
238
- georss_ns = options[:georss_ns] || "georss"
239
- gml_ns = options[:gml_ns] || "gml"
240
- out = "<#{georss_ns}:where>\n<#{gml_ns}:Point>\n<#{gml_ns}:pos>"
241
- out += "#{y} #{x}"
242
- out += "</#{gml_ns}:pos>\n</#{gml_ns}:Point>\n</#{georss_ns}:where>\n"
246
+ georss_ns = options[:georss_ns] || 'georss'
247
+ gml_ns = options[:gml_ns] || 'gml'
248
+ "<#{georss_ns}:where>\n<#{gml_ns}:Point>\n<#{gml_ns}:pos>#{y} #{x}" \
249
+ "</#{gml_ns}:pos>\n</#{gml_ns}:Point>\n</#{georss_ns}:where>\n"
243
250
  end
244
251
 
245
252
  # outputs the geometry in kml format : options are
@@ -252,9 +259,9 @@ module GeoRuby
252
259
  out = "<Point#{options[:id_attr]}>\n"
253
260
  out += options[:geom_data] if options[:geom_data]
254
261
  out += "<coordinates>#{x},#{y}"
255
- out += ",#{options[:fixed_z] || z ||0}" if options[:allow_z]
262
+ out += ",#{options[:fixed_z] || z || 0}" if options[:allow_z]
256
263
  out += "</coordinates>\n"
257
- out += "</Point>\n"
264
+ out + "</Point>\n"
258
265
  end
259
266
 
260
267
  def html_representation(options = {})
@@ -262,23 +269,25 @@ module GeoRuby
262
269
  out = '<span class=\'geo\'>'
263
270
  out += "<abbr class='latitude' title='#{x}'>#{as_lat(options)}</abbr>"
264
271
  out += "<abbr class='longitude' title='#{y}'>#{as_long(options)}</abbr>"
265
- out += '</span>'
272
+ out + '</span>'
266
273
  end
267
274
 
268
275
  # Human representation of the geom, don't use directly, use:
269
276
  # #as_lat, #as_long, #as_latlong
270
- def human_representation(options = { }, g = { :x => x, :y => y })
277
+ def human_representation(options = {}, g = { x: x, y: y })
271
278
  g.map do |k, v|
272
279
  deg = v.to_i.abs
273
280
  min = (60 * (v.abs - deg)).to_i
274
281
  labs = (v * 1_000_000).abs / 1_000_000
275
- sec = ((((labs - labs.to_i) * 60) - ((labs - labs.to_i) * 60).to_i) * 100_000) * 60 / 100_000
276
- str = options[:full] ? "%.i°%.2i′%05.2f″" : "%.i°%.2i′%02.0f″"
282
+ sec = ((((labs - labs.to_i) * 60) -
283
+ ((labs - labs.to_i) * 60).to_i) * 100_000) * 60 / 100_000
284
+ str = options[:full] ? '%.i°%.2i′%05.2f″' : '%.i°%.2i′%02.0f″'
277
285
  if options[:coord]
278
- out = str % [deg,min,sec]
279
- out += k == :x ? v > 0 ? 'N' : 'S' : v > 0 ? 'E' : 'W'
286
+ out = format(str, deg, min, sec)
287
+ # Add cardinal
288
+ out + (k == :x ? v > 0 ? 'N' : 'S' : v > 0 ? 'E' : 'W')
280
289
  else
281
- str % [v.to_i, min, sec]
290
+ format(str, v.to_i, min, sec)
282
291
  end
283
292
  end
284
293
  end
@@ -286,22 +295,22 @@ module GeoRuby
286
295
  # Outputs the geometry coordinate in human format:
287
296
  # 47°52′48″N
288
297
  def as_lat(options = {})
289
- human_representation(options, { x: x }).join
298
+ human_representation(options, x: x).join
290
299
  end
291
300
 
292
301
  # Outputs the geometry coordinate in human format:
293
302
  # -20°06′00W″
294
303
  def as_long(options = {})
295
- human_representation(options, { y: y }).join
304
+ human_representation(options, y: y).join
296
305
  end
297
- alias :as_lng :as_long
306
+ alias_method :as_lng, :as_long
298
307
 
299
308
  # Outputs the geometry in coordinates format:
300
309
  # 47°52′48″, -20°06′00″
301
310
  def as_latlong(options = {})
302
311
  human_representation(options).join(', ')
303
312
  end
304
- alias :as_ll :as_latlong
313
+ alias_method :as_ll, :as_latlong
305
314
 
306
315
  # Polar stuff
307
316
  #
@@ -317,8 +326,8 @@ module GeoRuby
317
326
  if @x.zero?
318
327
  @y < 0 ? 3 * HALFPI : HALFPI
319
328
  else
320
- th = Math.atan(@y/@x)
321
- th += 2 * Math::PI if r > 0
329
+ th = Math.atan(@y / @x)
330
+ r > 0 ? th + 2 * Math::PI : th
322
331
  end
323
332
  end
324
333
 
@@ -333,8 +342,8 @@ module GeoRuby
333
342
  end
334
343
 
335
344
  # Outputs the point in json format
336
- def as_json(options = {})
337
- {:type => 'Point', :coordinates => self.to_coordinates }
345
+ def as_json(_options = {})
346
+ { type: 'Point', coordinates: to_coordinates }
338
347
  end
339
348
 
340
349
  # Invert signal of all coordinates
@@ -342,13 +351,12 @@ module GeoRuby
342
351
  set_x_y_z(-@x, -@y, -@z)
343
352
  end
344
353
 
345
- # TODO Perhaps should support with_m analogous to from_coordinates?
354
+ # Helper to get all coordinates as array.
346
355
  def to_coordinates
347
- if with_z
348
- [x, y, z]
349
- else
350
- [x, y]
351
- end
356
+ coord = [x, y]
357
+ coord << z if with_z
358
+ coord << m if with_m
359
+ coord
352
360
  end
353
361
 
354
362
  # Simple helper for 2D maps
@@ -362,12 +370,12 @@ module GeoRuby
362
370
  end
363
371
 
364
372
  # Creates a point from an array of coordinates
365
- def self.from_coordinates(coords, srid = DEFAULT_SRID, with_z = false, with_m = false)
366
- if ! (with_z || with_m)
373
+ def self.from_coordinates(coords, srid = DEFAULT_SRID, z = false, m = false)
374
+ if !(z || m)
367
375
  from_x_y(coords[0], coords[1], srid)
368
- elsif with_z && with_m
376
+ elsif z && m
369
377
  from_x_y_z_m(coords[0], coords[1], coords[2], coords[3], srid)
370
- elsif with_z
378
+ elsif z
371
379
  from_x_y_z(coords[0], coords[1], coords[2], srid)
372
380
  else
373
381
  from_x_y_m(coords[0], coords[1], coords[2], srid)
@@ -413,7 +421,8 @@ module GeoRuby
413
421
  # Creates a point using coordinates like 22`34 23.45N
414
422
  def self.from_latlong(lat, lon, srid = DEFAULT_SRID)
415
423
  p = [lat, lon].map do |l|
416
- sig, deg, min, sec, cen = l.scan(/(-)?(\d{1,2})\D*(\d{2})\D*(\d{2})(\D*(\d{1,3}))?/).flatten
424
+ sig, deg, min, sec, cen = \
425
+ l.scan(/(-)?(\d{1,2})\D*(\d{2})\D*(\d{2})(\D*(\d{1,3}))?/).flatten
417
426
  sig = true if l =~ /W|S/
418
427
  dec = deg.to_i + (min.to_i * 60 + "#{sec}#{cen}".to_f) / 3600
419
428
  sig ? dec * -1 : dec
@@ -422,22 +431,19 @@ module GeoRuby
422
431
  point.set_x_y(p[0], p[1])
423
432
  end
424
433
 
425
- # Aliasing the constructors in case you like lat/lon instead of y/x
434
+ # Aliasing the constructors in case you like lat/lon over y/x
426
435
  class << self
427
- alias :xy :from_x_y
428
- alias :from_xy :from_x_y
429
- alias :xyz :from_x_y_z
430
- alias :from_xyz :from_x_y_z
431
- alias :from_lon_lat_z :from_x_y_z
432
- alias :from_lon_lat :from_x_y
433
- alias :from_lon_lat_z :from_x_y_z
434
- alias :from_lon_lat_m :from_x_y_m
435
- alias :from_lon_lat_z_m :from_x_y_z_m
436
- alias :from_rad_tet :from_r_t
437
- end
438
-
439
- end #Point
440
-
441
- end #SimpleFeatures
442
-
443
- end #GeoRuby
436
+ alias_method :xy, :from_x_y
437
+ alias_method :from_xy, :from_x_y
438
+ alias_method :xyz, :from_x_y_z
439
+ alias_method :from_xyz, :from_x_y_z
440
+ alias_method :from_lon_lat_z, :from_x_y_z
441
+ alias_method :from_lon_lat, :from_x_y
442
+ alias_method :from_lon_lat_z, :from_x_y_z
443
+ alias_method :from_lon_lat_m, :from_x_y_m
444
+ alias_method :from_lon_lat_z_m, :from_x_y_z_m
445
+ alias_method :from_rad_tet, :from_r_t
446
+ end
447
+ end # Point
448
+ end # SimpleFeatures
449
+ end # GeoRuby