장소 세부정보 요소

장소 세부정보 요소와 장소 세부정보 좁게 요소는 장소의 세부정보를 렌더링하는 HTML 요소입니다.

장소 세부정보 요소

PlaceDetailsElement는 전체 영업시간, 웹사이트, 전화번호, 편집 요약, 유형별 하이라이트, 리뷰, 플러스 코드, 기능 목록을 비롯한 다양한 콘텐츠 요소를 지원합니다.

지도에 장소 세부정보를 표시하려면 HTML 페이지의 gmp-map 요소에 gmp-place-details 요소를 추가합니다. 하위 요소 gmp-place-details-place-request를 포함하여 장소를 선택합니다. 장소 객체, 장소 ID 또는 'places/{place_id}' 형식의 장소 리소스 이름일 수 있습니다.

<gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
  <div class="widget-container" slot="control-inline-start-block-start">
    <gmp-place-details>
      <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
      <gmp-place-all-content></gmp-place-all-content>
    </gmp-place-details>
  </div>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

콘텐츠 구성

다음 예와 같이 중첩된 gmp-place-content-config 요소를 사용하여 gmp-place-details 요소에 표시되는 특정 장소 콘텐츠를 제어하고 장소 세부정보를 선택하고 구성할 수 있습니다.

<gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
  <div class="widget-container" slot="control-inline-start-block-start">
    <gmp-place-details>
      <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
      <gmp-place-content-config>
        <gmp-place-address></gmp-place-address>
        <gmp-place-rating></gmp-place-rating>
        <gmp-place-type></gmp-place-type>
        <gmp-place-price></gmp-place-price>
        <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
        <gmp-place-opening-hours></gmp-place-opening-hours>
        <gmp-place-website></gmp-place-website>
        <gmp-place-phone-number></gmp-place-phone-number>
        <gmp-place-summary></gmp-place-summary>
        <gmp-place-type-specific-highlights></gmp-place-type-specific-highlights>
        <gmp-place-reviews></gmp-place-reviews>
        <gmp-place-feature-list></gmp-place-feature-list>
        <gmp-place-media
          lightbox-preferred
          ></gmp-place-media>
          <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
      </gmp-place-content-config>
    </gmp-place-details>
  </div>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

gmp-place-content-config 요소 자체에는 여러 하위 콘텐츠 요소가 포함되어 있으며, 각 요소는 표시할 해당 장소 세부정보를 선택합니다. PlaceAddressElement는 장소 주소를 선택하고, PlacePriceElement는 장소의 가격대를 선택합니다. 선택된 세부정보는 항상 사전 정의된 고정된 순서로 렌더링되므로 하위 요소의 순서는 중요하지 않습니다.

이러한 요소 중 일부는 콘텐츠별 속성을 사용하여 추가로 구성할 수 있습니다.

  • gmp-place-media 요소는 단일 사진을 표시하는 데 사용되며 클릭 시 라이트박스에서 사진을 여는 lightbox-preferred 속성을 포함합니다. 라이트박스는 기본적으로 사용 중지되어 있습니다.
  • gmp-place-attribution 요소는 사진의 소스를 표시하는 데 사용됩니다. light-scheme-colordark-scheme-color 속성은 밝은 모드와 어두운 모드에서 저작자 표시 텍스트의 색상을 설정하는 데 사용됩니다.
지원되는 모든 콘텐츠 요소에 관한 자세한 내용은 PlaceContentConfigElement 참조 문서를 참고하세요.

간편하게 gmp-place-content-config 요소를 gmp-place-all-content로 대체하여 장소 세부정보 요소에 사용 가능한 모든 세부정보를 표시하거나 gmp-place-standard-content로 대체하여 표준 구성을 표시할 수 있습니다.

디자인 구성

gmp-place-details 요소의 권장 너비 범위는 250~400픽셀입니다. 너비가 250px 미만이면 제대로 표시되지 않을 수 있습니다. 애플리케이션에 맞게 높이를 설정합니다. 장소 세부정보 요소는 필요에 따라 할당된 공간 내에서 스크롤되도록 설계되었습니다.

gmp-place-details 요소는 요소의 색상과 글꼴을 구성하는 다양한 맞춤 CSS 속성도 지원합니다. 자세한 내용은 장소 UI 키트 맞춤 스타일 지정을 참고하세요.

전체 코드 예 보기

자바스크립트

// Use querySelector to select elements for interaction.
const map = document.querySelector('gmp-map');
const placeDetails = document.querySelector('gmp-place-details');
const placeDetailsRequest = document.querySelector('gmp-place-details-place-request');
const marker = document.querySelector('gmp-advanced-marker');
let center = { lat: 47.759737, lng: -122.250632 };
async function initMap() {
    // Request needed libraries.
    await google.maps.importLibrary("maps");
    await google.maps.importLibrary("marker");
    await google.maps.importLibrary("places");
    // Hide the map type control.
    map.innerMap.setOptions({ mapTypeControl: false });
    // Function to update map and marker based on place details
    const updateMapAndMarker = () => {
        if (placeDetails.place && placeDetails.place.location) {
            let adjustedCenter = offsetLatLngRight(placeDetails.place.location, -0.005);
            map.innerMap.panTo(adjustedCenter);
            map.innerMap.setZoom(16); // Set zoom after panning if needed
            marker.position = placeDetails.place.location;
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;
            marker.style.display = 'block';
        }
    };
    // Set up map once widget is loaded.
    placeDetails.addEventListener('gmp-load', (event) => {
        updateMapAndMarker();
    });
    // Add an event listener to handle clicks.
    map.innerMap.addListener('click', async (event) => {
        marker.position = null;
        event.stop();
        if (event.placeId) {
            // Fire when the user clicks a POI.
            placeDetailsRequest.place = event.placeId;
            updateMapAndMarker();
        }
        else {
            // Fire when the user clicks the map (not on a POI).
            console.log('No place was selected.');
            marker.style.display = 'none';
        }
    });
}
// Helper function to offset marker placement for better visual appearance.
function offsetLatLngRight(latLng, longitudeOffset) {
    const newLng = latLng.lng() + longitudeOffset;
    return new google.maps.LatLng(latLng.lat(), newLng);
}
initMap();

CSS

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
    display: flex; /* Use flexbox for layout */
    justify-content: center; /* Center the content horizontally */
    align-items: flex-start; /* Align items to the top */
    width: 100%
}

h1 {
  font-size: 16px;
  text-align: center;
}

gmp-map {
  height: 400px;
}

gmp-place-details {
  border-radius: 0px;
  margin: 20px;
  width: 400px;
  height: 400px;
  margin-top: 0px;
}

gmp-advanced-marker {
    display: none;
}

.widget-container {
  min-width: 400px;
  overflow-y: none;
  overflow-x: none;
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Click on the map to view place details</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <gmp-map center="47.759737, -122.250632" zoom="16" map-id="DEMO_MAP_ID">
        <gmp-advanced-marker></gmp-advanced-marker>
    </gmp-map>
    <div class="widget-container" slot="control-inline-start-block-start">
      <gmp-place-details>
        <gmp-place-details-place-request place="ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
        <gmp-place-all-content></gmp-place-all-content> 
      </gmp-place-details>
    </div>
    <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>
  </body>
</html>

장소 세부정보 좁게 표시 요소

PlaceDetailsCompactElement는 최소한의 공간을 사용하여 선택한 장소의 세부정보를 렌더링합니다. PlaceDetailsCompactElement는 지도에서 장소를 강조 표시하는 정보 창, 채팅에서 위치를 공유하는 등의 소셜 미디어 환경, 현재 위치를 선택하기 위한 추천으로, 또는 Google 지도에서 장소를 참조하기 위한 미디어 기사 내에서 유용할 수 있습니다.PlaceDetailsCompactElement는 이름, 주소, 평점, 유형, 가격, 접근성 아이콘, 영업 상태, 단일 사진을 표시할 수 있습니다.

지도에 요소를 추가하려면 HTML 페이지의 gmp-map 요소에 gmp-place-details-compact 요소를 추가하고 orientation 속성을 사용하여 가로로 표시할지 세로로 표시할지 선택합니다.

다음 예에서 gmp-place-details-compactgmp-map 요소 내에 중첩되어 있으며 orientationhorizontal로 설정되어 있습니다. 추가 속성인 truncation-preferred는 특정 콘텐츠를 줄바꿈하는 대신 한 줄에 맞게 잘립니다. gmp-place-details-compact 요소에는 장소를 선택하는 하위 요소인 gmp-place-details-place-request가 포함됩니다. 장소 객체, 장소 ID 또는 'places/{place_id}' 형식의 장소 리소스 이름일 수 있습니다.

<gmp-map center="47.75972, -122.25094" zoom="19" map-id="DEMO_MAP_ID">
  <gmp-place-details-compact orientation = "horizontal" truncation-preferred slot="control-block-start-inline-center" >
    <gmp-place-details-place-request place = "ChIJC8HakaIRkFQRiOgkgdHmqkk"></gmp-place-details-place-request>
    <gmp-place-content-config>
        <gmp-place-media lightbox-preferred></gmp-place-media>
        <gmp-place-rating></gmp-place-rating>
        <gmp-place-type></gmp-place-type>
        <gmp-place-price></gmp-place-price>
        <gmp-place-accessible-entrance-icon></gmp-place-accessible-entrance-icon>
        <gmp-place-open-now-status></gmp-place-open-now-status>
        <gmp-place-attribution light-scheme-color="gray" dark-scheme-color="white"></gmp-place-attribution>
    </gmp-place-content-config>
  </gmp-place-details-compact>
  <gmp-advanced-marker></gmp-advanced-marker>
</gmp-map>

콘텐츠 구성

중첩된 gmp-place-content-config 요소를 사용하여 gmp-place-details-compact 요소에 표시되는 특정 장소 콘텐츠를 제어하여 장소 세부정보를 선택하고 구성할 수 있습니다. gmp-place-content-config 요소 자체에는 여러 하위 콘텐츠 요소가 포함되어 있으며, 각 요소는 표시할 해당 장소 세부정보를 선택합니다. 선택한 세부정보는 항상 사전 정의된 고정된 순서로 렌더링되므로 하위 요소의 순서는 중요하지 않습니다. 이러한 요소 중 일부는 콘텐츠별 속성을 사용하여 추가로 구성할 수 있습니다.

지원되는 모든 콘텐츠 요소에 관한 자세한 내용은 PlaceContentConfigElement 참조 문서를 확인하세요.

간편하게 gmp-place-content-config 요소를 gmp-place-all-content로 대체하여 장소 세부정보 좁게 보기 요소에서 사용 가능한 모든 세부정보를 표시하거나 gmp-place-standard-content로 대체하여 표준 구성을 표시할 수 있습니다.

디자인 구성

세로 방향의 gmp-place-details-compact 요소에 권장되는 너비 범위는 180~300px입니다. 너비가 160px 미만이면 올바르게 표시되지 않을 수 있습니다. 고정 높이를 설정하지 마세요.

가로 방향의 gmp-place-details-compact 요소에 권장되는 너비 범위는 180~500픽셀입니다. 너비가 160px 미만이면 올바르게 표시되지 않을 수 있습니다. 너비가 350픽셀 미만이면 썸네일 이미지가 표시되지 않습니다. 고정 높이를 설정하지 마세요.

gmp-place-details-compact 요소는 요소의 색상과 글꼴을 구성하는 다양한 맞춤 CSS 속성도 지원합니다. 자세한 내용은 장소 UI 키트 맞춤 스타일 지정을 참고하세요.

전체 코드 예 보기

자바스크립트

// Use querySelector to select elements for interaction.
const mapContainer = document.getElementById("map-container");
const detailsContainer = document.getElementById("details-container");
const placeDetails = document.querySelector("gmp-place-details-compact");
const placeDetailsRequest = document.querySelector("gmp-place-details-place-request");
let gMap;
let infowindow;
let marker;
async function initMap() {
    const { PlaceDetailsCompactElement, PlaceDetailsPlaceRequestElement } = await google.maps.importLibrary("places");
    const { Map, InfoWindow } = await google.maps.importLibrary("maps");
    const { AdvancedMarkerElement } = await google.maps.importLibrary("marker");
    gMap = new Map(mapContainer, { mapId: 'DEMO_MAP_ID' });
    marker = new AdvancedMarkerElement({ map: gMap });
    infowindow = new InfoWindow({});
    // Hide the map type control.
    gMap.setOptions({ mapTypeControl: false });
    // Set up map, marker, and infowindow once widget is loaded.
    placeDetails.style.visibility = 'visible';
    placeDetails.addEventListener('gmp-load', (event) => {
        console.log("placeDetails initialized!");
        updateMapAndMarker();
    });
    // Add an event listener to handle clicks.
    gMap.addListener("click", async (event) => {
        marker.position = null;
        event.stop();
        // Fire when the user clicks on a POI.
        if (event.placeId) {
            console.log("clicked on POI");
            console.log(event.placeId);
            placeDetailsRequest.place = event.placeId;
            updateMapAndMarker();
        }
        else {
            // Fire when the user clicks the map (not on a POI).
            console.log('No place was selected.');
        }
        ;
    });
    // Function to update map, marker, and infowindow based on place details
    const updateMapAndMarker = () => {
        console.log("function called");
        if (placeDetails.place && placeDetails.place.location) {
            gMap.panTo(placeDetails.place.location);
            gMap.setZoom(16); // Set zoom after panning if needed
            marker.position = placeDetails.place.location;
            marker.collisionBehavior = google.maps.CollisionBehavior.REQUIRED_AND_HIDES_OPTIONAL;
            marker.style.display = 'block';
            //@ts-ignore
            infowindow.setOptions({
                content: placeDetails
            });
            //@ts-ignore
            infowindow.open({
                anchor: marker,
                map: gMap,
            });
        }
    };
}
initMap();

CSS

html,
body {
  display: flex;
  width: 100%;
  height: 100%;
  margin: 0;
}

h1 {
  font-size: 16px;
  text-align: center;
}

#map-container {
    box-sizing: border-box;
    width: 100%;
}
gmp-place-details-compact {
  /* Sets the color for text and icons on the surface */
  /* Adapts automatically to the user's system light/dark mode preference */
  --gmp-mat-color-on-surface: light-dark(black, white);
  /* Sets the background color of the surface */
  /* Adapts automatically to the user's system light/dark mode preference */
  --gmp-mat-color-surface: light-dark(white, black);
  /* Defines the primary font stack used within the component */
  --gmp-mat-font-family: Google Sans Text, sans-serif;
  /* Defines the style for medium body text (e.g., address, descriptions) */
  --gmp-mat-font-body-medium: normal 400 0.875em/1.25em var(--gmp-mat-font-family, 'Google Sans Text');

  width: 360px;
  border: none;
  overflow-y: hidden;
}

.gm-style-iw button {
    display: none !important;
}

.gm-style-iw-c {
    padding: 0 !important;
    margin: 0 !important;
}

.gm-style-iw-d {
    padding: 0 !important;
    margin: 0 !important; /* Sometimes margin can also contribute to unwanted space */
    overflow: visible !important; /* If you don't want scrollbars, but be careful with content overflow */
}

.gm-style-iw-c * { /* Target all elements inside the infowindow content container */
    padding: 0 !important;
    margin: 0 !important;
}

@media (prefers-color-scheme: dark) {

    .gm-style-iw.gm-style-iw-c,
    .gm-style .gm-style-iw-d,
    .gm-style .gm-style-iw-d::-webkit-scrollbar-track, 
    .gm-style .gm-style-iw-d::-webkit-scrollbar-track-piece,
    .gm-style .gm-style-iw-c,
    .gm-style .gm-style-iw-t::after,
    .gm-style .gm-style-iw-tc::after { 
        background-color: #000 !important;
    }
    .gm-ui-hover-effect>span {
        background-color: #fff !important;
    }
}

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Click on the map to view place details</title>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id = "map-container">
        <gmp-place-details-compact orientation="horizontal">
            <gmp-place-details-place-request place = ChIJn97JQNpC1moRIcJsVMEQLI8></gmp-place-details-place-request>
            <gmp-place-all-content></gmp-place-all-content>
        </gmp-place-details-compact>
    </div>
    <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>  
  </body>
</html>