Используйте геопространственные привязки для позиционирования реального контента на iOS

Геопространственные привязки — это тип привязки , позволяющий размещать 3D-контент в реальном мире.

Типы геопространственных привязок

Существует три типа геопространственных привязок, каждый из которых по-разному обрабатывает высоту:

  1. Якоря WGS84 :
    Якоря WGS84 позволяют размещать 3D-контент на любой заданной широте, долготе и высоте.

  2. Местные якоря :
    Привязки к местности позволяют размещать контент, используя только широту и долготу, а также высоту относительно местности в этой позиции. Высота определяется относительно земли или пола, как известно VPS .

  3. Анкеры на крыше :
    Привязки на крыше позволяют размещать контент, используя только широту и долготу, а также высоту относительно крыши здания в этом положении. Высота определяется относительно вершины здания, известной как Streetscape Geometry . По умолчанию используется высота местности, если она не размещена на здании.

WGS84 Местность Крыша
Горизонтальное положение Широта, Долгота Широта, Долгота Широта, Долгота
Вертикальное положение Относительно высоты WGS84 Относительно уровня местности, определенного Google Maps Относительно уровня крыши, определенного с помощью Google Maps.
Требуется разрешение на сервере? Нет Да Да

Предварительные условия

Прежде чем продолжить, убедитесь, что вы включили Geospatial API .

Разместите геопространственные привязки

У каждого типа привязки есть специальные API для их создания; дополнительную информацию см. в разделе «Типы геопространственных привязок» .

Создайте якорь на основе хит-теста

Вы также можете создать геопространственную привязку на основе результатов проверки попадания . Используйте Transform из теста попадания и преобразуйте его в GARGeospatialTransform . Используйте его для размещения любого из трех описанных типов якорей.

Получите геопространственное преобразование из преобразования AR

GARSession.geospatialTransformFromTransform:error: предоставляет дополнительный способ определения широты и долготы путем преобразования AR-преобразования в геопространственное преобразование.

Получите преобразование AR из геопространственного преобразования

GARSession.transformFromGeospatialCoordinate:altitude:eastUpSouthQTarget:error: преобразует заданное Землей горизонтальное положение, высоту и вращение кватерниона относительно системы координат восток-вверх-юг в преобразование AR относительно мировой координаты GL.

Выберите, какой метод подходит для вашего случая использования

Каждый метод создания якоря имеет связанные с ним компромиссы, о которых следует помнить:

  • При использовании Streetscape Geometry используйте проверку попадания, чтобы прикрепить контент к зданию.
  • Предпочитайте якоря Terrain или Rooftop, а не якоря WGS84, поскольку они используют значения высоты, определенные Google Maps.

Определить широту и долготу места

Вычислить широту и долготу местоположения можно тремя способами:

  • Используйте Geospatial Creator , чтобы просматривать и дополнять мир трехмерным контентом без необходимости физического посещения определенного места. Это позволяет визуально размещать иммерсивный 3D-контент с помощью карт Google в редакторе Unity. Широта, долгота, поворот и высота контента будут рассчитаны автоматически.
  • Используйте Карты Google
  • Используйте Google Планета Земля. Обратите внимание, что получение этих координат с помощью Google Earth, в отличие от Google Maps, даст вам погрешность до нескольких метров.
  • Перейти к физическому местоположению

Используйте Карты Google

Чтобы получить широту и долготу местоположения с помощью Google Maps:

  1. Откройте Карты Google на настольном компьютере.

  2. Перейдите в «Слои» > «Еще» .

  3. Измените тип карты на «Спутник» и снимите флажок «Вид глобуса» в левом нижнем углу экрана.

    Это обеспечит 2D-перспективу и устранит возможные ошибки, которые могут возникнуть при просмотре 3D-изображения под углом.

  4. На карте щелкните правой кнопкой мыши местоположение и выберите долготу/широту, чтобы скопировать его в буфер обмена.

Используйте Google Планета Земля

Вы можете рассчитать широту и долготу местоположения с помощью Google Earth, щелкнув местоположение в пользовательском интерфейсе и прочитав данные из сведений о метке.

Чтобы получить широту и долготу местоположения с помощью Google Earth:

  1. Откройте Google Планета Земля на настольном компьютере.

  2. Перейдите в гамбургер-меню и выберите Стиль карты .

  3. Выключите переключатель «3D-здания» .

  4. Когда переключатель «3D-здания» выключен, щелкните значок булавки. чтобы добавить метку в выбранном месте.

  5. Укажите проект, в котором будет храниться метка, и нажмите « Сохранить» .

  6. В поле Название метки введите имя метки.

  7. Нажмите стрелку назад на панели проекта и выберите Меню дополнительных действий .

  8. В меню выберите «Экспортировать как файл KML» .

Файл KLM сообщает широту, долготу и высоту метки в теге <coordinates> , разделенные запятыми, следующим образом:

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

Не используйте широту и долготу из тегов <LookAt> , которые определяют положение камеры, а не местоположение.

Перейти к физическому местоположению

Вы можете рассчитать высоту места, физически придя туда и проведя местные наблюдения.

Получить кватернион вращения

GARGeospatialTransform.eastUpSouthQTarget извлекает ориентацию из геопространственного преобразования и выводит кватернион, который представляет матрицу вращения, преобразующую вектор из цели в систему координат восток-вверх-юг (EUS). X+ указывает на восток, Y+ указывает вверх, а Z+ указывает на юг. Значения записываются в порядке {x, y, z, w} .

Якоря WGS84

Якорь WGS84 — это тип якоря , который позволяет размещать 3D-контент на любой заданной широте, долготе и высоте. Он основан на преобразовании и ориентации для размещения в реальном мире. Позиция состоит из широты, долготы и высоты, которые указаны в системе координат WGS84 . Ориентация состоит из вращения кватернионов.

Высота указывается в метрах над эталонным эллипсоидом WGS84, так что уровень земли не равен нулю. Ваше приложение отвечает за предоставление этих координат для каждой созданной привязки.

Разместите якорь WGS84 в реальном мире.

Определить высоту места

Есть несколько способов определить высоту места для установки якорей:

  • Если привязка физически находится рядом с пользователем, вы можете использовать высоту, аналогичную высоте устройства пользователя.
  • Получив широту и долготу, используйте Elevation API , чтобы получить высоту на основе спецификации EGM96 . Необходимо преобразовать высоту Maps API EGM96 в WGS84 для сравнения с высотой GARGeospatialTransform . См. GeoidEval , который имеет как командную строку, так и интерфейс HTML. API Карт сообщает широту и долготу в соответствии со спецификацией WGS84.
  • Вы можете получить широту, долготу и высоту местоположения из Google Earth . Это даст вам погрешность до нескольких метров. Используйте широту, долготу и высоту из тегов <coordinates> , а не тегов <LookAt> в файле KML.
  • Если существующая якорь находится рядом и вы не находитесь на крутом склоне, вы можете использовать высоту из GARGeospatialTransform камеры, не используя другой источник, например Maps API.

Создайте якорь

Получив кватернион широты, долготы, высоты и вращения, используйте createAnchorWithCoordinate:altitude:eastUpSouthQAnchor:error: чтобы привязать контент к указанным вами географическим координатам.

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

Якоря местности

Якорь местности — это тип якоря , который позволяет размещать объекты AR, используя только широту и долготу, используя информацию от VPS для определения точной высоты над землей.

Вместо ввода желаемой высоты вы указываете высоту над местностью. Когда это значение равно нулю, якорь будет находиться на одном уровне с местностью.

Установите режим поиска плоскости

Поиск плоскости не является обязательным и не требует использования якорей. Обратите внимание, что используются только горизонтальные плоскости. Горизонтальные плоскости помогут динамическому выравниванию якорей местности на земле.

Используйте ARWorldTrackingConfiguration.PlaneDetection , чтобы выбрать, как ваше приложение будет обнаруживать самолеты.

Создайте привязку Terrain с помощью нового API Async.

Чтобы создать и разместить привязку Terrain, вызовите GARSession.createAnchorWithCoordinate:altitudeAboveTerrain:eastUpSouthQAnchor:completionHandler:error: .

Якорь не будет готов сразу и его необходимо разрешить. Как только проблема будет решена, она будет доступна в GARCreateAnchorOnTerrainFuture .

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

Проверьте состояние будущего

Будущее будет иметь связанный GARFutureState .

Состояние Описание
GARFutureStatePending Операция еще предстоит.
GARFutureStateDone Операция завершена, результат доступен.
GARFutureStateCancelled Операция отменена.

Проверьте состояние привязки Terrain в результате Future.

GARTerrainAnchorState принадлежит асинхронной операции и является частью конечного результата 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;
}

Анкеры на крыше

Анкеры для крыши Hero

Якоря на крыше представляют собой разновидность якоря и очень похожи на якоря Terrain, описанные выше. Разница в том, что вы указываете высоту над крышей, а не над местностью.

Создайте якорь на крыше с помощью нового API Async.

Якорь не будет готов сразу и его необходимо разрешить.

Чтобы создать и разместить привязку на крыше, вызовите GARSession.createAnchorWithCoordinate:altitudeAboveRooftop:eastUpSouthQAnchor:completionHandler:error: . Как и в случае с якорями Terrain, вы также получите доступ к GARFutureState of the Future. Затем вы можете проверить результат Future, чтобы получить доступ к GARRooftopAnchorState .

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

Проверьте состояние будущего

Future будет иметь связанный GARFutureState , см. таблицу выше.

Проверьте состояние привязки на крыше результата Future.

GARRooftopAnchorState принадлежит асинхронной операции и является частью конечного результата 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;
}

Что дальше