swissmatch-location 0.0.1.201208 → 0.1.1.201304

Sign up to get free protection for your applications and to get access to all the features.
@@ -10,6 +10,6 @@ module SwissMatch
10
10
  module Location
11
11
 
12
12
  # The version of the swissmatch-location gem.
13
- Version = Gem::Version.new("0.0.1")
13
+ Version = Gem::Version.new("0.1.1.201304")
14
14
  end
15
15
  end
@@ -38,6 +38,10 @@ module SwissMatch
38
38
  }
39
39
  end
40
40
 
41
+ def to_a
42
+ [to_s, @language, @sequence_number]
43
+ end
44
+
41
45
  # @private
42
46
  # @see Object#inspect
43
47
  def inspect
@@ -57,6 +57,12 @@ module SwissMatch
57
57
  # The official name of this zip code (max. 18 characters)
58
58
  attr_reader :name_short
59
59
 
60
+ # @note This method exists mostly for internal purposes
61
+ #
62
+ # @return [String]
63
+ # All names, short and long, as strings, without sequence number nor language.
64
+ attr_reader :all_names
65
+
60
66
  # @return [Symbol]
61
67
  # The main language in the area of this zip code. One of :de, :fr, :it or :rt.
62
68
  attr_reader :language
@@ -74,8 +80,12 @@ module SwissMatch
74
80
  attr_reader :delivery_by
75
81
 
76
82
  # @return [SwissMatch::Community]
77
- # The community this zip code belongs to.
78
- attr_reader :community
83
+ # The largest community which belongs to this zip code.
84
+ attr_reader :largest_community
85
+
86
+ # @return [SwissMatch::Communities]
87
+ # The communities which belong to this zip code.
88
+ attr_reader :communities
79
89
 
80
90
  # @return [Date, nil]
81
91
  # The date from which on this zip code starts to be in use
@@ -105,7 +115,8 @@ module SwissMatch
105
115
  language_alternative,
106
116
  sortfile_member,
107
117
  delivery_by,
108
- community,
118
+ largest_community,
119
+ communities,
109
120
  valid_from,
110
121
  valid_until = nil
111
122
  )
@@ -120,28 +131,51 @@ module SwissMatch
120
131
  @name_short = name_short.is_a?(Name) ? name_short : Name.new(name_short, language)
121
132
  @names = (names || [@name]).sort_by(&:sequence_number)
122
133
  @names_short = (names_short || [@name_short]).sort_by(&:sequence_number)
134
+ @all_names = @names.map(&:to_s) | @names_short.map(&:to_s)
123
135
  @region_names = region_names
124
136
  @region_names_short = region_names_short
125
137
  @canton = canton
126
138
  @sortfile_member = sortfile_member
127
139
  @delivery_by = delivery_by == :self ? self : delivery_by
128
- @community = community
140
+ @largest_community = largest_community
141
+ @communities = communities
129
142
  @valid_from = valid_from
130
143
  @valid_until = valid_until
131
144
  end
132
145
 
146
+ # @return [String]
147
+ # The zip code add-on as 2 digit string, with leading zeros if necessary
148
+ def two_digit_add_on
149
+ "%02d" % @add_on
150
+ end
151
+
133
152
  # @return [Array<String>]
134
153
  # The name of this zip code in all languages and normalizations (only unique values)
135
154
  def transliterated_names
136
- names.flat_map { |name, ary|
137
- name = name.to_s # convert from SwissMatch::Name
138
- [
139
- SwissMatch.transliterate1(name),
140
- SwissMatch.transliterate2(name) # TODO: use transliterate gem
141
- ]
142
- }.uniq
155
+ (
156
+ @all_names.map { |name| SwissMatch.transliterate1(name) } |
157
+ @all_names.map { |name| SwissMatch.transliterate2(name) }
158
+ ).uniq
159
+ end
160
+
161
+ # @return [Hash<String, String>]
162
+ # A map to get the names which match a transliteration
163
+ def reverse_name_transliteration_map
164
+ result = {}
165
+ @all_names.map { |name|
166
+ trans_name1 = SwissMatch.transliterate1(name)
167
+ trans_name2 = SwissMatch.transliterate2(name)
168
+ result[trans_name1] ||= []
169
+ result[trans_name2] ||= []
170
+ result[trans_name1] << name
171
+ result[trans_name2] << name
172
+ }
173
+ result.each_value(&:uniq!)
174
+
175
+ result
143
176
  end
144
177
 
178
+
145
179
  # Since a zip code can - for any given language - have no name, exactly one name,
146
180
  # or even multiple names, it is sometimes difficult to write good code to
147
181
  # automatically provide well localized addresses. This method helps with that, in that
@@ -250,14 +284,16 @@ module SwissMatch
250
284
 
251
285
  # @param [Boolean] retain_references
252
286
  # If set to false, :delivery_by will be set to the ordering number,
253
- # :community to the community_number and :canton to the canton's license_tag.
287
+ # :largest_community to the community_number, :communities to their respective
288
+ # community numbers and :canton to the canton's license_tag.
254
289
  #
255
290
  # @return [Hash]
256
291
  # All properties of the zip code as a hash.
257
292
  def to_hash(retain_references=false)
258
- delivery_by = retain_references ? @delivery_by : (@delivery_by && @delivery_by.ordering_number)
259
- community = retain_references ? @community : (@community && @community.community_number)
260
- canton = retain_references ? @canton : (@canton && @canton.license_tag)
293
+ delivery_by = retain_references ? @delivery_by : (@delivery_by && @delivery_by.ordering_number)
294
+ largest_community = retain_references ? @largest_community : (@largest_community && @largest_community.community_number)
295
+ communities = retain_references ? @communities : @communities.map(&:community_number)
296
+ canton = retain_references ? @canton : (@canton && @canton.license_tag)
261
297
  {
262
298
  :ordering_number => @ordering_number,
263
299
  :type => @type,
@@ -270,7 +306,8 @@ module SwissMatch
270
306
  :language_alternative => @language_alternative,
271
307
  :sortfile_member => @sortfile_member,
272
308
  :delivery_by => delivery_by,
273
- :community => community,
309
+ :largest_community => largest_community,
310
+ :communities => communities,
274
311
  :valid_from => @valid_from,
275
312
  :valid_until => @valid_until,
276
313
  }
@@ -285,7 +322,7 @@ module SwissMatch
285
322
  # @private
286
323
  # @see Object#eql?
287
324
  def eql?(other)
288
- self.class == other.class && @ordering_number == other.ordering_number
325
+ self.class.eql?(other.class) && @ordering_number.eql?(other.ordering_number)
289
326
  end
290
327
 
291
328
  # @return [String]
@@ -3,6 +3,7 @@
3
3
 
4
4
 
5
5
  require 'autocompletion'
6
+ require 'unicode'
6
7
 
7
8
 
8
9
 
@@ -175,6 +176,34 @@ module SwissMatch
175
176
  ZipCodes.new(@autocomplete.complete(*words))
176
177
  end
177
178
 
179
+ # @return [Array<String>]
180
+ # An array of ZipCode names which match the given string in an autocompletion.
181
+ # Sorted alphabetically (Umlaut-aware)
182
+ def autocompleted_names(name)
183
+ name_dc = Unicode.downcase(name)
184
+ len = name_dc.length
185
+ base = autocomplete(name)
186
+ names = base.flat_map { |zip_code|
187
+ zip_code.reverse_name_transliteration_map.select { |transliterated_name, real_names|
188
+ Unicode.downcase(transliterated_name[0, len]) == name_dc
189
+ }.values.flatten(1)
190
+ }
191
+
192
+ names.uniq.sort(&Unicode.method(:strcmp))
193
+ end
194
+
195
+ # @return [Array<String>]
196
+ # An array of ZipCode names suitable for presentation of a select.
197
+ def names_for_select(language=nil)
198
+ if language
199
+ names = flat_map { |zip_code| [zip_code.name, zip_code.suggested_name(I18n.language)] }
200
+ else
201
+ names = map(&:name)
202
+ end
203
+
204
+ names.uniq.sort(&Unicode.method(:strcmp))
205
+ end
206
+
178
207
  # @return [SwissMatch::ZipCodes]
179
208
  # A SwissMatch::ZipCodes collection with zip codes of type 10 and 20.
180
209
  def residential
@@ -203,31 +232,26 @@ module SwissMatch
203
232
  # @return [SwissMatch::ZipCodes]
204
233
  # A SwissMatch::ZipCodes collection with all SwissMatch::ZipCode objects having the given 4 digit code.
205
234
  def by_code(code)
206
- @by_code ||= @zip_codes.group_by { |c| c.code }
207
- ZipCodes.new(@by_code[code] || [])
235
+ ZipCodes.new(by_code_lookup_table[code] || [])
208
236
  end
209
237
 
210
238
  # @return [SwissMatch::ZipCode]
211
239
  # The SwissMatch::ZipCode with the given 4 digit code and given 2 digit code add-on.
212
240
  def by_code_and_add_on(code, add_on)
213
- @by_full_code ||= Hash[@zip_codes.map { |c| [c.full_code, c] }]
214
- @by_full_code[code*100+add_on]
241
+ by_full_code_lookup_table[code*100+add_on]
215
242
  end
216
243
 
217
244
  # @return [SwissMatch::ZipCode]
218
245
  # The SwissMatch::ZipCode with the given 4 digit code and name in any language.
219
246
  def by_code_and_name(code, name)
220
- @by_code_and_name ||= Hash[@zip_codes.flat_map { |c|
221
- c.names.map { |name| [[c.code, name], c] }
222
- }]
223
- @by_code_and_name[[code,name]]
247
+ by_code_and_name_lookup_table[[code, name]]
224
248
  end
225
249
 
226
250
  # @return [SwissMatch::ZipCodes]
227
251
  # A SwissMatch::ZipCodes collection with all SwissMatch::ZipCode objects having the given name.
228
252
  def by_name(name)
229
253
  @by_name ||= @zip_codes.each_with_object({}) { |zip_code, hash|
230
- zip_code.names.map(&:to_s).uniq.each do |name|
254
+ (zip_code.names + zip_code.names_short).map(&:to_s).uniq.each do |name|
231
255
  hash[name] ||= []
232
256
  hash[name] << zip_code
233
257
  end
@@ -246,10 +270,31 @@ module SwissMatch
246
270
  @zip_codes.dup
247
271
  end
248
272
 
273
+ # @return [true, false] Whether this zip code collection contains any zip codes.
274
+ def empty?
275
+ @zip_codes.size.zero?
276
+ end
277
+ alias blank? empty?
278
+
249
279
  # @private
250
280
  # @see Object#inspect
251
281
  def inspect
252
282
  sprintf "\#<%s:%x size: %d>", self.class, object_id>>1, size
253
283
  end
284
+
285
+ private
286
+ def by_code_lookup_table
287
+ @by_code ||= @zip_codes.group_by { |c| c.code }
288
+ end
289
+
290
+ def by_full_code_lookup_table
291
+ @by_full_code ||= Hash[@zip_codes.map { |c| [c.full_code, c] }]
292
+ end
293
+
294
+ def by_code_and_name_lookup_table
295
+ @by_code_and_name ||= Hash[@zip_codes.flat_map { |c|
296
+ (c.names + c.names_short).map(&:to_s).uniq.map { |name| [[c.code, name], c] }
297
+ }]
298
+ end
254
299
  end
255
300
  end
@@ -2,19 +2,18 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "swissmatch-location"
5
- s.version = "0.0.1.201208"
5
+ s.version = "0.1.1.201304"
6
6
  s.authors = "Stefan Rusterholz"
7
7
  s.email = "stefan.rusterholz@gmail.com"
8
8
  s.homepage = "http://github.com/apeiros/swissmatch-location"
9
9
 
10
10
  s.description = <<-DESCRIPTION.gsub(/^ /, '').chomp
11
- Deal with swiss cantons, communities and zip codes, as provided by the swiss postal
12
- service.
11
+ Deal with swiss zip codes, communities, districts and cantons, using the official swiss post mat[ch] database.
13
12
  Additionally handle data updates provided by the swiss postal service.
14
13
  DESCRIPTION
15
14
 
16
15
  s.summary = <<-SUMMARY.gsub(/^ /, '').chomp
17
- Deal with swiss zip codes, cantons and communities.
16
+ Deal with swiss zip codes, communities, districts and cantons, using the official swiss post mat[ch] database.
18
17
  SUMMARY
19
18
 
20
19
  s.files =
@@ -36,7 +35,8 @@ Gem::Specification.new do |s|
36
35
  end
37
36
 
38
37
  s.add_dependency "rubyzip"
39
- s.add_dependency "autocompletion", ">= 0.0.2"
38
+ s.add_dependency "unicode"
39
+ s.add_dependency "autocompletion", ">= 0.0.3"
40
40
 
41
41
  s.required_rubygems_version = Gem::Requirement.new("> 1.3.1")
42
42
  s.rubygems_version = "1.3.1"
metadata CHANGED
@@ -1,18 +1,24 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: swissmatch-location
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.201208
5
4
  prerelease:
5
+ version: 0.1.1.201304
6
6
  platform: ruby
7
7
  authors:
8
8
  - Stefan Rusterholz
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-11 00:00:00.000000000 Z
12
+ date: 2013-04-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rubyzip
16
+ version_requirements: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
16
22
  requirement: !ruby/object:Gem::Requirement
17
23
  none: false
18
24
  requirements:
@@ -21,32 +27,40 @@ dependencies:
21
27
  version: '0'
22
28
  type: :runtime
23
29
  prerelease: false
30
+ - !ruby/object:Gem::Dependency
31
+ name: unicode
24
32
  version_requirements: !ruby/object:Gem::Requirement
25
33
  none: false
26
34
  requirements:
27
35
  - - ! '>='
28
36
  - !ruby/object:Gem::Version
29
37
  version: '0'
30
- - !ruby/object:Gem::Dependency
31
- name: autocompletion
32
38
  requirement: !ruby/object:Gem::Requirement
33
39
  none: false
34
40
  requirements:
35
41
  - - ! '>='
36
42
  - !ruby/object:Gem::Version
37
- version: 0.0.2
43
+ version: '0'
38
44
  type: :runtime
39
45
  prerelease: false
46
+ - !ruby/object:Gem::Dependency
47
+ name: autocompletion
40
48
  version_requirements: !ruby/object:Gem::Requirement
41
49
  none: false
42
50
  requirements:
43
51
  - - ! '>='
44
52
  - !ruby/object:Gem::Version
45
- version: 0.0.2
46
- description: ! 'Deal with swiss cantons, communities and zip codes, as provided by
47
- the swiss postal
48
-
49
- service.
53
+ version: 0.0.3
54
+ requirement: !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ! '>='
58
+ - !ruby/object:Gem::Version
59
+ version: 0.0.3
60
+ type: :runtime
61
+ prerelease: false
62
+ description: ! 'Deal with swiss zip codes, communities, districts and cantons, using
63
+ the official swiss post mat[ch] database.
50
64
 
51
65
  Additionally handle data updates provided by the swiss postal service.'
52
66
  email: stefan.rusterholz@gmail.com
@@ -54,13 +68,17 @@ executables: []
54
68
  extensions: []
55
69
  extra_rdoc_files: []
56
70
  files:
57
- - data/swissmatch/plz_c_20120821.txt
58
- - data/swissmatch/plz_p1_20120821.txt
59
- - data/swissmatch/plz_p2_20120821.txt
71
+ - data/swissmatch-location/communities_20120401.csv
72
+ - data/swissmatch-location/districts_20120401.csv
73
+ - data/swissmatch-location/plz_c_20130318.txt
74
+ - data/swissmatch-location/plz_p1_20130318.txt
75
+ - data/swissmatch-location/plz_p2_20130318.txt
60
76
  - lib/swissmatch/canton.rb
61
77
  - lib/swissmatch/cantons.rb
62
78
  - lib/swissmatch/communities.rb
63
79
  - lib/swissmatch/community.rb
80
+ - lib/swissmatch/district.rb
81
+ - lib/swissmatch/districts.rb
64
82
  - lib/swissmatch/loaderror.rb
65
83
  - lib/swissmatch/location/autoload.rb
66
84
  - lib/swissmatch/location/datafiles.rb
@@ -103,9 +121,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
121
  version: 1.3.1
104
122
  requirements: []
105
123
  rubyforge_project:
106
- rubygems_version: 1.8.24
124
+ rubygems_version: 1.8.25
107
125
  signing_key:
108
126
  specification_version: 3
109
- summary: Deal with swiss zip codes, cantons and communities.
127
+ summary: Deal with swiss zip codes, communities, districts and cantons, using the
128
+ official swiss post mat[ch] database.
110
129
  test_files: []
111
130
  has_rdoc: