文本搜索(新)

请选择平台: Android iOS JavaScript 网络服务
欧洲经济区 (EEA) 开发者

文本搜索(新)可接受文本查询并返回匹配的地点列表。

文本搜索(新)可以根据一个字符串(例如,“北京烤鸭”“南京附近的鞋店”或“长安街 8 号”)返回一组地点的相关信息。该服务会返回一列与所指定的文本字符串和任何位置偏向设置相匹配的地点。通过文本搜索(新),您可以按类型搜索地点,使用营业时间和评分等条件进行过滤,还可以使结果限制在或偏向于特定位置。

若要使用文本搜索(新),您必须在 Google Cloud 项目中启用“Places API(新)”。如需了解详情,请参阅开始使用

通过文本查询查找地点

调用 searchByText 即可根据文本查询或电话号码返回地点列表。 请使用请求指定搜索参数,然后调用 searchByText()。返回的结果将会是一个 Place 对象列表,您可以从中获取地点详情。以下代码段显示了一个请求和 searchByText 调用示例:

TypeScript

const request = {
    textQuery: query,
    fields: ['displayName', 'location', 'businessStatus'],
    includedType: '', // Restrict query to a specific type (leave blank for any).
    useStrictTypeFiltering: true,
    locationBias: map.center,
    isOpenNow: true,
    language: 'en-US',
    maxResultCount: 8,
    minRating: 1, // Specify a minimum rating.
    region: 'us',
};

const { places } = await Place.searchByText(request);

JavaScript

const request = {
    textQuery: query,
    fields: ['displayName', 'location', 'businessStatus'],
    includedType: '', // Restrict query to a specific type (leave blank for any).
    useStrictTypeFiltering: true,
    locationBias: map.center,
    isOpenNow: true,
    language: 'en-US',
    maxResultCount: 8,
    minRating: 1, // Specify a minimum rating.
    region: 'us',
};
const { places } = await Place.searchByText(request);
  • 使用 textQuery 参数指定要搜索的文本查询或电话号码。
  • 您可以使用 fields 参数(必需)指定一个逗号分隔列表,其中包含一个或多个采用驼峰命名法的数据字段
  • 使用 includedType 参数可仅返回指定类型的结果。
  • 使用 locationBiaslocationRestriction 可使文本搜索结果偏向或限制在特定区域。
查看完整的属性列表。

如果查询内容中包含电话号码,则应设置 region 参数。例如,如果您使用电话号码搜索日本的某个地点,而发出请求的网域是 jp,则必须将 region 参数设置为“jp”。如果请求中省略了 region,该 API 会默认设为美国 (us) 区域。

返回的结果将会是一个 Place 对象列表,您可以从中获取地点详情

示例

以下示例使用提供的查询文本调用 searchByText,然后使用可点击的标记在地图中填充结果。

TypeScript

let map;
let markers = {};
let infoWindow;

async function initMap() {
    const { Map, InfoWindow } = await google.maps.importLibrary("maps") as google.maps.MapsLibrary;

    const center = { lat: 37.4161493, lng: -122.0812166 };
    map = new Map(document.getElementById('map') as HTMLElement, {
        center: center,
        zoom: 11,
        mapTypeControl: false,
        mapId: 'DEMO_MAP_ID',
    });

    const textInput = document.getElementById('text-input') as HTMLInputElement;
    const textInputButton = document.getElementById('text-input-button') as HTMLButtonElement;
    const card = document.getElementById('text-input-card') as HTMLElement;
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

    textInputButton.addEventListener('click', () => {
        findPlaces(textInput.value);
    });

    textInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            findPlaces(textInput.value);
        }
    });

    infoWindow = new google.maps.InfoWindow();
}

async function findPlaces(query) {
    const { Place } = await google.maps.importLibrary("places") as google.maps.PlacesLibrary;
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker") as google.maps.MarkerLibrary;
    const request = {
        textQuery: query,
        fields: ['displayName', 'location', 'businessStatus'],
        includedType: '', // Restrict query to a specific type (leave blank for any).
        useStrictTypeFiltering: true,
        locationBias: map.center,
        isOpenNow: true,
        language: 'en-US',
        maxResultCount: 8,
        minRating: 1, // Specify a minimum rating.
        region: 'us',
    };

    const { places } = await Place.searchByText(request);

    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary("core") as google.maps.CoreLibrary;
        const bounds = new LatLngBounds();

        // First remove all existing markers.
        for (const id in markers) {
            markers[id].map = null;
        };
        markers = {};

        // Loop through and get all the results.
        places.forEach(place => {
            const marker = new AdvancedMarkerElement({
                map,
                position: place.location,
                title: place.displayName,
            });
            markers[place.id] = marker;

            marker.addListener('gmp-click', () => {
                map.panTo(place.location);
                updateInfoWindow(place.displayName, place.id, marker);
            });

            if (place.location != null) {
                bounds.extend(place.location);
            }
        });

        map.fitBounds(bounds);

    } else {
        console.log('No results');
    }
}

// Helper function to create an info window.
async function updateInfoWindow(title, content, anchor) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        map,
        anchor,
        shouldFocus: false,
    });
}

initMap();

JavaScript

let map;
let markers = {};
let infoWindow;
async function initMap() {
    const { Map, InfoWindow } = await google.maps.importLibrary("maps");
    const center = { lat: 37.4161493, lng: -122.0812166 };
    map = new Map(document.getElementById('map'), {
        center: center,
        zoom: 11,
        mapTypeControl: false,
        mapId: 'DEMO_MAP_ID',
    });
    const textInput = document.getElementById('text-input');
    const textInputButton = document.getElementById('text-input-button');
    const card = document.getElementById('text-input-card');
    map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);
    textInputButton.addEventListener('click', () => {
        findPlaces(textInput.value);
    });
    textInput.addEventListener('keydown', (event) => {
        if (event.key === 'Enter') {
            findPlaces(textInput.value);
        }
    });
    infoWindow = new google.maps.InfoWindow();
}
async function findPlaces(query) {
    const { Place } = await google.maps.importLibrary("places");
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
    const request = {
        textQuery: query,
        fields: ['displayName', 'location', 'businessStatus'],
        includedType: '', // Restrict query to a specific type (leave blank for any).
        useStrictTypeFiltering: true,
        locationBias: map.center,
        isOpenNow: true,
        language: 'en-US',
        maxResultCount: 8,
        minRating: 1, // Specify a minimum rating.
        region: 'us',
    };
    const { places } = await Place.searchByText(request);
    if (places.length) {
        const { LatLngBounds } = await google.maps.importLibrary("core");
        const bounds = new LatLngBounds();
        // First remove all existing markers.
        for (const id in markers) {
            markers[id].map = null;
        }
        ;
        markers = {};
        // Loop through and get all the results.
        places.forEach(place => {
            const marker = new AdvancedMarkerElement({
                map,
                position: place.location,
                title: place.displayName,
            });
            markers[place.id] = marker;
            marker.addListener('gmp-click', () => {
                map.panTo(place.location);
                updateInfoWindow(place.displayName, place.id, marker);
            });
            if (place.location != null) {
                bounds.extend(place.location);
            }
        });
        map.fitBounds(bounds);
    }
    else {
        console.log('No results');
    }
}
// Helper function to create an info window.
async function updateInfoWindow(title, content, anchor) {
    infoWindow.setContent(content);
    infoWindow.setHeaderContent(title);
    infoWindow.open({
        map,
        anchor,
        shouldFocus: false,
    });
}
initMap();

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#text-input-card {
  width: 25%;
  background-color: #fff;
  border-radius: 5px;
  box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
  margin: 10px;
  padding: 5px;
  font-family: Roboto, sans-serif;
  font-size: large;
  font-weight: bold;
}

#text-input {
  width: 100%;
  padding: 10px;
  margin: 0;
  box-sizing: border-box;
}

#text-input-button {
  display: inline-block;
  margin-top: .5rem;
  width: auto;
  padding: .6rem .75rem;
  font-size: .875rem;
  font-weight: 500;
  color: #fff;
  background-color: #2563eb;
  border: none;
  border-radius: .375rem;
  cursor: pointer;
  transition: background-color .15s ease-in-out;
  text-align: center
}

HTML

<html>
  <head>
    <title>Text Search</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="text-input-card">
      <input type="text" id="text-input" placeholder="Search for a place"></input>
      <input type="button" id="text-input-button" value="Search"></input>
    </div>
    <div id="map"></div>

    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
        ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</script>
  </body>
</html>

试用示例