Search code examples
androidgoogle-mapsdictionaryoverlayitemizedoverlay

Android Itemizedoverlay! place and remove markers on map


I am trying to show the user's current location and allowing user to place one marker on the map. When user is tapped on the marker he placed, the marker will disappear and he can put another one on the map again.

The following code works fine in showing the user's current location and placing one marker on the map. It also is able to remove the marker. But once I tried to re-place a marker on the map after removing it. The program crashed! Could anyone tell me the reason?

class InterestingLocations extends ItemizedOverlay {
    private ArrayList<OverlayItem> locations = new ArrayList<OverlayItem>();
    private GeoPoint center = null;
    private Context mContext ;
    private boolean placed=false;


    public InterestingLocations(Drawable defaultMarker) {
        super(boundCenterBottom(defaultMarker));
        // create locations of interest
        GeoPoint me = new 
            GeoPoint((int)(lat*1000000),(int)(lng*1000000));

        locations.add(new OverlayItem(me, 
               "Me!", "Me! Me! Me!"));
        center=me;
        populate();
      }

    public InterestingLocations(Drawable marker, Context context)
    {
        super(marker);
        mContext= context;
        // create locations of interest
        GeoPoint me = new 
            GeoPoint((int)(lat*1000000),(int)(lng*1000000));

        locations.add(new OverlayItem(me, 
               "Me!", "Me!"));
        center=me;

        populate();
    }

    //  We added this method to find the middle point of the cluster
    //  Start each edge on its opposite side and move across with each point.
    //  The top of the world is +90, the bottom -90,
    //  the west edge is -180, the east +180


    @Override
    public void draw(Canvas canvas, MapView mapview, boolean shadow) {
        // Here is where we can eliminate shadows by setting to false
        super.draw(canvas, mapview, shadow);
    }

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

    @Override
    public int size() {
        return locations.size();
    }

    public boolean onTap (final GeoPoint p, final MapView mapView){
        boolean tapped = super.onTap(p, mapView);
        Log.i("onTap", "onTap 1");

        if (tapped){            
            Log.i("Hit item!!", "Hited");
            //do what you want to do when you hit an item       
            if(p!=me2){
                Log.i("Hit item!!", "Hited and p!=me2");
                removeOverlay();
                placed=false;
            }
        }           
        else{
            if(placed==false&&placeAble==true){
                Log.i("placed=="+placed, "placed==false");

                addOverlay(new OverlayItem(p, "Dest", "Destination"));
                destLat = (float)p.getLatitudeE6() / 1000000f;
                destLng = (float)p.getLongitudeE6() / 1000000f;
                placed=true;
            }   
            else{
                Log.i("placed=="+placed, "here is else");
            }
            //do what you want to do when you DONT hit an item
            }                   
        return true;
    }


    //You must have this method, even if it doesn't visibly do anything
    @Override
    protected boolean onTap(int index) {

        Log.i("Hit item!!", "Hited"+ index);
        return true;
    }


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


    public void removeOverlay() {
        locations.clear();
        GeoPoint me = new GeoPoint((int)(lat*1000000),(int)(lng*1000000));
        locations.add(new OverlayItem(me, "Me!", "Me! Me! Me!"));
        populate();
    }


}

Error from eclipse:

06-04 18:03:03.859: E/global(29049): Deprecated Thread methods are not supported.
06-04 18:03:03.859: E/global(29049): java.lang.UnsupportedOperationException
06-04 18:03:03.859: E/global(29049):    at java.lang.VMThread.stop(VMThread.java:85)
06-04 18:03:03.859: E/global(29049):    at java.lang.Thread.stop(Thread.java:1280)
06-04 18:03:03.859: E/global(29049):    at java.lang.Thread.stop(Thread.java:1247)
06-04 18:03:03.859: E/global(29049):    at com.knowithk.kpass.KPassActivity$1.run(KPassActivity.java:46)
06-04 18:03:17.429: E/MapActivity(29049): Couldn't get connection factory client
06-04 18:03:32.773: E/AndroidRuntime(29049): FATAL EXCEPTION: main
06-04 18:03:32.773: E/AndroidRuntime(29049): java.lang.ArrayIndexOutOfBoundsException
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.ItemizedOverlay.maskHelper(ItemizedOverlay.java:562)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.ItemizedOverlay.setFocus(ItemizedOverlay.java:365)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.ItemizedOverlay.focus(ItemizedOverlay.java:539)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.ItemizedOverlay.onTap(ItemizedOverlay.java:455)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.knowithk.kpass.taxifare.MyMap$InterestingLocations.onTap(MyMap.java:333)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.OverlayBundle.onTap(OverlayBundle.java:83)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.MapView$1.onSingleTapUp(MapView.java:356)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.GestureDetector.onTouchEvent(GestureDetector.java:533)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.google.android.maps.MapView.onTouchEvent(MapView.java:683)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.View.dispatchTouchEvent(View.java:3938)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:903)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:942)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1733)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1151)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.app.Activity.dispatchTouchEvent(Activity.java:2096)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1717)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewRoot.deliverPointerEvent(ViewRoot.java:2215)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1886)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.os.Handler.dispatchMessage(Handler.java:99)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.os.Looper.loop(Looper.java:130)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at android.app.ActivityThread.main(ActivityThread.java:3687)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at java.lang.reflect.Method.invokeNative(Native Method)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at java.lang.reflect.Method.invoke(Method.java:507)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
06-04 18:03:32.773: E/AndroidRuntime(29049):    at dalvik.system.NativeStart.main(Native Method)

Solution

  • change the way that you removed the tapped item by adding this to protected boolean onTap(int index):

                    mOverlays.remove(index);
                    setLastFocusedIndex(-1);
                    map.invalidate();
    

    and it will fix your problem.

    BTW, am i the only one who thinks that the ItemizedOverlay and OverlayItem classes suffers bad design?