Khám phá địa điểm bằng Thành phần tìm kiếm địa điểm và API Maps JavaScript

Mục tiêu

Tìm hiểu cách tích hợp Phần tử tìm kiếm địa điểm với Google Maps để giúp người dùng tìm địa điểm bằng tính năng tìm kiếm lân cận hoặc tìm kiếm bằng văn bản, từ đó nâng cao khả năng khám phá các địa điểm yêu thích. Sử dụng Phần tử thu gọn thông tin chi tiết về địa điểm để cung cấp thêm thông tin chi tiết về những địa điểm xuất hiện trong ứng dụng của bạn.

Phần tử tìm kiếm địa điểm là gì?

Phần tử Tìm kiếm địa điểm là một phần của Places UI Kit trong Maps JavaScript API. Đây là một phần tử HTML hiển thị kết quả tìm kiếm địa điểm trực tiếp ở định dạng danh sách trong ứng dụng của bạn. Phần tử này đơn giản hoá quy trình hiển thị những địa điểm được tìm thấy bằng tính năng Tìm kiếm lân cận hoặc Tìm kiếm bằng văn bản, mang đến trải nghiệm liền mạch cho người dùng khi khám phá địa điểm. Khi người dùng chọn một địa điểm trong danh sách, bạn có thể hiển thị thông tin chi tiết của địa điểm đó trên bản đồ, thường là bằng cách sử dụng Cửa sổ thông tin và Phần tử thông tin chi tiết về địa điểm.

Trực quan hoá việc khám phá địa điểm

Hình ảnh sau đây minh hoạ ví dụ về cách hoạt động của Phần tử tìm kiếm địa điểm. Ở bên trái, một danh sách các nhà hàng sẽ xuất hiện (Phần tử tìm kiếm địa điểm). Khi bạn chọn một nhà hàng, thông tin chi tiết về nhà hàng đó sẽ xuất hiện trong một Cửa sổ thông tin trên bản đồ và bản đồ sẽ tập trung vào vị trí của nhà hàng đó.

hình ảnh

Các trường hợp sử dụng tính năng Khám phá địa điểm

Việc tích hợp Phần tử tìm kiếm địa điểm có thể nâng cao nhiều ứng dụng trong các ngành khác nhau:

  • Du lịch và tham quan: Cho phép khách du lịch tìm kiếm các điểm tham quan, khách sạn hoặc các loại ẩm thực cụ thể ở một khu vực.
  • Bất động sản: Giúp người mua hoặc người thuê tiềm năng tìm thấy các trường học, siêu thị hoặc phương tiện công cộng ở gần.
  • Hậu cần và dịch vụ: Hỗ trợ người lái xe tìm trạm sạc xe điện, trạm xăng hoặc trung tâm dịch vụ cụ thể.

Quy trình giải pháp: Triển khai tính năng Khám phá địa điểm

Phần này hướng dẫn bạn các bước tích hợp Place Search Element để khám phá các địa điểm trên bản đồ, bao gồm cả các đoạn mã để tương tác với Places UI Kit. Chúng ta sẽ đề cập đến việc khởi tạo bản đồ và triển khai cả chức năng Tìm kiếm lân cận và Tìm kiếm bằng văn bản. Cuối cùng, chúng ta sẽ sử dụng phần tử PlaceDetails để hiện thêm thông tin chi tiết về một địa điểm cụ thể khi người dùng nhấp vào ghim của địa điểm đó trên bản đồ.

Điều kiện tiên quyết

Bạn nên nắm rõ các tài liệu sau:

Bật Maps JavaScript APIPlaces UI Kit trong dự án của bạn.

Xác minh rằng bạn đã tải Maps JavaScript API và nhập các thư viện bắt buộc trước khi bắt đầu. Tài liệu này cũng giả định rằng bạn có kiến thức về phát triển web, bao gồm cả HTML, CSS và JavaScript.

Thêm bản đồ vào trang

Bước đầu tiên là thêm bản đồ vào trang của bạn. Bản đồ này sẽ được dùng để hiển thị kết quả của Place Search Element dưới dạng các ghim có thể chọn.

Có hai cách để thêm bản đồ vào trang:

  1. Sử dụng thành phần web HTML gmp-map.
  2. Sử dụng JavaScript.

Các đoạn mã trên trang này được tạo bằng bản đồ JavaScript.

Bản đồ có thể được đặt ở giữa một vị trí mà bạn muốn người dùng tìm kiếm xung quanh, chẳng hạn như một khách sạn, hoặc được khởi tạo để yêu cầu người dùng cung cấp vị trí hiện tại của họ để đặt bản đồ ở giữa. Để phục vụ mục đích của tài liệu này, chúng tôi sẽ sử dụng một vị trí cố định để cố định vị trí tìm kiếm.

Nếu bạn đang hình dung các địa điểm gần một vị trí cố định, chẳng hạn như một khách sạn, hãy đặt một điểm đánh dấu trên bản đồ để biểu thị địa điểm này. Ví dụ:

hình ảnh

Bản đồ được căn giữa ở San Francisco, với một ghim màu xanh dương biểu thị địa điểm mà chúng ta đang tìm kiếm ở gần đó. Bạn đã tuỳ chỉnh màu của ghim bằng biểu tượng PinElement. Chế độ điều khiển Loại bản đồ đã bị ẩn khỏi giao diện người dùng.

Thiết lập phần tử Tìm kiếm địa điểm

Bây giờ, chúng ta có thể thiết lập HTML và CSS để hiển thị Phần tử tìm kiếm địa điểm. Trong ví dụ này, chúng ta sẽ di chuyển phần tử lên phía bên trái của bản đồ, nhưng bạn nên thử các bố cục khác nhau cho phù hợp với ứng dụng của mình.

Phần tử Tìm kiếm địa điểm sử dụng phương pháp khai báo. Thay vì định cấu hình hoàn toàn trong JavaScript, bạn xác định loại tìm kiếm ngay trong HTML bằng cách lồng một phần tử yêu cầu (chẳng hạn như <gmp-place-nearby-search-request>) bên trong thành phần <gmp-place-search> chính.

Trong mã HTML, hãy khởi tạo một phần tử <gmp-place-search>. Sử dụng thuộc tính selectable để bật các sự kiện nhấp chuột trên kết quả. Trong đó, hãy thêm một <gmp-place-nearby-search-request> để chỉ định rằng phần tử này sẽ được dùng cho tính năng tìm kiếm lân cận.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Để thực hiện một lượt tìm kiếm ban đầu và hiển thị kết quả, chúng ta sẽ dùng JavaScript để lấy thông tin tham chiếu đến phần tử yêu cầu lồng nhau và đặt các thuộc tính của phần tử đó. Khởi động một Circle để dùng làm locationRestriction, sử dụng vị trí của điểm đánh dấu ở bước trước làm tâm. Sau đó, hãy đặt các thuộc tính locationRestrictionincludedPrimaryTypes trên phần tử yêu cầu để kích hoạt thao tác tìm kiếm.

Đoạn mã cho việc này như sau:

// Get references to the Place Search and its nested request element
const placeSearchElement = document.querySelector("gmp-place-search");
const placeSearchRequestElement = document.querySelector("gmp-place-nearby-search-request");

// Define the location restriction for the search
const circleRestriction = new Circle({
    center: marker.position,
    radius: 500
});

// Set the properties on the request element to perform an initial search for restaurants.
placeSearchRequestElement.locationRestriction = circleRestriction;
placeSearchRequestElement.includedPrimaryTypes = ['restaurant'];

Sau đây là ví dụ về giao diện của ứng dụng ở giai đoạn này:

hình ảnh

Phần tử Tìm kiếm địa điểm cho phép 2 lựa chọn tìm kiếm:

Đây là các phần tử lồng nhau bên trong <gmp-place-search>. Sau đó, bạn kích hoạt các lượt tìm kiếm bằng cách đặt các thuộc tính trên phần tử yêu cầu lồng ghép đó bằng JavaScript.

Phần này mô tả cách triển khai cả hai phương thức.

hình ảnh

Để cho phép người dùng thực hiện tìm kiếm lân cận, trước tiên, bạn cần có một phần tử giao diện người dùng để họ chọn một Loại địa điểm. Chọn phương thức lựa chọn phù hợp nhất với ứng dụng của bạn, ví dụ: danh sách thả xuống chứa một số loại địa điểm.

Bạn nên chọn một tập hợp con các loại phù hợp với trường hợp sử dụng của mình. Ví dụ: nếu đang phát triển một ứng dụng để cho khách du lịch biết những địa điểm gần một khách sạn, bạn có thể chọn: bakery, coffee_shop, museum, restauranttourist_attraction.

HTML của bạn phải chứa phần tử <gmp-place-search><gmp-place-nearby-search-request> được lồng bên trong.

<gmp-place-search selectable>
  <gmp-place-nearby-search-request>
  </gmp-place-nearby-search-request>
</gmp-place-search>

Tiếp theo, hãy tạo một trình nghe JavaScript cho sự kiện change trên bộ chọn loại địa điểm. Trình nghe này sẽ gọi một hàm cập nhật các thuộc tính của phần tử <gmp-place-nearby-search-request>, thao tác này sẽ tự động kích hoạt một lượt tìm kiếm mới và cập nhật danh sách.

// Get a reference to the nested request element
const placeSearchRequestElement = document.querySelector('gmp-place-nearby-search-request');

// Function to update the place search based on the selected type
function updatePlaceList() {
    const selectedType = placeTypeSelect.value;
    if (!selectedType) {
        // If no type is selected, don't perform a search.
        // You could optionally hide the list or clear previous results here.
        placeSearchElement.style.display = 'none';
        return;
    }
    placeSearchElement.style.display = 'block';

    // Set properties on the request element to trigger a new search
    placeSearchRequestElement.locationRestriction = searchCircle;
    placeSearchRequestElement.maxResultCount = 8;
    placeSearchRequestElement.includedPrimaryTypes = [selectedType];
}

searchCircle giống nhau từ bước thiết lập được dùng cho locationRestriction. Thuộc tính includedPrimaryTypes được đặt thành giá trị từ lựa chọn của người dùng. Bạn cũng có thể đặt maxResultCount (không bắt buộc) để giới hạn số lượng kết quả.

hình ảnh

Để bật tính năng tìm kiếm bằng văn bản, bạn phải thay đổi cấu hình HTML. Thay vì yêu cầu tìm kiếm lân cận, bạn lồng một phần tử <gmp-place-text-search-request>.

<gmp-place-search selectable>
  <gmp-place-text-search-request>
  </gmp-place-text-search-request>
</gmp-place-search>

Thêm một ô nhập văn bản và một nút tìm kiếm vào giao diện người dùng. Tạo một trình nghe JavaScript cho sự kiện click của nút. Trình xử lý sự kiện sẽ lấy thông tin đầu vào của người dùng và cập nhật các thuộc tính của phần tử <gmp-place-text-search-request> để thực hiện tìm kiếm.

// Get a reference to the text search request element
const placeTextSearchRequestElement = document.querySelector('gmp-place-text-search-request');
const textSearchInput = document.getElementById('textSearchInput');
const textSearchButton = document.getElementById('textSearchButton');

textSearchButton.addEventListener('click', performTextSearch);

function performTextSearch() {
    const query = textSearchInput.value.trim();
    if (!query) {
        console.log("Search query is empty.");
        return;
    }
    // Set properties on the request element to trigger a new search
    placeTextSearchRequestElement.textQuery = query;
    placeTextSearchRequestElement.locationBias = map.getBounds();
    placeTextSearchRequestElement.maxResultCount = 8;
}

Ở đây, chúng ta đặt thuộc tính textQuery bằng thông tin đầu vào của người dùng. Chúng tôi cũng cung cấp một locationBias bằng cách sử dụng ranh giới hiện tại của bản đồ, cho biết API nên ưu tiên kết quả trong khu vực đó mà không giới hạn nghiêm ngặt. maxResultCount (không bắt buộc) giới hạn số lượng kết quả được trả về.

Hiển thị ghim và thông tin chi tiết về địa điểm

Giờ đây, ứng dụng có thể thực hiện tìm kiếm địa điểm và điền sẵn thông tin vào phần tử. Trong bước tiếp theo, chúng ta sẽ cải thiện chức năng của nó bằng cách:

  • Hiển thị ghim trên bản đồ cho từng địa điểm được điền sẵn trong Place Search Element.
  • Cho phép người dùng nhấp vào một ghim hoặc địa điểm trong Place Search Element (Phần tử Tìm kiếm địa điểm) để xem thêm thông tin chi tiết về địa điểm cụ thể đó.

Nguyên tắc của bước này là như nhau cho dù ứng dụng đang sử dụng tính năng tìm kiếm lân cận hay tìm kiếm bằng văn bản.

Trước tiên, hãy thêm một biến chung vào mã JavaScript để lưu trữ các điểm đánh dấu. Điều này sẽ cho phép bạn xoá các mục đó khi nội dung tìm kiếm thay đổi và xử lý các sự kiện nhấp.

let markers = {};

Tạo một hàm để thêm điểm đánh dấu vào bản đồ. Hàm này sẽ được gọi bất cứ khi nào kết quả tìm kiếm mới được tải. Thao tác này sẽ:

  • Xoá mọi điểm đánh dấu địa điểm hiện có trên bản đồ.
  • Lặp lại các kết quả từ Phần tử tìm kiếm địa điểm và thêm một điểm đánh dấu cho từng kết quả.
  • Điều chỉnh ranh giới của bản đồ để tất cả điểm đánh dấu mới đều xuất hiện.

Để theo dõi thời điểm có kết quả tìm kiếm, hãy thêm trình nghe sự kiện gmp-load vào phần tử <gmp-place-search>. Sự kiện này kích hoạt sau khi quá trình tìm kiếm hoàn tất và kết quả được hiển thị.

Chúng ta sẽ thêm trình nghe vào bên trong hàm tìm kiếm (ví dụ: updatePlaceList) và sử dụng lựa chọn { once: true } để đảm bảo rằng sự kiện chỉ kích hoạt cho kết quả của lượt tìm kiếm hiện tại.

// In your search function, after setting the request properties:
placeSearchElement.addEventListener('gmp-load', addMarkers, { once: true });

Hàm addMarkers có dạng như sau:

async function addMarkers() {
    const { LatLngBounds } = await google.maps.importLibrary("core");
    const bounds = new LatLngBounds();

    if (placeSearchElement.places.length > 0) {
        // Remove existing markers
        for (const m in markers) {
            markers[m].map = null;
        }
        markers = {};

        // Loop through each place from the search results
        // and add a marker for each one.
        for (const place of placeSearchElement.places) {
            const marker = new google.maps.marker.AdvancedMarkerElement({
                map: map,
                position: place.location,
            });

            markers[place.id] = marker;
            bounds.extend(place.location);
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;

            // Add a click listener for each marker.
            marker.addListener('gmp-click', (event) => {
                // The main logic for showing details will go here.
            });
        }
        // Position the map to display all markers.
        map.setCenter(bounds.getCenter());
        map.fitBounds(bounds);
    }
}

Sau khi hoàn tất bước này, ứng dụng sẽ có dạng như sau, có khả năng hiện các điểm đánh dấu cho từng địa điểm do Phần tử tìm kiếm địa điểm trả về:

hình ảnh

Giờ đây, khi đã có các điểm đánh dấu trên bản đồ, bước cuối cùng là xử lý các sự kiện nhấp vào điểm đánh dấu và phần tử để hiện một cửa sổ thông tin có thông tin chi tiết về địa điểm, do Phần tử thông tin chi tiết về địa điểm cung cấp. Trong ví dụ này, chúng ta sẽ sử dụng Phần tử thu gọn Chi tiết về địa điểm.

Thêm HTML của Phần tử thu gọn thông tin chi tiết về địa điểm vào mã của bạn, ví dụ:

<gmp-place-details-compact orientation="vertical" style="display: none;">
    <gmp-place-all-content></gmp-place-all-content>
    <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
</gmp-place-details-compact>

style được đặt thành display: none; bạn sẽ không thấy style cho đến khi cần. gmp-place-all-content được truyền để hiển thị tất cả nội dung phần tử. Để chọn nội dung cần hiển thị, hãy xem tài liệu Phần tử nhỏ gọn Chi tiết về địa điểm.

Tạo một biến chung trong JavaScript để lưu giữ thông tin tham chiếu đến Phần tử thu gọn Chi tiết về địa điểm và điền thông tin này vào mã khởi tạo của bạn, ví dụ:

let placeDetailsElement;
...
placeDetailsElement = document.querySelector('gmp-place-details-compact');

Trong hàm addMarkers, hãy thêm một trình nghe sự kiện gmp-click vào từng điểm đánh dấu và định cấu hình Phần tử nhỏ gọn về thông tin chi tiết về địa điểm để hiện thông tin chi tiết về địa điểm bằng cách truyền mã địa điểm của điểm đánh dấu hiện tại.

Sau khi hoàn tất, một Cửa sổ thông tin sẽ mở ra để hiển thị Phần tử nhỏ gọn về thông tin chi tiết về địa điểm, được cố định trên điểm đánh dấu.

Cuối cùng, bản đồ sẽ được đặt vào khung hiển thị của địa điểm đã chọn, giúp địa điểm đó xuất hiện.

async function addMarkers() {
          ...
            marker.addListener('gmp-click', (event) => {
                //Set up Place Details Compact Widget
                placeDetailsElement.style.display = "block";
                // Remove any existing place request element
                const existingPlaceRequest = placeDetailsElement.querySelector('gmp-place-details-place-request');
                if (existingPlaceRequest) {
                    existingPlaceRequest.remove();
                }
                // Create and configure the new place request element
                const placeRequestElement = new google.maps.places.PlaceDetailsPlaceRequestElement({ place: place.id });
                // Prepend the new place request element to the main widget
                placeDetailsElement.prepend(placeRequestElement);
                if (infoWindow.isOpen) {
                    infoWindow.close();
                }
                infoWindow.setOptions({
                    content: placeDetailsElement
                });
                infoWindow.open({
                    anchor: marker,
                    map: map
                });
                // Position the map to show the selected place
                placeDetailsElement.addEventListener('gmp-load', () => {
                    map.fitBounds(place.viewport, { top: 500, left: 400 });
                });
            });
          ...
        });
    }
}

Để cho phép người dùng nhấp vào một địa điểm trong Phần tử danh sách địa điểm để hiện Phần tử chi tiết địa điểm thu gọn, hãy thêm nội dung sau vào mã JavaScript sau khi gọi configureFromSearchNearbyRequest.

placeSearchElement.addEventListener("gmp-select", ({ place }) => {
    if (markers[place.id]) {
        markers[place.id].click();
    }
});

Sau khi hoàn tất bước này, ứng dụng sẽ có thể sử dụng tính năng Tìm kiếm lân cận hoặc Tìm kiếm bằng văn bản để điền sẵn Place List Element. Kết quả của thao tác này sẽ hiển thị các ghim trên bản đồ và khi bạn nhấp vào một ghim hoặc một địa điểm trong Phần tử Danh sách địa điểm, một Cửa sổ thông tin sẽ xuất hiện kèm theo thông tin chi tiết về địa điểm do Phần tử Thông tin chi tiết về địa điểm thu gọn cung cấp.

Ứng dụng sẽ có giao diện như sau:

hình ảnh

Kết luận

Place Search Element (Phần tử tìm kiếm địa điểm) kết hợp với Place Details Compact Element (Phần tử thông tin chi tiết về địa điểm dạng thu gọn) mang đến một cách thức tinh giản để thêm các tính năng khám phá địa điểm phong phú vào các ứng dụng Google Maps Platform của bạn.

Hãy dùng thử Places UI Kit ngay hôm nay để giúp người dùng tìm và khám phá các địa điểm bằng cả tìm kiếm lân cận và tìm kiếm bằng văn bản, đồng thời hiển thị thông tin chi tiết phong phú về địa điểm, nâng cao mức độ tương tác của họ với các trường hợp sử dụng khám phá địa điểm của bạn.

Người đóng góp

Henrik Valve | Kỹ sư DevX