nofxx-georuby 1.7.1 → 1.7.3

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/Rakefile CHANGED
@@ -9,28 +9,27 @@ begin
9
9
  gem.description = "GeoRuby provides geometric data types from the OGC 'Simple Features' specification."
10
10
  gem.email = "x@nofxx.com"
11
11
  gem.homepage = "http://github.com/nofxx/georuby"
12
- gem.authors = ["Guilhem Vellut", "Marcos Augusto"]
13
-
14
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
12
+ gem.authors = ["Guilhem Vellut", "Marcos Piccinini"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ gem.add_development_dependency "dbf", ">= 1.1.2"
15
15
  end
16
16
  rescue LoadError
17
17
  puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
18
18
  end
19
19
 
20
- require 'spec/rake/spectask'
21
- Spec::Rake::SpecTask.new(:spec) do |spec|
22
- spec.libs << 'lib' << 'spec'
23
- spec.spec_files = FileList['spec/**/*_spec.rb']
24
- end
25
-
26
- Spec::Rake::SpecTask.new(:rcov) do |spec|
27
- spec.libs << 'lib' << 'spec'
28
- spec.pattern = 'spec/**/*_spec.rb'
29
- spec.rcov = true
30
- end
20
+ # require 'spec/rake/spectask'
21
+ # Spec::Rake::SpecTask.new(:spec) do |spec|
22
+ # spec.libs << 'lib' << 'spec'
23
+ # spec.spec_files = FileList['spec/**/*_spec.rb']
24
+ # end
31
25
 
26
+ # Spec::Rake::SpecTask.new(:rcov) do |spec|
27
+ # spec.libs << 'lib' << 'spec'
28
+ # spec.pattern = 'spec/**/*_spec.rb'
29
+ # spec.rcov = true
30
+ # end
32
31
 
33
- task :default => :spec
32
+ # task :default => :spec
34
33
 
35
34
  require 'rake/rdoctask'
36
35
  Rake::RDocTask.new do |rdoc|
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.7.1
1
+ 1.7.3
@@ -31,7 +31,7 @@ module GeoRuby
31
31
  gpxfile = GpxFile.new(file, *opts)
32
32
  if block_given?
33
33
  yield gpxfile
34
- gpxfile.close
34
+ # gpxfile.close
35
35
  else
36
36
  gpxfile
37
37
  end
@@ -67,7 +67,7 @@ module GeoRuby
67
67
 
68
68
  # Return the GPX file as LineString
69
69
  def as_line_string
70
- LineString.from_points(@points)
70
+ GeoRuby::SimpleFeatures::LineString.from_points(@points)
71
71
  end
72
72
  alias :as_polyline :as_line_string
73
73
 
@@ -75,7 +75,7 @@ module GeoRuby
75
75
  # If the GPX isn't closed, a line from the first
76
76
  # to the last point will be created to close it.
77
77
  def as_polygon
78
- Polygon.from_points([@points[0] == @points[-1] ? @points : @points.push(@points[0].clone)])
78
+ GeoRuby::SimpleFeatures::Polygon.from_points([@points[0] == @points[-1] ? @points : @points.push(@points[0].clone)])
79
79
  end
80
80
 
81
81
  # Return GPX Envelope
@@ -94,14 +94,15 @@ module GeoRuby
94
94
  # trk(pt) => track /
95
95
  def parse_file(with_z, with_m)
96
96
  data = @gpx.read
97
- @file_mode = data =~ /trkpt/ ? "//trkpt" : "//rtept"
97
+ @file_mode = data =~ /trkpt/ ? "//trkpt" : (data =~ /wpt/ ? "//wpt" : "//rtept")
98
98
  Nokogiri.HTML(data).search(@file_mode).each do |tp|
99
- z = z.inner_text.to_i if with_z && z = tp.at("ele")
99
+ z = z.inner_text.to_f if with_z && z = tp.at("ele")
100
100
  m = m.inner_text if with_m && m = tp.at("time")
101
- @points << Point.from_coordinates([tp["lon"].to_f, tp["lat"].to_f, z, m],nil,with_z, with_m)
101
+ @points << GeoRuby::SimpleFeatures::Point.from_coordinates([tp["lon"].to_f, tp["lat"].to_f, z, m],4326,with_z, with_m)
102
102
  end
103
103
  close
104
104
  @record_count = @points.length
105
+ self.envelope
105
106
  rescue => e
106
107
  raise MalformedGpxException.new("Bad GPX. Error: #{e}")
107
108
  # trackpoint.at("gpxdata:hr").nil? # heartrate
@@ -4,7 +4,8 @@ require 'rubygems'
4
4
  begin
5
5
  require 'dbf'
6
6
  rescue LoadError
7
- puts "Unable to find gem 'dbf'. Please install."
7
+ puts "You've loaded GeoRuby SHP Support."
8
+ puts "Please install the gem 'dbf' to use it. `gem install dbf`"
8
9
  end
9
10
 
10
11
  module GeoRuby
@@ -166,6 +166,28 @@ module GeoRuby
166
166
  pos_list.join(" ")
167
167
  end
168
168
 
169
+ # Simplify linestring (Douglas Peucker Algorithm)
170
+ # http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
171
+ def simplify(epsilon=1)
172
+ LineString.from_points(do_simplify(@points, epsilon))
173
+ end
174
+
175
+ def do_simplify(list, epsilon)
176
+ index = dmax = 0
177
+ 2.upto(list.length - 1) do |i|
178
+ d = list[i].orthogonal_distance(list[0], list[-1])
179
+ index, dmax = i, d if d > dmax
180
+ end
181
+
182
+ if dmax >= epsilon
183
+ res1 = do_simplify(list[0..index], epsilon)
184
+ res2 = do_simplify(list[index..-1], epsilon)
185
+ res1[0..-2] + res2[0..-1]
186
+ else
187
+ [list[0], list[-1]]
188
+ end
189
+ end
190
+
169
191
  #Creates a new line string. Accept an array of points as argument
170
192
  def self.from_points(points,srid=DEFAULT_SRID,with_z=false,with_m=false)
171
193
  line_string = new(srid,with_z,with_m)
@@ -6,6 +6,7 @@ module GeoRuby
6
6
  #Represents a point. It is in 3D if the Z coordinate is not +nil+.
7
7
  class Point < Geometry
8
8
  DEG2RAD = 0.0174532925199433
9
+ HALFPI = 1.5707963267948966
9
10
  attr_accessor :x,:y,:z,:m
10
11
  attr_reader :r, :t # radium and theta
11
12
 
@@ -46,16 +47,15 @@ module GeoRuby
46
47
  Math.sqrt((point.x - x)**2 + (point.y - y)**2)
47
48
  end
48
49
 
49
- #Returns the sperical distance in meters, with a radius of 6471000m, with the haversine law.
50
- #Assumes x is the lon and y the lat, in degrees (Changed in version 1.1).
51
- #The user has to make sure using this distance makes sense (ie she should be in latlon coordinates)
50
+ # Spherical distance in meters, using 'Haversine' formula.
51
+ # with a radius of 6471000m
52
+ # Assumes x is the lon and y the lat, in degrees (Changed in version 1.1).
53
+ # The user has to make sure using this distance makes sense (ie she should be in latlon coordinates)
52
54
  def spherical_distance(point,r=6370997.0)
53
- radlat_from = lat * DEG2RAD
54
- radlat_to = point.lat * DEG2RAD
55
55
  dlat = (point.lat - lat) * DEG2RAD / 2
56
56
  dlon = (point.lon - lon) * DEG2RAD / 2
57
57
 
58
- a = Math.sin(dlat)**2 + Math.cos(radlat_from) * Math.cos(radlat_to) * Math.sin(dlon)**2
58
+ a = Math.sin(dlat)**2 + Math.cos(lat * DEG2RAD) * Math.cos(point.lat * DEG2RAD) * Math.sin(dlon)**2
59
59
  c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
60
60
  r * c
61
61
  end
@@ -108,6 +108,29 @@ module GeoRuby
108
108
  b*a_bis*(sigma-deltaSigma)
109
109
  end
110
110
 
111
+ # Orthogonal Distance
112
+ # Based http://www.allegro.cc/forums/thread/589720
113
+ def orthogonal_distance(line, tail = nil)
114
+ head, tail = tail ? [line, tail] : [line[0], line[-1]]
115
+ a, b = @x - head.x, @y - head.y
116
+ c, d = tail.x - head.x, tail.y - head.y
117
+
118
+ dot = a * c + b * d
119
+ len = c * c + d * d
120
+ res = dot / len
121
+
122
+ xx, yy = if res < 0
123
+ [head.x, head.y]
124
+ elsif res > 1
125
+ [tail.x, tail.y]
126
+ else
127
+ [head.x + res * c, head.y + res * d]
128
+ end
129
+ # todo benchmark if worth creating an instance
130
+ # euclidian_distance(Point.from_x_y(xx, yy))
131
+ Math.sqrt((@x - xx) ** 2 + (@y - yy) ** 2)
132
+ end
133
+
111
134
  #Bearing from a point to another, in degrees.
112
135
  def bearing_to(other)
113
136
  return 0 if self == other
@@ -146,21 +169,19 @@ module GeoRuby
146
169
  end
147
170
 
148
171
  #tests the equality of the position of points + m
149
- def ==(other_point)
150
- if other_point.class != self.class
151
- false
152
- else
153
- @x == other_point.x and @y == other_point.y and @z == other_point.z and @m == other_point.m
154
- end
172
+ def ==(other)
173
+ return false unless other.kind_of?(Point)
174
+ @x == other.x and @y == other.y and @z == other.z and @m == other.m
155
175
  end
156
176
 
157
177
  #binary representation of a point. It lacks some headers to be a valid EWKB representation.
158
178
  def binary_representation(allow_z=true,allow_m=true) #:nodoc:
159
- bin_rep = [@x,@y].pack("EE")
160
- bin_rep += [@z].pack("E") if @with_z and allow_z #Default value so no crash
161
- bin_rep += [@m].pack("E") if @with_m and allow_m #idem
179
+ bin_rep = [@x.to_f,@y.to_f].pack("EE")
180
+ bin_rep += [@z.to_f].pack("E") if @with_z and allow_z #Default value so no crash
181
+ bin_rep += [@m.to_f].pack("E") if @with_m and allow_m #idem
162
182
  bin_rep
163
183
  end
184
+
164
185
  #WKB geometry type of a point
165
186
  def binary_geometry_type#:nodoc:
166
187
  1
@@ -173,6 +194,7 @@ module GeoRuby
173
194
  tex_rep += " #{@m}" if @with_m and allow_m
174
195
  tex_rep
175
196
  end
197
+
176
198
  #WKT geometry type of a point
177
199
  def text_geometry_type #:nodoc:
178
200
  "POINT"
@@ -184,11 +206,13 @@ module GeoRuby
184
206
  geom_attr = options[:geom_attr]
185
207
  "<#{georss_ns}:point#{geom_attr}>#{y} #{x}</#{georss_ns}:point>\n"
186
208
  end
209
+
187
210
  #georss w3c representation
188
211
  def georss_w3cgeo_representation(options) #:nodoc:
189
212
  w3cgeo_ns = options[:w3cgeo_ns] || "geo"
190
213
  "<#{w3cgeo_ns}:lat>#{y}</#{w3cgeo_ns}:lat>\n<#{w3cgeo_ns}:long>#{x}</#{w3cgeo_ns}:long>\n"
191
214
  end
215
+
192
216
  #georss gml representation
193
217
  def georss_gml_representation(options) #:nodoc:
194
218
  georss_ns = options[:georss_ns] || "georss"
@@ -235,29 +259,32 @@ module GeoRuby
235
259
  val.join(", ")
236
260
  end
237
261
 
238
- #Polar stuff
239
- #http://www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html
240
- #http://rcoordinate.rubyforge.org/svn/point.rb
262
+ # Polar stuff
263
+ #
264
+ # http://www.engineeringtoolbox.com/converting-cartesian-polar-coordinates-d_1347.html
265
+ # http://rcoordinate.rubyforge.org/svn/point.rb
241
266
  # outputs radium
242
- def r; Math.sqrt(x**2 + y**2); end
267
+ def r; Math.sqrt(@x**2 + @y**2); end
243
268
 
244
- #outputs theta
269
+ # outputs theta
245
270
  def theta_rad
246
271
  if @x.zero?
247
- @y < 0 ? 3 * Math::PI / 2 : Math::PI / 2
272
+ @y < 0 ? 3 * HALFPI : HALFPI
248
273
  else
249
274
  th = Math.atan(@y/@x)
250
275
  th += 2 * Math::PI if r > 0
251
276
  end
252
277
  end
253
278
 
254
- def theta_deg
255
- theta_rad / DEG2RAD
256
- end
279
+ # outputs theta in degrees
280
+ def theta_deg; theta_rad / DEG2RAD; end
281
+
282
+ # outputs an array containing polar distance and theta
283
+ def as_polar; [r,t]; end
257
284
 
258
- #outputs an array containing polar distance and theta
259
- def as_polar
260
- [r,t]
285
+ # invert signal of all coordinates
286
+ def -@
287
+ set_x_y_z(-@x, -@y, -@z)
261
288
  end
262
289
 
263
290
  #creates a point from an array of coordinates
@@ -323,11 +350,14 @@ module GeoRuby
323
350
 
324
351
  #aliasing the constructors in case you want to use lat/lon instead of y/x
325
352
  class << self
326
- alias :from_lon_lat :from_x_y
327
- alias :from_lon_lat_z :from_x_y_z
328
- alias :from_lon_lat_m :from_x_y_m
353
+ alias :xy :from_x_y
354
+ alias :xyz :from_x_y_z
355
+ alias :from_lon_lat_z :from_x_y_z
356
+ alias :from_lon_lat :from_x_y
357
+ alias :from_lon_lat_z :from_x_y_z
358
+ alias :from_lon_lat_m :from_x_y_m
329
359
  alias :from_lon_lat_z_m :from_x_y_z_m
330
- alias :from_rad_tet :from_r_t
360
+ alias :from_rad_tet :from_r_t
331
361
  end
332
362
  end
333
363
  end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{nofxx-georuby}
8
- s.version = "1.7.1"
8
+ s.version = "1.7.3"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Guilhem Vellut", "Marcos Augusto"]
12
- s.date = %q{2010-01-28}
11
+ s.authors = ["Guilhem Vellut", "Marcos Piccinini"]
12
+ s.date = %q{2010-09-20}
13
13
  s.description = %q{GeoRuby provides geometric data types from the OGC 'Simple Features' specification.}
14
14
  s.email = %q{x@nofxx.com}
15
15
  s.extra_rdoc_files = [
@@ -85,43 +85,48 @@ Gem::Specification.new do |s|
85
85
  "spec/geo_ruby/simple_features/point_spec.rb",
86
86
  "spec/geo_ruby/simple_features/polygon_spec.rb",
87
87
  "spec/geo_ruby_spec.rb",
88
- "spec/spec.opts",
89
88
  "spec/spec_helper.rb"
90
89
  ]
91
90
  s.homepage = %q{http://github.com/nofxx/georuby}
92
91
  s.rdoc_options = ["--charset=UTF-8"]
93
92
  s.require_paths = ["lib"]
94
- s.rubygems_version = %q{1.3.5}
93
+ s.rubygems_version = %q{1.3.7}
95
94
  s.summary = %q{Ruby data holder for OGC Simple Features}
96
95
  s.test_files = [
97
- "spec/geo_ruby/gpx4r/gpx_spec.rb",
96
+ "spec/geo_ruby_spec.rb",
97
+ "spec/spec_helper.rb",
98
+ "spec/geo_ruby/gpx4r/gpx_spec.rb",
98
99
  "spec/geo_ruby/shp4r/shp_spec.rb",
99
- "spec/geo_ruby/simple_features/envelope_spec.rb",
100
- "spec/geo_ruby/simple_features/ewkb_parser_spec.rb",
101
- "spec/geo_ruby/simple_features/ewkt_parser_spec.rb",
102
- "spec/geo_ruby/simple_features/geometry_collection_spec.rb",
100
+ "spec/geo_ruby/simple_features/point_spec.rb",
103
101
  "spec/geo_ruby/simple_features/geometry_factory_spec.rb",
104
- "spec/geo_ruby/simple_features/geometry_spec.rb",
105
- "spec/geo_ruby/simple_features/georss_parser_spec.rb",
102
+ "spec/geo_ruby/simple_features/envelope_spec.rb",
103
+ "spec/geo_ruby/simple_features/polygon_spec.rb",
106
104
  "spec/geo_ruby/simple_features/line_string_spec.rb",
107
- "spec/geo_ruby/simple_features/linear_ring_spec.rb",
108
105
  "spec/geo_ruby/simple_features/multi_line_string_spec.rb",
109
- "spec/geo_ruby/simple_features/multi_point_spec.rb",
106
+ "spec/geo_ruby/simple_features/ewkt_parser_spec.rb",
107
+ "spec/geo_ruby/simple_features/ewkb_parser_spec.rb",
108
+ "spec/geo_ruby/simple_features/linear_ring_spec.rb",
109
+ "spec/geo_ruby/simple_features/geometry_collection_spec.rb",
110
110
  "spec/geo_ruby/simple_features/multi_polygon_spec.rb",
111
- "spec/geo_ruby/simple_features/point_spec.rb",
112
- "spec/geo_ruby/simple_features/polygon_spec.rb",
113
- "spec/geo_ruby_spec.rb",
114
- "spec/spec_helper.rb"
111
+ "spec/geo_ruby/simple_features/multi_point_spec.rb",
112
+ "spec/geo_ruby/simple_features/georss_parser_spec.rb",
113
+ "spec/geo_ruby/simple_features/geometry_spec.rb"
115
114
  ]
116
115
 
117
116
  if s.respond_to? :specification_version then
118
117
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
119
118
  s.specification_version = 3
120
119
 
121
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
120
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
121
+ s.add_development_dependency(%q<rspec>, [">= 1.2.9"])
122
+ s.add_development_dependency(%q<dbf>, [">= 1.1.2"])
122
123
  else
124
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
125
+ s.add_dependency(%q<dbf>, [">= 1.1.2"])
123
126
  end
124
127
  else
128
+ s.add_dependency(%q<rspec>, [">= 1.2.9"])
129
+ s.add_dependency(%q<dbf>, [">= 1.1.2"])
125
130
  end
126
131
  end
127
132
 
@@ -25,7 +25,7 @@ describe Gpx4r do
25
25
  end
26
26
 
27
27
  it "should open and parse no trkpt one" do
28
- @gpxfile2.record_count.should eql(46)
28
+ @gpxfile2.record_count.should eql(86)
29
29
  end
30
30
 
31
31
  it "should open and parse 3" do
@@ -38,18 +38,18 @@ describe Gpx4r do
38
38
  end
39
39
 
40
40
  it "should read Z and M" do
41
- @gpxfile[0].z.should eql(468)
41
+ @gpxfile[0].z.should eql(468.0)
42
42
  @gpxfile[0].m.should eql("2008-09-07T17:36:57Z")
43
43
  end
44
44
 
45
45
  it "should read X and Y 2" do
46
- @gpxfile2[0].x.should be_close(-71.107628, 0.0001)
47
- @gpxfile2[0].y.should be_close(42.43095, 0.0001)
46
+ @gpxfile2[0].x.should be_close(-71.119277, 0.0001)
47
+ @gpxfile2[0].y.should be_close(42.438878, 0.0001)
48
48
  end
49
49
 
50
50
  it "should read Z and M 2" do
51
- @gpxfile2[0].z.should eql(23)
52
- @gpxfile2[0].m.should eql("2001-06-02T00:18:15Z")
51
+ @gpxfile2[0].z.should eql(44.586548)
52
+ @gpxfile2[0].m.should eql("2001-11-28T21:05:28Z")
53
53
  end
54
54
 
55
55
  it "should read X and Y 3" do
@@ -58,7 +58,7 @@ describe Gpx4r do
58
58
  end
59
59
 
60
60
  it "should read Z and M 3" do
61
- @gpxfile3[0].z.should eql(88)
61
+ @gpxfile3[0].z.should eql(88.5787354)
62
62
  @gpxfile3[0].m.should eql(0.0)
63
63
  end
64
64
 
@@ -45,18 +45,18 @@ describe GeorssParser do
45
45
  end
46
46
 
47
47
  it "test_envelope" do
48
- linear_ring1 = LinearRing.from_coordinates([[12.4,-45.3,5],[45.4,41.6,6],[4.456,1.0698,8],[12.4,-45.3,3.5]],256,true)
49
- linear_ring2 = LinearRing.from_coordinates([[2.4,5.3,9.0],[5.4,1.4263,-5.4],[14.46,1.06,34],[2.4,5.3,3.14]],256,true)
48
+ linear_ring1 = LinearRing.from_coordinates([[12,-45,5],[45,41,6],[4,1,8],[12.4,-45,3]],256,true)
49
+ linear_ring2 = LinearRing.from_coordinates([[2,5,9],[5.4,1,-5.4],[14,1,34],[2,5,3]],256,true)
50
50
  polygon = Polygon.from_linear_rings([linear_ring1,linear_ring2],256,true)
51
51
 
52
52
  e = polygon.envelope
53
53
 
54
- e.as_georss(:dialect => :simple).gsub("\n","").should eql("<georss:box>-45.3 4.456 41.6 45.4</georss:box>")
54
+ e.as_georss(:dialect => :simple).gsub("\n","").should eql("<georss:box>-45 4 41 45</georss:box>")
55
55
  #center
56
- e.as_georss(:dialect => :w3cgeo).gsub("\n","").should eql("<geo:lat>-1.85</geo:lat><geo:long>24.928</geo:long>")
57
- e.as_georss(:dialect => :gml).gsub("\n","").should eql("<georss:where><gml:Envelope><gml:LowerCorner>-45.3 4.456</gml:LowerCorner><gml:UpperCorner>41.6 45.4</gml:UpperCorner></gml:Envelope></georss:where>")
56
+ e.as_georss(:dialect => :w3cgeo).gsub("\n","").should eql("<geo:lat>-2</geo:lat><geo:long>24</geo:long>")
57
+ e.as_georss(:dialect => :gml).gsub("\n","").should eql("<georss:where><gml:Envelope><gml:LowerCorner>-45 4</gml:LowerCorner><gml:UpperCorner>41 45</gml:UpperCorner></gml:Envelope></georss:where>")
58
58
 
59
- e.as_kml.gsub("\n","").should eql("<LatLonAltBox><north>41.6</north><south>-45.3</south><east>45.4</east><west>4.456</west><minAltitude>-5.4</minAltitude><maxAltitude>34</maxAltitude></LatLonAltBox>")
59
+ e.as_kml.gsub("\n","").should eql("<LatLonAltBox><north>41</north><south>-45</south><east>45</east><west>4</west><minAltitude>-5.4</minAltitude><maxAltitude>34</maxAltitude></LatLonAltBox>")
60
60
  end
61
61
 
62
62
  it "test_point_georss_read" do
@@ -205,4 +205,41 @@ describe LineString do
205
205
  @line.euclidian_distance.should eql(20)
206
206
  end
207
207
  end
208
+
209
+ describe "Simplify" do
210
+
211
+ before do
212
+ @line = LineString.from_coordinates([[6,0],[4,1],[3,4],[4,6],[5,8],[5,9],[4,10],[6,15]], 4326)
213
+ end
214
+
215
+ it "should simplify a simple linestring" do
216
+ line = LineString.from_coordinates([[12,15],[14,17],[17, 20]], 4326)
217
+ line.simplify.should have(2).points
218
+ end
219
+
220
+ it "should simplify a harder linestring" do
221
+ @line.simplify(6).should have(6).points
222
+ @line.simplify(9).should have(4).points
223
+ @line.simplify(10).should have(3).points
224
+ end
225
+
226
+ it "should barely touch it" do
227
+ @line.simplify(1).should have(7).points
228
+ end
229
+
230
+ it "should simplify to five points" do
231
+ @line.simplify(7).should have(5).points
232
+ end
233
+
234
+ it "should flatten it" do
235
+ @line.simplify(11).should have(2).points
236
+ end
237
+
238
+ it "should be the first and last in a flatten" do
239
+ line = @line.simplify(11)
240
+ line[0].should be_a_point(6, 0)
241
+ line[1].should be_a_point(6, 15)
242
+ end
243
+
244
+ end
208
245
  end
@@ -11,6 +11,22 @@ describe Point do
11
11
  @point.should be_instance_of(Point)
12
12
  end
13
13
 
14
+ it "should have a nice matcher" do
15
+ @point.should be_a_point
16
+ end
17
+
18
+ it "should have a very nice matcher" do
19
+ @point.should be_a_point(0.0, 0.0)
20
+ end
21
+
22
+ it "should have a very nice matcher" do
23
+ Point.from_x_y_z_m(1,2,3.33,"t").should be_a_point(1, 2, 3.33, "t")
24
+ end
25
+
26
+ it "should have a dumb matcher" do
27
+ Point.should be_geometric
28
+ end
29
+
14
30
  it "should be subclassable" do
15
31
  place = Class.new(Point)
16
32
  p = place.from_x_y(1,2)
@@ -207,6 +223,34 @@ describe Point do
207
223
  should be_close(156876.149400742, 0.00000001)
208
224
  end
209
225
 
226
+ describe "Orthogonal Distance" do
227
+ before do
228
+ @line = LineString.from_coordinates([[0,0],[1,3]], 4326)
229
+ @line2 = LineString.from_coordinates([[1,1],[1,2]], 4326)
230
+ end
231
+
232
+ it "should calcula orthogonal distance from a line (90 deg)" do
233
+ @p1.orthogonal_distance(@line).should be_close(1.414, 0.001)
234
+ end
235
+
236
+ it "should calcula orthogonal distance very close..." do
237
+ @p1.orthogonal_distance(@line2).should be_zero
238
+ end
239
+
240
+ it "should calcula orthogonal distance from a line (90 deg)" do
241
+ @p2.orthogonal_distance(@line).should be_close(2.828, 0.001)
242
+ end
243
+
244
+ it "should calcula orthogonal distance from a line (0 deg)" do
245
+ @p2.orthogonal_distance(@line2).should be_close(1.0, 0.1)
246
+ end
247
+
248
+ it "should calcula orthogonal distance from a line (0 deg)" do
249
+ @p2.orthogonal_distance(@line2).should be_close(1.0, 0.1)
250
+ end
251
+
252
+ end
253
+
210
254
  it "should calculate the bearing from apoint to another in degrees" do
211
255
  @p1.bearing_to(@p2).should be_close(45.0, 0.01)
212
256
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,8 @@
1
1
  begin
2
- require 'spec'
3
- rescue LoadError
4
2
  require 'rubygems'
5
- gem 'rspec'
6
3
  require 'spec'
4
+ rescue LoadError
5
+ require 'rspec'
7
6
  end
8
7
 
9
8
  $:.unshift(File.dirname(__FILE__) + '/../lib')
@@ -13,3 +12,53 @@ require 'geo_ruby/gpx'
13
12
 
14
13
  include GeoRuby
15
14
  include SimpleFeatures
15
+
16
+ module GeorubyMatchers
17
+
18
+ class BeGeometric
19
+
20
+ def matches?(actual)
21
+ actual.ancestors.include?(actual) || actual.kind_of?("Geometry")
22
+ end
23
+
24
+ def failure_message; "expected #{@actual.inspect} to be some geom"; end
25
+ end
26
+
27
+ class BeAPoint
28
+ include RSpec::Matchers
29
+
30
+ def initialize(expect=nil)
31
+ @expect = expect
32
+ end
33
+
34
+ def matches?(actual)
35
+ if @expect
36
+ [:x, :y, :z, :m].each_with_index do |c, i|
37
+ next unless val = @expect[i]
38
+ if val.kind_of? Numeric
39
+ actual.send(c).should be_close(val, 0.1)
40
+ else
41
+ actual.send(c).should eql(val)
42
+ end
43
+ end
44
+ end
45
+ actual.should be_instance_of(Point)
46
+ end
47
+
48
+ def failure_message; "expected #{@expect} but received #{@actual.inspect}"; end
49
+ def negative_failure_message; "expected something else then '#{@expect}' but got '#{@actual}'"; end
50
+ end
51
+
52
+ def be_a_point(*args)
53
+ args.empty? ? BeAPoint.new : BeAPoint.new(args)
54
+ end
55
+
56
+ def be_geometric
57
+ BeGeometric.new
58
+ end
59
+ end
60
+
61
+ RSpec.configure do |config|
62
+ config.include GeorubyMatchers
63
+ end
64
+
metadata CHANGED
@@ -1,19 +1,53 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nofxx-georuby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 7
8
+ - 3
9
+ version: 1.7.3
5
10
  platform: ruby
6
11
  authors:
7
12
  - Guilhem Vellut
8
- - Marcos Augusto
13
+ - Marcos Piccinini
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
17
 
13
- date: 2010-01-28 00:00:00 -02:00
18
+ date: 2010-09-20 00:00:00 -03:00
14
19
  default_executable:
15
- dependencies: []
16
-
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rspec
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ segments:
30
+ - 1
31
+ - 2
32
+ - 9
33
+ version: 1.2.9
34
+ type: :development
35
+ version_requirements: *id001
36
+ - !ruby/object:Gem::Dependency
37
+ name: dbf
38
+ prerelease: false
39
+ requirement: &id002 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ segments:
45
+ - 1
46
+ - 1
47
+ - 2
48
+ version: 1.1.2
49
+ type: :development
50
+ version_requirements: *id002
17
51
  description: GeoRuby provides geometric data types from the OGC 'Simple Features' specification.
18
52
  email: x@nofxx.com
19
53
  executables: []
@@ -92,7 +126,6 @@ files:
92
126
  - spec/geo_ruby/simple_features/point_spec.rb
93
127
  - spec/geo_ruby/simple_features/polygon_spec.rb
94
128
  - spec/geo_ruby_spec.rb
95
- - spec/spec.opts
96
129
  - spec/spec_helper.rb
97
130
  has_rdoc: true
98
131
  homepage: http://github.com/nofxx/georuby
@@ -104,40 +137,44 @@ rdoc_options:
104
137
  require_paths:
105
138
  - lib
106
139
  required_ruby_version: !ruby/object:Gem::Requirement
140
+ none: false
107
141
  requirements:
108
142
  - - ">="
109
143
  - !ruby/object:Gem::Version
144
+ segments:
145
+ - 0
110
146
  version: "0"
111
- version:
112
147
  required_rubygems_version: !ruby/object:Gem::Requirement
148
+ none: false
113
149
  requirements:
114
150
  - - ">="
115
151
  - !ruby/object:Gem::Version
152
+ segments:
153
+ - 0
116
154
  version: "0"
117
- version:
118
155
  requirements: []
119
156
 
120
157
  rubyforge_project:
121
- rubygems_version: 1.3.5
158
+ rubygems_version: 1.3.7
122
159
  signing_key:
123
160
  specification_version: 3
124
161
  summary: Ruby data holder for OGC Simple Features
125
162
  test_files:
163
+ - spec/geo_ruby_spec.rb
164
+ - spec/spec_helper.rb
126
165
  - spec/geo_ruby/gpx4r/gpx_spec.rb
127
166
  - spec/geo_ruby/shp4r/shp_spec.rb
128
- - spec/geo_ruby/simple_features/envelope_spec.rb
129
- - spec/geo_ruby/simple_features/ewkb_parser_spec.rb
130
- - spec/geo_ruby/simple_features/ewkt_parser_spec.rb
131
- - spec/geo_ruby/simple_features/geometry_collection_spec.rb
167
+ - spec/geo_ruby/simple_features/point_spec.rb
132
168
  - spec/geo_ruby/simple_features/geometry_factory_spec.rb
133
- - spec/geo_ruby/simple_features/geometry_spec.rb
134
- - spec/geo_ruby/simple_features/georss_parser_spec.rb
169
+ - spec/geo_ruby/simple_features/envelope_spec.rb
170
+ - spec/geo_ruby/simple_features/polygon_spec.rb
135
171
  - spec/geo_ruby/simple_features/line_string_spec.rb
136
- - spec/geo_ruby/simple_features/linear_ring_spec.rb
137
172
  - spec/geo_ruby/simple_features/multi_line_string_spec.rb
138
- - spec/geo_ruby/simple_features/multi_point_spec.rb
173
+ - spec/geo_ruby/simple_features/ewkt_parser_spec.rb
174
+ - spec/geo_ruby/simple_features/ewkb_parser_spec.rb
175
+ - spec/geo_ruby/simple_features/linear_ring_spec.rb
176
+ - spec/geo_ruby/simple_features/geometry_collection_spec.rb
139
177
  - spec/geo_ruby/simple_features/multi_polygon_spec.rb
140
- - spec/geo_ruby/simple_features/point_spec.rb
141
- - spec/geo_ruby/simple_features/polygon_spec.rb
142
- - spec/geo_ruby_spec.rb
143
- - spec/spec_helper.rb
178
+ - spec/geo_ruby/simple_features/multi_point_spec.rb
179
+ - spec/geo_ruby/simple_features/georss_parser_spec.rb
180
+ - spec/geo_ruby/simple_features/geometry_spec.rb
data/spec/spec.opts DELETED
@@ -1,6 +0,0 @@
1
- --colour
2
- --format
3
- profile
4
- --timeout
5
- 20
6
- --diff