From: Richard Fairhurst Date: Wed, 25 Feb 2009 01:14:19 +0000 (+0000) Subject: further work on 0.6 history (not quite complete yet) X-Git-Tag: live~7619^2~65 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/e827a0460795bc076c115f941d074dca67decaa1 further work on 0.6 history (not quite complete yet) --- diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index 4103ceda0..69222fc53 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -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| d0 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 diff --git a/app/models/old_way.rb b/app/models/old_way.rb index da9cf0697..df2ab3fa4 100644 --- a/app/models/old_way.rb +++ b/app/models/old_way.rb @@ -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 diff --git a/config/potlatch/autocomplete.txt b/config/potlatch/autocomplete.txt index ad6cb0154..a3c80c7da 100755 --- a/config/potlatch/autocomplete.txt +++ b/config/potlatch/autocomplete.txt @@ -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 diff --git a/config/potlatch/presets.txt b/config/potlatch/presets.txt index c46f9d12a..6be23b993 100644 --- a/config/potlatch/presets.txt +++ b/config/potlatch/presets.txt @@ -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) diff --git a/lib/potlatch.rb b/lib/potlatch.rb index ebafbce00..cfb602817 100644 --- a/lib/potlatch.rb +++ b/lib/potlatch.rb @@ -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 diff --git a/public/potlatch/potlatch.swf b/public/potlatch/potlatch.swf index 5a9b7572a..2d237cd22 100755 Binary files a/public/potlatch/potlatch.swf and b/public/potlatch/potlatch.swf differ