0

I want the autocomplete result to show only 1 km from the user location. there is a way with RectangularBounds:

setLocationBias(RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363),
new LatLng(-33.858754, 151.229596)))
  1. There are only 2 points here. How does it make a rectangular?

  2. If the user Latlng is for example 32.0000000, 30.0000000 , How can I do a RectangularBounds of 1 km around him?

1 Answers1

3

For the first question if you look at the docs

RectangularBounds newInstance (LatLng southwest, LatLng northeast)

Is rectangular because it represents two coordinates: southwest and northeast, that's usually refered as a Bounding Box (or shortened to bbox) and represents the area inside that two coordinates.

The second question is less simple and there is more than one way of doing it.

One approach is to find out a method to add a distance to a coordinate, this methods are always approximate. For this LatLng geographic coordinates you could use:

public static LatLng getCoordinate(double lat0, double lng0, long dy, long dx) {
    double lat = lat0 + (180 / Math.PI) * (dy / 6378137);
    double lng = lng0 + (180 / Math.PI) * (dx / 6378137) / Math.cos(lat0);
    return new LatLng(lat, lng);
}

where lat0 and long0 are the original coordinates and dx and dy are a distance in meters (as the Earth radius is set in meters 6378137).

And now you can create an aproximate bounding box with the original point +- 1000 meters. Supposing the point you set as starting point is at latitude -33.869622 and longitude 151.206979 the bbox would be:

RectangularBounds.newInstance(
    getCoordinate(-33.869622, 151.206979, -1000, -1000),
    getCoordinate(-33.869622, 151.206979, 1000, 1000))

That is the bbox you could use for the api call.

In case you have an instance variable named currentlocation this will be:

RectangularBounds.newInstance(
    getCoordinate(this.currentlocation.getLatitude(), this.currentlocation.getLongitude(), -1000, -1000),
    getCoordinate(this.currentlocation.getLatitude(), this.currentlocation.getLongitude(), 1000, 1000))

If you still need to be more precise with the 1km distance and discard points that are inside that square (bbox) but out of circle of 1km radius you could filter the results by checking the distance to the original point before returning the result or displaying it.

As a curiosity

Another way I could think of is to change the coordinate's projection to another one to make the calculations easier, if you transform the coordinate to mercator adding 1000 to the x value would add 1 km and adding 1000 to the y would also add 1 km as it uses meters as unit, but then you should transform back to the original projection (working with LatLng) as it's the one that api is using so I don't think it's worth it, but it should work as well.

jeprubio
  • 17,312
  • 5
  • 45
  • 56
  • I tried to do this: new LatLng(this.currentlocation.getLatitude()+1000.0, this.currentlocation.getLongitude()+1000.0), new LatLng(this.currentlocation.getLatitude()-1000.0, this.currentlocation.getLongitude()-1000.0))) .build(this); startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE); but it crashed :( any idea what I did wrong? – Or Halachmi May 05 '20 at 20:09
  • The problem is that this is wrong if you want something similar to 1km, the units of latlng have nothing to do with meters and the units of X axis and the units of the Y axis are very different. That's why I wrote a method to pass the latitude and longitude and the meters to get something with much better precission – jeprubio May 05 '20 at 20:12
  • About the crash I don't know what is the intent you are trying to open. Is a new activity? Is it defined in the manifest? you should check the [logcat](https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this/23353174#23353174) to know what has caused the crash – jeprubio May 05 '20 at 20:15
  • so you cant do +1000? – Or Halachmi May 05 '20 at 20:16
  • I've added an update with the coordinate in this.currentlocation and adding 1000m to get each coordinate. Check it. In the case the coordinates were in [mercator projection](https://en.wikipedia.org/wiki/Mercator_projection) (not in LatLng) then you could do +1000 the way you were doing as units would be in meters. It's what I was trying to say in the extras as a curiosity. But since they are not you should perform changes of projections and I think its not worth it in this case. – jeprubio May 05 '20 at 20:32
  • Kotlin: I'm using Kotlin, and had to change dy and dx to Double - here's why... Without that, something like dy=1000 will be (1000 / 6378137) which Kotlin will interpret as a Long, rounding down to 0. I noticed that getCoordinate() was just passing back exactly the same thing I was passing in. As I stepped through it, I realized what was happening. – wildcat12 May 01 '21 at 13:52