]> git.openstreetmap.org Git - rails.git/commitdiff
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)
1  2 
app/controllers/api_controller.rb
app/controllers/node_controller.rb
app/controllers/swf_controller.rb
app/controllers/way_controller.rb
config/environment.rb

index 6e8e77c2f13de432aa3937d37b773ddaa79c2321,6964071098f5785baceef0dd4cd9397ddd981d0f..2e693042e98a70c4e1efd04d85d751c964526796
@@@ -1,6 -1,7 +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
      # check the bbox isn't too large
      requested_area = (max_lat-min_lat)*(max_lon-min_lon)
      if requested_area > MAX_REQUEST_AREA
 -      report_error("The maximum bbox size is " + MAX_REQUEST_AREA.to_s + ", and your request was too large. Either request a smaller area, or use planet.osm")
 +      report_error("The maximum bbox size is " + MAX_REQUEST_AREA.to_s + 
 +        ", and your request was too large. Either request a smaller area, or use planet.osm")
        return
      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 }
  
      end
  
      if node_ids.length == 0
 -      render :text => "<osm version='0.4'></osm>", :content_type => "text/xml"
 +      render :text => "<osm version='0.5'></osm>", :content_type => "text/xml"
        return
      end
  
 -    # grab the segments
 -    segments = Array.new
 -    if node_ids.length > 0
 -      node_ids_sql = "(#{node_ids.join(',')})"
 -      # get the referenced segments
 -      segments = Segment.find_by_sql "select * from current_segments where visible = 1 and (node_a in #{node_ids_sql} or node_b in #{node_ids_sql})"
 -    end
 -    # see if we have any missing nodes
 -    segments_nodes = segments.collect {|segment| segment.node_a }
 -    segments_nodes += segments.collect {|segment| segment.node_b }
 -
 -    segments_nodes.uniq!
 -
 -    missing_nodes = segments_nodes - node_ids
 -
 -    # get missing nodes if there are any
 -    nodes += Node.find(missing_nodes) if missing_nodes.length > 0
 +    relations = Array.new
  
      doc = OSM::API.new.get_xml_doc
  
      # get ways
      # find which ways are needed
 -    segment_ids = segments.collect {|segment| segment.id }
      ways = Array.new
 -    if segment_ids.length > 0
 -      way_segments = WaySegment.find_all_by_segment_id(segment_ids)
 -      way_ids = way_segments.collect {|way_segment| way_segment.id }
 -      ways = Way.find(way_ids) # NB: doesn't pick up segments, tags from db until accessed via way.way_segments etc.
 -
 -      # seg_ids = way_segments.collect {|way_segment| way_segment.segment_id }
 -
 -      list_of_way_segs = ways.collect {|way| way.way_segments}
 -      list_of_way_segs.flatten!
 +    if node_ids.length > 0
 +      way_nodes = WayNode.find_all_by_node_id(node_ids)
 +      way_ids = way_nodes.collect {|way_node| way_node.id }
 +      ways = Way.find(way_ids)
  
 -      list_of_way_segments = list_of_way_segs.collect { |way_seg| way_seg.segment_id }
 +      list_of_way_nodes = ways.collect { |way|
 +      way.way_nodes.collect { |way_node| way_node.node_id }
 +      }
 +      list_of_way_nodes.flatten!
  
 -      else
 -        list_of_way_segments = Array.new
 +    else
 +      list_of_way_nodes = Array.new
      end
  
 -    # - [0] in case some thing links to segment 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
 -    segments_to_fetch = (list_of_way_segments.uniq - segment_ids) - [0]
 +    # - [0] in case some thing links to node 0 which doesn't exist. Shouldn't actually ever happen but it does. FIXME: file a ticket for this
 +    nodes_to_fetch = (list_of_way_nodes.uniq - node_ids) - [0]
  
 -    if segments_to_fetch.length > 0
 -      segments += Segment.find(segments_to_fetch)
 +    if nodes_to_fetch.length > 0
 +      nodes += Node.find(nodes_to_fetch)
      end
  
 -    # get more nodes
 -    #
 -
 -    segments_nodes = segments.collect {|segment| segment.node_a }
 -    segments_nodes += segments.collect {|segment| segment.node_b }
 -
 -    node_ids_a = nodes.collect {|node| node.id }
 -
 -    nodes_to_get = segments_nodes - node_ids_a
 -    nodes += Node.find(nodes_to_get) if nodes_to_get.length > 0
 -
      visible_nodes = {}
      user_display_name_cache = {}
  
        end
      end
  
 -    visible_segments = {}
 -
 -    segments.each do |segment|
 -      if visible_nodes[segment.node_a] and visible_nodes[segment.node_b] and segment.visible?
 -        doc.root << segment.to_xml_node(user_display_name_cache) 
 -        visible_segments[segment.id] = segment
 -      end
 -    end
 -
 +    way_ids = Array.new
      ways.each do |way|
 -      doc.root << way.to_xml_node(visible_segments, user_display_name_cache) if way.visible?
 +      if way.visible?
 +        doc.root << way.to_xml_node(visible_nodes, user_display_name_cache)
 +        way_ids << way.id
 +      end
      end 
  
 +    # 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(',')})")
 +    # 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)
 +    relation_ids = relations.collect { |relation| relation.id }
 +    if relation_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='relation' and em.member_id in (#{relation_ids.join(',')})")
 +    end
 +
 +    # 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.
 +    relations.uniq.each do |relation|
 +      doc.root << relation.to_xml_node(user_display_name_cache)
 +    end
 +
      render :text => doc.to_s, :content_type => "text/xml"
      
      #exit when we have too many requests
  
      api = XML::Node.new 'api'
      version = XML::Node.new 'version'
 -    version['minimum'] = '0.4';
 -    version['maximum'] = '0.4';
 +    version['minimum'] = '0.5';
 +    version['maximum'] = '0.5';
      api << version
      area = XML::Node.new 'area'
      area['maximum'] = MAX_REQUEST_AREA.to_s;
index 7c7e3e6e4f85cf78ef6f915c5e97fcef287d46a2,0a3897fe9986da7318dafd557c84949a91b8020e..62987cf9433b35d0d8b8c3b770615e6758465cbc
@@@ -3,7 -3,8 +3,8 @@@ class NodeController < ApplicationContr
  
    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
@@@ -69,9 -70,7 +70,9 @@@
        node = Node.find(params[:id])
  
        if node.visible
 -        if Segment.find(:first, :conditions => [ "visible = 1 and (node_a = ? or node_b = ?)", node.id, node.id])
 +        if WayNode.find(:first, :joins => "INNER JOIN current_ways ON current_ways.id = current_way_nodes.id", :conditions => [ "current_ways.visible = 1 AND current_way_nodes.node_id = ?", node.id ])
 +          render :nothing => true, :status => :precondition_failed
 +        elsif RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='node' and member_id=?", params[:id]])
            render :nothing => true, :status => :precondition_failed
          else
            node.user_id = @user.id
index 6b29d1535e8878608c25930c22f0da719896b026,47ddcf9022068ae31a290a75f692f7cedbc28f03..40969c20fc5984f01aed60969e23c582353f10cf
@@@ -1,6 -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]}")
                # - 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_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,d569991af109469c2eee4c39dde9dd189bbf5e1a..7b7dbe81cad4a2d491102ac1d4cc90a890368594
@@@ -3,7 -3,8 +3,8 @@@ class WayController < ApplicationContro
  
    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
@@@ -54,7 -55,7 +55,7 @@@
            else
              way.user_id = @user.id
              way.tags = new_way.tags
 -            way.segs = new_way.segs
 +            way.nds = new_way.nds
              way.visible = true
              way.save_with_history!
  
        way = Way.find(params[:id])
  
        if way.visible
 -        way.user_id = @user.id
 -        way.tags = []
 -        way.segs = []
 -        way.visible = false
 -        way.save_with_history!
 +        if RelationMember.find(:first, :joins => "INNER JOIN current_relations ON current_relations.id=current_relation_members.id", :conditions => [ "visible = 1 AND member_type='way' and member_id=?", params[:id]])
 +          render :nothing => true, :status => :precondition_failed
 +        else
 +          way.user_id = @user.id
 +          way.tags = []
 +          way.nds = []
 +          way.visible = false
 +        way.save_with_history!
  
 -        render :nothing => true
 +        render :nothing => true
 +        end
        else
          render :nothing => true, :status => :gone
        end
      rescue ActiveRecord::RecordNotFound
        render :nothing => true, :status => :not_found
 +    rescue => ex
 +      puts ex
      end
    end
  
        way = Way.find(params[:id])
  
        if way.visible
 -        # In future, we might want to do all the data fetch in one step
 -        seg_ids = way.segs + [-1]
 -        segments = Segment.find_by_sql "select * from current_segments where visible = 1 and id IN (#{seg_ids.join(',')})"
 -
 -        node_ids = segments.collect {|segment| segment.node_a }
 -        node_ids += segments.collect {|segment| segment.node_b }
 -        node_ids += [-1]
 -        nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{node_ids.join(',')})")
 +        nd_ids = way.nds + [-1]
 +        nodes = Node.find(:all, :conditions => "visible = 1 AND id IN (#{nd_ids.join(',')})")
  
          # Render
          doc = OSM::API.new.get_xml_doc
          nodes.each do |node|
            doc.root << node.to_xml_node()
          end
 -        segments.each do |segment|
 -          doc.root << segment.to_xml_node()
 -        end
          doc.root << way.to_xml_node()
  
          render :text => doc.to_s, :content_type => "text/xml"
      end
    end
  
 -  def ways_for_segment
 -    wayids = WaySegment.find(:all, :conditions => ['segment_id = ?', params[:id]]).collect { |ws| ws.id }.uniq
 +  def ways_for_node
 +    wayids = WayNode.find(:all, :conditions => ['node_id = ?', params[:id]]).collect { |ws| ws.id }.uniq
  
      if wayids.length > 0
        doc = OSM::API.new.get_xml_doc
diff --combined config/environment.rb
index 3820ed29406f69a1b84808af0ef0dfa9c6e5244a,e58631901728abae9966c48ddf0dedc4062a22f2..0d98c70bdd409fa07346ef78c793c37584fdea79
@@@ -17,7 -17,7 +17,7 @@@ RAILS_GEM_VERSION = '1.2.3
  require File.join(File.dirname(__FILE__), 'boot')
  
  # Application constants needed for routes.rb - must go before Initializer call
 -API_VERSION = ENV['OSM_API_VERSION'] || '0.4'
 +API_VERSION = ENV['OSM_API_VERSION'] || '0.5'
  
  # Custom logger class to format messages sensibly
  class OSMLogger < Logger
@@@ -77,8 -77,9 +77,9 @@@ en
  #   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'