package Ġde . p 7 2 b . geo . demo . show case Ċ Ċ import Ġandroidx . lifecycle . Lifecycle Observer Ċ import Ġandroidx . lifecycle . Mutable LiveData Ċ import Ġcom . google . android . gms . maps . model . LatLng Ċ import Ġde . p 7 2 b . geo . demo . use case .* Ċ import Ġde . p 7 2 b . geo . demo . util . Base ViewModel Ċ import Ġde . p 7 2 b . geo . demo . util . Converter Helper Ċ import Ġde . p 7 2 b . geo . google . Directions Route Ċ import Ġde . p 7 2 b . geo . util . Unit Locale Ċ import Ġio . reactivex . Scheduler Ċ import Ġio . reactivex . rx kotlin . subscribe By Ċ Ċ class ĠMain ViewModel ( ĊĠĠĠ Ġprivate Ġval Ġmain Thread : ĠScheduler , ĊĠĠĠ Ġprivate Ġval Ġnetwork Thread : ĠScheduler , ĊĠĠĠ Ġprivate Ġval Ġos rm D riving Directions UseCase : ĠOs rm D riving Directions UseCase , ĊĠĠĠ Ġprivate Ġval Ġos rm Walk ing Directions UseCase : ĠOs rm Walk ing Directions UseCase , ĊĠĠĠ Ġprivate Ġval Ġgoogle D riving Directions UseCase : ĠGoogle D riving Directions UseCase , ĊĠĠĠ Ġprivate Ġval Ġgoogle Walk ing Directions UseCase : ĠGoogle Walk ing Directions UseCase Ċ ) Ġ: ĠBase ViewModel (), ĠLifecycle Observer Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠCACHE _ BOX _ HIT _ SIZE _ DEFAULT Ġ= Ġ 1 2 ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠGOOGLE _ SERVICE _ ID Ġ= Ġ" google " ĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠO SR M _ SERVICE _ ID Ġ= Ġ" os rm " ĊĠĠĠĠĠĠĠ Ġval Ġorigin Default Ġ= ĠLat Lng ( 5 2 . 5 3 2 9 7 0 4 , Ġ 1 3 . 3 8 3 2 8 5 1 ) ĊĠĠĠĠĠĠĠ Ġval Ġdestination Default Ġ= ĠLat Lng ( 5 2 . 5 0 7 6 0 6 2 , Ġ 1 3 . 3 6 4 6 3 5 3 ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġval Ġorigin Ġ= ĠMutable LiveData < String >() ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ Ġpost Value ( Converter Helper . lat Lng ToString ( origin Default )) Ġ} ĊĠĠĠ Ġval Ġdestination Ġ= ĠMutable LiveData < String >() ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ Ġpost Value ( Converter Helper . lat Lng ToString ( destination Default )) Ġ} ĊĠĠĠ Ġval Ġbox Hit Cache Size In Met ers Ġ= ĠMutable LiveData < String >() ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ Ġpost Value ( CACHE _ BOX _ HIT _ SIZE _ DEFAULT . toString ()) Ġ} ĊĠĠĠ Ġval Ġos rm Trip Summary Ġ= ĠMutable LiveData < String >() ĊĠĠĠ Ġval Ġgoogle Trip Summary Ġ= ĠMutable LiveData < String >() ĊĠĠĠ Ġval Ġos rm Route Ġ= ĠMutable LiveData < Pair < String , ĠList < LatLng >> >() ĊĠĠĠ Ġval Ġgoogle Route Ġ= ĠMutable LiveData < Pair < String , ĠList < LatLng >> >() ĊĠĠĠ Ġval Ġprogress Active Ġ= ĠMutable LiveData < Boolean >() ĊĠĠĠĠĠĠĠ Ġ. apply Ġ{ Ġpost Value ( false ) Ġ} ĊĠĠĠ Ġprivate Ġvar Ġon Finally Count Ġ= Ġ 0 ĊĊĠĠĠ Ġfun Ġon Walk ing Route Clicked () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Input Valid ()) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġcalculate Walk ing Route ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConverter Helper . string To LatLng ( origin . value !! ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConverter Helper . string To LatLng ( destination . value !! ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠInteger . parseInt ( box Hit Cache Size In Met ers . value !! ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġon D riving Route Clicked () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! is Input Valid ()) Ġreturn ĊĊĠĠĠĠĠĠĠ Ġcalculate D riving Route ( ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConverter Helper . string To LatLng ( origin . value !! ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠConverter Helper . string To LatLng ( destination . value !! ), ĊĠĠĠĠĠĠĠĠĠĠĠ ĠInteger . parseInt ( box Hit Cache Size In Met ers . value !! ) ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġcache Hit Box Size Changed ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġbox Hit Cache Size In Met ers . post Value ( value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġorigin Changed ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġorigin . post Value ( value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġdestination Changed ( value : ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġdestination . post Value ( value ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġis Input Valid (): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( origin . value . isNull OrEmpty ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( destination . value . isNull OrEmpty ()) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġif Ġ( box Hit Cache Size In Met ers . value Ġ== Ġnull ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalculate Walk ing Route ( origin : ĠLat Lng , Ġdestination : ĠLat Lng , Ġcache Hit Size : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprogress Active . post Value ( true ) ĊĠĠĠĠĠĠĠ Ġcall Directions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm Walk ing Directions UseCase , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdestination , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Hit Size , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠO SR M _ SERVICE _ ID , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm Trip Summary , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm Route ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġcall Directions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Walk ing Directions UseCase , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdestination , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Hit Size , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGOOGLE _ SERVICE _ ID , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Trip Summary , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Route ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcalculate D riving Route ( origin : ĠLat Lng , Ġdestination : ĠLat Lng , Ġcache Hit Size : ĠInt ) Ġ{ ĊĠĠĠĠĠĠĠ Ġprogress Active . post Value ( true ) ĊĠĠĠĠĠĠĠ Ġcall Directions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm D riving Directions UseCase , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdestination , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Hit Size , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠO SR M _ SERVICE _ ID , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm Trip Summary , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġos rm Route ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġcall Directions ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle D riving Directions UseCase , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġorigin , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdestination , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcache Hit Size , ĊĠĠĠĠĠĠĠĠĠĠĠ ĠGOOGLE _ SERVICE _ ID , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Trip Summary , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgoogle Route ĊĠĠĠĠĠĠĠ Ġ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġcall Directions ( ĊĠĠĠĠĠĠĠ Ġuse Case : ĠDirection s UseCase , ĊĠĠĠĠĠĠĠ Ġorigin : ĠLat Lng , ĊĠĠĠĠĠĠĠ Ġdestination : ĠLat Lng , ĊĠĠĠĠĠĠĠ Ġcache Hit Size : ĠInt , ĊĠĠĠĠĠĠĠ Ġservice Result Name : ĠString , ĊĠĠĠĠĠĠĠ Ġsummary : ĠMutable LiveData < String >, ĊĠĠĠĠĠĠĠ Ġroute : ĠMutable LiveData < Pair < String , ĠList < LatLng >>> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġuse Case . invoke ( origin , Ġdestination , Ġcache Hit Size , Ġcache Hit Size ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe On ( network Thread ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. observe On ( main Thread ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. do Finally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdo On Finally () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ. subscribe By ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonError Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . out . println (" ERROR Ġ$ it ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}, ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠonSuccess Ġ= Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġhandle Directions Result ( service Result Name , Ġit , Ġsummary , Ġroute ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ). auto Dispose () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġdo On Finally () Ġ{ ĊĠĠĠĠĠĠĠ Ġon Finally Count ++ ĊĠĠĠĠĠĠĠ Ġif Ġ( on Finally Count Ġ< Ġ 2 ) Ġreturn ĊĠĠĠĠĠĠĠ Ġon Finally Count Ġ= Ġ 0 ĊĠĠĠĠĠĠĠ Ġprogress Active . post Value ( false ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġhandle Directions Result ( ĊĠĠĠĠĠĠĠ Ġservice Result Name : ĠString , ĊĠĠĠĠĠĠĠ Ġresult : ĠDirection s Route ?, ĊĠĠĠĠĠĠĠ Ġsummary : ĠMutable LiveData < String >, ĊĠĠĠĠĠĠĠ Ġroute : ĠMutable LiveData < Pair < String , ĠList < LatLng >>> ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġresult ?. let Ġ{ Ġdirections Route Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdirections Route . poly Line ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( route . value ?. first Ġ!= Ġit . points ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġroute . post Value ( Pair ( it . points , Ġit . decode Path ())) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdistance Ġ= Ġdirections Route . get Distance ?. in Met ers Ġ?: Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġduration Ġ= Ġdirections Route . get Duration ?. in Seconds Ġ?: Ġ 0 L ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( distance Ġ> Ġ 0 L Ġ&& Ġduration Ġ> Ġ 0 L ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsummary . post Value ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ service Result Name : Ġ${ duration Ġ/ Ġ 6 0 } ĠMin . Ġ(${ Unit Locale . default . from Met ers ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdistance ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) })" ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġsummary . post Value ("") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ }