charta 0.2.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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