brokjson 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/lib/brokjson.rb +173 -0
  3. data/test/test_brokjson.rb +79 -0
  4. metadata +46 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '0013492d14661dd0d183aee536c4ff4c4f01d0b58d70edf201a3e157554bd6ef'
4
+ data.tar.gz: 2d13984d0c27917e8d09cd35c57f7eba92b300ffd798ef518950a1d39ac78dc0
5
+ SHA512:
6
+ metadata.gz: 66930a92352f886ca573458abee6a0917197722bfa638f51a09df02d546d0f1d5d22b0a4398d3411035394ad625bde1ade697e0489803482f643b25b065bfc67
7
+ data.tar.gz: 7307728c001fbf46d8a5a98bb667ea31c06050f0df49ffe98219146538a23645fe545d739ffd37074c03d0cc80546fe9b7f1f6f914bba8bb8532f079286ae19e
data/lib/brokjson.rb ADDED
@@ -0,0 +1,173 @@
1
+ class BrokJson
2
+ def self.geo2brok(geojson)
3
+ global_geometries = []
4
+ global_properties = []
5
+ global_foreign_members = []
6
+
7
+ geojson['features'].each do |feature|
8
+ next if feature['type'].downcase != 'feature'
9
+
10
+ return unless feature.key?('geometry')
11
+
12
+ # Add properties
13
+ props = []
14
+ if feature.key?('properties')
15
+ feature['properties'].each do |property_key, property_value|
16
+ # Add to list if item in list
17
+ global_properties << property_key unless global_properties.include? property_key
18
+
19
+ index = global_properties.find_index(property_key)
20
+
21
+ # Check if props are long enough
22
+ props = props + [nil] * (index + 1 - props.length) if props.length - 1 < index
23
+
24
+ # Add to props
25
+ props[index] = property_value
26
+ end
27
+ end
28
+
29
+ # Add foreign members
30
+ foreign_members = []
31
+ feature.each do |item_key, item_val|
32
+ next if ['type', 'properties', 'geometry'].include? item_key.downcase
33
+
34
+ global_foreign_members << item_key unless global_foreign_members.include? item_key
35
+
36
+ index = global_foreign_members.find_index(item_key)
37
+
38
+ foreign_members = foreign_members + [nil] * (index + 1 - foreign_members.length) if foreign_members.length - 1 < index
39
+
40
+ foreign_members[index] = item_val
41
+ end
42
+
43
+ coords = nil
44
+ if feature['geometry']['type'].downcase == 'geometrycollection'
45
+ # GeometryCollection detected!
46
+ coords = []
47
+
48
+ feature["geometry"]["geometries"].each do |geom|
49
+ # Now check if last item of geometries is same type. If not, add the type
50
+ if (coords.length == 0 || coords[-1]['type'].downcase != geom['type'].downcase)
51
+ # Add new geometry list
52
+ coords << { 'type' => geom['type'], 'features' => [] }
53
+ end
54
+
55
+ # Add feature to geometry list
56
+ coords[coords.length - 1]['features'] << [geom['coordinates']]
57
+ end
58
+ else
59
+ # Add Coords
60
+ coords = feature['geometry']['coordinates']
61
+ end
62
+
63
+ # Create feature-array
64
+ brok_feature = [coords]
65
+
66
+ # Add props
67
+ brok_feature << props if props.length > 0
68
+
69
+ # Add foreign members
70
+ if foreign_members.length > 0
71
+ brok_feature << nil if brok_feature.length < 2
72
+ brok_feature << foreign_members
73
+ end
74
+
75
+ # Now check if last item of geometries is same type. If not, add the type
76
+ if (global_geometries.length == 0 || global_geometries[-1]['type'].downcase != feature['geometry']['type'].downcase)
77
+ # Add new geometry list
78
+ global_geometries << { 'type' => feature['geometry']['type'], 'features' => [] }
79
+ end
80
+
81
+ # Add feature to geometry list
82
+ global_geometries[global_geometries.length - 1]['features'] << brok_feature
83
+ end
84
+
85
+ # Build BrokJSON
86
+ brok = {}
87
+
88
+ # Add global properties
89
+ brok['properties'] = global_properties if global_properties.length > 0
90
+
91
+ # Add foreign members
92
+ brok['foreignMembers'] = global_foreign_members if global_foreign_members.length > 0
93
+
94
+ # Add all unknown members
95
+ geojson.each do |member_key, member_val|
96
+ # Exclude List
97
+ next if ['type', 'features'].include? member_key
98
+
99
+ brok[member_key] = member_val
100
+ end
101
+
102
+ # Add geometry
103
+ brok['geometries'] = global_geometries if global_geometries.length > 0
104
+
105
+ return brok
106
+ end
107
+
108
+ def self.brok2geo(brok)
109
+ geo = {
110
+ 'type' => 'FeatureCollection'
111
+ }
112
+
113
+ # Look for custom properties on root
114
+ brok.each do |member_key, member_val|
115
+ geo[member_key] = member_val unless ['properties', 'geometries', 'foreignMembers'].include? member_key
116
+ end
117
+
118
+ geo['features'] = [] if brok['geometries'].length > 0
119
+
120
+ # Add geometries
121
+ brok['geometries'].each do |geometry_collection|
122
+ geometry_collection['features'].each do |feature|
123
+ # Create Feature
124
+ json_feature = { 'type' => 'Feature' }
125
+
126
+ # Check and add properties
127
+ properties = {}
128
+ if feature.length >= 2
129
+ (0..feature[1].length).each do |p|
130
+ prop = feature[1][p]
131
+
132
+ next if prop.nil?
133
+
134
+ properties[brok['properties'][p]] = prop
135
+ end
136
+ end
137
+
138
+ # Check and add foreign members
139
+ if feature.length >= 3
140
+ (0..feature[2].length).each do |m|
141
+ json_feature[brok['foreignMembers'][m]] = feature[2][m]
142
+ end
143
+ end
144
+
145
+ # Add props
146
+ json_feature['properties'] = properties if properties.length > 0
147
+
148
+ # Check if geometry collection
149
+ if geometry_collection['type'].downcase == 'geometryCollection'
150
+ new_coords = []
151
+ geometry_collection['features'].each do |coordinates|
152
+ coordinates[0].each do |geocol|
153
+ geocol['features'].each do |types|
154
+ coord = { 'type' => geocol['type'], 'coordinates' => types[0] }
155
+ new_coords << coord
156
+ end
157
+ end
158
+ end
159
+
160
+ # Add Geometry
161
+ json_feature['geometry'] = { 'type' => geometry_collection['type'], 'geometries' => new_coords }
162
+ else
163
+ # Normal Geometry
164
+ json_feature['geometry'] = { 'type' => geometry_collection['type'], 'coordinates' => feature[0] }
165
+ end
166
+
167
+ geo['features'] << json_feature
168
+ end
169
+ end
170
+
171
+ return geo
172
+ end
173
+ end
@@ -0,0 +1,79 @@
1
+ require 'test/unit'
2
+ require 'brokjson'
3
+
4
+ class BrokJsonTest < Test::Unit::TestCase
5
+ def test_can_convert_from_geojson_to_brokjson
6
+ assert_equal sample_brokjson, BrokJson.geo2brok(sample_geojson)
7
+ end
8
+
9
+ def test_can_convert_from_brokjson_to_geojson
10
+ assert_equal sample_geojson, BrokJson.brok2geo(sample_brokjson)
11
+ end
12
+
13
+ private
14
+
15
+ def sample_geojson
16
+ {
17
+ 'type' => 'FeatureCollection',
18
+ 'title' => 'Hello World',
19
+ 'features' => [
20
+ {
21
+ 'type' => 'Feature',
22
+ 'properties' => {
23
+ 'id' => 1,
24
+ 'title' => 'Datapoint 1',
25
+ 'value' => 343
26
+ },
27
+ 'geometry' => {
28
+ 'type' => 'Point',
29
+ 'coordinates' => [
30
+ 8.5402,
31
+ 47.3782
32
+ ]
33
+ }
34
+ },
35
+ {
36
+ 'type' => 'Feature',
37
+ 'properties' => {
38
+ 'id' => 1,
39
+ 'title' => 'Datapoint 2',
40
+ 'value' => 14
41
+ },
42
+ 'geometry' => {
43
+ 'type' => 'Point',
44
+ 'coordinates' => [
45
+ 8.5637,
46
+ 47.4504
47
+ ]
48
+ }
49
+ }
50
+ ]
51
+ }
52
+ end
53
+
54
+ def sample_brokjson
55
+ {
56
+ 'properties' => [
57
+ 'id',
58
+ 'title',
59
+ 'value'
60
+ ],
61
+ 'title' => 'Hello World',
62
+ 'geometries' => [
63
+ {
64
+ 'type' => 'Point',
65
+ 'features'=> [
66
+ [
67
+ [8.5402, 47.3782],
68
+ [1, 'Datapoint 1', 343]
69
+ ],
70
+ [
71
+ [8.5637, 47.4504],
72
+ [1, 'Datapoint 2', 14]
73
+ ]
74
+ ]
75
+ }
76
+ ]
77
+ }
78
+ end
79
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: brokjson
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Hazimi Asyraf
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-24 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: BrokJSON is a space-saving alternative to GeoJSON. Convert GeoJSON to
14
+ BrokJSON and vice versa
15
+ email: hazimi@hazimiasyraf.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/brokjson.rb
21
+ - test/test_brokjson.rb
22
+ homepage: https://github.com/jimmyasyraf/brokJSON_rb
23
+ licenses:
24
+ - MIT
25
+ metadata: {}
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '2.6'
35
+ required_rubygems_version: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ requirements: []
41
+ rubygems_version: 3.1.2
42
+ signing_key:
43
+ specification_version: 4
44
+ summary: BrokJSON is a space-saving alternative to GeoJSON
45
+ test_files:
46
+ - test/test_brokjson.rb