地理空間錨定是錨定的一種,用來在現實世界中放置 3D 內容。
地理空間錨點類型
地理空間錨點有三種,每種類型處理海拔高度的方式皆不同:
WGS84 錨點:
您可使用 WGS84 錨定標記在任何經緯度放置 3D 內容 經度和海拔高度地形錨點:
地形錨點可以僅使用經緯度 經度與該位置的地形相對的高度。 海拔高度是相對於地面或樓層的已知高度 上傳者:VPS。屋頂錨點:
透過屋頂錨定標記,您可以只使用緯度和 相對於建築物屋頂的高度。 海拔高度是相對於建築物頂端的位置 (稱為 製作者:Streetscape Geometry。 未放置在建築物上時,系統預設會使用地形海拔高度。
WGS84 | 地形 | 屋頂 | |
---|---|---|---|
水平位置 | 緯度, 經度 | 緯度, 經度 | 緯度, 經度 |
垂直位置 | 相對於 WGS84 高度 | 相對於 Google 地圖所決定地形等級的比較 | 相對於 Google 地圖判定的屋頂樓層 |
需要由伺服器解決嗎? | 否 | 是 | 是 |
必要條件
請務必先啟用 Geospatial API,再繼續操作。
地點地理空間錨點
每個錨定類型都有專屬 API 來建立這些錨定標記;詳情請參閱「地理空間錨點類型」。
根據命中測試建立錨定廣告
您也可以透過命中測試結果建立地理空間錨點。
使用命中測試中的 Pose 轉換為 ArGeospatialPose
。可用來放置上述 3 種錨定類型。
透過 AR 姿勢取得地理空間姿勢
ArEarth_getGeospatialPose()
可將 AR Pose 轉換為地理空間表,提供另一種判斷經緯度的方式。
從地理空間姿勢取得 AR 姿勢
ArEarth_getPose()
會根據 GL 世界座標,將地球指定的水平位置、海拔高度和四元旋轉,對應到 GL 世界座標的 AR Pose。
選擇符合您用途的方法
每個建立錨點的方法都需留意相關優缺點:
- 使用「Streetscape 幾何圖形」時 請使用點擊測試將內容附加到建築物上
- 優先使用 Terrain 或 Rooftop 錨點,而不是 WGS84 錨點,因為它們使用 Google 地圖判定的海拔高度值。
判斷某個位置的經緯度
計算地點經緯度的方式有三種:
- 善用地理空間創作者,透過 3D 內容飽覽並擴增世界,完全不必親臨當地。這可讓您在 Unity 編輯器中使用 Google 地圖,以視覺化方式放置 3D 沉浸式內容。並自動計算內容的緯度、經度、旋轉和高度。
- 使用 Google 地圖
- 使用 Google 地球。請注意,使用「Google 地球」取得這些座標時,您得到的誤差範圍只有幾公尺,而非「Google 地圖」。
- 前往實際位置
使用 Google 地圖
如何透過 Google 地圖取得地點的經緯度:
透過電腦前往 Google 地圖。
前往 [圖層] >更多:
將 [地圖類型] 變更為 [衛星],並取消勾選畫面左下角的 [地球視圖] 核取方塊。
這會強制採用 2D 視角,並消除 3D 檢視中可能產生的錯誤。
在地圖上,用滑鼠右鍵按一下該地點,然後選取經緯度,即可複製到剪貼簿。
使用 Google 地球
只要在使用者介面中按一下某個位置,即可讀取地標詳細資料的資料,在 Google 地球中計算位置的經緯度。
如要透過 Google 地球取得特定地點的經緯度,請按照下列步驟操作:
在電腦上前往 Google 地球。
前往漢堡選單 ,然後選取「地圖樣式」。
將「3D 建築物」切換按鈕設為關閉。
關閉「3D 建築物」開關後,按一下圖釘圖示 ,即可在所選位置新增地標。
指定要包含地標的專案,然後按一下「儲存」。
在地標的「標題」欄位中,輸入地標名稱。
按一下專案窗格中的返回箭頭 ,然後選取 「More Actions」選單。
從選單中選擇「匯出成 KML 檔案」。
KLM 檔案會回報 <coordinates>
標記中地標的經緯度和海拔高度 (以半形逗號分隔),如下所示:
<coordinates>-122.0755182435043,37.41347299422944,7.420342565583832</coordinates>
請「不要」使用 <LookAt>
標記中的經緯度;這些標記指定了攝影機位置,而非位置。
前往實際位置
如要計算某地點的海拔高度,請實際前往現場進行當地觀察。
取得旋轉四元數
ArGeospatialPose_getEastUpSouthQuaternion()
從地理空間 Pose 擷取方向,並輸出代表旋轉矩陣,將向量從目標轉換為東南 (EUS) 座標系統。X+ 點往東、Y+ 點向上,以及 Z+ 點朝南。值會依 {x, y, z, w}
順序寫入。
WGS84 錨點
WGS84 Anchor 是一種錨點,可讓您在任何指定的經緯度及高度位置放置 3D 內容。這需要先靠姿勢和方向,才能擺放在現實世界中。位置包含經緯度和海拔高度,(於 WGS84 座標系統中指定)。方向包含四元數旋轉。
海拔高度值於參考 WGS84 橢圓球體上方以公尺為單位,因此地面等級「不是」0。您的應用程式負責為每個已建立的錨點提供這些座標。
在現實世界中放置 WGS84 錨點
判斷位置的海拔高度
您可以透過下列幾種方式判斷位置的海拔高度:
- 如果錨點的位置與使用者裝置的海拔高度相近,您可以使用與使用者裝置的高度相似的海拔高度,
- 取得經緯度後,您可以使用 Elevation API,根據 EGM96 規格取得海拔高度。如要與
ArGeospatialPose
高度進行比較,您必須將 Maps API EGM96 高度轉換成 WGS84。請參閱含有指令列和 HTML 介面的 GeoidEval。Maps API 會根據內建的 WGS84 規格,回報經緯度。 - 你可以從 Google 地球取得特定地點的經緯度。所提供的誤差範圍最多可達數公尺。請使用 KML 檔案中的
<coordinates>
標記 (「不是」<LookAt>
標記),使用經緯度和海拔高度。 - 如果現有錨點在靠近附近且不是陡坡,即使不使用其他來源 (例如 Maps API),也可以使用相機
ArGeospatialPose
中的海拔高度。
建立錨定標記
取得緯度、經度、高度和旋轉四元後,即可使用 ArEarth_acquireNewAnchor()
將內容錨定在您指定的地理座標。
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. } }
地形錨點
地形錨點是一種錨點,可讓您僅利用經緯度放置 AR 物件,並運用 VPS 資訊,找出地面上的精確海拔高度。
您不必輸入所需海拔高度,而是提供地形上方的海拔高度。當此值為零時,錨點就會與地形水平。
設定飛機搜尋模式
平面發現項目為選用項目,且不一定要使用錨點。請注意,僅使用水平平面。水平平面可協助地面上地形錨點的動態對齊方式。
使用 ArPlaneFindingMode
選取應用程式偵測飛機的方式。
使用新的 Async API 建立地形錨點
如要建立及放置地形錨點,請呼叫 ArEarth_resolveAnchorOnTerrainAsync()
。
錨定廣告可能無法立即使用,需要解決問題。問題解決後,就會在 ArResolveAnchorOnTerrainFuture
中顯示。
使用 ArResolveAnchorOnTerrainFuture_getResultTerrainAnchorState()
檢查地形錨點狀態。
使用 ArResolveAnchorOnTerrainFuture_acquireResultAnchor()
取得已解析的錨點。
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); } }
查看未來狀況
Future 會有相關聯的 ArFutureState
。
州 | 說明 |
---|---|
AR_FUTURE_STATE_PENDING |
這項作業仍待處理。 |
AR_FUTURE_STATE_DONE |
作業完成且結果可供使用。 |
AR_FUTURE_STATE_CANCELLED |
作業已取消。 |
查看未來結果的地形錨點狀態
ArTerrainAnchorState
屬於非同步作業,屬於 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; }
屋頂錨栓
屋頂錨點是一種錨點,與上述的地形錨點十分類似。不同之處在於您需要提供屋頂上的海拔高度,而非地形上方的海拔高度。
使用新的 Async API 建立 Rooftop 錨點
錨定廣告可能無法立即使用,需要解決問題。
如要建立及放置屋頂錨點,請呼叫 ArEarth_resolveAnchorOnRooftopAsync()
。與地形錨點類似,您還可以存取 Future 的 ArFutureState
。然後,您可以查看 Future 結果,以存取 ArRooftopAnchorState
。
使用 ArEarth_resolveAnchorOnRooftopAsync()
建立 ArResolveAnchorOnRooftopFuture
。
使用 ArResolveAnchorOnRooftopFuture_getResultRooftopAnchorState()
檢查屋頂錨定狀態。
使用 ArResolveAnchorOnRooftopFuture_acquireResultAnchor()
取得已解析的錨點。
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); } }
查看未來狀況
Future 會有相關聯的 ArFutureState
,請參閱上文表格。
檢查未來結果的屋頂錨點狀態
ArRooftopAnchorState
屬於非同步作業,屬於 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; }
後續步驟
- 請務必瞭解地理空間 API 使用配額。