Usar âncoras geoespaciais para posicionar conteúdo real no iOS

As âncoras geoespaciais são um tipo de âncora que permite colocar conteúdo 3D no mundo real.

Tipos de âncoras geoespaciais

Há três tipos de âncoras geoespaciais, e cada uma delas processa a altitude de maneira diferente:

  1. Âncoras WGS84:
    Com as âncoras WGS84, é possível posicionar conteúdo 3D em qualquer latitude, longitude e altitude.

  2. Âncoras de terreno:
    Com as âncoras de terreno, você pode inserir conteúdo usando apenas latitude e longitude, com uma altura relativa ao terreno nessa posição. A altitude é determinada em relação ao solo ou ao andar, como conhecido pelo VPS.

  3. Âncoras de telhado:
    Com elas, você pode posicionar conteúdo usando apenas latitude e longitude, com uma altura relativa ao telhado de um edifício nessa posição. A altitude é determinada em relação ao topo de um edifício, conforme conhecido pela Geometria da paisagem urbana. O padrão será a altitude do terreno quando não estiver em uma construção.

WGS84 Terreno Telhado
Posição horizontal Latitude, longitude Latitude, longitude Latitude, longitude
Posição vertical Relativa à altitude WGS84 Relativo ao nível do terreno determinado pelo Google Maps Relativo ao nível do terraço determinado pelo Google Maps
Precisa ser resolvida pelo servidor? Não Sim Sim

Pré-requisitos

Antes de continuar, ative a API Geospatial.

Colocar âncoras geoespaciais

Cada tipo de âncora tem APIs dedicadas para isso. Consulte Tipos de âncoras geoespaciais para saber mais.

Criar uma âncora com base em um teste de hit

Também é possível criar uma âncora geoespacial usando um resultado do teste de hit. Use a transformação do teste de hit e a converta em um GARGeospatialTransform. Use-a para colocar qualquer um dos três tipos de âncora descritos.

Receber uma transformação geoespacial em uma transformação RA

O GARSession.geospatialTransformFromTransform:error: oferece outra maneira de determinar a latitude e a longitude convertendo uma transformação AR em geoespacial.

Extrair uma transformação RA com uma transformação geoespacial

GARSession.transformFromGeospatialCoordinate:altitude:eastUpSouthQTarget:error: converte uma posição horizontal, altitude e rotação de quatérnio especificadas pela Terra em relação a um frame de coordenadas leste-para-sul em uma transformação AR em relação à coordenada mundial GL.

Escolha o método mais adequado ao seu caso de uso

Cada método de criação de uma âncora tem vantagens e desvantagens associadas a serem lembradas:

  • Ao usar a Geometria da paisagem urbana, utilize um teste de hit para anexar conteúdo a um edifício.
  • Prefere as âncoras para terreno ou telhado em vez das âncoras WGS84 porque elas usam valores de altitude determinados pelo Google Maps.

Determinar a latitude e longitude de um local

Há três maneiras de calcular a latitude e longitude de um local:

  • Use o Geospatial Creator para visualizar e ampliar o mundo com conteúdo 3D sem ter que ir fisicamente a um local. Isso permite posicionar conteúdo imersivo em 3D visualmente usando o Google Maps no Editor do Unity. A latitude, longitude, rotação e altitude do conteúdo serão calculadas automaticamente.
  • Usar o Google Maps
  • Usar o Google Earth. A obtenção dessas coordenadas usando o Google Earth, e não o Google Maps, gera uma margem de erro de até vários metros.
  • Acessar o local físico

Usar o Google Maps

Para conferir a latitude e a longitude de um local usando o Google Maps:

  1. Acesse o Google Maps no seu computador.

  2. Navegue até Camadas > Mais.

  3. Mude o Tipo de mapa para Satélite e desmarque a caixa de seleção Visualização de globo no canto inferior esquerdo da tela.

    Isso força uma perspectiva 2D e elimina possíveis erros que podem ocorrer com a visualização em 3D inclinada.

  4. No mapa, clique com o botão direito do mouse no local e selecione a longitude/latitude para copiá-lo para a área de transferência.

Usar o Google Earth

Para calcular a latitude e a longitude de um local no Google Earth, clique nele na interface e leia os dados dos detalhes do marcador.

Para conferir a latitude e a longitude de um local usando o Google Earth:

  1. Acesse o Google Earth no seu computador desktop.

  2. Navegue até o menu de navegação e selecione Estilo do mapa.

  3. Desative a opção Construções em 3D.

  4. Quando a chave Construções em 3D estiver desativada, clique no ícone de alfinete para adicionar um marcador de local no local selecionado.

  5. Especifique um projeto para conter seu marcador de local e clique em Salvar.

  6. No campo Título do marcador de local, insira um nome para ele.

  7. Clique na seta para voltar no painel do projeto e selecione o menu More Actions.

  8. Escolha Exportar como arquivo KML no menu.

O arquivo KLM informa a latitude, a longitude e a altitude de um marcador na tag <coordinates>, separados por vírgulas, da seguinte forma:

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

Não use a latitude e a longitude das tags <LookAt>, que especificam a posição da câmera, não o local.

Acessar o local físico

Para calcular a altitude de um local, faça uma observação local nele.

Acessar o quatérnio de rotação

GARGeospatialTransform.eastUpSouthQTarget extrai a orientação de uma transformação geoespacial e gera um quatérnio que representa a matriz de rotação que transforma um vetor do sistema de coordenadas leste-up-sul (EUS, na sigla em inglês). X+ aponta para o leste, Y+ aponta para cima e Z+ aponta para o sul. Os valores são gravados na ordem {x, y, z, w}.

Âncoras WGS84

Uma âncora WGS84 é um tipo de âncora que permite colocar conteúdo 3D em qualquer latitude, longitude e altitude. Ela depende de uma Transformação e da orientação para ser colocada no mundo real. A posição consiste em latitude, longitude e altitude, especificadas no sistema de coordenadas WGS84. A orientação consiste em uma rotação de quatérnio.

A altitude é informada em metros acima do elipsoide WGS84 de referência, de modo que o nível do solo não seja zero. Seu app é responsável por fornecer essas coordenadas para cada âncora criada.

Coloque uma âncora WGS84 no mundo real

Determinar a altitude de um local

Existem algumas maneiras de determinar a altitude de um local para colocar âncoras:

  • Se o local da âncora estiver fisicamente perto do usuário, você poderá usar uma altitude semelhante à do dispositivo.
  • Quando você tiver a latitude e a longitude, use a API Elevation para conferir uma elevação com base na especificação EGM96 (link em inglês). Você precisa converter a elevação EGM96 da API Maps em WGS84 para comparação com a altitude GARGeospatialTransform. Consulte GeoidEval que tem uma linha de comando e uma interface HTML. A API do Google Maps informa a latitude e a longitude de acordo com a especificação WGS84 pronta para uso.
  • Você pode conferir essas informações de um local no Google Earth. Isso gera uma margem de erro de até vários metros. Use a latitude, a longitude e a altitude das tags <coordinates>, não das tags <LookAt>, no arquivo KML.
  • Se uma âncora existente estiver por perto e se você não estiver em uma subida íngreme, poderá usar a altitude do GARGeospatialTransform da câmera sem usar outra fonte, como a API Maps.

Criar a âncora

Depois de definir a latitude, a longitude, a altitude e o quatérnio de rotação, use createAnchorWithCoordinate:altitude:eastUpSouthQAnchor:error: para fixar o conteúdo nas coordenadas geográficas especificadas.

  NSError *error = nil;
  GARAnchor *anchor = [self.garSession createAnchorWithCoordinate:coordinate
                                                         altitude:altitude
                                               eastUpSouthQAnchor:eastUpSouthQAnchor
                                                            error:&error];

Âncoras de terreno

Uma âncora de terreno é um tipo de fixação que permite posicionar objetos de RA usando apenas latitude e longitude, aproveitando as informações do VPS para descobrir a altitude exata acima do solo.

Em vez de inserir a altitude desejada, você fornece a altitude acima do terreno. Quando esse valor for zero, a âncora estará nivelada com o terreno.

Definir o modo de descoberta de avião

A descoberta de planos é opcional e não é necessária para usar âncoras. Apenas planos horizontais são usados. Planos horizontais ajudam no alinhamento dinâmico das âncoras do terreno no solo.

Use ARWorldTrackingConfiguration.PlaneDetection para selecionar como o app detecta planos.

Criar uma âncora de terreno usando a nova API Async

Para criar e posicionar uma âncora de terreno, chame GARSession.createAnchorWithCoordinate:altitudeAboveTerrain:eastUpSouthQAnchor:completionHandler:error:.

A âncora não estará pronta imediatamente e precisa ser resolvida. Assim que o problema for resolvido, ele vai estar disponível no GARCreateAnchorOnTerrainFuture.

GARCreateAnchorOnTerrainFuture *future = [self.garSession createAnchorWithCoordinate:coordinate
                                                                altitudeAboveTerrain:altitude
                                                                  eastUpSouthQAnchor:eastUpSouthQTarget
                                                                   completionHandler:^(GARAnchor *anchor, GARTerrainAnchorState state) {
                                                                     // handle completion
                                                                   }
                                                                               error:&error];

Verificação do estado do futuro

O Future terá um GARFutureState associado.

Estado Descrição
GARFutureStatePending A operação ainda está pendente.
GARFutureStateDone A operação foi concluída e o resultado está disponível.
GARFutureStateCancelled A operação foi cancelada.

Verificar o estado de âncora do terreno do resultado Futuro

O GARTerrainAnchorState pertence à operação assíncrona e faz parte do resultado final de Future.

switch (future.resultTerrainAnchorState) {
  case GARTerrainAnchorStateSuccess:
    // Terrain anchor finished resolving.
    break;
  case GARTerrainAnchorStateErrorUnsupportedLocation:
    // The requested anchor is in a location that isn't supported by the Geospatial API.
    break;
  case GARTerrainAnchorStateErrorNotAuthorized:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/ios/group/GARTerrainAnchorState#garterrainanchorstateerrornotauthorized
    // for troubleshooting steps.
    break;
  case GARTerrainAnchorStateErrorInternal:
    // The Terrain anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

Buchas para telhado

Imagem principal dos âncoras de telhado

As âncoras no telhado são um tipo de âncora e são muito semelhantes às fixas de terreno acima. A diferença é que você fornecerá a altitude acima do telhado, e não a altitude acima do terreno.

Criar uma âncora no telhado usando a nova API Async

A âncora não estará pronta imediatamente e precisa ser resolvida.

Para criar e colocar uma âncora no telhado, chame GARSession.createAnchorWithCoordinate:altitudeAboveRooftop:eastUpSouthQAnchor:completionHandler:error:. Assim como as âncoras de terreno, você também acessa GARFutureState do Futuro. Em seguida, verifique o resultado Future para acessar o GARRooftopAnchorState.

GARCreateAnchorOnRooftopFuture *future = [self.garSession createAnchorWithCoordinate:coordinate
                                                                altitudeAboveRooftop:altitude
                                                                  eastUpSouthQAnchor:eastUpSouthQTarget
                                                                   completionHandler:^(GARAnchor *anchor, GARRooftopAnchorState state) {
                                                                     // handle completion
                                                                   }
                                                                               error:&error];

Verificação do estado do futuro

O Future terá um GARFutureState associado. Consulte a tabela acima.

Verificar o estado da âncora no telhado do resultado Future

O GARRooftopAnchorState pertence à operação assíncrona e faz parte do resultado final de Future.

switch (future.resultRooftopAnchorState) {
  case GARRooftopAnchorStateSuccess:
    // Rooftop anchor finished resolving.
    break;
  case GARRooftopAnchorStateErrorUnsupportedLocation:
    // The requested anchor is in a location that isn't supported by the Geospatial API.
    break;
  case GARRooftopAnchorStateErrorNotAuthorized:
    // An error occurred while authorizing your app with the ARCore API. See
    // https://developers.google.com/ar/reference/ios/group/GARRooftopAnchorState#garrooftopanchorstateerrornotauthorized
    // for troubleshooting steps.
    break;
  case GARRooftopAnchorStateErrorInternal:
    // The Rooftop anchor could not be resolved due to an internal error.
    break;
  default:
    break;
}

A seguir