Leaflet JS Maps and functions to select new layers

2020-05-04 10:44发布

问题:

I'm working with leaflet.js and pulling data from a CSV file via omnivore. I am able to make individual layers for each of the features I am "filtering" on from the CSV. Aside from writing a lot of the same ominvore.csv(), is there a way to create a function that will return what the user is looking for when they click on a radio button or checkbox in the groupLayers l.control or a custom div / form?

For example, here is my hiking layer:

var hiking = omnivore.csv('data/all.csv', null, trailheadLayer).on('ready', function(layer) {
    markerArray = [];
    this.eachLayer(function(marker) {
        if (marker.toGeoJSON().properties.fee_type == "Free") {
            marker.setIcon(L.icon({
                iconSize: [27, 27],
                iconAnchor: [13, 27],
                popupAnchor: [1, -24],
                iconUrl: 'images/trailheadFree.png'
            }));

            var popupData = "<table class='table table-striped table-sm table-bordered'><tr><th>Site Name</th><td>" + marker.toGeoJSON().properties.site_name + "</td></tr><tr><th>Fee Payment Method</th><td>" + marker.toGeoJSON()
                .properties.fee_payment_method + "</td></tr><tr><th>Site Type</th><td>" +
                marker.toGeoJSON().properties.site_type + "</td></tr></table>";
            marker.bindPopup(popupData);
            marker.bindLabel(marker.toGeoJSON().properties.site_name);

        } else {
            marker.setIcon(L.icon({
                iconSize: [27, 27],
                iconAnchor: [13, 27],
                popupAnchor: [1, -24],
                iconUrl: 'images/trailheadFee.png'
            }));

            var popupData = "<table class='table table-striped table-sm table-bordered'><tr><th>Site Name</th><td>" + marker.toGeoJSON().properties.site_name + "</td></tr><tr><th>Fee Payment Method</th><td>" + marker.toGeoJSON()
                .properties.fee_payment_method + "</td></tr><tr><th>Site Type</th><td>" +
                marker.toGeoJSON().properties.site_type + "</td></tr></table>";
            marker.bindPopup(popupData);
            marker.bindLabel(marker.toGeoJSON().properties.site_name);

        }
    });
});

and my trailheadLayer filter is like so:

var trailheadLayer = L.geoJson(null, {
    filter: function(layer) {
        if (layer.properties.site_type == "Trailhead")
            return true;
    }
});

I've tried passing a variable via .val() from an input into the omnivore parser like so:

function selectedLayer(forest, activity) {
    omnivore.csv('data/'+forest+'.csv',null,activity).addTo(map);
}

selectedLayer("sbnf", "trailheadLayer");

However, i get this console error:

Uncaught TypeError: omnivore.csv(...).addTo is not a function

If I manually add sbnf and trailheadLayer into the omnviore.csv(...), it works just fine.

Thanks for any hints, help or ideas.

EDIT::

Making sure I am passing an object into omnivore:

function selectedLayer(forest, activity) {
    var micon = activity;
    var theActivity = JSON.parse('{ "activity": "' + activity + '"}');
    console.log("this activity is: " + activity + " type is: " + typeof(activity) + ", and after json.parse(): " + typeof(theActivity));

    omnivore.csv('data/' + forest + '.csv', null, theActivity).on('ready', function(layer) { ............

However, getting the non-function error here. Isn't the object enough? No quotes on it... not a string...

回答1:

EDIT

If I understand correctly, you have HTML inputs (radios / checkboxes) with associated String values, that incidentally correspond to the name of your L.geoJSON layer groups variables.

Then you do not know how to correctly call omnivore, given only this String value?

You have several ways to associate the actual Layer Groups to your inputs, so that you can pass them to omnivore (which, once again, needs a Leaflet GeoJSON Layer Group as 3rd parameter, not an Object).

For example, you could use jQuery's data to associate directly the Layer Group to each input. It accepts any kind of objects, not just String's.

Another simple solution would be to use a hash map / dictionary object that holds the bijective association between your String input value and your Layer Group:

var strValueToLayerGroup = {
  "trailheadLayer": trailheadLayer
  // more as appropriate
};

selectedLayer("sbnf", strValueToLayerGroup["trailheadLayer"]);

Original answer

As for your console error, it comes from the fact that you provide a String ("trailheadLayer") as omnivore.csv() 3rd argument, whereas it expects a GeoJSON Layer Group.

So selectedLayer("sbnf", trailheadLayer); (without quotes around trailheadLayer) should not trigger that error.

BTW, you could use pointToLayer option on your L.geoJson() constructor to directly assign the appropriate icon, popup and label, instead of having to go through eachLayer() afterwards.