charta 0.1.12 → 0.1.13
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/.gitlab-ci.yml +13 -0
- data/lib/charta.rb +2 -0
- data/lib/charta/coordinates.rb +65 -0
- data/lib/charta/ewkt_serializer.rb +92 -0
- data/lib/charta/geo_json.rb +9 -124
- data/lib/charta/version.rb +1 -1
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5026ab204ac67b2187e5a338c178009582401ef
|
4
|
+
data.tar.gz: 07f73034e6c19c9f307b59aa4aecc359767b7544
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9cb51c59524dfb7c022069d805f936282dc143419ec124bcc7d491ae6fe1b692ab397bd377bee875b663564319ad97111748e9db640df71583470bffbf868963
|
7
|
+
data.tar.gz: 26e4afcc4e8ec23478883923af1313fe91ef64cc071b3892a7d0963bddb9bc00ad2f79b05782725f99cc9f718fd90f634a9421cdbb97456aa4a838498477ab9f
|
data/.gitlab-ci.yml
ADDED
data/lib/charta.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
module Charta
|
2
|
+
module Coordinates
|
3
|
+
class << self
|
4
|
+
|
5
|
+
# Force coordinates to 2D
|
6
|
+
def flatten(hash)
|
7
|
+
map_coordinates(hash) { |position| position[0..1] }
|
8
|
+
end
|
9
|
+
|
10
|
+
def map_coordinates(hash, &block)
|
11
|
+
case hash['type']
|
12
|
+
when 'FeatureCollection'
|
13
|
+
map_feature_collection_coordinates hash, &block
|
14
|
+
when 'Feature'
|
15
|
+
map_feature_coordinates hash, &block
|
16
|
+
else
|
17
|
+
map_geometry_coordinates hash, &block
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def normalize_4326_geometry(json)
|
22
|
+
map_coordinates json do |(x, y)|
|
23
|
+
[((x + 180) % 360) - 180, ((y + 90) % 180) - 90]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def map_feature_collection_coordinates(hash, &block)
|
30
|
+
hash.merge 'features' => hash['features'].map { |feature| map_feature_coordinates feature, &block }
|
31
|
+
end
|
32
|
+
|
33
|
+
def map_feature_coordinates(hash, &block)
|
34
|
+
hash.merge 'geometry' => map_geometry_coordinates(hash['geometry'], &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def map_geometry_coordinates(hash, &block)
|
38
|
+
if hash['type'] == 'GeometryCollection'
|
39
|
+
map_geometry_collection_coordinates hash, &block
|
40
|
+
else
|
41
|
+
coordinates = hash['coordinates']
|
42
|
+
mapped =
|
43
|
+
case hash['type']
|
44
|
+
when 'Point' then
|
45
|
+
block.call coordinates
|
46
|
+
when 'MultiPoint', 'LineString'
|
47
|
+
coordinates.map(&block)
|
48
|
+
when 'MultiLineString', 'Polygon'
|
49
|
+
coordinates.map { |line| line.map(&block) }
|
50
|
+
when 'MultiPolygon'
|
51
|
+
coordinates.map { |poly| poly.map { |line| line.map(&block) } }
|
52
|
+
else
|
53
|
+
raise StandardError, "Cannot handle: #{hash['type'].inspect}. In #{hash.inspect}"
|
54
|
+
end
|
55
|
+
|
56
|
+
hash.merge 'coordinates' => mapped
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def map_geometry_collection_coordinates(hash, &block)
|
61
|
+
hash.merge 'geometries' => map_geometry_coordinates(hash['geometries'], &block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Charta
|
2
|
+
module EwktSerializer
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def object_to_ewkt(hash)
|
6
|
+
type = hash[:type] || hash['type']
|
7
|
+
send("#{type.gsub(/(.)([A-Z])/, '\1_\2').downcase}_to_ewkt", hash)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def feature_collection_to_ewkt(hash)
|
13
|
+
return 'GEOMETRYCOLLECTION EMPTY' if hash['features'].nil?
|
14
|
+
'GEOMETRYCOLLECTION(' + hash['features'].collect do |feature|
|
15
|
+
object_to_ewkt(feature)
|
16
|
+
end.join(', ') + ')'
|
17
|
+
end
|
18
|
+
|
19
|
+
def geometry_collection_to_ewkt(hash)
|
20
|
+
return 'GEOMETRYCOLLECTION EMPTY' if hash['geometries'].nil?
|
21
|
+
'GEOMETRYCOLLECTION(' + hash['geometries'].collect do |feature|
|
22
|
+
object_to_ewkt(feature)
|
23
|
+
end.join(', ') + ')'
|
24
|
+
end
|
25
|
+
|
26
|
+
def feature_to_ewkt(hash)
|
27
|
+
object_to_ewkt(hash['geometry'])
|
28
|
+
end
|
29
|
+
|
30
|
+
def point_to_ewkt(hash)
|
31
|
+
return 'POINT EMPTY' if hash['coordinates'].nil?
|
32
|
+
'POINT(' + hash['coordinates'].join(' ') + ')'
|
33
|
+
end
|
34
|
+
|
35
|
+
def line_string_to_ewkt(hash)
|
36
|
+
return 'LINESTRING EMPTY' if hash['coordinates'].nil?
|
37
|
+
'LINESTRING(' + hash['coordinates'].collect do |point|
|
38
|
+
point.join(' ')
|
39
|
+
end.join(', ') + ')'
|
40
|
+
end
|
41
|
+
|
42
|
+
def polygon_to_ewkt(hash)
|
43
|
+
return 'POLYGON EMPTY' if hash['coordinates'].nil?
|
44
|
+
'POLYGON(' + hash['coordinates'].collect do |hole|
|
45
|
+
'(' + hole.collect do |point|
|
46
|
+
point.join(' ')
|
47
|
+
end.join(', ') + ')'
|
48
|
+
end.join(', ') + ')'
|
49
|
+
end
|
50
|
+
|
51
|
+
def multi_point_to_ewkt(hash)
|
52
|
+
return 'MULTIPOINT EMPTY' if hash['coordinates'].nil?
|
53
|
+
'MULTIPOINT(' + hash['coordinates'].collect do |point|
|
54
|
+
'(' + point.join(' ') + ')'
|
55
|
+
end.join(', ') + ')'
|
56
|
+
end
|
57
|
+
|
58
|
+
def multi_line_string_to_ewkt(hash)
|
59
|
+
return 'MULTILINESTRING EMPTY' if hash['coordinates'].nil?
|
60
|
+
'MULTILINESTRING(' + hash['coordinates'].collect do |line|
|
61
|
+
'(' + line.collect do |point|
|
62
|
+
point.join(' ')
|
63
|
+
end.join(', ') + ')'
|
64
|
+
end.join(', ') + ')'
|
65
|
+
end
|
66
|
+
|
67
|
+
def multipolygon_to_ewkt(hash)
|
68
|
+
return 'MULTIPOLYGON EMPTY' if hash['coordinates'].nil?
|
69
|
+
'MULTIPOLYGON(' + hash['coordinates'].collect do |polygon|
|
70
|
+
'(' + polygon.collect do |hole|
|
71
|
+
'(' + hole.collect do |point|
|
72
|
+
point.join(' ')
|
73
|
+
end.join(', ') + ')'
|
74
|
+
end.join(', ') + ')'
|
75
|
+
end.join(', ') + ')'
|
76
|
+
end
|
77
|
+
|
78
|
+
# for PostGIS ST_ASGeoJSON compatibility
|
79
|
+
def multi_polygon_to_ewkt(hash)
|
80
|
+
return 'MULTIPOLYGON EMPTY' if hash['coordinates'].nil?
|
81
|
+
'MULTIPOLYGON(' + hash['coordinates'].collect do |polygon|
|
82
|
+
'(' + polygon.collect do |hole|
|
83
|
+
'(' + hole.collect do |point|
|
84
|
+
point.join(' ')
|
85
|
+
end.join(', ') + ')'
|
86
|
+
end.join(', ') + ')'
|
87
|
+
end.join(', ') + ')'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
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,14 @@ 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
|
-
'(' + polygon.collect do |hole|
|
165
|
-
'(' + hole.collect do |point|
|
166
|
-
point.join(' ')
|
167
|
-
end.join(', ') + ')'
|
168
|
-
end.join(', ') + ')'
|
169
|
-
end.join(', ') + ')'
|
51
|
+
%i[object_to_ewkt feature_collection_to_ewkt geometry_collection_to_ewkt feature_to_ewkt point_to_ewkt line_string_to_ewkt polygon_to_ewkt multi_point_to_ewkt multi_line_string_to_ewkt multipolygon_to_ewkt multi_polygon_to_ewkt].each do |m|
|
52
|
+
define_method m do |*args|
|
53
|
+
EwktSerializer.send m, *args
|
54
|
+
end
|
170
55
|
end
|
171
56
|
end
|
172
57
|
end
|
data/lib/charta/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brice TEXIER
|
@@ -130,6 +130,7 @@ extensions: []
|
|
130
130
|
extra_rdoc_files: []
|
131
131
|
files:
|
132
132
|
- ".gitignore"
|
133
|
+
- ".gitlab-ci.yml"
|
133
134
|
- ".travis.yml"
|
134
135
|
- CODE_OF_CONDUCT.md
|
135
136
|
- Gemfile
|
@@ -139,6 +140,8 @@ files:
|
|
139
140
|
- charta.gemspec
|
140
141
|
- lib/charta.rb
|
141
142
|
- lib/charta/bounding_box.rb
|
143
|
+
- lib/charta/coordinates.rb
|
144
|
+
- lib/charta/ewkt_serializer.rb
|
142
145
|
- lib/charta/geo_json.rb
|
143
146
|
- lib/charta/geojson_import.rb
|
144
147
|
- lib/charta/geometry.rb
|