[GIS] Leaflet select markers from multiple JSON files within the radius given

javascriptjsonleaflet

Continuing work with the issue presented here:

Leaflet – select markers within the radius given with details provided

I am going to a further step and I want to use more than 1 json file to fetch the panel select data.

So far I tried:

Leaflet – select markers within the radius given with details provided

var url = "Peterborough.json";
var url2 = "test.json";

In order to attach these 2 files into the click marker function:

https://zapytay.com/60828633 0 MultiGeoJSON function explained

Firstly I was trying to use the GetMultiJSON function placing my urls like this:

    function getMultiJSON(urlList,callback) {
 var respList = {};
 var doneCount = 0;

 for(var x = 0; x < urlList.length; x++) {
(function(url){
  $.getJSON(url,function(data){
      respList[url] = data;
      doneCount++;

      if(doneCount === urlList.length) {
        callback(respList);
      }
      });

    })(urlList[x]);
  }
}   

    // Get GeoJSON data and create features.
  $.getMultiJSON(['url', 'url2'], function(data) {

    job = L.geoJson(data, {

… ( you will see the next part of this code below further).

It dissapeared at all.

Finally I decided to copy a huge part of the code. Now it looks like this:

<script>

    var url = "Peterborough.json";
    var url2 = "test.json";


    var theMarker;
    var theCircle;
    var geojsonLayer;

    var map = L.map('map').setView([52.53, -0.26], 11); 

    var osm=new L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png',{ 
                attribution: '&copy; <a 
    href="http://osm.org/copyright">OpenStreetMap</a> contributors'});

    // https: also suppported.
    var Esri_WorldImagery = 






 L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
            attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
    });

    // https: also suppported.
    var Esri_WorldGrayCanvas = 



 L.tileLayer('http://server.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}', {
        attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ',
        maxZoom: 16
    }).addTo(map);;


    // https: also suppported.
    var Stamen_TopOSMFeatures = L.tileLayer('http://stamen-tiles-{s}.a.ssl.fastly.net/toposm-features/{z}/{x}/{y}.{ext}', {
        attribution: 'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data &copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
        subdomains: 'abcd',
        minZoom: 0,
        maxZoom: 20,
        ext: 'png',
        bounds: [[22, -132], [51, -56]],
        opacity: 0.9
    });

    var OpenStreetMap_BlackAndWhite = L.tileLayer('http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png', {
    maxZoom: 18,
    attribution: '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
    });
    //OpenStreetMap_BlackAndWhite.addTo(map);

    var blue = L.layerGroup([
        Esri_WorldGrayCanvas,
        Stamen_TopOSMFeatures
        ]); 

    // Set function for color ramp
    function getColor(league){
        return league == 'NL' ? 'blue' :
               league == 'AL' ? 'red' :
                                'black';
           }    

    // Set style function that sets fill color property
    function style(feature) {
        return {
            fillColor: setColor(feature.properties.League),
            fillOpacity: 0.5,
            weight: 2,
            opacity: 1,
            color: '#ffffff',
            dashArray: '3'
        };
    }
    var highlight = {
        'fillColor': 'yellow',
        'weight': 2,
        'opacity': 1
    };

    var job;
    var job2;

    // Get GeoJSON data and create features.
      $.getJSON(url, function(data) {

        job = L.geoJson(data, {

            pointToLayer: function(feature, latlng) {

                return L.circleMarker(latlng, {
                radius:6,
                opacity: .5,
                //color: "#000",
                color:getColor(feature.properties.League),
                fillColor:  getColor(feature.properties.League),
                fillOpacity: 0.8

                });  //.bindTooltip(feature.properties.Name);
            },
                onEachFeature: function (feature, layer) {
                    layer._leaflet_id = feature.properties.Owner;


                    var popupContent = "<p>The <b>" +
                    feature.properties.Owner + "</b> has order here,</br> Number of units: " +
                    feature.properties.Units + "</br>" +
                    '<a href="'+ feature.properties.Website +'" 
  target="_blank">Website</a></p>' ;

                    if (feature.properties && feature.properties.popupContent) {
                        popupContent += feature.properties.popupContent;
                    }
                        layer.bindPopup(popupContent);



                /*
                        layer.on('click', function (e) {

                            lat = e.latlng.lat;
                            lon = e.latlng.lng;
                            //ProcessClick(lat,lon);    


                            //place attributes in panel table.
                                var fieldA=document.getElementById('pict');
                                fieldA.innerHTML='<img src="' +e.target.feature.properties.Logo +'">';
                                var fieldB=document.getElementById('pict2');
                                fieldB.innerHTML='<img src="' +e.target.feature.properties.LeagueLogo +'">';

                                var field1=document.getElementById('f1');
                                field1.innerHTML=e.target.feature.properties.League;
                                var field2=document.getElementById('f2');
                                field2.innerHTML=e.target.feature.properties.Owner;
                                var field3=document.getElementById('f3');
                                field3.innerHTML=e.target.feature.properties.Address;
                                var field4=document.getElementById('f4');
                                field4.innerHTML=e.target.feature.properties.Stadium;
                                var field5=document.getElementById('f5');
                                field5.innerHTML=e.target.feature.properties.Capacity;
                                var field6=document.getElementById('f6');
                                var wsite = e.target.feature.properties.Website;
                                if (wsite !== null){ 
                                field6.innerHTML ='<a href="'+ wsite +'"target="_blank">website</a>' ;
                                } else{
                                field6.innerHTML = 'No site recorded';
                                }
                    });
                    */    //http://www.gistechsolutions.com/leaflet/DEMO/Table/GenerateTable.html
                    //https://www.electrictoolbox.com/jquey-make-entire-table-row-clickable/
                    //<tr onclick="location.href = this.getElementsByTagName("a").item(0).getAttribute("href");"><td><a href="/index.asp">Home</a></td></tr>
                    //https://stackoverflow.com/questions/4919629/html-css-how-to-create-scrollbar-for-tr?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa


                }
                }).addTo(map);

    });

    // Get GeoJSON data and create features.
      $.getJSON(url2, function(data) {

        job2 = L.geoJson(data, {

            pointToLayer: function(feature, latlng) {

                return L.circleMarker(latlng, {
                radius:6,
                opacity: .5,
                //color: "#000",
                color:getColor(feature.properties.League),
                fillColor:  getColor(feature.properties.League),
                fillOpacity: 0.8

                });  //.bindTooltip(feature.properties.Name);
            },
                onEachFeature: function (feature, layer) {
                    layer._leaflet_id = feature.properties.Owner;


                    var popupContent = "<p>The <b>" +
                    feature.properties.Owner + "</b> has order here,</br> Number of units: " +
                    feature.properties.Units + "</br>" +
                    '<a href="'+ feature.properties.Website 
    +'"target="_blank">Website</a></p>' ;

                    if (feature.properties && feature.properties.popupContent) {
                        popupContent += feature.properties.popupContent;
                    }
                        layer.bindPopup(popupContent);



                /*
                        layer.on('click', function (e) {

                            lat = e.latlng.lat;
                            lon = e.latlng.lng;
                            //ProcessClick(lat,lon);    


                            //place attributes in panel table.
                                var fieldA=document.getElementById('pict');
                                fieldA.innerHTML='<img src="' +e.target.feature.properties.Logo +'">';
                                var fieldB=document.getElementById('pict2');
                                fieldB.innerHTML='<img src="' +e.target.feature.properties.LeagueLogo +'">';

                                var field1=document.getElementById('f1');
                                field1.innerHTML=e.target.feature.properties.League;
                                var field2=document.getElementById('f2');
                                field2.innerHTML=e.target.feature.properties.Owner;
                                var field3=document.getElementById('f3');
                                field3.innerHTML=e.target.feature.properties.Address;
                                var field4=document.getElementById('f4');
                                field4.innerHTML=e.target.feature.properties.Stadium;
                                var field5=document.getElementById('f5');
                                field5.innerHTML=e.target.feature.properties.Capacity;
                                var field6=document.getElementById('f6');
                                var wsite = e.target.feature.properties.Website;
                                if (wsite !== null){ 
                                field6.innerHTML ='<a href="'+ wsite +'" 
     [![enter image description here][1]][1]target="_blank">website</a>' ;
                                } else{
                                field6.innerHTML = 'No site recorded';
                                }
                    });
                    */    //http://www.gistechsolutions.com/leaflet/DEMO/Table/GenerateTable.html
                    //https://www.electrictoolbox.com/jquey-make-entire-table-row-clickable/
                    //<tr onclick="location.href = this.getElementsByTagName("a").item(0).getAttribute("href");"><td><a href="/index.asp">Home</a></td></tr>
                    //https://stackoverflow.com/questions/4919629/html-css-how-to-create-scrollbar-for-tr?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa


                }
                }).addTo(map);

    });




    //////////////////////////  
    var baseMaps = {
    "Open Street Map": osm,
    "Imagery":Esri_WorldImagery,
    "OSM B&W":OpenStreetMap_BlackAndWhite
    };

    var overlayMaps = {};   
    //Add layer control
    L.control.layers(baseMaps, overlayMaps).addTo(map);
    //////////////////////

      map.on('click',function(e){  
        lat = e.latlng.lat;
        lon = e.latlng.lng;
        ProcessClick(lat,lon)   
      });


    /*
    // click marker
      var clickmark2;

      // When you click on a circle, it calls the onMapClick function and passes the layers coordinates.
     // I grab the coords which are X,Y, and I need to flip them to latLng for a marker,  
      function onMapClick(coords) {
        console.log(coords);
        var thecoords2 = coords.toString().split(',');
        var lat2 = thecoords[1];
        var lng2 = thecoords[0];
        //if prior marker exists, remove it.
        if (clickmark2 != undefined) {
          map.removeLayer(clickmark2);
        };

         clickmark2 = L.circleMarker([lat,lng],{
            radius: 8,
            //opacity: 1,
            color: "yellow",
            fillColor:  "yellow",
            fillOpacity: 0.8}
         ).addTo(map);
    }
    // end of code for click marker.

    */

    function ProcessClick(lat,lon){
    console.log("You clicked the map at LAT: "+ lat+" and LONG: "+lon );

        //Clear existing marker, circle, and selected points if selecting new points
        if (theCircle != undefined) {
          map.removeLayer(theCircle);
        };
        if (theMarker != undefined) {
              map.removeLayer(theMarker);
        };
        if (geojsonLayer != undefined) {
              map.removeLayer(geojsonLayer);
        };

        //Add a marker to show where you clicked.
         theMarker = L.marker([lat,lon]).addTo(map);  
        SelectPoints(lat,lon);
    };

    var selPts = [];

    function SelectPoints(lat,lon){
    var dist = document.getElementById("miles").value;

    xy = [lat,lon];  //center point of circle

    var theRadius = parseInt(dist) * 1609.34  //1609.34 meters in a mile 
    //dist is a string so it's convered to an Interger.

    selPts.length =0;  //Reset the array if selecting new points

    job.eachLayer(function (layer) {
        // Lat, long of current point as it loops through.
        layer_lat_long = layer.getLatLng();

        // Distance from our circle marker To current point in meters
        distance_from_centerPoint = layer_lat_long.distanceTo(xy);

        // See if meters is within radius, add the to array
        if (distance_from_centerPoint <= theRadius) {
             selPts.push(layer.feature);  
        }
    });

    // draw circle to see the selection area
    theCircle = L.circle(xy, theRadius , {   /// Number is in Meters
      color: 'orange',
      fillOpacity: 0,
      opacity: 1
    }).addTo(map);

    //Symbolize the Selected Points
         geojsonLayer = L.geoJson(selPts, {

            pointToLayer: function(feature, latlng) {
                return L.circleMarker(latlng, {
                radius: 4, //expressed in pixels circle size
                color: "green", 
                stroke: true,
                weight: 7,      //outline width  increased width to look like a filled circle.
                fillOpcaity: 1
                });
                }
        });
        //Add selected points back into map as green circles.
        map.addLayer(geojsonLayer);

        //Take array of features and make a GeoJSON feature collection 
        var GeoJS = { type: "FeatureCollection",  features: selPts   };

        //Show number of selected features.
        console.log(GeoJS.features.length +" Selected features");

         // show selected GEOJSON data in console
        console.log(JSON.stringify(GeoJS));

    //////////////////////////////////////////

        /// Putting the selected team name in the table

        //Clean up prior records
        $("#myTable tr").remove(); 

        var table = document.getElementById("myTable");
         //Add the header row.
        var row = table.insertRow(-1);
        var headerCell = document.createElement("th");
        headerCell.innerHTML = "Owner";  //Fieldname
        row.appendChild(headerCell);

        //Add the data rows. 
        //console.log(selPts);      
        for (var i = 0; i < selPts.length; i++) {
            //console.log(selPts[i].properties.Owner);
            row = table.insertRow(-1);

           var cell = row.insertCell(-1);
            cell.innerHTML = selPts[i].properties.Owner;
        }
          //Get the Team name in the cell.
         $('#myTable tr').click(function(x) {
            theOwner = (this.getElementsByTagName("td").item(0)).innerHTML;
            console.log(theOwner);
            map._layers[theOwner].fire('click');
            var coords = map._layers[theOwner]._latlng;
            console.log(coords);
            map.setView(coords, 15);
         });


    };  //end of SelectPoints function

At the outcome only the markers from 1 layer are highlighted within the marker, but not markers from another layer.

I believe, that a part code with TheMarker remains the same. Only what I should change is the click marker section, where I changed values from clickmark to clickmark2 in the section, which was copied from the first one. Unfortunately It haven't helped.

Is it a possibility to have a panel select map like here:

http://www.gistechsolutions.com/leaflet/DEMO/baseball/BaseballPanelSelect2.html

based on more than 1 json file?

Best Answer

Sure, what I would do is prep the data file, so both layers have the same field names. Then using that example, I'd modify this function.

function SelectPoints(lat,lon){ var dist = document.getElementById("miles").value;

xy = [lat,lon];  //center point of circle

var theRadius = parseInt(dist) * 1609.34  //1609.34 meters in a mile 
//dist is a string so it's convered to an Interger.

selPts.length =0;  //Reset the array if selecting new points

layer1.eachLayer(function (layer) {
    // Lat, long of current point as it loops through.
    layer_lat_long = layer.getLatLng();

    // Distance from our circle marker To current point in meters
    distance_from_centerPoint = layer_lat_long.distanceTo(xy);

    // See if meters is within radius, add the to array
    if (distance_from_centerPoint <= theRadius) {
         selPts.push(layer.feature);  
    }
}

layer2.eachLayer(function (layer) {
    // Lat, long of current point as it loops through.
    layer_lat_long = layer.getLatLng();

    // Distance from our circle marker To current point in meters
    distance_from_centerPoint = layer_lat_long.distanceTo(xy);

    // See if meters is within radius, add the to array
    if (distance_from_centerPoint <= theRadius) {
         selPts.push(layer.feature);  
    }
});

);

Now both layers are in the selPts and you can set them to the green geojson layer and add them to the panel.

See http://www.gistechsolutions.com/leaflet/DEMO/sports/ where it selects from 2 different GeoJSON files. http://www.gistechsolutions.com/leaflet/DEMO/sports/sports.zip is a copy of the working files