跳到主要内容
实操指南8 分钟阅读

如何通过官方 API 获取谷歌街景影像

官方路径是两个 HTTP 端点:免费的覆盖查询,再为每个需要的朝向请求一张计费 JPEG。够做试点;城市级采样是另一件事。

作者
HuiTu Technology
发布时间
更新时间

如果你要把谷歌街景当成数据来用——而不是在地图上手动拖着看——受支持的路径是 Street View Static API。它是一套 HTTP 影像服务:你提交位置和相机参数,Google 返回一张 JPEG。没有文档化的 360° 原始文件批量导出,也没有许可去爬面向普通用户的街景网页。

本文讲的是小规模、范围明确的官方做法:两个端点各自做什么、哪些参数真的会改变画面、计费与条款如何约束存储,以及几十次请求到什么时候就不再是合适的工具。

两个端点,两件不同的事

Street View Static API 两个端点分别做什么
端点返回什么是否按影像计费
streetview/metadataJSON:status、吸附后的坐标、拍摄月份、pano_id、copyright否。Google 文档写明元数据免费,且不消耗影像配额。
streetview按你指定尺寸返回的透视 JPEG,最大 640 × 640 像素是。每次成功的影像请求按 Static Street View 计费。

务必先跑元数据。status 不是 OK,就没有图可取,也不该为一张灰色占位图付费。真正请求影像时,设置 return_error_code=true,让缺失以 HTTP 错误返回,而不是返回一张流水线会照单全收的灰图。

一张图由哪些参数决定

影像请求就是一条 URL。必填的是 API 密钥、尺寸,以及 location(地址或经纬度)或全景 ID 二者之一。可选的相机参数决定 JPEG 实际拍到什么。

  • location 或 pano:搜索原点。用坐标时,接口在半径内(默认 50 米)找最近的全景。全景 ID 会随时间变化;若日后要刷新,应保存坐标而不是 ID。
  • size:宽 × 高,该接口上限为 640 × 640 像素。
  • heading:罗盘朝向,0–360。研究里常用四个朝向(0°、90°、180°、270°),避免单一镜头方向决定这条街有多绿、有多封闭。
  • fov:水平视场角,默认 90,最大 120。数值越小,看起来越像变焦。
  • pitch:相对采集车的俯仰,默认 0。没有特殊理由就保持接近水平;略微上仰会悄悄抬高天空占比。
  • source=outdoor:排除落在街道采样点附近的室内全景。
  • signature:对 URL 做数字签名。Google 建议使用;部分计费方案会要求。
import os
from urllib.parse import urlencode

import requests

KEY = os.environ["GOOGLE_MAPS_API_KEY"]  # never hard-code a key
META = "https://maps.googleapis.com/maps/api/streetview/metadata"
IMAGE = "https://maps.googleapis.com/maps/api/streetview"


def fetch_heading(lat, lon, heading, path):
    """Check coverage first, then request one billed perspective JPEG."""
    meta = requests.get(
        META,
        params={"location": f"{lat},{lon}", "source": "outdoor", "key": KEY},
        timeout=10,
    ).json()
    if meta.get("status") != "OK":
        return meta.get("status")

    params = {
        "location": f"{lat},{lon}",
        "size": "640x640",
        "heading": heading,
        "fov": 90,
        "pitch": 0,
        "source": "outdoor",
        "return_error_code": "true",
        "key": KEY,
    }
    response = requests.get(IMAGE, params=params, timeout=20)
    response.raise_for_status()
    with open(path, "wb") as handle:
        handle.write(response.content)
    return "OK"


# Example: one sample point, four compass headings
# fetch_heading(40.7536, -73.9804, 0, "heading-000.jpg")
print(urlencode({"size": "640x640", "heading": 90}))  # inspect query shape only
纽约第五大道的谷歌街景透视图,可见建筑、送货卡车、黄色出租车与行人
一个真实采样点上的一张计费 JPEG。Static API 返回的是这种透视裁切,不是可下载的等距柱状全景档案。

计费与吞吐

影像请求按 Static Street View SKU 按量计费。元数据是单独的 SKU,Google 列为免费。文档中的用量上限是每分钟 30,000 次查询;对研究脚本来说,真正卡住的通常是费用和条款,而不是这个上限。请打开结算、把密钥放在环境变量里,并在 Google Cloud 设好每日配额,避免循环跑飞。

这种方法适合做什么

  1. 少量点位:论文配图、方法附录,或给客户看的二十个样点。
  2. 只做覆盖与时效检查:只跑元数据,在为影像花钱之前先看全区情况。
  3. 每个点四个朝向,让分割模型看到的是可比较的街道,而不是碰巧拍到的一个角度。

这个规模你可以自己跑官方 API:一把密钥、一份坐标 CSV、先元数据再影像。真正费功夫的是采样设计,以及不要把不同拍摄月份混在一起。

做到城市级时该怎么办

整座城市的路网按 25 米采样、每点四个朝向,就是数万到数十万次影像请求,再加上重试、灰图校验、坐标吸附、年份控制和一份能把每个数字回溯到源影像的清单。这已经不是周末脚本,而是一次采集工程:配额与账单、采样几何、符合条款的存储,以及分析开始前的校验。

更多文章

继续阅读

下一步

比起了解方法,更想直接把事做完?

如果文章里描述的问题正好是你遇到的,把具体情况发来,我们会给出工作范围与固定报价。