brokjson 1.0.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 +7 -0
- data/lib/brokjson.rb +173 -0
- data/test/test_brokjson.rb +79 -0
- 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
|