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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1f642a6426275ec6a200705f9314ac60b783ec66
4
- data.tar.gz: ce8ae36da2895144752587caa3c0ddc9ad190a9b
3
+ metadata.gz: 8c4f8b3106e7d2ab362c2ec0adc1586e2d944855
4
+ data.tar.gz: a13bbeceb85ae96f24d484a5c63815f9aa00a3f7
5
5
  SHA512:
6
- metadata.gz: eaa948c90a6d82850fd9aa0f571ea947b1cbc77d049faf6db86b855c93eea37e5e8dc3a5730ebcc8d8ee399ed73f81fc92dc20615e5e42e93ca392065969a688
7
- data.tar.gz: 013276cf42be227087ae1ef62b54b8d25bddb1d91da560ac617903176482b62f258fcf853f22657facad18e974ccd6317665b34584f3cb47f02efb541fc43730
6
+ metadata.gz: 921c17e80d12c6175cebcb3dbecc98fe57aa8c87a49017bfa0839d6487b618c022b57d4418569c05a15a21c0e30bf7a2f7ddb537600900b88406f9d207ce0cac
7
+ data.tar.gz: 04d7b3314b08f2a5b7f084e21c68d2083f2318f16bf3bba9e632e600f753dd581a49ab0c67ce35042352fe675810060faf96a970ec0fced2f7a83ad32b5a70db
data/README.md CHANGED
@@ -43,7 +43,6 @@ To install the latest version, just type:
43
43
 
44
44
  gem install georuby
45
45
 
46
-
47
46
  Or include on your projects`s Gemfile:
48
47
 
49
48
  gem 'georuby'
@@ -52,11 +51,13 @@ Or include on your projects`s Gemfile:
52
51
  Optional, require if you need the functionality:
53
52
 
54
53
 
55
- require 'geo_ruby/shp4r/shp' # Shapefile
56
- require 'geo_ruby/gpx4r/gpx' # GPX data
57
- require 'geo_ruby/geojson' # GeoJSON
58
- require 'geo_ruby/georss' # GeoRSS
59
- require 'geo_ruby/kml' # KML data
54
+ require 'georuby'
55
+ require 'geo_ruby/ewk' # EWKT/EWKB
56
+ require 'geo_ruby/shp' # Shapefile
57
+ require 'geo_ruby/gpx' # GPX data
58
+ require 'geo_ruby/kml' # KML data
59
+ require 'geo_ruby/georss' # GeoRSS
60
+ require 'geo_ruby/geojson' # GeoJSON
60
61
 
61
62
 
62
63
  Use
@@ -72,7 +73,13 @@ Creating a 3D Point:
72
73
 
73
74
  Creating a LineString:
74
75
 
75
- LineString.from_coordinates([[1,1],[2,2]],4326))
76
+ LineString.from_coordinates([[1,1],[2,2]],4326))
77
+
78
+
79
+ Creating a Polygon:
80
+
81
+ Polygon.from_coordinates([[1,1],[2,2]],4326))
82
+ LineString.from_linear_rings(rings)
76
83
 
77
84
 
78
85
  Input and output
@@ -155,7 +162,7 @@ thoroughly so caveat emptor and backup before performing any destructive operati
155
162
 
156
163
 
157
164
  GPX Reading
158
- ---
165
+ -----------
159
166
 
160
167
  You can read and convert GPX Files to LineString/Polygon:
161
168
 
@@ -165,7 +172,7 @@ You can read and convert GPX Files to LineString/Polygon:
165
172
 
166
173
 
167
174
  GeoJSON Support
168
- -------
175
+ ---------------
169
176
 
170
177
  Basic GeoJSON support has been implemented per v1.0 of the {spec}[http://geojson.org/geojson-spec.html].
171
178
 
data/Rakefile CHANGED
@@ -1,33 +1,32 @@
1
1
  require 'bundler'
2
2
  Bundler.setup
3
3
 
4
- require "rspec"
5
- require "rspec/core/rake_task"
4
+ require 'rspec'
5
+ require 'rspec/core/rake_task'
6
6
 
7
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
8
- require "geo_ruby/version"
7
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
8
+ require 'geo_ruby/version'
9
9
 
10
- desc "Builds the gem"
11
- task :gem => :build
10
+ desc 'Builds the gem'
11
+ task gem: :build
12
12
  task :build do
13
- system "gem build georuby.gemspec"
14
- Dir.mkdir("pkg") unless Dir.exists?("pkg")
13
+ system 'gem build georuby.gemspec'
14
+ Dir.mkdir('pkg') unless Dir.exist?('pkg')
15
15
  system "mv georuby-#{GeoRuby::VERSION}.gem pkg/"
16
16
  end
17
17
 
18
- task :install => :build do
18
+ task install: :build do
19
19
  system "sudo gem install pkg/georuby-#{GeoRuby::VERSION}.gem"
20
20
  end
21
21
 
22
- task :release => :build do
22
+ task release: :build do
23
23
  system "git tag -a v#{GeoRuby::VERSION} -m 'Tagging #{GeoRuby::VERSION}'"
24
- system "git push --tags"
24
+ system 'git push --tags'
25
25
  system "gem push pkg/georuby-#{GeoRuby::VERSION}.gem"
26
26
  end
27
27
 
28
28
  RSpec::Core::RakeTask.new(:spec) do |spec|
29
- spec.pattern = "spec/**/*_spec.rb"
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
30
  end
31
31
 
32
- task :default => [:spec]
33
-
32
+ task default: [:spec]
@@ -0,0 +1,2 @@
1
+ require 'geo_ruby/ewk/ewkb_parser'
2
+ require 'geo_ruby/ewk/ewkt_parser'
@@ -1,218 +1,206 @@
1
- require 'geo_ruby/simple_features/point'
2
- require 'geo_ruby/simple_features/line_string'
3
- require 'geo_ruby/simple_features/linear_ring'
4
- require 'geo_ruby/simple_features/polygon'
5
- require 'geo_ruby/simple_features/multi_point'
6
- require 'geo_ruby/simple_features/multi_line_string'
7
- require 'geo_ruby/simple_features/multi_polygon'
8
- require 'geo_ruby/simple_features/geometry_collection'
9
-
10
- module GeoRuby
11
- module SimpleFeatures
12
-
13
- #Raised when an error in the EWKB string is detected
14
- class EWKBFormatError < StandardError
15
- end
16
-
17
- #Parses EWKB strings and notifies of events (such as the beginning of the definition of geometry, the value of the SRID...) the factory passed as argument to the constructor.
18
- #
19
- #=Example
20
- # factory = GeometryFactory::new
21
- # ewkb_parser = EWKBParser::new(factory)
22
- # ewkb_parser.parse(<EWKB String>)
23
- # geometry = @factory.geometry
24
- #
25
- #You can also use directly the static method Geometry.from_ewkb
26
- class EWKBParser
27
-
28
- def initialize(factory)
29
- @factory = factory
30
- end
31
-
32
- #Parses the ewkb string passed as argument and notifies the factory of events
33
- def parse(ewkb)
34
- @factory.reset
35
- @with_z = false
36
- @with_m = false
37
- @unpack_structure = UnpackStructure::new(ewkb)
38
- parse_geometry
39
- @unpack_structure.done
40
- @srid = nil
41
- end
42
-
43
- private
44
-
45
- def parse_geometry
46
- @unpack_structure.endianness = @unpack_structure.read_byte
47
- geometry_type = @unpack_structure.read_uint
48
-
49
- if (geometry_type & Z_MASK) != 0
50
- @with_z = true
51
- geometry_type = geometry_type & ~Z_MASK
52
- end
53
- if (geometry_type & M_MASK) != 0
54
- @with_m = true
55
- geometry_type = geometry_type & ~M_MASK
56
- end
57
- if (geometry_type & SRID_MASK) != 0
58
- @srid = @unpack_structure.read_uint
59
- geometry_type = geometry_type & ~SRID_MASK
60
- else
61
- #to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the root, we take the default srid
62
- @srid ||= DEFAULT_SRID
63
- end
64
-
65
- case geometry_type
66
- when 1
67
- parse_point
68
- when 2
69
- parse_line_string
70
- when 3
71
- parse_polygon
72
- when 4
73
- parse_multi_point
74
- when 5
75
- parse_multi_line_string
76
- when 6
77
- parse_multi_polygon
78
- when 7
79
- parse_geometry_collection
80
- else
81
- raise EWKBFormatError::new("Unknown geometry type")
82
- end
83
- end
84
-
85
- def parse_geometry_collection
86
- parse_multi_geometries(GeometryCollection)
87
- end
88
-
89
- def parse_multi_polygon
90
- parse_multi_geometries(MultiPolygon)
91
- end
92
-
93
- def parse_multi_line_string
94
- parse_multi_geometries(MultiLineString)
95
- end
96
-
97
- def parse_multi_point
98
- parse_multi_geometries(MultiPoint)
99
- end
100
-
101
- def parse_multi_geometries(geometry_type)
102
- @factory.begin_geometry(geometry_type,@srid)
103
- num_geometries = @unpack_structure.read_uint
104
- 1.upto(num_geometries) { parse_geometry }
105
- @factory.end_geometry(@with_z,@with_m)
106
- end
107
-
108
- def parse_polygon
109
- @factory.begin_geometry(Polygon,@srid)
110
- num_linear_rings = @unpack_structure.read_uint
111
- 1.upto(num_linear_rings) {parse_linear_ring}
112
- @factory.end_geometry(@with_z,@with_m)
113
- end
114
-
115
- def parse_linear_ring
116
- parse_point_list(LinearRing)
117
- end
118
-
119
- def parse_line_string
120
- parse_point_list(LineString)
121
- end
122
-
123
- #used to parse line_strings and linear_rings
124
- def parse_point_list(geometry_type)
125
- @factory.begin_geometry(geometry_type,@srid)
126
- num_points = @unpack_structure.read_uint
127
- 1.upto(num_points) {parse_point}
128
- @factory.end_geometry(@with_z,@with_m)
129
- end
130
-
131
- def parse_point
132
- @factory.begin_geometry(Point,@srid)
133
- x, y = *@unpack_structure.read_point
134
- if ! (@with_z or @with_m) #most common case probably
135
- @factory.add_point_x_y(x,y)
136
- elsif @with_m and @with_z
137
- z = @unpack_structure.read_double
138
- m = @unpack_structure.read_double
139
- @factory.add_point_x_y_z_m(x,y,z,m)
140
- elsif @with_z
141
- z = @unpack_structure.read_double
142
- @factory.add_point_x_y_z(x,y,z)
143
- else
144
- m = @unpack_structure.read_double
145
- @factory.add_point_x_y_m(x,y,m)
146
- end
147
-
148
- @factory.end_geometry(@with_z,@with_m)
149
- end
150
- end
151
-
152
- #Parses HexEWKB strings. In reality, it just transforms the HexEWKB string into the equivalent EWKB string and lets the EWKBParser do the actual parsing.
153
- class HexEWKBParser < EWKBParser
154
-
155
- #parses an HexEWKB string
156
- def parse(hexewkb)
157
- super(decode_hex(hexewkb))
158
- end
159
-
160
- #transforms a HexEWKB string into an EWKB string
161
- def decode_hex(hexewkb)
162
- [hexewkb].pack("H*")
163
- end
164
- end
165
-
166
- class UnpackStructure #:nodoc:
167
- NDR = 1
168
- XDR = 0
169
-
170
- def initialize(ewkb)
171
- @position = 0
172
- @ewkb = ewkb
173
- end
174
-
175
- def done
176
- raise EWKBFormatError::new("Trailing data") if @position != @ewkb.length
177
- end
178
-
179
- def read_point
180
- i = @position
181
- @position += 16
182
- raise EWKBFormatError::new("Truncated data") if @ewkb.length < @position
183
- @ewkb.unpack("@#{i}#@double_mark#@double_mark@*")
184
- end
185
-
186
- def read_double
187
- i = @position
188
- @position += 8
189
- raise EWKBFormatError::new("Truncated data") if @ewkb.length < @position
190
- @ewkb.unpack("@#{i}#@double_mark@*").first
191
- end
192
-
193
- def read_uint
194
- i = @position
195
- @position += 4
196
- raise EWKBFormatError::new("Truncated data") if @ewkb.length < @position
197
- @ewkb.unpack("@#{i}#@uint_mark@*").first
198
- end
199
-
200
- def read_byte
201
- i = @position
202
- @position += 1
203
- raise EWKBFormatError::new("Truncated data") if @ewkb.length < @position
204
- @ewkb.unpack("@#{i}C@*").first
205
- end
206
-
207
- def endianness=(byte_order)
208
- if(byte_order == NDR)
209
- @uint_mark="V"
210
- @double_mark="E"
211
- elsif(byte_order == XDR)
212
- @uint_mark="N"
213
- @double_mark="G"
214
- end
215
- end
216
- end
217
- end
218
- end
1
+ module GeoRuby
2
+ module SimpleFeatures
3
+ # Raised when an error in the EWKB string is detected
4
+ class EWKBFormatError < StandardError
5
+ end
6
+
7
+ # Parses EWKB strings and notifies of events (such as the beginning of the definition of geometry, the value of the SRID...) the factory passed as argument to the constructor.
8
+ #
9
+ # =Example
10
+ # factory = GeometryFactory::new
11
+ # ewkb_parser = EWKBParser::new(factory)
12
+ # ewkb_parser.parse(<EWKB String>)
13
+ # geometry = @factory.geometry
14
+ #
15
+ # You can also use directly the static method Geometry.from_ewkb
16
+ class EWKBParser
17
+ def initialize(factory)
18
+ @factory = factory
19
+ end
20
+
21
+ # Parses the ewkb string passed as argument and notifies the factory of events
22
+ def parse(ewkb)
23
+ @factory.reset
24
+ @with_z = false
25
+ @with_m = false
26
+ @unpack_structure = UnpackStructure.new(ewkb)
27
+ parse_geometry
28
+ @unpack_structure.done
29
+ @srid = nil
30
+ end
31
+
32
+ private
33
+
34
+ def parse_geometry
35
+ @unpack_structure.endianness = @unpack_structure.read_byte
36
+ geometry_type = @unpack_structure.read_uint
37
+
38
+ if (geometry_type & Z_MASK) != 0
39
+ @with_z = true
40
+ geometry_type = geometry_type & ~Z_MASK
41
+ end
42
+ if (geometry_type & M_MASK) != 0
43
+ @with_m = true
44
+ geometry_type = geometry_type & ~M_MASK
45
+ end
46
+ if (geometry_type & SRID_MASK) != 0
47
+ @srid = @unpack_structure.read_uint
48
+ geometry_type = geometry_type & ~SRID_MASK
49
+ else
50
+ # to manage multi geometries : the srid is not present in sub_geometries, therefore we take the srid of the parent ; if it is the root, we take the default srid
51
+ @srid ||= DEFAULT_SRID
52
+ end
53
+
54
+ case geometry_type
55
+ when 1
56
+ parse_point
57
+ when 2
58
+ parse_line_string
59
+ when 3
60
+ parse_polygon
61
+ when 4
62
+ parse_multi_point
63
+ when 5
64
+ parse_multi_line_string
65
+ when 6
66
+ parse_multi_polygon
67
+ when 7
68
+ parse_geometry_collection
69
+ else
70
+ fail EWKBFormatError.new('Unknown geometry type')
71
+ end
72
+ end
73
+
74
+ def parse_geometry_collection
75
+ parse_multi_geometries(GeometryCollection)
76
+ end
77
+
78
+ def parse_multi_polygon
79
+ parse_multi_geometries(MultiPolygon)
80
+ end
81
+
82
+ def parse_multi_line_string
83
+ parse_multi_geometries(MultiLineString)
84
+ end
85
+
86
+ def parse_multi_point
87
+ parse_multi_geometries(MultiPoint)
88
+ end
89
+
90
+ def parse_multi_geometries(geometry_type)
91
+ @factory.begin_geometry(geometry_type, @srid)
92
+ num_geometries = @unpack_structure.read_uint
93
+ 1.upto(num_geometries) { parse_geometry }
94
+ @factory.end_geometry(@with_z, @with_m)
95
+ end
96
+
97
+ def parse_polygon
98
+ @factory.begin_geometry(Polygon, @srid)
99
+ num_linear_rings = @unpack_structure.read_uint
100
+ 1.upto(num_linear_rings) { parse_linear_ring }
101
+ @factory.end_geometry(@with_z, @with_m)
102
+ end
103
+
104
+ def parse_linear_ring
105
+ parse_point_list(LinearRing)
106
+ end
107
+
108
+ def parse_line_string
109
+ parse_point_list(LineString)
110
+ end
111
+
112
+ # used to parse line_strings and linear_rings
113
+ def parse_point_list(geometry_type)
114
+ @factory.begin_geometry(geometry_type, @srid)
115
+ num_points = @unpack_structure.read_uint
116
+ 1.upto(num_points) { parse_point }
117
+ @factory.end_geometry(@with_z, @with_m)
118
+ end
119
+
120
+ def parse_point
121
+ @factory.begin_geometry(Point, @srid)
122
+ x, y = *@unpack_structure.read_point
123
+ if ! (@with_z || @with_m) # most common case probably
124
+ @factory.add_point_x_y(x, y)
125
+ elsif @with_m && @with_z
126
+ z = @unpack_structure.read_double
127
+ m = @unpack_structure.read_double
128
+ @factory.add_point_x_y_z_m(x, y, z, m)
129
+ elsif @with_z
130
+ z = @unpack_structure.read_double
131
+ @factory.add_point_x_y_z(x, y, z)
132
+ else
133
+ m = @unpack_structure.read_double
134
+ @factory.add_point_x_y_m(x, y, m)
135
+ end
136
+
137
+ @factory.end_geometry(@with_z, @with_m)
138
+ end
139
+ end
140
+
141
+ # Parses HexEWKB strings. In reality, it just transforms the HexEWKB string into the equivalent EWKB string and lets the EWKBParser do the actual parsing.
142
+ class HexEWKBParser < EWKBParser
143
+ # parses an HexEWKB string
144
+ def parse(hexewkb)
145
+ super(decode_hex(hexewkb))
146
+ end
147
+
148
+ # transforms a HexEWKB string into an EWKB string
149
+ def decode_hex(hexewkb)
150
+ [hexewkb].pack('H*')
151
+ end
152
+ end
153
+
154
+ class UnpackStructure #:nodoc:
155
+ NDR = 1
156
+ XDR = 0
157
+
158
+ def initialize(ewkb)
159
+ @position = 0
160
+ @ewkb = ewkb
161
+ end
162
+
163
+ def done
164
+ fail EWKBFormatError.new('Trailing data') if @position != @ewkb.length
165
+ end
166
+
167
+ def read_point
168
+ i = @position
169
+ @position += 16
170
+ fail EWKBFormatError.new('Truncated data') if @ewkb.length < @position
171
+ @ewkb.unpack("@#{i}#{@double_mark}#{@double_mark}@*")
172
+ end
173
+
174
+ def read_double
175
+ i = @position
176
+ @position += 8
177
+ fail EWKBFormatError.new('Truncated data') if @ewkb.length < @position
178
+ @ewkb.unpack("@#{i}#{@double_mark}@*").first
179
+ end
180
+
181
+ def read_uint
182
+ i = @position
183
+ @position += 4
184
+ fail EWKBFormatError.new('Truncated data') if @ewkb.length < @position
185
+ @ewkb.unpack("@#{i}#{@uint_mark}@*").first
186
+ end
187
+
188
+ def read_byte
189
+ i = @position
190
+ @position += 1
191
+ fail EWKBFormatError.new('Truncated data') if @ewkb.length < @position
192
+ @ewkb.unpack("@#{i}C@*").first
193
+ end
194
+
195
+ def endianness=(byte_order)
196
+ if (byte_order == NDR)
197
+ @uint_mark = 'V'
198
+ @double_mark = 'E'
199
+ elsif (byte_order == XDR)
200
+ @uint_mark = 'N'
201
+ @double_mark = 'G'
202
+ end
203
+ end
204
+ end
205
+ end
206
+ end