Utiliser des ancrages Geospatial pour positionner du contenu réel sur le SDK Android (Kotlin/Java)

Les ancrages géospatiaux sont un type d'ancre qui vous permet de placer du contenu 3D dans le monde réel.

Types d'ancrages géospatiaux

Il existe trois types d'ancrages géospatiaux, qui gèrent chacun l'altitude différemment:

  1. Ancrages WGS84:
    Les ancrages WGS84 vous permettent de placer du contenu 3D à n'importe quelle latitude, longitude et altitude.

  2. Ancrages de terrain:
    Les ancrages de terrain vous permettent de placer du contenu uniquement à l'aide de la latitude et de la longitude, avec une hauteur par rapport au terrain à cette position. L'altitude est déterminée par rapport au sol ou au plancher, comme indiqué par le VPS.

  3. Ancres de toit:
    Les ancrages de toit vous permettent de positionner du contenu en utilisant uniquement la latitude et la longitude, et une hauteur par rapport au toit d'un bâtiment à cette position. L'altitude est déterminée par rapport au sommet d'un bâtiment, comme indiqué par la géométrie du paysage urbain. La valeur par défaut est l'altitude du terrain lorsqu'elle n'est pas placée sur un bâtiment.

WGS84 Relief Toit
Position horizontale Latitude, Longitude Latitude, Longitude Latitude, Longitude
Position verticale Par rapport à l'altitude WGS84 Par rapport au niveau du terrain déterminé par Google Maps Par rapport au niveau du toit déterminé par Google Maps
Le serveur doit être résolu ? Non Oui Oui

Prérequis

Assurez-vous d'activer l'API Geospatial avant de continuer.

Placer des repères géospatiaux

Chaque type d'ancre dispose d'API dédiées permettant de les créer. Pour en savoir plus, consultez Types d'ancres géospatiales.

Créer une ancre à partir d'un test de positionnement

Vous pouvez également créer une ancre géospatiale à partir d'un résultat de test de positionnement. Utilisez la pose de l'élément détecté et convertissez-la en GeospatialPose. Utilisez-le pour placer l'un des trois types d'ancrage décrits.

Obtenir une posture géospatiale à partir d'une posture en RA

Earth.getGeospatialPose() offre un moyen supplémentaire de déterminer la latitude et la longitude en convertissant une pose AR en pose géospatiale.

Obtenir une pose RA à partir d'une pose géospatiale

Earth.getPose() convertit une position horizontale, une altitude et une rotation de quaternion spécifiées par la Terre par rapport à un repère de coordonnées est-haut-sud en position AR par rapport aux coordonnées mondiales GL.

Choisir la méthode adaptée à votre cas d'utilisation

Chaque méthode de création d'une ancre comporte des compromis à prendre en compte:

  • Lorsque vous utilisez la géométrie du paysage urbain, utilisez un test de positionnement pour associer du contenu à un bâtiment.
  • Privilégiez les repères "Terrain" ou "Toit" aux repères WGS84, car ils utilisent des valeurs d'altitude déterminées par Google Maps.

Déterminer la latitude et la longitude d'un lieu

Vous pouvez calculer la latitude et la longitude d'un lieu de trois manières:

  • Utilisez Geospatial Creator pour afficher et enrichir le monde avec du contenu 3D sans avoir à vous rendre physiquement sur un site. Vous pouvez ainsi placer visuellement du contenu immersif 3D à l'aide de Google Maps dans l'éditeur Unity. La latitude, la longitude, la rotation et l'altitude du contenu seront automatiquement calculées.
  • Utiliser Google Maps
  • Utilisez Google Earth. Notez que si vous obtenez ces coordonnées à l'aide de Google Earth, et non de Google Maps, vous obtiendrez une marge d'erreur pouvant aller jusqu'à plusieurs mètres.
  • Se rendre sur le site

Utiliser Google Maps

Pour obtenir la latitude et la longitude d'un lieu à l'aide de Google Maps:

  1. Accédez à Google Maps sur votre ordinateur de bureau.

  2. Accédez à Calques > Plus.

  3. Sélectionnez Satellite dans le champ Type de carte et décochez la case Vue Globe en bas à gauche de l'écran.

    Cela force une perspective 2D et élimine les erreurs potentielles pouvant découler d'une vue 3D angulaire.

  4. Sur la carte, effectuez un clic droit sur le lieu et sélectionnez la longitude/latitude pour la copier dans le presse-papiers.

Utiliser Google Earth

Vous pouvez calculer la latitude et la longitude d'un lieu dans Google Earth en cliquant sur un lieu dans l'interface utilisateur et en lisant les données des informations sur le repère.

Pour obtenir la latitude et la longitude d'un lieu à l'aide de Google Earth:

  1. Accédez à Google Earth sur votre ordinateur.

  2. Accédez au menu hamburger , puis sélectionnez Style de carte.

  3. Désactivez le bouton Bâtiments 3D.

  4. Une fois le bouton Bâtiments 3D désactivé, cliquez sur l'icône en forme de punaise  pour ajouter un repère à l'emplacement sélectionné.

  5. Spécifiez un projet pour contenir votre repère, puis cliquez sur Enregistrer.

  6. Dans le champ Titre du repère, saisissez un nom pour le repère.

  7. Cliquez sur la flèche de retour dans le volet du projet et sélectionnez le menu Autres actions.

  8. Sélectionnez Exporter en tant que fichier KML dans le menu.

Le fichier KLM indique la latitude, la longitude et l'altitude d'un repère dans la balise <coordinates>, séparés par des virgules, comme suit:

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

N'utilisez pas la latitude et la longitude des balises <LookAt>, qui indiquent la position de la caméra, et non l'emplacement.

Se rendre sur le site

Vous pouvez calculer l'altitude d'un lieu en vous y rendant physiquement et en effectuant une observation locale.

Obtenir le quaternion de rotation

GeospatialPose.getEastUpSouthQuaternion() extrait l'orientation d'une position géospatiale et produit un quaternion qui représente la matrice de rotation transformant un vecteur de la cible vers le système de coordonnées est-haut-sud (EUS). L'axe X+ pointe vers l'est, l'axe Y+ vers le haut et l'axe Z+ vers le sud. Les valeurs sont écrites dans l'ordre {x, y, z, w}.

Ancrages WGS84

Une ancre WGS84 est un type d'ancrage qui vous permet de placer du contenu 3D à n'importe quelle latitude, longitude et altitude. Il repose sur une posture (et une orientation) pour être placé dans le monde réel. La position comprend une latitude, une longitude et une altitude, qui sont spécifiées dans le système de coordonnées WGS84. L'orientation se compose d'une rotation quaternion.

L'altitude est indiquée en mètres au-dessus de l'ellipsoïde de référence WGS84, de sorte que le niveau du sol ne soit pas à zéro. Votre application est chargée de fournir ces coordonnées pour chaque ancre créée.

Placer une ancre WGS84 dans le monde réel

Déterminer l'altitude d'un lieu

Il existe plusieurs façons de déterminer l'altitude d'un emplacement pour placer des repères:

  • Si l'emplacement de l'ancre est physiquement proche de l'utilisateur, vous pouvez utiliser une altitude semblable à celle de l'appareil de l'utilisateur.
  • Une fois que vous avez la latitude et la longitude, utilisez l'API Elevation pour obtenir une altitude basée sur la spécification EGM96. Vous devez convertir l'altitude EGM96 de l'API Maps en WGS84 pour la comparer à l'altitude GeospatialPose. Consultez l'évaluation GeoidEval, qui dispose à la fois d'une ligne de commande et d'une interface HTML. L'API Google Maps indique la latitude et la longitude conformément aux spécifications WGS84.
  • Vous pouvez obtenir la latitude, la longitude et l'altitude d'un lieu à partir de Google Earth. Vous obtiendrez ainsi une marge d'erreur pouvant aller jusqu'à plusieurs mètres. Dans le fichier KML, utilisez la latitude, la longitude et l'altitude des balises <coordinates>, et non des balises <LookAt>.
  • Si un ancrage existant se trouve à proximité et si vous n'êtes pas sur une pente raide, vous pouvez peut-être utiliser l'altitude de l'GeospatialPose de la caméra sans utiliser une autre source, telle que l'API Maps.

Créer l'ancre

Une fois que vous avez la latitude, la longitude, l'altitude et le quaternion de rotation, utilisez Earth.createAnchor() pour ancrer le contenu aux coordonnées géographiques que vous spécifiez.

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.
}

Ancrages de terrain

Un ancrage de terrain est un type d'ancrage qui vous permet de placer des objets RA à l'aide de la latitude et de la longitude uniquement, en utilisant les informations de la VPS pour déterminer l'altitude exacte au-dessus du sol.

Au lieu d'indiquer l'altitude souhaitée, vous indiquez l'altitude au-dessus du relief. Lorsque cette valeur est égale à zéro, l'ancre est au même niveau que le relief.

Définir le mode de recherche d'avion

La recherche de plan est facultative et n'est pas nécessaire pour utiliser des ancrages. Notez que seuls les plans horizontaux sont utilisés. Les plans horizontaux facilitent l'alignement dynamique des ancrages de terrain au sol.

Utilisez Config.PlaneFindingMode pour sélectionner la façon dont votre application détecte les avions.

Créer une ancre de relief à l'aide de la nouvelle API Async

Pour créer et placer un ancrage de terrain, appelez Earth.resolveAnchorOnTerrainAsync().

L'ancre ne sera pas prête immédiatement et doit être résolue. Une fois le problème résolu, il sera disponible dans ResolveAnchorOnTerrainFuture.

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
      }
    }
  )

Consulter l'état de l'avenir

L'objet Future est associé à un FutureState.

État Description
FutureState.PENDING L'opération est toujours en attente.
FutureState.DONE L'opération est terminée et le résultat est disponible.
FutureState.CANCELLED L'opération a été annulée.

Vérifier l'état de l'ancrage de terrain du résultat futur

Anchor.TerrainAnchorState appartient à l'opération asynchrone et fait partie du résultat final de Future.

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.
  }
}

Points d'ancrage sur le toit

Hero Rooftop anchors

Les ancrages sur le toit sont un type d'ancrage et sont très semblables aux ancrages sur le terrain ci-dessus. La différence est que vous indiquerez l'altitude au-dessus du toit plutôt que l'altitude au-dessus du terrain.

Créer un repère sur le toit à l'aide de la nouvelle API Async

L'ancre ne sera pas prête immédiatement et doit être résolue.

Pour créer et placer un ancrage sur le toit, appelez Earth.resolveAnchorOnRooftopAsync(). Comme pour les ancrages de terrain, vous aurez également accès à FutureState de l'avenir. Vous pouvez ensuite vérifier le résultat futur pour accéder à Anchor.RooftopAnchorState.

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
      }
    }
  )

Consulter l'état de l'avenir

L'avenir est associé à un FutureState, consultez le tableau ci-dessus.

Vérifier l'état de l'ancrage "Toit" du résultat "Future"

Anchor.RooftopAnchorState appartient à l'opération asynchrone et fait partie du résultat final de Future.

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.
  }
}

Étape suivante