#JP69 Kelola Data Google Maps II dengan Upload Foto Menggunakan Apps Script (GIS)

Kelola Data Google Maps II dengan Upload Foto Menggunakan Apps Script (GIS)



1. Buatlah Spreadsheet pada Google Drive.

2. Buatlah Folder baru untuk menyimpan foto pada Google Drive dan beri nama JavabitproMaps




3. Buatlah lembar kerja Apps Script dengan klik menu Ektensi/Extensions lalu pilih Apps Script.


4. Buatlah 3 file pada Apps Script.


5. Tambkan API Google Drive pada Apps Script.


6. Copy dan pastekan script di bawah ini ke Code.gs

Masukkan Password Untuk Melihat Script (Password ada di dalam video)

// Code.gs
// Source Code by www.javabitpro.com
function doGet(e) {
  var template = HtmlService.createTemplateFromFile('index')
  return  template.evaluate().setSandboxMode(HtmlService.SandboxMode.IFRAME)
  .addMetaTag('viewport', 'width=device-width , initial-scale=1')
}


function getMapData() {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();
  return data;
}

function saveMapData(name, address, kunjungan, latitude, longitude) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  sheet.appendRow([name, address, kunjungan, latitude, longitude]);
}
function editMapData(oldName, oldAddress, oldKunjungan, newName, newAddress, newKunjungan, latitude, longitude) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();

  for (var i = 0; i < data.length; i++) {
    if (data[i][0] === oldName && data[i][1] === oldAddress && data[i][2] === oldKunjungan && data[i][3] === latitude && data[i][4] === longitude) {
      // Update data in the spreadsheet
      sheet.getRange(i + 1, 1).setValue(newName);
      sheet.getRange(i + 1, 2).setValue(newAddress);
      sheet.getRange(i + 1, 3).setValue(newKunjungan);
      break;
    }
  }
}

function deleteMapData(name, address, kunjungan, latitude, longitude) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();

  for (var i = 0; i < data.length; i++) {
    if (data[i][0] === name && data[i][1] === address && data[i][2] === kunjungan && data[i][3] === latitude && data[i][4] === longitude) {
      // Delete row from the spreadsheet
      sheet.deleteRow(i + 1);
      break;
    }
  }
}
function include(filename) {
   return HtmlService.createHtmlOutputFromFile(filename)
  .getContent();
}
function getURL(){
return ScriptApp.getService().getUrl()
}
function savePhoto(name, address, kunjungan, latitude, longitude, photoDataUrl) {
  var folderId = "GANTI_ID_FOLDER"; // Ganti dengan ID folder Google Drive Anda
  var fileName = name + "_" + address + "_" + kunjungan + "_" + latitude + "_" + longitude + ".jpg";

  // Hapus foto lama jika ada
  deletePhoto(name, address, kunjungan, latitude, longitude);

  // Buat blob dari data URL
  var blob = Utilities.newBlob(Utilities.base64Decode(photoDataUrl.split(',')[1]), 'image/jpeg', fileName);

  // Unggah blob ke Google Drive
  var file = Drive.Files.insert(
    {
      title: fileName,
      mimeType: 'image/jpeg',
      parents: [{ id: folderId }]
    },
    blob
  );

  // Simpan URL foto di spreadsheet
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();

  for (var i = 0; i < data.length; i++) {
    if (data[i][0] === name && data[i][1] === address && data[i][2] === kunjungan && data[i][3] === latitude && data[i][4] === longitude) {
      sheet.getRange(i + 1, 6).setValue(file.alternateLink); // Menggunakan alternateLink untuk melihat file di web
      break;
    }
  }

  return file.alternateLink;
}


function deletePhoto(name, address, kunjungan, latitude, longitude) {
  var folderId = "GANTI_ID_FOLDER"; // Ganti dengan ID folder Google Drive Anda
  var fileName = name + "_" + address + "_" + kunjungan + "_" + latitude + "_" + longitude + ".jpg";

  // Hapus file dari Google Drive
  var files = DriveApp.getFolderById(folderId).getFilesByName(fileName);
  while (files.hasNext()) {
    var file = files.next();
    file.setTrashed(true);
  }

  // Hapus URL foto di spreadsheet
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var data = sheet.getDataRange().getValues();

  for (var i = 0; i < data.length; i++) {
    if (data[i][0] === name && data[i][1] === address && data[i][2] === kunjungan && data[i][3] === latitude && data[i][4] === longitude) {
      sheet.getRange(i + 1, 6).setValue('');
      break;
    }
  }
}

KETERANGAN :

Pada line 55 & line 90 sesuaikan/ganti dengan ID Folder yang telah dibuat.


7. Copy dan pastekan script di bawah ini ke index.html


Masukkan Password Untuk Melihat Script (Password sama dengan di atas)

<!-- index.html -->
<!-- Source Code by www.javabitpro.com -->
<!DOCTYPE html>
<html>
  <head>
  <!-- font-awesome@6.2.0 icon Visit -->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.0/css/all.min.css">

   <?!= include('visit')?>

 <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kelola Data Google Maps Menggunakan Apps Script II by Javabitpro</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
    <style>
      #map {
        height: 400px;
        width: 100%;
      }
      #data-table {
        margin-top: 20px;
      }
    </style>
  </head>
  <body>
   <div class="container">
      <h2 class="mt-4 mb-4">GIS Web App</h2>

      <!-- Maps Container -->
      <div id="map" class="mb-4"></div>


      <!-- Data Table -->
      <table id="data-table" class="table table-bordered table-striped">
        <thead class="thead-dark">
          <tr>
            <th>Name</th>
            <th>Address</th>
            <th>Kunjungan</th>
            <th>Latitude</th>
            <th>Longitude</th>
            <th>Photo</th>
            <th>Actions</th>
          </tr>
        </thead>
        <tbody id="data-body"></tbody>
      </table>
    </div>

    <!-- Bootstrap JS and Popper.js -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>


    <script>
      var map;
      var markers = [];
      var infoWindow;

      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -8.179343323993091, lng: 113.6962948618509},
          zoom: 13
        });

        infoWindow = new google.maps.InfoWindow();

        // Add click event listener to the map
        map.addListener('click', function(event) {
          addMarker(event.latLng);
        });

        // Load existing markers from the sheet
        google.script.run.withSuccessHandler(loadMarkers).getMapData();
      }

      function addMarker(location) {
        var marker = new google.maps.Marker({
          position: location,
          map: map,
          draggable: true
        });

        // Add click event listener to the marker
        marker.addListener('click', function() {
          var name = prompt('Enter name:');
          var address = prompt('Enter address:');
          var kunjungan = prompt('Kunjungan ke:');
          saveDataToSheet(name, address, kunjungan, marker.getPosition().lat(), marker.getPosition().lng());
        });

        // Save the marker reference
        markers.push(marker);
      }

      function loadMarkers(data) {
        // Clear existing markers and reload from the sheet
        clearMarkers();
        markers = [];

        // Update the table with data from the spreadsheet
        var dataTable = document.getElementById('data-body');
        dataTable.innerHTML = '';

        for (var i = 0; i < data.length; i++) {
          var latLng = new google.maps.LatLng(data[i][3], data[i][4]);
          addMarkerWithInfo(latLng, data[i][0], data[i][1], data[i][2], data[i][3], data[i][4], data[i][5]);
          addRowToTable(data[i]);
        }
      }

      function addMarkerWithInfo(location, name, address, kunjungan, latitude, longitude, photoUrl) {
        var marker = new google.maps.Marker({
          position: location,
          map: map,
          draggable: true
        });

        // Add click event listener to the marker
        marker.addListener('click', function() {
          showInfoWindow(marker, name, address, kunjungan, latitude, longitude, photoUrl);
        });

        // Save the marker reference
        markers.push(marker);
      }

      function showInfoWindow(marker, name, address, kunjungan, latitude, longitude, photoUrl) {
        var content =
          '<strong>Name:</strong> ' + name +
          '<br><strong>Address:</strong> ' + address +
          '<br><strong>Kunjungan:</strong> ' + kunjungan +
          '<br><strong>Latitude:</strong> ' + latitude +
          '<br><strong>Longitude:</strong> ' + longitude +
          '<br><strong>Photo URL:</strong> ' + (photoUrl ? '<a href="' + photoUrl + '" target="_blank">View Photo</a>' : 'No Photo Available');

        infoWindow.setContent(content);
        infoWindow.open(map, marker);
      }

      function saveDataToSheet(name, address, kunjungan, latitude, longitude) {
        google.script.run.withSuccessHandler(function(data) {
          alert('Data has been saved.');
          // Reload the map and table after saving data
          google.script.run.withSuccessHandler(loadMarkers).getMapData();
        }).saveMapData(name, address, kunjungan, latitude, longitude);
      }

      function clearMarkers() {
        for (var i = 0; i < markers.length; i++) {
          markers[i].setMap(null);
        }
      }

      function addRowToTable(data) {
        var dataTable = document.getElementById('data-body');
        var row = dataTable.insertRow(-1);

        for (var i = 0; i < data.length; i++) {
          var cell = row.insertCell(i);
          if (i === 5) {
            // If it's the Photo column
            cell.innerHTML = data[i] ? '<a href="' + data[i] + '" target="_blank">View Photo</a>' : 'No Photo';
          } else {
            cell.textContent = data[i];
          }
        }

        // Add action buttons
        var actionCell = row.insertCell(data.length);
        actionCell.className = 'action-buttons';
        var editButton = document.createElement('button');
        editButton.textContent = 'Edit';
        editButton.addEventListener('click', function() {
          editData(data);
        });
        actionCell.appendChild(editButton);

        var deleteButton = document.createElement('button');
        deleteButton.textContent = 'Delete';
        deleteButton.addEventListener('click', function() {
          deleteData(data);
        });
        actionCell.appendChild(deleteButton);

        var uploadButton = document.createElement('button');
        uploadButton.textContent = data[5] ? 'View Photo' : 'Upload Photo';
        uploadButton.addEventListener('click', function() {
          data[5] ? viewPhoto(data[5]) : uploadPhoto(data[0], data[1], data[2], data[3], data[4], row);
        });
        actionCell.appendChild(uploadButton);
      }

      function uploadPhoto(name, address, kunjungan, latitude, longitude, row) {
        var fileUpload = document.createElement('input');
        fileUpload.type = 'file';
        fileUpload.accept = 'image/*';

        fileUpload.addEventListener('change', function() {
          var file = fileUpload.files[0];
          if (file) {
            var reader = new FileReader();
            reader.onload = function(e) {
              var photoDataUrl = e.target.result;
              savePhoto(name, address, kunjungan, latitude, longitude, photoDataUrl, row);
            };
            reader.readAsDataURL(file);
          }
        });

        fileUpload.click();
      }

      function savePhoto(name, address, kunjungan, latitude, longitude, photoDataUrl, row) {
        google.script.run.withSuccessHandler(function(photoUrl) {
          if (photoUrl) {
            alert('Photo has been uploaded.');
            // Update the table and row with the new photo URL
            row.cells[5].innerHTML = '<a href="' + photoUrl + '" target="_blank">View Photo</a>';
            google.script.run.withSuccessHandler(loadMarkers).getMapData();
          } else {
            alert('Failed to upload photo.');
          }
        }).savePhoto(name, address, kunjungan, latitude, longitude, photoDataUrl);
      }

      function viewPhoto(photoUrl) {
        window.open(photoUrl, '_blank');
      }

      function editData(data) {
        var newName = prompt('Edit Name:', data[0]);
        var newAddress = prompt('Edit Address:', data[1]);
        var newKunjungan = prompt('Edit Kunjungan:', data[2]);
        if (newName !== null && newAddress !== null && newKunjungan !== null) {
          google.script.run.withSuccessHandler(function() {
            alert('Data has been edited.');
            // Reload the map and table after editing data
            google.script.run.withSuccessHandler(loadMarkers).getMapData();
          }).editMapData(data[0], data[1], data[2], newName, newAddress, newKunjungan, data[3], data[4]);
        }
      }

      function deleteData(data) {
        var confirmDelete = confirm('Are you sure you want to delete this data?');
        if (confirmDelete) {
          google.script.run.withSuccessHandler(function() {
            alert('Data has been deleted.');
            // Reload the map and table after deleting data
            google.script.run.withSuccessHandler(loadMarkers).getMapData();
          }).deleteMapData(data[0], data[1], data[2], data[3], data[4]);
        }
      }

      function saveData() {
        var data = google.script.run.getMapData();
        console.log(data); // You can customize this part to save or display the data as needed
      }
    </script>
    <script src="https://raw.githack.com/javabitpro/maps/main/mapsJavaScriptAPI.js"
    async defer></script>
  </body>
</html>


8. Copy dan pastekan script di bawah ini visit.html


Masukkan Password Untuk Melihat Script (Password sama dengan di atas)

<style>


 .fab-container2 {
	position: fixed;
	bottom: 80px;
	right: 1px;
	z-index: 999;
	cursor: pointer;
}

.fab-label2 {
    padding: 2px 5px;
    align-self: center;
    user-select: none;
    white-space: nowrap;
    border-radius: 3px;
    font-size: 16px;
    background: #666666;
    color: #ffffff;
    box-shadow: 0 6px 20px rgba(0,0,0,0.2);
    /* margin-right: 10px; */
}

 .fab-container {
	position: fixed;
	bottom: 10px;
	right: 10px;
	z-index: 999;
	cursor: pointer;
}

.fab-icon-holder {
	width: 50px;
	height: 50px;
	border-radius: 100%;
	background: #6dd4fc;

	box-shadow: 0 6px 20px rgba(0,0,0,0.2);
}

.fab-icon-holder:hover{
	opacity: 0.8;
}

.fab-icon-holder i {
	display: flex;
	align-items: center;
	justify-content: center;

	height: 100%;
	font-size: 25px;
	color: #000000;
}

.fab {
	width: 56px;
	height: 56px;
	background: #6dd4fc;
}

.fab-options {
	list-style-type: none;
	margin: 0;

	position: absolute;
	bottom: 70px;
	right: 0;

	opacity: 0;

	transition: all 0.3s ease;
	transform: scale(0);
	transform-origin: 85% bottom;
}

.fab:hover + .fab-options, .fab-options:hover {
	opacity: 1;
	transform: scale(1);
}

.fab-options li {
	display: flex;
	justify-content: flex-end;
	padding: 5px;
}

.fab-label {
	padding: 2px 5px;
	align-self: center;
	user-select: none;
	white-space: nowrap;
	border-radius: 3px;
	font-size: 16px;
	background: #666666;
	color: #ffffff;
	box-shadow: 0 6px 20px rgba(0,0,0,0.2);
	margin-right: 10px;
} 

a {
  color: inherit;
  text-decoration: none;
}
</style>
  <!-- ------------------------------ Visit ------------------------------- -->
	<div class="fab-container2">
    <p class="fab-label2">Visit</p>
  </div>
	<div class="fab-container">
		<div class="fab fab-icon-holder">
			<i><img src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiC7hb7GJ4v4IwapVwZJJyvGsG5WF4RxsmEb0va1X0t-6urm1PGPDA2IEsETeLCuiyfJkUWhOOIUg9FN_Dr3gJJQmQUe2-AnYI3-R05TC6PbMRSnaljamNC9lQMOeE2q4Dr29jkfEaYwpadAjraVGgIgC_wGGp596Uh6tLX_ClrfbqK3wdhz4jE7i16/s1600/PNG%20JP.png" style="width: 75px;"></i>
		</div>
		<ul class="fab-options">
			<li>
				<span class="fab-label">Youtube</span>
				<div class="fab-icon-holder">
					<a target="_blank" href="https://www.youtube.com/@javabitpro-editor/videos"><i class="fa-brands fa-youtube"></i></i></a>
				</div>
			</li>
			<li style="margin-bottom: 60px;">
				<span class="fab-label">Website</span>
				<div class="fab-icon-holder">
					<a target="_blank" href="https://www.javabitpro.com/"><i class="fa-solid fa-globe"></i></a>
				</div>
			</li>			
		</ul>
	</div>


9. Klik Terapkan/Deploy dan pilih Deployment baru/New deployment


10. Samakan penagturan dengan gambar di bawah ini dan klik Deploy.


11. Copy atau klik Url yang sudah di deploy.


SELESAI !!!




Previous Post Next Post

Promo