]> git.openstreetmap.org Git - rails.git/blobdiff - app/controllers/api_controller.rb
Get pagination links right.
[rails.git] / app / controllers / api_controller.rb
index 44ae65285528636f028ff08d1eb1cb6402452fbe..a17e630c2c9657215132f65d068216c146a5e136 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
@@ -63,13 +64,8 @@ class ApiController < ApplicationController
       return
     end
 
-    # integerise
-    min_lat = min_lat * 1000000
-    max_lat = max_lat * 1000000
-    min_lon = min_lon * 1000000
-    max_lon = max_lon * 1000000
     # get all the points
-    points = Tracepoint.find(:all, :conditions => ['latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?', min_lat.to_i, max_lat.to_i, min_lon.to_i, max_lon.to_i], :select => "DISTINCT *", :offset => offset, :limit => TRACEPOINTS_PER_PAGE, :order => "timestamp DESC" )
+    points = Tracepoint.find_by_area(min_lat, min_lon, max_lat, max_lon, :offset => offset, :limit => TRACEPOINTS_PER_PAGE, :order => "timestamp DESC" )
 
     doc = XML::Document.new
     doc.encoding = 'UTF-8'
@@ -142,8 +138,7 @@ class ApiController < ApplicationController
     end
 
     # get all the nodes
-    nodes = Node.find(:all, :conditions => 
-        ['latitude > ? AND longitude > ? AND latitude < ? AND longitude < ? AND visible = 1', min_lat, min_lon, max_lat, 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 }
 
@@ -206,12 +201,17 @@ class ApiController < ApplicationController
     # collect relationships. currently done in one big block at the end;
     # may need to move this upwards if people want automatic completion of
     # relationships, i.e. deliver referenced objects like we do with ways...
-    relations = Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
-        "e.visible=1 and " +
-        "em.id = e.id and em.member_type='node' and em.member_id in (#{visible_nodes.keys.join(',')})")
-    relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
-        "e.visible=1 and " +
-        "em.id = e.id and em.member_type='way' and em.member_id in (#{way_ids.join(',')})")
+    relations = Array.new
+    if visible_nodes.length > 0
+        relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
+            "e.visible=1 and " +
+            "em.id = e.id and em.member_type='node' and em.member_id in (#{visible_nodes.keys.join(',')})")
+    end
+    if way_ids.length > 0
+        relations += Relation.find_by_sql("select e.* from current_relations e,current_relation_members em where " +
+            "e.visible=1 and " +
+            "em.id = e.id and em.member_type='way' and em.member_id in (#{way_ids.join(',')})")
+    end
     # we do not normally return the "other" partners referenced by an relation, 
     # e.g. if we return a way A that is referenced by relation X, and there's 
     # another way B also referenced, that is not returned. But we do make 
@@ -240,6 +240,51 @@ class ApiController < ApplicationController
     end
   end
 
+  def changes
+    zoom = (params[:zoom] || '12').to_i
+
+    if params.include?(:start) and params.include?(:end)
+      starttime = Time.parse(params[:start])
+      endtime = Time.parse(params[:end])
+    else
+      hours = (params[:hours] || '1').to_i.hours
+      endtime = Time.now
+      starttime = endtime - hours
+    end
+
+    if zoom >= 1 and zoom <= 16 and
+       endtime >= starttime and endtime - starttime <= 24.hours
+      mask = (1 << zoom) - 1
+
+      tiles = Node.count(:conditions => ["timestamp BETWEEN ? AND ?", starttime, endtime],
+                         :group => "maptile_for_point(latitude, longitude, #{zoom})")
+
+      doc = OSM::API.new.get_xml_doc
+      changes = XML::Node.new 'changes'
+      changes["starttime"] = starttime.xmlschema
+      changes["endtime"] = endtime.xmlschema
+
+      tiles.each do |tile, count|
+        x = (tile.to_i >> zoom) & mask
+        y = tile.to_i & mask
+
+        t = XML::Node.new 'tile'
+        t["x"] = x.to_s
+        t["y"] = y.to_s
+        t["z"] = zoom.to_s
+        t["changes"] = count.to_s
+
+        changes << t
+      end
+
+      doc.root << changes
+
+      render :text => doc.to_s, :content_type => "text/xml"
+    else
+      render :nothing => true, :status => :bad_request
+    end
+  end
+
   def capabilities
     doc = OSM::API.new.get_xml_doc