I'm following a tutorial to implement route drawing on my map. I implemented it, run it, choose points and then it crashes. It gives me this error
Attempt to invoke virtual method 'com.google.android.gms.maps.model.Polyline com.google.android.gms.maps.GoogleMap.addPolyline(com.google.android.gms.maps.model.PolylineOptions)' on a null object reference
The thing is that this shouldn't be empty since I have at least 3 points on the map....
The studio points my error to be here, but I dont find it: `protected void onPostExecute(List>> result) {
ArrayList points;
PolylineOptions lineOptions = null;
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.RED);
}
if(lineOptions != null) {
googleMap.addPolyline(lineOptions); //---> ERROR supose to be here..
}
else {
}
}
}`
If anybody could give me a hand, I would kindly appreciate it.
Related
I am drawing route on google map using waypoints. Everything looks good except my origin and destination is also connected. I am sure my origin and destination is not same.
Here is the url generated after I generate directions url from list of latitude/longitudes.
https://maps.googleapis.com/maps/api/directions/json?
&origin=26.8530478,75.78491989999999
&destination=26.8804683,75.75850109999999
&waypoints=26.8566917,75.7691974%7C
26.868405,75.76440269999999%7C
26.8762989,75.7664082
&key=MY_API_KEY
And also attaching the output. The straight line from "1" to "5' should not be there. Please help me in finding the mistake.
Thanks.
ParserTask -
ArrayList<LatLng> points = new ArrayList<LatLng>();
PolylineOptions lineOptions = new PolylineOptions();
// LatLngBounds.Builder builder = new LatLngBounds.Builder();
int color = ContextCompat.getColor(activity, R.color.black_overlay);
if (null != result)
for (int i = 0; i < result.size(); i++) {
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
//builder.include(position);
}
lineOptions = new PolylineOptions().width(15).color(color).addAll(points).zIndex(6);
}
if (activity instanceof OnRoutesParsingCompletedCallBack) {
((OnRoutesParsingCompletedCallBack) activity).
onRoutesParsingCompleted(lineOptions);
}
Activity with map object -
#Override
public void onRoutesParsingCompleted(PolylineOptions lineOptions) {//}, LatLngBounds.Builder builder) {
if (lineOptions.getPoints().size() > 0) {
googleMap.addPolyline(lineOptions);
} else
Toast.makeText(this, "There is something wrong. No routes to draw!", Toast.LENGTH_SHORT).show();
mCurrLocationMarker.showInfoWindow();
progressBar.setVisibility(GONE);
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLong, 13));
}
I think, the issue is that you are adding all possible routes to the same polyline. So, the polyline goes by the first route, then it "returns" to the start point and goes again by the second route. You either need to remove the for that loops over the results:
if (null != result)
// Fetching 1st route
List<HashMap<String, String>> path = result.get(0);
// Fetching all the points in 1st route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
//builder.include(position);
}
lineOptions = new PolylineOptions().width(15).color(color).addAll(points).zIndex(6);
}
Or you can create a polyline for each existing route.
on my app i add 2 marker on map. When i add a second marker with click i call a function to calculate route and add polyline on map.
This is the code for polyline
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
String value_duration = "";
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 0; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
if (j == 0) { // Get distance from the list
distance = (String) point.get("distance");
continue;
} else if (j == 1) { // Get duration from the list
duration = (String) point.get("duration");
value_duration = (String) point.get("duration_");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(10);
lineOptions.color(Color.parseColor("#F7B907"));
}
// Drawing polyline in the Google Map for the i-th route
distanza_percorso = distance;
durata_percorso = duration;
testo_car.setText(durata_percorso);
durata_tragitto = Float.parseFloat(value_duration);
Log.d("durata_tragitto", "durata: " + value_duration);
polylineFinal = map.addPolyline(lineOptions);
moveToBounds(map.addPolyline(lineOptions));
}
Now i would like to remove polyline by map if i replace second marker and call a new calculate route.
I have write this codde:
if (polylineFinal != null){
polylineFinal.remove();
}
but the polyline on map are not remove.
Can you help me please? Any idea why?
Thanks
Not sure but try updating your adding polyline code with this,
polylineFinal = map.addPolyline(lineOptions);
moveToBounds(polylineFinal);
I am an android noob and i am exploring android maps api.I am referring this site.
I can understand everything except the distance and duration retrieval.
The JSON parsing code is given below.
public List<List<HashMap<String,String>>> parse(JSONObject jObject){
List<List<HashMap<String, String>>> routes = new ArrayList<List<HashMap<String,String>>>() ;
JSONArray jRoutes = null;
JSONArray jLegs = null;
JSONArray jSteps = null;
JSONObject jDistance = null;
JSONObject jDuration = null;
try {
jRoutes = jObject.getJSONArray("routes");
/** Traversing all routes */
for(int i=0;i<jRoutes.length();i++){
jLegs = ( (JSONObject)jRoutes.get(i)).getJSONArray("legs");
List<HashMap<String, String>> path = new ArrayList<HashMap<String, String>>();
/** Traversing all legs */
for(int j=0;j<jLegs.length();j++){
/** Getting distance from the json data */
jDistance = ((JSONObject) jLegs.get(j)).getJSONObject("distance");
HashMap<String, String> hmDistance = new HashMap<String, String>();
hmDistance.put("distance", jDistance.getString("text"));
/** Getting duration from the json data */
jDuration = ((JSONObject) jLegs.get(j)).getJSONObject("duration");
HashMap<String, String> hmDuration = new HashMap<String, String>();
hmDuration.put("duration", jDuration.getString("text"));
/** Adding distance object to the path */
path.add(hmDistance);
/** Adding duration object to the path */
path.add(hmDuration);
jSteps = ( (JSONObject)jLegs.get(j)).getJSONArray("steps");
/** Traversing all steps */
for(int k=0;k<jSteps.length();k++){
String polyline = "";
polyline = (String)((JSONObject)((JSONObject)jSteps.get(k)).get("polyline")).get("points");
List<LatLng> list = decodePoly(polyline);
/** Traversing all points */
for(int l=0;l<list.size();l++){
HashMap<String, String> hm = new HashMap<String, String>();
hm.put("lat", Double.toString(((LatLng)list.get(l)).latitude) );
hm.put("lng", Double.toString(((LatLng)list.get(l)).longitude) );
path.add(hm);
}
}
}
routes.add(path);
}
} catch (JSONException e) {
e.printStackTrace();
}catch (Exception e){
}
return routes;
}
They are getting distance and duration data for every single leg.The Android docs says , distance indicates the total distance covered by this leg and "duration indicates the total duration of this leg".So my assumption was, during final distance and duration computaion,
all these datum would be added.
This is the final code:
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points = null;
PolylineOptions lineOptions = null;
MarkerOptions markerOptions = new MarkerOptions();
String distance = "";
String duration = "";
if(result.size()<1){
Toast.makeText(getBaseContext(), "No Points", Toast.LENGTH_SHORT).show();
return;
}
// Traversing through all the routes
for(int i=0;i<result.size();i++){
points = new ArrayList<LatLng>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for(int j=0;j<path.size();j++){
HashMap<String,String> point = path.get(j);
if(j==0){ // Get distance from the list
distance = (String)point.get("distance");
continue;
}else if(j==1){ // Get duration from the list
duration = (String)point.get("duration");
continue;
}
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(2);
lineOptions.color(Color.RED);
}
tvDistanceDuration.setText("Distance:"+distance + ", Duration:"+duration);
// Drawing polyline in the Google Map for the i-th route
map.addPolyline(lineOptions);
}
}
My assumption went wrong.Here the distance and duration are retrieved for every leg(they are not even stored) and after looping through every route and leg ,finally the textview is set to those variables(distance and duration) and it gives the overall distance and duration.
So my question is how the overall distance and duration are computed without any manual mathematical operations,while we have parsed those objects corresponding to all individual legs?
use distance matrix api to get the actual distance and time . see the bellow link
https://developers.google.com/maps/documentation/distance-matrix/start
i have a map v2 application with ability to drawing polylines from pinpointed location to user current location fetched from gps.
i used google directions in order to get polyline strings.
after drawing got some unease at the end point of each polyline.
see screenshot from actual device :
this is my drawing codes :
for(int j = 0; j < allPoints.length - 1;j++) {
if(allPoints[j] != null) {
System.out.println("pontos " + allPoints[j]);
List<LatLng> test = decodePoly(allPoints[j]);
for (int i = 0; i < test.size() - 1; i++) {
LatLng src = test.get(i);
LatLng dest = test.get(i + 1);
try {
Polygon line = googleMap.addPolygon(new PolygonOptions()
.add(new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude))
.strokeColor(Color.BLUE).geodesic(true));
} catch (NullPointerException e) {
Log.e("Error", "NullPointerException onPostExecute: " + e.toString());
} catch (Exception e2) {
Log.e("Error", "Exception onPostExecute: " + e2.toString());
}
}
}
}
can i put a circle after each polyline ? does it fix my problem ?
As #Cheesebaron states, the best options is adding only one Polyline. I haven't tested it because I don't have an example of your allPoints data, but it could be something like this:
for (int j = 0; j < allPoints.length - 1; j++) {
if (allPoints[j] != null) {
List<LatLng> test = decodePoly(allPoints[j]);
Polyline line = googleMap.addPolyline(new PolylineOptions().color(Color.BLUE).geodesic(true).addAll(test));
}
}
You can also create only one Polyline instead of one Polyline for each allPoints[j]:
PolylineOptions polylineOptions = new PolylineOptions().color(Color.BLUE).geodesic(true);
for (int j = 0; j < allPoints.length - 1; j++) {
if (allPoints[j] != null) {
List<LatLng> test = decodePoly(allPoints[j]);
polylineOptions.addAll(test);
}
}
Polyline line = googleMap.addPolyline(polylineOptions);
I am trying to draw a path on roads and follow some given points.I am using Google Directions API to follow the roads.I put some markers on roads and link these points with polylines.But not all points were linked.Sometimes all points were drawn sometimes some of them is missing.I could’t understand why?
MyList is an array which consists of lat lng values of some points.latlngBoundsfunction links elements of that array in a for loop.
for (int i = 0; i < myList.size(); i++) {
Double latS = Double.parseDouble(myList.get(i).getlat());
Double lngS = Double.parseDouble(myList.get(i).getlng());
Double latD = Double.parseDouble(myList.get(i+1).getlat());
Double lngD = Double.parseDouble(myList.get(i+1).getlng());
LatLng first = new LatLng(latS,lngS);
LatLng second = new LatLng(latD,lngD);
findDirections(latS,lngS,latD,lngD, GMapV2Direction.MODE_DRIVING );
latlngBounds = createLatLngBoundsObject(first,second);
}
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);
}
public void handleGetDirectionsResult(ArrayList<LatLng> directionPoints) {
PolylineOptions rectLine = new PolylineOptions().width(5).color(Color.BLUE);
for(int i = 0 ; i < directionPoints.size() ; i++)
{
rectLine.add(directionPoints.get(i));
}
newPolyline = googleMap.addPolyline(rectLine);
}
I make use of two class of this source in the link GMapV2Direction,GetDirectionsAsyncTask