I have 2 LatLng, usually a few kilometers apart, and I want to zoom map such that both points are visible. My code below sometimes works, sometimes not (map is zoomed to level 3 then). I think the reason is that the loop is too fast for the map to make the necessary adjustments in time.
Is there a way to wait for the map to update before making the test again? To note that process runs on UI thread
double x1=from.latitude;
double x2= to.latitude;
double x1half=(x1+x2)/2;
x1=from.longitude;
x2= to.longitude;
double x2half=(x1+x2)/2;
LatLng pp=new LatLng(x1half, x2half);
map.moveCamera(CameraUpdateFactory.newLatLng(pp));//3.0
//now zoom map so that both points are in
double zoom=21;//V3.3
while(zoom>2){//
map.animateCamera( CameraUpdateFactory.zoomTo( (float) zoom ) );
if(isCurrentLocationVisible(from,map)&&isCurrentLocationVisible(to,map)) return;
/now we know map is still not visible. give it a bit more room
zoom--;
}
I'd advice you to use the newLatLngBounds() instead..You can create your bounds from your two geo points with the LatLngBounds.builder().
To the second part of your question..You could do somethink like map.post(new Runnable..) which could solve the concurrency issue.
You can use LatLngBounds like the following:
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(locationOne);
builder.include(locationTwo);
LatLngBounds bounds = builder.build();
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds,screen width, screen height, padding);
map.moveCamera(cu);
Related
I've looked at everything I can find on this, and haven't found a solution. I'm trying to do something very simple:
protected void moveCamera(final LatLng position, final float zoom) {
getMap(new OnMapReadyCallback() {
#Override
public void onMapReady(final GoogleMap googleMap) {
logger.debug("Moving map to " + position);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(position)
.zoom(zoom)
.build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
});
}
Nothing happens. No errors, no camera movement. I've also tried moveCamera instead. I've tried different types of calls to CameraUpdateFactory, I've tried moving and zooming separately, I've tried posting with a Handler with a delay. Sometimes this works perfectly, but if I leave the fragment with the map and come back, then it doesn't work. The map resets to latitude 0,0 and standard map type (it was set to hybrid) and I can't get it to do anything. I know the method is getting called by logging statements. Is there some kind of lifecycle thing I need to do to make sure the map can be restored?
I'd really prefer not to switch to Mapbox or something because that would be a lot of work to fix a little bug, but I need this to work correctly.
Try this code for this camera issue.
You can change zoom level, radius.
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
height = Math.round(0.45f*height);
int padding = (int) (width * 0.10);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
LatLngBounds bounds = builder.include(new LatLng(INSERT_LAT,
INSERT_LNG)).build();
CameraUpdate cameraUpdate =
CameraUpdateFactory.newLatLngBounds(bounds,width,height,padding);
googleMap.moveCamera(cameraUpdate);
googleMap.animateCamera(CameraUpdateFactory.zoomTo(14), 1000, null);
I've used the following and it works fine:
GoogleMap mGoogleMap;
LatLngBounds bounds = builder.build();
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
height = Math.round(0.45f*height);
int padding = (int) (width * 0.10);
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds,width,height,padding);
// Add this where you want to move map camera
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng("<pass_LatLng_here"));
mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(14)); //set the zoom level here
For me, the move camera inside the onPlaceSelected callback in Places Autocomplete api doesn't work.
I moved the moveCamera into a runOnUiThread and it's now working fine.
I am working on an Android app and I have two markers i want to place on a google map. The idea is that the user can see the two locations at a glance without having to interact with the map.
LatLngBounds.Builder b = new LatLngBounds.Builder();
b.include(userPos);
b.include(cardPos);
LatLngBounds bounds = b.build();
int width = (int) (0.7 * infoView.getWidth());
int height = (int) (0.7 * mapView.getHeight());
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, width, height, 5);
googleMap.animateCamera(cu);
The code works fine when the two locations are not very far apart. But when the locations are, for example, Singapore and USA, the two markers cannot be seen together.
I have tried to manually set the zoom level to 0 with the same result.
Is there any way that I can show the entire world map on the android device at once (i.e without the need for scrolling on the user's part)?
Update:
I have tried setting the map to zoom level 0 explicitly. The map does not fit the View I have created. Is it not possible to have the full world view of the map on the screen?
You should use the CameraUpdate class to do (probably) all programmatic map movements.
To do this, first calculate the bounds of all the markers like so:
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
Then obtain a movement description object by using the factory: CameraUpdateFactory:
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
Finally move the map:
googleMap.moveCamera(cu);
Or if you want an animation:
googleMap.animateCamera(cu);
That's all :)
How to show only a specific region/area in google map for android api v2?.all functionalities must be available in that region like zooming,dragging etc.
the all other areas must be cropped off or invisible. Is that possible???
I am using eclipse.help me please
This trick worked for me
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//get latlong for corners for specified place
LatLng one = new LatLng(27.700769, 85.300140);
LatLng two = new LatLng(27.800769, 85.400140);
LatLngBounds.Builder builder = new LatLngBounds.Builder();
//add them to builder
builder.include(one);
builder.include(two);
LatLngBounds bounds = builder.build();
//get width and height to current display screen
int width = getResources().getDisplayMetrics().widthPixels;
int height = getResources().getDisplayMetrics().heightPixels;
// 20% padding
int padding = (int) (width * 0.20);
//set latlong bounds
mMap.setLatLngBoundsForCameraTarget(bounds);
//move camera to fill the bound to screen
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, width, height, padding));
//set zoom to level to current so that you won't be able to zoom out viz. move outside bounds
mMap.setMinZoomPreference(mMap.getCameraPosition().zoom);
}
To show only specific area or region then you can use Polygons.
Polygon objects are similar to Polyline objects in that they consist of a series of coordinates in an ordered sequence. However, instead of being open-ended, polygons are designed to define regions within a closed loop with the interior filled in.
You can add a Polygon to the map in the same way as you add a Polyline. First create a PolygonOptions object and add some points to it. These points will form the outline of the polygon. You then add the polygon to the map by calling GoogleMap.addPolygon(PolygonOptions) which will return a Polygon object.
Visit this page on how to use Polygon.
Currently I work with Google-Map-v2 and I want to show Direction between two Markers. Everything is ok and direction between two Markers calculate and draw fine.But only one problem is remain.
The problem is Zoom level between these two markers in Google-Map is too much. I Search in SO and find a solution for changing Zoom Level by Following code :
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(origin);
builder.include(dest);
LatLngBounds bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 50);
mMap.animateCamera(cu);
Now it's better But still zoom level is not good. Is it possible to do some fixes on Code ? ( if I can some padding to view is fixed )
I Also change 50 to 6,12,... But nothing changed.
You are using the correct code, and the value (50) needs to be increased if you want to zoom less (be outer) or decreased to 0 if you want to be in the smallest area containing the two markers (you can skip the value in case).
If you set a value of 150 or more, and the level is too much you can use the animation callback to zoom out after the LatLng zoom:
Google API
com.google.android.gms.maps.GoogleMap.CancelableCallback)
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(origin);
builder.include(dest);
LatLngBounds bounds = builder.build();
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, 50);
mMap.animateCamera(cu, new GoogleMap.CancelableCallback(){
void onCancel(){}
void onFinish(){
CameraUpdate zout = CameraUpdateFactory.zoomBy(-3.0);
mMap.animateCamera(zout);
}
});
This should zoom to the LatLng and when finished, zoom back of 3 levels.
try this:
CameraPosition cameraPosition =
new CameraPosition.Builder()
.target(yourlatlng)
// .bearing(targetBearing)// you can ignore it
.zoom(12)// your zoom value
// .tilt(40) // angle of view
.build();
mMap.animateCamera(
CameraUpdateFactory.newCameraPosition(cameraPosition),
500,
null);
I have two geo points that vary intermittently, and want the MapView to resize and translate to make sure both points are always visible. I can easily re-centre the map on the point mid-way between the two, but how do I set the zoom level to ensure my two points are visible?
Check out his answer in a different post:
Google Map V2 how to set ZoomToSpan?
It solves it without much hassle. Note that you can only use that function AFTER the map has been loaded at least once. If not use function with specified map size on screen
LatLngBounds bounds = new LatLngBounds.Builder()
.include(new LatLng(CURRENTSTOP.latitude, CURRENTSTOP.longitude))
.include(new LatLng(MYPOSITION.latitude, MYPOSITION.longitude)).build();
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getSize(displaySize);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, displaySize.x, 250, 30));
Works like a charm and very dynamic!
Try this and see:
double latitudeSpan = Math.round(Math.abs(firstLat -
secLat));
double longitudeSpan = Math.round(Math.abs(firstLong -
secLong));
double currentLatitudeSpan = (double)mapView.getLatitudeSpan();
double currentLongitudeSpan = (double)mapView.getLongitudeSpan();
double ratio = currentLongitudeSpan/currentLatitudeSpan;
if(longitudeSpan < (double)(latitudeSpan+2E7) * ratio){
longitudeSpan = ((double)(latitudeSpan+2E7) * ratio);
}
mapController.zoomToSpan((int)(latitudeSpan*2), (int)(longitudeSpan*2));
mapView.invalidate();
in the new Maps API (v2) you can do it this way:
LatLng southwest = new LatLng(Math.min(laglng1.latitude, laglng2.latitude), Math.min(laglng1.longitude, laglng2.longitude));
LatLng northeast = new LatLng(Math.max(laglng1.latitude, laglng2.latitude), Math.max(laglng1.longitude, laglng2.longitude));
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(new LatLngBounds(southwest, northeast),500,500, 0));