when 'putway'; results[index]=putdata(index,putway(args))
when 'deleteway'; results[index]=putdata(index,deleteway(args))
when 'makeway'; results[index]=putdata(index,makeway(args))
+ when 'putpoi'; results[index]=putdata(index,putpoi(args))
+ when 'getpoi'; results[index]=putdata(index,getpoi(args))
end
end
def getpresets
presets={}
- presetmenus={}; presetmenus['point']=[]; presetmenus['way']=[]
- presetnames={}; presetnames['point']={}; presetnames['way']={}
+ presetmenus={}; presetmenus['point']=[]; presetmenus['way']=[]; presetmenus['POI']=[]
+ presetnames={}; presetnames['point']={}; presetnames['way']={}; presetnames['POI']={}
presettype=''
presetcategory=''
way/footway
footpath: highway=footway,foot=yes
-bridleway: highway=bridleway,foot=yes,horse=yes,bicycle=yes
-byway: highway=byway,foot=yes,horse=yes,bicycle=yes,motorcar=yes
+bridleway: highway=bridleway,foot=yes
+byway: highway=unsurfaced,foot=yes
permissive path: highway=footway,foot=permissive
way/cycleway
course of old railway: railway=abandoned
way/natural
-forest: natural=wood,landuse=forest
-woodland: natural=wood,landuse=
-reservoir: natural=water,landuse=reservoir
-lake: natural=water,landuse=
-marsh: natural=marsh
-beach: natural=beach
-coastline: natural=coastline
+lake: landuse=water
+forest: landuse=forest
point/road
mini roundabout: highway=mini_roundabout
level crossing: railway=crossing
point/natural
-peak: natural=peak
+peak: point=peak
+
+POI/road
+car park: amenity=parking
+petrol station: amenity=fuel
+
+POI/cycleway
+bike park: amenity=bicycle_parking
+
+POI/place
+city: place=city,name=(type name here),is_in=(type region or county)
+town: place=town,name=(type name here),is_in=(type region or county)
+suburb: place=suburb,name=(type name here),is_in=(type region or county)
+village: place=village,name=(type name here),is_in=(type region or county)
+hamlet: place=hamlet,name=(type name here),is_in=(type region or county)
+
+POI/tourism
+attraction: tourism=attraction,amenity=,religion=,denomination=
+church: tourism=,amenity=place_of_worship,name=(type name here),religion=christian,denomination=(type denomination here)
+hotel: tourism=hotel,amenity=,religion=,denomination=
+other religious: tourism=,amenity=place_of_worship,name=(type name here),religion=(type religion),denomination=
+post box: amenity=post_box,tourism=,name=,religion=,denomination=
+post office: amenity=post_office,tourism=,name=,religion=,denomination=
+pub: tourism=,amenity=pub,name=(type name here),religion=,denomination=
+
+POI/natural
+peak: point=peak
EOF
StringIO.open(txt) do |file|
ymin = args[1].to_f-0.01
xmax = args[2].to_f+0.01
ymax = args[3].to_f+0.01
+ baselong = args[4]
+ basey = args[5]
+ masterscale = args[6]
RAILS_DEFAULT_LOGGER.info(" Message: whichways, bbox=#{xmin},#{ymin},#{xmax},#{ymax}")
ways = waylist.collect {|a| a.wayid.to_i } # get an array of way id's
- pointlist =ActiveRecord::Base.connection.select_all("SELECT current_nodes.id,current_nodes.tags "+
+ pointlist =ActiveRecord::Base.connection.select_all("SELECT current_nodes.id,latitude,longitude,current_nodes.tags "+
" FROM current_nodes "+
" LEFT OUTER JOIN current_segments cs1 ON cs1.node_a=current_nodes.id "+
" LEFT OUTER JOIN current_segments cs2 ON cs2.node_b=current_nodes.id "+
" AND cs1.id IS NULL AND cs2.id IS NULL "+
" AND current_nodes.visible=1")
- points = pointlist.collect {|a| [a['id'],tag2array(a['tags'])] } # get a list of node ids and their tags
+ points = pointlist.collect {|a| [a['id'],long2coord(a['longitude'].to_f,baselong,masterscale),lat2coord(a['latitude'].to_f,basey,masterscale),tag2array(a['tags'])] } # get a list of node ids and their tags
return [ways,points]
end
[originalway,way,renumberednodes,numberedsegments,xmin,xmax,ymin,ymax]
end
+ # ----- putpoi (user token, id, x,y,tag array,visible,baselong,basey,masterscale)
+ # returns current id, new id
+ # if new: add new row to current_nodes and nodes
+ # if old: add new row to nodes, update current_nodes
+
+ def putpoi(args)
+ usertoken,id,x,y,tags,visible,baselong,basey,masterscale=args
+ uid=getuserid(usertoken)
+ return if !uid
+ db_now='@now'+uid.to_s+id.to_i.abs.to_s+Time.new.to_i.to_s # 'now' variable name, typically 51 chars
+ ActiveRecord::Base.connection.execute("SET #{db_now}=NOW()")
+
+ id=id.to_i
+ visible=visible.to_i
+ x=coord2long(x.to_f,masterscale,baselong)
+ y=coord2lat(y.to_f,masterscale,basey)
+ tagsql="'"+sqlescape(array2tag(tags))+"'"
+
+ if (id>0) then
+ ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{id},#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
+ ActiveRecord::Base.connection.update("UPDATE current_nodes SET latitude=#{y},longitude=#{x},timestamp=#{db_now},user_id=#{uid},visible=#{visible},tags=#{tagsql} WHERE id=#{id}");
+ newid=id
+ else
+ newid=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes (latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
+ ActiveRecord::Base.connection.update("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{newid},#{y},#{x},#{db_now},#{uid},#{visible},#{tagsql})");
+ end
+ [id,newid]
+ end
+
+ # ----- getpoi (id,baselong,basey,masterscale)
+ # returns id,x,y,tag array
+
+ def getpoi(args)
+ id,baselong,basey,masterscale=args; id=id.to_i
+ poi=ActiveRecord::Base.connection.select_one("SELECT latitude,longitude,tags "+
+ "FROM current_nodes WHERE visible=1 AND id=#{id}")
+ if poi.nil? then return [nil,nil,nil,''] end
+ [id,
+ long2coord(poi['longitude'].to_f,baselong,masterscale),
+ lat2coord(poi['latitude'].to_f,basey,masterscale),
+ tag2array(poi['tags'])]
+ end
+
# ----- deleteway (user token, way)
# returns way ID only
def createuniquenodes(uqs_name,uqn_name)
# Finds nodes which appear in uniquesegments but no other segments
sql=<<-EOF
- CREATE TEMPORARY TABLE #{uqn_name}
- SELECT DISTINCT node_id
- FROM (SELECT cn.id AS node_id
- FROM current_nodes AS cn,
- current_segments AS cs,
- #{uqs_name} AS us
- WHERE cs.id=us.segment_id
- AND (cn.id=cs.node_a OR cn.id=cs.node_b)) AS n
- LEFT JOIN current_segments AS cs2 ON node_id=cs2.node_a AND cs2.visible=1
- LEFT JOIN current_segments AS cs3 ON node_id=cs3.node_b AND cs3.visible=1
- WHERE cs2.node_a IS NULL
- AND cs3.node_b IS NULL
+ CREATE TEMPORARY TABLE #{uqn_name}
+ SELECT DISTINCT node_id
+ FROM (SELECT cn.id AS node_id
+ FROM current_nodes AS cn,
+ current_segments AS cs,
+ #{uqs_name} AS us
+ WHERE cs.id=us.segment_id
+ AND cn.id=cs.node_a) AS n
+ LEFT JOIN current_segments AS cs2 ON node_id=cs2.node_a AND cs2.visible=1
+ LEFT JOIN current_segments AS cs3 ON node_id=cs3.node_b AND cs3.visible=1
+ WHERE cs2.node_a IS NULL
+ AND cs3.node_b IS NULL
+ EOF
+ ActiveRecord::Base.connection.execute(sql)
+ sql=<<-EOF
+ INSERT INTO #{uqn_name}
+ SELECT DISTINCT node_id
+ FROM (SELECT cn.id AS node_id
+ FROM current_nodes AS cn,
+ current_segments AS cs,
+ #{uqs_name} AS us
+ WHERE cs.id=us.segment_id
+ AND cn.id=cs.node_b) AS n
+ LEFT JOIN current_segments AS cs2 ON node_id=cs2.node_a AND cs2.visible=1
+ LEFT JOIN current_segments AS cs3 ON node_id=cs3.node_b AND cs3.visible=1
+ WHERE cs2.node_a IS NULL
+ AND cs3.node_b IS NULL
EOF
ActiveRecord::Base.connection.execute(sql)
end
return
end
- # integerise
- min_lat = min_lat * 1000000
- max_lat = max_lat * 1000000
- min_lon = min_lon * 1000000
- max_lon = max_lon * 1000000
# get all the points
- points = Tracepoint.find(:all, :conditions => ['latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ?', min_lat.to_i, max_lat.to_i, min_lon.to_i, max_lon.to_i], :select => "DISTINCT *", :offset => offset, :limit => TRACEPOINTS_PER_PAGE, :order => "timestamp DESC" )
+ points = Tracepoint.find_by_area(min_lat, min_lon, max_lat, max_lon, :offset => offset, :limit => TRACEPOINTS_PER_PAGE, :order => "timestamp DESC" )
doc = XML::Document.new
doc.encoding = 'UTF-8'
end
# get all the nodes
- nodes = Node.find(:all, :conditions =>
- ['latitude > ? AND longitude > ? AND latitude < ? AND longitude < ? AND visible = 1', min_lat, min_lon, max_lat, max_lon])
+ nodes = Node.find(:all, :conditions => ['latitude BETWEEN ? AND ? AND longitude BETWEEN ? AND ? AND visible = 1', min_lat, max_lat, min_lon, max_lon])
node_ids = nodes.collect {|node| node.id }
def new
@title = 'new diary entry'
if params[:diary_entry]
- @entry = DiaryEntry.new(params[:diary_entry])
- @entry.user = @user
- if @entry.save
+ @diary_entry = DiaryEntry.new(params[:diary_entry])
+ @diary_entry.user = @user
+ if @diary_entry.save
redirect_to :controller => 'diary_entry', :action => 'list', :display_name => @user.display_name
end
end
end
@entries.each do |entry|
- # add geodata here
- latitude = nil
- longitude = nil
- rss.add(latitude, longitude, entry.title, entry.user.display_name, url_for({:controller => 'diary_entry', :action => 'list', :id => entry.id, :display_name => entry.user.display_name}), entry.body, entry.created_at)
+ rss.add(entry.latitude, entry.longitude, entry.title, entry.user.display_name, url_for({:controller => 'diary_entry', :action => 'list', :id => entry.id, :display_name => entry.user.display_name}), entry.body, entry.created_at)
end
render :text => rss.to_s, :content_type => "application/rss+xml"
def new
@title = 'send message'
if params[:message]
- to_user = User.find(params[:user_id])
- body = params[:message][:body]
- title = params[:message][:title]
- message = Message.new
- message.body = body
- message.title = title
- message.to_user_id = params[:user_id]
- message.from_user_id = @user.id
- message.sent_on = Time.now
+ @message = Message.new(params[:message])
+ @message.to_user_id = params[:user_id]
+ @message.from_user_id = @user.id
+ @message.sent_on = Time.now
- if message.save
+ if @message.save
flash[:notice] = 'Message sent'
+ Notifier::deliver_message_notification(@message)
redirect_to :controller => 'message', :action => 'inbox', :display_name => @user.display_name
- else
- @message.errors.add("Sending message failed")
end
-
end
end
if node
node.user_id = @user.id
node.visible = true
+ node.save_with_history!
- if node.save_with_history
- render :text => node.id.to_s, :content_type => "text/plain"
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :text => node.id.to_s, :content_type => "text/plain"
else
render :nothing => true, :status => :bad_request
end
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
node.latitude = new_node.latitude
node.longitude = new_node.longitude
node.tags = new_node.tags
+ node.save_with_history!
- if node.save_with_history
- render :nothing => true
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :nothing => true
else
render :nothing => true, :status => :bad_request
end
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
else
node.user_id = @user.id
node.visible = 0
- node.save_with_history
+ node.save_with_history!
+
render :nothing => true
end
else
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
render :nothing => true, :status => :precondition_failed
else
relation.user_id = @user.id
+ relation.save_with_history!
- if relation.save_with_history
- render :text => relation.id.to_s, :content_type => "text/plain"
- else
- render :text => "save error", :status => :internal_server_error
- end
+ render :text => relation.id.to_s, :content_type => "text/plain"
end
else
render :nothing => true, :status => :bad_request
relation.tags = new_relation.tags
relation.members = new_relation.members
relation.visible = true
+ relation.save_with_history!
- if relation.save_with_history
- render :nothing => true
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :nothing => true
end
else
render :nothing => true, :status => :bad_request
relation.tags = []
relation.members = []
relation.visible = false
+ relation.save_with_history!
- if relation.save_with_history
- render :nothing => true
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :nothing => true
end
else
render :nothing => true, :status => :gone
basey =params['basey'].to_f
masterscale =params['masterscale'].to_f
- xmin=params['xmin'].to_f; xminr=xmin/0.000001
- xmax=params['xmax'].to_f; xmaxr=xmax/0.000001
- ymin=params['ymin'].to_f; yminr=ymin/0.000001
- ymax=params['ymax'].to_f; ymaxr=ymax/0.000001
+ xmin=params['xmin'].to_f;
+ xmax=params['xmax'].to_f;
+ ymin=params['ymin'].to_f;
+ ymax=params['ymax'].to_f;
# - Begin movie
if params['token']
user=User.authenticate(:token => params[:token])
- sql="SELECT gps_points.latitude*0.000001 AS lat,gps_points.longitude*0.000001 AS lon,gpx_files.id AS fileid,UNIX_TIMESTAMP(gps_points.timestamp) AS ts "+
+ sql="SELECT gps_points.latitude*0.0000001 AS lat,gps_points.longitude*0.0000001 AS lon,gpx_files.id AS fileid,UNIX_TIMESTAMP(gps_points.timestamp) AS ts "+
" FROM gpx_files,gps_points "+
"WHERE gpx_files.id=gpx_id "+
" AND gpx_files.user_id=#{user.id} "+
- " AND (gps_points.longitude BETWEEN #{xminr} AND #{xmaxr}) "+
- " AND (gps_points.latitude BETWEEN #{yminr} AND #{ymaxr}) "+
+ " AND "+OSM.sql_for_area(ymin,xmin,ymax,xmax,"gps_points.")+
" AND (gps_points.timestamp IS NOT NULL) "+
"ORDER BY fileid DESC,ts "+
"LIMIT 10000"
else
- sql="SELECT latitude*0.000001 AS lat,longitude*0.000001 AS lon,gpx_id AS fileid,UNIX_TIMESTAMP(timestamp) AS ts "+
+ sql="SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,gpx_id AS fileid,UNIX_TIMESTAMP(timestamp) AS ts "+
" FROM gps_points "+
- "WHERE (longitude BETWEEN #{xminr} AND #{xmaxr}) "+
- " AND (latitude BETWEEN #{yminr} AND #{ymaxr}) "+
+ "WHERE "+OSM.sql_for_area(ymin,xmin,ymax,xmax,"gps_points.")+
" AND (gps_points.timestamp IS NOT NULL) "+
"ORDER BY fileid DESC,ts "+
"LIMIT 10000"
render :nothing => true, :status => :precondition_failed
else
way.user_id = @user.id
+ way.save_with_history!
- if way.save_with_history
- render :text => way.id.to_s, :content_type => "text/plain"
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :text => way.id.to_s, :content_type => "text/plain"
end
else
render :nothing => true, :status => :bad_request
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
way.tags = new_way.tags
way.nds = new_way.nds
way.visible = true
+ way.save_with_history!
- if way.save_with_history
- render :nothing => true
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :nothing => true
end
else
render :nothing => true, :status => :bad_request
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
way.tags = []
way.nds = []
way.visible = false
+ way.save_with_history!
- if way.save_with_history
- render :nothing => true
- else
- render :nothing => true, :status => :internal_server_error
- end
+ render :nothing => true
end
else
render :nothing => true, :status => :gone
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
+ rescue => ex
+ puts ex
end
end
end
rescue ActiveRecord::RecordNotFound
render :nothing => true, :status => :not_found
- rescue
- render :nothing => true, :status => :internal_server_error
end
end
def result_to_html(result)
html_options = {}
#html_options[:title] = strip_tags(result[:description]) if result[:description]
- html_options[:href] = "?lat=#{result[:lat]}&lon=#{result[:lon]}&zoom=#{result[:zoom]}"
+ html_options[:href] = "?mlat=#{result[:lat]}&mlon=#{result[:lon]}&zoom=#{result[:zoom]}"
html = ""
html << result[:prefix] if result[:prefix]
html << link_to_function(result[:name],"setPosition(#{result[:lat]}, #{result[:lon]}, #{result[:zoom]})", html_options) if result[:name]
class DiaryEntry < ActiveRecord::Base
belongs_to :user
+
+ validates_presence_of :title, :body
+ validates_numericality_of :latitude, :allow_nil => true
+ validates_numericality_of :longitude, :allow_nil => true
+ validates_associated :user
end
class Message < ActiveRecord::Base
belongs_to :sender, :class_name => "User", :foreign_key => :from_user_id
belongs_to :recipient, :class_name => "User", :foreign_key => :to_user_id
+
+ validates_presence_of :title, :body, :sent_on
+ validates_inclusion_of :message_read, :in => [ true, false ]
+ validates_associated :sender, :recipient
end
return node
end
- def save_with_history
- begin
- Node.transaction do
- self.timestamp = Time.now
- self.save!
- old_node = OldNode.from_node(self)
- old_node.save!
- end
-
- return true
- rescue
- return nil
+ def save_with_history!
+ Node.transaction do
+ self.timestamp = Time.now
+ self.save!
+ old_node = OldNode.from_node(self)
+ old_node.save!
end
end
@body['trace_name'] = trace.name
@body['error'] = error
end
+
+ def message_notification(message)
+ @recipients = message.recipient.email
+ @from = 'abuse@openstreetmap.org'
+ @subject = "[OpenStreetMap] #{message.sender.display_name} sent you a new message"
+ @body['to_user'] = message.recipient.display_name
+ @body['from_user'] = message.sender.display_name
+ @body['body'] = message.body
+ @body['subject'] = message.title
+ @body['readurl'] = "http://#{SERVER_URL}/message/read/#{message.id}"
+ @body['replyurl'] = "http://#{SERVER_URL}/message/new/#{message.from_user_id}"
+ end
end
@tags[k] = v
end
- def save_with_history
- begin
- Relation.transaction do
- t = Time.now
- self.timestamp = t
- self.save!
-
- tags = self.tags
-
- RelationTag.delete_all(['id = ?', self.id])
-
- tags.each do |k,v|
- tag = RelationTag.new
- tag.k = k
- tag.v = v
- tag.id = self.id
- tag.save!
- end
-
- members = self.members
+ def save_with_history!
+ Relation.transaction do
+ t = Time.now
+ self.timestamp = t
+ self.save!
+
+ tags = self.tags
+
+ RelationTag.delete_all(['id = ?', self.id])
+
+ tags.each do |k,v|
+ tag = RelationTag.new
+ tag.k = k
+ tag.v = v
+ tag.id = self.id
+ tag.save!
+ end
- RelationMember.delete_all(['id = ?', self.id])
+ members = self.members
- members.each do |n|
- mem = RelationMember.new
- mem.id = self.id
- mem.member_type = n[0];
- mem.member_id = n[1];
- mem.member_role = n[2];
- mem.save!
- end
+ RelationMember.delete_all(['id = ?', self.id])
- old_relation = OldRelation.from_relation(self)
- old_relation.timestamp = t
- old_relation.save_with_dependencies!
+ members.each do |n|
+ mem = RelationMember.new
+ mem.id = self.id
+ mem.member_type = n[0];
+ mem.member_id = n[1];
+ mem.member_role = n[2];
+ mem.save!
end
- return true
- rescue Exception => ex
- return nil
+ old_relation = OldRelation.from_relation(self)
+ old_relation.timestamp = t
+ old_relation.save_with_dependencies!
end
end
f_lon = 0
first = true
- Tracepoint.delete_all(['gpx_id = ?', self.id])
+ # If there are any existing points for this trace then delete
+ # them - we check for existing points first to avoid locking
+ # the table in the common case where there aren't any.
+ if Tracepoint.exists?(['gpx_id = ?', self.id])
+ Tracepoint.delete_all(['gpx_id = ?', self.id])
+ end
gpx.points do |point|
if first
max_lon = Tracepoint.maximum('longitude', :conditions => ['gpx_id = ?', id])
min_lon = Tracepoint.minimum('longitude', :conditions => ['gpx_id = ?', id])
- max_lat = max_lat.to_f / 1000000
- min_lat = min_lat.to_f / 1000000
- max_lon = max_lon.to_f / 1000000
- min_lon = min_lon.to_f / 1000000
+ max_lat = max_lat.to_f / 10000000
+ min_lat = min_lat.to_f / 10000000
+ max_lon = max_lon.to_f / 10000000
+ min_lon = min_lon.to_f / 10000000
self.latitude = f_lat
self.longitude = f_lon
class Tracepoint < ActiveRecord::Base
-set_table_name 'gps_points'
+ set_table_name 'gps_points'
-# validates_numericality_of :latitude
-# validates_numericality_of :longitude
+ validates_numericality_of :trackid, :only_integer => true
+ validates_numericality_of :latitude, :only_integer => true
+ validates_numericality_of :longitude, :only_integer => true
+ validates_associated :trace
+ validates_presence_of :timestamp
- belongs_to :user
belongs_to :trace, :foreign_key => 'gpx_id'
+
+ before_save :update_tile
+
+ def self.find_by_area(minlat, minlon, maxlat, maxlon, options)
+ self.with_scope(:find => {:conditions => OSM.sql_for_area(minlat, minlon, maxlat, maxlon)}) do
+ return self.find(:all, options)
+ end
+ end
+
+ def update_tile
+ self.tile = QuadTile.tile_for_point(lat, lon)
+ end
def lat=(l)
- self.latitude = l * 1000000
+ self.latitude = (l * 10000000).round
end
def lng=(l)
- self.longitude = l * 1000000
+ self.longitude = (l * 10000000).round
end
def lat
- return self.latitude.to_f / 1000000
+ return self.latitude.to_f / 10000000
end
def lon
- return self.longitude.to_f / 1000000
+ return self.longitude.to_f / 10000000
end
def to_xml_node
el1['lon'] = self.lon.to_s
return el1
end
-
end
@tags[k] = v
end
- def save_with_history
- begin
- Way.transaction do
- t = Time.now
- self.timestamp = t
- self.save!
+ def save_with_history!
+ t = Time.now
- tags = self.tags
+ Way.transaction do
+ self.timestamp = t
+ self.save!
+ end
- WayTag.delete_all(['id = ?', self.id])
+ WayTag.transaction do
+ tags = self.tags
- tags.each do |k,v|
- tag = WayTag.new
- tag.k = k
- tag.v = v
- tag.id = self.id
- tag.save!
- end
+ WayTag.delete_all(['id = ?', self.id])
- nds = self.nds
+ tags.each do |k,v|
+ tag = WayTag.new
+ tag.k = k
+ tag.v = v
+ tag.id = self.id
+ tag.save!
+ end
+ end
- WayNode.delete_all(['id = ?', self.id])
+ WayNode.transaction do
+ nds = self.nds
- i = 1
- nds.each do |n|
- nd = WayNode.new
- nd.id = self.id
- nd.node_id = n
- nd.sequence_id = i
- nd.save!
- i += 1
- end
+ WayNode.delete_all(['id = ?', self.id])
- old_way = OldWay.from_way(self)
- old_way.timestamp = t
- old_way.save_with_dependencies!
+ i = 1
+ nds.each do |n|
+ nd = WayNode.new
+ nd.id = self.id
+ nd.node_id = n
+ nd.sequence_id = i
+ nd.save!
+ i += 1
end
-
- return true
- rescue => ex
- puts ex
- return nil
end
+
+ old_way = OldWay.from_way(self)
+ old_way.timestamp = t
+ old_way.save_with_dependencies!
end
def preconditions_ok?
<b><%= diary_entry.title %></b><br />
<%= simple_format(diary_entry.body) %>
-Posted by user <b><%= link_to diary_entry.user.display_name, :controller => 'user', :action => 'view', :display_name => diary_entry.user.display_name %></b> at <%= diary_entry.created_at %><br />
+<% if diary_entry.latitude and diary_entry.longitude %>
+Coordinates: <div class="geo" style="display: inline"><span class="latitude"><%= diary_entry.latitude %></span>; <span class="longitude"><%= diary_entry.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => diary_entry.latitude, :lon => diary_entry.longitude, :zoom => 14 %>)<br/>
+<% end %>
+Posted by <b><%= link_to diary_entry.user.display_name, :controller => 'user', :action => 'view', :display_name => diary_entry.user.display_name %></b> at <%= diary_entry.created_at %><br />
<br />
<hr />
<% if @this_user %>
<h2><%= @this_user.display_name %>'s diary</h2>
-
- <% if @user and @this_user.id == @user.id %>
+ <% if @user == @this_user %>
+ <%= link_to 'New diary post', :controller => 'diary_entry', :action => 'new', :display_name => @user.display_name %>
+ <% end %>
+<% else %>
+ <h2>Users' diaries</h2>
+ <% if @user %>
<%= link_to 'New diary post', :controller => 'diary_entry', :action => 'new', :display_name => @user.display_name %>
<% end %>
<% end %>
<th>Body</th>
<td><%= f.text_area :body, :cols => 80 %></td>
</tr>
+ <tr valign="top">
+ <th>Location</th>
+ <td><a name="map"></a><div id="map" style="border: 1px solid black; position: relative; width : 90%; height : 300px; display: none;"></div>
+ <span class="location">Latitude: <%= f.text_field :latitude, :size => 20, :id => "latitude" %> Longitude: <%= f.text_field :longitude, :size => 20, :id => "longitude" %></span> <a href="#map" id="usemap" onclick="document.getElementById('map').style.display = 'block'; document.getElementById('usemap').style.display = 'none';">use map</a> </td>
+ </tr>
<tr>
<th></th>
<td><%= submit_tag 'Save' %></td>
</tr>
</table>
<% end %>
+
+<% if @user.home_lat.nil? or @user.home_lon.nil? %>
+ <% lon = params['lon'] || '-0.1' %>
+ <% lat = params['lat'] || '51.5' %>
+ <% zoom = params['zoom'] || '4' %>
+<% else %>
+ <% lon = @user.home_lon %>
+ <% lat = @user.home_lat %>
+ <% zoom = '12' %>
+<% end %>
+
+<script type="text/javascript" src="/openlayers/OpenLayers.js"></script>
+<%= javascript_include_tag 'map.js' %>
+
+<script type="text/javascript">
+ <!--
+ var marker;
+
+ function init(){
+ var centre = lonLatToMercator(new OpenLayers.LonLat(<%= lon %>, <%= lat %>));
+ var zoom = <%= zoom %>;
+
+ var map = createMap("map");
+
+ map.setCenter(centre, zoom);
+
+ map.events.register("click", map, setLocation);
+ }
+
+ function setLocation( e ) {
+ closeMapPopup();
+
+ var merc = map.getLonLatFromViewPortPx(e.xy);
+ var lonlat = mercatorToLonLat(merc);
+
+ document.getElementById('latitude').value = lonlat.lat;
+ document.getElementById('longitude').value = lonlat.lon;
+
+ if (marker) {
+ removeMarkerFromMap(marker);
+ }
+
+ marker = addMarkerToMap(merc, null, "Diary entry location");
+ }
+
+ window.onload = init;
+// -->
+</script>
\ No newline at end of file
+<% this_colour = cycle('lightgrey', 'white') # can only call once for some dumb reason %>
+
<tr class="inbox-row<%= "-unread" if not message_summary.message_read? %>">
- <td class="inbox-sender"><%= link_to message_summary.sender.display_name , :controller => 'user', :action => message_summary.sender.display_name %></td>
- <td class="inbox-subject"><%= link_to message_summary.title , :controller => 'message', :action => 'read', :message_id => message_summary.id %></td>
- <td class="inbox-sent"><%= message_summary.sent_on %></td>
+ <td class="inbox-sender" bgcolor='<%= this_colour %>'><%= link_to message_summary.sender.display_name , :controller => 'user', :action => message_summary.sender.display_name %></td>
+ <td class="inbox-subject" bgcolor='<%= this_colour %>'><%= link_to message_summary.title , :controller => 'message', :action => 'read', :message_id => message_summary.id %></td>
+ <td class="inbox-sent" bgcolor='<%= this_colour %>'><%= message_summary.sent_on %></td>
<% if message_summary.message_read? %>
<td><%= button_to 'Mark as unread', :controller => 'message', :action => 'mark', :message_id => message_summary.id, :mark => 'unread' %></td>
<% else %>
<table>
<tr>
- <th>From</th>
+ <th align="right">From</th>
<td><%= link_to @message.sender.display_name, :controller => 'user', :action => 'view', :display_name => @message.sender.display_name %></td>
</tr>
<tr>
- <th>Subject</th>
+ <th align="right">Subject</th>
<td><%= @message.title %></td>
</tr>
<tr>
- <th>Date</th>
+ <th align="right">Date</th>
<td><%= @message.sent_on %></td>
</tr>
<tr>
- <th>Message</th>
+ <th></th>
<td><%= @message.body %></td>
</tr>
</table>
--- /dev/null
+Hi <%= @to_user %>,
+
+<%= @from_user %> has sent you a message through OpenStreetMap with the subject "<%= @subject %>":
+
+==
+<%= @body %>
+==
+
+You can also read the message at <%= @readurl %>
+and you can reply at <%= @replyurl %>
<p class="search_help">
examples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ',
or 'post offices near Lünen'
- <a href="http://wiki.openstreetmap.org/index.php/Search_Help">more examples...</a>
+ <a href="http://wiki.openstreetmap.org/index.php/Search">more examples...</a>
</p>
</div>
<% end %>
var fo = new SWFObject("/potlatch/potlatch.swf?d="+Math.round(Math.random()*1000), "potlatch", "700", "600", "6", "#FFFFFF");
function doSWF(lat,lon,sc) {
+ if (sc < 11) sc = 11;
fo.addVariable('lat',lat);
fo.addVariable('long',lon);
fo.addVariable('scale',sc);
fo.addVariable('token','<%= session[:token] %>');
+<% if params['gpx'] %> fo.addVariable('gpx','<%= params['gpx']+"/data" %>'); <% end %>
fo.write("map");
}
map.setCenter(centre, zoom);
<% end %>
- <% if marker %>
- marker = addMarkerToMap(lonLatToMercator(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>)));
- <% end %>
-
<% if layers %>
setMapLayers("<%= layers %>");
<% end %>
+ <% if marker %>
+ marker = addMarkerToMap(lonLatToMercator(new OpenLayers.LonLat(<%= mlon %>, <%= mlat %>)));
+ <% end %>
+
map.events.register("moveend", map, updateLocation);
updateLocation();
... <%= time_ago_in_words( trace.timestamp ) %> ago</span>
<%= link_to 'more', {:controller => 'trace', :action => 'view', :display_name => trace.user.display_name, :id => trace.id}, {:title => 'View Trace Details'} %> /
<%= link_to_if trace.inserted?, 'map', {:controller => 'site', :action => 'index', :lat => trace.latitude, :lon => trace.longitude, :zoom => 14}, {:title => 'View Map'} %> /
- <%= link_to_if trace.inserted?, 'edit', {:controller => 'site', :action => 'edit', :lat => trace.latitude, :lon => trace.longitude, :zoom => 14}, {:title => 'Edit Map'} %>
+ <%= link_to_if trace.inserted?, 'edit', {:controller => 'site', :action => 'edit', :lat => trace.latitude, :lon => trace.longitude, :zoom => 14, :gpx => trace.id }, {:title => 'Edit Map'} %>
<br />
<%= escape_once(trace.description) %>
<br />
<td><%= @trace.size.to_s.gsub(/(\d)(?=(\d{3})+$)/,'\1,') %></td></tr>
<tr>
<td>Start coordinate:</td>
- <td><%= @trace.latitude %>, <%= @trace.longitude %> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %>)</td>
+ <td><div class="geo" style="display: inline"><span class="latitude"><%= @trace.latitude %></span>; <span class="longitude"><%= @trace.longitude %></span></div> (<%=link_to 'map', :controller => 'site', :action => 'index', :lat => @trace.latitude, :lon => @trace.longitude, :zoom => 14 %> / <%=link_to 'edit', :controller => 'site', :action => 'edit', :lat => @trace.latitude, :lon => @trace.longitude, :gpx=> @trace.id, :zoom => 14 %>)</td>
</tr>
<% end %>
<tr>
# Be sure to restart your web server when you modify this file.
+# Limit each rails process to a 512Mb resident set size
+Process.setrlimit Process::RLIMIT_AS, 640*1024*1024, Process::RLIM_INFINITY
+
# Uncomment below to force Rails into production mode when
# you don't control web/app server and can't set it the proper way
ENV['RAILS_ENV'] ||= 'production'
> flush privileges;
> exit
+Creating functions
+====================
+
+Run this command in the db/functions directory:
+
+$ make
+
+Make sure the db/functions directory is on the MySQL server's library
+path and restart the MySQL server. On linux the easiest way to do this
+is to create /etc/ld.so.conf.d/osm.conf and place the path to the
+db/functions directory in it and then run the following command as root:
+
+$ ldconfig
+
+Now create the functions as follows:
+
+$ mysql -u <uid> -p openstreetmap
+
+(change <uid> with appropriate username of administrative user eg. root )
+
+> create function tile_for_point returns integer soname 'libquadtile.so';
+> exit
+
Creating database skeleton tables
===================================
-Run this command from the root of your rails direcotry:
+Run this command from the root of your rails directory:
$ rake db:migrate
--- /dev/null
+QTDIR=../../lib/quad_tile
+
+libquadtile.so: quadtile.c ${QTDIR}/quad_tile.h
+ cc `mysql_config --include` -I${QTDIR} -fPIC -O3 -shared -o libquadtile.so quadtile.c
--- /dev/null
+#include <my_global.h>
+#include <my_sys.h>
+#include <m_string.h>
+#include <mysql.h>
+#include <quad_tile.h>
+
+my_bool tile_for_point_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+ if ( args->arg_count != 2 ||
+ args->arg_type[0] != INT_RESULT ||
+ args->arg_type[1] != INT_RESULT )
+ {
+ strcpy( message, "Your tile_for_point arguments are bogus!" );
+ return 1;
+ }
+
+ return 0;
+}
+
+void tile_for_point_deinit(UDF_INIT *initid)
+{
+ return;
+}
+
+long long tile_for_point(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
+{
+ long long lat = *(long long *)args->args[0];
+ long long lon = *(long long *)args->args[1];
+
+ return xy2tile(lon2x(lon / 10000000.0), lat2y(lat / 10000000.0));
+}
--- /dev/null
+class TileTracepoints < ActiveRecord::Migration
+ def self.up
+ add_column "gps_points", "tile", :integer, :null => false, :unsigned => true
+ add_index "gps_points", ["tile"], :name => "points_tile_idx"
+ remove_index "gps_points", :name => "points_idx"
+
+ Tracepoint.update_all("latitude = latitude * 10, longitude = longitude * 10, tile = tile_for_point(latitude * 10, longitude * 10)")
+ end
+
+ def self.down
+ add_index "gps_points", ["latitude", "longitude"], :name => "points_idx"
+ remove_index "gps_points", :name => "points_tile_idx"
+ remove_column "gps_points", "tile"
+ end
+end
have_segs = select_value("SELECT count(*) FROM current_segments").to_i != 0
if have_segs
- prefix = File.join Dir.tmpdir, "006_remove_segments.#{$$}."
+ prefix = File.join Dir.tmpdir, "007_remove_segments.#{$$}."
- cmd = "db/migrate/006_remove_segments_helper"
+ cmd = "db/migrate/007_remove_segments_helper"
src = "#{cmd}.cc"
if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then
system 'c++ -O3 -Wall `mysql_config --cflags --libs` ' +
static void exit_mysql_err(MYSQL *mysql) {
const char *err = mysql_error(mysql);
if (err) {
- fprintf(stderr, "005_remove_segments_helper: MySQL error: %s\n", err);
+ fprintf(stderr, "007_remove_segments_helper: MySQL error: %s\n", err);
} else {
- fprintf(stderr, "005_remove_segments_helper: MySQL error\n");
+ fprintf(stderr, "007_remove_segments_helper: MySQL error\n");
}
abort();
exit(EXIT_FAILURE);
static void exit_stmt_err(MYSQL_STMT *stmt) {
const char *err = mysql_stmt_error(stmt);
if (err) {
- fprintf(stderr, "005_remove_segments_helper: MySQL stmt error: %s\n", err);
+ fprintf(stderr, "007_remove_segments_helper: MySQL stmt error: %s\n", err);
} else {
- fprintf(stderr, "005_remove_segments_helper: MySQL stmt error\n");
+ fprintf(stderr, "007_remove_segments_helper: MySQL stmt error\n");
}
abort();
exit(EXIT_FAILURE);
char *tempfn;
if (argc != 8) {
- printf("Usage: 006_remove_segments_helper host user passwd database port socket prefix\n");
+ printf("Usage: 007_remove_segments_helper host user passwd database port socket prefix\n");
exit(EXIT_FAILURE);
}
return false if options[:options] =~ /AUTO_INCREMENT/i
return old_options_include_default?(options)
end
+
+ alias_method :old_add_column_options!, :add_column_options!
+
+ def add_column_options!(sql, options)
+ sql << " UNSIGNED" if options[:unsigned]
+ old_add_column_options!(sql, options)
+ sql << " #{options[:options]}"
+ end
end
class MysqlAdapter
change_column_sql = "ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
add_column_options!(change_column_sql, options)
- change_column_sql << " #{options[:options]}"
execute(change_column_sql)
end
return Digest::MD5.hexdigest(password) if salt.nil?
return Digest::MD5.hexdigest(salt + password)
end
+
+ # Return an SQL fragment to select a given area of the globe
+ def self.sql_for_area(minlat, minlon, maxlat, maxlon, prefix = nil)
+ tilesql = QuadTile.sql_for_area(minlat, minlon, maxlat, maxlon, prefix)
+ minlat = (minlat * 10000000).round
+ minlon = (minlon * 10000000).round
+ maxlat = (maxlat * 10000000).round
+ maxlon = (maxlon * 10000000).round
+
+ return "#{tilesql} AND #{prefix}latitude BETWEEN #{minlat} AND #{maxlat} AND #{prefix}longitude BETWEEN #{minlon} AND #{maxlon}"
+ end
end
--- /dev/null
+module QuadTile
+ begin
+ require "quad_tile/quad_tile_so"
+ rescue MissingSourceFile
+ def self.tile_for_point(lat, lon)
+ x = ((lon + 180) * 65535 / 360).round
+ y = ((lat + 90) * 65535 / 180).round
+
+ return tile_for_xy(x, y)
+ end
+
+ def self.tiles_for_area(minlat, minlon, maxlat, maxlon)
+ minx = ((minlon + 180) * 65535 / 360).round
+ maxx = ((maxlon + 180) * 65535 / 360).round
+ miny = ((minlat + 90) * 65535 / 180).round
+ maxy = ((maxlat + 90) * 65535 / 180).round
+ tiles = []
+
+ minx.upto(maxx) do |x|
+ miny.upto(maxy) do |y|
+ tiles << tile_for_xy(x, y)
+ end
+ end
+
+ return tiles
+ end
+
+ def self.tile_for_xy(x, y)
+ t = 0
+
+ 16.times do
+ t = t << 1
+ t = t | 1 unless (x & 0x8000).zero?
+ x <<= 1
+ t = t << 1
+ t = t | 1 unless (y & 0x8000).zero?
+ y <<= 1
+ end
+
+ return t
+ end
+ end
+
+ def self.sql_for_area(minlat, minlon, maxlat, maxlon, prefix)
+ sql = Array.new
+ single = Array.new
+
+ iterate_tiles_for_area(minlat, minlon, maxlat, maxlon) do |first,last|
+ if first == last
+ single.push(first)
+ else
+ sql.push("#{prefix}tile BETWEEN #{first} AND #{last}")
+ end
+ end
+
+ sql.push("#{prefix}tile IN (#{single.join(',')})") if single.size > 0
+
+ return "( " + sql.join(" OR ") + " )"
+ end
+
+ def self.iterate_tiles_for_area(minlat, minlon, maxlat, maxlon)
+ tiles = tiles_for_area(minlat, minlon, maxlat, maxlon)
+ first = last = nil
+
+ tiles.sort.each do |tile|
+ if last.nil?
+ first = last = tile
+ elsif tile == last + 1
+ last = tile
+ else
+ yield first, last
+
+ first = last = tile
+ end
+ end
+
+ yield first, last unless last.nil?
+ end
+
+ private_class_method :tile_for_xy, :iterate_tiles_for_area
+end
--- /dev/null
+require "mkmf"
+
+create_makefile("quad_tile_so")
--- /dev/null
+#include "ruby.h"
+#include "quad_tile.h"
+
+static VALUE tile_for_point(VALUE self, VALUE lat, VALUE lon)
+{
+ unsigned int x = lon2x(NUM2DBL(lon));
+ unsigned int y = lat2y(NUM2DBL(lat));
+
+ return UINT2NUM(xy2tile(x, y));
+}
+
+static VALUE tiles_for_area(VALUE self, VALUE minlat, VALUE minlon, VALUE maxlat, VALUE maxlon)
+{
+ unsigned int minx = lon2x(NUM2DBL(minlon));
+ unsigned int maxx = lon2x(NUM2DBL(maxlon));
+ unsigned int miny = lat2y(NUM2DBL(minlat));
+ unsigned int maxy = lat2y(NUM2DBL(maxlat));
+ VALUE tiles = rb_ary_new();
+ unsigned int x;
+ unsigned int y;
+
+ for (x = minx; x <= maxx; x++)
+ {
+ for (y = miny; y <= maxy; y++)
+ {
+ rb_ary_push(tiles, UINT2NUM(xy2tile(x, y)));
+ }
+ }
+
+ return tiles;
+}
+
+static VALUE tile_for_xy(VALUE self, VALUE x, VALUE y)
+{
+ return UINT2NUM(xy2tile(NUM2UINT(x), NUM2UINT(y)));
+}
+
+void Init_quad_tile_so(void)
+{
+ VALUE m = rb_define_module("QuadTile");
+
+ rb_define_module_function(m, "tile_for_point", tile_for_point, 2);
+ rb_define_module_function(m, "tiles_for_area", tiles_for_area, 4);
+ rb_define_module_function(m, "tile_for_xy", tile_for_xy, 2);
+
+ return;
+}
--- /dev/null
+#include <math.h>
+
+inline unsigned int xy2tile(unsigned int x, unsigned int y)
+{
+ unsigned int tile = 0;
+ int i;
+
+ for (i = 15; i >= 0; i--)
+ {
+ tile = (tile << 1) | ((x >> i) & 1);
+ tile = (tile << 1) | ((y >> i) & 1);
+ }
+
+ return tile;
+}
+
+inline unsigned int lon2x(double lon)
+{
+ return round((lon + 180.0) * 65535.0 / 360.0);
+}
+
+inline unsigned int lat2y(double lat)
+{
+ return round((lat + 90.0) * 65535.0 / 180.0);
+}
t1:
+ id: 1
+ member_role: "some"
+ member_type: "way"
+ member_id: 3
+
+t2:
id: 1
member_role: "some"
member_type: "node"
+ member_id: 5
+
+t3:
+ id: 1
+ member_role: "some"
+ member_type: "relation"
member_id: 3
+
+t4:
+ id: 3
+ member_role: "some"
+ member_type: "node"
+ member_id: 5
id: 2
k: test
v: yes
+
+t2:
+ id: 3
+ k: test
+ v: yes
user_id: 1
timestamp: 2007-01-01 00:00:00
visible: 0
+
+used_relation:
+ id: 3
+ user_id: 1
+ timestamp: 2007-01-01 00:00:00
+ visible: 1
t1:
+ id: 1
+ member_role: "some"
+ member_type: "way"
+ member_id: 3
+ version: 1
+t2:
id: 1
member_role: "some"
member_type: "node"
+ member_id: 5
+ version: 1
+t3:
+ id: 1
+ member_role: "some"
+ member_type: "relation"
member_id: 3
version: 1
+t4:
+ id: 3
+ member_role: "some"
+ member_type: "node"
+ member_id: 5
+ version: 1
k: test
v: yes
version: 1
+
+t3:
+ id: 3
+ k: test
+ v: yes
+ version: 1
timestamp: 2007-01-01 00:00:00
visible: 0
version: 1
+
+used_relation:
+ id: 3
+ user_id: 1
+ timestamp: 2007-01-01 00:00:00
+ visible: 1
+ version: 1
assert_response :not_found
# check the "relations for node" mode
- get :relations_for_node, :id => current_nodes(:used_node_1).id
+ get :relations_for_node, :id => current_nodes(:node_used_by_relationship).id
assert_response :success
# FIXME check whether this contains the stuff we want!
if $VERBOSE
# check the "relations for relation" mode
- get :relations_for_node, :id => current_relations(:used_relation).id
+ get :relations_for_relation, :id => current_relations(:used_relation).id
assert_response :success
# FIXME check whether this contains the stuff we want!
if $VERBOSE
end
# check the "full" mode
- get :full, :id => current_relations(:relation_using_all).id
+ get :full, :id => current_relations(:visible_relation).id
assert_response :success
# FIXME check whether this contains the stuff we want!
if $VERBOSE
:user_id => users(:normal_user).id,
:visible => 1,
:tags => "")
- assert node_template.save_with_history
+ assert node_template.save_with_history!
node = Node.find(node_template.id)
assert_not_nil node
node_template.latitude = 12.3456
node_template.longitude = 65.4321
node_template.tags = "updated=yes"
- assert node_template.save_with_history
+ assert node_template.save_with_history!
node = Node.find(node_template.id)
assert_not_nil node
assert_not_nil old_node_template
node_template.visible = 0
- assert node_template.save_with_history
+ assert node_template.save_with_history!
node = Node.find(node_template.id)
assert_not_nil node