Skip to content

Instantly share code, notes, and snippets.

@Eunoia
Created November 5, 2012 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Eunoia/4019225 to your computer and use it in GitHub Desktop.
Save Eunoia/4019225 to your computer and use it in GitHub Desktop.
A class that logs locations using HTML5 geolocation
window.randomly = () -> (Math.round(Math.random())-0.5)
Number::toRadians = () -> @*2*Math.PI/360
class LocationHistory
constructor: (name = "Name", load = false, onUpdate) ->
if not navigator.geolocation
return "not supported"
@name = name
@times = []
@locations = []
@EARTH_RADIUS = { kilometers: 6378.135, miles: 3963.1676 }
if(load)
item = localStorage.getItem(@name)
item = JSON.parse(item)
for k,v in item
@times.push(k);
@locations.push(v);
@interval = setInterval =>
navigator.geolocation.getCurrentPosition (position) =>
here = "#{position.coords.latitude},#{position.coords.longitude}"
if(@movedFrom here)
@add(Date().valueOf(), here)
onUpdate(position,here);
,(error) ->
console.log(error)
switch(error.code)
when 1
console.log("declined")
when 3
console.log("timeout")
,enableHighAccuracy: true
,1000
null
haversine: (from, to, units = 'miles') ->
if(typeof from=="string" and typeof from=="string")
from_ = from.split /,\s*/
from_longitude = parseFloat(from_[0]).toRadians()
from_latitude = parseFloat(from_[1]).toRadians()
to_ = to.split /,\s*/
to_longitude = parseFloat(to_[0]).toRadians()
to_latitude = parseFloat(to_[1]).toRadians()
else
from_longitude = from.longitude.toRadians
from_latitude = from.latitude.toRadians
to_longitude = to.longitude.toRadians
to_latitude = to.latitude.toRadians
latitude_delta = to_latitude - from_latitude
longitude_delta = to_longitude - from_longitude
a = Math.pow(Math.sin(latitude_delta/2),2) +
Math.cos(from_latitude) *
Math.cos(to_latitude) *
Math.pow(Math.sin(longitude_delta/2),2)
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a))
d = @EARTH_RADIUS[units] * c
add: (time,location) ->
@times.push(time)
@locations.push(location)
null
length: () ->
@times.length
last: () ->
length = @times.length-1
length = 0 if length == -1
[ @times[length], @locations[length] ]
save: () ->
hash = {}
for i in [0..@times.length]
hash[@times[i]] = @locations[i]
console.log(JSON.stringify(hash))
localStorage.setItem(@name,JSON.stringify(hash))
movedFrom: (location) ->
length = @locations.length - 1
location != @locations[@locations.length - 1 ] || length==-1
timeAtPoint: (index=-1) ->
(new Date() - new Date(@times[index..]))/1000
distanceFromPoint: (index = -1) ->
@haversine(@location[-2],@location
stopLogging: ->
clearInterval(@interval)
prettyTime = () ->
now = new Date()
meridian = if now.getHours()<12 then "AM" else "PM"
h = if meridian=="AM" then now.getHours() else now.getHours()-12
date = now.toDateString().split(" ")[1] + " " + now.getDate()
"#{date} #{h}:#{now.getMinutes()} #{meridian}"
window.hash2 = new LocationHistory("test2", false,
(raw, here) -> document.getElementsByTagName("ul")[0].innerHTML+= "<li><b>#{here}</b><em>#{prettyTime()}</em></li>")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment