واجهة برمجة تطبيقات بيانات الإكمال التلقائي للأماكن

تتيح لك واجهة برمجة التطبيقات لبيانات الإكمال التلقائي للأماكن استرجاع عبارات البحث المقترحة آليًا لإنشاء تجارب مخصّصة للإكمال التلقائي مع قدر أكبر من التحكّم أكثر مما هو ممكن باستخدام أداة الإكمال التلقائي. ستتعلم في هذا الدليل كيفية استخدام وضع واجهة برمجة التطبيقات لبيانات الإكمال التلقائي لإجراء طلبات الإكمال التلقائي استنادًا إلى المستخدم طلبات البحث.

يوضح المثال التالي دمجًا بسيطًا للكتابة الأمامية. أدخل استعلام البحث، ثم انقر لتحديد النتيجة التي تريدها.

طلبات الإكمال التلقائي

يأخذ طلب الإكمال التلقائي سلسلة إدخال طلب بحث ويعرض قائمة بتنبؤات الأماكن. إلى تقديم طلب إكمال تلقائي، أو الاتصال بالرقم fetchAutocompleteSuggestions() وتمرير طلب بالخصائص المطلوبة. input تحتوي السمة على السلسلة المطلوب البحث فيها؛ في أحد التطبيقات النموذجية، سيتم تحديث هذه القيمة باعتبارها يكتب المستخدم استعلامًا. يجب أن يتضمّن الطلب sessionToken التي تستخدم لأغراض الفوترة

يعرض المقتطف التالي إنشاء نص طلب وإضافة رمز مميّز للجلسة، ثم استدعاء fetchAutocompleteSuggestions() للحصول على قائمة PlacePrediction

// Add an initial request body.
let request = {
  input: "Tadi",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};
// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

تقييد توقعات الإكمال التلقائي

بشكل تلقائي، تقدّم ميزة "الإكمال التلقائي للأماكن" جميع أنواع الأماكن، وتكون متحيّزة للتوقعات القريبة من مكان تواجد المستخدم الموقع، وجلب جميع حقول البيانات المتاحة للمكان الذي اختاره المستخدم. تحديد المكان خيارات الإكمال التلقائي لتقديم توقعات أكثر صلة من خلال تقييد النتائج أو انحيازها

يؤدي تقييد النتائج إلى تجاهل أداة الإكمال التلقائي لأي نتائج خارج منطقة القيود. من الممارسات الشائعة تقييد النتائج بحدود الخريطة. انحياز النتائج تجعل أداة الإكمال التلقائي تعرض نتائج ضمن المنطقة المحددة، إلا أن بعض التطابقات قد خارج تلك المنطقة.

استخدِم السمة origin لتحديد نقطة الأصل المطلوب إجراء الحساب منها. المسافة الجيوديسية إلى الوجهة. في حال إسقاط هذه القيمة، لن يتم عرض المسافة.

استخدام includedPrimaryTypes لتحديد ما يصل إلى خمسة أنواع أماكن. وإذا لم يتم تحديد أي أنواع، سيتم عرض الأماكن بجميع أنواعها.

الاطّلاع على مرجع واجهة برمجة التطبيقات

الحصول على تفاصيل المكان

لإرجاع Place كائن من نتيجة بحث مقترحة مكان، أول طلب toPlace()، اتصِل بالرقم fetchFields(). على عنصر Place الناتج (يتم تضمين رقم تعريف الجلسة من توقّع المكان تلقائيًا). يؤدي الاتصال بالرقم fetchFields() إلى إنهاء جلسة الإكمال التلقائي.

let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});

const placeInfo = document.getElementById("prediction");

placeInfo.textContent =
  "First predicted place: " +
  place.displayName +
  ": " +
  place.formattedAddress;

الرموز المميزة للجلسة

تعمل الرموز المميزة للجلسة على تجميع مرحلتي طلب البحث والتحديد لبحث الإكمال التلقائي للمستخدم في جلسة منفصلة لأغراض الفوترة. تبدأ الجلسة عندما يبدأ المستخدم في الكتابة. تنتهي الجلسة عندما يختار المستخدم مكانًا وتُجرى فيه مكالمة للتعرّف على تفاصيل المكان.

لإنشاء رمز مميز جديد للجلسة وإضافته إلى أحد الطلبات، قم بإنشاء مثيل AutocompleteSessionToken، ثم اضبط sessionToken خاصية الطلب لاستخدام الرموز المميزة كما هو موضح في المقتطف التالي:

// Create a session token.
const token = new AutocompleteSessionToken();

// Add the token to the request.
// @ts-ignore
request.sessionToken = token;

تنتهي الجلسة عند fetchFields() البيانات. بعد إنشاء المثيل Place، لن تحتاج إلى اجتياز الجلسة. رمز مميز إلى fetchFields() حيث تتم معالجة هذا الإجراء تلقائيًا.

await place.fetchFields({
  fields: ["displayName", "formattedAddress"],
});
await place.fetchFields({
    fields: ['displayName'],
  });

يمكنك إنشاء رمز مميّز للجلسة للجلسة التالية من خلال إنشاء مثيل جديد من AutocompleteSessionToken.

اقتراحات الرموز المميّزة للجلسة:

  • استخدم الرموز المميزة للجلسة لجميع مكالمات الإكمال التلقائي للأماكن.
  • إنشاء رمز مميّز جديد لكل جلسة
  • اجتياز رمز مميز فريد للجلسة لكل جلسة جديدة. استخدام الرمز المميز نفسه لأكثر من جلسة واحدة سيؤدي إلى تحصيل فواتير كل طلب على حدة.

يمكنك اختياريًا حذف الرمز المميز لجلسة الإكمال التلقائي من أحد الطلبات. إذا كان الرمز المميز للجلسة يتم إصدار فاتورة لكل طلب على حدة، ما يؤدي إلى الإكمال التلقائي - لكل طلب رمز التخزين التعريفي. في حال إعادة استخدام رمز مميّز للجلسة، سيتم اعتبار الجلسة غير صالحة ويتم تحصيل رسوم من الطلبات. كما لو أنه لم يتم تقديم رمز مميز للجلسة.

مثال

أثناء كتابة المستخدم لطلب بحث، يتم استدعاء طلب إكمال تلقائي كل بضعة ضغطات المفاتيح (وليس لكل حرف)، ويتم عرض قائمة بالنتائج المحتملة. عندما يقوم المستخدم بالاختيار من قائمة النتائج، يتم احتساب التحديد كـ طلب ما، ويتم تجميع كل الطلبات المقدمة أثناء البحث كطلب واحد. إذا اختار المستخدم مكانًا، فسيُترك طلب البحث متاحة بدون أي رسوم، ولن يتم تحصيل رسوم سوى طلب بيانات المكان. إذا لم يُجرِ المستخدم التحديد في غضون بضع دقائق من بداية الجلسة، سيتم تحديد يتم تحصيل رسوم استعلام البحث.

من منظور التطبيق، يسير سير الأحداث على النحو التالي:

  1. يبدأ أحد المستخدمين في كتابة طلب بحث عن "القاهرة، مصر".
  2. عند رصد البيانات التي أدخلها المستخدم، ينشئ التطبيق جلسة جديدة. وهو "Token A".
  3. أثناء كتابة المستخدم، تقدِّم واجهة برمجة التطبيقات طلب إكمال تلقائي كل بضعة حرف، لعرض قائمة جديدة بالنتائج المحتملة لكل حرف:
    "P"
    "Par"
    و"باريس"
    "باريس، فرنسا"
  4. عندما يقوم المستخدم بالاختيار:
    • يتم تجميع كل الطلبات الناتجة من طلب البحث وإضافتها إلى يمثلها "الرمز المميز أ"، كطلب واحد.
    • ويتم احتساب اختيار المستخدم كطلب تفصيلي للمكان، وتتم إضافته إلى الجلسة التي يمثلها "الرمز المميز أ".
  5. تنتهي الجلسة ويتجاهل التطبيق "الرمز المميّز أ".
اطّلع على مزيد من المعلومات عن كيفية فوترة الجلسات

إكمال نموذج الرمز البرمجي

يحتوي هذا القسم على أمثلة كاملة توضح كيفية استخدام واجهة برمجة التطبيقات لبيانات الإكمال التلقائي للأماكن .

توقعات الإكمال التلقائي للأماكن

يوضح المثال التالي استدعاء fetchAutocompleteSuggestions() لإدخال "Tadi"، ثم استدعاء toPlace() في أول نتيجة للتنبؤ، يليها طلب إلى fetchFields() للحصول على تفاصيل المكان.

TypeScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
    // @ts-ignore
    const { Place, AutocompleteSessionToken, AutocompleteSuggestion } = await google.maps.importLibrary("places") as google.maps.PlacesLibrary;

    // Add an initial request body.
    let request = {
        input: "Tadi",
        locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
        origin: { lat: 37.7893, lng: -122.4039 },
        includedPrimaryTypes: ["restaurant"],
        language: "en-US",
        region: "us",
    };

    // Create a session token.
    const token = new AutocompleteSessionToken();
    // Add the token to the request.
    // @ts-ignore
    request.sessionToken = token;
    // Fetch autocomplete suggestions.
    const { suggestions } = await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    const title = document.getElementById('title') as HTMLElement;
    title.appendChild(document.createTextNode('Query predictions for "' + request.input + '":'));

    for (let suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a new list element.
        const listItem = document.createElement('li');
        const resultsElement = document.getElementById("results") as HTMLElement;
        listItem.appendChild(document.createTextNode(placePrediction.text.toString()));
        resultsElement.appendChild(listItem);
    }

    let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });

    const placeInfo = document.getElementById("prediction") as HTMLElement;
    placeInfo.textContent = 'First predicted place: ' + place.displayName + ': ' + place.formattedAddress;

}

init();

JavaScript

/**
 * Demonstrates making a single request for Place predictions, then requests Place Details for the first result.
 */
async function init() {
  // @ts-ignore
  const { Place, AutocompleteSessionToken, AutocompleteSuggestion } =
    await google.maps.importLibrary("places");
  // Add an initial request body.
  let request = {
    input: "Tadi",
    locationRestriction: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
  };
  // Create a session token.
  const token = new AutocompleteSessionToken();

  // Add the token to the request.
  // @ts-ignore
  request.sessionToken = token;

  // Fetch autocomplete suggestions.
  const { suggestions } =
    await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);
  const title = document.getElementById("title");

  title.appendChild(
    document.createTextNode('Query predictions for "' + request.input + '":'),
  );

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a new list element.
    const listItem = document.createElement("li");
    const resultsElement = document.getElementById("results");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.toString()),
    );
    resultsElement.appendChild(listItem);
  }

  let place = suggestions[0].placePrediction.toPlace(); // Get first predicted place.

  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent =
    "First predicted place: " +
    place.displayName +
    ": " +
    place.formattedAddress;
}

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;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Predictions</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="title"></div>
    <ul id="results"></ul>
    <p><span id="prediction"></span></p>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 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: "AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg", v: "weekly"});</script>
  </body>
</html>

تجربة "عيّنة"

وضع النص التالي للإكمال التلقائي من خلال الجلسات

يوضح هذا المثال استدعاء fetchAutocompleteSuggestions() استنادًا إلى طلبات بحث المستخدم، وعرض قائمة بالأماكن المتوقعة للرد، وأخيرًا استرداد تفاصيل المكان للمكان المحدد. يوضح المثال أيضًا استخدام الرموز المميزة للجلسة تجميع طلب بحث المستخدم مع طلب "تفاصيل المكان" الأخير.

TypeScript

let title;
let results;
let input;
let token;

// Add an initial request body.
let request = {
    input: "",
    locationRestriction: { west: -122.44, north: 37.8, east: -122.39, south: 37.78 },
    origin: { lat: 37.7893, lng: -122.4039 },
    includedPrimaryTypes: ["restaurant"],
    language: "en-US",
    region: "us",
};

async function init() {
    token = new google.maps.places.AutocompleteSessionToken();

    title = document.getElementById('title');
    results = document.getElementById('results');
    input = document.querySelector("input");
    input.addEventListener("input", makeAcRequest);
    request = refreshToken(request) as any;
}

async function makeAcRequest(input) {
    // Reset elements and exit if an empty string is received.
    if (input.target.value == '') {
        title.innerText = '';
        results.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = input.target.value;

    // Fetch autocomplete suggestions and show them in a list.
    // @ts-ignore
    const { suggestions } = await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    title.innerText = 'Query predictions for "' + request.input + '"';

    // Clear the list first.
    results.replaceChildren();

    for (const suggestion of suggestions) {
        const placePrediction = suggestion.placePrediction;

        // Create a link for the place, add an event handler to fetch the place.
        const a = document.createElement('a');
        a.addEventListener('click', () => {
            onPlaceSelected(placePrediction.toPlace());
        });
        a.innerText = placePrediction.text.toString();

        // Create a new list element.
        const li = document.createElement('li');
        li.appendChild(a);
        results.appendChild(li);
    }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    await place.fetchFields({
        fields: ['displayName', 'formattedAddress'],
    });
    let placeText = document.createTextNode(place.displayName + ': ' + place.formattedAddress);
    results.replaceChildren(placeText);
    title.innerText = 'Selected Place:';
    input.value = '';
    refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
    // Create a new session token and add it to the request.
    token = new google.maps.places.AutocompleteSessionToken();
    request.sessionToken = token;
    return request;
}

declare global {
    interface Window {
      init: () => void;
    }
  }
  window.init = init;

JavaScript

let title;
let results;
let input;
let token;
// Add an initial request body.
let request = {
  input: "",
  locationRestriction: {
    west: -122.44,
    north: 37.8,
    east: -122.39,
    south: 37.78,
  },
  origin: { lat: 37.7893, lng: -122.4039 },
  includedPrimaryTypes: ["restaurant"],
  language: "en-US",
  region: "us",
};

async function init() {
  token = new google.maps.places.AutocompleteSessionToken();
  title = document.getElementById("title");
  results = document.getElementById("results");
  input = document.querySelector("input");
  input.addEventListener("input", makeAcRequest);
  request = refreshToken(request);
}

async function makeAcRequest(input) {
  // Reset elements and exit if an empty string is received.
  if (input.target.value == "") {
    title.innerText = "";
    results.replaceChildren();
    return;
  }

  // Add the latest char sequence to the request.
  request.input = input.target.value;

  // Fetch autocomplete suggestions and show them in a list.
  // @ts-ignore
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(
      request,
    );

  title.innerText = 'Query predictions for "' + request.input + '"';
  // Clear the list first.
  results.replaceChildren();

  for (const suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    // Create a link for the place, add an event handler to fetch the place.
    const a = document.createElement("a");

    a.addEventListener("click", () => {
      onPlaceSelected(placePrediction.toPlace());
    });
    a.innerText = placePrediction.text.toString();

    // Create a new list element.
    const li = document.createElement("li");

    li.appendChild(a);
    results.appendChild(li);
  }
}

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
  await place.fetchFields({
    fields: ["displayName", "formattedAddress"],
  });

  let placeText = document.createTextNode(
    place.displayName + ": " + place.formattedAddress,
  );

  results.replaceChildren(placeText);
  title.innerText = "Selected Place:";
  input.value = "";
  refreshToken(request);
}

// Helper function to refresh the session token.
async function refreshToken(request) {
  // Create a new session token and add it to the request.
  token = new google.maps.places.AutocompleteSessionToken();
  request.sessionToken = token;
  return request;
}

window.init = 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;
}

a {
  cursor: pointer;
  text-decoration: underline;
  color: blue;
}

input {
  width: 300px;
}

HTML

<html>
  <head>
    <title>Place Autocomplete Data API Session</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <input id="input" type="text" placeholder="Search for a place..." />
    <div id="title"></div>
    <ul id="results"></ul>
    <img
      class="powered-by-google"
      src="https://storage.googleapis.com/geo-devrel-public-buckets/powered_by_google_on_white.png"
      alt="Powered by Google"
    />

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=init&libraries=places&v=weekly"
      defer
    ></script>
  </body>
</html>

تجربة "عيّنة"