worlddb-models 2.2.2 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/Manifest.txt +31 -13
  3. data/README.md +7 -7
  4. data/Rakefile +1 -1
  5. data/lib/worlddb/deleter.rb +6 -1
  6. data/lib/worlddb/helpers/value_helper.rb +117 -0
  7. data/lib/worlddb/matcher.rb +99 -135
  8. data/lib/worlddb/matcher_adm.rb +82 -0
  9. data/lib/worlddb/models/city.rb +30 -208
  10. data/lib/worlddb/models/city_base.rb +220 -0
  11. data/lib/worlddb/models/continent.rb +9 -0
  12. data/lib/worlddb/models/country.rb +21 -4
  13. data/lib/worlddb/models/forward.rb +25 -9
  14. data/lib/worlddb/models/lang.rb +6 -0
  15. data/lib/worlddb/models/place.rb +1 -1
  16. data/lib/worlddb/models/state.rb +83 -0
  17. data/lib/worlddb/models/{region.rb → state_base.rb} +52 -36
  18. data/lib/worlddb/models/tagdb/tag.rb +1 -1
  19. data/lib/worlddb/models.rb +11 -8
  20. data/lib/worlddb/patterns.rb +4 -4
  21. data/lib/worlddb/reader.rb +68 -39
  22. data/lib/worlddb/reader_file.rb +36 -3
  23. data/lib/worlddb/reader_zip.rb +33 -3
  24. data/lib/worlddb/readers/base.rb +149 -0
  25. data/lib/worlddb/readers/city.rb +2 -65
  26. data/lib/worlddb/readers/country.rb +2 -63
  27. data/lib/worlddb/readers/lang.rb +3 -68
  28. data/lib/worlddb/readers/state.rb +61 -0
  29. data/lib/worlddb/readers/state_tree.rb +118 -0
  30. data/lib/worlddb/readers/usage.rb +2 -65
  31. data/lib/worlddb/schema.rb +142 -43
  32. data/lib/worlddb/stats.rb +7 -4
  33. data/lib/worlddb/tree_reader.rb +97 -0
  34. data/lib/worlddb/version.rb +2 -2
  35. data/test/adm/test_fixture_matcher_adm2.rb +73 -0
  36. data/test/{test_fixture_matcher_adm3.rb → adm/test_fixture_matcher_adm3.rb} +6 -6
  37. data/test/adm/test_fixture_matcher_tree.rb +52 -0
  38. data/test/{test_read_adm.rb → adm/test_read_adm.rb} +13 -20
  39. data/test/adm/test_read_tree.rb +63 -0
  40. data/test/data/at-austria/2--n-niederoesterreich/counties.txt +6 -4
  41. data/test/data/at-austria/orte.txt +23 -0
  42. data/test/data/at-austria/setups/tree.txt +9 -0
  43. data/test/data/de-deutschland/3--by-bayern/4--oberfranken/counties.txt +14 -13
  44. data/test/data/de-deutschland/3--by-bayern/4--oberfranken/orte.txt +104 -0
  45. data/test/data/de-deutschland/3--by-bayern/4--oberfranken/orte_ii.txt +17 -0
  46. data/test/data/de-deutschland/3--by-bayern/{districts.txt → parts.txt} +1 -1
  47. data/test/data/de-deutschland/orte.txt +12 -0
  48. data/test/data/de-deutschland/setups/adm.txt +1 -1
  49. data/test/data/de-deutschland/setups/tree.txt +9 -0
  50. data/test/helper.rb +8 -1
  51. data/test/test_fixture_matchers.rb +9 -10
  52. data/test/test_fixture_matchers_ii.rb +20 -19
  53. data/test/test_model_city.rb +26 -9
  54. data/test/{test_model_comp.rb → test_model_compat.rb} +15 -13
  55. data/test/test_model_country.rb +1 -1
  56. data/test/test_model_state.rb +54 -0
  57. data/test/test_model_states_at.rb +111 -0
  58. data/test/test_model_states_de.rb +147 -0
  59. data/test/test_models.rb +10 -3
  60. data/test/test_parse_city.rb +70 -0
  61. data/test/test_parse_country.rb +56 -0
  62. data/test/test_parse_state.rb +46 -0
  63. data/test/test_state_tree_reader_at.rb +54 -0
  64. data/test/test_state_tree_reader_de.rb +71 -0
  65. data/test/test_tree_reader.rb +39 -0
  66. metadata +50 -22
  67. data/lib/worlddb/models/city_compat.rb +0 -27
  68. data/lib/worlddb/models/continent_compat.rb +0 -24
  69. data/lib/worlddb/models/country_compat.rb +0 -35
  70. data/lib/worlddb/models/lang_compat.rb +0 -23
  71. data/lib/worlddb/models/region_compat.rb +0 -26
  72. data/lib/worlddb/readers/region.rb +0 -79
  73. data/test/test_fixture_matcher_adm2.rb +0 -62
  74. data/test/test_model_region.rb +0 -50
@@ -0,0 +1,83 @@
1
+ # encoding: UTF-8
2
+
3
+ module WorldDb
4
+ module Model
5
+
6
+
7
+ class State < StateBase
8
+
9
+ belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
10
+
11
+ has_many :parts, class_name: 'Part', foreign_key: 'state_id' # x / ADM2
12
+ has_many :counties, class_name: 'County', foreign_key: 'state_id' # ADM2 / ADM3
13
+ has_many :munis, class_name: 'Muni', foreign_key: 'state_id' # ADM3 / ADM4
14
+ has_many :cities, class_name: 'City', foreign_key: 'state_id'
15
+
16
+ def place_kind # use place_kind_of_code ??
17
+ 'ADM1' # note: for now assumes always level 1
18
+ end
19
+
20
+ def state_id # return top-level (e.g. adm1) state_id
21
+ id
22
+ end
23
+
24
+ end # class State
25
+
26
+
27
+ class Part < StateBase ## optional ADM2 e.g. Regierungsbezirke in Bayern, etc.
28
+
29
+ belongs_to :state, class_name: 'State', foreign_key: 'state_id'
30
+
31
+ has_many :counties, class_name: 'County', foreign_key: 'part_id'
32
+ has_many :cities, class_name: 'City', foreign_key: 'part_id'
33
+
34
+ def place_kind # use place_kind_of_code ??
35
+ 'ADM2' # note: for now assumes always level 2
36
+ end
37
+
38
+ def country_id # return country_id via top-level (e.g. adm1) state; -- used for auto-creating cities
39
+ state.country_id
40
+ end
41
+
42
+ end # class Part
43
+
44
+
45
+ class County < StateBase ## note: might be ADM2 or ADM3
46
+
47
+ belongs_to :state, class_name: 'State', foreign_key: 'state_id'
48
+ belongs_to :part, class_name: 'Part', foreign_key: 'part_id' ## optional assoc (used if level=3 and not 2)
49
+
50
+ has_many :munis, class_name: 'Muni', foreign_key: 'county_id'
51
+ has_many :cities, class_name: 'City', foreign_key: 'county_id'
52
+
53
+ def place_kind # use place_kind_of_code ??
54
+ "ADM#{level}" # note: might be ADM2 or ADM3
55
+ end
56
+
57
+ def country_id # return country_id via top-level (e.g. adm1) state
58
+ state.country_id
59
+ end
60
+
61
+ end # class County
62
+
63
+
64
+ class Muni < StateBase ## note: might be ADM3 or ADM4
65
+
66
+ belongs_to :state, class_name: 'State', foreign_key: 'state_id'
67
+ belongs_to :county, class_name: 'County', foreign_key: 'county_id'
68
+
69
+ has_many :cities, class_name: 'City', foreign_key: 'muni_id'
70
+
71
+ def place_kind # use place_kind_of_code ??
72
+ "ADM#{level}" # note: might be ADM3 or ADM4
73
+ end
74
+
75
+ def country_id # return country_id via top-level (e.g. adm1) state
76
+ state.country_id
77
+ end
78
+
79
+ end # class Muni
80
+
81
+
82
+ end # module Model
83
+ end # module WorldDb
@@ -4,29 +4,35 @@ module WorldDb
4
4
  module Model
5
5
 
6
6
 
7
- class Region < ActiveRecord::Base
7
+ class StateBase < ActiveRecord::Base
8
+
9
+ self.abstract_class = true
8
10
 
9
11
  extend TextUtils::TagHelper # will add self.find_tags, self.find_tags_in_attribs!, etc.
10
12
 
11
13
  # NB: use extend - is_<type>? become class methods e.g. self.is_<type>? for use in
12
14
  # self.create_or_update_from_values
13
- extend TextUtils::ValueHelper # e.g. is_year?, is_region?, is_address?, is_taglist? etc.
15
+ extend TextUtils::ValueHelper # e.g. is_year?, is_address?, is_taglist? etc.
14
16
 
15
17
  belongs_to :place, class_name: 'Place', foreign_key: 'place_id'
16
- belongs_to :country, class_name: 'Country', foreign_key: 'country_id'
17
-
18
- has_many :cities, class_name: 'City', foreign_key: 'region_id'
19
18
 
20
- has_many_tags
19
+ has_many_tags # note: check if working w/ base class (statebase) -- use/try concern??
21
20
 
22
- validates :key, format: { with: /#{REGION_KEY_PATTERN}/, message: REGION_KEY_PATTERN_MESSAGE }
23
- validates :code, format: { with: /#{REGION_CODE_PATTERN}/, message: REGION_CODE_PATTERN_MESSAGE }, allow_nil: true
21
+ validates :key, format: { with: /#{STATE_KEY_PATTERN}/, message: STATE_KEY_PATTERN_MESSAGE }
22
+ validates :code, format: { with: /#{STATE_CODE_PATTERN}/, message: STATE_CODE_PATTERN_MESSAGE }, allow_nil: true
24
23
 
25
24
  ### recursive self-reference - use "generic" node??
26
- ## has_many :nodes, class_name: 'Region', foregin_key: 'region_id'
27
- belongs_to :parent, class_name: 'Region', foreign_key: 'region_id'
28
- has_many :regions, class_name: 'Region', foreign_key: 'region_id' ## subregions
25
+ ## has_many :nodes, class_name: 'State', foreign_key: 'state_id'
26
+ # belongs_to :parent, class_name: 'State', foreign_key: 'state_id'
27
+ # has_many :states, class_name: 'State', foreign_key: 'state_id' ## substates
29
28
 
29
+ ## begin compat
30
+ def title() name; end
31
+ def title=(value) self.name = value; end
32
+
33
+ def synonyms() alt_names; end
34
+ def synonyms=(value) self.alt_names = value; end
35
+ ## end
30
36
 
31
37
  before_create :on_create
32
38
  before_update :on_update
@@ -41,20 +47,6 @@ class Region < ActiveRecord::Base
41
47
  place.update_attributes!( name: name, kind: place_kind )
42
48
  end
43
49
 
44
- def is_district?() d? == true; end
45
- def is_county?() c? == true; end
46
-
47
- def place_kind # use place_kind_of_code ??
48
- ### fix: use "generic" level counter - make it a database field (default/top level is 1)
49
- if is_district?
50
- 'ADM2'
51
- elsif is_county?
52
- 'ADM3'
53
- else
54
- 'ADM1'
55
- end
56
- end
57
-
58
50
 
59
51
  def all_names( opts={} )
60
52
  ### fix:
@@ -70,15 +62,25 @@ class Region < ActiveRecord::Base
70
62
  end
71
63
 
72
64
 
65
+ def self.parse( *args )
66
+ ## remove (extract) attribs hash (if last arg is a hash n present)
67
+ more_attribs = args.last.is_a?(Hash) ? args.pop : {} ## extract_options!
68
+ values = args
69
+
70
+ self.create_or_update_from_values( values, more_attribs )
71
+ end
73
72
 
74
73
  def self.create_or_update_from_values( values, more_attribs={} )
75
74
 
76
75
  ## key & title & country required
77
76
  attribs, more_values = find_key_n_title( values )
77
+ ## fix/hack: change :title to :name
78
+ ## attribs[:name] = attribs[:title]; attribs.delete( :title )
78
79
  attribs = attribs.merge( more_attribs )
79
80
 
80
81
  ## check for optional values
81
- Region.create_or_update_from_attribs( attribs, more_values )
82
+ puts "[debug] StateBase.create_or_update_from_values calling #{self.name}" # note: assume self is derived class (object)
83
+ self.create_or_update_from_attribs( attribs, more_values )
82
84
  end
83
85
 
84
86
 
@@ -107,7 +109,7 @@ class Region < ActiveRecord::Base
107
109
  elsif match_number( value ) do |num| # numeric (nb: can use any _ or spaces inside digits e.g. 1_000_000 or 1 000 000)
108
110
  value_numbers << num
109
111
  end
110
- elsif value =~ /#{REGION_CODE_PATTERN}/ ## assume two or three-letter code
112
+ elsif value =~ /#{STATE_CODE_PATTERN}/ ## assume two or three-letter code
111
113
  new_attributes[ :code ] = value
112
114
  elsif (values.size==(index+1)) && is_taglist?( value ) # tags must be last entry
113
115
  logger.debug " found tags: >>#{value}<<"
@@ -129,27 +131,40 @@ class Region < ActiveRecord::Base
129
131
  end # if value_numbers.size > 0
130
132
 
131
133
  ## todo: assert that country_id is present/valid, that is, NOT null
132
- rec = Region.find_by_key_and_country_id( new_attributes[ :key ], new_attributes[ :country_id] )
134
+ puts "[debug] StateBase.create_or_update_from_attribs calling #{self.name}.where" # note: assume self is derived class (object)
135
+ # note: was self.find_by_key_and_country_id
136
+ if self == State
137
+ ## note: state scoped by country (all others by top-level state and NOT country)
138
+ rec = self.where(
139
+ key: new_attributes[ :key ],
140
+ country_id: new_attributes[ :country_id] ).first
141
+ else
142
+ rec = self.where(
143
+ key: new_attributes[ :key ],
144
+ state_id: new_attributes[ :state_id] ).first
145
+ end
133
146
 
134
147
  if rec.present?
135
- logger.debug "update Region #{rec.id}-#{rec.key}:"
148
+ logger.debug "update #{self.name} #{rec.id}-#{rec.key}:"
136
149
  else
137
- logger.debug "create Region:"
138
- rec = Region.new
150
+ logger.debug "create #{self.name}:" ## e.g. self.name => State, County, Muni, etc.
151
+ puts "[debug] StateBase.create_or_update_from_attribs calling #{self.name}.new" # note: assume self is derived class (object)
152
+ rec = self.new
139
153
  end
140
-
154
+
141
155
  logger.debug new_attributes.to_json
142
-
156
+
143
157
  rec.update_attributes!( new_attributes )
144
158
 
145
159
  #################
146
160
  # auto add capital cities
161
+ # - note: get added to top-level state (e.g. adm1)
147
162
 
148
163
  City.create_or_update_from_titles( value_cities,
149
- region_id: rec.id,
164
+ state_id: rec.state_id,
150
165
  country_id: rec.country_id )
151
166
 
152
- ### todo/fix: add captial ref to country/region
167
+ ### todo/fix: add captial ref to country/state
153
168
  ## todo/fix: use update_from_title and only allow one capital city
154
169
 
155
170
 
@@ -185,7 +200,8 @@ class Region < ActiveRecord::Base
185
200
 
186
201
 
187
202
 
188
- end # class Region
203
+ end # class State
189
204
 
190
205
  end # module Model
191
206
  end # module WorldDb
207
+
@@ -7,7 +7,7 @@ class Tag
7
7
 
8
8
  has_many :cities, :through => :taggings, :source => :taggable, source_type: 'WorldDb::Model::City', class_name: 'WorldDb::Model::City'
9
9
  has_many :countries, :through => :taggings, :source => :taggable, source_type: 'WorldDb::Model::Country', class_name: 'WorldDb::Model::Country'
10
- has_many :regions, :through => :taggings, :source => :taggable, source_type: 'WorldDb::Model::Region', class_name: 'WorldDb::Model::Region'
10
+ has_many :states, :through => :taggings, :source => :taggable, source_type: 'WorldDb::Model::State', class_name: 'WorldDb::Model::State'
11
11
 
12
12
  end # class Tag
13
13
 
@@ -42,30 +42,31 @@ require 'worlddb/models/forward'
42
42
  require 'worlddb/models/name'
43
43
  require 'worlddb/models/place'
44
44
  require 'worlddb/models/continent'
45
- require 'worlddb/models/continent_compat' # todo: move to compat gem
46
45
  require 'worlddb/models/country'
47
- require 'worlddb/models/country_compat' # todo: move to compat gem
48
46
  require 'worlddb/models/country_code'
49
- require 'worlddb/models/region'
50
- require 'worlddb/models/region_compat' # todo: move to compat gem
47
+ require 'worlddb/models/state_base'
48
+ require 'worlddb/models/state'
49
+ require 'worlddb/models/city_base'
51
50
  require 'worlddb/models/city'
52
- require 'worlddb/models/city_compat' # todo: move to compat gem
53
51
  require 'worlddb/models/lang'
54
- require 'worlddb/models/lang_compat' # todo: move to compat gem
55
52
  require 'worlddb/models/usage'
56
53
 
57
54
  require 'worlddb/models/tagdb/tag'
58
55
  require 'worlddb/models/tagdb/tagging'
59
56
 
57
+ require 'worlddb/helpers/value_helper' # Note: extends module TextUtils(!!)::ValueHelper
60
58
 
61
59
 
62
- require 'worlddb/schema' # NB: requires worlddb/models (include WorldDB::Models)
60
+ require 'worlddb/schema' # Note: requires worlddb/models (include WorldDB::Models)
63
61
  require 'worlddb/matcher'
62
+ require 'worlddb/matcher_adm'
64
63
 
64
+ require 'worlddb/readers/base'
65
65
  require 'worlddb/readers/lang'
66
66
  require 'worlddb/readers/usage'
67
67
  require 'worlddb/readers/country'
68
- require 'worlddb/readers/region'
68
+ require 'worlddb/readers/state'
69
+ require 'worlddb/readers/state_tree'
69
70
  require 'worlddb/readers/city'
70
71
 
71
72
  require 'worlddb/reader'
@@ -74,6 +75,8 @@ require 'worlddb/reader_zip'
74
75
  require 'worlddb/deleter'
75
76
  require 'worlddb/stats'
76
77
 
78
+ require 'worlddb/tree_reader'
79
+
77
80
 
78
81
  module WorldDb
79
82
 
@@ -33,11 +33,11 @@ module WorldDb
33
33
  COUNTRY_CODE_PATTERN_MESSAGE = "expected three uppercase letters A-Z (and _) /#{COUNTRY_CODE_PATTERN}/"
34
34
 
35
35
 
36
- REGION_KEY_PATTERN = '\A[a-z]+\z'
37
- REGION_KEY_PATTERN_MESSAGE = "expected one or more lowercase letters a-z /#{REGION_KEY_PATTERN}/"
36
+ STATE_KEY_PATTERN = '\A[a-z]+\z'
37
+ STATE_KEY_PATTERN_MESSAGE = "expected one or more lowercase letters a-z /#{STATE_KEY_PATTERN}/"
38
38
 
39
- REGION_CODE_PATTERN = '\A[A-Z_]{2,3}\z'
40
- REGION_CODE_PATTERN_MESSAGE = "expected two or three uppercase letters A-Z (and _) /#{REGION_CODE_PATTERN}/"
39
+ STATE_CODE_PATTERN = '\A[A-Z_]{2,3}\z'
40
+ STATE_CODE_PATTERN_MESSAGE = "expected two or three uppercase letters A-Z (and _) /#{STATE_CODE_PATTERN}/"
41
41
 
42
42
 
43
43
  CITY_KEY_PATTERN = '\A[a-z]{3,}\z'
@@ -10,7 +10,7 @@ class ReaderBase
10
10
  ## make models available in sportdb module by default with namespace
11
11
  # e.g. lets you use City instead of Models::City
12
12
  include Models
13
- include Matcher # e.g. match_cities_for_country, match_regions_for_country, etc.
13
+ include Matcher # e.g. match_cities_for_country, match_states_for_country, etc.
14
14
 
15
15
  ## value helpers e.g. is_year?, is_taglist? etc.
16
16
  include TextUtils::ValueHelper
@@ -21,9 +21,9 @@ class ReaderBase
21
21
 
22
22
 
23
23
  def initialize( opts={} )
24
- ## option: do NOT generate/add any tags for countries/regions/cities
24
+ ## option: do NOT generate/add any tags for countries/states/cities
25
25
  @skip_tags = opts[:skip_tags].present? ? true : false
26
- ## option: for now issue warning on update, that is, if key/record (country,region,city) already exists
26
+ ## option: for now issue warning on update, that is, if key/record (country,state,city) already exists
27
27
  @strict = opts[:strict].present? ? true : false
28
28
  end
29
29
 
@@ -80,56 +80,85 @@ class ReaderBase
80
80
  elsif match_cities_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/cities/
81
81
  ## auto-add required country code (from folder structure)
82
82
  country = Country.find_by_key!( country_key )
83
- logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
83
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
84
84
 
85
85
  r = create_city_reader( name, country_id: country.id )
86
86
  r.read()
87
87
  end
88
- elsif match_regions_abbr_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/regions\.abbr/
89
- load_regions_xxx( country_key, 'abbr', name )
88
+ elsif match_tree_for_country( name ) do |country_key|
89
+ ## auto-add required country code (from folder structure)
90
+ country = Country.find_by_key!( country_key )
91
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
92
+
93
+ r = create_tree_reader( name, country_id: country.id )
94
+ r.read()
90
95
  end
91
- elsif match_regions_iso_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/regions\.iso/
92
- load_regions_xxx( country_key, 'iso', name )
96
+ elsif match_states_abbr_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/states\.abbr/
97
+ load_states_xxx( country_key, 'abbr', name )
93
98
  end
94
- elsif match_regions_nuts_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/regions\.nuts/
95
- load_regions_xxx( country_key, 'nuts', name )
99
+ elsif match_states_iso_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/states\.iso/
100
+ load_states_xxx( country_key, 'iso', name )
96
101
  end
97
- elsif match_adm3_for_country( name ) do |country_key,region_key,adm2_name|
102
+ elsif match_states_nuts_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/states\.nuts/
103
+ load_states_xxx( country_key, 'nuts', name )
104
+ end
105
+ elsif match_adm3_counties_for_country( name ) do |country_key, state_key, part_name|
98
106
  ## auto-add required country code (from folder structure)
99
107
  country = Country.find_by_key!( country_key )
100
- logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
101
- region = Region.find_by_key_and_country_id!( region_key, country.id )
102
- logger.debug "Region (Adm1) #{region.key} >#{region.title}<"
108
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
109
+ state = State.find_by_key_and_country_id!( state_key, country.id )
110
+ logger.debug "State (ADM1) #{state.key} >#{state.name}<"
111
+
103
112
  ### todo: move find adm2 to model for (re)use !!!
104
- adm2 = Region.where( "lower(name) = ? AND country_id = ?",
105
- adm2_name, country.id ).first ## check - first needed? returns ary??
106
- if adm2.nil?
107
- puts "*** error/warn: fix - skipping adm3 - adm2 '#{adm2_name}' not found"
113
+ part = Part.where( "lower(name) = ? AND state_id = ?",
114
+ part_name, state.id ).first ## check - first needed? returns ary??
115
+ if part.nil?
116
+ logger.error "fix!! - skipping adm3_counties - part (ADM2) '#{part_name}' not found"
108
117
  next
109
118
  end
110
- logger.debug "Region (Adm2) #{adm2.key} >#{adm2.title}<"
119
+ logger.debug "Part (ADM2) #{part.key} >#{part.name}<"
111
120
 
112
- r = create_region_reader( name, country_id: country.id, region_id: adm2.id, level:3, c:true )
113
- r.read()
121
+ st = create_county_reader( name,
122
+ state_id: state.id,
123
+ part_id: part.id,
124
+ level: 3 ) # note: change county level to 3 (default is 2)
125
+ st.read()
114
126
  end
115
- elsif match_adm2_for_country( name ) do |country_key,region_key|
127
+ elsif match_adm2_counties_for_country( name ) do |country_key,state_key|
116
128
  ## auto-add required country code (from folder structure)
117
129
  country = Country.find_by_key!( country_key )
118
- logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
119
- region = Region.find_by_key_and_country_id!( region_key, country.id )
120
- logger.debug "Region (Adm1) #{region.key} >#{region.title}<"
121
-
122
- r = create_region_reader( name, country_id: country.id, region_id: region.id, level:2, d:true )
123
- r.read()
130
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
131
+ state = State.find_by_key_and_country_id!( state_key, country.id )
132
+ logger.debug "State (ADM1) #{state.key} >#{state.name}<"
133
+
134
+ st = create_county_reader( name,
135
+ state_id: state.id,
136
+ ## part_id: nil,
137
+ level: 2 )
138
+ st.read()
139
+ end
140
+ elsif match_adm2_parts_for_country( name ) do |country_key,state_key|
141
+ ## auto-add required country code (from folder structure)
142
+ country = Country.find_by_key!( country_key )
143
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
144
+ state = State.find_by_key_and_country_id!( state_key, country.id )
145
+ logger.debug "State (ADM2) #{state.key} >#{state.name}<"
146
+
147
+ st = create_part_reader( name,
148
+ state_id: state.id,
149
+ level: 2 )
150
+ st.read()
124
151
  end
125
- ### fix: change to match_adm1_for_country()
126
- elsif match_regions_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/regions/
152
+ ### fix: change to match_adm1_states_for_country() - why? why not??
153
+ elsif match_states_for_country( name ) do |country_key| # name =~ /\/([a-z]{2})\/states/
127
154
  ## auto-add required country code (from folder structure)
128
155
  country = Country.find_by_key!( country_key )
129
- logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
156
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
130
157
 
131
- r = create_region_reader( name, country_id: country.id, region_id: nil, level:1, s:true )
132
- r.read()
158
+ st = create_state_reader( name,
159
+ country_id: country.id,
160
+ level: 1 )
161
+ st.read()
133
162
  end
134
163
  else
135
164
  logger.error "unknown world.db fixture type >#{name}<"
@@ -138,17 +167,17 @@ class ReaderBase
138
167
  end
139
168
 
140
169
 
141
- ### use RegionAttrReader
142
- def load_regions_xxx( country_key, xxx, name )
170
+ ### use StateAttrReader
171
+ def load_states_xxx( country_key, xxx, name )
143
172
  country = Country.find_by_key!( country_key )
144
- logger.debug "Country #{country.key} >#{country.title} (#{country.code})<"
173
+ logger.debug "Country #{country.key} >#{country.name} (#{country.code})<"
145
174
 
146
175
  reader = create_hash_reader( name )
147
176
 
148
177
  reader.each do |key, value|
149
- region = Region.find_by_country_id_and_key!( country.id, key )
150
- region.send( "#{xxx}=", value )
151
- region.save!
178
+ state = State.find_by_country_id_and_key!( country.id, key )
179
+ state.send( "#{xxx}=", value )
180
+ state.save!
152
181
  end
153
182
  end
154
183
 
@@ -40,14 +40,47 @@ class Reader < ReaderBase
40
40
  CountryReader.from_file( path, more_attribs )
41
41
  end
42
42
 
43
- def create_region_reader( name, more_attribs={} )
43
+ def create_state_reader( name, more_attribs={} )
44
44
  path = "#{@include_path}/#{path_to_real_path(name)}.txt"
45
45
 
46
- logger.info "parsing data (region) '#{name}' (#{path})..."
46
+ logger.info "parsing data (state) '#{name}' (#{path})..."
47
47
 
48
- RegionReader.from_file( path, more_attribs )
48
+ StateReader.from_file( path, more_attribs )
49
49
  end
50
50
 
51
+ def create_part_reader( name, more_attribs={} )
52
+ path = "#{@include_path}/#{path_to_real_path(name)}.txt"
53
+
54
+ logger.info "parsing data (part) '#{name}' (#{path})..."
55
+
56
+ PartReader.from_file( path, more_attribs )
57
+ end
58
+
59
+ def create_county_reader( name, more_attribs={} )
60
+ path = "#{@include_path}/#{path_to_real_path(name)}.txt"
61
+
62
+ logger.info "parsing data (county) '#{name}' (#{path})..."
63
+
64
+ CountyReader.from_file( path, more_attribs )
65
+ end
66
+
67
+ def create_muni_reader( name, more_attribs={} )
68
+ path = "#{@include_path}/#{path_to_real_path(name)}.txt"
69
+
70
+ logger.info "parsing data (muni) '#{name}' (#{path})..."
71
+
72
+ MuniReader.from_file( path, more_attribs )
73
+ end
74
+
75
+
76
+ def create_tree_reader( name, more_attribs={} )
77
+ path = "#{@include_path}/#{path_to_real_path(name)}.txt"
78
+ logger.info "parsing data (state tree) '#{name}' (#{path})..."
79
+
80
+ StateTreeReader.from_file( path, more_attribs )
81
+ end
82
+
83
+
51
84
  def create_city_reader( name, more_attribs={} )
52
85
  path = "#{@include_path}/#{path_to_real_path(name)}.txt"
53
86
  logger.info "parsing data (city) '#{name}' (#{path})..."
@@ -85,13 +85,43 @@ class ZipReader < ReaderBase
85
85
  CountryReader.from_zip( @zip_file, path, more_attribs )
86
86
  end
87
87
 
88
- def create_region_reader( name, more_attribs={} )
88
+ def create_state_reader( name, more_attribs={} )
89
89
  path = name_to_zip_entry_path( name )
90
- logger.info "parsing data (region) in zip '#{name}' (#{path})..."
90
+ logger.info "parsing data (state) in zip '#{name}' (#{path})..."
91
91
 
92
- RegionReader.from_zip( @zip_file, path, more_attribs )
92
+ StateReader.from_zip( @zip_file, path, more_attribs )
93
93
  end
94
94
 
95
+ def create_part_reader( name, more_attribs={} )
96
+ path = name_to_zip_entry_path( name )
97
+ logger.info "parsing data (part) in zip '#{name}' (#{path})..."
98
+
99
+ PartReader.from_zip( @zip_file, path, more_attribs )
100
+ end
101
+
102
+ def create_county_reader( name, more_attribs={} )
103
+ path = name_to_zip_entry_path( name )
104
+ logger.info "parsing data (county) in zip '#{name}' (#{path})..."
105
+
106
+ CountyReader.from_zip( @zip_file, path, more_attribs )
107
+ end
108
+
109
+ def create_muni_reader( name, more_attribs={} )
110
+ path = name_to_zip_entry_path( name )
111
+ logger.info "parsing data (muni) in zip '#{name}' (#{path})..."
112
+
113
+ MuniReader.from_zip( @zip_file, path, more_attribs )
114
+ end
115
+
116
+
117
+ def create_tree_reader( name, more_attribs={} )
118
+ path = name_to_zip_entry_path( name )
119
+ logger.info "parsing data (state tree) in zip '#{name}' (#{path})..."
120
+
121
+ StateTreeReader.from_zip( @zip_file, path, more_attribs )
122
+ end
123
+
124
+
95
125
  def create_city_reader( name, more_attribs={} )
96
126
  path = name_to_zip_entry_path( name )
97
127
  logger.info "parsing data (city) in zip '#{name}' (#{path})..."