rails_port_0.5: Merge rails_port r4643
authorGabriel Ebner <gabriel@svn.openstreetmap.org>
Sat, 22 Sep 2007 19:55:33 +0000 (19:55 +0000)
committerGabriel Ebner <gabriel@svn.openstreetmap.org>
Sat, 22 Sep 2007 19:55:33 +0000 (19:55 +0000)
13 files changed:
app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/controllers/application.rb
app/controllers/node_controller.rb
app/controllers/old_node_controller.rb
app/controllers/old_way_controller.rb
app/controllers/swf_controller.rb
app/controllers/way_controller.rb
app/models/node.rb
app/models/old_node.rb
app/views/layouts/site.rhtml
app/views/site/edit.rhtml
config/environment.rb

index 99c2a48cdb6254208352c637fcc4e6def6360287..8132b5311b5d412d631517b20457d5388f94a699 100644 (file)
@@ -2,7 +2,7 @@ class AmfController < ApplicationController
   require 'stringio'
 
   session :off
-  before_filter :check_availability
+  before_filter :check_write_availability
 
   # to log:
   # RAILS_DEFAULT_LOGGER.error("Args: #{args[0]}, #{args[1]}, #{args[2]}, #{args[3]}")
@@ -215,34 +215,32 @@ EOF
     ymin = args[1].to_f-0.01
     xmax = args[2].to_f+0.01
     ymax = args[3].to_f+0.01
-       baselong    = args[4]
-       basey       = args[5]
-       masterscale = args[6]
+    baselong    = args[4]
+    basey       = args[5]
+    masterscale = args[6]
 
     RAILS_DEFAULT_LOGGER.info("  Message: whichways, bbox=#{xmin},#{ymin},#{xmax},#{ymax}")
 
-    waylist=WayNode.find_by_sql("SELECT DISTINCT current_way_nodes.id AS wayid"+
-       "  FROM current_way_nodes,current_segments,current_nodes,current_ways "+
+    waylist = WaySegment.find_by_sql("SELECT DISTINCT current_way_segments.id AS wayid"+
+       "  FROM current_way_segments,current_segments,current_nodes,current_ways "+
        " WHERE segment_id=current_segments.id "+
        "   AND current_segments.visible=1 "+
        "   AND node_a=current_nodes.id "+
-          "   AND current_ways.id=current_way_nodes.id "+
-          "   AND current_ways.visible=1 "+
-       "   AND (latitude  BETWEEN "+ymin.to_s+" AND "+ymax.to_s+") "+
-       "   AND (longitude BETWEEN "+xmin.to_s+" AND "+xmax.to_s+")")
+       "   AND current_ways.id=current_way_segments.id "+
+       "   AND current_ways.visible=1 "+
+       "   AND "+OSM.sql_for_area(ymin, xmin, ymax, xmax, "current_nodes."))
 
-       ways = waylist.collect {|a| a.wayid.to_i } # get an array of way id's
+    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,latitude,longitude,current_nodes.tags "+
+    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_segments cs1 ON cs1.node_a=current_nodes.id "+
        "  LEFT OUTER JOIN current_segments cs2 ON cs2.node_b=current_nodes.id "+
-       " WHERE (latitude  BETWEEN "+ymin.to_s+" AND "+ymax.to_s+") "+
-       "   AND (longitude BETWEEN "+xmin.to_s+" AND "+xmax.to_s+") "+
+       " WHERE "+OSM.sql_for_area(ymin, xmin, ymax, xmax, "current_nodes.")+
        "   AND cs1.id IS NULL AND cs2.id IS NULL "+
        "   AND current_nodes.visible=1")
 
-           points = pointlist.collect {|a| [a['id'],long2coord(a['longitude'].to_f,baselong,masterscale),lat2coord(a['latitude'].to_f,basey,masterscale),tag2array(a['tags'])] } # get a list of node ids and their tags
+    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
@@ -307,7 +305,7 @@ EOF
         id2=row['id2'].to_i; xc[id2]=row['long2'].to_f; yc[id2]=row['lat2'].to_f; tagc[id2]=row['tags2']
         seg[row['segment_id'].to_i]=id1.to_s+'-'+id2.to_s
       }
-         ActiveRecord::Base.connection.update("UPDATE current_ways SET timestamp=#{db_now},user_id=#{uid},visible=1 WHERE id=#{way}")
+      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
@@ -330,31 +328,33 @@ EOF
       ymin=[ys,ymin].min; ymax=[ys,ymax].max
       node=points[i][2].to_i
       tagstr=array2tag(points[i][4])
-         tagstr=tagstr.gsub(/[\000-\037]/,"")
+      tagstr=tagstr.gsub(/[\000-\037]/,"")
       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) VALUES (           #{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
-                                       ActiveRecord::Base.connection.insert("INSERT INTO nodes         (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{newnode},#{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
-                       points[i][2]=newnode
-                       renumberednodes[node.to_s]=newnode.to_s
-               else
-                       points[i][2]=renumberednodes[node.to_s].to_i
-               end
+       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
+          renumberednodes[node.to_s]=newnode.to_s
+       else
+          points[i][2]=renumberednodes[node.to_s].to_i
+       end
 
       elsif xc.has_key?(node)
         # old node from original way - update
-        if (xs!=xc[node] or (ys/0.0000001).round!=(yc[node]/0.0000001).round or tagstr!=tagc[node])
-          ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{node},#{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
-          ActiveRecord::Base.connection.update("UPDATE current_nodes SET latitude=#{ys},longitude=#{xs},timestamp=#{db_now},user_id=#{uid},tags=#{tagsql},visible=1 WHERE id=#{node}")
+        if (xs!=xc[node] or ys!=yc[node] or tagstr!=tagc[node])
+          ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES (#{node},#{lat},#{long},#{db_now},#{uid},1,#{tagsql},#{tile})")
+          ActiveRecord::Base.connection.update("UPDATE current_nodes SET latitude=#{lat},longitude=#{long},timestamp=#{db_now},user_id=#{uid},tags=#{tagsql},visible=1,tile=#{tile} WHERE id=#{node}")
         end
       else
         # old node, created in another way and now added to this way
       end
-
     end
 
 
@@ -368,19 +368,19 @@ EOF
       from =points[i  ][2].to_i
       to   =points[i+1][2].to_i
       if seg.has_key?(segid)
-               # if segment exists, check it still refers to the same nodes
+       # if segment exists, check it still refers to the same nodes
         if seg[segid]=="#{from}-#{to}" then 
           if (seglist!='') then seglist+=',' end; seglist+=segid.to_s
           next
         end
-         elsif segid>0
-               # not in previous version of way, but supplied, so assume
-               # that it's come from makeway (i.e. unwayed segments)
-               if (seglist!='') then seglist+=',' end; seglist+=segid.to_s
-               next
+      elsif segid>0
+        # not in previous version of way, but supplied, so assume
+        # that it's come from makeway (i.e. unwayed segments)
+        if (seglist!='') then seglist+=',' end; seglist+=segid.to_s
+        next
       end
       segid=ActiveRecord::Base.connection.insert("INSERT INTO current_segments (   node_a,node_b,timestamp,user_id,visible,tags) VALUES (         #{from},#{to},#{db_now},#{uid},1,'')")
-               ActiveRecord::Base.connection.insert("INSERT INTO segments         (id,node_a,node_b,timestamp,user_id,visible,tags) VALUES (#{segid},#{from},#{to},#{db_now},#{uid},1,'')")
+            ActiveRecord::Base.connection.insert("INSERT INTO segments         (id,node_a,node_b,timestamp,user_id,visible,tags) VALUES (#{segid},#{from},#{to},#{db_now},#{uid},1,'')")
       points[i+1][5]=segid
       numberedsegments[(i+1).to_s]=segid.to_s
     end
@@ -412,10 +412,10 @@ EOF
     createuniquenodes(db_uqs,db_uqn)   # nodes which appear in this way but no other
 
     sql=<<-EOF
-               INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible)  
-               SELECT DISTINCT cn.id,cn.latitude,cn.longitude,#{db_now},#{uid},0 
-                 FROM current_nodes AS cn,#{db_uqn}
-                WHERE cn.id=node_id
+       INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tile)  
+       SELECT DISTINCT cn.id,cn.latitude,cn.longitude,#{db_now},#{uid},0,cn.tile
+         FROM current_nodes AS cn,#{db_uqn}
+        WHERE cn.id=node_id
     EOF
     ActiveRecord::Base.connection.insert(sql)
 
@@ -429,7 +429,7 @@ EOF
     ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqs}")
     ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqn}")
 
-    #          insert new version of route into way_nodes
+    #          insert new version of route into way_segments
 
     insertsql =''
     currentsql=''
@@ -443,9 +443,9 @@ EOF
       sequence  +=1
     end
 
-    ActiveRecord::Base.connection.execute("DELETE FROM current_way_nodes WHERE id=#{way}");
-    ActiveRecord::Base.connection.insert("INSERT INTO         way_nodes (id,segment_id,version    ) VALUES #{insertsql}");
-    ActiveRecord::Base.connection.insert("INSERT INTO current_way_nodes (id,segment_id,sequence_id) VALUES #{currentsql}");
+    ActiveRecord::Base.connection.execute("DELETE FROM current_way_segments WHERE id=#{way}");
+    ActiveRecord::Base.connection.insert("INSERT INTO         way_segments (id,segment_id,version    ) VALUES #{insertsql}");
+    ActiveRecord::Base.connection.insert("INSERT INTO current_way_segments (id,segment_id,sequence_id) VALUES #{currentsql}");
 
     # -- 7. insert new way tags
 
@@ -475,27 +475,30 @@ EOF
   #                    if old: add new row to nodes, update current_nodes
 
   def putpoi(args)
-       usertoken,id,x,y,tags,visible,baselong,basey,masterscale=args
-       uid=getuserid(usertoken)
-       return if !uid
+    usertoken,id,x,y,tags,visible,baselong,basey,masterscale=args
+    uid=getuserid(usertoken)
+    return if !uid
     db_now='@now'+uid.to_s+id.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()")
 
-       id=id.to_i
-       visible=visible.to_i
-       x=coord2long(x.to_f,masterscale,baselong)
-       y=coord2lat(y.to_f,masterscale,basey)
-       tagsql="'"+sqlescape(array2tag(tags))+"'"
+    id=id.to_i
+    visible=visible.to_i
+    x=coord2long(x.to_f,masterscale,baselong)
+    y=coord2lat(y.to_f,masterscale,basey)
+    tagsql="'"+sqlescape(array2tag(tags))+"'"
+    lat=(y * 10000000).round
+    long=(x * 10000000).round
+    tile=QuadTile.tile_for_point(y, x)
        
-       if (id>0) then
-               ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{id},#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
-               ActiveRecord::Base.connection.update("UPDATE current_nodes SET latitude=#{y},longitude=#{x},timestamp=#{db_now},user_id=#{uid},visible=#{visible},tags=#{tagsql} WHERE id=#{id}");
-               newid=id
-       else
-               newid=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes (latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
-                         ActiveRecord::Base.connection.update("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{newid},#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
-       end
-       [id,newid]
+    if (id>0) then
+        ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES (#{id},#{lat},#{long},#{db_now},#{uid},#{visible},#{tagsql},#{tile})");
+        ActiveRecord::Base.connection.update("UPDATE current_nodes SET latitude=#{lat},longitude=#{long},timestamp=#{db_now},user_id=#{uid},visible=#{visible},tags=#{tagsql},tile=#{tile} WHERE id=#{id}");
+        newid=id
+    else
+        newid=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes (latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES (#{lat},#{long},#{db_now},#{uid},#{visible},#{tagsql},#{tile})");
+              ActiveRecord::Base.connection.update("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags,tile) VALUES (#{newid},#{lat},#{long},#{db_now},#{uid},#{visible},#{tagsql},#{tile})");
+    end
+    [id,newid]
   end
 
   # -----      getpoi (id,baselong,basey,masterscale)
@@ -503,12 +506,12 @@ EOF
   
   def getpoi(args)
        id,baselong,basey,masterscale=args; id=id.to_i
-       poi=ActiveRecord::Base.connection.select_one("SELECT latitude,longitude,tags "+
+       poi=ActiveRecord::Base.connection.select_one("SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lng,tags "+
                "FROM current_nodes WHERE visible=1 AND id=#{id}")
        if poi.nil? then return [nil,nil,nil,''] end
        [id,
-        long2coord(poi['longitude'].to_f,baselong,masterscale),
-        lat2coord(poi['latitude'].to_f,basey,masterscale),
+        long2coord(poi['lng'].to_f,baselong,masterscale),
+        lat2coord(poi['lat'].to_f,basey,masterscale),
         tag2array(poi['tags'])]
   end
 
@@ -521,61 +524,61 @@ EOF
     RAILS_DEFAULT_LOGGER.info("  Message: deleteway, id=#{way}")
 
     uid=getuserid(usertoken); if !uid then return end
-       way=way.to_i
+    way=way.to_i
 
-       db_uqs='uniq'+uid.to_s+way.to_i.abs.to_s+Time.new.to_i.to_s     # temp uniquesegments table name, typically 51 chars
-       db_uqn='unin'+uid.to_s+way.to_i.abs.to_s+Time.new.to_i.to_s     # temp uniquenodes table name, typically 51 chars
-       db_now='@now'+uid.to_s+way.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()")
-       createuniquesegments(way,db_uqs,'')
+    db_uqs='uniq'+uid.to_s+way.to_i.abs.to_s+Time.new.to_i.to_s        # temp uniquesegments table name, typically 51 chars
+    db_uqn='unin'+uid.to_s+way.to_i.abs.to_s+Time.new.to_i.to_s        # temp uniquenodes table name, typically 51 chars
+    db_now='@now'+uid.to_s+way.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()")
+    createuniquesegments(way,db_uqs,'')
 
-       # -     delete any otherwise unused segments
+    # -        delete any otherwise unused segments
 
-       sql=<<-EOF
+    sql=<<-EOF
       INSERT INTO segments (id,node_a,node_b,timestamp,user_id,visible) 
       SELECT DISTINCT segment_id,node_a,node_b,#{db_now},#{uid},0 
         FROM current_segments AS cs, #{db_uqs} AS us
        WHERE cs.id=us.segment_id
     EOF
-       ActiveRecord::Base.connection.insert(sql)
+    ActiveRecord::Base.connection.insert(sql)
 
-       sql=<<-EOF
+    sql=<<-EOF
       UPDATE current_segments AS cs, #{db_uqs} AS us
          SET cs.timestamp=#{db_now},cs.visible=0,cs.user_id=#{uid} 
        WHERE cs.id=us.segment_id
     EOF
-       ActiveRecord::Base.connection.update(sql)
+    ActiveRecord::Base.connection.update(sql)
 
-       # - delete any unused nodes
+    # - delete any unused nodes
   
     createuniquenodes(db_uqs,db_uqn)
 
-       sql=<<-EOF
-               INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible)  
-               SELECT DISTINCT cn.id,cn.latitude,cn.longitude,#{db_now},#{uid},0 
-                 FROM current_nodes AS cn,#{db_uqn}
-                WHERE cn.id=node_id
+    sql=<<-EOF
+       INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tile)
+       SELECT DISTINCT cn.id,cn.latitude,cn.longitude,#{db_now},#{uid},0,cn.tile
+         FROM current_nodes AS cn,#{db_uqn}
+        WHERE cn.id=node_id
     EOF
-       ActiveRecord::Base.connection.insert(sql)
+    ActiveRecord::Base.connection.insert(sql)
 
-       sql=<<-EOF
+    sql=<<-EOF
       UPDATE current_nodes AS cn, #{db_uqn}
          SET cn.timestamp=#{db_now},cn.visible=0,cn.user_id=#{uid} 
        WHERE cn.id=node_id
     EOF
-       ActiveRecord::Base.connection.update(sql)
+    ActiveRecord::Base.connection.update(sql)
        
-       ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqs}")
-       ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqn}")
+    ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqs}")
+    ActiveRecord::Base.connection.execute("DROP TABLE #{db_uqn}")
 
-       # - delete way
+    # - delete way
        
-       ActiveRecord::Base.connection.insert("INSERT INTO ways (id,user_id,timestamp,visible) VALUES (#{way},#{uid},#{db_now},0)")
-       ActiveRecord::Base.connection.update("UPDATE current_ways SET user_id=#{uid},timestamp=#{db_now},visible=0 WHERE id=#{way}")
-       ActiveRecord::Base.connection.execute("DELETE FROM current_way_nodes WHERE id=#{way}")
-       ActiveRecord::Base.connection.execute("DELETE FROM current_way_tags WHERE id=#{way}")
+    ActiveRecord::Base.connection.insert("INSERT INTO ways (id,user_id,timestamp,visible) VALUES (#{way},#{uid},#{db_now},0)")
+    ActiveRecord::Base.connection.update("UPDATE current_ways SET user_id=#{uid},timestamp=#{db_now},visible=0 WHERE id=#{way}")
+    ActiveRecord::Base.connection.execute("DELETE FROM current_way_segments WHERE id=#{way}")
+    ActiveRecord::Base.connection.execute("DELETE FROM current_way_tags WHERE id=#{way}")
        
-       way
+    way
 end
 
 # ----- makeway(x,y,baselong,basey,masterscale)
@@ -601,14 +604,13 @@ def makeway(args)
        ys1=yc-0.001; ys2=yc+0.001
        
        sql=<<-EOF
-               SELECT cn1.latitude AS lat1,cn1.longitude AS lon1,cn1.id AS id1,
-                      cn2.latitude AS lat2,cn2.longitude AS lon2,cn2.id AS id2, cs.id AS segid
+               SELECT cn1.latitude*0.0000001 AS lat1,cn1.longitude*0.0000001 AS lon1,cn1.id AS id1,
+                      cn2.latitude*0.0000001 AS lat2,cn2.longitude*0.0000001 AS lon2,cn2.id AS id2, cs.id AS segid
                  FROM current_nodes AS cn1,
                       current_nodes AS cn2,
                       current_segments AS cs 
-                      LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id 
-                WHERE (cn1.longitude BETWEEN #{xs1} AND #{xs2}) 
-                  AND (cn1.latitude  BETWEEN #{ys1} AND #{ys2}) 
+                      LEFT OUTER JOIN current_way_segments ON segment_id=cs.id 
+                WHERE #{OSM.sql_for_area(ys1,xs1,ys2,xs2,"cn1.")}
                   AND segment_id IS NULL 
                    AND cs.visible=1
                   AND cn1.id=node_a AND cn1.visible=1 
@@ -667,24 +669,24 @@ def findconnect(id,nodesused,lookfor,toreverse,baselong,basey,masterscale)
        # get all segments with 'id' as a point
        # (to look for both node_a and node_b, UNION is faster than node_a=id OR node_b=id)!
        sql=<<-EOF
-               SELECT cn1.latitude AS lat1,cn1.longitude AS lon1,cn1.id AS id1,
-                      cn2.latitude AS lat2,cn2.longitude AS lon2,cn2.id AS id2, cs.id AS segid
+               SELECT cn1.latitude*0.0000001 AS lat1,cn1.longitude*0.0000001 AS lon1,cn1.id AS id1,
+                      cn2.latitude*0.0000001 AS lat2,cn2.longitude*0.0000001 AS lon2,cn2.id AS id2, cs.id AS segid
                  FROM current_nodes AS cn1,
                       current_nodes AS cn2,
                       current_segments AS cs 
-                      LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id 
+                      LEFT OUTER JOIN current_way_segments ON segment_id=cs.id 
                 WHERE segment_id IS NULL 
                    AND cs.visible=1
                   AND cn1.id=node_a AND cn1.visible=1 
                   AND cn2.id=node_b AND cn2.visible=1 
                   AND node_a=#{id}
        UNION
-               SELECT cn1.latitude AS lat1,cn1.longitude AS lon1,cn1.id AS id1,
-                      cn2.latitude AS lat2,cn2.longitude AS lon2,cn2.id AS id2, cs.id AS segid
+               SELECT cn1.latitude*0.0000001 AS lat1,cn1.longitude*0.0000001 AS lon1,cn1.id AS id1,
+                      cn2.latitude*0.0000001 AS lat2,cn2.longitude*0.0000001 AS lon2,cn2.id AS id2, cs.id AS segid
                  FROM current_nodes AS cn1,
                       current_nodes AS cn2,
                       current_segments AS cs 
-                      LEFT OUTER JOIN current_way_nodes ON segment_id=cs.id 
+                      LEFT OUTER JOIN current_way_segments ON segment_id=cs.id 
                 WHERE segment_id IS NULL 
                    AND cs.visible=1
                   AND cn1.id=node_a AND cn1.visible=1 
@@ -730,13 +732,13 @@ end
 # Support functions for remote calls
 
 def readwayquery(id)
-  ActiveRecord::Base.connection.select_all "SELECT n1.latitude AS lat1,n1.longitude AS long1,n1.id AS id1,n1.tags as tags1, "+
-      "                  n2.latitude AS lat2,n2.longitude AS long2,n2.id AS id2,n2.tags as tags2,segment_id "+
-      "    FROM current_way_nodes,current_segments,current_nodes AS n1,current_nodes AS n2 "+
-      "   WHERE current_way_nodes.id=#{id} "+
+  ActiveRecord::Base.connection.select_all "SELECT n1.latitude*0.0000001 AS lat1,n1.longitude*0.0000001 AS long1,n1.id AS id1,n1.tags as tags1, "+
+      "                  n2.latitude*0.0000001 AS lat2,n2.longitude*0.0000001 AS long2,n2.id AS id2,n2.tags as tags2,segment_id "+
+      "    FROM current_way_segments,current_segments,current_nodes AS n1,current_nodes AS n2 "+
+      "   WHERE current_way_segments.id=#{id} "+
       "     AND segment_id=current_segments.id "+
-         "     AND current_segments.visible=1 "+
-      "     AND n1.id=node_a and n2.id=node_b "+
+      "     AND current_segments.visible=1 "+
+      "     AND n1.id=node_a AND n2.id=node_b "+
       "     AND n1.visible=1 AND n2.visible=1 "+
       "   ORDER BY sequence_id"
 end
@@ -746,9 +748,9 @@ def createuniquesegments(way,uqs_name,seglist)
   sql=<<-EOF
       CREATE TEMPORARY TABLE #{uqs_name}
               SELECT a.segment_id
-                FROM (SELECT DISTINCT segment_id FROM current_way_node
+                FROM (SELECT DISTINCT segment_id FROM current_way_segment
                   WHERE id = #{way}) a
-             LEFT JOIN current_way_nodes b 
+             LEFT JOIN current_way_segments b 
                 ON b.segment_id = a.segment_id
                  AND b.id != #{way}
                WHERE b.segment_id IS NULL
index 6e8e77c2f13de432aa3937d37b773ddaa79c2321..2e693042e98a70c4e1efd04d85d751c964526796 100644 (file)
@@ -1,6 +1,7 @@
 class ApiController < ApplicationController
 
   session :off
+  before_filter :check_read_availability, :except => [:capabilities]
   after_filter :compress_output
 
   #COUNT is the number of map requests to allow before exiting and starting a new process
@@ -137,7 +138,7 @@ class ApiController < ApplicationController
     end
 
     # get all the nodes
-    nodes = Node.find(:all, :conditions => ['latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ? AND visible = 1', min_lat, max_lat, min_lon, max_lon])
+    nodes = Node.find_by_area(min_lat, min_lon, max_lat, max_lon, :conditions => "visible = 1")
 
     node_ids = nodes.collect {|node| node.id }
 
index d22ed5c9f5d17154815873d93c238def19e6fbd5..acb2f916291ab02aced0486022b4688c2b109677 100644 (file)
@@ -39,8 +39,16 @@ class ApplicationController < ActionController::Base
     end 
   end 
 
-  def check_availability
-    if API_READONLY
+  def check_read_availability
+    if API_STATUS == :offline
+      response.headers['Error'] = "Database offline for maintenance"
+      render :nothing => true, :status => :service_unavailable
+      return false
+    end
+  end
+
+  def check_write_availability
+    if API_STATUS == :offline or API_STATUS == :readonly
       response.headers['Error'] = "Database offline for maintenance"
       render :nothing => true, :status => :service_unavailable
       return false
index 7c7e3e6e4f85cf78ef6f915c5e97fcef287d46a2..62987cf9433b35d0d8b8c3b770615e6758465cbc 100644 (file)
@@ -3,7 +3,8 @@ class NodeController < ApplicationController
 
   session :off
   before_filter :authorize, :only => [:create, :update, :delete]
-  before_filter :check_availability, :only => [:create, :update, :delete]
+  before_filter :check_write_availability, :only => [:create, :update, :delete]
+  before_filter :check_read_availability, :except => [:create, :update, :delete]
   after_filter :compress_output
 
   def create
index 0337cb2cffcec604e26f7090eff565234680c998..e27898336361832ed193c9d1b3c8de04ddb14a41 100644 (file)
@@ -2,6 +2,7 @@ class OldNodeController < ApplicationController
   require 'xml/libxml'
 
   session :off
+  before_filter :check_read_availability
   after_filter :compress_output
 
   def history
index f10e0d2f0193e0550932e0d15396369fa2939f52..e72c97a0078022650a8484d08c070b7d67fed6c7 100644 (file)
@@ -2,6 +2,7 @@ class OldWayController < ApplicationController
   require 'xml/libxml'
 
   session :off
+  before_filter :check_read_availability
   after_filter :compress_output
 
   def history
index 6b29d1535e8878608c25930c22f0da719896b026..40969c20fc5984f01aed60969e23c582353f10cf 100644 (file)
@@ -1,6 +1,6 @@
 class SwfController < ApplicationController
        session :off
-       before_filter :check_availability
+       before_filter :check_read_availability
 
 # to log:
 # RAILS_DEFAULT_LOGGER.error("Args: #{args[0]}, #{args[1]}, #{args[2]}, #{args[3]}")
@@ -89,14 +89,13 @@ class SwfController < ApplicationController
                # - Draw unwayed segments
                
                if params['unwayed']=='true'
-                       sql="SELECT cn1.latitude AS lat1,cn1.longitude AS lon1,"+
-                               "               cn2.latitude AS lat2,cn2.longitude AS lon2 "+
+                       sql="SELECT cn1.latitude*0.0000001 AS lat1,cn1.longitude*0.0000001 AS lon1,"+
+                               "               cn2.latitude*0.0000001 AS lat2,cn2.longitude*0.0000001 AS lon2 "+
                                "  FROM current_segments "+
                                "       LEFT OUTER JOIN current_way_nodes"+
                                "       ON segment_id=current_segments.id,"+
                                "       current_nodes AS cn1,current_nodes AS cn2"+
-                               " WHERE (cn1.longitude BETWEEN #{xmin} AND #{xmax})"+
-                               "   AND (cn1.latitude  BETWEEN #{ymin} AND #{ymax})"+
+                               " WHERE "+OSM.sql_for_area(ymin,xmin,ymax,xmax,"cn1.")+
                                "   AND segment_id IS NULL"+
                                "   AND current_segments.visible=1"+
                                "   AND cn1.id=node_a AND cn1.visible=1"+
index 2e0623df4d7e120e2297784c19ea2c952be6d02f..7b7dbe81cad4a2d491102ac1d4cc90a890368594 100644 (file)
@@ -3,7 +3,8 @@ class WayController < ApplicationController
 
   session :off
   before_filter :authorize, :only => [:create, :update, :delete]
-  before_filter :check_availability, :only => [:create, :update, :delete]
+  before_filter :check_write_availability, :only => [:create, :update, :delete]
+  before_filter :check_read_availability, :except => [:create, :update, :delete]
   after_filter :compress_output
 
   def create
index 7e78aaf592acfab37a89a9c20bbc084ea3b28ef5..f9210bf0664a88a296a8c41e200d88fb9e8652a2 100644 (file)
@@ -9,14 +9,42 @@ class Node < ActiveRecord::Base
 
   has_many :old_nodes, :foreign_key => :id
   belongs_to :user
+  before_save :update_tile
+
+  def self.find_by_area(minlat, minlon, maxlat, maxlon, options)
+    self.with_scope(:find => {:conditions => OSM.sql_for_area(minlat, minlon, maxlat, maxlon)}) do
+      return self.find(:all, options)
+    end
+  end
+
+  def update_tile
+    self.tile = QuadTile.tile_for_point(lat, lon)
+  end
+
+  def lat=(l)
+    self.latitude = (l * 10000000).round
+  end
+
+  def lon=(l)
+    self.longitude = (l * 10000000).round
+  end
+
+  def lat
+    return self.latitude.to_f / 10000000
+  end
+
+  def lon
+    return self.longitude.to_f / 10000000
+  end
 
   def validate_position
     errors.add_to_base("Node is not in the world") unless in_world?
   end
 
   def in_world?
-    return false if self.latitude < -90 or self.latitude > 90
-    return false if self.longitude < -180 or self.longitude > 180
+    return false if self.lat < -90 or self.lat > 90
+    return false if self.lon < -180 or self.lon > 180
     return true
   end
 
@@ -29,8 +57,8 @@ class Node < ActiveRecord::Base
       node = Node.new
 
       doc.find('//osm/node').each do |pt|
-        node.latitude = pt['lat'].to_f
-        node.longitude = pt['lon'].to_f
+        node.lat = pt['lat'].to_f
+        node.lon = pt['lon'].to_f
 
         return nil unless node.in_world?
 
@@ -86,8 +114,8 @@ class Node < ActiveRecord::Base
   def to_xml_node(user_display_name_cache = nil)
     el1 = XML::Node.new 'node'
     el1['id'] = self.id.to_s
-    el1['lat'] = self.latitude.to_s
-    el1['lon'] = self.longitude.to_s
+    el1['lat'] = self.lat.to_s
+    el1['lon'] = self.lon.to_s
 
     user_display_name_cache = {} if user_display_name_cache.nil?
 
index d7a52c33617aaaedeaa4a0b1387555a8a701ac1c..c63738fc48e3b8e4a89c8fbf5c425a6905d67b32 100644 (file)
@@ -7,14 +7,42 @@ class OldNode < ActiveRecord::Base
   validate :validate_position
 
   belongs_to :user
+  before_save :update_tile
+
+  def self.find_by_area(minlat, minlon, maxlat, maxlon, options)
+    self.with_scope(:find => {:conditions => OSM.sql_for_area(minlat, minlon, maxlat, maxlon)}) do
+      return self.find(:all, options)
+    end
+  end
+
+  def update_tile
+    self.tile = QuadTile.tile_for_point(lat, lon)
+  end
+
+  def lat=(l)
+    self.latitude = (l * 10000000).round
+  end
+
+  def lon=(l)
+    self.longitude = (l * 10000000).round
+  end
+
+  def lat
+    return self.latitude.to_f / 10000000
+  end
+
+  def lon
+    return self.longitude.to_f / 10000000
+  end
 
   def validate_position
     errors.add_to_base("Node is not in the world") unless in_world?
   end
 
   def in_world?
-    return false if self.latitude < -90 or self.latitude > 90
-    return false if self.longitude < -180 or self.longitude > 180
+    return false if self.lat < -90 or self.lat > 90
+    return false if self.lon < -180 or self.lon > 180
     return true
   end
 
@@ -33,8 +61,8 @@ class OldNode < ActiveRecord::Base
   def to_xml_node
     el1 = XML::Node.new 'node'
     el1['id'] = self.id.to_s
-    el1['lat'] = self.latitude.to_s
-    el1['lon'] = self.longitude.to_s
+    el1['lat'] = self.lat.to_s
+    el1['lon'] = self.lon.to_s
     el1['user'] = self.user.display_name if self.user.data_public?
     Node.split_tags(el1, self.tags)
     el1['visible'] = self.visible.to_s
index 3c84dc47f0de2f64452d00b0f74c9e5497aab00c..f3cdc97873b41628185289a75e65a223fcae2354 100644 (file)
       </div>
       <% end %>
 
-      <% if API_READONLY %>
+      <% if API_STATUS == :offline %>
+      <div id="alert">
+        The OpenStreetMap database is currently offline while
+        essential database maintenance work is carried out.
+      </div>
+      <% elsif API_STATUS == :readonly %>
       <div id="alert">
         The OpenStreetMap database is currently in read-only mode while
         essential database maintenance work is carried out.
index b1c5555866a69b957cb9a39b224833911600ccfb..6b5952f3856d32ca3a93294b0d85535e6d5c5843 100644 (file)
@@ -1,4 +1,8 @@
-<% if API_READONLY %>
+<% if API_STATUS == :offline %>
+<p>The OpenStreetMap database is currently offline while
+   essential database maintenance work is carried out.
+</p>
+<% elsif API_STATUS == :readonly %>
 <p>The OpenStreetMap database is currently in read-only mode while
    essential database maintenance work is carried out.
 </p>
index 3820ed29406f69a1b84808af0ef0dfa9c6e5244a..0d98c70bdd409fa07346ef78c793c37584fdea79 100644 (file)
@@ -77,8 +77,9 @@ end
 #   inflect.uncountable %w( fish sheep )
 # end
 
-# Set to true to put the API in read-only mode
-API_READONLY = false
+# Set to :readonly to put the API in read-only mode or :offline to
+# take it completely offline
+API_STATUS = :online
 
 # Include your application configuration below
 SERVER_URL = ENV['OSM_SERVER_URL'] || 'www.openstreetmap.org'