Safari5 Unable To Get Geolocation, Why?

With the latest release of Safari, the browser claims to support HTML5. A few days ago, I got a feedback that the NearBy Tweet prototype is not working in Safari5 (desktop). I never test it in Safari before, and turn out it doesn’t work due to no geolocation detected. So I tried map.google.com, it was unable to show my location as well. See screenshot below.


After a bit of digging around, It turns out Safari5 is using CoreLocation (wifi triangulation) to get geolocation data and it is only works when Wifi is ON. If you are using Safari5 on PC just turn on your wireless and if you are using Mac, just turn on Airport. It works!!

Advertisements

Find Destination (Lat,Lng) Given Distance & Bearing

Here, I will be posting a C# implementation to find a destination (latitude, longitude) given distance and bearing. This will be continuation from my previous post. Just add the method to the skeleton class GLatLng.

public GLatLng DestinationPoint(double dist, double brng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    dist = dist / R;
    brng = Math.PI * brng / 180;
    double lat1 = DegreeToRadian(latitude);
    double lon1 = DegreeToRadian(longitude);
<p>    double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(dist) + Math.Cos(lat1) * Math.Sin(dist) * Math.Cos(brng));
    double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(dist) * Math.Cos(lat1), Math.Cos(dist) - Math.Sin(lat1) * Math.Sin(lat2));
<p>    lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
    lat2 = RadianToDegree(lat2);
    lon2 = RadianToDegree(lon2);
<p>    GLatLng newLatLng = new GLatLng(lat2, lon2);
    return newLatLng;
} // end DestinationPoint
public GLatLng RhumbDestinationPoint(double dist, double brng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double d = dist / R;  
    double lat1 = DegreeToRadian(this.latitude);
    double lon1 = DegreeToRadian(this.longitude);
    brng = DegreeToRadian(brng);
    double lat2 = lat1 + d * Math.Cos(brng);
    double dLat = lat2 - lat1;
    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    double q = Math.Cos(lat1);
    if (dPhi != 0) q = dLat / dPhi;  // E-W line gives dPhi=0
    double dLon = d * Math.Sin(brng) / q;
     if (Math.Abs(lat2) &gt; Math.PI / 2) lat2 = (lat2 &gt; 0) ? Math.PI - lat2 : -(Math.PI - lat2);
    double lon2 = (lon1 + dLon + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
   return new GLatLng(RadianToDegree(lat2), RadianToDegree(lon2));
} // end RhumbDestinationPoint

Calculate Distance & Bearing Between Geolocation

Recently, I toyed with “nearby” services based on geolocation. In this post, I will be sharing C# implementation to calculate distance and bearing between geolocation.  

Let’s start with the skeleton class GLatLng below

using System;

namespace GMap
{
    public enum DistanceType : int
    {
        Miles = 0,
        Kilometers = 1
    }
   
    public class GLatLng
    {
        public const double EarthRadiusInMiles = 3956.0;
        public const double EarthRadiusInKilometers = 6367.0;
       
        private double latitude;
        private double longitude;

        public GLatLng(double latitude, double longitude)
        {
            this.latitude = latitude;
            this.longitude = longitude;
        }

        public double DegreeToRadian(double angle) { return Math.PI * angle / 180.0; }

        public double RadianToDegree(double angle) { return 180.0 * angle / Math.PI; }
       
        public double Latitude
        {
            get { return this.latitude; }
            set { this.latitude = value; }
        }
        public double Longitude
        {
            get { return this.longitude; }
            set { this.longitude = value; }
        }
    } // end class GLatLng
}

The following is the method to calculate the distance. You can choose the distance type between miles or kilometers. This uses haversine formula which give great-circle distances between two points on a sphere from their longitudes and latitudes.

public double DistanceTo(double lat, double lng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double dLat = DegreeToRadian(lat) - DegreeToRadian(this.latitude);
    double dLon = DegreeToRadian(lng) - DegreeToRadian(this.longitude);
    double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) + Math.Cos(DegreeToRadian(this.latitude)) * Math.Cos(DegreeToRadian(lat)) * Math.Sin(dLon / 2) * Math.Sin(dLon / 2);
    double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
    double distance = c * R;

    return Math.Round(distance, 2);
} // end DistanceTo

The second way to calculate the distance is based on the rhumb line which generally longer than great-circle routes.

public double RhumbDistanceTo(double lat, double lng, DistanceType dType)
{
    double R = (dType == DistanceType.Miles) ? EarthRadiusInMiles : EarthRadiusInKilometers;
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLat = DegreeToRadian(lat - this.latitude);
    double dLon = DegreeToRadian(Math.Abs(lng - this.longitude));

    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    double q = Math.Cos(lat1);
    if (dPhi != 0) q = dLat / dPhi;  // E-W line gives dPhi=0
    // if dLon over 180° take shorter rhumb across 180° meridian:
    if (dLon > Math.PI) dLon = 2 * Math.PI - dLon;
    double dist = Math.Sqrt(dLat * dLat + q * q * dLon * dLon) * R;

    return dist;
} // end RhumbDistanceTo

Next methods calculate the bearing between geolocation. Similar to distance there are 2 ways to calculate the bearing.


public double RhumbBearingTo(double lat, double lng)
{
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLon = DegreeToRadian(lng - this.longitude);

    double dPhi = Math.Log(Math.Tan(lat2 / 2 + Math.PI / 4) / Math.Tan(lat1 / 2 + Math.PI / 4));
    if (Math.Abs(dLon) > Math.PI) dLon = (dLon > 0) ? -(2 * Math.PI - dLon) : (2 * Math.PI + dLon);
    double brng = Math.Atan2(dLon, dPhi);

    return (RadianToDegree(brng) + 360) % 360;
} // end RhumbBearingTo

public double BearingTo(double lat, double lng)
{
    double lat1 = DegreeToRadian(this.latitude);
    double lat2 = DegreeToRadian(lat);
    double dLon = DegreeToRadian(lng) - DegreeToRadian(this.longitude);

    double y = Math.Sin(dLon) * Math.Cos(lat2);
    double x = Math.Cos(lat1) * Math.Sin(lat2) - Math.Sin(lat1) * Math.Cos(lat2) * Math.Cos(dLon);
    double brng = Math.Atan2(y, x);

    return (RadianToDegree(brng) + 360) % 360;
} // end BearingTo

Detects Support for HTML5 and CSS3 (cont’d)

Previously I blog about the same topic “Detects Support for HTML5 and CSS3” but I did not cover much on the CSS3. As a follow up now we look into it. Similar to HTML5, we can use Modernizr to detect CSS3 support. It is like having an if-statement in the css and the syntax is easy to use. There are 2 things you can do with Modernizr in this scenario: 

  1. Automatically load the style supported by the browser. This can be achieve by defining 2 set of classes (see example below); and
  2. Perform additional action when the CSS class is not supported. This can be achive by checking the JavaScript property (see example below).

The snippet below show how to define the CSS classes.

  .borderradius div.somediv {
   /* properties for browsers that
      support border radius */
  }
  .no-borderradius div.somediv {
   /* optional fallback properties
     for browsers that don't */  
  }

Detect CSS3 Classes & JS Property for Border Radius
As you can see the syntax is simple, as add “no” to handle the non-supported style. Find out more about the features that can be detected using Modernizr in the documentation (http://www.modernizr.com/docs/). The figure below shows Modernizr in action and the full example is available below. 

Detects CSS3 - Modernizr in Action
<!DOCTYPE html>
<html>
  <head>
  <title>Detect CSS3</title>

 <style type="text/css">
  body {
      margin: 0;
      font-family: Helvetica;
      background-color: #ddd;
  }
  div.somediv {
   margin: 50px;
  }
  
  .borderradius div.somediv {
     background: #fff;
     border-radius: 30px 30px 0 0;
     -moz-border-radius-topleft: 30px;
     -moz-border-radius-topright: 30px;
     -webkit-border-top-left-radius: 30px;
     -webkit-border-top-right-radius: 30px;
     width: 300px;
     padding: 30px;
  }
  .no-borderradius div.somediv {
     background: #000;
     color: #fff;
     border: 1px solid #fff;
     width: 300px;
     padding: 30px;
  }
 </style>

</head>
<body>

<div id="outer">
  Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi vitae consequat tellus. Nulla non velit leo, a pellentesque arcu. Donec aliquet urna in nibh consectetur aliquet non id purus. Curabitur vitae lacus ut nisl elementum sollicitudin. Etiam lorem nunc, iaculis in vehicula vel, convallis in nisi. Quisque diam risus, pharetra sed hendrerit ac, scelerisque non quam. Sed ac ligula nulla, vel lobortis purus. Suspendisse potenti. Integer sit amet diam quam, vitae posuere ligula. Vestibulum lorem nibh, vehicula ac venenatis eu, ornare pharetra tortor. Aliquam sed massa sem, non viverra enim. Integer augue odio, laoreet at posuere sit amet, convallis nec nisl. Donec vel purus arcu, ac venenatis mi.
</div>

</body>
</html>
<script type="text/javascript" src="<a href="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js%22%3E%3C/script">http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script</a>>
<script language=JavaScript src="js/modernizr-1.5.min.js" type="text/javascript"></script>
<script>
 $(document).ready(function () {
  if (!Modernizr.borderradius)  {
   alert('Border Radius is not supported in this browser.\n Do something about it ');
  }
 });// end document ready

</script>