Android Google Map show markers on zoom change - android

Guys I have to show markers on google maps with zoom.When user zoom in or zoom out markers will be visible covering the map area which is on the screen.How can I do this using Android google map?

Okay so you can use a CameraChangeListener:
private HashMap<Integer, Marker> courseMarkers = new HashMap<Integer, Marker>();
//all your visible markers
ArrayList<Item> yourMarkerList = new ArrayList<Item>();
//method to add all your markers with unique ids
addItemsToMap(); //first call to initially show the markers you want
googleMap.setOnCameraChangeListener(new OnCameraChangeListener() {
private float currentZoom = -1; //keep track of your current zoom level
#Override
public void onCameraChange(CameraPosition camera) {
if (camera.zoom != currentZoom){
currentZoom = camera.zoom;
//here you will then check your markers
addItemsToMap(yourMarkerList);
}
}
});
You will need a class Item that has a variable for a unique int id and a MarkerOptions
private void addItemsToMap(List<Item> items)
{
if(this.mMap != null)
{
//This is the current user-viewable region of the map
LatLngBounds bounds = this.mMap.getProjection().getVisibleRegion().latLngBounds;
//Loop through all the items that are available to be placed on the map
for(Item m : item)
{
//If the item is within the the bounds of the screen
if(bounds.contains(item.getMarker().getPosition()))
{
//If the item isn't already being displayed
if(!courseMarkers.containsKey(item.getId()))
{
//Add the Marker to the Map and keep track of it with the HashMap
//getMarkerForItem just returns a MarkerOptions object
this.courseMarkers.put(item.getId(), this.googleMap.addMarker(item.getMarker())); //getmarkerforitem
}
}
//If the marker is off screen
else
{
//If the course was previously on screen
if(courseMarkers.containsKey(item.getId()))
{
//1. Remove the Marker from the GoogleMap
courseMarkers.get(item.getId()).remove();
//2. Remove the reference to the Marker from the HashMap
courseMarkers.remove(item.getId());
}
}
}
}
}
This should do it

private void pointToPosition(LatLng position) {
//Build camera position
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(position)
.zoom(15).build();
//Zoom in and animate the camera.
mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}

Related

Android: Google Maps Clustermanager behaves weirdly. The cluster icon does not go away sometimes on full zoom. Why?

I wrote the following method to display my markers (clustered). However, some of the clusters work fine - i.e. when I zoom in, the blue cluster icon (that says 10+ for ex) goes away and reveals the individual markers.
However, some times, when I zoom in fully, the blue cluster marker is still displayed on full zoom ALONG with one of the individual markers. Why is this happening?
private void displayCluster(List<MyItem> items) {
mClusterManager = new ClusterManager<MyItem>(this, googleMap);
mClusterManager.setRenderer(new MyRender(getApplicationContext(),googleMap,mClusterManager));
googleMap.setOnCameraChangeListener(mClusterManager);
googleMap.setOnMarkerClickListener(mClusterManager);
for (MyItem item : items) {
mClusterManager.addItem(item);
}
}
DefaultClusterRenderer decides whether the markers should be clustered or not.This class contains DefaultClusterRenderer#shouldRenderAsCluster() method - in which the clustering starts only when size of cluster is > MIN_CLUSTER_SIZE. Default value of MIN_CLUSTER_SIZE is 4.
You need to extend DefaultClusterRenderer class and override shouldRenderAsCluster() method to provide your own logic:
class CustomRenderer<T extends ClusterItem> extends DefaultClusterRenderer<T>
{
public CustomRenderer(Context context, GoogleMap map, ClusterManager<T> clusterManager) {
super(context, map, clusterManager);
}
#Override
protected boolean shouldRenderAsCluster(Cluster<T> cluster) {
//start clustering if at least 2 items overlap
//Change your logic here
return cluster.getSize() > 1;
}
}
private void setUpMapIfNeeded() {
if (mMap != null) {
return;
}
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
if (mMap != null) {
mClusterManager = new ClusterManager<Place>(this, mMap);
mClusterManager.setRenderer(new CustomRenderer<Place>(this, mMap, mClusterManager));
........
}
}

Make Google Maps Markers draggable within region/area?

I am creating markers based on my location and I would like to make the markers draggable within 1km of that location.
So, basically I want to know how to make a marker draggable within a certain area/region only and not the entire map.
Thank you
You have to define bounds and check if the new position is outside the bounds in the onDragListener of the marker: if the new position is outside the bounds you can reset the marker to the last valid position or do whatever you want.
To match if the marker is-or-not inside the bounds you must use the method contains of the LatLngBounds object.
Something like this:
LatLngBounds bounds;
LatLngBounds.Builder builder = new LatLngBounds.Builder();
// You construct your bounds in a way like this
builder.include(new LatLng(latitude1, longitude1));
builder.include(new LatLng(latitude2, longitude2));
builder.include(new LatLng(latitude3, longitude3));
// etc
bounds = builder.build();
googleMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
}
#Override
public void onMarkerDragEnd(Marker marker) {
if (bounds.contains(marker.getPosition())) {
// cast your spell
} else {
// you can't drag here
}
}
});

Android : If markers are overlapping each other on the map, then the click event is fired for the last hidden one

In our application, a lot of markers are drawn in different locations and in certain cases at a certain zoom level, markers overlap each other. So when I click on the marker, I expect the top marker's onMarkerClick to be fired but instead it is fired for the last hidden marker i-e the last marker, with no markers behind it.
What do you suggest I do? Also, I have no info windows, therefore I return true from onMarkerClick method.
I found the solution here: https://github.com/googlemaps/android-maps-utils/issues/26
mGoogleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
// Empty info window.
return new View(getApplicationContext());
}
#Override
public View getInfoContents(Marker marker)
{
return null;
}
});
Identify the size of your maker relative to the overall screen (e.g. 10%). Define this as a float called IMAGE_SIZE_RATIO
Maintain List markers as you add markers to your map. In your OnMarkerClickListener onMarkerClick method iterate through your other markers and compare distance between the markers relative to the current visible map dimensions and the marker size. As in the following example code:
static final float IMAGE_SIZE_RATIO = .15f; //define how big your marker is relative to the total screen
private void setupListeners() {
getMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
LatLngBounds b = getMap().getProjection().getVisibleRegion().latLngBounds;
Float distance = distanceBetweenPoints(b.northeast, b.southwest) * IMAGE_SIZE_RATIO;
for (Marker m : makers ) {
if (marker.equals(m) ) { continue; } //don't compare the same one
if (distanceBetweenPoint(m.getPosition(), marker.getPosition()) {
/*Note do onMarkerClick this as an Aynch task and continue along
if also want to fire off against the main object.
*/
return onMarkerClick(m);
}
}
// do the operation you want on the actual marker.
}
....(remainder of listener)...
}
}
protected Float getDistanceInMeters(LatLng a, LatLng b) {
Location l1 = new Location("");
Location l2 = new Location("");
l1.setLatitude(a.latitude);
l1.setLongitude(a.longitude);
l2.setLatitude(b.latitude);
l2.setLongitude(b.longitude);
return l1.distanceTo(l2)
}

Is there a Android Google Maps v2 Marker Manager out there?

I'm trying to find a way to manage the markers I have on a android map (v2) implementation in my app. I'd like to be able to draw markers that are inside the viewable boundary and at the same time only show markers above a certain zoom level. It seems like a common problem. So, I'm asking if anybody here uses something like a marker manager library or something. Just to make things easier and that I don't have to make one from scratch. Thanks.
Not yet a manager, but you may want to check Android Maps Extensions, which has clustering functionality.
Edit:
In AME, drawing markers inside visible region can be achieved by using:
map.setClustering(new ClusteringSettings().addMarkersDynamically(true));
or
map.setClustering(new ClusteringSettings().enabled(false).addMarkersDynamically(true));
if you don't want clustering but only optimize for case when adding many markers.
Showing markers only when you hit a certain zoom level is not yet fully implemented, but already requested here.
I realise that this question is pretty old but if anybody has still the same problem, one can use Google Maps Android Marker Clustering Utility.
Steps which should be taken are listed below:
Implement ClusterItem to represent a marker on the map. The cluster item returns the position of the marker as a LatLng object.
Add a new ClusterManager to group the cluster items (markers) based on zoom level.
Set the map's OnCameraChangeListener() to the ClusterManager, since ClusterManager implements the listener.
If you want to add specific functionality in response to a marker click event, set the map's OnMarkerClickListener() to the ClusterManager, since ClusterManager implements the listener.
Feed the markers into the ClusterManager.
Example implementation:
public class MyItem implements ClusterItem {
private final LatLng mPosition;
public MyItem(double lat, double lng) {
mPosition = new LatLng(lat, lng);
}
#Override
public LatLng getPosition() {
return mPosition;
}
}
private void setUpClusterer() {
// Declare a variable for the cluster manager.
private ClusterManager<MyItem> mClusterManager;
// Position the map.
getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));
// Initialize the manager with the context and the map.
// (Activity extends context, so we can pass 'this' in the constructor.)
mClusterManager = new ClusterManager<MyItem>(this, getMap());
// Point the map's listeners at the listeners implemented by the cluster
// manager.
getMap().setOnCameraChangeListener(mClusterManager);
getMap().setOnMarkerClickListener(mClusterManager);
// Add cluster items (markers) to the cluster manager.
addItems();
}
private void addItems() {
// Set some lat/lng coordinates to start with.
double lat = 51.5145160;
double lng = -0.1270060;
// Add ten cluster items in close proximity, for purposes of this example.
for (int i = 0; i < 10; i++) {
double offset = i / 60d;
lat = lat + offset;
lng = lng + offset;
MyItem offsetItem = new MyItem(lat, lng);
mClusterManager.addItem(offsetItem);
}
}
For more information you can check here and the library's Github page

Google map camera position on multiple markers

I am using google map API 2 and showing multiple markers on it. My problem it that I want my camera to be positioned on all my markers.
I have done it for single marker as
myMap.moveCamera(CameraUpdateFactory.newLatLngZoom(MyLocation, 22));
I have Used Below Way to see all markers in view. It will Bound your Mapview including all the Lat-Long Location you have in your arraylist.
// Pan to see all markers in view.
// Cannot zoom to bounds until the map has a size.
final View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#SuppressLint("NewApi")
#Override
public void onGlobalLayout() {
LatLngBounds.Builder bld = new LatLngBounds.Builder();
for (int i = 0; i < YOUR_ARRAYLIST.size(); i++) {
LatLng ll = new LatLng(YOUR_ARRAYLIST.get(i).getPos().getLat(), YOUR_ARRAYLIST.get(i).getPos().getLon());
bld.include(ll);
}
LatLngBounds bounds = bld.build();
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 70));
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
});
}
Hope it Will Help.

Categories

Resources