Yêu cầu và phản hồi vị trí địa lý

Yêu cầu định vị vị trí

Yêu cầu về vị trí địa lý được gửi bằng phương thức POST đến URL sau:

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

Bạn phải chỉ định một khoá trong yêu cầu, được đưa vào dưới dạng giá trị của tham số key. key là khoá API của ứng dụng. Khoá này giúp xác định ứng dụng của bạn cho mục đích quản lý hạn mức. Tìm hiểu cách lấy khoá.

Nội dung yêu cầu

Nội dung yêu cầu phải được định dạng dưới dạng JSON. Nếu không có nội dung yêu cầu, kết quả sẽ được trả về dựa trên địa chỉ IP của vị trí yêu cầu. Các trường sau đây được hỗ trợ và tất cả các trường đều không bắt buộc, trừ phi có quy định khác:

Trường Loại JSON Mô tả Ghi chú
homeMobileCountryCode number (uint32) Mã di động quốc gia (MCC) cho mạng gia đình của thiết bị. Được hỗ trợ cho radioType gsm (mặc định), wcdma, lte và nr; không dùng cho cdma.
Phạm vi hợp lệ: 0 – 999.
homeMobileNetworkCode number (uint32) Mã mạng di động cho mạng gia đình của thiết bị. Đây là MNC cho GSM, WCDMA, LTE và NR.
CDMA sử dụng Mã hệ thống (SID)
Phạm vi hợp lệ cho MNC: 0 – 999.
Phạm vi hợp lệ cho SID: 0–32767.
radioType string Loại sóng di động. Các giá trị được hỗ trợ là gsm, cdma, wcdma, lte và nr. Mặc dù trường này là không bắt buộc, nhưng bạn nên luôn đưa trường này vào nếu ứng dụng khách biết loại sóng vô tuyến.
Nếu bạn bỏ qua trường này, Geolocation API sẽ mặc định là gsm, sẽ dẫn đến kết quả không hợp lệ hoặc không có kết quả nếu loại sóng vô tuyến giả định không chính xác.
carrier string Tên hãng vận chuyển.
considerIp boolean Chỉ định xem có quay lại vị trí địa lý IP hay không nếu thiếu tín hiệu Wi-Fi và trạm phát sóng, trống hoặc không đủ để ước tính vị trí thiết bị. Giá trị mặc định là true. Đặt considerIp thành false để ngăn chặn việc quay lại.
cellTowers array Một mảng đối tượng trạm phát sóng. Hãy xem phần Đối tượng trạm phát sóng bên dưới.
wifiAccessPoints array Một mảng gồm các đối tượng điểm truy cập Wi-Fi. Hãy xem phần Đối tượng điểm truy cập Wi-Fi bên dưới.

Dưới đây là ví dụ về nội dung yêu cầu API của Geolocation.

{
  "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.
  ]
}

Đối tượng trạm phát sóng

Mảng cellTowers của nội dung yêu cầu chứa không hoặc nhiều đối tượng trạm phát sóng.

Trường Loại JSON Mô tả Ghi chú
cellId number (uint32) Giá trị nhận dạng riêng biệt của ô. Bắt buộc đối với radioType gsm (mặc định), cdma, wcdma và lte; bị từ chối đối với nr.
Hãy xem phần Tính toán cellId bên dưới, trong đó cũng liệt kê phạm vi giá trị hợp lệ cho từng loại sóng vô tuyến.
newRadioCellId number (uint64) Giá trị nhận dạng riêng biệt của ô NR (5G). Bắt buộc đối với radioType nr; bị từ chối đối với các loại khác.
Hãy xem phần Tính toán newRadioCellId bên dưới, phần này cũng liệt kê dải giá trị hợp lệ cho trường.
locationAreaCode number (uint32) Mã vùng vị trí (LAC) cho mạng GSM và WCDMA.
Mã mạng (NID) cho mạng CDMA.
Mã vùng theo dõi (TAC) cho mạng LTE và NR.
Bắt buộc đối với radioType gsm (mặc định) và cdma, không bắt buộc đối với các giá trị khác.
Phạm vi hợp lệ với gsm, cdma, wcdma và lte: 0–65535.
Phạm vi hợp lệ với nr: 0 – 16777215.
mobileCountryCode number (uint32) Mã di động quốc gia (MCC) của trạm phát sóng. Bắt buộc đối với radioType gsm (mặc định), wcdma, lte và nr; không dùng cho cdma.
Phạm vi hợp lệ: 0 – 999.
mobileNetworkCode number (uint32) Mã mạng di động của trạm phát sóng. Đây là MNC cho GSM, WCDMA, LTE và NR.
CDMA sử dụng Mã hệ thống (SID).
Bắt buộc.
Phạm vi hợp lệ cho MNC: 0 – 999.
Phạm vi hợp lệ cho SID: 0–32767.

Các trường không bắt buộc sau đây không được sử dụng, nhưng có thể được đưa vào nếu có giá trị.

Trường Loại JSON Mô tả Ghi chú
age number (uint32) Số mili giây kể từ khi ô này là ô chính. Nếu tuổi là 0, thì cellId hoặc newRadioCellId đại diện cho một phép đo hiện tại.
signalStrength number (double) Cường độ tín hiệu vô tuyến được đo bằng dBm.
timingAdvance number (double) Giá trị thời gian trước.

Đang tính cellId

Các loại sóng vô tuyến trước NR (5G) sử dụng trường cellId 32 bit để truyền mã nhận dạng ô mạng đến API Vị trí địa lý.

  • Mạng GSM (2G) sử dụng Mã nhận dạng ô (CID) 16 bit nguyên trạng. Phạm vi hợp lệ: 0–65535.
  • Mạng CDMA (2G) sử dụng Mã trạm gốc (BID) 16 bit nguyên trạng. Phạm vi hợp lệ: 0 – 65535.
  • Mạng WCDMA (3G) sử dụng Mã nhận dạng ô UTRAN/GERAN (UC-ID), là một giá trị số nguyên 28 bit nối Mã nhận dạng bộ điều khiển mạng vô tuyến (RNC-ID) 12 bit và Mã nhận dạng ô (CID) 16 bit.
    Công thức: rnc_id << 16 | cid.
    Phạm vi hợp lệ: 0 – 268435455.
    Lưu ý: Việc chỉ chỉ định giá trị Mã nhận dạng ô 16 bit trong mạng WCDMA sẽ dẫn đến kết quả không chính xác hoặc không có kết quả.
  • Mạng LTE (4G) sử dụng Mã nhận dạng ô E-UTRAN (ECI), là một giá trị số nguyên 28 bit nối Mã nhận dạng nút B E-UTRAN (eNBId) 20 bit và Mã nhận dạng ô (CID) 8 bit.
    Công thức: enb_id << 8 | cid.
    Phạm vi hợp lệ: 0 – 268435455.
    Lưu ý: Việc chỉ chỉ định giá trị Mã nhận dạng ô 8 bit trong mạng LTE sẽ dẫn đến kết quả không chính xác hoặc không có kết quả.

Việc đặt các giá trị nằm ngoài những phạm vi này trong yêu cầu API có thể dẫn đến hành vi không xác định. API, theo quyết định của Google, có thể cắt bớt số để số đó nằm trong phạm vi được ghi nhận, suy luận một giá trị điều chỉnh cho radioType hoặc trả về kết quả NOT_FOUND mà không có bất kỳ chỉ báo nào trong phản hồi.

Dưới đây là ví dụ về đối tượng trạm phát sóng LTE, là một phần của nội dung yêu cầu.

{
  ...

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

Phản hồi cho yêu cầu trước đó sẽ có dạng như sau:

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

Đang tính newRadioCellId

Các mạng mới hơn có mã nhận dạng trạm phát sóng dài hơn 32 bit sẽ sử dụng trường newRadioCellId 64 bit để truyền mã nhận dạng trạm phát sóng mạng đến API Định vị địa lý.

  • Mạng NR (5G) sử dụng Mã nhận dạng ô vô tuyến mới (NCI) 36 bit như hiện tại.
    Phạm vi hợp lệ: 0 – 68719476735.

Dưới đây là ví dụ về một đối tượng trạm phát sóng NR, là một phần của nội dung yêu cầu.

{
  ...

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

Phản hồi cho yêu cầu trước đó sẽ có dạng như sau:

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

Đối tượng điểm truy cập Wi-Fi

Mảng wifiAccessPoints của nội dung yêu cầu phải chứa ít nhất hai đối tượng điểm truy cập Wi-Fi đại diện cho các thiết bị điểm truy cập cố định khác biệt về mặt vật lý. Trường macAddress là trường bắt buộc. Tất cả các trường khác đều không bắt buộc. Dịch vụ này bỏ qua các điểm truy cập di chuyển, chẳng hạn như các điểm truy cập trên máy bay và tàu hoả.

Trường Loại JSON Mô tả Ghi chú
macAddress string Địa chỉ MAC của nút Wi-Fi. Thông thường, địa chỉ này được gọi là BSS, BSSID hoặc địa chỉ MAC. Bắt buộc.Chuỗi thập lục phân được phân tách bằng dấu hai chấm (:).
Chỉ có thể tìm thấy địa chỉ MAC được quản lý trên toàn hệ thống bằng API. Các địa chỉ MAC khác sẽ bị loại bỏ mà không có thông báo và có thể khiến yêu cầu API trở nên trống. Để biết thông tin chi tiết, hãy xem phần Bỏ qua các điểm truy cập Wi-Fi không hữu ích.
signalStrength number (double) Cường độ tín hiệu hiện tại được đo bằng dBm. Đối với điểm truy cập Wi-Fi, giá trị dBm thường là -35 trở xuống và nằm trong khoảng từ -128 đến -10 dBm. Hãy nhớ thêm dấu trừ.
Đối với các giá trị lớn hơn -10 dBm, API sẽ trả về NOT FOUND.
age number (uint32) Số mili giây kể từ khi phát hiện điểm truy cập này.
channel number (uint32) Kênh mà ứng dụng khách đang dùng để giao tiếp với điểm truy cập.
signalToNoiseRatio number (double) Tỷ lệ tín hiệu trên tạp âm hiện tại được đo bằng dB.

Ví dụ về đối tượng điểm truy cập Wi-Fi (một phần của nội dung yêu cầu) được trình bày dưới đây.

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

Phản hồi cho yêu cầu trước đó sẽ có dạng như sau:

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

Yêu cầu mẫu

Nếu bạn muốn dùng thử Geolocation API bằng dữ liệu mẫu, hãy lưu tệp JSON sau đây vào một tệp:

{
  "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
    }
  ]
}

Sau đó, bạn có thể sử dụng curl để đưa ra yêu cầu từ dòng lệnh:

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

Phản hồi cho các địa chỉ MAC trước đó sẽ có dạng như sau:

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

Bỏ các điểm truy cập Wi-Fi không dùng đến

Việc xoá các đối tượng điểm truy cập Wi-Fi có macAddress là địa chỉ truyền tin (FF:FF:FF:FF:FF:FF) hoặc do IANA đặt trước có thể cải thiện tỷ lệ thành công của các lệnh gọi API vị trí địa lý sử dụng Wi-Fi làm dữ liệu đầu vào. Nếu sau khi lọc, bạn xác định được rằng lệnh gọi API Vị trí địa lý sẽ không thành công, thì bạn có thể sử dụng các biện pháp giảm thiểu như dùng tín hiệu vị trí cũ hơn hoặc điểm truy cập Wi-Fi có tín hiệu yếu hơn. Cách tiếp cận này là sự đánh đổi giữa nhu cầu của ứng dụng về thông tin ước đoán vị trí và các yêu cầu về độ chính xác và độ ghi nhớ. Các kỹ thuật lọc sau đây minh hoạ cách lọc dữ liệu đầu vào, nhưng không cho thấy các biện pháp giảm thiểu mà bạn có thể chọn áp dụng với tư cách là kỹ sư ứng dụng.

Phạm vi địa chỉ MAC từ 00:00:5E:00:00:00 đến 00:00:5E:FF:FF:FF được dành riêng cho IANA và thường được dùng cho các chức năng quản lý mạng và multicast, nên không thể dùng làm tín hiệu vị trí. Bạn cũng nên xoá các địa chỉ MAC này khỏi dữ liệu đầu vào cho API.

Ví dụ: bạn có thể thu thập các địa chỉ MAC có thể sử dụng cho tính năng Định vị địa lý từ một mảng chuỗi macAddress có tên là macs:

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');
    

Khi sử dụng bộ lọc này, chỉ còn 1c:34:56:78:9a:bc trong danh sách. Vì danh sách này có ít hơn 2 địa chỉ MAC Wi-Fi, nên yêu cầu sẽ không thành công và hệ thống sẽ trả về phản hồi HTTP 404 (notFound).

Câu trả lời về vị trí địa lý

Yêu cầu định vị địa lý thành công sẽ trả về một phản hồi có định dạng JSON xác định vị trí và bán kính.

  • location: Toạ độ vĩ độ và kinh độ ước tính của người dùng, tính bằng độ. Chứa một trường phụ lat và một trường phụ lng.
  • accuracy: Độ chính xác của vị trí ước đoán, tính bằng mét. Giá trị này thể hiện bán kính của một hình tròn xung quanh location đã cho.
{
  "location": {
    "lat": 37.421875199999995,
    "lng": -122.0851173
  },
  "accuracy": 120
}

API này trả về một vị trí và bán kính chính xác dựa trên các tín hiệu đầu vào. Mặc dù API có thể trả về thông tin vị trí có độ chính xác cao, nhưng độ chính xác có thể thay đổi tuỳ thuộc vào nguồn, số lượng, mật độ và cường độ của tín hiệu có sẵn. Thông thường, bạn có thể thấy các bán kính chính xác sau:

  • Điểm truy cập Wi-Fi: Nếu yêu cầu bao gồm hai hoặc nhiều wifiAccessPoints, thì bán kính chính xác được trả về thường là khoảng 20 mét. Độ chính xác sẽ cải thiện theo số lượng điểm truy cập và tín hiệu mạnh hơn (đo bằng dBm), với cường độ tín hiệu thường nằm trong khoảng từ -100 đến -20 dBm.
  • Trạm phát sóng: Nếu thông tin Wi-Fi không có sẵn hoặc không đủ, API sẽ sử dụng cellTowers cho vị trí. Độ chính xác thay đổi đáng kể tuỳ theo loại trạm phát sóng, cường độ tín hiệu và mật độ mạng:
    • Trạm phát sóng vĩ mô (loại phổ biến nhất, dùng để phủ sóng diện rộng) có độ chính xác thấp hơn. Bán kính thường nằm trong phạm vi hàng trăm mét và có thể lên đến vài nghìn mét ở những khu vực có phạm vi phủ sóng thưa thớt của trạm phát sóng. Đối với các ô vĩ mô, việc đạt được bán kính chính xác dưới 100 mét là điều không phổ biến. Độ chính xác thường cao hơn đối với các trạm phát sóng có tín hiệu mạnh. Tín hiệu mạnh thường là > -110 dBm đối với LTE (phạm vi tín hiệu từ -140 đến -55 dBm), > -100 dBm đối với WCDMA (phạm vi tín hiệu từ -111 đến -53 dBm), > -100 dBm đối với CDMA (phạm vi tín hiệu từ -120 đến -40 dBm) và > -80 dBm đối với GSM (phạm vi tín hiệu từ -121 đến -1 dBm).
    • Các trạm phát sóng nhỏ (ví dụ: femtocell, picocell hoặc bộ lặp trong nhà) cung cấp vị trí chính xác nhất dựa trên trạm phát sóng, với bán kính chính xác có thể nằm trong phạm vi 10-30 mét.
  • Vị trí địa lý IP: Nếu considerIp là true và không có tín hiệu Wi-Fi hoặc trạm phát sóng nào có thể được định vị địa lý, thì API sẽ ước tính vị trí dựa trên địa chỉ IP của yêu cầu. Phương pháp này có độ chính xác thấp nhất, với bán kính có thể lên đến hàng nghìn mét. Hãy xem phần Tại sao bán kính chính xác lại rất lớn? trong Hướng dẫn khắc phục sự cố.