various gpx bits
authorSteve Coast <steve@asklater.com>
Fri, 1 Dec 2006 15:59:13 +0000 (15:59 +0000)
committerSteve Coast <steve@asklater.com>
Fri, 1 Dec 2006 15:59:13 +0000 (15:59 +0000)
app/controllers/api_controller.rb
app/controllers/trace_controller.rb
app/controllers/tracepoint_controller.rb [new file with mode: 0644]
app/helpers/tracepoint_helper.rb [new file with mode: 0644]
app/models/notifier.rb
app/models/tracepoint.rb [new file with mode: 0644]
app/views/notifier/gpx_failure.rhtml [new file with mode: 0644]
app/views/notifier/gpx_success.rhtml [new file with mode: 0644]
db/migrate/015_create_tracepoints.rb [new file with mode: 0644]
lib/daemons/gpx_import.rb
lib/osm.rb [new file with mode: 0644]

index e829a173266192b582533d1b206046e3c7bdfee2..d6b0b037a78cbd6e875b4c35bdcff8c09f75935d 100644 (file)
@@ -40,12 +40,7 @@ class ApiController < ApplicationController
     # get missing nodes if there are any
     nodes += Node.find(missing_nodes) if missing_nodes.length > 0
 
-    doc = XML::Document.new
-    doc.encoding = 'UTF-8' 
-    root = XML::Node.new 'osm'
-    root['version'] = API_VERSION
-    root['generator'] = 'OpenStreetMap server'
-    doc.root = root
+    doc = get_xml_doc
 
     # get ways
     # find which ways are needed
@@ -59,15 +54,15 @@ class ApiController < ApplicationController
     end
 
     nodes.each do |node|
-      root << node.to_xml_node()
+      doc.root << node.to_xml_node()
     end
 
     segments.each do |segment|
-      root << segment.to_xml_node()
+      doc.root << segment.to_xml_node()
     end 
 
     ways.each do |way|
-      root << way.to_xml_node()
+      doc.root << way.to_xml_node()
     end 
 
     render :text => doc.to_s
index 337f27e0e80c32164f8d0790e4a6062c3833574a..c8b33060134f319224ac2c0cec6267752d7bfacc 100644 (file)
@@ -15,8 +15,6 @@ class TraceController < ApplicationController
 
     File.open(filename, "w") { |f| f.write(@params['trace']['gpx_file'].read) }
     @params['trace']['name'] = @params['trace']['gpx_file'].original_filename.gsub(/[^a-zA-Z0-9.]/, '_') # This makes sure filenames are sane
-    #@params['trace']['data'] = @params['trace']['gpx_file'].read
-#    @params['trace']['mime_type'] = @params['trace']['gpx_file'].content_type.chomp
     @params['trace'].delete('gpx_file') # let's remove the field from the hash, because there's no such field in the DB anyway.
     @trace = Trace.new(@params['trace'])
     @trace.inserted = false
diff --git a/app/controllers/tracepoint_controller.rb b/app/controllers/tracepoint_controller.rb
new file mode 100644 (file)
index 0000000..fed84c6
--- /dev/null
@@ -0,0 +1,2 @@
+class TracepointController < ApplicationController
+end
diff --git a/app/helpers/tracepoint_helper.rb b/app/helpers/tracepoint_helper.rb
new file mode 100644 (file)
index 0000000..8a5a031
--- /dev/null
@@ -0,0 +1,2 @@
+module TracepointHelper
+end
index 4b80e1de8212dec993662130acf6501cf5e923aa..80c1b1f8236b365200102f901c2ecfe2968fe5b0 100644 (file)
@@ -21,4 +21,18 @@ class Notifier < ActionMailer::Base
     @body['pass'] = pass
   end
 
+  def gpx_success(trace)
+    @recipients = user.email
+    @from = 'abuse@openstreetmap.org'
+    @subject = '[OpenStreetMap] GPX Import success'
+    @body['trace_name'] = trace.name
+    @body['trace_points'] = trace.size
+  end
+
+  def gpx_failure(trace)
+    @recipients = user.email
+    @from = 'abuse@openstreetmap.org'
+    @subject = '[OpenStreetMap] GPX Import failure'
+    @body['trace_name'] = trace.name
+  end
 end
diff --git a/app/models/tracepoint.rb b/app/models/tracepoint.rb
new file mode 100644 (file)
index 0000000..9de8dc5
--- /dev/null
@@ -0,0 +1,9 @@
+class Tracepoint < ActiveRecord::Base
+  set_table_name 'gps_points'
+
+  validates_numericality_of :latitude
+  validates_numericality_of :longitude
+
+  belongs_to :user
+  belongs_to :trace, :foreign_key => 'gpx_id'
+end
diff --git a/app/views/notifier/gpx_failure.rhtml b/app/views/notifier/gpx_failure.rhtml
new file mode 100644 (file)
index 0000000..6a2f81e
--- /dev/null
@@ -0,0 +1,7 @@
+Hi,
+
+It looks like your GPX file
+
+  <%= @trace_name %>
+
+failed to import :-(
diff --git a/app/views/notifier/gpx_success.rhtml b/app/views/notifier/gpx_success.rhtml
new file mode 100644 (file)
index 0000000..5e77516
--- /dev/null
@@ -0,0 +1,7 @@
+Hi,
+
+It looks like your GPX file
+
+  <%= @trace_name %>
+
+loaded successfully with <%= @trace_points %> points.
diff --git a/db/migrate/015_create_tracepoints.rb b/db/migrate/015_create_tracepoints.rb
new file mode 100644 (file)
index 0000000..3d75f03
--- /dev/null
@@ -0,0 +1,11 @@
+class CreateTracepoints < ActiveRecord::Migration
+  def self.up
+    create_table :tracepoints do |t|
+      # t.column :name, :string
+    end
+  end
+
+  def self.down
+    drop_table :tracepoints
+  end
+end
index c3cd9b06b414b56998a3ff9b96df418e7095b93e..015a2791648451ae0555ad8c1a2de53a9a2ae517 100755 (executable)
@@ -1,7 +1,7 @@
 #!/usr/bin/env ruby
 
 #You might want to change this
-ENV["RAILS_ENV"] ||= "production"
+ENV["RAILS_ENV"] ||= "development"
 
 require File.dirname(__FILE__) + "/../../config/environment"
 
@@ -12,8 +12,26 @@ end
 
 while($running) do
   
-  # Replace this with your code
-  ActiveRecord::Base.logger << "This daemon is still running at #{Time.now}.\n"
-  
-  sleep 10
-end
\ No newline at end of file
+  ActiveRecord::Base.logger.info("GPX Import daemon wake @ #{Time.now}.")
+
+  traces = Trace.find(:all, :conditions => ['inserted = ?', false])
+
+  if traces and traces.length > 0
+    traces.each do |trace|
+      begin
+
+        ActiveRecord::Base.logger.info("GPX Import importing #{trace.name} from #{trace.user.email}")
+
+        #  gpx = OSM::GPXImporter.new('/tmp/2.gpx')
+        #  gpx.points do |point|
+        #    puts point['latitude']
+        #  end
+        
+        Notifier::deliver_gpx_success(trace)
+      rescue
+        Notifier::deliver_gpx_failure(trace)
+      end
+    end
+  end
+  sleep 15.minutes
+end
diff --git a/lib/osm.rb b/lib/osm.rb
new file mode 100644 (file)
index 0000000..41c5874
--- /dev/null
@@ -0,0 +1,74 @@
+module OSM
+
+  # This piece of magic reads a GPX with SAX and spits out
+  # lat/lng and stuff
+  #
+  # This would print every latitude value:
+  #
+  # gpx = OSM:GPXImporter.new('somefile.gpx')
+  # gpx.points {|p| puts p['latitude']}
+  
+  require 'time'
+  require 'rexml/parsers/sax2parser'
+  require 'rexml/text'
+
+  class GPXImporter
+    attr_reader :possible_points
+    attr_reader :tracksegs
+
+    def initialize(filename)
+      @filename = filename
+      @possible_points = 0
+      @tracksegs = 0
+    end
+
+    def points
+      file = File.new(@filename)
+      parser = REXML::Parsers::SAX2Parser.new( file )
+
+      lat = -1
+      lon = -1
+      ele = -1
+      date = Time.now();
+      gotlatlon = false
+      gotele = false
+      gotdate = false
+
+      parser.listen( :start_element,  %w{ trkpt }) do |uri,localname,qname,attributes| 
+        lat = attributes['lat'].to_f
+        lon = attributes['lon'].to_f
+        gotlatlon = true
+        @possible_points += 1
+      end
+
+      parser.listen( :characters, %w{ ele } ) do |text|
+        ele = text
+        gotele = true
+      end
+
+      parser.listen( :characters, %w{ time } ) do |text|
+        if text && text != ''
+          date = Time.parse(text)
+          gotdate = true
+        end
+      end
+
+      parser.listen( :end_element, %w{ trkseg } ) do |uri, localname, qname|
+        @tracksegs += 1
+      end
+
+      parser.listen( :end_element, %w{ trkpt } ) do |uri,localname,qname|
+        if gotlatlon && gotdate
+          ele = '0' unless gotele
+          if lat < 90 && lat > -90 && lon > -180 && lon < 180
+            yield Hash['latitude' => lat,'longitude' => lon,'timestamp' => date,'altitude' => ele,'segment' => @tracksegs]
+          end
+        end
+        gotlatlon = false
+        gotele = false
+        gotdate = false
+      end
+      parser.parse
+    end
+  end
+end