Google map API + Angular 6 --- 3 在使用者點擊marker 時顯示圖片。

在使用者點擊google map上面的marker時跳出一個小小畫面顯示這個marker的相關資訊~如:地點名稱、圖片....等主要是靠著 google maps api裡的一個叫做info window的物件功能。
官方的詳細說明可以在這個連結裡參閱。

主要的概念就是我們透過marker去listen點擊(click)的行為,然後在當marker遇到click的行為之後然後把info window顯示在相對應的地圖與marker上面。而marker的內容則是用文字的方式填入,因此我們可以把html的內容填入字串內。最後就會變成在info window內顯示類似網頁的樣式與內容出來當然要顯示圖片的內容也是透過 img 這個html tag就可以實現啦!

首先我們先對一個marker加入info window來顯示一張圖片好了。依舊在html 內我們加入一段新的section作為新的一張地圖。

<section class="showmap"> <h4 class="name">Info window with Mark</h4> <div class="map" id="map3"></div> </section>

然後我們找一張圖片放在Angular project的 src/assets/ 內當作等等要顯示在info window的圖片檔案名稱假設為 robot.png。

接著撰寫這部份typescript邏輯部份如下:

1. 首先先用Map物件在我們的DOM (id="map3")的位置畫出我們設計好的地圖。

const map3 = new google.maps.Map( this.el.nativeElement.querySelector('#map3'), { center: this.position, zoom: 15 } );

2. 我們把info window的內容寫好,把html當作字串填入並且設定圖片大小為寬160、高度為120然後指定給info window這個物件(infow)。
const contentString = `<div> <img src="assets/robot.png" width='160' height='120'></div> `; const infow = new google.maps.InfoWindow({ content: contentString, });

3. 接著在指定的地圖(id="map3")上面顯示marker
const marker = new google.maps.Marker({
position: this.position, map: map3, title: 'Clover' });

4. 最後我們把marker物件加入監聽點擊(click)的行為並且在聽到點擊的時候使用callback去呼叫 info windowopen的方法。然後open的方法參數為我們顯示的地圖物件(map3)與marker物件(marker)。

marker.addListener('click', () => infow.open(map7, marker));

然後在terminal 下執行 ng serve 後開啟localhost:4200 點擊map3 上的marker應該就會顯示圖片的info window才對。




接著我們試著在多個marker上面顯示info windows
在官方的說明裡只有講說我們可以用一個info window物件來對不同的marker來做顯示info window但是沒有相關範例說明如何實做。在這邊網路上也有不少人詢問如何實做!以下就是參考stackoverflow的方式實做,主要是用了Javascript的一個特性來達成~函式定義後的立即調用

1. 首先我們在html部份新增map4的地圖作為這次的範例。
<section class="showmap"> <h4 class="name">Info window with multiple Mark</h4> <div class="map" id="map4"></div> </section>

2. 我們宣告一個Array來放我們接下來要產生在map4上面的多個marker之經緯度值與每個marker info window相對應顯示的圖片名稱,這邊圖片的內容與名稱可以依據你自己的檔案名稱做修改。

const markersAry = [ { lat: 24.980102, lng: 121.549126, img: 'ball.png'}, { lat: 24.981312, lng: 121.546236, img: 'castle.png'}, { lat: 24.980622, lng: 121.549246, img: 'ginza.jpg'}, { lat: 24.982832, lng: 121.543656, img: 'goomba.png'}, { lat: 24.980942, lng: 121.549966, img: 'mario.png'}, { lat: 24.983052, lng: 121.547076, img: 'robot.png'} ];

3. 透過google map 物件指定html id="map4"的DOM元件上產生我們需要的地圖。

const map4 = new google.maps.Map( this.el.nativeElement.querySelector('#map4'), {center: this.position, zoom: 15} );

4. 這邊我們宣告3個變數:一個日google Marker物件、一個info window的內容字串變數info window物件
let multMarks: google.maps.Marker; let contentString: string; let infow: google.maps.InfoWindow;

5. 再來我們使用markersAry每個經緯度與map4來對每個Marker做設定。這邊我們用forEach在每個元素內做Marker設定與info window的內容與建立,最後在對info window物件建立監聽點擊的行為。

markersAry.forEach((loc) => { multMarks = new google.maps.Marker({ position: { lat: loc.lat, lng: loc.lng }, map: map4 });
// 對每個Marker的 info window的內容做設定
contentString = `<div><img src="assets/${loc.img}" width='160' height='120'></div>`;
// 建立 info window物件。
infow = new google.maps.InfoWindow(); // 使用google maps event的addListener來對Marker做 // 點擊監聽與info window的內容與顯示。 google.maps.event.addListener( multMarks, 'click', (( mark: google.maps.Marker, content: string, infowindow: google.maps.InfoWindow) => { return () => { infowindow.setContent(content); infowindow.open(map4, mark); }; })(multMarks, contentString, infow)); });

這邊我們採用 google.maps.event.addListener()這個method來設定多個Marker!這個method需要傳入三個變數:
第一個instance也就是我們的Marker(multMarks)
第二個eventName也就是點擊的行為(click)
第三個handler也就是我們點擊後要做callback function

在callback function 中我們採用Javascript的函式定義立即調用的功能來作到對每一個Marker設定後就運行callback的小方法。
其中這個callback function為return 一個Function,此Function用來設定info window的內容與open的參數值這是最讓人沒想到的小方法但也是這個方式才有辦法讓多個Marker可以顯示不同的info window的小技巧

最後在terminal 下執行ng server應該就可以看到結果了!


.........待續



  • Google map API + Angular 6 ---1 繪出地圖使用紀錄
  • Google map API + Angular 6 ---2 加上 marker
  • Google map API + Angular 6 --- 3 在使用者點擊marker 時顯示圖片。


  • 留言