Map overlay not updating - android

i am trying to draw the path as the farmer moves around his farm the below are my classes ,my problem is when i start tracing the line moves even when the user is not moving and path is not updating as he moves
public class RouteOverlay extends Overlay {
private GeoPoint gp1;
private GeoPoint gp2;
private int mode = 1;
public RouteOverlay(GeoPoint paramGeoPoint1, GeoPoint paramGeoPoint2,int paramInt)
{
this.gp1 = paramGeoPoint1;
this.gp2 = paramGeoPoint2;
this.mode = paramInt;
}
public void draw(Canvas paramCanvas, MapView paramMapView,
boolean paramShadow)
{
super.draw(paramCanvas, paramMapView, paramShadow);
Projection projection = paramMapView.getProjection();
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(3);
mPaint.setAlpha(120);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path.moveTo(p2.x,p2.y);
path.lineTo(p1.x,p1.y);
paramCanvas.drawPath(path, mPaint);
}
mainactivity:
public class MainActivity extends MapActivity {
public final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
coordinates.add(location);
mapView.getController().animateTo(getGeoByLocation(location));
drawRoute(coordinates, mapView);
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_area_measurement);
this.mapView = ((MapView) findViewById(R.id.mapview));
this.mapView.setBuiltInZoomControls(false);
this.mapView.getController().setZoom(17);
this.coordinates = new ArrayList<Location>();
}
protected boolean isRouteDisplayed() {
return false;
}
private GeoPoint getGeoByLocation(Location location) {
GeoPoint gp = null;
try {
if (location != null) {
double geoLatitude = location.getLatitude() * 1E6;
double geoLongitude = location.getLongitude() * 1E6;
gp = new GeoPoint((int) geoLatitude, (int) geoLongitude);
}
} catch (Exception e) {
e.printStackTrace();
}
return gp;
}
public String getLocationProvider(LocationManager paramLocationManager) {
try {
Criteria localCriteria = new Criteria();
localCriteria.setAccuracy(1);
localCriteria.setAltitudeRequired(false);
localCriteria.setBearingRequired(false);
localCriteria.setCostAllowed(true);
localCriteria.setPowerRequirement(3);
String str = paramLocationManager.getBestProvider(localCriteria,
true);
return str;
} catch (Exception localException) {
while (true) {
localException.printStackTrace();
}
}
}
private void drawRoute(ArrayList<Location> paramArrayList,MapView paramMapView) {
List<Overlay> overlays = paramMapView.getOverlays();
//Changed for smooth rendering
overlays.clear();
for (int i = 1; i < paramArrayList.size(); i++) {
overlays.add(new RouteOverlay(getGeoByLocation(paramArrayList.get(i - 1)), getGeoByLocation(paramArrayList.get(i)),2));
}
}
public void startRecording() {
this.isMeasuring = true;
lm = (LocationManager) getSystemService(LOCATION_SERVICE);
lm.requestLocationUpdates(getLocationProvider(lm),500,2,this.locationListener);
/*if (lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
gpsstatus.setText("Gps Is Enabled");
}else
{ gpsstatus.setText("Gps Is disabled");}*/
}

Can you confirm that you're always using the GPS to trace the route? Otherwise you might get incorrect results and your patch might get drawn like on Apple maps. For those cases always try using the GPS, I'm sure you don't want incorrect path to be drawn on the map. The network provider can triangulate a relative point on the map, but it will be incorrect 99% of the time in this case, because the position is relative.
Cheers

Related

Overlay not drawing on the right spot

I have an extremely weird issue.
First of all, when I zoom in and out of a MapView, the marker (overlay) moves to incorrect places (doesn't work well with scaling).
Secondly, the market is being drawn at the wrong position!
I'll post code below but first listen to this:
I'm in Islamabad. The GeoCoder also tells me I'm in Islamabad. But when I draw a circle around my location using overlays, it draws it in a city that's 100s of kilometers away.
Kindly help me with both the problems.
Here's the activity:
public class LocatePickup extends MapActivity implements LocationListener {
Geocoder gc;
MapView mapView;
MapController mc;
GeoPoint p;
double lat = 0;
double lng = 0;
LocationManager lm;
WebMethods wm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.locate_pickup);
mapView = (MapView) findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mapView.setStreetView(true);
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000L, 500.0f, this);
Location l = new Location(LocationManager.NETWORK_PROVIDER);
l = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
mc = mapView.getController();
p = new GeoPoint((int) (l.getLatitude()), (int) (l.getLongitude()));
mc.setCenter(p);
mc.setZoom(14);
MapOverlay myLocationOverlay = new MapOverlay();
List<Overlay> list = mapView.getOverlays();
list.add(myLocationOverlay);
gc = new Geocoder(this);
try {
List<Address> address = gc.getFromLocation(l.getLatitude(), l.getLongitude(), 1);
Toast.makeText(this, ""+address.get(0).getAddressLine(1), 1).show();
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
class MapOverlay extends com.google.android.maps.Overlay {
Paint paint = new Paint();
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
Point myScreenCoords = new Point();
mapView.getProjection().toPixels(p, myScreenCoords);
paint.setStrokeWidth(1);
paint.setARGB(255, 218, 28, 28);
paint.setStyle(Paint.Style.STROKE);
//Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.pin);
canvas.drawCircle(myScreenCoords.x, myScreenCoords.y, 15, paint);
//(bmp, myScreenCoords.x, myScreenCoords.y - 256, paint);
canvas.drawText("Hey!", myScreenCoords.x, myScreenCoords.y, paint);
return true;
}
}
#Override
public void onLocationChanged(Location arg0) {
if(arg0 != null) {
Log.d("New Location: ", arg0.getLatitude() + " - " + arg0.getLongitude());
lat = arg0.getLatitude();
lng = arg0.getLongitude();
p = new GeoPoint((int) lat * 1000000, (int) lng * 1000000);
mc.animateTo(p);
}
}
#Override
public void onProviderDisabled(String provider) {
// empty
}
#Override
public void onProviderEnabled(String provider) {
// empty
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
//empty
}
}
Once the code is complete, I'd like the user to be able to tap a spot on the map and get its address (the marker should move to that spot as well). But it should be accurate.
Since no one answered this question correctly..
For some reason, the normal Overlay class wasn't working for me the way it should have. I switched to ItemizedOverlay and now everything is perfect.
I'm no Android expert so I'd like someone with better experience to comment on this but, I feel that ItemizedOverlay is much better than the simple Overlay. With itemizedoverlay, zooming in and out of the mapview with an object drawn at a fixed point works the way it should, the pin (object) stays exactly where it should stay (that wasn't the case previously).
Here's some code for those who are looking for it. This is of course incomplete, and for a specific purpose, but you get the general idea.
`class CustomOverlay extends com.google.android.maps.ItemizedOverlay
{
private ArrayList mOverlays = new ArrayList();
Context mContext;
public CustomOverlay(Drawable defaultMarker)
{
super(defaultMarker);
}
public void addOverlay(OverlayItem overlay)
{
mOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i)
{
return mOverlays.get(i);
}
#Override
public int size()
{
return mOverlays.size();
}
public CustomOverlay(Drawable defaultMarker, Context context)
{
super(boundCenterBottom(defaultMarker));
mContext = context;
}
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView)
{
if (event.getAction() == 1)
{
p = mapView.getProjection().fromPixels((int) event.getX(),
(int) event.getY());
gc = new Geocoder(getBaseContext(), Locale.getDefault());
try
{
address = gc.getFromLocation(
(double) p.getLatitudeE6() / 1E6,
(double) p.getLongitudeE6() / 1E6, 1);
addressfound = true;
}
catch (IOException e)
{
addressfound = false;
e.printStackTrace();
}
if (address.size() != 0)
{
l1 = address.get(0).getAddressLine(0);
l2 = address.get(0).getAddressLine(1);
l3 = address.get(0).getAddressLine(2);
}
OverlayItem point = new OverlayItem(p, "Location", l1 + ", "
+ l2 + ", " + l3);
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = getBaseContext().getResources()
.getDrawable(R.drawable.androidmarker);
CustomOverlay itemizedoverlay = new CustomOverlay(drawable,
getBaseContext());
itemizedoverlay.addOverlay(point);
mapOverlays.clear();
mapOverlays.add(itemizedoverlay);
mapView.invalidate();
}`

Unable To Call Task Within A Thread

I am trying to display multiple pin locations on the map i.e. my location and another location I get from the cloud server.
Based on the code below:
I keep getting a NullPointer Error message when I try to tokenize my string. This implies that my CloudTask activity is never fired.... I can't figure out why and the Eclipse Debugger won't step through the threads...any help is appreciated.
public class MapsActivity extends com.google.android.maps.MapActivity {
private static final String TAG = null;
private MapController mapController;
private MapView mapView;
private LocationManager locationManager;
private MyOverlays itemizedoverlay;
private MyLocationOverlay myLocationOverlay;
private MyLocationOverlay otherLocationOverlay;
private Handler handler;
private String message;
StringTokenizer tokens;
Integer p1 = null;
Integer p2;
GeoPoint point;
static Context mContext = null;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.main); // bind the layout to the activity
// Configure the Map
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mapView.setSatellite(true);
mapController = mapView.getController();
mapController.setZoom(14); // Zoon 1 is world view
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 2500,
0,(LocationListener) new GeoUpdateHandler());
//new Intent("android.intent.action.LOCATION_CHANGED");
//(LocationListener) new GeoUpdateHandler());
myLocationOverlay = new MyLocationOverlay(this, mapView);
mapView.getOverlays().add(myLocationOverlay);
handler = new Handler();
// new AsyncTask<Void, Void, String>() {
myLocationOverlay.runOnFirstFix(new Runnable(){
public void run(){
MyRequestFactory requestFactory = Util.getRequestFactory(mContext,
MyRequestFactory.class);
final CloudTask1Request request = requestFactory.cloudTask1Request();
Log.i(TAG, "Sending request to server");
request.queryTasks().fire(new Receiver<List<TaskProxy>>() {
#Override
public void onSuccess(List<TaskProxy> taskList) {
//message = result;
message = "\n";
for (TaskProxy task : taskList) {
message += task.getId()+","+task.getNote()+",";
}
}
});
//return message;
//}
if(message.length() == 0){
Log.i("MESSAGE","Did not get any points from cloud");
}
tokens = new StringTokenizer(message,",");
tokens.nextToken();
p1 = Integer.parseInt(tokens.nextToken());
p2 = Integer.parseInt(tokens.nextToken());
point = new GeoPoint(p1,p2);
mapView.getController().animateTo(point);
}
});
Drawable drawable = this.getResources().getDrawable(R.drawable.pushpin);
itemizedoverlay = new MyOverlays(this, drawable);
createMarker();
myLocationOverlay.runOnFirstFix(new Runnable() {
public void run() {
mapView.getController().animateTo(
myLocationOverlay.getMyLocation());
}
});
//Drawable drawable = this.getResources().getDrawable(R.drawable.pushpin);
itemizedoverlay = new MyOverlays(this, drawable);
createMarker();
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
public class GeoUpdateHandler implements LocationListener {
#Override
public void onLocationChanged(Location location) {
int lat = (int) (location.getLatitude() * 1E6);
int lng = (int) (location.getLongitude() * 1E6);
GeoPoint point = new GeoPoint(lat, lng);
createMarker();
mapController.animateTo(point); // mapController.setCenter(point);
}
#Override
public void onProviderDisabled(String provider) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
private void createMarker() {
GeoPoint p = mapView.getMapCenter();
OverlayItem overlayitem = new OverlayItem(p, "", "");
itemizedoverlay.addOverlay(overlayitem);
if (itemizedoverlay.size() > 0) {
mapView.getOverlays().add(itemizedoverlay);
}
}
#Override
protected void onResume() {
super.onResume();
myLocationOverlay.enableMyLocation();
myLocationOverlay.enableCompass();
}
#Override
protected void onPause() {
super.onResume();
myLocationOverlay.disableMyLocation();
myLocationOverlay.disableCompass();
}
}
put these inside onSuccess()
if(message.length() == 0){
Log.i("MESSAGE","Did not get any points from cloud");
}
tokens = new StringTokenizer(message,",");
tokens.nextToken();
p1 = Integer.parseInt(tokens.nextToken());
p2 = Integer.parseInt(tokens.nextToken());
point = new GeoPoint(p1,p2);
mapView.getController().animateTo(point);

How I can get current geographical location of the device programatically

I need to get the device's current geographical location.
Scenario : if I am in US..:
my device location should be US
Same as in the case, when I am in UK :
my device location should be UK
I need the sample code for finding this geographical location.(location determined by Network Location Provider)
If you want to get the current country code, you want to look into Geocoder which you can use to get an Address which provides a getCountryCode method. Something like this
Geocoder geocoder = new Geocoder(this);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(), 1);
} catch (IOException e) {
e.printStackTrace();
}
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String countryCode = address.getCountryCode();
}
As far as getting the current latitude and longitude, there is plenty of information out there on how to do that
How do I get the current GPS location programmatically in Android?
What is the simplest and most robust way to get the user's current location on Android?
http://developer.android.com/guide/topics/location/index.html
Here is the code
Main MapActivity
public class WhereIam extends MapActivity {
MapController mapController;
MyPositionOverlay positionOverlay;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
MapView myMapView=(MapView)findViewById(R.id.myMapView);
myMapView.setSatellite(true);
myMapView.setBuiltInZoomControls(true);
mapController=myMapView.getController();
mapController.setZoom(17);
positionOverlay = new MyPositionOverlay();
List<Overlay> overlays = myMapView.getOverlays();
overlays.add(positionOverlay);
LocationManager locationManager;
String context=Context.LOCATION_SERVICE;
locationManager=(LocationManager)getSystemService(context);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
String provider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(provider);
final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
updateWithNewLocation(location);
}
public void onProviderDisabled(String provider){
updateWithNewLocation(null);
}
public void onProviderEnabled(String provider){ }
public void onStatusChanged(String provider, int status,
Bundle extras){ }
};
updateWithNewLocation(location);
locationManager.requestLocationUpdates(provider, 2000, 10,
locationListener);
}
private void updateWithNewLocation(Location location) {
if(location!=null) {
// Update the map location.
positionOverlay.setLocation(location);
Double geoLat = location.getLatitude()*1E6;
Double geoLng = location.getLongitude()*1E6;
GeoPoint point = new GeoPoint(geoLat.intValue(),
geoLng.intValue());
mapController.animateTo(point);
}
}
#Override
protected boolean isRouteDisplayed() {
return true;
}
Another MyPositionOverlay class
public class MyPositionOverlay extends Overlay {
Location location;
private final int mRadius = 5;
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Projection projection = mapView.getProjection();
if (shadow == false) {
// Get the current location
Double latitude = location.getLatitude()*1E6;
Double longitude = location.getLongitude()*1E6;
GeoPoint geoPoint;
geoPoint = new GeoPoint(latitude.intValue(),longitude.intValue());
// Convert the location to screen pixels
Point point = new Point();
projection.toPixels(geoPoint, point);
RectF oval = new RectF(point.x - mRadius, point.y - mRadius,
point.x + mRadius, point.y + mRadius);
// Setup the paint
Paint paint = new Paint();
paint.setARGB(250, 255, 0, 0);
paint.setAntiAlias(true);
paint.setFakeBoldText(true);
Paint backPaint = new Paint();
backPaint.setARGB(175, 50, 50, 50);
backPaint.setAntiAlias(true);
RectF backRect = new RectF(point.x + 2 + mRadius,
point.y - 3*mRadius,
point.x + 65, point.y + mRadius);
// Draw the marker
canvas.drawOval(oval, paint);
canvas.drawRoundRect(backRect, 5, 5, backPaint);
canvas.drawText("Here I Am", point.x + 2*mRadius, point.y, paint);
}
super.draw(canvas, mapView, shadow);
}
#Override
public boolean onTap(GeoPoint point, MapView mapView) {
return false;
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
}
There are many tutorial available for this, Here on SO i have read nice answer by Fedor on get current location of the user, try this What is the simplest and most robust way to get the user's current location in Android?. To give answer of your question in code is some lengthy, also in that answer he explain nice way..
Also go through Android developer guide Obtaining User Location for basic information how location manager works in android..
Thanks.
Above solutions is also correct, but some time if location is null then it crash the app or not working properly. The best way to get Latitude and Longitude of android is:
Geocoder geocoder;
String bestProvider;
List<Address> user = null;
double lat;
double lng;
LocationManager lm = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
bestProvider = lm.getBestProvider(criteria, false);
Location location = lm.getLastKnownLocation(bestProvider);
if (location == null){
Toast.makeText(activity,"Location Not found",Toast.LENGTH_LONG).show();
}else{
geocoder = new Geocoder(activity);
try {
user = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
lat=(double)user.get(0).getLatitude();
lng=(double)user.get(0).getLongitude();
System.out.println(" DDD lat: " +lat+", longitude: "+lng);
}catch (Exception e) {
e.printStackTrace();
}
}
public class LocationHelper {
LocationManager locationManager;
public boolean getLocation(Context context)
{
if(locationManager==null)
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
List<String> providers = locationManager.getAllProviders();
Location location;
for(String provider: providers) {
try {
if(locationManager.isProviderEnabled(provider)) {
//dont use listener, it sometimes does not work
location = locationManager.getLastKnownLocation(provider);
if(location != null) {
getDeviceInfo(location, context);
break;
}
}
} catch (Exception e) {
}
}
return true;
}
private void getDeviceInfo(Location location, Context context) {
Geocoder geocoder = new Geocoder(context);
List<Address> addresses = null;
try {
addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
} catch (Exception e) {
e.printStackTrace();
}
if (addresses != null && addresses.size() > 0) {
Address address = addresses.get(0);
String countryCode = address.getCountryCode();
//any other data...
}
}
}

I want to open my current location in google map

i want to open or focus to my current location in google map in android. I want my app to get coordinates and then give the name of my location from these coordinates and also in the end focus the current location map...
Kindly someone suggest me what and how to do and if possible give me some code sample. i m new to android :)
Thanks in advance! :)
here is the example of simple map display with current location
MyMap.java for display map
class MyMap extends MapActivity{
/** Called when the activity is first created. */
GeoPoint defaultPoint;
static GeoPoint point;
static MapController mc;
static MapView mapView;
static double curLat =0;
static double curLng =0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
String coordinates[] = {"22.286595", "70.795685"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
mc = mapView.getController();
defaultPoint = new GeoPoint(
(int) (lat * 1E6),
(int) (lng * 1E6));
mc.animateTo(defaultPoint);
mc.setZoom(13);
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
Intent startService = new Intent(getApplicationContext(),ServiceLocation.class);
startService(startService);
}
public static void updateMap() {
if(ServiceLocation.curLocation!=null){
curLat = ServiceLocation.curLocation.getLatitude();
curLng = ServiceLocation.curLocation.getLongitude();
if(mapView!=null){
point = new GeoPoint((int)(curLat*1e6),(int)(curLng*1e6));
mc.animateTo(point);
mapView.invalidate();
}
}
}
#Override
protected boolean isRouteDisplayed(){
return false;
}
class MapOverlay extends com.google.android.maps.Overlay{
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when) {
super.draw(canvas, mapView, shadow);
if(!shadow){
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
if(curLat==0 && curLng==0)
mapView.getProjection().toPixels(defaultPoint, screenPts);
else{
mapView.getProjection().toPixels(point, screenPts);
}
//---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.cur_loc);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);
}
return true;
}
}
}
here is my background service code for fetching lat/lng using gps
class ServiceLocation extends Service{
private LocationManager locMan;
private Boolean locationChanged;
private Handler handler = new Handler();
public static Location centerLoc;
public static Location curLocation;
public static boolean isService = true;
LocationListener gpsListener = new LocationListener() {
public void onLocationChanged(Location location) {
if (curLocation == null) {
curLocation = location;
locationChanged = true;
}else if (curLocation.getLatitude() == location.getLatitude() && curLocation.getLongitude() == location.getLongitude()){
locationChanged = false;
return;
}else
locationChanged = true;
curLocation = location;
if (locationChanged)
locMan.removeUpdates(gpsListener);
MyMap.updateMap();
}
public void onProviderDisabled(String provider) {
}
public void onProviderEnabled(String provider) {
// Log.w("GPS", "Location changed", null);
}
public void onStatusChanged(String provider, int status,Bundle extras) {
if (status == 0)// UnAvailable
{
} else if (status == 1)// Trying to Connect
{
} else if (status == 2) {// Available
}
}
};
#Override
public void onCreate() {
super.onCreate();
if (locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,100, 1, gpsListener);
} else {
this.startActivity(new Intent("android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS"));
}
centerLoc = new Location("");
curLocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);;*/
centerLoc = new Location("");
curLocation = getBestLocation();
if (curLocation == null)
Toast.makeText(getBaseContext(),"Unable to get your location", Toast.LENGTH_SHORT).show();
isService = true;
}
final String TAG="LocationService";
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onLowMemory() {
super.onLowMemory();
}
#Override
public void onStart(Intent i, int startId){
handler.postDelayed(GpsFinder,5000);// will start after 5 seconds
}
#Override
public void onDestroy() {
handler.removeCallbacks(GpsFinder);
handler = null;
Toast.makeText(this, "Stop services", Toast.LENGTH_SHORT).show();
isService = false;
}
public IBinder onBind(Intent arg0) {
return null;
}
public Runnable GpsFinder = new Runnable(){
public void run(){
Location tempLoc = getBestLocation();
if(tempLoc!=null)
curLocation = tempLoc;
handler.postDelayed(GpsFinder,5000);// register again to start after 5 seconds...
}
};
private Location getBestLocation() {
Location gpslocation = null;
Location networkLocation = null;
if(locMan==null)
locMan = (LocationManager) getApplicationContext() .getSystemService(Context.LOCATION_SERVICE);
try {
if(locMan.isProviderEnabled(LocationManager.GPS_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER,100, 1, gpsListener);
gpslocation = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
if(locMan.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
locMan.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,100, 1, gpsListener);
networkLocation = locMan.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
} catch (IllegalArgumentException e) {
//Log.e(ErrorCode.ILLEGALARGUMENTERROR, e.toString());
Log.e("error", e.toString());
}
if(gpslocation==null && networkLocation==null)
return null;
if(gpslocation!=null && networkLocation!=null){
if(gpslocation.getTime() < networkLocation.getTime())
return networkLocation;
else
return gpslocation;
}
if (gpslocation == null) {
return networkLocation;
}
if (networkLocation == null) {
return gpslocation;
}
return null;
}
}

Draw the route between 2 overlays

In my app I displayed on map 2 locations and I marked them with a marker. Now, I want to draw the route between them,and I don't know how can I do this. How should my function draw look like?
This is my code:
package com.ShoppingList.Maps;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.KeyEvent;
import android.widget.TextView;
import android.widget.Toast;
import com.ShoppingList.R;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
import java.util.ArrayList;
import java.util.List;
public class OnMap extends MapActivity {
private MapView map = null;
private MyLocationOverlay me = null;
//private myOverlay m = null;
double latitudine;
double longitudine;
double latshop;
double longshop;
String nameshop;
Canvas canvas = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.shopsonmap);
map = (MapView) findViewById(R.id.shopsonmap);
latitudine = getIntent().getDoubleExtra("latcurent", 0);
longitudine = getIntent().getDoubleExtra("longcurent", 0);
latshop = getIntent().getDoubleExtra("latshop", 0);
longshop = getIntent().getDoubleExtra("longshop", 0);
nameshop = getIntent().getStringExtra("nameshop");
GeoPoint p1 = new GeoPoint((int) latitudine, (int) longitudine);
GeoPoint p2 = new GeoPoint((int) latshop, (int) longshop);
map.getController().setCenter(getPoint(latitudine, longitudine));
map.getController().setZoom(15);
map.setBuiltInZoomControls(true);
map.setSatellite(false);
map.setStreetView(true);
map.invalidate();
Drawable marker = getResources().getDrawable(R.drawable.marker);
marker.setBounds(0, 0, marker.getIntrinsicWidth(), marker
.getIntrinsicHeight());
map.getOverlays().add(new SitesOverlay(marker));
me = new MyLocationOverlay(this, map);
map.getOverlays().add(me);
}
/*class myOverlay extends Overlay {
GeoPoint gp1;
GeoPoint gp2;
public myOverlay(GeoPoint gp1, GeoPoint gp2) {
this.gp1 = gp1;
this.gp2 = gp2;
}
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Projection projection = mapView.getProjection();
Paint mPaint = new Paint();
Point from = new Point();
projection.toPixels(gp1, from);
mPaint.setColor(Color.BLUE);
Point to = new Point();
projection.toPixels(gp2, to);
mPaint.setStrokeWidth(9);
mPaint.setAlpha(120);
canvas.drawLine(from.x, from.y, to.x, to.y, mPaint);
super.draw(canvas, mapView, shadow);
}
}*/
#Override
public void onResume() {
super.onResume();
me.enableCompass();
}
#Override
public void onPause() {
super.onPause();
me.disableCompass();
}
#Override
protected boolean isRouteDisplayed() {
return (false);
}
private GeoPoint getPoint(double lat, double lon) {
return (new GeoPoint((int) (lat * 1000000.0), (int) (lon * 1000000.0)));
}
private class SitesOverlay extends ItemizedOverlay<OverlayItem> {
private List<OverlayItem> items = new ArrayList<OverlayItem>();
private Drawable marker = null;
public SitesOverlay(Drawable marker) {
super(marker);
this.marker = marker;
items.add(new OverlayItem(getPoint(latitudine, longitudine),
"Your location", "You are here!"));
items.add(new OverlayItem(getPoint(latshop, longshop), "The shop",
"The shop " + nameshop + " is here"));
populate();
}
#Override
protected OverlayItem createItem(int i) {
return (items.get(i));
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
boundCenterBottom(marker);
}
#Override
protected boolean onTap(int i) {
Toast.makeText(OnMap.this, items.get(i).getSnippet(),
Toast.LENGTH_SHORT).show();
return (true);
}
#Override
public int size() {
return (items.size());
}
}
}
Thanks..
So let's suppose you are obtaining the locations (in JSON) from a REST web service. For this, I used Volley library to connect and obtain the response from the server.
Example of JSONArray response:
[ {...,"location":"44.924654,8.586219", ...},
{...,"location":"44.906177,8.157752", ...},
{...,"location":"44.906177,8.157752", ...}, {..., "location":
"44.956733,7.876227", ...}, {..., "location": "45.034424,7.671607",
...} ]
The step would be to set the first and the last locations as the markers, and the intermediate locations will draw the line between them.
Because location is obtained as a string, we have first to split the string and assign the part before the "," to the latitude and the rest as longitude.
public void onResponse(JSONArray response) {
if (response.length() > 0) {
try {
//creating the markers: for this I need the first and the last location
JSONObject firstLocationJson = response.getJSONObject(0);
JSONObject lastLocationJson = response.getJSONObject(response.length() - 1);
String[] firstLocationLatLng = firstLocationJson.getString("location").split(",");
Location firstLocation = new Location(LocationManager.GPS_PROVIDER);
firstLocation.setLatitude(Double.parseDouble(firstLocationLatLng[0]));
firstLocation.setLongitude(Double.parseDouble(firstLocationLatLng[1]));
String[] lastLocationLatLng = lastLocationJson.getString("location").split(",");
Location lastLocation = new Location(LocationManager.GPS_PROVIDER);
lastLocation.setLatitude(Double.parseDouble(lastLocationLatLng[0]));
lastLocation.setLongitude(Double.parseDouble(lastLocationLatLng[1]));
final float distance = firstLocation.distanceTo(lastLocation); //distance in meters
if (distance > 50000 && distance < 200000) { //distance bigger than 50 km
showMapView(response, firstLocation, lastLocation, 7);
} else if (distance > 300000) {
showMapView(response, firstLocation, lastLocation, 5);
}
} catch (JSONException e) {
// TODO
}
}
// TODO -
}
Now let's see the method that is drawing our MapView. Note that I am not inside an activity, and if I want to force code to be run on main thread (for updating the UI), I will use a Handler and a Runnable.
The method showMapView() is the one taking care of drawing the markers and the locations in between.
private void showMapView(JSONArray response, Location firstLoc, Location lastLoc, final int zoom) {
final LatLng latLng1 = new LatLng(firstLoc.getLatitude(), firstLoc.getLongitude());
final LatLng latLng2 = new LatLng(lastLoc.getLatitude(), lastLoc.getLongitude());
final MarkerOptions marker1 = new MarkerOptions().position(latLng1);
final MarkerOptions marker2 = new MarkerOptions().position(latLng2);
final PolylineOptions polylineOptions = new PolylineOptions();
final ArrayList<LatLng> points = new ArrayList<LatLng>();
//saving all the locations in an ArrayList
if (response.length() > 0) {
for (int i = 0; i < response.length(); i++) {
JSONObject locationsJson = null;
try {
locationsJson = response.getJSONObject(i);
} catch (JSONException e) {
e.printStackTrace();
}
String locationString = null;
try {
locationString = locationsJson.getString("location");
} catch (JSONException e) {
e.printStackTrace();
}
//here I am splitting the location string in a String array.
String[] locationLatLng = locationString.split(",");
Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(Double.parseDouble(locationLatLng[0]));
loc.setLongitude(Double.parseDouble(locationLatLng[1]));
LatLng latLng = new LatLng(loc.getLatitude(), loc.getLongitude());
points.add(latLng);
}
}
Handler mainHandler = new Handler(Looper.getMainLooper());
Runnable myRunnable = new Runnable() {
#Override
public void run() {
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
googleMap.addMarker(marker1);
googleMap.addMarker(marker2);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng1, zoom));
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng2, zoom));
polylineOptions.addAll(points);
polylineOptions.width(10);
polylineOptions.color(Color.BLUE);
googleMap.addPolyline(polylineOptions);
}
});
}
};
mainHandler.post(myRunnable);
}
The code is plain and clear, the points (intermediate locations) are draw using an object of type PolylineOptions and it is added to the map using this line: googleMap.addPolyline(polylineOptions);
The desired zoom level, is in the range of 2.0 to 21.0. Values below this range are set to 2.0, and values above it are set to 21.0. Increase the value to zoom in. Not all areas have tiles at the largest zoom levels.
read here about zoom
I have already given the answer of this question please read the following link blow
Draw line between two points in google map in android
I hope this is help.

Categories

Resources