تتلقّى خدمة Text Search (New) طلب بحث نصيًا وتعرِض قائمة بالأماكن المطابقة.
تعرض خدمة Text Search (New) معلومات عن مجموعة من الأماكن استنادًا إلى سلسلة نصية، مثل "بيتزا في نيويورك" أو "متاجر أحذية بالقرب من أوتاوا" أو "123 شارع التحرير". تستجيب الخدمة بقائمة من الأماكن التي تتطابق مع السلسلة النصية وأي انحياز للموقع الجغرافي تم ضبطه. تتيح لك خدمة Text Search (New) البحث عن الأماكن حسب النوع، والفلترة باستخدام معايير مثل ساعات العمل والتقييم، وحصر النتائج أو توجيهها إلى موقع جغرافي معيّن.
لاستخدام Text Search (New)، يجب تفعيل "Places API (New)" في مشروعك على Google Cloud. لمزيد من التفاصيل، يُرجى الاطّلاع على البدء.
العثور على أماكن من خلال طلب نصي
يمكنك استدعاء 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, 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);
- حدِّد طلب بحث نصيًا أو رقم هاتف للبحث باستخدام المَعلمة
textQuery. - استخدِم المَعلمة
fields(مطلوبة) لتحديد قائمة قيم مفصولة بفاصلة تتضمّن حقل بيانات واحدًا أو أكثر بتنسيق Camel Case. تحدّد الحقول التي تطلبها سعر الطلب. يُرجى الاطّلاع على اختيار حقول البيانات. - استخدِم المَعلمة
includedTypeلعرض النتائج من النوع المحدّد فقط. - استخدِم
locationBiasأوlocationRestrictionلتفضيل نتائج البحث النصي أو حصرها في منطقة معيّنة.
إذا كان طلب البحث يحتوي على رقم هاتف، يجب ضبط مَعلمة المنطقة. على سبيل المثال، إذا كنت تستخدم رقم هاتف للبحث عن مكان في اليابان، وكان النطاق الذي يرسل الطلب هو jp، يجب ضبط المَعلمة region على "jp". في حال حذف region من الطلب، ستستخدم واجهة برمجة التطبيقات تلقائيًا منطقة الولايات المتحدة ('us').
Place، والتي يمكنك من خلالها الحصول على
تفاصيل المكان.
مثال
يستدعي المثال التالي searchByText مع نص طلب البحث المقدَّم، ثم يملأ خريطة بعلامات قابلة للنقر لعرض النتائج.
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>اختيار حقول البيانات
تحدّد الحقول التي تطلبها سعر كل طلب بحث. تتم فوترة الطلب
مرة واحدة، وفقًا
لأعلى
رمز تخزين تعريفي بين الحقول المطلوبة. على سبيل المثال، عند إضافة
reviews
إلى
fields،
يتم تحصيل رسوم الطلب بالكامل على أنّه Text Search Enterprise + Atmosphere.
لإبقاء طلبات البحث في Text Search Pro، اطلب فقط الحقول التي تعرضها نتائج البحث، مثل id وdisplayName وformattedAddress وlocation.
عندما يختار مستخدم مكانًا، يمكنك استدعاء
fetchFields()
في ذلك المكان للحصول على حقول مثل
reviews
أو
nationalPhoneNumber
أو
websiteURI.
كل طلب fetchFields()
هو طلب منفصل للحصول على تفاصيل المكان، ويتم تحصيل رسومه وفقًا لأعلى رمز تخزين تعريفي بين
الحقول التي يطلبها. ويعتمد توفير المال من خلال هذا النهج على عدد الأماكن التي يفتحها المستخدمون.
الحقول التي تؤدي إلى تفعيل كل رمز تخزين تعريفي
تؤدي الحقول التالية إلى تفعيل رمز التخزين التعريفي لأساسيات البحث النصي (أرقام التعريف فقط):
idتؤدي الحقول التالية إلى تفعيل رمز التخزين التعريفي لميزة "البحث النصي" الاحترافية:
accessibilityOptions
addressComponents
adrFormatAddress
businessStatus
displayName
formattedAddress
googleMapsUri
iconBackgroundColor
location
photos
plusCode
svgIconMaskURI
types
utcOffsetMinutes
viewportتؤدي الحقول التالية إلى تفعيل رمز التخزين التعريفي لرزمة الشركات لميزة "البحث النصي":
internationalPhoneNumber
nationalPhoneNumber
priceLevel
rating
regularOpeningHours
userRatingCount
websiteURIتؤدي الحقول التالية إلى تفعيل رمز التخزين التعريفي 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
للاطّلاع على رمز التخزين التعريفي لكل حقل، يُرجى مراجعة حقول بيانات فئة المكان.