地图注点 (POI) Feed

创建并上传 POI Feed

创建和上传 POI Feed 时,请遵循以下说明:

  • 对于 POI 数据文件,请遵循 POI Feed 中所述的规范。我们建议您为每次上传使用唯一的 POI 数据文件名。在文件名中添加时间戳,例如 POI_1633621547.json
  • 每天将 Feed 上传到本地 POI SFTP 服务器,以进行完全刷新。
  • 您可以在合作伙伴门户的配置 > Feed 部分中找到 SFTP 服务器详细信息。

选择 Feed 服务器

Feed 规范

字段要求

VssPoi

表示单个地图注点 (POI) 实体,例如酒店或餐馆。

字段名称类型要求说明
poi_id字符串

必填

必需。合作伙伴生成的用于标识 POI 的字符串。
name对象
(Text)

必填

必需。相应 POI 的名称。
telephone字符串

POI 的联系电话号码,包括国家/地区代码和区号,例如 +14567891234。
url字符串

相应 POI 的公共网站的网址。 注意:此信息仅用于匹配目的,不会显示。
location对象
(GeoCoordinates)

必填

必需。相应 POI 的位置。
display_address对象
(Text)

界面上显示的地址。
images对象数组
(Image)

地图注点的图片。 图片数量上限:5 张。
rating数值

相应 POI 的平均评分。
num_ratings数值

rating 字段的贡献评分数量。
rating_scale数值

用于 rating 字段的评分量表。如果最大评分值为 5,则 rating_scale 为 5。
category枚举
(Category)

必填

必需。表示 POI 的类别。
description对象
(Text)

POI 的说明。
oneOf
(additional_data)

必填

只能设置相应 oneOf 中的一个字段。

文本

表示包含本地化内容的文本。

字段名称类型要求说明
localizations对象数组
(LocalizedString)

本地化字符串。
default_locale字符串

要用作默认语言的语言区域必须存在于本地化中。

LocalizedString

表示本地化字符串。

字段名称类型要求说明
locale字符串

文本的语言标记,例如“en”“en-US”或“sr-Latn”。
text字符串

指定语言区域中的文本。

GeoCoordinates

某一地点的地理位置数据,包括纬度、经度和地址。

字段名称类型要求说明
latitude数值

[-90, +90] 度(含边界值)。 如果设置了经度,则为必需;否则为可选。
longitude数值

[-180, +180] 度(含)。 如果设置了纬度,则为必需;否则为可选。
oneOf
(addresses)

必填

只能设置相应 oneOf 中的一个字段。

PostalAddress

相应地点的邮政地址。

字段名称类型要求说明
country字符串

必填

必需。国家/地区,使用 ISO 3166-1 alpha-2 国家/地区代码,例如“US”。
locality字符串

必填

必需。市行政区/城市,例如“山景城”。
region字符串

地区/州/省,例如“CA”。只有在地区通常是地址的一部分的国家/地区才需要填写此字段。(可选)
postal_code字符串

必填

必需。邮政编码,例如“94043”。
street_address字符串

必填

必需。街道地址,例如“1600 Amphitheatre Pkwy”。

图片

表示地图注点 (POI) 的图片。

字段名称类型要求说明
url字符串

图片的网址。Google 会抓取托管在此网址上的媒体。 长度上限:2000。
alt_text对象
(Text)

用于无障碍功能的替代文本。

HotelData

特定于酒店的 Feed 数据。

字段名称类型要求说明
hotel_star_class数值

官方酒店星级值。 可用于“5 星级酒店”等标签。 此值应为介于 1 到 5 之间的整数。
brand_ids字符串数组

可展示此酒店的品牌。 如果此字段为空,则酒店可以显示在与 Feed 关联的任何品牌下。

LocalData

特定于场所的 Feed 数据。

字段名称类型要求说明
business_hours对象
(BusinessHours)

场所的正常营业时间。
price_range对象
(PriceRange)

商家提供的服务的价格范围。
establishment_category对象
(Text)

商家的类型。
brand_landing_pages对象数组
(BrandLandingPages)

品牌着陆页。

BusinessHours

表示此营业地点正常营业的时间段。 包含 [TimeRange][madden.vss_poi_feed.TimeRange] 实例的集合。 示例:周六的营业时间为 09:00-12:00 和 13:00-17:00: time_ranges { open_day: SATURDAY open_time: { hours: 9, minutes: 0 } close_day: SATURDAY close_time: { hours: 12, minutes: 0 } } time_rages { open_day: SATURDAY open_time: { hours: 13, minutes: 0 } close_day: SATURDAY close_time: { hours: 17, minutes: 0 } } 示例:周六的营业时间为 21:00 至周日 02:00: time_ranges { open_day: SATURDAY open_time: { hours: 21, minutes: 0 } close_day: SUNDAY close_time: { hours: 2, minutes: 0 } }

字段名称类型要求说明
time_ranges对象数组
(TimeRange)

相应 POI 的营业时间。每个时间段都表示 POI 在一周内正常营业的时段。

TimeRange

表示 POI 的营业时间范围,从指定的开始营业日期/时间开始,到指定的结束营业日期/时间结束。 结束营业时间必须在开始营业时间之后,例如当天晚些时候或次日。

字段名称类型要求说明
open_day枚举
(DayOfWeek)

时间范围的开始日期。
open_time对象
(TimeOfDay)

时间范围的开始时间。
close_day枚举
(DayOfWeek)

时间范围的结束日期。
close_time对象
(TimeOfDay)

时间范围的结束时间。

TimeOfDay

字段名称类型要求说明
hours数值

一天中的小时(采用 24 小时制)。必须大于或等于 0,且通常必须小于或等于 23。对于业务结束时间等场景,API 可以选择允许“24:00:00”一值。
minutes数值

一小时中的分钟数。必须大于或等于 0,且小于或等于 59。
seconds数值

一分钟中的秒数。必须大于或等于 0,且通常必须小于或等于 59。如果 API 允许闰秒,则 API 可以允许 60 一值。
nanos数值

秒数的小数部分(以纳秒为单位)。必须大于或等于 0,且小于或等于 999,999,999。

PriceRange

POI 提供的服务的价格范围。

字段名称类型要求说明
min_price对象
(Money)

相应 POI 提供的服务的最低价格。
max_price对象
(Money)

相应 POI 提供的服务的最高价格。

Money

表示含有货币类型的金额。

字段名称类型要求说明
currency_code字符串

采用 ISO 4217 标准定义的三位字母货币代码。
units数值

金额的整数单位。 例如,如果 currencyCode"USD",则 1 单位就是一美元。
nanos数值

以纳单位 (10^-9) 表示的金额数量。 取值范围必须在 -999,999,999 至 +999,999,999 之间(含边界值)。 如果 units 是正数,nanos 必须是正数或零。 如果 units 是零,nanos 可以是正数、零或负数。 如果 units 是负数,nanos 必须是负数或零。 例如,$-1.75 表示为 units=-1 和 nanos=-750,000,000。

BrandLandingPages

单个地图注点 (POI) 的本地化品牌着陆页。

字段名称类型要求说明
brand_id字符串

相应配置所适用的品牌。
localized_landing_pages对象数组
(LocalizedLandingPage)

本地化着陆页。 url 和 locales 字段值在所有本地化着陆页中必须是唯一的。
default_url字符串

当任何本地化着陆页都与用户的语言不匹配时,要使用的默认着陆页网址。

LocalizedLandingPage

地图注点 (POI) 的本地化着陆页。

字段名称类型要求说明
url字符串

着陆页的网址。 长度上限:2000。
locales字符串数组

将此页面限制为具有指定语言偏好的用户。 必须包含语言标记,例如“en”“en-US”或“sr-Latn”。

类别

表示 POI 的类别。 它应与下面的 additional_data oneof 字段匹配。

名称说明
UNKNOWN_CATEGORY
HOTEL
LOCAL

DayOfWeek

表示星期几。

名称说明
DAY_OF_WEEK_UNSPECIFIED未指定星期几。
MONDAY星期一
TUESDAY星期二
WEDNESDAY星期三
THURSDAY星期四
FRIDAY星期五
SATURDAY星期六
SUNDAY星期日

additional_data

必需。特定于类别的字段。 它应与上方的 category 字段匹配。

字段名称类型要求说明
hotel_data对象
(HotelData)

local_data 互斥

酒店专用字段。
local_data对象
(LocalData)

hotel_data 互斥

特定于本地的字段。

addresses

必需。某个地点的地址。

字段名称类型要求说明
address对象
(PostalAddress)

营业地点的邮政地址。
  • 格式:必须为 JPEG、PNG 或 WebP。
  • 文件大小上限:每张图片不超过 30 MB。
  • 最大尺寸:总像素数不超过 7,500 万(宽度 x 高度 < 75,000,000)。
  • 网址类型:指向图片素材资源的直接路径(例如,以 .jpg 结尾)。
  • 权限:确保托管服务器允许 Googlebot 或抓取工具访问,并且没有 robots.txt 屏蔽图片目录。

定义

VssPoiFeed 的定义

// Represents a Point of Interest (POI) data feed provided by a partner.
export message VssPoiFeed {
  // The POIs in the feed.
  repeated VssPoi data = 1;
}

VssPoi 定义

// Represents a single Point of Interest (POI) entity e.g. a hotel or
// restaurant.
export message VssPoi {
  // Required. A string generated by the partner that identifies a POI.
  string poi_id = 1;

  // The entity name, telephone, url and location are used to support
  // matching partner inventory with entities already present on Google.

  // Required. The name of the POI.
  Text name = 2;

  // The contact telephone number of the POI including its country and
  // area codes, e.g. +14567891234.
  string telephone = 3 [(datapol.semantic_type) = ST_PHONE_NUMBER];

  // The url of the POI's public website.
  // Note: This will be used just for matching purposes, not for display.
  string url = 4;

  // Required. The location of the POI.
  GeoCoordinates location = 5;

  // The address displayed on the UI.
  Text display_address = 17;

  // Images of the POI.
  // Max number of images: 5.
  repeated Image images = 6;

  // Average rating for the POI.
  float rating = 12;

  // The number of contributing ratings for the `rating` field.
  int64 num_ratings = 13;

  // The rating scale used for the `rating` field. If max rating is 5, then
  // rating_scale is 5.
  int32 rating_scale = 14;

  // Represents the category of the POI.
  // It should match the `additional_data` oneof field below.
  export enum Category {


    LOCAL = 4;
  }

  // Required. Represents the category of the POI.
  Category category = 9;

  // A description of the POI.
  Text description = 16;

  // Required. Category specific fields.
  // It should match the `category` field above.
  oneof additional_data {


    // Local specific fields.
    LocalData local_data = 15;
  }

}

Text 的定义

// Represents a text with localizations.
message Text {
  // Represents a localized string.
  message LocalizedString {
    // The text's language tag, such as "en", "en-US" or "sr-Latn".
    string locale = 1;

    // The text in the specified locale.
    string text = 2;
  }

  // The localized strings.
  repeated LocalizedString localizations = 1;

  // The locale to use as the default language it must be present in the
  // localizations.
  string default_locale = 2;
}

GeoCoordinates 的定义

// The Geo data of a location, including latitude, longitude, and address.
message GeoCoordinates {
  option (datapol.msg_semantic_type) = ST_LOCATION;

  // [-90, +90] degrees (inclusive).
  // Required if longitude is set, otherwise nice to have.
  double latitude = 1;

  // [-180, +180] degrees (inclusive).
  // Required if latitude is set, otherwise nice to have.
  double longitude = 2;

  // Required. Address for a location.
  oneof addresses {
    // Postal address of the location.
    PostalAddress address = 3;

  }
}

PostalAddress 的定义

// The postal address for the location.
message PostalAddress {
  option (datapol.msg_semantic_type) = ST_LOCATION;

  // Required. The country, using ISO 3166-1 alpha-2 country code, e.g. "US".
  string country = 1;

  // Required. The locality/city, e.g. "Mountain View".
  string locality = 2;

  // The region/state/province, e.g. "CA". This field is only required in
  // countries where region is commonly a part of the address. (optional)
  string region = 3;

  // Required. The postal code, e.g. "94043".
  string postal_code = 4;

  // Required. The street address, e.g. "1600 Amphitheatre Pkwy".
  string street_address = 5;
}

图片定义

// Represents an image of the Point of Interest (POI).
export message Image {
  // The url of the image. Google will crawl the media hosted at this URL.
  // Max length: 2000.
  string url = 1;

  // The alternative text to be used for accessibility.
  Text alt_text = 2;
}

LocalData 的定义

// Establishment specific feed data.
message LocalData {
  // The regular business hours of the establishment.
  BusinessHours business_hours = 1;

  // Price range of the services offered by the establishment.
  PriceRange price_range = 2;

  // The type of establishment.
  Text establishment_category = 3;

  // The brand landing pages.
  repeated BrandLandingPages brand_landing_pages = 4;
}

BrandLandingPages 的定义

// The Localized brand landing pages for a single Point of Interest (POI).
message BrandLandingPages {
  // The brand this configuration applies to.
  string brand_id = 1 [(datapol.semantic_type) = ST_PARTNER_ID];

  // Localized landing page for the Point of Interest (POI).
  message LocalizedLandingPage {

    // The url of the landing page.
    // Max length: 2000.
    string url = 1;

    // Restricts this page to users with the specified language preference.
    // Must contain language tags, such as "en", "en-US" or "sr-Latn".
    repeated string locales = 3;
  }

  // The localized landing pages.
  // The url and locales fields values must be unique across all the localized
  // landing pages.
  repeated LocalizedLandingPage localized_landing_pages = 2;

  // The default landing page url to be used when none of the localized
  // landing pages matches the user's language.
  string default_url = 3;
}

示例

地图注点 Feed

文件名:poi_1707240000.json

{
  "data": [
    {
      "poi_id": "test_restaurant_1",
      "name": {
        "localizations": [
          {
            "locale": "en",
            "text": "Tasty Bites Test Restaurant"
          }
        ],
        "default_locale": "en"
      },
      "telephone": "+1234567890",
      "url": "https://www.tastybitestest.com",
      "location": {
        "latitude": 37.422,
        "longitude": -122.084,
        "address": {
          "country": "US",
          "locality": "Mountain View",
          "postal_code": "94043",
          "street_address": "1600 Amphitheatre Pkwy"
        }
      },
      "display_address": {
        "localizations": [
          {
            "locale": "en",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          }
        ],
        "default_locale": "en"
      },
      "images": [
        {
          "url": "https://www.tastybitestest.com/images/interior.jpg",
          "alt_text": {
            "localizations": [
              {
                "locale": "en",
                "text": "Cozy dining area of Tasty Bites"
              }
            ],
            "default_locale": "en"
          }
        }
      ],
      "rating": 4.7,
      "num_ratings": 150,
      "rating_scale": 5,
      "category": "LOCAL",
      "description": {
        "localizations": [
          {
            "locale": "en",
            "text": "A mock restaurant for testing the POI feed ingestion."
          }
        ],
        "default_locale": "en"
      },
      "local_data": {
        "establishment_category": {
           "localizations": [
             {
               "locale": "en",
               "text": "Restaurant"
             }
           ],
           "default_locale": "en"
        },
        "price_range": {
          "min_price": {
            "currency_code": "USD",
            "units": 15,
            "nanos": 0
          },
          "max_price": {
            "currency_code": "USD",
            "units": 45,
            "nanos": 0
          }
        },
        "business_hours": {
          "time_ranges": [
            {
              "open_day": "MONDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "MONDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "TUESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "TUESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "WEDNESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "WEDNESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "THURSDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "THURSDAY",
              "close_time": { "hours": 22, "minutes": 0 }
            },
            {
              "open_day": "FRIDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "FRIDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SATURDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SATURDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SUNDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SUNDAY",
              "close_time": { "hours": 20, "minutes": 0 }
            }
          ]
        },
        "brand_landing_pages": [
          {
            "brand_id": "tasty_bites_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.tastybitestest.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.tastybitestest.com"
          },
          {
            "brand_id": "delicious_eats_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.deliciouseats.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.deliciouseats.com"
          }
        ]
      }
    }
  ]
}

多语言地图注点 Feed

文件名:poi_multilingual.json

{
  "data": [
    {
      "poi_id": "test_restaurant_1",
      "name": {
        "localizations": [
          {
            "locale": "en",
            "text": "Tasty Bites Test Restaurant"
          },
          {
            "locale": "fr",
            "text": "Restaurant de test Tasty Bites"
          }
        ],
        "default_locale": "en"
      },
      "telephone": "+1234567890",
      "url": "https://www.tastybitestest.com",
      "location": {
        "latitude": 37.422,
        "longitude": -122.084,
        "address": {
          "country": "US",
          "locality": "Mountain View",
          "postal_code": "94043",
          "street_address": "1600 Amphitheatre Pkwy"
        }
      },
      "display_address": {
        "localizations": [
          {
            "locale": "en",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          },
          {
            "locale": "fr",
            "text": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
          }
        ],
        "default_locale": "en"
      },
      "images": [
        {
          "url": "https://www.tastybitestest.com/images/interior.jpg",
          "alt_text": {
            "localizations": [
              {
                "locale": "en",
                "text": "Cozy dining area of Tasty Bites"
              },
              {
                "locale": "fr",
                "text": "Espace salle à manger accueillant de Tasty Bites"
              }
            ],
            "default_locale": "en"
          }
        }
      ],
      "rating": 4.7,
      "num_ratings": 150,
      "rating_scale": 5,
      "category": "LOCAL",
      "description": {
        "localizations": [
          {
            "locale": "en",
            "text": "A mock restaurant for testing the POI feed ingestion."
          },
          {
            "locale": "fr",
            "text": "Un faux restaurant pour tester l'ingestion de flux de points d'intérêt."
          }
        ],
        "default_locale": "en"
      },
      "local_data": {
        "establishment_category": {
           "localizations": [
             {
               "locale": "en",
               "text": "Restaurant"
             },
             {
               "locale": "fr",
               "text": "Restaurant"
             }
           ],
           "default_locale": "en"
        },
        "price_range": {
          "min_price": {
            "currency_code": "USD",
            "units": 15,
            "nanos": 0
          },
          "max_price": {
            "currency_code": "USD",
            "units": 45,
            "nanos": 0
          }
        },
        "business_hours": {
          "time_ranges": [
            {
              "open_day": "MONDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "MONDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "TUESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "TUESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "WEDNESDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "WEDNESDAY",
              "close_time": { "hours": 21, "minutes": 0 }
            },
            {
              "open_day": "THURSDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "THURSDAY",
              "close_time": { "hours": 22, "minutes": 0 }
            },
            {
              "open_day": "FRIDAY",
              "open_time": { "hours": 11, "minutes": 0 },
              "close_day": "FRIDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SATURDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SATURDAY",
              "close_time": { "hours": 23, "minutes": 0 }
            },
            {
              "open_day": "SUNDAY",
              "open_time": { "hours": 10, "minutes": 0 },
              "close_day": "SUNDAY",
              "close_time": { "hours": 20, "minutes": 0 }
            }
          ]
        },
        "brand_landing_pages": [
          {
            "brand_id": "tasty_bites_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.tastybitestest.com/fr",
                "locales": ["fr-FR", "fr-CA"]
              },
              {
                "url": "https://www.tastybitestest.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.tastybitestest.com"
          },
          {
            "brand_id": "delicious_eats_brand",
            "localized_landing_pages": [
              {
                "url": "https://www.deliciouseats.com/fr",
                "locales": ["fr-FR", "fr-CA"]
              },
              {
                "url": "https://www.deliciouseats.com/en",
                "locales": ["en-US", "en-GB"]
              }
            ],
            "default_url": "https://www.deliciouseats.com"
          }
        ]
      }
    }
  ]
}