GeoJSON 是基於 JSON 格式的地理空間資料格式。可用來表示點 (Point)、線(LineString)、多邊形(Polygon)、多個點(MultiPoint)、多個線段(MultiLineString)、多個多邊形(MultiPolygon)。
基本型態大概會長得像下面這個範例一樣:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0,0.5]
},
"properties": {
"prop0": "value0"
}
},
{
"type": "Feature",
"geometry": {
"type": "LineString",
"coordinates": [
[102.0, 0.0],
[103.0, 1.0],
[104.0, 0.0],
[105.0, 1.0]
]
},
"properties": {
"prop0": "value0",
"prop1": 0.0
}
},
{
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
]
]
},
"properties": {
"prop0": "value0",
"prop1": {
"this": "that"
}
}
}
]
}
最外層會是 FeatureCollection,其中的 features 則包裹著不同型態的 Feature。
Feature 中除了有基本的 geometry 負責帶有幾何形狀的空間資訊外,還包含可自定義的 properties。
一個 geometry 一定會有以下這兩個屬性參數:
type: 說明經緯度所代表的幾何圖形 (點、線、面)。
Point、LineString、Polygon
MultiPoint、MultiLineString、MultiPolygon
coordinates: 經緯度座標。接下來我們將使用 g0v/twgeojson 的 twCounty2010.geo.json這份檔案,實際操作一次 GeoJSON 的套疊。

從檔案裡可以看到,每個 feature 都帶有縣市名稱的 property,geometry 中也有寫出它所提供的空間資料屬於 MultiPolygon。
可以參考 Day 19: Maps SDK for Android Utility Library 介紹與環境建置。
GeoJsonLayer讀入 GeoJSON 資料以建立 GeoJsonLayer 的方式可分為兩種:
JSONObject 物件。val geoJsonData: JSONObject? = // 看你的來源是什麼,只要可以轉 JSONObject 就可以了
// 傳入 GoogleMap 物件 與 GeoJSON 資料 建立
val layer = GeoJsonLayer(map, geoJsonData)
raw 資料夾中的檔案,可以直接透過建構式加入。// 傳入 GoogleMap 物件 與 GeoJSON 檔案的 resId 與 Context 建立
val layer = GeoJsonLayer(map, R.raw.geojson_file, context)
assets 資料夾怎麼做?概念上可以使用方法一。
將放置在 assets 資料夾的檔案讀取成 String 再轉成 JSONObject 傳遞給 GeoJsonLayer。
val jsonString = resources.assets.open("twCounty2010.geo.json").bufferedReader().use { it.readText() }
val geoJson = JSONObject(jsonString)
val geoJsonLayer = GeoJsonLayer(map, geoJson)
GeoJsonLayer 加到地圖上這裡的方法跟之前的幾何圖形繪製不太一樣,是呼叫 GeoJsonLayer 的 addLayerToMap() 來實現加入到地圖。
geoJsonLayer.addLayerToMap()

GeoJsonLayer很簡單,呼叫 GeoJsonLayer 的 removeLayerFromMap() 就可以了。
geoJsonLayer.removeLayerFromMap()
GeoJsonFeatureGeoJSON 中的 feature 也可以透過程式另外加入或移除,方法如下:
GeoJsonPoint, GeoJsonLineString, GeoJsonPolygon 等)properties (HashMap)。GeoJsonFeature 的建構式。id 可以視需求命名。GeoJsonFeature 加入到已建立的 GeoJsonLayer。private fun addGeoJsonPointToLayer() {
// 台中中央公園
val centralPark = LatLng(24.1858, 120.6533)
// 建立 GeoJsonPoint
val point = GeoJsonPoint(centralPark)
// 建立 GeoJson 的 Property
val properties = hashMapOf("title" to "Taichung Central Park")
// 建立 Feature
val pointFeature = GeoJsonFeature(point, "test", properties, null)
// 加入到 GeoJson 圖層
geoJsonLayer?.addFeature(pointFeature)
}

如果要移除該 GeoJsonFeature,可以呼叫以下程式碼:
geoJsonLayer.removeFeature(pointFeature)
GeoJsonLayer 上的 GeoFeature要存取已建立的 GeoJsonLayer 中的 GeoFeature 們,可以使用以下方法:
for (feature in layer.features) {
// TODO
}
GeoFeature 下的 Property// 檢查是否有該 Property
if (feature.hasProperty("title")) {
// 存取其 Property
val titleProperty = feature.getProperty("title")
}
GeoJsonLayer 的點擊事件可透過 GeoJsonLayer.OnFeatureClickListener() 來取得,每個 Feature 被點擊時的事件回呼
private fun addFeatureClickListener() {
geoJsonLayer?.setOnFeatureClickListener {feature ->
if (feature.hasProperty("title")) {
val title = feature.getProperty("title")
Toast.makeText(this, title, Toast.LENGTH_SHORT).show()
}
}
}
外觀樣式的調整,可以針對整個 GeoJsonLayer 或是個別的 GeoJsonFeature。
GeoJsonLayer針對整個 GeoJsonLayer,我們可以設定點、線、面的預設外觀樣式。
// 點預設樣式
geoJsonLayer?.defaultPointStyle
// 線預設樣式
geoJsonLayer?.defaultLineStringStyle
// 面預設樣式
geoJsonLayer?.defaultPolygonStyle
透過上述的三種方法,就可以個別取得三種類型的預設樣式。
假設我們要設定該 GeoJsonLayer 的點預設樣式,可以這樣寫。
val pointStyle = layer.defaultPointStyle
// 設定為可拖曳
pointStyle.isDraggable = true
// 預設標題
pointStyle.title = "Hello, World!"
// 預設說明文字
pointStyle.snippet = "I am a draggable marker"
GeoJsonFeature概念上跟針對圖層的調整一樣,只是將 ****Syle 物件設定到指定的物件上。
以前面加入的台中中央公園 Point 來說,我們可以將它的外觀設定為綠色,並顯示標題。
private fun addGeoJsonPointToLayer() {
val centralPark = LatLng(24.1858, 120.6533)
val point = GeoJsonPoint(centralPark)
val properties = hashMapOf("title" to "Taichung Central Park")
val pointFeature = GeoJsonFeature(point, "test", properties, null)
// 自定義的樣式
val pointStyle = GeoJsonPointStyle()
// 改 Icon
pointStyle.icon = BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)
// 標題設為台中中央公園
pointStyle.title = "台中中央公園"
// 將修改完的樣式傳入
pointFeature.pointStyle = pointStyle
geoJsonLayer?.addFeature(pointFeature)
}

以上就是 Google Maps SDK for Android 套疊 GeoJSON 資料的基本介紹,對於文章中的內容有任何問題,歡迎留言討論指教,謝謝大家~
明天見!!![]()