terraformer 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 27549564ba7d079289298f08d49e921d0ed19441
4
+ data.tar.gz: 5d621a88f01cd1f7eff842808776a536567ac28f
5
+ SHA512:
6
+ metadata.gz: 1629d4a4f49486fb44512a7e37505a7faea5f6ce1352696b49522fea11162ac5cffa15cf6094d1dec6310980caccbe8da8e1e4abf3c731d206f22a2ccee21273
7
+ data.tar.gz: c697882b6880196f71120edd5dea0eac38a273e98da9989ee9fcf39dd9f32f41b78728213653aa432b16bdc18bd9d02c273ed1af38edbf96e1d839142383a767
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rake'
4
+
5
+ group :test do
6
+ gem 'pry'
7
+ gem 'pry-nav'
8
+ end
data/README.md ADDED
@@ -0,0 +1,4 @@
1
+ terraformer-ruby
2
+ ================
3
+
4
+ mostly faithful port of [terraformer](https://github.com/Esri/Terraformer)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.pattern = ENV['TEST_PATTERN'] || "test/**/*_spec.rb"
5
+ end
6
+
7
+ task :default => :test
@@ -0,0 +1,92 @@
1
+ module Terraformer
2
+
3
+ module Bounds
4
+ class << self
5
+
6
+ def bounds obj, format = :bbox
7
+
8
+ obj = Terraformer.parse obj unless Primitive === obj
9
+
10
+ bbox = case obj.type
11
+ when 'Point'
12
+ [ obj.coordinates[0], obj.coordinates[1],
13
+ obj.coordinates[0], obj.coordinates[1] ]
14
+ when 'MultiPoint'
15
+ bounds_for_array obj.coordinates
16
+ when 'LineString'
17
+ bounds_for_array obj.coordinates
18
+ when 'MultiLineString'
19
+ bounds_for_array obj.coordinates, 1
20
+ when 'Polygon'
21
+ bounds_for_array obj.coordinates, 1
22
+ when 'MultiPolygon'
23
+ bounds_for_array obj.coordinates, 2
24
+ when 'Feature'
25
+ obj.geometry ? bounds(obj.geometry) : nil
26
+ when 'FeatureCollection'
27
+ bounds_for_feature_collection obj
28
+ when 'GeometryCollection'
29
+ bounds_for_geometry_collection obj
30
+ else
31
+ raise ArgumentError.new 'unknown type: ' + obj.type
32
+ end
33
+
34
+ case format
35
+ when :bbox
36
+ bbox
37
+ when :polygon
38
+ Polygon.new [[bbox[0], bbox[1]],
39
+ [bbox[0], bbox[3]],
40
+ [bbox[2], bbox[3]],
41
+ [bbox[2], bbox[1]],
42
+ [bbox[0], bbox[1]]]
43
+ end
44
+ end
45
+
46
+ X1, Y1, X2, Y2 = 0, 1, 2, 3
47
+
48
+ def bounds_for_array array, nesting = 0, box = Array.new(4)
49
+ if nesting > 0
50
+ array.reduce box do |b, a|
51
+ bounds_for_array a, (nesting - 1), b
52
+ end
53
+ else
54
+ array.reduce box do |b, lonlat|
55
+ lon, lat = *lonlat
56
+ set = ->(d, i, t){ b[i] = d if b[i].nil? or d.send(t, b[i]) }
57
+ set[lon, X1, :<]
58
+ set[lon, X2, :>]
59
+ set[lat, Y1, :<]
60
+ set[lat, Y2, :>]
61
+ b
62
+ end
63
+ end
64
+ end
65
+
66
+ def bounds_for_feature_collection fc
67
+ bounds_for_collection fc.features, &:geometry
68
+ end
69
+
70
+ def bounds_for_geometry_collection gc
71
+ bounds_for_collection gc
72
+ end
73
+
74
+ def bounds_for_collection collection
75
+ bounds_for_array collection.map {|e| bounds(block_given? ? yield(e) : e)}
76
+ end
77
+ private :bounds_for_collection
78
+
79
+ def envelope geometry
80
+ b = bounds geometry
81
+ {
82
+ x: b[0],
83
+ y: b[1],
84
+ w: (b[0] - b[2]).abs,
85
+ h: (b[1] - b[3]).abs
86
+ }
87
+ end
88
+
89
+ end
90
+ end
91
+
92
+ end
@@ -0,0 +1,120 @@
1
+ module Terraformer
2
+
3
+ class Coordinate < ::Array
4
+
5
+ attr_accessor :crs
6
+
7
+ class << self
8
+
9
+ def from arys
10
+ arys.map {|e| Coordinate.from_array e}
11
+ end
12
+
13
+ def from_array a
14
+ Coordinate.__send__ Numeric === a[0] ? :new : :from, a
15
+ end
16
+
17
+ def big_decimal n
18
+ case n
19
+ when String
20
+ BigDecimal.new n
21
+ when BigDecimal
22
+ n
23
+ when Numeric
24
+ n.to_d
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ def initialize _x, _y = nil, _z = nil, _m = nil
31
+ super 4
32
+ case _x
33
+ when Array
34
+ raise ArgumentError if _y
35
+ self.x = _x[0]
36
+ self.y = _x[1]
37
+ when Numeric
38
+ raise ArgumentError unless _y
39
+ self.x = _x
40
+ self.y = _y
41
+ else
42
+ raise ArgumentError.new "invalid argument: #{_x}"
43
+ end
44
+ end
45
+
46
+ def x
47
+ self[0]
48
+ end
49
+
50
+ def x= _x
51
+ self[0] = Coordinate.big_decimal _x
52
+ end
53
+
54
+ def y
55
+ self[1]
56
+ end
57
+
58
+ def y= _y
59
+ self[1] = Coordinate.big_decimal _y
60
+ end
61
+
62
+ def z
63
+ self[2]
64
+ end
65
+
66
+ def m
67
+ self[3]
68
+ end
69
+
70
+ [:z=, :m=, :<<, :+ , :-, :*, :&, :|].each do |sym|
71
+ define_method(sym){|*a| raise NotImplementedError }
72
+ end
73
+
74
+ def to_geographic
75
+ xerd = (x / EARTH_RADIUS).to_deg
76
+ _x = xerd - (((xerd + 180.0) / 360.0).floor * 360.0)
77
+ _y = (
78
+ (Math::PI / 2).to_d -
79
+ (2 * BigMath.atan(BigMath.exp(-1.0 * y / EARTH_RADIUS, PRECISION), PRECISION))
80
+ ).to_deg
81
+ geog = self.class.new _x, _y
82
+ geog.crs = GEOGRAPHIC_CRS
83
+ geog
84
+ end
85
+
86
+ def to_mercator
87
+ _x = x.to_rad * EARTH_RADIUS
88
+ syr = BigMath.sin y.to_rad, PRECISION
89
+ _y = (EARTH_RADIUS / 2.0) * BigMath.log((1.0 + syr) / (1.0 - syr), PRECISION)
90
+ merc = self.class.new _x, _y
91
+ merc.crs = MERCATOR_CRS
92
+ merc
93
+ end
94
+
95
+ def to_json *args
96
+ [x, y, z, m].map! {|e| e.nil? ? nil : e.to_f}.compact.to_json(*args)
97
+ end
98
+
99
+ def geographic?
100
+ crs.nil? or crs == GEOGRAPHIC_CRS
101
+ end
102
+
103
+ def mercator?
104
+ crs == MERCATOR_CRS
105
+ end
106
+
107
+ def buffer radius, resolution = DEFAULT_BUFFER_RESOLUTION
108
+ center = to_mercator unless mercator?
109
+ coordinates = (1..resolution).map {|step|
110
+ radians = step.to_d * (360.to_d / resolution.to_d) * PI / 180.to_d
111
+ [center.x + radius.to_d * BigMath.cos(radians, PRECISION),
112
+ center.y + radius.to_d * BigMath.sin(radians, PRECISION)]
113
+ }
114
+ coordinates << coordinates[0]
115
+ Polygon.new(coordinates).to_geographic
116
+ end
117
+
118
+ end
119
+
120
+ end
@@ -0,0 +1,59 @@
1
+ module Terraformer
2
+
3
+ class Feature < Primitive
4
+
5
+ attr_accessor :id, :geometry
6
+ attr_writer :properties
7
+
8
+ def initialize *args
9
+ unless args.empty?
10
+ super *args do |arg|
11
+ self.id = arg['id'] if arg.key? 'id'
12
+ self.properties = arg['properties'] if arg.key? 'properties'
13
+ self.geometry = Terraformer.parse arg['geometry']
14
+ end
15
+ end
16
+ end
17
+
18
+ def properties
19
+ @properties ||= {}
20
+ end
21
+
22
+ def to_hash
23
+ h = {
24
+ type: type,
25
+ properties: properties,
26
+ geometry: geometry.to_hash
27
+ }
28
+ h.merge! id: id if id
29
+ h
30
+ end
31
+
32
+ end
33
+
34
+ class FeatureCollection < Primitive
35
+
36
+ attr_writer :features
37
+
38
+ def initialize *args
39
+ unless args.empty?
40
+ super *args do |arg|
41
+ self.features = arg['features'].map {|f| Terraformer.parse f}
42
+ end
43
+ end
44
+ end
45
+
46
+ def features
47
+ @features ||= []
48
+ end
49
+
50
+ def to_hash
51
+ {
52
+ type: type,
53
+ features: features.map(&:to_hash)
54
+ }
55
+ end
56
+
57
+ end
58
+
59
+ end
@@ -0,0 +1,98 @@
1
+ module Terraformer
2
+
3
+ class Geometry < Primitive
4
+
5
+ MULTI_REGEX = /^Multi/
6
+
7
+ attr_accessor :coordinates
8
+
9
+ def initialize *args
10
+ if args.length > 1 or Array === args[0]
11
+ self.coordinates = Coordinate.from_array args
12
+ else
13
+ super *args do |arg|
14
+ self.coordinates = Coordinate.from_array arg['coordinates']
15
+ end
16
+ end
17
+ end
18
+
19
+ def to_hash
20
+ {
21
+ type: type,
22
+ coordinates: coordinates
23
+ }
24
+ end
25
+
26
+ def to_mercator
27
+ self.class.new *coordinates.map_coordinate(&:to_mercator)
28
+ end
29
+
30
+ def to_geographic
31
+ self.class.new *coordinates.map_coordinate(&:to_geographic)
32
+ end
33
+
34
+ def first_coordinate
35
+ raise NotImplementedError
36
+ end
37
+
38
+ def mercator?
39
+ first_coordinate.mercator?
40
+ end
41
+
42
+ def geographic?
43
+ first_coordinate.geographic?
44
+ end
45
+
46
+ def get index
47
+ if MULTI_REGEX.match type
48
+ sub = type.sub MULTI_REGEX, ''
49
+ Terraformer.const_get(sub).new *coordinates[index]
50
+ else
51
+ raise NotImplementedError
52
+ end
53
+ end
54
+
55
+ def convex_hull
56
+ raise NotImplementedError
57
+ end
58
+
59
+ def contains other
60
+ raise NotImplementedError
61
+ end
62
+
63
+ def within other
64
+ raise NotImplementedError
65
+ end
66
+
67
+ def intersects other
68
+ raise NotImplementedError
69
+ end
70
+
71
+ end
72
+
73
+ class GeometryCollection < Primitive
74
+
75
+ attr_writer :geometries
76
+
77
+ def initialize *args
78
+ unless args.empty?
79
+ super *args do |arg|
80
+ self.geometries = arg['geometries'].map {|g| Terraformer.parse g}
81
+ end
82
+ end
83
+ end
84
+
85
+ def geometries
86
+ @geometries ||= []
87
+ end
88
+
89
+ def to_hash
90
+ {
91
+ type: type,
92
+ geometries: geometries.map(&:to_hash)
93
+ }
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,11 @@
1
+ module Terraformer
2
+
3
+ class LineString < Geometry
4
+
5
+ def first_coordinate
6
+ coordinates[0]
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Terraformer
2
+
3
+ class MultiLineString < Geometry
4
+
5
+ def first_coordinate
6
+ coordinates[0][0]
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Terraformer
2
+
3
+ class MultiPoint < Geometry
4
+
5
+ def first_coordinate
6
+ coordinates[0]
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Terraformer
2
+
3
+ class MultiPolygon < Geometry
4
+
5
+ def first_coordinate
6
+ coordinates[0][0][0]
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,11 @@
1
+ module Terraformer
2
+
3
+ class Point < Geometry
4
+
5
+ def first_coordinate
6
+ coordinates
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,15 @@
1
+ module Terraformer
2
+
3
+ class Polygon < Geometry
4
+
5
+ def has_holes?
6
+ coordinates.length > 1
7
+ end
8
+
9
+ def first_coordinate
10
+ coordinates[0][0]
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,3 @@
1
+ module Terraformer
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,134 @@
1
+ require 'json'
2
+ require 'bigdecimal'
3
+ require 'bigdecimal/math'
4
+ require 'bigdecimal/util'
5
+
6
+ module Terraformer
7
+
8
+ PRECISION = 8
9
+ PI = BigMath.PI PRECISION
10
+ DEFAULT_BUFFER_RESOLUTION = 64
11
+
12
+ EARTH_RADIUS = 6378137.to_d
13
+ DEGREES_PER_RADIAN = 180.0.to_d / PI
14
+ RADIANS_PER_DEGREE = PI / 180.0.to_d
15
+ MERCATOR_CRS = {
16
+ type: "link",
17
+ properties: {
18
+ href: "http://spatialreference.org/ref/sr-org/6928/ogcwkt/",
19
+ type: "ogcwkt"
20
+ }
21
+ }
22
+ GEOGRAPHIC_CRS = {
23
+ type: "link",
24
+ properties: {
25
+ href: "http://spatialreference.org/ref/epsg/4326/ogcwkt/",
26
+ type: "ogcwkt"
27
+ }
28
+ }
29
+
30
+ def self.parse geojson
31
+ geojson = JSON.parse geojson if String === geojson
32
+ raise ArgumentError.new "invalid arg: #{geojson}" unless Hash === geojson
33
+
34
+ if klass = Terraformer.const_get(geojson['type'])
35
+ klass.new geojson
36
+ else
37
+ raise ArgumentError.new 'unknown type: ' + geojson['type']
38
+ end
39
+ end
40
+
41
+ class Primitive
42
+
43
+ def initialize *args
44
+ arg = String === args[0] ? JSON.parse(args[0]) : args[0]
45
+ raise ArgumentError.new "invalid argument(s): #{args}" unless Hash === arg
46
+ raise ArgumentError.new "invalid type: #{arg['type']}" unless arg['type'] == self.type
47
+ yield arg if block_given?
48
+ end
49
+
50
+ def type
51
+ self.class.to_s.sub 'Terraformer::', ''
52
+ end
53
+
54
+ def envelope
55
+ Bounds.envelope self
56
+ end
57
+
58
+ def bbox type = :bbox
59
+ Bounds.bounds self, type
60
+ end
61
+
62
+ def to_json *args
63
+ self.to_hash.to_json *args
64
+ end
65
+
66
+ def [] prop
67
+ self.__send__ prop.to_sym
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ module Enumerable
75
+
76
+ def each_coordinate opts = {}, &block
77
+ iter_coordinate :each, opts, &block
78
+ end
79
+
80
+ def map_coordinate opts = {}, &block
81
+ iter_coordinate :map, opts, &block
82
+ end
83
+ alias_method :collect_coordinate, :map_coordinate
84
+
85
+ def map_coordinate! opts = {}, &block
86
+ iter_coordinate :map!, opts, &block
87
+ end
88
+ alias_method :collect_coordinate!, :map_coordinate!
89
+
90
+ def iter_coordinate meth, opts = {}, &block
91
+ opts[:recurse] = true if opts[:recurse].nil?
92
+
93
+ if Array === self and Numeric === self[0]
94
+ yield self
95
+ else
96
+
97
+ self.__send__ meth do |pair|
98
+ raise IndexError unless Array === pair
99
+ case pair[0]
100
+ when Numeric
101
+ yield pair
102
+ when Array
103
+ pair.iter_coordinate meth, opts, &block if opts[:recurse]
104
+ else
105
+ raise IndexError.new "#{pair[0]} is not a Numeric or Array type"
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ class BigDecimal
114
+
115
+ def to_deg
116
+ self * Terraformer::DEGREES_PER_RADIAN
117
+ end
118
+
119
+ def to_rad
120
+ self * Terraformer::RADIANS_PER_DEGREE
121
+ end
122
+
123
+ end
124
+
125
+ require 'terraformer/coordinate'
126
+ require 'terraformer/bounds'
127
+ require 'terraformer/geometry'
128
+ require 'terraformer/feature'
129
+ require 'terraformer/point'
130
+ require 'terraformer/multi_point'
131
+ require 'terraformer/line_string'
132
+ require 'terraformer/multi_line_string'
133
+ require 'terraformer/polygon'
134
+ require 'terraformer/multi_polygon'
@@ -0,0 +1,15 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/terraformer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Kenichi Nakamura"]
6
+ gem.email = ["kenichi.nakamura@gmail.com"]
7
+ gem.description = gem.summary = ""
8
+ gem.homepage = "https://github.com/esripdx/terraformer-ruby"
9
+ gem.files = `git ls-files | grep -Ev '^(myapp|examples)'`.split("\n")
10
+ gem.test_files = `git ls-files -- test/*`.split("\n")
11
+ gem.name = "terraformer"
12
+ gem.require_paths = ["lib"]
13
+ gem.version = Terraformer::VERSION
14
+ gem.license = 'apache'
15
+ end
@@ -0,0 +1,267 @@
1
+ {
2
+ "type": "Polygon",
3
+ "coordinates": [
4
+ [
5
+ [
6
+ 100.00089398965049,
7
+ 8.82355685852279e-05
8
+ ],
9
+ [
10
+ 100.00088105440783,
11
+ 0.00017532535375140864
12
+ ],
13
+ [
14
+ 100.00085963412958,
15
+ 0.0002606963900620961
16
+ ],
17
+ [
18
+ 100.00082993510475,
19
+ 0.0003437757085983607
20
+ ],
21
+ [
22
+ 100.00079224335116,
23
+ 0.00042341737532065687
24
+ ],
25
+ [
26
+ 100.00074692186101,
27
+ 0.0004990484131054821
28
+ ],
29
+ [
30
+ 100.00069440710504,
31
+ 0.0005700958425710862
32
+ ],
33
+ [
34
+ 100.00063520482904,
35
+ 0.0006354137183563783
36
+ ],
37
+ [
38
+ 100.00056988518331,
39
+ 0.0006944290561239309
40
+ ],
41
+ [
42
+ 100.00049907723172,
43
+ 0.0007471418363985708
44
+ ],
45
+ [
46
+ 100.00042346289358,
47
+ 0.0007924061103353283
48
+ ],
49
+ [
50
+ 100.00034377037628,
51
+ 0.0008296488941866115
52
+ ],
53
+ [
54
+ 100.00026076716232,
55
+ 0.0008594431386974881
56
+ ],
57
+ [
58
+ 100.00017525261805,
59
+ 0.0008812158656376033
60
+ ],
61
+ [
62
+ 100.00008805029526,
63
+ 0.000893821132384516
64
+ ],
65
+ [
66
+ 100.0,
67
+ 0.0008984048664345436
68
+ ],
69
+ [
70
+ 99.99991194970474,
71
+ 0.000893821132384516
72
+ ],
73
+ [
74
+ 99.99982474738195,
75
+ 0.0008812158656376033
76
+ ],
77
+ [
78
+ 99.99973923283768,
79
+ 0.0008594431386974881
80
+ ],
81
+ [
82
+ 99.99965622962372,
83
+ 0.0008296488941866115
84
+ ],
85
+ [
86
+ 99.99957653710642,
87
+ 0.0007924061103353283
88
+ ],
89
+ [
90
+ 99.99950092276828,
91
+ 0.0007471418363985708
92
+ ],
93
+ [
94
+ 99.99943011481669,
95
+ 0.0006944290561239309
96
+ ],
97
+ [
98
+ 99.99936479517096,
99
+ 0.0006354137183563783
100
+ ],
101
+ [
102
+ 99.99930559289496,
103
+ 0.0005700958425710862
104
+ ],
105
+ [
106
+ 99.99925307813899,
107
+ 0.0004990484131054821
108
+ ],
109
+ [
110
+ 99.99920775664884,
111
+ 0.00042341737532065687
112
+ ],
113
+ [
114
+ 99.99917006489525,
115
+ 0.0003437757085983607
116
+ ],
117
+ [
118
+ 99.99914036587042,
119
+ 0.0002606963900620961
120
+ ],
121
+ [
122
+ 99.99911894559217,
123
+ 0.00017532535375140864
124
+ ],
125
+ [
126
+ 99.99910601034951,
127
+ 8.82355685852279e-05
128
+ ],
129
+ [
130
+ 99.99910168471588,
131
+ 1.9370377676740394e-13
132
+ ],
133
+ [
134
+ 99.99910601034951,
135
+ -8.594373353370475e-05
136
+ ],
137
+ [
138
+ 99.99911894559217,
139
+ -0.00017761719160345075
140
+ ],
141
+ [
142
+ 99.99914036587042,
143
+ -0.0002635611917568658
144
+ ],
145
+ [
146
+ 99.99917006489525,
147
+ -0.00034377570821095315
148
+ ],
149
+ [
150
+ 99.99920775664884,
151
+ -0.0004239903369654551
152
+ ],
153
+ [
154
+ 99.99925307813899,
155
+ -0.0004984754499351452
156
+ ],
157
+ [
158
+ 99.99930559289496,
159
+ -0.0005672310247747656
160
+ ],
161
+ [
162
+ 99.99936479517096,
163
+ -0.0006359866821211351
164
+ ],
165
+ [
166
+ 99.99943011481669,
167
+ -0.0006932831262689893
168
+ ],
169
+ [
170
+ 99.99950092276828,
171
+ -0.000744849974990818
172
+ ],
173
+ [
174
+ 99.99957653710642,
175
+ -0.0007906872128161134
176
+ ],
177
+ [
178
+ 99.99965622962372,
179
+ -0.0008307948259940207
180
+ ],
181
+ [
182
+ 99.99973923283768,
183
+ -0.0008594431383100805
184
+ ],
185
+ [
186
+ 99.99982474738195,
187
+ -0.0008823617984762712
188
+ ],
189
+ [
190
+ 99.99991194970474,
191
+ -0.0008938211319971085
192
+ ],
193
+ [
194
+ 100.0,
195
+ -0.0008995507996170583
196
+ ],
197
+ [
198
+ 100.00008805029526,
199
+ -0.0008938211319971085
200
+ ],
201
+ [
202
+ 100.00017525261805,
203
+ -0.0008823617984762712
204
+ ],
205
+ [
206
+ 100.00026076716232,
207
+ -0.0008594431383100805
208
+ ],
209
+ [
210
+ 100.00034377037628,
211
+ -0.0008307948259940207
212
+ ],
213
+ [
214
+ 100.00042346289358,
215
+ -0.0007906872128161134
216
+ ],
217
+ [
218
+ 100.00049907723172,
219
+ -0.000744849974990818
220
+ ],
221
+ [
222
+ 100.00056988518331,
223
+ -0.0006932831262689893
224
+ ],
225
+ [
226
+ 100.00063520482904,
227
+ -0.0006359866821211351
228
+ ],
229
+ [
230
+ 100.00069440710504,
231
+ -0.0005672310247747656
232
+ ],
233
+ [
234
+ 100.00074692186101,
235
+ -0.0004984754499351452
236
+ ],
237
+ [
238
+ 100.00079224335116,
239
+ -0.0004239903369654551
240
+ ],
241
+ [
242
+ 100.00082993510475,
243
+ -0.00034377570821095315
244
+ ],
245
+ [
246
+ 100.00085963412958,
247
+ -0.0002635611917568658
248
+ ],
249
+ [
250
+ 100.00088105440783,
251
+ -0.00017761719160345075
252
+ ],
253
+ [
254
+ 100.00089398965049,
255
+ -8.594373353370475e-05
256
+ ],
257
+ [
258
+ 100.00089831528412,
259
+ 1.9370377676740394e-13
260
+ ],
261
+ [
262
+ 100.00089398965049,
263
+ 8.82355685852279e-05
264
+ ]
265
+ ]
266
+ ]
267
+ }
@@ -0,0 +1,10 @@
1
+ { "type": "GeometryCollection",
2
+ "geometries": [
3
+ { "type": "Point",
4
+ "coordinates": [100.0, 0.0]
5
+ },
6
+ { "type": "LineString",
7
+ "coordinates": [ [101.0, 0.0], [102.0, 1.0] ]
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,3 @@
1
+ { "type": "LineString",
2
+ "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
3
+ }
@@ -0,0 +1,6 @@
1
+ { "type": "MultiLineString",
2
+ "coordinates": [
3
+ [ [100.0, 0.0], [101.0, 1.0] ],
4
+ [ [102.0, 2.0], [103.0, 3.0] ]
5
+ ]
6
+ }
@@ -0,0 +1,3 @@
1
+ { "type": "MultiPoint",
2
+ "coordinates": [ [100.0, 0.0], [101.0, 1.0] ]
3
+ }
@@ -0,0 +1,7 @@
1
+ { "type": "MultiPolygon",
2
+ "coordinates": [
3
+ [[[102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0]]],
4
+ [[[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]],
5
+ [[100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2]]]
6
+ ]
7
+ }
@@ -0,0 +1 @@
1
+ { "type": "Point", "coordinates": [100.0, 0.0] }
@@ -0,0 +1,5 @@
1
+ { "type": "Polygon",
2
+ "coordinates": [
3
+ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ]
4
+ ]
5
+ }
@@ -0,0 +1,6 @@
1
+ { "type": "Polygon",
2
+ "coordinates": [
3
+ [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],
4
+ [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]
5
+ ]
6
+ }
data/test/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'bundler'
2
+ Bundler.require :default, :test
3
+
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+
7
+ lib = File.expand_path '../../lib', __FILE__
8
+ $:.unshift lib unless $:.include? lib
9
+ require 'terraformer'
10
+
11
+ module MiniTest::Expectations
12
+ infect_an_assertion :refute_nil, :dont_be_terrible_ok, :unary
13
+ end
14
+
15
+ examples = File.expand_path '../examples', __FILE__
16
+ EXAMPLES = Dir[examples + '/*.geojson'].reduce({}) do |h, gj|
17
+ h[gj.sub(examples+'/','').sub(/\.geojson$/,'').to_sym] =
18
+ File.read(gj).gsub(/\r*\n*/,'').gsub(' ',' ')
19
+ h
20
+ end
@@ -0,0 +1,137 @@
1
+ require_relative './helper'
2
+
3
+ describe Terraformer do
4
+
5
+ it 'dont be terrible ok' do
6
+ Terraformer.dont_be_terrible_ok
7
+ end
8
+
9
+ describe 'parsing' do
10
+
11
+ it 'parses points' do
12
+ p = Terraformer.parse EXAMPLES[:point]
13
+ p.dont_be_terrible_ok
14
+ p.type.must_equal 'Point'
15
+ p.coordinates.must_be_instance_of Terraformer::Coordinate
16
+ p.coordinates.must_equal Terraformer::Coordinate.new 100, 0
17
+ end
18
+
19
+ it 'parses multi points' do
20
+ p = Terraformer.parse EXAMPLES[:multi_point]
21
+ p.dont_be_terrible_ok
22
+ p.type.must_equal 'MultiPoint'
23
+ p.coordinates.must_be_instance_of Array
24
+ p.coordinates.length.must_equal 2
25
+ p.coordinates[0].must_equal Terraformer::Coordinate.new 100, 0
26
+ p.coordinates[1].must_equal Terraformer::Coordinate.new 101, 1
27
+ end
28
+
29
+ it 'parses line strings' do
30
+ p = Terraformer.parse EXAMPLES[:line_string]
31
+ p.dont_be_terrible_ok
32
+ p.type.must_equal 'LineString'
33
+ p.coordinates.must_be_instance_of Array
34
+ p.coordinates.length.must_equal 2
35
+ p.coordinates[0].must_equal Terraformer::Coordinate.new 100, 0
36
+ p.coordinates[1].must_equal Terraformer::Coordinate.new 101, 1
37
+ end
38
+
39
+ it 'parses multi line strings' do
40
+ p = Terraformer.parse EXAMPLES[:multi_line_string]
41
+ p.dont_be_terrible_ok
42
+ p.type.must_equal 'MultiLineString'
43
+ p.coordinates.must_be_instance_of Array
44
+ p.coordinates.length.must_equal 2
45
+ p.coordinates[0].must_be_instance_of Array
46
+ p.coordinates[0][0].must_equal Terraformer::Coordinate.new 100, 0
47
+ p.coordinates[0][1].must_equal Terraformer::Coordinate.new 101, 1
48
+ p.coordinates[1].must_be_instance_of Array
49
+ p.coordinates[1][0].must_equal Terraformer::Coordinate.new 102, 2
50
+ p.coordinates[1][1].must_equal Terraformer::Coordinate.new 103, 3
51
+ end
52
+
53
+ it 'parses polygons' do
54
+ p = Terraformer.parse EXAMPLES[:polygon]
55
+ p.dont_be_terrible_ok
56
+ p.type.must_equal 'Polygon'
57
+ p.coordinates.must_be_instance_of Array
58
+ p.coordinates[0].must_be_instance_of Array
59
+ p.coordinates[0][0].must_equal Terraformer::Coordinate.new 100, 0
60
+ p.coordinates[0][1].must_equal Terraformer::Coordinate.new 101, 0
61
+ p.coordinates[0][2].must_equal Terraformer::Coordinate.new 101, 1
62
+ p.coordinates[0][3].must_equal Terraformer::Coordinate.new 100, 1
63
+ p.coordinates[0][4].must_equal Terraformer::Coordinate.new 100, 0
64
+ refute p.has_holes?
65
+ end
66
+
67
+ it 'parses polygons with holes' do
68
+ p = Terraformer.parse EXAMPLES[:polygon_with_holes]
69
+ p.dont_be_terrible_ok
70
+ p.type.must_equal 'Polygon'
71
+ p.coordinates.must_be_instance_of Array
72
+ p.coordinates[0].must_be_instance_of Array
73
+ p.coordinates[0][0].must_equal Terraformer::Coordinate.new 100, 0
74
+ p.coordinates[0][1].must_equal Terraformer::Coordinate.new 101, 0
75
+ p.coordinates[0][2].must_equal Terraformer::Coordinate.new 101, 1
76
+ p.coordinates[0][3].must_equal Terraformer::Coordinate.new 100, 1
77
+ p.coordinates[0][4].must_equal Terraformer::Coordinate.new 100, 0
78
+ p.coordinates[1].must_be_instance_of Array
79
+ p.coordinates[1][0].must_equal Terraformer::Coordinate.new 100.2, 0.2
80
+ p.coordinates[1][1].must_equal Terraformer::Coordinate.new 100.8, 0.2
81
+ p.coordinates[1][2].must_equal Terraformer::Coordinate.new 100.8, 0.8
82
+ p.coordinates[1][3].must_equal Terraformer::Coordinate.new 100.2, 0.8
83
+ p.coordinates[1][4].must_equal Terraformer::Coordinate.new 100.2, 0.2
84
+ assert p.has_holes?
85
+ end
86
+
87
+ it 'parses multipolygons' do
88
+ p = Terraformer.parse EXAMPLES[:multi_polygon]
89
+ p.dont_be_terrible_ok
90
+ p.type.must_equal 'MultiPolygon'
91
+ p.coordinates[0].must_be_instance_of Array
92
+ p.coordinates[0][0].must_be_instance_of Array
93
+ p.coordinates[0][0][0].must_equal Terraformer::Coordinate.new 102, 2
94
+ p.coordinates[0][0][1].must_equal Terraformer::Coordinate.new 103, 2
95
+ p.coordinates[0][0][2].must_equal Terraformer::Coordinate.new 103, 3
96
+ p.coordinates[0][0][3].must_equal Terraformer::Coordinate.new 102, 3
97
+ p.coordinates[0][0][4].must_equal Terraformer::Coordinate.new 102, 2
98
+ p.coordinates[1].must_be_instance_of Array
99
+ p.coordinates[1][0].must_be_instance_of Array
100
+ p.coordinates[1][0][0].must_equal Terraformer::Coordinate.new 100, 0
101
+ p.coordinates[1][0][1].must_equal Terraformer::Coordinate.new 101, 0
102
+ p.coordinates[1][0][2].must_equal Terraformer::Coordinate.new 101, 1
103
+ p.coordinates[1][0][3].must_equal Terraformer::Coordinate.new 100, 1
104
+ p.coordinates[1][0][4].must_equal Terraformer::Coordinate.new 100, 0
105
+ p.coordinates[1][1].must_be_instance_of Array
106
+ p.coordinates[1][1][0].must_equal Terraformer::Coordinate.new 100.2, 0.2
107
+ p.coordinates[1][1][1].must_equal Terraformer::Coordinate.new 100.8, 0.2
108
+ p.coordinates[1][1][2].must_equal Terraformer::Coordinate.new 100.8, 0.8
109
+ p.coordinates[1][1][3].must_equal Terraformer::Coordinate.new 100.2, 0.8
110
+ p.coordinates[1][1][4].must_equal Terraformer::Coordinate.new 100.2, 0.2
111
+ end
112
+
113
+ it 'parses as geographic' do
114
+ [:point, :multi_point, :line_string, :multi_line_string,
115
+ :polygon, :polygon_with_holes, :multi_polygon].each do |type|
116
+ g = Terraformer.parse EXAMPLES[type]
117
+ assert g.geographic?
118
+ end
119
+ end
120
+
121
+ end
122
+
123
+ describe 'coordinates' do
124
+
125
+ it 'buffers into circles' do
126
+ p = Terraformer.parse EXAMPLES[:point]
127
+ p.dont_be_terrible_ok
128
+ p.type.must_equal 'Point'
129
+ p.coordinates.must_be_instance_of Terraformer::Coordinate
130
+ p.coordinates.must_equal Terraformer::Coordinate.new 100, 0
131
+ c = p.coordinates.buffer 100
132
+ JSON.parse(c.to_json).must_equal JSON.parse(EXAMPLES[:circle])
133
+ end
134
+
135
+ end
136
+
137
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: terraformer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kenichi Nakamura
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-08 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: ''
14
+ email:
15
+ - kenichi.nakamura@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - ".gitignore"
21
+ - Gemfile
22
+ - README.md
23
+ - Rakefile
24
+ - lib/terraformer.rb
25
+ - lib/terraformer/bounds.rb
26
+ - lib/terraformer/coordinate.rb
27
+ - lib/terraformer/feature.rb
28
+ - lib/terraformer/geometry.rb
29
+ - lib/terraformer/line_string.rb
30
+ - lib/terraformer/multi_line_string.rb
31
+ - lib/terraformer/multi_point.rb
32
+ - lib/terraformer/multi_polygon.rb
33
+ - lib/terraformer/point.rb
34
+ - lib/terraformer/polygon.rb
35
+ - lib/terraformer/version.rb
36
+ - terraformer.gemspec
37
+ - test/examples/circle.geojson
38
+ - test/examples/geometry_collection.geojson
39
+ - test/examples/line_string.geojson
40
+ - test/examples/multi_line_string.geojson
41
+ - test/examples/multi_point.geojson
42
+ - test/examples/multi_polygon.geojson
43
+ - test/examples/point.geojson
44
+ - test/examples/polygon.geojson
45
+ - test/examples/polygon_with_holes.geojson
46
+ - test/helper.rb
47
+ - test/terraformer_spec.rb
48
+ homepage: https://github.com/esripdx/terraformer-ruby
49
+ licenses:
50
+ - apache
51
+ metadata: {}
52
+ post_install_message:
53
+ rdoc_options: []
54
+ require_paths:
55
+ - lib
56
+ required_ruby_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ requirements: []
67
+ rubyforge_project:
68
+ rubygems_version: 2.2.2
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: ''
72
+ test_files:
73
+ - test/examples/circle.geojson
74
+ - test/examples/geometry_collection.geojson
75
+ - test/examples/line_string.geojson
76
+ - test/examples/multi_line_string.geojson
77
+ - test/examples/multi_point.geojson
78
+ - test/examples/multi_polygon.geojson
79
+ - test/examples/point.geojson
80
+ - test/examples/polygon.geojson
81
+ - test/examples/polygon_with_holes.geojson
82
+ - test/helper.rb
83
+ - test/terraformer_spec.rb