Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'yajl'
- require 'geokit'
- require 'socket'
- require 'ruby-units'
- require 'json/pure'
- class GPSPipe
- attr_accessor :host, :port
- def initialize(host='127.0.0.1', port='2947')
- @host = host
- @port = port
- # Hash that stores history for distance calculation
- @history = {'TPV' => []} # defaultize the hash
- end
- # Opens a connection to gpsd and streams from it
- def stream()
- TCPSocket.open(@host, @port) do |socket|
- socket.write "?WATCH={\"enable\":true,\"json\":true}"
- socket.each_line do |line|
- parsed = handle_data(line)
- yield parsed if parsed
- end
- end
- end
- private
- def handle_data(data)
- data = JSON.parse(data.chomp)
- case data["class"]
- when "VERSION", "DEVICES", "WATCH"
- data
- when "SKY"
- # TODO
- when "TPV"
- moved?(data) ? data : nil
- else
- raise ArgumentError, 'Unknown input: %s' % data
- end
- end
- def cleanup_history!
- @history.each_value do |value|
- raise "History is bogus" if value.length > 4
- value.shift if value.length > 3
- end
- end
- def has_moved?(data)
- # Remove old items from history, append item to history and return the history
- cleanup_history!
- h = @history['TPV']
- h << data
- # Check that we moved 1m away from history coordinates
- minimum_distance = Unit.new("0.2 meters")
- now = GeoKit::LatLng.new(h.last['lat'], h.last['lon'])
- matches = h[0..-2].select { |test|
- previous = GeoKit::LatLng.new(test['lat'], test['lon'])
- distance = Unit.new("%s miles" % previous.distance_to(now))
- distance > minimum_distance
- }
- # Return true if our distance changed compard to *all* items in history
- # If we really moved, then we aren't just jumping between 2 coordinates.
- matches.length == h.length-1
- end
- end
- gpspipe = GPSPipe.new()
- gpspipe.stream do |output|
- p output
- end
Add Comment
Please, Sign In to add comment