ARCore Geospatial APIは、Googleストリートビューの画像から作った位置特定モデル(VPS)を使い、スマートフォンの位置と向きを緯度・経度・高度で求めるAPIです。求めた座標にARコンテンツを固定でき、周囲の建物メッシュ(Streetscape Geometry)を取れば建物の陰に隠れるオクルージョン表現も自前の3Dモデルなしで作れます。この記事では、測位の仕組みと公称精度、3種類のアンカーの使い分け、建物メッシュと深度の取り方、対応エリアの判定、料金と使用量の上限、そしてAndroid XR向けのJetpack XR版との違いを、2026年11月時点の公式リファレンスとリリースノートを基準に整理します。
まとめ
- Geospatial APIは端末のセンサー・GPS・VPSを組み合わせて位置を決めます。VPSが効く場所の公称精度は、位置が5m未満で多くは1m前後、回転が5度未満です。
- コンテンツの置き方は3種類です。高度を楕円体高で指定するWGS84アンカー、地面からの高さで指定するTerrainアンカー、建物の屋上からの高さで指定するRooftopアンカーで、公式はTerrainかRooftopを推奨しています。
- 建物メッシュを得るには
GeospatialMode.ENABLEDとStreetscapeGeometryMode.ENABLEDの両方が必要です。建物の詳細度は2段階で、上位のLOD2でも煙突や換気口はメッシュからはみ出します。 - Depth APIと組み合わせるGeospatial Depthを使うと、深度画像に約65m先までの建物と地形が入ります。通常のDepth APIは20〜30mが目安です。
- 対象地点で使えるかは
checkVpsAvailabilityAsyncが緯度経度ごとに返します。対応エリアの一覧は公開されていません。 - ARCore APIに料金表はなく、明示されているのは1分あたり1,000セッションまたは100,000リクエストの上限です。金額が発生するのは、Geospatial Creatorで使うGoogle Maps PlatformのAPIです。
- Android XR向けのARCore for Jetpack XRは2026年10月21日に1.0.0が安定版になりました。こちらの
GeospatialModeは DISABLED・SPATIAL・INERTIAL の3値で、従来のARCore SDK(ENABLED/DISABLEDの2値)とは書き方が違います。
Geospatial APIが位置と向きを決める仕組みと精度
GPS単体の測位はビルの多い市街地で誤差が大きくなり、建物などに正確に合わせるAR表示には精度が足りない場合があります。Geospatial APIはこの誤差をカメラ映像で補正します。
ストリートビュー由来のVPSで補正する測位
公式の概要ページによると、VPSの土台は15年以上にわたって撮影されたストリートビューの画像です。長期間変わりにくい特徴をニューラルネットワークで画像から抜き出し、数百億枚の画像をまたいで組み合わせて地球規模の3D点群を作っています。端末はカメラ映像の特徴をこの点群と照合し、GPS単体より精度の高い位置と向きを得ます。
端末が地図を自分で作りながら位置を推定するSLAMは相対位置しか分かりませんが、Geospatial APIは撮影済みのデータと照合するので緯度・経度という絶対座標が返ります。Cloud Anchorのように、事前にその場所をスキャンして地図を作る作業も要りません。
精度の目安は、Jetpack XR版の GeospatialModeのリファレンスに数字で書かれています。VPSが効く通常の条件で、位置は5m未満、多くの場合1m前後、回転は5度未満です。VPSの対象外でも、端末が位置を取れれば精度が低いまま動作は続きます。
カメラの位置姿勢と精度値を取り出すコード
従来のARCore SDK(Android)では、セッションに Config.GeospatialMode.ENABLED を設定し、Earth の追跡状態が TRACKING になってから getCameraGeospatialPose() を呼びます。
val earth = session.earth ?: return
if (earth.trackingState == TrackingState.TRACKING) {
val pose = earth.cameraGeospatialPose
val lat = pose.latitude
val lng = pose.longitude
val alt = pose.altitude // WGS84楕円体からの高さ(m)
val hAcc = pose.horizontalAccuracy // 水平誤差の推定値(m)
val vAcc = pose.verticalAccuracy // 高度誤差の推定値(m)
val yawAcc = pose.orientationYawAccuracy
}
古いサンプルに残っている getHeading() と getHeadingAccuracy() は非推奨です。向きは getEastUpSouthQuaternion()、向きの精度は getOrientationYawAccuracy() を使います(GeospatialPoseのリファレンス)。getHorizontalAccuracy() は推定位置を中心とする68%信頼水準の半径(m)で、値が大きいほど精度が低いことを示します。GoogleのAndroidクイックスタートのサンプルは、水平精度10m以下・向きの精度15度以下になってからアンカーの配置を許しています。この待ち合わせを省くと、測位が落ち着く前のずれた位置にコンテンツが固定されます。
緯度経度に置くアンカー3種の違いと作り方
3種類のアンカーは、水平位置をどれも緯度・経度で指定し、高さの基準だけが違います(Geospatialアンカーのガイド)。
| 種類 | 高さの基準 | サーバーでの解決 | 作成メソッド(Android) |
|---|---|---|---|
| WGS84 | WGS84楕円体からの高さ | 不要 | Earth.createAnchor |
| Terrain | VPSが把握する地面・床 | 必要 | Earth.resolveAnchorOnTerrainAsync |
| Rooftop | Streetscape Geometryの屋上 | 必要 | Earth.resolveAnchorOnRooftopAsync |
迷ったらTerrainかRooftopを選んでください。WGS84アンカーの高さは楕円体高なので、海抜(標高)とは一致しません。地図アプリで調べた標高をそのまま入れると、コンテンツが地中や空中に出ます。公式もGoogleマップが把握する高さを使うTerrain・Rooftopを推奨しています。Rooftopアンカーは建物が無い地点ではTerrainと同じ高さになります。
earth.resolveAnchorOnTerrainAsync(
latitude, longitude,
1.5, // 地面からの高さ(m)
qx, qy, qz, qw
) { anchor, state ->
if (state == Anchor.TerrainAnchorState.SUCCESS) {
placeModel(anchor)
}
}
TerrainとRooftopはサーバーへの問い合わせを伴う非同期処理なので、結果の状態を見てから描画します。緯度経度はGoogleマップの衛星表示(地球儀表示をオフにした2D)で右クリックして取るのが手早く、ガイドはGoogle Earthで取った座標には数mの誤差が出うると注意しています。
Streetscape GeometryとGeospatial Depthで作る建物オクルージョン
建物の陰に隠す、壁に当たって跳ね返るといった表現には、座標だけでなく現実の形状データが要ります。それを返すのがStreetscape Geometryです。
建物と地形のメッシュ種別と2段階の詳細度
Streetscape Geometryは、端末の周囲にある地形・建物などをポリゴンメッシュで返します。getType() は建物か地形か、getQuality() は詳細度を返します。詳細度の値はCityGML 2.0のLOD(詳細度)に対応し、Qualityのリファレンスが形状と残る誤差まで書いています。
| Quality の値 | 対象 | 形状 | 残る誤差 |
|---|---|---|---|
| BUILDING_LOD_1 | 建物 | 平らな上面まで押し出し | 傾斜屋根の上が空洞 |
| BUILDING_LOD_2 | 建物 | 粗いハイトマップ付き | 煙突・換気口がはみ出す |
| NONE | 地形など | 定義なし | TERRAIN時の値 |
LOD1でも建物による遮蔽に使えますが、建物高や屋根形状の誤差により、コンテンツが実際より広く隠れるなどのずれが生じることがあります。屋上にキャラクターを立たせる、傾斜屋根に沿って物を転がすといった演出では、LOD2でも公式が認める誤差が画面に出ます。形状精度に頼る企画は、実機で対象の建物を確かめてから固めてください。
2つのモードを立てる設定とメッシュの取り出し
Streetscape Geometryのモードは既定で DISABLED です。Geospatial APIを有効にしたうえで、別途立てます。
session.configure(
session.config.apply {
geospatialMode = Config.GeospatialMode.ENABLED
streetscapeGeometryMode = Config.StreetscapeGeometryMode.ENABLED
}
)
val geometries = session.getAllTrackables(StreetscapeGeometry::class.java)
for (geometry in geometries) {
if (geometry.type == StreetscapeGeometry.Type.BUILDING) {
val mesh = geometry.mesh
val meshPose = geometry.meshPose
}
}
getMesh() で頂点とインデックスのリスト、getMeshPose() で原点の姿勢が取れます。ガイドは、建物にコンテンツを貼り付けるならメッシュへのヒットテストを使うよう勧めています。取得範囲の半径は公式リファレンスに数値がありません。
Geospatial Depthの深度範囲と有効化設定
オクルージョンを画面全体で効かせたいなら、Depth APIと組み合わせるGeospatial Depthが近道です。Geospatial Depthのガイドによると、Depth APIの深度は通常20〜30m程度ですが、VPSとStreetscape Geometryの両方に対応した場所でStreetscape Geometryを有効にすると、深度画像に現在位置から65m先までの地形と建物が入ります。設定はDepthモードを AUTOMATIC、Geospatialモードと Streetscape Geometryモードを ENABLED にするだけで、深度画像は既存の取得APIで受け取れます。計算コストが増えるのはセッション開始時の1回だけとされています。
深度をメートル単位の浮動小数で受け取るなら、2026年9月4日のARCore SDK for Android 1.56.0で追加された AcquireDepthImageMeters と AcquireRawDepthImageMeters が使えます(リリースノート)。対象エリアの外では、Depth APIはGeospatialの値を使わない通常の動作に戻ります。
PLATEAUの3D都市モデルと使い分ける判断
国内では、国土交通省が整備してオープンデータ化しているPLATEAUの3D都市モデルも建物形状の選択肢になります。どちらもCityGMLのLODで詳細度を表しますが、性質は逆です。
- Streetscape Geometryは端末の周囲を実行時に取得します。データの準備は要りませんが、範囲と詳細度はGoogle側で決まり、オフラインでは使えません。
- PLATEAUは事前にダウンロードしてアプリへ組み込みます。整備されたLODは都市ごとに違い、PLATEAUのサイトにある「整備都市の属性リスト」で確認できます。オフラインでも使えますが、端末の現在位置との位置合わせは自前で作ることになります。
判断は単純です。PLATEAUの整備範囲外で使う場合やデータ準備の工数を抑えたい場合は、対象地点で必要な建物メッシュを取得できることを確認したうえでStreetscape Geometryを選びます。対象地区が決まっていてLOD2以上が整備済み、または属性情報(建物の用途や高さ)を表現に使いたいなら、PLATEAUのモデルをGeospatialアンカーで位置合わせする構成が向いています。行政や都市計画の文脈で建物データを重ねる設計は、デジタルツインやGIS側の座標系と揃える前提で組みます。
対応エリアの判定方法とストリートビュー由来の制約
VPSはストリートビューの撮影データを土台にしているので、撮影が入っていない場所では実装が正しくても高精度にはなりません。使える場所の一覧は公開されておらず、判定は緯度経度ごとの問い合わせで行います。
緯度経度単位でVPSの可否を返すチェックAPI
対象地点が使えるかは Session.checkVpsAvailabilityAsync で事前に確かめます。
session.checkVpsAvailabilityAsync(latitude, longitude) { result ->
when (result) {
VpsAvailability.AVAILABLE -> enableStreetscapeGeometry()
VpsAvailability.UNAVAILABLE -> fallbackToPlaneDetection()
VpsAvailability.ERROR_NETWORK_CONNECTION -> retryWhenOnline()
else -> reportError(result)
}
}
エラーの値をまとめて「エリア外です」と表示しないでください。ERROR_NOT_AUTHORIZED はGoogle CloudのARCore APIへの認可の問題、ERROR_RESOURCE_EXHAUSTED は要求の出しすぎ、ERROR_NETWORK_CONNECTION は外部サービスに届かない状態です。まとめてしまうと、認可設定のミスを現地の電波のせいだと誤診します。UNKNOWN は要求がまだ終わっていない状態で、完了コールバックには届きません。
ストリートビューが入っていない場所で崩れる前提
- 屋内。商業施設や駅の構内は撮影されていない区画が多く、VPSが効きません。
- 車両が入れない私道・路地・私有地。撮影経路が通っていない可能性があります。
- 撮影後に建った建物や建て替えが済んだ区画。メッシュが現況と食い違います。
GPSやWi-Fi測位で動く一般的なLBS(位置情報サービス)と違い、Geospatial APIは撮影データの有無という外部条件に左右されます。企画を固める前に、対象エリアの可用性を実測してください。
Geospatial APIの料金と使用量の上限
ARCore APIの利用そのものに請求は発生しません。Googleは2022年5月の提供開始時にGeospatial APIを無償と案内しており、公式ドキュメントにもARCore APIの料金表はありません。示されているのは使用量の上限で、プロジェクトごとに1分あたり1,000セッションの開始、または1分あたり100,000リクエストです。超えた分の要求は満たされず、iOSでは GAREarthStateErrorResourceExhausted が返ります。
金額が発生するのは、Unityエディタ上で地図を見ながらコンテンツを置けるGeospatial Creator(ARCore Extensions for AR Foundationの一部)を併用する構成です。Geospatial Creatorのcodelabは請求先アカウントの設定を必須とし、無償枠を超えた場合にだけ課金されると書いたうえで、Photorealistic 3D Tiles(Map Tiles API)とPlaces APIの料金を確認するよう指示しています。見積もりの対象はGoogle Maps Platform側なので、金額はMaps Platformの最新の料金ページで確かめてください。SDKだけでアンカーとStreetscape Geometryを使う構成なら、見るべき数字は課金額ではなく上の上限です。
導入手順:Google Cloudの認可設定と主要SDKの現行版
実装ではGoogle Cloudの認可設定に加え、端末の対応確認、正確な位置情報の実行時権限、端末データ利用への同意表示が必要です。認可設定を省くと、ビルドが通ってもGeospatialのサービスを利用できません。
AndroidとiOSで異なるKeyless認可の設定
Google Cloudのプロジェクトで「ARCore API」を有効にします。認可方式はKeyless authorizationとAPIキー方式です。AndroidのKeyless authorizationは、アプリのパッケージ名と署名証明書のSHA-1フィンガープリントを登録したOAuth 2.0クライアントIDを使い、自前のJWT署名サーバは不要です。Androidではバックエンドの有無にかかわらず、公式が推奨するKeyless authorizationを第一候補にします。デバッグ用とリリース用で署名証明書が異なる場合は、それぞれに対応するOAuth 2.0クライアントIDを登録します。iOSのKeyless authorizationは仕組みが違い、サービスアカウントの鍵で署名したJWTをアプリに渡すため、トークンに署名する自前のサーバが必要です(iOSの認可ガイド)。サーバを持てないiOSアプリはAPIキー方式になり、キーにアプリの制限をかけます。Androidアプリでは play-services-location のバージョン16以上を宣言します。端末はARCore認定機種であることに加え、Geospatial APIの要件を満たす磁力計が必要です。
主要SDKの現行版と最近の変更
| SDK | 現行版 | 公開日 |
|---|---|---|
| ARCore SDK for Android | 1.57.0 | 2026-10-16 |
| ARCore SDK for iOS | 1.57.1 | 2026-10-28 |
| ARCore Extensions for AR Foundation | 1.57.0 | 2026-10-16 |
| ARCore for Jetpack XR | 1.0.0 | 2026-10-21 |
従来のARCore SDKで注意が要るのは1.56.0です。ARCoreの targetSdkVersion がAPIレベル37に上がり、アプリ側で指定していないとマニフェストのマージで37になります。1.57.0のAndroid版はサンプルのビルド設定の更新だけです。iOS版の1.57.1は、Swift Package ManagerでCloudAnchorsのチェックサムが合わない不具合の修正です。
Android XR向けJetpack XR版との違いと定数の書き分け
同じ「Geospatial API」の名前で、従来のARCore SDKとJetpack XRのAPIが並んでいます。Jetpack XR側にも対応モバイル端末のPlay Servicesランタイムがあるため、端末種別だけでなくパッケージ名と対応ランタイムで区別します。com.google.ar.core が従来のARCore SDK、androidx.xr.arcore がAndroid XR向けに始まったARCore for Jetpack XRです。後者はリリースノートのとおり2026年10月21日に1.0.0として安定版になり、主な機能としてVPSを使うGeospatialの姿勢取得が挙がっています。
| 項目 | ARCore SDK | Jetpack XR 1.0.0 |
|---|---|---|
| パッケージ | com.google.ar.core | androidx.xr.arcore |
| GeospatialMode | DISABLED / ENABLED | DISABLED / SPATIAL / INERTIAL |
| 可用性の確認 | checkVpsAvailabilityAsync | Geospatial.checkVpsAvailability |
Jetpack XR版では、alpha14(2026年5月19日)で VPS_AND_GPS が非推奨になり、1.0.0の GeospatialMode は上の3値です。INERTIAL はIMUとGPSだけで測位する低消費電力モードで、対応ランタイムはProjected(グラス型端末)だけです。いったん SPATIAL で初期化してから切り替えます。Jetpack XR向けのサンプルを従来のARCore SDKのコードに写すと、SPATIAL が解決できずにビルドが止まります。パッケージ名で見分けてください。
開発版の1.1.0-alpha01(同日公開)では、Geospatialの状態に horizontalAccuracy・verticalAccuracy・orientationYawAccuracy が加わりました。従来のARCore SDKで取れていた精度値が、Jetpack XR側でも揃いつつあります。ブラウザで同じような体験を作れるかは、WebXRの対応ブラウザと機能の範囲を先に確認してください。
採用を見送るべき条件
次のどれかに当てはまるなら、Geospatial APIを軸にした企画は組まないでください。
- 主な利用場所が屋内。VPSが効かないので、代替の位置合わせを最初から設計することになります。
- オフライン動作が要件。
ERROR_NETWORK_CONNECTIONが定義されているとおり、VPSはネットワーク接続が前提です。 - 建物の形状精度に体験が依存する。LOD2でも煙突や換気口はメッシュ外に出ます。
- 本当の要件が地図表示・経路検索・位置の追跡で、AR表現は飾り。この場合はAmazon Location Serviceのような地図基盤のほうが要件に合います。
国内の前例にも注意が要ります。日本語で参照される代表的な検証は、NTTコノキューが2023年5月11日に公表したStreetscape Geometryの技術検証ですが、資料自体がアプリ実装の時期を未定としており、コノキューは2026年3月31日に解散しています(XR事業はNTTドコモへ移管)。前例を根拠に社内を説得するより、対象エリアでVPSの可用性を実測したプロトタイプを先に見せるほうが早く結論に届きます。Android・iOSの両方で位置連動ARアプリを作るときは、スマホアプリ開発の段階でエリア実測を工程に組み込んでおくと手戻りが減ります。
よくある質問
Geospatial APIとは何ですか?
ARCoreの機能の一つで、端末のセンサーとGPSに加え、ストリートビュー由来のVPSを使って端末の位置と向きを緯度・経度・高度で求めるAPIです。求めた座標にWGS84・Terrain・Rooftopの3種類のアンカーでARコンテンツを固定できます。VPSが効く場所の公称精度は位置が5m未満(多くは1m前後)、回転が5度未満です。
Geospatial APIの料金はいくらですか?
ARCore APIの利用自体に請求は発生せず、料金表もありません。示されているのは1分あたり1,000セッションの開始または100,000リクエストという上限です。Geospatial Creatorを使う構成では、Map Tiles APIやPlaces APIの利用量が無償枠を超えた場合に、Google Maps Platform側で課金されます。
Geospatial APIはiPhoneでも使えますか?
使えます。ARCore SDK for iOSがGeospatial APIに対応しており、現行版は2026年10月28日公開の1.57.1です。Swift Package Managerで入れる場合、1.57系のパッケージ定義は対応OSをiOS 15以上にしています。UnityならARCore Extensions for AR Foundationで、AndroidとiOSを同じプロジェクトで扱えます。
対応エリアの一覧はどこかで確認できますか?
一覧は公開されていません。checkVpsAvailabilityAsync に緯度経度を渡すと AVAILABLE か UNAVAILABLE などが返るので、候補地点を並べて照会します。屋内や車両が入れない私道は外れやすい前提で設計してください。
ARのオクルージョンはGeospatial APIだけで作れますか?
屋外の建物を使うオクルージョンなら作れます。Streetscape Geometryで建物メッシュを取り、メッシュを深度として描画するか、Depth APIと組み合わせるGeospatial Depthで約65m先までの深度画像を得ます。Streetscape Geometryが返すのは建物と地形なので、人や車など動く物の前後関係は通常のDepth APIで扱います。