Update google map markers every "x" seconds?

Eric Calkins
Eric Calkins used Ask the Experts™
on
Hi Everyone!  I got tired of endlessly searching google so I thought I'd sign up and ask this here.  I'm by no means an expert, but I'm trying to find some help adding code to my code to get these google map markers to update every 1-5 seconds, without any flashing and without a page refresh.

This code is fairly complete I think but any advise is always welcome to make it better.

<!DOCTYPE html >
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>MADAR with Google Maps</title>
    <style>
      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      
    </style>
  </head>

<html>
  <body>
  
    <div id="map"></div>

    <script>
      var customLabel = {
        status: {
          label: ''
        },
        alert: {
          label: 'A'
        }
      };

        function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
          center: new google.maps.LatLng(37.6458, -97.4543),
          zoom: 5,
          
          styles: [
            {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
            {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
            {
              featureType: 'administrative.locality',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'geometry',
              stylers: [{color: '#263c3f'}]
            },
            {
              featureType: 'poi.park',
              elementType: 'labels.text.fill',
              stylers: [{color: '#6b9a76'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry',
              stylers: [{color: '#38414e'}]
            },
            {
              featureType: 'road',
              elementType: 'geometry.stroke',
              stylers: [{color: '#212a37'}]
            },
            {
              featureType: 'road',
              elementType: 'labels.text.fill',
              stylers: [{color: '#9ca5b3'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry',
              stylers: [{color: '#746855'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'geometry.stroke',
              stylers: [{color: '#1f2835'}]
            },
            {
              featureType: 'road.highway',
              elementType: 'labels.text.fill',
              stylers: [{color: '#f3d19c'}]
            },
            {
              featureType: 'transit',
              elementType: 'geometry',
              stylers: [{color: '#2f3948'}]
            },
            {
              featureType: 'transit.station',
              elementType: 'labels.text.fill',
              stylers: [{color: '#d59563'}]
            },
            {
              featureType: 'water',
              elementType: 'geometry',
              stylers: [{color: '#17263c'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.fill',
              stylers: [{color: '#515c6d'}]
            },
            {
              featureType: 'water',
              elementType: 'labels.text.stroke',
              stylers: [{color: '#17263c'}]
            }
          ]
          
        });
        var infoWindow = new google.maps.InfoWindow;





          // Change this depending on the name of your PHP or XML file
          downloadUrl('https://madar.site/mapdata-ec.php', function(data) {
            var xml = data.responseXML;
            var markers = xml.documentElement.getElementsByTagName('marker');
            
            Array.prototype.forEach.call(markers, function(markerElem) {
              var id = markerElem.getAttribute('id');
              var nodeid = markerElem.getAttribute("nodeid");
              var city = markerElem.getAttribute('city');
              var state = markerElem.getAttribute('state');
              var rate = markerElem.getAttribute('rate');
              var latitude = markerElem.getAttribute('lat');
              var longitude = markerElem.getAttribute('lng');
              var trigger = markerElem.getAttribute('trigger');
              var version = markerElem.getAttribute('version');
              var compass = markerElem.getAttribute('compass');
              var datetime = markerElem.getAttribute('datetime');
              var pressure = markerElem.getAttribute('pressure');
              var avgmga = markerElem.getAttribute('avgmga');
              var event_type = markerElem.getAttribute('event_type');
              var type = markerElem.getAttribute('type');
              var point = new google.maps.LatLng(
                  parseFloat(markerElem.getAttribute('lat')),
                  parseFloat(markerElem.getAttribute('lng')));

              var infowincontent = document.createElement('div');
              var strong = document.createElement('strong');
              strong.textContent = "NODE: " + nodeid
              infowincontent.appendChild(strong);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Status: " + event_type
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Location: " + city + ", " + state
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Lat/Long: " + latitude + ", " + longitude
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));


              var text = document.createElement('text');
              text.textContent = "Trigger (+/- mGa): " + trigger
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Update Rate (sec): " + rate
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Compass (deg): " + compass
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Pressure (in/Hg): " + pressure
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

              var text = document.createElement('text');
              text.textContent = "Average Milligauss: " + avgmga
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));



              var text = document.createElement('text');
              text.textContent = "Version: " + version
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));
              
             var text = document.createElement('text');
              text.textContent = "Data Updated: " + datetime
              infowincontent.appendChild(text);
              infowincontent.appendChild(document.createElement('br'));

//              if (customLabel == 'alert') {		
              if (type == 'alert') {		

              var icon = customLabel[type] || {};			
              var marker = new google.maps.Marker({
                map: map,
                position: point,
                label: icon.label,
				animation: google.maps.Animation.BOUNCE 
 
              });
              marker.addListener('click', function() {
                infoWindow.setContent(infowincontent);
                infoWindow.open(map, marker);
//              });
//            }});   
		  });
       }
              if (type == 'status') {		

              var icon = customLabel[type] || {};			
              var marker = new google.maps.Marker({
                map: map,
                position: point,
                label: icon.label,
				animation: google.maps.Animation.DROP 
 
              });
              marker.addListener('click', function() {
                infoWindow.setContent(infowincontent);
                infoWindow.open(map, marker);
                
              });
           }});   
		  });
       }








      function downloadUrl(url, callback) {
        var request = window.ActiveXObject ?
            new ActiveXObject('Microsoft.XMLHTTP') :
            new XMLHttpRequest;

        request.onreadystatechange = function() {
          if (request.readyState == 4) {
            request.onreadystatechange = doNothing;
            callback(request, request.status);
          }
        };

        request.open('GET', url, true);
        request.send(null);
      }

      function doNothing() {}
    </script>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB_uwBBL3YPzbYDVhKQ_N0xpVieXKsPCAM&callback=initMap">
    </script>

  </body>
</html>

Open in new window


Thanks all!
Eric
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
leakim971Multitechnician
Top Expert 2014

Commented:
check lines 126 to 130
lines 131 and 256, we put all the code loading the point in a function : loadMarkers
lines 134, 137, 252, 253,
line 257 to run the function to load
line 258 a timer will reload (remove+load) the markers every 10s

<!DOCTYPE html >
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>MADAR with Google Maps</title>
    <style>
        /* Always set the map height explicitly to define the size of the div
         * element that contains the map. */
        #map {
            height: 100%;
        }
        /* Optional: Makes the sample page fill the window. */
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }

    </style>
</head>

<html>
<body>

<div id="map"></div>

<script>
    var customLabel = {
        status: {
            label: ''
        },
        alert: {
            label: 'A'
        }
    };

    function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
            center: new google.maps.LatLng(37.6458, -97.4543),
            zoom: 5,

            styles: [
                {elementType: 'geometry', stylers: [{color: '#242f3e'}]},
                {elementType: 'labels.text.stroke', stylers: [{color: '#242f3e'}]},
                {elementType: 'labels.text.fill', stylers: [{color: '#746855'}]},
                {
                    featureType: 'administrative.locality',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#d59563'}]
                },
                {
                    featureType: 'poi',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#d59563'}]
                },
                {
                    featureType: 'poi.park',
                    elementType: 'geometry',
                    stylers: [{color: '#263c3f'}]
                },
                {
                    featureType: 'poi.park',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#6b9a76'}]
                },
                {
                    featureType: 'road',
                    elementType: 'geometry',
                    stylers: [{color: '#38414e'}]
                },
                {
                    featureType: 'road',
                    elementType: 'geometry.stroke',
                    stylers: [{color: '#212a37'}]
                },
                {
                    featureType: 'road',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#9ca5b3'}]
                },
                {
                    featureType: 'road.highway',
                    elementType: 'geometry',
                    stylers: [{color: '#746855'}]
                },
                {
                    featureType: 'road.highway',
                    elementType: 'geometry.stroke',
                    stylers: [{color: '#1f2835'}]
                },
                {
                    featureType: 'road.highway',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#f3d19c'}]
                },
                {
                    featureType: 'transit',
                    elementType: 'geometry',
                    stylers: [{color: '#2f3948'}]
                },
                {
                    featureType: 'transit.station',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#d59563'}]
                },
                {
                    featureType: 'water',
                    elementType: 'geometry',
                    stylers: [{color: '#17263c'}]
                },
                {
                    featureType: 'water',
                    elementType: 'labels.text.fill',
                    stylers: [{color: '#515c6d'}]
                },
                {
                    featureType: 'water',
                    elementType: 'labels.text.stroke',
                    stylers: [{color: '#17263c'}]
                }
            ]

        });
        var infoWindow = new google.maps.InfoWindow;

        var markersArray = [];
        function removeAllMarkers() {
            while(markersArray.length)
                markersArray.pop().setMap(null);
        }
        function loadMarkers() {
            // Change this depending on the name of your PHP or XML file
            downloadUrl('https://madar.site/mapdata-ec.php', function(data) {
                removeAllMarkers();
                var xml = data.responseXML;
                var markers = xml.documentElement.getElementsByTagName('marker');
                var i = 0;
                Array.prototype.forEach.call(markers, function(markerElem) {
                    var id = markerElem.getAttribute('id');
                    var nodeid = markerElem.getAttribute("nodeid");
                    var city = markerElem.getAttribute('city');
                    var state = markerElem.getAttribute('state');
                    var rate = markerElem.getAttribute('rate');
                    var latitude = markerElem.getAttribute('lat');
                    var longitude = markerElem.getAttribute('lng');
                    var trigger = markerElem.getAttribute('trigger');
                    var version = markerElem.getAttribute('version');
                    var compass = markerElem.getAttribute('compass');
                    var datetime = markerElem.getAttribute('datetime');
                    var pressure = markerElem.getAttribute('pressure');
                    var avgmga = markerElem.getAttribute('avgmga');
                    var event_type = markerElem.getAttribute('event_type');
                    var type = markerElem.getAttribute('type');
                    var point = new google.maps.LatLng(
                        parseFloat(markerElem.getAttribute('lat')),
                        parseFloat(markerElem.getAttribute('lng')));

                    var infowincontent = document.createElement('div');
                    var strong = document.createElement('strong');
                    strong.textContent = "NODE: " + nodeid
                    infowincontent.appendChild(strong);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Status: " + event_type
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Location: " + city + ", " + state
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Lat/Long: " + latitude + ", " + longitude
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));


                    var text = document.createElement('text');
                    text.textContent = "Trigger (+/- mGa): " + trigger
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Update Rate (sec): " + rate
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Compass (deg): " + compass
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Pressure (in/Hg): " + pressure
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Average Milligauss: " + avgmga
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));



                    var text = document.createElement('text');
                    text.textContent = "Version: " + version
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

                    var text = document.createElement('text');
                    text.textContent = "Data Updated: " + datetime
                    infowincontent.appendChild(text);
                    infowincontent.appendChild(document.createElement('br'));

//              if (customLabel == 'alert') {
                    if (type == 'alert') {

                        var icon = customLabel[type] || {};
                        var marker = new google.maps.Marker({
                            map: map,
                            position: point,
                            label: icon.label,
                            animation: google.maps.Animation.BOUNCE

                        });
                        marker.addListener('click', function() {
                            infoWindow.setContent(infowincontent);
                            infoWindow.open(map, marker);
//              });
//            }});
                        });
                        markersArray[i] = marker;
                        i++
                    }
                    if (type == 'status') {

                        var icon = customLabel[type] || {};
                        var marker = new google.maps.Marker({
                            map: map,
                            position: point,
                            label: icon.label,
                            animation: google.maps.Animation.DROP

                        });
                        marker.addListener('click', function() {
                            infoWindow.setContent(infowincontent);
                            infoWindow.open(map, marker);

                        });
                        markersArray[i] = marker;
                        i++
                    }});
            });
        }
        loadMarkers();
        setInterval(loadMarkers, 10*1000); // refresh every 10s
    }








    function downloadUrl(url, callback) {
        var request = window.ActiveXObject ?
            new ActiveXObject('Microsoft.XMLHTTP') :
            new XMLHttpRequest;

        request.onreadystatechange = function() {
            if (request.readyState == 4) {
                request.onreadystatechange = doNothing;
                callback(request, request.status);
            }
        };

        request.open('GET', url, true);
        request.send(null);
    }

    function doNothing() {}
</script>
<script async defer
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB_uwBBL3YPzbYDVhKQ_N0xpVieXKsPCAM&callback=initMap">
</script>

</body>
</html>

Open in new window

Multitechnician
Top Expert 2014
Commented:
bonus a jQuery version test page : http://leak.im/29152370/
<!DOCTYPE html >
<head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <title>MADAR with Google Maps</title>
    <style>
        /* Always set the map height explicitly to define the size of the div
         * element that contains the map. */
        #map {
            height: 100%;
        }
        /* Optional: Makes the sample page fill the window. */
        html, body {
            height: 100%;
            margin: 0;
            padding: 0;
        }
    </style>
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<div id="map"></div>
<script src="styles.js"></script>
<script>
    function initMap() {
        var customLabel = {
            status: {
                label: ''
            },
            alert: {
                label: 'A'
            }
        };
        var map = new google.maps.Map(document.getElementById('map'), {
            center: new google.maps.LatLng(37.6458, -97.4543),
            zoom: 5,
            styles: styles
        });
        var infoWindow = new google.maps.InfoWindow;
        var markers = [];
        function removeAllMarkers() {
            while(markers.length) {
                markers.pop().setMap(null);
            }
        }
        function loadMarkers() {
            $.get('proxy.php', function(data) {
                removeAllMarkers();
                $("marker", data).each(function(index,markerElem) {
                    var html = "";
                    html += "<div>";
                    html += "<strong>NODE: " + markerElem.getAttribute("nodeid") + "</strong><br>";
                    html += "<text>Status: " + markerElem.getAttribute("event_type") + "</text><br>";
                    html += "<text>Location: " + markerElem.getAttribute("city")  + ", " + markerElem.getAttribute("state") + "</text><br>";
                    html += "<text>Lat/Long: " + markerElem.getAttribute("lat") + ", " + markerElem.getAttribute("lng") + "</text><br>";
                    html += "<text>Trigger (+/- mGa): " + markerElem.getAttribute("trigger") + "</text><br>";
                    html += "<text>Update Rate (sec): " + markerElem.getAttribute("rate") + "</text><br>";
                    html += "<text>Compass (deg): " + markerElem.getAttribute("compass") + "</text><br>";
                    html += "<text>Pressure (in/Hg): " + markerElem.getAttribute("pressure") + "</text><br>";
                    html += "<text>Average Milligauss: " + markerElem.getAttribute("avgmga") + "</text><br>";
                    html += "<text>Version: " + markerElem.getAttribute("version") + "</text><br>";
                    html += "<text>Data Updated: " + markerElem.getAttribute("datetime") + "</text><br>";
                    html += "</div>";
                    var infowincontent = $(html).get(0);

                    var point = new google.maps.LatLng(parseFloat(markerElem.getAttribute('lat')), parseFloat(markerElem.getAttribute('lng')));

                    var type = markerElem.getAttribute("type");
                    var icon = customLabel[type] || {};
                    var markerAttr = {
                        map: map,
                        position: point,
                        label: icon.label,
                    };
                    if(type == 'alert')
                        markerAttr.animation = google.maps.Animation.BOUNCE;
                    else if(type == 'status')
                        markerAttr.animation = google.maps.Animation.DROP;
                    var marker = new google.maps.Marker(markerAttr);
                    marker.addListener('click', function() {
                        infoWindow.setContent(infowincontent);
                        infoWindow.open(map, marker);
                    });
                    markers[index] = marker;
                });
            });
        }
        loadMarkers();
        setTimeout(loadMarkers, 10000);
    }
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB_uwBBL3YPzbYDVhKQ_N0xpVieXKsPCAM&callback=initMap"></script>
</body>
</html>

Open in new window

Eric CalkinsSenior Systems Engineer

Author

Commented:
Perfect! Thank you so much for your help!

Eric :)
Eric CalkinsSenior Systems Engineer

Author

Commented:
This refresh code has been working great, however the web browser (tested in Chrome, Firefox, Safari) becomes somewhat unresponsive over a short time.  No errors in the console.  Seems to be some memory issue.  Have any thoughts?
leakim971Multitechnician
Top Expert 2014

Commented:
you can use Chrome Dev Tools and check Memory tab (and others)
you may want to refresh the page instead delete/add markers after a certains period

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial