Place Autocomplete Data API

מפתחים באזור הכלכלי האירופי (EEA)

‫Place Autocomplete Data API מאפשר לכם לאחזר תחזיות של מקומות באופן פרוגרמטי, כדי ליצור חוויות השלמה אוטומטית מותאמות אישית עם רמת שליטה גבוהה יותר מזו שאפשרה ווידג'ט ההשלמה האוטומטית. במדריך הזה נסביר איך להשתמש ב-Place Autocomplete Data API כדי לשלוח בקשות להשלמה אוטומטית על סמך שאילתות של משתמשים.

בדוגמה הבאה מוצג שילוב פשוט של השלמה אוטומטית. מזינים את שאילתת החיפוש, למשל 'פיצה' או 'פוקי', ואז לוחצים על התוצאה הרצויה כדי לבחור בה.

בקשות להשלמה אוטומטית

בקשה להשלמה אוטומטית מקבלת מחרוזת קלט של שאילתה ומחזירה רשימה של חיזויים של מקומות. כדי לשלוח בקשה להשלמה אוטומטית, קוראים ל-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 כדי לציין עד חמישה סוגי מקומות. אם לא מציינים סוגים, יוחזרו מקומות מכל הסוגים.

לעיון בהפניית ה-API

קבלת פרטי מקום

כדי להחזיר אובייקט 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'],
});

יוצרים טוקן הפעלה להפעלה הבאה על ידי יצירת מופע חדש של AutocompleteSessionToken.

המלצות לטוקן סשן:

  • מומלץ להשתמש באסימוני סשן לכל הקריאות ל-Place Autocomplete.
  • צריך ליצור טוקן חדש לכל סשן.
  • צריך להעביר טוקן ייחודי של סשן לכל סשן חדש. אם משתמשים באותו אסימון ליותר מסשן אחד, כל בקשה תחויב בנפרד.

אפשר גם להשמיט את טוקן הסשן של ההשלמה האוטומטית מבקשה. אם לא מציינים את טוקן הסשן, כל בקשה מחויבת בנפרד, והשימוש במק"ט השלמה אוטומטית – לכל בקשה מופעל. אם משתמשים מחדש בטוקן סשן, הסשן נחשב לא תקף והחיוב על הבקשות מתבצע כאילו לא סופק טוקן סשן.

דוגמה

בזמן שהמשתמש מקליד שאילתה, נשלחת בקשה להשלמה אוטומטית אחרי כל כמה הקשות (לא אחרי כל תו), ומוחזרת רשימה של תוצאות אפשריות. כשמשתמש בוחר משהו מרשימת התוצאות, הבחירה נחשבת כבקשה, וכל הבקשות שנשלחות במהלך החיפוש מקובצות יחד ונספרות כבקשה אחת. אם המשתמש בוחר מקום, שאילתת החיפוש זמינה ללא תשלום, ורק בקשת הנתונים של המקום מחויבת. אם המשתמש לא בוחר תוך כמה דקות מתחילת הסשן, הוא יחויב רק על שאילתת החיפוש.

מנקודת המבט של אפליקציה, רצף האירועים הוא כזה:

  1. משתמש מתחיל להקליד שאילתה כדי לחפש את 'פריז, צרפת'.
  2. כשמזוהה קלט משתמש, האפליקציה יוצרת אסימון סשן חדש, Token A.
  3. בזמן שהמשתמש מקליד, ה-API שולח בקשה להשלמה אוטומטית אחרי כל כמה תווים, ומציג רשימה חדשה של תוצאות אפשריות לכל אחד מהם:
    'P'
    'Par'
    'Paris'
    'Paris, Fr'
  4. כשהמשתמש בוחר:
    • כל הבקשות שנובעות מהשאילתה מקובצות ונוספות לסשן שמיוצג על ידי Token A, כבקשה אחת.
    • הבחירה של המשתמש נספרת כבקשה לפרטי מקום, והיא מתווספת לסשן שמיוצג על ידי Token A.
  5. הסשן מסתיים, והאפליקציה מבטלת את האסימון A.
מידע על חיוב על סשנים

קוד לדוגמה מלא

בקטע הזה יש דוגמאות מלאות שמראות איך להשתמש ב-Place Autocomplete Data API .

הצעות להשלמת החיפוש של מקומות

בדוגמה הבאה מוסבר איך להפעיל את השיטה fetchAutocompleteSuggestions() כדי לקבל את התוצאה של ההשלמה האוטומטית של הקלט 'Tadi', ואז להפעיל את השיטה toPlace() כדי לקבל את התוצאה הראשונה של ההשלמה האוטומטית, ואז להפעיל את השיטה fetchFields() כדי לקבל את פרטי המקום.

TypeScript

async function init() {
    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 + '":'
        )
    );

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

    for (let 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);
    }

    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

async function init() {
    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 + '":'));
    const resultsElement = document.getElementById('results');
    for (let 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);
    }
    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>
        <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</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() על סמך שאילתות של משתמשים והצגת רשימה של מקומות חזויים בתגובה.
  • שימוש באסימוני סשן כדי לקבץ שאילתת משתמש עם בקשת הפרטים הסופית של המקום.
  • שליפת פרטי המקום שנבחר והצגת סמן.
  • שימוש ב-control slotting כדי להטמיע רכיבי ממשק משתמש ברכיב gmp-map.

TypeScript

const mapElement = document.querySelector('gmp-map') as google.maps.MapElement;
let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;
let titleElement = document.querySelector('.title') as HTMLElement;
let resultsContainerElement = document.querySelector('.results') as HTMLElement;
let inputElement = document.querySelector('input') as HTMLInputElement;
let tokenStatusElement = document.querySelector('.token-status') as HTMLElement;
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.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        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'
    )) as google.maps.PlacesLibrary;

    if (!inputEvent.target?.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', () => {
            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'
    )) as google.maps.MarkerLibrary;

    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'
    )) as google.maps.PlacesLibrary;

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

init();

JavaScript

const mapElement = document.querySelector('gmp-map');
let innerMap;
let marker;
let titleElement = document.querySelector('.title');
let resultsContainerElement = document.querySelector('.results');
let inputElement = document.querySelector('input');
let 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.
    google.maps.event.addListener(innerMap, 'bounds_changed', async () => {
        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', () => {
            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}`;
}
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>
        <!-- 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: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "weekly"});</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>

דוגמה לניסיון

אופטימיזציה של השלמה אוטומטית (חדש)

בקטע הזה מתוארות שיטות מומלצות שיעזרו לכם להפיק את המרב מהשירות 'השלמה אוטומטית (חדש)'.

הנה כמה הנחיות כלליות:

  • הדרך הכי מהירה לפתח ממשק משתמש תקין היא להשתמש בווידג'ט החדש של השלמה אוטומטית ב-Maps JavaScript API, בווידג'ט החדש של השלמה אוטומטית ב-Places SDK ל-Android או בווידג'ט החדש של השלמה אוטומטית ב-Places SDK ל-iOS.
  • הבנה של שדות הנתונים החיוניים של ההשלמה האוטומטית (חדש) כבר מההתחלה.
  • השדות 'הטיה לפי מיקום' ו'הגבלת מיקום' הם אופציונליים, אבל יכולה להיות להם השפעה משמעותית על הביצועים של ההשלמה האוטומטית.
  • כדאי להשתמש בטיפול בשגיאות כדי לוודא שהאפליקציה תפעל בצורה תקינה גם אם ה-API יחזיר שגיאה.
  • חשוב לוודא שהאפליקציה מטפלת במקרים שבהם לא נבחרה אפשרות, ומציעה למשתמשים דרך להמשיך.

שיטות מומלצות לאופטימיזציה של עלויות

אופטימיזציה בסיסית של עלויות

כדי לייעל את העלות של השימוש בשירות 'השלמה אוטומטית (חדש)', כדאי להשתמש במסכות שדות בווידג'טים 'פרטי מקום (חדש)' ו'השלמה אוטומטית (חדש)' כדי להחזיר רק את שדות הנתונים של 'השלמה אוטומטית (חדש)' שאתם צריכים.

אופטימיזציה מתקדמת של עלויות

כדאי לשקול הטמעה פרוגרמטית של השלמה אוטומטית (חדש) כדי לגשת אל מק"ט: תמחור של בקשות להשלמה אוטומטית ולבקש תוצאות של Geocoding API לגבי המקום שנבחר במקום פרטי מקום (חדש). התמחור לפי בקשה בשילוב עם Geocoding API הוא חסכוני יותר מהתמחור לפי סשן (מבוסס-סשן) אם מתקיימים שני התנאים הבאים:

  • אם אתם צריכים רק את קו הרוחב/קו האורך או את הכתובת של המקום שהמשתמש בחר, Geocoding API מספק את המידע הזה בפחות משיחה של Place Details (New).
  • אם המשתמשים בוחרים תחזית להשלמה אוטומטית בממוצע של ארבע בקשות או פחות להשלמה אוטומטית (חדשה), יכול להיות שהתמחור לפי בקשה יהיה חסכוני יותר מהתמחור לפי סשן.
כדי לקבל עזרה בבחירת ההטמעה של התכונה 'השלמה אוטומטית (חדשה)' שמתאימה לצרכים שלכם, בוחרים את הכרטיסייה שמתאימה לתשובה שלכם לשאלה הבאה.

האם האפליקציה שלך דורשת מידע כלשהו מלבד הכתובת וקו הרוחב/קו האורך של החיזוי שנבחר?

כן, צריך עוד פרטים

שימוש בהשלמה אוטומטית מבוססת-סשן (חדש) עם Place Details (חדש).
מכיוון שהאפליקציה שלך דורשת פרטים על מקומות (חדש), כמו שם המקום, סטטוס העסק או שעות הפתיחה, ההטמעה של ההשלמה האוטומטית (חדש) צריכה להשתמש באסימון סשן (באופן פרוגרמטי או מוטמע בווידג'טים של JavaScript,‏ Android או iOS) לכל סשן, בנוסף למק"טים הרלוונטיים של Places, בהתאם לשדות הנתונים של המקום שביקשת.1

הטמעה של ווידג'ט
ניהול הסשנים מוטמע אוטומטית בווידג'טים של JavaScript, Android, או iOS. הבקשה כוללת גם את הבקשות של ההשלמה האוטומטית (חדש) וגם את הבקשה של פרטי המקום (חדש) לחיזוי שנבחר. כדי לוודא שאתם מבקשים רק את שדות הנתונים שאתם צריכים להשלמה אוטומטית (חדש), הקפידו לציין את הפרמטר fields.

הטמעה פרוגרמטית
משתמשים בטוקן סשן בבקשות של השלמה אוטומטית (חדשה). כשמבקשים פרטים על מקום (חדש) לגבי התחזית שנבחרה, צריך לכלול את הפרמטרים הבאים:

  1. מזהה המקום מהתשובה של ההשלמה האוטומטית (חדש)
  2. טוקן הסשן שמשמש בבקשה של ההשלמה האוטומטית (חדשה)
  3. הפרמטר fields שמציין את שדות הנתונים של ההשלמה האוטומטית (חדש) שאתם צריכים

לא, צריך רק כתובת ומיקום

יכול להיות ש-Geocoding API יהיה אפשרות חסכונית יותר מאשר Place Details (New) לאפליקציה שלכם, בהתאם לביצועים של השימוש ב-Autocomplete (New). היעילות של ההשלמה האוטומטית (חדשה) בכל אפליקציה משתנה בהתאם למה שהמשתמשים מזינים, איפה האפליקציה נמצאת והאם הוטמעו שיטות מומלצות לאופטימיזציה של הביצועים.

כדי לענות על השאלה הבאה, צריך לנתח כמה תווים משתמש מקליד בממוצע לפני שהוא בוחר חיזוי של השלמה אוטומטית (חדשה) באפליקציה.

האם המשתמשים בוחרים חיזוי של השלמה אוטומטית (חדשה) בארבע בקשות או פחות, בממוצע?

כן

הטמעה של השלמה אוטומטית (חדש) באופן פרוגרמטי ללא טוקנים של סשן, וקריאה ל-Geocoding API בתחזית המיקום שנבחרה.
‫Geocoding API מספק כתובות וקואורדינטות של קו רוחב וקו אורך. ביצוע ארבע בקשות של השלמה אוטומטית בתוספת קריאה ל-Geocoding API לגבי החיזוי של המקום שנבחר, עולה פחות מהעלות של השלמה אוטומטית (חדשה) לכל סשן.1

כדאי להשתמש בשיטות מומלצות לשיפור הביצועים כדי לעזור למשתמשים לקבל את התחזית שהם מחפשים גם אם הם מקלידים פחות תווים.

לא

שימוש בהשלמה אוטומטית מבוססת-סשן (חדש) עם Place Details (חדש).
מכיוון שהמספר הממוצע של הבקשות שצפויות להתבצע לפני שמשתמש בוחר השלמה אוטומטית (חדשה) חורג מהעלות של תמחור לפי סשן, ההטמעה של ההשלמה האוטומטית (חדשה) צריכה להשתמש באסימון סשן גם לבקשות של ההשלמה האוטומטית (חדשה) וגם לבקשה המשויכת של פרטי מקום (חדשים) לכל סשן. 1

הטמעה של ווידג'ט
ניהול הסשנים מוטמע אוטומטית בווידג'טים של JavaScript, Android, או iOS. הבקשות האלה כוללות גם את הבקשות של ההשלמה האוטומטית (חדש) וגם את הבקשות של פרטי המקום (חדש) לגבי החיזוי שנבחר. כדי לוודא שאתם מבקשים רק את השדות שאתם צריכים, חשוב לציין את הפרמטר fields.

הטמעה פרוגרמטית
משתמשים בטוקן סשן בבקשות של השלמה אוטומטית (חדשה). כשמבקשים פרטים על מקום (חדש) לגבי התחזית שנבחרה, צריך לכלול את הפרמטרים הבאים:

  1. מזהה המקום מהתשובה של ההשלמה האוטומטית (חדש)
  2. טוקן הסשן שמשמש בבקשה של ההשלמה האוטומטית (חדשה)
  3. הפרמטר fields שמציין שדות כמו כתובת וגיאומטריה

כדאי לשקול לדחות בקשות של השלמה אוטומטית (חדשה)
אפשר להשתמש באסטרטגיות כמו דחיית בקשה של השלמה אוטומטית (חדשה) עד שהמשתמש יקליד את שלושת או ארבעת התווים הראשונים, כדי שהאפליקציה תשלח פחות בקשות. לדוגמה, אם שולחים בקשות להשלמה אוטומטית (חדשה) לכל תו אחרי שהמשתמש הקליד את התו השלישי, ואם המשתמש מקליד שבעה תווים ואז בוחר תחזית שבשבילה נשלחת בקשה אחת ל-Geocoding API, העלות הכוללת תהיה של 4 בקשות להשלמה אוטומטית (חדשה) + קידוד גאוגרפי.1

אם עיכוב הבקשות יכול להוריד את הממוצע של הבקשות הפרוגרמטיות מתחת לארבע, אפשר לפעול לפי ההנחיות להטמעה של השלמה אוטומטית יעילה (חדשה) עם Geocoding API. חשוב לזכור שעיכוב בקשות עלול להיתפס כזמן אחזור על ידי המשתמש, שאולי מצפה לראות תחזיות עם כל הקשה חדשה על המקשים.

כדאי להשתמש בשיטות מומלצות לשיפור הביצועים כדי לעזור למשתמשים לקבל את התחזית שהם מחפשים בפחות תווים.


  1. למידע על עלויות, אפשר לעיין ברשימות המחירים של הפלטפורמה של מפות Google.

שיטות מומלצות לשיפור הביצועים

בהנחיות הבאות מפורטות דרכים לאופטימיזציה של הביצועים של התכונה 'השלמה אוטומטית (חדשה)':

  • מוסיפים הגבלות לפי מדינה, הטיה לפי מיקום, והעדפת שפה (להטמעות פרוגרמטיות) להטמעה של התכונה 'השלמה אוטומטית (חדשה)'. אין צורך בהעדפת שפה בווידג'טים, כי הם בוחרים את העדפות השפה מתוך הדפדפן או המכשיר הנייד של המשתמש.
  • אם ההשלמה האוטומטית (חדשה) מופיעה עם מפה, אפשר להטות את המיקום לפי אזור התצוגה של המפה.
  • במצבים שבהם משתמש לא בוחר באף אחת מההצעות להשלמה אוטומטית (חדשה), בדרך כלל כי אף אחת מההצעות האלה לא מתאימה לכתובת שהוא מחפש, אפשר להשתמש מחדש בקלט המקורי של המשתמש כדי לנסות לקבל תוצאות רלוונטיות יותר:
    • אם אתם מצפים שהמשתמש יזין רק פרטי כתובת, תוכלו להשתמש מחדש בקלט המקורי של המשתמש בקריאה ל-Geocoding API.
    • אם אתם מצפים שהמשתמש יזין שאילתות לגבי מקום ספציפי לפי שם או כתובת, תשתמשו בבקשה של פרטי מקום (חדש). אם אתם מצפים לתוצאות רק באזור מסוים, כדאי להשתמש בהטיה לפי מיקום.
    תרחישים נוספים שבהם מומלץ לחזור ל-Geocoding API כוללים:
    • משתמשים שמזינים כתובות של יחידות משנה, כמו כתובות של יחידות או דירות ספציפיות בתוך בניין. לדוגמה, הכתובת הצ'כית "Stroupežnického 3191/17, Praha" תניב חיזוי חלקי בהשלמה האוטומטית (חדש).
    • משתמשים שמזינים כתובות עם קידומות של קטע כביש כמו "23-30 29th St, Queens" בניו יורק או "47-380 Kamehameha Hwy, Kaneohe" באי קוואי בהוואי.

הטיה של מיקום

כדי להטות את התוצאות לאזור מסוים, מעבירים פרמטר location ופרמטר radius. ההגדרה הזו מורה להשלמה האוטומטית (חדשה) להעדיף הצגת תוצאות באזור המוגדר. יכול להיות שיוצגו תוצאות מחוץ לאזור שהוגדר. אפשר להשתמש בפרמטר components כדי לסנן את התוצאות ולהציג רק מקומות במדינה שצוינה.

הגבלת מיקום

כדי להגביל את התוצאות לאזור מסוים, מעבירים פרמטר locationRestriction.

אפשר גם להגביל את התוצאות לאזור שהוגדר על ידי location והפרמטר radius, על ידי הוספת הפרמטר locationRestriction. ההוראה הזו גורמת להשלמה האוטומטית (חדשה) להחזיר רק תוצאות באזור הזה.