source: subversion/utils/little-osm/readxml.rb @ 1168

Last change on this file since 1168 was 1168, checked in by imi, 14 years ago

fixed little-osm. It is usable together with JOSM again.

  • Property svn:executable set to *
File size: 2.9 KB
Line 
1#!/usr/bin/ruby
2
3# Read in planet.osm and create a sqlite3 database file named "planet.db"
4
5require 'data/core'
6require 'rexml/document'
7require 'sqlite3'
8require 'time'
9
10
11# define from_db in data classes which retrieve the data from the just created database
12def Node.from_db uid, tags, time, reference, minlat, minlon, maxlat, maxlon
13  Node.new minlat, minlon, uid.to_i>>3, time
14end
15def Node.from_db_id uid
16  Node.from_db(*$db.execute("select * from data where uid=#{uid};")[0].to_a)
17end
18def Segment.from_db uid, tags, time, reference, minlat, minlon, maxlat, maxlon
19  fid, tid = reference.split ','
20  Segment.new(Node.from_db_id(fid.to_i), Node.from_db_id(tid.to_i), ((uid.to_i)>>3).to_s, time)
21end
22def Segment.from_db_id uid
23  q = $db.execute("select * from data where uid=#{uid};")[0].to_a
24  throw :incomplete_way if q.empty?
25  Segment.from_db(*q)
26end
27
28# define load_references in segment and way, which replaces the id-references by their real data
29class Segment < OsmPrimitive
30  def load_references
31    self.from = Node.from_db_id Node.to_uid(self.from)
32    self.to = Node.from_db_id Node.to_uid(self.to)
33  end
34end
35class Way < OsmPrimitive
36  def load_references
37    segment.collect! do |id|
38      Segment.from_db_id Segment.to_uid(id)
39    end
40  end
41end
42
43
44# writes the data object into the database.
45def write_sql data
46  tags = data.tags ? data.tags.to_a.join("\n") : "null"
47  tags.gsub!(/\"/, '')
48  time = data.timestamp ? '"'+data.timestamp.xmlschema+'"' : "null"
49  case data.class.name
50  when "Node"
51        reference = ""
52  when "Segment"
53        reference = Node.to_uid(data.from).to_s + "," + Node.to_uid(data.to).to_s
54        data.load_references
55  when "Way"
56        reference = data.segment.collect {|s| Segment.to_uid(s).to_s}.join ','
57        data.load_references
58  end
59  sql = %Q{insert into data values (#{data.to_uid}, "#{tags}", #{time}, "#{reference}", #{data.bbox.join(',')});}
60  $tmpsql << sql << "\n"
61  $db.execute sql
62end
63
64# parses the input data and call to write_sql for each object.
65class XmlReader
66  def method_missing sym, *args; end
67  def tag_start name, a
68    time = Time.parse(a['timestamp']) if a.include? 'timestamp'
69    id = a['id'].to_i
70
71    case name
72    when "node"
73      @current = Node.new a['lat'].to_f, a['lon'].to_f, id, time
74    when "segment"
75      @current = Segment.new a['from'].to_i, a['to'].to_i, id, time
76    when "way"
77      @current = Way.new [], id, time
78    when "tag"
79      @current[a['k']] = a['v']
80    when "seg"
81      @current.segment << a['id'].to_i
82    end
83  end
84
85  def tag_end name
86    catch :incomplete_way do
87      write_sql @current if name =~ /node|segment|way/
88    end
89  end
90end
91
92
93
94abort "planet.osm not found." unless File.exist? "planet.osm"
95File.delete "planet.db" if File.exist? "planet.db"
96$db = SQLite3::Database.new PLANET_DB
97$db.execute 'BEGIN'
98open('planet.sql').each {|sql| $db.execute sql}
99REXML::Document.parse_stream File.new('planet.osm'), XmlReader.new
100$db.execute 'COMMIT'
Note: See TracBrowser for help on using the repository browser.