From d6e047d7d45ea76d56dccb53cc1fe1f5b54734d5 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Wed, 16 Jul 2008 23:42:59 +0000 Subject: [PATCH] Optimise finding of relations, partially reversing change #8443 but in a more rails like way. --- app/controllers/amf_controller.rb | 4 ++-- app/controllers/api_controller.rb | 6 +++--- app/models/relation.rb | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 1ff85888c..ce3dc91d5 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -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 diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 8b735600d..6b36b41ae 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -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. diff --git a/app/models/relation.rb b/app/models/relation.rb index 9ee118f6e..5d7092908 100644 --- a/app/models/relation.rb +++ b/app/models/relation.rb @@ -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 -- 2.43.2