Optimise finding of relations, partially reversing change #8443 but in
authorTom Hughes <tom@compton.nu>
Wed, 16 Jul 2008 23:42:59 +0000 (23:42 +0000)
committerTom Hughes <tom@compton.nu>
Wed, 16 Jul 2008 23:42:59 +0000 (23:42 +0000)
a more rails like way.

app/controllers/amf_controller.rb
app/controllers/api_controller.rb
app/models/relation.rb

index 1ff85888c12e126aeff6343c21553931b598cc7c..ce3dc91d5b3107d8718e1242e32826f2ff21b0f8 100644 (file)
@@ -128,8 +128,8 @@ class AmfController < ApplicationController
          points = nodes_not_used_in_area.collect { |n| [n.id, n.lon, n.lat, n.tags_as_hash] }
 
          # find the relations used by those nodes and ways
-         relations = nodes_in_area.collect { |node| node.containing_relations.visible }.flatten +
-                                 way_ids.collect { |id| Way.find(id).containing_relations.visible }.flatten
+         relations = Relation.find_for_nodes(nodes_in_area.collect { |n| n.id }, :conditions => "visible = 1") +
+                  Relation.find_for_ways(way_ids, :conditions => "visible = 1")
          relation_ids = relations.collect { |relation| relation.id }.uniq
        end
 
index 8b735600d38e465f267295e0b93dfc7e7072906d..6b36b41ae947e25fdfe035f5377e2cc652e0d3a5 100644 (file)
@@ -176,15 +176,15 @@ class ApiController < ApplicationController
       end
     end 
 
-    relations = visible_nodes.values.collect { |node| node.containing_relations.visible }.flatten +
-                way_ids.collect { |id| Way.find(id).containing_relations.visible }.flatten
+    relations = Relation.find_for_nodes(visible_nodes.keys, :conditions => "visible = 1") +
+                Relation.find_for_ways(way_ids, :conditions => "visible = 1")
 
     # 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 
     # an exception for cases where an relation references another *relation*; 
     # in that case we return that as well (but we don't go recursive here)
-    relations += relations.collect { |relation| relation.containing_relations.visible }.flatten
+    relations += Relation.find_for_relations(relations.collect { |r| r.id }, :conditions => "visible = 1")
 
     # this "uniq" may be slightly inefficient; it may be better to first collect and output
     # all node-related relations, then find the *not yet covered* way-related ones etc.
index 9ee118f6e0c22fb26f4bff0012e30e3cb2c92173..5d7092908baa302c868cf8725378fb7d43763355 100644 (file)
@@ -105,6 +105,24 @@ class Relation < ActiveRecord::Base
     return el1
   end 
 
+  def self.find_for_nodes(ids, options = {})
+    self.with_scope(:find => { :joins => "INNER JOIN current_relation_members ON current_relation_members.id = current_relations.id", :conditions => "current_relation_members.member_type = 'node' AND current_relation_members.member_id IN (#{ids.join(',')})" }) do
+      return self.find(:all, options)
+    end
+  end
+
+  def self.find_for_ways(ids, options = {})
+    self.with_scope(:find => { :joins => "INNER JOIN current_relation_members ON current_relation_members.id = current_relations.id", :conditions => "current_relation_members.member_type = 'way' AND current_relation_members.member_id IN (#{ids.join(',')})" }) do
+      return self.find(:all, options)
+    end
+  end
+
+  def self.find_for_relations(ids, options = {})
+    self.with_scope(:find => { :joins => "INNER JOIN current_relation_members ON current_relation_members.id = current_relations.id", :conditions => "current_relation_members.member_type = 'relation' AND current_relation_members.member_id IN (#{ids.join(',')})" }) do
+      return self.find(:all, options)
+    end
+  end
+
   # FIXME is this really needed?
   def members
     unless @members