目標Achievements
這個類別顧名思義就是要去顯示目前使用者的地理位置並顯示在我們的地圖上面。
程式碼Code
package lien.ching.maptracker.overlay; import android.Manifest; import android.app.ActionBar; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; import android.location.Criteria; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.util.Log; import android.widget.TextView; import org.mapsforge.core.graphics.Bitmap; import org.mapsforge.core.graphics.Canvas; import org.mapsforge.core.graphics.GraphicFactory; import org.mapsforge.core.graphics.Paint; import org.mapsforge.core.graphics.Style; import org.mapsforge.core.model.BoundingBox; import org.mapsforge.core.model.LatLong; import org.mapsforge.core.model.Point; import org.mapsforge.map.android.graphics.AndroidGraphicFactory; import org.mapsforge.map.android.view.MapView; import org.mapsforge.map.layer.Layer; import org.mapsforge.map.layer.overlay.Circle; import org.mapsforge.map.layer.overlay.Marker; import org.mapsforge.map.layer.overlay.Polyline; import org.mapsforge.map.model.MapViewPosition; import org.mapsforge.map.android.util.AndroidSupportUtil; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import lien.ching.maptracker.R; /** * Created by lienching on 12/2/15. */ //This class is using LocationManager to provided location information it may cause some issue, for more reliable location information use Google Play services location APIs(http://developer.android.com/training/location/index.html) public class NowLocationLayout extends Layer implements LocationListener,GpsStatus.Listener,ActivityCompat.OnRequestPermissionsResultCallback { private Activity activity; private MapViewPosition mapViewPosition; private MapView mapView; private LocationManager locationManager; private Listhistory_path; private Boolean track; //For drawing purpose (http://mapsforge.org/docs/0.6.0/org/mapsforge/map/android/graphics/AndroidGraphicFactory.html) private static final GraphicFactory GRAPHIC_FACTORY = AndroidGraphicFactory.INSTANCE; private Circle accuray_circle; private Marker loc_marker; private Polyline usr_path; //Constructor public NowLocationLayout(Activity activity,MapViewPosition mapViewPosition,MapView mapView){ this.activity = activity; this.mapViewPosition = mapViewPosition; this.mapView = mapView; this.locationManager = (LocationManager) activity.getSystemService(activity.LOCATION_SERVICE); track = false; locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L,0, this); //Check if location services available if(!locationManager.isProviderEnabled (LocationManager.GPS_PROVIDER)){ activity.startActivityForResult(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS), 0); } locationManager.addGpsStatusListener(this);//To add satellite listener //setDisplayModel(this.displayModel) set circle, polyline, marker etc... in to mapview's display model, so DisplayModel.getTileSize() won't point to a null object. accuray_circle = new Circle(null,0,getDefaultCircleFill(),getDefaultCircleStroke());//Circle(LatLong,radius,color,stroke); accuray_circle.setDisplayModel(mapView.getModel().displayModel); usr_path = new Polyline(getDefaultPolylineStroke(),GRAPHIC_FACTORY); usr_path.setDisplayModel(mapView.getModel().displayModel); //AndroidGraphicFactory.convertToBitmap() for detail please check AndroidGraphicFactory Drawable drawable = activity.getResources().getDrawable(R.drawable.locationmarker); Bitmap bitmap = AndroidGraphicFactory.convertToBitmap(drawable); loc_marker = new Marker(null, bitmap, 1, 0); loc_marker.setDisplayModel(mapView.getModel().displayModel); history_path = new LinkedList ();//record user path } //Transfer Function private LatLong LocationToLatLong(Location location){ LatLong latlong = new LatLong(location.getLatitude(),location.getLongitude()); return latlong; } //Getter protected Paint getPaint(int color, float strokeWidth, Style style){ Paint paint = GRAPHIC_FACTORY.createPaint(); paint.setColor(color); paint.setStrokeWidth(strokeWidth); paint.setStyle(style); return paint; } private Paint getDefaultCircleFill() { return this.getPaint(GRAPHIC_FACTORY.createColor(48, 0, 0, 255), 0, Style.FILL); } private Paint getDefaultCircleStroke() { return this.getPaint(GRAPHIC_FACTORY.createColor(160, 0, 0, 255), 2, Style.STROKE); } private Paint getDefaultPolylineStroke() { return this.getPaint(GRAPHIC_FACTORY.createColor(160, 0, 255, 0), 20, Style.STROKE); } //Enable Location Tracking public void startTrack(){ this.track = true; } @Override public void draw(BoundingBox boundingBox, byte zoomLevel, Canvas canvas, Point topLeftPoint) { if(track) { loc_marker.draw(boundingBox, zoomLevel, canvas, topLeftPoint); accuray_circle.draw(boundingBox, zoomLevel, canvas, topLeftPoint); } List temp = usr_path.getLatLongs(); //To get all the LatLong that had been drew temp.removeAll(temp); //Remove all temp.addAll(history_path);//To re-add all path usr_path.draw(boundingBox, zoomLevel, canvas, topLeftPoint); } @Override public void onGpsStatusChanged(int event) { } @Override public void onLocationChanged(Location location) { LatLong latLong = this.LocationToLatLong(location); loc_marker.setLatLong(latLong); accuray_circle.setLatLong(latLong); history_path.add(latLong); accuray_circle.setRadius(location.getAccuracy()); mapViewPosition.setCenter(latLong); mapViewPosition.setZoomLevel((byte) 17); requestRedraw(); } @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) { locationManager.requestLocationUpdates(provider, 1000L, 0, this); if(locationManager.GPS_PROVIDER.equals(provider)) { track = true; } } @Override public void onProviderDisabled(String provider) { if(locationManager.GPS_PROVIDER.equals(provider)){ track = false; } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {} }
說明Explanation
第79行:這行是用來設定GPS更新頻率,參數大概為(地理資訊提供(GPS, Network), 更新時間(單位:毫秒), 更新距離(當距離超過就更新), 接收資訊的Listener),For Detail
第90、93、99行:如果不把那些物件的DisplayModel設定成MapView的,會出現NullPointerException
第145~147行:第145行是Pass by Reference所以我們可以直接用temp去操作,然後我們先把原本的List清空,再把歷史紀錄再放回去
第164行:這句是利用GPS準確度來當作圓的半徑,For Detail
沒有留言:
張貼留言