iT邦幫忙

2023 iThome 鐵人賽

DAY 10
0
Mobile Development

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

Day 10: Google Maps SDK for Android–線上圖層套疊 WMTS

  • 分享至 

  • xImage
  •  

前言

在第二天的資料格式介紹中,曾提到的 WMTS 線上圖磚服務,今天我們將實際的串接服務並將圖層呈現在地圖上。

複習一下
WMTS 全稱是 Web Map Tile Service,是一種將高品質地圖依據網格系統切割成小圖磚發布的網路服務。

圖磚在 Google Maps 上的概念

Google Maps API (SDK) 將地圖依不同層級,切割成數個正方形的網格,當地圖移動至新的位置或縮放層級時,會根據當下的層級位置,給出 z, x, y 這三個數值,並根據這三個數值取得它對應的圖片。

https://ithelp.ithome.com.tw/upload/images/20230924/201602712PdTEUmPxW.png

圖片來源:PTV Logistics GmbH 2023

資料來源:國土測繪服務雲

這次練習所要使用的圖磚資源,是由國土測繪中心所提供的國土測繪服務雲的資源。

目前國土測繪服務雲所提供的資料,大多數需要以機關單位的身份提出申請,但今天我們要使用的 WMTS 服務,是屬於不用申請的免申請服務 API。

https://ithelp.ithome.com.tw/upload/images/20230924/201602712YZeObZFf2.png

資料格式

連線國土測繪的 EPSG:3857 版本的介接網址 https://wmts.nlsc.gov.tw/wmts ,會發現拿到的是一個 XML 格式的檔案,內容長得像下面這個截圖。

https://ithelp.ithome.com.tw/upload/images/20230924/20160271HoyuxUlOeI.png

這個 XML 檔案其實是由 OGC (開放地理空間協會) 所提出的網路地圖介接規格,內容會描述這個 WMTS 服務所能提供的圖層與詳細規格。

而在 SDK 中介接圖磚,我們要看的是這個區塊的 ResourceURL tag 中的 template。

<Layer>
	<ows:Title>臺灣通用電子地圖</ows:Title>
	<ows:Identifier>EMAP</ows:Identifier>
	<ows:BoundingBox crs="urn:ogc:def:crs:EPSG::3857">
	<ows:LowerCorner>-2.0037507842788246E7 -3.0240971958386146E7</ows:LowerCorner>
	<ows:UpperCorner>2.0037507842788246E7 3.024097145838615E7</ows:UpperCorner>
	</ows:BoundingBox>
	<Style isDefault="true">
	<ows:Title>Default Style</ows:Title>
	<ows:Identifier>default</ows:Identifier>
	</Style>
	<Format>image/jpeg</Format>
	<TileMatrixSetLink>
	<TileMatrixSet>GoogleMapsCompatible</TileMatrixSet>
	</TileMatrixSetLink>
	<ResourceURL format="image/jpeg" resourceType="tile" template="https://wmts.nlsc.gov.tw/wmts/EMAP/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}"/>
</Layer>

比對 tags 所提供的各欄位資訊,我們可以串出以下的 URL。

https://wmts.nlsc.gov.tw/wmts/EMAP/default/GoogleMapsCompatible/{TileMatrix}/{TileRow}/{TileCol}

參照國土測繪雲上所提供的連線範例,確認無誤。

連線範例:https://wmts.nlsc.gov.tw/wmts/EMAP/default/GoogleMapsCompatible/15/14127/27366

https://ithelp.ithome.com.tw/upload/images/20230924/20160271BDR8Q7rfcS.png

實作

在 Google Maps SDK 上要加入 WMTS 圖層,使用的是 TileOverlay 這個類別,並實作 TileProvider 這個介面 (圖磚的來源)。

1. 實作 UrlTileProvider

UrlTileProvider 是實作 TileProvider 的類別,專門用來讀取 Url 來源的圖磚,而我們需要 override 的方法是 getUrl()

完整實作會如以下:

class WMTSTileProvider(tileWidth: Int, tileHeight: Int):
    UrlTileProvider(tileWidth, tileHeight) {
    override fun getTileUrl(x: Int, y: Int, zoom: Int): URL? {
        val url = "https://wmts.nlsc.gov.tw/wmts/EMAP/default/GoogleMapsCompatible/$zoom/$y/$x"

        return try {
            URL(url)
        } catch (e: MalformedURLException) {
            null
        }
    }
}

Google Maps SDK 的 x, y, zoom 分別是對照 Url 上的 TileCol, TileRow, TileMatrix,在寫的時候要特別注意,不然讀取出來的圖磚會對不上圖面的位置。

2. 加入 TileOverlayGoogleMap

class WMTSMapActivity : AppCompatActivity() {

    private val binding: ActivityWmtsMapBinding by lazy {
        ActivityWmtsMapBinding.inflate(layoutInflater)
    }

    private var googleMap: GoogleMap? = null

    private var wmtsTileOverlay: TileOverlay? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(binding.root)
        binding.mapView.onCreate(savedInstanceState)

        binding.mapView.getMapAsync {
            googleMap = it

            wmtsTileOverlay = setWmtsTileOverlay(it)
        }
    }

    /**
     * 設定 WMTS 圖層並取得 TileOverlay 物件
     */
    private fun setWmtsTileOverlay(map: GoogleMap): TileOverlay? {
        
        // 建立 WMTS 圖磚服務來源 並填入圖磚的長寬
        val provider = WMTSTileProvider(256, 256)
        
        // 建立 WMTS 圖層設定
        val tileOverlayOptions = 
                TileOverlayOptions().tileProvider(provider)
        
        // 將圖層加入到圖台上
        return map.addTileOverlay(tileOverlayOptions)
    }
    
    // 以下省略...
}

Google Maps 使用的圖磚預設是 256 x 256 的大小,但官方建議高解析度裝置,可使用 512 x 512 的大小,效果會更好。

而國土測繪所提供的圖磚是 256 的大小,因此在程式碼中設定的是 256 x 256。

另外,如果是要加入 TileOverlay 作為整個圖台的底圖,可以將原本的地圖類型設定為 GoogleMap.MAP_TYPE_NONE,才不會像上方的範例程式,在縮放的時候會看得到預設的 Google 電子地圖。

3. AndroidManifest.xml 設定網路權限

因為圖磚是透過網路服務存取,記得網路權限也要設定。

<manifest>
    <!--   略...   -->
    <uses-permission android:name="android.permission.INTERNET"/>
    
    <!--   略...   -->
</manifest>

4. 載入成功

https://ithelp.ithome.com.tw/upload/images/20230924/20160271jQxrZ7muVF.png

5. 清除 TileOverlay

假設圖層是可以讓使用者切換的,這時候就會需要清除功能。
清除的方式也很簡單,只要對我們剛才建立的 TileOverlay 呼叫 remove() 即可。

wmtsTileOverlay?.remove()

6. TileOverlay 細部調整

TileOverlayOptions 除了 tileProvider 用來設定圖磚來源外,還有幾個方法參數能夠調整圖面的樣式。

  1. fadeIn: 圖層的淡入動畫,預設為開啟。
  2. transparency: 圖層的透明度,範圍值從完全不透明 0.0f 到完全透明 1.0f。適合用在不同資訊圖層的套疊上。
  3. visible: 預設為 true。當設定為 false 時,圖層為不顯示,但設定的屬性等仍存在。
  4. zIndex: 圖層在圖台上疊加的位置,預設為 0 。數字越高的疊在上面,相同數值時則隨機。

7. 清除圖磚快取 clearTileCache()

當圖磚來源有更新時,clearTileCache() 可以強制圖磚重新整理。

小結

以上,就是今天的 WMTS 圖層套疊功能的介紹。

有興趣的朋友,可以再另外套疊看看國土測繪的其他圖磚服務,或是 中央研究院臺灣百年歷史地圖 WMTS 服務來玩玩。

發文數來到第十篇,也代表挑戰已進行了三分之一,繼續努力!

明天見啦~/images/emoticon/emoticon08.gif


上一篇
Day 9: Google Maps SDK for Android-樣式化地圖
下一篇
Day 11: Google Maps SDK for Android–離線圖層套疊 MBTiles
系列文
Google Maps SDK for Android 與 GIS App 開發筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言