Sử dụng neo không gian địa lý để định vị nội dung trong thế giới thực trên SDK Android (Kotlin/Java)

Neo không gian địa lý là một loại neo cho phép bạn đặt nội dung 3D trong thế giới thực.

Các loại neo không gian địa lý

Có ba loại neo không gian địa lý, mỗi loại lại xử lý độ cao theo cách khác nhau:

  1. Neo WGS84:
    Meo WGS84 cho phép bạn đặt nội dung 3D ở bất kỳ vĩ độ, kinh độ và độ cao nào cho trước.

  2. Cố định địa hình:
    Cố định địa hình cho phép bạn đặt nội dung chỉ sử dụng vĩ độ và kinh độ với độ cao tương ứng với địa hình tại vị trí đó. Độ cao được xác định tương ứng so với mặt đất hoặc sàn nhà như VPS.

  3. Neo trên mái:
    Neo trên mái nhà cho phép bạn chỉ đặt nội dung bằng vĩ độ và kinh độ có độ cao tương ứng với mái nhà của toà nhà tại vị trí đó. Độ cao được xác định tương ứng với đỉnh của một toà nhà (được gọi là Hình học cảnh đường phố). Giá trị này sẽ mặc định là độ cao của bản đồ địa hình khi không được đặt trên một toà nhà.

WGS84 Địa hình Sân thượng
Vị trí ngang Vĩ độ, Kinh độ Vĩ độ, Kinh độ Vĩ độ, Kinh độ
Vị trí dọc Tương đối so với độ cao WGS84 Tương đối so với cấp địa hình do Google Maps xác định Tương đối so với tầng mái nhà do Google Maps xác định
Cần phải được máy chủ giải quyết? Không

Điều kiện tiên quyết

Hãy nhớ bật API Không gian địa lý trước khi tiếp tục.

Đặt neo không gian địa lý

Mỗi loại liên kết có các API chuyên biệt để tạo chúng; hãy xem Các loại liên kết không gian địa lý để biết thêm thông tin.

Tạo liên kết từ thử nghiệm nhấn

Bạn cũng có thể tạo neo không gian địa lý từ kết quả kiểm tra lượt truy cập. Sử dụng Pose từ phép kiểm thử lượt truy cập và chuyển đổi Pose đó thành GeospatialPose. Dùng nút này để đặt bất kỳ loại neo nào trong 3 loại neo được mô tả.

Tạo tư thế không gian địa lý bằng tư thế thực tế tăng cường

Earth.getGeospatialPose() cung cấp một cách khác để xác định vĩ độ và kinh độ bằng cách chuyển đổi Tư thế AR thành Tư thế không gian địa lý.

Tạo tư thế thực tế tăng cường từ một Tư thế không gian địa lý

Earth.getPose() chuyển đổi vị trí nằm ngang, độ cao và hướng xoay quaternion được chỉ định bởi Trái đất đối với khung toạ độ hướng đông-lên-nam thành Tư thế AR đối với toạ độ thế giới GL.

Chọn phương pháp phù hợp với trường hợp sử dụng của bạn

Mỗi phương pháp tạo quảng cáo cố định cuối màn hình đều có những ưu điểm riêng cần lưu ý:

  • Khi sử dụng Hình học cảnh đường phố, hãy sử dụng thử nghiệm nhấn để đính kèm nội dung vào tòa nhà.
  • Ưu tiên neo Địa hình hoặc Mái nhà hơn neo WGS84 vì các neo này sử dụng giá trị độ cao do Google Maps xác định.

Xác định vĩ độ và kinh độ của một vị trí

Bạn có thể tính vĩ độ và kinh độ của một vị trí theo ba cách:

  • Sử dụng Trình tạo không gian địa lý để xem và tăng cường thế giới bằng nội dung 3D mà không cần phải đi đến một địa điểm. Tính năng này cho phép bạn đặt nội dung 3D sống động một cách trực quan bằng cách sử dụng Google Maps trong Trình chỉnh sửa Unity. Vĩ độ, kinh độ, chế độ xoay và cao độ của nội dung sẽ được tính tự động cho bạn.
  • Sử dụng Google Maps
  • Sử dụng Google Earth. Lưu ý rằng việc nhận những toạ độ này sử dụng Google Earth, chứ không phải Google Maps, sẽ cung cấp cho bạn khoảng sai số lên tới vài mét.
  • Chuyển đến vị trí thực tế

Sử dụng Google Maps

Để biết vĩ độ và kinh độ của một vị trí bằng Google Maps, hãy làm như sau:

  1. Truy cập vào Google Maps trên máy tính.

  2. Chuyển tới Lớp > Thêm.

  3. Thay đổi Loại bản đồ thành Vệ tinh và bỏ chọn hộp đánh dấu Chế độ xem hình cầu ở góc dưới cùng bên trái màn hình.

    Điều này sẽ buộc có phối cảnh 2D và loại bỏ các lỗi có thể xảy ra từ chế độ xem 3D góc.

  4. Trên bản đồ, hãy nhấp chuột phải vào vị trí rồi chọn kinh độ/vĩ độ để sao chép thông tin đó vào bảng nhớ tạm.

Sử dụng Google Earth

Bạn có thể tính vĩ độ và kinh độ của một vị trí từ Google Earth bằng cách nhấp vào một vị trí trong giao diện người dùng và đọc dữ liệu từ thông tin chi tiết của dấu vị trí.

Để biết vĩ độ và kinh độ của một vị trí bằng Google Earth, hãy làm như sau:

  1. Truy cập vào Google Earth trên máy tính.

  2. Chuyển đến trình đơn ba đường kẻ rồi chọn Kiểu bản đồ.

  3. Tắt nút chuyển Toà nhà 3D.

  4. Sau khi đã tắt nút chuyển Toà nhà 3D, hãy nhấp vào biểu tượng ghim để thêm dấu vị trí tại vị trí đã chọn.

  5. Chỉ định một dự án để chứa dấu vị trí của bạn rồi nhấp vào Lưu.

  6. Trong trường Tiêu đề của dấu vị trí, hãy nhập tên cho dấu vị trí.

  7. Nhấp vào mũi tên quay lại trong ngăn dự án rồi chọn trình đơn Thao tác khác.

  8. Chọn Xuất dưới dạng tệp KML từ trình đơn.

Tệp KLM báo cáo vĩ độ, kinh độ và độ cao cho một dấu vị trí trong thẻ <coordinates> được phân tách bằng dấu phẩy như sau:

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

Không sử dụng vĩ độ và kinh độ trong các thẻ <LookAt> để chỉ định vị trí của máy ảnh chứ không phải vị trí.

Chuyển đến vị trí thực tế

Bạn có thể tính toán độ cao của một vị trí bằng cách đi đến vị trí đó trên thực tế và quan sát tại địa phương.

Lấy quaternion xoay

GeospatialPose.getEastUpSouthQuaternion() trích xuất hướng từ Vị trí không gian địa lý và tạo ra một quaternion đại diện cho ma trận xoay biến đổi một vectơ từ mục tiêu sang hệ toạ độ đông-lên-nam (EUS). X+ điểm về phía đông, Y+ điểm lên trên và Z+ điểm về phía nam. Các giá trị được viết theo thứ tự {x, y, z, w}.

Neo WGS84

Neo WGS84 là một loại neo cho phép bạn đặt nội dung 3D ở bất kỳ vĩ độ, kinh độ và độ cao nào cho trước. Hình ảnh này phụ thuộc vào Tư thế và hướng để đặt trong thế giới thực. Vị trí bao gồm vĩ độ, kinh độ và độ cao, được chỉ định trong hệ toạ độ WGS84. Hướng bao gồm một vòng xoay quaternion.

Độ cao được báo cáo bằng mét trên hình elip WGS84 tham chiếu sao cho độ cao mặt đất không bằng 0. Ứng dụng của bạn chịu trách nhiệm cung cấp các toạ độ này cho mỗi điểm neo đã tạo.

Đặt neo WGS84 trong thế giới thực

Xác định độ cao của một vị trí

Có một số cách xác định cao độ của một vị trí để đặt neo:

  • Nếu vị trí của điểm neo thực tế là gần người dùng, bạn có thể sử dụng độ cao tương tự như độ cao trên thiết bị của người dùng.
  • Sau khi bạn có vĩ độ và kinh độ, hãy sử dụng API Độ cao để lấy độ cao dựa trên thông số kỹ thuật EGM96. Bạn phải chuyển đổi độ cao API Maps EGM96 thành WGS84 để so sánh với độ cao GeospatialPose. Xem GeoidEval có cả dòng lệnh và giao diện HTML. API Maps báo cáo vĩ độ và kinh độ theo thông số kỹ thuật WGS84 ngay từ đầu.
  • Bạn có thể lấy vĩ độ, kinh độ và độ cao của một vị trí từ Google Earth. Khi làm như vậy, bạn sẽ có phạm vi sai số lên đến vài mét. Sử dụng vĩ độ, kinh độ và độ cao trong các thẻ <coordinates>, chứ không phải thẻ <LookAt> trong tệp KML.
  • Nếu điểm neo hiện có ở gần nếu bạn không ở trên đường dốc, bạn có thể sử dụng độ cao từ GeospatialPose của máy ảnh mà không cần sử dụng một nguồn khác, chẳng hạn như API Maps.

Tạo liên kết

Sau khi có được vĩ độ, kinh độ, độ cao và tứ phân vị xoay, hãy sử dụng Earth.createAnchor() để cố định nội dung theo toạ độ địa lý mà bạn chỉ định.

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

Neo cho địa hình

Neo Địa hình là một loại neo cho phép bạn đặt các đối tượng thực tế tăng cường chỉ cần vĩ độ và kinh độ, tận dụng thông tin từ VPS để tìm độ cao chính xác so với mặt đất.

Thay vì nhập độ cao mong muốn, bạn cung cấp độ cao phía trên địa hình. Khi giá trị này bằng 0, neo sẽ cân bằng với địa hình.

Đặt chế độ tìm máy bay

Việc tìm kiếm máy bay là không bắt buộc và không cần thiết để sử dụng neo. Xin lưu ý rằng chỉ sử dụng mặt phẳng nằm ngang. Mặt phẳng ngang sẽ giúp căn chỉnh động các neo địa hình trên mặt đất.

Sử dụng Config.PlaneFindingMode để chọn cách ứng dụng của bạn phát hiện máy bay.

Tạo neo Địa hình bằng API Async mới

Để tạo và đặt neo Địa hình, hãy gọi Earth.resolveAnchorOnTerrainAsync().

Quảng cáo cố định cuối màn hình sẽ chưa sẵn sàng ngay lập tức và cần được giải quyết. Sau khi được giải quyết, đơn khiếu nại đó sẽ có trong 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
      }
    }
  )

Kiểm tra tình hình tương lai

Tương lai sẽ có một FutureState liên kết.

Tiểu bang Nội dung mô tả
FutureState.PENDING Thao tác này vẫn đang chờ xử lý.
FutureState.DONE Thao tác đã hoàn tất và đã có kết quả.
FutureState.CANCELLED Thao tác đã bị huỷ.

Kiểm tra trạng thái neo Địa hình của kết quả Tương lai

Anchor.TerrainAnchorState thuộc về hoạt động không đồng bộ và là một phần của kết quả Tương lai cuối cùng.

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

Neo trên mái nhà

Neo trên mái nhà

Neo trên mái nhà là một loại neo và rất giống với Neo địa hình ở trên. Sự khác biệt là bạn sẽ cung cấp độ cao phía trên mái nhà thay vì độ cao phía trên địa hình.

Tạo neo trên Sân thượng bằng Async API mới

Quảng cáo cố định cuối màn hình sẽ chưa sẵn sàng ngay lập tức và cần được giải quyết.

Để tạo và đặt neo trên Sân thượng, hãy gọi Earth.resolveAnchorOnRooftopAsync(). Tương tự như neo Địa hình, bạn cũng sẽ truy cập được vào FutureState của Tương lai. Sau đó, bạn có thể xem Kết quả trong tương lai để truy cập vào 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
      }
    }
  )

Kiểm tra tình hình tương lai

Tương lai sẽ có một FutureState liên kết, hãy xem bảng ở trên.

Kiểm tra trạng thái neo trên Sân thượng của kết quả Tương lai

Anchor.RooftopAnchorState thuộc về hoạt động không đồng bộ và là một phần của kết quả Tương lai cuối cùng.

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

Các bước tiếp theo