+ ways = waylist.collect {|a| a['wayid'].to_i } # get an array of way id's
+
+ pointlist = ActiveRecord::Base.connection.select_all("SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lng,current_nodes.tags "+
+ " FROM current_nodes "+
+ " LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id "+
+ " WHERE "+OSM.sql_for_area(ymin, xmin, ymax, xmax, "current_nodes.")+
+ " AND cwn.id IS NULL "+
+ " AND current_nodes.visible=1")
+
+ points = pointlist.collect {|a| [a['id'],long2coord(a['lng'].to_f,baselong,masterscale),lat2coord(a['lat'].to_f,basey,masterscale),tag2array(a['tags'])] } # get a list of node ids and their tags
+
+ return [ways,points]
+ end
+
+ # ----- getway (objectname, way, baselong, basey, masterscale)
+ # returns objectname, array of co-ordinates, attributes,
+ # xmin,xmax,ymin,ymax
+
+ def getway(args)
+ objname,wayid,baselong,basey,masterscale=args
+ wayid = wayid.to_i
+ points = []
+ lastid = -1
+ xmin = ymin = 999999
+ xmax = ymax = -999999
+
+ RAILS_DEFAULT_LOGGER.info(" Message: getway, id=#{wayid}")
+
+ readwayquery(wayid).each {|row|
+ points<<[long2coord(row['longitude'].to_f,baselong,masterscale),lat2coord(row['latitude'].to_f,basey,masterscale),row['id'].to_i,nil,tag2array(row['tags'])]
+ xmin = [xmin,row['longitude'].to_f].min
+ xmax = [xmax,row['longitude'].to_f].max
+ ymin = [ymin,row['latitude'].to_f].min
+ ymax = [ymax,row['latitude'].to_f].max
+ }
+
+ attributes={}
+ attrlist=ActiveRecord::Base.connection.select_all "SELECT k,v FROM current_way_tags WHERE id=#{wayid}"
+ attrlist.each {|a| attributes[a['k'].gsub(':','|')]=a['v'] }
+
+ [objname,points,attributes,xmin,xmax,ymin,ymax]
+ end
+
+ # ----- putway (user token, way, array of co-ordinates, array of attributes,
+ # baselong, basey, masterscale)
+ # returns current way ID, new way ID, hash of renumbered nodes,
+ # xmin,xmax,ymin,ymax
+
+ def putway(args)
+ RAILS_DEFAULT_LOGGER.info(" putway started")
+ usertoken,originalway,points,attributes,baselong,basey,masterscale=args
+ uid=getuserid(usertoken)
+ return if !uid
+ RAILS_DEFAULT_LOGGER.info(" putway authenticated happily")
+ db_uqn='unin'+uid.to_s+originalway.to_i.abs.to_s+Time.new.to_i.to_s # temp uniquenodes table name, typically 51 chars
+ db_now='@now'+uid.to_s+originalway.to_i.abs.to_s+Time.new.to_i.to_s # 'now' variable name, typically 51 chars
+ ActiveRecord::Base.connection.execute("SET #{db_now}=NOW()")
+ originalway=originalway.to_i
+
+ RAILS_DEFAULT_LOGGER.info(" Message: putway, id=#{originalway}")
+
+ # -- 3. read original way into memory
+
+ xc={}; yc={}; tagc={}
+ if originalway>0
+ way=originalway
+ readwayquery(way).each { |row|
+ id=row['id'].to_i
+ xc[id]=row['longitude'].to_f
+ yc[id]=row['latitude' ].to_f
+ tagc[id]=row['tags']
+ }
+ ActiveRecord::Base.connection.update("UPDATE current_ways SET timestamp=#{db_now},user_id=#{uid},visible=1 WHERE id=#{way}")
+ else
+ way=ActiveRecord::Base.connection.insert("INSERT INTO current_ways (user_id,timestamp,visible) VALUES (#{uid},#{db_now},1)")
+ end
+
+ # -- 4. get version by inserting new row into ways
+
+ version=ActiveRecord::Base.connection.insert("INSERT INTO ways (id,user_id,timestamp,visible) VALUES (#{way},#{uid},#{db_now},1)")
+
+ # -- 5. compare nodes and update xmin,xmax,ymin,ymax
+
+ xmin=ymin= 999999
+ xmax=ymax=-999999
+ insertsql=''
+ renumberednodes={}
+ nodelist=[]
+
+ points.each_index do |i|
+ xs=coord2long(points[i][0],masterscale,baselong)
+ ys=coord2lat(points[i][1],masterscale,basey)
+ xmin=[xs,xmin].min; xmax=[xs,xmax].max
+ ymin=[ys,ymin].min; ymax=[ys,ymax].max
+ node=points[i][2].to_i
+ tagstr=array2tag(points[i][4])
+ tagsql="'"+sqlescape(tagstr)+"'"
+ lat=(ys * 10000000).round
+ long=(xs * 10000000).round
+ tile=QuadTile.tile_for_point(ys, xs)
+
+ # compare node
+ if node<0
+ # new node - create
+ if renumberednodes[node.to_s].nil?
+ newnode=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes ( latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES ( #{lat},#{long},#{db_now},#{uid},1,#{tagsql},#{tile})")
+ ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES (#{newnode},#{lat},#{long},#{db_now},#{uid},1,#{tagsql},#{tile})")
+ points[i][2]=newnode
+ nodelist.push(newnode)
+ renumberednodes[node.to_s]=newnode.to_s
+ else
+ points[i][2]=renumberednodes[node.to_s].to_i