jipcode-address_locator 0.0.2 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff7d724f508557838d4bed4046b14e273c16b799c8f9a057d2f45dfff947d0c2
4
- data.tar.gz: 37a2b5adc599fc0dc8eed2795e723eab8a43ded8e0f225503835fe8bc3fe64f3
3
+ metadata.gz: ac96c49da433461acb724242cf9afda8895d00913c48c400ad75f4c2025d73e1
4
+ data.tar.gz: d43fcc25ec3303c54b392e6b73c739ca9da8543555f743d056008a01277d2ce6
5
5
  SHA512:
6
- metadata.gz: 6d9570d78d16667257237650fe5ccb6fe1625b8f2b41caea7f7398d6bcbe6921b6c008e29fa576bce2ab5c9b532b31bb30358673170a606bbdd79fc3683b9594
7
- data.tar.gz: db79b508751d18b87b1d29b820dbaf67d2cb32a730efb7c674c934b93cd856cf04cc27a6014e61637fbbbe85bd5a545692528e75a88cd9f3ce7d14137b37fc68
6
+ metadata.gz: 00a0d6342e9294be6902f52d32afdc9b4a347f8385a0cdeaed5c64027e020dc7575f83e210bc96d23811fa992576e3298c0340e81ae78f25a023aadb6a99d46e
7
+ data.tar.gz: 4132cdc0057bf44e954f64163c84742b648b91b80d648309c56afcf4becdb0c70e9a5256511ba88a253ab094826cad9e711704bbfd0d9db6191a7d5cdc6bbeef
data/.gitignore CHANGED
@@ -12,4 +12,6 @@
12
12
  .rspec_status
13
13
  .byebug_history
14
14
 
15
+ Gemfile.lock
16
+
15
17
  /zipcode/by_prefecture/
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  # Jipcode::AddressLocator
5
5
 
6
- [Jipcode](http://rubygems.org/gems/jipcode)に住所から郵便番号データを検索するメソッド(`locate_by_address`)を追加します。
6
+ [jipcode](http://rubygems.org/gems/jipcode)に住所から郵便番号データを検索するメソッド(`locate_by_address`)を追加します。
7
7
 
8
8
  ## Installation
9
9
 
@@ -28,9 +28,7 @@ $ gem install jipcode-address_locator
28
28
 
29
29
  ### 住所から郵便番号情報を検索する
30
30
 
31
- [Jaro-Winkler](https://rubygems.org/gems/jaro_winkler)距離計算の結果から近い順に郵便番号情報を返します。
32
-
33
- [Jipcode](http://rubygems.org/gems/jipcode)の最新郵便番号のインデックスをまだ持っていない場合インデックスファイルを作成します。なので初回の処理は重いです
31
+ [jaro-winkler](https://rubygems.org/gems/jaro_winkler)距離計算の結果から近い順に郵便番号情報を返す。
34
32
 
35
33
  ```ruby
36
34
  require 'jipcode'
@@ -38,11 +36,36 @@ require 'jipcode/address_locator'
38
36
 
39
37
  Jipcode.locate_by_address '東京都千代田区千代田1-1', prefecture_code: true, distance: true
40
38
  # [
39
+ # {:zipcode=>"1008111", :prefecture=>"東京都", :city=>"千代田区", :town=>"千代田1−1", :prefecture_code=>13, :distance=>1.0},
41
40
  # {:zipcode=>"1000001", :prefecture=>"東京都", :city=>"千代田区", :town=>"千代田", :prefecture_code=>13, :distance=>0.9538461538461538},
42
41
  # {:zipcode=>"1000000", :prefecture=>"東京都", :city=>"千代田区", :town=>nil, :prefecture_code=>13, :distance=>0.9076923076923077}
43
42
  # ]
44
43
  ```
45
44
 
45
+ #### 備考
46
+
47
+ [jipcode](http://rubygems.org/gems/jipcode)の該当するバージョンのインデックスをまだ持っていない場合インデックスファイルを作成する。
48
+
49
+ 受け取った住所は以下の正規化を行う。(`Jipcode::AddressLocator.normalize_address()`)
50
+
51
+ - 全角の数字とハイフンを半角にする
52
+ - 「漢数字 + `丁目`」 を「半角数字 + ハイフン」 にする
53
+ - `丁目`、`番地`、`号`などをハイフンにする
54
+
55
+
56
+ ```ruby
57
+ Jipcode::AddressLocator.normalize_address('稲穂県ミドリ市一番町一丁目2の3番')
58
+ # => '稲穂県ミドリ市一番町1-2-3'
59
+ ```
60
+
61
+ ### インデックスを更新する
62
+
63
+ 明示的にインデックスを作り直す場合は以下を実行する。
64
+
65
+ ```ruby
66
+ Jipcode::AddressLocator.create_index!
67
+ ```
68
+
46
69
  ## License
47
70
 
48
71
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -22,9 +22,9 @@ Gem::Specification.new do |spec|
22
22
 
23
23
  spec.add_dependency 'jaro_winkler', '~> 1.5.3'
24
24
  spec.add_dependency 'jipcode', '~> 1.5.0'
25
- spec.add_development_dependency 'bundler', '~> 1.16'
25
+ spec.add_development_dependency 'bundler'
26
26
  spec.add_development_dependency 'byebug'
27
- spec.add_development_dependency 'rake', '~> 10.0'
28
- spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'rake'
28
+ spec.add_development_dependency 'rspec'
29
29
  spec.add_development_dependency 'rubocop'
30
30
  end
@@ -14,7 +14,7 @@ module Jipcode
14
14
 
15
15
  AddressLocator.locate(search_address).map do |address_param|
16
16
  address = extended_address_from(address_param, opt)
17
- address[:distance] = address_param[4] if opt[:distance]
17
+ address[:distance] = address_param['distance'] if opt[:distance]
18
18
  address
19
19
  end
20
20
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'csv'
4
4
  require 'jipcode/address_locator/helper'
5
+ require 'jipcode/address_locator/normalizer'
5
6
 
6
7
  module Jipcode
7
8
  module AddressLocator
@@ -25,8 +26,6 @@ module Jipcode
25
26
  File.open(INDEX_VERSION_FILE, 'w') do |f|
26
27
  f.write(Jipcode::VERSION)
27
28
  end
28
- rescue StandardError => e
29
- raise e, 'Failed to create index'
30
29
  end
31
30
 
32
31
  # @private
@@ -37,25 +36,26 @@ module Jipcode
37
36
 
38
37
  # @private
39
38
  def self.collect_index
40
- # 都道府県コードは1から始まるので一つ余計に作る
41
- index = Array.new(PREFECTURE_CODE.size + 1) { [] }
39
+ index = 47.times.each_with_object({}) { |item, memo| memo[item + 1] = []; }
42
40
 
43
41
  Dir.glob("#{ZIPCODE_PATH}/*.csv").each do |file_name|
44
42
  CSV.read(file_name).each do |row|
45
- _zipcode, prefecture_name, _city, _town = row
43
+ _zipcode, prefecture_name, city, town = row
44
+ row << normalize_address("#{prefecture_name}#{city}#{town}")
46
45
  prefecture_code = extract_prefecture_code(prefecture_name)
47
46
  index[prefecture_code] << row
48
47
  end
49
48
  end
50
- index.shift
49
+
51
50
  index
52
51
  end
53
52
 
54
53
  # @private
55
54
  def self.export_index(index)
56
- index.each.with_index(1) do |rows, prefecture_code|
55
+ index.each do |prefecture_code, rows|
57
56
  rows.sort_by! { |row| [row[0], row[2], row[3]] }
58
57
  CSV.open("#{INDEX_PATH}/#{prefecture_code}.csv", 'wb') do |csv|
58
+ csv << %w[zipcode prefecture_name city town normalized_address]
59
59
  rows.each { |row| csv << row }
60
60
  end
61
61
  end
@@ -3,6 +3,7 @@
3
3
  require 'csv'
4
4
  require 'jaro_winkler'
5
5
  require 'jipcode/address_locator/helper'
6
+ require 'jipcode/address_locator/normalizer'
6
7
 
7
8
  module Jipcode
8
9
  module AddressLocator
@@ -10,9 +11,11 @@ module Jipcode
10
11
  # @param [String] search_address
11
12
  # @return [Array<Hash>] zipcode data
12
13
  def self.locate(search_address)
13
- find_by_address(search_address)
14
- .yield_self { |addresses| calc_and_add_distance(addresses, search_address) }
15
- .sort_by(&:last)
14
+ normalized = normalize_address(search_address)
15
+
16
+ find_by_address(normalized)
17
+ .map { |address| calc_and_add_distance!(address, normalized) }
18
+ .sort_by { |address| address['distance'] }
16
19
  .reverse
17
20
  end
18
21
 
@@ -22,8 +25,8 @@ module Jipcode
22
25
  path = "#{INDEX_PATH}/#{prefecture_code}.csv"
23
26
  return [] if prefecture_code.nil?
24
27
 
25
- CSV.read(path).select do |row|
26
- address = row[1..3].join('')
28
+ CSV.read(path, headers: true).select do |row|
29
+ address = row['normalized_address']
27
30
  # 長いほうが短い方に含まれてるか判別
28
31
  long = [address, search_address].max
29
32
  short = [address, search_address].min
@@ -32,14 +35,12 @@ module Jipcode
32
35
  end
33
36
 
34
37
  # @private
35
- def self.calc_and_add_distance(addresses, search_address)
36
- addresses.map do |row|
37
- combined = row[1..3].join('')
38
- distance = JaroWinkler.distance(combined, search_address)
39
- row << distance
40
- end
38
+ def self.calc_and_add_distance!(address, search_address)
39
+ distance = JaroWinkler.distance(address['normalized_address'], search_address)
40
+ address['distance'] = distance
41
+ address
41
42
  end
42
43
 
43
- private_class_method :calc_and_add_distance, :find_by_address
44
+ private_class_method :calc_and_add_distance!, :find_by_address
44
45
  end
45
46
  end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jipcode
4
+ module AddressLocator
5
+ # Normalize japanese address for search.
6
+ # @example
7
+ # Jipcode::AddressLocator.normalize_address('稲穂県ミドリ市一番町一丁目2の3番')
8
+ # # => '稲穂県ミドリ市一番町1-2-3'
9
+ # @param [String] raw_address
10
+ # @return [String] normalized address
11
+ def self.normalize_address(raw_address)
12
+ zenkaku2hankaku(raw_address)
13
+ .yield_self { |address| kansuji2hankaku(address) }
14
+ .yield_self { |address| jukyohyouji2hyphen(address) }
15
+ end
16
+
17
+ # 全角数字ハイフン→半角数字ハイフン
18
+ # @private
19
+ def self.zenkaku2hankaku(string)
20
+ string.tr('0-9', '0-9')
21
+ .tr('–−', '-')
22
+ end
23
+
24
+ # 住居表示の漢数字を半角数字に置き換える
25
+ # @private
26
+ def self.kansuji2hankaku(string)
27
+ # 漢数字は「丁目」の前に使われてるもののみを半角にする
28
+ string.gsub(/[一二三四五六七八九十]+丁目/) do |match|
29
+ match.tr('一二三四五六七八九', '1-9')
30
+ # TODO: 十丁目 -> 10、十三丁目 -> 13 二十丁目 -> 20
31
+ end
32
+ end
33
+
34
+ # 丁目・番・号・地割・番地をハイフンに置換する
35
+ # 1丁目2番3号 -> 1-2-3
36
+ # 1丁目2番3 -> 1-2-3
37
+ # 1丁目2-3 -> 1-2-3
38
+ # 1丁目2番 -> 1-2
39
+ # 1地割2番地 -> 1-2
40
+ # 1丁目2番地の3 -> 1-2-3
41
+ # etc..
42
+ # @private
43
+ # @see https://ja.wikipedia.org/wiki/%E4%BD%8F%E5%B1%85%E8%A1%A8%E7%A4%BA
44
+ GAIKU_HYOUJI = %w[
45
+ 丁目
46
+ 番地
47
+
48
+
49
+ 地割
50
+
51
+ ].freeze
52
+ def self.jukyohyouji2hyphen(string)
53
+ string.gsub(/\d(#{GAIKU_HYOUJI.join('|')})/) { |match| match.gsub(/(#{GAIKU_HYOUJI.join('|')})/, '-') }
54
+ .gsub(/-$/, '')
55
+ end
56
+
57
+ private_class_method :jukyohyouji2hyphen, :kansuji2hankaku, :zenkaku2hankaku
58
+ end
59
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Jipcode
4
4
  module AddressLocator
5
- VERSION = '0.0.2'
5
+ VERSION = '0.1.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jipcode-address_locator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - oieioi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-18 00:00:00.000000000 Z
11
+ date: 2019-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jaro_winkler
@@ -42,16 +42,16 @@ dependencies:
42
42
  name: bundler
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '1.16'
47
+ version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '1.16'
54
+ version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: byebug
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -70,30 +70,30 @@ dependencies:
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '10.0'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - "~>"
87
+ - - ">="
88
88
  - !ruby/object:Gem::Version
89
- version: '3.0'
89
+ version: '0'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - "~>"
94
+ - - ">="
95
95
  - !ruby/object:Gem::Version
96
- version: '3.0'
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: rubocop
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -120,7 +120,6 @@ files:
120
120
  - ".rubocop.yml"
121
121
  - ".travis.yml"
122
122
  - Gemfile
123
- - Gemfile.lock
124
123
  - LICENSE
125
124
  - README.md
126
125
  - Rakefile
@@ -132,6 +131,7 @@ files:
132
131
  - lib/jipcode/address_locator/helper.rb
133
132
  - lib/jipcode/address_locator/indexer.rb
134
133
  - lib/jipcode/address_locator/locator.rb
134
+ - lib/jipcode/address_locator/normalizer.rb
135
135
  - lib/jipcode/address_locator/version.rb
136
136
  - zipcode/by_prefecture/latest/.gitkeep
137
137
  homepage: https://github.com/oieioi/jipcode-address_locator
data/Gemfile.lock DELETED
@@ -1,56 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- jipcode-address_locator (0.0.2)
5
- jaro_winkler (~> 1.5.3)
6
- jipcode (~> 1.5.0)
7
-
8
- GEM
9
- remote: https://rubygems.org/
10
- specs:
11
- ast (2.4.0)
12
- byebug (11.0.1)
13
- diff-lcs (1.3)
14
- jaro_winkler (1.5.3)
15
- jipcode (1.5.0)
16
- parallel (1.17.0)
17
- parser (2.6.3.0)
18
- ast (~> 2.4.0)
19
- rainbow (3.0.0)
20
- rake (10.5.0)
21
- rspec (3.8.0)
22
- rspec-core (~> 3.8.0)
23
- rspec-expectations (~> 3.8.0)
24
- rspec-mocks (~> 3.8.0)
25
- rspec-core (3.8.2)
26
- rspec-support (~> 3.8.0)
27
- rspec-expectations (3.8.4)
28
- diff-lcs (>= 1.2.0, < 2.0)
29
- rspec-support (~> 3.8.0)
30
- rspec-mocks (3.8.1)
31
- diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.8.0)
33
- rspec-support (3.8.2)
34
- rubocop (0.73.0)
35
- jaro_winkler (~> 1.5.1)
36
- parallel (~> 1.10)
37
- parser (>= 2.6)
38
- rainbow (>= 2.2.2, < 4.0)
39
- ruby-progressbar (~> 1.7)
40
- unicode-display_width (>= 1.4.0, < 1.7)
41
- ruby-progressbar (1.10.1)
42
- unicode-display_width (1.6.0)
43
-
44
- PLATFORMS
45
- ruby
46
-
47
- DEPENDENCIES
48
- bundler (~> 1.16)
49
- byebug
50
- jipcode-address_locator!
51
- rake (~> 10.0)
52
- rspec (~> 3.0)
53
- rubocop
54
-
55
- BUNDLED WITH
56
- 1.17.2