I am implementing animation in google map using this example. I am getting LatLng data from a server. But the problem arises when I get too many data for a single point on map. The animated marker wait on a single point so long as there are data for that point. Please see the following sample code
for (i = 0; i < jsonAssets.length(); i++) {
JSONObject nlmJsonObject = jsonAssets.getJSONObject(i);
JSONObject lastData_JsonObject = nlmJsonObject.getJSONObject("last_data");
JSONObject nlm_locJsonObject = lastData_JsonObject.getJSONObject("loc");
JSONArray coordinated = nlm_locJsonObject.getJSONArray("coordinates");
Log.d("LASTLATLONG_ANIMATION", coordinated.toString());
latt = (double) coordinated.get(0);
lng = (double) coordinated.get(1);
addMarkerToMap(new LatLng(lng, latt));
}
animator.startAnimation(true);
How can I check and omit similar points to make my map animation smoother?
Thanks
Just edited your code, to give the idea
private double latt;
private double lng;
private void showMarkers(){
// Your other codes
for (i = 0; i < jsonAssets.length(); i++) {
JSONObject nlmJsonObject = jsonAssets.getJSONObject(i);
JSONObject lastData_JsonObject = nlmJsonObject.getJSONObject("last_data");
JSONObject nlm_locJsonObject = lastData_JsonObject.getJSONObject("loc");
JSONArray coordinated = nlm_locJsonObject.getJSONArray("coordinates");
Log.d("LASTLATLONG_ANIMATION", coordinated.toString());
// Current values
double currentLat = (double) coordinated.get(0);
double currentLng = (double) coordinated.get(1);
// Compare. If not same add the marker
if(currentLat != latt && currentLng != lng){
latt = (double) coordinated.get(0);
lng = (double) coordinated.get(1);
addMarkerToMap(new LatLng(lng, latt));
}
}
animator.startAnimation(true);
}
The best option is to add a new marker only when it's location is farther than a given distance to the last marker added.
My example uses the SphericalUtil.computeDistanceBetween from the Google Maps API Utility Library to compute the distance betwen two LatLng objects:
final float MIN_DISTANCE = 10; // Minimum distance in meters to consider that two locations are the same
LatLng lastLatLng = null;
// ...
for (i = 0; i < jsonAssets.length(); i++) {
JSONObject nlmJsonObject = jsonAssets.getJSONObject(i);
JSONObject lastData_JsonObject = nlmJsonObject.getJSONObject("last_data");
JSONObject nlm_locJsonObject = lastData_JsonObject.getJSONObject("loc");
JSONArray coordinated = nlm_locJsonObject.getJSONArray("coordinates");
Log.d("LASTLATLONG_ANIMATION", coordinated.toString());
latt = (double) coordinated.get(0);
lng = (double) coordinated.get(1);
LatLng currentLatLng = new LatLng(latt, lng);
if (lastLatLng == null || SphericalUtil.computeDistanceBetween(lastLatLng, currentLatLng) > MIN_DISTANCE) {
addMarkerToMap(new LatLng(lng, latt));
lastLatLng = currentLatLng;
}
}
animator.startAnimation(true);
Related
I have a hicking app, that gets a array of markers from my database and plots them on my map, afterward it draws a polyline connecting all the markers. What i want to do is , to draw the polyline connecting the markers, but instead of showing 10 or 20 or 100 markers, to only SHOW 2, the marker that starts and the one that ends.
Would appreciate any help.
Below is the function that i use to draw the polylines.
private void createPolylinesFromLatLng(ArrayList<LatLng> polylist){
PolylineOptions options = new PolylineOptions().width(5).color(Color.BLUE).geodesic(true);
for (int z = 0; z < polylist.size(); z++) {
LatLng point = polylist.get(z);
options.add(point);
totalDistanceInMeters = SphericalUtil.computeLength(polylist);
test=String.format("%.2f",totalDistanceInMeters);
}
and this is how i retrieve my markers into a array
JSONArray array = new JSONArray(response);
for (int i = 0; i < array.length(); i++) {
JSONObject jo = array.getJSONObject(i);
Double lat = Double.parseDouble(jo.getString("lat"));
Double lng = Double.parseDouble(jo.getString("lon"));
polyline = new LatLng(Double.parseDouble(jo.getString("lat")),
Double.parseDouble(jo.getString("lon")));
polylist.add(polyline);
// location = new LatLng(lat,lng);
location=polyline;
MarkerOptions options = new MarkerOptions();
options.position(location);
mMap.addMarker(options);
thank you
One way of doing this would to just surround your code where you add the Marker with a if statement like this:
if(i == 0 || i == (array.length() - 1)){
MarkerOptions options = new MarkerOptions();
options.position(location);
mMap.addMarker(options);
}
That way only the first location and the last location are added.
I am trying to display multiple markers on a google map but I seem to only get the last one to display. The reason is that the markers get overwritten in a for loop. I have created an ArrayList that will store the markers but I don't how to add it to the google Map..
the polylines library contains a method called addAll that adds an arraylist of polylines but markers does not have such a thing..could anyone suggest a way to add multiple markers to the map?
public void mapForGPS(GoogleMap googleMap) {
mMap = googleMap;
double[] firstCoords;
double[] lastCoords;
double[] receivedDataArray;
double latitude;
double longitude;
double[] firstSetOfCoordinatesFromArray;
double[] lastSetOfCoordinatesFromArray;
double[] tempCoordinatesArray;
String[] tempDurationAndTimeArray;
String time;
GpsData gpsDataObj;
String[] dataForOneGreenDot;
String[] arrayOfGreenDots = new String[3];
// this will store coordinates for one iteration of a selected day
ArrayList<LatLng> coordList = new ArrayList<LatLng>();
ArrayList<String[]> arrayListOfGreenDots = new ArrayList<String[]>();
// clear polyline array that has coordinates form previous iteration
coordList.clear();
// clears all the markers on the map for the next iteration
mMap.clear();
// loop through JSON array of coordinates and assign data into a coordinates array with an
// object of Latitude and Longitude
for (int i = 0; i <= arrayOfGpsData.size() - 1; i++) {
gpsDataObj = arrayOfGpsData.get(i);
tempCoordinatesArray = gpsDataObj.getArrayOfDoubles();
tempDurationAndTimeArray = gpsDataObj.getArrayOfStrings();
latitude = tempCoordinatesArray[0];
longitude = tempCoordinatesArray[1];
coordList.add(new LatLng(latitude,longitude));
time = tempDurationAndTimeArray[0];
String latString = String.valueOf(latitude);
String longString = String.valueOf(longitude);
arrayOfGreenDots[0] = latString;
arrayOfGreenDots[1] = longString;
arrayOfGreenDots[2] = time;
arrayListOfGreenDots.add(arrayOfGreenDots);
}
// if there was a previous polyline on the map, clear it
if(polylineGPS != null){
polylineGPS.remove();
}
// add coordinates to a polylineGPS object
options = new PolylineOptions().addAll(coordList).width(5).color(Color.BLUE).geodesic(true);
polylineGPS = mMap.addPolyline(options);
// if user selected date in date-time picker then marker will point to
// first set of coordinates in the coordinatesArray and the map will zoom in on that point
if(!arrayOfGpsData.isEmpty())
{
double[] coordinatesFromFirstIndex = new double[2];
String[] timeAndDurationFromFirstIndex = new String[2];
double[] coordinatesFromLastIndex = new double[2];
String[] timeAndDurationFromLastIndex = new String[2];
GpsData objectDataFromFirstIndex = new GpsData(coordinatesFromFirstIndex, timeAndDurationFromFirstIndex);
GpsData objectDataFromLastIndex = new GpsData(coordinatesFromLastIndex, timeAndDurationFromLastIndex);
// get first set of coordinates from array as starting position
objectDataFromFirstIndex = arrayOfGpsData.get(0);
firstSetOfCoordinatesFromArray = objectDataFromFirstIndex.getArrayOfDoubles();
// get last set of coordinates from array as ending position
objectDataFromLastIndex = arrayOfGpsData.get(arrayOfGpsData.size() - 1);
lastSetOfCoordinatesFromArray = objectDataFromLastIndex.getArrayOfDoubles();
//timeAndDurationFromFirstIndex = objectDataFromFirstIndex.getArrayOfStrings();
// place marker for starting position
LatLng firstLocationPointOfDevice = new LatLng(firstSetOfCoordinatesFromArray[0], firstSetOfCoordinatesFromArray[1]);
mMap.addMarker(new MarkerOptions().position(firstLocationPointOfDevice).icon((BitmapDescriptorFactory.fromResource(R.drawable.blue_marker))).title("Starting Location"));
// place marker for ending position
LatLng lastLocationPointOfDevice = new LatLng(lastSetOfCoordinatesFromArray[0], lastSetOfCoordinatesFromArray[1]);
mMap.addMarker(new MarkerOptions().position(lastLocationPointOfDevice).icon(BitmapDescriptorFactory.fromResource(R.drawable.pink_marker)).title("Ending Location"));
// zoom in on first set of coordinates form coordinatesArray
mMap.moveCamera(CameraUpdateFactory.newLatLng(firstLocationPointOfDevice));
// camera zoom in position
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(firstLocationPointOfDevice, 10));
List<Marker> markers = new ArrayList<Marker>();
// adding markers to array list
for(int k = 0; k <= arrayListOfGreenDots.size() - 1; k++){
dataForOneGreenDot = arrayListOfGreenDots.get(k);
double latSingle = Double.parseDouble(dataForOneGreenDot[0]);
double longSingle = Double.parseDouble(dataForOneGreenDot[1]);
String timeSingle = dataForOneGreenDot[2];
//drawMarker(latSingle, longSingle, timeSingle);
LatLng greenDot = new LatLng(latSingle, longSingle);
marker = mMap.addMarker(new MarkerOptions().position(greenDot).icon(BitmapDescriptorFactory.fromResource(R.drawable.green_dot)).title(timeSingle));
markers.add(marker);
}
}
// if user did not select any date from date time picker, then by default the map will zoom on vancouver
else if(arrayOfGpsData.isEmpty())
{
// default location if no date is selected
LatLng defaultLocation = new LatLng(49.2827, -123.1207);
mMap.moveCamera(CameraUpdateFactory.newLatLng(defaultLocation));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, 10));
}
}
I really don't know why this question got downvoted because it addresses a legit concern for which there was no immidiate answer.
I have found a solution though:
for (int i = 0; i <= arrayOfGpsData.size() - 1; i++) {
gpsDataObj = arrayOfGpsData.get(i);
tempCoordinatesArray = gpsDataObj.getArrayOfDoubles();
tempDurationAndTimeArray = gpsDataObj.getArrayOfStrings();
latitude = tempCoordinatesArray[0];
longitude = tempCoordinatesArray[1];
coordList.add(new LatLng(latitude,longitude));
time = tempDurationAndTimeArray[0];
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude,longitude))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.green_dot_6px))
.title(time)
);
}
as I loop through my arrayOfGpsData and assign lat and long to my LatLng object, I add a marker to that LatLng right away with a time stamp.
I hope this helps someone in the future :D
I'm trying to calculate distance between LatLng points. It's easy to calculate for two coordinates. I have to calculate distance between more than two LatLngs and calculate the cumulative distance from a set of LatLngs. I calculated distance between two points as per the following code.
tvDistance=(TextView)findViewById(R.id.textView4);
Location loc1=new Location("");
loc1.setLatitude(11.2805);
loc1.setLongitude(77.5989);
Location loc2=new Location("");
loc2.setLatitude(11.2801);
loc2.setLongitude(77.5976);
DecimalFormat format=new DecimalFormat("#.##");
double distanceInMeters = loc1.distanceTo(loc2)/1000;
tvDistance.setText(format.format(distanceInMeters) + " Km's");
Now I have for example sixteen LatLng points. First is starting place and last is stopping place. I have the LatLngs in a ArrayList. tried the following code. But it caused ArrayIndexOutOfBoundException.
Do anybody know a method please share with me. Thanks.
private void calculateDistance() {
for (int i=0;i<coordList.size();i++){
LatLng l1=coordList.get(i);
double lat1=l1.latitude;
double lng1=l1.longitude;
Location location1=new Location("");
location1.setLatitude(lat1);
location1.setLongitude(lng1);
LatLng l2=coordList.get(i+1);
double lat2=l2.latitude;
double lng2=l2.longitude;
Location location2=new Location("");
location2.setLatitude(lat2);
location2.setLongitude(lng2);
DecimalFormat format=new DecimalFormat("#.##");
double distance=location1.distanceTo(location2)/1000;
Toast.makeText(MainPage.this,format.format(distance) + " Km's",Toast.LENGTH_SHORT).show();
}
}
You can use SphericalUtil.computeLength method:
http://googlemaps.github.io/android-maps-utils/javadoc/com/google/maps/android/SphericalUtil.html#computeLength-java.util.List-
Sources: https://github.com/googlemaps/android-maps-utils/blob/master/library/src/com/google/maps/android/SphericalUtil.java
The line
LatLng l2=coordList.get(i+1);
causes the exception.
jon
->Its easy to calculate the distance if you have sets of latitudes and longitudes
ArrayList<RideRoutes> ride_route_list = new ArrayList<>();
//suppose "ride_route_list" contains collections of Latitudes and longitudes
String distance_covered_str;
double total_meters = 0.0;
for(int i = 0; i < (ride_route_list.size() - 1); i++){
double previous_latitude = Double.parseDouble(ride_route_list.get(i).getRout_latitude());
double previous_longitude = Double.parseDouble(ride_route_list.get(i).getRout_longitude());
double updated_latitude = Double.parseDouble(ride_route_list.get(i+1).getRout_latitude());
double updated_longitude = Double.parseDouble(ride_route_list.get(i+1).getRout_longitude());
Location start_latlng = new Location("location_previous");
start_latlng.setLatitude(previous_latitude);
start_latlng.setLongitude(previous_longitude);
Location end_latlng = new Location("location_updated");
end_latlng.setLatitude(updated_latitude);
end_latlng.setLongitude(updated_longitude);
total_meters += start_latlng.distanceTo(end_latlng);
}
double distance_covered_km = total_meters / 1000;
distance_covered_str = String.format(Locale.getDefault(), "%.2f", distance_covered_km);
Note:
->here ride_route_list is an ArrayList which contains the list of Latitude and longitude
RideRoutes Class Structure:
public class RideRoutes {
private String rout_latitude;
private String rout_longitude;
public RideRoutes(String rout_latitude, String rout_longitude) {
this.rout_latitude = rout_latitude;
this.rout_longitude = rout_longitude;
}
public String getRout_latitude() {
return rout_latitude;
}
public void setRout_latitude(String rout_latitude) {
this.rout_latitude = rout_latitude;
}
public String getRout_longitude() {
return rout_longitude;
}
public void setRout_longitude(String rout_longitude) {
this.rout_longitude = rout_longitude;
}
}
I am using a circle and trying to use its latitude and longitude values to load markers from a database that are within distance, the problem is, it is loading all the markers, rather than just the ones within the circle.
Can anyone point out where I'm going wrong? Code:
float[] distance = new float[10];
for(int i=0; i<jArray.length(); i++)
{
JSONObject jsonData = jArray.getJSONObject(i);
databaseMarkerData.add(new BasicNameValuePair("name", jsonData.getString("name")));
databaseMarkerData.add(new BasicNameValuePair("address", jsonData.getString("address")));
databaseMarkerData.add(new BasicNameValuePair("description", jsonData.getString("description")));
databaseMarkerData.add(new BasicNameValuePair("rating", jsonData.getString("rating")));
databaseMarkerData.add(new BasicNameValuePair("lat", jsonData.getString("lat")));
databaseMarkerData.add(new BasicNameValuePair("lng", jsonData.getString("lng")));
databaseMarkerData.add(new BasicNameValuePair("estType", jsonData.getString("estType")));
databaseMarkerData.add(new BasicNameValuePair("reliability", jsonData.getString("reliability")));
String latText = jsonData.getString("lat");
Double lat = Double.parseDouble(latText);
String lngText = jsonData.getString("lng");
Double lng = Double.parseDouble(lngText);
getMarkerDataArray.add(new MarkerData(jsonData.getString("name"), jsonData.getString("address"), jsonData.getString("description"),
jsonData.getString("rating"), jsonData.getString("reliability"), lat, lng, jsonData.getString("estType")));
Location.distanceBetween( lat, lng, circle.getCenter().latitude, circle.getCenter().longitude, distance);
if( distance[i] < circle.getRadius())
{
plotMarkers(getMarkerDataArray);
}
}
this is my plotMarkers function just in case it is needed:
plotMarkers()
private void plotMarkers(ArrayList<MarkerData> markers)
{
if(markers.size() > 0)
{
for (MarkerData markerData : markers)
{
// Create user marker with custom icon and other options
MarkerOptions markerOption = new MarkerOptions().position(new LatLng(markerData.getLat(), markerData.getLng()));
Marker currentMarker = googleMap.addMarker(markerOption);
markerDataHashmap.put(currentMarker, markerData);
googleMap.setInfoWindowAdapter(new MarkerInfoWindowAdapter());
}
}
There are more than one problem.
One is the first element of distance is what you should use:
if( distance[0] < circle.getRadius()){
plotMarkers(getMarkerDataArray);
}
And you just need one element array float[] distance = new float[1];
Two is this
if( distance[i] < circle.getRadius())
{
plotMarkers(getMarkerDataArray);
}
that getMarkerDataArray is a list that is filled regardless whether the distance condition is met or not and used in plotMarkers for every time it is. I think what you want is
for (...){
if( distance[0] < circle.getRadius()){
getMarkerDataArray.add(new MarkerData(...));
}
}
plotMarkers(getMarkerDataArray);
I'm trying to calculate the route between two locations with a code that you already know.
In my case the first location is MY location and the second location is the nearest LatLng
of a path.
This code below calculates the nearest LatLng:
private LatLng nearestLatLng(Location mCurrentLocation) {
LatLng latLngCurrentLocation = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
double nearestLatitude = 0;
double nearestLongitude = 0;
float minDistance = 1000; //I don't know how to initialize
float currentDistance;
for(int i=0; i<mLatLngGpxList.size(); i++) {
LatLng currentTrackLatLng = mLatLngGpxList.get(i);
currentDistance = getDistance(latLngCurrentLocation, currentTrackLatLng);
if(currentDistance <= minDistance) {
minDistance = currentDistance;
nearestLatitude = currentTrackLatLng.latitude;
nearestLongitude = currentTrackLatLng.longitude;
}
}
//mGoogleMap.addMarker(new MarkerOptions().position(new LatLng(nearestLatitude, nearestLongitude)));
return new LatLng(nearestLatitude,nearestLongitude);
}
//Calcola la distanza tra due LatLng
private float getDistance(LatLng first, LatLng second) {
float [] dist = new float[1];
Location.distanceBetween(first.latitude, first.longitude, second.latitude, second.longitude, dist);
return dist[0];
}
If i draw a path in my country, i can also draw the path for reach it, but if i draw a path
away from my country, i get this:
org.json.JSONException: Index 0 out of range [0..0)
at org.json.JSONArray.get(JSONArray.java:263)
at org.json.JSONArray.getJSONObject(JSONArray.java:480)
etc.
and consequently no path to my path is drawn. Why? :(
Ps: i DON'T get "error_message" : "You have exceeded your daily request quota for this API."
Update: the error is in the code above. Advice? :/
Second Update: float minDistance = 1000; --> became float minDistance = 100000000
and now works. It remains a logical problem but i'll see.. :/