![](https://developers.google.com/static/ar/develop/geospatial/images/hero-streetscape-geometry-eiffel-tower.jpg)

The Streetscape Geometry APIs provide the geometry of terrain, buildings, or other structures in a scene. The geometry can be used for occlusion, rendering, or placing AR content via hit-test APIs. Streetscape Geometry data is obtained through Google Street View imagery.

## Try the sample

The [Geospatial sample app](https://github.com/google-ar/arcore-unity-extensions/tree/master/Samples~/Geospatial) demonstrates how to obtain and render Streetscape Geometries.

## Set up the Geospatial API

To use Streetscape Geometry, you'll need to set up the Geospatial API in your project.
Follow instructions on [Enabling the Geospatial API](https://developers.google.com/ar/develop/unity-arf/geospatial/enable) to set up the Geospatial API.

## Enable Streetscape Geometry

The Geospatial API obtains Streetscape Geometry data when the [`GeospatialMode`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#geospatialmode) is set to [`GeospatialMode.Enabled`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#geospatialmode_enabled) and [`StreetscapeGeometryMode`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#streetscapegeometrymode) is set to [`StreetscapeGeometryMode.Enabled`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#streetscapegeometrymode_enabled).

![](https://developers.google.com/static/ar/develop/unity-arf/geospatial/images/enable-streetscape-geometry.png)

## Obtain Streetscape Geometry in an ARCore session

Add an [`ARStreetscapeGeometryManager`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometryManager) component to a `GameObject`. When Streetscape Geometries are added, updated, or removed, the [`ARStreetscapeGeometryManager.StreetscapeGeometriesChanged`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometryManager#streetscapegeometrieschanged) event is triggered.

<br />

    public Material streetscapeGeometryMaterial;

    List<ARStreetscapeGeometry> _addedStreetscapeGeometries = new List<ARStreetscapeGeometry>();
    List<ARStreetscapeGeometry> _updatedStreetscapeGeometries = new List<ARStreetscapeGeometry>();
    List<ARStreetscapeGeometry> _removedStreetscapeGeometries = new List<ARStreetscapeGeometry>();

    public void OnEnable()
    {
        StreetscapeGeometryManager.StreetscapeGeometriesChanged +=
            GetStreetscapeGeometry;
    }

    public void Update() {
      foreach (ARStreetscapeGeometry streetscapegeometry in _addedStreetscapeGeometries)
      {
        GameObject renderObject = new GameObject(
           "StreetscapeGeometryMesh", typeof(MeshFilter), typeof(MeshRenderer));

        if (renderObject)
        {
            renderObject.transform.position = streetscapegeometry.pose.position;
            renderObject.transform.rotation = streetscapegeometry.pose.rotation;
            renderObject.GetComponent<MeshFilter>().mesh = streetscapegeometry.mesh;
            renderObject.GetComponent<MeshRenderer>().material = streetscapeGeometryMaterial;
        }
      }
    }

    public void OnDisable()
    {
        StreetscapeGeometryManager.StreetscapeGeometriesChanged -=
            GetStreetscapeGeometry;
    }

    private void GetStreetscapeGeometry(ARStreetscapeGeometriesChangedEventArgs eventArgs)
    {
        _addedStreetscapeGeometries = eventArgs.Added;
        _updatedStreetscapeGeometries = eventArgs.Updated;
        _removedStreetscapeGeometries = eventArgs.Removed;
    }

## Understand [`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry)

[`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry) contains information about a building:

- [`ARStreetscapeGeometry.streetscapeGeometryType`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry#streetscapegeometrytype)  
  Identifies the StreetscapeGeometry as either terrain or a building.
- [`ARStreetscapeGeometry.mesh`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry#mesh)  
  Obtain a polygon [`Mesh`](https://docs.unity3d.com/ScriptReference/Mesh.html) that corresponds to this terrain or building.
- [`ARStreetscapeGeometry.quality`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry#quality)  
  Provides the quality of the mesh data. Levels of detail are described in the [CityGML 2.0 standard](https://portal.ogc.org/files/?artifact_id=16675).

### Building LOD 1

[`BuildingLOD1`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#streetscapegeometryquality_buildinglod1) consists of building footprints extruded upwards to a flat top. Building heights may be inaccurate.

![](https://developers.google.com/static/ar/develop/images/streetscape-geometry-lod1.png)

### Building LOD 2

[`BuildingLOD2`](https://developers.google.com/ar/reference/unity-arf/namespace/Google/XR/ARCoreExtensions#streetscapegeometryquality_buildinglod2) will have higher fidelity geometry. Mesh walls and roofs will more closely match the building's shape. Smaller features like chimneys or roof vents may still poke outside of the mesh.

![](https://developers.google.com/static/ar/develop/images/streetscape-geometry-lod2.png)

## Understand [`Mesh`](https://docs.unity3d.com/ScriptReference/Mesh.html)

[`Mesh`](https://docs.unity3d.com/ScriptReference/Mesh.html) is a polygon mesh representing a surface reconstruction of the Streetscape Geometry.

See [`Mesh`](https://docs.unity3d.com/ScriptReference/Mesh.html) and [`MeshRenderer`](https://docs.unity3d.com/Manual/class-MeshRenderer.html). Note that the normals are not calculated by default;
see [`Mesh.RecalculateNormals()`](https://docs.unity3d.com/ScriptReference/Mesh.RecalculateNormals.html) to calculate them.

## Attach AR content to a [`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry)

Use [`ARAnchorManager.AddAnchor()`](https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@4.2/api/UnityEngine.XR.ARFoundation.ARAnchorManager.html#UnityEngine_XR_ARFoundation_ARAnchorManager_AddAnchor_UnityEngine_Pose_) to create an anchor at a given pose near vertices in [`ARStreetscapeGeometry.mesh`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry#mesh). This anchor will inherit its tracking state from the parent [`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry).

<br />

### Perform a hit-test against [`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry)

[`ARRaycastManagerExtensions.RaycastStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARRaycastManagerExtensions#raycaststreetscapegeometry) can be used to hit-test against Streetscape Geometry. If intersections are found, [`XRRaycastHit`](https://docs.unity3d.com/Packages/com.unity.xr.arsubsystems@4.2/api/UnityEngine.XR.ARSubsystems.XRRaycastHit.html) contains pose information about the hit location as well as a reference to the [`ARStreetscapeGeometry`](https://developers.google.com/ar/reference/unity-arf/class/Google/XR/ARCoreExtensions/ARStreetscapeGeometry) which was hit. This Streetscape Geometry can be passed to [`ARAnchorManager.AddAnchor()`](https://docs.unity3d.com/Packages/com.unity.xr.arfoundation@4.2/api/UnityEngine.XR.ARFoundation.ARAnchorManager.html#UnityEngine_XR_ARFoundation_ARAnchorManager_AddAnchor_UnityEngine_Pose_) to create an anchor attached to it.

    Vector2 screenTapPosition = Input.GetTouch(0).position;
    List<XRRaycastHit> hitResults = new List<XRRaycastHit>();
    if (RaycastManager.RaycastStreetscapeGeometry(screenTapPosition, ref hitResults)){
      ARStreetscapeGeometry streetscapegeometry =
          StreetscapeGeometryManager.GetStreetscapeGeometry(hitResults[0].trackableId);
      if (streetscapegeometry != null)
      {
          ARAnchor anchor = StreetscapeGeometryManager.AttachAnchor(streetscapegeometry, hitResults[0].pose);
      }
    }

## Enable Geospatial Depth

[Geospatial Depth](https://developers.google.com/ar/develop/unity-arf/depth/geospatial-depth) combines Streetscape Geometry
with local sensor input to enhance depth data. When Geospatial Depth is enabled,
the output depth and raw depth images are modified to include rasterized Streetscape Geometry in addition to locally observed depth.
This may improve the accuracy of poses using Depth.