views:

737

answers:

3

I need to determine a person's location within 50m. I'm wondering if I should use navigator.location.watchPostion() or call getCurrentPostion() over and over again. watchPostion() is the proper W3C API for doing what I want, but practically, it seems to be overkill.

Here's my code:

var map = null;
var marker = null;
var layer = null;

function locFn(pos) {

  var lat = pos.coords.latitude;
  var lon = pos.coords.longitude;

  $("#hlat").val(lat);
  $("#hlong").val(lon);

  document.getElementById("lnkMap").href = 
    "http://maps.google.com/maps?q=My+Loc@" + lat
    + "," + lon + "&z=18&t=h";

  var point = new GLatLng(lat, lon);

  if (pos.coords.accuracy < 100) {
    map.setCenter(point, 18);

    if (marker != null) {
      marker.setLatLng(point);
    }
    else {
      var ico = new GIcon();
      ico.image = "img/Blue-Dot.png";
      ico.iconSize = new GSize(22, 22);
      ico.iconAnchor = new GPoint(11, 11);
      marker = new GMarker(point, { icon: ico });
      layer = map.addOverlay(marker, { title: "You are here." });
    }
  }
  else if (pos.coords.accuracy > 2000) {
    if (marker != null) { marker.setLatLng(point); }
    map.setCenter(point, 15);
  }
  else if (pos.coords.accuracy > 900) {
    if (marker != null) { marker.setLatLng(point); }
    map.setCenter(point, 16);
  }
  else if (pos.coords.accuracy > 100) {
    if (marker != null) { marker.setLatLng(point); }
    map.setCenter(point, 17);
  }
}

function locFail() {
  //alert("Failed to retrieve location.");
}

var watchID = null;

function processPoints() {
  map = new GMap2(document.getElementById("map_canvas"), 
                  { mapTypes: [G_HYBRID_MAP] });
  try {
    watchID = navigator.geolocation.watchPosition(locFn, locFail,
          { enableHighAccuracy: true });
  }
  catch(err) { /* desktop?*/ }
}
$(function(){processPoints();});

I've noticed watchPostion() seems to ultimately result in more accuracy (after a while), but I'm wondering if the position changes so fast that it results in a lot of thing being downloaded to my map canvas, with constant http requests that are soon out-of-date, replaced by the new ones coming in. When I use watchPosition(), it does take a while before the page loads.

+3  A: 

After some serious testing, I have verified watchPosition() will give you an accurate location much more quickly than getCurrentPostion() over and over again. When using watchPostion(), the map behaves poorly if you redraw it over and over again every time the device updates your location. To get around this, I have added a listener to the tilesloaded event, which allows me to only redraw the map if there is not already a thread trying to draw on the map. Once the user is happy with the determined location, I will clear the watch. This will get me the best of both worlds, as far as battery consumption and accuracy are concerned.

alord1689
A: 

Any chance of posting a sample of that listener?

Sam
All I did was this: GEvent.addListener(map, "tilesloaded", function() { console.log("tiles loaded"); tilesloaded = true; });Then in the loop that is called either in the watchPosition() event or the setTimeout if using getCurrentPosition(), I check to see if tilesloaded. Calling enableContinuousZoom() seems to help the map work better as well.
alord1689
Excellent, thanks very much!
Sam
+2  A: 

Everytime you call getCurrentLocation the gps is spun up which takes a few moments. If you call watchPosition and wait until you get a certain accuracy, then remove your watch you will have better results, without the overhead of a constant watch.

Jesse MacFadyen