further work on 0.6 history (not quite complete yet)

This commit is contained in:
Richard Fairhurst 2009-02-25 01:14:19 +00:00
parent 5143fbcd5b
commit e827a04607
6 changed files with 271 additions and 126 deletions

View file

@ -27,7 +27,10 @@
# return(-1,"message") <-- just puts up a dialogue
# return(-2,"message") <-- also asks the user to e-mail me
#
# To write to the Rails log, use RAILS_DEFAULT_LOGGER.info("message").
# To write to the Rails log, use logger.info("message").
# Remaining issues:
# * version conflict when POIs and ways are reverted
class AmfController < ApplicationController
require 'stringio'
@ -75,7 +78,7 @@ class AmfController < ApplicationController
when 'whichways_deleted'; results[index]=AMF.putdata(index,whichways_deleted(*args))
when 'getway'; results[index]=AMF.putdata(index,getway(args[0].to_i))
when 'getrelation'; results[index]=AMF.putdata(index,getrelation(args[0].to_i))
when 'getway_old'; results[index]=AMF.putdata(index,getway_old(args[0].to_i,args[1].to_i))
when 'getway_old'; results[index]=AMF.putdata(index,getway_old(args[0].to_i,args[1]))
when 'getway_history'; results[index]=AMF.putdata(index,getway_history(args[0].to_i))
when 'getnode_history'; results[index]=AMF.putdata(index,getnode_history(args[0].to_i))
when 'findgpx'; results[index]=AMF.putdata(index,findgpx(*args))
@ -180,8 +183,9 @@ class AmfController < ApplicationController
# 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:
xmin -= 0.01; ymin -= 0.01
xmax += 0.01; ymax += 0.01
enlarge = [(xmax-xmin)/8,0.01].min
xmin -= enlarge; ymin -= enlarge
xmax += enlarge; ymax += enlarge
# check boundary is sane and area within defined
# see /config/application.yml
@ -202,7 +206,7 @@ class AmfController < ApplicationController
# find the node ids in an area that aren't part of ways
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, n.lat, n.tags, n.version] }
points = nodes_not_used_in_area.collect { |n| [n.id, n.lon, n.lat, n.tags, n.version] }.uniq
# find the relations used by those nodes and ways
relations = Relation.find_for_nodes(nodes_in_area.collect { |n| n.id }, :conditions => {:visible => true}) +
@ -210,7 +214,7 @@ class AmfController < ApplicationController
relations = relations.collect { |relation| [relation.id,relation.version] }.uniq
end
[0,ways, points, relations]
[0, ways, points, relations]
rescue Exception => err
[-2,"Sorry - I can't get the map for that area."]
@ -220,8 +224,9 @@ class AmfController < ApplicationController
# with a deleted node only - not POIs or relations).
def whichways_deleted(xmin, ymin, xmax, ymax) #:doc:
xmin -= 0.01; ymin -= 0.01
xmax += 0.01; ymax += 0.01
enlarge = [(xmax-xmin)/8,0.01].min
xmin -= enlarge; ymin -= enlarge
xmax += enlarge; ymax += enlarge
# check boundary is sane and area within defined
# see /config/application.yml
@ -284,23 +289,24 @@ class AmfController < ApplicationController
# 3. hash of tags,
# 4. version,
# 5. is this the current, visible version? (boolean)
#
# *** FIXME:
# Should work by timestamp, not version (so that we can recover versions when
# a node has been changed, but not the enclosing way)
# Use strptime (http://www.ruby-doc.org/core/classes/DateTime.html) to
# to turn string back into timestamp.
def getway_old(id, version) #:doc:
if version < 0
def getway_old(id, timestamp) #:doc:
if timestamp == ''
# undelete
old_way = OldWay.find(:first, :conditions => ['visible = ? AND id = ?', true, id], :order => 'version DESC')
points = old_way.get_nodes_undelete unless old_way.nil?
else
old_way = OldWay.find(:first, :conditions => ['id = ? AND version = ?', id, version])
points = old_way.get_nodes_revert unless old_way.nil?
# revert
timestamp = DateTime.strptime(timestamp, "%d %b %Y, %H:%M:%S")
old_way = OldWay.find(:first, :conditions => ['id = ? AND timestamp <= ?', id, timestamp], :order => 'timestamp DESC')
points = old_way.get_nodes_revert(timestamp) unless old_way.nil?
if !old_way.visible
return [-1, "Sorry, the way was deleted at that time - please revert to a previous version."]
end
end
if old_way.nil?
# *** FIXME: shouldn't this be returning an error?
return [-1, id, [], {}, -1,0]
else
curway=Way.find(id)
@ -309,67 +315,68 @@ class AmfController < ApplicationController
end
end
# Find history of a way. Returns 'way', id, and
# an array of previous versions.
# Find history of a way.
# Returns 'way', id, and an array of previous versions:
# - formerly [old_way.version, old_way.timestamp.strftime("%d %b %Y, %H:%M"), old_way.visible ? 1 : 0, user, uid]
# - now [timestamp,user,uid]
#
# *** FIXME:
# Should look for changes in constituent nodes as well,
# and return timestamps.
# Heuristic: Find all nodes that have ever been part of the way;
# Heuristic: Find all nodes that have ever been part of the way;
# get a list of their revision dates; add revision dates of the way;
# sort and collapse list (to within 2 seconds); trim all dates before the
# start dateÊof the way.
# start date of the way.
def getway_history(wayid) #:doc:
# Find list of revision dates for way and all constituent nodes
revdates=[]
Way.find(wayid).old_ways.collect do |a|
revdates.push(a.timestamp)
a.nds.each do |n|
Node.find(n).old_nodes.collect do |o|
revdates.push(o.timestamp)
begin
# Find list of revision dates for way and all constituent nodes
revdates=[]
revusers={}
Way.find(wayid).old_ways.collect do |a|
revdates.push(a.timestamp)
unless revusers.has_key?(a.timestamp.to_i) then revusers[a.timestamp.to_i]=change_user(a) end
a.nds.each do |n|
Node.find(n).old_nodes.collect do |o|
revdates.push(o.timestamp)
unless revusers.has_key?(o.timestamp.to_i) then revusers[o.timestamp.to_i]=change_user(o) end
end
end
end
waycreated=revdates[0]
revdates.uniq!
revdates.sort!
revdates.reverse!
# Remove any dates (from nodes) before first revision date of way
revdates.delete_if { |d| d<waycreated }
# Remove any elements where 2 seconds doesn't elapse before next one
revdates.delete_if { |d| revdates.include?(d+1) or revdates.include?(d+2) }
# Collect all in one nested array
revdates.collect! {|d| [d.strftime("%d %b %Y, %H:%M:%S")] + revusers[d.to_i] }
return ['way',wayid,revdates]
rescue ActiveRecord::RecordNotFound
return ['way', wayid, []]
end
waycreated=revdates[0]
revdates.uniq!
revdates.sort!
# Remove any dates (from nodes) before first revision date of way
revdates.delete_if { |d| d<waycreated }
# Remove any elements where 2 seconds doesn't elapse before next one
revdates.delete_if { |d| revdates.include?(d+1) or revdates.include?(d+2) }
RAILS_DEFAULT_LOGGER.info("** revision dates: #{revdates.inspect}")
RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
history = Way.find(wayid).old_ways.reverse.collect do |old_way|
user_object = old_way.changeset.user
user = user_object.data_public? ? user_object.display_name : 'anonymous'
uid = user_object.data_public? ? user_object.id : 0
[old_way.version, old_way.timestamp.strftime("%d %b %Y, %H:%M"), old_way.visible ? 1 : 0, user, uid]
end
return ['way',wayid,history]
rescue ActiveRecord::RecordNotFound
return ['way', wayid, []]
end
# Find history of a node. Returns 'node', id, and
# an array of previous versions.
# Find history of a node. Returns 'node', id, and an array of previous versions as above.
def getnode_history(nodeid) #:doc:
history = Node.find(nodeid).old_nodes.reverse.collect do |old_node|
user_object = old_node.changeset.user
user = user_object.data_public? ? user_object.display_name : 'anonymous'
uid = user_object.data_public? ? user_object.id : 0
[old_node.version, old_node.timestamp.strftime("%d %b %Y, %H:%M"), old_node.visible ? 1 : 0, user, uid]
begin
history = Node.find(nodeid).old_nodes.reverse.collect do |old_node|
[old_node.timestamp.strftime("%d %b %Y, %H:%M:%S")] + change_user(old_node)
end
return ['node', nodeid, history]
rescue ActiveRecord::RecordNotFound
return ['node', nodeid, []]
end
end
return ['node',nodeid,history]
rescue ActiveRecord::RecordNotFound
return ['node', nodeid, []]
def change_user(obj)
user_object = obj.changeset.user
user = user_object.data_public? ? user_object.display_name : 'anonymous'
uid = user_object.data_public? ? user_object.id : 0
[user,uid]
end
# Find GPS traces with specified name/id.
@ -582,17 +589,6 @@ RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
end
end
# -- Delete any unique nodes no longer used
uniques=uniques-pointlist
uniques.each do |n|
node = Node.find(n)
new_node = Node.new
new_node.changeset_id = changeset
new_node.version = version
node.delete_with_history!(new_node, user)
end
# -- Save revised way
pointlist.collect! {|a|
@ -609,6 +605,18 @@ RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
elsif way.tags!=attributes or way.nds!=pointlist or !way.visible?
way.update_from(new_way, user)
end
# -- Delete any unique nodes no longer used
uniques=uniques-pointlist
uniques.each do |n|
node = Node.find(n)
new_node = Node.new
new_node.changeset_id = changeset
new_node.version = node.version
node.delete_with_history!(new_node, user)
end
end # transaction
[0, originalway, way.id, renumberednodes, way.version, nodeversions]
@ -697,11 +705,11 @@ RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
#
# Returns array of id, long, lat, hash of tags, version.
def getpoi(id,version) #:doc:
if version>0 then
n = OldNode.find(id, :conditions=>['version=?',version])
else
def getpoi(id,timestamp) #:doc:
if timestamp == '' then
n = Node.find(id)
else
n = OldNode.find(id, :conditions=>['timestamp=?',DateTime.strptime(timestamp, "%d %b %Y, %H:%M:%S")])
end
if n
@ -729,27 +737,29 @@ RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
# Need a transaction so that if one item fails to delete, the whole delete fails.
Way.transaction do
# delete the way
old_way = Way.find(way_id)
delete_way = Way.new
delete_way.version = way_version
delete_way.changeset_id = changeset_id
old_way.delete_with_history!(delete_way, user)
# FIXME: would be good not to make two history entries when removing
# two nodes from the same relation
old_way = Way.find(way_id)
#old_way.unshared_node_ids.each do |n|
# deleteitemrelations(n, 'node')
#end
#deleteitemrelations(way_id, 'way')
#way.delete_with_relations_and_nodes_and_history(changeset_id.to_i)
old_way.unshared_node_ids.each do |node_id|
# delete the node
node = Node.find(node_id)
delete_node = Node.new
delete_node.version = node_id_version[node_id]
delete_node.changeset_id = changeset_id
delete_node.version = node_id_version[node_id.to_s]
node.delete_with_history!(delete_node, user)
end
# delete the way
delete_way = Way.new
delete_way.version = way_version
old_way.delete_with_history!(delete_way, user)
end # transaction
[0, way_id]
rescue OSM::APIChangesetAlreadyClosedError => ex
@ -770,11 +780,6 @@ RAILS_DEFAULT_LOGGER.info("** range: #{revdates[-1]-revdates[0]}")
# ====================================================================
# Support functions
# delete a way and its nodes that aren't part of other ways
# this functionality used to be in the model, however it is specific to amf
# controller
#def delete_unshared_nodes(changeset_id, way_id)
# Remove a node or way from all relations
# FIXME needs version, changeset, and user
# Fixme make sure this doesn't depend on anything and delete this, as potlatch

View file

@ -134,10 +134,10 @@ class OldWay < ActiveRecord::Base
points
end
def get_nodes_revert
def get_nodes_revert(timestamp)
points=[]
self.nds.each do |n|
oldnode=OldNode.find(:first, :conditions=>['id=? AND timestamp<=?',n,self.timestamp], :order=>"timestamp DESC")
oldnode=OldNode.find(:first, :conditions=>['id=? AND timestamp<=?',n,timestamp], :order=>"timestamp DESC")
curnode=Node.find(n)
id=n; v=curnode.visible ? 1 : 0
if oldnode.lat!=curnode.lat or oldnode.lon!=curnode.lon or oldnode.tags!=curnode.tags then

View file

@ -82,12 +82,31 @@ is_in/way -
note/point -
note/POI -
note/way -
source/point -
source/POI -
source/way -
source/point survey,Yahoo,NPE,local_knowledge,GPS,cadastre
source/POI survey,Yahoo,NPE,local_knowledge,GPS,cadastre
source/way survey,Yahoo,NPE,local_knowledge,GPS,cadastre
postal_code/point -
postal_code/POI -
postal_code/way -
description/point -
description/POI -
description/way -
addr:housenumber/point -
addr:street/point -
addr:full/point -
addr:postcode/point -
addr:city/point -
addr:country/point -
addr:housenumber/POI -
addr:street/POI -
addr:full/POI -
addr:postcode/POI -
addr:city/POI -
addr:country/POI -
addr:housenumber/way -
addr:street/way -
addr:full/way -
addr:postcode/way -
addr:city/way -
addr:country/way -
addr:interpolation/way even,odd,all,alphabetic

View file

@ -12,17 +12,16 @@ way/footway
public footpath: highway=footway,foot=yes,tracktype=
permissive path: highway=footway,foot=permissive,tracktype=
bridleway: highway=bridleway,foot=yes,tracktype=
paved track: highway=track,foot=,tracktype=grade1
gravel track: highway=track,foot=,tracktype=grade2
rough track: highway=track,foot=,tracktype=grade3
dirt track: highway=track,foot=,tracktype=grade4
grass track: highway=track,foot=,tracktype=grade5
paved track: highway=track,foot=,surface=paved
gravel track: highway=track,foot=,surface=gravel
dirt track: highway=track,foot=,surface=dirt
grass track: highway=track,foot=,surface=grass
way/cycleway
cycle lane: highway=cycleway,cycleway=lane,ncn_ref=
cycle track: highway=cycleway,cycleway=track,ncn_ref=
cycle lane (NCN): highway=cycleway,cycleway=lane,name=(type name here),ncn_ref=(type route number)
cycle track (NCN): highway=cycleway,cycleway=track,name=(type name here),ncn_ref=(type route number)
cycle track: highway=cycleway,ncn_ref=,rcn_ref=,lcn_ref=
cycle track (national route): highway=cycleway,ncn_ref=(type route number)
cycle track (regional route): highway=cycleway,rcn_ref=(type route number)
cycle track (local route): highway=cycleway,lcn_ref=(type route number)
way/waterway
canal: waterway=canal,name=(type name here)
@ -42,9 +41,57 @@ disused railway tracks: railway=disused
course of old railway: railway=abandoned
railway platform: railway=platform
way/tourism
archaeological: place=,tourism=,historic=archaeological_site,name=(type name here)
attraction: place=,tourism=attraction,historic=,amenity=,name=(type name here)
campsite: place=,tourism=camp_site,historic=,amenity=,name=(type name here)
caravan site: place=,tourism=camp_site,historic=,amenity=,name=(type name here)
castle: place=,tourism=,historic=castle,name=(type name here)
hotel: place=,tourism=hotel,historic=,amenity=,name=(type name here),operator=(type chain here)
museum: place=,tourism=museum,historic=,amenity=,name=(type name here)
ruins: place=,tourism=,historic=ruins,name=(type name here)
way/recreation
golf course: landuse=,leisure=golf_course
pitch: landuse=,leisure=pitch, sport=(type sport here)
playground: landuse=,leisure=playground
recreation ground: landuse=recreation_ground,leisure=
sports centre: landuse=,leisure=sports_centre
stadium: landuse=,leisure=stadium
way/utility
college: place=,tourism=,amenity=college,name=(type name here)
school: place=,tourism=,amenity=school,name=(type name here)
hospital: place=,tourism=,amenity=hospital,name=(type name here)
library: place=,tourism=,amenity=library,name=(type name here)
university: place=,tourism=,amenity=university,name=(type name here)
way/natural
lake: natural=water,landuse=
forest: landuse=forest,natural=
coastline: natural=coastline,landuse=,leisure=
fell: natural=fell,landuse=,leisure=
heath: natural=heath,landuse=,leisure=
lake: natural=water,landuse=,leisure=
forest: landuse=forest,natural=,leisure=
marsh: natural=marsh,landuse=,leisure=
nature reserve: leisure=nature_reserve,landuse=,natural=
scree: natural=scree,landuse=,leisure=
woodland: natural=wood,landuse=,leisure=
way/landuse
allotments: landuse=allotments,leisure=
building site: landuse=construction,leisure=
commercial: landuse=commercial,leisure=
common: landuse=,leisure=common
farm: landuse=farm,leisure=
farmyard: landuse=farmyard,leisure=
industry: landuse=industrial,leisure=
landfill site: landuse=landfill,leisure=
park: leisure=park,landuse=
quarry: landuse=quarry,leisure=
reservoir: landuse=reservoir,leisure=
residential: landuse=residential,leisure=
retail: landuse=retail,leisure=
village green: landuse=village_green,leisure=
point/road
mini roundabout: place=,highway=mini_roundabout
@ -57,20 +104,25 @@ stile: place=,highway=stile
cattle grid: place=,highway=cattle_grid
point/cycleway
gate: place=,highway=gate
bike park: place=,highway=,amenity=bicycle_parking,capacity=(type number of spaces)
gate: place=,highway=gate,amenity=,capacity=
point/waterway
lock gate: place=,waterway=lock_gate
weir: place=,waterway=weir
aqueduct: place=,waterway=aqueduct
winding hole: place=,waterway=turning_point
mooring: place=,waterway=mooring
lock: place=,waterway=,lock=yes,name=(type name here)
single lockgate: place=,waterway=lock_gate,lock=
weir: place=,waterway=weir,lock=
aqueduct: place=,waterway=aqueduct,lock=
winding hole: place=,waterway=turning_point,lock=
mooring: place=,waterway=mooring,lock=
point/railway
station: place=,railway=station,name=(type name here)
viaduct: place=,railway=viaduct
level crossing: place=,railway=crossing
point/landmark
pylon: man_made=,power=tower
point/natural
peak: place=,natural=peak
@ -78,8 +130,13 @@ POI/road
car park: place=,amenity=parking
petrol station: place=,amenity=fuel
POI/footway
bench: amenity=bench
POI/cycleway
bike park: place=,amenity=bicycle_parking
bike park: place=,shop=,amenity=bicycle_parking,capacity=(type number of spaces)
bike rental: place=,amenity=bicycle_rental,capacity=(type number of bikes)
bike shop: place=,shop=bicycle
POI/place
city: place=city,name=(type name here),is_in=(type region or county)
@ -89,14 +146,78 @@ 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: place=,tourism=attraction,amenity=,religion=,denomination=
church: place=,tourism=,amenity=place_of_worship,name=(type name here),religion=christian,denomination=(type denomination here)
hotel: place=,tourism=hotel,amenity=,religion=,denomination=
other religious: place=,tourism=,amenity=place_of_worship,name=(type name here),religion=(type religion),denomination=
post box: place=,amenity=post_box,tourism=,name=,religion=,denomination=
post office: place=,amenity=post_office,tourism=,name=,religion=,denomination=
pub: place=,tourism=,amenity=pub,name=(type name here),religion=,denomination=
school: place=,tourism=,amenity=school,name=(type name here),religion=,denomination=
archaeological: place=,tourism=,historic=archaeological_site,name=(type name here)
artwork: place=,tourism=artwork,historic=,amenity=
attraction: place=,tourism=attraction,historic=,amenity=,name=(type name here)
cafe: place=,tourism=,historic=,amenity=cafe,name=(type name here)
campsite: place=,tourism=camp_site,historic=,amenity=,name=(type name here)
caravan site: place=,tourism=camp_site,historic=,amenity=,name=(type name here)
castle: place=,tourism=,historic=castle,name=(type name here)
cinema: place=,tourism=,historic=,amenity=cinema,name=(type name here),operator=(type chain here)
fast food: place=,tourism=,historic=,amenity=fast_food,name=(type name here)
guesthouse: place=,tourism=guest_house,historic=,amenity=,name=(type name here)
hostel: place=,tourism=hostel,historic=,amenity=,name=(type name here),operator=(type chain here)
hotel: place=,tourism=hotel,historic=,amenity=,name=(type name here),operator=(type chain here)
monument: place=,tourism=,historic=monument,name=(type name here)
museum: place=,tourism=museum,historic=,amenity=,name=(type name here)
picnic site: place=,tourism=picnic_site,historic=
pub: place=,tourism=,historic=,amenity=pub,name=(type name here)
restaurant: place=,tourism=,historic=,amenity=restaurant,name=(type name here)
ruins: place=,tourism=,historic=ruins,name=(type name here)
viewpoint: place=,tourism=viewpoint,historic=
POI/landmark
church: man_made=,amenity=place_of_worship,name=(type name here),religion=christian,denomination=(type denomination here),power=
other religious: man_made=,amenity=place_of_worship,name=(type name here),religion=(type religion),denomination=,power=
lighthouse: man_made=lighthouse,power=,amenity=,name=,religion=,denomination=
pylon: man_made=,power=tower,amenity=,name=,religion=,denomination=
windmill: man_made=windmill,power=,amenity=,name=,religion=,denomination=
POI/recreation
golf course: leisure=golf_course
pitch: leisure=pitch, sport=(type sport here)
playground: leisure=playground
recreation ground: landuse=recreation_ground,leisure=
sports centre: leisure=sports_centre
stadium: leisure=stadium
POI/shop
bank: amenity=bank,shop=,operator=(type bank name)
bike shop: amenity=,shop=bicycle,name=(type name here),operator=(type chain here)
bookshop: amenity=,shop=books,name=(type name here),operator=(type chain here)
butchers: amenity=,shop=butcher,name=(type name here),operator=(type chain here)
chemists: amenity=,shop=chemist,name=(type name here),operator=(type chain here)
convenience store: amenity=,shop=convenience,operator=(type chain here)
department store: amenity=,shop=department_store,operator=(type chain here)
DIY: amenity=,shop=doityourself,operator=(type chain here)
garden centre: amenity=,shop=garden_centre,name=(type name here),operator=(type chain here)
laundry: amenity=,shop=laundry,name=(type name here),operator=(type chain here)
off-licence: amenity=,shop=alcohol,name=(type name here),operator=(type chain here)
outdoor: amenity=,shop=outdoor,name=(type name here),operator=(type chain here)
pharmacy: amenity=pharmacy,shop=,name=(type name here),operator=(type chain here)
post office: amenity=post_office,shop=,name=(type name here)
supermarket: amenity=,shop=supermarket,operator=(type chain here)
POI/utility
college: place=,tourism=,amenity=college,name=(type name here)
post box: place=,amenity=post_box,tourism=,name=,ref=(type code here)
recycling: place=,amenity=recycling,tourism=,name=,ref=(type code here)
school: place=,tourism=,amenity=school,name=(type name here)
surgery: place=,tourism=,amenity=doctors,name=(type name here)
hospital: place=,tourism=,amenity=hospital,name=(type name here)
library: place=,tourism=,amenity=library,name=(type name here)
phone box: place=,tourism=,amenity=telephone,name=(type name here)
toilets: place=,tourism=,amenity=toilets,name=(type name here)
university: place=,tourism=,amenity=university,name=(type name here)
POI/natural
peak: place=,natural=peak
point/address
address: addr:housenumber=(type house number),addr:street=(type street name),addr:postcode=(type postcode),addr:city=(type town name)
POI/address
address: addr:housenumber=(type house number),addr:street=(type street name),addr:postcode=(type postcode),addr:city=(type town name)
way/address
address: addr:housenumber=(type house number),addr:street=(type street name),addr:interpolation=(type pattern of house numbers),addr:postcode=(type postcode),addr:city=(type town name)

View file

@ -147,7 +147,7 @@ module Potlatch
presetcategory=$2
presetmenus[presettype].push(presetcategory)
presetnames[presettype][presetcategory]=["(no preset)"]
elsif (t=~/^(.+):\s?(.+)$/) then
elsif (t=~/^([\w\s]+):\s?(.+)$/) then
pre=$1; kv=$2
presetnames[presettype][presetcategory].push(pre)
presets[pre]={}
@ -191,7 +191,7 @@ module Potlatch
File.open("#{RAILS_ROOT}/config/potlatch/autocomplete.txt") do |file|
file.each_line {|line|
t=line.chomp
if (t=~/^(\w+)\/(\w+)\s+(.+)$/) then
if (t=~/^([\w:]+)\/(\w+)\s+(.+)$/) then
tag=$1; type=$2; values=$3
if values=='-' then autotags[type][tag]=[]
else autotags[type][tag]=values.split(',').sort.reverse end

Binary file not shown.