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

المطوّرون في المنطقة الاقتصادية الأوروبية

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

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

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

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

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

// Add an initial request body.
const 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.
request.sessionToken = token;

تقييد عبارات البحث المقترحة من خلال ميزة "الإكمال التلقائي"

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

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

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

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

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

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

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

const 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.
request.sessionToken = token;

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

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

أنشئ رمزًا مميزًا للجلسة التالية من خلال إنشاء مثيل جديد من AutocompleteSessionToken.

اقتراحات بشأن الرموز المميّزة للجلسات:

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

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

مثال

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

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

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

مثال على الرمز الكامل

يحتوي هذا القسم على أمثلة كاملة توضّح كيفية استخدام واجهة Place Autocomplete Data API .

عبارات البحث المقترحة من خلال ميزة "الإكمال التلقائي" للأماكن

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

TypeScript

async function init() {
    const { AutocompleteSessionToken, AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    // Add an initial request body.
    const request: google.maps.places.AutocompleteRequest = {
        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.
    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 + '":'
        )
    );

    const resultsElement = document.getElementById('results')!;

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

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

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

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

void init();

JavaScript

async function init() {
    const { AutocompleteSessionToken, AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    // Add an initial request body.
    const 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.
    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 + '":'
        )
    );

    const resultsElement = document.getElementById('results');

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

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

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

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

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

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>
        <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="title"></div>
        <ul id="results"></ul>
        <p><span id="prediction"></span></p>
        <img
            class="powered-by-google"
            src="./powered_by_google_on_white.png"
            alt="Powered by Google" />
    </body>
</html>

الإكمال التلقائي للأماكن أثناء الكتابة مع الجلسات

يوضّح هذا المثال المفاهيم التالية:

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

TypeScript

const mapElement = document.querySelector('gmp-map')!;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
const titleElement = document.querySelector<HTMLElement>('.title')!;
const resultsContainerElement = document.querySelector('.results')!;
const inputElement = document.querySelector('input')!;
const tokenStatusElement = document.querySelector('.token-status')!;
let newestRequestId = 0;
let tokenCount = 0;

// Create an initial request body.
const request: google.maps.places.AutocompleteRequest = {
    input: '',
    includedPrimaryTypes: [
        'restaurant',
        'cafe',
        'museum',
        'park',
        'botanical_garden',
    ],
};

async function init() {
    await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Update request center and bounds when the map bounds change.
    innerMap.addListener('bounds_changed', () => {
        request.locationRestriction = innerMap.getBounds();
        request.origin = innerMap.getCenter();
    });

    inputElement.addEventListener('input', makeAutocompleteRequest);
}

async function makeAutocompleteRequest(inputEvent: Event) {
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

    const { AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    if (!(inputEvent.target as HTMLInputElement)?.value) {
        titleElement.textContent = '';
        resultsContainerElement.replaceChildren();
        return;
    }

    // Add the latest char sequence to the request.
    request.input = (inputEvent.target as HTMLInputElement).value;

    // Fetch autocomplete suggestions and show them in a list.
    const { suggestions } =
        await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Place predictions for "${request.input}"`;

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

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

        if (!placePrediction) {
            continue;
        }

        // Create a link for the place, add an event handler to fetch the place.
        // We are using a button element to take advantage of its a11y capabilities.
        const placeButton = document.createElement('button');
        placeButton.addEventListener('click', () => {
            void onPlaceSelected(placePrediction.toPlace());
        });

        placeButton.textContent = placePrediction.text.toString();
        placeButton.classList.add('place-button');

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

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place: google.maps.places.Place) {
    const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');

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

    resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`;
    titleElement.textContent = 'Selected Place:';
    inputElement.value = '';

    await refreshToken();

    // Remove the previous marker, if it exists.
    if (marker) {
        marker.remove();
    }

    // Create a new marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    });

    // Center the map on the selected place.
    if (place.location) {
        innerMap.setCenter(place.location);
        innerMap.setZoom(15);
    }
}

// Helper function to refresh the session token.
async function refreshToken() {
    const { AutocompleteSessionToken } =
        await google.maps.importLibrary('places');

    // Increment the token counter.
    tokenCount++;

    // Create a new session token and add it to the request.
    request.sessionToken = new AutocompleteSessionToken();
    tokenStatusElement.textContent = `Session token count: ${tokenCount}`;
}

void init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
let marker;
const titleElement = document.querySelector('.title');
const resultsContainerElement = document.querySelector('.results');
const inputElement = document.querySelector('input');
const tokenStatusElement = document.querySelector('.token-status');
let newestRequestId = 0;
let tokenCount = 0;

// Create an initial request body.
const request = {
    input: '',
    includedPrimaryTypes: [
        'restaurant',
        'cafe',
        'museum',
        'park',
        'botanical_garden',
    ],
};

async function init() {
    await google.maps.importLibrary('maps');
    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
    });

    // Update request center and bounds when the map bounds change.
    innerMap.addListener('bounds_changed', () => {
        request.locationRestriction = innerMap.getBounds();
        request.origin = innerMap.getCenter();
    });

    inputElement.addEventListener('input', makeAutocompleteRequest);
}

async function makeAutocompleteRequest(inputEvent) {
    // To avoid race conditions, store the request ID and compare after the request.
    const requestId = ++newestRequestId;

    const { AutocompleteSuggestion } =
        await google.maps.importLibrary('places');

    if (!inputEvent.target?.value) {
        titleElement.textContent = '';
        resultsContainerElement.replaceChildren();
        return;
    }

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

    // Fetch autocomplete suggestions and show them in a list.
    const { suggestions } =
        await AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

    // If the request has been superseded by a newer request, do not render the output.
    if (requestId !== newestRequestId) return;

    titleElement.innerText = `Place predictions for "${request.input}"`;

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

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

        if (!placePrediction) {
            continue;
        }

        // Create a link for the place, add an event handler to fetch the place.
        // We are using a button element to take advantage of its a11y capabilities.
        const placeButton = document.createElement('button');
        placeButton.addEventListener('click', () => {
            void onPlaceSelected(placePrediction.toPlace());
        });

        placeButton.textContent = placePrediction.text.toString();
        placeButton.classList.add('place-button');

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

// Event handler for clicking on a suggested place.
async function onPlaceSelected(place) {
    const { AdvancedMarkerElement } = await google.maps.importLibrary('marker');

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

    resultsContainerElement.textContent = `${place.displayName}: ${place.formattedAddress}`;
    titleElement.textContent = 'Selected Place:';
    inputElement.value = '';

    await refreshToken();

    // Remove the previous marker, if it exists.
    if (marker) {
        marker.remove();
    }

    // Create a new marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
        position: place.location,
        title: place.displayName,
    });

    // Center the map on the selected place.
    if (place.location) {
        innerMap.setCenter(place.location);
        innerMap.setZoom(15);
    }
}

// Helper function to refresh the session token.
async function refreshToken() {
    const { AutocompleteSessionToken } =
        await google.maps.importLibrary('places');

    // Increment the token counter.
    tokenCount++;

    // Create a new session token and add it to the request.
    request.sessionToken = new AutocompleteSessionToken();
    tokenStatusElement.textContent = `Session token count: ${tokenCount}`;
}

void init();

CSS

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

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

.place-button {
    height: 3rem;
    width: 100%;
    background-color: transparent;
    text-align: left;
    border: none;
    cursor: pointer;
}

.place-button:focus-visible {
    outline: 2px solid #0056b3;
    border-radius: 2px;
}

.input {
    width: 300px;
    font-size: small;
    margin-bottom: 1rem;
}

/* Styles for the floating panel */
.controls {
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
    font-family: sans-serif;
    font-size: small;
    margin: 12px;
    padding: 1rem;
}

.title {
    font-weight: bold;
    margin-top: 1rem;
    margin-bottom: 0.5rem;
}

.results {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

.results li:not(:last-child) {
    border-bottom: 1px solid #ddd;
}

.results li:hover {
    background-color: #eee;
}

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>
        <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>
        <gmp-map center="37.7893, -122.4039" zoom="12" map-id="DEMO_MAP_ID">
            <div class="controls" slot="control-inline-start-block-start">
                <input
                    type="text"
                    class="input"
                    placeholder="Search for a place..."
                    autocomplete="off" /><!-- Turn off the input's own autocomplete (not supported by all browsers).-->
                <div class="token-status"></div>
                <div class="title"></div>
                <ol class="results"></ol>
            </div>
        </gmp-map>
    </body>
</html>

تحسين ميزة "الإكمال التلقائي (جديد)"

يوضّح هذا القسم أفضل الممارسات لمساعدتك في الاستفادة إلى أقصى حدّ من خدمة "الإكمال التلقائي (جديد)".

إليك بعض الإرشادات العامة:

  • أسرع طريقة لتطوير واجهة مستخدم فعّالة هي استخدام تطبيق &quot;الإكمال التلقائي&quot; (الجديد) المصغّر في Maps JavaScript API، أو تطبيق &quot;الإكمال التلقائي&quot; (الجديد) المصغّر في حزمة تطوير البرامج بالاستناد إلى بيانات &quot;الأماكن&quot; لنظام التشغيل Android، أو تطبيق &quot;الإكمال التلقائي&quot; (الجديد) المصغّر في حزمة تطوير البرامج بالاستناد إلى بيانات &quot;الأماكن&quot; لنظام التشغيل iOS.
  • يمكنك فهم حقول البيانات الأساسية في ميزة "الإكمال التلقائي (جديد)" من البداية.
  • إنّ حقول تحديد الموقع الجغرافي وحظر المواقع الجغرافية اختيارية، ولكن يمكن أن يكون لها تأثير كبير في أداء ميزة "الإكمال التلقائي".
  • استخدِم معالجة الأخطاء للتأكّد من أنّ تطبيقك يتراجع بشكل سلس في حال عرضت واجهة برمجة التطبيقات خطأً.
  • تأكَّد من أنّ تطبيقك يتعامل مع الحالات التي لا يتم فيها تحديد أي خيار، ويوفّر للمستخدمين طريقة للمتابعة.

أفضل الممارسات لتحسين التكلفة

تحسين التكلفة الأساسية

لتحسين تكلفة استخدام خدمة "الإكمال التلقائي (جديد)"، استخدِم أقنعة الحقول في تطبيقات "تفاصيل المكان (جديد)" و"الإكمال التلقائي (جديد)" المصغّرة لعرض حقول بيانات "الإكمال التلقائي (جديد)" التي تحتاج إليها فقط.

تحسين التكلفة المتقدّم

ننصحك بتنفيذ ميزة "الإكمال التلقائي (الجديدة)" آليًا للوصول إلى رمز التخزين التعريفي: أسعار طلبات الإكمال التلقائي وطلب نتائج Geocoding API حول المكان المحدّد بدلاً من ميزة "تفاصيل المكان (الجديدة)". يكون التسعير لكل طلب مع Geocoding API أكثر فعالية من حيث التكلفة مقارنةً بالتسعير لكل جلسة (المستند إلى الجلسة) في حال استيفاء الشرطَين التاليَين:

  • إذا كنت بحاجة فقط إلى خط العرض وخط الطول أو عنوان المكان الذي اختاره المستخدم، توفّر Geocoding API هذه المعلومات بتكلفة أقل من طلب تفاصيل المكان (جديد).
  • إذا اختار المستخدمون عبارة بحث مقترحة ضمن متوسط أربعة طلبات أو أقل من طلبات عبارات البحث المقترحة (الجديدة)، يمكن أن يكون السعر لكل طلب أقل تكلفة من السعر لكل جلسة.
للحصول على مساعدة في اختيار طريقة تنفيذ ميزة "الإكمال التلقائي (جديد)" التي تناسب احتياجاتك، اختَر علامة التبويب التي تتوافق مع إجابتك عن السؤال التالي.

هل يتطلّب تطبيقك أي معلومات أخرى غير العنوان وخط العرض/خط الطول للتوقّع المحدّد؟

نعم، يجب إضافة المزيد من التفاصيل

استخدِم ميزة "الإكمال التلقائي (جديد)" المستندة إلى الجلسة مع ميزة "تفاصيل المكان (جديد)".
بما أنّ تطبيقك يتطلّب استخدام ميزة "تفاصيل المكان (الجديدة)"، مثل اسم المكان أو حالة المؤسسة أو ساعات العمل، يجب أن يستخدم تنفيذك لميزة "الإكمال التلقائي (الجديدة)" رمزًا مميزًا للجلسة (برمجيًا أو مضمّنًا في تطبيقات JavaScript أو Android أو iOS المصغّرة) لكل جلسة بالإضافة إلى رموز التخزين التعريفية السارية في Places، استنادًا إلى حقول بيانات المكان التي تطلبها.1

تنفيذ التطبيق المصغّر
يتم دمج إدارة الجلسات تلقائيًا في التطبيقات المصغّرة JavaScript أو Android أو iOS. ويشمل ذلك كلاً من طلبات "الإكمال التلقائي (الجديد)" وطلب "تفاصيل المكان (الجديد)" بشأن عبارة البحث المقترَحة المحدّدة. تأكَّد من تحديد المَعلمة fields لضمان طلب حقول بيانات الإكمال التلقائي (الجديدة) التي تحتاج إليها فقط.

التنفيذ الآلي
استخدِم رمزًا مميزًا للجلسة مع طلبات "الإكمال التلقائي (الجديد)". عند طلب تفاصيل المكان (الإصدار الجديد) حول عبارة البحث المقترَحة المحدّدة، يجب تضمين المَعلمات التالية:

  1. رقم تعريف المكان من ردّ "الإكمال التلقائي (الجديد)"
  2. الرمز المميّز للجلسة المستخدَم في طلب الإكمال التلقائي (الجديد)
  3. المَعلمة fields التي تحدّد حقول بيانات ميزة "الإكمال التلقائي (جديد)" التي تحتاج إليها

لا، يحتاج فقط إلى العنوان والموقع الجغرافي

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

للإجابة عن السؤال التالي، عليك تحليل عدد الأحرف التي يكتبها المستخدم في المتوسط قبل اختيار عبارة مقترَحة من ميزة "الإكمال التلقائي (جديد)" في تطبيقك.

هل يختار المستخدمون عبارة مقترَحة من ميزة "الإكمال التلقائي (جديد)" في أربعة طلبات أو أقل في المتوسط؟

نعم

تنفيذ ميزة "الإكمال التلقائي (جديد)" آليًا بدون الرموز المميّزة للجلسات واستدعاء Geocoding API في توقّعات المكان المحدّد
توفّر واجهة Geocoding API العناوين وإحداثيات خطوط العرض والطول. إنّ إجراء أربعة طلبات إكمال تلقائي بالإضافة إلى طلب بيانات من Geocoding API بشأن عبارة البحث المقترَحة المحدّدة للمكان هو أقل من تكلفة الإكمال التلقائي (الجديد) لكل جلسة.1

ننصحك باتّباع أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على التوقّعات التي يبحثون عنها باستخدام عدد أقل من الأحرف.

لا

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

تنفيذ التطبيق المصغّر
يتم دمج إدارة الجلسات تلقائيًا في التطبيقات المصغّرة التي تستخدم JavaScript أو Android أو iOS. ويشمل ذلك كلاً من طلبات &quot;الإكمال التلقائي (الجديد)&quot; وطلب &quot;تفاصيل المكان (الجديد)&quot; بشأن عبارة البحث المقترَحة المحدّدة. احرص على تحديد مَعلمة fields لضمان طلب الحقول التي تحتاج إليها فقط.

التنفيذ الآلي
استخدِم رمزًا مميزًا للجلسة مع طلبات "الإكمال التلقائي (الجديد)". عند طلب تفاصيل المكان (الإصدار الجديد) حول عبارة البحث المقترَحة المحدّدة، يجب تضمين المَعلمات التالية:

  1. رقم تعريف المكان من ردّ "الإكمال التلقائي (الجديد)"
  2. الرمز المميّز للجلسة المستخدَم في طلب الإكمال التلقائي (الجديد)
  3. مَعلمة fields التي تحدّد الحقول مثل العنوان والشكل الهندسي

ننصحك بتأخير طلبات "الإكمال التلقائي (جديد)"
يمكنك استخدام استراتيجيات مثل تأخير طلب "الإكمال التلقائي (جديد)" إلى أن يكتب المستخدم الأحرف الثلاثة أو الأربعة الأولى لكي يرسل تطبيقك عددًا أقل من الطلبات. على سبيل المثال، إذا أرسلت طلبات "الإكمال التلقائي (جديد)" لكل حرف بعد أن يكتب المستخدم الحرف الثالث، يعني ذلك أنّه إذا كتب المستخدم سبعة أحرف ثم اختار عبارة بحث مقترَحة ترسل لها طلب بيانات من واجهة برمجة التطبيقات واحدًا من Geocoding API، ستكون التكلفة الإجمالية مقابل 4 طلبات "الإكمال التلقائي (جديد)" لكل طلب + الترميز الجغرافي.1

إذا كان تأخير الطلبات يمكن أن يخفّض متوسط الطلبات الآلية إلى أقل من أربعة، يمكنك اتّباع الإرشادات الخاصة بتنفيذ ميزة "الإكمال التلقائي (جديد)" العالية الأداء مع Geocoding API. يُرجى العِلم أنّ تأخير الطلبات قد يظهر للمستخدم على أنّه وقت استجابة، وقد يتوقّع المستخدم ظهور عبارات بحث مقترَحة مع كل ضغطة مفتاح جديدة.

ننصحك باتّباع أفضل الممارسات المتعلّقة بالأداء لمساعدة المستخدمين في الحصول على التوقّعات التي يبحثون عنها باستخدام عدد أقل من الأحرف.


  1. لمعرفة التكاليف، يُرجى الاطّلاع على قوائم أسعار "منصة خرائط Google".

أفضل الممارسات المتعلّقة بالأداء

توضّح الإرشادات التالية طرق تحسين أداء ميزة "الإكمال التلقائي (جديد)":

  • أضِف القيود المفروضة على البلدان والانحياز للموقع الجغرافي واللغة المفضّلة (لعمليات التنفيذ الآلية) إلى عملية تنفيذ ميزة "الإكمال التلقائي (جديد)". لا حاجة إلى تحديد اللغة المفضّلة عند استخدام التطبيقات المصغّرة لأنّها تختار اللغات المفضّلة من متصفّح المستخدم أو جهازه الجوّال.
  • إذا كانت ميزة "الإكمال التلقائي (جديد)" مصحوبة بخريطة، يمكنك تحديد الموقع الجغرافي حسب إطار العرض في الخريطة.
  • في الحالات التي لا يختار فيها المستخدم إحدى عبارات البحث المقترَحة من ميزة &quot;الإكمال التلقائي (جديد)&quot;، لأنّ أيًا من هذه العبارات لا يمثّل العنوان المطلوب، يمكنك إعادة استخدام البيانات التي أدخلها المستخدم في الأصل لمحاولة الحصول على نتائج أكثر صلة:
    • إذا كنت تتوقّع أن يُدخل المستخدم معلومات العنوان فقط، أعِد استخدام البيانات الأصلية التي أدخلها المستخدم في طلب إلى Geocoding API.
    • إذا كنت تتوقّع أن يُدخل المستخدم طلبات بحث عن مكان معيّن حسب الاسم أو العنوان، استخدِم طلب "تفاصيل المكان (جديد)". إذا كان من المتوقّع ظهور النتائج في منطقة معيّنة فقط، استخدِم الانحياز للموقع الجغرافي.
    تشمل السيناريوهات الأخرى التي يُفضَّل فيها استخدام Geocoding API ما يلي:
    • المستخدمون الذين يُدخلون عناوين فرعية، مثل عناوين وحدات أو شقق معيّنة داخل مبنى على سبيل المثال، يؤدي العنوان التشيكي "Stroupežnického 3191/17, Praha" إلى عرض عبارة بحث مقترَحة جزئية في ميزة "الإكمال التلقائي" (الإصدار الجديد).
    • المستخدمون الذين يُدخلون عناوين تحتوي على بادئات لأجزاء من الطرق، مثل "‎23-30 29th St, Queens" في مدينة نيويورك أو "‎47-380 Kamehameha Hwy, Kaneohe" في جزيرة كاواي في هاواي

تحديد الموقع الجغرافي

يمكنك تحسين النتائج لمنطقة معيّنة من خلال تمرير مَعلمة location ومَعلمة radius. يؤدي ذلك إلى توجيه ميزة "الإكمال التلقائي (جديد)" إلى تفضيل عرض النتائج ضمن المنطقة المحدّدة. وقد يستمر عرض النتائج خارج المنطقة المحدّدة. يمكنك استخدام المَعلمة includedRegionCodes لفلترة النتائج وعرض الأماكن ضمن بلد محدّد فقط.

تقييد الموقع الجغرافي

يمكنك حصر النتائج بمنطقة معيّنة من خلال تمرير مَعلمة locationRestriction.

يمكنك أيضًا حصر النتائج بالمنطقة المحدّدة من خلال المَعلمة location والمَعلمة radius، وذلك من خلال إضافة المَعلمة locationRestriction. يؤدي ذلك إلى توجيه خدمة "الإكمال التلقائي (جديد)" لعرض النتائج ضمن تلك المنطقة فقط.