georuby 2.3.0 → 2.5.1

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.
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