Geospatiale Anchors verwenden, um reale Inhalte im Android SDK (Kotlin/Java) zu positionieren

Raumbezogene Anker sind eine Art Anker, mit dem Sie 3D-Inhalte in der realen Welt platzieren können.

Arten von raumbezogenen Ankern

Es gibt drei Arten von raumbezogenen Ankern, die die Höhen jeweils unterschiedlich verarbeiten:

  1. WGS84-Anker:
    Mit WGS84-Ankern können Sie 3D-Content an einem beliebigen Breitengrad, Längengrad und Höhe.

  2. Geländeanker:
    Mit Geländeankern können Sie Inhalte nur mithilfe von Breiten- und Längengrad mit einer Höhe relativ zum Gelände an dieser Position. Die Höhe wird relativ zum Boden bestimmt, von VPS.

  3. Dübel:
    Mit Dachankern können Sie Inhalte nur mithilfe von Breiten- und Längengrad mit einer Höhe relativ zum Dach eines Gebäudes an dieser Position. Die Höhe wird relativ zur Spitze eines Gebäudes von Streetscape Geometry. Wird diese Option nicht auf einem Gebäude platziert, wird standardmäßig die Geländehöhe verwendet.

WGS84 Gelände Dach
Horizontale Position Breitengrad, Längengrad Breitengrad, Längengrad Breitengrad, Längengrad
Vertikale Position Relativ zur WGS84-Höhe Relativ zur von Google Maps ermittelten Geländeebene Relativ zur Dachhöhe (von Google Maps festgelegt)
Muss vom Server behoben werden? Nein Ja Ja

Vorbereitung

Aktivieren Sie die Geospatial API, bevor Sie fortfahren.

Raumbezogene Anker platzieren

Für jeden Ankertyp gibt es eigene APIs. Weitere Informationen finden Sie unter Arten von raumbezogenen Ankern.

Anker aus einem Treffertest erstellen

Sie können einen raumbezogenen Anker auch aus einem Treffertestergebnis erstellen. Verwende die Pose aus dem Treffertest und konvertiere sie in einen GeospatialPose. Damit können Sie einen der drei beschriebenen Ankertypen platzieren.

Raumbezogene Pose aus AR-Positionen erstellen

Earth.getGeospatialPose() bietet eine weitere Möglichkeit, Breiten- und Längengrad zu bestimmen, indem eine AR-Position in eine raumbezogene Pose umgewandelt wird.

AR-Stellung aus einer raumbezogenen Pose erstellen

Earth.getPose() wandelt eine von der Erde angegebene horizontale Position, Höhe und Quaternionrotation in Bezug auf einen Ost-auf-Süd-Koordinaten-Frame in eine AR-Position in Bezug auf die GL-Weltkoordinaten um.

Passende Methode für Ihren Anwendungsfall auswählen

Jede Methode zum Erstellen eines Ankers hat bestimmte Vor- und Nachteile:

  • Wenn Sie Streetscape-Geometrie verwenden: einen Treffertest verwenden, um einem Gebäude Inhalte hinzuzufügen.
  • Sie sollten Gelände- oder Dachanker gegenüber WGS84-Ankern vorziehen, da sie von Google Maps festgelegte Höhenwerte verwenden.

Längen- und Breitengrad eines Standorts ermitteln

Es gibt drei Möglichkeiten, den Längen- und Breitengrad eines Standorts zu berechnen:

  • Mit dem Geospatial Creator kannst du die Welt mit 3D-Inhalten erweitern, ohne dich persönlich vor Ort aufsuchen zu müssen. So können Sie immersive 3D-Inhalte mithilfe von Google Maps-Karten im Unity-Editor visuell platzieren. Breiten- und Längengrad, Drehung und Höhe des Inhalts werden automatisch für Sie berechnet.
  • Google Maps verwenden
  • Verwenden Sie Google Earth. Beachten Sie, dass Sie, wenn Sie diese Koordinaten in Google Earth statt in Google Maps abrufen, eine Fehlerspanne von bis zu mehreren Metern erhalten.
  • Begib dich zum physischen Standort

Google Maps verwenden

So rufen Sie den Längen- und Breitengrad eines Standorts in Google Maps ab:

  1. Rufen Sie Google Maps auf Ihrem Desktop-Computer auf.

  2. Gehen Sie zu Ebenen > Mehr.

  3. Ändern Sie den Kartentyp zu Satellit und deaktivieren Sie links unten auf dem Bildschirm das Kästchen Globusansicht.

    Dadurch wird eine 2D-Perspektive erzwungen und mögliche Fehler vermieden, die aus einer schrägen 3D-Ansicht entstehen könnten.

  4. Klicken Sie auf der Karte mit der rechten Maustaste auf den Ort und wählen Sie Längen- und Breitengrad aus, um ihn in die Zwischenablage zu kopieren.

Google Earth verwenden

Sie können den Längen- und Breitengrad eines Ortes in Google Earth berechnen, indem Sie in der Benutzeroberfläche auf einen Ort klicken und die Daten der Ortsmarkierungsdetails auslesen.

So rufen Sie den Längen- und Breitengrad eines Ortes in Google Earth ab:

  1. Rufen Sie auf Ihrem Computer Google Earth auf.

  2. Gehen Sie zum Dreistrich-Menü und wählen Sie Kartenstil aus.

  3. Deaktivieren Sie den Schalter 3D-Gebäude.

  4. Deaktivieren Sie den Schalter 3D-Gebäude und klicken Sie auf das Stecknadelsymbol , um eine Ortsmarkierung für den ausgewählten Ort hinzuzufügen.

  5. Geben Sie ein Projekt für die Ortsmarkierung an und klicken Sie auf Speichern.

  6. Geben Sie im Feld Titel für die Ortsmarkierung einen Namen ein.

  7. Klicken Sie im Projektbereich auf den Zurückpfeil und wählen Sie das Menü Weitere Aktionen aus.

  8. Wählen Sie im Menü Als KML-Datei exportieren aus.

In der KLM-Datei werden Breiten-, Längengrad und Höhe für eine Ortsmarkierung im <coordinates>-Tag wie folgt getrennt durch Kommas angegeben:

<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>

Verwenden Sie nicht den Breiten- und Längengrad aus den <LookAt>-Tags, da diese die Kameraposition und nicht den Standort angeben.

Begib dich zum physischen Standort

Sie können die Höhe eines Orts berechnen, indem Sie eine physische Beobachtung machen und eine lokale Beobachtung machen.

Rotationsquaternion abrufen

GeospatialPose.getEastUpSouthQuaternion() extrahiert die Ausrichtung aus einer raumbezogenen Position und gibt eine Quaternion aus, die die Rotationsmatrix darstellt, die einen Vektor vom Ziel in das Ost-auf-Süd-Koordinatensystem (EUS) umwandelt. X+ zeigt nach Osten, Y+ zeigt nach oben und Z+ zeigt nach Süden. Werte werden in der Reihenfolge {x, y, z, w} geschrieben.

WGS84-Anker

Ein WGS84-Ankertyp ist eine Art Anker, mit dem Sie 3D-Inhalte an einem beliebigen Breiten-, Längengrad und in der Höhe platzieren können. Es erfordert eine Haltung und Ausrichtung, um in der realen Welt platziert zu werden. Die Position besteht aus Breiten-, Längengrad und Höhe, die im WGS84-Koordinatensystem angegeben werden. Die Ausrichtung besteht aus einer Quaternionrotation.

Die Höhe wird in Metern über der WGS84-Referenzellipsoid angegeben, sodass die Bodenhöhe nicht bei null liegt. Ihre App ist für die Bereitstellung dieser Koordinaten für jeden erstellten Anker verantwortlich.

Platziere einen WGS84-Anker in der realen Welt

Höhe eines Standorts bestimmen

Es gibt mehrere Möglichkeiten, die Höhe eines Standorts zum Platzieren von Ankern zu bestimmen:

  • Befindet sich der Anker physisch in der Nähe des Nutzers, können Sie eine Höhe verwenden, die der Höhe des Nutzergeräts entspricht.
  • Sobald Sie den Breiten- und Längengrad haben, können Sie mit der Elevation API eine Höhe auf Grundlage der EGM96-Spezifikation abrufen. Die Höhe des Maps API-EGM96 muss in WGS84 konvertiert werden, damit sie mit der Höhe GeospatialPose verglichen werden kann. Sehen Sie sich die Anleitung GeoidEval an, die sowohl über eine Befehlszeile als auch über eine HTML-Schnittstelle verfügt. Die Google Maps API meldet automatisch Breiten- und Längengrade gemäß der WGS84-Spezifikation.
  • Die Breiten- und Längengrade sowie die Höhe eines Ortes können Sie in Google Earth abrufen. Dadurch erhalten Sie einen Fehlerbereich von bis zu mehreren Metern. Verwenden Sie in der KML-Datei die Werte für Breiten-, Längengrad und Höhe aus den <coordinates>-Tags, nicht aus den <LookAt>-Tags.
  • Wenn sich ein vorhandener Anker in der Nähe befindet und nicht auf einer steilen Steigung, können Sie die Höhe der Kamera GeospatialPose ohne eine andere Quelle, z. B. die Maps API, verwenden.

Anker erstellen

Sobald Sie Breiten-, Längengrad, Höhe und Quaternion der Drehung ermittelt haben, verwenden Sie Earth.createAnchor(). , um Inhalte an den von Ihnen angegebenen geografischen Koordinaten zu verankern.

Java

if (earth != null && earth.getTrackingState() == TrackingState.TRACKING) {
  Anchor anchor =
    earth.createAnchor(
      /* Location values */
      latitude,
      longitude,
      altitude,
      /* Rotational pose values */
      qx,
      qy,
      qz,
      qw);

  // Attach content to the anchor specified by geodetic location and pose.
}

Kotlin

if (earth.trackingState == TrackingState.TRACKING) {
  val anchor =
    earth.createAnchor(
      /* Location values */
      latitude,
      longitude,
      altitude,
      /* Rotational pose values */
      qx,
      qy,
      qz,
      qw
    )

  // Attach content to the anchor specified by geodetic location and pose.
}

Geländeanker

Ein Geländeanker ist eine Art Anker, mit dem Sie AR-Objekte nur anhand des Breiten- und Längengrads platzieren können. Dabei werden Informationen von VPS genutzt, um die genaue Höhe über dem Boden zu bestimmen.

Anstelle der gewünschten Höhe geben Sie die Höhe über dem Gelände an. Wenn dieser Wert null ist, wird der Anker eben mit dem Gelände ausgerichtet.

Flugsuchmodus festlegen

Die Ebenensuche ist optional und für die Verwendung von Ankern nicht erforderlich. Beachten Sie, dass nur horizontale Ebenen verwendet werden. Horizontale Ebenen erleichtern die dynamische Ausrichtung von Geländeankern am Boden.

Mit Config.PlaneFindingMode können Sie festlegen, wie Ihre App Flugzeuge erkennt.

Geländeanker mit der neuen Async API erstellen

Rufen Sie zum Erstellen und Platzieren eines Geländeankers Earth.resolveAnchorOnTerrainAsync() auf.

Der Anker ist nicht sofort bereit und muss aufgelöst werden. Sobald das Problem behoben ist, ist es in der ResolveAnchorOnTerrainFuture verfügbar.

Java

final ResolveAnchorOnTerrainFuture future =
  earth.resolveAnchorOnTerrainAsync(
    latitude,
    longitude,
    /* altitudeAboveTerrain= */ 0.0f,
    qx,
    qy,
    qz,
    qw,
    (anchor, state) -> {
      if (state == TerrainAnchorState.SUCCESS) {
        // do something with the anchor here
      } else {
        // the anchor failed to resolve
      }
    });

Kotlin

var future =
  earth.resolveAnchorOnTerrainAsync(
    latitude,
    longitude,
    altitudeAboveTerrain,
    qx,
    qy,
    qz,
    qw,
    { anchor, state ->
      if (state == TerrainAnchorState.SUCCESS) {
        // do something with the anchor here
      } else {
        // the anchor failed to resolve
      }
    }
  )

Den Stand der Zukunft prüfen

Das Future hat ein verknüpftes FutureState.

Status Beschreibung
FutureState.PENDING Der Vorgang steht noch aus.
FutureState.DONE Der Vorgang ist abgeschlossen und das Ergebnis ist verfügbar.
FutureState.CANCELLED Der Vorgang wurde abgebrochen.

Ankerstatus „Gelände“ des Ergebnisses „Future“ prüfen

Anchor.TerrainAnchorState gehört zum asynchronen Vorgang und ist Teil des endgültigen Future-Ergebnisses.

Java

switch (terrainAnchorState) {
  case SUCCESS:
    // A resolving task for this Terrain anchor has finished successfully.
    break;
  case ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the Geospatial API.
    break;
  case ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/java/com/google/ar/core/Anchor.TerrainAnchorState#error_not_authorized
    // for troubleshooting steps.
    break;
  case ERROR_INTERNAL:
    // The Terrain anchor could not be resolved due to an internal error.
    break;
  default:
    // not reachable
    break;
}

Kotlin

when (state) {
  TerrainAnchorState.SUCCESS -> {
    // A resolving task for this Terrain anchor has finished successfully.
  }
  TerrainAnchorState.ERROR_UNSUPPORTED_LOCATION -> {
    // The requested anchor is in a location that isn't supported by the Geospatial API.
  }
  TerrainAnchorState.ERROR_NOT_AUTHORIZED -> {
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/java/com/google/ar/core/Anchor.TerrainAnchorState#error_not_authorized
    // for troubleshooting steps.
  }
  TerrainAnchorState.ERROR_INTERNAL -> {
    // The Terrain anchor could not be resolved due to an internal error.
  }
  else -> {
    // Default.
  }
}

Dachdübel

Hero-Image für Dachanker

Dachdübel sind eine Art Anker und sind den Geländedübeln oben sehr ähnlich. Der Unterschied besteht darin, dass Sie die Höhe über dem Dach und nicht die Höhe über dem Gelände angeben.

Dachanker mit der neuen Async API erstellen

Der Anker ist nicht sofort bereit und muss aufgelöst werden.

Rufen Sie Earth.resolveAnchorOnRooftopAsync() auf, um einen Dachanker zu erstellen und zu platzieren. Ähnlich wie bei Geländeankern greifen Sie auch auf FutureState der Zukunft zu. Anschließend können Sie das Future-Ergebnis prüfen, um auf Anchor.RooftopAnchorState zuzugreifen.

Java

final ResolveAnchorOnRooftopFuture future =
  earth.resolveAnchorOnRooftopAsync(
    latitude,
    longitude,
    /* altitudeAboveRooftop= */ 0.0f,
    qx,
    qy,
    qz,
    qw,
    (anchor, state) -> {
      if (state == RooftopAnchorState.SUCCESS) {
        // do something with the anchor here
      } else {
        // the anchor failed to resolve
      }
    });

Kotlin

var future =
  earth.resolveAnchorOnRooftopAsync(
    latitude,
    longitude,
    altitudeAboveRooftop,
    qx,
    qy,
    qz,
    qw,
    { anchor, state ->
      if (state == RooftopAnchorState.SUCCESS) {
        // do something with the anchor here
      } else {
        // the anchor failed to resolve
      }
    }
  )

Den Stand der Zukunft prüfen

Das Future hat ein verknüpftes FutureState (siehe Tabelle oben).

Ankerstatus „Dach“ des Ergebnisses „Future“ prüfen

Anchor.RooftopAnchorState gehört zum asynchronen Vorgang und ist Teil des endgültigen Future-Ergebnisses.

Java

switch (rooftopAnchorState) {
  case SUCCESS:
    // A resolving task for this Rooftop anchor has finished successfully.
    break;
  case ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the Geospatial API.
    break;
  case ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API.
    // https://developers.google.com/ar/reference/java/com/google/ar/core/Anchor.RooftopAnchorState#error_not_authorized
    // for troubleshooting steps.
    break;
  case ERROR_INTERNAL:
    // The Rooftop anchor could not be resolved due to an internal error.
    break;
  default:
    // not reachable
    break;
}

Kotlin

when (state) {
  RooftopAnchorState.SUCCESS -> {
    // A resolving task for this Rooftop anchor has finished successfully.
  }
  RooftopAnchorState.ERROR_UNSUPPORTED_LOCATION -> {
    // The requested anchor is in a location that isn't supported by the Geospatial API.
  }
  RooftopAnchorState.ERROR_NOT_AUTHORIZED -> {
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/java/com/google/ar/core/Anchor.RooftopAnchorState#error_not_authorized
    // for troubleshooting steps.
  }
  RooftopAnchorState.ERROR_INTERNAL -> {
    // The Rooftop anchor could not be resolved due to an internal error.
  }
  else -> {
    // Default.
  }
}

Nächste Schritte