class WorldDb::StateTreeReader
Public Instance Methods
read()
click to toggle source
# 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 recs = Name.find_states( node.value, country.id ) elsif node.level == part_level # 2 state = stack[0] recs = Name.find_parts( node.value, state.id ) elsif node.level == county_level # 2 or 3 state = stack[0] recs = Name.find_counties( node.value, state.id ) elsif node.level == muni_level # 3 or 4 state = stack[0] recs = Name.find_munis( node.value, state.id ) 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 recs = Name.find_cities( node.value, country.id ) else puts "*** (fatal) error: unknown level for tree node: #{node.inspect}" fail "[StateTreeReader] unknown level for tree node: #{node.inspect}" end if recs.size > 0 if recs.size == 1 puts "ok - record match found: #{recs.inspect}" rec = recs[0].place_object # e.g. state,part,county,muni,city,etc. else puts "** ok - #{recs.size} record(s) match found: #{recs.inspect}" ## fix/todo: note - uses always first entry for now; ## make lookup/matching more intelligent/usable!! rec = recs[0].place_object # e.g. state,part,county,muni,city,etc. end 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}" fail "[StateTreeReader] record not found for tree node: #{node.inspect}" end end level_diff = node.level - stack.size if level_diff > 0 logger.debug "[StateTreeReader] up +#{level_diff}" if level_diff > 1 fail "[StateTreeReader] level diff MUST be +1 is +#{level_diff}" end 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