class AmfController < ApplicationController
require 'stringio'
+ before_filter :check_availability
+
# to log:
# RAILS_DEFAULT_LOGGER.error("Args: #{args[0]}, #{args[1]}, #{args[2]}, #{args[3]}")
disused railway tracks: railway=disused
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
+
point/road
mini roundabout: highway=mini_roundabout
traffic lights: highway=traffic_signals
station: railway=station
viaduct: railway=viaduct
level crossing: railway=crossing
+
+point/natural
+peak: natural=peak
EOF
StringIO.open(txt) do |file|
# compare node
if node<0
# new node - create
- newnode=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes ( latitude,longitude,timestamp,user_id,visible,tags) VALUES ( #{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
- ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{newnode},#{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
- points[i][2]=newnode
- renumberednodes[node.to_s]=newnode.to_s
+ if renumberednodes[node.to_s].nil?
+ newnode=ActiveRecord::Base.connection.insert("INSERT INTO current_nodes ( latitude,longitude,timestamp,user_id,visible,tags) VALUES ( #{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
+ ActiveRecord::Base.connection.insert("INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tags) VALUES (#{newnode},#{ys},#{xs},#{db_now},#{uid},1,#{tagsql})")
+ points[i][2]=newnode
+ renumberednodes[node.to_s]=newnode.to_s
+ else
+ points[i][2]=renumberednodes[node.to_s].to_i
+ end
elsif xc.has_key?(node)
# old node from original way - update
# returns way made from unwayed segments
def makeway(args)
- x,y,baselong,basey,masterscale=args
+ usertoken,x,y,baselong,basey,masterscale=args
+ uid=getuserid(usertoken)
+ return if !uid
+
points=[]
+ toreverse=[] # segments to reverse
nodesused={} # so we don't go over the same node twice
# - find start point near x
xc=coord2long(x,masterscale,baselong)
yc=coord2lat(y,masterscale,basey)
+
+ RAILS_DEFAULT_LOGGER.info(" Message: makeway, xc=#{xc}, y=#{yc}")
+
xs1=xc-0.001; xs2=xc+0.001
ys1=yc-0.001; ys2=yc+0.001
WHERE (cn1.longitude BETWEEN #{xs1} AND #{xs2})
AND (cn1.latitude BETWEEN #{ys1} AND #{ys2})
AND segment_id IS NULL
+ AND cs.visible=1
AND cn1.id=node_a AND cn1.visible=1
AND cn2.id=node_b AND cn2.visible=1
- ORDER BY SQRT(POW(cn1.longitude-#{xc},2)+
+ ORDER BY SQRT(POW(cn1.longitude-#{xc},2)+
POW(cn1.latitude -#{yc},2))
LIMIT 1
EOF
points<<[xs2,ys2,row['id2'].to_i,1,{},row['segid'].to_i]
# - extend at start, then end
- while (a,point,nodesused=findconnect(points[0][2],nodesused,'b',baselong,basey,masterscale))[0]
+ while (a,point,nodesused,toreverse=findconnect(points[0][2],nodesused,'b',toreverse,baselong,basey,masterscale))[0]
points[0][5]=point[5]; point[5]=0 # segment leads to next node
points.unshift(point)
xmin=[point[0],xmin].min; xmax=[point[0],xmax].max
ymin=[point[1],ymin].min; ymax=[point[1],ymax].max
end
- while (a,point,nodesused=findconnect(points[-1][2],nodesused,'a',baselong,basey,masterscale))[0]
+ while (a,point,nodesused,toreverse=findconnect(points[-1][2],nodesused,'a',toreverse,baselong,basey,masterscale))[0]
points.push(point)
xmin=[point[0],xmin].min; xmax=[point[0],xmax].max
ymin=[point[1],ymin].min; ymax=[point[1],ymax].max
end
points[0][3]=0 # start with a move
+ # reverse segments in toreverse
+ if toreverse.length>0
+ sql=<<-EOF
+ UPDATE current_segments c1, current_segments c2
+ SET c1.node_a=c2.node_b,c1.node_b=c2.node_a,
+ c1.timestamp=NOW(),c1.user_id=#{uid}
+ WHERE c1.id=c2.id
+ AND c1.id IN (#{toreverse.join(',')})
+ EOF
+ ActiveRecord::Base.connection.update sql
+ sql=<<-EOF
+ INSERT INTO segments
+ (SELECT * FROM current_segments
+ WHERE id IN (#{toreverse.join(',')}))
+ EOF
+ ActiveRecord::Base.connection.insert sql
+ end
+
[points,xmin,xmax,ymin,ymax]
end
-def findconnect(id,nodesused,lookfor,baselong,basey,masterscale)
+def findconnect(id,nodesused,lookfor,toreverse,baselong,basey,masterscale)
# get all segments with 'id' as a point
# (to look for both node_a and node_b, UNION is faster than node_a=id OR node_b=id)!
sql=<<-EOF
current_segments AS cs
LEFT OUTER JOIN current_way_segments ON segment_id=cs.id
WHERE segment_id IS NULL
+ AND cs.visible=1
AND cn1.id=node_a AND cn1.visible=1
AND cn2.id=node_b AND cn2.visible=1
AND node_a=#{id}
current_segments AS cs
LEFT OUTER JOIN current_way_segments ON segment_id=cs.id
WHERE segment_id IS NULL
+ AND cs.visible=1
AND cn1.id=node_a AND cn1.visible=1
AND cn2.id=node_b AND cn2.visible=1
AND node_b=#{id}
EOF
connectlist=ActiveRecord::Base.connection.select_all sql
- if lookfor=='b' then tocol='id1'; tolat='lat1'; tolon='lon1'; fromcol='id2'
- else tocol='id2'; tolat='lat2'; tolon='lon2'; fromcol='id1'
+ if lookfor=='b' then tocol='id1'; tolat='lat1'; tolon='lon1'; fromcol='id2'; fromlat='lat2'; fromlon='lon2'
+ else tocol='id2'; tolat='lat2'; tolon='lon2'; fromcol='id1'; fromlat='lat1'; fromlon='lon1'
end
# eliminate those already in the hash
tonode=row[tocol].to_i
fromnode=row[fromcol].to_i
if id==tonode and !nodesused.has_key?(fromnode)
+ # wrong way round; add, then add to 'segments to reverse' list
connex+=1
nodesused[fromnode]=true
+ point=[long2coord(row[fromlon].to_f,baselong,masterscale),lat2coord(row[fromlat].to_f,basey,masterscale),fromnode,1,{},row['segid'].to_i]
+ toreverse.push(row['segid'].to_i)
elsif id==fromnode and !nodesused.has_key?(tonode)
+ # right way round; just add
connex+=1
point=[long2coord(row[tolon].to_f,baselong,masterscale),lat2coord(row[tolat].to_f,basey,masterscale),tonode,1,{},row['segid'].to_i]
nodesused[tonode]=true
# if only one left, then add it; otherwise return false
if connex!=1 or point.nil? then
- return [false,[],nodesused]
+ return [false,[],nodesused,toreverse]
else
- return [true,point,nodesused]
+ return [true,point,nodesused,toreverse]
end
end