rgeo-geojson 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/rgeo-geojson.svg)](http://badge.fury.io/rb/rgeo-geojson)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/rgeo/rgeo-geojson/workflows/CI/badge.svg)](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.
|