[Android]GoogleMap上ランドマークタップして建物情報を取得


# GoogleMap上ランドマークタップして建物情報を取得

以下の手順となります。
・ランドマークタップイベントを取得
・Google Map SDKからデリゲートを通してPlaceIDを取得する
・PlaceIDを使ってplace/details API 実行して情報取得

## ランドマークタップイベントを取得

GoogleMap.OnPoiClickListenerをextends する

```
class MapsActivity : AppCompatActivity(), GoogleMap.OnPoiClickListener {
mMap.setOnPoiClickListener(this@MapsActivity)
```

## Google Map SDKからデリゲートを通してPlaceIDを取得する

```
override fun onPoiClick(landmark: PointOfInterest?) {
    var placeIdLandMark = landmark!!.placeId
```

## PlaceIDを使ってplace/details API 実行して情報取得
https://maps.googleapis.com/maps/api/place/details/json?

```
  placeIdLandMark?.let {
        getBuildingInfo(
            it,
            { buildingInfo: List<BuildingInfo?> ->

            }, { errorMessage: String ->

            })
    }
```

```
data class BuildingInfo(
    @SerializedName("html_attributions")
    var htmlAttributions: List<Any?>?,
    @SerializedName("result")
    var result: BuildingResult?,
    @SerializedName("status")
    var status: String?
)
```

```
 fun getBuildingInfo(placeId: String, onSuccess: (List<BuildingInfo?>) -> Unit, onError: (String) -> Unit) {
        GlobalScope.launch(Dispatchers.Main) {
            placeId?.let {
                var (response, errorMsg) = fetchBuildingInfo(placeId)
                if (errorMsg.equals("err")) {
                    onError(errorMsg)
                } else {
                    onSuccess(response)
                }
            } ?: run {
            }
        }
    }
```

```
suspend fun fetchBuildingInfo(placeId:String): HttpResponse<List<BuildingInfo?>,String>  {
        var building_info : List<BuildingInfo?> = ArrayList()
        var errMsg : String  = ""
        try {
            val primaryNewsResponse = callBuildingInfoAsync(BuildConfig.GOOGLE_API_KEY,placeId)
            if (primaryNewsResponse.isSuccessful) {
                building_info = listOf(primaryNewsResponse!!.body())
            } else {
                errMsg = "err"
                //Handle unsuccessful response
            }
        } catch (e: Exception) {
            e.printStackTrace()
            errMsg = "err"
            //Handle error
        }
        return HttpResponse(building_info,errMsg)
    }
```

```
var api = Service()
suspend fun callBuildingInfoAsync(key:String,placeId: String):Response<BuildingInfo?> = api.getBuildingInfo(key, placeId,"ja")
```

```
class AtisService {
    private val buildingInfoApi:BuildingInfoInterface

    init {
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
        val retrofitmapplace = Retrofit.Builder()
            .baseUrl("https://maps.googleapis.com/maps/api/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        
        buildingInfoApi = retrofitmapplace.create(BuildingInfoInterface::class.java)
    }

    suspend fun getBuildingInfo(key: String, placeId: String,language: String):Response<BuildingInfo?> {
        return buildingInfoApi.getBuildingInfo(key, placeId, language)
    }
}
```

```
interface BuildingInfoInterface {
    @Headers("Content-Type: application/json;charset=UTF-8")
    @GET("/place/details/json?")
    suspend fun getBuildingInfo(
        @Query("key") key: String,
        @Query("placeid") placeid: String,
        @Query("language") language: String
    ): Response<BuildingInfo?>
}
```

ログ結果

```BuildingResult(

addressComponents=
	[AddressComponent(longName=８, shortName=８, types=[premise]),
	AddressComponent(longName=２, shortName=２, types=[sublocality_level_4, sublocality, political]), 
	AddressComponent(longName=４丁目, shortName=４丁目, types=[sublocality_level_3, sublocality, political]), 
	AddressComponent(longName=芝公園, shortName=芝公園, types=[sublocality_level_2, sublocality, political]), 
	AddressComponent(longName=港区, shortName=港区, types=[locality, political]), 
	AddressComponent(longName=東京都, shortName=東京都, types=[administrative_area_level_1, political]), 
	AddressComponent(longName=日本, shortName=JP, types=[country, political]), 
	AddressComponent(longName=105-0011, shortName=105-0011, types=[postal_code])], 
	adrAddress=<span class="country-name">日本</span>、
				<span class="postal-code">〒105-0011</span>
				<span class="region">東京都</span>
				<span class="street-address">港区芝公園４丁目２−８</span>, 
				formattedAddress=日本、〒105-0011 東京都港区芝公園４丁目２−８,
				formattedPhoneNumber=03-3433-5111, 
				geometry=Geometry(location=Location(lat=35.6585805, lng=139.7454329), 
				viewport=Viewport(northeast=BuildingNortheast(lat=35.6602786302915, lng=139.7469706802915),
				southwest=BuildingSouthwest(lat=35.6575806697085, lng=139.7442727197085))), 
				icon=https://maps.gstatic.com/mapfiles/place_api/icons/geocode-71.png, 
				id=0f193d8a0df922a2bcb369673944240a8cb182c3, 
				internationalPhoneNumber=+81 3-3433-5111, 				name=東京タワー, 
				openingHours=OpeningHours(openNow=true, periods=[Period(open=Open(day=0, time=0900), 
				close=Close(day=0, time=2300)), 
				Period(open=Open(day=1, time=0900), 
				close=Close(day=1, time=2300)), 
				Period(open=Open(day=2, time=0900), 
				close=Close(day=2, time=2300)), 
				Period(open=Open(day=3, time=0900), 
				close=Close(day=3, time=2300)), 
				Period(open=Open(day=4, time=0900), 
				close=Close(day=4, time=2300)), 
				Period(open=Open(day=5, time=0900),
				close=Close(day=5, time=2300)),
				Period(open=Open(day=6, time=0900), 
				close=Close(day=6, time=2300))],
				weekdayText=[月曜日: 9時00分～23時00分, 
				火曜日: 9時00分～23時00分, 水曜日: 9時00分～23時00分, 
				木曜日: 9時00分～23時00分, 金曜日: 9時00分～23時00分, 
				土曜日: 9時00分～23時00分, 日曜日: 9時00分～23時00分]), 
				photos=[
					Photo(height=3265, 
						htmlAttributions=[<a href="https://maps.google.com/maps/contrib/107957051173910448327">David Sun</a>],
						photoReference=CmRaAAAAM6U-kUOZ92TO4xvlCB1az-Poru6I6dJxL0I76k7Mf8WBJJnKQKMGMhTXGJpZbvvjFb3r-SECxmFzh8TK3mffPQ7m6m7ynaMyVagMI5Pt8nAlbaFDnfAmLEHEfTylt7G1EhBHFzGCFNz6mzFMI-								ACmma7GhR4VVV5WfH4kLnNxecXAmRsfXPYKQ, width=4898), Photo(height=3024, 						htmlAttributions=[<a href="https://maps.google.com/maps/contrib/107143984355792935176">Hiroto Okada</a>], 
						photoReference=CmRaAAAA_EvQ65Svj1tcm9-WAlJ4gZGCXn_5yL5ZUb2mn5bRYv7yqk25hDf6ho-sUwFIipOa7rOntO2XlyjTh-wZ7NLza4ElAF7H_R8bbU8-								JhSMTXwbqVxWn1oybUoqr2IPxysoEhDHADb2YFsZwkfGt_ijCJx9GhRktKao_xg4r8Xg6RSZ3u7lgILUyA, width=4032), 

					Photo(height=3648, 
						htmlAttributions=[<a href="https://maps.google.com/maps/contrib/112380757976351936951">Alex Lin</a>], 						photoReference=CmRaAAAALkL3oSyRYYGBxg6Kr9v5OR7yKWC6NsV0qRj_ckoi4gu05Zz0ptmrD5h6WcSYL0TKfIYogfotJ7BH0hBwSmdUwwKr1bOjHqk1zFxz4Roc9F5dZQjnosLhzv-								Q9uKzCipGEhDvFijq1Af4AVBGz_4X0wXAGhTxzekrMh2xSTeAmhTTFFJruZm3Lw, width=2736), Photo(height=2448, htmlAttributions=[<a href="https://maps.google.com/maps/contrib/107563570268866137064">王小民</a>], 						photoReference=CmRaAAAA6j1SX0QHReoxHoJitVTK-								BMdDkF89OEgrPqi4Ul1wRkYKSoAocnXufcZ_uWbNvUBdma-80vwXrmssDwbIQjA4YEWANabVn8AG2Kd1V6yxxkDA8I7dj1jEQ9EmNsK6CREEhCCpCHKntDeUarpKvbiTMZEGhQ6yPO6PTw-fQ6sqWe6I9ylyr7G-g, 						width=3264), 

					Photo(height=3376, 
						htmlAttributions=[<a href="https://maps.google.com/maps/contrib/113713956430187611308">Masa Tanahashi</a>], 						photoReference=CmRaAAAABEwoYVdyVJa1yWYq7n1rU2oSX6bU64zfnsAgnFWNImWQUdjMlMdkjHwGd8ORtJ82UX3R_hqtFrY5-						Nqj2FVtHNvPny3d6PNN8GF3qFuTM23Q1kIcPM6fdKoZcxRKChovEhC6ecqXVnVkBMYG0xsby3TmGhSFbXQ5VbVOkMbdCOPmNJudDfQ4NQ, width=6000), 
				
```