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()
GeoJsonFeature
GeoJSON 中的 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 資料的基本介紹,對於文章中的內容有任何問題,歡迎留言討論指教,謝謝大家~
明天見!!