rgeo-geojson 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +5 -0
- data/README.rdoc +104 -0
- data/Version +1 -0
- data/lib/rgeo/geo_json.rb +62 -0
- data/lib/rgeo/geo_json/coder.rb +401 -0
- data/lib/rgeo/geo_json/entities.rb +301 -0
- data/lib/rgeo/geo_json/interface.rb +129 -0
- data/test/tc_basic.rb +281 -0
- metadata +88 -0
@@ -0,0 +1,301 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GeoJSON standard entities
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module GeoJSON
|
40
|
+
|
41
|
+
|
42
|
+
# This is a GeoJSON wrapper entity that corresponds to the GeoJSON
|
43
|
+
# "Feature" type. It is an immutable type.
|
44
|
+
#
|
45
|
+
# This is the default implementation that is generated by
|
46
|
+
# RGeo::GeoJSON::EntityFactory. You may replace this implementation
|
47
|
+
# by writing your own entity factory. Note that an alternate Feature
|
48
|
+
# implementation need not subclass or even duck-type this class.
|
49
|
+
# the entity factory mediates all interaction between the GeoJSON
|
50
|
+
# engine and features.
|
51
|
+
|
52
|
+
class Feature
|
53
|
+
|
54
|
+
|
55
|
+
# Create a feature wrapping the given geometry, with the given ID
|
56
|
+
# and properties.
|
57
|
+
|
58
|
+
def initialize(geometry_, id_=nil, properties_={})
|
59
|
+
@geometry = geometry_
|
60
|
+
@id = id_
|
61
|
+
@properties = properties_.dup
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
def inspect # :nodoc:
|
66
|
+
"#<#{self.class}:0x#{object_id.to_s(16)} id=#{@id.inspect} geom=#{@geometry ? @geometry.as_text.inspect : 'nil'}>"
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_s # :nodoc:
|
70
|
+
inspect
|
71
|
+
end
|
72
|
+
|
73
|
+
def hash # :nodoc:
|
74
|
+
@geometry.hash + @id.hash + @properties.hash
|
75
|
+
end
|
76
|
+
|
77
|
+
|
78
|
+
# Two features are equal if their geometries, IDs, and properties
|
79
|
+
# are all equal.
|
80
|
+
# This method uses the eql? method to test geometry equality, which
|
81
|
+
# may behave differently than the == operator.
|
82
|
+
|
83
|
+
def eql?(rhs_)
|
84
|
+
rhs_.kind_of?(Feature) && @geometry.eql?(rhs_.geometry) && @id.eql?(rhs_.feature_id) && @properties.eql?(rhs_.instance_variable_get(:@properties))
|
85
|
+
end
|
86
|
+
|
87
|
+
|
88
|
+
# Two features are equal if their geometries, IDs, and properties
|
89
|
+
# are all equal.
|
90
|
+
# This method uses the == operator to test geometry equality, which
|
91
|
+
# may behave differently than the eql? method.
|
92
|
+
|
93
|
+
def ==(rhs_)
|
94
|
+
rhs_.kind_of?(Feature) && @geometry == rhs_.geometry && @id == rhs_.feature_id && @properties == rhs_.instance_variable_get(:@properties)
|
95
|
+
end
|
96
|
+
|
97
|
+
|
98
|
+
# Returns the geometry contained in this feature, which may be nil.
|
99
|
+
|
100
|
+
def geometry
|
101
|
+
@geometry
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
# Returns the ID for this feature, which may be nil.
|
106
|
+
|
107
|
+
def feature_id
|
108
|
+
@id
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# Returns a copy of the properties for this feature.
|
113
|
+
|
114
|
+
def properties
|
115
|
+
@properties.dup
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Gets the value of the given named property.
|
120
|
+
# Returns nil if the given property is not found.
|
121
|
+
|
122
|
+
def property(key_)
|
123
|
+
@properties[key_.to_s]
|
124
|
+
end
|
125
|
+
alias_method :[], :property
|
126
|
+
|
127
|
+
|
128
|
+
# Gets an array of the known property keys in this feature.
|
129
|
+
|
130
|
+
def keys
|
131
|
+
@properties.keys
|
132
|
+
end
|
133
|
+
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
# This is a GeoJSON wrapper entity that corresponds to the GeoJSON
|
139
|
+
# "FeatureCollection" type. It is an immutable type.
|
140
|
+
#
|
141
|
+
# This is the default implementation that is generated by
|
142
|
+
# RGeo::GeoJSON::EntityFactory. You may replace this implementation
|
143
|
+
# by writing your own entity factory. Note that an alternate
|
144
|
+
# FeatureCollection implementation need not subclass or even
|
145
|
+
# duck-type this class. The entity factory mediates all interaction
|
146
|
+
# between the GeoJSON engine and feature collections.
|
147
|
+
|
148
|
+
class FeatureCollection
|
149
|
+
|
150
|
+
include ::Enumerable
|
151
|
+
|
152
|
+
|
153
|
+
# Create a new FeatureCollection with the given features, which must
|
154
|
+
# be provided as an Enumerable.
|
155
|
+
|
156
|
+
def initialize(features_=[])
|
157
|
+
@features = []
|
158
|
+
features_.each{ |f_| @features << f_ if f_.kind_of?(Feature) }
|
159
|
+
end
|
160
|
+
|
161
|
+
|
162
|
+
def inspect # :nodoc:
|
163
|
+
"#<#{self.class}:0x#{object_id.to_s(16)}>"
|
164
|
+
end
|
165
|
+
|
166
|
+
def to_s # :nodoc:
|
167
|
+
inspect
|
168
|
+
end
|
169
|
+
|
170
|
+
def hash # :nodoc:
|
171
|
+
@features.hash
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
# Two feature collections are equal if they contain the same
|
176
|
+
# features in the same order.
|
177
|
+
# This methods uses the eql? method to test geometry equality, which
|
178
|
+
# may behave differently than the == operator.
|
179
|
+
|
180
|
+
def eql?(rhs_)
|
181
|
+
rhs_.kind_of?(FeatureCollection) && @features.eql?(rhs_.instance_variable_get(:@features))
|
182
|
+
end
|
183
|
+
|
184
|
+
|
185
|
+
# Two feature collections are equal if they contain the same
|
186
|
+
# features in the same order.
|
187
|
+
# This methods uses the == operator to test geometry equality, which
|
188
|
+
# may behave differently than the eql? method.
|
189
|
+
|
190
|
+
def ==(rhs_)
|
191
|
+
rhs_.kind_of?(FeatureCollection) && @features == rhs_.instance_variable_get(:@features)
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
# Iterates or returns an iterator for the features.
|
196
|
+
|
197
|
+
def each(&block_)
|
198
|
+
@features.each(&block_)
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
# Returns the number of features contained in this collection.
|
203
|
+
|
204
|
+
def size
|
205
|
+
@features.size
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
# Access a feature by index.
|
210
|
+
|
211
|
+
def [](index_)
|
212
|
+
@features[index_]
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
end
|
217
|
+
|
218
|
+
|
219
|
+
# This is the default entity factory. It creates objects of type
|
220
|
+
# RGeo::GeoJSON::Feature and RGeo::GeoJSON::FeatureCollection.
|
221
|
+
# You may create your own entity factory by duck-typing this class.
|
222
|
+
|
223
|
+
class EntityFactory
|
224
|
+
|
225
|
+
|
226
|
+
# Create and return a new feature, given geometry, ID, and
|
227
|
+
# properties hash. Note that, per the GeoJSON spec, geometry and/or
|
228
|
+
# properties may be nil.
|
229
|
+
|
230
|
+
def feature(geometry_, id_=nil, properties_=nil)
|
231
|
+
Feature.new(geometry_, id_, properties_ || {})
|
232
|
+
end
|
233
|
+
|
234
|
+
|
235
|
+
# Create and return a new feature collection, given an enumerable
|
236
|
+
# of feature objects.
|
237
|
+
|
238
|
+
def feature_collection(features_=[])
|
239
|
+
FeatureCollection.new(features_)
|
240
|
+
end
|
241
|
+
|
242
|
+
|
243
|
+
# Returns true if the given object is a feature created by this
|
244
|
+
# entity factory.
|
245
|
+
|
246
|
+
def is_feature?(object_)
|
247
|
+
object_.kind_of?(Feature)
|
248
|
+
end
|
249
|
+
|
250
|
+
|
251
|
+
# Returns true if the given object is a feature collection created
|
252
|
+
# by this entity factory.
|
253
|
+
|
254
|
+
def is_feature_collection?(object_)
|
255
|
+
object_.kind_of?(FeatureCollection)
|
256
|
+
end
|
257
|
+
|
258
|
+
|
259
|
+
# Run Enumerable#map on the features contained in the given feature
|
260
|
+
# collection.
|
261
|
+
|
262
|
+
def map_feature_collection(object_, &block_)
|
263
|
+
object_.map(&block_)
|
264
|
+
end
|
265
|
+
|
266
|
+
|
267
|
+
# Returns the geometry associated with the given feature.
|
268
|
+
|
269
|
+
def get_feature_geometry(object_)
|
270
|
+
object_.geometry
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
# Returns the ID of the given feature, or nil for no ID.
|
275
|
+
|
276
|
+
def get_feature_id(object_)
|
277
|
+
object_.feature_id
|
278
|
+
end
|
279
|
+
|
280
|
+
|
281
|
+
# Returns the properties of the given feature as a hash. Editing
|
282
|
+
# this hash does not change the state of the feature.
|
283
|
+
|
284
|
+
def get_feature_properties(object_)
|
285
|
+
object_.properties
|
286
|
+
end
|
287
|
+
|
288
|
+
|
289
|
+
# Return the singleton instance of EntityFactory.
|
290
|
+
|
291
|
+
def self.instance
|
292
|
+
@instance ||= self.new
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# GeoJSON toplevel interface
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
module RGeo
|
38
|
+
|
39
|
+
module GeoJSON
|
40
|
+
|
41
|
+
class << self
|
42
|
+
|
43
|
+
|
44
|
+
# High-level convenience routine for encoding an object as GeoJSON.
|
45
|
+
# Pass the object, which may one of the geometry objects specified
|
46
|
+
# in RGeo::Feature, or an appropriate GeoJSON wrapper entity such
|
47
|
+
# as RGeo::GeoJSON::Feature or RGeo::GeoJSON::FeatureCollection.
|
48
|
+
#
|
49
|
+
# The only option supported is <tt>:entity_factory</tt>, which lets
|
50
|
+
# you override the types of GeoJSON entities supported. See
|
51
|
+
# RGeo::GeoJSON::EntityFactory for more information. By default,
|
52
|
+
# encode supports objects of type RGeo::GeoJSON::Feature and
|
53
|
+
# RGeo::GeoJSON::FeatureCollection.
|
54
|
+
|
55
|
+
def encode(object_, opts_={})
|
56
|
+
Coder.new(opts_).encode(object_)
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# High-level convenience routine for decoding an object from GeoJSON.
|
61
|
+
# The input may be a JSON hash, a String, or an IO object from which
|
62
|
+
# to read the JSON string.
|
63
|
+
#
|
64
|
+
# Options include:
|
65
|
+
#
|
66
|
+
# <tt>:geo_factory</tt>::
|
67
|
+
# Specifies the geo factory to use to create geometry objects.
|
68
|
+
# Defaults to the preferred cartesian factory.
|
69
|
+
# <tt>:entity_factory</tt>::
|
70
|
+
# Specifies an entity factory, which lets you override the types
|
71
|
+
# of GeoJSON entities that are created. It defaults to the default
|
72
|
+
# RGeo::GeoJSON::EntityFactory, which generates objects of type
|
73
|
+
# RGeo::GeoJSON::Feature or RGeo::GeoJSON::FeatureCollection.
|
74
|
+
# See RGeo::GeoJSON::EntityFactory for more information.
|
75
|
+
# <tt>:json_parser</tt>::
|
76
|
+
# Specifies a JSON parser to use when decoding a String or IO
|
77
|
+
# object. The value may be a Proc object taking the string as the
|
78
|
+
# sole argument and returning the JSON hash, or it may be one of
|
79
|
+
# the special values <tt>:json</tt>, <tt>:yajl</tt>, or
|
80
|
+
# <tt>:active_support</tt>. Setting one of those special values
|
81
|
+
# will require the corresponding library to be available. Note
|
82
|
+
# that the <tt>:json</tt> library is present in the standard
|
83
|
+
# library in Ruby 1.9, but requires the "json" gem in Ruby 1.8.
|
84
|
+
# If a parser is not specified, then the decode method will not
|
85
|
+
# accept a String or IO object; it will require a Hash.
|
86
|
+
|
87
|
+
def decode(input_, opts_={})
|
88
|
+
Coder.new(opts_).decode(input_)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
# Creates and returns a coder object of type RGeo::GeoJSON::Coder
|
93
|
+
# that encapsulates encoding and decoding settings (principally the
|
94
|
+
# RGeo::Feature::Factory and the RGeo::GeoJSON::EntityFactory to be
|
95
|
+
# used).
|
96
|
+
#
|
97
|
+
# The geo factory is a required argument. Other options include:
|
98
|
+
#
|
99
|
+
# <tt>:geo_factory</tt>::
|
100
|
+
# Specifies the geo factory to use to create geometry objects.
|
101
|
+
# Defaults to the preferred cartesian factory.
|
102
|
+
# <tt>:entity_factory</tt>::
|
103
|
+
# Specifies an entity factory, which lets you override the types
|
104
|
+
# of GeoJSON entities that are created. It defaults to the default
|
105
|
+
# RGeo::GeoJSON::EntityFactory, which generates objects of type
|
106
|
+
# RGeo::GeoJSON::Feature or RGeo::GeoJSON::FeatureCollection.
|
107
|
+
# See RGeo::GeoJSON::EntityFactory for more information.
|
108
|
+
# <tt>:json_parser</tt>::
|
109
|
+
# Specifies a JSON parser to use when decoding a String or IO
|
110
|
+
# object. The value may be a Proc object taking the string as the
|
111
|
+
# sole argument and returning the JSON hash, or it may be one of
|
112
|
+
# the special values <tt>:json</tt>, <tt>:yajl</tt>, or
|
113
|
+
# <tt>:active_support</tt>. Setting one of those special values
|
114
|
+
# will require the corresponding library to be available. Note
|
115
|
+
# that the <tt>:json</tt> library is present in the standard
|
116
|
+
# library in Ruby 1.9, but requires the "json" gem in Ruby 1.8.
|
117
|
+
# If a parser is not specified, then the decode method will not
|
118
|
+
# accept a String or IO object; it will require a Hash.
|
119
|
+
|
120
|
+
def coder(opts_={})
|
121
|
+
Coder.new(opts_)
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
data/test/tc_basic.rb
ADDED
@@ -0,0 +1,281 @@
|
|
1
|
+
# -----------------------------------------------------------------------------
|
2
|
+
#
|
3
|
+
# Tests for basic GeoJSON usage
|
4
|
+
#
|
5
|
+
# -----------------------------------------------------------------------------
|
6
|
+
# Copyright 2010 Daniel Azuma
|
7
|
+
#
|
8
|
+
# All rights reserved.
|
9
|
+
#
|
10
|
+
# Redistribution and use in source and binary forms, with or without
|
11
|
+
# modification, are permitted provided that the following conditions are met:
|
12
|
+
#
|
13
|
+
# * Redistributions of source code must retain the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer.
|
15
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
16
|
+
# this list of conditions and the following disclaimer in the documentation
|
17
|
+
# and/or other materials provided with the distribution.
|
18
|
+
# * Neither the name of the copyright holder, nor the names of any other
|
19
|
+
# contributors to this software, may be used to endorse or promote products
|
20
|
+
# derived from this software without specific prior written permission.
|
21
|
+
#
|
22
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
23
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
24
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
25
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
26
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
27
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
28
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
29
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
30
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
31
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
32
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
33
|
+
# -----------------------------------------------------------------------------
|
34
|
+
;
|
35
|
+
|
36
|
+
|
37
|
+
require 'test/unit'
|
38
|
+
require 'rgeo/geo_json'
|
39
|
+
|
40
|
+
|
41
|
+
module RGeo
|
42
|
+
module GeoJSON
|
43
|
+
module Tests # :nodoc:
|
44
|
+
|
45
|
+
class TestGeoJSON < ::Test::Unit::TestCase # :nodoc:
|
46
|
+
|
47
|
+
|
48
|
+
def setup
|
49
|
+
@geo_factory = ::RGeo::Cartesian.simple_factory(:srid => 4326)
|
50
|
+
@geo_factory_z = ::RGeo::Cartesian.simple_factory(:srid => 4326, :has_z_coordinate => true)
|
51
|
+
@geo_factory_m = ::RGeo::Cartesian.simple_factory(:srid => 4326, :has_m_coordinate => true)
|
52
|
+
@geo_factory_zm = ::RGeo::Cartesian.simple_factory(:srid => 4326, :has_z_coordinate => true, :has_m_coordinate => true)
|
53
|
+
@entity_factory = ::RGeo::GeoJSON::EntityFactory.instance
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
def test_point
|
58
|
+
object_ = @geo_factory.point(10, 20)
|
59
|
+
json_ = {
|
60
|
+
'type' => 'Point',
|
61
|
+
'coordinates' => [10.0, 20.0],
|
62
|
+
}
|
63
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
64
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
def test_point_z
|
69
|
+
object_ = @geo_factory_z.point(10, 20, -1)
|
70
|
+
json_ = {
|
71
|
+
'type' => 'Point',
|
72
|
+
'coordinates' => [10.0, 20.0, -1.0],
|
73
|
+
}
|
74
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
75
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory_z).eql?(object_))
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
def test_point_m
|
80
|
+
object_ = @geo_factory_m.point(10, 20, -1)
|
81
|
+
json_ = {
|
82
|
+
'type' => 'Point',
|
83
|
+
'coordinates' => [10.0, 20.0, -1.0],
|
84
|
+
}
|
85
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
86
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory_m).eql?(object_))
|
87
|
+
end
|
88
|
+
|
89
|
+
|
90
|
+
def test_point_zm
|
91
|
+
object_ = @geo_factory_zm.point(10, 20, -1, -2)
|
92
|
+
json_ = {
|
93
|
+
'type' => 'Point',
|
94
|
+
'coordinates' => [10.0, 20.0, -1.0, -2.0],
|
95
|
+
}
|
96
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
97
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory_zm).eql?(object_))
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def test_line_string
|
102
|
+
object_ = @geo_factory.line_string([@geo_factory.point(10, 20), @geo_factory.point(12, 22), @geo_factory.point(-3, 24)])
|
103
|
+
json_ = {
|
104
|
+
'type' => 'LineString',
|
105
|
+
'coordinates' => [[10.0, 20.0], [12.0, 22.0], [-3.0, 24.0]],
|
106
|
+
}
|
107
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
108
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
def test_polygon
|
113
|
+
object_ = @geo_factory.polygon(@geo_factory.linear_ring([@geo_factory.point(10, 20), @geo_factory.point(12, 22), @geo_factory.point(-3, 24), @geo_factory.point(10, 20)]))
|
114
|
+
json_ = {
|
115
|
+
'type' => 'Polygon',
|
116
|
+
'coordinates' => [[[10.0, 20.0], [12.0, 22.0], [-3.0, 24.0], [10.0, 20.0]]],
|
117
|
+
}
|
118
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
119
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def test_polygon_complex
|
124
|
+
object_ = @geo_factory.polygon(@geo_factory.linear_ring([@geo_factory.point(0, 0), @geo_factory.point(10, 0), @geo_factory.point(10, 10), @geo_factory.point(0, 10), @geo_factory.point(0, 0)]), [@geo_factory.linear_ring([@geo_factory.point(4, 4), @geo_factory.point(6, 5), @geo_factory.point(4, 6), @geo_factory.point(4, 4)])])
|
125
|
+
json_ = {
|
126
|
+
'type' => 'Polygon',
|
127
|
+
'coordinates' => [[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[4.0, 4.0], [6.0, 5.0], [4.0, 6.0], [4.0, 4.0]]],
|
128
|
+
}
|
129
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
130
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
def test_multi_point
|
135
|
+
object_ = @geo_factory.multi_point([@geo_factory.point(10, 20), @geo_factory.point(12, 22), @geo_factory.point(-3, 24)])
|
136
|
+
json_ = {
|
137
|
+
'type' => 'MultiPoint',
|
138
|
+
'coordinates' => [[10.0, 20.0], [12.0, 22.0], [-3.0, 24.0]],
|
139
|
+
}
|
140
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
141
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
def test_multi_line_string
|
146
|
+
object_ = @geo_factory.multi_line_string([@geo_factory.line_string([@geo_factory.point(10, 20), @geo_factory.point(12, 22), @geo_factory.point(-3, 24)]), @geo_factory.line_string([@geo_factory.point(1, 2), @geo_factory.point(3, 4)])])
|
147
|
+
json_ = {
|
148
|
+
'type' => 'MultiLineString',
|
149
|
+
'coordinates' => [[[10.0, 20.0], [12.0, 22.0], [-3.0, 24.0]], [[1.0, 2.0], [3.0, 4.0]]],
|
150
|
+
}
|
151
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
152
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
def test_multi_polygon
|
157
|
+
object_ = @geo_factory.multi_polygon([@geo_factory.polygon(@geo_factory.linear_ring([@geo_factory.point(0, 0), @geo_factory.point(10, 0), @geo_factory.point(10, 10), @geo_factory.point(0, 10), @geo_factory.point(0, 0)]), [@geo_factory.linear_ring([@geo_factory.point(4, 4), @geo_factory.point(6, 5), @geo_factory.point(4, 6), @geo_factory.point(4, 4)])]), @geo_factory.polygon(@geo_factory.linear_ring([@geo_factory.point(-10,-10), @geo_factory.point(-15, -10), @geo_factory.point(-10, -15), @geo_factory.point(-10, -10)]))])
|
158
|
+
json_ = {
|
159
|
+
'type' => 'MultiPolygon',
|
160
|
+
'coordinates' => [[[[0.0, 0.0], [10.0, 0.0], [10.0, 10.0], [0.0, 10.0], [0.0, 0.0]], [[4.0, 4.0], [6.0, 5.0], [4.0, 6.0], [4.0, 4.0]]], [[[-10.0, -10.0], [-15.0, -10.0], [-10.0, -15.0], [-10.0, -10.0]]]]
|
161
|
+
}
|
162
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
163
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
def test_geometry_collection
|
168
|
+
object_ = @geo_factory.collection([@geo_factory.point(10, 20), @geo_factory.collection([@geo_factory.point(12, 22), @geo_factory.point(-3, 24)])])
|
169
|
+
json_ = {
|
170
|
+
'type' => 'GeometryCollection',
|
171
|
+
'geometries' => [
|
172
|
+
{
|
173
|
+
'type' => 'Point',
|
174
|
+
'coordinates' => [10.0, 20.0],
|
175
|
+
},
|
176
|
+
{
|
177
|
+
'type' => 'GeometryCollection',
|
178
|
+
'geometries' => [
|
179
|
+
{
|
180
|
+
'type' => 'Point',
|
181
|
+
'coordinates' => [12.0, 22.0],
|
182
|
+
},
|
183
|
+
{
|
184
|
+
'type' => 'Point',
|
185
|
+
'coordinates' => [-3.0, 24.0],
|
186
|
+
},
|
187
|
+
],
|
188
|
+
},
|
189
|
+
],
|
190
|
+
}
|
191
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
192
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
193
|
+
end
|
194
|
+
|
195
|
+
|
196
|
+
def test_feature
|
197
|
+
object_ = @entity_factory.feature(@geo_factory.point(10, 20))
|
198
|
+
json_ = {
|
199
|
+
'type' => 'Feature',
|
200
|
+
'geometry' => {
|
201
|
+
'type' => 'Point',
|
202
|
+
'coordinates' => [10.0, 20.0],
|
203
|
+
},
|
204
|
+
'properties' => {},
|
205
|
+
}
|
206
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
207
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
def test_feature_nulls
|
212
|
+
json_ = {
|
213
|
+
'type' => 'Feature',
|
214
|
+
'geometry' => nil,
|
215
|
+
'properties' => nil,
|
216
|
+
}
|
217
|
+
obj_ = ::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory)
|
218
|
+
assert_not_nil(obj_)
|
219
|
+
assert_nil(obj_.geometry)
|
220
|
+
assert_equal({}, obj_.properties)
|
221
|
+
end
|
222
|
+
|
223
|
+
|
224
|
+
def test_feature_complex
|
225
|
+
object_ = @entity_factory.feature(@geo_factory.point(10, 20), 2, {'prop1' => 'foo', 'prop2' => 'bar'})
|
226
|
+
json_ = {
|
227
|
+
'type' => 'Feature',
|
228
|
+
'geometry' => {
|
229
|
+
'type' => 'Point',
|
230
|
+
'coordinates' => [10.0, 20.0],
|
231
|
+
},
|
232
|
+
'id' => 2,
|
233
|
+
'properties' => {'prop1' => 'foo', 'prop2' => 'bar'},
|
234
|
+
}
|
235
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
236
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
237
|
+
end
|
238
|
+
|
239
|
+
|
240
|
+
def test_feature_collection
|
241
|
+
object_ = @entity_factory.feature_collection([@entity_factory.feature(@geo_factory.point(10, 20)), @entity_factory.feature(@geo_factory.point(11, 22)), @entity_factory.feature(@geo_factory.point(10, 20), 8)])
|
242
|
+
json_ = {
|
243
|
+
'type' => 'FeatureCollection',
|
244
|
+
'features' => [
|
245
|
+
{
|
246
|
+
'type' => 'Feature',
|
247
|
+
'geometry' => {
|
248
|
+
'type' => 'Point',
|
249
|
+
'coordinates' => [10.0, 20.0],
|
250
|
+
},
|
251
|
+
'properties' => {},
|
252
|
+
},
|
253
|
+
{
|
254
|
+
'type' => 'Feature',
|
255
|
+
'geometry' => {
|
256
|
+
'type' => 'Point',
|
257
|
+
'coordinates' => [11.0, 22.0],
|
258
|
+
},
|
259
|
+
'properties' => {},
|
260
|
+
},
|
261
|
+
{
|
262
|
+
'type' => 'Feature',
|
263
|
+
'geometry' => {
|
264
|
+
'type' => 'Point',
|
265
|
+
'coordinates' => [10.0, 20.0],
|
266
|
+
},
|
267
|
+
'id' => 8,
|
268
|
+
'properties' => {},
|
269
|
+
},
|
270
|
+
]
|
271
|
+
}
|
272
|
+
assert_equal(json_, ::RGeo::GeoJSON.encode(object_))
|
273
|
+
assert(::RGeo::GeoJSON.decode(json_, :geo_factory => @geo_factory).eql?(object_))
|
274
|
+
end
|
275
|
+
|
276
|
+
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|