Bản tóm tắt dựa trên AI

Xem mã nguồn ví dụ hoàn chỉnh

Tìm kiếm địa điểm để xem thông tin tóm tắt dựa trên AI. Một số cụm từ tìm kiếm đề xuất:

  • "Khách sạn" cho thông tin tóm tắt về khu vực lân cận.
  • "Trạm sạc xe điện" cho thông tin tóm tắt về tiện nghi của trạm sạc xe điện.
  • Bất kỳ nhà hàng hoặc doanh nghiệp nào cho thông tin tóm tắt về địa điểm và bài đánh giá.

TypeScript

// Define DOM elements.
const mapElement = document.querySelector('gmp-map')!;
const placeAutocomplete = document.querySelector('gmp-place-autocomplete')!;
const summaryPanel = document.getElementById('summary-panel')!;
const placeName = document.getElementById('place-name')!;
const placeAddress = document.getElementById('place-address')!;
const tabContainer = document.getElementById('tab-container')!;
const summaryContent = document.getElementById('summary-content')!;
const aiDisclosure = document.getElementById('ai-disclosure')!;
const flagContentLink = document.getElementById(
    'flag-content-link'
) as HTMLAnchorElement;

let innerMap: google.maps.Map;
let marker: google.maps.marker.AdvancedMarkerElement;

async function init(): Promise<void> {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
        streetViewControl: false,
        fullscreenControl: false,
    });

    // Bind autocomplete bounds to map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds()!;
    });

    // Create the marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    // Handle selection of an autocomplete result.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();

            // Fetch all summary fields.
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'generativeSummary',
                    'neighborhoodSummary',
                    'reviewSummary',
                    'evChargeAmenitySummary',
                ],
            });

            // Update the map viewport and position the marker.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location!);
                innerMap.setZoom(17);
            }
            marker.position = place.location;

            // Update the panel UI.
            updateSummaryPanel(place);
        }
    );
}

function updateSummaryPanel(place: google.maps.places.Place) {
    // Reset UI
    summaryPanel.classList.remove('hidden');
    tabContainer.innerHTML = ''; // innerHTML is OK here since we're clearing known child elements.
    summaryContent.textContent = '';
    aiDisclosure.textContent = '';

    placeName.textContent = place.displayName || '';
    placeAddress.textContent = place.formattedAddress || '';

    let firstTabActivated = false;

    /**
     * Safe Helper: Accepts either a text string or a DOM Node (like a div or DocumentFragment).
     */
    const createTab = (
        label: string,
        content: string | Node,
        disclosure: string | null,
        flagUrl: string | null
    ) => {
        const btn = document.createElement('button');
        btn.className = 'tab-button';
        btn.textContent = label;

        btn.onclick = () => {
            // Do nothing if the tab is already active.
            if (btn.classList.contains('active')) {
                return;
            }

            // Manage the active class state.
            document.querySelectorAll('.tab-button').forEach((b) => {
                b.classList.remove('active');
            });
            btn.classList.add('active');

            if (typeof content === 'string') {
                summaryContent.textContent = content;
            } else {
                summaryContent.replaceChildren(content.cloneNode(true));
            }

            // Set the disclosure text.
            aiDisclosure.textContent = disclosure || 'AI-generated content.';

            // Add the content flag URI.
            if (flagUrl) {
                flagContentLink.href = flagUrl;
                flagContentLink.textContent = 'Report an issue';
            }
        };

        tabContainer.appendChild(btn);

        // Auto-select the first available summary.
        if (!firstTabActivated) {
            btn.click();
            firstTabActivated = true;
        }
    };

    // --- 1. Generative Summary (Place) ---
    if (place.generativeSummary?.overview) {
        createTab(
            'Overview',
            place.generativeSummary.overview,
            place.generativeSummary.disclosureText,
            place.generativeSummary.flagContentURI
        );
    }

    // --- 2. Review Summary ---
    if (place.reviewSummary?.text) {
        createTab(
            'Reviews',
            place.reviewSummary.text,
            place.reviewSummary.disclosureText,
            place.reviewSummary.flagContentURI
        );
    }

    // --- 3. Neighborhood Summary ---
    if (place.neighborhoodSummary?.overview?.content) {
        createTab(
            'Neighborhood',
            place.neighborhoodSummary.overview.content,
            place.neighborhoodSummary.disclosureText,
            place.neighborhoodSummary.flagContentURI
        );
    }

    // --- 4. EV Amenity Summary (uses content blocks)) ---
    if (place.evChargeAmenitySummary) {
        const evSummary = place.evChargeAmenitySummary;
        const evContainer = document.createDocumentFragment();

        // Helper to build a safe DOM section for EV categories.
        const createSection = (title: string, text: string) => {
            const wrapper = document.createElement('div');
            wrapper.style.marginBottom = '15px'; // Or use a CSS class

            const titleEl = document.createElement('strong');
            titleEl.textContent = title;

            const textEl = document.createElement('div');
            textEl.textContent = text;

            wrapper.appendChild(titleEl);
            wrapper.appendChild(textEl);
            return wrapper;
        };

        // Check and append each potential section
        if (evSummary.overview?.content) {
            evContainer.appendChild(
                createSection('Overview', evSummary.overview.content)
            );
        }
        if (evSummary.coffee?.content) {
            evContainer.appendChild(
                createSection('Coffee', evSummary.coffee.content)
            );
        }
        if (evSummary.restaurant?.content) {
            evContainer.appendChild(
                createSection('Food', evSummary.restaurant.content)
            );
        }
        if (evSummary.store?.content) {
            evContainer.appendChild(
                createSection('Shopping', evSummary.store.content)
            );
        }

        // Only add the tab if the container has children
        if (evContainer.hasChildNodes()) {
            createTab(
                'EV Amenities',
                evContainer, // Passing a Node instead of string
                evSummary.disclosureText,
                evSummary.flagContentURI
            );
        }
    }

    // Safely handle the empty state.
    if (!firstTabActivated) {
        const msg = document.createElement('em');
        msg.textContent =
            'No AI summaries are available for this specific location.';
        summaryContent.replaceChildren(msg);
        aiDisclosure.textContent = '';
    }
}

void init();

JavaScript

// Define DOM elements.
const mapElement = document.querySelector('gmp-map');
const placeAutocomplete = document.querySelector('gmp-place-autocomplete');
const summaryPanel = document.getElementById('summary-panel');
const placeName = document.getElementById('place-name');
const placeAddress = document.getElementById('place-address');
const tabContainer = document.getElementById('tab-container');
const summaryContent = document.getElementById('summary-content');
const aiDisclosure = document.getElementById('ai-disclosure');
const flagContentLink = document.getElementById('flag-content-link');

let innerMap;
let marker;

async function init() {
    // Request needed libraries.
    const [{ AdvancedMarkerElement }] = await Promise.all([
        google.maps.importLibrary('marker'),
        google.maps.importLibrary('places'),
    ]);

    innerMap = mapElement.innerMap;
    innerMap.setOptions({
        mapTypeControl: false,
        streetViewControl: false,
        fullscreenControl: false,
    });

    // Bind autocomplete bounds to map bounds.
    innerMap.addListener('bounds_changed', () => {
        placeAutocomplete.locationRestriction = innerMap.getBounds();
    });

    // Create the marker.
    marker = new AdvancedMarkerElement({
        map: innerMap,
    });

    // Handle selection of an autocomplete result.
    placeAutocomplete.addEventListener(
        'gmp-select',
        async ({ placePrediction }) => {
            const place = placePrediction.toPlace();

            // Fetch all summary fields.
            await place.fetchFields({
                fields: [
                    'displayName',
                    'formattedAddress',
                    'location',
                    'generativeSummary',
                    'neighborhoodSummary',
                    'reviewSummary',
                    'evChargeAmenitySummary',
                ],
            });

            // Update the map viewport and position the marker.
            if (place.viewport) {
                innerMap.fitBounds(place.viewport);
            } else {
                innerMap.setCenter(place.location);
                innerMap.setZoom(17);
            }
            marker.position = place.location;

            // Update the panel UI.
            updateSummaryPanel(place);
        }
    );
}

function updateSummaryPanel(place) {
    // Reset UI
    summaryPanel.classList.remove('hidden');
    tabContainer.innerHTML = ''; // innerHTML is OK here since we're clearing known child elements.
    summaryContent.textContent = '';
    aiDisclosure.textContent = '';

    placeName.textContent = place.displayName || '';
    placeAddress.textContent = place.formattedAddress || '';

    let firstTabActivated = false;

    /**
     * Safe Helper: Accepts either a text string or a DOM Node (like a div or DocumentFragment).
     */
    const createTab = (label, content, disclosure, flagUrl) => {
        const btn = document.createElement('button');
        btn.className = 'tab-button';
        btn.textContent = label;

        btn.onclick = () => {
            // Do nothing if the tab is already active.
            if (btn.classList.contains('active')) {
                return;
            }

            // Manage the active class state.
            document.querySelectorAll('.tab-button').forEach((b) => {
                b.classList.remove('active');
            });
            btn.classList.add('active');

            if (typeof content === 'string') {
                summaryContent.textContent = content;
            } else {
                summaryContent.replaceChildren(content.cloneNode(true));
            }

            // Set the disclosure text.
            aiDisclosure.textContent = disclosure || 'AI-generated content.';

            // Add the content flag URI.
            if (flagUrl) {
                flagContentLink.href = flagUrl;
                flagContentLink.textContent = 'Report an issue';
            }
        };

        tabContainer.appendChild(btn);

        // Auto-select the first available summary.
        if (!firstTabActivated) {
            btn.click();
            firstTabActivated = true;
        }
    };

    // --- 1. Generative Summary (Place) ---
    if (place.generativeSummary?.overview) {
        createTab(
            'Overview',
            place.generativeSummary.overview,
            place.generativeSummary.disclosureText,
            place.generativeSummary.flagContentURI
        );
    }

    // --- 2. Review Summary ---
    if (place.reviewSummary?.text) {
        createTab(
            'Reviews',
            place.reviewSummary.text,
            place.reviewSummary.disclosureText,
            place.reviewSummary.flagContentURI
        );
    }

    // --- 3. Neighborhood Summary ---
    if (place.neighborhoodSummary?.overview?.content) {
        createTab(
            'Neighborhood',
            place.neighborhoodSummary.overview.content,
            place.neighborhoodSummary.disclosureText,
            place.neighborhoodSummary.flagContentURI
        );
    }

    // --- 4. EV Amenity Summary (uses content blocks)) ---
    if (place.evChargeAmenitySummary) {
        const evSummary = place.evChargeAmenitySummary;
        const evContainer = document.createDocumentFragment();

        // Helper to build a safe DOM section for EV categories.
        const createSection = (title, text) => {
            const wrapper = document.createElement('div');
            wrapper.style.marginBottom = '15px'; // Or use a CSS class

            const titleEl = document.createElement('strong');
            titleEl.textContent = title;

            const textEl = document.createElement('div');
            textEl.textContent = text;

            wrapper.appendChild(titleEl);
            wrapper.appendChild(textEl);
            return wrapper;
        };

        // Check and append each potential section
        if (evSummary.overview?.content) {
            evContainer.appendChild(
                createSection('Overview', evSummary.overview.content)
            );
        }
        if (evSummary.coffee?.content) {
            evContainer.appendChild(
                createSection('Coffee', evSummary.coffee.content)
            );
        }
        if (evSummary.restaurant?.content) {
            evContainer.appendChild(
                createSection('Food', evSummary.restaurant.content)
            );
        }
        if (evSummary.store?.content) {
            evContainer.appendChild(
                createSection('Shopping', evSummary.store.content)
            );
        }

        // Only add the tab if the container has children
        if (evContainer.hasChildNodes()) {
            createTab(
                'EV Amenities',
                evContainer, // Passing a Node instead of string
                evSummary.disclosureText,
                evSummary.flagContentURI
            );
        }
    }

    // Safely handle the empty state.
    if (!firstTabActivated) {
        const msg = document.createElement('em');
        msg.textContent =
            'No AI summaries are available for this specific location.';
        summaryContent.replaceChildren(msg);
        aiDisclosure.textContent = '';
    }
}

void init();

CSS

/* Reuse existing map height */
gmp-map {
    height: 100%;
}

html,
body {
    height: 100%;
    margin: 0;
    padding: 0;
}

/* Existing Autocomplete Card Style */
.place-autocomplete-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 2px;
    font-family: Roboto, sans-serif;
    font-size: 1rem;
}

gmp-place-autocomplete {
    width: 330px;
}

/* New: Summary Panel Styles */
.summary-card {
    background-color: #fff;
    border-radius: 5px;
    box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
    margin: 10px;
    padding: 0; /* Padding handled by children */
    font-family: Roboto, sans-serif;
    width: 350px;
    max-height: 80vh; /* Prevent overflow on small screens */
    overflow-y: auto;
    display: flex;
    flex-direction: column;
}

.hidden {
    display: none;
}

#place-header {
    padding: 15px;
    background-color: #f8f9fa;
    border-bottom: 1px solid #ddd;
}

#place-header h2 {
    margin: 0 0 5px 0;
    font-size: 1.2rem;
}

#place-address {
    margin: 0;
    color: #555;
    font-size: 0.9rem;
}

/* Tab Navigation */
.tab-container {
    display: flex;
    border-bottom: 1px solid #ddd;
    background-color: #fff;
}

.tab-button {
    flex: 1;
    background: none;
    border: none;
    padding: 10px;
    cursor: pointer;
    font-weight: 500;
    color: #555;
    border-bottom: 3px solid transparent;
}

.tab-button:hover {
    background-color: #f1f1f1;
}

.tab-button.active {
    font-weight: bold;
    border-bottom: 3px solid #000000;
}

.tab-button.active:hover {
    background-color: #ffffff;
    cursor: default;
}

/* Content Area */
.content-area {
    padding: 15px;
    line-height: 1.5;
    font-size: 0.95rem;
    color: #333;
}

.disclosure-footer {
    font-size: 0.75rem;
    color: #666;
    padding: 10px 15px;
    border-top: 1px solid #eee;
    font-style: italic;
}

.flag-content-link {
    font-size: 0.75rem;
    color: #666;
    padding: 10px 15px;
    border-top: 1px solid #eee;
}

HTML

<html>
    <head>
        <title>AI Place Summaries</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.80, -122.425" zoom="14" map-id="DEMO_MAP_ID">
            <!-- Search Input Card -->
            <div
                class="place-autocomplete-card"
                slot="control-inline-start-block-start">
                <gmp-place-autocomplete
                    placeholder="Find places with AI summaries"></gmp-place-autocomplete>
            </div>

            <!-- Summary text panel (initially hidden) -->
            <div
                id="summary-panel"
                class="summary-card hidden"
                slot="control-inline-end-block-start">
                <div id="place-header">
                    <h2 id="place-name"></h2>
                    <p id="place-address"></p>
                </div>

                <!-- Tabs for toggling summary types -->
                <div class="tab-container" id="tab-container"></div>

                <!-- Content display area -->
                <div id="summary-content" class="content-area"></div>

                <!-- Legal/AI Disclosure -->
                <div id="ai-disclosure" class="disclosure-footer"></div>

                <!-- Flag content link -->
                <a id="flag-content-link" class="flag-content-link"></a>
            </div>
        </gmp-map>
    </body>
</html>

Bản tóm tắt do AI tạo là thông tin tổng quan về một địa điểm hoặc khu vực, cung cấp thông tin chi tiết hữu ích về các địa điểm cụ thể, khu vực xung quanh một địa điểm và các bài đánh giá liên quan đến một địa điểm. Có 3 loại bản tóm tắt khác nhau dựa trên AI:

  • Thông tin tóm tắt về địa điểm: Thông tin tổng quan ngắn gọn, dài 100 ký tự dành riêng cho một mã địa điểm nhất định, tổng hợp nhiều loại dữ liệu khác nhau thành thông tin tổng quan cấp cao về một địa điểm.

  • Tóm tắt bài đánh giá: Bản tóm tắt được tạo về một địa điểm, chỉ dựa trên bài đánh giá của người dùng.

  • Tóm tắt về khu vực: Bản tóm tắt được tạo về khu vực xung quanh một địa điểm, cung cấp thêm bối cảnh, bao gồm cả các địa điểm yêu thích lân cận. Thông tin tóm tắt về khu vực có thể là một trong hai loại:

    • Tóm tắt về khu vực lân cận: Thông tin tổng quan chung về các điểm yêu thích lân cận cho những địa điểm có loại premise, street_address và tất cả các loại trong danh mục Nhà ở và Chỗ lưu trú.

    • Thông tin tóm tắt về tiện nghi của trạm sạc xe điện: Thông tin tổng quan cấp cao về các địa điểm yêu thích lân cận cho những địa điểm có loại electric_vehicle_charging_station.

Truy xuất bản tóm tắt dựa trên AI

Để truy xuất và hiển thị bản tóm tắt do AI tạo, hãy làm theo các bước sau:

  1. Tải thư viện Places.

    const { Place } = await google.maps.importLibrary("places");
  2. Lấy một thực thể Place. Đoạn mã sau đây cho biết cách tạo một thực thể Place từ mã địa điểm:

    const place = new Place("ChIJaYaXFTqq3oARNy537Kb_W_c");
  3. Trong lệnh gọi đến place.fetchFields(), hãy chỉ định các trường cho loại tóm tắt mà bạn muốn sử dụng. Trong đoạn mã sau, tất cả các trường tóm tắt đều được yêu cầu:

    await place.fetchFields({
      fields: [
        'generativeSummary',
        'neighborhoodSummary',
        'reviewSummary',
        'evChargeAmenitySummary'
        // Include other fields as needed.
      ]
    });
              
  4. Truy xuất dữ liệu tóm tắt bằng cách truy cập vào các thuộc tính generativeSummary, neighborhoodSummary, reviewSummary và evChargeAmenitySummary tương ứng. Đoạn mã sau đây cho thấy cách truy xuất thông tin tổng quan từ generativeSummary.

    const summaryText = place.generativeSummary.overview;
            

Vì không phải địa điểm nào cũng có bản tóm tắt dựa trên AI, nên hãy nhớ kiểm tra xem có dữ liệu cần thiết hay không trước khi hiển thị cho người dùng. Đoạn mã sau đây sử dụng câu lệnh if để kiểm tra generativeSummary:

if (place.generativeSummary) {
  overviewText = place.generativeSummary.overview;
} else {
  overviewText = 'No summary is available.';
}
    

Ngoài ra, hãy sử dụng toán tử rỗng để kiểm tra nhanh xem có bản tóm tắt hay không:

const overviewText = place.generativeSummary.overview ?? 'No summary is available.';
    

Hiển thị thông tin ghi nhận tác giả bắt buộc

Tất cả bản tóm tắt dựa trên AI xuất hiện trong ứng dụng của bạn phải đi kèm thông tin ghi nhận tác giả phù hợp theo chính sách và tiêu chuẩn của Google. Để biết thêm thông tin, hãy xem Chính sách và thông tin ghi nhận tác giả cho API Maps JavaScript.

Bản tóm tắt về địa điểm

Bản tóm tắt địa điểm là thông tin tổng quan ngắn gọn, dài 100 ký tự, dành riêng cho một Mã địa điểm nhất định, để cung cấp thông tin tổng quan cấp cao về một địa điểm. Thông tin tóm tắt về địa điểm có thể làm nổi bật các món ăn, dịch vụ hoặc hàng hoá phổ biến mà khách hàng có thể mua tại một địa điểm:

  • "Nhà hàng trong trung tâm mua sắm Forum Shops, phục vụ các món ăn truyền thống của Ý với khẩu phần lớn trong không gian bình dân."

  • "Salon sành điệu cung cấp dịch vụ cắt tóc, nhuộm tóc và sấy tóc."

  • "Cửa hàng lớn có nhiều nhà cung cấp bán nhiều loại đồ trang trí, đồ nội thất và quần áo cổ điển."

Bản tóm tắt địa điểm được cung cấp cho các loại địa điểm xuất hiện trong phần Các loại địa điểm được hỗ trợ cho các danh mục Văn hoá, Giải trí và thư giãn, Đồ ăn và thức uống, Mua sắm, Dịch vụ và Thể thao.

Thông tin tóm tắt về địa điểm được hỗ trợ cho các địa điểm yêu thích bằng những ngôn ngữ và khu vực sau:

Ngôn ngữ Khu vực
Tiếng Anh

Ấn Độ

Hoa Kỳ

Yêu cầu bản tóm tắt về địa điểm

Để yêu cầu bản tóm tắt địa điểm bằng AI tạo sinh, hãy thêm trường generativeSummary khi gọi fetchFields():

await place.fetchFields({
    fields: [
        'generativeSummary',
        // Include other fields as needed.
    ],
});
    

Sử dụng thuộc tính generativeSummary để truy xuất thông tin tóm tắt về địa điểm. Đoạn mã sau đây truy xuất thông tin tổng quan và văn bản công bố từ generativeSummary:

if (place.generativeSummary) {
    console.log("Place Overview:", place.generativeSummary.overview);
    console.log("Disclosure:", place.generativeSummary.disclosureText);
}
    

Bản tóm tắt bài đánh giá

Bản tóm tắt bài đánh giá là bản tóm tắt được tạo hoàn toàn dựa trên bài đánh giá của người dùng. Bằng cách tổng hợp các yếu tố chính trong bài đánh giá của người dùng, chẳng hạn như thuộc tính địa điểm và cảm nhận của người đánh giá, bản tóm tắt bài đánh giá cung cấp thông tin chi tiết cấp cao và giúp người dùng đưa ra quyết định sáng suốt.

Ví dụ: một bản tóm tắt bài đánh giá về Toà nhà Ferry ở San Francisco bao gồm thông tin từ đồ ăn và mua sắm cho đến quang cảnh và bầu không khí:

"Du khách cho biết địa danh lịch sử này có nhiều cửa hàng, nhà hàng và chợ nông sản, đồng thời nhiều người cũng khen ngợi quang cảnh vịnh và thành phố. Họ cũng nhấn mạnh bầu không khí sôi động, dịch vụ phà thuận tiện đến các điểm đến khác và cơ hội tận hưởng các doanh nghiệp địa phương."

Bản tóm tắt bài đánh giá được hỗ trợ cho các địa điểm yêu thích bằng những ngôn ngữ và khu vực sau:

Ngôn ngữ Khu vực
Tiếng Anh Argentina, Bolivia, Brazil, Chile, Colombia, Costa Rica, Cộng hoà Dominica, Ecuador, Guatemala, Ấn Độ, Nhật Bản, Mexico, Paraguay, Peru, Vương quốc Anh, Hoa Kỳ, Uruguay, Venezuela
Tiếng Nhật Nhật Bản
Tiếng Bồ Đào Nha Brazil
Tiếng Tây Ban Nha Argentina, Bolivia, Chile, Colombia, Costa Rica, Cộng hoà Dominica, Ecuador, Guatemala, Mexico, Paraguay, Peru, Hoa Kỳ, Uruguay, Venezuela

Yêu cầu tóm tắt bài đánh giá

Để yêu cầu tóm tắt bài đánh giá, hãy thêm trường reviewSummary khi gọi fetchFields():

await place.fetchFields({
    fields: [
        'reviewSummary',
        // Include other fields as needed.
    ],
});
  

Sử dụng thuộc tính reviewSummary để truy xuất thông tin tóm tắt bài đánh giá. Để truy xuất thông tin tóm tắt bài đánh giá, hãy truy cập vào thuộc tính reviewSummary.text. Đoạn mã sau đây truy xuất văn bản từ reviewSummary.

if (place.reviewSummary) {
    console.log("Place Review Summary:", place.reviewSummary.text);
}
  

Tóm tắt về khu vực

Bản tóm tắt về khu vực được tạo cho khu vực xung quanh một địa điểm. Bản tóm tắt về khu vực cung cấp thêm thông tin về một địa điểm, bao gồm cả các địa điểm yêu thích lân cận, để người dùng có thể đưa ra quyết định sáng suốt hơn về nơi cần đến và việc cần làm khi đến đó. Ví dụ: khi đến một thành phố mới, bạn có thể xem thông tin tóm tắt về khu vực lân cận của một khách sạn để tìm hiểu thêm về khu vực xung quanh:

  • "Khu vực sôi động này ở San Francisco, kết hợp giữa North Beach và Chinatown, nằm ở phía tây bắc của Khu Tài chính và có các địa danh văn học, điểm tham quan văn hoá độc đáo và ẩm thực đa dạng. Các địa điểm nổi bật bao gồm Hiệu sách City Lights mang tính biểu tượng, Bảo tàng Cáp treo hấp dẫn và những con phố nhộn nhịp của Khu Phố Hoa."

Nếu đang cân nhắc sạc xe điện, bạn có thể xem thông tin tóm tắt được tạo cho một trạm sạc xe điện để tìm hiểu thêm về khu vực xung quanh:

  • "Khu vực này có nhiều lựa chọn ăn uống trong phạm vi 9 phút đi bộ, bao gồm Starbucks, Sushi Jin và Safeway."

Cùng với nội dung mô tả về khu vực, phản hồi cũng chứa danh sách các thực thể Place cho những địa điểm được tham chiếu trong nội dung mô tả; hãy gọi fetchFields() trên các thực thể Place này để yêu cầu thêm thông tin chi tiết cho từng địa điểm.

Có hai loại thông tin tóm tắt về khu vực do AI cung cấp:

  • Tóm tắt về khu vực lân cận: Thông tin tổng quan chung về các địa điểm yêu thích lân cận cho những địa điểm có loại premise, street_address và tất cả các loại trong danh mục Nhà ở và Nhà nghỉ.

  • Thông tin tóm tắt về tiện nghi của trạm sạc xe điện: Thông tin tổng quan cấp cao về các điểm yêu thích lân cận cho những địa điểm có loại electric_vehicle_charging_station.

Thông tin tóm tắt về khu vực được hỗ trợ cho các địa điểm yêu thích bằng những ngôn ngữ và ở những khu vực sau:

Ngôn ngữ Khu vực
Tiếng Anh Hoa Kỳ

Yêu cầu tóm tắt về khu vực lân cận

Bạn có thể yêu cầu thông tin tóm tắt về khu vực lân cận cho những địa điểm có loại premise, street_address và tất cả các loại trong danh mục Nhà ở và Chỗ ở. Để yêu cầu thông tin tóm tắt về khu vực lân cận, hãy thêm trường neighborhoodSummary khi gọi fetchFields():

await place.fetchFields({
    fields: [
        'neighborhoodSummary',
        // Include other fields as needed.
    ],
});
  

Sử dụng thuộc tính neighborhoodSummary để truy xuất thông tin tóm tắt về khu vực lân cận. Để truy xuất thông tin tóm tắt về khu vực lân cận, hãy truy cập vào thuộc tính neighborhoodSummary.content để lấy văn bản.

Đoạn mã sau đây truy xuất nội dung của neighborhoodSummary:

if (place.neighborhoodSummary) {
    console.log("Place Neighborhood Summary:", place.neighborhoodSummary.overview.content);
}
  

Yêu cầu tóm tắt về tiện nghi trạm sạc xe điện

Bạn có thể yêu cầu thông tin tóm tắt về tiện nghi của trạm sạc xe điện cho những địa điểm có loại electric_vehicle_charging_station. Thông tin tóm tắt về tiện ích EVCS cung cấp 4 loại thông tin tóm tắt: overview, coffee, restaurant và store; do đó, cấu trúc dữ liệu là một mảng đối tượng, mỗi đối tượng chứa một thông tin tóm tắt. Để yêu cầu thông tin tóm tắt về tiện ích trạm sạc xe điện, hãy thêm trường evChargeAmenitySummary khi gọi fetchFields():

await place.fetchFields({
    fields: [
        'evChargeAmenitySummary',
        // Include other fields as needed.
    ],
});
  

Sử dụng thuộc tính evChargeAmenitySummary để truy xuất thông tin tóm tắt về tiện nghi của trạm sạc xe điện. Để truy xuất văn bản từ bản tóm tắt, hãy truy cập vào thuộc tính content của các thuộc tính evChargeAmenitySummary.overview, evChargeAmenitySummary.coffee, evChargeAmenitySummary.restaurant và evChargeAmenitySummary.store.

Đoạn mã sau đây truy xuất nội dung của evChargeAmenitySummary:

// overview, coffee, restaurant, store.
if (place.evChargeAmenitySummary) {
    console.log("Place EVCS Amenity Summary:", place.evChargeAmenitySummary.overview.content);
    console.log("Coffee:", place.evChargeAmenitySummary.coffee.content);
    console.log("Restaurants:", place.evChargeAmenitySummary.restaurant.content);
    console.log("Stores:", place.evChargeAmenitySummary.store.content);
}