0

I am making a Leaflet map that gets its marker and popup information from a database.

I have a dropdown that allows me to retrieve a subset of the entire database based on category. The drop-down and map work correctly.

I have 2 problems:

  1. I have been unsuccessful getting fitBounds to work.
  2. When the map loads a category of markers from the dropdown, I want any existing markers on the map from previous searches removed

Here is the code:

<link rel="stylesheet" href="leaflet.css" />
<script src="leaflet-src.js"></script>
<script type="text/javascript" src="leaflet.ajax.js"></script>
<title>Member Map</title>
</head>
<body>
  <div id="options">
    <?php
      $conn = new mysqli("localhost","","","") or die($this->mysqli->error);
      $result = $conn->query("SELECT Bus_categories FROM markers GROUP BY Bus_categories");
      echo "<form>";
      echo "<select name='cs' onchange='showUser (this.value)'>";
      echo "<option style='value=selected'>Select Business Category</option>";
      while ($row = $result->fetch_assoc()) {
        unset($name);
        $name = $row['Bus_categories']; 
        echo '<option  value="'.$name.'">'.$name.'</option>';
      }
      echo "</select></form>";
    ?>
  </div>
  <div id="map"></div>
  <script type="text/javascript">
    var geojsonLayer;
    var bounds;
    var m = L.map('map').setView([39.1, -94.5], 8);
    var mopt = {
      url: 'https://api.mapbox.com/styles/v1/mapbox/streets-v10/tiles/256/{z}/{x}/{y}?access_token=<API KEY HERE>',
      options: {attribution:'© <a href="https://www.mapbox.com/map-feedback/">Mapbox</a> © <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'}
    };
    var mq = L.tileLayer(mopt.url,mopt.options);
    mq.addTo(m);

    function popUp(feature,layer) {
      layer.bindPopup(
        "<h2>"+feature.properties.Member_Name+
        "<h3>"+feature.properties.Address+
        "<br>"+feature.properties.City+
        "<br><br><a href=tel:"+feature.properties.Phone+ ">"+feature.properties.Phone+ "</a>" +
        "<br><br><a href=mailto:"+feature.properties.Email+ ">" +feature.properties.Email+ "</a>" +
        "<br><br><a href=http://"+feature.properties.Website+ ">" +feature.properties.Website+ "</a>" +
        "<br>"
      );
    }

    function showUser(str) {
      geojsonLayer = new L.GeoJSON.AJAX(["geojson.php?cs="+str,true],{onEachFeature:popUp}).addTo(m);
      if(geojsonLayer){ m.removeLayer(geojsonLayer) };
      bounds = geojsonLayer.getBounds().pad(0.2);  
      m.fitBounds(bounds);      
    }
  </script>
</body>

Here is an example of the geojson data the map is getting from geojson.php

 {"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.905793,39.416633]},"properties":{"Member_Name":"Angels Rock Bar","Contact":"Pedro Lopez","Address":"1323 Walnut","City":"Kansas City","Phone":"(816) 896-3943","Email":"[email protected]","Website":"www.angelsrockbarkc.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.541461,39.051003]},"properties":{"Member_Name":"Bar K","Contact":"Leib Dodell","Address":"501 Berkley Parkway","City":"Kansas City","Phone":"(816) 225-6961","Email":"[email protected]","Website":"www.barkdogbar.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.583506,39.098954]},"properties":{"Member_Name":"The Indie on Main","Contact":"Jamie Pitts","Address":"1228 Main St.","City":"Kansas City","Phone":"(816) 283-9900","Email":"","Website":""}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.578476,39.091498]},"properties":{"Member_Name":"International Tap House (iTap)","Contact":"Jonathan Whitaker","Address":"403 E. 18th St.","City":"Kansas City","Phone":"(816) 701-6606","Email":"[email protected]","Website":"www.internationaltaphouse.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.541461,39.051003]},"properties":{"Member_Name":"Kill Devil Club","Contact":"Scott Tipton","Address":"31 E.14th St.","City":"Kansas City","Phone":"(816) 674-4137","Email":"","Website":"www.killdevilclub.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.603187,39.061865]},"properties":{"Member_Name":"The Monarch Bar, LLC","Contact":"Kenny Cohrs","Address":"4808 Roanoke Pkwy.","City":"Kansas City","Phone":"(816) 437-7912","Email":"[email protected]","Website":"www.themonarchbar.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.581677,39.098391]},"properties":{"Member_Name":"PBR Big Sky","Contact":"Will Kinser","Address":"111 E 13th St.","City":"Kansas City","Phone":"(816) 442-8145","Email":"[email protected]","Website":"www.pbrbigskykc.com"}},{"type":"Feature","geometry":{"type":"Point","coordinates":[-94.581637,39.097872]},"properties":{"Member_Name":"Shark Bar","Contact":"Elliot Duckworth","Address":"1340 Grand Blvd.","City":"Kansas City","Phone":"(816) 377-9442","Email":"[email protected]","Website":"www.sharkbarkc.com"}}]}
2
  • What are the error message? (Press F12 in Firefox or Chrome (?) and look at the console output.) Commented Nov 28, 2018 at 7:19
  • Please see my comment about errors to @Francisco
    – dnevels
    Commented Nov 28, 2018 at 20:06

1 Answer 1

1

The variable geojsonLayer is local to the function showUser. Each time showUser is called (when the select changes) the value of geojsonLayer will NOT be, the previous layer that you use.

An easy solution for your currently code is convert geojsonLayer to be global variable.

And use removeLayer instead of clearLayers.

<script type="text/javascript">
    var geojsonLayer;  // outside any function it will be global
    var m= L.map('map').setView([39.1, -94.5], 8);

    ...


    function showUser(str) {
        if (geojsonLayer) {
            m.removeLayer(geojsonLayer);  // Remove the object from the map
        }
        geojsonLayer = new L.GeoJSON.AJAX(["geojson.php?cs="+str,true],{onEachFeature:popUp})
        geojsonLayer.addTo(m);
        var bounds = geojsonLayer.getBounds().pad(0.2);  // Extend the bounds a a 10%. Take care if the layer is a single point. Should be a local var
        m.fitBounds(bounds);
     }
5
  • I updated the code I originally posted to include your code. The console did not show any errors on page load but when I attempt to choose a select, no markers appear and the console shows a TypeError for removeLayer, showUser and onchange. These errors did not occur before addition of the code. I deleted the removeLayer and TypeErrors are the same except removeLayer points to 'leaflet-src.js' instead of where I added it. Still does not show any markers. Did I put the code in the wrong place?
    – dnevels
    Commented Nov 28, 2018 at 20:02
  • The first time you call showUser, geojsonLayer would be empty. Thus you cannot remove it from the map. You can catch this by writing if(geojsonLayer){m.removeLayer(geojsonLayer)} as the first command of showUser. Commented Nov 28, 2018 at 21:54
  • @Stefan_Fairphone I updated the code to include your suggestions. If all the code is included then no markers are shown and same TypeErrors as before. If I comment out the removeLayer statement I get markers but the fitBounds does not work and I get the same errors. If I comment out the bounds and just leave the removeLayer then I get no markers and no errors
    – dnevels
    Commented Nov 28, 2018 at 23:29
  • I update my code. It will be usefull have the geojson that your are getting from your backend Commented Nov 29, 2018 at 8:27
  • I added some example geojson data the file above is getting when a category is selected from the drop down.
    – dnevels
    Commented Nov 30, 2018 at 4:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.