0

I'm posting this question here because it is related to GeoJSON and Leaflet.

Here are my requirements :

My map is ready and functional. I'm using markerCluster to create clusters when several markers have exact same coordinates. When I click on the markers, finally, instead of showing markers in a spiderfy shape, I managed to make the cluster clickable directly to show the corresponding markers information.

var promise = $.getJSON("examen.json");


var clusters = L.markerClusterGroup({
    spiderfyOnMaxZoom: false, 
    showCoverageOnHover: false, 
    zoomToBoundsOnClick: true 
});

/* special cluster click action with associated html. I'm targetting the markers inside the selected cluster. */
clusters.on('clusterclick', function(a){

/**/

/**/
if(a.layer._zoom == 18){
 var html = '';

for (feat in a.layer._markers){




if (a.layer._markers[feat].feature.properties['Professeur']) {
    html += '<p class="prof">' + a.layer._markers[feat].feature.properties['Professeur'] + '</p>';
}
 if (a.layer._markers[feat].feature.properties['Professeur2']) {
    html += '<p class="prof2">' + a.layer._markers[feat].feature.properties['Professeur2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Chu']) {
    html += '<p class="chu">' + a.layer._markers[feat].feature.properties['Chu'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Laboratoire']) {
    html += '<p class="labo">' + a.layer._markers[feat].feature.properties['Laboratoire'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Prelevement']) {
    html += '<p>' + a.layer._markers[feat].feature.properties['Prelevement'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Envoi']) {
    html += '<p>' + a.layer._markers[feat].feature.properties['Envoi'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Adresse']) {
    html += '<p class="adress">' + a.layer._markers[feat].feature.properties['Adresse'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Cp']) {
    html += '<p class="cp">' + a.layer._markers[feat].feature.properties['Cp'] + '</p>';
}

if (a.layer._markers[feat].feature.properties['Tel']) {
    html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Fax']) {
    html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Mail']) {
    html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail'] +'">' + a.layer._markers[feat].feature.properties['Mail'] + '</a></p>';
}
if (a.layer._markers[feat].feature.properties['Tel2']) {
    html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Fax2']) {
    html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax2'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Mail2']) {
    html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail2'] +'">' + a.layer._markers[feat].feature.properties['Mail2'] + '</a></p>';
}
if (a.layer._markers[feat].feature.properties['Renseignement']) {
    html += '<p class="rt">' + a.layer._markers[feat].feature.properties['Renseignement'] + '</p>';
}
if (a.layer._markers[feat].feature.properties['Url']) {
    html += '<p class="url"><a href="' + a.layer._markers[feat].feature.properties['Url'] + '">' + a.layer._markers[feat].feature.properties['Url'] + '</a></p>';
}
html+='<div class="pictos">';
if (a.layer._markers[feat].feature.properties['Examen']) {
    html += '<span class="' + a.layer._markers[feat].feature.properties['Examen'] + '">' + a.layer._markers[feat].feature.properties['Examen'] + '</span>';
}

    html+='</div>';
}

$('#layer_infos .fill').html(html);
}
})

promise.then(function(data) { 
etc... 

I click on the marker, and it displays the associated markers properties values (all the html part above) in a dynamic sidebar.

Here is an example :

enter image description here

I can have more than 5 markers at the same coordinates, so in my div, I can have 5 blocks appended, like in the image.

What I'm trying to achieve:

Most of properties values are equivalent for those clustered markers. So I'm trying to avoid duplicate properties. My goal would be to have only one HTML block, with the common information on top (like hospital name, address, phone number etc), and the changing properties below (like medical specialities etc) , maybe in a carousel, a slider, accordion or whatever.

What I tried :

I saw many topics on this subject, most of them are pure JavaScript and are not related to Leaflet or GeoJSON specifically. I tried implementing it but with no success. So I'm trying to understand how to:

  • Avoid duplicate properties in a GeoJSON file when creating the cluster click function
  • Display my HTML block directly without duplicate properties...

How can I do this?

EDIT:

Following TomacizM advice I tried but failed. I have to store multiple arrays (unknown number)properties values, compare them, remove duplicates, and restore a cleaned unique array.

What I tried with a cluster containing two markers.

if(a.layer._zoom == 18){
     var html = '';
    var gap = a.layer._markers;
    var result = [];
    for(var i in gap)
    result.push([i, gap[i]]);

console.log(result);

It is showing me two arrays, like here in the console:

enter image description here

From there, I spend more than a day trying to merge and remove duplicates properties from a unique global array. I followed some tutorials, like this one, but get nothing..

I really need advice on what syntax to use.

Thanks

4
  • There is no other way than first storing properties in an array an then going through it and check for duplicate values. – TomazicM Apr 25 '20 at 17:00
  • What is you criteria for duplicate? All properties equal? Some properties equal? If some, which ones? Any by the way, this is not GIS question any more, it's more suitable for StackOverflow. – TomazicM Apr 26 '20 at 11:49
  • Thanks TomazicM! My criteria are the following : Show me just one array (html block) with all properties from all markers For example,. if adress is the same for all markers, keep one adress only, or show it once only. As soon as properties values are the same between all the markers, just show them once. And show all others properties from all markers (array) when they differ..Whatever I do, it shows me the 2 arrays with all properties in console. – blogob Apr 26 '20 at 11:57
  • Yes, I guess it's a stackoverflow question, but there I can't find anything suitable for my need (geoJson file, etc).In addition, I'm banned from two days ago for asking question, even if I try to make them clear enough...so bad..Anyway, thank you very much for your patience! – blogob Apr 26 '20 at 11:57
0

Finaly I got it. I hope this can help others people searching for an equivalent solution.

I used the clusters.on ('clusterclick', function(){ to add an event on the clusters click.

This way I can show inside markers data directly without showing the markers themselves.

Then I use the "indeOf ==-1" to remove duplicates properties values.

Here is my code:

  /*cluster for the first map */
    var clusters = L.markerClusterGroup({
        spiderfyOnMaxZoom: false,
        showCoverageOnHover: false,
        zoomToBoundsOnClick: true
    });


    clusters.on('clusterclick', function(a) {
        if (a.layer._zoom == 18) {

            var html = '';
            for (feat in a.layer._markers) {

                if (a.layer._markers[feat].feature.properties['Chu']) {
                    var chu = a.layer._markers[feat].feature.properties['Chu'];
                    if (html.indexOf(chu) == -1)
                        html += '<p class="chu">' + a.layer._markers[feat].feature.properties['Chu'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Laboratoire']) {
                    var labo = a.layer._markers[feat].feature.properties['Laboratoire'];
                    if (html.indexOf(labo) == -1)
                        html += '<p class="labo">' + a.layer._markers[feat].feature.properties['Laboratoire'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Adresse']) {
                    var adresse = a.layer._markers[feat].feature.properties['Adresse'];
                    if (html.indexOf(adresse) == -1)
                        html += '<p class="adress">' + a.layer._markers[feat].feature.properties['Adresse'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Cp']) {
                    var cp = a.layer._markers[feat].feature.properties['Cp'];
                    if (html.indexOf(cp) == -1)
                        html += '<p class="cp">' + a.layer._markers[feat].feature.properties['Cp'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Examen']) {
                    var examen = a.layer._markers[feat].feature.properties['Examen'];
                    if (html.indexOf(examen) == -1)
                        html += '<div class="pictos"><span class="circle-' + a.layer._markers[feat].feature.properties['Examen'] + '"></span><span class="' + a.layer._markers[feat].feature.properties['Examen'] + '">' + a.layer._markers[feat].feature.properties['Examen'] + '</span></div>';
                }
                if (a.layer._markers[feat].feature.properties['Professeur']) {
                    var prof = a.layer._markers[feat].feature.properties['Professeur'];
                    if (html.indexOf(prof) == -1)
                        html += '<p class="prof">' + a.layer._markers[feat].feature.properties['Professeur'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Tel']) {
                    var tel = a.layer._markers[feat].feature.properties['Tel'];
                    if (html.indexOf(tel) == -1)
                        html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Fax']) {
                    var fax = a.layer._markers[feat].feature.properties['Fax'];
                    if (html.indexOf(fax) == -1)
                        html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Mail']) {
                    var mail = a.layer._markers[feat].feature.properties['Mail'];
                    if (html.indexOf(mail) == -1)
                        html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail'] + '">' + a.layer._markers[feat].feature.properties['Mail'] + '</a></p>';
                }
                if (a.layer._markers[feat].feature.properties['Professeur2']) {
                    var prof2 = a.layer._markers[feat].feature.properties['Professeur2'];
                    if (html.indexOf(prof2) == -1)
                        html += '<p class="prof2">' + a.layer._markers[feat].feature.properties['Professeur2'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Tel2']) {
                    var tel2 = a.layer._markers[feat].feature.properties['Tel2'];
                    if (html.indexOf(tel2) == -1)
                        html += '<p class="tel">' + a.layer._markers[feat].feature.properties['Tel2'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Fax2']) {
                    var fax2 = a.layer._markers[feat].feature.properties['Fax2'];
                    if (html.indexOf(fax2) == -1)
                        html += '<p class="fax">' + a.layer._markers[feat].feature.properties['Fax2'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Mail2']) {
                    var mail2 = a.layer._markers[feat].feature.properties['Mail2'];
                    if (html.indexOf(mail2) == -1)
                        html += '<p class="mail"><a href="mailto:' + a.layer._markers[feat].feature.properties['Mail2'] + '">' + a.layer._markers[feat].feature.properties['Mail2'] + '</a></p>';
                }
                if (a.layer._markers[feat].feature.properties['Prelevement']) {
                    var prelevement = a.layer._markers[feat].feature.properties['Prelevement'];
                    if (html.indexOf(prelevement) == -1)
                        html += '<p>' + a.layer._markers[feat].feature.properties['Prelevement'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Envoi']) {
                    var envoi = a.layer._markers[feat].feature.properties['Envoi'];
                    if (html.indexOf(envoi) == -1)
                        html += '<p>' + a.layer._markers[feat].feature.properties['Envoi'] + '</p>';
                }
                if (a.layer._markers[feat].feature.properties['Url']) {
                    var url = a.layer._markers[feat].feature.properties['Url'];
                    if(html.indexOf(url)==-1)
                        html += '<p class="url"><a href="' + a.layer._markers[feat].feature.properties['Url'] + '">' + a.layer._markers[feat].feature.properties['Url'] + '</a></p>';
                }
            }
            $('#layer_infos .fill').html(html);
        }
    })

Now in my side panel I display the redundant information once only !

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.