2014-03-25 55 views
0

我现在的工作与策划客车及客车一个应用程序绘制到地图上停止在地图上。一个任务是获取用户的当前位置,并停止更新应用程序暂停时,继续当应用程序恢复更新。此外,位置更新至多每10秒发生一次,或者位置更改至少25米。我需要在地图上绘制用户的当前位置。如何获得用户的当前位置,并使用OverlayItem

下面是MapDisplayFragment的代码。 OverlayItems在这里添加(包括代表用户的位置OverlayItem),似乎我需要创建新类在这个类来实现这些功能,而不需要编写代码,就像我所做的。我正在考虑构建两个类:扩展LocationListener的MyLocationListener和扩展Fragment的MyLocationFragment,但现在我不知道如何开始:更具体地说,我不知道我应该创建这些类之间的关系。任何想法?

import java.util.ArrayList; 
import java.util.List; 

import org.osmdroid.DefaultResourceProxyImpl; 
import org.osmdroid.ResourceProxy; 
import org.osmdroid.api.IMapController; 
import org.osmdroid.tileprovider.tilesource.TileSourceFactory; 
import org.osmdroid.util.GeoPoint; 
import org.osmdroid.views.MapView; 
import org.osmdroid.views.overlay.ItemizedIconOverlay; 
import org.osmdroid.views.overlay.ItemizedIconOverlay.OnItemGestureListener; 
import org.osmdroid.views.overlay.OverlayItem; 

import android.app.Activity; 
import android.app.AlertDialog; 
import android.app.ProgressDialog; 
import android.content.Context; 
import android.content.res.Resources; 
import android.location.Criteria; 
import android.location.Location; 
import android.location.LocationManager; 
import android.os.AsyncTask; 
import android.os.Bundle; 
import android.support.v4.app.Fragment; 
import android.util.Log; 
import android.view.LayoutInflater; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.view.ViewGroup; 
import ca.ubc.cpsc210.exception.TranslinkException; 
import ca.ubc.cpsc210.nextbus.model.Bus; 
import ca.ubc.cpsc210.nextbus.model.BusStop; 
import ca.ubc.cpsc210.nextbus.translink.ITranslinkService; 
import ca.ubc.cpsc210.nextbus.translink.TranslinkService; 
import ca.ubc.cpsc210.nextbus.util.LatLon; 
import ca.ubc.cpsc210.nextbus.util.TextOverlay; 

/** 
* Fragment holding the map in the UI. 
*/ 
public class MapDisplayFragment extends Fragment { 

    /** 
    * Log tag for LogCat messages 
    */ 
    private final static String LOG_TAG = "MapDisplayFragment"; 

    /** 
    * Location of Nelson & Granville, downtown Vancouver 
    */ 
    private final static GeoPoint NELSON_GRANVILLE 
    = new GeoPoint(49.279285, -123.123007); 

    /** 
    * Overlay for bus markers. 
    */ 
    private ItemizedIconOverlay<OverlayItem> busLocnOverlay; 

    /** 
    * Overlay for bus stop location 
    */ 
    private ItemizedIconOverlay<OverlayItem> busStopLocationOverlay; 

    /** 
    * Overlay for legend 
    */ 
    private TextOverlay legendOverlay; 


    /** 
    * View that shows the map 
    */ 
    private MapView mapView; 

    /** 
    * Selected bus stop 
    */ 
    private BusStop selectedStop; 

    /** 
    * Wraps Translink web service 
    */ 
    private ITranslinkService tlService; 

    /** 
    * Map controller for zooming in/out, centering 
    */ 
    private IMapController mapController; 

    /** 
    * True if and only if map should zoom to fit displayed route. 
    */ 
    private boolean zoomToFit; 

    /** 
    * Bus selected by user 
    */ 
    private OverlayItem selectedBus; 

    /** 
    * User's location icon. 
    */ 
    private OverlayItem userLocnIcon; 

    /** 
    * Overlay for user current location. 
    */ 
    private ItemizedIconOverlay<OverlayItem> userLocnOverlay; 

    /** 
    * User's location. 
    */ 
    private GeoPoint location; 

    /** 
    * Set up Translink service 
    */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     Log.d(LOG_TAG, "onActivityCreated"); 

     setHasOptionsMenu(true); 

     tlService = new TranslinkService(getActivity()); 

     Log.d(LOG_TAG, "Stop number for mapping: " + (selectedStop == null ? "not set" : selectedStop.getStopNum())); 
    } 

    /** 
    * Set up map view with overlays for buses and selected bus stop. 
    */ 
    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     Log.d(LOG_TAG, "onCreateView"); 

     if (mapView == null) { 
      mapView = new MapView(getActivity(), null); 

      mapView.setTileSource(TileSourceFactory.MAPNIK); 
      mapView.setClickable(true); 
      mapView.setBuiltInZoomControls(true); 

      // set default view for map (this seems to be important even when 
      // it gets overwritten by plotBuses) 
      mapController = mapView.getController(); 
      mapController.setZoom(mapView.getMaxZoomLevel() - 4); 
      mapController.setCenter(NELSON_GRANVILLE); 


      busLocnOverlay = createBusLocnOverlay(); 
      busStopLocationOverlay = createBusStopLocnOverlay(); 
      legendOverlay = createTextOverlay(); 
      userLocnOverlay = createUserLocnOverlay(); 

      // Order matters: overlays added later are displayed on top of 
      // overlays added earlier. 
      mapView.getOverlays().add(busStopLocationOverlay); 
      mapView.getOverlays().add(busLocnOverlay); 
      mapView.getOverlays().add(userLocnOverlay); 
      mapView.getOverlays().add(legendOverlay); 


     } 

     return mapView; 
    } 


    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     inflater.inflate(R.menu.fragment_map_refresh, menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     if (item.getItemId() == R.id.map_refresh) { 
      update(false); 
      return true; 
     } 

     return super.onOptionsItemSelected(item); 
    } 

    /** 
    * When view is destroyed, remove map view from its parent so that it can be 
    * added again when view is re-created. 
    */ 
    @Override 
    public void onDestroyView() { 
     Log.d(LOG_TAG, "onDestroyView"); 

     ((ViewGroup) mapView.getParent()).removeView(mapView); 

     super.onDestroyView(); 
    } 

    @Override 
    public void onDestroy() { 
     Log.d(LOG_TAG, "onDestroy"); 

     super.onDestroy(); 
    } 

    /** 
    * Update bus locations. 
    */ 
    @Override 
    public void onResume() { 
     Log.d(LOG_TAG, "onResume"); 

     update(true); 

     super.onResume(); 
    } 

    /** 
    * Set selected bus stop 
    * @param selectedStop the selected stop 
    */ 
    public void setBusStop(BusStop selectedStop) { 
     this.selectedStop = selectedStop; 
    } 

    /** 
    * Update bus location info for selected stop, 
    * zoomToFit status and repaint. 
    * 
    * @Param zoomToFit true if map must be zoomed to fit (when new bus stop has been selected) 
    */ 
    void update(boolean zoomToFit) { 
     Log.d(LOG_TAG, "update - zoomToFit: " + zoomToFit); 

     this.zoomToFit = zoomToFit; 

     if(selectedStop != null) { 
      new GetBusInfo().execute(selectedStop); 
      selectedBus = null; 
     } 

     mapView.invalidate(); 

    } 

    /** 
    * Create the overlay for bus markers. 
    */ 
    private ItemizedIconOverlay<OverlayItem> createBusLocnOverlay() { 
     ResourceProxy rp = new DefaultResourceProxyImpl(getActivity()); 

     OnItemGestureListener<OverlayItem> gestureListener = new OnItemGestureListener<OverlayItem>() { 
      /** 
      * Display bus information in dialog box when user taps 
      * bus. 
      * 
      * @param index index of item tapped 
      * @param oi the OverlayItem that was tapped 
      * @return true to indicate that tap event has been handled 
      */ 
      @Override 
      public boolean onItemSingleTapUp(int index, OverlayItem oi) { 
       AlertDialog dlg = createSimpleDialog(oi.getTitle(), oi.getSnippet()); 
       dlg.show(); 
       if(selectedBus != null){ 
        selectedBus.setMarker(getResources().getDrawable(R.drawable.bus)); 
       } 
       selectedBus = oi; 
       selectedBus.setMarker(getResources().getDrawable(R.drawable.selected_bus)); 
       mapView.postInvalidate(); 
       return true; 
      } 

      @Override 
      public boolean onItemLongPress(int index, OverlayItem oi) { 
       // do nothing 
       return false; 
      } 
     }; 

     return new ItemizedIconOverlay<OverlayItem>(
       new ArrayList<OverlayItem>(), 
       getResources().getDrawable(R.drawable.bus), 
       gestureListener, rp); 
    } 



    /** 
    * Create the overlay for bus stop marker. 
    */ 
    private ItemizedIconOverlay<OverlayItem> createBusStopLocnOverlay() { 
     ResourceProxy rp = new DefaultResourceProxyImpl(getActivity()); 

     OnItemGestureListener<OverlayItem> gestureListener = new OnItemGestureListener<OverlayItem>() { 
      /** 
      * Display bus stop description in dialog box when user taps 
      * stop. 
      * 
      * @param index index of item tapped 
      * @param oi the OverlayItem that was tapped 
      * @return true to indicate that tap event has been handled 
      */ 
      @Override 
      public boolean onItemSingleTapUp(int index, OverlayItem oi) { 
       AlertDialog dlg = createSimpleDialog(oi.getTitle(), oi.getSnippet()); 
       dlg.show(); 

       return true; 
      } 

      @Override 
      public boolean onItemLongPress(int index, OverlayItem oi) { 
       // do nothing 
       return false; 
      } 
     }; 

     return new ItemizedIconOverlay<OverlayItem>(
       new ArrayList<OverlayItem>(), 
       getResources().getDrawable(R.drawable.stop), 
       gestureListener, rp); 
    } 

    private TextOverlay createTextOverlay() { 
     ResourceProxy rp = new DefaultResourceProxyImpl(getActivity()); 
     Resources res = getResources(); 
     String legend = res.getString(R.string.legend); 

     return new TextOverlay(rp, legend); 
    } 

    /** 
    * Create the overlay for user location markers. 
    */ 
    private ItemizedIconOverlay<OverlayItem> createUserLocnOverlay() { 
     ResourceProxy rp = new DefaultResourceProxyImpl(getActivity()); 

     OnItemGestureListener<OverlayItem> gestureListener = new OnItemGestureListener<OverlayItem>() { 
      /** 
      * Display user location. 
      * 
      * @param index index of item tapped 
      * @param oi the OverlayItem that was tapped 
      * @return true to indicate that tap event has been handled 
      */ 
      @Override 
      public boolean onItemSingleTapUp(int index, OverlayItem oi) { 
       // Don't do anything. 
       return false; 
      } 

      @Override 
      public boolean onItemLongPress(int index, OverlayItem oi) { 
       // do nothing 
       return false; 
      } 
     }; 

     return new ItemizedIconOverlay<OverlayItem>(
       new ArrayList<OverlayItem>(), 
       getResources().getDrawable(R.drawable.map_pin_blue), 
       gestureListener, rp); 
    } 

    /** 
    * Plot bus stop 
    */ 
    private void plotBusStop() { 
     LatLon latlon = selectedStop.getLatLon(); 
     GeoPoint point = new GeoPoint(latlon.getLatitude(), 
       latlon.getLongitude()); 
     OverlayItem overlayItem = new OverlayItem(Integer.valueOf(selectedStop.getStopNum()).toString(), 
       selectedStop.getLocationDesc(), point); 
     busStopLocationOverlay.removeAllItems(); // make sure not adding 
     // bus stop more than once 
     busStopLocationOverlay.addItem(overlayItem); 
    } 

    /** 
    * Plot buses onto bus location overlay 
    * 
    * @param zoomToFit determines if map should be zoomed to bounds of plotted buses 
    */ 
    private void plotBuses(boolean zoomToFit) { 
     List<Bus> buses = selectedStop.getBuses(); 
     Double maxlatSpan = 0.0; 
     Double maxlonSpan = 0.0; 


     busLocnOverlay.removeAllItems(); 
     for(Bus b : buses){ 
      Double latDifference = Math.abs(b.getLatLon().getLatitude()-NELSON_GRANVILLE.getLatitude()); 
      if(latDifference > maxlatSpan && (latDifference < 2.0)){ 
       maxlatSpan = latDifference; 
      } 
      Double lonDifference = Math.abs(b.getLatLon().getLongitude()-NELSON_GRANVILLE .getLongitude()); 
      if(lonDifference > maxlonSpan && (lonDifference < 2.0)){ 
       maxlonSpan = lonDifference; 
      } 
      String routeNo = b.getRoute().getName(); 
      String desc = b.getDescription(); 
      LatLon latlon = b.getLatLon(); 
      GeoPoint point = new GeoPoint(latlon.getLatitude(), latlon.getLongitude()); 
      OverlayItem overlayItem = new OverlayItem(routeNo, desc, point); 
      busLocnOverlay.addItem(overlayItem); 
     } 

     if(zoomToFit){ 
      mapController.zoomToSpan((int)Math.abs(maxlatSpan*2E6), (int) Math.abs(maxlonSpan*2E6)); 
     } 


    } 


    /** 
    * Helper to create simple alert dialog to display message 
    * @param title the title to be displayed at top of dialog 
    * @param msg message to display in dialog 
    * @return the alert dialog 
    */ 
    private AlertDialog createSimpleDialog(String title, String msg) { 
     AlertDialog.Builder dialogBldr = new AlertDialog.Builder(getActivity()); 
     dialogBldr.setTitle(title); 
     dialogBldr.setMessage(msg); 
     dialogBldr.setNeutralButton(R.string.ok, null); 

     return dialogBldr.create(); 
    } 

    public void getUserLocation() { 
     Criteria criteria = new Criteria(); 
     Context cont = new Activity(); 


     LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE); 
     String bestProvider = locationManager.getBestProvider(criteria, true); 

     Location userLocation = locationManager.getLastKnownLocation(bestProvider); 
     location = new GeoPoint(userLocation.getLatitude() * 1E6, userLocation.getLongitude() * 1E6); 




    } 

    private void plotUserLocation() { 
     getUserLocation(); 
     userLocnIcon = new OverlayItem("UserLocn", "User location", location); 

     userLocnOverlay.addItem(userLocnIcon); 

    } 

    /** 
    * Asynchronous task to get bus location estimates from Translink service. 
    * Displays progress dialog while running in background. 
    */ 
    private class GetBusInfo extends 
    AsyncTask<BusStop, Void, Void> { 
     private ProgressDialog dialog = new ProgressDialog(getActivity()); 
     private boolean success = true; 

     @Override 
     protected void onPreExecute() { 
      dialog.setMessage("Retrieving bus info..."); 
      dialog.show(); 
     } 

     @Override 
     protected Void doInBackground(BusStop... selectedStops) { 
      BusStop selectedStop = selectedStops[0]; 

      try { 
       tlService.addBusLocationsForStop(selectedStop); 
      } catch (TranslinkException e) { 
       e.printStackTrace(); 
       success = false; 
      } 

      return null; 
     } 

     @Override 
     protected void onPostExecute(Void dummy) { 
      dialog.dismiss(); 

      if (success) { 
       plotBuses(zoomToFit); 
       plotBusStop(); 
       plotUserLocation(); 
       mapView.invalidate(); 
      } else { 
       AlertDialog dialog = createSimpleDialog("Error", "Unable to retrieve bus location info..."); 
       dialog.show(); 
      } 
     } 
    } 
} 

任何帮助表示赞赏。

回答

0

我有同样的问题,但经过谷歌搜索后,我才知道mapview现在已被弃用。所以,你必须使用地图片段和扩展,而不是mapactivity

fragmentActivity