O Text Search (novo) recebe uma consulta de texto e retorna uma lista de lugares correspondentes.
O Text Search (novo) retorna informações sobre um conjunto de lugares com base em uma string, por exemplo, "pizza em São Paulo", "loja de sapatos perto do Rio de Janeiro" ou "Avenida Brasil, 123". O serviço responde com uma lista de locais correspondentes à string de texto e a todos os direcionamentos de localização definidos. Com o Text Search (novo), você pode pesquisar lugares por tipo, filtrar usando critérios como horário de funcionamento e classificação, além de restringir ou direcionar os resultados para um local específico.
Para usar o Text Search (novo), ative a "API Places (nova)" no projeto na nuvem do Google Cloud. Consulte o artigo Começar para mais detalhes.
Encontrar lugares por consulta de texto
Chame searchByText para retornar uma lista de lugares de uma consulta de texto ou número de telefone.
Especifique os parâmetros de pesquisa usando uma solicitação e, em seguida, chame searchByText(). Os resultados são retornados como uma lista de objetos Place, da qual você pode obter Place Details. O
snippet a seguir mostra um exemplo de solicitação e chamada para searchByText:
TypeScript
const request = { textQuery: query, fields: ['displayName', 'location', 'businessStatus'], includedType: '', // Restrict query to a specific type (leave blank for any). useStrictTypeFiltering: true, locationRestriction: map.getBounds(), 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, locationRestriction: map.getBounds(), isOpenNow: true, language: 'en-US', maxResultCount: 8, minRating: 1, // Specify a minimum rating. region: 'us', }; const { places } = await Place.searchByText(request);
- Especifique uma consulta de texto ou um número de telefone para pesquisar com o parâmetro
textQuery. - Use o parâmetro
fields(obrigatório) para especificar uma lista separada por vírgulas de um ou mais campos de dados com letras concatenadas. Os campos solicitados definem o preço da solicitação. Consulte Escolher campos de dados. - Use o parâmetro
includedTypepara retornar apenas resultados do tipo especificado. - Use
locationBiasoulocationRestrictionpara direcionar ou restringir os resultados da pesquisa de texto a uma região específica.
Se a consulta tiver um número de telefone, o parâmetro "region" precisará ser definido. Por exemplo, se você usar um número de telefone para pesquisar um lugar no Japão e o domínio solicitante for jp, defina o parâmetro region como "jp". Se region for omitido da solicitação, a API vai adotar como padrão a região dos Estados Unidos ("us").
Place, e nela você consegue os detalhes dos lugares.
Exemplo
O exemplo a seguir chama searchByText com o texto de consulta fornecido e, em seguida, preenche um mapa com marcadores clicáveis para mostrar os resultados.
TypeScript
let map: google.maps.Map; let markers: Record<string, google.maps.marker.AdvancedMarkerElement> = {}; let infoWindow: google.maps.InfoWindow; async function init() { const [{ Map, InfoWindow }, { ControlPosition }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('core'), ]); const center = { lat: 37.4161493, lng: -122.0812166 }; map = new Map(document.getElementById('map')!, { 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')!; map.controls[ControlPosition.TOP_LEFT].push(card); textInputButton.addEventListener('click', () => { void findPlaces(textInput.value); }); textInput.addEventListener('keydown', (event) => { if (event.key === 'Enter') { void findPlaces(textInput.value); } }); infoWindow = new InfoWindow(); } async function findPlaces(query: string) { const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([ google.maps.importLibrary('places'), 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, locationRestriction: map.getBounds(), 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: google.maps.places.Place) => { const marker = new AdvancedMarkerElement({ map, position: place.location, title: place.displayName, gmpClickable: true, }); markers[place.id] = marker; marker.addEventListener('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. function updateInfoWindow( title: string | Element | null, content: string | Element | null, anchor: google.maps.marker.AdvancedMarkerElement ) { infoWindow.setContent(content); infoWindow.setHeaderContent(title); infoWindow.open({ map, anchor, shouldFocus: false, }); } void init();
JavaScript
let map; let markers = {}; let infoWindow; async function init() { const [{ Map, InfoWindow }, { ControlPosition }] = await Promise.all([ google.maps.importLibrary('maps'), google.maps.importLibrary('core'), ]); const center = { lat: 37.4161493, lng: -122.0812166 }; map = new Map(document.getElementById('map'), { 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[ControlPosition.TOP_LEFT].push(card); textInputButton.addEventListener('click', () => { void findPlaces(textInput.value); }); textInput.addEventListener('keydown', (event) => { if (event.key === 'Enter') { void findPlaces(textInput.value); } }); infoWindow = new InfoWindow(); } async function findPlaces(query) { const [{ Place }, { AdvancedMarkerElement }] = await Promise.all([ google.maps.importLibrary('places'), 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, locationRestriction: map.getBounds(), 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, gmpClickable: true, }); markers[place.id] = marker; marker.addEventListener('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. function updateInfoWindow(title, content, anchor) { infoWindow.setContent(content); infoWindow.setHeaderContent(title); infoWindow.open({ map, anchor, shouldFocus: false, }); } void init();
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: 0.5rem; width: auto; padding: 0.6rem 0.75rem; font-size: 0.875rem; font-weight: 500; color: #fff; background-color: #2563eb; border: none; border-radius: 0.375rem; cursor: pointer; transition: background-color 0.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>
<script>
// prettier-ignore
(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: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<div id="text-input-card">
<input
type="text"
id="text-input"
placeholder="Search for a place" />
<input type="button" id="text-input-button" value="Search" />
</div>
<div id="map"></div>
</body>
</html>Testar amostra
Escolher campos de dados
Os campos solicitados definem o preço de cada solicitação de pesquisa. A solicitação é cobrada uma vez, na SKU mais alta entre os campos solicitados. Por exemplo, adicionar
reviews
a
fields
fatura toda a solicitação como Text Search Enterprise + Atmosphere.
Para manter as solicitações de pesquisa no Text Search Pro, solicite apenas os campos que os resultados da pesquisa mostram, como id, displayName, formattedAddress e location.
Quando um usuário selecionar um lugar, chame
fetchFields()
nele para receber campos como
reviews,
nationalPhoneNumber
ou
websiteURI.
Cada chamada de fetchFields() é uma solicitação separada do Place Details, faturada na SKU mais alta entre os campos solicitados. Se essa abordagem economiza dinheiro depende de quantos lugares os usuários abrem.
Campos que acionam cada SKU
Os campos a seguir acionam a SKU Text Search Essentials (somente IDs):
idOs campos a seguir acionam a SKU Text Search Pro:
accessibilityOptions
addressComponents
adrFormatAddress
businessStatus
displayName
formattedAddress
googleMapsUri
iconBackgroundColor
location
photos
plusCode
svgIconMaskURI
types
utcOffsetMinutes
viewportOs campos a seguir acionam a SKU Text Search Enterprise:
internationalPhoneNumber
nationalPhoneNumber
priceLevel
rating
regularOpeningHours
userRatingCount
websiteURIOs campos a seguir acionam a SKU Text Search Enterprise + Atmosphere:
allowsDogs
editorialSummary
evChargeOptions
fuelOptions
hasCurbsidePickup
hasDelivery
hasDineIn
hasLiveMusic
hasMenuForChildren
hasOutdoorSeating
hasRestroom
hasTakeout
hasWifi
isGoodForChildren
isGoodForGroups
isGoodForWatchingSports
isReservable
parkingOptions
paymentOptions
reviews
servesBeer
servesBreakfast
servesBrunch
servesCocktails
servesCoffee
servesDessert
servesDinner
servesLunch
servesVegetarianFood
servesWine
Para ver a SKU de cada campo, consulte Campos de dados da classe Place.