Try   HackMD

Google Map API 使用手冊

什麼是 Google Map API

「Google 地圖 API」可讓您利用 JavaScript 將「Google 地圖」嵌入自己的網頁。此 API 透過多種服務提供一些公用程式,以操控地圖 (如同 http://maps.google.com 網頁上所示),並新增地圖內容,能讓您在網站上建立強大的地圖應用程式。——Google 地圖 API 的使用方法

開始使用

  1. 在index.html加入,地圖會顯示在這個標籤裡。
<div id="map"></div>


2. 再加上這行引用,請寫在所有script的最上層。

<script async defer
src="https://maps.googleapis.com/maps/api/js?key=your_key&libraries=places,drawing,geometry&v=3&callback=initMap">
</script>


3. 在<body>插入<script>成對標籤,並寫入function initMap()

var map;
function initMap() {
    map = new google.maps.Map(document.getElementById('map'), {
        center: {lat: 25.04, lng: 121.512},
        zoom: 18
    });
}


4. 新增index.css,寫入以下樣式:

html, body { height: 100%; margin: 0; padding: 0; }

記得一定要寫出height,才會看到地圖出現在網頁上。


5. 瀏覽器展示成果。

初始化地圖相關設定(initMap)

  1. 修改initMap()
function initMap() {  
        const directionsService = new google.maps.DirectionsService();
         // 載入路線服務

        const directionsRenderer = new google.maps.DirectionsRenderer(
            {
                map: map,

                polylineOptions: {

                    strokeColor: '#6224BF',
                                
                    strokeOpacity: 0.8,

                    strokeWeight: 8,
                },
                suppressMarkers: true,
                // 隱藏座標

                draggable: true
                // 拖曳路線
            }            
        ); 
        
        map = new google.maps.Map(document.getElementById("map"), {            

            center:new google.maps.LatLng(24.114128, 120.61554),       
            // 地圖的起始顯示位置

            zoom: 20,

            mapTypeControl: false,
            // 街景
            
            streetViewControl: false
            // 地圖樣式 
            // 上面兩個要關掉,避免而外收費。 

        });

        directionsRenderer.setMap(map);
        // 加入地圖圖層    
    
        const onChangeHandler = function() {
            vehicleRouteMap(directionsService, directionsRenderer);
        };
     

        document.getElementById("go").addEventListener("change", onChangeHandler);
        // 行車路線的起始點。
    
        document.getElementById("fin").addEventListener("change", onChangeHandler);
        // 行車路線的目的地。 

        document.getElementById("showBtn").addEventListener("click", () => {
            vehicleRouteMap(directionsService, directionsRenderer); 
            // 呼叫行車路線  
        });

       
}

一 其他補充

  • polylineOptions:對座標與行車路線外觀與顏色進行改變。
參數名稱 代表意思
fillColor 簡單多邊形 (Simple Polygon) 覆蓋區域顏色
strokeColor 行車路線線條顏色
strokeOpacity 行車路線線條透明度,數值越低透明越高,反之。
strokeWeight 行車路線線條寬度,數值越低線條越細,反之。
參數名稱 代表意思
suppressMarkers 隱藏座標
draggable 是否可以拖曳,更改行車路線。
  • google.maps.Map:預設載入地圖時的相關設定,會寫在這裡。
參數名稱 代表意思
center 地圖預設出現的經緯度位置,有很多種不同的寫法,也可以寫成:{lat:24.0861162, lng: 120.6933002}這種格式。
zoom 載入地圖後,預設的縮放值。
mapTypeControl 街景服務。
streetViewControl 地圖樣式。
setMap 加入地圖圖層。

注意mapTypeControl和streetViewControl要關閉(false),避免被而外收取費用。

標示座標點(Marker)與製作資訊視窗(InfoWindow)

  1. 在最外圈宣告全域變數markersinfoWindows
var markers = [];

var infoWindows = []; 
  • markers 用來儲存座標點。
  • new google.maps.Marker 儲存座標的資訊視窗內容。


2. 新增加markWaypointMap的function。

function markWaypointMap() {   // 載入座標和資訊視窗 
    marker_config.forEach(function(e,i){
            markers[i] = new google.maps.Marker(e);
            markers[i].setMap(map);          
            infoWindows[i] = new google.maps.InfoWindow({
                content: "<table id='mapTable' cellspacing='0'>\
                        <thead><tr><th colspan='2'>座標資訊</th></tr></thead>\
                        <tr><td>路名一</td><td>" + markers[i].name + "</td></tr>\
                        <tr><td>地址一</td><td>" + markers[i].site + "</td></tr>\
                        <tr><td>經度一</td><td>" + markers[i].position.lat() + "</td></tr>\
                        <tr><td>緯度一</td><td>" + markers[i].position.lng() + "</td></tr>\
                        </table>",
                disableAutoPan: true
                // 設置爲true時可禁用自動平移功能
            });  
        }); 
        // 自訂座標,顯示資訊視窗。
   
        marker_config.forEach(function(e,i) {        
            markers[i].addListener('click', function() {
                infoWindows[i].open(map, markers[i]);
            });         
        });
        // 點擊跳出顯示資訊視窗。       

} 
  • new google.maps.Marker根據e內容產生座標點。
  • new google.maps.InfoWindow根據content內容產生資訊視窗。


3. 在initMap()加入,markWaypointMap()呼叫函式。

markWaypointMap()
// 呼叫座標和資訊視窗  


4. 瀏覽器展示成果 ( 可依需求再加上樣式 ) 。

標記叢集(MarkerClusterer)

  1. 新增加zoomInOutMap的function。
function zoomInOutMap() {

        const markerCluster = new markerClusterer.MarkerClusterer({ markers, map });
        // 當座標在一起時,改用Marker Clustering(標記叢集)。
}
  • markerClusterer.MarkerClusterer管理markers製造出標記叢集。
  1. 在initMap()加入,zoomInOutMap()呼叫函式。
zoomInOutMap()
// 呼叫zoomInOutMap 


3. 瀏覽器展示成果。

畫行車路線(setDirections)

  1. 在全域變數宣告marker_config,用來儲存經過點,行車路線會經過這些座標點。
var marker_config = [
        {
            "id": 1,
            "name": "台灣大道一段",
            "site": "400台中市中區台灣大道一段1號鐵鹿大街A10",
            "type": "Point",
            "position": {
                    lat: 24.1372369,
                    lng: 120.68687
            }
        },
        {
            "id": 2,
            "name": "台灣大道一段",
            "site": "400台中市中區台灣大道一段1號",
            "type": "Point",
            "position": {
                    lat: 24.1370597,
                    lng: 120.6869718
            }
        },
        {
            "id": 3,
            "name": "台灣大道一段",
            "site": "400台中市中區台灣大道一段1號B3櫃位",
            "type": "Point",
            "position": {
                    lat: 24.1373346,
                    lng: 120.6872849
            }
        },
        {
            "id": 4,
            "name": "新民街",
            "site": "401台中市東區新民街88號",
            "type": "Point",
            "position": {
                    lat: 24.137648,
                    lng: 120.686498
            }
        },
        {
            "id": 5,
            "name": "復興路四段",
            "site": "401台中市東區復興路四段186號",
            "type": "Point",
            "position": {
                    lat: 24.136575,
                    lng: 120.6862517
            }
        },
        {
            "id": 6,
            "name": "公園東路",
            "site": "401台中市東區公園東路150號",
            "type": "Point",
            "position": {
                    lat: 24.1397534,
                    lng: 120.683731
            }
        },
        {
            "id": 7,
            "name": "自由路二段",
            "site": "404台中市北區自由路二段湖心亭",
            "type": "Point",
            "position": {
                    lat: 24.1397534,
                    lng: 120.683731
            }
        },
        {
            "id": 8,
            "name": "南京路",
            "site": "4F, No. 66號南京路東區台中市401",
            "type": "Point",
            "position": {
                    lat: 24.1361803,
                    lng: 120.6883141
            }
        },
        {
            "id": 9,
            "name": "樂業一路",
            "site": "401台中市東區樂業一路79號",
            "type": "Point",
            "position": {
                    lat: 24.1348453,
                    lng: 120.6907701
            }
        },
        {
            "id": 10,
            "name": "林森路",
            "site": "403台中市西區林森路100巷",
            "type": "Point",
            "position": {
                    lat: 24.1223663,
                    lng: 120.6662814
            }
        },
        {
            "id": 11,
            "name": "民生路",
            "site": "40358台中市西區民生路368巷2弄12號",
            "type": "Point",
            "position": {
                    lat: 24.1319946,
                    lng: 120.6610709
            }
        },
        {
            "id": 12,
            "name": "興大路",
            "site": "402台中市南區興大路145號",
            "type": "Point",
            "position": {
                    lat: 24.1218507,
                    lng: 120.6742067
            }
        },
        {
            "id": 13,
            "name": "忠孝路",
            "site": "402台中市南區忠孝路",
            "type": "Point",
            "position": {
                    lat: 24.1292282,
                    lng: 120.6741345
            }
        },
        {
            "id": 14,
            "name": "育德路",
            "site": "404台中市北區育德路2號",
            "type": "Point",
            "position": {
                    lat: 24.1507654,
                    lng: 120.6792589
            }
        },
        {
            "id": 15,
            "name": "館前路",
            "site": "404台中市北區館前路1號",
            "type": "Point",
            "position": {
                    lat: 24.1417558,
                    lng: 120.6627565
            }
        },
        {
            "id": 16,
            "name": "文昌東十一街",
            "site": "406台中市北屯區文昌東十一街14巷1號",
            "type": "Point",
            "position": {
                    lat: 24.1437317,
                    lng: 120.677408
            }
        }
];
  1. 新增加vehicleRouteMap的function。
function vehicleRouteMap(directionsService, directionsRenderer) {  // 行車路線  
        const waypoint = [];
        
        for (let i = 0; i < marker_config.length; i++) {
            waypoint.push({         
                location: marker_config[i].position,
                stopover: true
            });           
        }
        // 將經過點存入waypoint

        var request = {
            origin: document.getElementById("go").value,
            // 出發點

            destination: document.getElementById("fin").value,
            // 目的地

            waypoints: waypoint,       
            // 經過點         

            optimizeWaypoints: true,    
            // 使用更有效的順序重新排列waypoints來優化
                       
            travelMode: 'DRIVING'
            // 開車
        }
        // 設定出發點與目的地的座標和移動方式


        directionsService.route(request)
        .then((response) => {

        directionsRenderer.setDirections(response);                 

        }).catch((e) => window.alert("status not 200!"));             
        // 根據request條件,畫行車路線。
}
  • waypoint將marker_config的座標位置儲存。
  • optimizeWaypoints 指定使用提供的路線waypoints可以通過以更有效的順序重新排列航點來優化。如果是true ,方向服務將waypoints 在waypoint_order字段中返回重新排序的內容 一 [官方介紹]

travelMode 補充

參數名稱 代表意思
BICYCLING 起點到終點的移動方式為腳踏車
DRIVING 起點到終點的移動方式為開車
WALKING 起點到終點的移動方式為走路
TRANSIT 起點到終點的移動方式為轉運
  1. 在initMap()加入,vehicleRouteMap()呼叫函式。
vehicleRouteMap()
// 呼叫行車路線


4. 瀏覽器展示成果。

根據zoom縮放呈現不同marker個數

  1. 因客戶需求在不同的縮放數值(getZoom()),需呈現不同的marker數量,伴隨的資訊視窗顯示內容也不同,因此會在原先的zoomInOutMap() function加入判斷式和新增兩個json檔案。

  2. 新增 10.json 和 16.json。

將縮放數值顯示不同座標與資訊內容的json data個別存到json檔案。


3. 新增function zoomInOutMarkerMap(),讀取10.json 與 16.json資料,標記座標與產生資訊視窗。

function zoomInOutMarkerMap(jsonData) { 
        $.getJSON( jsonData, function( data ) {
            data.data.forEach(function(e,i){                             
                markers[i] = new google.maps.Marker({
                    position: {
                        lat: data.data[i].latitude,
                        lng: data.data[i].longitude 
                    },
                    animation: google.maps.Animation.DROP
                });

                markers[i].setMap(map);          
                infoWindows[i] = new google.maps.InfoWindow({
                    content: "<table id='mapTable' cellspacing='0'>\
                            <thead><tr><th colspan='2'>座標資訊</th></tr></thead>\
                            <tr><td>編號一</td><td>" + data.data[i].plateNumber + "</td></tr>\
                            <tr><td>路名一</td><td>" + data.data[i].direction + "</td></tr>\
                            <tr><td>經度一</td><td>" + data.data[i].latitude + "</td></tr>\
                            <tr><td>緯度一</td><td>" + data.data[i].longitude + "</td></tr>\
                            </table>",
                    disableAutoPan: true
                    // 設置爲true時可禁用自動平移功能
                });  
            }); 
            // 自訂座標,顯示資訊視窗。
        
            data.data.forEach(function(e,i) {        
                markers[i].addListener('click', function() {
                    infoWindows[i].open(map, markers[i]);
                });         
            });
            // 點擊跳出顯示資訊視窗。 
        });
}
  1. 新增function deleteMarkersMap(),用來清空上次的座標標記。
function deleteMarkersMap() {   
    for (let i = 0; i < markers.length; i++) {   
        markers[i].setMap(null);   
    }  
    markers = [];  
};  
  1. 修改function zoomInOutMap()內容。
function zoomInOutMap() {  // 縮放地圖時,改變座標狀態。
        map.addListener("zoom_changed", () => {
            $('#zoom').text("");            
            $('#zoom').append("目前縮放數值: " + map.getZoom()); 
            // 左上方加入縮放數值顯示。
            
             let originalNum = true, tenNum = true, sixNum = true;
             tenNum = false, sixNum = false,  originalNum = false;
             /* 
                當zoom縮放改變時,將三個Num都改成false
                ,這樣當zoomValue條件成立,也不會重複標記。    
             */

            if ( map.getZoom() == 10 ) {
                zoomValue = 10;
                tenNum = true;                
            }
     
            else if ( map.getZoom() == 16 ) { 
                zoomValue = 16; 
                sixNum = true;                                 
            } 
            else if (map.getZoom() > 16){
                zoomValue = 20;  
                originalNum = true;                               
            }

                
           if ((zoomValue == 10)&&(tenNum == true)) {
                deleteMarkersMap() 
                // 呼叫清空上次的座標  

                zoomInOutMarkerMap("/js/10.json")
                // 呼叫10.json 與 16.json 標記座標用 
           }   
           else if ((zoomValue == 16)&&(sixNum == true)) {
                deleteMarkersMap() 
                // 呼叫清空上次的座標  

                zoomInOutMarkerMap("/js/16.json")
                // 呼叫10.json 與 16.json 標記座標用  
           } 
            else if ((zoomValue == 20)&&(originalNum == true))  {
                deleteMarkersMap()
                // 呼叫清空上次的座標

                markWaypointMap()
            }                   
        });
        // 當zoom的數值改變時,觸發條件式。


        $.getJSON( "/js/response_1646112019728.json", function( data ) {
        // 這條$.getJSON一定得加。
            markerCluster = new markerClusterer.MarkerClusterer({ markers, map });
            // 如果沒有顯示出Clustering,可以檢查markers有沒有值。           
        });
        // 當座標在一起時,改用Marker Clustering(標記叢集)。
}
  • 條件設定在當.getZoom()為 10 或者是 16 時,function裡的條件式會重新判斷,呼叫哪個function做重新標記的動作以及清空上次的標記。
  1. 瀏覽器展示成果。