Potlatch 0.8 - be afraid, be very, very afraid
This commit is contained in:
parent
d0aa199e92
commit
ae142c554b
6 changed files with 163 additions and 23 deletions
|
@ -30,6 +30,7 @@ class AmfController < ApplicationController
|
|||
req.read(2) # Skip version indicator and client ID
|
||||
results={} # Results of each body
|
||||
renumberednodes={} # Shared across repeated putways
|
||||
renumberedways={} # Shared across repeated putways
|
||||
|
||||
# -------------
|
||||
# Parse request
|
||||
|
@ -55,11 +56,16 @@ class AmfController < ApplicationController
|
|||
when 'whichways'; results[index]=AMF.putdata(index,whichways(args))
|
||||
when 'whichways_deleted'; results[index]=AMF.putdata(index,whichways_deleted(args))
|
||||
when 'getway'; results[index]=AMF.putdata(index,getway(args))
|
||||
when 'getrelation'; results[index]=AMF.putdata(index,getrelation(args))
|
||||
when 'getway_old'; results[index]=AMF.putdata(index,getway_old(args))
|
||||
when 'getway_history'; results[index]=AMF.putdata(index,getway_history(args))
|
||||
when 'putway'; r=putway(args,renumberednodes)
|
||||
renumberednodes=r[3]
|
||||
if r[1] != r[2]
|
||||
renumberedways[r[1]] = r[2]
|
||||
end
|
||||
results[index]=AMF.putdata(index,r)
|
||||
when 'putrelation'; results[index]=AMF.putdata(index,putrelation(args, renumberednodes, renumberedways))
|
||||
when 'deleteway'; results[index]=AMF.putdata(index,deleteway(args))
|
||||
when 'putpoi'; results[index]=AMF.putdata(index,putpoi(args))
|
||||
when 'getpoi'; results[index]=AMF.putdata(index,getpoi(args))
|
||||
|
@ -116,7 +122,10 @@ class AmfController < ApplicationController
|
|||
nodes_not_used_in_area = nodes_in_area.select { |node| node.ways.empty? }
|
||||
points = nodes_not_used_in_area.collect { |n| [n.id, n.lon_potlatch(baselong,masterscale), n.lat_potlatch(basey,masterscale), n.tags_as_hash] }
|
||||
|
||||
[way_ids,points]
|
||||
# find the relations used by those nodes and ways
|
||||
relation_ids = Relation.find_for_nodes_and_ways(nodes_in_area.collect {|n| n.id}, way_ids).collect {|n| n.id}.uniq
|
||||
|
||||
[way_ids,points,relation_ids]
|
||||
end
|
||||
|
||||
# ----- whichways_deleted
|
||||
|
@ -264,6 +273,80 @@ class AmfController < ApplicationController
|
|||
[history]
|
||||
end
|
||||
|
||||
# ----- getrelation
|
||||
# Get a relation with all of it's tags, and member IDs
|
||||
# The input is an array with the following components, in order:
|
||||
# 0. relid - the ID of the relation to get
|
||||
#
|
||||
# The output is an array which contains:
|
||||
# [0] relation id, [1] hash of tags, [2] list of members
|
||||
def getrelation(args) #:doc:
|
||||
relid = args[0]
|
||||
relid = relid.to_i
|
||||
|
||||
RAILS_DEFAULT_LOGGER.info(" Message: getrel, id=#{relid}")
|
||||
|
||||
rel = Relation.find(relid)
|
||||
|
||||
[relid,rel.tags,rel.members]#nodes,ways]
|
||||
end
|
||||
|
||||
# ----- getrelation
|
||||
# save relation to the database
|
||||
# in: [0] user token (string),
|
||||
# [1] original relation id (may be negative),
|
||||
# [2] hash of tags, [3] list of members,
|
||||
# [4] visible
|
||||
# out: [0] 0 (success), [1] original relation id (unchanged),
|
||||
# [2] new relation id
|
||||
def putrelation(args, renumberednodes, renumberedways) #:doc:
|
||||
usertoken,relid,tags,members,visible=args
|
||||
uid=getuserid(usertoken)
|
||||
if !uid then return -1,"You are not logged in, so the point could not be saved." end
|
||||
|
||||
relid = relid.to_i
|
||||
visible = visible.to_i
|
||||
|
||||
# create a new relation, or find the existing one
|
||||
if relid <= 0
|
||||
rel = Relation.new
|
||||
else
|
||||
rel = Relation.find(relid)
|
||||
end
|
||||
|
||||
# check the members are all positive, and correctly type
|
||||
typedmembers = []
|
||||
members.each do |m|
|
||||
mid = m[1].to_i
|
||||
if mid < 0
|
||||
mid = renumberednodes[mid] if m[0] == 'node'
|
||||
mid = renumberedways[mid] if m[0] == 'way'
|
||||
if mid < 0
|
||||
return -2, "Negative ID unresolved"
|
||||
end
|
||||
end
|
||||
typedmembers << [m[0], mid, m[2]]
|
||||
end
|
||||
|
||||
# assign new contents
|
||||
rel.members = typedmembers
|
||||
rel.tags = tags
|
||||
rel.visible = visible
|
||||
rel.user_id = uid
|
||||
|
||||
# check it then save it
|
||||
# BUG: the following is commented out because it always fails on my
|
||||
# install. I think it's a Rails bug.
|
||||
|
||||
#if !rel.preconditions_ok?
|
||||
# return -2, "Relation preconditions failed"
|
||||
#else
|
||||
rel.save_with_history!
|
||||
#end
|
||||
|
||||
[0,relid,rel.id]
|
||||
end
|
||||
|
||||
# ----- putway
|
||||
# saves a way to the database
|
||||
# in: [0] user token (string),
|
||||
|
@ -487,7 +570,7 @@ class AmfController < ApplicationController
|
|||
|
||||
n = Node.find(id.to_i)
|
||||
if n
|
||||
return [n.id, n.long_potlatch(baselong,masterscale), n.lat_potlatch(basey,masterscale), n.tags_as_hash]
|
||||
return [n.id, n.lon_potlatch(baselong,masterscale), n.lat_potlatch(basey,masterscale), n.tags_as_hash]
|
||||
else
|
||||
return [nil,nil,nil,'']
|
||||
end
|
||||
|
@ -500,18 +583,52 @@ class AmfController < ApplicationController
|
|||
# also removes ways/nodes from any relations they're in
|
||||
# out: [0] 0 (success), [1] way id (unchanged)
|
||||
def deleteway(args) #:doc:
|
||||
usertoken,way_id=args
|
||||
RAILS_DEFAULT_LOGGER.info(" Message: deleteway, id=#{way_id}")
|
||||
|
||||
usertoken,way=args
|
||||
|
||||
RAILS_DEFAULT_LOGGER.info(" Message: deleteway, id=#{way}")
|
||||
uid=getuserid(usertoken)
|
||||
if !uid then return -1,"You are not logged in, so the way could not be deleted." end
|
||||
|
||||
user = User.find(uid)
|
||||
way=way.to_i
|
||||
db_uqn='unin'+(rand*100).to_i.to_s+uid.to_s+way.to_i.abs.to_s+Time.new.to_i.to_s # temp uniquenodes table name, typically 51 chars
|
||||
db_now='@now'+(rand*100).to_i.to_s+uid.to_s+way.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()")
|
||||
|
||||
way = Way.find(way_id)
|
||||
# - delete any otherwise unused nodes
|
||||
|
||||
way.delete_with_relations_and_nodes_and_history(user)
|
||||
createuniquenodes(way,db_uqn,[])
|
||||
|
||||
return [0,way_id]
|
||||
# unless (preserve.empty?) then
|
||||
# ActiveRecord::Base.connection.execute("DELETE FROM #{db_uqn} WHERE node_id IN ("+preserve.join(',')+")")
|
||||
# end
|
||||
|
||||
sql=<<-EOF
|
||||
INSERT INTO nodes (id,latitude,longitude,timestamp,user_id,visible,tile)
|
||||
SELECT DISTINCT cn.id,cn.latitude,cn.longitude,#{db_now},#{uid},0,cn.tile
|
||||
FROM current_nodes AS cn,#{db_uqn}
|
||||
WHERE cn.id=node_id
|
||||
EOF
|
||||
ActiveRecord::Base.connection.insert(sql)
|
||||
|
||||
sql=<<-EOF
|
||||
UPDATE current_nodes AS cn, #{db_uqn}
|
||||
SET cn.timestamp=#{db_now},cn.visible=0,cn.user_id=#{uid}
|
||||
WHERE cn.id=node_id
|
||||
EOF
|
||||
ActiveRecord::Base.connection.update(sql)
|
||||
|
||||
deleteuniquenoderelations(db_uqn,uid,db_now)
|
||||
ActiveRecord::Base.connection.execute("DROP TEMPORARY TABLE #{db_uqn}")
|
||||
|
||||
# - delete way
|
||||
|
||||
ActiveRecord::Base.connection.insert("INSERT INTO ways (id,user_id,timestamp,visible) VALUES (#{way},#{uid},#{db_now},0)")
|
||||
ActiveRecord::Base.connection.update("UPDATE current_ways SET user_id=#{uid},timestamp=#{db_now},visible=0 WHERE id=#{way}")
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_nodes WHERE id=#{way}")
|
||||
ActiveRecord::Base.connection.execute("DELETE FROM current_way_tags WHERE id=#{way}")
|
||||
deleteitemrelations(way,'way',uid,db_now)
|
||||
[0,way]
|
||||
end
|
||||
|
||||
def readwayquery(id,insistonvisible) #:doc:
|
||||
|
|
|
@ -169,20 +169,8 @@ class ApiController < ApplicationController
|
|||
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 = Array.new
|
||||
if visible_nodes.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='node' and em.member_id in (#{visible_nodes.keys.join(',')})")
|
||||
end
|
||||
if way_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='way' and em.member_id in (#{way_ids.join(',')})")
|
||||
end
|
||||
relations = Relation.find_for_nodes_and_ways(visible_nodes.keys, way_ids)
|
||||
|
||||
# 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
|
||||
|
|
|
@ -102,6 +102,24 @@ class Relation < ActiveRecord::Base
|
|||
return el1
|
||||
end
|
||||
|
||||
def self.find_for_nodes_and_ways(node_ids, way_ids)
|
||||
# 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 = Array.new
|
||||
if node_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='node' and em.member_id in (#{node_ids.join(',')})")
|
||||
end
|
||||
if way_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='way' and em.member_id in (#{way_ids.join(',')})")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# FIXME is this really needed?
|
||||
def members
|
||||
unless @members
|
||||
|
|
3
config/potlatch/relation_colours.txt
Normal file
3
config/potlatch/relation_colours.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
# Potlatch relations colours file
|
||||
# each line must be tab-separated: tag, colour, alpha, width
|
||||
|
|
@ -168,6 +168,20 @@ module Potlatch
|
|||
}
|
||||
end
|
||||
|
||||
# Read relations colours/styling
|
||||
relcolours={}; relalphas={}; relwidths={}
|
||||
File.open("#{RAILS_ROOT}/config/potlatch/relation_colours.txt") do |file|
|
||||
file.each_line {|line|
|
||||
t=line.chomp
|
||||
if (t=~/(\w+)\s+([^\s]+)\s+([^\s]+)\s+([^\s]+)/) then
|
||||
tag=$1
|
||||
if ($2!='-') then relcolours[tag]=$2.hex end
|
||||
if ($3!='-') then relalphas[tag]=$3.to_i end
|
||||
if ($4!='-') then relwidths[tag]=$4.to_i end
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
# Read auto-complete
|
||||
autotags={}; autotags['point']={}; autotags['way']={}; autotags['POI']={};
|
||||
File.open("#{RAILS_ROOT}/config/potlatch/autocomplete.txt") do |file|
|
||||
|
@ -181,7 +195,7 @@ module Potlatch
|
|||
}
|
||||
end
|
||||
|
||||
[presets,presetmenus,presetnames,colours,casing,areas,autotags]
|
||||
[presets,presetmenus,presetnames,colours,casing,areas,autotags,relcolours,relalphas,relwidths]
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Add table
Reference in a new issue