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

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

Tipi di ancoraggi geospaziali

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

  1. Ancoraggi WGS84:
    Gli ancoraggi WGS84 ti consentono di posizionare contenuti 3D a qualsiasi latitudine, longitudine e altitudine.

  2. Ancoraggi al terreno:
    Gli ancoraggi dei rilievi ti consentono di inserire contenuti utilizzando solo latitudine e e longitudine con un'altezza relativa al terreno in quella posizione. L'altitudine è determinata in relazione al suolo o al piano come indicato di VPS.

  3. Ancoraggi sul tetto:
    Gli ancoraggi sui tetti ti consentono di inserire contenuti utilizzando solo latitudine e longitudine con un'altezza relativa al tetto di un edificio in quella posizione. L'altitudine è determinata in relazione alla cima di un edificio, come noto Streetscape Geometry. Se non posizionato su un edificio, viene utilizzata per impostazione predefinita l'altitudine del terreno.

WGS84 Rilievo Da tetto auto
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 risolta dal server? No

Prerequisiti

Assicurati di abilitare l'API Geospatial prima di procedere.

Posiziona ancoraggi geospaziali

Ogni tipo di ancoraggio ha API dedicate per crearli; consulta Tipi di ancoraggi geospaziali per ulteriori informazioni.

Creare un ancoraggio da un hit test

Puoi anche creare un ancoraggio geospaziale da un risultato hit-test. Usa la posa dell'hit test e convertila in una GeospatialPose. Usala per posizionare uno dei 3 tipi di ancoraggio descritti.

Ottieni una posizione geospaziale da una posizione AR

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

Ottieni una posizione AR da una posizione geospaziale

Earth.getPose() converte una rotazione di posizione orizzontale, altitudine e quaternione specificate dalla Terra rispetto a un frame di coordinate est-alto-sud in una posizione AR rispetto alla coordinata globale del GL.

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

A ogni metodo di creazione di un ancoraggio sono associati dei compromessi da tenere presenti:

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

Determinare la latitudine e la longitudine di un luogo

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

  • Utilizza Geospatial Creator per visualizzare e ampliare il mondo con contenuti 3D senza dover recarti fisicamente in una località. In questo modo puoi posizionare visivamente contenuti 3D immersivi utilizzando Google Maps nell'editor Unity. La latitudine, la longitudine, la rotazione e l'altitudine dei contenuti verranno calcolati automaticamente.
  • Utilizza Google Maps
  • Utilizzare Google Earth. Tieni presente che il recupero delle coordinate utilizzando Google Earth, invece che Google Maps, ti consente di ottenere un margine di errore anche di alcuni metri.
  • Vai al luogo fisico

Utilizza Google Maps

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

  1. Accedi a Google Maps sul tuo computer.

  2. Vai a Livelli > Altro.

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

    In questo modo viene forzata la prospettiva 2D ed elimina i possibili errori che potrebbero derivare da una visualizzazione 3D inclinata.

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

Utilizza 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 un luogo utilizzando Google Earth:

  1. Apri Google Earth sul tuo 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 segnala la latitudine, la longitudine e l'altitudine di un segnaposto nel tag <coordinates> separate da virgole, come segue:

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

Non utilizzare i valori di latitudine e longitudine dei tag <LookAt>, che specificano la posizione della fotocamera, non la posizione.

Vai al luogo fisico

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

Ottieni il quaternione di rotazione

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

Ancoraggi WGS84

Un ancoraggio WGS84 è un tipo di ancoraggio che consente di posizionare contenuti 3D a qualsiasi latitudine, longitudine e altitudine specificate. Si basa su una posa e un orientamento per essere collocato nel mondo reale. La posizione è composta dai valori di latitudine, longitudine e altitudine, specificati nel sistema di coordinate WGS84. L'orientamento consiste in una rotazione del quaternione.

L'altitudine è indicata in metri sopra l'ellissoide WGS84 di riferimento, in modo che il livello del suolo non sia pari a zero. La tua app è responsabile di fornire queste coordinate per ogni ancoraggio creato.

Posiziona un ancoraggio WGS84 nel mondo reale

Determinare l'altitudine di un luogo

Esistono diversi modi per determinare l'altitudine di una posizione per posizionare gli ancoraggi:

  • Se la posizione dell'ancoraggio è fisicamente vicino all'utente, puoi utilizzare un'altitudine simile a quella del dispositivo dell'utente.
  • Una volta indicate la latitudine e la longitudine, utilizza l'API Elevation per ottenere un'altitudine in base alla specifica EGM96. Devi convertire l'elevazione EGM96 dell'API di Google Maps in WGS84 per il confronto con l'altitudine di GeospatialPose. Vedi il documento GeoidEval che presenta sia una riga di comando sia un'interfaccia HTML. L'API di Google Maps registra latitudine e longitudine in base alla specifica WGS84 senza bisogno di ulteriori configurazioni.
  • Puoi ottenere la latitudine, la longitudine e l'altitudine di una località da Google Earth. In questo modo otterrai un margine di errore fino a diversi metri. Utilizza nel file KML la latitudine, la longitudine e l'altitudine dei tag <coordinates>, non dei tag <LookAt>.
  • Se un ancoraggio esistente è nelle vicinanze e se non sei su una pendenza ripida, potresti essere in grado di utilizzare l'altitudine della videocamera GeospatialPose senza ricorrere a un'altra sorgente, ad esempio l'API di Google Maps.

Crea l'ancoraggio

Una volta ottenuti i valori di latitudine, longitudine, altitudine e quaternione di rotazione, utilizza Earth.createAnchor() per ancorare i contenuti alle coordinate geografiche da te 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.

Invece di inserire l'altitudine desiderata, devi specificare l'altitudine sopra il livello del terreno. Quando questo valore è pari a zero, l'ancoraggio sarà alla stessa altezza del terreno.

Impostare la modalità di ricerca dei piani

Il rilevamento del piano è facoltativo e non è obbligatorio per utilizzare gli ancoraggi. 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 ancoraggio del terreno, chiama Earth.resolveAnchorOnTerrainAsync().

L'ancoraggio non sarà pronto immediatamente e deve essere risolto. Una volta risolto, sarà disponibile nel 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
      }
    }
  )

Verifica lo stato del futuro

Al futuro sarà associato un elemento FutureState.

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

Controllare lo stato di ancoraggio 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 ai tetti sono un tipo di ancoraggio e sono molto simili agli ancoraggi a terra di cui sopra. La differenza è che verrà indicata l'altitudine sopra il tetto piuttosto che l'altitudine sopra il livello del terreno.

Crea un ancoraggio sul tetto utilizzando la nuova API Async

L'ancoraggio non sarà pronto immediatamente e deve essere risolto.

Per creare e posizionare un ancoraggio sul tetto, chiama Earth.resolveAnchorOnRooftopAsync(). Come per gli ancoraggi del 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.

Controllare lo stato dell'ancoraggio sul tetto del risultato Futuro

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

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