地理定位请求和响应

地理位置请求

使用 POST 将地理位置请求发送到以下网址:

https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY

您必须在请求中指定一个密钥,并将其作为 key 参数的值。key 是应用的 API 密钥。此密钥用于标识您的应用,以便进行配额管理。了解如何获取密钥。

请求正文

请求正文必须采用 JSON 格式。如果未包含请求正文,系统会根据请求位置的 IP 地址返回结果。支持以下字段,除非另有说明,否则所有字段均为可选字段:

字段 JSON 类型 说明 备注
homeMobileCountryCode number (uint32) 设备家庭网络的移动设备国家/地区代码 (MCC)。 radioType gsm(默认)、wcdma、lte 和 nr 支持;cdma 不使用。
有效范围:0–999。
homeMobileNetworkCode number (uint32) 设备家庭网络的移动网络代码。 这是 GSM、WCDMA、LTE 和 NR 的 MNC。
CDMA 使用系统 ID (SID)
MNC 的有效范围:0-999。
SID 的有效范围:0–32767。
radioType string 移动无线网络类型。支持的值包括 gsm、cdma、wcdma、lte 和 nr。 虽然此字段是可选字段,但如果客户端知道无线装置类型,则应始终包含此字段。
如果省略该字段,Geolocation API 会默认使用 gsm,如果假设的无线电类型不正确,将导致结果无效或没有结果。
carrier string 运营商名称。
considerIp boolean 指定在 Wi-Fi 和手机基站信号缺失、为空或不足以估算设备位置时,是否回退到 IP 地理定位。 默认为 true。将 considerIp 设置为 false 以防止回退。
cellTowers array 由手机基站对象组成的数组。 请参阅下文的手机基站对象部分。
wifiAccessPoints array WLAN 接入点对象的数组。 请参阅下文的 Wi-Fi 接入点对象部分。

下面是一个 Geolocation API 请求正文示例。

{
  "homeMobileCountryCode": 310,
  "homeMobileNetworkCode": 410,
  "radioType": "lte",
  "carrier": "Vodafone",
  "considerIp": true,
  "cellTowers": [
    // See the Cell Tower Objects section below.
  ],
  "wifiAccessPoints": [
    // See the WiFi Access Point Objects section below.
  ]
}

手机基站对象

请求正文的 cellTowers 数组包含零个或多个手机基站对象。

字段 JSON 类型 说明 备注
cellId number (uint32) 小区的唯一标识符。 对于 radioType gsm(默认)、cdma、wcdma 和 lte,此属性为必需;对于 nr,此属性不适用。
请参阅下面的计算 cellId 部分,其中还列出了每种无线装置类型的有效值范围。
newRadioCellId number (uint64) NR (5G) 小区的唯一标识符。 radioType nr 必须提供;其他类型拒绝提供。
请参阅下文中的计算 newRadioCellId 部分,其中还列出了该字段的有效值范围。
locationAreaCode number (uint32) GSM 和 WCDMA 网络的位置区域代码 (LAC)。
CDMA 网络的网络 ID (NID)。
LTE 和 NR 网络的跟踪区域代码 (TAC)。
对于 radioType gsm(默认)和 cdma,此属性为必需属性;对于其他值,此属性为可选属性。
gsm、cdma、wcdma 和 lte 的有效范围:0–65535。
nr 的有效范围:0–16777215。
mobileCountryCode number (uint32) 手机基站的移动设备国家/地区代码 (MCC)。 对于 radioType gsm(默认)、wcdma、lte 和 nr,此参数为必需;对于 cdma,此参数不使用。
有效范围:0–999。
mobileNetworkCode number (uint32) 手机基站的移动网络代码。 这是 GSM、WCDMA、LTE 和 NR 的 MNC。
CDMA 使用系统 ID (SID)。
必填。
MNC 的有效范围:0-999。
SID 的有效范围:0–32767。

以下可选字段不使用,但如果值可用,则可以包含。

字段 JSON 类型 说明 备注
age number (uint32) 自从此小区成为主小区后经过的毫秒数。 如果年龄为 0,则 cellId 或 newRadioCellId 表示当前测量值。
signalStrength number (double) 测量到的无线信号强度(以 dBm 为单位)。
timingAdvance number (double) 时间提前量值。

正在计算 cellId

NR (5G) 之前的无线装置类型使用 32 位 cellId 字段将网络小区 ID 传递给 Geolocation API。

  • GSM (2G) 网络按原样使用 16 位小区 ID (CID)。有效范围:0-65535。
  • CDMA (2G) 网络按原样使用 16 位基站 ID (BID)。有效范围:0-65535。
  • WCDMA (3G) 网络使用 UTRAN/GERAN 小区标识 (UC-ID),这是一个 28 位整数值,由 12 位无线网络控制器标识符 (RNC-ID) 和 16 位小区 ID (CID) 串联而成。
    公式:rnc_id << 16 | cid。
    有效范围:0–268435455。
    注意:在 WCDMA 网络中,如果仅指定 16 位小区 ID 值,会导致结果不正确或结果为零。
  • LTE (4G) 网络使用 E-UTRAN 小区标识 (ECI),这是一个 28 位整数值,由 20 位 E-UTRAN Node B 标识符 (eNBId) 和 8 位小区 ID (CID) 串联而成。
    公式:enb_id << 8 | cid。
    有效范围:0–268435455。
    注意:在 LTE 网络中,如果仅指定 8 位小区 ID 值,会导致结果不正确或为零。

在 API 请求中放置超出这些范围的值可能会导致未定义的行为。API 可能会自行决定截断该数字,使其符合文档中规定的范围,推断对 radioType 的更正,或返回 NOT_FOUND 结果,而不在响应中提供任何指示。

以下是一个 LTE 手机基站对象示例,它是请求正文的一部分。

{
  ...

  "cellTowers": [
    {
      "cellId": 170402199,
      "locationAreaCode": 35632,
      "mobileCountryCode": 310,
      "mobileNetworkCode": 410,
      "age": 0,
      "signalStrength": -60,
      "timingAdvance": 15
    }
  ]
}

上述请求的响应如下所示:

{
  "location": {
    "lat": 37.7801129,
    "lng": -122.4168229
  },
  "accuracy": 180.052
}

正在计算 newRadioCellId

较新的网络(其基站 ID 超过 32 位)使用 64 位 newRadioCellId 字段将网络基站 ID 传递给 Geolocation API。

  • NR (5G) 网络按原样使用 36 位新无线电小区标识 (NCI)。
    有效范围:0–68719476735。

以下是一个示例 NR 手机基站对象,它是请求正文的一部分。

{
  ...

  "cellTowers": [
    {
      "newRadioCellId": 68719476735,
      "mobileCountryCode": 310,
      "mobileNetworkCode": 410,
      "age": 0,
      "signalStrength": -60,
    }
  ]
}

对上述请求的响应如下所示:

{
  "location": {
    "lat": 37.7646157,
    "lng": -122.4127361
  },
  "accuracy": 1458.5570522410717
}

WLAN 接入点对象

请求正文的 wifiAccessPoints 数组必须包含两个或更多个 Wi-Fi 接入点对象,这些对象代表物理上不同的固定接入点设备。macAddress 字段是必填字段。所有其他字段都是选填字段。该服务会忽略移动的接入点,例如飞机和火车上的接入点。

字段 JSON 类型 说明 备注
macAddress string Wi-Fi 节点的 MAC 地址。通常称为 BSS、BSSID 或 MAC 地址。 必需。以英文冒号分隔 (:) 的十六进制字符串。
只有通用管理的 MAC 地址可以使用该 API 进行定位。其他 MAC 地址会被静默丢弃,并可能导致 API 请求实际上变为空。如需了解详情,请参阅丢弃无用的 Wi-Fi 接入点。
signalStrength number (double) 测量到的当前信号强度(以 dBm 为单位)。 对于 Wi-Fi 接入点,dBm 值通常为 -35 或更低,范围为 -128 到 -10 dBm。 请务必添加减号。
对于大于 -10 dBm 的值,API 会返回 NOT FOUND。
age number (uint32) 自从检测到此接入点后经过的毫秒数。
channel number (uint32) 客户端与接入点进行通信的信道。
signalToNoiseRatio number (double) 当前信噪比(以 dB 为单位)。

下面显示了一个示例 Wi-Fi 接入点对象,它是请求正文的一部分。

{
  ...
  
  "macAddress": "f0:d5:bf:fd:12:ae",
  "signalStrength": -43,
  "signalToNoiseRatio": 0,
  "channel": 11,
  "age": 0
}

上述请求的响应如下所示:

{
  "location": {
    "lat": 37.7801129,
    "lng": -122.4168229
  },
  "accuracy": 180.052
}

采样请求

如果您想使用示例数据试用 Geolocation API,请将以下 JSON 保存到文件中:

{
  "considerIp": "false",
  "wifiAccessPoints": [
    {
      "macAddress": "3c:37:86:5d:75:d4",
      "signalStrength": -35,
      "signalToNoiseRatio": 0
    },
    {
      "macAddress": "30:86:2d:c4:29:d0",
      "signalStrength": -35,
      "signalToNoiseRatio": 0
    }
  ]
}

然后,您可以使用 curl 从命令行发出请求:

$ curl -d @your_filename.json -H "Content-Type: application/json" -i "https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY"

上述 MAC 地址的响应如下所示:

{
  "location": {
    "lat": 37.4241173,
    "lng": -122.0915717
  },
  "accuracy": 20
}

丢弃未使用的 Wi-Fi 接入点

移除 macAddress 为广播地址 (FF:FF:FF:FF:FF:FF) 或由 IANA 保留的 Wi-Fi 接入点对象,可以提高使用 Wi-Fi 作为输入的 Geolocation API 调用的成功率。如果在过滤后可以确定 Geolocation API 调用不会成功,则可以采取缓解措施,例如使用较旧的位置信号或信号较弱的 Wi-Fi AP。这种方法需要在应用对位置估算的需求与其精确率和召回率要求之间进行权衡。以下过滤技术演示了如何过滤输入,但未显示您作为应用工程师可能选择应用的缓解措施。

00:00:5E:00:00:00 到 00:00:5E:FF:FF:FF 之间的 MAC 地址范围为 IANA 保留,通常用于网络管理和多播功能,因此无法用作位置信号。您还应从 API 的输入中移除这些 MAC 地址。

例如,可从名为 macs 的 macAddress 字符串数组中收集可用于地理定位的 MAC 地址:

Java
String[] macs = {"ff:ff:ff:ff:ff:ff", "1c:34:56:78:9a:bc", "00:00:5e:00:00:01"};
ArrayList<String> _macs = new ArrayList<>(Arrays.asList(macs));
_macs.removeIf(m -> !(!m.toUpperCase().equals("FF:FF:FF:FF:FF:FF")
                      && !m.substring(0, 8).toUpperCase().equals("00:00:5E")));
    
Python
macs = ['ff:ff:ff:ff:ff:ff', '1c:34:56:78:9a:bc', '00:00:5e:00:00:01']
macs = [m for m in macs if (m.upper() != "FF:FF:FF:FF:FF:FF" and m[:8].upper() != '00:00:5E')]
    
JavaScript
macs = ['ff:ff:ff:ff:ff:ff', '1c:34:56:78:9a:bc', '00:00:5e:00:00:01'];
macs = macs.filter(m => m.toUpperCase() !== "FF:FF:FF:FF:FF:FF"
                        && m.substr(0, 8).toUpperCase() !== '00:00:5E');
    

使用此过滤条件后,列表中仅会保留 1c:34:56:78:9a:bc。由于此列表包含的 Wi-Fi MAC 地址少于 2 个,因此请求不会成功,并且会返回 HTTP 404 (notFound) 响应。

地理位置响应

成功的地理定位请求会返回一个 JSON 格式的响应,其中定义了位置和半径。

  • location:用户的估算纬度和经度坐标(以度为单位)。包含一个 lat 和一个 lng 子字段。
  • accuracy:估计位置的准确度(以米为单位)。这表示给定 location 周围圆圈的半径。
{
  "location": {
    "lat": 37.421875199999995,
    "lng": -122.0851173
  },
  "accuracy": 120
}

该 API 会根据输入信号返回位置和准确度半径。虽然该 API 可以返回高精确度的位置信息,但准确度可能会因可用信号的来源、数量、密度和强度而异。通常,您可以预期以下精确度半径:

  • Wi-Fi 接入点:如果请求包含两个或更多 wifiAccessPoints,则返回的准确度半径通常约为 20 米。准确性会随着接入点数量的增加和信号强度的增强(以 dBm 为单位)而提高,信号强度通常在 -100 到 -20 dBm 之间。
  • 手机基站:如果 Wi-Fi 信息不可用或不充分,API 会使用 cellTowers 来确定位置。准确性因手机基站类型、信号强度和网络密度而异:
    • 宏小区(最常见的类型,用于广域覆盖)提供的准确度较低。半径通常在几百米范围内,在手机基站覆盖范围稀疏的区域,半径可达几千米。对于宏小区,其精度半径通常不会低于 100 米。对于信号较强的手机基站,准确度通常较高。强信号通常为:LTE > -110 dBm(信号范围为 -140 至 -55 dBm)、WCDMA > -100 dBm(信号范围为 -111 至 -53 dBm)、CDMA > -100 dBm(信号范围为 -120 至 -40 dBm)以及 GSM > -80 dBm(信号范围为 -121 至 -1 dBm)。
    • 小型基站(例如毫微微蜂窝基站、微微蜂窝基站或室内中继器)可提供最精确的基于基站的位置信息,其精确度半径可在 10-30 米范围内。
  • IP 地理定位:如果 considerIp 为 true,并且无法对任何 Wi-Fi 或手机基站信号进行地理定位,则该 API 会根据请求的 IP 地址估算位置。此方法提供的准确度最低,半径可能达到数千米。请参阅为什么精确度半径非常大? 问题排查指南中的说明。