---
# System prepended metadata

title: Google Map
tags: [Android, Java]

---

###### tags: `Android` `Java`
# Google Map

## 相機移動到我的位置
我們可以開啟內建按鈕，讓使用者點選按鈕移動到自己位置，或是自製按鈕

### 開啟 Map 內建按鈕
```java=
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    mMap.setMyLocationEnabled(true); //地圖顯示我的位置
    mMap.getUiSettings().setMyLocationButtonEnabled(true); //顯示我的位置的按鈕 預設就打開了
}
```

### 修改 Map 內建按鈕
```java=
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    locationButtonInit();
    mMap.setMyLocationEnabled(true); //地圖顯示我的位置
}

private void locationButtonInit() {
    View mapView = mFragment.getView();
    if (mapView != null && mapView.findViewById(Integer.parseInt("1")) != null) {
        ImageView btn = ((View) mapView.findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
        btn.setImageResource(R.drawable.transport_location_icon);

        int pixels = (int)(40 * getResources().getDisplayMetrics().density);
        btn.setLayoutParams(new RelativeLayout.LayoutParams(pixels, pixels));
        RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) btn.getLayoutParams();
        // position on right bottom
        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT, RelativeLayout.TRUE);
        layoutParams.setMargins(0, 30, 30, 0);
    }
}
```

### 自製按鈕
```java=
mMap.setMyLocationEnabled(true); //地圖顯示我的位置
mMap.getUiSettings().setMyLocationButtonEnabled(false); //關閉內建按鈕
...//自製按鈕，點擊後移動相機到我的位置
```

## 客製化地圖
### 修改 Map UI Style
官方文件最下方還有 UI 介面提供開發者調整並匯出 json 檔
https://developers.google.com/maps/documentation/android-sdk/styling

### 依地區上色
如果要在不同地區上色，可能無法使用 Map
目前查到的方式是用 Google Chart

[How to color countries using google maps?](https://stackoverflow.com/questions/7739830/how-to-color-countries-using-google-maps)

[How to use Google chart API](https://stackoverflow.com/questions/10814142/how-to-use-google-chart-api)

[官方文件](https://developers.google.com/chart/interactive/docs/gallery/geochart)

### HeatMap
熱點地圖
https://developers.google.com/maps/documentation/android-sdk/utility/heatmap

### Marker
https://stackoverflow.com/questions/14811579/how-to-create-a-custom-shaped-bitmap-marker-with-android-map-api-v2

## 資訊視窗
InfoWindow 是地圖 marker 上顯示的小視窗
透過 title、snippet 可以設定內容，也可以客製化自己的 InfoWindow

https://developers.google.com/maps/documentation/android-sdk/infowindows#info_window_events

==客製化的 InfoWindow 內部無法自訂點擊事件==

:::danger
資訊視窗並非實景，而是將檢視畫面算繪為地圖上的圖片。因此，系統會忽略您在檢視畫面中設定的任何事件監聽器，您也無法分辨檢視畫面中各部分的不同點擊事件。既然如此，我們建議您不要在自訂資訊視窗置入互動元件，像是按鈕、核取方塊或文字輸入欄位等。
:::

其他人討論的解決方法
https://stackoverflow.com/questions/14123243/google-maps-android-api-v2-interactive-infowindow-like-in-original-android-go/15040761#15040761

https://stackoverflow.com/questions/20283539/button-onclicklistener-on-infowindow-in-google-map

套件：https://github.com/Appolica/InteractiveInfoWindowAndroid

## 取得使用者目前位置
https://guides.codepath.com/android/Retrieving-Location-with-LocationServices-API

## 兩點之間的距離
使用 Location.distanceBetween()方法
https://ithelp.ithome.com.tw/articles/10129085
```kotlin=
val destination = stages[stageIndex].latLng
val result = FloatArray(1)
Location.distanceBetween(userLatLng.latitude, userLatLng.longitude, destination.latitude, destination.longitude, result)
val distance = result[0].toInt()
```