I want te measure distance from start position while driving - android

I am building an Android application to measure 1km from a start position while driving.
i tried this : https://github.com/quentin7b/android-location-tracker/blob/master/README.md
val settings = TrackerSettings()
.setUseNetwork(true)
.setUseGPS(true)
.setUsePassive(false)
.setTimeBetweenUpdates(1000)
.setMetersBetweenUpdates(10F)
And i change postions to get distance between to position using:
val distance = currentPosition!!.distanceTo(location)
totalDistance += distance
But the result is not precise, anyone how can give a better solution

private fun distance(
startLatitude: Double,
startLongitude: Double,
endLatitude: Double,
endLongitude: Double,
unit: String
): String {
val theta = startLongitude - endLongitude
var dist: Double = sin(deg2rad(startLatitude)) * sin(deg2rad(endLatitude)) +
cos(deg2rad(startLatitude)) * cos(deg2rad(endLatitude)) * cos(deg2rad(theta))
dist = acos(dist)
dist = rad2deg(dist)
dist *= 60 * 1.1515 //miles
if (unit == "k") {
dist *= 1.609344 // km
}
return dist.toString()
}
private fun deg2rad(deg: Double): Double {
return deg * 3.1415926535897932 / 180.0
}
private fun rad2deg(rad: Double): Double {
return rad * 180.0 / 3.1415926535897932
}

You can use android.location.Location.distanceBetween() method which does this quite well. For more info

Related

How to implement the "fast inverse square root" with Kotlin?

fun invSqrt(x: Float): Float {
var x = x
val xhalf = 0.5F * x
var i = java.lang.Float.floatToIntBits(x)
i = 0x5f3759df - (i shr 1)
x = java.lang.Float.intBitsToFloat(i)
x *= 1.5F - xhalf * x * x
return x
}
Is there any shorter or faster way to do this with Kotlin?

" 'onSensorChanged' overrides nothing " Fault

I'm trying to get values from SensorManager. I copied the code from Android API. But problems occurred. Please look at the code.
I was working on the gyroscope sensor. I wanted to examine gyroscope values and results. I found codes on this website
" https://developer.android.com/guide/topics/sensors/sensors_motion#sensors-motion-gyro "
I took error message at override fun onSensorChanged(event: SensorEvent?)
It says " 'onSensorChanged' overrides nothing "
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
// Create a constant to convert nanoseconds to seconds.
private val NS2S = 1.0f / 1000000000.0f
private val deltaRotationVector = FloatArray(4) { 0f }
private var timestamp: Float = 0f
override fun onSensorChanged(event: SensorEvent?) {
// This timestep's delta rotation to be multiplied by the current rotation
// after computing it from the gyro sample data.
if (timestamp != 0f && event != null) {
val dT = (event.timestamp - timestamp) * NS2S
// Axis of the rotation sample, not normalized yet.
var axisX: Float = event.values[0]
var axisY: Float = event.values[1]
var axisZ: Float = event.values[2]
// Calculate the angular speed of the sample
val omegaMagnitude: Float = sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ)
// Normalize the rotation vector if it's big enough to get the axis`enter code here`
// (that is, EPSILON should represent your maximum allowable margin of error)
if (omegaMagnitude > EPSILON) {
axisX /= omegaMagnitude
axisY /= omegaMagnitude
axisZ /= omegaMagnitude
}
// Integrate around this axis with the angular speed by the timestep
// in order to get a delta rotation from this sample over the timestep
// We will convert this axis-angle representation of the delta rotation
// into a quaternion before turning it into the rotation matrix.
val thetaOverTwo: Float = omegaMagnitude * dT / 2.0f
val sinThetaOverTwo: Float = sin(thetaOverTwo).toFloat()
val cosThetaOverTwo: Float = cos(thetaOverTwo).toFloat()
deltaRotationVector[0] = sinThetaOverTwo * axisX
deltaRotationVector[1] = sinThetaOverTwo * axisY
deltaRotationVector[2] = sinThetaOverTwo * axisZ
deltaRotationVector[3] = cosThetaOverTwo
Log.d("DENEME", "onSensorChanged: " + axisX)
Log.d("DENEME", "onSensorChanged: " + axisY)
Log.d("DENEME", "onSensorChanged: " + axisZ)
}
timestamp = event?.timestamp?.toFloat() ?: 0f
val deltaRotationMatrix = FloatArray(9) { 0f }
SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
// User code should concatenate the delta rotation we computed with the current rotation
// in order to get the updated rotation.
// rotationCurrent = rotationCurrent * deltaRotationMatrix;
}
fun onClickDevam(view: View) // click event button to check values
{
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
}
}
The override keyword in Kotlin suggests that the class is inheriting a function from a super class or interface. The Android documentation seems to be missing a pretty important step which is having your activity class implement the SensorEventListener interface.
To do this change your MainActivity declaration to something like this:
class MainActivity : AppCompatActivity(), SensorEventListener {
SensorEventListener contains the onSensorChanged function you're talking about. It will also require you to override an additional function, onAccuracyChanged, so you'll need to do this as well (but if you don't really care about accuracy changes you can leave the function's body empty - you just need to override it to satisfy the interface).
Android Studio has a handy shortcut for automatically overriding functions from interfaces which you may find useful: Ctrl+O

Transform a EditText in to a integer (INT)

var distanta = findViewById<EditText>(android.R.id.input)
km = seekBar.progress
km = km / 60
km2 = distanta / km
textView2.setText(km2).toString()
Project Link:https://drive.google.com/file/d/1s6Pi1kmC1oRmMqf0yJjtV1fAxiDuOr03/view?usp=sharing
Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
public inline operator fun BigDecimal.div(other: BigDecimal): BigDecimal defined in kotlin
public inline operator fun BigInteger.div(other: BigInteger): BigInteger defined in kotlin
Try this that may help you
var distanta = findViewById<EditText>(android.R.id.input)
km = seekBar.progress
km = km / 60
km2 = (distanta.text?.toString()?.toInt() ?: 0) / km
textView2.setText(km2.toString())

Kotlin - I cannot get the same distance accuracy as Google maps

I'm using Google Places api in my app which calculate the distance between 2 address,
the problem is that I get less distance than in google maps.
I cannot get the same accuracy as Google maps,
Most of the time distance is shorter than the result from Google Maps
private fun SetupPlacesAutocompleteFun() {
val _autocompletFragment1 = supportFragmentManager
.findFragmentById(R.id.fragmentPlaces1) as AutocompleteSupportFragment
_autocompletFragment1.setPlaceFields(_placesFields)
_autocompletFragment1.setOnPlaceSelectedListener(object:PlaceSelectionListener{
override fun onPlaceSelected(p1: Place) {
_adrees1 = p1.latLng!!
_adressString1 = p1.address!!
}
override fun onError(p1: Status) {
Toast.makeText(this#GooglePlaces_Activity,"status "+p1.statusMessage,Toast.LENGTH_LONG).show()
}
})
val _autocompletFragment2 = supportFragmentManager
.findFragmentById(R.id.fragmentPlaces2) as AutocompleteSupportFragment
_autocompletFragment2.setPlaceFields(_placesFields)
_autocompletFragment2.setOnPlaceSelectedListener(object :PlaceSelectionListener{
override fun onPlaceSelected(p2: Place) {
_adress2 =p2.latLng!!
_adressString2 = p2.address!!
}
override fun onError(p2: Status) {
Toast.makeText(this#GooglePlaces_Activity,"status "+p2.statusMessage,Toast.LENGTH_LONG).show()
}
})
}
private fun InitPlacesFun() {
Places.initialize(this,getString(R.string.Places_api))
_placcesClint = Places.createClient(this)
}
fun TestButtonFun () {
button.setOnClickListener() {
var _loc:Location= Location("start")
_loc.latitude = _adrees1.latitude
_loc.longitude = _adrees1.longitude
var _loc2:Location= Location("start")
_loc2.latitude = _adress2.latitude
_loc2.longitude = _adress2.longitude
dist = (round(((_loc.distanceTo(_loc2).toDouble()/1000))*100) /100).toDouble()
}
I have also tried this:
var _Lat1 = _adrees1.latitude
var _Lat2 = _adress2.latitude
var _Long1 = _adrees1.longitude
var _Long2 = _adress2.longitude
var _LatRes = _Lat1 - _Lat2
var _longRes = _Long1 - _Long2
var R = 6371000f; // Radius of the earth in m
var dLat = _LatRes * Math.PI / 180f;
var dLon = _longRes * Math.PI / 180f;
var a = Math.sin(dLat/2) * Math.sin(dLat/2) +
Math.cos(_Lat1 * Math.PI / 180f) * Math.cos(_Lat2 * Math.PI / 180f) *
Math.sin(dLon/2) * Math.sin(dLon/2);
var c = 2f * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
dist = R* c
You get less distance because you're calculating the radial distance and not the actual route distance.
Try calculating the distance using google directions API.
You can see the difference between radial distance (orange) and actual distance (blue) in the image

Draw an arc with rounded corners on Canvas

I'm trying to implement a pie chart as shown in pictures below, where corners of the arc should be rounded.
I've tried to use CornerPathEffect(), but it seems to work only on the intersection of two lines (path.lineTo()). Nothing changes if I use this method for arc (path.arcTo()).
Try to set Stroke Cap of paint.
mPaint.setStrokeCap(Paint.Cap.ROUND);
I know it's too late for this answer but here is my solution.
PieSlice.kt
data class PieSlice(
val name: String,
var value: Double,
var startAngle: Float,
var sweepAngle: Float,
var indicatorCircleLocation: PointF,
val paint: Paint
)
Function to make round corner arc
private fun drawCurvedArc(canvas: Canvas?, pieItem: PieSlice) {
val path = Path()
path.moveTo(originX, originY)
val angleStart = pieItem.startAngle
val angleEnd = (pieItem.startAngle - pieItem.sweepAngle)
val arcOffset = pieItem.sweepAngle.coerceAtMost(7f)
val lineOffset = if (pieItem.sweepAngle < 7f) 0f else 25f
// line from origin to top
val line1x = getPointX(angleStart, lineOffset)
val line1y = getPointY(angleStart, lineOffset)
path.lineTo(line1x, line1y)
//Curve corner from line top to arc start
val arcStartx = getPointX(angleStart - arcOffset)
val arcStarty = getPointY(angleStart - arcOffset)
joinLineAndArc(path, line1x, line1y, arcStartx, arcStarty)
//Arc
path.arcTo(
outerRect, (pieItem.startAngle - arcOffset),
(-pieItem.sweepAngle + 2 * arcOffset), true
)
val line2x = getPointX(angleEnd, lineOffset)
val line2y = getPointY(angleEnd, lineOffset)
val arcEndx = getPointX(angleEnd + arcOffset)
val arcEndy = getPointY(angleEnd + arcOffset)
//Curve corner from arc end to bottom line
joinLineAndArc(path, arcEndx, arcEndy, line2x, line2y)
// Bottom line
path.lineTo(originX, originY)
val borderPaint = Paint()
borderPaint.strokeJoin = Paint.Join.ROUND
borderPaint.strokeCap = Paint.Cap.ROUND
borderPaint.color = pieItem.paint.color
borderPaint.style = Paint.Style.FILL
borderPaint.strokeWidth = 0f
canvas?.drawPath(path, borderPaint)
}
/**
* Join line and arc with a curve
*
* vector = (x1-x2,y1-y2)
*
* pVector perpendicular to vector
* pVector = (y1-y2,x2-x1)
*
* midX = (x1+x2)/2
* midY = (y1+y2)/2
*
* (px,py) = (midX,midY) ± (D/√((y1−y2)^2,(x2−x1)^2))*(y1-y2,x2-x1)
*/
private fun joinLineAndArc(
path: Path,
x1: Float,
y1: Float,
x2: Float,
y2: Float
) {
val midX: Float = (x2 + x1) / 2f
val midY: Float = (y2 + y1) / 2f
val x2_x1 = (x2 - x1).toDouble()
val y1_y2 = (y1 - y2).toDouble()
val powY = y1_y2.pow(2.0)
val powX = x2_x1.pow(2.0)
val den = sqrt(powY + powX)
val len = 20.0
// perpendicular1
val p1x = (midX + ((len * y1_y2) / den)).toFloat()
val p1y = (midY + ((len * x2_x1) / den)).toFloat()
// perpendicular2
val p2x = (midX - ((len * y1_y2) / den)).toFloat()
val p2y = (midY - ((len * x2_x1) / den)).toFloat()
val len1 = Math.sqrt(
Math.pow((originX - p1x).toDouble(), 2.0)
+ Math.pow((originY - p1y).toDouble(), 2.0)
)
val len2 = Math.sqrt(
Math.pow((originX - p2x).toDouble(), 2.0)
+ Math.pow((originY - p2y).toDouble(), 2.0)
)
//Make a curve to the point which is far from origin
if (len1 > len2) {
path.cubicTo(x1, y1, p1x, p1y, x2, y2)
} else {
path.cubicTo(x1, y1, p2x, p2y, x2, y2)
}
}
/**
* Get the x coordinate on a circle
* formula for x pos: (radius) * cos(angle) + (distance from left edge of screen)
* #param angle angle of point from origin
* #param offset to make shorter line than actual radius
*/
private fun getPointX(angle: Float, offset: Float = 0f): Float {
return ((radius - offset)
* cos(Math.toRadians((angle.toDouble())))
+ originX).toFloat()
}
/**
* Get the y coordinate on a circle
* formula for y pos: (radius) * sin(angle) + (distance from top edge of screen)
*
* #param angle angle of point from origin
* #param offset to make shorter line than actual radius
*/
private fun getPointY(angle: Float, offset: Float = 0f): Float {
return ((radius - offset)
* sin(Math.toRadians((angle.toDouble())))
+ originY).toFloat()
}

Categories

Resources