Pan map in a single direction - android

My V2 Map has been set in a random position, with a random bearing from north (so the compass symbol is likely to be pointing anywhere, but probably not north).
I want to shift/pan the map directly up the screen as the user looks at it, a short distance.
This may be very simple or require some complex calculations with lats, longs and trigonometry.
But I'm struggling to find a solution that works whatever the angle and zoom level is.
How can i do this ?

Well I solved this by finding a position on the screen and converting it to a LatLng, and then panning the map to this position. It worked perfectly.
Projection projection = mapView.getProjection();
Point p = new Point(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2);
LatLng pos = projection.fromScreenLocation(p);

Related

How do you find relative bearing between two points?

double computeHeading(double latitude1, double longitude1, double latitude2, double longitude2)
{
double degToRad = PI / 180.0;
double phi1 = latitude1*degToRad;
double phi2 = latitude2*degToRad;
double lam1 = longitude1*degToRad;
double lam2 = longitude2*degToRad;
double x,y;
x = cos(phi2) * sin(lam2-lam1);
printf("X is %lf\n", x);
y = cos(phi1) * sin(phi2) - sin(phi1) * cos(phi2) * cos(lam2-lam1);
printf("Y is %lf\n", y);
return atan2(x,y)*180/PI;
}
I am using the above function to determine the true bearing from North between two geographic coordinates.
I'm currently developing a small navigation widget which uses GPS data from Android sensors. The widget has an arrow facing towards a point away from the device's current location. The arrow's direction changes with the device's current location and azimuth to always face the distant point.
Here is a scenario:
I'm at a location, facing north, and another location has a bearing of 300 degrees(somewhat northwest of me). If I face towards south, without moving, my relative bearing to the distant location should be 120 degrees.
How can I find the relative bearing with accounting for the facing direction (azimuth)?
There are a couple of ways you can work this out. The first, which is what you appear to be doing, assumes the earth is spherical. Relative bearings are calculated using Haversine formulation for great circle navigation. Given starting and ending points, this formulation finds the great circle passing through the two points. From this an initial bearing can be calculated. This great circle route is the shortest route between the two points, but suffers from the problem the bearing, in general, will not be constant along the route. Also, except under some very specific cases, the reverse bearing does not behave as you seem to expect and if you want to determine it in general, you will have to perform another calculation reversing the starting and ending points.
Another method you could use is the Rhumb line formulation. In this case, the bearing between the starting point and ending point is constant and would allow you to use the relation you have for the reverse course if you would like. Since this will in general differ from the great circle distance, following Rhumb lines will not result in the shortest path between the two points, but it does simplify the navigation by holding the course constant.
Both of these approaches are described in detail at Calculate distance, bearing and more between Latitude/Longitude points
Another formulation for great circle navigation which uses a more accurate representation of the earth's shape, an oblate spheriod, which is a special type of ellipsoid, is attributed to Vincenty with additional enhancements provided by Karney. In these cases, the formulation is quite a bit more complicated and is probably overkill for most applications, and performance is quite a bit worse than the Haversine formulations above. But these formulations provide much better accuracy if you need it.
Update:
Based on the comment below, the main issue is one of figuring out how far to turn. This will simply be the angle between the normals of the plane containing the great circles for the current heading and the desired heading. To get the normal for the plane on the current heading, you need your current location L and a point some distance away on the current heading, C. The normal is just V = L×C. To compute the normal for the plane containing the great circle along the desired heading, you only need to know a point along the desired route, which you already have in the form of your destination point, which we call D. You can then find the normal by U = L×D. The angle between them is given by θ = acos((U∙V)/(|U||V|)).
In order to find L, C and D you must convert the Latitude, Longitude, Altitude (LLA) coordinates into Earth Centered, Earth Fixed (ECEF) coordinates.

Map v2 convert distance to pixels

I have been searching but I couldn't find it. I am using google map v2. Is there any way I can convert distance ( meters) to pixels on my screen? I need the pixels equivalent of the distance. I have the distance and I have the zoom level.
Any help is appreciated.
If I understand correctly, you have a MapFragment on your screen showing a map. You know the distance in meters between 2 points on the map that are shown on the screen and you want to calculate the distance between those two points in pixels. If you know the LatLng location of the two points, you can use the Projection class like this:
Point point1 = map.getProjection().toScreenLocation(latLng1);
Point point2 = map.getProjection().toScreenLocation(latLng2);
and then you just need to use the distance mathematic formula:

Longest distance displayed on screen in kilometers

On Google Map Api V2 for Android,
I would like to calculate the longest distance in kilometers displayed on screen (while zoom factor is a parameter) in order to determinate the radius of the smallest circle containing all the map displayed on screen at present time:
That means the distance between the center of the screen and one of the edges.
Is there some Tool I can use to do that ? (Maybe to get the coordinates of one of the edges...)
You can probably use the Projection class (http://developer.android.com/reference/com/google/android/gms/maps/Projection.html)
For example:
Projection projection = map.getProjection(); // get map projection
VisibleRegion vr = projection.getVisibleRegion(); //
vr now contains the corners of your map, from there you can compute the distances...
http://developer.android.com/reference/com/google/android/gms/maps/model/VisibleRegion.html
It would probably be wise to do this inside an OnCameraChangedListener , to be sure you have valid a projection value

android How to convert pixel coordinates to LatLng on mapsv2

I've looked on the net but couldn't find an accurate answer. I have an ImageView to use as a marker centred on map, Its position not change when I pan the map. I want to get the latlng of position when I stop panning on the map. I guess I have to use projection but because of I am not so expert in android I got stuck. Can anybody help please.
Use map.getProjection().fromScreenLocation(Point) and map.getProjection().toScreenLocation(LatLng) to convert between screen position and geo location.
Use the Projection via map.getProjection().
This will allow you to convert between screen coordinates and LatLngs. The pixels returned are relative to the View containing the map.
For Maps API v2
VisibleRegion vr = mMap.getProjection().getVisibleRegion();
double left = vr.latLngBounds.southwest.longitude;
double top = vr.latLngBounds.northeast.latitude;
double right = vr.latLngBounds.northeast.longitude;
double bottom = vr.latLngBounds.southwest.latitude;
Also you can use,
LatLngBounds curScreen = mMap.getProjection()
.getVisibleRegion().latLngBounds;
Hope this will help.

Google MapView zoomout to span a circle

I have a MapView centered at point P. The user can't change the MapView center, but he can choose a radius of a circle to be display around point P, and change it dynamically with the map being redrawn at each change to show the new circle.
The thing is, i want the map to zoom in or out as necessary, in order to display the entire circle at the viewable area. I've tried this:
Projection proj = m_Map.getProjection();
Point mapCenterPixles = new Point();
proj.toMapPixels(center, mapCenterPixles);
float radiusPixels = proj.metersToEquatorPixels(newRadius);
IGeoPoint topLeft = proj.fromPixels(mapCenterPixles.x - radiusPixels,
mapCenterPixles.y - radiusPixels);
IGeoPoint bottomRight = proj.fromPixels(mapCenterPixles.x
+ radiusPixels, mapCenterPixles.y + radiusPixels);
m_Map.getController().zoomToSpan(
topLeft.getLatitudeE6() - bottomRight.getLatitudeE6(),
topLeft.getLongitudeE6() - bottomRight.getLongitudeE6());
But it seems i'm missing something, as the values passed to zoomToSpan() cause no chnage, I'm kind of lost here, can someone please shed some light on how to zoom the map to span a bounding box of the circle given its radius in meters, and its center points?
Google Maps zoom levels are defined in powers of two, so MapController#zoomToSpan() also zooms by powers of two.
Ergo, if the span you compute above is already displayable within the current zoom level, it's likely nothing would actually change visually in the map until you need to go to the next larger or smaller zoom level.
This behavior is somewhat vaguely described in the documentation for MapController#zoomToSpan

Categories

Resources