Class: WorldDb::StateTreeReader
- Inherits:
-
ReaderBaseWithMoreAttribs
- Object
- ReaderBaseWithMoreAttribs
- WorldDb::StateTreeReader
- Defined in:
- lib/worlddb/readers/state_tree.rb
Instance Method Summary collapse
Methods inherited from ReaderBaseWithMoreAttribs
from_file, from_string, from_zip, #initialize, #skip_tags?, #strict?
Methods included from TextUtils::ValueHelper
#is_state?, #match_city, #match_country, #match_metro, #match_metro_flag, #match_metro_pop, #match_state_for_country, #match_supra, #match_supra_flag
Constructor Details
This class inherits a constructor from WorldDb::ReaderBaseWithMoreAttribs
Instance Method Details
#read ⇒ Object
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/worlddb/readers/state_tree.rb', line 7 def read ## for now requires country_id !! country = Country.find( @more_attribs[ :country_id ] ) puts "[StateTreeReader] country key: #{country.key}, name: #{country.name}" reader = TreeReader.from_string( @text ) stack = [] # note: last_level => stack.size; starts w/ 0 if country.key == 'de' ## use state (1) > part (2) > county (3) > muni (4) > city (5) state_level = 1 # Land part_level = 2 # Regierungsbezirk county_level = 3 # Landkreis, Kreisfreie Stadt muni_level = 4 # Gemeinde city_level = 5 # Stadt, Ort, etc. else ## use state (1) > county (2) > muni (3) > city (4) state_level = 1 part_level = -1 ## note: not in use (-1) county_level = 2 muni_level = 3 city_level = 4 end reader.each_line do |nodes| names = nodes.map { |item| "(#{item.level}) #{item.value}" } node = nodes.last puts " #{names.join( ' › ' )}:" puts " key: >#{node.key}<, level: >#{node.level}<, value: >#{node.value}<" if node.level == state_level # 1 rec = State.where( "name like '#{node.value}%'" ).first elsif node.level == part_level # 2 state = stack[0] rec = Part.where( "name like '#{node.value}%' AND state_id = #{state.id}" ).first elsif node.level == county_level # 2 or 3 state = stack[0] rec = County.where( "name like '#{node.value}%' AND state_id = #{state.id}" ).first elsif node.level == muni_level # 3 or 4 state = stack[0] rec = Muni.where( "name like '#{node.value}%' AND state_id = #{state.id}" ).first elsif node.level == city_level # 4 or 5 ## note: city requires country scope for lookup ## todo/fix: how to deal with cities with the same name ## in the same country (and same state and same county etc.) ??? - add some examples here rec = City.where( "name like '#{node.value}%' AND country_id = #{country.id}" ).first else puts "*** (fatal) error: unknown level for tree node: #{node.inspect}" ## todo/fix: exit here end if rec.present? puts "ok - record match found: #{rec.inspect}" else ## note: for now only auto-adds munis n cities if node.level == muni_level # 3 or 4 ## add muni key = TextUtils.title_to_key( node.value ) name = node.value level = node.level state = stack[0] county = stack[county_level-1] # note: stack is zero-based (thus, -1) puts "*** adding muni record:" rec = Muni.create!( key: key, name: name, level: level, state_id: state.id, county_id: county.id ) elsif node.level == city_level # 4 or 5 ## add city key = TextUtils.title_to_key( node.value ) name = node.value state = stack[0] county = stack[county_level-1] # note: stack is zero-based (thus, -1) muni = stack[muni_level-1] # note: stack is zero-based (thus, -1) puts "*** adding city record:" rec = City.create!( key: key, name: name, state_id: state.id, ## add county_id too ??? muni_id: muni.id, country_id: country.id ) else puts "*** (fatal) error: record not found for tree node: #{node.inspect}" ## todo/fix: exit here end end level_diff = node.level - stack.size if level_diff > 0 logger.debug "[StateTreeReader] up +#{level_diff}" ## FIX!!! todo/check/verify/assert: always must be +1 elsif level_diff < 0 logger.debug "[StateTreeReader] down #{level_diff}" level_diff.abs.times { stack.pop } stack.pop else ## same level stack.pop end stack.push( rec ) ## hierarchy of records (mirrors hierarchy of read-in text) end # each_line end |