Search code examples
androidgoogle-maps-markersgoogle-maps-android-api-2android-geofence

android detect various circles on a map v2


In my little app I have a map and i'm parsing an XML from the web, like this:

<place>
<lat>42.827602</lat>
<lon>-1.663957</lon>
<place_name>Place one</place_name>
<snippet>Snippet de place Facebook</snippet>
<thumb>http://www.animage.com/myicon1.png</thumb>
</place>

<place>
<lat>42.830750</lat>
<lon>-1.669064</lon>
<place_name>Place two</place_name>
<snippet>Snippet de place Twitter</snippet>
<thumb>http://www.animage.com/myicon2.png</thumb>
</place>

<place>
<lat>42.825333</lat>
<lon>-1.668232</lon>
<place_name>Place Three</place_name>
<snippet>Snippet de place Skype</snippet>
<thumb>http://www.animage.com/myicon3.png</thumb>
</place>

</response>

every time I read a "place" from the xml, the onPostExecute of my AsyncTask, calls the method that creates a new marker and circle on the map of my application

For example, if the xml has seven "places", the method to create a new marker and a circle is called seven times.

Marker aMarker;
Circle aCircle;

//... 

public void createNewMarkerAndCircle() {

    //...

     aMarker = mMap.addMarker(new MarkerOptions()
                    .position(new LatLng(dLat, dLon))
                    .title(nombre_punto)
                    .snippet(introduccion_punto)
                    .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));


            aCircle = mMap.addCircle(new CircleOptions()
                            .center(new LatLng(dLat, dLon))
                            .radius(150)
                            .strokeColor(Color.RED)

}
//...

 public void onPostExecute(String xml) {

        xml = stringBuffer.toString();
        try {

            Document doc = parser.getDomElement(xml);

            NodeList nl0 = doc.getElementsByTagName(KEY_PLACE);

            Element e = (Element) nl0.item(lap);

            theLat = parser.getValue(e, KEY_LATITUDE);
            theLon = parser.getValue(e, KEY_LONGITUDE);

            //...

            createNewMarkerAndCircle();

      //...

So far, everything works fine and markers and circles are created on the map.

My purpose is that when the user on the map comes within the radius of one of the circles, get the datas of the marker that is inside. I show you what I'm doing:

I have a listener of my location that every time it´s updated, check the distance from the current location and radius of the circle.

  GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
            @Override
            public void onMyLocationChange(Location location) {
                LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());

                float[] distance = new float[2];

                try {

                    Location.distanceBetween(
                            location.getLatitude(),
                            location.getLongitude(),
                            aCircle.getCenter().latitude,
                            aCircle.getCenter().longitude, distance);

                    if (distance[0] > aCircle.getRadius()) {

                        Log.i("myLogs", "Outside");

                    } else {

                        String markerTitle;
                        markerTitle = aMarker.getTitle();

                        Log.i("myLogs", "I´ in the circle" + " " + markerTitle);

                    }
          //....

This works fine, but with a big problem.

When I start to walk the route, only detected when I go into the last "place" parsed from xml, and therefore, the last marker and circle created.

I understand what the problem is, the last marker (Marker aMarker;) and circle (Circle aCircle;) created are those with the values assigned ... But i do not know how to fix it.

I would appreciate any help, several days ago I'm looking for solutions, but without success.

Thanks and regards.

More information:

I found this other way , but the problem remains exactly the same:

https://gist.github.com/saxman/5347195


Solution

  • the last marker (Marker aMarker;) and circle (Circle aCircle;) created are those with the values assigned ... But i do not know how to fix it.

    In order to check the distance against all the points of interests you create you need to hold them in some sort of structure, the most simple being a list, to reference them later in the listener:

    Marker aMarker;
    Circle aCircle;
    // this will hold the circles
    List<Circle> allCircles = new ArrayList<Circle>();
    // this will hold the markers
    List<Marker> allMarkers = new ArrayList<Marker>();
    
    public void createNewMarkerAndCircle() {
         aMarker = mMap.addMarker(new MarkerOptions()
                .position(new LatLng(dLat, dLon))
                .title(nombre_punto)
                .snippet(introduccion_punto)
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE   )));
        // store the new marker in the above list 
        allMarkers.add(aMarker);
       aCircle = mMap.addCircle(new CircleOptions()
                .center(new LatLng(dLat, dLon))
                .radius(150)
                .strokeColor(Color.RED)
       // store the created circles
       allCircles.add(aCircle);
    }
    
    // in the LocationListener iterate over all stored circles and check the distances against each one of them
    // as you add the circles and markers in the same method you'll have a correspondence between them in the two lists
    // another sensible approach would be to create a custom Area class
    // to hold both the Marker and the circle in one single place
    // so when you find yourself inside a circle the marker will be at the same position in allMarkers
    for (int i = 0; i < allCircles.size(); i++) {
          Circle c = allCircles.get(i);
          Location.distanceBetween(location.getLatitude(),    location.getLongitude(), c.getCenter().latitude, c.getCenter().longitude,  distance);
         if (distance[0] > c.getRadius()) {
            Log.i("myLogs", "Outside");
         } else {
            String markerTitle;
            markerTitle = allMarkers.get(i).getTitle();
            Log.i("myLogs", "I´ in the circle" + " " + markerTitle);
           // you found a circles so you may want to break out of the for  loop, break; 
    }