iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0
Mobile Development

Google Maps SDK for Android 與 GIS App 開發筆記系列 第 14

Day 14: Google Maps SDK for Android–繪製線段 Polyline

  • 分享至 

  • xImage
  •  

前言

看完了地圖上的點位,接下來要看的是線段 (Polyline)。線段在地圖上的應用十分常見,像是導航 App 上的路徑規劃,或是運動 App 的軌跡記錄,都需要用線段來呈現。事不宜遲,就讓我們開始吧~

線段的資料

大家都知道兩點連成一條線,在地圖上的繪製也是。所以要在地圖上畫線,至少要有兩組經緯度,才能進行繪製。

繪製 Line

跟之前繪製 Marker 的概念一樣,Polyline 的建立會是透過 PolylineOptions() 設定線段的內容與外觀,最後呼叫 GoogleMap.addPolyline(PolylineOptions) 將線段繪製到地圖上。

加入經緯度

PolylineOptions().add()

一次加入一個經緯度。

private fun addOnePolyline(map: GoogleMap) {
    val point1 = LatLng(24.1627, 120.645)
    val point2 = LatLng(24.1626, 120.647)
    val polylineOptions =
        PolylineOptions()
            .add(point1)
            .add(point2)
    map.addPolyline(polylineOptions)
}

PolylineOptions().addAll()

一次加入多個經緯度。

在大於二的經緯度數量下,經緯度加入的順序會影響線段繪製的方向性,這點要特別注意。

    private fun addOnePolyline(map: GoogleMap) {
        val point1 = LatLng(24.1627, 120.645)
        val point2 = LatLng(24.1626, 120.647)

        val latLngList = mutableListOf(point1, point2)

        val polylineOptions =
            PolylineOptions()
                .addAll(latLngList)

        map.addPolyline(polylineOptions)
    }

因為這個範例裡的 latLngList 的順序性與前一個範例一樣,而且只有兩個點,所以線段繪製的結果不會有差異。。

https://ithelp.ithome.com.tw/upload/images/20230928/20160271q7MeqJ3rzB.png

更新線段經緯度

如果線段已經繪製在地圖上,可以呼叫 Polyline.setPoints() 設定新的經緯度。

線段外觀

前面的範例裡可以看到,PolylineOptions() 只有單純的加入點位,所以只有看到預設的黑色線段。

顏色 PolylineOptions().color()

單一顏色

private fun addSingleColorPolyline(map: GoogleMap) {
    val point1 = LatLng(24.1627, 120.6403)
    val point2 = LatLng(24.1657, 120.6398)
    val point3 = LatLng(24.1666, 120.6424)
    val latLngList = listOf(point1, point2, point3)
    val polylineOptions = PolylineOptions()
        .addAll(latLngList)
        .color(Color.BLUE)
    map.addPolyline(polylineOptions)
}

同線段給不同顏色

🚨 注意!要使用 addSpan() 調整線段外觀,必須要使用 Maps SDK for Android 18.1.0 以上版本,並使用最新的轉譯器,不然都只會看到黑色的線~

/**
 * 多線段不同色
 *
 * @param map
 */
private fun addMultiColorPolyline(map: GoogleMap) {
    val point1 = LatLng(24.1687, 120.6391)
    val point2 = LatLng(24.1706, 120.6369)
    val point3 = LatLng(24.1731, 120.6374)
    val latLngList = listOf(point1, point2, point3)
    val polylineOptions = PolylineOptions()
        .addAll(latLngList)
        .addSpan(StyleSpan(Color.GREEN), StyleSpan(Color.MAGENTA))
    map.addPolyline(polylineOptions)
}

https://ithelp.ithome.com.tw/upload/images/20230928/20160271TKcKLxEHJv.png

漸層顏色

/**
 * 漸層顏色的線段
 *
 * @param map
 */
private fun addGradientColorPolyline(map: GoogleMap) {
    val point1 = LatLng(24.1603, 120.6484)
    val point2 = LatLng(24.1581, 120.6516)
    val latLngList = listOf(point2, point1)
    val polylineOptions = PolylineOptions()
        .addAll(latLngList)
        .addSpan(StyleSpan(
            StrokeStyle.gradientBuilder(
                Color.RED,
                Color.YELLOW
            ).build()
        ))
    map.addPolyline(polylineOptions)
}

https://ithelp.ithome.com.tw/upload/images/20230928/20160271MTrpKpU1PQ.png

將線段顯示為重複的 PNG

我選的圖片效果不是很明顯,效果可以參考官方的圖片

但基本的 API 使用如下:

private fun addStampStylePolyline(map: GoogleMap) {
    
    // 將 PNG 圖片 讀取並建立 TextureStyle
    val stampStyle =
        TextureStyle.newBuilder(BitmapDescriptorFactory.fromResource(R.drawable.chevron)).build()
    // 建立裝飾外觀的 StyleSpan  並設定底色
    val span = StyleSpan(StrokeStyle.colorBuilder(Color.YELLOW).stamp(stampStyle).build())
    map.addPolyline(
        PolylineOptions()
            .add(LatLng(24.1640, 120.6552), LatLng(24.1614, 120.6598))
            .addSpan(span)
    )
}

線段寬度 (粗細) PolylineOptions.width()

預設的線段寬度是 10px,圖層縮放也不會改變其尺寸。

要改變線段寬度,要呼叫 PolylineOptions.width() 並傳入以 px 為單位的浮點數。

private fun addThickerPolyline(map: GoogleMap) {
    val point1 = LatLng(24.1603, 120.6484)
    val point2 = LatLng(24.1581, 120.6516)
    val latLngList = listOf(point2, point1)
    val polylineOptions = PolylineOptions()
        .addAll(latLngList)
        .width(25f)
    map.addPolyline(polylineOptions)
}

https://ithelp.ithome.com.tw/upload/images/20230928/20160271BMZ9JaHqEN.png

圓角/斜角

線段的圓角或斜角也是可以調整的,並以調整的目標,分為兩種:

  1. 連接處 jointType
  2. 線條末端 startCapendCap

連接處

polyline.jointType = JointType.ROUND

線段末端

// 起點
polyline.startCap = RoundCap()
// 終點
polyline.endCap = RoundCap()

// 自定義
polyline.endCap = CustomCap(BitmapDescriptorFactory.fromResource(R.drawable.arrow), 16F)

綜合使用

private fun addSmoothPolyline(map: GoogleMap) {
    val point1 = LatLng(24.1576, 120.6591)
    val point2 = LatLng(24.1581, 120.6603)
    val point3 = LatLng(24.1575, 120.6623)
    val latLngList = listOf(point1, point2, point3)
    val polylineOptions = PolylineOptions()
        .addAll(latLngList)
        .width(20f) // 調整寬度
        .startCap(RoundCap()) // 起點圓滑
        .endCap(RoundCap()) // 終點圓滑
        .jointType(JointType.ROUND) // 連接處
        .addSpan(StyleSpan(Color.YELLOW), StyleSpan(Color.BLUE))
    map.addPolyline(polylineOptions)
}

https://ithelp.ithome.com.tw/upload/images/20230928/20160271NBG41yH2Yh.png

移除線段

跟其他圖層上的物件一樣,呼叫 remove() 即可將它從圖面上移除。

polyline.remove()

點擊事件

線段的點擊事件預設是不可點擊,如果要啟用必須設定。

Polyline.setClickable(true)

並在地圖上加入 OnPolylineClickListener 監聽點擊事件。

GoogleMap.setOnPolylineClickListener(OnPolylineClickListener)

小結

以上就是如何在 Google Maps 上加入線段並自定外觀的介紹。
對文章內容有任何問題,歡迎留言一起討論。

是說時間過得好快,明天就是第 15 天啦~
代表賽程也過了一半,繼續努力!

明天見囉!!/images/emoticon/emoticon07.gif


上一篇
Day 13: Google Maps SDK for Android–自訂 Marker 外觀
下一篇
Day 15: Google Maps SDK for Android–繪製多邊形 Polygon
系列文
Google Maps SDK for Android 與 GIS App 開發筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言