source: subversion/ruby/api/dataset.rb @ 710

Revision 710, 3.5 KB checked in by nick, 8 years ago (diff)

added dataset.rb to API for uploading complete 0.2 XML documents

Line 
1#! /usr/bin/ruby -w
2
3# Parses a complete OSM 0.2 format XML document containing both nodes and
4# segments.
5# If the node IDs are negative, and corresponding negative node IDs are
6# present in the segments, it will be assumed that the user is uploading new
7# nodes and segments. New nodes will be created and segments will be formed
8# between the new nodes. Each new node will be reallocated a real, positive ID.
9# For example, if the file
10#
11# <osm version='0.2'>
12# <node lat='51' lon='-1' uid='-1'/>
13# <node lat='51.01' lon='-1.01' uid='-2'/>
14# <node lat='51.04' lon='-1.02' uid='-3'/>
15# <node lat='51.09' lon='-1.03' uid='-4'/>
16# <node lat='52' lon='0' uid='200000' />
17# <segment from='-1' to='-2'/>
18# <segment from='-2' to='-3'/>
19# <segment from='-3' to='-4'/>
20# </osm>
21#
22# is uploaded, four new nodes (the ones with supplied uid of -1 to -4) will
23# be created, one existing node (200000) will be updated, and three segments
24# will be formed between the four new nodes.
25# The real, positive node IDs allocated to the new nodes (with supplied
26# negative IDs) will be returned as standard output.
27
28require 'cgi'
29load 'osm/dao.rb'
30require 'rexml/document'
31
32include Apache
33include REXML
34
35r = Apache.request
36
37dao = OSM::Dao.instance
38
39if r.request_method == "PUT"
40        r.setup_cgi_env
41        userid = dao.useruidfromcreds(r.user,r.get_basic_auth_pw)
42        if userid > 0
43
44                id_conv_table = {}
45
46                # This will work if the XML is on separate lines.
47                # reading in from 'gets' won't.
48                doc = Document.new $stdin.read
49
50                # Go through each node tag...
51                doc.elements.each('osm/node') do |node|
52                        # Get the attributes
53                        lat = node.attributes['lat'].to_f
54                        lon = node.attributes['lon'].to_f
55                        nodeid = node.attributes['uid'].to_i
56                        tags = node.attributes['tags']
57
58                        tags = '' unless tags
59                        nodeid = 0 unless nodeid
60
61                        # If the supplied ID of the node is 0 or less, it's a new node so
62                        # act accordingly.
63                        if nodeid <= 0 
64                                new_node_uid = dao.create_node(lat,lon,userid,tags)
65                                if not new_node_uid
66                                        exit HTTP_INTERNAL_SERVER_ERROR
67                                end
68
69                                # Map the supplied nodeid to the allocated real nodeid
70                                # We'll use this later when doing segments
71                                if nodeid < 0 
72                                        id_conv_table[nodeid] = new_node_uid
73                                end
74                               
75                                # Write out the allocated real node ID
76                                puts new_node_uid
77                        else
78                                # If the nodeid is greater than 0, we want to do an update
79                                if not dao.update_node?(nodeid,userid,lat,lon,tags)
80                                        exit HTTP_INTERNAL_SERVER_ERROR
81                                end
82                        end
83                end
84
85                # Go through each segment tag...
86                doc.elements.each('osm/segment') do |segment|
87                        from = segment.attributes['from'].to_i
88                        to = segment.attributes['to'].to_i
89                        segid = segment.attributes['uid'].to_i
90                        tags = segment.attributes['tags']
91                        tags = '' unless tags
92                        segid = 0 unless segid
93
94                        # If the 'from' node is less than 0, it will relate to the negative
95                        # IDs supplied in the node list. So convert it to the corresponding
96                        # real node id.
97                        if from < 0
98                                from = id_conv_table[from]
99                        end
100
101                        # same with 'to'
102                        if to < 0 
103                                to = id_conv_table[to]
104                        end
105
106                        # If negative numbers which don't map to supplied nodes were given,
107                        # throw an Internal Server Error and exit.
108                        if from == nil or to == nil
109                                exit HTTP_INTERNAL_SERVER_ERROR
110                        end
111
112
113                        # Again either create or update segment depending on the segment ID
114                        if segid <= 0
115                                if not dao.create_segment(from,to,userid,tags)
116                                        exit HTTP_INTERNAL_SERVER_ERROR
117                                end
118                        else
119                                if not dao.update_segment?(segid,userid,from,to,tags)
120                                        exit HTTP_INTERNAL_SERVER_ERROR
121                                end
122                        end
123                end
124        else
125                exit AUTH_REQUIRED
126        end
127end
Note: See TracBrowser for help on using the repository browser.