charta 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/charta/geometry.rb +83 -42
- data/lib/charta/version.rb +1 -1
- data/lib/charta.rb +19 -12
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b57d9dc1461dc8978d34f13e8724d173fcb9a95a
|
4
|
+
data.tar.gz: 7dda0f7c5d00088060e6475b88a770bb19365f06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4b1f0c6e499b09df8c156d3bf449f5655c4f686586624f42b6cf8b8d2bb1efede40e1d53444a2f70d64f24f70502edc153d51acba254c7643eab0935233b4e3
|
7
|
+
data.tar.gz: 2db91883e43df8348abeffb14398613b1e8503e5bc12e182c1d241ef18da05d8ef35fefabe71711153e2665ba5bd135857e2899dee95cb7f95816aed8cc09b82
|
data/lib/charta/geometry.rb
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
require 'json'
|
2
2
|
require 'rgeo/geo_json'
|
3
3
|
require 'rgeo/svg' # integrated lib for now
|
4
|
+
require 'byebug'
|
4
5
|
|
5
6
|
module Charta
|
6
7
|
# Represents a Geometry with SRID
|
7
8
|
class Geometry
|
8
|
-
def initialize(
|
9
|
-
@
|
9
|
+
def initialize(feature, properties = {})
|
10
|
+
@feature = feature
|
10
11
|
@properties = properties
|
11
|
-
raise ArgumentError, 'Need EWKT to instantiate Geometry' if @ewkt.to_s =~ /\A[[:space:]]*\z/
|
12
|
+
# raise ArgumentError, 'Need EWKT to instantiate Geometry' if @ewkt.to_s =~ /\A[[:space:]]*\z/
|
12
13
|
end
|
13
14
|
|
14
15
|
def inspect
|
@@ -18,7 +19,7 @@ module Charta
|
|
18
19
|
# Returns the type of the geometry as a string. Example: point,
|
19
20
|
# multi_polygon, geometry_collection...
|
20
21
|
def type
|
21
|
-
Charta.underscore(feature.geometry_type.type_name).to_sym
|
22
|
+
Charta.underscore(@feature.geometry_type.type_name).to_sym
|
22
23
|
end
|
23
24
|
|
24
25
|
# Returns the type of the geometry as a string. EG: 'ST_Linestring', 'ST_Polygon',
|
@@ -26,29 +27,29 @@ module Charta
|
|
26
27
|
# in the case of the string and ST in front that is returned, as well as the fact
|
27
28
|
# that it will not indicate whether the geometry is measured.
|
28
29
|
def collection?
|
29
|
-
feature.geometry_type == RGeo::Feature::GeometryCollection
|
30
|
+
@feature.geometry_type == RGeo::Feature::GeometryCollection
|
30
31
|
end
|
31
32
|
|
32
33
|
# Return the spatial reference identifier for the ST_Geometry
|
33
34
|
def srid
|
34
|
-
feature.srid.to_i
|
35
|
+
@feature.srid.to_i
|
35
36
|
end
|
36
37
|
|
37
38
|
# Returns the underlaying object managed by Charta: the RGeo feature
|
38
39
|
def to_rgeo
|
39
|
-
feature
|
40
|
+
@feature
|
40
41
|
end
|
41
42
|
|
42
43
|
# Returns the Well-Known Text (WKT) representation of the geometry/geography without SRID metadata
|
43
44
|
def to_text
|
44
|
-
feature.as_text
|
45
|
+
@feature.as_text
|
45
46
|
end
|
46
47
|
alias as_text to_text
|
47
48
|
alias to_wkt to_text
|
48
49
|
|
49
50
|
# Returns EWKT: WKT with its SRID
|
50
51
|
def to_ewkt
|
51
|
-
@
|
52
|
+
Charta.generate_ewkt(@feature).to_s
|
52
53
|
end
|
53
54
|
alias to_s to_ewkt
|
54
55
|
|
@@ -60,7 +61,7 @@ module Charta
|
|
60
61
|
# Return the Well-Known Binary (WKB) representation of the geometry with SRID meta data.
|
61
62
|
def to_binary
|
62
63
|
generator = RGeo::WKRep::WKBGenerator.new(tag_format: :ewkbt, emit_ewkbt_srid: true)
|
63
|
-
generator.generate(feature)
|
64
|
+
generator.generate(@feature)
|
64
65
|
end
|
65
66
|
alias to_ewkb to_binary
|
66
67
|
|
@@ -78,7 +79,7 @@ module Charta
|
|
78
79
|
|
79
80
|
# Return the geometry as Scalar Vector Graphics (SVG) path data.
|
80
81
|
def to_svg_path
|
81
|
-
RGeo::SVG.encode(feature)
|
82
|
+
RGeo::SVG.encode(@feature)
|
82
83
|
end
|
83
84
|
|
84
85
|
# Return the geometry as a Geometry Javascript Object Notation (GeoJSON) element.
|
@@ -89,7 +90,7 @@ module Charta
|
|
89
90
|
|
90
91
|
# Returns object in JSON (Hash)
|
91
92
|
def to_json_object
|
92
|
-
RGeo::GeoJSON.encode(feature)
|
93
|
+
RGeo::GeoJSON.encode(@feature)
|
93
94
|
end
|
94
95
|
|
95
96
|
# Test if the other measure is equal to self
|
@@ -97,7 +98,7 @@ module Charta
|
|
97
98
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
98
99
|
return true if empty? && other_geometry.empty?
|
99
100
|
return inspect == other_geometry.inspect if collection? && other_geometry.collection?
|
100
|
-
feature.equals?(other_geometry.feature)
|
101
|
+
@feature.equals?(other_geometry.feature)
|
101
102
|
end
|
102
103
|
|
103
104
|
# Test if the other measure is equal to self
|
@@ -105,23 +106,23 @@ module Charta
|
|
105
106
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
106
107
|
return true if empty? && other_geometry.empty?
|
107
108
|
return inspect == other_geometry.inspect if collection? && other_geometry.collection?
|
108
|
-
|
109
|
+
!@feature.equals?(other_geometry.feature)
|
109
110
|
end
|
110
111
|
|
111
112
|
# Returns true if Geometry is a Surface
|
112
113
|
def surface?
|
113
|
-
[RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? feature.geometry_type
|
114
|
+
[RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? @feature.geometry_type
|
114
115
|
end
|
115
116
|
|
116
117
|
# Returns area in unit corresponding to the SRS
|
117
118
|
def area
|
118
|
-
surface? ? feature.area : 0
|
119
|
+
surface? ? @feature.area : 0
|
119
120
|
end
|
120
121
|
|
121
122
|
# Returns true if this Geometry is an empty geometrycollection, polygon,
|
122
123
|
# point etc.
|
123
124
|
def empty?
|
124
|
-
feature.is_empty?
|
125
|
+
@feature.is_empty?
|
125
126
|
end
|
126
127
|
alias blank? empty?
|
127
128
|
|
@@ -129,14 +130,14 @@ module Charta
|
|
129
130
|
# of mass of the geometry as a POINT.
|
130
131
|
def centroid
|
131
132
|
return nil unless surface?
|
132
|
-
point = feature.centroid
|
133
|
+
point = @feature.centroid
|
133
134
|
[point.y, point.x]
|
134
135
|
end
|
135
136
|
|
136
137
|
# Returns a POINT guaranteed to lie on the surface.
|
137
138
|
def point_on_surface
|
138
139
|
return nil unless surface?
|
139
|
-
point = feature.point_on_surface
|
140
|
+
point = @feature.point_on_surface
|
140
141
|
[point.y, point.x]
|
141
142
|
end
|
142
143
|
|
@@ -153,9 +154,9 @@ module Charta
|
|
153
154
|
items = []
|
154
155
|
as_multi_type = "multi_#{as_type}".to_sym
|
155
156
|
if type == as_type
|
156
|
-
items << feature
|
157
|
+
items << @feature
|
157
158
|
elsif as_type == :geometry_collection
|
158
|
-
feature.each do |geom|
|
159
|
+
@feature.each do |geom|
|
159
160
|
type_name = Charta.underscore(geom.geometry_type.type_name).to_sym
|
160
161
|
if type_name == as_type
|
161
162
|
items << geom
|
@@ -166,7 +167,7 @@ module Charta
|
|
166
167
|
end
|
167
168
|
end
|
168
169
|
end
|
169
|
-
Charta.new_geometry(feature.factory.send(as_multi_type, items))
|
170
|
+
Charta.new_geometry(@feature.factory.send(as_multi_type, items))
|
170
171
|
end
|
171
172
|
|
172
173
|
# Returns a new geometry with the coordinates converted into the new SRS
|
@@ -179,39 +180,39 @@ module Charta
|
|
179
180
|
raise "Cannot find proj for SRID: #{new_srid}" if new_proj_entry.nil?
|
180
181
|
new_feature = RGeo::CoordSys::Proj4.transform(
|
181
182
|
database.get(srid).proj4,
|
182
|
-
feature,
|
183
|
+
@feature,
|
183
184
|
new_proj_entry.proj4,
|
184
185
|
self.class.factory(new_srid)
|
185
186
|
)
|
186
187
|
generator = RGeo::WKRep::WKTGenerator.new(tag_format: :ewkt, emit_ewkt_srid: true)
|
187
|
-
|
188
|
+
Charta.new_geometry(generator.generate(new_feature))
|
188
189
|
end
|
189
190
|
|
190
191
|
# Produces buffer
|
191
192
|
def buffer(radius)
|
192
|
-
feature.buffer(radius)
|
193
|
+
@feature.buffer(radius)
|
193
194
|
end
|
194
195
|
|
195
196
|
def merge(other)
|
196
197
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
197
|
-
feature.union(other_geometry.feature)
|
198
|
+
@feature.union(other_geometry.feature)
|
198
199
|
end
|
199
200
|
alias + merge
|
200
201
|
|
201
202
|
def intersection(other)
|
202
203
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
203
|
-
feature.intersection(other_geometry.feature)
|
204
|
+
@feature.intersection(other_geometry.feature)
|
204
205
|
end
|
205
206
|
|
206
207
|
def difference(other)
|
207
208
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
208
|
-
feature.difference(other_geometry.feature)
|
209
|
+
@feature.difference(other_geometry.feature)
|
209
210
|
end
|
210
211
|
alias - difference
|
211
212
|
|
212
213
|
def bounding_box
|
213
214
|
unless defined? @bounding_box
|
214
|
-
bbox = RGeo::Cartesian::BoundingBox.create_from_geometry(feature)
|
215
|
+
bbox = RGeo::Cartesian::BoundingBox.create_from_geometry(@feature)
|
215
216
|
instance_variable_set('@x_min', bbox.min_x || 0)
|
216
217
|
instance_variable_set('@y_min', bbox.min_y || 0)
|
217
218
|
instance_variable_set('@x_max', bbox.max_x || 0)
|
@@ -232,7 +233,7 @@ module Charta
|
|
232
233
|
end
|
233
234
|
|
234
235
|
def feature
|
235
|
-
|
236
|
+
@feature
|
236
237
|
end
|
237
238
|
|
238
239
|
def to_json_feature
|
@@ -245,10 +246,37 @@ module Charta
|
|
245
246
|
end
|
246
247
|
|
247
248
|
def factory(srid = 4326)
|
249
|
+
return projected_factory(srid) if srid.to_i == 4326
|
250
|
+
geos_factory(srid)
|
251
|
+
end
|
252
|
+
|
253
|
+
def feature(ewkt_or_rgeo)
|
254
|
+
return from_rgeo(ewkt_or_rgeo) if ewkt_or_rgeo.is_a? RGeo::Feature::Instance
|
255
|
+
from_ewkt(ewkt_or_rgeo)
|
256
|
+
end
|
257
|
+
|
258
|
+
private
|
259
|
+
|
260
|
+
def from_rgeo(rgeo)
|
261
|
+
srid = rgeo.srid
|
262
|
+
RGeo::Feature.cast(rgeo, factory: Geometry.factory(srid))
|
263
|
+
end
|
264
|
+
|
265
|
+
def from_ewkt(ewkt)
|
266
|
+
# Cleans empty geometries
|
267
|
+
ewkt.gsub!(/(GEOMETRYCOLLECTION|GEOMETRY|((MULTI)?(POINT|LINESTRING|POLYGON)))\(\)/, '\1 EMPTY')
|
268
|
+
srs = ewkt.split(/[\=\;]+/)[0..1]
|
269
|
+
srid = nil
|
270
|
+
srid = srs[1] if srs[0] =~ /srid/i
|
271
|
+
srid ||= 4326
|
272
|
+
factory(srid).parse_wkt(ewkt)
|
273
|
+
rescue RGeo::Error::ParseError => e
|
274
|
+
raise "Invalid EWKT (#{e.class.name}: #{e.message}): #{ewkt}"
|
275
|
+
end
|
276
|
+
|
277
|
+
def geos_factory(srid)
|
248
278
|
RGeo::Geos.factory(
|
249
|
-
# srs_database: srs_database,
|
250
279
|
srid: srid,
|
251
|
-
# has_z_coordinate: true,
|
252
280
|
wkt_generator: {
|
253
281
|
type_format: :ewkt,
|
254
282
|
emit_ewkt_srid: true,
|
@@ -268,16 +296,29 @@ module Charta
|
|
268
296
|
)
|
269
297
|
end
|
270
298
|
|
271
|
-
def
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
299
|
+
def projected_factory(srid)
|
300
|
+
proj4 = '+proj=cea +lon_0=0 +lat_ts=30 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs'
|
301
|
+
RGeo::Geographic.projected_factory(
|
302
|
+
srid: srid,
|
303
|
+
wkt_generator: {
|
304
|
+
type_format: :ewkt,
|
305
|
+
emit_ewkt_srid: true,
|
306
|
+
convert_case: :upper
|
307
|
+
},
|
308
|
+
wkt_parser: {
|
309
|
+
support_ewkt: true
|
310
|
+
},
|
311
|
+
wkb_generator: {
|
312
|
+
type_format: :ewkb,
|
313
|
+
emit_ewkb_srid: true,
|
314
|
+
hex_format: true
|
315
|
+
},
|
316
|
+
wkb_parser: {
|
317
|
+
support_ewkb: true
|
318
|
+
},
|
319
|
+
projection_srid: 6933,
|
320
|
+
projection_proj4: proj4
|
321
|
+
)
|
281
322
|
end
|
282
323
|
end
|
283
324
|
end
|
data/lib/charta/version.rb
CHANGED
data/lib/charta.rb
CHANGED
@@ -25,12 +25,14 @@ module Charta
|
|
25
25
|
}.freeze
|
26
26
|
|
27
27
|
class << self
|
28
|
-
def
|
28
|
+
def new_feature(coordinates, srs = nil, format = nil, _flatten_collection = true, _options = {})
|
29
29
|
geom_ewkt = nil
|
30
|
-
if coordinates.
|
31
|
-
|
30
|
+
if coordinates.is_a?(RGeo::Feature::Instance)
|
31
|
+
return Geometry.feature(coordinates)
|
32
32
|
elsif coordinates.is_a?(::Charta::Geometry)
|
33
|
-
|
33
|
+
return coordinates
|
34
|
+
elsif coordinates.to_s =~ /\A[[:space:]]*\z/
|
35
|
+
geom_ewkt = empty_geometry(srs).to_ewkt
|
34
36
|
elsif coordinates.is_a?(Hash) || (coordinates.is_a?(String) && ::Charta::GeoJSON.valid?(coordinates)) # GeoJSON
|
35
37
|
srid = srs ? find_srid(srs) : :WGS84
|
36
38
|
geom_ewkt = ::Charta::GeoJSON.new(coordinates, srid).to_ewkt
|
@@ -66,21 +68,26 @@ module Charta
|
|
66
68
|
if geom_ewkt.to_s =~ /\A[[:space:]]*\z/
|
67
69
|
raise ArgumentError, "Invalid data: coordinates=#{coordinates.inspect}, srid=#{srid.inspect}"
|
68
70
|
end
|
69
|
-
|
70
|
-
|
71
|
+
Geometry.feature(geom_ewkt)
|
72
|
+
end
|
73
|
+
|
74
|
+
def new_geometry(coordinates, srs = nil, format = nil, _flatten_collection = true, _options = {})
|
75
|
+
return coordinates if coordinates.is_a?(::Charta::Geometry)
|
76
|
+
feature = Charta.new_feature(coordinates)
|
77
|
+
type = feature.geometry_type
|
71
78
|
geom = case type
|
72
79
|
when RGeo::Feature::Point then
|
73
|
-
Point.new(
|
80
|
+
Point.new(feature)
|
74
81
|
when RGeo::Feature::LineString then
|
75
|
-
LineString.new(
|
82
|
+
LineString.new(feature)
|
76
83
|
when RGeo::Feature::Polygon then
|
77
|
-
Polygon.new(
|
84
|
+
Polygon.new(feature)
|
78
85
|
when RGeo::Feature::MultiPolygon then
|
79
|
-
MultiPolygon.new(
|
86
|
+
MultiPolygon.new(feature)
|
80
87
|
when RGeo::Feature::GeometryCollection then
|
81
|
-
GeometryCollection.new(
|
88
|
+
GeometryCollection.new(feature)
|
82
89
|
else
|
83
|
-
Geometry.new(
|
90
|
+
Geometry.new(feature)
|
84
91
|
end
|
85
92
|
geom
|
86
93
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: charta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brice TEXIER
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|