Get Radius Of Visible Map in Android
thank you so much for your answer @kaho, it helped me alot (even you calculated the distanceWidth and distanceHeight in the same way).
Clarification:
farLeft LatLng object that defines the top left corner of the camera.
farRight LatLng object that defines the top right corner of the camera.
nearLeft LatLng object that defines the bottom left corner of the camera.
nearRight LatLng object that defines the bottom right corner of the camera.
EDITED: I don't know why we made a simple calculation become a bit complicated, the visible radius is just A HALF OF VISIBLE DIAGONAL LINE, that's all!
private double getMapVisibleRadius() {
VisibleRegion visibleRegion = map.getProjection().getVisibleRegion();
float[] diagonalDistance = new float[1];
LatLng farLeft = visibleRegion.farLeft;
LatLng nearRight = visibleRegion.nearRight;
Location.distanceBetween(
farLeft.latitude,
farLeft.longitude,
nearRight.latitude,
nearRight.longitude,
diagonalDistance
);
return diagonalDistance[0] / 2;
}
I also logged my results to compare with @jossef-harush 's results and it's approximately:
For the Google Maps Android API, you can get the bounds by...
From the map reference, get the Projection
by getProjection(). And,
a projection is used to translate between on screen location and geographic coordinates..
So from the projection, we can use the getVisibleRegion(), and to get the VisibleRegion of the map, which contains a LatLngBounds, which is a class that contains 2 LatLng
variables, one for the Northeast corner of the bound and one for the Southwest corner.
So the code should look something like this:
googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition position) {
LatLngBounds bounds = googleMap.getProjection().getVisibleRegion().latLngBounds;
LatLng northeast = bounds.northeast;
LatLng southwest = bounds.southwest;
Context context = getApplicationContext();
CharSequence text = "ne:"+northeast+" sw:"+southwest;
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
});
=-=-=-=-=-= edit:
May be I was too naive, given only the NE and SW can solve this problem, but only under the special case where user did not rotate the map or tilt up for the 3D map.
So instead, you can just grab the VisibleRegion
, which provided 4 variable, farRight, farLeft, nearRight, nearLeft, each represent 4 conners of the area.
Then we can calculate the width and height of the area for that 4 points and pick the smaller one (well, sometime width can be greater than height I guess.)
And for the calculation, we can just use the Location.distanceBetween(x1,y1,x2,y2,result)
function...
which makes the code look like the following:
VisibleRegion visibleRegion = googleMap.getProjection().getVisibleRegion();
LatLng farRight = visibleRegion.farRight;
LatLng farLeft = visibleRegion.farLeft;
LatLng nearRight = visibleRegion.nearRight;
LatLng nearLeft = visibleRegion.nearLeft;
float[] distanceWidth = new float[2];
Location.distanceBetween(
(farRight.latitude+nearRight.latitude)/2,
(farRight.longitude+nearRight.longitude)/2,
(farLeft.latitude+nearLeft.latitude)/2,
(farLeft.longitude+nearLeft.longitude)/2,
distanceWidth
);
float[] distanceHeight = new float[2];
Location.distanceBetween(
(farRight.latitude+nearRight.latitude)/2,
(farRight.longitude+nearRight.longitude)/2,
(farLeft.latitude+nearLeft.latitude)/2,
(farLeft.longitude+nearLeft.longitude)/2,
distanceHeight
);
float distance;
if (distanceWidth[0]>distanceHeight[0]){
distance = distanceWidth[0];
} else {
distance = distanceHeight[0];
}
Full area, even corners!
I don't see other answers cover the entire map area;
see image below, to test it I drew a circle overlay to see the bounds of the calculated radius, it does not cover entire map area.
my modification is quite simple, I've used Pythagorean theorem to find the suitable radius to contain the map "rectangle".
private double getMapVisibleRadius() {
VisibleRegion visibleRegion = googleMap.getProjection().getVisibleRegion();
float[] distanceWidth = new float[1];
float[] distanceHeight = new float[1];
LatLng farRight = visibleRegion.farRight;
LatLng farLeft = visibleRegion.farLeft;
LatLng nearRight = visibleRegion.nearRight;
LatLng nearLeft = visibleRegion.nearLeft;
Location.distanceBetween(
(farLeft.latitude + nearLeft.latitude) / 2,
farLeft.longitude,
(farRight.latitude + nearRight.latitude) / 2,
farRight.longitude,
distanceWidth
);
Location.distanceBetween(
farRight.latitude,
(farRight.longitude + farLeft.longitude) / 2,
nearRight.latitude,
(nearRight.longitude + nearLeft.longitude) / 2,
distanceHeight
);
double radiusInMeters = Math.sqrt(Math.pow(distanceWidth[0], 2) + Math.pow(distanceHeight[0], 2)) / 2;
return radiusInMeters;
}