How can I determine if a geopoint is displayed in currently viewable area?
-
20-09-2019 - |
Question
Say I have mapview control in my Android app. If I know a landmark exists at a certain latitude and longitude, how can I determine if that landmark is currently viewable on the user's screen? Is there a method for getting the coordinates for the top left and bottom right corners of the visible area?
Solution
You can project GeoPoint to Point and check if it is box (0, screen width) by (0, screen height)
See: https://developer.android.com/reference/com/google/android/gms/maps/Projection.html
OTHER TIPS
Something like this will do the trick.
private boolean isCurrentLocationVisible()
{
Rect currentMapBoundsRect = new Rect();
Point currentDevicePosition = new Point();
GeoPoint deviceLocation = new GeoPoint((int) (bestCurrentLocation.getLatitude() * 1000000.0), (int) (bestCurrentLocation.getLongitude() * 1000000.0));
mapView.getProjection().toPixels(deviceLocation, currentDevicePosition);
mapView.getDrawingRect(currentMapBoundsRect);
return currentMapBoundsRect.contains(currentDevicePosition.x, currentDevicePosition.y);
}
Joining the tips here, here and here:
Here is the complete code of my CustomMapView:
package net.alouw.alouwCheckin.ui.map;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Pair;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
/**
* @author Felipe Micaroni Lalli (micaroni@gmail.com)
*/
public class CustomMapView extends MapView {
public CustomMapView(Context context, String s) {
super(context, s);
}
public CustomMapView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
public CustomMapView(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
}
/**
*
* @return a Pair of two pairs with: top right corner (lat, lon), bottom left corner (lat, lon)
*/
public Pair<Pair<Double, Double>, Pair<Double, Double>> getMapCorners() {
GeoPoint center = getMapCenter();
int latitudeSpan = getLatitudeSpan();
int longtitudeSpan = getLongitudeSpan();
double topRightLat = (center.getLatitudeE6() + (latitudeSpan / 2.0d)) / 1.0E6;
double topRightLon = (center.getLongitudeE6() + (longtitudeSpan / 2.0d)) / 1.0E6;
double bottomLeftLat = (center.getLatitudeE6() - (latitudeSpan / 2.0d)) / 1.0E6;
double bottomLeftLon = (center.getLongitudeE6() - (longtitudeSpan / 2.0d)) / 1.0E6;
return new Pair<Pair<Double, Double>, Pair<Double, Double>>(
new Pair<Double, Double>(topRightLat, topRightLon),
new Pair<Double, Double>(bottomLeftLat, bottomLeftLon));
}
}
Ok since it took me some time now to find a simple working solution I will post it here for all after me ;) In your own subclass of MapView just use the following:
GeoPoint topLeft = this.getProjection().fromPixels(0, 0);
GeoPoint bottomRight = this.getProjection().fromPixels(getWidth(),getHeight());
Thats all, then you can get the coordinates via
topLeft.getLatitudeE6() / 1E6
topLeft.getLongitudeE6() / 1E6
and
bottomRight.getLatitudeE6() / 1E6
bottomRight.getLongitudeE6() / 1E6