Search code examples
androiditemizedoverlay

ItemizedOverlays Android maps not working


I'm trying to add multiple markers on the mapview and i can't make it work, it doesn't
seems to load even the mapview when i comment the method that calls LoadMarkers(). can you tell me what is wrong with my code please??

public class MyATMLocatorActivity extends MapActivity {
    /** Called when the activity is first created. */

    private MapView mapView;
    private MapController myMapController;
    private GeoPoint myGeoPoint;
    private LocationManager myLocationManager;
    private LocationListener myLocationListener;

    public static Context context;
    private MyItemizedOverlay myItemizedOverlay = null;
    private MyLocationOverlay myLocationOverlay = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        context = getApplicationContext();
        setContentView(R.layout.main);

        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);

        myMapController = mapView.getController();

        this.LoadMarkers();

    }

this is the method that loads the markers..

private void LoadMArkers() {

        mapView.getOverlays().clear();
        mapView.postInvalidate();

        OverlayItem overlayItem = null;

        Drawable myATMPic = getResources().getDrawable(R.drawable.atmicon);
        myATMPic.setBounds(0, 0, myATMPic.getIntrinsicWidth(), myATMPic.getIntrinsicHeight());

        // Super España
        myItemizedOverlay = new MyItemizedOverlay(myATMPic);
        myGeoPoint = new GeoPoint((int) (-25.353043), (int) (-57.444495));
        overlayItem = new OverlayItem(myGeoPoint, "Supermercado Espana","Capiatá");
        myItemizedOverlay.addOverlay(overlayItem);
        mapView.getOverlays().add(myItemizedOverlay);

        // Martín Ledesma
        myItemizedOverlay = new MyItemizedOverlay(myATMPic);
        myGeoPoint = new GeoPoint((int) (-25.353974), (int) (-57.445214));
        overlayItem = new OverlayItem(myGeoPoint, "Martín Ledesma", "Capiatá");
        myItemizedOverlay.addOverlay(overlayItem);
        mapView.getOverlays().add(myItemizedOverlay);               

        mapView.postInvalidate();
    }

and this is my ItemizedOverlay() class

public class MyItemizedOverlay extends com.google.android.maps.ItemizedOverlay<OverlayItem> {

    private Context mContext;   
    private ArrayList<OverlayItem> myOverlaysArray = new ArrayList<OverlayItem>();;

    private GeoPoint geoPoint = null;

    public MyItemizedOverlay(Drawable defaultMarker) {
        super(boundCenterBottom(defaultMarker));        
    }

     public MyItemizedOverlay(Drawable defaultMarker, Context context) {
         super(boundCenterBottom(defaultMarker));
         mContext = context;
   }

    public void addOverlay(OverlayItem overlay) {
        myOverlaysArray.add(overlay);
        populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
        return myOverlaysArray.get(i);
    }

    // Removes overlay item i
    public void removeItem(int i) {
        myOverlaysArray.remove(i);
        populate();
    }

    // Returns present number of items in list
    @Override
    public int size() {
        return myOverlaysArray.size();
    }

    public void addOverlayItem(OverlayItem overlayItem) {
        myOverlaysArray.add(overlayItem);
        populate();
    }

    public void addOverlayItem(int lat, int lon, String title) {
        try {
            geoPoint = new GeoPoint(lat, lon);
            OverlayItem overlayItem = new OverlayItem(geoPoint, title, null);
            addOverlayItem(overlayItem);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected boolean onTap(int index) {
        OverlayItem item = myOverlaysArray.get(index);
        AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
        dialog.setTitle(item.getTitle());
        dialog.setMessage(item.getSnippet());
        dialog.show();
        return true;
    }

}

Solution

  • Are you adding the right code to the android manifest.xml? Add the com.google.android.maps as a child to the application element using a MapView.

    <uses-library android:name="com.google.android.maps" />
    

    Add INTERNET as a child element to the element.

    <uses-permission android:name="android.permission.INTERNET" />
    

    You don't need to create 2 itemized overlays. Also, you need to multiply all GPS coordinates by 1e6 before casting them to ints. In your previous code, both GPS coordinates will be casted to the same integer pair values and the markers will be placed on the same location on the map(-25,-57) and only the last 1 will be touchable. Also, don't forget to pass the application's context to the itemized overlay.

    MyATMLocatorActivity.java

    package maps.test;
    
    import java.util.List;
    
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.location.LocationListener;
    import android.location.LocationManager;
    import android.os.Bundle;
    
    import com.google.android.maps.GeoPoint;
    import com.google.android.maps.MapActivity;
    import com.google.android.maps.MapController;
    import com.google.android.maps.MapView;
    import com.google.android.maps.MyLocationOverlay;
    import com.google.android.maps.Overlay;
    import com.google.android.maps.OverlayItem;
    
    public class MyATMLocatorActivity extends MapActivity {
        /** Called when the activity is first created. */
    
        private MapView mapView;
        private MapController myMapController;
        private GeoPoint myGeoPoint;
        private GeoPoint myGeoPoint2;
        private LocationManager myLocationManager;
        private LocationListener myLocationListener;
    
        public static Context context;
        private MyItemizedOverlay myItemizedOverlay = null;
        private final MyLocationOverlay myLocationOverlay = null;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            context = getApplicationContext();
            setContentView(R.layout.main);
    
            mapView = (MapView) findViewById(R.id.mapview);
            mapView.setBuiltInZoomControls(true);
    
            myMapController = mapView.getController();
    
            this.LoadMarkers();
    
        }
    
        private void LoadMarkers() {
    
            List<Overlay> overlays = mapView.getOverlays();
            mapView.postInvalidate();
    
            OverlayItem overlayItem = null;
    
            Drawable myATMPic = getResources().getDrawable(R.drawable.ic_launcher);
            myATMPic.setBounds(0, 0, myATMPic.getIntrinsicWidth(), myATMPic.getIntrinsicHeight());
            myItemizedOverlay = new MyItemizedOverlay(myATMPic, this);
    
            // Super España
            myGeoPoint = new GeoPoint((int) (-25.353043*1e6), (int) (-57.444495*1e6));
            overlayItem = new OverlayItem(myGeoPoint, "Supermercado Espana","Capiatá");
            myItemizedOverlay.addOverlay(overlayItem);
    
            // Martín Ledesma
            myGeoPoint = new GeoPoint((int) (25.353974*1e6), (int) (-57.445214*1e6));
            overlayItem = new OverlayItem(myGeoPoint2, "Martín Ledesma", "Capiatá");
            myItemizedOverlay.addOverlay(overlayItem);
    
            overlays.add(myItemizedOverlay);
            mapView.postInvalidate();
        }
    
    
        @Override
        protected boolean isRouteDisplayed() {
            // TODO Auto-generated method stub
            return false;
        }
    }
    

    MyItemizedOverlay.java

    package maps.test;
    
    import java.util.ArrayList;
    
    import android.app.AlertDialog;
    import android.content.Context;
    import android.graphics.drawable.Drawable;
    
    import com.google.android.maps.GeoPoint;
    import com.google.android.maps.OverlayItem;
    
    public class MyItemizedOverlay extends com.google.android.maps.ItemizedOverlay<OverlayItem> {
    
        private Context mContext;
        private final ArrayList<OverlayItem> myOverlaysArray = new ArrayList<OverlayItem>();
        private GeoPoint geoPoint = null;
        public MyItemizedOverlay(Drawable defaultMarker) {
            super(boundCenterBottom(defaultMarker));
        }
    
        public MyItemizedOverlay(Drawable defaultMarker, Context context) {
            super(boundCenterBottom(defaultMarker));
            mContext = context;
        }
    
        public void addOverlay(OverlayItem overlay) {
            myOverlaysArray.add(overlay);
            populate();
        }
    
        @Override
        protected OverlayItem createItem(int i) {
            return myOverlaysArray.get(i);
        }
    
        // Removes overlay item i
        public void removeItem(int i) {
            myOverlaysArray.remove(i);
            populate();
        }
    
        // Returns present number of items in list
        @Override
        public int size() {
            return myOverlaysArray.size();
        }
    
        public void addOverlayItem(OverlayItem overlayItem) {
            myOverlaysArray.add(overlayItem);
            populate();
        }
    
        public void addOverlayItem(int lat, int lon, String title) {
            try {
                geoPoint = new GeoPoint(lat, lon);
                OverlayItem overlayItem = new OverlayItem(geoPoint, title, null);
                addOverlayItem(overlayItem);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        @Override
        protected boolean onTap(int index) {
            OverlayItem item = myOverlaysArray.get(index);
            AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
            dialog.setTitle(item.getTitle());
            dialog.setMessage(item.getSnippet());
            dialog.show();
            return true;
        }
    }
    

    I've tested the code in a sample application and here is my android manifest, compare it to your own.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="maps.test"
        android:versionCode="1"
        android:versionName="1.0" >
        <uses-sdk android:minSdkVersion="8" />
        <uses-permission android:name="android.permission.INTERNET" />
        <application
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name" >
            <uses-library android:name="com.google.android.maps" />
            <activity
                android:name=".MyATMLocatorActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    </manifest>
    

    Here is my Main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <com.google.android.maps.MapView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:apiKey="Your Maps API Key goes here"
    />