-
Notifications
You must be signed in to change notification settings - Fork 16
/
osm_print.rb
125 lines (107 loc) · 3.37 KB
/
osm_print.rb
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
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
115
116
117
118
119
120
121
122
123
124
require './osm'
require './actions'
USERNAME = "Redaction bot"
UID = 0
TIMESTAMP = "2012-04-01T00:00:00Z"
def compare(a, b)
aklass, bklass = nil, nil
aid, bid = 0, 0
if a.class == Delete then
aklass = a.klass
aid = a.element_id
else
aklass = a.obj.class
aid = a.obj.element_id
end
if b.class == Delete then
bklass = b.klass
bid = b.element_id
else
bklass = b.obj.class
bid = b.obj.element_id
end
ai = if aklass == OSM::Node then 0 elsif aklass == OSM::Way then 1 else 2 end
bi = if bklass == OSM::Node then 0 elsif bklass == OSM::Way then 1 else 2 end
return ai <=> bi if ai != bi
aid <=> bid
end
module OSM
def self.print_osmchange(changeset, db, out = $stdout, changeset_id = -1)
#changeset.sort! {|a, b| compare(a, b)}
out << '<osmChange version="0.6" generator="Redaction bot">' << "\n"
changeset.each do |o|
if o.class == Edit then
out << ' <modify>' << "\n"
self.print(o.obj, out, 2, changeset_id)
out << ' </modify>' << "\n"
elsif o.class == Delete then
out << ' <delete>' << "\n"
self.print(self.from_delete(o, db, changeset_id), out, 2, changeset_id)
out << ' </delete>' << "\n"
end
end
out << '</osmChange>' << "\n"
end
def self.from_delete(delete, db, changeset_id)
t = if delete.klass == OSM::Node then db.current_node(delete.element_id)
elsif delete.klass == OSM::Way then db.current_way(delete.element_id)
elsif delete.klass == OSM::Relation then db.current_relation(delete.element_id)
end
delete.klass.new({:id => delete.element_id, :changeset => changeset_id, :visible => false, :version => t.version},[],[])
end
def self.print(obj, out = $stdout, indent = 0, changeset_id = -1)
attributes = {
:id => obj.element_id,
:changeset => changeset_id,
:user => USERNAME,
:uid => UID,
:visible => obj.visible,
:timestamp => TIMESTAMP,
:version => obj.version,
}
tags = obj.tags
child_name = nil
children = []
if obj.class == OSM::Node
name = "node"
attributes[:lat] = obj.position.size == 2 ? obj.position[1].to_f : 0
attributes[:lon] = obj.position.size == 2 ? obj.position[0].to_f : 0
elsif obj.class == OSM::Way
name = "way"
child_name = "nd"
children = obj.nodes.map {|id| {:ref => id}}
elsif obj.class == OSM::Relation
name = "relation"
child_name = "member"
children = obj.members.map {|member| {
:type => (if member.type == OSM::Node then "node"
elsif member.type == OSM::Way then "way"
else "relation" end),
:ref => member.ref,
:role => member.role}}
end
out << ' '*indent << '<' << name
attributes.each {|k, v| out << " #{k}=\"#{v}\""}
if tags.empty? and children.empty? then
out << "/>\n"
return
end
out << ">\n"
if not tags.empty?
tags.each do |k, v|
t = XML::Node.new 'tag'
t['k'] = k
t['v'] = v
out << ' '*(indent+1) << t.to_s << "\n"
end
end
if not children.empty?
children.each do |attribs|
c = XML::Node.new child_name
attribs.each {|k,v| c[k.to_s] = v.to_s}
out << ' '*(indent+1) << c.to_s << "\n"
end
end
out << ' '*indent << '</' << name << ">\n"
end
end