새 Place Autocomplete로 이전

Place Autocomplete는 Maps JavaScript API의 장소 라이브러리 기능입니다. 자동 완성을 사용하여 애플리케이션에 Google 지도 검색창의 검색 전 입력 기능을 제공할 수 있습니다.

이 페이지에서는 기존 Place Autocomplete 기능과 새 Place Autocomplete 기능의 차이점을 설명합니다. 두 버전 모두 자동 완성을 통합하는 일반적인 방법에는 두 가지가 있습니다.

자동 완성 프로그래매틱 인터페이스

다음 표에는 Places Autocomplete 서비스 (기존)Autocomplete Data API (신규) 간의 프로그래매틱 Place Autocomplete 사용의 주요 차이점이 나와 있습니다.

PlacesService (기존) Place (신규)
Place Autocomplete 서비스 참조 자동 완성 데이터 (신규) 참조
AutocompletionRequest AutocompleteRequest
AutocompleteService.getPlacePredictions AutocompleteSuggestion.fetchAutocompleteSuggestions
AutocompletePrediction PlacePrediction
메서드는 결과 객체와 PlacesServiceStatus 응답을 처리하기 위해 콜백을 사용해야 합니다. Promise를 사용하며 비동기식으로 작동합니다.
메서드에는 PlacesServiceStatus 검사가 필요합니다. 필수 상태 검사가 없으며 표준 오류 처리를 사용할 수 있습니다.
장소 데이터 필드는 Autocomplete 인스턴스가 생성될 때 옵션으로 설정됩니다. 장소 데이터 필드는 나중에 fetchFields()이 호출될 때 설정됩니다.
쿼리 예측이 지원됩니다 (SearchBox만 해당). Autocomplete 클래스에서는 쿼리 예측을 사용할 수 없습니다.
고정된 장소 유형장소 데이터 필드 집합으로 제한됩니다. 확장된 장소 유형장소 데이터 필드에 액세스할 수 있습니다.

다음은 기존 Autocomplete API와 새 Autocomplete API에서 모두 사용됩니다.

코드 비교 (프로그래매틱)

이 섹션에서는 자동 완성 코드를 비교하여 프로그래매틱 인터페이스의 경우 Places 서비스와 Place 클래스의 차이점을 보여줍니다.

자동 완성 예상 검색어 가져오기 (기존)

기존 Places 서비스를 사용하면 자동 완성 예측을 프로그래매틱 방식으로 검색하여 Autocomplete 클래스에서 제공하는 것보다 더 효과적으로 사용자 인터페이스를 제어할 수 있습니다. 다음 예에서는 입력 값과 예측 편향에 관한 경계 집합으로 구성된 AutocompletionRequest를 사용하여 'par'에 대한 단일 요청이 이루어집니다. 이 예에서는 AutocompletePrediction 인스턴스 목록을 반환하고 각 인스턴스의 설명을 표시합니다. 또한 이 예시 함수는 세션 토큰을 만들고 이를 요청에 적용합니다.

function init() {
  const placeInfo = document.getElementById("prediction");
  const service = new google.maps.places.AutocompleteService();
  const placesService = new google.maps.places.PlacesService(placeInfo);
  var sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    bounds: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  }

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const displaySuggestions = function (predictions, status) {
    // Check the status of the Places Service.
    if (status != google.maps.places.PlacesServiceStatus.OK || !predictions) {
      alert(status);
      return;
    }

    predictions.forEach((prediction) => {
      const li = document.createElement("li");
      li.appendChild(document.createTextNode(prediction.description));
      document.getElementById("results").appendChild(li);
    });

    const placeRequest = {
      placeId: predictions[0].place_id,
      fields: ["name", "formatted_address"],
    };

    placesService.getDetails(placeRequest, (place, status) => {
      if (status == google.maps.places.PlacesServiceStatus.OK && place) {
        placeInfo.textContent = `
          First predicted place: ${place.name} at ${place.formatted_address}`
      }
    });

  };

  // Show the results of the query.
  service.getPlacePredictions(request, displaySuggestions);
}

자동 완성 예상 검색어 가져오기 (신규)

또한 새 장소 클래스를 사용하면 자동 완성 예측을 프로그래매틱 방식으로 검색하여 PlaceAutocompleteElement 클래스에서 제공하는 것보다 사용자 인터페이스를 더 세부적으로 제어할 수 있습니다. 다음 예에서는 입력 값과 예측 편향을 위한 경계 집합으로 구성된 AutocompleteRequest를 사용하여 'par'에 대한 단일 요청이 이루어집니다. 이 예에서는 placePrediction 인스턴스 목록을 반환하고 각 인스턴스의 설명을 표시합니다. 또한 이 예시 함수는 세션 토큰을 만들고 이를 요청에 적용합니다.

async function init() {
  let sessionToken = new google.maps.places.AutocompleteSessionToken();

  // Define request options.
  let request = {
    input: "par",
    sessionToken: sessionToken,
    locationBias: {
      west: -122.44,
      north: 37.8,
      east: -122.39,
      south: 37.78,
    },
  };

  // Display the query string.
  const title = document.getElementById("title");
  title.appendChild(
    document.createTextNode('Place predictions for "' + request.input + '":'),
  );

  // Perform the query and display the results.
  const { suggestions } =
    await google.maps.places.AutocompleteSuggestion.fetchAutocompleteSuggestions(request);

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

  for (let suggestion of suggestions) {
    const placePrediction = suggestion.placePrediction;
    const listItem = document.createElement("li");

    listItem.appendChild(
      document.createTextNode(placePrediction.text.text),
    );

    resultsElement.appendChild(listItem);
  }

  // Show the first predicted place.
  let place = suggestions[0].placePrediction.toPlace();

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

  const placeInfo = document.getElementById("prediction");

  placeInfo.textContent = `
    First predicted place: ${place.displayName} at ${place.formattedAddress}`
}

장소 자동 완성 위젯

다음 표에는 장소 서비스 (기존)와 장소 클래스(신규) 간에 자동 완성 위젯을 사용하는 데 있어 몇 가지 주요 차이점이 나와 있습니다.

장소 서비스 (기존) 장소 (신규)
장소 예측을 위한 Autocomplete 클래스 장소 예측을 위한 PlaceAutocompleteElement 클래스
쿼리 예측을 위한 SearchBox 클래스
Autocomplete 클래스에서는 쿼리 예측을 사용할 수 없습니다.
기본 입력 자리표시자 텍스트만 현지화됩니다. 텍스트 입력 자리표시자, 예상 검색어 목록 로고, 장소 예상 검색어 모두 지역 현지화를 지원합니다.
위젯은 setBounds() 또는 autocomplete.bindTo()를 사용하여 검색을 지정된 경계로 제한 (편향)하고 strictBounds를 사용하여 결과를 지정된 경계로 제한합니다. 위젯은 locationBias 속성을 사용하여 결과를 지정된 경계로 편향시키고 locationRestriction 속성을 사용하여 검색을 지정된 경계로 제한합니다.
위젯은 표준 HTML 입력 요소를 사용하여야만 통합할 수 있습니다. 위젯은 표준 HTML 입력 요소 또는 gmp-place-autocomplete 요소를 사용하여 통합할 수 있습니다.
위젯을 사용할 때 사용자가 유효하지 않은 항목 (예: 'bisneyland')을 요청할 수 있습니다. 이 경우 명시적으로 처리해야 합니다. 위젯은 제공된 추천에 대한 결과만 반환하며 임의 값에 대한 요청을 실행할 수 없으므로 잘못된 요청을 처리할 필요가 없습니다.
기존 PlaceResult 인스턴스를 반환합니다. Place 인스턴스를 반환합니다.
장소 데이터 필드는 Autocomplete 객체의 옵션으로 설정됩니다. 장소 데이터 필드는 사용자가 선택하고 fetchFields()이 호출될 때 설정됩니다.
고정된 장소 유형장소 데이터 필드 집합으로 제한됩니다. 확장된 장소 유형장소 데이터 필드에 액세스할 수 있습니다.

코드 비교 (위젯)

이 섹션에서는 자동 완성 코드를 비교하여 기존 Place Autocomplete 위젯과 새 Place Autocomplete 요소의 차이를 보여줍니다.

장소 자동 완성 위젯 (기존)

장소 서비스는 AutocompleteSearchBox 클래스를 사용하여 추가할 수 있는 두 가지 유형의 자동 완성 위젯을 제공합니다. 각 종류의 위젯은 지도 컨트롤로 지도에 추가하거나 웹페이지에 직접 삽입할 수 있습니다. 다음 코드 예는 Autocomplete 위젯을 지도 컨트롤로 삽입하는 방법을 보여줍니다.

  • Autocomplete 위젯 생성자는 다음 두 인수를 사용합니다.
    • text 유형의 HTML input 요소. 자동 완성 서비스가 모니터링하고 결과를 첨부하는 입력란입니다.
    • 선택적 AutocompleteOptions 인수로, 여기서 추가 옵션을 지정하여 쿼리를 제한할 수 있습니다.
  • 경계를 설정하려면 autocomplete.bindTo()를 호출하여 Autocomplete 인스턴스를 지도에 명시적으로 바인딩할 수 있습니다.
  • 자동 완성 옵션에서 장소 데이터 필드를 지정합니다.
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapTypeControl: false,
  });
  const card = document.getElementById("pac-card");
  const input = document.getElementById("pac-input");
  const options = {
    fields: ["formatted_address", "geometry", "name"],
    strictBounds: false,
  };

  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  const autocomplete = new google.maps.places.Autocomplete(input, options);

  // Bind the map's bounds (viewport) property to the autocomplete object,
  // so that the autocomplete requests use the current map bounds for the
  // bounds option in the request.
  autocomplete.bindTo("bounds", map);

  const infowindow = new google.maps.InfoWindow();
  const infowindowContent = document.getElementById("infowindow-content");

  infowindow.setContent(infowindowContent);

  const marker = new google.maps.Marker({
    map,
    anchorPoint: new google.maps.Point(0, -29),
  });

  autocomplete.addListener("place_changed", () => {
    infowindow.close();
    marker.setVisible(false);

    const place = autocomplete.getPlace();

    if (!place.geometry || !place.geometry.location) {
      // User entered the name of a Place that was not suggested and
      // pressed the Enter key, or the Place Details request failed.
      window.alert("No details available for input: '" + place.name + "'");
      return;
    }

    // If the place has a geometry, then present it on a map.
    if (place.geometry.viewport) {
      map.fitBounds(place.geometry.viewport);
    } else {
      map.setCenter(place.geometry.location);
      map.setZoom(17);
    }

    marker.setPosition(place.geometry.location);
    marker.setVisible(true);
    infowindowContent.children["place-name"].textContent = place.name;
    infowindowContent.children["place-address"].textContent =
      place.formatted_address;
    infowindow.open(map, marker);
  });
}

장소 자동 완성 위젯 (신규)

장소 클래스는 지도에 지도 컨트롤로 추가하거나 웹페이지에 직접 삽입할 수 있는 UI 구성요소를 제공하는 HTMLElement 하위 클래스인 PlaceAutocompleteElement를 제공합니다. 다음 코드 예는 PlaceAutocompleteElement 위젯을 지도 컨트롤로 삽입하는 방법을 보여줍니다.

Place Autocomplete 위젯이 다음과 같이 개선되었습니다.

  • 자동 완성 위젯 UI는 텍스트 입력 자리표시자, 예상 검색어 목록 로고, 장소 예상 검색어의 지역 현지화 (RTL 언어 포함)를 지원합니다.
  • 스크린 리더 및 키보드 상호작용에 대한 지원을 포함하여 접근성이 개선되었습니다.
  • 자동 완성 위젯은 반환된 객체의 처리를 간소화하기 위해 새 Place 클래스를 반환합니다.
  • 휴대기기 및 소형 화면에 대한 지원이 개선되었습니다.
  • 성능이 향상되고 그래픽 모양이 개선되었습니다.

주요 구현 차이점은 다음과 같습니다.

  • Autocomplete 클래스에서는 쿼리 예측을 사용할 수 없습니다.
  • PlaceAutocompleteElementPlaceAutocompleteElementOptions를 사용하여 구성됩니다.
  • 장소 데이터 필드는 선택 시 (fetchFields()이 호출될 때) 지정됩니다.
  • locationBounds 또는 locationRestriction 옵션을 사용하여 경계를 설정합니다.
  • id 속성 (HTMLElement에서 상속됨)을 사용하여 PlaceAutocompleteElement를 HTML 텍스트 입력 요소와 연결합니다.
let map;
let marker;
let infoWindow;

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

  // Initialize the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.749933, lng: -73.98633 },
    zoom: 13,
    mapId: "4504f8b37365c3d0",
    mapTypeControl: false,
  });

  const placeAutocomplete =
    new google.maps.places.PlaceAutocompleteElement({
      locationRestriction: map.getBounds(),
    });

  placeAutocomplete.id = "place-autocomplete-input";
  const card = document.getElementById("place-autocomplete-card");

  card.appendChild(placeAutocomplete);
  map.controls[google.maps.ControlPosition.TOP_LEFT].push(card);

  // Create the marker and infowindow.
  marker = new google.maps.marker.AdvancedMarkerElement({
    map,
  });
  infoWindow = new google.maps.InfoWindow({});

  // Add the gmp-placeselect listener, and display the results on the map.
  placeAutocomplete.addEventListener("gmp-placeselect", async ({ place }) => {
    await place.fetchFields({
      fields: ["displayName", "formattedAddress", "location"],
    });
    // If the place has a geometry, then present it on a map.
    if (place.viewport) {
      map.fitBounds(place.viewport);
    } else {
      map.setCenter(place.location);
      map.setZoom(17);
    }

    let content =
      '<div id="infowindow-content">' +
      '<span id="place-displayname" class="title">' +
      place.displayName +
      '</span><br />' +
      '<span id="place-address">' +
      place.formattedAddress +
      '</span>' +
      '</div>';

    updateInfoWindow(content, place.location);
    marker.position = place.location;
  });
}

// Helper function to create an info window.
function updateInfoWindow(content, center) {
  infoWindow.setContent(content);
  infoWindow.setPosition(center);
  infoWindow.open({
    map,
    anchor: marker,
    shouldFocus: false,
  });
}