getting users geolocation via html5 and javascript

17,523

Solution 1

Here is a script (geolocator.js) I wrote some time ago and updated recently.

Update: Geolocator v2 is released.

Features:

  • HTML5 geolocation (by user permission)
  • Location by IP
  • Geocoding (coordinates from address)
  • Reverse Geocoding (address lookup from coordinates)
  • Full address information (street, town, neighborhood, region, country, country code, postal code, etc...)
  • Fallback mechanism (from HTML5-geolocation to IP-geo lookup)
  • Watch geographic position
  • Get distance matrix and duration
  • Calculate distance between two geographic points
  • Get timezone information
  • Get client IP
  • Supports Google Loader (loads Google Maps dynamically)
  • Dynamically creates Google Maps (with marker, info window, auto-adjusted zoom)
  • Non-blocking script loading (external sources are loaded on the fly without interrupting page load)

See a live demo.
See API documentation.

Geolocator Example Screenshot

Usage:

var options = {
    enableHighAccuracy: true,
    timeout: 6000,
    maximumAge: 0,
    desiredAccuracy: 30, // meters
    fallbackToIP: true, // get location by IP if geolocation fails or rejected
    addressLookup: true, // requires Google API key
    timezone: true, // requires Google API key
    map: "my-map" // creates a Google map. requires Google API key
};
geolocator.locate(options, function (err, location) {
    console.log(err || location);
});

Example Output:

{
    coords: {
        latitude: 37.4224764,
        longitude: -122.0842499,
        accuracy: 30,
        altitude: null,
        altitudeAccuracy: null,
        heading: null,
        speed: null
    },
    address: {
        commonName: "",
        street: "Amphitheatre Pkwy",
        route: "Amphitheatre Pkwy",
        streetNumber: "1600",
        neighborhood: "",
        town: "",
        city: "Mountain View",
        region: "Santa Clara County",
        state: "California",
        stateCode: "CA",
        postalCode: "94043",
        country: "United States",
        countryCode: "US"
    },
    formattedAddress: "1600 Amphitheatre Parkway, Mountain View, CA 94043, USA",
    type: "ROOFTOP",
    placeId: "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
    timezone: {
        id: "America/Los_Angeles",
        name: "Pacific Standard Time",
        abbr: "PST",
        dstOffset: 0,
        rawOffset: -28800
    },
    flag: "//cdnjs.cloudflare.com/ajax/libs/flag-icon-css/2.3.1/flags/4x3/us.svg",
    map: {
        element: HTMLElement,
        instance: Object, // google.maps.Map
        marker: Object, // google.maps.Marker
        infoWindow: Object, // google.maps.InfoWindow
        options: Object // map options
    },
    timestamp: 1456795956380
}

Solution 2

You would then use a geo ip api like this one:

http://freegeoip.net/static/index.html

Solution 3

Ok so this is not a code answer, more of an User Experience answer.

From a UX standpoint, the first thing that stands out is the lack of information you are offering before you trigger the browser to ask them for permission.

I suggest you have some sort of overlay box showing a screen shot (with a large arrow on it) demonstrating "where" on the screen that they are going to get asked for permission. Also you can take that opportunity to tell them what will happen if they deny permission or fail to accept it within say 10 seconds (ie. where they ignore the prompt bar).

I suggest you don't default to showing the IP location, because they essentially 'could be saying' I don't agree to letting you know where I am. Then you show a big map of where they are, that may freak a few people out that clicked deny! Besides it may be very inaccurate.

The idea of "don't ask for permission ask for forgiveness", may work in Biz dev, but not in UI as they just don't come back.

I would ask yourself if you really need high accuracy too, because it will drain user battery, take longer, and may not give you much more bang for your buck, especially if you only need it to find out loosely where they are. You can always call it again later for a more accurate reading if you need to.

The concept of timing out if they don't click deny or allow could be achieved with a setTimeout. So once they click "Ok I'm ready to click allow" on your overlay box, kick off a timeout and if it does eventually timeout then do what you told them you would do in the above step.

By using this method, you force the user to either allow or deny(ignore), either-way it puts control back in your court, and keep the user totally informed.

Although this is not a code specific answer, it is clear from your JS that "code implementation help" is not really the issue here. I hope if nothing else this gets you thinking a little more about your User Experience.

Share:
17,523

Related videos on Youtube

whatf
Author by

whatf

Updated on June 29, 2022

Comments

  • whatf
    whatf almost 2 years

    I am trying to get the users geolocation via the html5 geolcation api, and i use the following snippet for it:

    if (navigator.geolocation) {
        var timeoutVal = 10 * 1000 * 1000;
        navigator.geolocation.getCurrentPosition(
          displayPosition, 
          displayError,
          { enableHighAccuracy: true, timeout: timeoutVal, maximumAge: 0 }
        );
      }
      else {
         // DO SOME STUFF HERE
      }
    
    
      function displayPosition(position) {
    
        // configuration
        var myZoom = 12;
        var myMarkerIsDraggable = true;
        var myCoordsLenght = 6;
        var defaultLat = position.coords.latitude;
        var defaultLng = position.coords.longitude;
        document.getElementById('latitude').value = defaultLat;
        document.getElementById('longitude').value = defaultLng;
        /*
          1. creates the map
          2. zooms
          3. centers the map
          4. sets the map’s type
        */
        var map = new google.maps.Map(document.getElementById('canvas'), {
          zoom: myZoom,
          center: new google.maps.LatLng(defaultLat, defaultLng),
          mapTypeId: google.maps.MapTypeId.ROADMAP
        });
    
    
        });
        // centers the map on markers coords
        map.setCenter(myMarker.position);
        // adds the marker on the map
        myMarker.setMap(map);
      }
    
      function displayError(error) {
        var errors = { 
          1: 'Permission denied',
          2: 'Position unavailable',
          3: 'Request timeout'
        };
        alert("Error: " + errors[error.code]);
      }
    });
    

    The trouble with the above approach is that, few of the users have found it difficult to use. Few of the times, they have clicked Deny instead of Allow and keep staring on the screen. So from usability point of view, I think a good approach would be:

    1. Ask them for permission.

    2. Wait for 3 seconds, if they click deny or don't respond, use IP to show the geolcation on the map.

    How can I accomplish the second step in my above snippets. Please let me know, thanks! However, what would be a better way to handle

  • whatf
    whatf about 11 years
    i want an answer for webapp.
  • Suvi Vignarajah
    Suvi Vignarajah about 11 years
    Very well put. I want to second the point made about defaulting to show IP Location when they initially Deny showing their location - this would definitely make the user feel "unsafe" visiting your site, because they won't necessarily be aware that your using an IP to Geolocation service once they deny HTML5 geolocation.
  • Suvi Vignarajah
    Suvi Vignarajah about 11 years
    I've actually done an assessment on a few of the free IP to Geolocation services out there and compared their accuracy on a map. You can check it out here if your deciding on a service to use: svignara.github.com/geolocation.html You can check my codebase on github to see how to make the ajax requests to these services.