Monday, 30 December 2013

JQuery mobile page event order

When navigating from A to B this is the page event order

page B---pagebeforeload
page B---pageload
page B---pagebeforecreate
page B---pagecreate
page B---pageinit
page A---pagebeforehide
page B---pagebeforeshow
page A---pageremove
page A---pagehide
page B---pageshow

Thursday, 19 December 2013

Distance between two latitude longitude coordinates using javascript

I'm building a smartphone app that enables users to search for holiday homes throughout the UK. To improve the UX I decided that a once-per-session download of the headline JSON data, into local storage, would allow me to perform lightning fast searches and filters without going back to the server each time.

One requirement is to search by radius from the user's location, which effectively means calculating the straight-line distance between two lat-lon coordinates on the surface of sphere. And not not consulting the server means using javascript.

This turned out to be easier than I'd imagined, and as ever thanks go to SO users with superior maths than I. One formula available is called the haversine formual, and the javascript implementation of it looks like this:
function getDistanceFromLatLonInKm(lat1,lon1,lat2,lon2) {
  var R = 6371; // Radius of the earth in km
  var dLat = deg2rad(lat2-lat1);  // deg2rad below
  var dLon = deg2rad(lon2-lon1); 
  var a = 
    Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * 
    Math.sin(dLon/2) * Math.sin(dLon/2)
    ; 
  var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
  var d = R * c; // Distance in km
  return d;
}

function deg2rad(deg) {
  return deg * (Math.PI/180)
}
What should be noted about this is the assumption that the Earth is spherical. It isn't, as it's actually fatter at the equator, making it a spheroid I believe. The radius figure of 6371km is a global average. So if you know you're only going to be using this formula for certain regions or countries it may be worth adjusting this figure to the radius appropriate to that particular latitude, thereby reducing the error margin.

Another option is to use a flat-earth model, which would presumably produce more accurate results over shorter distances, and runs faster because there's less computation:
HalfPi = 1.5707963;
R = 3956; /* the radius gives you the measurement unit*/

a = HalfPi - latoriginrad;
b = HalfPi - latdestrad;
u = a * a + b * b;
v = - 2 * a * b * cos(longdestrad - longoriginrad);
c = sqrt(abs(u + v));
return R * c;
I'm rolling with the haversine formula for now, but during testing I'll be comparing my distance results with 'real' ones from Google (who are always right - fact) to see what kind of accuracy I'm getting. It may be that the flat-earth formula suits me better for both speed and accuracy.

Friday, 6 December 2013

Change Active Admin password

Note to self.
    admin = AdminUser.find_by_email("admin@domain.com")
    admin.password = "newPassword"
    admin.save