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
Related
I'm using a MapView to display a Google Map and the trying to create a circle overlay. But for some reason the circle border is displayed but it is not filled with any color, here is what is generated using the android emulator:
Here is an idea of what I would like to achieve (i created it through the w3school online editor).
Here is the code:
LatLng center = new LatLng(-16.272425327210556,166.4380745618525);
double radius = 9944545.500957435;
CircleOptions co = new CircleOptions().center(center).clickable(false).radius((radius)).fillColor(Color.YELLOW).visible(false);
this.marker_twilight_civil = map.addCircle(co);
I tried with a different radius value and actually it works with a specific one, here i created 3 circles with different radius values, and olny one is filled, the other two are not filled.
Here is the code for the circle that is filled correctly
LatLng center = new LatLng(-16.272425356472187,166.43807456511806);
double radius = 8006044.77150472;
CircleOptions co = new CircleOptions().center(center).clickable(false).radius((radius)).fillColor(Color.GREEN).visible(true);
this.marker_night = map.addCircle(co);
Could it be a issue with the too large radius? But on the web version is working well.
It could be because the radius is too large. Google Maps uses a Mercator projection, which will skew circles if they are large enough. For technical reasons, if the shape isn't "closed" then the fill won't be applied. If the shape is too large, or too close to the highly-skewed top or bottom of the map, then the shape will break open and the fill will be ignored.
If it was truly important you could try forcing a custom Projection on Google Maps (which could avoid the skew and keep the shape closed), but this isn't a well-tread path and I can't provide a solution beyond the link:
https://developers.google.com/maps/documentation/javascript/examples/map-projection-simple
The Google Map provides over its projection a method, which converts Point to Geo Position.
If I pass e.x. Point p = new Point(-1000,1000), I get a position like -89.3425,140.0345. The point is outside the visible region but I could not found any information if that method has a limitation to the current visible region.
Has someone a source code or more information about that ?
Create a Rect with the size of your MapView and use Rect.contains(x,y) to check if the given point is inside the MapView
Remember:
The screen location is specified in screen pixels (not display pixels)
relative to the top left of the map (not the top left of the whole
screen).
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
It's not easy explaining my problem but I will try.
I have an android GoogleMap, on top of it, I have an ImageView positioned at its center at all times. If I drag/pan the map, the pin will always be in the center of the GoogleMap.
Now, I add a marker, somewhere on the map. I want to zoom such that the center point remains in the center of the map, and the marker is visible within the map, and to the highest zoom level.
The problem is if I simply check if the marker is within boundaries of the map or not, and then keep zooming in/out till it is, this process will always repeat itself, i.e. trying to zoom in and if the marker became outside, then zoom out.
The problem is I rely on an OnCameraChange listener which will keep calling itself everytime I zoom in or out, hence, the process of zooming in/out will keep occuring indefinitely
journeyGoogleMap.setOnCameraChangeListener(new OnCameraChangeListener()
{
#Override
public void onCameraChange(final CameraPosition position)
{
Basically, what I need is a function where I can provide the center LatLng and the markerLatLng and it will automatically calculate the LatLngBounds making sure my center is within the center of the LatLng bounds, and then I can simply use
public static CameraUpdate newLatLngBounds (LatLngBounds bounds, int width, int height, int padding)
as shown in the link below
https://developers.google.com/maps/documentation/android/reference/com/google/android/gms/maps/CameraUpdateFactory#newLatLngBounds(com.google.android.gms.maps.model.LatLngBounds,int, int,int)
If you need anymore clarification please do tell me
You need to calculate LatLngBounds from two points:
Your marker position and
Place on the opposite side of your current center.
The second is calculated like this:
LatLng other = new LatLng(2 * center.latitude - position.latitude, 2 * center.longitude - position.longitude);
See LatLngBoundsUtils.fromCenterAndPositions for a general solution.
Use googleMap.getProjection().getVisibleRegion() to get all four corners of screen as LatLng values forming trapezium. Calculate where trapezium intersects with line drawn through center and your marker. Scale factor is (distance from center to marker / distance from center to intersection point). Now just scale trapezium with this scale factor relative to center. This is new visible regison.
You may also use getVisibleRegion().latLngBounds to simplify calculation, but note that some areas of returned rectangle are actually not visible.
i have 5 markers to display on the map, out of which 4 are very near to each other and the fifth one is a little bit distant to these 4. now when i display the map i want all these 5 markers to be shown on map and the with the highest possible zoom. i dont care whether they are on the border of the screen or in the center of the screen.i mean the markers can be scattered on the screen but all i want is that all markers should visible to the user and with the highest possible zoom.
i have tried this Android map v2 zoom to show all the markers . but the result is that it is showing all markers at the center of the map with very little zoom. actually i have calculated screen dimensions using this code.
DisplayMetrics metrics=new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
float height=metrics.heightPixels/metrics.xdpi;
float width=metrics.widthPixels/metrics.ydpi;
but i dont know why there is very little zoom. But wen i saw android documentation, i think the function is doing justice by doing whatever it said it will do.
public static CameraUpdate newLatLngBounds (LatLngBounds bounds, int width, int height, int padding)
Returns a CameraUpdate that transforms the camera such that the specified
latitude/longitude bounds are centered on screen within a bounding box of specified
dimensions at the greatest possible zoom level. You can specify additional padding,
to further restrict the size of the bounding box. The returned CameraUpdate has a
bearing of 0 and a tilt of 0.
Unlike newLatLngBounds(LatLngBounds, int), you can use the CameraUpdate returned by
this method to change the camera prior to the map's the layout phase, because the
arguments specify the desired size of the bounding box.
as it says it keeps all the markers at the center of the map. i do not want that. i want all the markers visible to the user with the maximum possible zoom and markers scattered. can anybody please help me?
Your calculation of float width and height is incorrect.
What your width holds now is inches (value of approx. 2 on phones). You need not to divide pixels width.