街景

请选择平台: Android iOS JavaScript

Google 街景提供整个覆盖区域内以指定道路为中心的 360 度全景视图。

这段视频展示了如何利用街景服务让您的用户在查看地图上的地址时获得身临其境般的体验,为他们提供有关其目的地或所关注的任何地点的实用背景信息。

通过 Google Maps Android API v2 提供的覆盖范围与您的 Android 设备上 Google 地图应用的覆盖范围相同。您可以在关于街景中阅读更多有关街景的内容,并通过交互地图查看支持的区域。

StreetViewPanorama 类可在您的应用中为街景全景图片建模。在您的界面中,全景图片由 StreetViewPanoramaFragmentStreetViewPanoramaView 对象表示。

代码示例

GitHub 上的 ApiDemos 代码库中有一些示例展示了如何使用街景:

Kotlin 示例

Java 示例

Maps SDK for Android 中的街景概述

Maps SDK for Android 提供了用于获取和处理 Google 街景中使用的图像的街景服务。图片以全景图片的形式返回。

每张街景全景图片都是一个或一组图片,提供以单个位置为中心的 360 度全景视图。图片符合等矩形投影(简易圆柱投影)的特点,包含 360 度的水平视角(完整环绕)和 180 度垂直视角(直上直下)。生成的 360 度全景图片定义了一个球面投影,其中图片包绕在该球面的二维表面上。

StreetViewPanorama 提供了一个查看器,以镜头为中心将全景图片渲染为一个球面。您可以通过操纵 StreetViewPanoramaCamera 来控制镜头的缩放级别和朝向(倾斜度和方向角)。

开始使用

设置项目

请按照入门指南设置一个 Maps SDK for Android 项目。

添加全景图片之前,检查是否可使用街景全景图片

Google Play 服务 SDK 客户端库提供了几个街景示例应用,您可以将它们导入项目,以其为基础开发应用。请参阅简介,获得有关导入示例应用的指导。

Maps SDK for Android 实用程序库是一个开源库,包含可用于各种应用的类。GitHub 代码库中包含街景元数据实用程序。此实用程序检查街景是否支持某个地点。在将街景全景图片添加到 Android 应用时,您可以调用此元数据实用程序,并且仅在响应为 OK 时添加街景全景图片,从而避免发生错误。

使用 API

请按照以下说明向 Android fragment 添加街景全景图片。这是向您的应用添加街景的最简单方法。然后阅读更多有关 fragment、视图和自定义全景图片的内容。

添加街景全景图片

请按照以下步骤添加如下例所示的街景全景图片:

街景全景图片演示

步骤简述:

  1. 向将用于处理街景全景图片的 Activity 添加一个 Fragment 对象。最简单的方法是向 Activity 的布局文件添加一个 <fragment> 元素。
  2. 实现 OnStreetViewPanoramaReadyCallback 接口并使用 onStreetViewPanoramaReady(StreetViewPanorama) 回调方法获取 StreetViewPanorama 对象的句柄。
  3. 对该 fragment 调用 getStreetViewPanoramaAsync() 以注册回调函数。

下面更详细地介绍了各个步骤。

添加 Fragment

向 activity 的布局文件添加一个 <fragment> 元素,以定义一个 Fragment 对象。在此元素中,将 class 属性设置为 com.google.android.gms.maps.StreetViewPanoramaFragment(或 SupportStreetViewPanoramaFragment)。

以下是一个布局文件中的 fragment 示例:

<fragment
    android:name="com.google.android.gms.maps.StreetViewPanoramaFragment"
    android:id="@+id/streetviewpanorama"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

添加街景代码

如需在应用内使用街景全景图片,您需要实现 OnStreetViewPanoramaReadyCallback 接口,并为 StreetViewPanoramaFragmentStreetViewPanoramaView 对象设置一个该回调函数的实例。本教程使用的是 StreetViewPanoramaFragment,因为这是向应用添加街景的最简单方法。第一步是实现回调接口:

Kotlin



class StreetViewActivity : AppCompatActivity(), OnStreetViewPanoramaReadyCallback {
    // ...
}

      

Java


class StreetViewActivity extends AppCompatActivity implements OnStreetViewPanoramaReadyCallback {
    // ...
}

      

在您的 ActivityonCreate() 方法中,将布局文件设置为内容视图。例如,如果布局文件的名称是 main.xml,请使用以下代码:

Kotlin



override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_street_view)
    val streetViewPanoramaFragment =
        supportFragmentManager
            .findFragmentById(R.id.street_view_panorama) as SupportStreetViewPanoramaFragment
    streetViewPanoramaFragment.getStreetViewPanoramaAsync(this)
}

      

Java


@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_street_view);
    SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
        (SupportStreetViewPanoramaFragment) getSupportFragmentManager()
            .findFragmentById(R.id.street_view_panorama);
    streetViewPanoramaFragment.getStreetViewPanoramaAsync(this);
}

      

调用 FragmentManager.findFragmentById() 并向其传递 <fragment> 元素的资源 ID,以此获取 fragment 的句柄。请注意,当您生成布局文件时,系统会自动将资源 ID R.id.streetviewpanorama 添加到 Android 项目中。

然后,使用 getStreetViewPanoramaAsync() 在该 fragment 上设置回调。

Kotlin



val streetViewPanoramaFragment =
    supportFragmentManager
        .findFragmentById(R.id.street_view_panorama) as SupportStreetViewPanoramaFragment
streetViewPanoramaFragment.getStreetViewPanoramaAsync(this)

      

Java


SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
    (SupportStreetViewPanoramaFragment) getSupportFragmentManager()
        .findFragmentById(R.id.street_view_panorama);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(this);

      

使用 onStreetViewPanoramaReady(StreetViewPanorama) 回调方法来检索可直接使用的 StreetViewPanorama 非 null 实例。

Kotlin



override fun onStreetViewPanoramaReady(streetViewPanorama: StreetViewPanorama) {
    val sanFrancisco = LatLng(37.754130, -122.447129)
    streetViewPanorama.setPosition(sanFrancisco)
}

      

Java


@Override
public void onStreetViewPanoramaReady(StreetViewPanorama streetViewPanorama) {
    LatLng sanFrancisco = new LatLng(37.754130, -122.447129);
    streetViewPanorama.setPosition(sanFrancisco);
}

      

有关配置初始状态的更多说明

与使用地图时不同,无法通过 XML 来配置街景全景图片的初始状态。不过,您可以通过传入包含所指定选项的 StreetViewPanoramaOptions 对象,以编程方式配置全景图片。

Kotlin



val sanFrancisco = LatLng(37.754130, -122.447129)
val view = StreetViewPanoramaView(
    this,
    StreetViewPanoramaOptions().position(sanFrancisco)
)

      

Java


LatLng sanFrancisco = new LatLng(37.754130, -122.447129);
StreetViewPanoramaView view = new StreetViewPanoramaView(this,
    new StreetViewPanoramaOptions().position(sanFrancisco));

      

有关 StreetViewPanoramaFragment 的更多说明

StreetViewPanoramaFragmentAndroid Fragment 类的子类,您可使用它在 Android Fragment 中放置街景全景图片。StreetViewPanoramaFragment 对象充当全景图片的容器,并提供对 StreetViewPanorama 对象的访问权限。

StreetViewPanoramaView

StreetViewPanoramaView 是 Android View 类的子类,您可以使用它在 Android View 中放置街景全景图片。View 表示屏幕的某个矩形区域,是 Android 应用和 widget 的基本构建块。与 StreetViewPanoramaFragment 类似,StreetViewPanoramaView 也充当全景图片的容器,通过 StreetViewPanorama 对象公开核心功能。此类的用户必须将所有 activity 生命周期方法(例如 onCreate()onDestroy()onResume()onPause()))都转发给 StreetViewPanoramaView 类中的相应方法。

自定义由用户控制的功能

默认情况下,用户在查看街景全景图片时可使用以下功能:平移、缩放和前往相邻全景图片。您可以通过 StreetViewPanorama 中的方法启用和停用由用户控制的手势。停用手势时,仍可通过编程方式做出更改。

设置全景图片的位置

如需设置街景全景图片的位置,请调用 StreetViewPanorama.setPosition() 并传递 LatLng。您还可以将 radiussource 作为可选参数传递。

如果您想扩大或缩小街景在其中寻找匹配全景图片的区域,就可以使用半径。半径为 0 意味着必须将全景图片链接到指定 LatLng 所在的确切位置。默认半径为 50 米。如果匹配区域中有多幅全景图片,API 将返回匹配度最高的全景图片。

如果您希望限制街景,以便仅查找室外全景图片,就可以使用来源。默认情况下,可以查看博物馆、公共建筑、咖啡馆和商家等室内地点的街景全景图片。请注意,指定位置可能不存在室外全景图片。

Kotlin



val sanFrancisco = LatLng(37.754130, -122.447129)

// Set position with LatLng only.
streetViewPanorama.setPosition(sanFrancisco)

// Set position with LatLng and radius.
streetViewPanorama.setPosition(sanFrancisco, 20)

// Set position with LatLng and source.
streetViewPanorama.setPosition(sanFrancisco, StreetViewSource.OUTDOOR)

// Set position with LaLng, radius and source.
streetViewPanorama.setPosition(sanFrancisco, 20, StreetViewSource.OUTDOOR)

      

Java


LatLng sanFrancisco = new LatLng(37.754130, -122.447129);

// Set position with LatLng only.
streetViewPanorama.setPosition(sanFrancisco);

// Set position with LatLng and radius.
streetViewPanorama.setPosition(sanFrancisco, 20);

// Set position with LatLng and source.
streetViewPanorama.setPosition(sanFrancisco, StreetViewSource.OUTDOOR);

// Set position with LaLng, radius and source.
streetViewPanorama.setPosition(sanFrancisco, 20, StreetViewSource.OUTDOOR);

      

此外,您还可以通过向 StreetViewPanorama.setPosition() 传递 panoId,根据全景图片 ID 设置位置。

要检索相邻全景图片的全景图片 ID,请先使用 getLocation() 检索 StreetViewPanoramaLocation。该对象包含当前全景图片的 ID 和一个 StreetViewPanoramaLink 对象数组,其中的每个对象都包含与当前全景图片相关联的某个全景图片的 ID。

Kotlin



streetViewPanorama.location.links.firstOrNull()?.let { link: StreetViewPanoramaLink ->
    streetViewPanorama.setPosition(link.panoId)
}

      

Java


StreetViewPanoramaLocation location = streetViewPanorama.getLocation();
if (location != null && location.links != null) {
    streetViewPanorama.setPosition(location.links[0].panoId);
}

      

放大和缩小

您可以通过设置 StreetViewPanoramaCamera.zoom 以编程方式更改缩放级别。将缩放级别设置为 1.0 会将图片放大 2 倍。

下面这段代码使用 StreetViewPanoramaCamera.Builder() 构建一个新的镜头,该镜头具有现有镜头的倾斜度和方向角,但将缩放级别增加了 50%。

Kotlin



val zoomBy = 0.5f
val camera = StreetViewPanoramaCamera.Builder()
    .zoom(streetViewPanorama.panoramaCamera.zoom + zoomBy)
    .tilt(streetViewPanorama.panoramaCamera.tilt)
    .bearing(streetViewPanorama.panoramaCamera.bearing)
    .build()

      

Java


float zoomBy = 0.5f;
StreetViewPanoramaCamera camera = new StreetViewPanoramaCamera.Builder()
    .zoom(streetViewPanorama.getPanoramaCamera().zoom + zoomBy)
    .tilt(streetViewPanorama.getPanoramaCamera().tilt)
    .bearing(streetViewPanorama.getPanoramaCamera().bearing)
    .build();

      

设置镜头朝向(视角)

您可以通过在 StreetViewPanoramaCamera 上设置方向角和倾斜度来确定街景镜头的朝向。

方向角
镜头指向的方向,以与镜头所在点正北方所呈顺时针角度表示。正北方为 0,东方为 90,南方为 180,西方为 270。
倾斜度
Y 轴上倾或下倾角度。范围是 -90 至 0 至 90,-90 为垂直俯视,0 为水平居中,90 为垂直仰视。这是相对于镜头的初始默认倾斜度测得的差值,初始默认倾斜度通常(但并不总是)为水平。例如,在小山上拍摄的图片的默认倾斜度多半并非水平。

下面这段代码使用 StreetViewPanoramaCamera.Builder() 构建一个新的镜头,该镜头具有现有镜头的缩放级别和倾斜度,但将方向角向左调整了 30 度。

Kotlin



val panBy = 30f
val camera = StreetViewPanoramaCamera.Builder()
    .zoom(streetViewPanorama.panoramaCamera.zoom)
    .tilt(streetViewPanorama.panoramaCamera.tilt)
    .bearing(streetViewPanorama.panoramaCamera.bearing - panBy)
    .build()

      

Java


float panBy = 30;
StreetViewPanoramaCamera camera = new StreetViewPanoramaCamera.Builder()
    .zoom(streetViewPanorama.getPanoramaCamera().zoom)
    .tilt(streetViewPanorama.getPanoramaCamera().tilt)
    .bearing(streetViewPanorama.getPanoramaCamera().bearing - panBy)
    .build();

      

下面这段代码可使镜头向上倾斜 30 度。

Kotlin



var tilt = streetViewPanorama.panoramaCamera.tilt + 30
tilt = if (tilt > 90) 90f else tilt
val previous = streetViewPanorama.panoramaCamera
val camera = StreetViewPanoramaCamera.Builder(previous)
    .tilt(tilt)
    .build()

      

Java


float tilt = streetViewPanorama.getPanoramaCamera().tilt + 30;
tilt = (tilt > 90) ? 90 : tilt;

StreetViewPanoramaCamera previous = streetViewPanorama.getPanoramaCamera();

StreetViewPanoramaCamera camera = new StreetViewPanoramaCamera.Builder(previous)
    .tilt(tilt)
    .build();

      

为镜头移动添加动画效果

要为镜头移动添加动画效果,请调用 StreetViewPanorama.animateTo()。动画会插入当前镜头属性和新的镜头属性之间。如果您想直接完成镜头切换而不使用动画,可以将持续时间设置为 0。

Kotlin



// Keeping the zoom and tilt. Animate bearing by 60 degrees in 1000 milliseconds.
val duration: Long = 1000
val camera = StreetViewPanoramaCamera.Builder()
    .zoom(streetViewPanorama.panoramaCamera.zoom)
    .tilt(streetViewPanorama.panoramaCamera.tilt)
    .bearing(streetViewPanorama.panoramaCamera.bearing - 60)
    .build()
streetViewPanorama.animateTo(camera, duration)

      

Java


// Keeping the zoom and tilt. Animate bearing by 60 degrees in 1000 milliseconds.
long duration = 1000;
StreetViewPanoramaCamera camera =
    new StreetViewPanoramaCamera.Builder()
        .zoom(streetViewPanorama.getPanoramaCamera().zoom)
        .tilt(streetViewPanorama.getPanoramaCamera().tilt)
        .bearing(streetViewPanorama.getPanoramaCamera().bearing - 60)
        .build();
streetViewPanorama.animateTo(camera, duration);

      

如果使用 Handler.postDelayed() 让上述动画每 2,000 毫秒运行一次,效果如下图所示:

街景全景图片动画演示