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.
- checksums.yaml +4 -4
- data/README.md +16 -9
- data/Rakefile +13 -14
- data/lib/geo_ruby/ewk.rb +2 -0
- data/lib/geo_ruby/{simple_features → ewk}/ewkb_parser.rb +206 -218
- data/lib/geo_ruby/ewk/ewkt_parser.rb +321 -0
- data/lib/geo_ruby/geojson.rb +27 -32
- data/lib/geo_ruby/georss.rb +88 -66
- data/lib/geo_ruby/gpx.rb +113 -1
- data/lib/geo_ruby/kml.rb +43 -31
- data/lib/geo_ruby/shp.rb +1 -0
- data/lib/geo_ruby/shp4r/dbf.rb +7 -3
- data/lib/geo_ruby/shp4r/shp.rb +297 -284
- data/lib/geo_ruby/simple_features.rb +2 -6
- data/lib/geo_ruby/simple_features/circle.rb +15 -13
- data/lib/geo_ruby/simple_features/envelope.rb +84 -77
- data/lib/geo_ruby/simple_features/geometry.rb +89 -69
- data/lib/geo_ruby/simple_features/geometry_collection.rb +46 -43
- data/lib/geo_ruby/simple_features/geometry_factory.rb +50 -47
- data/lib/geo_ruby/simple_features/helper.rb +14 -14
- data/lib/geo_ruby/simple_features/line_string.rb +94 -97
- data/lib/geo_ruby/simple_features/linear_ring.rb +4 -9
- data/lib/geo_ruby/simple_features/multi_line_string.rb +18 -21
- data/lib/geo_ruby/simple_features/multi_point.rb +18 -20
- data/lib/geo_ruby/simple_features/multi_polygon.rb +19 -25
- data/lib/geo_ruby/simple_features/point.rb +134 -128
- data/lib/geo_ruby/simple_features/polygon.rb +60 -59
- data/lib/geo_ruby/version.rb +1 -1
- data/spec/data/geojson/feature.json +9 -0
- data/spec/data/geojson/feature_collection.json +3 -4
- data/spec/geo_ruby/{simple_features → ewk}/ewkb_parser_spec.rb +56 -57
- data/spec/geo_ruby/{simple_features → ewk}/ewkt_parser_spec.rb +62 -63
- data/spec/geo_ruby/geojson_spec.rb +34 -17
- data/spec/geo_ruby/georss_spec.rb +76 -64
- data/spec/geo_ruby/{gpx4r/gpx_spec.rb → gpx_spec.rb} +25 -25
- data/spec/geo_ruby/kml_spec.rb +40 -36
- data/spec/geo_ruby/shp4r/shp_spec.rb +51 -51
- data/spec/geo_ruby/simple_features/circle_spec.rb +2 -2
- data/spec/geo_ruby/simple_features/envelope_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/geometry_collection_spec.rb +26 -26
- data/spec/geo_ruby/simple_features/geometry_factory_spec.rb +5 -5
- data/spec/geo_ruby/simple_features/geometry_spec.rb +8 -8
- data/spec/geo_ruby/simple_features/line_string_spec.rb +102 -102
- data/spec/geo_ruby/simple_features/linear_ring_spec.rb +7 -7
- data/spec/geo_ruby/simple_features/multi_line_string_spec.rb +20 -20
- data/spec/geo_ruby/simple_features/multi_point_spec.rb +16 -16
- data/spec/geo_ruby/simple_features/multi_polygon_spec.rb +19 -19
- data/spec/geo_ruby/simple_features/point_spec.rb +180 -174
- data/spec/geo_ruby/simple_features/polygon_spec.rb +55 -56
- data/spec/geo_ruby_spec.rb +4 -4
- data/spec/spec_helper.rb +19 -13
- metadata +10 -9
- data/lib/geo_ruby/gpx4r/gpx.rb +0 -118
- 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:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c4f8b3106e7d2ab362c2ec0adc1586e2d944855
|
4
|
+
data.tar.gz: a13bbeceb85ae96f24d484a5c63815f9aa00a3f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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 '
|
56
|
-
require 'geo_ruby/
|
57
|
-
require 'geo_ruby/
|
58
|
-
require 'geo_ruby/
|
59
|
-
require 'geo_ruby/kml'
|
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
|
-
|
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
|
5
|
-
require
|
4
|
+
require 'rspec'
|
5
|
+
require 'rspec/core/rake_task'
|
6
6
|
|
7
|
-
$LOAD_PATH.unshift File.expand_path(
|
8
|
-
require
|
7
|
+
$LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
|
8
|
+
require 'geo_ruby/version'
|
9
9
|
|
10
|
-
desc
|
11
|
-
task :
|
10
|
+
desc 'Builds the gem'
|
11
|
+
task gem: :build
|
12
12
|
task :build do
|
13
|
-
system
|
14
|
-
Dir.mkdir(
|
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 :
|
18
|
+
task install: :build do
|
19
19
|
system "sudo gem install pkg/georuby-#{GeoRuby::VERSION}.gem"
|
20
20
|
end
|
21
21
|
|
22
|
-
task :
|
22
|
+
task release: :build do
|
23
23
|
system "git tag -a v#{GeoRuby::VERSION} -m 'Tagging #{GeoRuby::VERSION}'"
|
24
|
-
system
|
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 =
|
29
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
30
30
|
end
|
31
31
|
|
32
|
-
task :
|
33
|
-
|
32
|
+
task default: [:spec]
|
data/lib/geo_ruby/ewk.rb
ADDED
@@ -1,218 +1,206 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@
|
30
|
-
end
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
@
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
96
|
-
|
97
|
-
def
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
end
|
107
|
-
|
108
|
-
def
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
@
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
@
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
@
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
@
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
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
|