rgeo-geojson 2.1.0 → 2.2.0
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/History.md +11 -0
- data/README.md +1 -1
- data/lib/rgeo/geo_json/coder.rb +4 -5
- data/lib/rgeo/geo_json/collection_methods.rb +35 -0
- data/lib/rgeo/geo_json/conversion_methods.rb +50 -0
- data/lib/rgeo/geo_json/entities.rb +41 -25
- data/lib/rgeo/geo_json/interface.rb +5 -4
- data/lib/rgeo/geo_json/version.rb +3 -1
- data/lib/rgeo/geo_json.rb +8 -5
- data/lib/rgeo-geojson.rb +3 -1
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 448049463c510bdeb2fa366eaa3834566962116632675ccb509134cc54875fc0
|
4
|
+
data.tar.gz: 7a6c7b327824850c164d3fca314347256e9b8513574afae86687361e92b00c26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6009ac4f8cdd344ca8403235a20d40c71b9dcf891c17a3646650a8b307d863dd5bf2b63d1ce58bcd768f7d394a572f5f14f822ea294818a7c42e307839e0bb6
|
7
|
+
data.tar.gz: 8a53d85316ec32a69a36a287bc6a5f44702427f2b54b9720da82e91fa599aa33e6fd7ccf600f06a1c01442675cf8b267c749506c32151f798c310e4c6060286e
|
data/History.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
### 2.2.0 / 2024-07-22
|
2
|
+
|
3
|
+
* Delegation to inner geometry for a feature (#53)
|
4
|
+
* MultiJson rather than JSON (#46)
|
5
|
+
* Conversion methods for better integration with core (#56)
|
6
|
+
|
7
|
+
### 2.1.1 / 2018-11-27
|
8
|
+
|
9
|
+
* Freeze strings
|
10
|
+
|
11
|
+
|
1
12
|
### 2.1.0 / 2018-11-27
|
2
13
|
|
3
14
|
* Allow rgeo 2.0
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# rgeo-geojson
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/rgeo-geojson)
|
4
|
-
[](https://github.com/rgeo/rgeo-geojson/actions?query=workflow%3ACI+branch%3Amaster+event%3Apush)
|
5
5
|
|
6
6
|
`rgeo-geojson` is an extension to [RGeo](https://github.com/rgeo/rgeo)
|
7
7
|
that provides GeoJSON encoding and decoding.
|
data/lib/rgeo/geo_json/coder.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RGeo
|
2
4
|
module GeoJSON
|
3
5
|
# This object encapsulates encoding and decoding settings (principally
|
4
6
|
# the RGeo::Feature::Factory and the RGeo::GeoJSON::EntityFactory to
|
5
7
|
# be used) so that you can encode and decode without specifying those
|
6
8
|
# settings every time.
|
7
|
-
|
8
9
|
class Coder
|
9
10
|
# Create a new coder settings object. The geo factory is passed as
|
10
11
|
# a required argument.
|
@@ -39,7 +40,6 @@ module RGeo
|
|
39
40
|
# appropriate JSON library installed.
|
40
41
|
#
|
41
42
|
# Returns nil if nil is passed in as the object.
|
42
|
-
|
43
43
|
def encode(object)
|
44
44
|
if @entity_factory.is_feature_collection?(object)
|
45
45
|
{
|
@@ -58,13 +58,12 @@ module RGeo
|
|
58
58
|
# Decode an object from GeoJSON. The input may be a JSON hash, a
|
59
59
|
# String, or an IO object from which to read the JSON string.
|
60
60
|
# If an error occurs, nil is returned.
|
61
|
-
|
62
61
|
def decode(input)
|
63
62
|
if input.is_a?(IO)
|
64
63
|
input = input.read rescue nil
|
65
64
|
end
|
66
65
|
if input.is_a?(String)
|
67
|
-
input =
|
66
|
+
input = MultiJson.load(input)
|
68
67
|
end
|
69
68
|
return unless input.is_a?(Hash)
|
70
69
|
|
@@ -193,7 +192,7 @@ module RGeo
|
|
193
192
|
|
194
193
|
def decode_point_coords(point_coords)
|
195
194
|
return unless point_coords.is_a?(Array)
|
196
|
-
@geo_factory.point(*
|
195
|
+
@geo_factory.point(*point_coords[0...@num_coordinates].map(&:to_f)) rescue nil
|
197
196
|
end
|
198
197
|
|
199
198
|
def decode_line_string_coords(line_coords)
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RGeo
|
4
|
+
# This module is here to fill the gap between what is a GeometryCollection (GIS)
|
5
|
+
# and a FeatureCollection (GeoJSON).
|
6
|
+
#
|
7
|
+
# Note for contributors, you can rely on `@features` to be defined and
|
8
|
+
# you can consider working with an Enumerable wrapping `@features`. See
|
9
|
+
# GeoJSON::FeatureCollection.
|
10
|
+
module GeoJSON::CollectionMethods
|
11
|
+
# There is tight coupling between {FeatureCollection} and this, hence the
|
12
|
+
# guard.
|
13
|
+
private_class_method def self.included(base)
|
14
|
+
return if base.to_s == "RGeo::GeoJSON::FeatureCollection"
|
15
|
+
|
16
|
+
raise Error::RGeoError, "#{self.class} must only be used by FeatureCollection"
|
17
|
+
end
|
18
|
+
|
19
|
+
private def method_missing(symbol, *args)
|
20
|
+
return super unless any? { |feature| feature.respond_to?(symbol) }
|
21
|
+
|
22
|
+
raise Error::UnsupportedOperation, "Method FeatureCollection##{symbol} " \
|
23
|
+
"is not defined. You may consider filing an issue or opening a pull " \
|
24
|
+
"request at https://github.com/rgeo/rgeo-geojson"
|
25
|
+
end
|
26
|
+
|
27
|
+
def contains?(geometry)
|
28
|
+
any? { |feature| feature.contains?(geometry) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def intersects?(geometry)
|
32
|
+
any? { |feature| feature.intersects?(geometry) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RGeo
|
4
|
+
# This module serves to provide handy methods when using GeoJSON. The methods
|
5
|
+
# provided eases the passage between entities and GeoJSON String/Hash.
|
6
|
+
module GeoJSON::ConversionMethods
|
7
|
+
# Convert a geometry to a GeoJSON Hash
|
8
|
+
def as_geojson
|
9
|
+
GeoJSON.encode(self)
|
10
|
+
end
|
11
|
+
alias as_json as_geojson
|
12
|
+
|
13
|
+
# Convert a geometry to a GeoJSON String
|
14
|
+
def to_geojson
|
15
|
+
::MultiJson.dump(as_geojson)
|
16
|
+
end
|
17
|
+
alias to_json to_geojson
|
18
|
+
end
|
19
|
+
|
20
|
+
# These convenience methods are added directly into the module rather than
|
21
|
+
# including the module above into the Feature::Instance module which is in
|
22
|
+
# every geometry implementation. This is due to a behavior in ruby versions
|
23
|
+
# <3.0.2 where dynamically included modules will not be included automatically
|
24
|
+
# in the ancestor tree.
|
25
|
+
# See https://bugs.ruby-lang.org/issues/9573 for more information.
|
26
|
+
module Feature
|
27
|
+
module Instance
|
28
|
+
# Convert a geometry to a GeoJSON Hash
|
29
|
+
def as_geojson
|
30
|
+
GeoJSON.encode(self)
|
31
|
+
end
|
32
|
+
alias as_json as_geojson
|
33
|
+
|
34
|
+
# Convert a geometry to a GeoJSON String
|
35
|
+
def to_geojson
|
36
|
+
::MultiJson.dump(as_geojson)
|
37
|
+
end
|
38
|
+
alias to_json to_geojson
|
39
|
+
end
|
40
|
+
|
41
|
+
module Factory::Instance
|
42
|
+
# Parses a GeoJSON String/Hash, or an IO object from which
|
43
|
+
# the JSON string is read and returns the corresponding
|
44
|
+
# feature. Returns nil if unable to parse.
|
45
|
+
def parse_geojson(input)
|
46
|
+
GeoJSON.decode(input, geo_factory: self)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -1,5 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "collection_methods"
|
4
|
+
require_relative "conversion_methods"
|
5
|
+
|
1
6
|
module RGeo
|
7
|
+
module CastOverlay
|
8
|
+
def self.included(base)
|
9
|
+
# The original {RGeo::Feature.cast} would copy a GeoJSON::Feature, which
|
10
|
+
# fails most operations. When casting, we MUST get a geometry.
|
11
|
+
original_cast = base.method(:cast)
|
12
|
+
base.define_singleton_method(:cast) do |obj, *params|
|
13
|
+
if obj.class == GeoJSON::Feature
|
14
|
+
original_cast.call(obj.geometry, *params)
|
15
|
+
else
|
16
|
+
original_cast.call(obj, *params)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
Feature.include(CastOverlay)
|
22
|
+
|
2
23
|
module GeoJSON
|
24
|
+
# Simplify usage of inner geometries for Feature and FeatureCollection
|
25
|
+
# objets. Including class must contain a `#geometry` method.
|
26
|
+
module DelegateToGeometry
|
27
|
+
private def method_missing(symbol, *args)
|
28
|
+
return geometry.public_send(symbol, *args) if geometry
|
29
|
+
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
private def respond_to_missing?(symbol, *)
|
34
|
+
geometry&.respond_to?(symbol) || super
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
3
38
|
# This is a GeoJSON wrapper entity that corresponds to the GeoJSON
|
4
39
|
# "Feature" type. It is an immutable type.
|
5
40
|
#
|
@@ -9,11 +44,12 @@ module RGeo
|
|
9
44
|
# implementation need not subclass or even duck-type this class.
|
10
45
|
# the entity factory mediates all interaction between the GeoJSON
|
11
46
|
# engine and features.
|
12
|
-
|
13
47
|
class Feature
|
48
|
+
include DelegateToGeometry
|
49
|
+
include ConversionMethods
|
50
|
+
|
14
51
|
# Create a feature wrapping the given geometry, with the given ID
|
15
52
|
# and properties.
|
16
|
-
|
17
53
|
def initialize(geometry, id = nil, properties = {})
|
18
54
|
@geometry = geometry
|
19
55
|
@id = id
|
@@ -39,7 +75,6 @@ module RGeo
|
|
39
75
|
# are all equal.
|
40
76
|
# This method uses the eql? method to test geometry equality, which
|
41
77
|
# may behave differently than the == operator.
|
42
|
-
|
43
78
|
def eql?(other)
|
44
79
|
other.is_a?(Feature) && @geometry.eql?(other.geometry) && @id.eql?(other.feature_id) && @properties.eql?(other.instance_variable_get(:@properties))
|
45
80
|
end
|
@@ -48,37 +83,31 @@ module RGeo
|
|
48
83
|
# are all equal.
|
49
84
|
# This method uses the == operator to test geometry equality, which
|
50
85
|
# may behave differently than the eql? method.
|
51
|
-
|
52
86
|
def ==(other)
|
53
87
|
other.is_a?(Feature) && @geometry == other.geometry && @id == other.feature_id && @properties == other.instance_variable_get(:@properties)
|
54
88
|
end
|
55
89
|
|
56
90
|
# Returns the geometry contained in this feature, which may be nil.
|
57
|
-
|
58
91
|
attr_reader :geometry
|
59
92
|
|
60
93
|
# Returns the ID for this feature, which may be nil.
|
61
|
-
|
62
94
|
def feature_id
|
63
95
|
@id
|
64
96
|
end
|
65
97
|
|
66
98
|
# Returns a copy of the properties for this feature.
|
67
|
-
|
68
99
|
def properties
|
69
100
|
@properties.dup
|
70
101
|
end
|
71
102
|
|
72
103
|
# Gets the value of the given named property.
|
73
104
|
# Returns nil if the given property is not found.
|
74
|
-
|
75
105
|
def property(key)
|
76
106
|
@properties[key.to_s]
|
77
107
|
end
|
78
108
|
alias [] property
|
79
109
|
|
80
110
|
# Gets an array of the known property keys in this feature.
|
81
|
-
|
82
111
|
def keys
|
83
112
|
@properties.keys
|
84
113
|
end
|
@@ -93,16 +122,17 @@ module RGeo
|
|
93
122
|
# FeatureCollection implementation need not subclass or even
|
94
123
|
# duck-type this class. The entity factory mediates all interaction
|
95
124
|
# between the GeoJSON engine and feature collections.
|
96
|
-
|
97
125
|
class FeatureCollection
|
98
126
|
include Enumerable
|
127
|
+
include CollectionMethods
|
128
|
+
include ConversionMethods
|
99
129
|
|
100
130
|
# Create a new FeatureCollection with the given features, which must
|
101
131
|
# be provided as an Enumerable.
|
102
|
-
|
103
132
|
def initialize(features = [])
|
104
133
|
@features = []
|
105
134
|
features.each { |f| @features << f if f.is_a?(Feature) }
|
135
|
+
@features.freeze
|
106
136
|
end
|
107
137
|
|
108
138
|
def inspect
|
@@ -121,7 +151,6 @@ module RGeo
|
|
121
151
|
# features in the same order.
|
122
152
|
# This methods uses the eql? method to test geometry equality, which
|
123
153
|
# may behave differently than the == operator.
|
124
|
-
|
125
154
|
def eql?(other)
|
126
155
|
other.is_a?(FeatureCollection) && @features.eql?(other.instance_variable_get(:@features))
|
127
156
|
end
|
@@ -130,25 +159,21 @@ module RGeo
|
|
130
159
|
# features in the same order.
|
131
160
|
# This methods uses the == operator to test geometry equality, which
|
132
161
|
# may behave differently than the eql? method.
|
133
|
-
|
134
162
|
def ==(other)
|
135
163
|
other.is_a?(FeatureCollection) && @features == other.instance_variable_get(:@features)
|
136
164
|
end
|
137
165
|
|
138
166
|
# Iterates or returns an iterator for the features.
|
139
|
-
|
140
167
|
def each(&block)
|
141
168
|
@features.each(&block)
|
142
169
|
end
|
143
170
|
|
144
171
|
# Returns the number of features contained in this collection.
|
145
|
-
|
146
172
|
def size
|
147
173
|
@features.size
|
148
174
|
end
|
149
175
|
|
150
176
|
# Access a feature by index.
|
151
|
-
|
152
177
|
def [](index)
|
153
178
|
@features[index]
|
154
179
|
end
|
@@ -162,60 +187,51 @@ module RGeo
|
|
162
187
|
# Create and return a new feature, given geometry, ID, and
|
163
188
|
# properties hash. Note that, per the GeoJSON spec, geometry and/or
|
164
189
|
# properties may be nil.
|
165
|
-
|
166
190
|
def feature(geometry, id = nil, properties = nil)
|
167
191
|
Feature.new(geometry, id, properties || {})
|
168
192
|
end
|
169
193
|
|
170
194
|
# Create and return a new feature collection, given an enumerable
|
171
195
|
# of feature objects.
|
172
|
-
|
173
196
|
def feature_collection(features = [])
|
174
197
|
FeatureCollection.new(features)
|
175
198
|
end
|
176
199
|
|
177
200
|
# Returns true if the given object is a feature created by this
|
178
201
|
# entity factory.
|
179
|
-
|
180
202
|
def is_feature?(object)
|
181
203
|
object.is_a?(Feature)
|
182
204
|
end
|
183
205
|
|
184
206
|
# Returns true if the given object is a feature collection created
|
185
207
|
# by this entity factory.
|
186
|
-
|
187
208
|
def is_feature_collection?(object)
|
188
209
|
object.is_a?(FeatureCollection)
|
189
210
|
end
|
190
211
|
|
191
212
|
# Run Enumerable#map on the features contained in the given feature
|
192
213
|
# collection.
|
193
|
-
|
194
214
|
def map_feature_collection(object, &block)
|
195
215
|
object.map(&block)
|
196
216
|
end
|
197
217
|
|
198
218
|
# Returns the geometry associated with the given feature.
|
199
|
-
|
200
219
|
def get_feature_geometry(object)
|
201
220
|
object.geometry
|
202
221
|
end
|
203
222
|
|
204
223
|
# Returns the ID of the given feature, or nil for no ID.
|
205
|
-
|
206
224
|
def get_feature_id(object)
|
207
225
|
object.feature_id
|
208
226
|
end
|
209
227
|
|
210
228
|
# Returns the properties of the given feature as a hash. Editing
|
211
229
|
# this hash does not change the state of the feature.
|
212
|
-
|
213
230
|
def get_feature_properties(object)
|
214
231
|
object.properties
|
215
232
|
end
|
216
233
|
|
217
234
|
# Return the singleton instance of EntityFactory.
|
218
|
-
|
219
235
|
def self.instance
|
220
236
|
@instance ||= new
|
221
237
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module RGeo
|
2
4
|
module GeoJSON
|
3
5
|
class << self
|
@@ -11,9 +13,8 @@ module RGeo
|
|
11
13
|
# RGeo::GeoJSON::EntityFactory for more information. By default,
|
12
14
|
# encode supports objects of type RGeo::GeoJSON::Feature and
|
13
15
|
# RGeo::GeoJSON::FeatureCollection.
|
14
|
-
|
15
16
|
def encode(object, opts = {})
|
16
|
-
|
17
|
+
coder(opts).encode(object)
|
17
18
|
end
|
18
19
|
|
19
20
|
# High-level convenience routine for decoding an object from GeoJSON.
|
@@ -31,8 +32,8 @@ module RGeo
|
|
31
32
|
# RGeo::GeoJSON::EntityFactory, which generates objects of type
|
32
33
|
# RGeo::GeoJSON::Feature or RGeo::GeoJSON::FeatureCollection.
|
33
34
|
# See RGeo::GeoJSON::EntityFactory for more information.
|
34
|
-
def decode(
|
35
|
-
|
35
|
+
def decode(input, opts = {})
|
36
|
+
coder(opts).decode(input)
|
36
37
|
end
|
37
38
|
|
38
39
|
# Creates and returns a coder object of type RGeo::GeoJSON::Coder
|
data/lib/rgeo/geo_json.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "rgeo"
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
require_relative "geo_json/version"
|
5
|
+
require_relative "geo_json/conversion_methods"
|
6
|
+
require_relative "geo_json/entities"
|
7
|
+
require_relative "geo_json/coder"
|
8
|
+
require_relative "geo_json/interface"
|
9
|
+
require "multi_json"
|
data/lib/rgeo-geojson.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rgeo-geojson
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Azuma
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2024-07-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rgeo
|
@@ -26,19 +26,19 @@ dependencies:
|
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 1.0.0
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: multi_json
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '1.
|
35
|
-
type: :
|
34
|
+
version: '1.15'
|
35
|
+
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '1.
|
41
|
+
version: '1.15'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: minitest
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,6 +72,7 @@ description: Convert RGeo data to and from GeoJSON. rgeo-geojson is an extension
|
|
72
72
|
email:
|
73
73
|
- dazuma@gmail.com
|
74
74
|
- parhameter@gmail.com
|
75
|
+
- kfdoggett@gmail.com
|
75
76
|
executables: []
|
76
77
|
extensions: []
|
77
78
|
extra_rdoc_files: []
|
@@ -82,12 +83,14 @@ files:
|
|
82
83
|
- lib/rgeo-geojson.rb
|
83
84
|
- lib/rgeo/geo_json.rb
|
84
85
|
- lib/rgeo/geo_json/coder.rb
|
86
|
+
- lib/rgeo/geo_json/collection_methods.rb
|
87
|
+
- lib/rgeo/geo_json/conversion_methods.rb
|
85
88
|
- lib/rgeo/geo_json/entities.rb
|
86
89
|
- lib/rgeo/geo_json/interface.rb
|
87
90
|
- lib/rgeo/geo_json/version.rb
|
88
91
|
homepage: https://github.com/rgeo/rgeo-geojson
|
89
92
|
licenses:
|
90
|
-
- BSD
|
93
|
+
- BSD-3-Clause
|
91
94
|
metadata: {}
|
92
95
|
post_install_message:
|
93
96
|
rdoc_options: []
|
@@ -104,8 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
107
|
- !ruby/object:Gem::Version
|
105
108
|
version: '0'
|
106
109
|
requirements: []
|
107
|
-
|
108
|
-
rubygems_version: 2.7.8
|
110
|
+
rubygems_version: 3.5.2
|
109
111
|
signing_key:
|
110
112
|
specification_version: 4
|
111
113
|
summary: Convert RGeo data to and from GeoJSON.
|