Hey guys, I came across this module a few days ago and WOW, it is awesome. I've been playing around and very excited about the potential.

I'm trying to do something a little off the beaten path and my javascript handicaps are holding me back, so I was wondering if anyone could help out.

I'm trying to integrate the new html 5 getCurrentPosition function (and watchPosition) to define the center of some, or all, of the maps on my site. I have some javascript I swiped from someone else that gets the functionality working, but I can't seem to use the variables in this code with the actual OL centering function.

SO, right now I'm using the OL views module and have pasted my getCurrentPosition code into the header. Here's that code.

function mapSetup() {
				if(navigator.geolocation) {
					// Get current position
					navigator.geolocation.getCurrentPosition(createMap, handleError); // Request live position
				
					window.scrollTo(0,1);
				} else {
					loaderContainer.getElementsByTagName("p")[0].textContent = "Browser does not support geolocation object";
					window.setTimeout(failedError, 1000);
				}

			};
			
			// Update handlers
			function createMap(){
				currentLatLng = new CM.LatLng(position.coords.latitude,position.coords.longitude);
				
				locationMarker = new CM.Marker(currentLatLng);

				loaderContainer.style.display = "none";
				
				mapInstance.setCenter(currentLatLng, 15);
				mapInstance.addOverlay(locationMarker);
				locationMarker.openInfoWindow("<h3>Your location</h3>");
				
				// Inital location found create a watchPosition instance for continuous updates
				coordsListener = navigator.geolocation.watchPosition(updateLocation, handleError);  

			};
			function cacheLocation(position){
				cacheLatLng = new CM.LatLng(position.coords.latitude,position.coords.longitude);
				
				locationMarker = new CM.Marker(cacheLatLng);     
				mapInstance.setCenter(cacheLatLng, 15);
				mapInstance.addOverlay(locationMarker);
				locationMarker.openInfoWindow("<h3>Your last known location</h3>");
			};
			function updateLocation(position){ // Fires everytime your location changes
				updatedLatLng = new CM.LatLng(position.coords.latitude,position.coords.longitude);
				
				// Moves marker to updated location.
				locationMarker.setLatLng(updatedLatLng);
				
				mapInstance.setCenter(updatedLatLng, 15);
				locationMarker.openInfoWindow("<h3>Your are here</h3>");
				window.scrollTo(0,1);
			};
			
			// Error handlers
function handleError(error){
				if(error.code === 1) {
					//Location services is either disabled or you denied access to your position
					failedError();
				} else {
					//Current location could not be determined, falling back to last known within 10 minutes
					navigator.geolocation.getCurrentPosition(cacheLocation, cacheError, {maximumAge:600000, timeout:0});
				}
				
				loaderContainer.style.display = "none";
			};
			function cacheError(error){
				//Couldn't get current nor no more than 10 min old cache location, fallback to any cache
				navigator.geolocation.getCurrentPosition(cacheLocation, failedError, {maximumAge:"Infinite", timeout:0});
			};
			function failedError(error){
				//Failed to find any location, fallback to Apple HQ
				
				failedLatLng = new CM.LatLng(37.331689,-122.030731);
				
				locationMarker = new CM.Marker(failedLatLng);         
				mapInstance.setCenter(failedLatLng, 15);
				mapInstance.addOverlay(locationMarker);
				locationMarker.openInfoWindow("<h3>Apple HQ</h3>");
				window.scrollTo(0,1);
			};

			
mapSetup();

SO, if I'm reading this correctly, and I'm sure that I'm not, the lat/lon is dumped to the variables position.coords.latitude and position.coords.longitude.

I've embedded the above code into a views header using the included views plugin which seems to be working fine by itself. The browser is asking to use my location, and it works standalone, so that's where I'm at.

I spent about 4 hours trying to hack this directly into the openlayers.js file with no luck. I'm wondering (read: hoping) that there is some small setCenter function or something that I can render with the above variables inside the mapSetup function that will update using my custom center-getting code.

OK, that's a mouthful. I may be off in la la land and this is a completely wrong approach. That's probably the case. BUT, if we were to acheive this level of functionality, it could be a very cool addition to the module to allow modern browsers (and mobile browsers) to interact with your work on a whole new level.

Anyhow, thanks to anyone who can offer advice. I look forward to hearing it.

Comments

tmcw’s picture

Hey,

I actually started on a project called geolocator (which is on drupal.org without any code currently). I'll put the code in that cvs this afternoon and get back to you. It certainly could use a little work, but the main idea is:

1. Support HTML5 location but eventually wrap the semi-nonstandard location apis (there's already some good code to do this, just need to bring it in and hope it's GPL)
2. Integrate with form widgets in simple ways. This probably shouldn't be a form widget itself, because it isn't an interface, rather a kind of shortcut. Right now, I've just put another button next to save, which users can easily reposition. More thinking needed.
3. Have a little code that updates certain complex widgets: the openlayers_cck widget, possibly other map selectors (like geo, if the geo cck module is stable enough)

apt94jesse’s picture

That's great, it's good to see other people are working towards this functionality too.

Like I said, my javascript is weak compared to my html and css (and even php) but it seems like the getCurrentPosition and watchPosition functions are pretty quick and easy to implement.

In my head, it goes something like this:

---

if checkboxOption = true

then

use getCurrentPosition as map center

---

then someone could just add a the getCurrentPosition function to make the lat/lon variables available to the map if the option was enabled.

I'm sure I'm oversimplifying things INCREDIBLY but it seems like a killer feature of HTML 5 and one that shouldn't be too tough for people smarter than I. Hell, if I can get a working version without Drupal, I know there are people out there that can integrate for the greater good.

tmcw’s picture

Hey, the source in head of the Geolocator module I'll refine it when I get a block of time to do so, but for now expect to need to hack it a little bit.

apt94jesse’s picture

Awesome, I took a look and it looks like you're off to a great start.

I've gotten some progress hacking the openlayers.js file, though there are still some roadblocks.

It's going something like this:



updateLocation = function(position){ // Fires everytime your location changes
                                var newCenter = new OpenLayers.LonLat(position.coords.longitude, position.coords.latitude);
                            var zoom = parseInt(map.center.zoom);

			OL.maps[map.id].map.setCenter(newCenter, zoom);
				window.scrollTo(0,1);


			};

 success = function(position) // 'position' can be named anything
{
    var center = new OpenLayers.LonLat(position.coords.longitude, position.coords.latitude);
	  var zoom = parseInt(map.center.zoom);
	  


    OL.maps[map.id].map.setCenter(center, zoom, false, false);

    locationMarker = new marker(center);
    OL.maps[map.id].map.addOverlay(locationMarker);
    locationMarker.openInfoWindow("<h3>Your location</h3>");

}
 fail = function() // 'position' can be named anything
{
  	alert("Your browser does not support Geolocation.  Centering at default."
 		+ position.coords.longitude);
    var center = new OpenLayers.LonLat(map.center.lon, map.center.lat);
	  var zoom = parseInt(map.center.zoom);
    OL.maps[map.id].map.setCenter(center, zoom, false, false);
}

  // Zoom to Center
  // @@TODO: Do this in the map options -- As is,
  // this will result in a bug in the zoom map helper in the map form
  if (OL.isSet(map.center)) {

// success callback, gets passed position object
      navigator.geolocation.getCurrentPosition(success, fail);


  }

With this code in place, all of the maps grab the gps coords from capable browsers and centers the map there. Then it constantly pings for new coords and updates if new ones are found.

The biggest problem I'm having right now is that it only works with the default WMS Layer and not with any of the 900913 projections. I'm thinking it has something to do with the placement being rendered from lat/lon coords instead of the alternative (which I'm learning about daily). HOWEVER, viewing the code from http://www.thecssninja.com/demo/gps_browser/ tells me otherwise, because this demo is using a cloudmade map (900913) and the coords are from exactly the same source (and same copied code).

Still a long way from drupal usable but at least it's getting there. These are very simple functions that should be easily extendable to other modules, which looks like what you're laying the groundwork for.

tmcw’s picture

Status: Active » Closed (won't fix)

Hey, I just noticed that the code you're using (with the CM namespace) is using CloudMade's web maps lite. The API for their code has no correlation to the OpenLayers API.

apt94jesse’s picture

Yea, I started from that point but if you'll look at the updated code, I've taken out the CM as it wasn't really necessary.

I've currently got everything working except I'm adding a marker at the center spot so that it follows you similar to standard gps systems. It will render in place at first but does not update the lon/lat when the center changes so it basically leaves yourself behind as you move.

That should be remedied soon. Then I plan to wrap it in an if statement and create some sort of toggle checkbox in the settings. Someone else will probably need to implement that but it should be available should the maintainers want to.

patrickroma’s picture

Hi there,im really interested in how you Managed the geolocation function in the Open Layers.js! Could you send or post a Step by step Approach? Do i have to Change the .js? Thanx in Advance

tmcw’s picture

The geolocator module has gone undeveloped for a while (I should just do it, it'll take an afternoon), but in the meantime, the code is really mostly in this project - get it via svn

svn co http://svn.openlayers.org/sandbox/camptocamp/geolocation/trunk geolocation

There's an examples/ directory in there with an example of how it might be integrated into a page. My eventual plan is to write an openlayers panel control that geolocates on click.

patrickroma’s picture

Hi, thanx for your answer. I still do not understand how - after having activated the module in drupal - how to set up the geoloaction to communicate with the openlayer-map? Maybe you could help me with a short description on how to integrate the code? I would also write then a short documentation if I will be able to understand how it works.

And I really like the idea of an openlayers panel control that geolocates... I think that with the upcoming use of mobile devices the geolocator module will become really important.

Would be nice, if you could help me out.

Thanx in advance...