AI 生成摘要

查看完整範例原始碼

搜尋地點,即可查看 AI 輔助的摘要。建議搜尋:

  • 「飯店」:用於社區摘要。
  • 「電動車充電站」:電動車充電站設施摘要。
  • 任何餐廳或商家,用於地點和評論摘要。

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>

AI 輔助摘要是地點或區域的總覽,提供特定地點、地點周邊區域和地點相關評論的實用深入分析。AI 生成摘要分為三種:

  • 地點摘要:特定地點 ID 的簡短 100 字元總覽,將多種不同類型的資料彙整成地點的概略摘要。

  • 評論摘要:根據使用者評論生成的地點摘要。

  • 區域摘要:系統生成的摘要,說明地點周邊區域,並提供附近搜尋點等額外背景資訊。區域摘要可分為兩種類型:

    • 鄰近地區摘要:premise、street_address 類型地點,以及「住宅」和「住宿」類別中所有類型地點的附近搜尋點概略總覽。

    • 電動車充電站設施摘要:electric_vehicle_charging_station 類型地點附近搜尋點的概略總覽。

擷取 AI 生成的摘要

如要擷取並顯示 AI 生成的摘要,請按照下列步驟操作:

  1. 載入 Places 程式庫。

    const { Place } = await google.maps.importLibrary("places");
  2. 取得 Place 例項。下列程式碼片段說明如何從地點 ID 建立 Place 執行個體:

    const place = new Place("ChIJaYaXFTqq3oARNy537Kb_W_c");
  3. 呼叫 place.fetchFields() 時,請指定要使用的摘要類型欄位。在下列程式碼片段中,系統會要求所有摘要欄位:

    await place.fetchFields({
      fields: [
        'generativeSummary',
        'neighborhoodSummary',
        'reviewSummary',
        'evChargeAmenitySummary'
        // Include other fields as needed.
      ]
    });
              
  4. 分別存取 generativeSummary、neighborhoodSummary、reviewSummary 和 evChargeAmenitySummary 屬性,擷取摘要資料。下列程式碼片段顯示如何從 generativeSummary 擷取總覽。

    const summaryText = place.generativeSummary.overview;
            

並非所有地點都有 AI 輔助摘要,因此請務必先確認是否有必要資料,再向使用者顯示。下列程式碼片段使用 if 陳述式檢查 generativeSummary:

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

或者,您也可以使用 nullish 運算子,簡潔地檢查摘要是否存在:

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

顯示必要的作者資訊

應用程式中顯示的所有 AI 輔助摘要,都必須依據 Google 的政策和標準,附上適當的出處。詳情請參閱「Maps JavaScript API 政策和出處」。

地點摘要

地點摘要是特定地點 ID 的簡短總覽,長度為 100 個字元,可提供地點的概略資訊。地點摘要可能會醒目顯示某個地點提供的熱門餐點、服務或商品:

  • 「Forum Shops 餐廳,在輕鬆的空間中供應大份量的傳統義式料理。」

  • 「時尚沙龍,提供剪髮、染髮和吹整服務。」

  • 「大型商店,有許多供應商提供各種復古裝飾、家具和服飾。」

地點摘要適用於「支援類型」中顯示的地點類型,涵蓋文化、娛樂和休閒、餐飲、購物、服務和運動等類別。

地點摘要支援下列語言和地區的搜尋點:

語言 區域
英文

印度

美國

要求生成地點摘要

如要要求生成式地點摘要,請在呼叫 fetchFields() 時加入 generativeSummary 欄位:

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

使用 generativeSummary 屬性擷取地點摘要。下列程式碼片段會從 generativeSummary 擷取總覽和揭露事項文字:

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

評論摘要

評論摘要是根據使用者評論生成的摘要。評論摘要會整合使用者評論的重要元素 (例如地點屬性和評論者情緒),提供高層次的深入分析,協助使用者做出明智決定。

舉例來說,舊金山渡輪大廈的評論摘要包含美食、購物、景觀和氣氛等資訊:

「遊客表示,這個歷史地標提供多樣化的商店、餐廳和農夫市集,許多人對海灣和城市景觀讚譽有加。此外,他們也強調這裡充滿活力的氛圍、方便搭乘渡輪前往其他目的地,以及享受當地商家的機會。

評論摘要功能支援下列語言和地區的搜尋點:

語言 區域
英文 阿根廷、玻利維亞、巴西、智利、哥倫比亞、哥斯大黎加、多明尼加共和國、厄瓜多、瓜地馬拉、印度、日本、墨西哥、巴拉圭、秘魯、英國、美國、烏拉圭、委內瑞拉
日文 日本
葡萄牙文 巴西
西班牙文 阿根廷、玻利維亞、智利、哥倫比亞、哥斯大黎加、多明尼加共和國、厄瓜多、瓜地馬拉、墨西哥、巴拉圭、秘魯、美國、烏拉圭、委內瑞拉

要求生成評論摘要

如要要求評論摘要,請在呼叫 fetchFields() 時加入 reviewSummary 欄位:

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

使用 reviewSummary 屬性擷取評論摘要。如要擷取評論摘要,請存取 reviewSummary.text 屬性。下列程式碼片段會從 reviewSummary 擷取文字。

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

區域摘要

系統會生成地點周邊區域的摘要。區域摘要會提供地點的額外背景資訊,包括附近景點,方便使用者更明智地決定目的地和行程。舉例來說,造訪新城市時,您可以查看飯店的鄰近地區摘要,進一步瞭解周遭環境:

  • 「這個充滿活力的舊金山地區融合了北灘和中國城,位於金融區西北方,擁有文學地標、獨特的文化景點和多元化的餐飲。知名景點包括著名的城市之光書店、迷人的纜車博物館,以及熱鬧的中國城街道。

如果您考慮為電動車充電,可以查看電動車充電站的生成摘要,進一步瞭解周遭區域:

  • 「這個區域提供多種餐飲選擇,步行 9 分鐘內即可抵達,包括星巴克、Sushi Jin 和 Safeway。」

除了區域說明外,回覆也包含說明中提及地點的 Place 執行個體清單;請對這些 Place 執行個體呼叫 fetchFields(),要求各個地點的詳細資料。

AI 輔助的區域摘要分為兩種類型:

  • 周邊摘要:premise、street_address 類型地點,以及「住宅」和「住宿」類別中所有類型地點的周邊搜尋點概略總覽。

  • 電動車充電站設施摘要:概略總覽 electric_vehicle_charging_station 類型地點附近的搜尋點。

區域摘要功能支援下列語言和地區的搜尋點:

語言 區域
英文 美國

要求生成鄰近地區摘要

您可以要求提供 premise、street_address 類型地點的周邊摘要,以及「住宅」和「住宿」類別中所有類型的地點。如要要求鄰近地區摘要,請在呼叫 fetchFields() 時加入 neighborhoodSummary 欄位:

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

使用 neighborhoodSummary 屬性擷取鄰近區域摘要。如要擷取鄰近區域摘要,請存取 neighborhoodSummary.content 屬性來取得文字。

下列程式碼片段會擷取 neighborhoodSummary 的內容:

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

要求提供電動車充電站設施摘要

您可以要求類型為 electric_vehicle_charging_station 的地點,提供電動車充電站設施摘要。EVCS 設施摘要提供四種摘要類型:overview、coffee、restaurant 和 store。因此,資料結構是物件陣列,每個物件都包含摘要。如要要求電動車充電站設施摘要,請在呼叫 fetchFields() 時加入 evChargeAmenitySummary 欄位:

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

使用 evChargeAmenitySummary 屬性,擷取電動車充電站設施摘要。如要從摘要中擷取文字,請存取 evChargeAmenitySummary.overview、evChargeAmenitySummary.coffee、evChargeAmenitySummary.restaurant 和 evChargeAmenitySummary.store 屬性的 content 屬性。

下列程式碼片段會擷取 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);
}