australia_postcode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,124 @@
1
+ # coding: utf-8
2
+ require "csv"
3
+ require "australia/postcode/version"
4
+
5
+ # A module for all things Australian
6
+ module Australia
7
+ # The Australia::Postcode class represents Australian postcodes and provides
8
+ # methods for manipulating them. Right now you can find the distance between
9
+ # two postcodes and that's about it.
10
+ class Postcode
11
+ attr_reader :postcode, :suburb, :state, :delivery_center, :type, :latitude, :longitude
12
+
13
+ def initialize(postcode, suburb, state, delivery_center, type, latitude, longitude)
14
+ @postcode = postcode.to_i
15
+ @suburb = suburb.strip
16
+ @state = state.strip
17
+ @delivery_center = delivery_center.strip
18
+ @type = type.strip
19
+ @latitude = latitude.to_f
20
+ @longitude = longitude.to_f
21
+ end
22
+
23
+ # Returns a [latitude, longitude] tuple
24
+ #
25
+ # @return [Array]
26
+ def coords
27
+ [latitude, longitude]
28
+ end
29
+
30
+ # Computes the distance from this postcode to another postcode using the
31
+ # Haversine formula
32
+ #
33
+ # @return [Float]
34
+ def distance(other)
35
+ earth_radius = 6371
36
+ Δlat = radians(other.latitude - latitude)
37
+ Δlong = radians(other.longitude - longitude)
38
+ a = sin(Δlat / 2) * sin(Δlat / 2) +
39
+ cos(radians(latitude)) * cos(radians(other.latitude)) *
40
+ sin(Δlong / 2) * sin(Δlong / 2)
41
+ c = 2 * atan2(√(a), √(1 - a))
42
+ earth_radius * c
43
+ end
44
+
45
+ alias_method :-, :distance
46
+
47
+ # Inspects the [Postcode]
48
+ def inspect
49
+ "#<#{self.class} postcode=#{postcode.inspect} suburb=#{suburb.inspect} latitude=#{latitude.inspect} longitude=#{longitude.inspect}>"
50
+ end
51
+
52
+ private
53
+
54
+ def sin(θ)
55
+ Math.sin θ
56
+ end
57
+
58
+ def cos(θ)
59
+ Math.sin θ
60
+ end
61
+
62
+ def atan2(y, x)
63
+ Math.atan2 y, x
64
+ end
65
+
66
+ def √(x)
67
+ Math.sqrt x
68
+ end
69
+
70
+ def radians(degrees)
71
+ degrees * π / 180
72
+ end
73
+
74
+ def π
75
+ Math::PI
76
+ end
77
+
78
+ class << self
79
+ # Finds all postcodes/suburbs for the given postcode.
80
+ #
81
+ # @return [Array[Postcode]]
82
+ def find(postcode)
83
+ indexed_on_postcode[postcode.to_i]
84
+ end
85
+
86
+ # Finds all the postcodes/suburbs for the given suburb name.
87
+ #
88
+ # @return [Array[Postcode]]
89
+ def find_by_suburb(suburb)
90
+ indexed_on_suburb[suburb.strip.upcase]
91
+ end
92
+
93
+ # Finds the closest postcode to the given coordinates
94
+ #
95
+ # @return [Postcode]
96
+ def find_by_coords(latitude, longitude)
97
+ data.min_by { |postcode|
98
+ (latitude - postcode.latitude) ** 2 + (longitude - postcode.longitude) ** 2
99
+ }
100
+ end
101
+
102
+ private
103
+ def indexed_on_postcode
104
+ @indexed_on_postcode ||= data.group_by(&:postcode)
105
+ end
106
+
107
+ def indexed_on_suburb
108
+ @indexed_on_suburb ||= data.group_by(&:suburb)
109
+ end
110
+
111
+ def data
112
+ @data ||= raw_data.map { |data| new(*data) }
113
+ end
114
+
115
+ def raw_data
116
+ CSV.parse(File.read(data_filename)).drop(1)
117
+ end
118
+
119
+ def data_filename
120
+ File.expand_path("../postcode/data.csv", __FILE__)
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1 @@
1
+ require "australia/postcode"
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: australia_postcode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Charlie Somerville
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: yard
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: Library for manipulating Australian postcodes
31
+ email: charlie@charliesomerville.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - lib/australia_postcode.rb
37
+ - lib/australia/postcode.rb
38
+ - lib/australia/postcode/data.csv
39
+ homepage: https://github.com/charliesome/australia_postcode
40
+ licenses: []
41
+ post_install_message:
42
+ rdoc_options: []
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ none: false
47
+ requirements:
48
+ - - ! '>='
49
+ - !ruby/object:Gem::Version
50
+ version: '0'
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 1.8.24
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Manipulates Australian postcodes
63
+ test_files: []
64
+ has_rdoc: