make amf_controller use rails objects, and stuff, in the getway method. You need...
authorSteve Coast <steve@asklater.com>
Tue, 22 Jan 2008 15:00:54 +0000 (15:00 +0000)
committerSteve Coast <steve@asklater.com>
Tue, 22 Jan 2008 15:00:54 +0000 (15:00 +0000)
README
app/controllers/amf_controller.rb
app/models/geo_record.rb
app/models/node.rb
app/models/way.rb
app/models/way_node.rb
app/models/way_tag.rb
config/environment.rb

diff --git a/README b/README
index b28b918fb489adbb431eb1e9d89b7e3cfa1103fa..fbcaa096bf0ed5cf1b4ab2e52a8d6984c2e3c6b7 100644 (file)
--- 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
index c526141222f77f8fe879a5da5cfe3b6d2de7769c..5a8952b0f854e72ce540b041d522b3ad9106932a 100644 (file)
@@ -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
index 12a2a643e259d5b1cccc3fabcaa49a5a64fcaf43..e675b11e0d354b8d3d43e3bce9717c51302bfb16 100644 (file)
@@ -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
+
index 59aa4d36ffd01ef845896ca1199594253a6ef0fe..69ce5d6821618929062a58d338f9d29d54cf5a03 100644 (file)
@@ -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
index e0a4450741202b2ed5f39e9c6a672f9abb1f8a48..ff2e643709b24bf2a2c9a423b208e52701e6a812 100644 (file)
@@ -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
index 06515fc20711e179f978264e0b1514d75d462181..7f7789303f736da688195cad874df0c324d93aa1 100644 (file)
@@ -1,5 +1,6 @@
 class WayNode < ActiveRecord::Base
   set_table_name 'current_way_nodes'
 
+  set_primary_keys :id, :sequence_id
   belongs_to :node
 end
index 5ce7c8fbc4758081282bf9a5098c99a784fb6ec7..101085f129a4e0989f7623b55d68c7456bfba86b 100644 (file)
@@ -2,5 +2,4 @@ class WayTag < ActiveRecord::Base
   set_table_name 'current_way_tags'
 
   belongs_to :way, :foreign_key => 'id'
-
 end
index ed7bb67745cbcd1f2f41436a208aad7f9d5cba3c..436d5961dc46549422d980a336df9139d3141445 100644 (file)
@@ -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'