Map Draw Path and Calculate Distance - android

How to Draw path and Calculate Distance on Move. The code below dont calculate distance at onLocationChanged method??
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
String text = String.format("Lat:\t %f\nLong:\t %f\nAlt:\t %f\nBearing:\t %f\nDistance:\t %f",
location.getLatitude() *1E6, location.getLongitude() *1E6,
location.getAltitude() *1E6, location.getBearing() *1E6, location.distanceTo(location));
textOut.setText(text);
lat = (int) (location.getLatitude() *1E6);
longi = (int) (location.getLongitude() *1E6);
GeoPoint myLocation = new GeoPoint(lat, longi);
OverlayItem overlayItem = new OverlayItem(myLocation, "WHATZ UP", "2nd String");
StagePoint custom = new StagePoint(d, Start.this);
custom.insertPinpoint(overlayItem);
overlayList.add(custom);
}

private class MyLocationOverlay1 extends MyLocationOverlay {
#Override
public void drawMyLocation(Canvas canvas, MapView mapView, Location lastFix, GeoPoint myLocation, long when)
super.drawMyLocation(canvas,mapView,lastFix,myLocation,when);
Location bLocation = new Location("reverseGeocoded");
bLocation.setLatitude(FindList.gpslat);
bLocation.setLongitude(FindList.gpslong);
Location aLocation = new Location("reverseGeocoded");
aLocation.setLatitude(myLocation.getLatitudeE6() / 1e6);
aLocation.setLongitude(myLocation.getLongitudeE6() / 1e6);
int distance = (int)aLocation.distanceTo(bLocation);
String str = " (" + String.valueOf(distance) + " meters)";
}
}

Related

Location change and put Marker on Click in openstreetmap

I am new to Open Street Map map. I want to put the marker on map where i Tapped. I want to delete previous marker also. Please help me.
Thanks in advance. Here is my code
Overlay touchOverlay = new Overlay(this) {
ItemizedIconOverlay<OverlayItem> anotherItemizedIconOverlay = null;
#Override
protected void draw(Canvas arg0, MapView arg1, boolean arg2) {
}
#Override
public boolean onSingleTapConfirmed(final MotionEvent e,
final MapView mapView) {
Projection proj = mapView.getProjection();
GeoPoint loc = (GeoPoint) proj.fromPixels((int) e.getX(),
(int) e.getY());
String longitude = Double
.toString(((double) loc.getLongitudeE6()) / 1000000);
String latitude = Double
.toString(((double) loc.getLatitudeE6()) / 1000000);
ArrayList<OverlayItem> overlayArray = new ArrayList<OverlayItem>();
OverlayItem mapItem = new OverlayItem("", "", new GeoPoint(
(((double) loc.getLatitudeE6()) / 1000000),
(((double) loc.getLongitudeE6()) / 1000000)));
Drawable marker = null;
mapItem.setMarker(marker);
overlayArray.add(mapItem);
if (anotherItemizedIconOverlay == null) {
anotherItemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
getApplicationContext(), overlayArray, null);
mapView.getOverlays().add(anotherItemizedIconOverlay);
mapView.invalidate();
} else {
mapView.getOverlays().remove(anotherItemizedIconOverlay);
mapView.invalidate();
anotherItemizedIconOverlay = new ItemizedIconOverlay<OverlayItem>(
getApplicationContext(), overlayArray, null);
mapView.getOverlays().add(anotherItemizedIconOverlay);
}
return true;
}
};
Finally i get solution of this problem. here is my answer.
#Override
public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView) {
Projection proj = mapView.getProjection();
p = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
proj = mapView.getProjection();
loc = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
String longitude = Double
.toString(((double) loc.getLongitudeE6()) / 1000000);
String latitude = Double
.toString(((double) loc.getLatitudeE6()) / 1000000);
Toast toast = Toast.makeText(getApplicationContext(),
"Longitude: "
+ longitude + " Latitude: " + latitude, Toast.LENGTH_SHORT);
toast.show();
return true;
}
private void addLocation(double lat, double lng) {
// ---Add a location marker---
p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
Drawable marker = getResources().getDrawable(
android.R.drawable.star_big_on);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
getApplicationContext());
myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(myItemizedOverlay);
mapView.invalidate();
}

How to make the touch event in openstreetmap android

I am suffering in OSM map. This new for me. I want to print the Toast message on Single-click and on Long press I try all things that can i do. But i don't get the right way. Here is my code. Please give me right way to solve this. Thanks in dvance. please
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map1);
final MapView mapView = (MapView) findViewById(R.id.mapViewosm);
mapView.setBuiltInZoomControls(true);
MapController myMapController = mapView.getController();
myMapController.setZoom(13);
ScaleBarOverlay myScaleBarOverlay = new ScaleBarOverlay(this);
mapView.getOverlays().add(myScaleBarOverlay);
Drawable marker = getResources().getDrawable(
android.R.drawable.star_big_on);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
getApplicationContext());
myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
mapView.getOverlays().add(myItemizedOverlay);
GeoPoint myPoint1 = new GeoPoint(0 * 1000000, 0 * 1000000);
myItemizedOverlay.addItem(myPoint1, "myPoint1", "myPoint1");
GeoPoint myPoint2 = new GeoPoint(50 * 1000000, 50 * 1000000);
myItemizedOverlay.addItem(myPoint2, "myPoint2", "myPoint2");
myLocationOverlay = new MyLocationOverlay(this, mapView);
mapView.getOverlays().add(myLocationOverlay);
myLocationOverlay.enableMyLocation();
myLocationOverlay.runOnFirstFix(new Runnable() {
public void run() {
mapView.getController().animateTo(
myLocationOverlay.getMyLocation());
}
});
// 2nd
// // --- Create Overlay
// overlayItemArray = new ArrayList<OverlayItem>();
//
// DefaultResourceProxyImpl defaultResourceProxyImpl = new
// DefaultResourceProxyImpl(
// this);
// MyItemizedIconOverlay myItemizedIconOverlay = new
// MyItemizedIconOverlay(
// overlayItemArray, null, defaultResourceProxyImpl);
// mapView.getOverlays().add(myItemizedIconOverlay);
// // ---
// locationManager = (LocationManager)
// getSystemService(Context.LOCATION_SERVICE);
//
// // for demo, getLastKnownLocation from GPS only, not from NETWORK
// Location lastLocation = locationManager
// .getLastKnownLocation(LocationManager.GPS_PROVIDER);
// if (lastLocation != null) {
// updateLoc(lastLocation);
// }
// 1st
anotherOverlayItemArray = new ArrayList<OverlayItem>();
anotherOverlayItemArray.add(new OverlayItem("0, 0", "0, 0",
new GeoPoint(0, 0)));
anotherOverlayItemArray.add(new OverlayItem("US", "US", new GeoPoint(
38.883333, -77.016667)));
ItemizedIconOverlay<OverlayItem> anotherItemizedIconOverlay = new
ItemizedIconOverlay<OverlayItem>(
this, anotherOverlayItemArray, myOnItemGestureListener);
mapView.getOverlays().add(anotherItemizedIconOverlay);
}
// 1st
OnItemGestureListener<OverlayItem> myOnItemGestureListener = new
OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemLongPress(int arg0, OverlayItem arg1) {
// TODO Auto-generated method stub
Toast.makeText(getApplicationContext(), "long tap",
Toast.LENGTH_SHORT).show();
return true;
}
#Override
public boolean onItemSingleTapUp(int index, OverlayItem item) {
Toast.makeText(getApplicationContext(), "single tap",
Toast.LENGTH_SHORT).show();
Toast.makeText(
Map.this,
item.mDescription + "\n" + item.mTitle + "\n"
+ item.mGeoPoint.getLatitudeE6() + " : "
+ item.mGeoPoint.getLongitudeE6(),
Toast.LENGTH_LONG).show();
return true;
}
};
in osm you can use MapEventsReceiver like blew to detect taps:
MapEventsReceiver mReceive = new MapEventsReceiver() {
#Override
public boolean singleTapConfirmedHelper(GeoPoint p) {
// write your code here
return false;
}
#Override
public boolean longPressHelper(GeoPoint p) {
// write your code here
return false;
}
};
MapEventsOverlay OverlayEvents = new MapEventsOverlay(getBaseContext(), mReceive);
map.getOverlays().add(OverlayEvents);
source:https://github.com/osmdroid/osmdroid/issues/295
Finally i got solution for this problem. here is my answer
#Override
public boolean onSingleTapConfirmed(MotionEvent e, MapView mapView) {
Projection proj = mapView.getProjection();
p = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
proj = mapView.getProjection();
loc = (GeoPoint) proj.fromPixels((int) e.getX(), (int) e.getY());
String longitude = Double
.toString(((double) loc.getLongitudeE6()) / 1000000);
String latitude = Double
.toString(((double) loc.getLatitudeE6()) / 1000000);
Toast toast = Toast.makeText(getApplicationContext(),
"Longitude: "
+ longitude + " Latitude: " + latitude, Toast.LENGTH_SHORT);
toast.show();
return true;
}
private void addLocation(double lat, double lng) {
// ---Add a location marker---
p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
Drawable marker = getResources().getDrawable(
android.R.drawable.star_big_on);
int markerWidth = marker.getIntrinsicWidth();
int markerHeight = marker.getIntrinsicHeight();
marker.setBounds(0, markerHeight, markerWidth, 0);
ResourceProxy resourceProxy = new DefaultResourceProxyImpl(
getApplicationContext());
myItemizedOverlay = new MyItemizedOverlay(marker, resourceProxy);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(myItemizedOverlay);
mapView.invalidate();
}

Android google maps show geo points which are closest to current location

Is there any way If I have like 100 geo points added in my MapActivity and I want to show only these which are like 1000m away from my current location. The other ones should not be visible on the map.
Any suggestions?
Ok, here is the example. You can subclass Overlay class and override draw method. Whenever the Overlay is invalidated, you should check if your points are within 1000m from your location. Off course, you should know your location within your overlay class. The flowing is the example:
public class MyMapOverlay extends Overlay {
Bitmap bmp;
Context context;
public MyMapOverlay()
{
bmp = BitmapFactory.decodeResource(MyApplication.getContext().getResources(), R.drawable.myplace);
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow, long when)
{
super.draw(canvas, mapView, shadow);
Point screenPts = new Point();
for(int i = 0;i<points.size(); i++)
{
GeoPoint point = points.get(i);
Location locationA = new Location("point " + String.valueOf(i));
locationA.setLatitude(point.getLatitudeE6());
locationA.setLongitude(point.getLongitudeE6());
float distance = myLocation.distanceTo(locationA);
if(distance < 1000.0)
{
mapView.getProjection().toPixels(p, screenPts);
canvas.drawBitmap(bmp, screenPts.x-bmp.getWidth()/2, screenPts.y-bmp.getHeight(), null);
}
}
return true;
}
With some help of the first answer I find this solution :
if(location != null){
Location locA = new Location("gps");
GeoPoint myLoc = new GeoPoint((int)(location.getLatitude() * 1E6), (int)(location.getLongitude() * 1E6));
mapController.animateTo(myLoc);
String sqlbars = "SELECT DISTINCT id, latitude, longitude, address, " +
" (SELECT category FROM bars_categories WHERE bar_id=bars.id) AS category " +
" FROM bars WHERE is_active=1";
Cursor curBars = dbHelper.executeSQLQuery(sqlbars);
if(curBars != null){
if(curBars.getCount() > 0){
for(curBars.move(0);curBars.moveToNext();curBars.isAfterLast()){
double latitude = curBars.getDouble(curBars.getColumnIndex("latitude"));
double longitude = curBars.getDouble(curBars.getColumnIndex("longitude"));
final List<Overlay> mapOverlays = mapView.getOverlays();
Drawable drawable = SofiaLiveNearbyActivity.this.getResources().getDrawable(R.drawable.pin_map_icon);
int markerWidth = drawable.getIntrinsicWidth();
int markerHeight = drawable.getIntrinsicHeight();
drawable.setBounds(0, markerHeight, markerWidth, 0);
final HelloItemizedOverlay itemizedoverlay = new HelloItemizedOverlay(drawable, SofiaLiveNearbyActivity.this);
GeoPoint point = new GeoPoint((int)(latitude * 1E6),(int)(longitude *1E6));
OverlayItem overlayitem = new OverlayItem(point, "Type: "+category+"\n----------------\nAddress: "+address, id);
locA.setLatitude(latitude);
locA.setLongitude(longitude);
float distance = location.distanceTo(locA);
if(distance < 1000.0){
itemizedoverlay.addOverlay(overlayitem);
mapOverlays.add(itemizedoverlay);
}
}
}
curBars.close();
}
and it worked.

Wrong distances when creating random locations

I am trying to create random locations nearby my location. What i want is to create random latitude/longitude pairs inside a 200 meters circle surrounding my location. After asking this question: generate random locations nearby my location this is what i have come up with.
in onLocationChanged, this is what i do:
private void updateWithNewLocation(Location location) {
if (location != null) {
this.myItemizedOverlay.clear();
this.nonPlayerItemizedOverlay.clear();
this.mapOverlays.clear();
// Update my map location.
Double latitude = location.getLatitude() * 1E6;
Double longitude = location.getLongitude() * 1E6;
GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
longitude.intValue());
CustomOverlayItem pcOverlayItem = new CustomOverlayItem(geoPoint,
"", "", "");
this.mapController.animateTo(geoPoint);
this.myItemizedOverlay.setLocation(location);
this.myItemizedOverlay.addOverlay(pcOverlayItem);
this.mapOverlays.add(this.myItemizedOverlay);
// Everytime i get a new location i generate random non player
// characters near my location
int numberOfNonPlayers = new Random().nextInt(5);
for (int i = 0; i < numberOfNonPlayers; i++) {
int radius = (int) this.myMapView.getProjection()
.metersToEquatorPixels(200);
double lowerLimit = -1;
double upperLimit = 1;
Double newLatitude = location.getLatitude()
* 1E6
+ (radius * (lowerLimit + (Math.random() * ((upperLimit - lowerLimit) + 1))));
Double newLongitude = location.getLongitude()
* 1E6
+ (radius * (lowerLimit + (Math.random() * ((upperLimit - lowerLimit) + 1))));
GeoPoint geoPoint2 = new GeoPoint(newLatitude.intValue(),
newLongitude.intValue());
CustomOverlayItem npcOverlayItem = new CustomOverlayItem(
geoPoint2, "", "", "");
Location newLocation = new Location("npc " + i);
newLocation.setLatitude(newLatitude);
newLocation.setLongitude(newLongitude);
this.nonPlayerItemizedOverlay = new NonPlayerItemizedOverlay(
this.nonPlayerDrawable, this.myMapView);
this.nonPlayerItemizedOverlay.setLocation(newLocation);
this.nonPlayerItemizedOverlay.addOverlay(npcOverlayItem);
this.mapOverlays.add(this.nonPlayerItemizedOverlay);
}
}
}
And this is my NonPlayerItemizedOverlay class:
public class NonPlayerItemizedOverlay extends BaseItemizedOverlay {
public NonPlayerItemizedOverlay(Drawable defaultMarker, MapView mapView) {
super(defaultMarker, mapView);
// TODO Auto-generated constructor stub
}
private Location location;
public static int metersToRadius(float meters, MapView map, double latitude) {
return (int) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math
.cos(Math.toRadians(latitude))));
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
if (shadow == false) {
Projection projection = mapView.getProjection();
// Get the current location
Double latitude = location.getLatitude();
Double longitude = location.getLongitude();
GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
longitude.intValue());
// Convert the location to screen pixels
Point point = new Point();
projection.toPixels(geoPoint, point);
// int radius = metersToRadius(30, mapView, latitude);
int radius = (int) mapView.getProjection()
.metersToEquatorPixels(50);
RectF oval = new RectF(point.x - radius, point.y - radius, point.x
+ radius, point.y + radius);
// Setup the paint
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(2.0f);
paint.setColor(0xffE62020);
paint.setStyle(Style.STROKE);
canvas.drawOval(oval, paint);
paint.setColor(0x18E62020);
paint.setStyle(Style.FILL);
canvas.drawOval(oval, paint);
}
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
And my MyItemizedOverlay class:
public class MyItemizedOverlay extends BaseItemizedOverlay {
public MyItemizedOverlay(Drawable defaultMarker, MapView mapView) {
super(defaultMarker, mapView);
// TODO Auto-generated constructor stub
}
private Location location;
public static int metersToRadius(float meters, MapView map, double latitude) {
return (int) (map.getProjection().metersToEquatorPixels(meters) * (1 / Math
.cos(Math.toRadians(latitude))));
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
super.draw(canvas, mapView, shadow);
if (shadow == false) {
Projection projection = mapView.getProjection();
// Get the current location
Double latitude = location.getLatitude() * 1E6;
Double longitude = location.getLongitude() * 1E6;
GeoPoint geoPoint = new GeoPoint(latitude.intValue(),
longitude.intValue());
// Convert the location to screen pixels
Point point = new Point();
projection.toPixels(geoPoint, point);
// int radius = metersToRadius(100, mapView, latitude);
int radius = (int) mapView.getProjection().metersToEquatorPixels(
200);
RectF oval = new RectF(point.x - radius, point.y - radius, point.x
+ radius, point.y + radius);
// Setup the paint
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(2.0f);
paint.setColor(0xff6666ff);
paint.setStyle(Style.STROKE);
canvas.drawOval(oval, paint);
paint.setColor(0x186666ff);
paint.setStyle(Style.FILL);
canvas.drawOval(oval, paint);
}
}
public Location getLocation() {
return location;
}
public void setLocation(Location location) {
this.location = location;
}
The thing is that something weird is happening because all the random locations are too near of my location center, it seems that the formula does not cover the whole radius and i think that distances are not in real meters.
Any idea of what could be wrong with my formula?
Thanks in advance
For questions regarding map projections and coordinate calculations, this SE site could be helpful: http://gis.stackexchange.com (Geographic Information Systems).
To be sure use the distanceTo() formula of location class.You can do it this way:
double distance = a.distanceTo(b);
where a and b are Location objects.

Problem in the MapActivity

i m testing an app that uses the google maps api. My app is working but my problem is:
i want the gps to find my location and present it.If my gps in enabled,it wants some seconds to find my location.In these seconds, my app starts and uses the default long and lat..How could i add something like progress bar until my location found?thanks
this is a part of my code:
private double locationLat=37.979116;
private double locationLon=23.717766;
MapView mapView;
MapController mc;
GeoPoint p;
//..........
//in the onCreate
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
LocationListener mlocListener = new MyLocationListener();
mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER,0,0, mlocListener);
MapView mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
// mapView.setSatellite(true);
// mapView.setStreetView(true);
mc = mapView.getController();
String lata = String.valueOf(locationLat);
String lnga = String.valueOf(locationLon);
String coordinates[] = {lata, lnga};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
p = new GeoPoint(
(int) (lat * 1E6),
(int) (lng * 1E6));
mc.animateTo(p);
mc.setZoom(17);
//---Add a location marker---
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
//out of onCreate
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);
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(p, screenPts);
//---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(
getResources(), R.drawable.avatar);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);
return true;
}
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView)
{
//---when user lifts his finger---
if (event.getAction() == 1) {
GeoPoint p = mapView.getProjection().fromPixels(
(int) event.getX(),
(int) event.getY());
Geocoder geoCoder = new Geocoder(
getBaseContext(), Locale.getDefault());
try {
List<Address> addresses = geoCoder.getFromLocation(
p.getLatitudeE6() / 1E6,
p.getLongitudeE6() / 1E6, 1);
String add = "";
if (addresses.size() > 0)
{
for (int i=0; i<addresses.get(0).getMaxAddressLineIndex();
i++)
add += addresses.get(0).getAddressLine(i) + "\n";
}
Toast.makeText(getBaseContext(), add, Toast.LENGTH_SHORT).show();
}
catch (IOException e) {
e.printStackTrace();
}
return true;
}
else
return false;
}
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
/* Class My Location Listener */
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(Location loc)
{
loc.getLatitude();
loc.getLongitude();
//String Text = "My current location is: " +
//"Latitud = " + loc.getLatitude() +
//"Longitud = " + loc.getLongitude();
locationLat=loc.getLatitude();
locationLon=loc.getLongitude();
// Toast.makeText( getApplicationContext(),
//
// Text,
//
// Toast.LENGTH_SHORT).show();
}
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(),
"Gps Disabled",
Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),
"Gps Enabled",
Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
}/* End of Class MyLocationListener */
}/* End of Activity */
I would just put it into an ASyncTask and then pop up a Dialog Box saying finding your location...once found dismiss the dialog box...Google ASyncTask examples...that should help you out.
^^ Agreed with that not sure if you are just updating the overlay or calling your map controller to follow the lat and lon that gets updated but that is an idea you could use.
Also please read the documentation of "requestLocationUpdates" 0,0 will DESTROY a real phones battery. that is updating location every 0 milliseconds and/or 0 ft change.

Categories

Resources