Search code examples
javascripthtmlgoogle-maps

issue with getting the markers on Google map to display from database?


Could you help with getting the markers on Google map to display? Markers are drawn from an SQL database which is converted into XML via a PHP request, then displayed on to the map through a separate JavaScript file. Ideally the clustering should work once the markers appear, but the issue is that they wont appear at all. Not sure if its an issue with defining the map or an issue with retrieving the data.

If someone has any idea I would be truly grateful.

JavaScript code

function initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
            center: new google.maps.LatLng(51.8642112, -2.2380335),
            zoom: 11 
        });
        var infoWindow = new google.maps.InfoWindow();

        downloadUrl("./MapStolenDAO.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 address = markerElem.getAttribute('address');
            var time = markerElem.getAttribute('time');
            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 = address
            infowincontent.appendChild(strong);
            infowincontent.appendChild(document.createElement('br'));
            
            var time = document.createElement('timestamp');
            time.timestampContent = time
            infowincontent.appendChild(Time);
            var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
            var marker = new google.maps.Marker({
                position: point,
                label: labels[i % labels.length]
            });

            marker.addListener('click', function() {
              infoWindow.setContent(infowincontent);
              infoWindow.open(map, marker);
            });
            var markerCluster = new MarkerClusterer(map, marker,
                {imagePath: './mapImages'});
        });
    });
}

PHP conversion of the SQL data to XML

<?php
$username="username is here but I've hidden it because of privacy";
$password="password is here but I've hidden it because of privacy";
$database="DBFlogger";

function parseToXML($htmlStr)
{
$xmlStr=str_replace('<','&lt;',$htmlStr);
$xmlStr=str_replace('>','&gt;',$xmlStr);
$xmlStr=str_replace('"','&quot;',$xmlStr);
$xmlStr=str_replace("'",'&#39;',$xmlStr);
$xmlStr=str_replace("&",'&amp;',$xmlStr);
return $xmlStr;
}

// Opens a connection to a MySQL server
$connection = mysqli_connect('localhost', $username, $password);
if (!$connection) {
    error_log("Failed to connect to MySQL: " . mysqli_error($connection));
    die('Internal server error');
}

// Set the active MySQL database
$db_selected = mysqli_select_db($connection, $database);
if (!$db_selected) {
    error_log("Database selection failed: " . mysqli_error($connection));
    die('Internal server error');
}

// Select all the rows in the markers table
$query = "SELECT * FROM tblBikeStolen WHERE 1";
$result = mysqli_query($connection, $query);
if (!$result) {
    error_log("Database query failed:" . mysqli_error($connection));
    die('Internal server error');
}

header("Content-type: text/xml");

// Start XML file, echo parent node
echo "<?xml version='1.0' ?>";
echo '<markers>';
$ind=0;
// Iterate through the rows, printing XML nodes for each
while ($row = @mysqli_fetch_assoc($result)){
  // Add to XML document node
  echo '<marker ';
  echo 'id="' . $row['BikeID'] . '" ';
  echo 'address="' . parseToXML($row['Address']) . '" ';
  echo 'lat="' . $row['Lat'] . '" ';
  echo 'lng="' . $row['Lng'] . '" ';
  echo 'time="' . $row['stolenTimestamp'] . '" ';
  echo '/>';
  $ind = $ind + 1;
}

// End XML file
echo '</markers>';

?>

Html for web page

<!DOCTYPE html>
 <html>
 <head>
     <title></title>
     <link rel="stylesheet" type="text/css" href="../../styles.css">
     <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
     <script src="https://kit.fontawesome.com/57cdec9607.js" crossorigin="anonymous"></script>
      <script src="https://unpkg.com/@google/[email protected]/dist/markerclustererplus.min.js"> 
     </script>

 </head>
 <body>
      <header>
         <a href="" style="float:left">BIKEIT!</a>
         <a href="../Public/Contacts.html">CONTACT</a>
         <a href="../Public/AboutUs.html">ABOUT</a>
         <a href="../Public/FAQ.html">FAQ</a>
         <a href="../Police/Police_Home.html">HOME</a>
      </header>
      <div id="master"></div>
      <h1 style="color: white; margin: 10px; text-align: center">Victim Location Frequency Map</h1>
       <div id="content">
        <div id="map" style="width:60%;height:700px;"></div>
    
        <script>
        initMap()
        </script>

        <script src="MapStolen.js"></script>
    
        <script 
        src="https://maps.googleapis.com/maps/api/js?key=AIzaSyAFkcR79QqNX1TuaLjSCmfgdSujOeYt1FU&callback=initMap">
        </script>
        
    </div>
    <div class="space"></div>
<!-- Site footer -->
    <footer class="site-footer">
        <div class="footcontainer">
            <div class="footrow">
                <div class="col-1-2 flL">
                    <img src="../../resources/gloucestershire-logo-header.png" class="footlogo">
                </div>

            <div class="col-1-4 flL">
                <h6>Quick Links</h6>
                <ul class="footer-links">
                    <li><a href="../Public/AboutUs.html">About Us</a></li>
                    <li><a href="../Public/Contacts.html">Contact Us</a></li>
                    <li><a href="https://www.gloucestershire.police.uk/contact/find-a-police-station/">Find a police station</a></li>
                    <li><a href="https://www.gloucestershire.police.uk/hyg/fpngloucs/privacy-notice/">Privacy Policy</a></li>
                    <li><a href="#">Cookies</a></li>
                    <li><a href="https://www.gloucestershire.police.uk/hyg/terms-conditions/">Terms and conditions</a></li>
                </ul>
            </div>

            <div class="col-1-4 flL">
                <h6>Partners</h6>
                <ul class="footer-links">
                    <li><a    href="https://www.gloucestershire.police.uk/">Gloucestershire Constabulary</a> </li>
                    <li><a href="https://www.police.uk/">Police.co.uk</a></li>
                    <li><a href="https://www.askthe.police.uk/content/@1.htm">Ask the Police</a></li>
                    <li><a href="https://www.gloucestershire-pcc.gov.uk/">Police and Crime Commissioner</a></li>
                </ul>
            </div>
        </div>
        <hr>
    </div>
    <div class="footcontainer">
        <div class="footrow">
            <div class="col-2-3 flL">
                <p class="copyright-text">Copyright &copy; 2020 All Rights Reserved by 
                <a href="https://www.gloucestershire.police.uk/">Gloucestershire Constabulary</a>
                     &amp; 
                <a href="../Police/Police_Home.html">BikeIt</a>.
                </p>
                </div>

            <div class="col-1-3 flL">
                <ul class="social-icons">
                    <li><a class="facebook" href="https://www.facebook.com/gloucestershire.constabulary"><i class="fa fa-facebook"></i></a></li>
                    <li><a class="twitter" href="https://twitter.com/glos_police"><i class="fa fa-twitter"></i></a></li>
                    <li><a class="youtube" href="https://www.youtube.com/user/GlosPolice"><i class="fab fa-youtube"></i></a></li>
                    <li><a class="snapchat" href="https://www.snapchat.com/add/glospol"><i class="fab fa-snapchat-ghost"></i></a></li>   
                </ul>
            </div>
        </div>
    </div>
</footer>
</body>
</html>

Solution

  • To see if it's an issue with retrieving the data, you could always print out the point variable to see if it's a valid lat/lng point.

    However I suspect the issue might be with the MarkerClusterer being inside the markers forEach loop. What you want to do is pass an array of markers to one instance of MarkerClusterer instead of creating a MarkerClusterer for each marker.

    It could look something like:

    downloadUrl("./MapStolenDAO.php", function(data) {
      var xml = data.responseXML;
      var markers = xml.documentElement.getElementsByTagName('marker');
      const mapMarkers = markers.map((markerElem) => {
        var id = markerElem.getAttribute('id');
        var address = markerElem.getAttribute('address');
        var time = markerElem.getAttribute('time');
        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 = address
        infowincontent.appendChild(strong);
        infowincontent.appendChild(document.createElement('br'));
    
        var time = document.createElement('timestamp');
        time.timestampContent = time
        infowincontent.appendChild(Time);
        var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
        var marker = new google.maps.Marker({
            position: point,
            label: labels[i % labels.length]
        });
    
        marker.addListener('click', function() {
          infoWindow.setContent(infowincontent);
          infoWindow.open(map, marker);
        });
        return marker;
      });
      var markerCluster = new MarkerClusterer(map, mapMarkers,
          {imagePath: './mapImages'});
      });
    });