How to get center of map for v2 android maps? - android

In Google Maps for Android v1, MapView had a convenience method:
getMapCenter(). Now I cannot figure out how to get map center with v2 of this api. I have perused the API documentation, but there is no mention of such a feature. Please advise.
Thanks,
Igor

I had the same problem. It seems you can get the center this way:
mMap.getCameraPosition().target
where mMap is the GoogleMap instance from your activity. This will return a LatLng object which basically represents the center of the map.
Note that the GeoPoint class is not available anymore.
According to http://developer.android.com/reference/com/google/android/gms/maps/model/CameraPosition.html
target is "The location that the camera is pointing at." (I tested it with the sample code and it worked okay for me)

I have found two ways of do this:
1) The easiest, The first is using the target property in the Map's CameraPosition Object
LatLng center = mMap.getCameraPosition().target;
2) The second is using a VisibleRegion object:
VisibleRegion visibleRegion = mMap.getProjection()
.getVisibleRegion();
Point x = mMap.getProjection().toScreenLocation(
visibleRegion.farRight);
Point y = mMap.getProjection().toScreenLocation(
visibleRegion.nearLeft);
Point centerPoint = new Point(x.x / 2, y.y / 2);
LatLng centerFromPoint = mMap.getProjection().fromScreenLocation(
centerPoint);
I have compared both answers:
Log.d("MapFragment: ", "Center From camera: Long: " + center.longitude
+ " Lat" + center.latitude);
Log.d("Punto x", "x:" + x.x + "y:" + x.y);
Log.d("Punto y", "y:" + y.x + "y:" + y.y);
Log.d("MapFragment: ", "Center From Point: Long: "
+ centerFromPoint.longitude + " Lat"
+ centerFromPoint.latitude);

You can use :
latlng=map.getProjection().getVisibleRegion().latLngBounds.getCenter();

to get center of map I used onMapReady() method in activity, then used googleMap.setOnCameraChangeListener() method to get position of Came:
#Override
public void onMapReady(GoogleMap googMap) {
googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.i("centerLat",cameraPosition.target.latitude);
Log.i("centerLong",cameraPosition.target.longitude);
}
});
}

If you only want to get the position once (e.g. after the user has stopped panning the map), use setOnCameraIdleListener:
https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap.OnCameraIdleListener
mMap.setOnCameraIdleListener(new GoogleMap.OnCameraIdleListener() {
#Override
public void onCameraIdle() {
LatLng position = mMap.getCameraPosition().target;
Log.d("MapActivity", "Position: " + position);
}
});
or using a Java 8 lambda:
mMap.setOnCameraIdleListener(() -> {
LatLng position = mMap.getCameraPosition().target;
Log.d("MapActivity", "Position: " + position);
});
Note that the listener registered with setOnCameraChangeListener is called many times, and as the documentation states:
This may be called as often as once every frame and should not perform expensive operations.

best way use cameraPosition
java:
LatLng centerMap = googleMap.getCameraPosition().target;
kotlin:
googleMap?.cameraPosition?.target?.let {
// it is LatLng center
}

Related

Drawable icons on route not pinned at base

I am using drawable images for marker icons on a route. The base of the image does not appear at the point but rather more in the middle.
Can this be addressed?
Double latitude = new Double(getString(R.string.sagrada_latitude));
Double longitude = new Double(getString(R.string.sagrada_longitude));
final Position origin = Position.fromCoordinates(longitude, latitude);
latitude = new Double(getString(R.string.mataro_latitude));
longitude = new Double(getString(R.string.mataro_longitude));
final Position destination = Position.fromCoordinates(longitude, latitude);
// Create an Icon object for the marker to use
IconFactory iconFactory = IconFactory.getInstance(this);
Drawable iconDrawable = ContextCompat.getDrawable(this, R.drawable.green_pin);
final Icon greenPinIcon = iconFactory.fromDrawable(iconDrawable);
iconDrawable = ContextCompat.getDrawable(this, R.drawable.red_pin);
final Icon redPinIcon = iconFactory.fromDrawable(iconDrawable);
// Setup the MapView
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(MapboxMap mapboxMap) {
map = mapboxMap;
// Add origin and destination to the map
LatLng originLatLng = (new LatLng(origin.getLatitude(), origin.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(originLatLng)
.title("Origin")
.snippet("current location: (" + origin.getLatitude() + ", " + origin.getLongitude() + ")")
.icon(greenPinIcon));
Log.d(TAG, "getMapAsync(): destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")");
LatLng destinationLatLng = (new LatLng(destination.getLatitude(), destination.getLongitude()));
mapboxMap.addMarker(new MarkerOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
mapboxMap.easeCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, 50), 5000);
// Get route from API
try {
getRoute(origin, destination);
}
catch (ServicesException servicesException) {
Log.e(TAG, servicesException.toString());
servicesException.printStackTrace();
}
}
});
}
private void getRoute(Position origin, Position destination) throws ServicesException {
client = new MapboxDirections.Builder()
.setOrigin(origin)
.setDestination(destination)
.setProfile(DirectionsCriteria.PROFILE_CYCLING)
.setAccessToken(MapboxAccountManager.getInstance().getAccessToken())
.build();
client.enqueueCall(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
} else if (response.body().getRoutes().size() < 1) {
Log.e(TAG, "No routes found");
return;
}
// Print some info about the route
currentRoute = response.body().getRoutes().get(0);
Log.d(TAG, "Distance: " + currentRoute.getDistance());
Double km = currentRoute.getDistance() / 1000;
// there are 4 digits to the right of the decimal, make it 2
String kilometers = km.toString();
int index = kilometers.lastIndexOf(".");
kilometers = kilometers.substring(0, index + 3);
Toast.makeText(
DirectionsActivity.this,
"Route is " + kilometers + " kilometers",
Toast.LENGTH_SHORT).show();
// Draw the route on the map
drawRoute(currentRoute);
}
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable) {
Log.e(TAG, "Error: " + throwable.getMessage());
Toast.makeText(DirectionsActivity.this, "Error: " + throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
A side question ... the Position.fromCoordinates method:
private Position(double longitude, double latitude, double altitude)
takes the arguments in order of longitude then latitude, not latitude then longitude as one might expect. Why?
Edit:
Changed MarkerOptions to MarkerViewOptions and the icons moved even further away. Also tried .anchor(0,0) which had no effect.
Also, with default Icons (which are off):
Icon:
// Mapbox dependencies
compile('com.mapbox.mapboxsdk:mapbox-android-sdk:4.1.1#aar') {
transitive = true
}
compile ('com.mapbox.mapboxsdk:mapbox-android-directions:1.0.0#aar'){
transitive=true
}
compile('com.mapbox.mapboxsdk:mapbox-android-services:1.3.1#aar') {
transitive = true
}
You either need to add padding to the bottom of the marker icon png or a better option would be using MarkerViewOptions() instead. They give more options then the GL markers your currently using including anchor. By default the anchoring is center bottom. So one of you markers would look like this:
mapboxMap.addMarker(new MarkerViewOptions()
.position(destinationLatLng)
.title("Destination")
.snippet("destination: (" + destination.getLatitude() + ", " + destination.getLongitude() + ")")
.icon(redPinIcon));
To answer your other question, why position takes in longitude, latitude in that order, many of the Mapbox APIs consume coordinates in that order. The bigger question is why does the Position object exist when LatLng is found already in the Map SDK? This is because the objects would conflict since they are found in separate SDKs yet are typically used together. It is something we look forward to changing in the near future.
EDIT: first you need to remove the mapbox-android-directions, this is an old, non supported, SDK we have deprecated. Mapbox Android Services (MAS) is it's replacement and uses Mapbox Directions V5. Use this example which shows how to properly make a directions call using MAS and add the markers to the map. Using the coordinates found in your question, the result looks like this:

How to get polyline latitude and longitude by click on polyline android?

I have set Polyline click listener like this :
map.setOnPolylineClickListener(new GoogleMap.OnPolylineClickListener() {
public void onPolylineClick(Polyline polyline) {
int strokeColor = polyline.getColor() ^ 0x0000CC00;
polyline.setColor(strokeColor);
Log.e("TAG", "Polyline points # " + polyline.getPoints());
Toast.makeText(Draw_Route.this, "Polyline klick: " + polyline.getPoints(), Toast.LENGTH_LONG).show();
}
});
But i need to get coordinates of that point when user click on polyline, i also used this code to get the codrinates -- >
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng clickCoords) {
Log.e("TAG", "Found # " + clickCoords.latitude + " " + clickCoords.longitude);
}
});
But it only works when i click on map, i need to get that point coordinates on click on polyline so please help me, how to get that.
Thanks

How to get the latitude and longitude of location where user taps on the map in android

In my Android application, I'm using google maps v2 to show map by getting the latitute and longitude of the device's current location And I'm showing pin on that location.
Now when user clicks or taps on any other location on the map, then I have to get that points latitude and longitude and i have to set the pin at that location.
Could you please tell me how get the latitude and longitude of the user taps/clicks location.
An example of what i use. Change it accordingly for your needs. I use it with long press.
map.setOnMapLongClickListener(new OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng point) {
map.addMarker(new MarkerOptions().position(point).title("Custom location").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));enter code here
}
});
the LatLng point contains the coordinated of the longpress
Try to use google-maps v2 built-in method.
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng position) {
Toast.makeText(context,position.latitude+" : "+position.longitude,Toast.LENGTH_SHORT).show();
}
});
Try the following.
Write a class which derives from the Overlay class and override the onTap() method. Then you can add your overlay to the your MapView. A GeoPoint object, which represents the position of you tap, is passed to the onTap() method when you tab somewhere on the map.
OR
The modern answer here, using Android Maps v2, is to use OnMapClickListener, which gives you the LatLng of a tap on the map.
// Setting onclick event listener for the map
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
// Creating MarkerOptions
MarkerOptions options = new MarkerOptions();
// Setting the position of the marker
options.position(point);
//Get LatLng from touched point
double touchLat=point.latitude;
double touchLong=point.longitude;
///here is reverse GeoCoding which helps in getting address from latlng
try {
Geocoder geo = new Geocoder(MainActivity.this.getApplicationContext(), Locale.getDefault());
List<Address> addresses = geo.getFromLocation(touchLat,touchLong, 1);
if (addresses.isEmpty()) {
Toast.makeText(getApplicationContext(),"Waiting for Location",Toast.LENGTH_SHORT).show();
}
else {
if (addresses.size() > 0) {
address =addresses.get(0).getFeatureName()
+ ", " + addresses.get(0).getLocality()
+ ", " + addresses.get(0).getAdminArea()
+ ", " + addresses.get(0).getCountryName();
Toast.makeText(getApplicationContext(), "Address:- " +address, Toast.LENGTH_LONG).show();
}
// draws the marker at the currently touched location
drawMarker(point,"Your Touched Position",address+"");
}
}
catch (Exception e) {
e.printStackTrace(); // getFromLocation() may sometimes fail
}

MarkerOptions position() set value is different from Marker getPosition() in Android

In my Android application, I'm using Google Map to point some locations. But what I mark as latitude and longitude value is different from what I'm getting when click on a Marker. Here is the relevant code
import com.google.android.gms.maps.GoogleMap;
public class MyClass extends SupportMapFragment{
private GoogleMap mMap;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mMap = getMap();
myMethod();
mMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
LatLng latLng = marker.getPosition();
Log.d(TAG, "# latLng.latitude : " + latLng.latitude + " # latLng.longitude : " + latLng.longitude);
/*
* Print for the above Log statement is
*
* # latLng.latitude : 45.446733371796135 # latLng.longitude : 6.97720717638731
*
*/
}
}
}
private void myMethod(){
MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(coords.getDouble(1), coords.getDouble(0)));
Log.d(TAG, "# latitude : " + coords.getDouble(1) + " # longitude : " + coords.getDouble(0));
/*
* Print for the above Log statement is
*
* # latitude : 45.44673337246575 # longitude : 6.977207233013699
*
*/
}
}
Those printing values are almost same but not exactly. Can I know why is that? Because I need to get the exact value I'm feeding to the Map when I click on a particular Marker. If it is because how I include the value to the Map, how should I change it?
This sounds like the same bug as here:
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5353
As one commentor pointed out, the LatLng's are being flattened to floats and when retrieving them to doubles again they lose their precision.
I found that getting the lat/lngs into strings and stripping everything but the first 8 characters before comparing them seems to work:
String lat1 = String.valueOf(marker.latitude).substring(0, 8);

How to get Current Lat Lng position on GMAPS API V3?

I'm trying to calculate my route, from my current position to the specific location (var: end). How I suppose to get my LatLng from my current position ? Thx
Here's my Code :
function calcRoute() {
var start = "How to get this LatLng ?";
var end = new google.maps.LatLng(-6.28529,106.871542);
var request = {
origin:start,
destination:end,
travelMode: google.maps.TravelMode.WALKING
};
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(result);
}
});
}
If you have a Location object (lets call it location), all you need to do is LatLng mLatLng = new LatLng(location.getLatitude(), location.getLongitude()) and you will have a LatLng object. location.getLatitude() returns a double corresponding to the latitude in degrees and location.getLongitude() returns the same but for longitude. See the documentation for more details: http://developer.android.com/reference/android/location/Location.html

Categories

Resources