Utilizzare gli ancoraggi geospaziali per posizionare contenuti reali nell'SDK per Android (Kotlin/Java)

Gli ancoraggi geospaziali sono un tipo di ancoraggio che ti consentono di posizionare contenuti 3D nel mondo reale.

Tipi di ancore geospaziali

Esistono tre tipi di ancoraggi geospaziali, che gestiscono l'altitudine in modo diverso:

  1. Ancoraggi WGS84:
    gli ancoraggi WGS84 ti consentono di posizionare i contenuti 3D in qualsiasi latitudine, longitudine e altitudine.

  2. Ancoraggi del terreno:
    Gli ancoraggi del terreno ti consentono di posizionare i contenuti utilizzando solo la latitudine e la longitudine con un'altezza relativa al terreno in quella posizione. L'altitudine è determinata rispetto al suolo o al piano, come conosciuto dai VPS.

  3. Ancoraggie sul tetto:
    Gli ancoraggi sul tetto ti consentono di posizionare i contenuti utilizzando solo la latitudine e la longitudine con un'altezza relativa al tetto di un edificio in quella posizione. L'altitudine viene determinata in base alla sommità di un edificio, come indicato da Streetscape Geometry. Per impostazione predefinita, viene utilizzata l'altitudine del suolo se l'edificio non è presente.

WGS84 Rilievo Tetto
Posizione orizzontale Latitudine, longitudine Latitudine, longitudine Latitudine, longitudine
Posizione verticale Rispetto all'altitudine WGS84 Rispetto al livello del terreno determinato da Google Maps Rispetto al livello del tetto determinato da Google Maps
Deve essere risolto dal server? No

Prerequisiti

Prima di procedere, assicurati di abilitare l'API Geospatial.

Posiziona gli elementi di ancoraggio geospaziali

Per ogni tipo di ancora esistono API dedicate per la loro creazione. Per ulteriori informazioni, consulta la sezione Tipi di ancore geospaziali.

Creare un'ancora da un test di hit

Puoi anche creare un'ancora geospaziale da un risultato del test di corrispondenza. Utilizza la posa dall'hit-test e convertila in un GeospatialPose. Utilizzalo per inserire uno dei tre tipi di ancoraggi descritti.

Ottenere una posa geospaziale da una posa AR

Earth.getGeospatialPose() fornisce un modo aggiuntivo per determinare la latitudine e la longitudine convertendo una posa AR in una posa geospaziale.

Ottenere una posa AR da una posa geospaziale

Earth.getPose() converte una posizione orizzontale, un'altitudine e una rotazione di quaternione specificati per la Terra rispetto a un sistema di coordinate est-alto-sud in una posa AR rispetto alle coordinate mondiali GL.

Scegli il metodo più adatto al tuo caso d'uso

Ogni metodo di creazione di un'ancora ha dei compromessi da tenere presenti:

  • Quando utilizzi la geometria di Streetscape, ricorri a un test di hit per allegare contenuti a un edificio.
  • Preferisci gli ancoraggi sul tetto o sul terreno rispetto a quelli WGS84 perché utilizzano i valori di altitudine determinati da Google Maps.

Determinare la latitudine e la longitudine di una località

Esistono tre modi per calcolare la latitudine e la longitudine di una località:

  • Utilizza Geospatial Creator per visualizzare e migliorare il mondo con contenuti 3D senza doverti recare fisicamente in un luogo. In questo modo puoi posizionare visivamente contenuti immersivi 3D utilizzando Google Maps in Unity Editor. La latitudine, la longitudine, la rotazione e l'altitudine dei contenuti verranno calcolati automaticamente.
  • Utilizza Google Maps
  • Utilizzare Google Earth. Tieni presente che l'ottenimento di queste coordinate utilizzando Google Earth, anziché Google Maps, ti darà un margine di errore fino a diversi metri.
  • Vai alla sede fisica

Utilizza Google Maps

Per ottenere la latitudine e la longitudine di un luogo utilizzando Google Maps:

  1. Vai su Google Maps sul computer.

  2. Vai a Livelli > Altro.

  3. Imposta Tipo di mappa su Satellitare e deseleziona la casella di controllo Visualizzazione globo nell'angolo in basso a sinistra dello schermo.

    In questo modo verrà forzata una prospettiva 2D ed eliminati i possibili errori che potrebbero derivare da una vista 3D inclinata.

  4. Sulla mappa, fai clic con il tasto destro del mouse sulla posizione e seleziona la longitudine/latitudine per copiarla negli appunti.

Utilizzare Google Earth

Per calcolare la latitudine e la longitudine di un luogo a partire da Google Earth, fai clic su un luogo nell'interfaccia utente e leggi i dati del segnaposto.

Per ottenere la latitudine e la longitudine di una località utilizzando Google Earth:

  1. Vai su Google Earth sul computer.

  2. Vai al menu a tre linee e seleziona Stile mappa.

  3. Disattiva l'opzione Edifici in 3D.

  4. Una volta disattivata l'opzione Edifici in 3D, fai clic sull'icona a forma di puntina per aggiungere un segnaposto nella posizione selezionata.

  5. Specifica un progetto che contenga il segnaposto e fai clic su Salva.

  6. Nel campo Titolo del segnaposto, assegnagli un nome.

  7. Fai clic sulla Freccia indietro nel riquadro del progetto e seleziona il menu Altre azioni.

  8. Scegli Esporta come file KML dal menu.

Il file KLM riporta la latitudine, la longitudine e l'altitudine di un segnaposto nel tag <coordinates> separati da virgole, come segue:

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

Non utilizzare la latitudine e la longitudine dei tag <LookAt>, che specificano la posizione della videocamera, non la posizione.

Vai alla sede fisica

Puoi calcolare l'altitudine di una località andando fisicamente sul luogo e facendo un'osservazione locale.

Recupera il quaternione di rotazione

GeospatialPose.getEastUpSouthQuaternion() estrae l'orientamento da una posa geospaziale e restituisce un quaternione che rappresenta la matrice di rotazione che trasforma un vettore dal target al sistema di coordinate est-alto-sud (EUS). X+ punta a est, Y+ punta verso l'alto e Z+ punta a sud. I valori vengono scritti nell'ordine {x, y, z, w}.

Ancore WGS84

Un'ancora WGS84 è un tipo di ancora che ti consente di posizionare contenuti 3D in qualsiasi latitudine, longitudine e altitudine. Si basa su una posa e sull'orientamento per essere posizionato nel mondo reale. La posizione è costituita da latitudine, longitudine e altitudine, specificate nel sistema di coordinate WGS84. L'orientamento è costituito da una rotazione di quaternioni.

L'altitudine viene indicata in metri sopra l'ellissoide di riferimento WGS84, in modo che il livello del suolo non sia pari a zero. È responsabilità della tua app fornire queste coordinate per ogni ancora creata.

Posiziona un'ancora WGS84 nel mondo reale

Determinare l'altitudine di una località

Esistono diversi modi per determinare l'altitudine di una posizione per il posizionamento delle ancore:

  • Se la posizione dell'ancora è fisicamente vicina all'utente, puoi utilizzare un'altitudine simile a quella del dispositivo dell'utente.
  • Una volta ottenute la latitudine e la longitudine, utilizza l'API Elevation per ottenere un'elevazione in base alla specifica EGM96. Devi convertire l'elevazione EGM96 dell'API Maps in WGS84 per il confronto con l'altitudine GeospatialPose. Consulta GeoidEval, che ha sia una riga di comando che un'interfaccia HTML. L'API Maps riporta la latitudine e la longitudine in base alla specifica WGS84.
  • Puoi ottenere la latitudine, la longitudine e l'altitudine di una località da Google Earth. In questo modo otterrai un margine di errore che può arrivare fino a diversi metri. Utilizza la latitudine, la longitudine e l'altitudine dei tag <coordinates>, non dei tag <LookAt>, nel file KML.
  • Se nelle vicinanze è presente un'ancora esistente e se non ti trovi su una salita ripida, potresti essere in grado di utilizzare l'altitudine del GeospatialPose della fotocamera senza utilizzare un'altra origine, come l'API Maps.

Crea l'ancora

Una volta ottenuti la latitudine, la longitudine, l'altitudine e il quaternione di rotazione, utilizza Earth.createAnchor() per ancorare i contenuti alle coordinate geografiche specificate.

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

Ancoraggi per rilievi

Un ancoraggio al terreno è un tipo di ancoraggio che ti consente di posizionare oggetti AR utilizzando solo latitudine e longitudine, sfruttando le informazioni del VPS per trovare l'altitudine esatta sul suolo.

Anziché inserire l'altitudine desiderata, fornisci l'altitudine sopra il terreno. Se il valore è zero, l'ancora sarà a livello del suolo.

Impostare la modalità di ricerca dell'aereo

La ricerca di aerei è facoltativa e non è necessaria per utilizzare le ancore. Tieni presente che vengono utilizzati solo piani orizzontali. I piani orizzontali aiuteranno l'allineamento dinamico degli ancoraggi del terreno sul suolo.

Usa Config.PlaneFindingMode per selezionare la modalità di rilevamento degli aerei da parte dell'app.

Crea un ancoraggio Terreno con la nuova API Async

Per creare e posizionare un'ancora del terreno, chiama Earth.resolveAnchorOnTerrainAsync().

L'ancora non sarà pronta immediatamente e dovrà essere risolta. Una volta risolto, sarà disponibile in 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
      }
    }
  )

Consulta lo stato del futuro

Al futuro sarà associato un FutureState.

Stato Descrizione
FutureState.PENDING L'operazione è ancora in attesa.
FutureState.DONE L'operazione è completata e il risultato è disponibile.
FutureState.CANCELLED L'operazione è stata annullata.

Controlla lo stato dell'ancora del terreno del risultato futuro

Anchor.TerrainAnchorState appartiene all'operazione asincrona e fa parte del risultato futuro finale.

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

Ancoraggi per tetti

Eroe dei tetti ancorati

Gli ancoraggi sul tetto sono un tipo di ancoraggio e sono molto simili agli ancoraggi sul terreno sopra descritti. La differenza è che dovrai fornire l'altitudine sopra il tetto anziché l'altitudine sopra il suolo.

Creare un'ancora sul tetto utilizzando la nuova API asincrona

L'ancora non sarà pronta immediatamente e dovrà essere risolta.

Per creare e posizionare un'ancora sul tetto, chiama Earth.resolveAnchorOnRooftopAsync(). Come per gli ancoraggi Terreno, accederai anche alla FutureState del Futuro. Potrai quindi controllare il risultato futuro per accedere al 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
      }
    }
  )

Verifica lo stato del futuro

Al futuro sarà associato un elemento FutureState, vedi la tabella sopra.

Controlla lo stato dell'ancora sul tetto del risultato futuro

Anchor.RooftopAnchorState appartiene all'operazione asincrona e fa parte del risultato finale 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.
  }
}

Passaggi successivi