charta 0.2.2 → 0.4.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 +5 -5
- data/charta.gemspec +21 -20
- data/lib/charta/bounding_box.rb +5 -1
- data/lib/charta/coordinates.rb +65 -0
- data/lib/charta/ewkt_serializer.rb +101 -0
- data/lib/charta/factory/ewkt_feature_builder.rb +17 -0
- data/lib/charta/factory/feature_factory_base.rb +15 -0
- data/lib/charta/factory/simple_feature_factory.rb +50 -0
- data/lib/charta/factory/simple_geometry_factory.rb +46 -0
- data/lib/charta/factory/srid_provider.rb +36 -0
- data/lib/charta/factory/transformers/ewkt_passthrough.rb +20 -0
- data/lib/charta/factory/transformers/ewkt_transformer.rb +20 -0
- data/lib/charta/factory/transformers/ewkt_transformer_chain.rb +42 -0
- data/lib/charta/factory/transformers/from_geo_json_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_gml_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_kml_transformer.rb +20 -0
- data/lib/charta/factory/transformers/from_wkb_transformer.rb +24 -0
- data/lib/charta/factory/transformers/transformation_error.rb +10 -0
- data/lib/charta/geo_json.rb +12 -124
- data/lib/charta/geometry.rb +70 -16
- data/lib/charta/geometry_collection.rb +6 -4
- data/lib/charta/gml.rb +18 -2
- data/lib/charta/gml_import.rb +24 -24
- data/lib/charta/kml.rb +21 -3
- data/lib/charta/multi_polygon.rb +1 -1
- data/lib/charta/point.rb +6 -0
- data/lib/charta/polygon.rb +5 -0
- data/lib/charta/version.rb +1 -1
- data/lib/charta.rb +39 -87
- data/lib/rgeo/svg.rb +44 -44
- metadata +78 -44
- data/.gitignore +0 -11
- data/.gitlab-ci.yml +0 -14
- data/.travis.yml +0 -7
- data/CODE_OF_CONDUCT.md +0 -74
- data/Gemfile +0 -4
- data/LICENSE.txt +0 -21
- data/README.md +0 -44
- data/Rakefile +0 -10
data/lib/charta/geo_json.rb
CHANGED
@@ -7,12 +7,14 @@ module Charta
|
|
7
7
|
|
8
8
|
def initialize(data, srid = :WGS84)
|
9
9
|
srid ||= :WGS84
|
10
|
-
@json =
|
10
|
+
@json = Coordinates.flatten(data.is_a?(Hash) ? data : JSON.parse(data))
|
11
11
|
lsrid = @json['crs']['properties']['name'] if @json.is_a?(Hash) &&
|
12
12
|
@json['crs'].is_a?(Hash) &&
|
13
13
|
@json['crs']['properties'].is_a?(Hash)
|
14
14
|
lsrid ||= srid
|
15
15
|
@srid = ::Charta.find_srid(lsrid)
|
16
|
+
|
17
|
+
@json = Coordinates.normalize_4326_geometry(@json) if @srid.to_i == 4326
|
16
18
|
end
|
17
19
|
|
18
20
|
def geom
|
@@ -24,7 +26,7 @@ module Charta
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def to_ewkt
|
27
|
-
"SRID=#{
|
29
|
+
"SRID=#{srid};" + EwktSerializer.object_to_ewkt(@json)
|
28
30
|
end
|
29
31
|
|
30
32
|
def valid?
|
@@ -42,131 +44,17 @@ module Charta
|
|
42
44
|
false
|
43
45
|
end
|
44
46
|
|
45
|
-
# Force coordinates to 2D
|
46
47
|
def flatten(hash)
|
47
|
-
|
48
|
-
flatten_feature_collection(hash)
|
49
|
-
elsif hash['type'] == 'Feature'
|
50
|
-
flatten_feature(hash)
|
51
|
-
else
|
52
|
-
flatten_geometry(hash)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def flatten_feature_collection(hash)
|
57
|
-
hash.merge('features' => hash['features'].map { |f| flatten_feature(f) })
|
58
|
-
end
|
59
|
-
|
60
|
-
def flatten_feature(hash)
|
61
|
-
hash.merge('geometry' => flatten_geometry(hash['geometry']))
|
62
|
-
end
|
63
|
-
|
64
|
-
def flatten_geometry(hash)
|
65
|
-
coordinates = hash['coordinates']
|
66
|
-
flattened =
|
67
|
-
case hash['type']
|
68
|
-
when 'Point' then
|
69
|
-
flatten_position(coordinates)
|
70
|
-
when 'MultiPoint', 'LineString'
|
71
|
-
coordinates.map { |p| flatten_position(p) }
|
72
|
-
when 'MultiLineString', 'Polygon'
|
73
|
-
coordinates.map { |l| l.map { |p| flatten_position(p) } }
|
74
|
-
when 'MultiPolygon'
|
75
|
-
coordinates.map { |m| m.map { |l| l.map { |p| flatten_position(p) } } }
|
76
|
-
when 'GeometryCollection' then
|
77
|
-
return hash.merge('geometries' => hash['geometries'].map { |g| flatten_geometry(g) })
|
78
|
-
else
|
79
|
-
raise StandardError, "Cannot handle: #{hash['type'].inspect}. In #{hash.inspect}"
|
80
|
-
end
|
81
|
-
|
82
|
-
hash.merge('coordinates' => flattened)
|
83
|
-
end
|
84
|
-
|
85
|
-
def flatten_position(position)
|
86
|
-
position[0..1]
|
87
|
-
end
|
88
|
-
|
89
|
-
def object_to_ewkt(hash)
|
90
|
-
type = hash[:type] || hash['type']
|
91
|
-
send("#{type.gsub(/(.)([A-Z])/, '\1_\2').downcase}_to_ewkt", hash)
|
92
|
-
end
|
93
|
-
|
94
|
-
def feature_collection_to_ewkt(hash)
|
95
|
-
return 'GEOMETRYCOLLECTION EMPTY' if hash['features'].nil?
|
96
|
-
'GEOMETRYCOLLECTION(' + hash['features'].collect do |feature|
|
97
|
-
object_to_ewkt(feature)
|
98
|
-
end.join(', ') + ')'
|
99
|
-
end
|
100
|
-
|
101
|
-
def geometry_collection_to_ewkt(hash)
|
102
|
-
return 'GEOMETRYCOLLECTION EMPTY' if hash['geometries'].nil?
|
103
|
-
'GEOMETRYCOLLECTION(' + hash['geometries'].collect do |feature|
|
104
|
-
object_to_ewkt(feature)
|
105
|
-
end.join(', ') + ')'
|
106
|
-
end
|
107
|
-
|
108
|
-
def feature_to_ewkt(hash)
|
109
|
-
object_to_ewkt(hash['geometry'])
|
110
|
-
end
|
111
|
-
|
112
|
-
def point_to_ewkt(hash)
|
113
|
-
return 'POINT EMPTY' if hash['coordinates'].nil?
|
114
|
-
'POINT(' + hash['coordinates'].join(' ') + ')'
|
115
|
-
end
|
116
|
-
|
117
|
-
def line_string_to_ewkt(hash)
|
118
|
-
return 'LINESTRING EMPTY' if hash['coordinates'].nil?
|
119
|
-
'LINESTRING(' + hash['coordinates'].collect do |point|
|
120
|
-
point.join(' ')
|
121
|
-
end.join(', ') + ')'
|
122
|
-
end
|
123
|
-
|
124
|
-
def polygon_to_ewkt(hash)
|
125
|
-
return 'POLYGON EMPTY' if hash['coordinates'].nil?
|
126
|
-
'POLYGON(' + hash['coordinates'].collect do |hole|
|
127
|
-
'(' + hole.collect do |point|
|
128
|
-
point.join(' ')
|
129
|
-
end.join(', ') + ')'
|
130
|
-
end.join(', ') + ')'
|
131
|
-
end
|
132
|
-
|
133
|
-
def multi_point_to_ewkt(hash)
|
134
|
-
return 'MULTIPOINT EMPTY' if hash['coordinates'].nil?
|
135
|
-
'MULTIPOINT(' + hash['coordinates'].collect do |point|
|
136
|
-
'(' + point.join(' ') + ')'
|
137
|
-
end.join(', ') + ')'
|
138
|
-
end
|
139
|
-
|
140
|
-
def multi_line_string_to_ewkt(hash)
|
141
|
-
return 'MULTILINESTRING EMPTY' if hash['coordinates'].nil?
|
142
|
-
'MULTILINESTRING(' + hash['coordinates'].collect do |line|
|
143
|
-
'(' + line.collect do |point|
|
144
|
-
point.join(' ')
|
145
|
-
end.join(', ') + ')'
|
146
|
-
end.join(', ') + ')'
|
147
|
-
end
|
148
|
-
|
149
|
-
def multipolygon_to_ewkt(hash)
|
150
|
-
return 'MULTIPOLYGON EMPTY' if hash['coordinates'].nil?
|
151
|
-
'MULTIPOLYGON(' + hash['coordinates'].collect do |polygon|
|
152
|
-
'(' + polygon.collect do |hole|
|
153
|
-
'(' + hole.collect do |point|
|
154
|
-
point.join(' ')
|
155
|
-
end.join(', ') + ')'
|
156
|
-
end.join(', ') + ')'
|
157
|
-
end.join(', ') + ')'
|
48
|
+
Coordinates.flatten hash
|
158
49
|
end
|
159
50
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
end.join(', ') + ')'
|
168
|
-
end.join(', ') + ')'
|
169
|
-
end.join(', ') + ')'
|
51
|
+
%i[
|
52
|
+
object_to_ewkt feature_collection_to_ewkt geometry_collection_to_ewkt feature_to_ewkt point_to_ewkt line_string_to_ewkt
|
53
|
+
polygon_to_ewkt multi_point_to_ewkt multi_line_string_to_ewkt multipolygon_to_ewkt multi_polygon_to_ewkt
|
54
|
+
].each do |m|
|
55
|
+
define_method m do |*args|
|
56
|
+
EwktSerializer.send m, *args
|
57
|
+
end
|
170
58
|
end
|
171
59
|
end
|
172
60
|
end
|
data/lib/charta/geometry.rb
CHANGED
@@ -2,6 +2,7 @@ require 'json'
|
|
2
2
|
require 'rgeo/geo_json'
|
3
3
|
require 'rgeo/svg' # integrated lib for now
|
4
4
|
require 'active_support/core_ext/module/delegation'
|
5
|
+
require 'victor' # for SVG
|
5
6
|
|
6
7
|
module Charta
|
7
8
|
# Represents a Geometry with SRID
|
@@ -63,16 +64,36 @@ module Charta
|
|
63
64
|
|
64
65
|
alias to_ewkb to_binary
|
65
66
|
|
66
|
-
#
|
67
|
+
# Generate SVG from geometry
|
68
|
+
# @param [Hash] options , the options for SVG object.
|
69
|
+
# @option options [Hash] :mode could be :stroke or :fill
|
70
|
+
# @option options [Hash] :color could be "orange", "red", "blue" or HTML color "#14TF15"
|
71
|
+
# @option options [Hash] :fill_opacity could be '0' to '100'
|
72
|
+
# @option options [Hash] :stroke_linecap could be 'round', 'square', 'butt'
|
73
|
+
# @option options [Hash] :stroke_linejoin default 'round'
|
74
|
+
# @option options [Hash] :stroke_width default '5%'
|
75
|
+
# @note more informations on https://developer.mozilla.org/fr/docs/Web/SVG/Tutorial/Fills_and_Strokes
|
76
|
+
# @return [String] the SVG image
|
67
77
|
def to_svg(options = {})
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
78
|
+
# set default options if not present
|
79
|
+
options[:mode] ||= :stroke
|
80
|
+
options[:color] ||= 'black'
|
81
|
+
options[:fill_opacity] ||= '100' # 0 to 100
|
82
|
+
options[:stroke_linecap] ||= 'butt' # round, square, butt
|
83
|
+
options[:stroke_linejoin] ||= 'round' #
|
84
|
+
options[:stroke_width] ||= '5%'
|
85
|
+
|
86
|
+
svg = Victor::SVG.new template: :html
|
87
|
+
svg.setup width: 180, height: 180, viewBox: bounding_box.svg_view_box.join(' ')
|
88
|
+
# return a stroke SVG with options
|
89
|
+
if options[:mode] == :stroke
|
90
|
+
svg.path d: to_svg_path, fill: 'none', stroke: options[:color], stroke_linecap: options[:stroke_linecap],
|
91
|
+
stroke_linejoin: options[:stroke_linejoin], stroke_width: options[:stroke_width]
|
92
|
+
# return a fill SVG with options
|
93
|
+
elsif options[:mode] == :fill
|
94
|
+
svg.path d: to_svg_path, fill: options[:color], fill_opacity: options[:fill_opacity]
|
73
95
|
end
|
74
|
-
svg
|
75
|
-
svg
|
96
|
+
svg.render
|
76
97
|
end
|
77
98
|
|
78
99
|
# Return the geometry as Scalar Vector Graphics (SVG) path data.
|
@@ -97,6 +118,7 @@ module Charta
|
|
97
118
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
98
119
|
return true if empty? && other_geometry.empty?
|
99
120
|
return inspect == other_geometry.inspect if collection? && other_geometry.collection?
|
121
|
+
|
100
122
|
feature.equals?(other_geometry.feature)
|
101
123
|
end
|
102
124
|
|
@@ -105,17 +127,30 @@ module Charta
|
|
105
127
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
106
128
|
return true if empty? && other_geometry.empty?
|
107
129
|
return inspect == other_geometry.inspect if collection? && other_geometry.collection?
|
130
|
+
|
108
131
|
!feature.equals?(other_geometry.feature)
|
109
132
|
end
|
110
133
|
|
111
134
|
# Returns true if Geometry is a Surface
|
112
135
|
def surface?
|
113
|
-
|
136
|
+
if collection?
|
137
|
+
feature.any? { |geometry| Charta.new_geometry(geometry).surface? }
|
138
|
+
else
|
139
|
+
[RGeo::Feature::Polygon, RGeo::Feature::MultiPolygon].include? feature.geometry_type
|
140
|
+
end
|
114
141
|
end
|
115
142
|
|
116
143
|
# Returns area in unit corresponding to the SRS
|
117
144
|
def area
|
118
|
-
surface?
|
145
|
+
if surface?
|
146
|
+
if collection?
|
147
|
+
feature.sum { |geometry| Charta.new_geometry(geometry).area }
|
148
|
+
else
|
149
|
+
feature.area
|
150
|
+
end
|
151
|
+
else
|
152
|
+
0
|
153
|
+
end
|
119
154
|
end
|
120
155
|
|
121
156
|
# Returns true if this Geometry is an empty geometrycollection, polygon,
|
@@ -130,6 +165,7 @@ module Charta
|
|
130
165
|
# of mass of the geometry as a POINT.
|
131
166
|
def centroid
|
132
167
|
return nil unless surface? && !feature.is_empty?
|
168
|
+
|
133
169
|
point = feature.centroid
|
134
170
|
[point.y, point.x]
|
135
171
|
end
|
@@ -137,16 +173,23 @@ module Charta
|
|
137
173
|
# Returns a POINT guaranteed to lie on the surface.
|
138
174
|
def point_on_surface
|
139
175
|
return nil unless surface?
|
176
|
+
|
140
177
|
point = feature.point_on_surface
|
141
178
|
[point.y, point.x]
|
142
179
|
end
|
143
180
|
|
144
181
|
def convert_to(new_type)
|
145
182
|
case new_type
|
146
|
-
when type
|
147
|
-
|
148
|
-
when :
|
149
|
-
|
183
|
+
when type
|
184
|
+
self
|
185
|
+
when :multi_point
|
186
|
+
flatten_multi(:point)
|
187
|
+
when :multi_line_string
|
188
|
+
flatten_multi(:line_string)
|
189
|
+
when :multi_polygon
|
190
|
+
flatten_multi(:polygon)
|
191
|
+
else
|
192
|
+
self
|
150
193
|
end
|
151
194
|
end
|
152
195
|
|
@@ -174,10 +217,12 @@ module Charta
|
|
174
217
|
def transform(new_srid)
|
175
218
|
return self if new_srid == srid
|
176
219
|
raise 'Proj is not supported. Cannot tranform' unless RGeo::CoordSys::Proj4.supported?
|
220
|
+
|
177
221
|
new_srid = Charta::SRS[new_srid] || new_srid
|
178
222
|
database = self.class.srs_database
|
179
223
|
new_proj_entry = database.get(new_srid)
|
180
224
|
raise "Cannot find proj for SRID: #{new_srid}" if new_proj_entry.nil?
|
225
|
+
|
181
226
|
new_feature = RGeo::CoordSys::Proj4.transform(
|
182
227
|
database.get(srid).proj4,
|
183
228
|
feature,
|
@@ -205,6 +250,11 @@ module Charta
|
|
205
250
|
feature.intersection(other_geometry.feature)
|
206
251
|
end
|
207
252
|
|
253
|
+
def intersects?(other)
|
254
|
+
other_geometry = Charta.new_geometry(other).transform(srid)
|
255
|
+
feature.intersects?(other_geometry.feature)
|
256
|
+
end
|
257
|
+
|
208
258
|
def difference(other)
|
209
259
|
other_geometry = Charta.new_geometry(other).transform(srid)
|
210
260
|
feature.difference(other_geometry.feature)
|
@@ -241,7 +291,7 @@ module Charta
|
|
241
291
|
@feature = ::Charta::Geometry.from_ewkt(@ewkt)
|
242
292
|
@properties = @options.dup if @options
|
243
293
|
else
|
244
|
-
raise StandardError
|
294
|
+
raise StandardError.new('Invalid geometry (no feature, no EWKT)')
|
245
295
|
end
|
246
296
|
end
|
247
297
|
@feature.dup
|
@@ -250,7 +300,8 @@ module Charta
|
|
250
300
|
alias to_rgeo feature
|
251
301
|
|
252
302
|
def feature=(new_feature)
|
253
|
-
raise ArgumentError
|
303
|
+
raise ArgumentError.new("Feature can't be nil") if new_feature.nil?
|
304
|
+
|
254
305
|
@feature = new_feature
|
255
306
|
end
|
256
307
|
|
@@ -269,6 +320,7 @@ module Charta
|
|
269
320
|
|
270
321
|
def respond_to_missing?(name, include_private = false)
|
271
322
|
return false if name == :init_with
|
323
|
+
|
272
324
|
super
|
273
325
|
end
|
274
326
|
|
@@ -279,11 +331,13 @@ module Charta
|
|
279
331
|
|
280
332
|
def factory(srid = 4326)
|
281
333
|
return projected_factory(srid) if srid.to_i == 4326
|
334
|
+
|
282
335
|
geos_factory(srid)
|
283
336
|
end
|
284
337
|
|
285
338
|
def feature(ewkt_or_rgeo)
|
286
339
|
return from_rgeo(ewkt_or_rgeo) if ewkt_or_rgeo.is_a? RGeo::Feature::Instance
|
340
|
+
|
287
341
|
from_ewkt(ewkt_or_rgeo)
|
288
342
|
end
|
289
343
|
|
@@ -1,10 +1,12 @@
|
|
1
1
|
module Charta
|
2
2
|
# Represent a Geometry with contains other geometries
|
3
3
|
class GeometryCollection < Geometry
|
4
|
-
|
5
|
-
srid =
|
6
|
-
|
7
|
-
|
4
|
+
class << self
|
5
|
+
def empty(srid = nil)
|
6
|
+
srid = Charta.find_srid(srid.nil? ? :WGS84 : srid)
|
7
|
+
feature = Charta.new_feature('GEOMETRYCOLLECTION EMPTY', srid)
|
8
|
+
new(feature)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
def to_json_feature_collection(collection_properties = [])
|
data/lib/charta/gml.rb
CHANGED
@@ -83,6 +83,7 @@ module Charta
|
|
83
83
|
'GEOMETRYCOLLECTION(' + gml.css("#{GML_PREFIX}|featureMember").collect do |feature|
|
84
84
|
TAGS.collect do |tag|
|
85
85
|
next if feature.css("#{GML_PREFIX}|#{tag}").empty?
|
86
|
+
|
86
87
|
feature.css("#{GML_PREFIX}|#{tag}").collect do |fragment|
|
87
88
|
object_to_ewkt(fragment, srid)
|
88
89
|
end.compact.join(', ')
|
@@ -90,6 +91,7 @@ module Charta
|
|
90
91
|
end.compact.join(', ') + ')'
|
91
92
|
end
|
92
93
|
end
|
94
|
+
|
93
95
|
alias geometry_collection_to_ewkt document_to_ewkt
|
94
96
|
|
95
97
|
def transform(data, from_srid, to_srid)
|
@@ -101,8 +103,9 @@ module Charta
|
|
101
103
|
|
102
104
|
wkt = 'POLYGON(' + %w[outerBoundaryIs innerBoundaryIs].collect do |boundary|
|
103
105
|
next if gml.css("#{GML_PREFIX}|#{boundary}").empty?
|
106
|
+
|
104
107
|
gml.css("#{GML_PREFIX}|#{boundary}").collect do |hole|
|
105
|
-
|
108
|
+
"(#{transform_coordinates(hole)})"
|
106
109
|
end.join(', ')
|
107
110
|
end.compact.join(', ') + ')'
|
108
111
|
|
@@ -115,6 +118,7 @@ module Charta
|
|
115
118
|
|
116
119
|
def point_to_ewkt(gml, srid)
|
117
120
|
return 'POINT EMPTY' if gml.css("#{GML_PREFIX}|coordinates").nil?
|
121
|
+
|
118
122
|
wkt = 'POINT(' + gml.css("#{GML_PREFIX}|coordinates").collect { |coords| coords.content.split ',' }.flatten.join(' ') + ')'
|
119
123
|
|
120
124
|
unless gml['srsName'].nil? || Charta.find_srid(gml['srsName']).to_s == srid.to_s
|
@@ -127,7 +131,7 @@ module Charta
|
|
127
131
|
def line_string_to_ewkt(gml, srid)
|
128
132
|
return 'LINESTRING EMPTY' if gml.css("#{GML_PREFIX}|coordinates").nil?
|
129
133
|
|
130
|
-
wkt =
|
134
|
+
wkt = "LINESTRING(#{transform_coordinates(gml)})"
|
131
135
|
|
132
136
|
unless gml['srsName'].nil? || Charta.find_srid(gml['srsName']).to_s == srid.to_s
|
133
137
|
wkt = transform(wkt, Charta.find_srid(gml['srsName']), srid)
|
@@ -135,6 +139,18 @@ module Charta
|
|
135
139
|
|
136
140
|
wkt
|
137
141
|
end
|
142
|
+
|
143
|
+
private
|
144
|
+
|
145
|
+
def transform_coordinates(coordinates)
|
146
|
+
coordinates.css("#{GML_PREFIX}|coordinates")
|
147
|
+
.collect { |coords| coords.content.split(/\r\n|\n| /) }
|
148
|
+
.flatten
|
149
|
+
.reject(&:empty?)
|
150
|
+
.collect { |c| c.split ',' }
|
151
|
+
.collect { |dimension| %(#{dimension.first} #{dimension[1]}) }
|
152
|
+
.join(', ')
|
153
|
+
end
|
138
154
|
end
|
139
155
|
end
|
140
156
|
end
|
data/lib/charta/gml_import.rb
CHANGED
@@ -63,30 +63,30 @@ class GmlImport
|
|
63
63
|
|
64
64
|
private
|
65
65
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
66
|
+
def featurize(node)
|
67
|
+
if node.element? && node.xpath('.//gml:Polygon')
|
68
|
+
geojson_feature = {}
|
69
|
+
|
70
|
+
geometry = node.xpath('.//gml:Polygon')
|
71
|
+
geometry.first['srsName'] = 'EPSG:2154'
|
72
|
+
|
73
|
+
if ::Charta::GML.valid?(geometry)
|
74
|
+
|
75
|
+
# properties
|
76
|
+
id = (Time.zone.now.to_i.to_s + Time.zone.now.usec.to_s)
|
77
|
+
|
78
|
+
geojson_feature = {
|
79
|
+
type: 'Feature',
|
80
|
+
properties: {
|
81
|
+
internal_id: id
|
82
|
+
}.reject { |_, v| v.nil? },
|
83
|
+
geometry: ::Charta.new_geometry(geometry.to_xml, nil, 'gml').transform(:WGS84).to_geojson
|
84
|
+
}.reject { |_, v| v.nil? }
|
85
|
+
|
86
|
+
return geojson_feature
|
87
|
+
else
|
88
|
+
return false
|
89
|
+
end
|
89
90
|
end
|
90
91
|
end
|
91
|
-
end
|
92
92
|
end
|
data/lib/charta/kml.rb
CHANGED
@@ -22,7 +22,9 @@ module Charta
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def to_ewkt
|
25
|
-
"SRID=#{@srid};"
|
25
|
+
srid_part = @srid.nil? ? '' : "SRID=#{@srid};"
|
26
|
+
|
27
|
+
srid_part + self.class.document_to_ewkt(@kml)
|
26
28
|
end
|
27
29
|
|
28
30
|
def valid?
|
@@ -46,15 +48,18 @@ module Charta
|
|
46
48
|
|
47
49
|
def document_to_ewkt(kml)
|
48
50
|
return 'GEOMETRYCOLLECTION EMPTY' if kml.css('Document').nil?
|
51
|
+
|
49
52
|
'GEOMETRYCOLLECTION(' + kml.css('Placemark').collect do |placemark|
|
50
53
|
TAGS.collect do |tag|
|
51
54
|
next if placemark.css(tag).empty?
|
55
|
+
|
52
56
|
placemark.css(tag).collect do |fragment|
|
53
57
|
object_to_ewkt(fragment)
|
54
58
|
end.compact.join(', ')
|
55
59
|
end.compact.join(', ')
|
56
60
|
end.compact.join(', ') + ')'
|
57
61
|
end
|
62
|
+
|
58
63
|
alias geometry_collection_to_ewkt document_to_ewkt
|
59
64
|
|
60
65
|
def feature_to_ewkt(kml)
|
@@ -63,13 +68,14 @@ module Charta
|
|
63
68
|
|
64
69
|
def point_to_ewkt(kml)
|
65
70
|
return 'POINT EMPTY' if kml.css('coordinates').nil?
|
71
|
+
|
66
72
|
'POINT(' + kml.css('coordinates').collect { |coords| coords.content.split ',' }.flatten.join(' ') + ')'
|
67
73
|
end
|
68
74
|
|
69
75
|
def line_string_to_ewkt(kml)
|
70
76
|
return 'LINESTRING EMPTY' if kml.css('coordinates').nil?
|
71
77
|
|
72
|
-
|
78
|
+
"LINESTRING(#{transform_coordinates(kml)})"
|
73
79
|
end
|
74
80
|
|
75
81
|
def polygon_to_ewkt(kml)
|
@@ -79,7 +85,7 @@ module Charta
|
|
79
85
|
next if kml.css(boundary).empty?
|
80
86
|
|
81
87
|
kml.css(boundary).collect do |hole|
|
82
|
-
|
88
|
+
"(#{transform_coordinates(hole)})"
|
83
89
|
end.join(', ')
|
84
90
|
end.compact.join(', ') + ')'
|
85
91
|
end
|
@@ -87,6 +93,18 @@ module Charta
|
|
87
93
|
def multigeometry_to_ewkt(_kml)
|
88
94
|
raise :not_implemented
|
89
95
|
end
|
96
|
+
|
97
|
+
private
|
98
|
+
|
99
|
+
def transform_coordinates(coordinates)
|
100
|
+
coordinates.css('coordinates')
|
101
|
+
.collect { |coords| coords.content.split(/\r\n|\n| /) }
|
102
|
+
.flatten
|
103
|
+
.reject(&:empty?)
|
104
|
+
.collect { |c| c.split ',' }
|
105
|
+
.collect { |dimension| %(#{dimension.first} #{dimension[1]}) }
|
106
|
+
.join(', ')
|
107
|
+
end
|
90
108
|
end
|
91
109
|
end
|
92
110
|
end
|
data/lib/charta/multi_polygon.rb
CHANGED
data/lib/charta/point.rb
CHANGED
data/lib/charta/polygon.rb
CHANGED
data/lib/charta/version.rb
CHANGED