Heim  >  Artikel  >  Web-Frontend  >  Erstellen eines interaktiven XY-Bildplots mit Google Apps Script und Leaflet.js

Erstellen eines interaktiven XY-Bildplots mit Google Apps Script und Leaflet.js

WBOY
WBOYOriginal
2024-09-08 22:35:08897Durchsuche

Google Maps verfügt über zahlreiche Funktionen zum Einzeichnen von Punkten auf einer Karte. Was aber, wenn Sie Punkte auf einem Bild einzeichnen möchten? Diese XY-Bilddiagramme werden häufig für Grundrisskarten, Baustelleninspektionen und sogar Spiele verwendet.

In dieser Anleitung zeige ich Ihnen, wie Sie mit Leaflet.js und Google Apps Script eine interaktive Karte mit ziehbaren Punkten erstellen. Wir decken alles ab, von der Einrichtung der Karte über die Integration von Daten aus Google Sheets bis hin zur Bereitstellung als Web-App.

Dieser Leitfaden behandelt Folgendes:

  • Einrichten von Leaflet.js in einem Google Apps Script-HTML-Dienst

  • Markierungen mithilfe von Daten aus Google Sheets anzeigen

  • Aktualisierung der Tabellenzeile, wenn eine Markierung verschoben wird

  • Neue Markierungen aus der Karte erstellen und in Tabellen speichern

  • Markierung aus der Web-App löschen

Einrichten von Leaflet.js in einem Google Apps Script-HTML-Dienst

Leaflet.js ist eine der beliebtesten Open-Source-Mapping-Bibliotheken. Es ist leicht, einfach zu bedienen und verfügt über eine hervorragende Dokumentation. Sie unterstützen eine Vielzahl verschiedener Kartentypen, einschließlich „CRS.Simple“ oder „Coordinate Reference System“, mit dem Sie ein Hintergrundbild bereitstellen können.

Google Sheets eingerichtet

Erstellen Sie zunächst ein Blatt namens „map_pin“ mit der folgenden Struktur:

id title x y
1 test1 10 30
2 test2 50 80

Öffnen Sie dann Apps Script aus dem Menü „Erweiterungen“.

HTML-Datei erstellen

Zuerst beginnen wir mit dem grundlegenden Beispiel aus den Leaflet-Dokumenten, um die Bibliothek zum Laufen zu bringen. Das vollständige Beispiel finden Sie hier in der Kurzanleitung.

Fügen Sie eine neue HTML-Datei mit dem Namen Index hinzu und legen Sie den Inhalt fest auf:

<!DOCTYPE html>
<html>
<head>
  <title>Quick Start - Leaflet</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" />
  <style>
    #map {
      height: 400px;
    }
  </style>
</head>
<body>
  <div id="map"></div>

  <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
  <script>
    var map = L.map('map').setView([40.73, -73.99], 13);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 19,
      attribution: '© OpenStreetMap'
    }).addTo(map);

    var marker = L.marker([40.73, -73.99]).addTo(map)
      .bindPopup('Test Popup Message')
      .openPopup();
  </script>
</body>
</html>

Aktualisieren Sie dann die Code.gs-Datei mit:

function doGet() {
  const html = HtmlService.createHtmlOutputFromFile('Index')
    .setTitle('Map with Draggable Points')
    .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
  return html;
}

Speichern Sie und klicken Sie dann auf „Bereitstellen“ und als Web-App veröffentlichen. Öffnen Sie dann den Link für die neue Bereitstellung und Sie sollten Leaflet.js sehen, das eine Karte von New York anzeigt.

Building an Interactive XY Image Plot with Google Apps Script and Leaflet.js

Ok, das ist das reguläre Kartenbeispiel mit Leaflet. Nun zum CRS.Simple-Kartentyp, der die Bereitstellung eines Hintergrundbilds ermöglicht.

Aktualisieren Sie den HTML-Code mit diesem Beispiel aus den Leaflet-Tutorials.

<!DOCTYPE html>
<html>
<head>
  <title>CRS Simple Example - Leaflet</title>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" />
  <style>
    #map {
      height: 400px;
      width: 600px;
    }
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
  <div id="map"></div>

  <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js"></script>
  <script>
    // Set up the map with a simple CRS (no geographic projection)
    var map = L.map('map', {
      crs: L.CRS.Simple,
      minZoom: -1,
      maxZoom: 4
    });

    // Define the dimensions of the image
    var bounds = [[0, 0], [1000, 1000]];
    var image = L.imageOverlay('https://leafletjs.com/examples/crs-simple/uqm_map_full.png', bounds).addTo(map);

    // Set the initial view of the map to show the whole image
    map.fitBounds(bounds);

    // Optional: Add a marker or other elements to the map
    var marker = L.marker([500, 500]).addTo(map)
      .bindPopup('Center of the image')
      .openPopup();
  </script>
</body>
</html>

Hier liefern wir ein Bild mit 1000 x 1000 Pixeln und setzen dann die Mittelmarkierung auf 500, 500.

Klicken Sie auf Speichern und dann auf Bereitstellen>Testbereitstellungen, um den neuen Kartentyp anzuzeigen. Sie sollten jetzt eine Karte mit einem Hintergrundbild und einer Markierung in der Mitte haben.

Building an Interactive XY Image Plot with Google Apps Script and Leaflet.js

Initialisieren einer Karte mit Daten aus Google Sheets

Als nächstes verwenden wir die Daten aus dem Blatt, um eine Reihe von Markierungen auf der Karte zu füllen.

Fügen Sie zunächst eine Funktion zur Code.gs-Datei hinzu, um die Markierungspositionen abzurufen:

function getPinData(){
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheetByName('map_pin');
  const data = sh.getDataRange().getValues();
  const json = arrayToJSON(data);
  //Logger.log(json);
  return json
}

function arrayToJSON(data=getPinData()){
  const headers = data[0];
  const rows = data.slice(1);
  let jsonData = [];
  for(row of rows){
    const obj = {};
    headers.forEach((h,i)=>obj[h] = row[i]);
    jsonData.push(obj)
  }
  //Logger.log(jsonData)
  return jsonData
}

Hier gebe ich die Pins als JSON zurück, damit sie im nächsten Abschnitt einfacher im HTML-Code verwendet werden können.

Fügen Sie nun dem HTML eine Funktion hinzu, um diesen JSON zu durchlaufen und die Karten-Pins zu erstellen, nachdem die Karte geladen wurde.

// Add map pins from sheet data
    google.script.run.withSuccessHandler(addMarkers).getPinData();

    function addMarkers(mapPinData) {
      mapPinData.forEach(pin => {
        const marker = L.marker([pin.x, pin.y], {
          draggable: true
        }).addTo(map);

        marker.bindPopup(`<b>${pin.title}`).openPopup();

        marker.on('dragend', function(e) {
          const latLng = e.target.getLatLng();
          console.log(`Marker ${pin.title} moved to: ${latLng.lat}, ${latLng.lng}`);
        });
      });
    }

Speichern Sie und öffnen Sie dann die Testbereitstellung. Sie sollten jetzt Markierungen aus Ihren Blattdaten generiert haben!

Building an Interactive XY Image Plot with Google Apps Script and Leaflet.js

Jeder Pin hat ein Popup mit dem Titel dieser Zeile. An dieser Stelle sind die Pins ziehbar, wir benötigen aber noch eine Funktion zum Speichern der neuen Position.

Markierungsposition beim Ziehen speichern

Um die neue Position zu speichern, benötigen wir zwei Funktionen: eine im HTML, um das Ereignis auf der Clientseite zu erfassen, und eine, um die neue Position auf der Serverseite in der Code.gs-Datei zu speichern.

Aktualisieren Sie den HTML-Code mit:

    function addMarkers(mapPinData) {
      mapPinData.forEach(pin => {
        const { id, title, x, y } = pin;
        const marker = L.marker([x, y], {
          draggable: true
        }).addTo(map);

        marker.bindPopup(`<b>${title}</b>`).openPopup();

        marker.on('dragend', function(e) {
          const latLng = e.target.getLatLng();
          console.log(`Marker ${title} moved to: ${latLng.lat}, ${latLng.lng}`);
          saveMarkerPosition({ id, title, lat: latLng.lat, lng: latLng.lng });
        });
      });
    }

    function saveMarkerPosition({ id, title, lat, lng }) {
      google.script.run.saveMarkerPosition({ id, title, lat, lng });
    }

Und fügen Sie dann eine Funktion zur Code.gs-Datei hinzu, um den Speicherort zu speichern:

function saveMarkerPosition({ id, lat, lng }) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheetByName('map_pin');
  const data = sh.getDataRange().getValues();

  for (let i = 1; i < data.length; i++) {
    if (data[i][0] === id) {  // ID column (index 0)
      sh.getRange(i + 1, 3).setValue(lat);  // latitude column
      sh.getRange(i + 1, 4).setValue(lng);  // longitude column
      break;
    }
  }
}

Speichern und aktualisieren Sie die Testbereitstellung. Sie sollten jetzt die Blattaktualisierung sehen, wenn eine Markierung gezogen wird!

Building an Interactive XY Image Plot with Google Apps Script and Leaflet.js

Neue Punkte hinzufügen

Wir können jetzt die vorhandenen Punkte verschieben, aber wie sieht es mit dem Hinzufügen neuer Punkte aus? Auch hier benötigen wir zwei Funktionen, eine im HTML und eine in der Code.gs-Datei.

Fügen Sie zunächst eine Funktion zum HTML hinzu, um eine Eingabeaufforderung zu öffnen, wenn der Benutzer auf eine leere Stelle auf der Karte klickt, und übergeben Sie den Wert an eine Serverfunktion.

    // Function to add a new pin
    map.on('click', function(e) {
      const latLng = e.latlng;
      const title = prompt('Enter a title for the new pin:');
      if (title) {
        google.script.run.withSuccessHandler(function(id) {
          addNewMarker({ id, title, lat: latLng.lat, lng: latLng.lng });
        }).addNewPin({ title, lat: latLng.lat, lng: latLng.lng });
      }
    });

    function addNewMarker({ id, title, lat, lng }) {
      const marker = L.marker([lat, lng], {
        draggable: true
      }).addTo(map);

      marker.bindPopup(`<b>${title}</b>`).openPopup();

      marker.on('dragend', function(e) {
        const latLng = e.target.getLatLng();
        saveMarkerPosition({ id, title, lat: latLng.lat, lng: latLng.lng });
      });
    }

Dann fügen Sie die Funktion zu Code.gs hinzu, um die neue Zeile zu speichern.

function addNewPin({ title, lat, lng }) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheetByName('map_pin');

  // Check if there are any rows present, if not initialize ID
  const lastRow = sh.getLastRow();
  let newId = 1;

  if (lastRow > 0) {
    const lastId = sh.getRange(lastRow, 1).getValue();
    newId = lastId + 1;
  }

  sh.appendRow([newId, title, lat, lng]);

  return newId;
}

Speichern Sie noch einmal und aktualisieren Sie die Testbereitstellung. Wenn Sie nun auf eine leere Stelle klicken, können Sie einen Titel eingeben und eine neue Markierung speichern!

Building an Interactive XY Image Plot with Google Apps Script and Leaflet.js

Eine Markierung löschen

Zuletzt sollten wir eine Möglichkeit zum Löschen von Markierungen hinzufügen, sodass wir eine vollständige CRUD-App in der Kartenansicht erhalten.

Aktualisieren Sie die Funktion zum Hinzufügen von Markierungen, um dem Popup eine Schaltfläche zum Löschen zu geben:

      const popupContent = `<b>${title}</b><br><button onclick="deleteMarker(${id})">Delete Marker</button>`;
      marker.bindPopup(popupContent).openPopup();

Und fügen Sie dann eine Funktion zum Löschen von der Clientseite hinzu:

// Function to delete a marker
  function deleteMarker(id) {
    const confirmed = confirm('Are you sure you want to delete this marker?');
    if (confirmed) {
      google.script.run.withSuccessHandler(() => {
        // Refresh the markers after deletion
        google.script.run.withSuccessHandler(addMarkers).getPinData();
      }).deleteMarker(id);
    }
  }

Dann fügen Sie die passende Funktion zur Code.gs-Datei hinzu:

function deleteMarker(id) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sh = ss.getSheetByName('map_pin');
  const data = sh.getDataRange().getValues();

  for (let i = 1; i < data.length; i++) {
    if (data[i][0] === id) {  // ID column (index 0)
      sh.deleteRow(i + 1);  // Delete the row
      break;
    }
  }
}

Was kommt als nächstes?

Von hier aus können Sie noch viel mehr tun, z. B. das Hinzufügen anderer Datenpunkte zu jeder Markierung, dynamische Hintergrundbilder oder andere Klick- und Drag-Interaktionen. Du könntest sogar ein Spiel machen! Haben Sie eine Idee für einen Anwendungsfall? Schreiben Sie unten einen Kommentar!

Das obige ist der detaillierte Inhalt vonErstellen eines interaktiven XY-Bildplots mit Google Apps Script und Leaflet.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn