[Android]GoogleMap でスタートとエンドマーカーの線を引く


# GoogleMap でスタートとエンドマーカーの線を引く

以下の手順となります。
・スタートとエンドマーカー作る
・Directions API実行
・polylines 作る
## スタートとエンドマーカー作る
[Google Map でピン立てる](https://qiita.com/myatthinkyu/items/6563ae9c53f7cfd14301)
## Directions API実行
https://maps.googleapis.com/maps/api/directions/json

```
interface DirectionsInterface {
    @Headers("Content-Type: application/json;charset=UTF-8")
    @GET("maps/api/directions/json?")
    suspend fun getDirections(
        @Query("destination") destination: String,
        @Query("key") key: String,
        @Query("mode") mode: String,
        @Query("origin") origin: String,
        @Query("language") language: String
    ): Response<Directions?>
}
```

```
private val directionsApi:DirectionsInterface
directionsApi = retrofitdirections.create(DirectionsInterface::class.java)
suspend fun getDirections(destination: String, key:String, mode:String, origin:String, language: String): Response<Directions?>  {
        return directionsApi.getDirections(destination,key,mode,origin,language)
    }

```


```
data class Directions(
    @SerializedName("geocoded_waypoints")
    var geocodedWaypoints: List<GeocodedWaypoint?>?,
    @SerializedName("routes")
    var routes: List<Route?>?,
    @SerializedName("status")
    var status: String?
)
```

```
 var api = Service()

suspend fun　callDirectionsAsync(destination:String,key:String,mode:String,origin:String): Response<Directions?>  = api.getDirections(destination,key,mode,origin,"ja")
```

```
class Service {
    private val directionsApi: DirectionsInterface
    init {
        val interceptor = HttpLoggingInterceptor()
        interceptor.level = HttpLoggingInterceptor.Level.BODY
        val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
        val retrofitdirections = Retrofit.Builder()
            .baseUrl("https://maps.googleapis.com/")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
        directionsApi = retrofitdirections.create(DirectionsInterface::class.java)
    }
}
```

```
    suspend fun fetchDirections (destination:String,key:String,mode:String,origin:String) : HttpResponse<List<Directions?>,String> {
        var directions : List<Directions?> = ArrayList()
        var errMsg : String  = ""
        try {
            val primaryNewsResponse = callDirectionsAsync(destination,key,mode,origin)
                if (primaryNewsResponse.isSuccessful) {
                    directions = listOf(primaryNewsResponse!!.body())
                    
                } else {
                    errMsg = "err"
                }
        } catch (e: Exception) {
            e.printStackTrace()
            errMsg = "err"
        }
        return HttpResponse(directions,errMsg)
    }
```


```
fun getDirections(origin: Marker, destination: Marker, mode: String, 
        onSuccess: (List<Directions?>) -> Unit,
        onError: (String) -> Unit
    ) {
        GlobalScope.launch(Dispatchers.Main) {
            var originPosition = origin.position
            var originlat = originPosition!!.latitude.toString()
            var originlon = originPosition!!.longitude.toString()
            var origin = originlat + "," + originlon
            var destinationPosition = destination.position
            var destinationlat = destinationPosition!!.latitude.toString()
            var destinationlon = destinationPosition!!.longitude.toString()
            var destination = destinationlat + "," + destinationlon
            var (response, errorMsg) = pinViewModel.fetchDirections(
                origin,
                BuildConfig.GOOGLE_API_KEY,
                mode,
                destination
            )
            if (errorMsg.equals("err")) {
                onError(errorMsg)
            } else {
                onSuccess(response)
            }
        }
    }
```

## polylines 作る


```
private var polyline: Polyline? = null
private var polylines: ArrayList<Polyline>? = arrayListOf()
fun drawPolyline(origin: Marker, destination: Marker) {
mMap.setOnMapClickListener{ null }
        Durattion = 0

        //エンドマーカーとスタートマーカーが存在するか調べる
        if (origin == null || destination == null) {
            return
        }

        //アプリは今までのポリラインを消去する。
        if (polylines != null) {
            polylines!!.forEach {
                it.remove()
            }
        }

        var builder = LatLngBounds.Builder()

        builder.include(origin!!.getPosition())
        builder.include(destination!!.getPosition())
        
        var polylinePointInfo: ArrayList<String>? = ArrayList()
        var path: MutableList<List<LatLng>> = ArrayList()
        var duration: Int?

        var mode = ""

        if(carFlg) {
            mode = "driving"
        }
        if(walkFlg){
            mode = "walking"
        }
        //アプリは行き方情報を取得する
        getDirections(
            origin!!, destination!!, mode,
            { directions: List<Directions?> ->
                mMap.setOnMapClickListener { this }
                Durattion = 0
                
                for (route in directions) {

                    for (leg in route?.routes!!) {
                        val LegList = leg!!.legs
                        //videosMarkerList.add(point_marker)
                        for (leg in LegList!!) {
                            val stepList = leg!!.steps

                            for (step in stepList!!) {
                                val points = step!!.polyline!!.points
                                duration = step.duration!!.value
                                polylinePointInfo!!.add(points.toString())
                                path.add(PolyUtil.decode(points))

                            }
                        }
                    }

                }
                polylines = arrayListOf()
                for (i in 0 until path.size) {
                    polyline = mMap!!.addPolyline(PolylineOptions().addAll(path[i]).color(Color.CYAN).width(20F))
                    polylines!!.add(polyline!!)
                }
            },
            { errorMessage: String ->

                mMap.setOnMapClickListener { this }
            })
}
```

![polyline_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618722/af168e86-cb05-3c2c-00c8-bd191541b79d.png)