5

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>
user714852
  • 2,054
  • 4
  • 30
  • 52
  • I don't have an iPhone or a Nokia n97, so I cannot test, but I'd suggest playing with your CSS. Try removing all of it, and just setting a fixed width and height to your map container
    .
    – Marcelo Oct 22 '12 at 15:17
  • 1
    Your question needs rewording because it's not explicitly asking what it is to be achieved as opposed to the current behaviour. There are many solutions to "make maps MORE cross-browser compatible". You got 75 views, no answers. Try a device/browser specific question first? – sainiuc Oct 23 '12 at 09:40
  • RoManiac, thank you for your feedback. I've edited the title and tags to make it a bit more specific. – user714852 Oct 23 '12 at 16:30

1 Answers1

2

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.

tagawa
  • 4,561
  • 2
  • 27
  • 34
  • tagawa, thanks for your response. I've tried the code and it doesn't work out the box - the 'current location' marker persists after refresh and you end up with a bunch of markers showing where you were 10 seconds ago. – user714852 Nov 21 '12 at 21:53