在網頁上使用 Apple 地圖

Apple MapKit JS
https://developer.apple.com/documentation/mapkitjs/
截圖 2023-01-15 11.06.44

今天換換口味,網站上除了使用 Google 地圖外,也可以使用 Apple 地圖。

首先來這裡根據步驟建立 Maps ID 並且取得 MapKit JS private key
https://developer.apple.com/documentation/mapkitjs/creating_a_maps_identifier_and_a_private_key

然後再來這裡根據 JS private key 建立 token
https://maps.developer.apple.com/token-maker

JS token 產生後在同一個頁面上 Apple 會給出一個範本網頁,如下。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">

<script
  src="https://cdn.apple-mapkit.com/mk/5.x.x/mapkit.core.js"
  crossorigin async
  data-callback="initMapKit"
  data-libraries="map,annotations"
  data-initial-token="YOUR_JS_TOKEN"
></script>

<style>
#map {
    width: 100%;
    height: 600px;
}
</style>

</head>

<body>
<div id="map"></div>

<script type="module">

(async () => {
    const tokenID = "YOUR_JS_TOKEN";

    if (!window.mapkit || window.mapkit.loadedLibraries.length === 0) {
        // mapkit.core.js or the libraries are not loaded yet.
        // Set up the callback and wait for it to be called.
        await new Promise(resolve => { window.initMapKit = resolve });

        // Clean up
        delete window.initMapKit;
    }

    mapkit.init({
        authorizationCallback: function(done) {
            done(tokenID);
        }
    });

    const map = new mapkit.Map("map");
})();

</script>
</body>
</html>

紫色部分刪除,紅色地方修改。先將最後的「const map = new mapkit.Map(“map”);」 這一行刪除,這不是我們要的地圖初始化程式,待會要改寫成需要的。上方 <script> 標籤中的 data-libraries 參數除了預設的 map 外,還要多載入 annotations。

資料來源就用我最常用的範例,AQI 空氣品質指標,這裡要自行撰寫一個後端程式或是從 GitHub 上抓下來存檔。網頁上剩餘的程式碼如下。

<script>
window.onload = function() {
    // 此地點為台灣地理中心碑
    const coordinate = new mapkit.Coordinate(23.97416, 120.97982)
    const span = new mapkit.CoordinateSpan(5, 5)  // 1degree=111km
    const region = new mapkit.CoordinateRegion(coordinate, span)
    const map = new mapkit.Map("map", {center: coordinate, region: region})

    fetch("aqi.php")  // 或是已準備好的資料檔,例如 data.json
    .then(function(response) {
        return response.json()
    })
    .then(function(jsonObj) {
        createAnnotation(map, jsonObj)
    })
}

function createAnnotation(map, jsonObj) {
    function getColor(aqi) {
        if (aqi >= 0 && aqi < 50) {
            return ["green", "white"]
        }

        if (aqi >= 50 && aqi < 100) {
            return ["yellow", "balck"]
        }

        if (aqi >= 100 && aqi < 150) {
            return ["orange", "white"]
        }

        if (aqi >= 150 && aqi < 200) {
            return ["red", "white"]
        }

        if (aqi >= 200 && aqi < 300) {
            return ["purple", "white"]
        }

        if (aqi >= 300) {
            return ["darkred", "white"]
        }

        return ["gray", "white"]
    }

    let annotations = []
    jsonObj['records'].forEach(record => {
        const coordinate = new mapkit.Coordinate(
            parseFloat(record.latitude), 
            parseFloat(record.longitude)
        )
        const ret = getColor(parseInt(record.aqi))
        const annotation = new mapkit.MarkerAnnotation(coordinate, {
            color: ret[0], 
            glyphColor: ret[1],
            glyphText: record.aqi,
            title: record.sitename,
            subtitle: record.county,
            collisionMode: mapkit.Annotation.CollisionMode.Circle,
            clusteringIdentifier: "mygroup"
        })
        annotations.push(annotation)
    })
    map.addAnnotations(annotations)
}
</script>

顯示結果如下,紅色圈圈為群組標記(clusteringIdentifier與collisionMode參數),不然標記太多會擠成一團不好看,右圖為南部地區放大結果,紅色圈圈會適當的展開

截圖 2023-01-15 10.49.54
截圖 2023-01-15 10.52.17

同樣的資料使用 Google 地圖時結果如下,這裡使用了叢集標記,不然標記擠成一團。至於標記顏色在處理上不像 Apple 地圖那樣簡單,所以使用預設的方式沒額外處理,因此標記展開後全部都是紅色。

截圖 2023-01-15 10.51.00
截圖 2023-01-15 11.00.15

喜歡哪種地圖風格呢?兩者比較之下,Apple 地圖好像有種清新的感覺。

發表迴響