diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index e605b1c..c173508 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 681f41a..7643783 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,6 +1,10 @@
+
+
+
+
@@ -112,5 +116,8 @@
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index 61a9130..fb7f4a8 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 4e6b049..40d2787 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -6,6 +6,7 @@
+
-
+
diff --git a/app/build.gradle b/app/build.gradle
index 3b019c9..a0875ae 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,4 +32,6 @@ dependencies {
implementation project(':easywaylocation')
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ implementation 'com.google.maps.android:android-maps-utils:0.6.2'
+
}
diff --git a/app/src/main/java/com/example/prabhat/locationsample/CustomInfoWindowForGoogleMap.kt b/app/src/main/java/com/example/prabhat/locationsample/CustomInfoWindowForGoogleMap.kt
new file mode 100644
index 0000000..bebcf38
--- /dev/null
+++ b/app/src/main/java/com/example/prabhat/locationsample/CustomInfoWindowForGoogleMap.kt
@@ -0,0 +1,51 @@
+package com.example.prabhat.locationsample
+
+import android.app.Activity
+import android.content.Context
+import android.view.View
+import android.widget.TextView
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.model.Marker
+import org.json.JSONObject
+import java.lang.Exception
+import java.text.DecimalFormat
+
+class CustomInfoWindowForGoogleMap(context: Context): GoogleMap.InfoWindowAdapter {
+ private val df: DecimalFormat = DecimalFormat("0.00")
+
+ var mWindow = (context as Activity).layoutInflater.inflate(R.layout.marker_window, null)
+
+
+ override fun getInfoWindow(p0: Marker?): View {
+ render(p0, mWindow)
+ return mWindow
+ }
+
+ override fun getInfoContents(p0: Marker?): View {
+ render(p0, mWindow)
+ return mWindow
+ }
+
+ private fun render(marker: Marker?, mWindow: View) {
+
+ val title = mWindow.findViewById(R.id.textView)
+ val time = mWindow.findViewById(R.id.textView2)
+ val distance = mWindow.findViewById(R.id.textView3)
+ try {
+ val json = JSONObject(marker?.title)
+ title.text = json.getString("placeSummary")
+ if (json.getString("time").isNotEmpty()){
+ time.visibility = View.VISIBLE
+ distance.visibility = View.VISIBLE
+ time.text = df.format(json.getString("timeFromPrevPoint").toDouble()/60) + " sec"
+ distance.text = df.format(json.getString("distanceFromPrevPoint").toDouble()/1609.344)+" mile"
+ }else{
+ time.visibility = View.GONE
+ distance.visibility = View.GONE
+ }
+ }catch (e:Exception){
+ e.printStackTrace()
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/prabhat/locationsample/MapsActivity.kt b/app/src/main/java/com/example/prabhat/locationsample/MapsActivity.kt
index fee933e..0155318 100644
--- a/app/src/main/java/com/example/prabhat/locationsample/MapsActivity.kt
+++ b/app/src/main/java/com/example/prabhat/locationsample/MapsActivity.kt
@@ -1,9 +1,9 @@
package com.example.prabhat.locationsample
-import android.graphics.Color
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
import android.os.Bundle
import android.os.Handler
-import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.easywaylocation.draw_path.DirectionUtil
import com.example.easywaylocation.draw_path.PolyLineDataBean
@@ -11,21 +11,58 @@ import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
+import com.google.android.gms.maps.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
-import com.google.android.gms.maps.model.PolylineOptions
+import com.google.android.gms.maps.model.MarkerOptions
+import com.google.maps.android.SphericalUtil
+import kotlinx.android.synthetic.main.activity_maps.*
class MapsActivity : AppCompatActivity(), OnMapReadyCallback, DirectionUtil.DirectionCallBack {
+ lateinit var polyLineDetails:HashMap
+ lateinit var directionUtil: DirectionUtil
+
companion object{
val WAY_POINT_TAG = "way_point_tag"
val ARC_POINT_TAG = "arc_point_tag"
+ val waypoint1 = LatLng(37.423669, -122.090168)
+ val waypoint2 = LatLng(37.420930, -122.085362)
+ val origin = LatLng(37.421481, -122.092156)
+ val destination = LatLng(37.421519, -122.086809)
+
+ val markerOptionsOrigin = MarkerOptions()
+ val markerOptionsDestination = MarkerOptions()
+
+ }
+
+ override fun pathFindFinish(
+ polyLineDetails: HashMap,
+ polyLineDetailsArray: ArrayList
+ ) {
+ this.polyLineDetails = polyLineDetails
+ mMap.clear()
+ initAllMarker(polyLineDetailsArray)
+ mMap.addMarker(markerOptionsOrigin)
+ directionUtil.drawPath(WAY_POINT_TAG)
}
- override fun pathFindFinish(polyLineDetails: HashMap) {
- for (i in polyLineDetails.keys){
- Log.v("sample", polyLineDetails[i]?.time)
- }
+ private fun initAllMarker(polyLineDetails: ArrayList) {
+ markerOptionsOrigin.icon(BitmapDescriptorFactory.fromBitmap(getIcon(R.drawable.car_icon)));
+ markerOptionsOrigin.rotation(SphericalUtil.computeHeading(origin, waypoint1).toFloat())
+
+ for (data in polyLineDetails){
+ data.position?.let {
+ val markerOptionswayPoint = MarkerOptions()
+ markerOptionswayPoint.position(data.position!!)
+ markerOptionswayPoint.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin));
+ markerOptionswayPoint.title(data.toJson().toString())
+ mMap.addMarker(markerOptionswayPoint)
+
+ }
+
+ }
+
}
private lateinit var mMap: GoogleMap
@@ -42,30 +79,68 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback, DirectionUtil.Dire
override fun onMapReady(googleMap: GoogleMap) {
mMap = googleMap
+ val markerInfoWindowAdapter = CustomInfoWindowForGoogleMap(this)
+ googleMap.setInfoWindowAdapter(markerInfoWindowAdapter)
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(LatLng(37.423669, -122.090168), 16F))
- wayPoints.add(LatLng(37.423669, -122.090168))
- wayPoints.add(LatLng(37.420930, -122.085362))
- val directionUtil = DirectionUtil.Builder()
- .setDirectionKey("xyz")
- .setOrigin(LatLng(37.421481, -122.092156))
- .setWayPoints(wayPoints)
- .setGoogleMap(mMap)
- .setPolyLinePrimaryColor(R.color.black)
- .setPolyLineWidth(5)
- .setPathAnimation(true)
- .setCallback(this)
- .setPolylineTag(WAY_POINT_TAG)
- .setDestination(LatLng(37.421519, -122.086809))
- .build()
-
- directionUtil.drawPath()
- directionUtil.drawArcDirection(LatLng(37.421481, -122.092156),LatLng(37.421519, -122.086809),0.5,ARC_POINT_TAG)
- Handler().postDelayed({ directionUtil.clearPolyline(WAY_POINT_TAG) }, 3000)
-
- Handler().postDelayed({ directionUtil.clearPolyline(ARC_POINT_TAG) }, 6000)
+ wayPoints.add(waypoint1)
+ wayPoints.add(waypoint2)
+ directionUtil = DirectionUtil.Builder()
+ .setDirectionKey("xyz")
+ .setOrigin(origin)
+ .setWayPoints(wayPoints)
+ .setGoogleMap(mMap)
+ .setPathAnimation(true)
+ .setPolyLineWidth(5)
+ .setCallback(this)
+ .setDestination(destination)
+ .build()
+
+ val bean = PolyLineDataBean().also {
+ it.placeSummary = "Origin"
+ }
+ val bean2 = PolyLineDataBean().also {
+ it.placeSummary = "destination"
+ }
+ markerOptionsOrigin.position(origin)
+ markerOptionsOrigin.icon(BitmapDescriptorFactory.fromBitmap(getIcon(R.drawable.map_pin)));
+ markerOptionsOrigin.title(bean.toJson().toString())
+
+ val data = directionUtil.getShortestPathDetails(origin, destination)
+
+ markerOptionsDestination.position(destination)
+ markerOptionsDestination.icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin));
+ markerOptionsDestination.title(data.toJson().toString())
+
+ directionUtil.drawArcDirection(origin, destination, 0.5, ARC_POINT_TAG)
+ mMap.addMarker(markerOptionsOrigin).tag = "origin"
+ mMap.addMarker(markerOptionsDestination)
+
+ button2.setOnClickListener {
+ directionUtil.clearPolyline(ARC_POINT_TAG)
+ directionUtil.initPath()
+ Handler().postDelayed({
+ try {
+ directionUtil.clearPolyline(WAY_POINT_TAG)
+ directionUtil.serOrigin(LatLng(37.422404, -122.091699),wayPoints)
+ directionUtil.setPathAnimation(false)
+ directionUtil.initPath()
+ }catch (erro:Exception){
+
+ }
+ },5000)
+ button2.text = "Complete Ride"
+ }
}
+ fun getIcon(id:Int):Bitmap{
+ val height = 100
+ val width = 100
+ val bitmapdraw: BitmapDrawable = resources.getDrawable(id) as BitmapDrawable
+ val b: Bitmap = bitmapdraw.getBitmap()
+ return Bitmap.createScaledBitmap(b, width, height, false)
+ }
+
}
diff --git a/app/src/main/res/drawable/car_icon.png b/app/src/main/res/drawable/car_icon.png
new file mode 100644
index 0000000..f1f1a1a
Binary files /dev/null and b/app/src/main/res/drawable/car_icon.png differ
diff --git a/app/src/main/res/drawable/map_pin.png b/app/src/main/res/drawable/map_pin.png
new file mode 100644
index 0000000..bb87086
Binary files /dev/null and b/app/src/main/res/drawable/map_pin.png differ
diff --git a/app/src/main/res/layout/activity_maps.xml b/app/src/main/res/layout/activity_maps.xml
index 4d0590c..266c700 100644
--- a/app/src/main/res/layout/activity_maps.xml
+++ b/app/src/main/res/layout/activity_maps.xml
@@ -1,8 +1,38 @@
-
\ No newline at end of file
+ xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/marker_window.xml b/app/src/main/res/layout/marker_window.xml
new file mode 100644
index 0000000..ffe62cf
--- /dev/null
+++ b/app/src/main/res/layout/marker_window.xml
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/DirectionUtil.kt b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/DirectionUtil.kt
index 3cd5bc1..955d50c 100644
--- a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/DirectionUtil.kt
+++ b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/DirectionUtil.kt
@@ -1,13 +1,13 @@
package com.example.easywaylocation.draw_path
import android.graphics.Color
-import android.util.Log
import androidx.annotation.ColorRes
import androidx.annotation.IntegerRes
import com.example.easywaylocation.Logger
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.JointType
import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Polyline
import com.google.android.gms.maps.model.PolylineOptions
import com.google.maps.android.SphericalUtil
import kotlinx.coroutines.*
@@ -23,12 +23,11 @@ class DirectionUtil private constructor(builder: Builder) {
private val allPathPoints:ArrayList = ArrayList()
private var mMap: GoogleMap?
private var directionKey: String?
- val TAG = "Draw path -->"
+ private val TAG = "Draw path -->"
private var wayPoints = ArrayList()
private var origin: LatLng?
private var destination: LatLng?
private var polyLineWidth = 10
- private var mTag:String
private var pathAnimation:Boolean
private var polyLinePrimaryColor:Int = 0
private var polyLineSecondaryColor = 0
@@ -36,15 +35,15 @@ class DirectionUtil private constructor(builder: Builder) {
private var pathCompletionTime = 2500
private var pathColorFillAnimationTime = 1800
private var polyLineDetails:HashMap = HashMap()
+ private var polyLineDetailsArray:ArrayList = ArrayList()
private var polyLineDataBean = PolyLineDataBean()
-
+ private var arrayOfPoints: ArrayList> = ArrayList()
private var primaryLineCompletionTime = 2000
private var animationDelay = 200
- private var polylineMap:HashMap = HashMap()
+ private var polylineMap:HashMap = HashMap()
init {
- this.mTag = builder.mTag
this.directionCallBack = builder.directionCallBack
this.destination = builder.destination
this.directionKey = builder.key
@@ -69,15 +68,37 @@ class DirectionUtil private constructor(builder: Builder) {
this.animationDelay = builder.animationDelay
}
+ fun setPathAnimation(boolean:Boolean) = apply { this.pathAnimation = boolean }
+
+ fun setCompletionTime(@IntegerRes time: Int) = apply { this.pathCompletionTime = time }
+
+ fun setColorFillCompletion(@IntegerRes time: Int) = apply { this.pathColorFillAnimationTime = time }
+
+ fun setPrimaryLineCompletion(@IntegerRes time: Int) = apply { this.primaryLineCompletionTime = time }
+
+ fun setDelayTime(@IntegerRes time: Int) = apply { this.animationDelay = time }
+
+ fun setPolyLineWidth(polyLineWidth: Int) {
+ this.polyLineWidth = polyLineWidth
+ }
+
+ fun setPolyLinePrimaryColor(@ColorRes color: Int) {
+ this.polyLinePrimaryColor = color
+ }
+
+ fun setPolyLineSecondaryColor(@ColorRes color: Int) {
+ this.polyLineSecondaryColor = color
+ }
+
@Throws(Exception::class)
- fun drawPath() {
+ fun initPath() {
if (directionKey.isNullOrBlank()) {
throw Exception("Direction directionKey is not valid")
}
if (allPathPoints.isNotEmpty()){
allPathPoints.clear()
+ polyLineDetailsArray.clear()
}
-
origin?.let { org ->
destination?.let { des ->
wayPoints.add(0, org)
@@ -87,11 +108,9 @@ class DirectionUtil private constructor(builder: Builder) {
if (i == wayPoints.size - 1) {
isEnd = true
}
- val url = getUrl(wayPoints[i - 1], wayPoints[i])
- val data = async(Dispatchers.IO + downloadDataFromUrlException) { downloadUrl(url) }
+ val data = downlaodDataFromUrl(wayPoints[i - 1],wayPoints[i],i)
Logger.LogDebug(TAG,data.await())
- val parseData = async(Dispatchers.IO + parseDataFromUrlException) { doParsingWork(data.await()) }
- drawData(parseData.await(),i)
+ drawData(parseDownloadedData(data.await(),i).await(),i)
}
}
@@ -102,29 +121,57 @@ class DirectionUtil private constructor(builder: Builder) {
} ?: kotlin.run {
throw Exception("Make sure Origin not null")
}
+ }
+ private fun downlaodDataFromUrl(o:LatLng,d:LatLng,i:Int):Deferred = runBlocking {
+ val url = getUrl(o, d)
+ Logger.LogInfo("$TAG url $i", url)
+ async(Dispatchers.IO + downloadDataFromUrlException) { downloadUrl(url) }
+ }
+ private fun parseDownloadedData(data:String,i:Int):Deferred>> > = runBlocking {
+ async(Dispatchers.IO + parseDataFromUrlException) { doParsingWork(data,wayPoints[i]) }
}
- val downloadDataFromUrlException = CoroutineExceptionHandler { _, exception ->
+ fun getShortestPathDetails(origin:LatLng, destination: LatLng):PolyLineDataBean = runBlocking{
+ val data = downlaodDataFromUrl(origin,destination,0)
+ val jObject = JSONObject(data.await())
+ Logger.LogInfo(TAG,jObject.toString())
+ val parser = DataParser()
+ parser.parse(jObject)
+ parser.polyLineDataBean.apply {
+ this.position = destination
+ this.distanceFromPrevPoint = this.distance
+ this.timeFromPrevPoint = this.time
+ }
+ }
+
+ private val downloadDataFromUrlException = CoroutineExceptionHandler { _, exception ->
exception.message?.let {
Logger.LogDebug(TAG, "${it}")
}
}
- val parseDataFromUrlException = CoroutineExceptionHandler { _, exception ->
+ private val parseDataFromUrlException = CoroutineExceptionHandler { _, exception ->
exception.message?.let {
Logger.LogDebug(TAG, "${it}")
}
}
- val mainException = CoroutineExceptionHandler { _, exception ->
+ private val mainException = CoroutineExceptionHandler { _, exception ->
exception.message?.let {
Logger.LogDebug(TAG, "${it} Please check your internet Connection.")
}
}
+ fun serOrigin(latLng: LatLng, wayPoint: ArrayList){
+ this.origin = latLng
+ this.wayPoints.clear()
+ this.wayPoints = ArrayList(wayPoint)
+ }
+
private fun drawData(result: List>>, pathIncrementer: Int) {
+ arrayOfPoints.clear();
var points: ArrayList
val lineOptions = PolylineOptions()
@@ -146,49 +193,72 @@ class DirectionUtil private constructor(builder: Builder) {
points.add(position)
allPathPoints.add(position)
- }
-
- // Adding all the points in the route to LineOptions
- lineOptions.addAll(points)
- lineOptions.jointType(JointType.ROUND)
- lineOptions.width(polyLineWidth.toFloat())
- lineOptions.clickable(true)
- Logger.LogInfo(TAG,"onPostExecute lineoptions decoded")
+ arrayOfPoints.add(allPathPoints)
- }
- // Drawing polyline in the Google Map for the i-th route
- if (!pathAnimation){
- val polyLine = mMap?.addPolyline(lineOptions)
-// polyLine?.tag = getTag()
+ }
}
polyLineDetails["path$pathIncrementer"] = polyLineDataBean
+ polyLineDetailsArray.add(polyLineDataBean)
if (isEnd) {
- directionCallBack?.pathFindFinish(polyLineDetails)
+ updatePathDetails(polyLineDetails)
+ directionCallBack?.pathFindFinish(polyLineDetails,polyLineDetailsArray)
isEnd = false
- if (pathAnimation){
- mMap?.let {
- val mapAnimator = MapAnimator()
- mapAnimator.setColorFillCompletion(pathColorFillAnimationTime)
- mapAnimator.setDelayTime(animationDelay)
- mapAnimator.setPrimaryLineColor(polyLinePrimaryColor)
- mapAnimator.setSecondaryLineColor(polyLineSecondaryColor)
- mapAnimator.setCompletionTime(pathCompletionTime)
- mapAnimator.setPrimaryLineCompletion(primaryLineCompletionTime)
- mapAnimator.animateRoute(it, allPathPoints,polyLineDataBean)
- polylineMap.put(mTag,mapAnimator)
- }
+ }
+ }
+
+ private fun updatePathDetails(polyLineDetails: java.util.HashMap) {
+ val size = polyLineDetails.size
+ if (size == 1) return
+ var pathIncrementer = 1;
+ while (pathIncrementer <= size){
+ polyLineDetails["path${pathIncrementer}"]?.timeFromPrevPoint = ((polyLineDetails["path${pathIncrementer-1}"]?.timeFromPrevPoint?.toDouble() ?: 0.0) + (polyLineDetails["path${pathIncrementer}"]?.time?.toDouble()
+ ?: 0.0)).toString()
+ polyLineDetails["path${pathIncrementer}"]?.distanceFromPrevPoint = ((polyLineDetails["path${pathIncrementer-1}"]?.distanceFromPrevPoint?.toDouble() ?: 0.0) + (polyLineDetails["path${pathIncrementer}"]?.distance?.toDouble()
+ ?: 0.0)).toString()
+ pathIncrementer++;
+ }
+ }
+
+ fun drawPath(mTag:String){
+ var polyLine: Polyline? = null
+ if (!pathAnimation){
+ for(array in arrayOfPoints){
+ val lineOptions = PolylineOptions()
+ // Adding all the points in the route to LineOptions
+ lineOptions.addAll(array)
+ lineOptions.jointType(JointType.ROUND)
+ lineOptions.width(polyLineWidth.toFloat())
+ lineOptions.clickable(true)
+ polyLine = mMap?.addPolyline(lineOptions)
+ Logger.LogInfo(TAG,"onPostExecute lineoptions decoded")
+ polylineMap.put(mTag,PolylineBean(polyLine,null))
+ }
+ }else{
+ mMap?.let {
+ val mapAnimator = MapAnimator()
+ mapAnimator.setColorFillCompletion(pathColorFillAnimationTime)
+ mapAnimator.setDelayTime(animationDelay)
+ mapAnimator.setPrimaryLineColor(polyLinePrimaryColor)
+ mapAnimator.setSecondaryLineColor(polyLineSecondaryColor)
+ mapAnimator.setCompletionTime(pathCompletionTime)
+ mapAnimator.setPrimaryLineCompletion(primaryLineCompletionTime)
+ mapAnimator.animateRoute(it, allPathPoints,polyLineDataBean)
+ polylineMap.put(mTag,mapAnimator.getPolyline())
}
}
+
}
- private fun doParsingWork(jsonData: String): List>> {
+ private fun doParsingWork(jsonData: String, latLng: LatLng): List>> {
val jObject = JSONObject(jsonData)
Logger.LogInfo(TAG,jsonData)
val parser = DataParser()
Logger.LogInfo(TAG,parser.toString())
// Starts parsing data
val routes: List>> = parser.parse(jObject)
- polyLineDataBean = parser.polyLineDataBean
+ polyLineDataBean = parser.polyLineDataBean.apply {
+ this.position = latLng
+ }
Logger.LogInfo(TAG,"Executing routes--->")
Logger.LogDebug(TAG, routes.toString())
return routes
@@ -236,7 +306,6 @@ class DirectionUtil private constructor(builder: Builder) {
// Destination of route
val str_dest = "destination=" + dest.latitude + "," + dest.longitude
-
// Sensor enabled
val sensor = "sensor=false"
@@ -255,41 +324,55 @@ class DirectionUtil private constructor(builder: Builder) {
return "https://maps.googleapis.com/maps/api/directions/$output?$parameters"
}
- fun drawArcDirection(origin: LatLng, destination: LatLng, radius: Double,tag:String) {
- val allPathPoints:ArrayList = ArrayList()
- val d: Double = SphericalUtil.computeDistanceBetween(origin, destination)
- val h: Double = SphericalUtil.computeHeading(origin, destination)
-
- //Midpoint position
- val p: LatLng = SphericalUtil.computeOffset(origin, d * 0.5, h)
-
- val x = (1 - radius * radius) * d * 0.5 / (2 * radius)
- val r = (1 + radius * radius) * d * 0.5 / (2 * radius)
- val c: LatLng = SphericalUtil.computeOffset(p, x, h + 90.0)
-
- //Calculate heading between circle center and two points
- val h1: Double = SphericalUtil.computeHeading(c, origin)
- val h2: Double = SphericalUtil.computeHeading(c, destination)
-
- //Calculate positions of points on circle border and add them to polyline options
- val numpoints = 100
- val step = (h2 - h1) / numpoints
- for (i in 0 until numpoints) {
- val pi: LatLng = SphericalUtil.computeOffset(c, r, h1 + i * step)
- allPathPoints.add(pi)
- }
-
- mMap?.let {
- val mapAnimator = MapAnimator()
- mapAnimator.setColorFillCompletion(pathColorFillAnimationTime)
- mapAnimator.setDelayTime(animationDelay)
- mapAnimator.setPrimaryLineColor(polyLinePrimaryColor)
- mapAnimator.setSecondaryLineColor(polyLineSecondaryColor)
- mapAnimator.setCompletionTime(pathCompletionTime)
- mapAnimator.setPrimaryLineCompletion(primaryLineCompletionTime)
- mapAnimator.animateRoute(it, allPathPoints,polyLineDataBean)
- polylineMap.put(tag,mapAnimator)
- }
+ fun drawArcDirection(origin: LatLng, destination: LatLng, radius: Double,tag:String) {
+ GlobalScope.launch(Dispatchers.IO) {
+ val allPathPoints:ArrayList = ArrayList()
+ val d: Double = SphericalUtil.computeDistanceBetween(origin, destination)
+ val h: Double = SphericalUtil.computeHeading(origin, destination)
+
+ //Midpoint position
+ val p: LatLng = SphericalUtil.computeOffset(origin, d * 0.5, h)
+
+ val x = (1 - radius * radius) * d * 0.5 / (2 * radius)
+ val r = (1 + radius * radius) * d * 0.5 / (2 * radius)
+ val c: LatLng = SphericalUtil.computeOffset(p, x, h + 90.0)
+
+ //Calculate heading between circle center and two points
+ val h1: Double = SphericalUtil.computeHeading(c, origin)
+ val h2: Double = SphericalUtil.computeHeading(c, destination)
+
+ //Calculate positions of points on circle border and add them to polyline options
+ val numpoints = 100
+ val step = (h2 - h1) / numpoints
+ for (i in 0 until numpoints) {
+ val pi: LatLng = SphericalUtil.computeOffset(c, r, h1 + i * step)
+ allPathPoints.add(pi)
+ }
+ withContext(Dispatchers.Main){
+ if (!pathAnimation){
+ val lineOptions = PolylineOptions()
+ lineOptions.addAll(allPathPoints)
+ lineOptions.jointType(JointType.ROUND)
+ lineOptions.width(polyLineWidth.toFloat())
+ lineOptions.clickable(true)
+ val polyLine = mMap?.addPolyline(lineOptions)
+ polylineMap.put(tag,PolylineBean(polyLine,null))
+ this.cancel()
+ return@withContext
+ }
+ mMap?.let {
+ val mapAnimator = MapAnimator()
+ mapAnimator.setColorFillCompletion(pathColorFillAnimationTime)
+ mapAnimator.setDelayTime(animationDelay)
+ mapAnimator.setPrimaryLineColor(polyLinePrimaryColor)
+ mapAnimator.setSecondaryLineColor(polyLineSecondaryColor)
+ mapAnimator.setCompletionTime(pathCompletionTime)
+ mapAnimator.setPrimaryLineCompletion(primaryLineCompletionTime)
+ mapAnimator.animateRoute(it, allPathPoints,polyLineDataBean)
+ polylineMap.put(tag,mapAnimator.getPolyline())
+ }
+ }
+ }
}
@@ -297,18 +380,22 @@ class DirectionUtil private constructor(builder: Builder) {
if (!polylineMap.containsKey(mTag)){
throw java.lang.Exception("No Polyline Tag Found")
}
- polylineMap.get(mTag)?.getBck()?.let {
- polylineMap.get(mTag)?.getFor()?.remove()
- it.remove()
+ polylineMap.get(mTag)?.let {
+ it.foreground?.remove()
+ if (pathAnimation){
+ it.backPolyline?.remove()
+ }
}?:run{
throw java.lang.Exception("Please initiate polyline before calling this.")
}
}
-
interface DirectionCallBack {
- fun pathFindFinish(polyLineDetails: HashMap)
+ fun pathFindFinish(
+ polyLineDetails: HashMap,
+ polyLineDetailsArray: ArrayList
+ )
}
class Builder {
@@ -316,8 +403,6 @@ class DirectionUtil private constructor(builder: Builder) {
private set
var mMap: GoogleMap? = null
private set
- var mTag: String = ""
- private set
var key: String? = null
private set
var wayPoints = ArrayList()
@@ -349,7 +434,7 @@ class DirectionUtil private constructor(builder: Builder) {
fun setCallback(directionCallBack: DirectionCallBack) = apply { this.directionCallBack = directionCallBack }
fun setWayPoints(wayPoints: ArrayList): Builder {
- this.wayPoints = wayPoints
+ this.wayPoints = ArrayList(wayPoints)
return this
}
@@ -363,6 +448,11 @@ class DirectionUtil private constructor(builder: Builder) {
return this
}
+ fun setDebuggable():Builder{
+ Logger.isDebuggable = true
+ return this
+ }
+
fun setDirectionKey(key: String): Builder {
this.key = key
return this
@@ -373,11 +463,6 @@ class DirectionUtil private constructor(builder: Builder) {
return this
}
- fun setPolylineTag(mTag: String): Builder {
- this.mTag = mTag
- return this
- }
-
fun setPolyLineWidth(polyLineWidth: Int): Builder {
this.polyLineWidth = polyLineWidth
return this
diff --git a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/MapAnimator.kt b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/MapAnimator.kt
index 5f6109f..d35e2be 100644
--- a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/MapAnimator.kt
+++ b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/MapAnimator.kt
@@ -30,6 +30,7 @@ internal class MapAnimator {
private var COLOR_FILL_ANIMATION = 1800
private var FOREGROUND_TIME = 2000
private var DELAY_TIME = 200
+ private lateinit var polylineBean: PolylineBean
private var polyLineDetails: HashMap = HashMap()
@@ -199,6 +200,15 @@ internal class MapAnimator {
})
firstRunAnimSet!!.start()
+ addPolyineToBean(foregroundPolyline,backgroundPolyline);
+ }
+
+ private fun addPolyineToBean(foregroundPolyline: Polyline?, backgroundPolyline: Polyline?) {
+ polylineBean = PolylineBean(foregroundPolyline,backgroundPolyline)
+ }
+
+ fun getPolyline():PolylineBean{
+ return polylineBean
}
/**
diff --git a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolyLineDataBean.kt b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolyLineDataBean.kt
index 906dc32..7466aad 100644
--- a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolyLineDataBean.kt
+++ b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolyLineDataBean.kt
@@ -1,7 +1,23 @@
package com.example.easywaylocation.draw_path
+import com.google.android.gms.maps.model.LatLng
+import org.json.JSONObject
+
class PolyLineDataBean(){
- var time:String = "" // in second
- var distance:String = "" // in meter
+ var time:String = "0.0" // in second
+ var timeFromPrevPoint:String = "0.0" // in second
+ var distance:String = "0.0" // in meter
+ var distanceFromPrevPoint:String = "0.0" // in meter
var placeSummary:String = ""
+ var position:LatLng? = null
+
+ fun toJson(): JSONObject {
+ return JSONObject().put("placeSummary",placeSummary)
+ .put("time",time)
+ .put("distance",distance)
+ .put("distanceFromPrevPoint",distanceFromPrevPoint)
+ .put("timeFromPrevPoint",timeFromPrevPoint)
+ }
+
+
}
\ No newline at end of file
diff --git a/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolylineBean.kt b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolylineBean.kt
new file mode 100644
index 0000000..d8f64f1
--- /dev/null
+++ b/easywaylocation/src/main/java/com/example/easywaylocation/draw_path/PolylineBean.kt
@@ -0,0 +1,5 @@
+package com.example.easywaylocation.draw_path
+
+import com.google.android.gms.maps.model.Polyline
+
+data class PolylineBean(val foreground:Polyline?,val backPolyline: Polyline?)
\ No newline at end of file