I've spent quite a bit of time reading up about using the google maps api and have put together the code below. The code first centers on a particular location, and then changes the centre of the map to the users current location - which it highlights with a second marker. It then refreshes the position of the second marker at 5s intervals, without re-centring the map. This works to different extents on different devices and browsers, and I was wondering how I might make it more cross-device compatible.
======================================================================================================================
Device Browser Display map Display map marker Display current location
======================================================================================================================
PC Chrome Yes Yes Yes (if allowed)
----------------------------------------------------------------------------------------------------------------------
iPhone 3 iOS 5 Yes Yes No
----------------------------------------------------------------------------------------------------------------------
Nokia n97 Opera Mobile Yes Yes Yes
----------------------------------------------------------------------------------------------------------------------
Nokia n97 Native symbian browser Yes, though hybrid map is poor No It detects the current location and centres the map there, but doesn't display the image.
----------------------------------------------------------------------------------------------------------------------
I need to host the map on my own site to ensure that it gets rendered correctly with my custom icons, etc.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>mysite - Find your way :)</title>
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
#map_canvas {
height: 100%;
}
@media print {
html, body {
height: auto;
}
#map_canvas {
height: 650px;
}
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?sensor=true"></script>
<script>
var map;
var current_location;
var clue_location;
function initialize()
{
var lostLatLong = new google.maps.LatLng(51.1,-0.1);
var mapOptions = {
zoom: 19,
center: lostLatLong,
mapTypeId: google.maps.MapTypeId.HYBRID,
streetViewControl: false,
rotateControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
}
}
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var image = '/static/images/maps_images/mysite-map-icon-48x48.png';
clue_location = new google.maps.Marker({
position: lostLatLong,
map: map,
icon: image
});
if(navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(function(position)
{
var current_location_image = '/static/images/maps_images/mysite_location-marker-64x64.png';
var newPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
current_location = new google.maps.Marker({
position: newPos,
map: map,
icon: current_location_image,
});
map.setCenter(newPos);
});
setTimeout(autoUpdateLocation, 5000);
}
}
function autoUpdateLocation()
{
navigator.geolocation.getCurrentPosition(function(position)
{
current_location.setMap(null);
var current_location_image = '/static/images/maps_images/mysite_location-marker-64x64.png';
var newPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
current_location = new google.maps.Marker({
position: newPos,
map: map,
icon: current_location_image,
});
});
setTimeout(autoUpdateLocation, 5000);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>
Your code seems to work for me in Opera Mobile 12.1 on Android. However, there are a couple of things which may be causing issues in some cases, for example there are two instances of setTimeout
running at the same time doing essentially the same thing. This also goes against the ideal of reusing code as much as possible, so I've tried to simplify your code here:
function initialize() {
var isFirstTime = true;
var lostLatLong = new google.maps.LatLng(51.1, -0.1);
var mapOptions = {
zoom: 19,
center: lostLatLong,
mapTypeId: google.maps.MapTypeId.HYBRID,
streetViewControl: false,
rotateControl: false,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
}
};
var map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
var image = '/static/images/maps_images/mysite-map-icon-48x48.png';
var clue_location = new google.maps.Marker({
position: lostLatLong,
map: map,
icon: image
});
function autoUpdateLocation() {
navigator.geolocation.getCurrentPosition(function(position) {
// Remove marker if necessary
if (!isFirstTime && current_location) {
current_location.setMap(null);
}
// Get new location
var current_location_image = '/static/images/maps_images/mysite_location-marker-64x64.png';
var newPos = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
var current_location = new google.maps.Marker({
position: newPos,
map: map,
icon: current_location_image
});
// Set centre first time only
if (isFirstTime && map) {
map.setCenter(newPos);
isFirstTime = false;
}
});
}
if (navigator.geolocation) {
setInterval(autoUpdateLocation, 5000);
}
}
google.maps.event.addDomListener(window, 'load', initialize);
Other notes:
I've replaced setTimeout
with setInterval
which is more appropriate for repeated tasks.
Put everything inside the initialize()
function to keep things out of the global namespace.
Removed ending commas on the last item in an object.
current_location
variable does not need to be declared outside the autoUpdateLocation()
function.
It can probably be improved further but this should be a bit more robust. Let me know if you're still having problems.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With