Geokodierung

Sie können mit Hilfe der SmartMaps-API sowohl beliebige Adressen geokodieren als auch einer Koordinate eine Adresse zuordnen. Verwenden Sie hierzu bitte die Klasse GeoCoder.

Die Optionen entsprechen denen des Konstruktors. Standardmäßig werden die Optionen aus dem Konstruktor und der Elternklasse verwendet. Wenn die Optionen hier gesetzt werden, überschreiben sie für diesen Aufruf die vorher gesetzten Optionen.

Anleitung

Für die Implementierung eines Formulars, welches die Geokodierung von Adressen auf der SmartMaps-Karte ermöglicht, wird vorerst im body-Tag des HTML-Skriptes ein div-Element mit der ID map-wrapper hinzugefügt. 

  <div id="map-wrapper">
     ...
  </div>.

Der map-wrapper beinhaltet in sich ein weiteres div-Element mit der Klasse geocoder-form. In diesem wird die Benutzeroberfläche für das Eingeben der Adressinformationen implementiert. Dabei handelt es sich bei der einfachen Geokodierung von Adressen um ein Formular (ID=location-form), welches die Postleitzahl, die Stadt und die Straße der zu geokodierenden Adresse abfragt. Das Input-Feld für die Eingabe des Landes der Adresse ist in diesem Fall auf hidden gestellt und standardmäßig Deutschland.

      <form id="location-form">
        <fieldset>
          <legend>Geokodiere Adresse</legend>
          <label>
              Postleitzahl:
              <input type="text" name="zip" value="76133" placeholder="zip code">
            </label>
          <label>
              Stadt:
              <input type="text" name="city" value="Karlsruhe" placeholder="city">
            </label>
          <label>
              Straße:
              <input type="text" name="street" value="Wattkopfstr" placeholder="street">
            </label>
          <input type="hidden" name="country" value="DE">
          <button type="submit">send</button>
        </fieldset>
      </form>

Für die Anzeige der SmartMaps-Karte, beinhaltet der map-wrapper ein leeres div-Element mit der ID map.  In diesem wird zur Laufzeit die Karte geladen. Für das div-Element kann man durch das style-Attribut eine feste Höhe und Breite für die Karte festlegen.

<div id="map" style="height: 400px; width: 500px;"></div>

Um die Funktionalität der Geokodierung zu realisieren, ist die Einbindung von JavaScript-Code notwendig. Dieser kann, wie in diesem Beispiel, anhand eines script-Tags im HTML-Skript eingebunden werden oder in einer separaten .js-Datei. Alle Variablen und Funktionen werden in der ym.ready-Methode implementiert, da diese Abhängigkeiten auflöst, um die eigentliche Kartenanwendung zu starten.

ym.ready(function(modules) {
...
});

Zur Verwaltung des Adressformulars wird die Variable geocodingForm definiert. Diese bekommt anhand der ID location-form das Formular zur Eingabe von Adressen zugewiesen. Für die Darstellung der Geokodierung auf der Karte wird eine Variable namens layerGroup angelegt. Diese stellt eine Layergruppe dar, welche dazu dient die SmartMaps-Karte und deren Objekte anhand von Ebenen zu verwalten.

    ym.ready(function(modules) {
// Auf Adressformular zugerifen. var geocodingForm = document.getElementById('location-form'); // Layergruppe definieren. var layerGroup = ym.layerGroup();

Ein Objekt der Klasse ym.map wird angelegt, um die Anzeige der SmartMaps-Karte zu ermöglichen. Als Parameter wird dabei die ID des div-Elementes übergeben, in dem die Karte eingezeichnet werden soll, und die gewünschten Karten-Optionen (Startposition, Startzoom-Level, usw.). Um die Karte weiterhin im Code zu verwalten, wird das Objekt in eine Variable map gelagert. Die zuvor angelegte Layergruppe wird im Nachhinein zur Karte hinzugefügt.

      // Karte einzeichnen.
      var map = ym.map("map", {
        center: ym.latLng(49.021273, 8.439316),
        zoom: 14
      });
      // Layergruppe einzeichnen.
      layerGroup.addTo(map);

Für das Verarbeiten der Formulareingaben des Nutzers, wird eine Funktion definiert. Diese liest, nach dem der Nutzer das Formular location-form absendet, die Adresseingaben aus und geokodiert diese.

      geocodingForm.onsubmit = function(e) {
        e.preventDefault();
        var inputs = document.querySelectorAll('#location-form input');
        var zip = inputs[0].value;
        var city = inputs[1].value;
        var street = inputs[2].value;
        var country = inputs[3].value;
        // Adressdaten geokodieren.
        modules.geocode({
          "country": country,
          "district": "",
          "zip": zip,
          "city": city,
          "cityAddOn": "",
          "cityPart": "",
          "street": street,
          "houseNo": "",
          "singleSlot": ""
        });
      };

Um die Geokodierung zu verfolgen, nutzt man für die geoCoder-Klasse, welche die Geokodierung auf der SmartMaps-Karte ermöglicht, einen EventEmitter. Dieser ermöglicht durch seine on-Methode, dass ein Listener hinzugefügt wird. Der Listener führt Funktionen bei bestimmten Events durch und kann somit genutzt werden um zwischen einer erfolgreichen und nicht erfolgreichen Geokodierung zu unterscheiden. In dem Falle ist die geoCoder-Klasse mit einen EventEmitter schon ausgestattet und kann direkt auf die on-Methode zugereifen.
Im Falle einer erfolgreichen Geokodierung ('success') wird an der geokodierten Adresse auf der Karte ein Marker gesetzt, welcher beim anklicken ein Popup-Fenster mit den Adressdaten anzeigt. Der Marker wird anhand von GeoJSON erstellt und als Layer in die SmartMaps-Karte eingefügt.

      ym.services.geoCoder.on('success', function(req, res) {
        // Alte Daten aus der Karte löschen.
        layerGroup.clearLayers();
        var geoJson = ym.geoJson(res.body, {
          // Für jeden Eintrag Marker einzeichnen.
          onEachFeature: function(feature, layer) {
            layer.setIcon(ym.provider.Icon.Default());
            var popUpContent = "";
            if (feature.properties.street) {
              popUpContent += feature.properties.street + ", "
            }
            if (feature.properties.zip) {
              popUpContent += feature.properties.zip + " "
            }
            if (feature.properties.city) {
              popUpContent += feature.properties.city + " "
            }
            if (feature.properties.cityPart) {
              popUpContent += feature.properties.cityPart
            }
            // Adressdaten im PopUp anzeigen.
            layer.bindPopup(popUpContent);
          }
        });
        // Kartenausschnitt auf Ergebnismenge optimieren.
        map.fitBounds(geoJson.getBounds());
        layerGroup.addLayer(geoJson);
      });

Im Falle einer nicht erfolgreichen Geokodierung ('error') wird ein Eintrag in die Konsole geschrieben.

      ym.services.geoCoder.on('error', function(req, res, errorType) {
        console.log(arguments);
      });

Die Geokodierung ist nun erfolgreich eingebunden.

HTML-Dokument

Codebeispiel: Geokodierung

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>Geokodierung mit einfachem Eingabefeld.</title>
</head>
<body>
  <div id="map-wrapper">
    <div class="geocoder-form" style="z-index:1000">
      <form id="location-form">
        <fieldset>
          <legend>Geokodiere Adresse</legend>
          <label>
            Postleitzahl:
            <input type="text" name="zip" value="76133" placeholder="zip code">
          </label>
          <label>
            Stadt:
            <input type="text" name="city" value="Karlsruhe" placeholder="city">
          </label>
          <label>
            Straße:
            <input type="text" name="street" value="Wattkopfstr" placeholder="street">
          </label>
          <input type="hidden" name="country" value="DE">
          <button type="submit">send</button>
        </fieldset>
      </form>
    </div>
    <div id="map" style="height: 400px; width: 500px;"></div>
  </div>
  <!-- SmartMaps-API -->
  <script
    src="https://www.yellowmap.de/api_rst/api/loader?libraries=free-3&apiKey={API_KEY}"></script>
  <script>
    ym.ready(function (modules) {
      // Auf Adressformular zugerifen. 
      var geocodingForm = document.getElementById('location-form');
      // Layergruppe definieren.
      var layerGroup = ym.layerGroup();

      // Karte einzeichnen.
      var map = ym.map("map", {
        center: ym.latLng(49.021273, 8.439316),
        zoom: 14
      });
      // Layergruppe einzeichnen.
      layerGroup.addTo(map);
      geocodingForm.onsubmit = function (e) {
        e.preventDefault();
        var inputs = document.querySelectorAll('#location-form input');
        var zip = inputs[0].value;
        var city = inputs[1].value;
        var street = inputs[2].value;
        var country = inputs[3].value;
        // Adressdaten geokodieren.
        modules.geocode({
          "country": country,
          "district": "",
          "zip": zip,
          "city": city,
          "cityAddOn": "",
          "cityPart": "",
          "street": street,
          "houseNo": "",
          "singleSlot": ""
        });
      };
      ym.services.geoCoder.on('success', function (req, res) {
        // Alte Daten aus der Karte löschen.
        layerGroup.clearLayers();
        var geoJson = ym.geoJson(res.body, {
          // Für jeden Eintrag Marker einzeichnen.
          onEachFeature: function (feature, layer) {
            layer.setIcon(ym.provider.Icon.Default());
            var popUpContent = "";
            if (feature.properties.street) {
              popUpContent += feature.properties.street + ", "
            }
            if (feature.properties.zip) {
              popUpContent += feature.properties.zip + " "
            }
            if (feature.properties.city) {
              popUpContent += feature.properties.city + " "
            }
            if (feature.properties.cityPart) {
              popUpContent += feature.properties.cityPart
            }
            // Adressdaten im PopUp anzeigen.
            layer.bindPopup(popUpContent);
          }
        });
        // Kartenausschnitt auf Ergebnismenge optimieren.
        map.fitBounds(geoJson.getBounds());
        layerGroup.addLayer(geoJson);
      });
      ym.services.geoCoder.on('error', function (req, res, errorType) {
        console.log(arguments);
      });
    });
  </script>
</body>
</html>