How to track path on google map? - android

I want to create an navigation app. I am able to create a polyline path from my current location to destination. I want to create it like google navigation app, means an arrrow navigate the user to the path continously while destination point doesn't arrived. But I don't know how can I do it.
I tried alot for finding it, but unable to find it. Please help me guys.
My code for map is as follow.
public class NavigationActivity extends FragmentActivity implements LocationListener {
public static final String TAG_SLAT = "sourcelat";
public static final String TAG_SLONG = "sourcelong";
public static final String TAG_DLAT = "destinationlat";
public static final String TAG_DLONG = "destinationg";
private static LatLng Source = null;
private static LatLng Destination = null;
private GoogleMap map;
private SupportMapFragment fragment;
private LatLngBounds latlngBounds;
private Button bNavigation;
private Polyline newPolyline;
private Marker smarker;
private Marker dmarker;
Geocoder geocoder;
private boolean isTraveling = false;
private int width, height;
private String sourcelat;
private String sourcelong;
private String destinationg;
private String destinationlat;
double slat;
double slong;
double dlat;
double dlong;
double d;
double tempDistance;
String distance;
String ts;
List<Address> addresses;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_navigation);
Intent in = getIntent();
sourcelat = in.getStringExtra(TAG_SLAT);
destinationlat = in.getStringExtra(TAG_DLAT);
destinationg = in.getStringExtra(TAG_DLONG);
sourcelong = in.getStringExtra(TAG_SLONG);
slat=Double.parseDouble(sourcelat);
slong=Double.parseDouble(sourcelong);
dlat=Double.parseDouble(destinationlat);
dlong=Double.parseDouble(destinationg);
Source = new LatLng(slat,slong);
Destination = new LatLng(dlat,dlong);
getSreenDimanstions();
fragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
map = fragment.getMap();
map.setMyLocationEnabled(true);
ImageButton cureent_location = (ImageButton)findViewById(R.id.clocation);
cureent_location.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
LocationShow();
}
});
if (!isTraveling) {
isTraveling = true;
findDirections(Source.latitude, Source.longitude, Destination.latitude, Destination.longitude, GMapV2Direction.MODE_DRIVING);
} else {
isTraveling = false;
}
}
public double calculateDistance(double fromLatitude,double fromLongitude,double toLatitude,double toLongitude)
{
float results[] = new float[1];
try {
Location.distanceBetween(fromLatitude, fromLongitude, toLatitude, toLongitude, results);
} catch (Exception e) {
if (e != null)
e.printStackTrace();
}
if (Source.equals(Destination)){
distance="0";
}
else {
int dist = (int) results[0];
if (dist <= 0)
return 0D;
DecimalFormat decimalFormat = new DecimalFormat("#.##");
results[0] /= 1000D;
distance = decimalFormat.format(results[0]);
double d = Double.parseDouble(distance);
double speed = 40;
double time = d / speed;
ts = manual(time);
Log.v("fdf", String.valueOf(ts));
}
return d;
}
private static String manual(double eta) {
int hour = (int) eta;
eta = (eta - hour) * 60;
int minutes = (int) eta;
eta = (eta - minutes) * 60;
int seconds = (int) eta;
eta = (eta - seconds) * 1000;
int ms = (int) eta;
//Log.d("ffgfh", String.valueOf(eta));
return String.format("%dHr %dMin ", hour, minutes);
}
#Override
protected void onResume() {
super.onResume();
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 150));
}
public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints) {
PolylineOptions rectLine = new PolylineOptions().width(5).color(Color.RED);
MarkerOptions marker = new MarkerOptions().position(Source).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
MarkerOptions marker1 = new MarkerOptions().position(Destination).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
for(int i = 0 ; i < directionPoints.size() ; i++)
{
rectLine.add(directionPoints.get(i));
}
if (newPolyline != null)
{
newPolyline.remove();
}
newPolyline = map.addPolyline(rectLine);
//smarker = map.addMarker(marker);
dmarker = map.addMarker(marker1);
if (isTraveling) {
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 150));
Dialog dialog_help = new Dialog(this);
dialog_help .requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog_help.setContentView(R.layout.title_multi_selectitems_dialog);
calculateDistance(slat, slong, dlat, dlong);
TextView dis = (TextView) dialog_help.findViewById(R.id.distance);
dis.setText("Distance " + distance + "Km ");
TextView tim = (TextView) dialog_help.findViewById(R.id.time);
tim.setText("Time " + ts);
dialog_help.setCancelable(true);
dialog_help.setTitle("Distance & Time" );
dialog_help.setCanceledOnTouchOutside(true);
dialog_help.show();
dialog_help.getWindow().setGravity(Gravity.CENTER);
dialog_help.getWindow().setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
dialog_help.getWindow().setLayout(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT);
}
else
{
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 150));
}
}
private void getSreenDimanstions()
{
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
private LatLngBounds createLatLngBoundsObject(LatLng firstLocation, LatLng secondLocation)
{
if (firstLocation != null && secondLocation != null)
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstLocation).include(secondLocation);
return builder.build();
}
return null;
}
public void findDirections(double fromPositionDoubleLat, double fromPositionDoubleLong, double toPositionDoubleLat, double toPositionDoubleLong, String mode)
{
Map<String, String> map = new HashMap<String, String>();
map.put(GetDirectionsAsyncTask.USER_CURRENT_LAT, String.valueOf(fromPositionDoubleLat));
map.put(GetDirectionsAsyncTask.USER_CURRENT_LONG, String.valueOf(fromPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DESTINATION_LAT, String.valueOf(toPositionDoubleLat));
map.put(GetDirectionsAsyncTask.DESTINATION_LONG, String.valueOf(toPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DIRECTIONS_MODE, mode);
GetDirectionsAsyncTask asyncTask = new GetDirectionsAsyncTask(this);
asyncTask.execute(map);
}
#Override
public void onLocationChanged(Location location) {
TextView cl = (TextView) findViewById(R.id.latlongLocation);
double latitude = location.getLatitude();
double longitude = location.getLongitude();
LatLng latLng = new LatLng(latitude, longitude);
map.addMarker(new MarkerOptions().position(latLng));
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
map.animateCamera(CameraUpdateFactory.zoomTo(5));
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
String prmises = addresses.get(0).getAddressLine(1);
String city = addresses.get(0).getAddressLine(2);
String country = addresses.get(0).getAddressLine(3);
cl.setText(address+" "+prmises+" "+city+" " +country);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
public void LocationShow() {
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
String bestProvider = locationManager.getBestProvider(criteria, true);
Location location = locationManager.getLastKnownLocation(bestProvider);
if (location != null) {
onLocationChanged(location);
}
locationManager.requestLocationUpdates(bestProvider, 20000, 0, this);
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
}

Maybe you want create a Polyline with a Line with multiple points, which represents each position of the user:
provide a global variable:
PolylineOptions pathOptions;
#Override
public View onCreate(Bundle savedInstanceState) {
...
pathOptions = new PolylineOptions();
...
}
#Override
public void onLocationChanged(Location location) {
...
pathOptions.add(new LatLng(42.255, 10.142));
}
And after creating an Object of PolylineOptions and the Map call:
Polyline userPath = map.addPolyline(pathOptions);

Related

I got problem with Marker using googlemap on android

got this message and i do not know how to solve it.
i'm getting data from a device (latitude, longitude, device_name, altitude).
when trying to get the device in real time moving i got this Log:
W/System.err: java.lang.ClassCastException: android.graphics.drawable.VectorDrawable cannot be cast to android.graphics.drawable.BitmapDrawable
W/System.err: at com.gabontech.gprstrack.activities.CurrentePositionActivity$6.doInBackground(CurrentePositionActivity.java:254)
W/System.err: at com.gabontech.gprstrack.activities.CurrentePositionActivity$6.doInBackground(CurrentePositionActivity.java:242)
W/System.err: at android.os.AsyncTask$3.call(AsyncTask.java:378)
W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:266)
W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:919)
i don't understand why. is there any probleme with my marker? please help . Also the marker does not move on the map. There is a mistake somewhere!
here is me code:
public class CurrentePositionActivity extends DrawerBaseActivity implements OnMapReadyCallback {
ActivityCurrentePositionBinding activityCurrentePositionBinding;
private static final String TAG = "Mappoisition Activity";
private GoogleMap map;
private String stopTime;
private boolean isRefreshLoced = false;
private long lastRefreshTime;
private Timer timer;
private AsyncTask downloadingAsync;
private Marker m;
ImageButton zoomin,zoomout;
ImageButton map_layer_icon, maplayer;
RelativeLayout content_layout, nodata_layout;
private int autoZoomedTimes = 0;
private HashMap<Integer, Marker> deviceIdMarkers;
private HashMap<String, Device> markerIdDevices;
private HashMap<Integer, Polyline> deviceIdPolyline;
private HashMap<Integer, LatLng> deviceIdLastLatLng;
// private HashMap<Integer, Marker> deviceIdSmallMarkerInfo;
boolean isAutoZoomEnabled = false;
boolean isTrafficEnabled = true;
boolean isShowTailsEnabled = true;
boolean isShowGeofencesEnabled = true;
private boolean isMaptraficactived = true;
ApiInterface.GetGeofencesResult geofencesResult;
ArrayList<PolygonWithName> polygonsWithDetails = new ArrayList<>();
ArrayList<HistoryItem> historyItems;
ApiInterface.GetHistoryResult getHistoryResult;
ArrayList<HistoryItemCoord> historyItemCoords;
ArrayList<HistoryItemClass> historyItemClasses;
HistoryItem item;
Device device ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activityCurrentePositionBinding = ActivityCurrentePositionBinding.inflate(getLayoutInflater());
setContentView(activityCurrentePositionBinding.getRoot());
ButterKnife.bind(this);
//fin de declaration de boutons
deviceIdMarkers = new HashMap<>();
markerIdDevices = new HashMap<>();
deviceIdPolyline = new HashMap<>();
deviceIdLastLatLng = new HashMap<>();
zoomin = findViewById(R.id.zoom_in);
zoomout = findViewById(R.id.zoom_out);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
if (mapFragment != null) {
mapFragment.getMapAsync(this);
}
item = new Gson().fromJson(getIntent().getStringExtra("item"), HistoryItem.class);
device = new Gson().fromJson(getIntent().getStringExtra("device"), Device.class);
zoomin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
map.animateCamera(CameraUpdateFactory.zoomIn());
}
});
zoomout.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
map.animateCamera(CameraUpdateFactory.zoomOut());
}
});
}
#Override
protected void onResume()
{
super.onResume();
timer = new Timer();
timer.schedule(new TimerTask()
{
#Override
public void run()
{
runOnUiThread(() -> {
float timeleft = 10 - Math.round(System.currentTimeMillis() - lastRefreshTime) / 1000f;
if (System.currentTimeMillis() - lastRefreshTime >= 10 * 1000)
if (map != null)
refresh();
});
}
}, 0, 1000);
}
#Override
protected void onPause()
{
super.onPause();
try
{
timer.cancel();
timer.purge();
downloadingAsync.cancel(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
map = googleMap;
refresh();
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
private void refresh(){
device = new Gson().fromJson(getIntent().getStringExtra("device"), Device.class);
LatLng geopoint = new LatLng(Double.valueOf(device.lat), Double.valueOf(device.lng));
if (isRefreshLoced)
return;
isRefreshLoced = true;
lastRefreshTime = System.currentTimeMillis();
Log.d(TAG, "success: loaded icons");
downloadingAsync = new AsyncTask<Void, Void, Void>() {
MarkerOptions marker = new MarkerOptions();
int deviceId = device.id;
#Override
protected Void doInBackground(Void... params)
{
int dp100 = Utils.dpToPx(CurrentePositionActivity.this, 50);
String server_base = (String) DataSaver.getInstance(CurrentePositionActivity.this).load("server_base");
// LatLng geopoint = new LatLng(Double.valueOf(device.lat), Double.valueOf(device.lng));
try
{
Drawable dr = getResources().getDrawable(R.drawable.ic_direction);
Bitmap bmp = ((BitmapDrawable) dr).getBitmap();
int srcWidth = bmp.getWidth();
int srcHeight = bmp.getHeight();
int maxWidth = Utils.dpToPx(CurrentePositionActivity.this, 40);
int maxHeight = Utils.dpToPx(CurrentePositionActivity.this, 40);
float ratio = Math.min((float) maxWidth / (float) srcWidth, (float) maxHeight / (float) srcHeight);
int dstWidth = (int) (srcWidth * ratio);
int dstHeight = (int) (srcHeight * ratio);
bmp = bmp.createScaledBitmap(bmp, dp100, dp100, true);
// marker
MarkerOptions m = new MarkerOptions();
m.position(geopoint);
m.icon(BitmapDescriptorFactory.fromBitmap(Bitmap.createScaledBitmap(bmp, dstWidth, dstHeight, true)));
// info windo
map.addMarker(m);
map.moveCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.fromLatLngZoom(geopoint, 14)));
} catch (OutOfMemoryError outOfMemoryError)
{
Toast.makeText(CurrentePositionActivity.this, "votre balise" + device.name, Toast.LENGTH_LONG).show();
} catch (Exception e)
{
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid){
if (autoZoomedTimes < 1)
{
new Handler().postDelayed(new Runnable()
{
#Override
public void run()
{
runOnUiThread(new Runnable()
{
#Override
public void run()
{
if (marker != null)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(new LatLng(Double.valueOf(device.lat), Double.valueOf(device.lng)));
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(CurrentePositionActivity.this, 50));
map.animateCamera(cu);
} catch (Exception e)
{
}
}
autoZoomedTimes++;
}
});
}
}, 50);
} else if (isAutoZoomEnabled)
{
try
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(m.getPosition());
LatLngBounds bounds = builder.build();
// int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, Utils.dpToPx(CurrentePositionActivity.this, 50));
map.animateCamera(cu);
} catch (Exception ignored)
{
}
map.moveCamera(CameraUpdateFactory.newLatLngZoom(geopoint, 15));
autoZoomedTimes++;
}
Log.d(TAG, "onPostExecute: icons downloaded and added to map, total markers: " + geopoint);
Marker m;
Polyline polyline;
if (deviceIdMarkers.containsKey(deviceId))
{
Log.d("aa", "moving to" + marker.getPosition());
Objects.requireNonNull(deviceIdMarkers.get(deviceId)).setPosition(new LatLng(device.lat, device.lng));
m = deviceIdMarkers.get(deviceId);
polyline = deviceIdPolyline.get(deviceId);
} else
{
Log.d("aa", "putting new");
m = map.addMarker(new MarkerOptions().position(new LatLng(Double.valueOf(device.lat), Double.valueOf(device.lng))));
deviceIdMarkers.put(device.id, m);
polyline = map.addPolyline(new PolylineOptions());
deviceIdPolyline.put(device.id, polyline);
}
Device thatonedevice = null;
thatonedevice = device;
assert m != null;
markerIdDevices.put(m.getId(), thatonedevice);
// update marker rotation based on driving direction
if (thatonedevice != null && deviceIdLastLatLng.containsKey(deviceId))
{
double dirLat = thatonedevice.lat - Objects.requireNonNull(deviceIdLastLatLng.get(deviceId)).latitude;
double dirLng = thatonedevice.lng - Objects.requireNonNull(deviceIdLastLatLng.get(deviceId)).longitude;
m.setRotation((float) Math.toDegrees(Math.atan2(dirLng, dirLat)));
}
deviceIdLastLatLng.put(device.id, new LatLng(thatonedevice.lat, thatonedevice.lng));
List<LatLng> polylinePoints = new ArrayList<>();
for (TailItem item : thatonedevice.tail)
polylinePoints.add(new LatLng(Double.valueOf(item.lat), Double.valueOf(item.lng)));
polyline.setPoints(polylinePoints);
polyline.setWidth(Utils.dpToPx(CurrentePositionActivity.this, 2));
polyline.setColor(Color.parseColor(thatonedevice.device_data.tail_color));
map.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
return null;
}
#Override
public View getInfoContents(final Marker marker)
{
synchronized (this)
{
}
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
View view = getLayoutInflater().inflate(R.layout.layout_map_infowindow, null);
view.bringToFront();
view.findViewById(R.id.close).setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
marker.hideInfoWindow();
}
});
TextView device_name = (TextView) view.findViewById(R.id.device_name);
device_name.setText(device.name);
TextView altitude = (TextView) view.findViewById(R.id.altitude);
altitude.setText(String.valueOf(device.altitude) + " " + device.unit_of_altitude);
TextView time = (TextView) view.findViewById(R.id.time);
time.setText(device.time);
TextView stopTimeView = (TextView) view.findViewById(R.id.stopTime);
stopTimeView.setText(stopTime);
TextView speed = (TextView) view.findViewById(R.id.speed);
speed.setText(device.speed + " " + device.distance_unit_hour);
TextView address = (TextView) view.findViewById(R.id.address);
address.setText(device.address);
final ArrayList<Sensor> showableSensors = new ArrayList<>();
for (Sensor item : device.sensors)
if (item.show_in_popup > 0)
showableSensors.add(item);
ListView sensors_list = (ListView) view.findViewById(R.id.sensors_list);
sensors_list.setAdapter(new AwesomeAdapter<Sensor>(CurrentePositionActivity.this)
{
#Override
public int getCount()
{
return showableSensors.size();
}
#NonNull
#Override
public View getView(int position, View convertView, #NonNull ViewGroup parent)
{
if (convertView == null)
convertView = getLayoutInflater().inflate(R.layout.adapter_map_sensorslist, null);
Sensor item = showableSensors.get(position);
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(item.name);
TextView value = (TextView) convertView.findViewById(R.id.value);
value.setText(item.value);
return convertView;
}
});
List<Address> addresses;
try
{
addresses = new Geocoder(CurrentePositionActivity.this).getFromLocation(device.lat, device.lng, 1);
if (addresses.size() > 0)
address.setText(addresses.get(0).getAddressLine(0));
} catch (IOException e)
{
e.printStackTrace();
}
return view;
}
return null;
}
});
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(final Marker marker)
{
int px = Utils.dpToPx(CurrentePositionActivity.this, 300);
map.setPadding(0, px, 0, 0);
stopTime = "...";
final Device device = markerIdDevices.get(marker.getId());
if (device != null)
{
API.getApiInterface(CurrentePositionActivity.this).deviceStopTime((String) DataSaver.getInstance(CurrentePositionActivity.this).load("api_key"), "en", device.id, new Callback<ApiInterface.DeviceStopTimeResult>()
{
#Override
public void success(ApiInterface.DeviceStopTimeResult result, Response response)
{
stopTime = result.time;
marker.showInfoWindow();
}
#Override
public void failure(RetrofitError retrofitError)
{
Toast.makeText(CurrentePositionActivity.this, R.string.errorHappened, Toast.LENGTH_SHORT).show();
}
});
}
return false;
}
});
map.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener()
{
#Override
public void onInfoWindowClick(Marker marker)
{
marker.hideInfoWindow();
}
});
map.setOnInfoWindowCloseListener(new GoogleMap.OnInfoWindowCloseListener()
{
#Override
public void onInfoWindowClose(Marker marker)
{
map.setPadding(0, 0, 0, 0);
}
});
// updateSmallMarkerData(allDevices);
isRefreshLoced = false;
}
}.execute();
}
private void putGeofenceNameMarkers(int textSize) {
for (Geofence geofence : geofencesResult.items.geofences)
{
if (geofence.active == 1)
{
String strText = geofence.name;
Paint.FontMetrics fm = new Paint.FontMetrics();
Paint paintText = new Paint();
paintText.setColor(Color.parseColor(geofence.polygon_color));
paintText.setTextAlign(Paint.Align.CENTER);
paintText.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
paintText.getFontMetrics(fm);
Rect rectText = new Rect();
paintText.getTextBounds(strText, 0, strText.length(),
rectText);
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmpText = Bitmap.createBitmap(rectText.width(),
rectText.height(), conf);
Canvas canvas = new Canvas(bmpText);
canvas.drawText(strText, canvas.getWidth() / 2,
canvas.getHeight() - rectText.bottom, paintText);
MarkerOptions markerOptions = new MarkerOptions()
.position(centroid(geofence.coordinatesList))
.icon(BitmapDescriptorFactory.fromBitmap(bmpText))
.anchor(0.5f, 1);
Marker marker = map.addMarker(markerOptions);
polygonsWithDetails.add(new PolygonWithName(map.addPolygon(new PolygonOptions()
.addAll(geofence.coordinatesList)
.strokeColor(Color.parseColor(geofence.polygon_color))
.fillColor(Color.parseColor("#59" + geofence.polygon_color.substring(1))))
, paintText, markerOptions, marker, geofence));
}
}
}
private LatLng centroid(List<LatLng> points)
{
double[] centroid = {0.0, 0.0};
for (int i = 0; i < points.size(); i++)
{
centroid[0] += points.get(i).latitude;
centroid[1] += points.get(i).longitude;
}
int totalPoints = points.size();
centroid[0] = centroid[0] / totalPoints;
centroid[1] = centroid[1] / totalPoints;
return new LatLng(centroid[0], centroid[1]);
}
}
Bitmap bmp = ((BitmapDrawable) dr).getBitmap();
dr is a VectorDrawable and cannot be cast to BitmapDrawable.
To get the bitmap of it, can refer to:
Getting Bitmap from vector drawable

Remove the last polyline line from Google Map Android?

I created a class that select latitudes and longitude from sqlite then mark on map then draw polyLine.
Problem :
Every time I select my records 100 to 100, when I saw first 100 then I clear map then I get second 100 but when I start animate it show me last polyline how I can clear last polyline ?
My code :
public class PathActivity_F extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
Query_DB QDB;
private List<Marker> markers = new ArrayList<>();
private final Handler mHandler = new Handler();
ImageView imgBack, imgClear, imgStop, imgPath, imgToggle, imgForward;
boolean flag = true;
int loadLimit = 0;
int ival = 0;
boolean ff = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_path);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapPath);
mapFragment.getMapAsync(this);
imgBack = (ImageView) findViewById(R.id.imgBack);
imgClear = (ImageView) findViewById(R.id.imgClear);
imgStop = (ImageView) findViewById(R.id.imgStop);
imgPath = (ImageView) findViewById(R.id.imgPath);
imgToggle = (ImageView) findViewById(R.id.imgToggle);
imgForward = (ImageView) findViewById(R.id.imgForward);
Button btnFill = (Button) findViewById(R.id.btnFill);
Button btnStop = (Button) findViewById(R.id.btnStop);
Button btnClear = (Button) findViewById(R.id.btnClear);
Button btnToggle = (Button) findViewById(R.id.btnToggle);*/
QDB = new Query_DB(PathActivity_F.this);
imgBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addLocations();
}
});
imgForward.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
imgPath.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animator.startAnimation(true);
}
});
imgStop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
animator.stopAnimation();
}
});
imgClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
clearMarkers();
}
});
imgToggle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
toggleStyle();
}
});
}
public void toggleStyle() {
if (GoogleMap.MAP_TYPE_NORMAL == mMap.getMapType()) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
} else {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}
/**
* Clears all markers from the map.
*/
public void clearMarkers() {
mMap.clear();
markers.clear();
}
private void addLocations() {
List<Marketing_Points_B> listPath = new ArrayList<>();
listPath.clear();
markers.clear();
String query;
if (flag) {
query = "select Time,Lat,Lng from ReportAct_tbl group by LatLng order by Time ASC LIMIT 100; ";
flag = false;
} else {
loadLimit = ival + 100;
ival = loadLimit;
query = "select Time,Lat,Lng from ReportAct_tbl group by LatLng order by Time ASC LIMIT 100 OFFSET " + loadLimit + ";";
}
Cursor cursor = QDB.db().rawQuery(query, null);
cursor.moveToFirst();
try {
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
Marketing_Points_B MP = new Marketing_Points_B();
Double lat = cursor.getDouble(cursor.getColumnIndex("Lat"));
Double lng = cursor.getDouble(cursor.getColumnIndex("Lng"));
String Time = cursor.getString(cursor.getColumnIndex("Time"));
MP.setLat(lat);
MP.setLng(lng);
MP.setTime(Time);
listPath.add(MP);
} while (cursor.moveToNext());
}
}
} catch (Exception ex) {
} finally {
cursor.close();
QDB.db().close();
}
for (int i = 0; i < listPath.size(); i++) {
Double lat = listPath.get(i).getLat();
Double lng = listPath.get(i).getLng();
addMarkerToMap(new LatLng(lat, lng));
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(34.637727, 50.877688);
mMap.addMarker(new MarkerOptions().position(sydney).title("OK").icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_red)));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
private Animator animator = new Animator();
int currentPt;
GoogleMap.CancelableCallback MyCancelableCallback =
new GoogleMap.CancelableCallback() {
#Override
public void onCancel() {
System.out.println("onCancelled called");
}
#Override
public void onFinish() {
if (++currentPt < markers.size()) {
float targetBearing = bearingBetweenLatLngs(mMap.getCameraPosition().target, markers.get(currentPt).getPosition());
LatLng targetLatLng = markers.get(currentPt).getPosition();
Log.i("currentPt", "currentPt = " + currentPt);
Log.i("size", "size = " + markers.size());
//Create a new CameraPosition
CameraPosition cameraPosition =
new CameraPosition.Builder()
.target(targetLatLng)
.tilt(currentPt < markers.size() - 1 ? 90 : 0)
.bearing(targetBearing)
.zoom(mMap.getCameraPosition().zoom)
.build();
mMap.animateCamera(
CameraUpdateFactory.newCameraPosition(cameraPosition),
3000,
MyCancelableCallback);
System.out.println("Animate to: " + markers.get(currentPt).getPosition() + "\n" +
"Bearing: " + targetBearing);
markers.get(currentPt).showInfoWindow();
} else {
}
}
};
private float bearingBetweenLatLngs(LatLng begin, LatLng end) {
Location beginL = convertLatLngToLocation(begin);
Location endL = convertLatLngToLocation(end);
return beginL.bearingTo(endL);
}
private Location convertLatLngToLocation(LatLng latLng) {
Location loc = new Location("someLoc");
loc.setLatitude(latLng.latitude);
loc.setLongitude(latLng.longitude);
return loc;
}
public class Animator implements Runnable {
private static final int ANIMATE_SPEEED = 100;
private static final int ANIMATE_SPEEED_TURN = 1000;
private static final int BEARING_OFFSET = 20;
private final Interpolator interpolator = new LinearInterpolator();
int currentIndex = 0;
float tilt = 90;
float zoom = 15.5f;
boolean upward = true;
long start = SystemClock.uptimeMillis();
LatLng endLatLng = null;
LatLng beginLatLng = null;
boolean showPolyline = false;
private Marker trackingMarker;
public void reset() {
resetMarkers();
start = SystemClock.uptimeMillis();
currentIndex = 0;
endLatLng = getEndLatLng();
beginLatLng = getBeginLatLng();
}
public void stop() {
trackingMarker.remove();
mHandler.removeCallbacks(animator);
}
public void initialize(boolean showPolyLine) {
reset();
this.showPolyline = showPolyLine;
highLightMarker(0);
if (showPolyLine) {
polyLine = initializePolyLine();
}
// We first need to put the camera in the correct position for the first run (we need 2 markers for this).....
LatLng markerPos = markers.get(0).getPosition();
LatLng secondPos = markers.get(1).getPosition();
setupCameraPositionForMovement(markerPos, secondPos);
}
private void setupCameraPositionForMovement(LatLng markerPos,
LatLng secondPos) {
float bearing = bearingBetweenLatLngs(markerPos, secondPos);
trackingMarker = mMap.addMarker(new MarkerOptions().position(markerPos)
.title("title")
.snippet("snippet").icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_red)));
CameraPosition cameraPosition =
new CameraPosition.Builder()
.target(markerPos)
.bearing(bearing + BEARING_OFFSET)
.tilt(90)
.zoom(mMap.getCameraPosition().zoom >= 16 ? mMap.getCameraPosition().zoom : 16)
.build();
mMap.animateCamera(
CameraUpdateFactory.newCameraPosition(cameraPosition),
ANIMATE_SPEEED_TURN,
new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
System.out.println("finished camera");
animator.reset();
Handler handler = new Handler();
handler.post(animator);
}
#Override
public void onCancel() {
System.out.println("cancelling camera");
}
}
);
}
private Polyline polyLine;
private PolylineOptions rectOptions = new PolylineOptions();
private Polyline initializePolyLine() {
//polyLinePoints = new ArrayList<LatLng>();
rectOptions.add(markers.get(0).getPosition());
return mMap.addPolyline(rectOptions);
}
/**
* Add the marker to the polyline.
*/
private void updatePolyLine(LatLng latLng) {
List<LatLng> points = polyLine.getPoints();
points.add(latLng);
polyLine.setPoints(points);
}
public void stopAnimation() {
animator.stop();
}
public void startAnimation(boolean showPolyLine) {
if (markers.size() > 2) {
animator.initialize(showPolyLine);
}
}
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
double t = interpolator.getInterpolation((float) elapsed / ANIMATE_SPEEED);
double lat = t * endLatLng.latitude + (1 - t) * beginLatLng.latitude;
double lng = t * endLatLng.longitude + (1 - t) * beginLatLng.longitude;
LatLng newPosition = new LatLng(lat, lng);
trackingMarker.setPosition(newPosition);
if (showPolyline) {
updatePolyLine(newPosition);
}
// It's not possible to move the marker + center it through a cameraposition update while another camerapostioning was already happening.
//navigateToPoint(newPosition,tilt,bearing,currentZoom,false);
//navigateToPoint(newPosition,false);
if (t < 1) {
mHandler.postDelayed(this, 16);
} else {
System.out.println("Move to next marker.... current = " + currentIndex + " and size = " + markers.size());
// imagine 5 elements - 0|1|2|3|4 currentindex must be smaller than 4
if (currentIndex < markers.size() - 2) {
currentIndex++;
endLatLng = getEndLatLng();
beginLatLng = getBeginLatLng();
start = SystemClock.uptimeMillis();
LatLng begin = getBeginLatLng();
LatLng end = getEndLatLng();
float bearingL = bearingBetweenLatLngs(begin, end);
highLightMarker(currentIndex);
CameraPosition cameraPosition =
new CameraPosition.Builder()
.target(end) // changed this...
.bearing(bearingL + BEARING_OFFSET)
.tilt(tilt)
.zoom(mMap.getCameraPosition().zoom)
.build();
mMap.animateCamera(
CameraUpdateFactory.newCameraPosition(cameraPosition),
ANIMATE_SPEEED_TURN,
null
);
start = SystemClock.uptimeMillis();
mHandler.postDelayed(animator, 16);
} else {
currentIndex++;
highLightMarker(currentIndex);
stopAnimation();
}
}
}
private LatLng getEndLatLng() {
return markers.get(currentIndex + 1).getPosition();
}
private LatLng getBeginLatLng() {
return markers.get(currentIndex).getPosition();
}
private void adjustCameraPosition() {
if (upward) {
if (tilt < 90) {
tilt++;
zoom -= 0.01f;
} else {
upward = false;
}
} else {
if (tilt > 0) {
tilt--;
zoom += 0.01f;
} else {
upward = true;
}
}
}
}
/**
* Adds a marker to the map.
*/
public void addMarkerToMap(LatLng latLng) {
Marker marker = mMap.addMarker(new MarkerOptions().position(latLng)
.title("title")
.snippet("snippet").icon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_red)));
markers.add(marker);
}
private void resetMarkers() {
for (Marker marker : this.markers) {
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_green));
}
}
/**
* Highlight the marker by index.
*/
private void highLightMarker(int index) {
highLightMarker(markers.get(index));
}
/**
* Highlight the marker by marker.
*/
private void highLightMarker(Marker marker) {
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.map_marker_yellow));
marker.showInfoWindow();
}
}
Resolve my problem, I commented this line:
//rectOptions.add(markers.get(0).getPosition());
have track added polyline on map and remove it by polyline.remove();. For reference you can use How to remove all the polylines from a map

Find the closest point on polygon to user location

I have an app that find the shortest distance between my user to a polygon.
I want to convert the polygon to Geofence to check the distance between the user to the area to give mor accurate information to the user.
how can I do that?
this is the MapsActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener, MinimumDistanceTask.GetMinimumDistanceListener {
private GoogleMap mMap;
private LocationManager manager;
private double lat, lng;
private KmlLayer layer;
private LatLng latLngTest;
private boolean contains = false;
private ArrayList<LatLng> outerBoundary;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
manager = (LocationManager) getSystemService(LOCATION_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
String provider = LocationManager.GPS_PROVIDER;
//take the user location every second
try {
manager.requestLocationUpdates(provider, 1000, 0, this);
}catch (SecurityException e){
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
#Override
public void onLocationChanged(Location location) {
//clear map before create new location
mMap.clear();
try {
//load the kml file
layer = new KmlLayer(mMap, R.raw.polygon_layer, this);
layer.addLayerToMap();
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
}
lat = location.getLatitude();
lng = location.getLongitude();
latLngTest = new LatLng(lat,lng);
// Add a marker in user location
LatLng userLocation = new LatLng(latLngTest.latitude, latLngTest.longitude);
mMap.addMarker(new MarkerOptions().position(userLocation).title("you are here"));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLocation, 15));
//check if the user in the polygon
boolean inside = ifUserInside();
if(inside){
Toast.makeText(MapsActivity.this, "you are in the polygon", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(MapsActivity.this, "you are outside the polygon", Toast.LENGTH_SHORT).show();
//create the string address for the url
String address = "";
for (int i = 0; i < outerBoundary.size(); i++) {
address += (outerBoundary.get(i).toString() + "|");
address = address.replace("lat/lng:", "");
address = address.replace(" ", "");
address = address.replace("(", "");
address = address.replace(")", "");
}
MinimumDistanceTask task = new MinimumDistanceTask(this);
task.execute("https://maps.googleapis.com/maps/api/distancematrix/json?units=imperial&origins="+latLngTest.latitude+ "," + latLngTest.longitude
+ "&destinations=" + address + "&mode=walking");
}
}
#Override
public void getMinimumDistance(int closeLocation) {
//check if you get results properly
if(closeLocation != -1) {
GetDirection direction = new GetDirection();
direction.execute("https://maps.googleapis.com/maps/api/directions/json?origin=" + latLngTest.latitude + "," + latLngTest.longitude
+ "&destination=" + outerBoundary.get(closeLocation).latitude + "+" + outerBoundary.get(closeLocation).longitude);
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
public boolean ifUserInside(){
if (layer.getContainers() != null) {
for (KmlContainer container : layer.getContainers()) {
if (container.getPlacemarks() != null) {
for (KmlPlacemark placemark : container.getPlacemarks()) {
contains = false;
if (placemark.getGeometry() instanceof KmlPolygon) {
KmlPolygon polygon = (KmlPolygon) placemark.getGeometry();
// Get the outer boundary and check if the test location lies inside
outerBoundary = polygon.getOuterBoundaryCoordinates();
contains = PolyUtil.containsLocation(latLngTest, outerBoundary, true);
if (contains) {
// Get the inner boundaries and check if the test location lies inside
ArrayList<ArrayList<LatLng>> innerBoundaries = polygon.getInnerBoundaryCoordinates();
if (innerBoundaries != null) {
for (ArrayList<LatLng> innerBoundary : innerBoundaries) {
// If the test location lies in a hole, the polygon doesn't contain the location
if (PolyUtil.containsLocation(latLngTest, innerBoundary, true)) {
contains = false;
}
}
}
}
}
}
}
}
}
return contains;
}
public class GetDirection extends AsyncTask<String , Void, String> {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
#Override
protected String doInBackground(String... params) {
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return "Error from server";
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return builder.toString();
}
#Override
protected void onPostExecute(String s) {
//get the polyline string
String polygonPoints = "";
try {
JSONObject object = new JSONObject(s);
JSONArray array = object.getJSONArray("routes");
for (int i = 0; i < array.length(); i++) {
JSONObject arrObj1 = array.getJSONObject(i);
JSONObject points = arrObj1.getJSONObject("overview_polyline");
polygonPoints = points.getString("points");
}
//convert the string to polyline;
ArrayList<LatLng> a = new ArrayList<>(decodePolyPoints(polygonPoints));
//add polyline to the map
mMap.addPolyline(new PolylineOptions().addAll(a).width(10).color(Color.BLUE));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
//the method that convert the string to polyline
public static ArrayList<LatLng> decodePolyPoints(String encodedPath){
int len = encodedPath.length();
final ArrayList<LatLng> path = new ArrayList<LatLng>();
int index = 0;
int lat = 0;
int lng = 0;
while (index < len) {
int result = 1;
int shift = 0;
int b;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lat += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
result = 1;
shift = 0;
do {
b = encodedPath.charAt(index++) - 63 - 1;
result += b << shift;
shift += 5;
} while (b >= 0x1f);
lng += (result & 1) != 0 ? ~(result >> 1) : (result >> 1);
path.add(new LatLng(lat * 1e-5, lng * 1e-5));
}
return path;
}
}
This is my AsyncTask to get the minimum distance point
public class MinimumDistanceTask extends AsyncTask<String, Void, Integer>{
private int closeLocation;
// private String points;
private GetMinimumDistanceListener listener;
public MinimumDistanceTask(GetMinimumDistanceListener listener){
// this.points = points;
this.listener = listener;
}
#Override
protected Integer doInBackground(String... params) {
HttpsURLConnection connection = null;
BufferedReader reader = null;
StringBuilder builder = new StringBuilder();
int minimumDis = -1;
String address = params[0];
try {
URL url = new URL(address);
connection = (HttpsURLConnection) url.openConnection();
if(connection.getResponseCode() != HttpURLConnection.HTTP_OK){
return -1;
}
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = reader.readLine()) != null){
builder.append(line);
}
///get the json data
JSONObject jsonObject1 = new JSONObject(builder.toString());
JSONArray points = jsonObject1.getJSONArray("rows");
JSONObject jsonObject2 = points.getJSONObject(0);
JSONArray elements = jsonObject2.getJSONArray("elements");
for (int i = 0; i < elements.length(); i++) {
JSONObject jsonObject3 = elements.getJSONObject(i);
JSONObject distance = jsonObject3.getJSONObject("distance");
if( distance.getInt("value") < minimumDis || minimumDis == -1) {
minimumDis = distance.getInt("value");
closeLocation = i;
}
}
} catch (MalformedURLException | JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return closeLocation;
}
#Override
protected void onPostExecute(Integer closeLocation) {
listener.getMinimumDistance(closeLocation);
}
public interface GetMinimumDistanceListener{
void getMinimumDistance(int closeLocation);
}
}
thanks a lot :)
You can use a function like the following to calculate the nearest point from polygon defined by a List<LatLng> and a given LatLng.
It uses the PolyUtil.distanceToLine from the Google Maps Android API Utility Library to compute the distance between the test LatLng and every segment of the list, and a method based on the distanceToLine method from https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java to compute the projection of a point on a segment.
private LatLng findNearestPoint(LatLng test, List<LatLng> target) {
double distance = -1;
LatLng minimumDistancePoint = test;
if (test == null || target == null) {
return minimumDistancePoint;
}
for (int i = 0; i < target.size(); i++) {
LatLng point = target.get(i);
int segmentPoint = i + 1;
if (segmentPoint >= target.size()) {
segmentPoint = 0;
}
double currentDistance = PolyUtil.distanceToLine(test, point, target.get(segmentPoint));
if (distance == -1 || currentDistance < distance) {
distance = currentDistance;
minimumDistancePoint = findNearestPoint(test, point, target.get(segmentPoint));
}
}
return minimumDistancePoint;
}
/**
* Based on `distanceToLine` method from
* https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/PolyUtil.java
*/
private LatLng findNearestPoint(final LatLng p, final LatLng start, final LatLng end) {
if (start.equals(end)) {
return start;
}
final double s0lat = Math.toRadians(p.latitude);
final double s0lng = Math.toRadians(p.longitude);
final double s1lat = Math.toRadians(start.latitude);
final double s1lng = Math.toRadians(start.longitude);
final double s2lat = Math.toRadians(end.latitude);
final double s2lng = Math.toRadians(end.longitude);
double s2s1lat = s2lat - s1lat;
double s2s1lng = s2lng - s1lng;
final double u = ((s0lat - s1lat) * s2s1lat + (s0lng - s1lng) * s2s1lng)
/ (s2s1lat * s2s1lat + s2s1lng * s2s1lng);
if (u <= 0) {
return start;
}
if (u >= 1) {
return end;
}
return new LatLng(start.latitude + (u * (end.latitude - start.latitude)),
start.longitude + (u * (end.longitude - start.longitude)));
}
You can test it with the following code:
List<LatLng> points = new ArrayList<>();
points.add(new LatLng(2, 2));
points.add(new LatLng(4, 2));
points.add(new LatLng(4, 4));
points.add(new LatLng(2, 4));
points.add(new LatLng(2, 2));
LatLng testPoint = new LatLng(3, 0);
LatLng nearestPoint = findNearestPoint(testPoint, points);
Log.e("NEAREST POINT: ", "" + nearestPoint); // lat/lng: (3.0,2.0)
Log.e("DISTANCE: ", "" + SphericalUtil.computeDistanceBetween(testPoint, nearestPoint)); // 222085.35856591124

Get lat/lng of points along the route after every 100m in android

Using Map Api V2 I have drawn a route on the map. Now i wish to save this route in my database.
So I need to get the lat/lng of points on the route say after each 100 meters which i will save as a polygon. How can i do it in Google Map V2 in android.
i am stuck on it from last 10 days but not getting a solution.
any help will be appriciable :)
public class NavigationActivity extends FragmentActivity {
public static final String TAG_SLAT = "sourcelat";
public static final String TAG_SLONG = "sourcelong";
public static final String TAG_DLAT = "destinationlat";
public static final String TAG_DLONG = "destinationg";
private static LatLng Source = null;
private static LatLng Destination = null;
private GoogleMap map;
private SupportMapFragment fragment;
private LatLngBounds latlngBounds;
private Button bNavigation;
private Polyline newPolyline;
private Marker smarker;
private Marker dmarker;
Geocoder geocoder;
private boolean isTraveling = false;
private int width, height;
private String sourcelat;
private String sourcelong;
private String destinationg;
private String destinationlat;
double slat;
double slong;
double dlat;
double dlong;
double d;
double tempDistance;
String distance;
ConnectionDetector cd;
Boolean isConnectingToInternet = false;
String ts;
LatLng latLng;
GPSTracker gps;
List<Address> addresses;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isGooglePlayServicesAvailable()) {
finish();
}
setContentView(R.layout.activity_navigation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
Intent in = getIntent();
sourcelat = in.getStringExtra(TAG_SLAT);
destinationlat = in.getStringExtra(TAG_DLAT);
destinationg = in.getStringExtra(TAG_DLONG);
sourcelong = in.getStringExtra(TAG_SLONG);
slat = Double.parseDouble(sourcelat);
slong = Double.parseDouble(sourcelong);
dlat = Double.parseDouble(destinationlat);
dlong = Double.parseDouble(destinationg);
Source = new LatLng(slat, slong);
Destination = new LatLng(dlat, dlong);
getSreenDimanstions();
fragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
map = fragment.getMap();
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
map.setTrafficEnabled(true);
ImageButton cureent_location = (ImageButton) findViewById(R.id.clocation);
cureent_location.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onLocationChanged();
}
});
if (!isTraveling) {
isTraveling = true;
findDirections(Source.latitude, Source.longitude, Destination.latitude, Destination.longitude, GMapV2Direction.MODE_DRIVING);
} else {
isTraveling = false;
}
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
public double calculateDistance(double fromLatitude,double fromLongitude,double toLatitude,double toLongitude)
{
float results[] = new float[1];
try {
Location.distanceBetween(fromLatitude, fromLongitude, toLatitude, toLongitude, results);
} catch (Exception e) {
if (e != null)
e.printStackTrace();
}
if (Source.equals(Destination)){
distance="0";
}
else {
int dist = (int) results[0];
if (dist <= 0)
return 0D;
DecimalFormat decimalFormat = new DecimalFormat("#.##");
results[0] /= 1000D;
distance = decimalFormat.format(results[0]);
double d = Double.parseDouble(distance);
double speed = 40;
double time = d / speed;
ts = manual(time);
Log.v("fdf", String.valueOf(ts));
}
return d;
}
private static String manual(double eta) {
int hour = (int) eta;
eta = (eta - hour) * 60;
int minutes = (int) eta;
eta = (eta - minutes) * 60;
int seconds = (int) eta;
eta = (eta - seconds) * 1000;
int ms = (int) eta;
//Log.d("ffgfh", String.valueOf(eta));
return String.format("%dHr %dMin ", hour, minutes);
}
#Override
protected void onResume() {
super.onResume();
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.moveCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints) {
PolylineOptions rectLine = new PolylineOptions().width(5).color(Color.RED);
//MarkerOptions marker = new MarkerOptions().position(Source).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
MarkerOptions marker1 = new MarkerOptions().position(Destination).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
for(int i = 0 ; i < directionPoints.size() ; i++)
{
rectLine.add(directionPoints.get(i));
}
if (newPolyline != null)
{
newPolyline.remove();
}
newPolyline = map.addPolyline(rectLine);
//smarker = map.addMarker(marker);
dmarker = map.addMarker(marker1);
if (isTraveling) {
latlngBounds = createLatLngBoundsObject(Source, Destination);
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
Dialog dialog_help = new Dialog(this);
dialog_help .requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog_help.setContentView(R.layout.title_multi_selectitems_dialog);
calculateDistance(slat, slong, dlat, dlong);
TextView dis = (TextView) dialog_help.findViewById(R.id.distance);
dis.setText("Distance " + distance + "Km ");
TextView tim = (TextView) dialog_help.findViewById(R.id.time);
tim.setText("Time " + ts);
dialog_help.setCancelable(true);
dialog_help.setTitle("Distance & Time" );
dialog_help.setCanceledOnTouchOutside(true);
dialog_help.show();
dialog_help.getWindow().setGravity(Gravity.CENTER);
dialog_help.getWindow().setBackgroundDrawable(new ColorDrawable(Color.LTGRAY));
dialog_help.getWindow().setLayout(RadioGroup.LayoutParams.WRAP_CONTENT, RadioGroup.LayoutParams.WRAP_CONTENT);
}
else {
map.animateCamera(CameraUpdateFactory.newLatLngBounds(latlngBounds, width, height, 100));
}
}
private void getSreenDimanstions()
{
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
}
private LatLngBounds createLatLngBoundsObject(LatLng firstLocation, LatLng secondLocation)
{
if (firstLocation != null && secondLocation != null)
{
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(firstLocation).include(secondLocation);
return builder.build();
}
return null;
}
public void findDirections(double fromPositionDoubleLat, double fromPositionDoubleLong, double toPositionDoubleLat, double toPositionDoubleLong, String mode)
{
Map<String, String> map = new HashMap<String, String>();
map.put(GetDirectionsAsyncTask.USER_CURRENT_LAT, String.valueOf(fromPositionDoubleLat));
map.put(GetDirectionsAsyncTask.USER_CURRENT_LONG, String.valueOf(fromPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DESTINATION_LAT, String.valueOf(toPositionDoubleLat));
map.put(GetDirectionsAsyncTask.DESTINATION_LONG, String.valueOf(toPositionDoubleLong));
map.put(GetDirectionsAsyncTask.DIRECTIONS_MODE, mode);
GetDirectionsAsyncTask asyncTask = new GetDirectionsAsyncTask(this);
try {
asyncTask.execute(map);
}catch (Exception e){
Toast.makeText(getBaseContext(), "Something went Wrong", Toast.LENGTH_SHORT).show();
}
}
public void onLocationChanged( ){
TextView cl = (TextView) findViewById(R.id.latlongLocation);
cd = new ConnectionDetector(getApplicationContext());
isConnectingToInternet = cd.isConnectingToInternet();
if (isConnectingToInternet) {
gps = new GPSTracker(NavigationActivity.this);
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
latLng = new LatLng(latitude, longitude);
geocoder = new Geocoder(this, Locale.getDefault());
try {
addresses = geocoder.getFromLocation(latitude, longitude, 1);
} catch (IOException e) {
e.printStackTrace();
}
String address = addresses.get(0).getAddressLine(0);
String prmises = addresses.get(0).getAddressLine(1);
String city = addresses.get(0).getAddressLine(2);
String country = addresses.get(0).getAddressLine(3);
cl.setText(address + " " + prmises + " " + city + " " + country);
}else {
AlertUtils.showAlertDialog(NavigationActivity.this, "No Internet Detected", "Please check your internet connection.", false);
}
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
}
You can try it with this map application: http://maps.cloudmade.com/.
At first you create your route with waypoints. Click on the button "Get directions" (upper left corner) and create your route (clicking on the map). After that you can export (there is a button on the upper right corner) your route (include waypoints) to a gpx-or a json-file. You can load both files to a GIS.

how to draw Bitmaps with specific ArrayList of coordinates on google maps api 2 using asynctask?

The idea of the application is to get ArrayList<LatLng> from the database then draw these coordinates as markers using bitmaps on the map
I'm getting:
NullPointerException at android.graphics.Canvas.drawBitmap(Canvas.java:1195) in onPostExecute
There's two questions in here:
Is it normal to draw bitmaps in onPostExecute method..??
Why I get NullPointerException at android.graphics.Canvas.drawBitmap(Canvas.java:1195) in onPostExecute...??
Asynctask Class:
public class BitmapAsyncTask extends
AsyncTask<ArrayList<Obstacle>, Void, ArrayList<LatLng>> {
static Canvas canvas1;
static BitmapFactory.Options o;
private Bitmap bmp;
MarkerOptions balloonmarker;
private double latitude;
private double longitude;
GoogleMap gm;
LatLng ll;
LatLng latlong;
private int len;
private static int resID = 1;
static ArrayList<Obstacle> obs;
static ArrayList<LatLng> coordinates;
static ArrayList<LatLng> sendingCoord;
private static double mydirection = 45;
static Context context;
public BitmapAsyncTask(Context contextx) {
context = contextx;
}
#Override
protected ArrayList<LatLng> doInBackground(ArrayList<Obstacle>... params) {
int i;
ArrayList<Obstacle> obstacleArray = params[0];
coordinates = new ArrayList<LatLng>();
len = obstacleArray.size();
for (i = 0; i < len; i++) {
Obstacle obstacle = obstacleArray.get(i);
latitude = obstacle.getLatitude();
longitude = obstacle.getLongitude();
mydirection = obstacle.getDirection();
}
for (int x = 0; x < 1; x++) {
ll = new LatLng(latitude, longitude);
coordinates.add(ll);
}
}
return coordinates;
}
#Override
protected void onPostExecute(ArrayList<LatLng> result) {
int i;
int size = result.size();
bmp = BitmapFactory.decodeResource(context.getResources(),
R.drawable.map_pin, null);
bmp=Bitmap.createBitmap(50, 50, Config.ARGB_4444);
for (i = 0; i < size; i++) {
latlong = result.get(i);
canvas1=new Canvas();
//the exception happens here
canvas1.drawBitmap(bmp, null, null);
balloonmarker = new MarkerOptions().title("MyLocation")
.snippet("This Is Me").position(latlong).anchor(0, 1)
.icon(BitmapDescriptorFactory.fromBitmap(bmp));
gm.addMarker(balloonmarker);
}
if (bmp != null) {
bmp.recycle();
bmp = null;
System.gc();
}
}
Obstacle class:
public class Obstacle {
long id;
double longitude;
double latitude;
double direction;
public Obstacle(double longitude, double latitude, double direction) {
super();
this.longitude = longitude;
this.latitude = latitude;
this.direction = direction;
}
public Obstacle() {
// TODO Auto-generated constructor stub
}
public double getLongitude() {
return longitude;
}
public void setLongitude(double longitude) {
this.longitude = longitude;
}
public double getLatitude() {
return latitude;
}
public void setLatitude(double latitude) {
this.latitude = latitude;
}
public double getDirection() {
return direction;
}
public void setDirection(double direction) {
this.direction = direction;
}
public Location getLocation() {
Location myLocation = new Location(MatabbatManager.PROVIDER_STRING);
myLocation.setLongitude(longitude);
myLocation.setLatitude(latitude);
return myLocation;
}
}
DataBase Class:
public class LocalCachedObstacles extends SQLiteOpenHelper {
static String DATABASE_NAME="localobstaclesdb";
private static final int DATABASE_VERSION = 1;
static String OBSTACLES_TABLE ="obstacles";
private static final String OBSTACLES_TABLE_CREATE ="" +
"CREATE Table " + OBSTACLES_TABLE +
"(" +
"long REAL," +
"lat REAL," +
"direction REAL, " +
"type REAL, " +
"address VARCHAR(500)," +
"time VARCHAR(100)," +
"submitterName VARCHAR(200) " +
")";
public ArrayList<Obstacle> getCachedObstacles() {
try {
SQLiteDatabase dblocs=this.getReadableDatabase();
Cursor cur=dblocs.rawQuery("SELECT * FROM "+OBSTACLES_TABLE,new String [] {});
ArrayList<Obstacle> obstacles = new ArrayList<Obstacle>();
while (cur.moveToNext()) {
Obstacle obstacle = new Obstacle
(cur.getDouble(0),
cur.getDouble(1),cur.getDouble(2),
cur.getDouble(3),cur.getString(4),
cur.getString(5),cur.getString(6));
obstacles.add(obstacle);
}
cur.close();
dblocs.close();
return obstacles;
}
catch (Exception locex){
Log.e(MatabbatManager.TAG," Get Local cache" + locex.getMessage());
return null;
}
}
Excecution class:
public class AnonymousUser extends FragmentActivity{
LocalCachedObstacles lo = new LocalCachedObstacles(
MyApplication.getAppContext());
ArrayList<Obstacle> localObstacles = lo.getCachedObstacles();
DrawTypes(localObstacles);
public void DrawTypes(ArrayList<Obstacle> obs) {
len = obs.size();
BitmapAsyncTask async = new BitmapAsyncTask(MyApplication.getAppContext());
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
async.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, obs);
}
}
You can not use Canvas as in your code , we can get canvas object by overriding onDraw method.
In my opinion you should use overlays to draw bitmaps on map.
I solved it finally after 2 weeks of trying everything related to threads threadpool,asynctaskloader.....
Solution:
Making aservice instead of AsyncTask because i need it to keep running in the background.

Categories

Resources