# Main AMF handlers: process the raw AMF string (using AMF library) and
# calls each action (private method) accordingly.
def amf_read
self.status = :ok
# Main AMF handlers: process the raw AMF string (using AMF library) and
# calls each action (private method) accordingly.
def amf_read
self.status = :ok
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
logger.info("Executing AMF #{message}(#{args.join(',')})")
case message
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
logger.info("Executing AMF #{message}(#{args.join(',')})")
case message
- when 'getpresets' then result = getpresets(*args)
- when 'whichways' then result = whichways(*args)
- when 'whichways_deleted' then result = whichways_deleted(*args)
- when 'getway' then result = getway(args[0].to_i)
- when 'getrelation' then result = getrelation(args[0].to_i)
- when 'getway_old' then result = getway_old(args[0].to_i, args[1])
- when 'getway_history' then result = getway_history(args[0].to_i)
- when 'getnode_history' then result = getnode_history(args[0].to_i)
- when 'findgpx' then result = findgpx(*args)
- when 'findrelations' then result = findrelations(*args)
- when 'getpoi' then result = getpoi(*args)
+ when "getpresets" then result = getpresets(*args)
+ when "whichways" then result = whichways(*args)
+ when "whichways_deleted" then result = whichways_deleted(*args)
+ when "getway" then result = getway(args[0].to_i)
+ when "getrelation" then result = getrelation(args[0].to_i)
+ when "getway_old" then result = getway_old(args[0].to_i, args[1])
+ when "getway_history" then result = getway_history(args[0].to_i)
+ when "getnode_history" then result = getnode_history(args[0].to_i)
+ when "findgpx" then result = findgpx(*args)
+ when "findrelations" then result = findrelations(*args)
+ when "getpoi" then result = getpoi(*args)
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
logger.info("Executing AMF #{message}")
self.response_body = Dispatcher.new(request.raw_post) do |message, *args|
logger.info("Executing AMF #{message}")
- when 'putway' then orn = renumberednodes.dup
- result = putway(renumberednodes, *args)
- result[4] = renumberednodes.reject { |k, _v| orn.key?(k) }
- if result[0] == 0 && result[2] != result[3] then renumberedways[result[2]] = result[3] end
- when 'putrelation' then result = putrelation(renumberednodes, renumberedways, *args)
- when 'deleteway' then result = deleteway(*args)
- when 'putpoi' then result = putpoi(*args)
- if result[0] == 0 && result[2] != result[3] then renumberednodes[result[2]] = result[3] end
- when 'startchangeset' then result = startchangeset(*args)
+ when "putway" then
+ orn = renumberednodes.dup
+ result = putway(renumberednodes, *args)
+ result[4] = renumberednodes.reject { |k, _v| orn.key?(k) }
+ renumberedways[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
+ when "putrelation" then
+ result = putrelation(renumberednodes, renumberedways, *args)
+ when "deleteway" then
+ result = deleteway(*args)
+ when "putpoi" then
+ result = putpoi(*args)
+ renumberednodes[result[2]] = result[3] if result[0].zero? && result[2] != result[3]
+ when "startchangeset" then
+ result = startchangeset(*args)
return [-2, "Sorry - I can't get the map for that area. The server said: #{ex}"]
rescue OSM::APIError => ex
return [-1, ex.to_s]
return [-2, "Sorry - I can't get the map for that area. The server said: #{ex}"]
rescue OSM::APIError => ex
return [-1, ex.to_s]
def startchangeset(usertoken, cstags, closeid, closecomment, opennew)
amf_handle_error("'startchangeset'", nil, nil) do
user = getuser(usertoken)
def startchangeset(usertoken, cstags, closeid, closecomment, opennew)
amf_handle_error("'startchangeset'", nil, nil) do
user = getuser(usertoken)
- unless user then return -1, "You are not logged in, so Potlatch can't write any changes to the database." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
- if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? then return -1, "You must accept the contributor terms before you can edit." end
+ return -1, "You are not logged in, so Potlatch can't write any changes to the database." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
+ return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil?
# Return presets (default tags, localisation etc.):
# uses POTLATCH_PRESETS global, set up in OSM::Potlatch.
# Return presets (default tags, localisation etc.):
# uses POTLATCH_PRESETS global, set up in OSM::Potlatch.
- if user && !user.languages.empty?
- http_accept_language.user_preferred_languages = user.languages
- end
+ langs = if user && !user.languages.empty?
+ Locale.list(user.languages)
+ else
+ Locale.list(http_accept_language.user_preferred_languages)
+ end
- lang = http_accept_language.compatible_language_from(getlocales)
- (real_lang, localised) = getlocalized(lang)
+ lang = getlocales.preferred(langs)
+ (real_lang, localised) = getlocalized(lang.to_s)
# nodes in the bbox, nodes are any visible nodes in the bbox but not
# used in any way, rel is any relation which refers to either a way
# or node that we're returning.
# nodes in the bbox, nodes are any visible nodes in the bbox but not
# used in any way, rel is any relation which refers to either a way
# or node that we're returning.
- def whichways(xmin, ymin, xmax, ymax) #:doc:
+ def whichways(xmin, ymin, xmax, ymax)
amf_handle_error_with_timeout("'whichways'", nil, nil) do
enlarge = [(xmax - xmin) / 8, 0.01].min
amf_handle_error_with_timeout("'whichways'", nil, nil) do
enlarge = [(xmax - xmin) / 8, 0.01].min
- [0, '', ways, points, relations]
+ [0, "", ways, points, relations]
end
end
# Find deleted ways in current bounding box (similar to whichways, but ways
# with a deleted node only - not POIs or relations).
end
end
# Find deleted ways in current bounding box (similar to whichways, but ways
# with a deleted node only - not POIs or relations).
- def whichways_deleted(xmin, ymin, xmax, ymax) #:doc:
+ def whichways_deleted(xmin, ymin, xmax, ymax)
amf_handle_error_with_timeout("'whichways_deleted'", nil, nil) do
enlarge = [(xmax - xmin) / 8, 0.01].min
amf_handle_error_with_timeout("'whichways_deleted'", nil, nil) do
enlarge = [(xmax - xmin) / 8, 0.01].min
nodes_in_area = Node.bbox(bbox).joins(:ways_via_history).where(:current_ways => { :visible => false })
way_ids = nodes_in_area.collect { |node| node.ways_via_history.invisible.collect(&:id) }.flatten.uniq
nodes_in_area = Node.bbox(bbox).joins(:ways_via_history).where(:current_ways => { :visible => false })
way_ids = nodes_in_area.collect { |node| node.ways_via_history.invisible.collect(&:id) }.flatten.uniq
end
end
# Get a way including nodes and tags.
# Returns the way id, a Potlatch-style array of points, a hash of tags, the version number, and the user ID.
end
end
# Get a way including nodes and tags.
# Returns the way id, a Potlatch-style array of points, a hash of tags, the version number, and the user ID.
- def getway(wayid) #:doc:
- amf_handle_error_with_timeout("'getway' #{wayid}", 'way', wayid) do
+ def getway(wayid)
+ amf_handle_error_with_timeout("'getway' #{wayid}", "way", wayid) do
[node.lon, node.lat, node.id, nodetags, node.version]
end
tags = way.tags
[node.lon, node.lat, node.id, nodetags, node.version]
end
tags = way.tags
- [0, '', wayid, points, tags, version, uid]
+ [0, "", wayid, points, tags, version, uid]
- def getway_old(id, timestamp) #:doc:
- amf_handle_error_with_timeout("'getway_old' #{id}, #{timestamp}", 'way', id) do
- if timestamp == ''
+ def getway_old(id, timestamp)
+ amf_handle_error_with_timeout("'getway_old' #{id}, #{timestamp}", "way", id) do
+ if timestamp == ""
# undelete
old_way = OldWay.where(:visible => true, :way_id => id).unredacted.order("version DESC").first
points = old_way.get_nodes_undelete unless old_way.nil?
else
begin
# revert
# undelete
old_way = OldWay.where(:visible => true, :way_id => id).unredacted.order("version DESC").first
points = old_way.get_nodes_undelete unless old_way.nil?
else
begin
# revert
old_way = OldWay.where("way_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first
unless old_way.nil?
old_way = OldWay.where("way_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first
unless old_way.nil?
return [-1, "Sorry, the way was deleted at that time - please revert to a previous version.", id]
end
end
rescue ArgumentError
# thrown by date parsing method. leave old_way as nil for
# the error handler below.
return [-1, "Sorry, the way was deleted at that time - please revert to a previous version.", id]
end
end
rescue ArgumentError
# thrown by date parsing method. leave old_way as nil for
# the error handler below.
return [-1, "Sorry, the server could not find a way at that time.", id]
else
curway = Way.find(id)
return [-1, "Sorry, the server could not find a way at that time.", id]
else
curway = Way.find(id)
- old_way.tags['history'] = "Retrieved from v#{old_way.version}"
- return [0, '', id, points, old_way.tags, curway.version, (curway.version == old_way.version && curway.visible)]
+ old_way.tags["history"] = "Retrieved from v#{old_way.version}"
+ return [0, "", id, points, old_way.tags, curway.version, (curway.version == old_way.version && curway.visible)]
history = Node.find(nodeid).old_nodes.unredacted.reverse.collect do |old_node|
[(old_node.timestamp + 1).strftime("%d %b %Y, %H:%M:%S")] + change_user(old_node)
end
history = Node.find(nodeid).old_nodes.unredacted.reverse.collect do |old_node|
[(old_node.timestamp + 1).strftime("%d %b %Y, %H:%M:%S")] + change_user(old_node)
end
def findgpx(searchterm, usertoken)
amf_handle_error_with_timeout("'findgpx'", nil, nil) do
user = getuser(usertoken)
def findgpx(searchterm, usertoken)
amf_handle_error_with_timeout("'findgpx'", nil, nil) do
user = getuser(usertoken)
- unless user then return -1, "You must be logged in to search for GPX traces." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
+
+ return -1, "You must be logged in to search for GPX traces." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
- if searchterm.to_i > 0
- query = query.where(:id => searchterm.to_i)
- else
- query = query.where("MATCH(name) AGAINST (?)", searchterm).limit(21)
- end
+ query = if searchterm.to_i > 0
+ query.where(:id => searchterm.to_i)
+ else
+ query.where("MATCH(name) AGAINST (?)", searchterm).limit(21)
+ end
gpxs = query.collect do |gpx|
[gpx.id, gpx.name, gpx.description]
end
gpxs = query.collect do |gpx|
[gpx.id, gpx.name, gpx.description]
end
- def getrelation(relid) #:doc:
- amf_handle_error("'getrelation' #{relid}", 'relation', relid) do
+ def getrelation(relid)
+ amf_handle_error("'getrelation' #{relid}", "relation", relid) do
- return [-4, 'relation', relid] if rel.nil? || !rel.visible
- [0, '', relid, rel.tags, rel.members, rel.version]
+ return [-4, "relation", relid] if rel.nil? || !rel.visible
+ [0, "", relid, rel.tags, rel.members, rel.version]
- def putrelation(renumberednodes, renumberedways, usertoken, changeset_id, version, relid, tags, members, visible) #:doc:
- amf_handle_error("'putrelation' #{relid}", 'relation', relid) do
+ def putrelation(renumberednodes, renumberedways, usertoken, changeset_id, version, relid, tags, members, visible)
+ amf_handle_error("'putrelation' #{relid}", "relation", relid) do
- unless user then return -1, "You are not logged in, so the relation could not be saved." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
- if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? then return -1, "You must accept the contributor terms before you can edit." end
- unless tags_ok(tags) then return -1, "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1." end
+ return -1, "You are not logged in, so the relation could not be saved." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
+ return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil?
+
+ return -1, "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1." unless tags_ok(tags)
# We always need a new node, based on the data that has been sent to us
new_relation = Relation.new
# We always need a new node, based on the data that has been sent to us
new_relation = Relation.new
end
if mid
typedmembers << [m[0], mid, m[2].delete("\000-\037\ufffe\uffff", "^\011\012\015")]
end
if mid
typedmembers << [m[0], mid, m[2].delete("\000-\037\ufffe\uffff", "^\011\012\015")]
- return [0, '', relid, new_relation.id, new_relation.version]
+ return [0, "", relid, new_relation.id, new_relation.version]
- return [0, '', relid, relid, relation.version]
+ return [0, "", relid, relid, relation.version]
- def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes) #:doc:
- amf_handle_error("'putway' #{originalway}", 'way', originalway) do
+ def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes)
+ amf_handle_error("'putway' #{originalway}", "way", originalway) do
- unless user then return -1, "You are not logged in, so the way could not be saved." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
- if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? then return -1, "You must accept the contributor terms before you can edit." end
+ return -1, "You are not logged in, so the way could not be saved." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
+ return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil?
- if id == 0 then return -2, "Server error - node with id 0 found in way #{originalway}." end
- if lat == 90 then return -2, "Server error - node with latitude -90 found in way #{originalway}." end
- if renumberednodes[id] then id = renumberednodes[id] end
+ return -2, "Server error - node with id 0 found in way #{originalway}." if id.zero?
+ return -2, "Server error - node with latitude -90 found in way #{originalway}." if lat == 90
+
+ id = renumberednodes[id] if renumberednodes[id]
- [0, '', originalway, way.id, renumberednodes, way.version, nodeversions, deletednodes]
+ [0, "", originalway, way.id, renumberednodes, way.version, nodeversions, deletednodes]
- def putpoi(usertoken, changeset_id, version, id, lon, lat, tags, visible) #:doc:
- amf_handle_error("'putpoi' #{id}", 'node', id) do
+ def putpoi(usertoken, changeset_id, version, id, lon, lat, tags, visible)
+ amf_handle_error("'putpoi' #{id}", "node", id) do
- unless user then return -1, "You are not logged in, so the point could not be saved." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
- if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? then return -1, "You must accept the contributor terms before you can edit." end
+ return -1, "You are not logged in, so the point could not be saved." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
+ return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil?
- unless visible
- unless node.ways.empty? then return -1, "Point #{id} has since become part of a way, so you cannot save it as a POI.", id, id, version end
+ unless visible || node.ways.empty?
+ return -1, "Point #{id} has since become part of a way, so you cannot save it as a POI.", id, id, version
- return [0, '', id, new_node.id, new_node.version]
+ return [0, "", id, new_node.id, new_node.version]
- return [0, '', id, node.id, node.version]
+ return [0, "", id, node.id, node.version]
#
# Returns array of id, long, lat, hash of tags, (current) version.
#
# Returns array of id, long, lat, hash of tags, (current) version.
- def getpoi(id, timestamp) #:doc:
- amf_handle_error("'getpoi' #{id}", 'node', id) do
+ def getpoi(id, timestamp)
+ amf_handle_error("'getpoi' #{id}", "node", id) do
- n = Node.find(id)
- v = n.version
- unless timestamp == ''
- n = OldNode.where("node_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first
+ n = Node.where(:id => id).first
+ if n
+ v = n.version
+ unless timestamp == ""
+ n = OldNode.where("node_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first
+ end
- return [0, '', n.id, n.lon, n.lat, n.tags, v]
+ return [0, "", id, n.lon, n.lat, n.tags, v]
# of the nodes have been changed by someone else then, there is a problem!
# Returns 0 (success), unchanged way id, new way version, new node versions.
# of the nodes have been changed by someone else then, there is a problem!
# Returns 0 (success), unchanged way id, new way version, new node versions.
- def deleteway(usertoken, changeset_id, way_id, way_version, deletednodes) #:doc:
- amf_handle_error("'deleteway' #{way_id}", 'way', way_id) do
+ def deleteway(usertoken, changeset_id, way_id, way_version, deletednodes)
+ amf_handle_error("'deleteway' #{way_id}", "way", way_id) do
- unless user then return -1, "You are not logged in, so the way could not be deleted." end
- if user.blocks.active.exists? then return -1, t('application.setup_user_auth.blocked') end
- if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? then return -1, "You must accept the contributor terms before you can edit." end
+ return -1, "You are not logged in, so the way could not be deleted." unless user
+ return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists?
+ return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil?
begin
node.delete_with_history!(new_node, user)
nodeversions[node.id] = node.version
begin
node.delete_with_history!(new_node, user)
nodeversions[node.id] = node.version
# We don't do anything with the exception as the node is in use
# elsewhere and we don't want to delete it
end
end
# We don't do anything with the exception as the node is in use
# elsewhere and we don't want to delete it
end
end
- end # transaction
- [0, '', way_id, old_way.version, nodeversions]
+ end
+ [0, "", way_id, old_way.version, nodeversions]
# When we are writing to the api, we need the actual user model,
# not just the id, hence this abstraction
# When we are writing to the api, we need the actual user model,
# not just the id, hence this abstraction
- Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") }
+ @locales ||= Locale.list(Dir.glob(Rails.root.join("config", "potlatch", "locales", "*")).collect { |f| File.basename(f, ".yml") })
SELECT DISTINCT current_ways.id AS wayid,current_ways.version AS version
FROM current_way_nodes
INNER JOIN current_nodes ON current_nodes.id=current_way_nodes.node_id
INNER JOIN current_ways ON current_ways.id =current_way_nodes.id
WHERE current_nodes.visible=TRUE
AND current_ways.visible=TRUE
SELECT DISTINCT current_ways.id AS wayid,current_ways.version AS version
FROM current_way_nodes
INNER JOIN current_nodes ON current_nodes.id=current_way_nodes.node_id
INNER JOIN current_ways ON current_ways.id =current_way_nodes.id
WHERE current_nodes.visible=TRUE
AND current_ways.visible=TRUE
- AND #{OSM.sql_for_area(bbox, "current_nodes.")}
- EOF
- ActiveRecord::Base.connection.select_all(sql).collect { |a| [a['wayid'].to_i, a['version'].to_i] }
+ AND #{OSM.sql_for_area(bbox, 'current_nodes.')}
+ SQL
+ ActiveRecord::Base.connection.select_all(sql).collect { |a| [a["wayid"].to_i, a["version"].to_i] }
SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lon,current_nodes.version
FROM current_nodes
LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
WHERE current_nodes.visible=TRUE
AND cwn.id IS NULL
SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lon,current_nodes.version
FROM current_nodes
LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
WHERE current_nodes.visible=TRUE
AND cwn.id IS NULL
ActiveRecord::Base.connection.select_all(sql).each do |row|
poitags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n|
ActiveRecord::Base.connection.select_all(sql).each do |row|
poitags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n|
- pois << [row['id'].to_i, row['lon'].to_f, row['lat'].to_f, poitags, row['version'].to_i]
+ pois << [row["id"].to_i, row["lon"].to_f, row["lat"].to_f, poitags, row["version"].to_i]
def sql_find_relations_in_area_and_ways(bbox, way_ids)
# ** It would be more Potlatchy to get relations for nodes within ways
# during 'getway', not here
def sql_find_relations_in_area_and_ways(bbox, way_ids)
# ** It would be more Potlatchy to get relations for nodes within ways
# during 'getway', not here
SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
INNER JOIN current_relation_members crm ON crm.id=cr.id
INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
INNER JOIN current_relation_members crm ON crm.id=cr.id
INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
UNION
SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
INNER JOIN current_relation_members crm ON crm.id=cr.id
WHERE crm.member_type='Way'
AND crm.member_id IN (#{way_ids.join(',')})
UNION
SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
INNER JOIN current_relation_members crm ON crm.id=cr.id
WHERE crm.member_type='Way'
AND crm.member_id IN (#{way_ids.join(',')})
SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,current_nodes.id,current_nodes.version
FROM current_way_nodes,current_nodes
WHERE current_way_nodes.id=#{wayid.to_i}
AND current_way_nodes.node_id=current_nodes.id
AND current_nodes.visible=TRUE
ORDER BY sequence_id
SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,current_nodes.id,current_nodes.version
FROM current_way_nodes,current_nodes
WHERE current_way_nodes.id=#{wayid.to_i}
AND current_way_nodes.node_id=current_nodes.id
AND current_nodes.visible=TRUE
ORDER BY sequence_id
ActiveRecord::Base.connection.select_all(sql).each do |row|
nodetags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n|
ActiveRecord::Base.connection.select_all(sql).each do |row|
nodetags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_node_tags WHERE id=#{row['id']}").each do |n|
- nodetags.delete('created_by')
- points << [row['lon'].to_f, row['lat'].to_f, row['id'].to_i, nodetags, row['version'].to_i]
+ nodetags.delete("created_by")
+ points << [row["lon"].to_f, row["lat"].to_f, row["id"].to_i, nodetags, row["version"].to_i]
def sql_get_tags_in_way(wayid)
tags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_way_tags WHERE id=#{wayid.to_i}").each do |row|
def sql_get_tags_in_way(wayid)
tags = {}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_way_tags WHERE id=#{wayid.to_i}").each do |row|