I'm trying to create a map with markers using data from Google Sheet using leaflet. I managed that but there are some bugs that I can't fix:
- Filter by group - I can filter by group, but only one marker is displayed for each selected group, even tho I have multiple data in the same group. Here attached a photo of the output
- Replacing markers - I wanted the map to show markers that correspond to the selected group only, i.e., if I select Male, then only show only data in the group Male, and vice versa. But for now, once I select a group (for example Male), when I attempt to select another group (Female), the marker for Male group still exists.
Here is the sample data from Google Sheet
Here's my code: Apps script:
function doGet(e) {
return HtmlService.createHtmlOutputFromFile('map');
}
function getAddress(group) {
var ss= SpreadsheetApp.getActiveSpreadsheet();
var groupSheet = ss.getSheetByName("Sheet1");
var getLastRow = groupSheet.getLastRow();
var return_array = [];
if (group === 'All'){
return groupSheet.getRange(2, 1, getLastRow - 1, 5).getValues();
} else {
for (var i = 2; i<= getLastRow; i ){
if (groupSheet.getRange(i,3).getValue() === group){
return_array.push(groupSheet.getRange(i,1,1,5).getValues());
}
}
return return_array;
}
}
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
</head>
<body>
<div id="divfilter" onchange="onSelect()">
Select a group:
<div >
<input type="radio" name="filGroup" value="All" checked>All
</div>
<div >
<input type="radio" name="filGroup" value="Male" >Male
</div>
<div >
<input type="radio" name="filGroup" value="Female" >Female
</div>
</div>
<div id="viewmap"></div>
<script>
var map_init = L.map('viewmap',{
center: [4.042649, 103.624396],
zoom:8
});
var basemap = L.tileLayer ('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo (map_init);
function onSelect(){
var map = map_init;
var group = document.querySelector('input[name="filGroup"]:checked').value;
google.script.run.withSuccessHandler(function(ar){
console.log(ar);
ar.forEach(function(item, index){
var group = document.querySelector('input[name="filGroup"]:checked').value;
if (group === 'All'){
var marker = L.marker([item[0], item[1]]).addTo(map);
marker.bindPopup('<div id="text"><p>Name: ' item[3] '<br>DOB: ' item[4] '</p></div>' );
} else{
var marker = L.marker([item[index][0], item[index][1]]).addTo(map);
marker.bindPopup('<div id="text"><p>Name: ' item[index][3] '<br>DOB: ' item[index][4] '</p></div>' );
}
});
}).getAddress(group);
}
</script>
</body>
</html>
<style>
body {
margin: 0;
padding: 0;
}
#viewmap {
width: 100%;
height: 100vh;
}
#text {
font-family:Georgia,'Times New Roman', Times, serif;
}
</style>
I'd be most grateful if anyone can help!
CodePudding user response:
This is my first attempt at maps but I tried it and it works.
Change your files accordingly.
HTML_TestMap
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Document</title>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<style>
body {
margin: 0;
padding: 0;
}
#viewmap {
width: 100%;
height: 100vh;
}
#text {
font-family:Georgia,'Times New Roman', Times, serif;
}
</style>
</head>
<body>
<div id="divfilter" onchange="onSelect()">
Select a group:
<div >
<input type="radio" name="filGroup" value="All" checked>All
</div>
<div >
<input type="radio" name="filGroup" value="Male" >Male
</div>
<div >
<input type="radio" name="filGroup" value="Female" >Female
</div>
</div>
<div id="viewmap"></div>
<script>
var map_init = null;
var basemap = null;
var map_markers = [];
(function () {
try {
map_init = L.map('viewmap',{
center: [4.042649, 103.624396],
zoom:8
});
basemap = L.tileLayer ('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo (map_init);
}
catch(err) {
alert(err);
}
})();
function onSelect(){
var map = map_init;
var group = document.querySelector('input[name="filGroup"]:checked').value;
google.script.run.withSuccessHandler(
function(ar){
try {
map_markers.forEach( marker => marker.remove() );
map_markers = [];
ar.forEach(function(item, index){
var group = document.querySelector('input[name="filGroup"]:checked').value;
var marker = L.marker([item[0], item[1]]).addTo(map);
marker.bindPopup('<div id="text"><p>Name: ' item[3] '<br>DOB: ' item[4] '</p></div>' );
map_markers.push(marker);
});
}
catch(err) {
alert(err);
}
}
).getAddress(group);
}
</script>
</body>
</html>
Code.gs
function getAddress(group) {
try {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var groupSheet = ss.getSheetByName("Sheet1");
let values = groupSheet.getDataRange().getValues();
values.shift(); // remove headers
if( group !== 'All' ) {
values = values.filter( row => row[2] === group )
}
return values;
}
catch(err) {
Logger.log(err);
}
}