Differentiate between different markers in Maps API v2 (unique identifiers)
Asked Answered
K

5

6

I have an ArrayList of a custom class. There are about 10 objects in the list, each with details like Title, Snippet, LatLng. I have successfully added all 10 to a Map by using my custom class functions like getTitle, getSnippet, getLatLng etc.

Now, when I click the info window (of the marker), I want to be able to somehow KNOW which object of my custom class does that marker correspond to.

For example, if I click the McDonald's market, I want to be able to know which item from my ArrayList did that marker belong to.

I've been looking at the MarkerOptions and there doesn't seem to be anything in there that I can use to identify the relevant custom object with.

If the question is too confusing, let me make it simple:

ArrayList<CustomObj> objects = blah
map.addMarker(new MarkerOptions().position(new LatLng(
                            Double.parseDouble(result.get(i).getCompanyLatLng()
                                    .split(",")[0]), Double.parseDouble(result
                                    .get(i).getCompanyLatLng().split(",")[1])))
                                    .title(result.get(i).getCompanyName())
                                    .snippet(result.get(i).getCompanyType())
                                    .icon(BitmapDescriptorFactory
                                            .fromResource(R.drawable.pin)));

Now when this is clicked, I go on to the next page. The next page needs to know WHICH object was clicked so that I can send the other details to that page (e.g. Image URLs that need to be loaded etc).

How do I add a unique integer or any identifier to my marker?

Kittie answered 23/5, 2013 at 12:46 Comment(3)
mMap.setOnMarkerClickListener(new OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker arg0) { if(arg0.getTitle().equals("marker 1 title")) Toast.makeText(MainActivity.this, arg0.getTitle(),1000).show(); return true; } }); you can use marker listener to check and use the title to compare to know which marker was clickedHoch
:) Titles aren't always unique in my case and hence can't be used for this purpose.Kittie
you can use getId() in that case.Hoch
A
6

One correct way is to use Map<Marker, CustomObj> which stores all markers:

Marker marker = map.addMarker(...);
map.put(marker, result.get(i));

and in onInfoWindowClick:

CustomObj obj = map.get(marker);

Another try is using Android Maps Extensions, which add getData and setData method to Marker, so you can assign your CustomObj object after creating marker and retrieve it in any callback.

Antipole answered 23/5, 2013 at 19:28 Comment(2)
I ended up using maps extensions. I wish google would fix this.Kittie
@Kittie I don't think this is not something that requires a fix. If such functions (getData and setData) were inside the original library, all your objects would have to be Parcelable and it would take additional time to send them via IPC to Google Play Services. Using Map is a good workaround, Android Maps Extensions just make this workaround more convinient.Zendejas
S
1

I used the the snippet text for saving an unique ID. If you need the snippet it's will be for the popup and there you can just make your own (by finding the object from the ID) so you wont miss it but you'll certainly miss a unique ID for identifying the objects.

To find the right object I just iterate through them:

for(SomeObject anObject : someObjects) {
    if(marker.getSnippet().equalsIgnoreCase(anObject.getID())) {
        //you got at match
    }
}
Spermatozoid answered 23/5, 2013 at 12:49 Comment(2)
But I've got info in snippets.. Useful info that needs to be displayedKittie
@Kittie you can get that info from the object as well right? Then take it from there. You only need the info when you are displaying it.Spermatozoid
I
1

According to the discussion at the following link, Marker.equals and Marker.hashCode don't work sometimes. For example, when the map is panned or zoomed, or it's restarted/resumed.

Add Tag / Identifier to Markers

So Marker's ID is a better key than Marker itself for a HashMap.

Map<String, MyObject> markerMap = new HashMap<String, MyObject>();
Marker marker = map.addMarker(...);
MyObject myObject = new MyObject();
markerMap.put(marker.getId(), myObject);
Indian answered 1/8, 2014 at 14:56 Comment(0)
Z
0

I think using latitude and longitude, this could be done

map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {

        @Override
        public boolean onMarkerClick(final Marker marker) {
            LatLng pos = marker.getPosition();
            int arryListPosition = getArrayListPosition(pos);
            return true;
        }
    });

and the method getArrayListPosition is

private int getArrayListPosition(LatLng pos) {
    for (int i = 0; i < result.size(); i++) {
        if (pos.latitude == result.get(i).getCompanyLatLng().split(",")[0]) {
            if (pos.longitude == result.get(i).getCompanyLatLng()
                    .split(",")[1])
                return i;
        }
    }
    return 0;
}

This method will return you the position of your ArrayList who's Marker you have clicked. and you can get data from that position.

Hope it helps...

Zapata answered 23/5, 2013 at 13:1 Comment(3)
This is a good idea. I'll give it a try and mark your answer correct if it works well.Kittie
But if you have 2 markers the same place your screwed. This is certainly not the best option compared with using title or snippet.Spermatozoid
@Warpzit: yes you are right. But if you are adding 2 or more markers at the same LatLng, then what's the purpose of it. Markers are used to display some point on the map. So a same Latlng will point to same position and I think the data for that point will be same for all marker.Zapata
A
0

I am 4 years late to answer but I really amazed why no-one talked about marker.setTag and marker.getTag method.

As written in google API docs,

This is easier than storing a separate Map<Marker, Object>

They have introduce setTag and getTag to avoid use of Map<...>. You can use it as following way.

Marker marker = map.addMarker(...);
marker.setTag(result.get(i));  //Store your marker information here.

//To fetch your object...
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
    @Override
    public boolean onMarkerClick(Marker marker) {
        CustomObj obj = (CustomObj)marker.getTag();
        //Your click handle event
        // Pass the obj to another activity and you are done
        return false;
    }
});
Auroreaurous answered 9/6, 2017 at 19:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.