-2

I have a Leaflet map with several sets of points read in from a PostgreSQL database. I would like to make each of these collections an overlay that I can toggle on and off. Without having overlays I can read in the information from the PostgreSQL database and display the points.

I have managed to create an empty overlay (no points display), or can display points and overlays if they the points are not read in from the database. I am having trouble combining the features.

I know this has been asked many times - but I have not been able to implement any of the solutions, nor get any of the examples working. I am new very new to Leaflet (and all the associated coding/programs).

I have tried to follow this solution but I do not know what their GeoJSON files look like - and have not been able to adapt the code.

Here is my attempt at following the above solution but with my data:

<!DOCTYPE html>
<html>
<head>
  <title> Test Map</title>
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.4/dist/leaflet.css"
  integrity="sha512-puBpdR0798OZvTTbP4A8Ix/l+A4dHDD0DGqYW6RQ+9jxkRFclaxxQb/SJAWZfWAkuyeQUytO7+7N4QKrDh+drA=="
  crossorigin=""/>
  <script src="https://unpkg.com/leaflet@1.3.4/dist/leaflet.js"
  integrity="sha512-nMMmRyTVoLYqjP9hrbed9S+FzjZHW5gY1TWCHA5ckwXZBadntCNs8kEqAWdrb9O7rxbCaA4lKTIWjDXZxflOcA=="
  crossorigin=""></script>
  <script src = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.3.min.js"></script>

  <style>
  #map {
    height:800px;
  }
  </style>

  <script type = "text/javascript">
  function init(){
    var osmLink = "<a href='http://www.openstreetmap.org'>Open StreetMap</a>"
    var map = new L.map('map').setView([ -20.91, 142.70], 5);
    osmMap = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: 'Map data &copy; ' + osmLink, maxZoom: 18,}).addTo(map);
    attrLink = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://creativecommons.org/licenses/by-sa/3.0">CC BY SA</a>.'
    attrLinkToner = 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>. Data by <a href="http://openstreetmap.org">OpenStreetMap</a>, under <a href="http://www.openstreetmap.org/copyright">ODbL</a>.';
    var terrainMap = L.tileLayer( 'http://{s}.tile.stamen.com/terrain/{z}/{x}/{y}.jpg',{
      attribution: attrLink,
      maxZoom: 18,
    }).addTo(map);
    var baseLayers = {
      "Open Street Map":osmMap, "Stamen Terrain": terrainMap
    };

    L.control.layers(baseLayers).addTo(map);

    showLayers(map);

    function showLayers(map) {

      var myIcon = L.icon({
        iconUrl: "./images/frog.png",
        iconSize: [24,24],
        iconAnchor: [12,24]
      });

      var controlLayers = L.control.layers().addTo(map);

      $.getJSON("getData.php", function(data) {
        var geojsonLayer = L.geoJson(data, {
          style: function(feature) {
            return {
              'weight': 0,
              'fillColor': 'brown',
              'fillOpacity': 1
            }
          },
          onEachFeature: function(feature, layer) {
            var popupText = "Popup Text";
            layer.bindPopup(popupText);
          }
        }).addTo(map);
        controlLayers.addOverlay(geojsonLayer, 'ExampleLayer');
      });

    } // end of function showLayers

  }// end of function init
  </script>
</head>
<h1>Page heading</h1>
<body onload=init()>
  <div id = "map"> </div>
</body>
</html>

The sample of the output from running getData.php is

[{"id":13,"siteID":"ClevelandBay","siteLatitude":"-19.22","siteLongitude":"146.92","studyTitle":"Seagrass Abundance","classification":"GroupA"}, {"id":5,"siteID":"KnappCreek","siteLatitude":"-28.1","siteLongitude":"152.8","studyTitle":"Gully erosion","classification":"GroupA"}]

I am not sure that the link is the right approach to take - so I'm happy with alternatives.

The following bit of code correctly shows the markers on the map (with the popup information that I will include once I get the basics working)

  $.getJSON("getData.php",function(data){
    for (let i = 0; i< data.length; i++) {
      let location = new L.LatLng(data[i].siteLatitude, data[i].siteLongitude);
      let marker = new L.Marker(location, {
        icon: modelIcon,
        title: 'thetitle' });

        let studyTitle = data[i].studyTitle
        let siteID = data[i].siteID;

        let content = "<h2>" + studyTitle + "</h2>" + "<p>" + siteID + "</p>" + "<p> <b>" + "</b></p>";
        marker.bindPopup(content, {
          maxWidth: '400'
        });
        marker.addTo(map);
      } 
    }  
  ) 
1

Your code looks fine. The issue you're having is related to the data you're passing in to the L.geoJson() method.

Refer to the Leaflet docs here, you can see it accepts GeoJson object and options.

You must convert your data from the getData.php to geojson, something like:

geojsonFeature = {
    "type": "Feature",
    "properties": {
        "id": id,
        "siteId": siteId,
        "classification": classification,
         "studyTitle": studyTitle
    },
    "geometry": {
        "type": "Point",
        "coordinates": [siteLongitude, siteLatitude]
    }
};

Which you can then pass into L.geoJson(data).

UPDATE: You can loop through the data returned from data.php and create geojson objects from there.

var data = [{"id":13,"siteID":"ClevelandBay","siteLatitude":"-19.22","siteLongitude":"146.92","studyTitle":"Seagrass Abundance","classification":"GroupA"}, {"id":5,"siteID":"KnappCreek","siteLatitude":"-28.1","siteLongitude":"152.8","studyTitle":"Gully erosion","classification":"GroupA"}];

    var collection = [];

    for (let i = 0; i < data.length; i +=1) {
        collection.push({
        "type": "Feature",
        "properties": {
            "id": data[i].id,
            "siteId": data[i].siteId,
            "classification": data[i].classification,
             "studyTitle": data[i].studyTitle
        },
        "geometry": {
            "type": "Point",
            "coordinates": [data[i].siteLongitude, data[i].siteLatitude]
        }
        });
    }

Please see the forked fiddle from the example you provided.

Hopefully this helps!

6
  • Thanks for the pointer Owen - but I cannot figure out how to incorporate this. I looked at the docs, but I really don't understand even the basics. I've tried a few different things and the best I could achieve is an empty layer (map but no points).
    – Esme_
    Sep 24 '18 at 4:44
  • @Esme_ I've provided an updated answer. I hope this helps you solve your problem! Sep 24 '18 at 22:35
  • Thanks Owen - I was able to get the example working, but unfortunately this didn't solve my problem. I suspect that the example I pointed to wasn't the right approach after all. I'll keep hunting.
    – Esme_
    Sep 27 '18 at 0:01
  • @Esme_ No worries, can you update your question? I'm still unsure what the problem is you're trying to solve. The example I provided creates a leaflet overlay layer that can be toggled on and off, which answers your original question. Sep 27 '18 at 14:36
  • Turns out part of my problem was with the getJSON call - I just didn't realise when I asked the question that this was a problem. I think I've almost got it sorted and will update when I've either got it working properly or have a clear understanding of exactly what I can't figure out. Thanks so much for your help - you solved part of my problem, which meant I could finally see some of the other things I'd done wrong.
    – Esme_
    Sep 27 '18 at 23:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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