Używaj kotwic geoprzestrzennych do określania pozycji rzeczywistych treści w pakiecie Android NDK

Kotwy geoprzestrzenne to rodzaj kotwic, które umożliwiają umieszczanie treści 3D w świecie rzeczywistym.

Typy punktów odniesienia geoprzestrzennych

Istnieją 3 rodzaje punktów odniesienia geoprzestrzennego, które inaczej obsługują wysokość:

  1. Punkty kotwiczenia WGS84:
    punkty kotwiczenia WGS84 umożliwiają umieszczanie treści 3D na dowolnej szerokości geograficznej, długości geograficznej i wysokości.

  2. Punkty kotwiczenia na lądzie:
    Punkty kotwiczenia na lądzie umożliwiają umieszczanie treści tylko za pomocą szerokości i długości geograficznej z wysokością w stosunku do terenu w danym miejscu. Wysokość jest określana względem podłoża lub podłogi zgodnie z danymi VPS.

  3. Punkty kotwiczenia na dachu:
    Punkty kotwiczenia na dachu umożliwiają umieszczanie treści tylko za pomocą współrzędnych geograficznych (szerokość i długość) z wysokością względną względem dachu budynku w tej pozycji. Wysokość jest określana względem szczytu budynku zgodnie z danymi Streetscape Geometry. Domyślnie jest to wysokość terenu, jeśli obiekt nie znajduje się na budynku.

WGS84 Teren Dach
Pozycja w poziomie Szerokość geograficzna, długość geograficzna Szerokość geograficzna, długość geograficzna Szerokość geograficzna, długość geograficzna
Pozycja pionowa Względem wysokości WGS84 Względem poziomu terenu określonego przez Mapy Google Względem poziomu dachu określonego przez Mapy Google
Czy musi być rozwiązany na serwerze? Nie Tak Tak

Wymagania wstępne

Zanim przejdziesz dalej, włącz interfejs Geospatial API.

Umieszczenie kotwic geoprzestrzennych

Każdy typ kotwic ma dedykowane interfejsy API do ich tworzenia. Więcej informacji znajdziesz w artykule Typy kotwic geoprzestrzennych.

Tworzenie kotwicy na podstawie testu trafień

Możesz też utworzyć punkt odniesienia geoprzestrzennego na podstawie wyniku testu trafień. Użyj pozy z testu kolizji i przekształć ją w ArGeospatialPose. Używaj go do umieszczania dowolnego z 3 opisanych typów kotwic.

Pobieranie danych geoprzestrzennych z pozy AR

ArEarth_getGeospatialPose() zapewnia dodatkowy sposób określania szerokości i długości geograficznej przez konwersję pozy AR na pozę geoprzestrzenną.

Pobieranie pozy AR z pozy geoprzestrzennej

ArEarth_getPose() konwertuje pozycję poziomą, wysokość i rotację kwateranionową określoną przez Ziemię na ramkę współrzędnych wschód-góra-południe na pozę AR w ramach współrzędnych świata GL.

Wybierz metodę odpowiednią do Twojego zastosowania

Każda metoda tworzenia kotwicy ma związane z nią kompromisy, o których warto pamiętać:

  • Jeśli używasz geometrii ulicy, dołącz treści do budynku za pomocą testu kolizji.
  • Zamiast punktów kotwiczenia WGS84 użyj punktów kotwiczenia Teren lub Dach, ponieważ wykorzystują one wartości wysokości określone przez Mapy Google.

Określanie szerokości i długości geograficznej lokalizacji

Szerokość i długość geograficzną lokalizacji można obliczyć na 3 sposoby:

  • Korzystaj z Kreatora geoprzestrzennego, aby wyświetlać i rozszerzać świat o treści 3D bez konieczności fizycznego przemieszczania się do danej lokalizacji. Pozwala to wizualnie umieszczać w mapach Google w Edytorze Unity treści angażujące 3D. Szerokość geograficzną, długość geograficzną, obrót i wysokość treści obliczymy automatycznie.
  • Użyj Map Google
  • Użyj Google Earth. Pamiętaj, że uzyskanie tych współrzędnych za pomocą Google Earth, a nie Google Maps, spowoduje powstanie marginesu błędu wynoszącego do kilku metrów.
  • Przejdź do lokalizacji fizycznej

Użyj Map Google

Aby uzyskać współrzędne geograficzne lokalizacji w Mapach Google:

  1. Na komputerze otwórz Mapy Google.

  2. Kliknij Warstwy > Więcej.

  3. Zmień Typ mapy na Satelita i odznacz pole wyboru Widok kuli ziemskiej w lewym dolnym rogu ekranu.

    Spowoduje to wymuszenie perspektywy 2D i wyeliminuje ewentualne błędy, które mogłyby wystąpić w przypadku widoku 3D pod kątem.

  4. Na mapie kliknij lokalizację prawym przyciskiem myszy i wybierz długość i szerokość geograficzną, aby skopiować je do schowka.

Korzystanie z Google Earth

Możesz obliczyć szerokość i długość geograficzną lokalizacji w Google Earth, klikając lokalizację w interfejsie i odczytując dane z szczegółów oznaczenia miejsca.

Aby uzyskać współrzędne geograficzne lokalizacji za pomocą Google Earth:

  1. Otwórz Google Earth na komputerze stacjonarnym.

  2. Otwórz menu hamburgera  i wybierz Styl mapy.

  3. Wyłącz przełącznik Budynki 3D.

  4. Po wyłączeniu przełącznika Budynki 3D kliknij ikonę szpilki , aby dodać punkt na mapie w wybranej lokalizacji.

  5. Określ projekt, który ma zawierać oznaczenie miejsca, i kliknij Zapisz.

  6. W polu Tytuł oznaczenia miejsca wpisz nazwę oznaczenia.

  7. W panelu projektu kliknij strzałkę wstecz  i wybierz menu  Więcej działań.

  8. W menu kliknij Eksportuj jako plik KML.

Plik KLM zawiera informacje o szerokości geograficznej, długości geograficznej i wysokości znaku geograficznego w tagu <coordinates> rozdzielone przecinkami w ten sposób:

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

Nie używaj szerokości i długości geograficznej z tagów <LookAt>, które określają położenie kamery, a nie lokalizację.

Przejdź do lokalizacji fizycznej

Możesz obliczyć wysokość lokalizacji, udając się tam osobiście i wykonując obserwację lokalną.

Pobieranie kwaterniony rotacji

ArGeospatialPose_getEastUpSouthQuaternion() wyodrębnia orientację z postaci geometrycznej i wyprowadza kwadrant reprezentujący macierz obrotu, która przekształca wektor z docelowego układu współrzędnych w układ współrzędnych wschodnia-góra-północ (EUS). X+ wskazuje na wschód, Y+ na górę, a Z+ na południe. Wartości są zapisywane w kolejności {x, y, z, w}.

Punkty kotwiczenia WGS84

Kotwica WGS84 to rodzaj kotwicy, która umożliwia umieszczanie treści 3D w dowolnej szerokości, długości geograficznej i wysokości. Używa ona pozy i orientacji, aby umieścić obiekt w rzeczywistym świecie. Pozycja składa się z szerokości geograficznej, długości geograficznej i wysokości, które są określone w systemie współrzędnych WGS84. Orientacja składa się z obrotu kwateranionowego.

Wysokość jest podawana w metrach nad elipsoidem odniesienia WGS84, dzięki czemu poziom gruntu nie wynosi zero. Twoja aplikacja jest odpowiedzialna za podanie tych współrzędnych w przypadku każdej utworzonej kotwicy.

Umieszczenie punktu odniesienia WGS84 w świecie rzeczywistym

Określanie wysokości lokalizacji

Istnieje kilka sposobów na określenie wysokości lokalizacji na potrzeby umieszczania punktów kotwiczenia:

  • Jeśli lokalizacja kotwicy znajduje się fizycznie blisko użytkownika, możesz użyć wysokości podobnej do wysokości urządzenia użytkownika.
  • Po uzyskaniu współrzędnych geograficznych użyj interfejsu Elevation API, aby uzyskać wysokość na podstawie specyfikacji EGM96. Aby porównać wysokość w usługach Mapy Google z wysokością w usługach WGS84, musisz przekonwertować wysokość w usługach Mapy Google EGM96 na WGS84.ArGeospatialPose Zapoznaj się z narzędziem GeoidEval, które ma zarówno interfejs wiersza poleceń, jak i interfejs HTML. Interfejs Maps API domyślnie podaje szerokość i długość geograficzną zgodnie ze specyfikacją WGS84.
  • Szerokość geograficzną, długość geograficzną i wysokość miejsca możesz sprawdzić w Google Earth. To da Ci margines błędu do kilku metrów. W pliku KML używaj współrzędnych geograficznych i wysokości z tagów <coordinates>, nie z tagów <LookAt>.
  • Jeśli istniejąca kotwica jest w pobliżu i nie znajdujesz się na stromym zboczu, możesz użyć wysokości z ArGeospatialPose kamery bez korzystania z innego źródła, takiego jak interfejs Maps API.

Tworzenie kotwicy

Gdy masz już szerokość, długość, wysokość i kwaternion obrotu, użyj atrybutu ArEarth_acquireNewAnchor(), aby zakotwiczyć treści w określonych przez siebie współrzędnych geograficznych.

float eus_quaternion_4[4] = {qx, qy, qz, qw};
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArAnchor* earth_anchor = NULL;
    ArStatus status = ArEarth_acquireNewAnchor(ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude,
        eus_quaternion_4, &earth_anchor);

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

Kotwice do terenu

Punkt kotwiczenia terenu to rodzaj kotwicy, która umożliwia umieszczanie obiektów AR tylko za pomocą szerokości i długości geograficznej. Korzysta ona z informacji z VPS, aby określić dokładną wysokość nad poziomem morza.

Zamiast podawać żądaną wysokość, podajesz wysokość nad rzeźbą terenu. Jeśli ustawisz wartość 0, kotwica będzie na poziomie terenu.

Ustawianie trybu wyszukiwania samolotu

Wyszukiwanie samolotów jest opcjonalne i nie jest wymagane do korzystania z kotwic. Pamiętaj, że używane są tylko płaszczyzny poziome. Płaszczyzny poziome pomogą w dynamicznym dopasowywaniu punktów kotwiczenia terenu do podłoża.

Użyj opcji ArPlaneFindingMode, aby wybrać sposób wykrywania samolotów przez aplikację.

Tworzenie punktu kotwicznego terenu za pomocą nowego interfejsu API asynchronicznego

Aby utworzyć i umieścić punkt odniesienia terenu, wybierz ArEarth_resolveAnchorOnTerrainAsync().

Kotwica nie będzie gotowa od razu i musi zostać rozwiązana. Gdy problem zostanie rozwiązany, będzie dostępny w sekcji ArResolveAnchorOnTerrainFuture.

Sprawdź stan kotwicy terenu za pomocą ArResolveAnchorOnTerrainFuture_getResultTerrainAnchorState(). Użyj parametru ArResolveAnchorOnTerrainFuture_acquireResultAnchor(), aby uzyskać rozwiązany element zakotwiczenia.

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnTerrainCallback callback = NULL;
ArResolveAnchorOnTerrainFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnTerrainAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_terrain, eus_quaternion_4,
        context, callback, &future);
  }
}

Sprawdzanie stanu przyszłości

Przyszłość będzie powiązana z ArFutureState.

Stan Opis
AR_FUTURE_STATE_PENDING Operacja jest nadal w stanie oczekiwania.
AR_FUTURE_STATE_DONE Operacja została zakończona, a jej wynik jest dostępny.
AR_FUTURE_STATE_CANCELLED Operacja została anulowana.

Sprawdź stan kotwicy terenu w przyszłości.

Wartość ArTerrainAnchorState należy do operacji asynchronicznej i jest częścią końcowego wyniku Future.

switch (terrain_anchor_state) {
  case AR_TERRAIN_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_TERRAIN_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_TERRAIN_ANCHOR_STATE_ERROR_INTERNAL:
    // The Terrain anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

Kotwice dachowe

Rooftop anchors Hero

Dachowe punkty kotwiczenia to rodzaj punktu kotwiczenia i są bardzo podobne do punktów kotwiczenia na terenie. Różnica polega na tym, że podasz wysokość nad dachem, a nie nad terenem.

Tworzenie kotwicy Rooftop za pomocą nowego interfejsu API asynchronicznego

Kotwica nie będzie gotowa od razu i musi zostać rozwiązana.

Aby utworzyć i umieścić punkt kotwiczenia na dachu, wybierz ArEarth_resolveAnchorOnRooftopAsync(). Podobnie jak w przypadku punktów orientacyjnych na mapie, będziesz mieć też dostęp do ArFutureState z przyszłości. Następnie możesz sprawdzić wynik z przyszłości, aby uzyskać dostęp do ArRooftopAnchorState.

Użyj ArEarth_resolveAnchorOnRooftopAsync(), aby utworzyć ArResolveAnchorOnRooftopFuture.

Sprawdź stan kotwicy na dachu za pomocą ArResolveAnchorOnRooftopFuture_getResultRooftopAnchorState().

Użyj parametru ArResolveAnchorOnRooftopFuture_acquireResultAnchor(), aby uzyskać rozwiązany element zakotwiczenia.

float eus_quaternion_4[4] = {qx, qy, qz, qw};
void* context = NULL;
ArResolveAnchorOnRooftopCallback callback = NULL;
ArResolveAnchorOnRooftopFuture* future = NULL;
if (ar_earth != NULL) {
  ArTrackingState earth_tracking_state = AR_TRACKING_STATE_STOPPED;
  ArTrackable_getTrackingState(ar_session, (ArTrackable*)ar_earth,
                               &earth_tracking_state);
  if (earth_tracking_state == AR_TRACKING_STATE_TRACKING) {
    ArStatus status = ArEarth_resolveAnchorOnRooftopAsync(
        ar_session, ar_earth,
        /* location values */
        latitude, longitude, altitude_above_rooftop, eus_quaternion_4,
        context, callback, &future);
  }
}

Sprawdzanie stanu przyszłości

Przyszłość będzie powiązana z ArFutureState (patrz tabela powyżej).

Sprawdź stan kotwicy dachu w przyszłym wyniku

Wartość ArRooftopAnchorState należy do operacji asynchronicznej i jest częścią końcowego wyniku Future.

switch (rooftop_anchor_state) {
  case AR_ROOFTOP_ANCHOR_STATE_SUCCESS:
    // A resolving task for this anchor has been successfully resolved.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_UNSUPPORTED_LOCATION:
    // The requested anchor is in a location that isn't supported by the
    // Geospatial API.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/c/group/ar-anchor#:~:text=from%20this%20error.-,AR_ROOFTOP_ANCHOR_STATE_ERROR_NOT_AUTHORIZED,-The%20authorization%20provided
    // for troubleshooting steps.
    break;
  case AR_ROOFTOP_ANCHOR_STATE_ERROR_INTERNAL:
    // The Rooftop anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

Co dalej?