carto_json 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .rbx
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Geoloqi
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
File without changes
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # CartoJson
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'carto_json'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install carto_json
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require "rake/testtask"
5
+
6
+ desc "Run all tests"
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "spec"
9
+ t.test_files = FileList['spec/*_spec.rb','spec/shapes/*_spec.rb']
10
+ t.verbose = true
11
+ end
12
+
13
+ task :default => :test
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
3
+ require File.expand_path('../lib/carto_json/version', __FILE__)
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.authors = ["Kyle Drake"]
7
+ gem.email = ["kyledrake@gmail.com"]
8
+ gem.description = %q{Helpers for the CartoJSON specification}
9
+ gem.summary = %q{Helpers for the CartoJSON spec}
10
+ gem.homepage = ""
11
+
12
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split("\n")
14
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
15
+ gem.name = "carto_json"
16
+ gem.require_paths = ["lib"]
17
+ gem.version = CartoJson::VERSION
18
+ gem.add_dependency 'multi_json'
19
+ gem.add_development_dependency 'rake'
20
+ gem.add_development_dependency 'pry'
21
+ gem.add_development_dependency 'minitest'
22
+ gem.add_development_dependency 'json'
23
+ end
@@ -0,0 +1,33 @@
1
+ module CartoJson
2
+ class Circle < Point
3
+ type :circle
4
+
5
+ attr_accessor :radius
6
+
7
+ def radius=(r)
8
+ raise InvalidRadiusError, 'radius cannot be negative' if r < 0
9
+ raise InvalidRadiusError, 'radius cannot be blank' if r.nil?
10
+ raise InvalidRadiusError, 'radius must be a number' unless (r.is_a?(Integer) || r.is_a?(Float))
11
+ raise InvalidRadiusError, 'radius cannot be zero' if r == 0
12
+ @radius = r
13
+ end
14
+
15
+ def to_wkt
16
+ raise NotImplementedError, 'WKT does not support circles directly, conversion to polygon is required'
17
+ end
18
+
19
+ def to_point
20
+ Point.new LAT => send(LAT), LNG => send(LNG)
21
+ end
22
+
23
+ def to_hash
24
+ {:type => self.class.type,
25
+ :center => {
26
+ LAT => send(LAT),
27
+ LNG => send(LNG)
28
+ },
29
+ :radius => radius
30
+ }
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,8 @@
1
+ module CartoJson
2
+ class Error < StandardError; end
3
+ class NotImplementedError < Error; end
4
+ class InputError < Error; end
5
+ class InsufficientPointsError < Error; end
6
+ class InvalidRadiusError < Error; end
7
+ class InvalidTypeError < Error; end
8
+ end
@@ -0,0 +1,39 @@
1
+ module CartoJson
2
+ class LineString
3
+ include Shape
4
+ type :linestring
5
+
6
+ attr_accessor :points
7
+
8
+ def initialize(input)
9
+ super
10
+ @points = []
11
+ input[:points].each do |p|
12
+ if p.is_a?(Point)
13
+ @points << p
14
+ else
15
+ @points << Point.new(LAT => p[LAT], LNG => p[LNG])
16
+ end
17
+ end
18
+
19
+ validate
20
+ end
21
+
22
+ def to_hash
23
+ {:type => self.class.type,
24
+ :points => points.collect {|p| p.to_hash_for_array}}
25
+ end
26
+
27
+ def to_wkt
28
+ "#{type.to_s.upcase} ((#{@points.dup.push(@points.first).collect {|p| "#{p.send(LNG)} #{p.send(LAT)}"}.join(', ')}))"
29
+ end
30
+
31
+ protected
32
+
33
+ def validate
34
+ if @points.length < 2
35
+ raise InsufficientPointsError, "a minimum of 2 points is required to make a linestring, you provided #{@points.length}"
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,55 @@
1
+ module CartoJson
2
+ class Parser
3
+ def self.parse(input)
4
+ p = new input
5
+ p.parse
6
+ end
7
+
8
+ def initialize(input)
9
+ @input = input
10
+ @parsed = nil
11
+ end
12
+
13
+ def parse(input=@input)
14
+ return nil if input.nil?
15
+
16
+ case input
17
+ when Array
18
+ @parsed = []
19
+ input.each {|element| @parsed << parse_element(element) }
20
+
21
+ when Hash
22
+ input = Utils.symbolize_keys(input)
23
+ @parsed = parse_element input
24
+
25
+ when String
26
+ begin
27
+ decoded = MultiJson.decode(input, :symbolize_keys => true)
28
+ rescue MultiJson::DecodeError => e
29
+ raise InputError, "unable to decode JSON: \"#{e.message}\""
30
+ end
31
+ @parsed = parse decoded
32
+ else
33
+ raise InputError, "expected Array, Hash or String, you provided #{input.class}"
34
+ end
35
+
36
+ @parsed
37
+ end
38
+
39
+ def parse_element(element)
40
+ if element[:type].nil?
41
+ if element[LAT] && element[LNG]
42
+ element[:type] = 'point'
43
+ else
44
+ raise InputError, "cannot determine type for the provided element (type is missing or #{LAT}/#{LNG} are not present)"
45
+ end
46
+ end
47
+
48
+ unless TYPES.include? element[:type].to_sym
49
+ raise InvalidTypeError, "unsupported type: \"#{element[:type]}\", supported types: #{TYPES.join(', ')}"
50
+ end
51
+
52
+ CartoJson.const_get(element[:type].capitalize).parse element
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ module CartoJson
2
+ class Point
3
+ include Shape
4
+
5
+ type :point
6
+
7
+ attr_accessor LAT, LNG
8
+
9
+ def initialize(input)
10
+ raise InputError, 'cannot create a shape with an array' if input.is_a?(Array)
11
+
12
+ if input[LAT].nil? || input[LNG].nil?
13
+ raise InputError, "#{LAT} and #{LNG} are required to instantiate a point"
14
+ end
15
+
16
+ input[LAT] = input[LAT].to_f
17
+ input[LNG] = input[LNG].to_f
18
+
19
+ super input
20
+
21
+ unless (-90..90).include? input[LAT]
22
+ raise InputError, "latitude must be between -90 and 90, \"#{input[LAT]}\" was provided"
23
+ end
24
+
25
+ unless (-180..180).include? input[LNG]
26
+ raise InputError, "longitude must be between -180 and 180, \"#{input[LNG]}\" was provided"
27
+ end
28
+ end
29
+
30
+ def to_hash
31
+ {:type => self.class.type,
32
+ LAT => send(LAT),
33
+ LNG => send(LNG)}
34
+ end
35
+
36
+ def to_hash_for_array
37
+ {LAT => send(LAT),
38
+ LNG => send(LNG)}
39
+ end
40
+
41
+ def ==(point)
42
+ send(LAT) == point.send(LAT) && send(LNG) == point.send(LNG)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,13 @@
1
+ module CartoJson
2
+ class Polygon < LineString
3
+ type :polygon
4
+
5
+ protected
6
+
7
+ def validate
8
+ if @points.length < 3
9
+ raise InsufficientPointsError, "a minimum of 3 points is required to make a polygon, you provided #{@points.length}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,52 @@
1
+ module CartoJson
2
+
3
+ module Shape
4
+ def self.included(base)
5
+ base.extend(ClassMethods)
6
+ end
7
+
8
+ module ClassMethods
9
+ attr_accessor :type
10
+
11
+ def type(val=nil)
12
+ @type = val unless val.nil?
13
+ @type
14
+ end
15
+
16
+ def parse(input)
17
+ new input
18
+ end
19
+ end
20
+
21
+ def initialize(input=nil)
22
+ raise InputError, 'cannot create a shape with an array' if input.is_a?(Array)
23
+
24
+ if input.respond_to?(:each)
25
+ input.each do |k,v|
26
+ next if k == :type
27
+ send "#{k}=".to_sym, v
28
+ end
29
+ end
30
+ end
31
+
32
+ def to_hash
33
+ raise NotImplementedError, 'you need to provide the to_hash method'
34
+ end
35
+
36
+ def to_json
37
+ MultiJson.encode to_hash
38
+ end
39
+
40
+ def to_pretty_json
41
+ MultiJson.encode to_hash, :pretty => true
42
+ end
43
+
44
+ def type
45
+ self.class.type
46
+ end
47
+
48
+ def to_wkt
49
+ "#{self.class.name.split('::').last.upcase} (#{send(LNG)} #{send(LAT)})"
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,19 @@
1
+ module CartoJson
2
+ module Utils
3
+ def self.symbolize_keys(arg)
4
+ case arg
5
+ when Array
6
+ arg.map { |elem| symbolize_keys elem }
7
+ when Hash
8
+ Hash[
9
+ arg.map { |key, value|
10
+ k = key.is_a?(String) ? key.to_sym : key
11
+ v = symbolize_keys value
12
+ [k,v]
13
+ }]
14
+ else
15
+ arg
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module CartoJson
2
+ VERSION = "0.0.6"
3
+ end
@@ -0,0 +1,39 @@
1
+ # TODO: Write in a real parsing library like Parslet, finish multi type support
2
+ module CartoJson
3
+ class WKTParser
4
+ def self.parse(input)
5
+ new(input).parse
6
+ end
7
+
8
+ def initialize(input)
9
+ @input = input
10
+ end
11
+
12
+ def parse
13
+ type = @input.match /(\w+) \(/i
14
+
15
+ raise InputError, "invalid WKT input" if type.nil?
16
+
17
+ type = type.captures.first
18
+
19
+ case type.downcase.to_sym
20
+ when :polygon
21
+ points = xy_to_points(@input.match(/polygon \(\((.+)\)\)/i).captures.first)
22
+ Polygon.new :points => points[0...points.length-1]
23
+ when :linestring
24
+ LineString.new :points => xy_to_points(@input.match(/linestring \((.+)\)/i).captures.first)
25
+ when :point
26
+ Point.new xy_to_points(@input.match(/point \((.+)\)/i).captures.first).first
27
+ else
28
+ raise NotImplementedError, 'multi types are not implemented yet' if MULTI_TYPES.include? type.downcase
29
+ raise Input Error, "invalid type: #{type}"
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def xy_to_points(capture)
36
+ capture.split(',').collect { |coordinates| coordinates.split(' ') }.collect {|c| {LAT => c.last, LNG => c.first}}
37
+ end
38
+ end
39
+ end
data/lib/carto_json.rb ADDED
@@ -0,0 +1,31 @@
1
+ module CartoJson
2
+ PRIMITIVE_TYPES = [:point, :linestring, :polygon, :rectangle]
3
+ MULTI_TYPES = [:multipoint, :multilinestring, :multipolygon]
4
+ TYPES = PRIMITIVE_TYPES+MULTI_TYPES
5
+
6
+ # These might change, so I've made it easier to switch.
7
+ LAT = :lat.freeze
8
+ LNG = :lng.freeze
9
+
10
+ class << self
11
+ def parse(input)
12
+ Parser.parse input
13
+ end
14
+
15
+ def parse_wkt(input)
16
+ WKTParser.parse input
17
+ end
18
+ end
19
+ end
20
+
21
+ require 'carto_json/errors'
22
+ require 'carto_json/utils'
23
+ require 'carto_json/parser'
24
+ require 'carto_json/shape'
25
+ require 'carto_json/point'
26
+ require 'carto_json/circle'
27
+ require 'carto_json/line_string'
28
+ require 'carto_json/polygon'
29
+ require 'carto_json/wkt_parser'
30
+ require 'carto_json/version'
31
+ require 'multi_json'
@@ -0,0 +1,18 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ describe CartoJson do
4
+ describe 'the parse module function' do
5
+ it 'should load point' do
6
+ point = CartoJson.parse MultiJson.encode({
7
+ :type => 'point',
8
+ LAT => 45.52,
9
+ LNG => -122.681944
10
+ })
11
+
12
+ point.class.must_equal CartoJson::Point
13
+ point.type.must_equal :point
14
+ point.send(LAT).must_equal 45.52
15
+ point.send(LNG).must_equal -122.681944
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,52 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ include CartoJson
4
+
5
+ describe CartoJson::Circle do
6
+ before do
7
+ @args = {LAT => 45.52, LNG => -122.681944, :radius => 500}
8
+ end
9
+
10
+ it 'should create a circle with valid data' do
11
+
12
+ circle = Circle.new @args
13
+ circle.is_a?(Circle).must_equal true
14
+ circle.type.must_equal :circle
15
+ circle.class.type.must_equal :circle
16
+
17
+ hash = MultiJson.decode(circle.to_json, :symbolize_keys => true)
18
+
19
+ hash[:center][LAT].must_equal @args[LAT]
20
+ hash[:center][LNG].must_equal @args[LNG]
21
+ hash[:radius].must_equal @args[:radius]
22
+ end
23
+
24
+ it 'should fail with negative radius' do
25
+ lambda {
26
+ Circle.new @args.merge(:radius => -40)
27
+ }.must_raise CartoJson::InvalidRadiusError
28
+ end
29
+
30
+ it 'should fail with crazy lat and lng' do
31
+ lambda {
32
+ Circle.new @args.merge(LAT => -31337)
33
+ }.must_raise CartoJson::InputError
34
+
35
+ lambda {
36
+ Circle.new @args.merge(LNG => -31337)
37
+ }.must_raise CartoJson::InputError
38
+ end
39
+
40
+ it 'fails for wkt' do
41
+ lambda { Circle.new(@args).to_wkt }.must_raise CartoJson::NotImplementedError
42
+ end
43
+
44
+ it 'converts to point' do
45
+ p = Circle.new(@args).to_point
46
+ @args.delete :radius
47
+
48
+ np = Point.new(@args)
49
+ p.send(LAT).must_equal np.send(LAT)
50
+ p.send(LNG).must_equal np.send(LNG)
51
+ end
52
+ end
data/spec/env.rb ADDED
@@ -0,0 +1,8 @@
1
+ # Bundler.setup
2
+ require 'rubygems'
3
+ require './lib/carto_json.rb'
4
+ require 'minitest/autorun'
5
+ require 'pry'
6
+
7
+ LAT = CartoJson::LAT
8
+ LNG = CartoJson::LNG
@@ -0,0 +1,32 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ include CartoJson
4
+
5
+ describe LineString do
6
+ before do
7
+ @args = {:points => [
8
+ {LAT => 45.52, LNG => -122.681944},
9
+ {LAT => 45.53, LNG => -122.681945},
10
+ {LAT => 45.54, LNG => -122.681946}]}
11
+ end
12
+
13
+ it 'should create a linestring with valid data' do
14
+ ls = LineString.new @args
15
+ ls.type.must_equal :linestring
16
+ ls.class.type.must_equal :linestring
17
+ ls.points.first.class.must_equal Point
18
+
19
+ hash = MultiJson.decode(ls.to_json, :symbolize_keys => true)
20
+ hash[:points].length.must_equal 3
21
+ hash[:points].first[LAT].must_equal @args[:points].first[LAT]
22
+ hash[:points].first[LNG].must_equal @args[:points].first[LNG]
23
+
24
+ ls.to_wkt.must_equal "LINESTRING ((#{ls.points.dup.push(ls.points.first).collect {|p| "#{p.send(LNG)} #{p.send(LAT)}"}.join(', ')}))"
25
+ end
26
+
27
+ it 'should fail if less than three points' do
28
+ @args[:points].pop
29
+ @args[:points].pop
30
+ lambda { LineString.new @args }.must_raise InsufficientPointsError
31
+ end
32
+ end
@@ -0,0 +1,62 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ describe CartoJson::Parser do
4
+
5
+ before do
6
+ @json_point_one = MultiJson.encode({
7
+ :type => 'point',
8
+ LAT => 45.52,
9
+ LNG => -122.681944
10
+ })
11
+
12
+ @json_point_two = MultiJson.encode({
13
+ :type => 'point',
14
+ LAT => 45.53,
15
+ LNG => -122.681945
16
+ })
17
+ end
18
+
19
+ describe 'the parse class method' do
20
+ it 'should fail when provided with crap data' do
21
+ lambda { CartoJson::Parser.parse MultiJson.encode({}) }.must_raise CartoJson::InputError
22
+ lambda { CartoJson::Parser.parse MultiJson.encode({:junk => 'ok'}) }.must_raise CartoJson::InputError
23
+ CartoJson::Parser.parse(nil).must_equal nil
24
+ lambda { CartoJson::Parser.parse 'CATS ARE FUN' }.must_raise CartoJson::InputError
25
+ end
26
+
27
+ it 'should load point from JSON string' do
28
+ point = CartoJson::Parser.parse @json_point_one
29
+
30
+ point.class.must_equal CartoJson::Point
31
+ point.type.must_equal :point
32
+ point.send(LAT).must_equal 45.52
33
+ point.send(LNG).must_equal -122.681944
34
+ end
35
+
36
+ it 'should load point from hash' do
37
+ point = CartoJson::Parser.parse MultiJson.decode(@json_point_one, :symbolize_keys => true)
38
+
39
+ point.class.must_equal CartoJson::Point
40
+ point.type.must_equal :point
41
+ point.send(LAT).must_equal 45.52
42
+ point.send(LNG).must_equal -122.681944
43
+ end
44
+
45
+ it 'should load point from hash with string keys' do
46
+ point = CartoJson::Parser.parse MultiJson.decode(@json_point_one, :symbolize_keys => false)
47
+
48
+ point.class.must_equal CartoJson::Point
49
+ point.type.must_equal :point
50
+ point.send(LAT).must_equal 45.52
51
+ point.send(LNG).must_equal -122.681944
52
+ end
53
+
54
+ it 'should parse objects with multiple points' do
55
+ points = CartoJson.parse "[#{@json_point_one}, #{@json_point_two}]"
56
+
57
+ points.length.must_equal 2
58
+ points.first.send(LAT).must_equal 45.52
59
+ points.last.send(LNG).must_equal -122.681945
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,49 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ include CartoJson
4
+
5
+ describe CartoJson::Point do
6
+ before do
7
+ @args = {LAT => 45.52, LNG => -122.681944}
8
+ end
9
+
10
+ it 'should create a point with valid data' do
11
+ point = Point.new @args
12
+ point.type.must_equal :point
13
+ point.class.type.must_equal :point
14
+
15
+ hash = MultiJson.decode(point.to_json, :symbolize_keys => true)
16
+ hash[LAT].must_equal @args[LAT]
17
+ hash[LNG].must_equal @args[LNG]
18
+ end
19
+
20
+ it 'should fail with crazy lat and lng' do
21
+ lambda {
22
+ Point.new @args.merge(LAT => -31337)
23
+ }.must_raise CartoJson::InputError
24
+
25
+ lambda {
26
+ Point.new @args.merge(LNG => -31337)
27
+ }.must_raise CartoJson::InputError
28
+ end
29
+
30
+ it 'should fail with an array' do
31
+ lambda {
32
+ Point.new [1,2,3]
33
+ }.must_raise CartoJson::InputError
34
+ end
35
+
36
+ it 'works with string keys' do
37
+ p = Point.new Hash[@args.map {|k,v| [k.to_sym, v]}]
38
+ p.send(LAT).class.must_equal Float
39
+ end
40
+
41
+ it 'converts latitude and longitude to float' do
42
+ p = Point.new Hash[@args.map {|k,v| [k.to_sym, v.to_s]}]
43
+ p.send(LAT).class.must_equal Float
44
+ end
45
+
46
+ it 'returns wkt' do
47
+ Point.new(@args).to_wkt.must_equal "POINT (#{@args[LNG]} #{@args[LAT]})"
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ include CartoJson
4
+
5
+ describe CartoJson::Polygon do
6
+ before do
7
+ @args = {:points => [
8
+ {LAT => 45.52, LNG => -122.681944},
9
+ {LAT => 45.53, LNG => -122.681945},
10
+ {LAT => 45.54, LNG => -122.681946}]}
11
+ end
12
+
13
+ it 'should create a polygon with valid data' do
14
+ p = Polygon.new @args
15
+ p.type.must_equal :polygon
16
+ p.class.type.must_equal :polygon
17
+
18
+ p.points.first.class.must_equal Point
19
+
20
+ hash = MultiJson.decode(p.to_json, :symbolize_keys => true)
21
+
22
+ hash[:points].length.must_equal 3
23
+ hash[:points].first[LAT].must_equal @args[:points].first[LAT]
24
+ hash[:points].first[LNG].must_equal @args[:points].first[LNG]
25
+
26
+ p.to_wkt.must_equal "POLYGON ((#{p.points.dup.push(p.points.first).collect {|p| "#{p.send(LNG)} #{p.send(LAT)}"}.join(', ')}))"
27
+ end
28
+
29
+ it 'should fail if less than three points' do
30
+ @args[:points].pop
31
+ lambda { Polygon.new @args }.must_raise InsufficientPointsError
32
+ end
33
+ end
@@ -0,0 +1,28 @@
1
+ require File.join File.dirname(__FILE__), 'env.rb'
2
+
3
+ include CartoJson
4
+
5
+ describe CartoJson::WKTParser do
6
+ it 'works with point' do
7
+ point = WKTParser.parse "POINT (2 1)"
8
+ point.class.must_equal Point
9
+ point.send(LAT).must_equal 1
10
+ point.send(LNG).must_equal 2
11
+ end
12
+
13
+ it 'works with polygon' do
14
+ polygon = WKTParser.parse "POLYGON ((2 1, 4 3, 6 5, 2 1))"
15
+ polygon.class.must_equal Polygon
16
+ polygon.points.length.must_equal 3
17
+ polygon.points.first.must_equal Point.new(LAT => 1, LNG => 2)
18
+ polygon.points.last.must_equal Point.new(LAT => 5, LNG => 6)
19
+ end
20
+
21
+ it 'works with linestring' do
22
+ ls = WKTParser.parse "LINESTRING (2 1, 4 3)"
23
+ ls.class.must_equal LineString
24
+ ls.type.must_equal :linestring
25
+ ls.points.first.must_equal Point.new(LAT => 1, LNG => 2)
26
+ ls.points.last.must_equal Point.new(LAT => 3, LNG => 4)
27
+ end
28
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: carto_json
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.6
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kyle Drake
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-09 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: multi_json
16
+ requirement: &70336033905880 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70336033905880
25
+ - !ruby/object:Gem::Dependency
26
+ name: rake
27
+ requirement: &70336033905460 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70336033905460
36
+ - !ruby/object:Gem::Dependency
37
+ name: pry
38
+ requirement: &70336033905040 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70336033905040
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: &70336033904620 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70336033904620
58
+ - !ruby/object:Gem::Dependency
59
+ name: json
60
+ requirement: &70336033904200 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70336033904200
69
+ description: Helpers for the CartoJSON specification
70
+ email:
71
+ - kyledrake@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - Gemfile
78
+ - LICENSE
79
+ - README
80
+ - README.md
81
+ - Rakefile
82
+ - carto_json.gemspec
83
+ - lib/carto_json.rb
84
+ - lib/carto_json/circle.rb
85
+ - lib/carto_json/errors.rb
86
+ - lib/carto_json/line_string.rb
87
+ - lib/carto_json/parser.rb
88
+ - lib/carto_json/point.rb
89
+ - lib/carto_json/polygon.rb
90
+ - lib/carto_json/shape.rb
91
+ - lib/carto_json/utils.rb
92
+ - lib/carto_json/version.rb
93
+ - lib/carto_json/wkt_parser.rb
94
+ - spec/carto_json_spec.rb
95
+ - spec/circle_spec.rb
96
+ - spec/env.rb
97
+ - spec/line_string_spec.rb
98
+ - spec/parser_spec.rb
99
+ - spec/point_spec.rb
100
+ - spec/polygon_spec.rb
101
+ - spec/wkt_parser_spec.rb
102
+ homepage: ''
103
+ licenses: []
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.17
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: Helpers for the CartoJSON spec
126
+ test_files:
127
+ - spec/carto_json_spec.rb
128
+ - spec/circle_spec.rb
129
+ - spec/env.rb
130
+ - spec/line_string_spec.rb
131
+ - spec/parser_spec.rb
132
+ - spec/point_spec.rb
133
+ - spec/polygon_spec.rb
134
+ - spec/wkt_parser_spec.rb
135
+ has_rdoc: