@@ -2,7 +2,7 @@ package com.ckdroid.geofirequery.utils
2
2
3
3
import com.ckdroid.geofirequery.model.BoundingBox
4
4
import com.ckdroid.geofirequery.model.QueryLocation
5
- import com.google.firebase.firestore.FirebaseFirestore
5
+ import com.google.firebase.firestore.GeoPoint
6
6
import kotlin.math.*
7
7
8
8
/* *
@@ -60,11 +60,67 @@ class BoundingBoxUtils(private val distanceUnit: DistanceUnit) {
60
60
return BoundingBox (minimumLatitude, minimumLongitude, maximumLatitude, maximumLongitude)
61
61
}
62
62
63
+ fun getBoundingBoxForNew (queryLocation : QueryLocation , distance : Double ): BoundingBox {
64
+ val nearByLocationList: MutableList <GeoPoint > = mutableListOf ()
65
+
66
+ (1 .. 200 ).forEach { _ ->
67
+ nearByLocationList.add(pointAtDistance(queryLocation, distance))
68
+ }
69
+
70
+ if (nearByLocationList.isNotEmpty()) {
71
+ val sortedBounds = nearByLocationList.sortedWith(compareBy({ it.latitude }, { it.longitude }))
72
+
73
+ val minimumGeoPoint = sortedBounds.first()
74
+
75
+ val maximumGeoPoint = sortedBounds.last()
76
+
77
+ return BoundingBox (
78
+ minimumGeoPoint.latitude,
79
+ minimumGeoPoint.longitude,
80
+ maximumGeoPoint.latitude,
81
+ maximumGeoPoint.longitude
82
+ )
83
+ }
84
+
85
+ return BoundingBox (
86
+ queryLocation.latitude,
87
+ queryLocation.longitude,
88
+ queryLocation.latitude,
89
+ queryLocation.longitude
90
+ )
91
+ }
92
+
93
+ private fun pointAtDistance (queryLocation : QueryLocation , distance : Double ): GeoPoint {
94
+ val sinLat = Math .sin(queryLocation.latitude)
95
+ val cosLat = Math .cos(queryLocation.latitude)
96
+
97
+ val bearing = Math .random().times(TWO_PI )
98
+ val theta = when (distanceUnit) {
99
+ DistanceUnit .KILOMETERS -> distance.div(EARTH_RADIUS_KM )
100
+ DistanceUnit .MILES -> distance.div(EARTH_RADIUS_MILES )
101
+ }
102
+
103
+ val sinBearing = sin(bearing)
104
+ val cosBearing = cos(bearing)
105
+ val sinTheta = sin(theta)
106
+ val cosTheta = cos(theta)
107
+
108
+ val latitude = asin(sinLat * cosTheta + cosLat * sinTheta * cosBearing)
109
+ var longitude =
110
+ queryLocation.longitude + atan2(sinBearing * sinTheta * cosLat, cosTheta - sinLat * sin(latitude))
111
+ longitude = ((longitude + THREE_PI ) % TWO_PI ) - Math .PI
112
+
113
+ return GeoPoint (Math .toDegrees(latitude), Math .toDegrees(longitude))
114
+ }
115
+
63
116
companion object {
64
117
65
- private val EARTH_RADIUS_KM = 6371.001
118
+ private val EARTH_RADIUS_KM = 6371.000 // 6371. 001
66
119
private val EARTH_RADIUS_MILES = 3958.756
67
120
121
+ private val THREE_PI = Math .PI .times(3 )
122
+ private val TWO_PI = Math .PI .times(2 )
123
+
68
124
private val MINIMUM_LATITUDE = Math .toRadians(- 90.0 ) // -PI/2
69
125
private val MAXIMUM_LATITUDE = Math .toRadians(90.0 ) // PI/2
70
126
private val MINIMUM_LONGITUDE = Math .toRadians(- 180.0 ) // -PI
0 commit comments