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