From: Steve Coast Date: Tue, 22 Jan 2008 15:00:54 +0000 (+0000) Subject: make amf_controller use rails objects, and stuff, in the getway method. You need... X-Git-Tag: live~7928 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/ddd5b4cf19a92582fd114914be5bd5a04d3522a7 make amf_controller use rails objects, and stuff, in the getway method. You need to install the multipart keys plugin now, see the README. --- diff --git a/README b/README index b28b918fb..fbcaa096b 100644 --- a/README +++ b/README @@ -9,6 +9,10 @@ INSTALL # sudo aptitude install libxml-ruby1.8 libxml-parser-ruby1.8 +* install primary keys plugin for active record + + # sudo gem install composite_primary_keys + * make sure you have a MTA listening on localhost:25 if you want mail * script/server diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index c52614122..5a8952b0f 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -235,39 +235,43 @@ class AmfController < ApplicationController [ways] end - # ----- getway - # in: [0] SWF object name, - # [1] way id, [2] baselong, [3] basey, [4] masterscale - # does: gets way and all nodes - # out: [0] SWF object name (unchanged), - # [1] array of points - # (where each point is an array containing - # [0] projected long, [1] projected lat, [2] node id, - # [3] null, [4] hash of node tags), - # [2] xmin, [3] xmax, [4] ymin, [5] ymax (unprojected bbox) - + # Get a way with all of it's nodes and tags + # The input is an array with the following components, in order: + # 0. SWF object name (String?) - fuck knows + # 1. wayid (String?) - the ID of the way to get + # 2. baselong - fuck knows + # 3. basey - fuck knows + # 4. masterscale - fuck knows + # + # The output is an array which contains all the nodes (with projected latitude and longitude) and tags for a way (and all the nodes tags). It also has the way's unprojected (WGS84) bbox. + # + # FIXME: The server really shouldn't be figuring out a ways bounding box and doing projection for potlatch + # FIXME: the argument splitting should be done in the 'talk' method, not here + # def getway(args) - objname,wayid,baselong,basey,masterscale=args + objname,wayid,baselong,basey,masterscale = args wayid = wayid.to_i - points = [] - xmin = ymin = 999999 - xmax = ymax = -999999 RAILS_DEFAULT_LOGGER.info(" Message: getway, id=#{wayid}") - readwayquery(wayid,true).each {|row| - points<<[long2coord(row['longitude'].to_f,baselong,masterscale),lat2coord(row['latitude'].to_f,basey,masterscale),row['id'].to_i,nil,tag2array(row['tags'])] - xmin = [xmin,row['longitude'].to_f].min - xmax = [xmax,row['longitude'].to_f].max - ymin = [ymin,row['latitude'].to_f].min - ymax = [ymax,row['latitude'].to_f].max - } + way = Way.find_eager(wayid) + long_array = [] + lat_array = [] + points = [] - attributes={} - attrlist=ActiveRecord::Base.connection.select_all "SELECT k,v FROM current_way_tags WHERE id=#{wayid}" - attrlist.each {|a| attributes[a['k'].gsub(':','|')]=a['v'] } + way.way_nodes.each do |way_node| + node = way_node.node # get the node record + projected_longitude = node.lon_potlatch(baselong,masterscale) # do projection for potlatch + projected_latitude = node.lat_potlatch(basey,masterscale) + id = node.id # node ide + tags_hash = node.tags_as_hash # hash of tags + + points << [projected_longitude, projected_latitude, id, nil, tags_hash] # FIXME remove the nil in potlatch. performance matters y'know! + long_array << projected_longitude + lat_array << projected_latitude + end - [objname,points,attributes,xmin,xmax,ymin,ymax] + [objname,points,way.tags,long_array.min,long_array.max,lat_array.min,lat_array.max] end # ----- getway_old @@ -792,7 +796,6 @@ class AmfController < ApplicationController ActiveRecord::Base.connection.execute("DELETE FROM current_relation_members WHERE id=#{relation} AND member_type='#{type}' AND member_id=#{objid}") end - def sqlescape(a) a.gsub(/[\000-\037]/,"").gsub("'","''").gsub(92.chr) {92.chr+92.chr} end diff --git a/app/models/geo_record.rb b/app/models/geo_record.rb index 12a2a643e..e675b11e0 100644 --- a/app/models/geo_record.rb +++ b/app/models/geo_record.rb @@ -19,11 +19,30 @@ class GeoRecord < ActiveRecord::Base self.longitude = (l * 10000000).round end + # Return WGS84 latitude def lat return self.latitude.to_f / 10000000 end + # Return WGS84 longitude def lon return self.longitude.to_f / 10000000 end + + # fuck knows + def lon_potlatch(baselong,masterscale) + (self.lon-baselong)*masterscale+350 + end + + def lat_potlatch(basey,masterscale) + -(lat2y(self.lat)-basey)*masterscale+250 + end + + private + + def lat2y(a) + 180/Math::PI * Math.log(Math.tan(Math::PI/4+a*(Math::PI/180)/2)) + end + end + diff --git a/app/models/node.rb b/app/models/node.rb index 59aa4d36f..69ce5d682 100644 --- a/app/models/node.rb +++ b/app/models/node.rb @@ -110,4 +110,13 @@ class Node < GeoRecord el1['timestamp'] = self.timestamp.xmlschema return el1 end + + def tags_as_hash + hash = {} + Tags.split(self.tags) do |k,v| + hash[k] = v + end + hash + end + end diff --git a/app/models/way.rb b/app/models/way.rb index e0a445074..ff2e64370 100644 --- a/app/models/way.rb +++ b/app/models/way.rb @@ -1,6 +1,6 @@ class Way < ActiveRecord::Base require 'xml/libxml' - + belongs_to :user has_many :way_nodes, :foreign_key => 'id', :order => 'sequence_id' @@ -47,6 +47,14 @@ class Way < ActiveRecord::Base return way end + # Find a way given it's ID, and in a single SQL call also grab its nodes + # + # You can't pull in all the tags too unless we put a sequence_id on the way_tags table and have a multipart key + def self.find_eager(id) + way = Way.find(id, :include => {:way_nodes => :node}) + end + + # Find a way given it's ID, and in a single SQL call also grab its nodes and tags def to_xml doc = OSM::API.new.get_xml_doc doc.root << to_xml_node() @@ -60,7 +68,7 @@ class Way < ActiveRecord::Base el1['timestamp'] = self.timestamp.xmlschema user_display_name_cache = {} if user_display_name_cache.nil? - + if user_display_name_cache and user_display_name_cache.key?(self.user_id) # use the cache if available elsif self.user.data_public? @@ -94,7 +102,7 @@ class Way < ActiveRecord::Base el1 << e end end - + self.way_tags.each do |tag| e = XML::Node.new 'tag' e['k'] = tag.k @@ -106,20 +114,20 @@ class Way < ActiveRecord::Base def nds unless @nds - @nds = Array.new - self.way_nodes.each do |nd| - @nds += [nd.node_id] - end + @nds = Array.new + self.way_nodes.each do |nd| + @nds += [nd.node_id] + end end @nds end def tags unless @tags - @tags = Hash.new - self.way_tags.each do |tag| - @tags[tag.k] = tag.v - end + @tags = {} + self.way_tags.each do |tag| + @tags[tag.k] = tag.v + end end @tags end diff --git a/app/models/way_node.rb b/app/models/way_node.rb index 06515fc20..7f7789303 100644 --- a/app/models/way_node.rb +++ b/app/models/way_node.rb @@ -1,5 +1,6 @@ class WayNode < ActiveRecord::Base set_table_name 'current_way_nodes' + set_primary_keys :id, :sequence_id belongs_to :node end diff --git a/app/models/way_tag.rb b/app/models/way_tag.rb index 5ce7c8fbc..101085f12 100644 --- a/app/models/way_tag.rb +++ b/app/models/way_tag.rb @@ -2,5 +2,4 @@ class WayTag < ActiveRecord::Base set_table_name 'current_way_tags' belongs_to :way, :foreign_key => 'id' - end diff --git a/config/environment.rb b/config/environment.rb index ed7bb6774..436d5961d 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -67,3 +67,6 @@ Rails::Initializer.run do |config| # Make Active Record use UTC-base instead of local time # config.active_record.default_timezone = :utc end + + +require 'composite_primary_keys'