I managed to build a custom leaflet map with filters.
I read many many stackoverflow topics trying to understand how things work with leaflet and finaly based all my code from this tutorial, which I think is very clear.
My Layout is the following. I have three columns in my container. In the first one I have all my checkboxes.
In the middle, my map.
And on the right,an empty sidebar.
When I click on checkbox, It show/hide the markers on the map. When I click on a marker, it fills the empty sidebar with all my "features" coming from a geoJson file.
I'm looking for a way to improve my code, to shorten it by using loops if possible, or functions that would allow me to lighten all this code. As I have in perspective dozens of Json objects to incorporate, my code may be very long. And I am sure it is possible to shorten it. I'm looking in particular, a quick way to add/remove markers instead of duplicating code like I do here.. As I'm really not good in js, can someone help me based on this example ? Because I see many tutorials on this but I'm unable to adapt it to my project..
<main class="flex-container">
<article>
<div class="flex-row relative">
<div class="hamburger">
<span class="line"></span>
<span class="line"></span>
<span class="line"></span>
</div>
<div class="flex-col-sm-4 flex-col-md-2" id="filters">
<nav id="filter-group" class="filter-group relative">
<div class="cc_filter_group">
<h3>Title</h3>
<div>
<input type="checkbox" class="gaucher" id="allmaladies" name="gaucher[]" checked>
<label for="allmaladies">Tout</label>
</div>
<div>
<input type="checkbox" class="gaucher" id="glucocerebrosidase" name="gaucher[]">
<label for="glucocerebrosidase">Glucocérébrosidase</label>
</div>
<div>
<input type="checkbox" class="gaucher" id="gba" name="gaucher[]">
<label for="gba">Gêne GBA</label>
</div>
<div>
<input type="checkbox" class="gaucher" id="gl1" name="gaucher[]">
<label for="gl1">Lyso GL1</label>
</div>
<div>
<input type="checkbox" class="gaucher" id="chito" name="gaucher[]">
<label for="chito">Chito</label>
</div>
<div>
<input type="checkbox" class="gaucher" id="ccl_18" name="gaucher[]">
<label for="ccl_18">CCL 18</label>
</div>
</div>
<div class="npb_filter_group">
<h3>NPB</h3>
<div>
<input type="checkbox" class="npb" id="sphingomyelinase" name="npb[]" checked>
<label for="sphingomyelinase">phingomyélinase acide</label>
</div>
<div>
<input type="checkbox" class="npb" id="smpd_1" name="npb[]">
<label for="smpd_1">Gêne SMPD1</label>
</div>
<div>
<input type="checkbox" class="npb" id="sm509" name="npb[]">
<label for="sm509">Lyso sm509</label>
</div>
<div>
<input type="checkbox" class="npb" "chito_npb" name="npb[]">
<label for="chito_npb">CCL 18/label>
</div>
</div>
</nav>
</div>
<div class="flex-col-sm-12 flex-col-md-6 map">
<div id="map" style="width:100%;height:100%;"></div>
</div>
<div class="flex-col-md-4" id="infos">
<div class="layer_infos" id="layer_infos">
<span class="close hidden-lg"></span>
<div class="fill">
<p>Cliquez sur une icône pour voir le détail</p>
</div>
</div>
</div>
</div> <!-- #main -->
</article> <!-- #main-container -->
</main>
<script type="text/javascript">
var cartoDb = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 19});
var glucocerebrosidaseIcon = L.AwesomeMarkers.icon({
prefix: 'fa', //font awesome rather than bootstrap
markerColor: 'red', // see colors above
iconColor:'white',
icon: 'ambulance' //http://fortawesome.github.io/Font-Awesome/icons/
});
var gbaIcon = L.AwesomeMarkers.icon({
prefix: 'fa', //font awesome rather than bootstrap
iconColor:'white',
markerColor: 'green', // see colors above
icon: 'ambulance' //http://fortawesome.github.io/Font-Awesome/icons/
});
var gl1Icon = L.AwesomeMarkers.icon({
prefix: 'fa', //font awesome rather than bootstrap
iconColor:'white',
markerColor: 'blue', // see colors above
icon: 'ambulance' //http://fortawesome.github.io/Font-Awesome/icons/
});
var sphingomyelinaseIcon = L.AwesomeMarkers.icon({
prefix: 'fa', //font awesome rather than bootstrap
iconColor:'white',
markerColor: 'darkred', // see colors above
icon: 'ambulance' //http://fortawesome.github.io/Font-Awesome/icons/
});
var map = L.map('map')
.addLayer(cartoDb)
.setView([46.85, 2.3518], 6); // LIGNE 14
function onEachFeature(feature, layer) {
var html = '';
if (feature.properties.Description) {
html += '<p>' + feature.properties.Description + '</p>';
}
if (feature.properties.Envoi) {
html += '<p>' + feature.properties.Envoi + '</p>';
}
if (feature.properties.Mode) {
html += '<p>' + feature.properties.Mode + '</p>';
}
if (feature.properties.Laboratoire) {
html += '<p>' + feature.properties.Laboratoire + '</p>';
}
if (feature.properties.Chu) {
html += '<p>' + feature.properties.Chu + '</p>';
}
if (feature.properties.Adresse) {
html += '<p>' + feature.properties.Adresse + '</p>';
}
if (feature.properties.Cp) {
html += '<p>' + feature.properties.Cp + '</p>';
}
if (feature.properties.Professeur) {
html += '<p>' + feature.properties.Professeur + '</p>';
}
if (feature.properties.Tel) {
html += '<p>' + feature.properties.Tel + '</p>';
}
if (feature.properties.Fax) {
html += '<p>' + feature.properties.Fax + '</p>';
}
if (feature.properties.Mail) {
html += '<p>' + feature.properties.Mail + '</p>';
}
if (feature.properties.Renseignement) {
html += '<p>' + feature.properties.Renseignement + '</p>';
}
layer.on('click', function () {
$('#layer_infos .fill').html(html);
})
$('input[type="checkbox"]').on('click',function(){
$('#layer_infos .fill').html('<p>Cliquez sur une icône pour voir le détail</p>');
})
if ( L.Browser.mobile ) {
layer.on('click', function () {
$('#infos').addClass("slide");
})
$('.hamburger').click(function(){
$(this).toggleClass("is-active");
$('#filters').toggleClass("slide");
})
$('.close').click(function(){
$('#infos').removeClass("slide");
})
}
}
var promise = $.getJSON("maladie.json");
promise.then(function(data){
var allmaladies = L.geoJson(data);
var glucocerebrosidase = L.geoJson(data, {
filter: function(feature, layer) {
return feature.properties.Maladie == "glucocerebrosidase";
},
onEachFeature: onEachFeature,
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: glucocerebrosidaseIcon
})
}
});
var gba = L.geoJson(data, {
filter: function(feature, layer) {
return feature.properties.Maladie == "gba";
},
onEachFeature: onEachFeature,
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: gbaIcon
})
}
});
var gl1 = L.geoJson(data, {
filter: function(feature, layer) {
return feature.properties.Maladie == "gl1";
},
onEachFeature: onEachFeature,
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: gl1Icon
})
}
});
var sphingomyelinase = L.geoJson(data, {
filter: function(feature, layer) {
return feature.properties.Maladie == "Sphingomyelinase-acide";
},
onEachFeature: onEachFeature,
pointToLayer: function(feature, latlng) {
return L.marker(latlng, {
icon: sphingomyelinaseIcon
})
}
});
// THIS IS NEW
map.fitBounds(allmaladies.getBounds(), {
padding: [50, 50]
});
glucocerebrosidase.addTo(map)
gba.addTo(map)
gl1.addTo(map)
sphingomyelinase.addTo(map)
$("#glucocerebrosidase").click(function() {
if(this.checked){
map.addLayer(glucocerebrosidase)
map.removeLayer(gba)
map.removeLayer(gl1)
}else{
map.removeLayer(gl1)
map.removeLayer(gba)
map.removeLayer(glucocerebrosidase)
}
});
$("#gba").click(function() {
if(this.checked){
map.addLayer(gba)
map.removeLayer(gl1)
map.removeLayer(glucocerebrosidase)
}else{
map.removeLayer(gl1)
map.removeLayer(gba)
map.removeLayer(glucocerebrosidase)
}
});
$("#gl1").click(function() {
if(this.checked){
map.addLayer(gl1)
map.removeLayer(gba)
map.removeLayer(glucocerebrosidase)
}else{
map.removeLayer(gl1)
map.removeLayer(gba)
map.removeLayer(glucocerebrosidase)
}
});
$("#sphingomyelinase").click(function() {
if(this.checked){
map.addLayer(sphingomyelinase)
}else{
map.removeLayer(sphingomyelinase)
}
});
$("#allmaladies").click(function() {
if(this.checked){
map.addLayer(gl1)
map.addLayer(gba)
map.addLayer(glucocerebrosidase)
map.addLayer(sphingomyelinase)
}else{
map.removeLayer(gl1)
map.removeLayer(gba)
map.removeLayer(glucocerebrosidase)
map.removeLayer(sphingomyelinase)
}
});
});
</script>
And finaly, in a separate js file, I have the following function, that let me check or uncheck my checkboxes One by One instead of a multiple selection.
jQuery(document).ready(function($){
$('input[type="checkbox"]').on('change', function() {
$('input[name="' + this.name + '"]').not(this).prop('checked', false);
});
});
In my code, I'm using this to fill the sidebar
layer.on('click', function () {
$('#layer_infos .fill').html(html);
})
I'm then using this to put a default text, each time I switch to another checkbox
$('input[type="checkbox"]').on('click',function(){
$('#layer_infos .fill').html('<p>my default text</p>');
})
I'm not sure this is the best way to do it !
I'm using the leaflet method L.Browser.mobile to change the display on mobile
I then have a problem with my getJSON method or function, It looks very long and redundant to me. Also, the 'addLayer' and 'removeLayer' method that I duplicate dozen of times, I'm sure it could be shorten. Is there a way instead to make a thing like : if (this) -> show this and hide all others markers etc..
Thanks for your help !
Aucun commentaire:
Enregistrer un commentaire