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);
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 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);
I'm working on Android Studio>> I have an origin point and destiny point. I draw the route with the JSONData from Google Services and I create a polyline. Now, I need to monitor user's current position from the polyline in the map, but I can't.
Here's my code:
private void drawRoute(List<LatLng> list) {
if ((list != null) && (list.size() > 0)) {
polylineOptions = new PolylineOptions()
.addAll(list)
.width(8);
map.addPolyline(polylineOptions);
CircleOptions circleOptions;
for (int i = 0; i < polylineOptions.getPoints().size(); i++) {
LatLng point = polylineOptions.getPoints().get(i);
circleOptions = new CircleOptions()
.center(new LatLng(point.latitude, point.longitude))
.strokeColor(Color.TRANSPARENT)
.strokeWidth(1)
.fillColor(Color.argb(100, 164, 171, 167))
.radius(10);
map.addCircle(circleOptions);
}
} else {
Log.i("Msg", "No routes");
}
}
And I get the distance with this:
private double getDistance(LatLng originPoint, LatLng destinyPoint) {
try {
Location origin = new Location("Origin point");
origin.setLatitude(originPoint.latitude);
origin.setLongitude(originPoint.longitude);
Location destiny = new Location("Destiny point");
destiny.setLatitude(destinyPoint.latitude);
destiny.setLongitude(destinyPoint.longitude);
return origin.distanceTo(destiny);
} catch (Exception e) {
Log.e("Msg", e.getMessage());
return 0d;
}
}
I don't know if there's a way to find a "piece" of polyline in the circle around user's current location and calculate the distance between that "piece" and current location. I've been searching but the code I found is in V3 and I'm starting Android apps. I appreciate your help!
Well, if you need it, I resolve it with this code:
#Override
protected Boolean doInBackground(List<LatLng>... params) {
publishProgress();
List<LatLng> list = params[0];
LatLng currentPosition = list.get(0);
for (int i = 1; i < list.size(); i++) {
if (obtenerDistancia(currentPosition, list.get(i)) <= 100) {
return false;
}
}
return true;
}
Where list = current position + polyline.getPoints()
list[0] = current position;
list[1], list[2]..., list[n] = polyline points.
I calculate distance between my current position (list[0]) and each point in polyline (list[1], list[2]..., list[n]]. If I find at least one point that is <= 100 meters from my current position, that means user is close to the drawn route.
You don't need to find the "piece" around the user current postion.
You just need to decodePolyLine the points in the JSon file and put all the LatLng to a list and use the class I have created to check it.
Here is my answer for the relative topic it have the Class and the method you're looking for: https://stackoverflow.com/a/49904276/7548514
I have a bunch of markers in which I load onto a google map. My problem is that, the camera is not ontop of the markers. Can I center it on top of all my markers?
I am adding my markers with this code:
for(int i = 0; i < jsonArray.length(); i++) {
String breweryName = jsonArray.getJSONObject(i).getString("brewery");
String lat = jsonArray.getJSONObject(i).getString("lat");
String lng = jsonArray.getJSONObject(i).getString("lng");
String bID = jsonArray.getJSONObject(i).getString("breweryID");
double latD = Double.parseDouble(lat);
double lngD = Double.parseDouble(lng);
m.addMarker(new MarkerOptions()
.position(new LatLng(latD, lngD))
.title(breweryName));
}
I looked on stack and found this question, which is the same as mine:
Android Google maps API V2 center markers
But there isnt much context behind it and am not sure how to implement it.
You can animate your camera within specific bounds. Let's say you have an ArrayList of markers, something like (this could also be a list of LatLngs, doubles, anything that contains the latitude/longitude for your marker)
List<MarkerOptions> markers = new ArrayList<MarkerOptions>();
You can then make sure they are all visible on your map by doing the following
LatLngBounds.Builder builder = new LatLngBounds.Builder();
LatLng position;
for(int i = 0; i < markers.size(); i++){
position = markers.get(i).getPosition();
builder.include(new LatLng(position.latitude, position.longitude));
}
LatLngBounds bounds = builder.build();
map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, 15));