fias 0.0.2 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -22
  3. data/.rubocop.yml +7 -0
  4. data/.travis.yml +10 -0
  5. data/Gemfile +1 -1
  6. data/LICENSE.txt +2 -2
  7. data/README.md +259 -155
  8. data/Rakefile +6 -1
  9. data/config/names.txt +0 -0
  10. data/config/synonyms.yml +50 -0
  11. data/examples/create.rb +106 -0
  12. data/examples/generate_index.rb +63 -0
  13. data/fias.gemspec +33 -21
  14. data/lib/fias.rb +197 -10
  15. data/lib/fias/config.rb +74 -0
  16. data/lib/fias/import/copy.rb +62 -0
  17. data/lib/fias/import/dbf.rb +81 -0
  18. data/lib/fias/import/download_service.rb +37 -0
  19. data/lib/fias/import/restore_parent_id.rb +51 -0
  20. data/lib/fias/import/tables.rb +74 -0
  21. data/lib/fias/name/append.rb +30 -0
  22. data/lib/fias/name/canonical.rb +42 -0
  23. data/lib/fias/name/extract.rb +85 -0
  24. data/lib/fias/name/house_number.rb +71 -0
  25. data/lib/fias/name/split.rb +60 -0
  26. data/lib/fias/name/synonyms.rb +93 -0
  27. data/lib/fias/query.rb +43 -0
  28. data/lib/fias/query/estimate.rb +67 -0
  29. data/lib/fias/query/finder.rb +75 -0
  30. data/lib/fias/query/params.rb +101 -0
  31. data/lib/fias/railtie.rb +3 -17
  32. data/lib/fias/version.rb +1 -1
  33. data/spec/fixtures/ACTSTAT.DBF +0 -0
  34. data/spec/fixtures/NORDOC99.DBF +0 -0
  35. data/spec/fixtures/STRSTAT.DBF +0 -0
  36. data/spec/fixtures/addressing.yml +93 -0
  37. data/spec/fixtures/query.yml +79 -0
  38. data/spec/fixtures/query_sanitization.yml +75 -0
  39. data/spec/fixtures/status_append.yml +60 -0
  40. data/spec/lib/import/copy_spec.rb +44 -0
  41. data/spec/lib/import/dbf_spec.rb +28 -0
  42. data/spec/lib/import/download_service_spec.rb +15 -0
  43. data/spec/lib/import/restore_parent_id_spec.rb +34 -0
  44. data/spec/lib/import/tables_spec.rb +26 -0
  45. data/spec/lib/name/append_spec.rb +14 -0
  46. data/spec/lib/name/canonical_spec.rb +20 -0
  47. data/spec/lib/name/extract_spec.rb +67 -0
  48. data/spec/lib/name/house_number_spec.rb +45 -0
  49. data/spec/lib/name/query_spec.rb +21 -0
  50. data/spec/lib/name/split_spec.rb +15 -0
  51. data/spec/lib/name/synonyms_spec.rb +51 -0
  52. data/spec/lib/query/params_spec.rb +15 -0
  53. data/spec/lib/query_spec.rb +27 -0
  54. data/spec/spec_helper.rb +30 -0
  55. data/spec/support/db.rb +30 -0
  56. data/spec/support/query.rb +13 -0
  57. data/tasks/db.rake +52 -0
  58. data/tasks/download.rake +15 -0
  59. metadata +246 -64
  60. data/lib/fias/active_record/address_object.rb +0 -231
  61. data/lib/fias/active_record/address_object_type.rb +0 -15
  62. data/lib/fias/dbf_wrapper.rb +0 -90
  63. data/lib/fias/importer.rb +0 -30
  64. data/lib/fias/importer/base.rb +0 -59
  65. data/lib/fias/importer/pg.rb +0 -81
  66. data/lib/fias/importer/sqlite.rb +0 -38
  67. data/lib/generators/fias/migration.rb +0 -34
  68. data/lib/generators/fias/templates/create_fias_tables.rb +0 -5
  69. data/tasks/fias.rake +0 -68
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  require 'bundler/gem_tasks'
2
- load 'tasks/fias.rake'
2
+ require 'rspec/core/rake_task'
3
+ load 'tasks/download.rake'
4
+ load 'tasks/db.rake'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+ task default: :spec
Binary file
@@ -0,0 +1,50 @@
1
+ ---
2
+ - ['б.', 'большая', 'большой', 'большие', 'большое', 'бол.']
3
+ - ['м.', 'малая', 'малый', 'малые', 'малое', 'мал.', 'маршала']
4
+ - ['нижн.', 'нижняя', 'нижний', 'нижние', 'нижнее', 'ниж.']
5
+ - ['верхн.', 'верхняя', 'верхний', 'верхние', 'верхнее', 'верх.']
6
+ - ['ср.', 'средний', 'средняя', 'средние', 'среднее']
7
+ - ['стар.', 'старый', 'старая', 'старые', 'старое']
8
+ - ['новая', 'нов.', 'н.', 'новый', 'новое']
9
+ - ['северное', 'северная', 'северный']
10
+ - ['южное', 'южная', 'южный']
11
+ - ['восточное', 'восточная', 'восточный']
12
+ - ['западное', 'западная', 'западный']
13
+ - ['соцтруда', 'соц.труда', '']
14
+ - ['им', 'имени', 'им.', '']
15
+ - ['ак.', 'академика', '']
16
+ - ['героя советского союза', '']
17
+ - ['героя ссср', '']
18
+ - ['героя', '']
19
+ - ['писателя', '']
20
+ - ['генерала', '']
21
+ - ['адмирала', '']
22
+ - ['генерал-лейтенанта', '']
23
+ - ['поэта-декабриста', '']
24
+ - ['композитора', '']
25
+ - ['братьев', 'бр.', '']
26
+ - ['архитектора', '']
27
+ - ['генерала армии', '']
28
+ - ['космонавта', '']
29
+ - ['милиционера', '']
30
+ - ['авиаконструктора', '']
31
+ - ['маршала', '']
32
+ - ['авиаконструктора', '']
33
+ - ['матроса', '']
34
+ - ['профессора', '']
35
+ - ['тиз', '']
36
+ - ['реки', '']
37
+ - ['солдата', '']
38
+ - ['цюрупа', 'цурюпа', 'цурюпы', 'цюрупы']
39
+ - ['в.о.', 'васильевского', 'васильевского острова', 'во', '']
40
+ - ['п.с.', 'петроградки', 'петроградской стороны', 'пс', '']
41
+ - ['пограничника', '']
42
+ - ['линия', '']
43
+ - ['вал', '']
44
+ - ['канала', 'кан.', '']
45
+ - ['комиссара', '']
46
+ - ['лат.', 'латышских']
47
+ - ['танкиста', '']
48
+ - ['подводника', 'подв.', '']
49
+ - ['совхоз', 'свх']
50
+ - ['политрука', '']
@@ -0,0 +1,106 @@
1
+ # Can be run in cloned repo
2
+ # DATABASE_URL=postgres://localhost/fias bundle exec ruby create.rb
3
+
4
+ require 'pg_data_encoder'
5
+ require 'ruby-progressbar'
6
+ require 'sequel'
7
+ require 'active_support/core_ext/object/blank'
8
+ require 'fias'
9
+
10
+ def create_bar(count)
11
+ ProgressBar.create(total: count, format: '%a |%B| [%E] (%c/%C) %p%%')
12
+ end
13
+
14
+ DB = Sequel.connect(ENV['DATABASE_URL'])
15
+
16
+ PREFIX = ENV['PREFIX'] || 'fias'
17
+
18
+ FIAS_ADDRESS_OBJECTS_TABLE_NAME =
19
+ [PREFIX, 'address_objects'].delete_if(&:blank?).join('_').to_sym
20
+
21
+ FIAS_ADDRESS_OBJECTS = DB[FIAS_ADDRESS_OBJECTS_TABLE_NAME]
22
+
23
+ ADDRESS_OBJECTS_TABLE_NAME = :address_objects
24
+
25
+ ADDRESS_OBJECTS = DB[ADDRESS_OBJECTS_TABLE_NAME]
26
+
27
+ def create_table
28
+ puts 'Creating target table...'
29
+
30
+ DB.create_table(ADDRESS_OBJECTS_TABLE_NAME) do
31
+ primary_key :id
32
+
33
+ column :aoid, :uuid
34
+ column :aoguid, :uuid
35
+ column :parentguid, :uuid
36
+ column :parent_id, :integer
37
+ column :name, :text
38
+ column :abbr, :text
39
+ column :code, :text
40
+ column :center, :boolean
41
+ end
42
+ end
43
+
44
+ def copy_fias_data
45
+ puts 'Copying data from FIAS...'
46
+
47
+ encoder = PgDataEncoder::EncodeForCopy.new(
48
+ column_types: { 0 => :uuid, 1 => :uuid, 2 => :uuid }
49
+ )
50
+
51
+ # Nonhistorical records
52
+ scope = FIAS_ADDRESS_OBJECTS.where(livestatus: 1)
53
+
54
+ bar = create_bar(scope.count)
55
+
56
+ scope.each do |row|
57
+ bar.increment
58
+
59
+ encoder.add([
60
+ row[:aoid],
61
+ row[:aoguid],
62
+ row[:parentguid],
63
+ row[:formalname],
64
+ row[:shortname],
65
+ row[:code],
66
+ row[:centerst].to_i > 0
67
+ ])
68
+ end
69
+
70
+ io = encoder.get_io
71
+
72
+ columns = %i(aoid aoguid parentguid name abbr code center)
73
+
74
+ DB.copy_into(ADDRESS_OBJECTS_TABLE_NAME, columns: columns, format: :binary) do
75
+ begin
76
+ io.readpartial(65_536)
77
+ rescue EOFError => _e
78
+ nil
79
+ end
80
+ end
81
+ end
82
+
83
+ def restore_hierarchy
84
+ puts 'Restoring parent_id values...'
85
+ Fias::Import::RestoreParentId.new(ADDRESS_OBJECTS).restore
86
+ end
87
+
88
+ create_table
89
+ copy_fias_data
90
+ restore_hierarchy
91
+
92
+ # Uncomment this migration if you want to use closure_tree for hierarchies:
93
+ #
94
+ # DB.create_table(:address_object_hierarchies) do
95
+ # column :ancestor_id, Integer
96
+ # column :descendant_id, Integer
97
+ # column :generations, Integer
98
+
99
+ # index [:ancestor_id, :descendant_id, :generations]
100
+ # index [:ancestor_id]
101
+ # index [:descendant_id]
102
+ # end
103
+ #
104
+ # Use http://github.com/gzigzigzeo/pg_closure_tree_rebuild to fill it.
105
+ #
106
+ # Database ready!
@@ -0,0 +1,63 @@
1
+ # Can be run in cloned repo
2
+ # DATABASE_URL=postgres://localhost/fias bundle exec ruby generate_index.rb
3
+
4
+ require 'ruby-progressbar'
5
+ require 'sequel'
6
+ require 'active_support/core_ext/object/blank'
7
+ require 'fias'
8
+
9
+ def create_bar(count)
10
+ ProgressBar.create(total: count, format: '%a |%B| [%E] (%c/%C) %p%%')
11
+ end
12
+
13
+ DB = Sequel.connect(ENV['DATABASE_URL'])
14
+ DB.extension :pg_array
15
+
16
+ ADDRESS_OBJECTS_TABLE_NAME = :address_objects
17
+ ADDRESS_OBJECTS = DB[ADDRESS_OBJECTS_TABLE_NAME]
18
+
19
+ def alter_table
20
+ puts 'Adding tokens field...'
21
+
22
+ DB.alter_table(ADDRESS_OBJECTS_TABLE_NAME) do
23
+ add_column :tokens, 'text[]'
24
+ add_column :ancestry, 'integer[]'
25
+ add_column :forms, 'text[]'
26
+ end
27
+
28
+ DB.run 'CREATE INDEX idx_tokens on "address_objects" USING GIN ("tokens");'
29
+ end
30
+
31
+ def ancestry_for(id)
32
+ ADDRESS_OBJECTS
33
+ .select(:id)
34
+ .join(:address_object_hierarchies, ancestor_id: :id)
35
+ .where(address_object_hierarchies__descendant_id: id)
36
+ .order(:address_object_hierarchies__generations)
37
+ .select_map(:id) - [id]
38
+ end
39
+
40
+ def tokenize
41
+ puts 'Generating tokens for search...'
42
+
43
+ scope = ADDRESS_OBJECTS
44
+
45
+ bar = create_bar(scope.count)
46
+
47
+ scope.select(:id, :name).each do |row|
48
+ bar.increment
49
+
50
+ tokens = Fias::Name::Synonyms.tokens(row[:name])
51
+ forms = Fias::Name::Synonyms.forms(row[:name])
52
+ ancestry = ancestry_for(row[:id])
53
+
54
+ ADDRESS_OBJECTS.where(id: row[:id]).update(
55
+ tokens: Sequel.pg_array(tokens, :text),
56
+ forms: Sequel.pg_array(forms, :text),
57
+ ancestry: Sequel.pg_array(ancestry, :integer)
58
+ )
59
+ end
60
+ end
61
+
62
+ alter_table
63
+ tokenize
@@ -1,27 +1,39 @@
1
- # -*- encoding: utf-8 -*-
1
+ # coding: utf-8
2
2
  lib = File.expand_path('../lib', __FILE__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'fias/version'
5
5
 
6
- Gem::Specification.new do |gem|
7
- gem.name = "fias"
8
- gem.version = Fias::VERSION
9
- gem.authors = ["Victor Sokolov"]
10
- gem.email = ["gzigzigzeo@evilmartians.com"]
11
- gem.description = %q{Ruby wrapper to FIAS database}
12
- gem.summary = %q{Ruby wrapper to FIAS database}
13
- gem.homepage = "http://github.com/evilmartians/fias"
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'fias'
8
+ spec.version = Fias::VERSION
9
+ spec.authors = ['Victor Sokolov']
10
+ spec.email = ['gzigzigzeo@evilmartians.com']
11
+ spec.summary = %q{Imports Russian FIAS database into SQL}
12
+ spec.description = %q{Imports Russian FIAS database into SQL (for Ruby on Rails on PostgreSQL projects)}
13
+ spec.homepage = 'http://github.com/evilmartians/fias'
14
+ spec.license = 'MIT'
14
15
 
15
- gem.files = `git ls-files`.split($/)
16
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
- gem.require_paths = ["lib"]
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
19
20
 
20
- gem.add_dependency 'dbf'
21
- gem.add_dependency 'rake'
22
- gem.add_dependency 'activerecord', '> 3'
23
- gem.add_dependency 'progress_bar'
24
- gem.add_development_dependency 'pg'
25
- gem.add_development_dependency 'sqlite3'
26
- gem.add_development_dependency 'hirb'
27
- end
21
+ spec.add_dependency 'dbf'
22
+ spec.add_dependency 'activesupport', '> 3'
23
+ spec.add_dependency 'sequel'
24
+ spec.add_dependency 'pg_data_encoder'
25
+ spec.add_dependency 'httparty'
26
+ spec.add_dependency 'pg'
27
+ spec.add_dependency 'ruby-progressbar'
28
+ spec.add_dependency 'unicode'
29
+
30
+ spec.add_development_dependency 'bundler', '~> 1.7'
31
+ spec.add_development_dependency 'rake', '~> 10.0'
32
+ spec.add_development_dependency 'rspec'
33
+ spec.add_development_dependency 'simplecov'
34
+ spec.add_development_dependency 'rubocop'
35
+ spec.add_development_dependency 'webmock'
36
+ spec.add_development_dependency 'sqlite3'
37
+ spec.add_development_dependency 'codeclimate-test-reporter'
38
+ spec.add_development_dependency 'ruby-prof'
39
+ end
@@ -1,15 +1,202 @@
1
- require 'dbf'
1
+ module Fias
2
+ class << self
3
+ attr_reader :config
2
4
 
3
- require 'active_record'
5
+ def configure(&block)
6
+ @config = Config.new(&block)
7
+ end
4
8
 
5
- require 'fias/version'
6
- require 'fias/dbf_wrapper'
7
- require 'fias/importer'
8
- require 'fias/importer/base'
9
- require 'fias/importer/pg'
10
- require 'fias/importer/sqlite'
9
+ def indivisible_words
10
+ @indivisible_words ||=
11
+ config
12
+ .synonyms
13
+ .flatten
14
+ .find_all { |w| w.include?(' ') }
15
+ .sort_by(&:size)
16
+ .reverse
17
+ .freeze
18
+ end
19
+
20
+ def word
21
+ @word ||=
22
+ /(#{ANNIVESARIES}|#{indivisible_words.join('|')}|[#{LETTERS}\"\'\d\.\)\(\/\-]+)(\s|\,|$)/ui
23
+ end
24
+ end
11
25
 
26
+ LETTERS = /[а-яА-ЯёЁA-Za-z]/ui
27
+ ANNIVESARIES = /(\d+)(\s\-|\-|\s)лет(ия)?/ui
28
+ INITIAL = /#{Fias::LETTERS}{1,2}\./ui
29
+ INITIALS = /(#{INITIAL}#{INITIAL}(#{INITIAL})?)(.+|$)/ui
30
+ SINGLE_INITIAL = /(\.|\s|^)(#{Fias::LETTERS}{1,3}\.)(.+|$)/ui
31
+ FEDERAL_CITIES = ['Москва', 'Санкт-Петербург', 'Севастополь', 'Байконур']
32
+ end
33
+
34
+ require 'unicode'
35
+ require 'active_support/core_ext/object/blank'
36
+ require 'active_support/core_ext/hash/slice'
37
+ require 'active_support/core_ext/hash/keys'
38
+ require 'active_support/hash_with_indifferent_access'
39
+ require 'active_support/core_ext/enumerable'
40
+ require 'active_support/core_ext/object/try'
41
+ require 'active_support/core_ext/array/extract_options'
42
+ require 'active_support/core_ext/array/wrap'
43
+ require 'dbf'
44
+ require 'httparty'
45
+ require 'pg_data_encoder'
46
+ require 'fias/version'
47
+ require 'fias/config'
48
+ require 'fias/import/dbf'
49
+ require 'fias/import/tables'
50
+ require 'fias/import/download_service'
51
+ require 'fias/import/copy'
52
+ require 'fias/import/restore_parent_id'
53
+ require 'fias/name/canonical'
54
+ require 'fias/name/append'
55
+ require 'fias/name/extract'
56
+ require 'fias/name/house_number'
57
+ require 'fias/name/split'
58
+ require 'fias/name/synonyms'
59
+ require 'fias/query'
60
+ require 'fias/query/params'
61
+ require 'fias/query/finder'
62
+ require 'fias/query/estimate'
12
63
  require 'fias/railtie' if defined?(Rails)
13
64
 
14
- module Fias
15
- end
65
+ Fias.configure do |config|
66
+ config.add_name('автономный округ', 'АО')
67
+ config.add_name('автономная область', 'Аобл')
68
+ config.add_name('город', 'г.')
69
+ config.add_name('край', 'край')
70
+ config.add_name('область', 'обл.')
71
+ config.add_name('округ', 'округ')
72
+ config.add_name('республика', 'Респ.')
73
+ config.add_name('поселение', 'п.')
74
+ config.add_name('район', 'р-н')
75
+ config.add_name('территория', 'тер.')
76
+ config.add_name('улус', 'у.')
77
+ config.add_name('волость', 'волость')
78
+ config.add_name('дачный поселок', 'дп.')
79
+ config.add_name('курортный поселок', 'кп.')
80
+ config.add_name('массив', 'массив')
81
+ config.add_name('поселок', 'п.', %w(пос посёлок))
82
+ config.add_name('почтовое отделение', 'п/о')
83
+ config.add_name('поселок городского типа', 'пгт')
84
+ config.add_name('рабочий поселок', 'рп')
85
+ config.add_name('сельская администрация', 'с/а')
86
+ config.add_name('сельское муниципальное образо', 'с/мо')
87
+ config.add_name('сельский округ', 'с/о')
88
+ config.add_name('сельское поселение', 'с/п')
89
+ config.add_name('сельсовет', 'с/с')
90
+ config.add_name('аал', 'аал')
91
+ config.add_name('автодорога', 'автодорога')
92
+ config.add_name('арбан', 'арбан')
93
+ config.add_name('аул', 'аул')
94
+ config.add_name('выселки(ок)', 'высел')
95
+ config.add_name('городок', 'городок')
96
+ config.add_name('деревня', 'д.', %w(дер))
97
+ config.add_name('железнодорожная будка', 'ж/д_будка')
98
+ config.add_name('железнодорожная казарма', 'ж/д_казарм')
99
+ config.add_name('ж/д останов. (обгонный) пункт', 'ж/д_оп')
100
+ config.add_name('железнодорожная платформа', 'ж/д_платф')
101
+ config.add_name('железнодорожный пост', 'ж/д_пост')
102
+ config.add_name('железнодорожный разъезд', 'ж/д_рзд')
103
+ config.add_name('железнодорожная станция', 'ж/д_ст', ['ж/д ст'])
104
+ config.add_name('жилая зона', 'жилзона')
105
+ config.add_name('жилой район', 'жилрайон')
106
+ config.add_name('заимка', 'заимка')
107
+ config.add_name('казарма', 'казарма')
108
+ config.add_name('квартал', 'кв-л', ['кварт'])
109
+ config.add_name('кордон', 'кордон')
110
+ config.add_name('леспромхоз', 'лпх')
111
+ config.add_name('местечко', 'м.')
112
+ config.add_name('микрорайон', 'мкр.', %w(мкрн микр))
113
+ config.add_name('населенный пункт', 'нп')
114
+ config.add_name('остров', 'остров')
115
+ config.add_name('планировочный район', 'п/р')
116
+ config.add_name('поселок и(при) станция(и)', 'п/ст')
117
+ config.add_name('погост', 'погост')
118
+ config.add_name('починок', 'починок')
119
+ config.add_name('промышленная зона', 'промзона')
120
+ config.add_name('разъезд', 'рзд')
121
+ config.add_name('село', 'с.')
122
+ config.add_name('слобода', 'сл.')
123
+ config.add_name('садовое неком-е товарищество', 'снт', ['садоводство'])
124
+ config.add_name('станция', 'ст-я')
125
+ config.add_name('станица', 'ст-ца', %w(стн ст))
126
+ config.add_name('хутор', 'х.')
127
+ config.add_name('абонентский ящик', 'а/я')
128
+ config.add_name('аллея', 'аллея')
129
+ config.add_name('берег', 'берег')
130
+ config.add_name('бульвар', 'б-р', %w(бул бульв))
131
+ config.add_name('бугор', 'бугор')
132
+ config.add_name('вал', 'вал')
133
+ config.add_name('въезд', 'въезд')
134
+ config.add_name('гаражно-строительный кооператив', 'гск')
135
+ config.add_name('дорога', 'дор.')
136
+ config.add_name('животноводческая точка', 'жт')
137
+ config.add_name('заезд', 'заезд')
138
+ config.add_name('зона', 'зона')
139
+ config.add_name('канал', 'канал', ['кан'])
140
+ config.add_name('километр', 'км.')
141
+ config.add_name('кольцо', 'кольцо')
142
+ config.add_name('коса', 'коса')
143
+ config.add_name('линия', 'линия', ['лин'])
144
+ config.add_name('мост', 'мост')
145
+ config.add_name('набережная', 'наб.')
146
+ config.add_name('парк', 'парк')
147
+ config.add_name('переулок', 'пер.', ['пер-к'])
148
+ config.add_name('переезд', 'переезд')
149
+ config.add_name('площадь', 'пл.')
150
+ config.add_name('платформа', 'платф.')
151
+ config.add_name('площадка', 'пл-ка')
152
+ config.add_name('полустанок', 'полустанок')
153
+ config.add_name('проспект', 'пр-кт', ['пр', 'просп', 'пр-т'])
154
+ config.add_name('проезд', 'проезд', ['пр-д', 'прз', 'прд'])
155
+ config.add_name('просек', 'просек')
156
+ config.add_name('просека', 'просека')
157
+ config.add_name('проселок', 'проселок')
158
+ config.add_name('проток', 'проток')
159
+ config.add_name('протока', 'протока')
160
+ config.add_name('проулок', 'проулок')
161
+ config.add_name('ряды', 'ряды')
162
+ config.add_name('сад', 'сад')
163
+ config.add_name('сквер', 'сквер')
164
+ config.add_name('спуск', 'спуск')
165
+ config.add_name('строение', 'стр')
166
+ config.add_name('тоннель', 'тоннель')
167
+ config.add_name('тракт', 'тр.')
168
+ config.add_name('тупик', 'туп.')
169
+ config.add_name('улица', 'ул.')
170
+ config.add_name('участок', 'уч-к')
171
+ config.add_name('ферма', 'ферма')
172
+ config.add_name('шоссе', 'ш.', ['шос'])
173
+ config.add_name('эстакада', 'эстакада')
174
+ config.add_name('гаражно-строительный кооператив', 'гск')
175
+ config.add_name('дачное некоммерческое партнерство', 'днп')
176
+ config.add_name('некоммерческое партнерство', 'н/п')
177
+ config.add_name('садовое товарищество', 'снт')
178
+ config.add_name('фермерское хозяйство', 'ф/х')
179
+ config.add_name('коттеджный поселок', 'кп', ['коттеджный'])
180
+
181
+ config.add_exception(
182
+ 'Чувашская Республика - Чувашия', 'Чувашия'
183
+ )
184
+ config.add_exception(
185
+ 'Ханты-Мансийский Автономный округ - Югра',
186
+ 'Ханты-Мансийский Автономный округ - Югра'
187
+ )
188
+
189
+ proper_names =
190
+ File.readlines(File.join(File.dirname(__FILE__), '../config/names.txt'))
191
+
192
+ proper_names.map(&:strip).each do |name|
193
+ config.add_proper_name(name)
194
+ end
195
+
196
+ synonyms =
197
+ YAML.load_file(File.join(File.dirname(__FILE__), '../config/synonyms.yml'))
198
+
199
+ synonyms.each do |synonym|
200
+ config.add_synonym(*synonym)
201
+ end
202
+ end