平移和缩放后在MapView上绘制点

时间:2011-11-29 07:01:07

标签: android android-maps

问题是,onPanChanged()方法被调用两次,导致点在每次用户移动或平移地图时绘制之前都会闪烁。我该怎么做才能使onPanChanged()方法只被调用一次。在代码中,我甚至尝试关闭侦听器并在退出AsyncTask时将其重新打开。

我希望您能分享一些想法和意见。

// MapActivity

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ViewGroup;
import android.widget.LinearLayout;

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.Overlay;
import com.google.android.maps.OverlayItem;

public class MapActivityNearby extends MapActivity implements EnhancedMapView.OnPanChangeListener {
    private EnhancedMapView mv;
    private static final String TAG = "MAPACTIVITY";
    private static final String PREF_NAME = "cookie";
    private double lat;
    private double lng;
    private ArrayList<MapItem> allCats;
    private GeoPoint p;
    private float latMin;
    private float latMax;
    private float longMin;
    private float longMax;
    private MapController mapControl;
    private List<Overlay> mapOverlays;
    private MyItemizedOverlay itemizedOverlay;
    boolean waitTime = true;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_nearby);
        LinearLayout ll = (LinearLayout) findViewById(R.id.maplayout);
        mv = new EnhancedMapView(this, "api_key");
        mv.setClickable(true);
        mv.setBuiltInZoomControls(true);
        mv.setOnZoomChangeListener(new EnhancedMapView.OnZoomChangeListener() {
            @Override
            public void onZoomChange(MapView view, int newZoom, int oldZoom) {
                Log.d("test", "zoom changed from " + oldZoom + " to " + newZoom);
            }
        });

        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mv.setLayoutParams(lp);
        ll.addView(mv);

        SharedPreferences cookies = getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        lat = Double.parseDouble(cookies.getString("lat", "0"));
        lng = Double.parseDouble(cookies.getString("lng", "0"));
        GeoPoint p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
        mapControl = mv.getController();
        mapControl.setZoom(11);
        mapControl.setCenter(p);
    }

    public void onResume()
    {
        super.onResume();

        if (isNetworkAvailable(MapActivityNearby.this))
        {
            PlotPoints plot = new PlotPoints();
            plot.execute(mv);
        }
        else
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(MapActivityNearby.this);
            builder.setMessage("No network connection.  Please try again when your within coverage area.")
                   .setTitle("Network Connection")
                   .setCancelable(false)
                   .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            //close dialog
                       }
                   });
            AlertDialog alert = builder.create();
            alert.show();
        }
    }

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

    public void plotPoints(ArrayList<MapItem> i) {

        mapOverlays = mv.getOverlays();

        // first overlay
        Drawable drawable;
        drawable = getResources().getDrawable(R.drawable.marker);

        itemizedOverlay = new MyItemizedOverlay(drawable, mv);
        mapOverlays.add(itemizedOverlay);
        for (MapItem x : i) {

            GeoPoint point = new GeoPoint((int) (x.getLat() * 1E6),
                    (int) (x.getLng() * 1E6));
            OverlayItem overlayItem = new OverlayItem(point,
                    x.getTitle(), x.getSubtitle());
            itemizedOverlay.addOverlay(overlayItem);
        }
        GeoPoint point = new GeoPoint((int) (((latMin + latMax) * 1E6) / 2), (int) (((longMin + longMax) * 1E6) /2));
        MapController mc = mv.getController();
        mc.setCenter(point);
    }

    private class PlotPoints extends AsyncTask<EnhancedMapView, Void, Boolean> {
        String result = "";
        InputStream is;
        @Override
        protected void onPreExecute() {
            turnOff();
        }

        @Override
        protected Boolean doInBackground(EnhancedMapView...params) {
            turnOff();
            int maxCount = 100;
            EnhancedMapView mapView = params[0];
            for (int i = 0; i < maxCount; i++)
            {
                p = mapView.getMapCenter();
                float latCenter = (float) (p.getLatitudeE6()) / 1000000;
                float longCenter = (float) (p.getLongitudeE6()) / 1000000;
                float latSpan = (float) (mapView.getLatitudeSpan()) / 1000000;
                float longSpan = (float) (mapView.getLongitudeSpan()) / 1000000;
                latMax = latCenter + (latSpan/2);
                latMin = latCenter - (latSpan/2);
                longMax = longCenter + (longSpan/2);
                longMin = longCenter - (longSpan/2);
                if (latMin == latMax)
                {
                    try
                    {
                        Thread.sleep(80);
                    }
                    catch(InterruptedException e)
                    {

                    }
                }
                else
                {
                    p = mapView.getMapCenter();
                    latCenter = (float) (p.getLatitudeE6()) / 1000000;
                    longCenter = (float) (p.getLongitudeE6()) / 1000000;
                    latSpan = (float) (mapView.getLatitudeSpan()) / 1000000;
                    longSpan = (float) (mapView.getLongitudeSpan()) / 1000000;
                    latMax = latCenter + (latSpan/2);
                    latMin = latCenter - (latSpan/2);
                    longMax = longCenter + (longSpan/2);
                    longMin = longCenter - (longSpan/2);
                    break;
                }
            }
            log(latMin);
            log(latMax);

            try {
                final String catURL = "url";
                log(catURL.toString());
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(catURL);
                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                nameValuePairs.add(new BasicNameValuePair("PHPSESSID", getCookie()));
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();
                result = convertStreamToString();
                log(result);
                allCats = new ArrayList<MapItem>();
                JSONObject object = new JSONObject(result);
                JSONArray temp = object.getJSONArray("l");
                log("Starting download");
                log(temp.length());
                long start = System.currentTimeMillis();
                for (int k = 0; k < temp.length(); k++) {
                    JSONObject j = temp.getJSONObject(k);
                    MapItem c = new MapItem();
                    c.setObject_id(j.getInt("object_id"));
                    c.setTitle(j.getString("title"));
                    c.setColor(j.getString("color"));
                    c.setLat(j.getDouble("lat"));
                    c.setLng(j.getDouble("lng"));
                    c.setSubtitle(j.getString("subtitle"));

                    allCats.add(c);
                    log(allCats.toString());
                }
                long end = System.currentTimeMillis();
                log("Download Took: " + (end - start) / 1000 + " seconds.");
                // log(allCats.toString());
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClientProtocolException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return true;
        }

        @Override
        protected void onPostExecute(Boolean results) {
            // pBar.setVisibility(View.GONE);
            plotPoints(allCats);
            turnOn();
        }

        private String convertStreamToString() {
            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "iso-8859-1"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();

                result = sb.toString();
                result.trim();
            } catch (Exception e) {
                Log.e("log_tag", "Error converting result " + e.toString());
            }

            return result;
        }
    }

    public String getCookie() {
        String cookie = "";
        SharedPreferences cookies = getSharedPreferences(PREF_NAME,
                Context.MODE_PRIVATE);
        if (cookies.contains("cookie")) {
            cookie = cookies.getString("cookie", "null");
        }

        return cookie;
    }

    private void log(Object obj) {
        Log.d(TAG, TAG + " :: " + obj.toString());
    }

    public static boolean isNetworkAvailable(Context context) {
        ConnectivityManager connectivity = (ConnectivityManager) context
                .getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo[] info = connectivity.getAllNetworkInfo();
            if (info != null) {
                for (int i = 0; i < info.length; i++) {
                    if (info[i].getState() == NetworkInfo.State.CONNECTED) {
                        return true;
                    }
                }
            }
        }
        return false;
    }

    @Override
    public void onPanChange(MapView view, GeoPoint newCenter, GeoPoint oldCenter) {
        Log.d("test", "center changed from " + oldCenter.getLatitudeE6() + "," + oldCenter.getLongitudeE6() + " to " + newCenter.getLatitudeE6() + "," + newCenter.getLongitudeE6());
        if(!mv.getOverlays().isEmpty())
        {
            mv.getOverlays().clear();
            mv.postInvalidate();
        }

        if (isNetworkAvailable(MapActivityNearby.this))
        {
            PlotPoints log = new PlotPoints();
            log.execute(mv);
        }
        else
        {
            AlertDialog.Builder builder = new AlertDialog.Builder(MapActivityNearby.this);
            builder.setMessage("No network connection.  Please try again when your within coverage area.")
                   .setTitle("Network Connection")
                   .setCancelable(false)
                   .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                       public void onClick(DialogInterface dialog, int id) {
                            //close dialog
                       }
                   });
            AlertDialog alert = builder.create();
            alert.show();
        }
    }

    public void turnOn ()
    {
        mv.setOnPanChangeListener(this);
    }

    public void turnOff ()
    {
        mv.setOnPanChangeListener(null);
    }
}

// EnhancedMapView

import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;

public class EnhancedMapView extends MapView {
    public interface OnZoomChangeListener {
        public void onZoomChange(MapView view, int newZoom, int oldZoom);
    }

    public interface OnPanChangeListener {
        public void onPanChange(MapView view, GeoPoint newCenter, GeoPoint oldCenter);
    }

    private EnhancedMapView _this;

        // Set this variable to your preferred timeout
    private long events_timeout = 500L;
    private boolean is_touched = false;
    private GeoPoint last_center_pos;
    private int last_zoom;
    private Timer zoom_event_delay_timer = new Timer();
    private Timer pan_event_delay_timer = new Timer();

    private EnhancedMapView.OnZoomChangeListener zoom_change_listener;
    private EnhancedMapView.OnPanChangeListener pan_change_listener;


    public EnhancedMapView(Context context, String apiKey) {
        super(context, apiKey);
        _this = this;
        last_center_pos = this.getMapCenter();
        last_zoom = this.getZoomLevel();
    }

    public EnhancedMapView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public EnhancedMapView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setOnZoomChangeListener(EnhancedMapView.OnZoomChangeListener l) {
        zoom_change_listener = l;
    }

    public void setOnPanChangeListener(EnhancedMapView.OnPanChangeListener l) {
        pan_change_listener = l;
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (ev.getAction() == 1) {
            is_touched = false;
        } else {
            is_touched = true;
        }

        return super.onTouchEvent(ev);
    }

    @Override
    public void computeScroll() {
        super.computeScroll();

        if (getZoomLevel() != last_zoom) {
                        // if computeScroll called before timer counts down we should drop it and start it over again
            zoom_event_delay_timer.cancel();
            zoom_event_delay_timer = new Timer();
            zoom_event_delay_timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    zoom_change_listener.onZoomChange(_this, getZoomLevel(), last_zoom);
                    last_zoom = getZoomLevel();
                }
            }, events_timeout);
        }

        // Send event only when map's center has changed and user stopped touching the screen
        if (!last_center_pos.equals(getMapCenter()) && !is_touched) {
            pan_event_delay_timer.cancel();
            pan_event_delay_timer = new Timer();
            try
            {
                pan_event_delay_timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        try
                        {
                             pan_change_listener.onPanChange(_this, getMapCenter(), last_center_pos);
                             last_center_pos = getMapCenter();
                        }
                        catch (IllegalArgumentException e)
                        {
                            Log.v("IllegalArgumentException", e.toString());
                        }
                        catch (IllegalStateException e)
                        {
                            Log.v("IllegalStateException", e.toString());
                        }
                        catch (NullPointerException e)
                        {
                            Log.v("NullPointerException", e.toString());
                        }
                    }
                }, events_timeout);
            }
            catch (IllegalArgumentException e)
            {
                Log.v("IllegalArgumentException", e.toString());
            }
            catch (IllegalStateException e)
            {
                Log.v("IllegalStateException", e.toString());
            }
            catch (NullPointerException e)
            {
                Log.v("NullPointerException", e.toString());
            }

        }
    }
}

0 个答案:

没有答案