Usługa Wyszukaj tekst (New) przyjmuje zapytanie tekstowe i zwraca listę pasujących miejsc.
Wyszukiwanie tekstowe (nowe) zwraca informacje o zbiorze miejsc na podstawie ciągu znaków, np. „pizza w Nowym Jorku”, „sklepy obuwnicze w pobliżu Warszawy” lub „ul. Główna 123”. Usługa odpowiada listą miejsc pasujących do ciągu tekstowego i ustawionych preferencji lokalizacji. Wyszukiwanie tekstowe (nowe) umożliwia wyszukiwanie miejsc według typu, filtrowanie według kryteriów takich jak godziny otwarcia i ocena oraz ograniczanie lub kierowanie wyników do określonej lokalizacji.
Aby używać funkcji Text Search (New), musisz włączyć „Places API (New)” w projekcie Google Cloud. Więcej informacji znajdziesz w artykule Pierwsze kroki.
Znajdowanie miejsc za pomocą zapytania tekstowego
Wywołaj searchByText, aby zwrócić listę miejsc na podstawie zapytania tekstowego lub numeru telefonu.
Określ parametry wyszukiwania za pomocą żądania, a następnie wywołaj searchByText(). Wyniki są zwracane jako lista obiektów Place, z których możesz uzyskać informacje o miejscu. Ten fragment kodu pokazuje przykładowe żądanie i wywołanie metody 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);
- Określ zapytanie tekstowe lub numer telefonu do wyszukania za pomocą parametru
textQuery. - Użyj parametru
fields(wymagany), aby określić listę rozdzieloną przecinkami zawierającą co najmniej 1 pole danych w formacie camelCase. Pola, o które prosisz, określają cenę żądania. Zobacz Wybieranie pól danych. - Użyj parametru
includedType, aby zwrócić tylko wyniki określonego typu. - Użyj parametru
locationBiaslublocationRestriction, aby ukierunkować lub ograniczyć wyniki wyszukiwania tekstowego do konkretnego regionu.
Jeśli zapytanie zawiera numer telefonu, należy ustawić parametr regionu. Jeśli na przykład używasz numeru telefonu do wyszukiwania miejsca w Japonii, a domena wysyłająca żądanie to jp, musisz ustawić parametr region na „jp”. Jeśli w żądaniu nie ma parametru region, interfejs API domyślnie używa regionu Stany Zjednoczone („us”).
Place, z których możesz uzyskać informacje o miejscu.
Przykład
W poniższym przykładzie wywoływana jest funkcja searchByText z podanym tekstem zapytania, a następnie mapa jest wypełniana klikalnymi znacznikami, które pokazują wyniki.
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>Wybierz pola danych
Pola, o które prosisz, określają cenę każdego żądania wyszukiwania. Żądanie jest rozliczane raz, według najwyższej ceny SKU wśród żądanych pól. Na przykład dodanie reviews do fields powoduje, że całe żądanie jest rozliczane jako wyszukiwanie tekstowe w wersji Enterprise + Atmosphere.
Aby żądania wyszukiwania były obsługiwane przez usługę Text Search Pro, proś tylko o pola, które są wyświetlane w wynikach wyszukiwania, takie jak id, displayName, formattedAddress i location.
Gdy użytkownik wybierze miejsce, wywołaj fetchFields() dla tego miejsca, aby uzyskać pola takie jak reviews, nationalPhoneNumber lub websiteURI.
Każde wywołanie fetchFields() jest osobnym żądaniem informacji o miejscu, rozliczanym według najwyższego SKU spośród żądanych pól. To, czy to podejście pozwoli zaoszczędzić pieniądze, zależy od liczby miejsc, które otwierają użytkownicy.
Pola, które aktywują poszczególne kody SKU
Poniższe pola aktywują SKU Wyszukaj tekst Essentials (tylko identyfikatory):
idTe pola aktywują SKU Wyszukaj tekst Pro:
accessibilityOptions
addressComponents
adrFormatAddress
businessStatus
displayName
formattedAddress
googleMapsUri
iconBackgroundColor
location
photos
plusCode
svgIconMaskURI
types
utcOffsetMinutes
viewportTe pola aktywują kod SKU Wyszukaj tekst Enterprise:
internationalPhoneNumber
nationalPhoneNumber
priceLevel
rating
regularOpeningHours
userRatingCount
websiteURITe pola aktywują kod SKU Wyszukaj tekst 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
Informacje o kodzie SKU każdego pola znajdziesz w artykule Pola danych klasy Place.