Delete previous circle before drawing new ones on the map - android

I have this method:
public void crowdArea(){
for (int n=0; n<place.length; n++) {
Location locationFromDB2 = new Location("");
locationFromDB2.setLatitude(latt2[n]);
locationFromDB2.setLongitude(longg2[n]);
total = 0;
double c [][]=new double[100][2];
double p [][]=new double[100][2];
for (int n2 = 0; n2 < latt.length; n2++) {
Location locationFromDB3 = new Location("");
locationFromDB3.setLatitude(latt[n2]);
locationFromDB3.setLongitude(longg[n2]);
float dist = locationFromDB2.distanceTo(locationFromDB3);
if (dist < 500f) {
c [total][0]=latt[n2];
c [total][1]=longg[n2];
p [total][0]=prelatt[n2];
p [total][1]=prelongg[n2];
total++;
}
}
if (total >= 5) {
draw(latt2[n], longg2[n]);
state[n]="yes";
boolean b=bearing2(c,p);
Log.d("diriction is: ", b+"");
}
else{
state[n]="no";
// draw2(latt2[n], longg2[n]);
}
}
}
public void draw(double lat, double lonng){
Circle myCircle;
LatLng lt=new LatLng(lat, lonng);
CircleOptions circleOptions = new CircleOptions()
.center(lt) //set center
.radius(500) //set radius in meters
.fillColor(0x40ff0000) //default
.strokeColor(Color.RED)
.strokeWidth(5);
myCircle = map.addCircle(circleOptions);
}
which draws a circle on my map.
this method is called every 15 secs, but it draws a circle on the previous circle and so on. what I want is to remove previous circles before adding the new one.
how to do this?

You can use map.clear() to clear the map before drawing the new circle.
Alternatively, if you have drawn other objects on the map and you don't want to delete them, just your previous Circle, you can do:
private Circle myCircle;
// ...
public void draw(double lat, double lonng){
LatLng lt=new LatLng(lat, lonng);
CircleOptions circleOptions = new CircleOptions()
.center(lt) //set center
.radius(500) //set radius in meters
.fillColor(0x40ff0000) //default
.strokeColor(Color.RED)
.strokeWidth(5);
if (myCircle != null) {
myCircle.remove();
}
myCircle = map.addCircle(circleOptions);
}
FOLLOWUP based on your code update:
private List<Circle> circles = new ArrayList<>();
public void crowdArea(){
clearCircles();
for (int n=0; n<place.length; n++) {
Location locationFromDB2 = new Location("");
locationFromDB2.setLatitude(latt2[n]);
locationFromDB2.setLongitude(longg2[n]);
total = 0;
double c [][]=new double[100][2];
double p [][]=new double[100][2];
for (int n2 = 0; n2 < latt.length; n2++) {
Location locationFromDB3 = new Location("");
locationFromDB3.setLatitude(latt[n2]);
locationFromDB3.setLongitude(longg[n2]);
float dist = locationFromDB2.distanceTo(locationFromDB3);
if (dist < 500f) {
c [total][0]=latt[n2];
c [total][1]=longg[n2];
p [total][0]=prelatt[n2];
p [total][1]=prelongg[n2];
total++;
}
}
if (total >= 5) {
draw(latt2[n], longg2[n]);
state[n]="yes";
boolean b=bearing2(c,p);
Log.d("diriction is: ", b+"");
}
else{
state[n]="no";
// draw2(latt2[n], longg2[n]);
}
}
}
public void draw(double lat, double lonng){
LatLng lt=new LatLng(lat, lonng);
CircleOptions circleOptions = new CircleOptions()
.center(lt) //set center
.radius(500) //set radius in meters
.fillColor(0x40ff0000) //default
.strokeColor(Color.RED)
.strokeWidth(5);
circles.add(map.addCircle(circleOptions));
}
private void clearCircles() {
for (Circle circle : circles) {
circle.remove();
}
circles.clear();
}

I suggest you to use
if(mapCircle!=null){
mapCircle.remove();
}
instead of map.clear() because this will remove every objects on the map

Related

draw line on google map on button click

i have Array list of LatLong which i got from database, i need to draw polyline on map but one by one(after some interval) and also want to move the marker.
here is my code.
if (v.getId() == R.id.btnPlayBack) {
googleMap.clear();
mStopHandler = true;
for (int i = 0; i < movementLine.size(); i++) {
marker.remove();
LatLng latlng = new LatLng(movementLine.get(i).latitude, movementLine.get(i).longitude);
marker = googleMap.addMarker(new MarkerOptions()
.position(latlng)
.title("Position")
.snippet("Latitude:" + latlng.latitude + ", Longitude:" + latlng.longitude));
googleMap.addPolyline(new PolylineOptions()
.add(new LatLng(latlng.latitude, latlng.longitude)));
animateMarker(googleMap, marker, new LatLng(latlng.latitude, latlng.longitude), false);
}
}
private static void animateMarker(GoogleMap googleMap, final Marker marker, final LatLng toPosition,
final boolean hideMarker) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = googleMap.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 500;
final Interpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
double lng = t * toPosition.longitude + (1 - t)
* startLatLng.longitude;
double lat = t * toPosition.latitude + (1 - t)
* startLatLng.latitude;
marker.setPosition(new LatLng(lat, lng));
if (t < 1.0) {
// Post again 16ms later.
handler.postDelayed(this, 16);
} else {
if (hideMarker) {
marker.setVisible(false);
} else {
marker.setVisible(true);
}
}
}
});
}
but its not working is there i did anything wrong?
i want show movement of marker with polyline.
here when i use
googleMap.addPolyline(new PolylineOptions()
.addAll(movementLine));
it will draw route with all point from array list.but i need show one by one.
please help me out..
Just create one like here:
PolylineOptions options = new PolylineOptions().width(5).color(Color.RED).geodesic(true);
for (int z = 0; z < list.size(); z++) {
LatLng point = list.get(z);
options.add(point);
}
line = myMap.addPolyline(options);
I'm also not sure you should use geodesic
if (v.getId() == R.id.btnPlayBack) {
final Handler handler = new Handler();
timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
//callToFetchRecords();
try {
PlayBack();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 2000); //execute in every 2 sec
}
}
private void PlayBack() {
LatLng latlng = new LatLng(movementLine.get(pos).latitude, movementLine.get(pos).longitude);
marker = googleMap.addMarker(new MarkerOptions()
.position(latlng)
.title("Staring Point")
.snippet("Latitude:" + latlng.latitude + ", Longitude:" + latlng.longitude));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng, 19));
options.add(latlng);
RoutePolyline = googleMap.addPolyline(options);
animateMarker(googleMap, marker, latlng, false);
pos++; }

Animate marker on Polyline path

I have 3 markers on a Google Map.
Two Markers to show starting and ending points
Here is the code using to draw a Polyline between these two points:
private void polyLine() {
LatLng starting = new LatLng(##.######, ##.######);
LatLng ending = new LatLng(##.######, ##.######);
PolylineOptions line = new PolylineOptions().add(starting, ending);
mGoogleMap.addMarker(new MarkerOptions().position(starting).title("Start"));
mGoogleMap.addMarker(new MarkerOptions().position(ending).title("End"));
mGoogleMap.addPolyline(line);
}
One Marker to show current Location [HUE_ROSE]
And to animate marker to current location using:
#Override
public void onLocationChanged(Location location)
{
Toast.makeText(this, "Location Changed " + location.getLatitude()
+ location.getLongitude(), Toast.LENGTH_LONG).show();
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
if(ourGlobalMarker == null) { // First time adding marker to map
ourGlobalMarker = mGoogleMap.addMarker(new MarkerOptions().position(latLng)
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ROSE)));
MarkerAnimation.animateMarkerToICS(ourGlobalMarker, latLng, new LatLngInterpolator.Spherical());
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
} else {
MarkerAnimation.animateMarkerToICS(ourGlobalMarker, latLng, new LatLngInterpolator.Spherical());
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 18));
}
}
PROBLEM:
Getting Animating Marker, but right side of Polyline
SOLUTION:
How Can I show Animated Marker on Polyline Path
I tried a lot to find solution for this one, but did not find any thing, share your suggestions.
I am assuming you have 3 marker
1. Source point
2. Destination Point
3. Moving marker
you have to try this way it will help you
private void animateMarkerNew(final LatLng startPosition, final LatLng destination, final Marker marker) {
if (marker != null) {
final LatLng endPosition = new LatLng(destination.latitude, destination.longitude);
final float startRotation = marker.getRotation();
final LatLngInterpolatorNew latLngInterpolator = new LatLngInterpolatorNew.LinearFixed();
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.setDuration(2000); // duration 3 second
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
try {
float v = animation.getAnimatedFraction();
LatLng newPosition = latLngInterpolator.interpolate(v, startPosition, endPosition);
marker.setPosition(newPosition);
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder()
.target(newPosition)
.zoom(18f)
.build()));
marker.setRotation(getBearing(startPosition, new LatLng(destination.latitude, destination.longitude)));
} catch (Exception ex) {
//I don't care atm..
}
}
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
// if (mMarker != null) {
// mMarker.remove();
// }
// mMarker = googleMap.addMarker(new MarkerOptions().position(endPosition).icon(BitmapDescriptorFactory.fromResource(R.drawable.icon_car)));
}
});
valueAnimator.start();
}
}
Note: marker is mean which marker you want to animate that one.
private interface LatLngInterpolatorNew {
LatLng interpolate(float fraction, LatLng a, LatLng b);
class LinearFixed implements LatLngInterpolatorNew {
#Override
public LatLng interpolate(float fraction, LatLng a, LatLng b) {
double lat = (b.latitude - a.latitude) * fraction + a.latitude;
double lngDelta = b.longitude - a.longitude;
// Take the shortest path across the 180th meridian.
if (Math.abs(lngDelta) > 180) {
lngDelta -= Math.signum(lngDelta) * 360;
}
double lng = lngDelta * fraction + a.longitude;
return new LatLng(lat, lng);
}
}
}
//Method for finding bearing between two points
private float getBearing(LatLng begin, LatLng end) {
double lat = Math.abs(begin.latitude - end.latitude);
double lng = Math.abs(begin.longitude - end.longitude);
if (begin.latitude < end.latitude && begin.longitude < end.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)));
else if (begin.latitude >= end.latitude && begin.longitude < end.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 90);
else if (begin.latitude >= end.latitude && begin.longitude >= end.longitude)
return (float) (Math.toDegrees(Math.atan(lng / lat)) + 180);
else if (begin.latitude < end.latitude && begin.longitude >= end.longitude)
return (float) ((90 - Math.toDegrees(Math.atan(lng / lat))) + 270);
return -1;
}
Try out with setting anchor like follows
mDetailPositionMarker = mDetailGoogleMap.addMarker(new MarkerOptions()
.position(newLatLonValue)
.anchor(0.5f, 0.5f)
.rotation(bearingValue)
.flat(true)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.biketopicon)));
And make sure your icon will not be having any padding or margin. Avoid unnecessary space in icon image than the content like shown below.
// Animation handler for old APIs without animation support
private void animateMarkerTo(final Marker marker, final double lat, final double lng) {
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
final long DURATION_MS = 3000;
final Interpolator interpolator = new AccelerateDecelerateInterpolator();
final LatLng startPosition = marker.getPosition();
handler.post(new Runnable() {
#Override
public void run() {
float elapsed = SystemClock.uptimeMillis() - start;
float t = elapsed/DURATION_MS;
float v = interpolator.getInterpolation(t);
double currentLat = (lat - startPosition.latitude) * v + startPosition.latitude;
double currentLng = (lng - startPosition.longitude) * v + startPosition.longitude;
marker.setPosition(new LatLng(currentLat, currentLng));
// if animation is not finished yet, repeat
if (t < 1) {
handler.postDelayed(this, 16);
}
}
});
}
call this method inside onLocationChange method and pass location lat and lang then you will see a magic ;)

HelpAndroid map marker change start and end color, put different details and add polylines

Is there a way I can change the icon of start and end of marker like blue for start and red for end, add different details and add connecting polyline?
Button:
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for (int i = 0; i < list_location.size(); i++) {
createMarker(list_location.get(i).getLatitude(), list_location.get(i).getLongitude());
}
}
});
Marker:
private void createMarker(String latitude, String longitude) {
// Adding the taped point to the ArrayList
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.ic_menu_camera);
Double lat = Double.parseDouble(latitude);
Double Longitude = Double.parseDouble(longitude);
map.addMarker(new MarkerOptions()
.position(new LatLng(lat, Longitude))
.anchor(0.5f, 0.5f)
.title("title")
.snippet("snippet")
.icon(icon));
}
It's easy but seems you haven't tried much
you can use index to find first and last points
and draw different color based on position
i.e.
for (int i = 0; i < list_location.size(); i++) {
createMarker(i, list_location.get(i).getLatitude(),list_location.get(i).getLongitude());
}
and in your createMarker() method
private void createMarker(int index, String latitude, String longitude) {
// Adding the taped point to the ArrayList
if (index == 0)
color = BitmapDescriptorFactory.COLOR_THAT_SUITS;
else if (index == list_location.size()-1)
color = BitmapDescriptorFactory.COLOR_THAT_SUITS;
//set this color to your marker
.....
.....
.icon(BitmapDescriptorFactory.defaultMarker(color)));
}

Regular Shape polygon Android map on Map Click

I want to create a regular polygon shape no matter the order of click on map. Currently I am facing a problem if a click on the map to draw polygon in the following manner then it works fine order is following
top left top right bottom right bottom left. IF this order is maintained then polygon drawn is perfectly fine similarly if i click on top right ,top left bottom right bottom it is also drawing perfectly fine. If when I change a single pint in order it does not draw proper shaped polygon
Image1
Image 2
Code 2 draw polygon is following
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
llClearSelection.setVisibility(View.VISIBLE);
gMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)).position(latLng));
if (markerClicked) {
// latLngArrayListPolygon.clear();
if (polygon != null) {
polygon.remove();
polygon = null;
}
polygonOptions.add(latLng);
latLngArrayListPolygon.add(latLng);
polygonOptions.strokeColor(Color.RED);
polygonOptions.fillColor(shadeColor);
polygon = gMap.addPolygon(polygonOptions);
if (latLngArrayListPolygon.size() > 1)
ivSaveMap.setVisibility(View.VISIBLE);
else
ivSaveMap.setVisibility(View.GONE);
} else {
if (polygon != null) {
polygon.remove();
polygon = null;
}
polygonOptions = new PolygonOptions().add(latLng);
latLngArrayListPolygon.add(latLng);
markerClicked = true;
}
}
});
My concern is I want to draw a regular shape irrespective of the order of click on map
Finally I derived solution to create regular shape polygon. This is not related to Convex hull.
Following are the Step to create regular shape polygon whether you click clock wise on map or counter clock wise on map.
Find the mid points of the edges of polygon
Calculate the nearest coordinate by finding distance between mid point of each edge and the coordinate to be drawn
The nearest coordinate = the edge with minimum distance from mid point to the coordinate to be drawn
move the nearest coordinate at the end by shifting array right
Following is the code :
ArrayList<LatLng> latLngArrayListPolygon = new ArrayList<>();
ArrayList<Double> distancesFromMidPointsOfPolygonEdges = new ArrayList<>();
private void adjustPolygonWithRespectTo(LatLng point) {
double minDistance = 0;
if (latLngArrayListPolygon.size() > 2) {
distancesFromMidPointsOfPolygonEdges.clear();
//midPointsOfPolygonEdges?.removeAll()
for (int i = 0; i < latLngArrayListPolygon.size(); i++) {
// 1. Find the mid points of the edges of polygon
ArrayList<LatLng> list = new ArrayList<>();
if (i == (latLngArrayListPolygon.size() - 1)) {
list.add(latLngArrayListPolygon.get(latLngArrayListPolygon.size() - 1));
list.add(latLngArrayListPolygon.get(0));
} else {
list.add((latLngArrayListPolygon.get(i)));
list.add((latLngArrayListPolygon.get(i + 1)));
}
LatLng midPoint = computeCentroid(list);
// 2. Calculate the nearest coordinate by finding distance between mid point of each edge and the coordinate to be drawn
Location startPoint = new Location("");
startPoint.setLatitude(point.latitude);
startPoint.setLongitude(point.longitude);
Location endPoint = new Location("");
endPoint.setLatitude(midPoint.latitude);
endPoint.setLongitude(midPoint.longitude);
double distance = startPoint.distanceTo(endPoint);
distancesFromMidPointsOfPolygonEdges.add(distance);
if (i == 0) {
minDistance = distance;
} else {
if (distance < minDistance) {
minDistance = distance;
}
}
//midPointsOfPolygonEdges?.append(midPoint)
}
// 3. The nearest coordinate = the edge with minimum distance from mid point to the coordinate to be drawn
int position = minIndex(distancesFromMidPointsOfPolygonEdges);
// 4. move the nearest coordinate at the end by shifting array right
int shiftByNumber = (latLngArrayListPolygon.size() - position - 1);
if (shiftByNumber != latLngArrayListPolygon.size()) {
latLngArrayListPolygon = rotate(latLngArrayListPolygon, shiftByNumber);
}
}
// 5. Now add coordinated to be drawn
latLngArrayListPolygon.add(point);
}
public static int minIndex(ArrayList<Double> list) {
return list.indexOf(Collections.min(list));
}
public static <T> ArrayList<T> rotate(ArrayList<T> aL, int shift) {
if (aL.size() == 0)
return aL;
T element = null;
for (int i = 0; i < shift; i++) {
// remove last element, add it to front of the ArrayList
element = aL.remove(aL.size() - 1);
aL.add(0, element);
}
return aL;
}
private LatLng computeCentroid(List<LatLng> points) {
double latitude = 0;
double longitude = 0;
int n = points.size();
for (LatLng point : points) {
latitude += point.latitude;
longitude += point.longitude;
}
return new LatLng(latitude / n, longitude / n);
}
And to draw polygon on clicking on map is Following
gMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
gMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)).position(latLng));
if (markerClicked) {
if (polygon != null) {
polygon.remove();
polygon = null;
}
adjustPolygonWithRespectTo(latLng);
PolygonOptions polygonOptions = null;
for (int i = 0; i < latLngArrayListPolygon.size(); i++)
if (i == 0)
polygonOptions = new PolygonOptions().add(latLngArrayListPolygon.get(0));
else
polygonOptions.add(latLngArrayListPolygon.get(i));
polygonOptions.strokeColor(Color.BLACK);
polygonOptions.strokeWidth(5f);
polygonOptions.fillColor(shadeColor);
polygon = gMap.addPolygon(polygonOptions);
} else {
if (polygon != null) {
polygon.remove();
polygon = null;
}
polygonOptions = new PolygonOptions().add(latLng);
latLngArrayListPolygon.add(latLng);
markerClicked = true;
}
}
});
Have a look at How can I determine whether a 2D Point is within a Polygon?
As your user clicks on the map you have to determine if the new vertex is within the polygon or outside. If it is inside, ignore. Else, add the polygon and run the algorithm for every point in polygon.
Hope this helps.

Move an icon on google maps

I've searched for similar questions here but none of them helped me.
I have an application running on the map that shows the path taken by the user and an icon in the form of "police". What I want now is that this icon to move the map behind me. So I created a method (stalk) that calculates a new point given the current position of the user, the position of the icon and the map. The method works, but the problem is that when I run my application icon only moves once, because his position is not updated.
Here's part of my code:
public void onMyLocationChange(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
lat = String.valueOf(latitude);
longi = String.valueOf(longitude);
posCurrent = new LatLng(latitude, longitude);
posAtuais.add(posCurrent);
posInicial = posAtuais.get(0);
Marker marker = map.addMarker(new MarkerOptions().position(posInicial));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(posCurrent, 19));
PolylineOptions options = new PolylineOptions().width(5).color(mudaLinhaCor(heart_rate)).geodesic(true);
for (int z = 0; z < posAtuais.size(); z++) {
LatLng point = posAtuais.get(z);
options.add(point);
}
line = map.addPolyline(options);
LatLng posPolice = stalk(posCurrent, POLICE, map);
Marker init = map.addMarker(new MarkerOptions().position(posPolice)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.police)));
}
//A method that computes a new position
public LatLng stalk(LatLng player,LatLng police,GoogleMap mapView){
Projection projection = mapView.getProjection();
Point pointInicial = new Point(); //police
pointInicial = projection.toScreenLocation(police);
Point pointFinal = new Point(); //player
pointFinal = projection.toScreenLocation(player);
double y=0.2;
int x=0;
if((pointInicial.x==pointFinal.x)){
y=pointInicial.y+1;
}else{
double m=(pointFinal.y-pointInicial.y)/(pointFinal.x-pointInicial.x);
double b=pointInicial.y-(m*pointInicial.x);
int i=1;
while(y != (int)y){
if(pointInicial.x<pointFinal.x){
x=pointInicial.x+i;
//System.out.println("entrou no x<xfnal: "+x);
}
else if(pointInicial.x>pointFinal.x){
//System.out.println("entrou no x>xfnal");
x=pointInicial.x-i;
}
y=m*x+b;
//System.out.println("y: : "+y);
i++;
}
}
return projection.fromScreenLocation(new Point(x, (int) y));
}
Someone could help me.
Implement OnMarkerDragListener in your activity then
#Override
public void onMarkerDragStart(Marker arg0) {
markerOptions.position(latLng);
}
#Override
public void onMarkerDragEnd(Marker arg0) {
myMap.clear();
latLng = arg0.getPosition();
markerOptions.position(latLng);
Marker marker = myMap.addMarker(markerOptions);
}

Categories

Resources