I am using GeoJSON and Leaflet.
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 :
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?
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:
From there, I am trying to merge and remove duplicates properties from a unique global array. I followed some tutorials, like this one, but get nothing.
1 Answer 1
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 !