I am trying to create heart shape polygon on Google Map using current location. I am able to identify some LatLngs and tried to create heart shape but as expected curves are not showing.
Can you please help me out to create exact heart shape polygon using current location.
Here is code which I am using to create heart shape.
private static final int FRONT = 0;
private static final int RIGHT = 90;
private static final int LEFT = 270;
private void drawHeartPolygon(LatLng currentLatLng) {
LatLng destLatLang = GetDestinationPoint(currentLatLng, FRONT, 0.050F);
frontAngleCalculation(currentLatLng, destLatLang, 0.050F);
}
private void frontAngleCalculation(LatLng latLng, LatLng destLatLang, float distance) {
PolygonOptions rectOptions = new PolygonOptions();
LatLng centerLocation = GetDestinationPoint(latLng, FRONT, (distance + (distance/4)/2)/2);
LatLng rightLocation = GetDestinationPoint(centerLocation, RIGHT, distance/2);
LatLng leftLocation = GetDestinationPoint(centerLocation, LEFT, distance/2);
LatLng centerLeftLocation = GetDestinationPoint(destLatLang, LEFT, distance/4);
LatLng centerLeftTopLocation = GetDestinationPoint(centerLeftLocation, FRONT, (distance/4)/2);
LatLng centerRightLocation = GetDestinationPoint(destLatLang, RIGHT, distance/4);
LatLng centerRightTopLocation = GetDestinationPoint(centerRightLocation, FRONT, (distance/4)/2);
rectOptions.add(new LatLng(latLng.latitude, latLng.longitude),
leftLocation,
centerLeftTopLocation,
new LatLng(destLatLang.latitude, destLatLang.longitude),
centerRightTopLocation,
rightLocation);
Log.d(TAG, "Current Location : "+latLng);
rectOptions.strokeColor(Color.RED);
// Get back the mutable Polygon
Polygon polygon = mMap.addPolygon(rectOptions);
List<PatternItem> pattern = Arrays.<PatternItem>asList(
new Dot(), new Gap(20), new Dash(30), new Gap(20));
polygon.setStrokePattern(pattern);
polygon.setStrokeWidth(POLYGON_STROKE_WIDTH_PX);
polygon.setStrokeColor(strokeColor);
}
public static LatLng GetDestinationPoint(LatLng startLoc, float bearing, float depth) {
LatLng newLocation = null;
double radius = 6371.0; // earth's mean radius in km
double lat1 = Math.toRadians(startLoc.latitude);
double lng1 = Math.toRadians(startLoc.longitude);
double brng = Math.toRadians(bearing);
double lat2 = Math.asin(Math.sin(lat1) * Math.cos(depth / radius) + Math.cos(lat1) * Math.sin(depth / radius) * Math.cos(brng));
double lng2 = lng1 + Math.atan2(Math.sin(brng) * Math.sin(depth / radius) * Math.cos(lat1), Math.cos(depth / radius) - Math.sin(lat1) * Math.sin(lat2));
lng2 = (lng2 + Math.PI) % (2 * Math.PI) - Math.PI;
// normalize to -180...+180
if (lat2 == 0 || lng2 == 0) {
newLocation = new LatLng(0.0, 0.0);
} else {
newLocation = new LatLng(Math.toDegrees(lat2), Math.toDegrees(lng2));
}
return newLocation;
}
#Override
public void onMapReady(GoogleMap googleMap) {
Log.d(TAG, "onMapReady");
mMap = googleMap;
LatLng latLng = new LatLng(latitude, longitude);
mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.setMaxZoomPreference(22.0f);
mMap.setMinZoomPreference(17.0f);
drawHeartPolygon(new LatLng(latitude, longitude));
}
Here is screenshot which shows heart shape which I achieved but not as per expectation.
Please give me reference or hint which will draw heart shape polygon with curves.
I don't know whether you'll like this answer or not but this will work as your requirement and is easy as hell but different.
Just place a marker:
LatLng latLng1 = new LatLng(13.014849, 80.224343);
mMap.addMarker(new MarkerOptions().position(latLng1).title("Name").snippet("snippet").flat(true).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker1)));
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng1).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
Here, marker1.png is an image created through photoshop which will provide the same result.
Result:
Marker1.png:
As you can see marker1 here is a whole image containing the marker + the heart but you can also create two markers on same LatLng: 1st is the red marker and 2nd is the Heart. Using this way, infowindow will open only on clicking the red marker instead of the provided result as you can disable the heart's infowindow or you can use heart's infowindow for some other info.
As I said earlier this solution is different and isn't similar to custom shaped polygon but is super easy to achieve.
Related
I want to integrate this code into mine, but don't know how to get it to work.
I got problem with the return statement and then how to create a mark with randomly generated position?
Can you please tell me how to get the getRandomLocation() method working in creating markers?
public Location getRandomLocation() {
Location location = new Location("");
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
int radius = 10;
double x0 = latLng.latitude;
double y0 = latLng.longitude;
Random random = new Random();
// Convert radius from meters to degrees
double radiusInDegrees = radius / 111000f;
double u = random.nextDouble();
double v = random.nextDouble();
double w = radiusInDegrees * Math.sqrt(u);
double t = 2 * Math.PI * v;
double x = w * Math.cos(t);
double y = w * Math.sin(t);
// Adjust the x-coordinate for the shrinking of the east-west distances
double new_x = x / Math.cos(y0);
double foundLatitude = new_x + x0;
double foundLongitude = y + y0;
LatLng randomLatLng = new LatLng(foundLatitude, foundLongitude);
Location loc = new Location("");
loc.setLatitude(randomLatLng.latitude);
loc.setLongitude(randomLatLng.longitude);
//dont know what to return
return ;
}
public final void addMarker(GoogleMap mMap) {
//dont know how to get working the getRandomLocation())
mMap.addMarker( new MarkerOptions()
// .position(new LatLng(48.349723, 18.052405))
.position(getRandomLocation())
.title("krokodĂl")
.icon(BitmapDescriptorFactory.fromBitmap(resizeMapIcons("krokodil", 100, 100))));
mMap.addMarker(new MarkerOptions()
// .position(new LatLng(48.310025, 18.038878))
.position(getRandomLocation())
.icon(BitmapDescriptorFactory.fromBitmap(resizeMapIcons("fretka", 100, 100)))
.title("fretk"));
mMap.addMarker (new MarkerOptions()
.title("hroch")
.icon(BitmapDescriptorFactory.fromBitmap(resizeMapIcons("hroch", 100, 100)))
// .title()
//.snippet(mObj.getNumber(Configs.MONSTERS_MONSTER_POINTS) + " points")
// .position(new LatLng(48.318569, 18.055767)));
.position(getRandomLocation()));
}
According to the logic of your code, you need to return randomLatLng.
Change the line:
public Location getRandomLocation() {
to:
public LatLng getRandomLocation() {
and make the return statement something like:
return randomLatLng;
The method MarkerOptions.position() needs an object of type LatLng, that is what your IDE showing you as an error.
I want to rotate marker as per bearing or sensor value received from Accelerometer to show the user where actually he is moving. I have set marker icon and flat value to true but its not working as required.
mCurrentLocationMarker.position(new LatLng(
LocationUtils.sLatitude, LocationUtils.sLongitude));
mCurrentLocationMarker.icon(icon);
mCurrentLocationMarker.flat(true);
mCurrentLocationMarker.rotation(LocationUtils.sBearing);
if (currentMarker != null) {
currentMarker.setPosition(new LatLng(
LocationUtils.sLatitude,
LocationUtils.sLongitude));
} else {
currentMarker = mGoogleMap
.addMarker(mCurrentLocationMarker);
}
animateCameraTo(true);
I have used this as marker.
I don't know why its not rotating as per user's direction. If anyone has any idea please kindly help me where i am making mistake.
LocationUtils.sBearing is the value of Bearing which i received from onLocationChanged or accelerometer.
Basically I want to make my marker same as google maps marker which shows user in which direction they are moving or turning.
This is an old question and it appears the API has changed since then.
I'm assuming you are able to get the devices bearing. If not here is a handy tutorial.
First thing is to create a marker we can use for bearing updates.
private Marker marker;
// Create this marker only once; probably in your onMapReady() method
marker = mGoogleMap.addMarker(new MarkerOptions()
.position(new LatLng(myLatitude, myLongitude))
.flat(true));
Note the .flat(true) portion. The ensures our marker is north aligned so that our bearings will work correctly even if the user rotates the map.
Now when you get your bearing updates you can do the following
marker.setRotation(bearing);
// or if following the linked tutorial
// marker.setRotation((float) azimuth);
This assumes your marker icon has the forward direction at the top. If your marker is rotated like the one pictured, you will have to adjust the bearing to compensate before setting it to the marker. Just a simple setRotation(bearing - 45) should do it.
Im posting this answer because people like me who are searching for a solution related to the above question might find it useful.
So here how i did it.
As #colin said you must enable .flat(true) to rotate markers.
1.For bearing angle i have used the following code.
Here latLng1 - my old location && latLng2 - my new location
private double bearingBetweenLocations(LatLng latLng1,LatLng latLng2) {
double PI = 3.14159;
double lat1 = latLng1.latitude * PI / 180;
double long1 = latLng1.longitude * PI / 180;
double lat2 = latLng2.latitude * PI / 180;
double long2 = latLng2.longitude * PI / 180;
double dLon = (long2 - long1);
double y = Math.sin(dLon) * Math.cos(lat2);
double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1)
* Math.cos(lat2) * Math.cos(dLon);
double brng = Math.atan2(y, x);
brng = Math.toDegrees(brng);
brng = (brng + 360) % 360;
return brng;
}
2.To rotate marker using above bearing angle i have used this code
Here isMarkerRotating is a boolean value. Add isMarkerRotating = false in OnCreate method
private void rotateMarker(final Marker marker, final float toRotation) {
if(!isMarkerRotating) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final float startRotation = marker.getRotation();
final long duration = 2000;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
isMarkerRotating = true;
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed / duration);
float rot = t * toRotation + (1 - t) * startRotation;
float bearing = -rot > 180 ? rot / 2 : rot;
marker.setRotation(bearing);
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
isMarkerRotating = false;
}
}
});
}
}
3.using above code
LatLng oldLocation, newLocaation;
float bearing = (float) bearingBetweenLocations(oldLocation, newLocaation);
rotateMarker(start_marker, bearing);
In Kotlin by using Google SphericalUtil class we can get bearing by passing source and destination LatLngs like:
fun calculateBearing(lat1: Double, lng1: Double, lat2: Double, lng2: Double): Float {
val sourceLatLng = LatLng(lat1, lng1)
val destinationLatLng = LatLng(lat2, lng2)
return SphericalUtil.computeHeading(sourceLatLng, destinationLatLng).toFloat()
}
Then set this result 'bearing` to the marker like
Val bearing = calculateBearing(lat1, lng1, lat2, lng2)
marker.rotation(bearing)
Reference: https://developers.google.com/maps/documentation/android-sdk/utility/#spherical
Is there any possible way of finding radius of the visible map from the middle point?
I want to get the near places against the center point of the map from an API, and that API require lat,lng and radius. I am able to get lat and lng from center point but couldnt find a way to get radius .
thanks
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];
}
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:
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;
}
For the Kotlin users, call this function from setOnCameraIdleListener
private fun getMapVisibleRadius(): Double {
val visibleRegion: VisibleRegion = mMap.projection.visibleRegion
val distanceWidth = FloatArray(1)
val distanceHeight = FloatArray(1)
val farRight: LatLng = visibleRegion.farRight
val farLeft: LatLng = visibleRegion.farLeft
val nearRight: LatLng = visibleRegion.nearRight
val nearLeft: LatLng = 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)
val radiusInMeters = Math.sqrt((Math.pow(distanceWidth.get(0).toString().toDouble(), 2.0))
+ Math.pow(distanceHeight.get(0).toString().toDouble(), 2.0)) / 2
return radiusInMeters
}
edit: The following answer is for Google Maps JavaScript API v3
=-=-=-=-=-=-=
I think the answer would be: Yes, you can.
According to the documentation, you can calculate distance between 2 points by: computeDistanceBetween(LatLngFrom, LatLngTo)
Also you can get the boundary of the map by using getBounds() method, which is in the google.maps.Map class.
Is there a way to get the coordinates of the current area, which is shown at the device?
Background is, we want to show "nearby" places, which are stored in our own database. So let's say, the user looks at following clip of a map:
How do we get the longitude/latitude of the screen (or the point in the middle of the screen and a radius which covers everything?). Please keep in mind, center of the map is not usually the current position, since the user can move the center of the card!
Use map.getProjection().getVisibleRegion(). From VisibleRegion you can get LatLngBounds, which is easy to work with. You may also try directly with the region, which might be trapezoid.
I found the solution for Google Map API v2 from few of responses:
stackoverflow#1 and
stackoverflow#2
So, need implements Activity from GoogleMap.OnCameraChangeListener interface
private static final int REQUEST_CODE_GOOGLE_PLAY_SERVECES_ERROR = -1;
private static final double EARTH_RADIOUS = 3958.75; // Earth radius;
private static final int METER_CONVERSION = 1609;
private GoogleMap mGoogleMap;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(mContext);
if (status != ConnectionResult.SUCCESS)
{
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, activity,
REQUEST_CODE_GOOGLE_PLAY_SERVECES_ERROR);
dialog.show();
mGoogleMap = null;
}
else
{
mGoogleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(
R.id.fragment_shops_layout_maps_fragment)).getMap();
mGoogleMap.setOnCameraChangeListener(this);
}
}
The listener, that working when map scaled. Determin as LatLng the positions of bottom left, bottom right, top left and top right sides of map, that showing on screen. By greatest side of screen and two points we can get radius from center of map.
#Override
public void onCameraChange(CameraPosition cameraPosition)
{
// Listener of zooming;
float zoomLevel = cameraPosition.zoom;
VisibleRegion visibleRegion = mGoogleMap.getProjection().getVisibleRegion();
LatLng nearLeft = visibleRegion.nearLeft;
LatLng nearRight = visibleRegion.nearRight;
LatLng farLeft = visibleRegion.farLeft;
LatLng farRight = visibleRegion.farRight;
double dist_w = distanceFrom(nearLeft.latitude, nearLeft.longitude, nearRight.latitude, nearRight.longitude);
double dist_h = distanceFrom(farLeft.latitude, farLeft.longitude, farRight.latitude, farRight.longitude);
Log.d("DISTANCE: ", "DISTANCE WIDTH: " + dist_w + " DISTANCE HEIGHT: " + dist_h);
}
Return distance between 2 points, stored as 2 pair location at meters;
public double distanceFrom(double lat1, double lng1, double lat2, double lng2)
{
// Return distance between 2 points, stored as 2 pair location;
double dLat = Math.toRadians(lat2 - lat1);
double dLng = Math.toRadians(lng2 - lng1);
double a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(Math.toRadians(lat1))
* Math.cos(Math.toRadians(lat2)) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double dist = EARTH_RADIOUS * c;
return new Double(dist * METER_CONVERSION).floatValue();
}
If you want get radius of area, that showed on screen just need devided by 2.
I hope will useful !
This calculates the radio in km based on the map width:
public double calculateVisibleRadius() {
float[] distanceWidth = new float[1];
VisibleRegion visibleRegion = map.getProjection().getVisibleRegion();
LatLng farRight = visibleRegion.farRight;
LatLng farLeft = visibleRegion.farLeft;
LatLng nearRight = visibleRegion.nearRight;
LatLng nearLeft = visibleRegion.nearLeft;
//calculate the distance between left <-> right of map on screen
Location.distanceBetween( (farLeft.latitude + nearLeft.latitude) / 2, farLeft.longitude, (farRight.latitude + nearRight.latitude) / 2, farRight.longitude, distanceWidth );
// visible radius is / 2 and /1000 in Km:
return distanceWidth[0] / 2 / 1000 ;
}
I have a map included in an application. I need the map to zoom in on the a marker and the users location but keep the marker centered. The zoom in works perfectly, but of course doesn't center the marker on the map.
#Override
public void onLocationChanged(Location location) {
if (mListener != null) {
mListener.onLocationChanged(location);
LatLngBounds bounds = new LatLngBounds.Builder()
.include(new LatLng(location.getLatitude(),location.getLongitude()))
.include((new LatLng(52.3563, 4.8790)))
.build();
mMap.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 35));
}
}
What is the best way to keep both within the bounds but keep the marker centered? I can't seem to find a solution in the official documentation.
There are two functions I would call, one for centering the marker and an other one to zoom on the map until your current location is still visible.
My solution for zooming to a point with a 15 zoom level:
myMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLngToCenter, 1));
zooming until all markers are still visible (change code to fit the marker and your position instead):
public void fitZoomAndPositionToMapByMarkers() {
int minLat = Integer.MAX_VALUE;
int maxLat = Integer.MIN_VALUE;
int minLon = Integer.MAX_VALUE;
int maxLon = Integer.MIN_VALUE;
List<MyMapMarker> markersShownOnMap = getMarkersToShow();
for (MyMapMarker item : markersShownOnMap) {
int lat = (int) (item.getLatitude() * 1E6);
int lon = (int) (item.getLongitude() * 1E6);
maxLat = Math.max(lat, maxLat);
minLat = Math.min(lat, minLat);
maxLon = Math.max(lon, maxLon);
minLon = Math.min(lon, minLon);
}
double latitudeToGo = (maxLat + minLat) / 1E6 / 2;
double longitudeToGo = (maxLon + minLon) / 1E6 / 2;
LatLng toCenter = new LatLng(latitudeToGo, longitudeToGo);
centerCameraToProperPosition(toCenter);
LatLng southWestLatLon = new LatLng(minLat / 1E6, minLon / 1E6);
LatLng northEastLatLon = new LatLng(maxLat / 1E6, maxLon / 1E6);
zoomInUntilAllMarkersAreStillVisible(southWestLatLon, northEastLatLon);
}
Hope this helps!
private void zoomInUntilAllMarkersAreStillVisible(final LatLng southWestLatLon, final LatLng northEastLatLon) {
myMap.setOnCameraChangeListener(new OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition arg0) {
myMap.moveCamera(CameraUpdateFactory.newLatLngBounds(new LatLngBounds(southWestLatLon, northEastLatLon), 50));
myMap.setOnCameraChangeListener(null);
}
});
}
Hello i have found a nice and easy way using LatLngbounds:
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(new LatLngBounds(latlngSW, latlngNE, 50));
this function will use the most SW point and the most NE point to create a rectangle to center the view with 50 padding, but u need to check first which one of the points should be given as first or second parameter, here is my code:
public void centerMap(LatLng latLng){
if(fenceMarker != null){
LatLngBounds center;
LatLng fence = fenceMarker.getPosition();
if(fence.latitude < latLng.latitude || fence.longitude < latLng.longitude)
center = new LatLngBounds(fenceMarker.getPosition(), latLng);
else{
center = new LatLngBounds(latLng, fenceMarker.getPosition());
}
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(center, 50));
}
}
The 2 points are my position latLng and the marker I have for the GeoFence, fenceMarker.
I call this function centerMap(latLng) from the onLocationChanged():
#Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
centerMap(latLng);
}
Setting Boundaries -
An overload of the method, newLatLngBounds(boundary, width, height, padding) allows you to specify a width and height in pixels for a rectangle, with the intention that these correspond to the dimensions of the map. The rectangle is positioned such that its center is the same as that of the map's view (so that if the dimensions specified are the same as those of the map's view, then the rectangle coincides with the map's view). The returned CameraUpdate will move the camera such that the specified LatLngBounds are centered on screen within the given rectangle at the greatest possible zoom level, taking into account the padding required.
Reference- https://developers.google.com/maps/documentation/android/views#target_location