在MapView上平移和缩放

时间:2011-11-23 09:37:43

标签: android-maps

我正在尝试创建一个使用地图上的平移和缩放功能的应用。我花了很多时间试图实现这个。我首先尝试在MapActivity中创建一个触摸方法,但我很快意识到它会比这更多。我发现了一些我试图实现的代码,它创建了mapview的子类并遇到了一些问题。我需要一些帮助来平移地图。我试图清除并显示叠加层到处都会导致问题。覆盖层被移除并显示在错误的位置,或者创建循环导致闪烁。请让我知道我需要做些什么来实现这个目标。我意识到如果有一个而不是onTouch方法,我可能需要覆盖onScroll方法。现在它很漂亮我需要一些帮助,所以我可以让它免于bug。如果我的想法是正确的,请告诉我。我需要立即在市场上推出这款产品。这是我的代码。提前谢谢。

// 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.view.ViewGroup.LayoutParams;
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 {
    private static final String TAG = "MAPACTIVITY";
    double lat;
    double lng;
    EnhancedMapView mv;
    ArrayList<MapItem> allCats;
    private static final String PREF_NAME = "cookie";
    private float latMax;
    private float latMin;
    private float longMax;
    private float longMin;
    GeoPoint p;
    private List<Overlay> mapOverlays;
    private MyItemizedOverlay itemizedOverlay;
    boolean waitTime = false;

    @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, "0ieXSx8GEy9Hm7bCZMLckus7pmPKg0w8kelRO_g");
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mv.setLayoutParams(lp);
        mv.setClickable(true);
        mv.setBuiltInZoomControls(true);

        mv.setOnZoomChangeListener(new EnhancedMapView.OnZoomChangeListener() {
            @Override
            public void onZoomChange(MapView view, int newZoom, int oldZoom) {
                Log.v("test", "zoom center changed");
                if (isNetworkAvailable(MapActivityNearby.this))
                {
                    LogIn log = new LogIn();
                    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();
                }
            }
        });
        mv.setOnPanChangeListener(new EnhancedMapView.OnPanChangeListener() {
            public void onPanChange(MapView view, GeoPoint newCenter, GeoPoint oldCenter) {
                Log.v("test", "pan center changed");
                if (isNetworkAvailable(MapActivityNearby.this))
                {
                    LogIn log = new LogIn();
                    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();
                }
            }
        });

        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));
        MapController mapControl = mv.getController();
        mapControl.setCenter(p);
        mapControl.setZoom(11);


    }

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

        if (isNetworkAvailable(MapActivityNearby.this))
        {
            LogIn log = new LogIn();
            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 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);
        }
    }

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

        }

        @Override
        protected Boolean doInBackground(EnhancedMapView...params) {
            if (!(mv.getOverlays().isEmpty()))
            {
                mv.getOverlays().clear();
            }
            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 goes here";
                log(catURL.toString());
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(catURL);
                ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
                waitTime = true;
                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 result) {
            // pBar.setVisibility(View.GONE);
            plotPoints(allCats);
        }

        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
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

}

// CustomMapView类 //包名称省略

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

import android.content.Context;
import android.util.AttributeSet;
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();
            pan_event_delay_timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    pan_change_listener.onPanChange(_this, getMapCenter(), last_center_pos);
                    last_center_pos = getMapCenter();
                }
            }, events_timeout);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

<强> main.xml中

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:weightSum="1">
    <LinearLayout   android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <com.google.android.maps.MapView
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
                 android:apiKey="0TqoE_fzA3Pv-m8188NwttzIKcYBzhNJsYRJkKQ"
                 android:id="@+id/mapview"
                 android:clickable="true"
                 android:enabled="true"
                 />
     </LinearLayout>
     <RelativeLayout   
                     android:layout_width="35dip"
                     android:layout_marginTop="300dip" 
                     android:layout_marginLeft="270dip"
                     android:layout_height="70dip"
                     android:background="#AA000000">

            <TextView android:layout_height="20dip" 
            android:gravity="center" android:textStyle="bold" 
            android:textColor="#000000" android:textSize="20dip"
             android:id="@+id/zoomButton1"             
              android:layout_width="100dip"
               android:text="+" />
            <TextView android:layout_height="20dip" 
            android:layout_below="@id/zoomButton1" 
            android:textStyle="bold" 
            android:textColor="#000000"
             android:gravity="center" 
             android:textSize="20dip" 
             android:id="@+id/zoomButton2" 
             android:layout_width="80dip" 
              android:text="-"   />
</RelativeLayout>      
</RelativeLayout>

<强> MyMapActivity

public class MyMapActivity extends MapActivity {
    /** Called when the activity is first created. */
     MapView mapView;
     ZoomControls zoomControls;
     MapController mapController;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mapView = (MapView)findViewById(R.id.mapview);
        System.out.println("oncreate");

        mapView.setStreetView(true);
        mapView.invalidate();
        mapController  = mapView.getController();
        // zoom contrlos
        int y=10;
        int x=10;
        /*MapView.LayoutParams lp;
        lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT,
                MapView.LayoutParams.WRAP_CONTENT,
                x, y,
                MapView.LayoutParams.TOP_LEFT);
        View zoomControls = mapView.getZoomControls();
        mapView.addView(zoomControls, lp);
        mapView.displayZoomControls(true);*/
        /*zoomControls = (ZoomControls) findViewById(R.id.zoomControls1);
        zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        mapController.zoomIn();
                }
        });
        zoomControls.setOnZoomOutClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                        mapController.zoomOut();
                }
        });*/
            TextView zButton =(TextView)findViewById(R.id.zoomButton1);
        TextView zButton1 =(TextView)findViewById(R.id.zoomButton2);
        zButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mapController.zoomIn();
                Toast.makeText(myMapActivity.this, "Zoomin", Toast.LENGTH_SHORT).show();

            }
        });
zButton1.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                mapController.zoomOut();
                Toast.makeText(myMapActivity.this, "ZoomOUT", Toast.LENGTH_SHORT).show();

            }
        });

        Double lat = 38.899049*1E6;
        Double lng = -77.017593*1E6;
        GeoPoint point = new GeoPoint(lat.intValue(),lng.intValue());
        System.out.println("Points"+point);
        mapController.setCenter(point);
        mapController.setZoom(15);
        mapController.animateTo(point);
    //  http://maps.google.com/maps?ie=UTF8&hl=en&layer=t&ll=38.899049,-77.017593&spn=0.268261,0.6427&z=11

    }

    @Override
    protected boolean isRouteDisplayed() {

        return false;
    }


}