I want to draw a route map from source to destination in Google Maps .The source is tracked from GPs and destination is got from the user .I want route to be displayed between these points .I want to repaint the map everytime the location gets updated by the gps
Here is source of my map activity:
package tvarwebu.projects.map;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
public class MapProjectActivity extends MapActivity {
GeoPoint myPoint = null;
GeoPoint nextPoint = null;
MapView map;
private Road mRoad;
int latSpan = -1;
boolean moving = false;
long lastTimestamp = 0;
int pointCount = 0;
int lat = 0;
int lng = 0;
Location currLoc = null;
OverlayItem currPoint;
MyItemizedOverlay currItemizedOverlay;
List<Overlay> mapOverlays;
LocationManager lm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
map = (MapView) findViewById(R.id.mapView);
map.setBuiltInZoomControls(true);
map.setStreetView(true);
map.setSatellite(false);
// Your position initialize
lat = 53324388;
lng = -6263194;
myPoint = new GeoPoint(lat, lng);
Drawable drawable = this.getResources().getDrawable(
R.drawable.flag_green);
MyItemizedOverlay itemizedoverlay = new MyItemizedOverlay(drawable,
this);
OverlayItem overlayitem = new OverlayItem(myPoint, "Start Position",
"Your start position");
itemizedoverlay.addOverlay(overlayitem);
// Position of next point
int lat2 = 53348084;
int lng2 = -6292434;
nextPoint = new GeoPoint(lat2, lng2);
OverlayItem overlayitem2 = new OverlayItem(nextPoint, "Position",
"Position of next point");
itemizedoverlay.addOverlay(overlayitem2);
mapOverlays = map.getOverlays();
mapOverlays.add(itemizedoverlay);
Drawable draw2 = this.getResources().getDrawable(R.drawable.flag_red);
MyItemizedOverlay over2 = new MyItemizedOverlay(draw2, this);
over2.addOverlay(overlayitem2);
mapOverlays.add(over2);
// zooming to both points
int maxLatitude = Math.max(lat, lat2);
int minLatitude = Math.min(lat, lat2);
int maxLongitude = Math.max(lng, lng2);
int minLongitude = Math.min(lng, lng2);
MapController mc = map.getController();
mc.zoomToSpan(maxLatitude - minLatitude, maxLongitude - minLongitude);
mc.animateTo(new GeoPoint((maxLatitude + minLatitude) / 2,
(maxLongitude + minLongitude) / 2));
map.invalidate();
//Drawing path in new Thread
new Thread() {
#Override
public void run() {
double fromLat = Double.valueOf(myPoint.getLatitudeE6()) / 1000000.0,
fromLon = Double.valueOf(myPoint.getLongitudeE6()) / 1000000.0;
double toLat = Double.valueOf(nextPoint.getLatitudeE6()) / 1000000.0,
toLon = Double.valueOf(nextPoint.getLongitudeE6()) / 1000000.0;
String url = RoadProvider
.getUrl(fromLat, fromLon, toLat, toLon);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
mHandler.sendEmptyMessage(0);
}
}.start();
}
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
MapOverlay mapOverlay = new MapOverlay(mRoad, map);
List<Overlay> listOfOverlays = map.getOverlays();
// listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
map.invalidate();
};
};
private InputStream getConnection(String url) {
InputStream is = null;
try {
URLConnection conn = new URL(url).openConnection();
is = conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
// Map extends overlay for drawing path
class MapOverlay extends com.google.android.maps.Overlay {
Road mRoad;
ArrayList<GeoPoint> mPoints;
public MapOverlay(Road road, MapView mv) {
mRoad = road;
// mRoute is field of route points getting from Google Maps
if (road.mRoute.length > 0) {
mPoints = new ArrayList<GeoPoint>();
for (int i = 0; i < road.mRoute.length; i++) {
mPoints.add(new GeoPoint(
(int) (road.mRoute[i][1] * 1000000),
(int) (road.mRoute[i][0] * 1000000)));
}
}
}
#Override
public void draw(Canvas canvas, MapView mv, boolean shadow) {
drawPath(mv, canvas);
}
public void drawPath(MapView mv, Canvas canvas) {
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
Paint paint = new Paint();
latSpan = mv.getLatitudeSpan();
paint.setColor(Color.parseColor("#998447cc"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(6);
if (mPoints != null) {
for (int i = 0; i < mPoints.size(); i++) {
Point point = new Point();
mv.getProjection().toPixels(mPoints.get(i), point);
x2 = point.x;
y2 = point.y;
if (i > 0) {
canvas.drawLine(x1, y1, x2, y2, paint);
}
x1 = x2;
y1 = y2;
}
}
}
}
}
In addition, you will need this files:
Road.java
package tvarwebu.projects.map;
public class Road {
public String mName;
public String mDescription;
public int mColor;
public int mWidth;
public double[][] mRoute = new double[][] {};
public Point[] mPoints = new Point[] {};
}
Point.java
package tvarwebu.projects.map;
public class Point {
String mName;
String mDescription;
String mIconUrl;
double mLatitude;
double mLongitude;
}
RoadProvider.java
package tvarwebu.projects.map;
import java.io.IOException;
import java.io.InputStream;
import java.util.Stack;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class RoadProvider {
public static Road getRoute(InputStream is) {
KMLHandler handler = new KMLHandler();
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return handler.mRoad;
}
public static String getUrl(double fromLat, double fromLon, double toLat,
double toLon) {// connect to map web service
StringBuffer urlString = new StringBuffer();
urlString.append("http://maps.google.com/maps?f=d&hl=en");
urlString.append("&saddr=");// from
urlString.append(Double.toString(fromLat));
urlString.append(",");
urlString.append(Double.toString(fromLon));
urlString.append("&daddr=");// to
urlString.append(Double.toString(toLat));
urlString.append(",");
urlString.append(Double.toString(toLon));
urlString.append("&ie=UTF8&0&om=0&output=kml");
String ggg = urlString.toString();
return urlString.toString();
}
}
class KMLHandler extends DefaultHandler {
Road mRoad;
boolean isPlacemark;
boolean isRoute;
boolean isItemIcon;
private Stack mCurrentElement = new Stack();
private String mString;
public KMLHandler() {
mRoad = new Road();
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
mCurrentElement.push(localName);
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = true;
mRoad.mPoints = addPoint(mRoad.mPoints);
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isPlacemark)
isItemIcon = true;
}
mString = new String();
}
public void characters(char[] ch, int start, int length)
throws SAXException {
String chars = new String(ch, start, length).trim();
mString = mString.concat(chars);
}
public void endElement(String uri, String localName, String name) throws SAXException {
if (mString.length() > 0) {
if (localName.equalsIgnoreCase("name")) {
if (isPlacemark) {
isRoute = mString.equalsIgnoreCase("Route");
if (!isRoute) {
mRoad.mPoints[mRoad.mPoints.length - 1].mName = mString;
}
} else {
mRoad.mName = mString;
}
} else if (localName.equalsIgnoreCase("color") && !isPlacemark) {
mRoad.mColor = Integer.parseInt(mString, 16);
} else if (localName.equalsIgnoreCase("width") && !isPlacemark) {
mRoad.mWidth = Integer.parseInt(mString);
} else if (localName.equalsIgnoreCase("description")) {
if (isPlacemark) {
String description = cleanup(mString);
if (!isRoute)
mRoad.mPoints[mRoad.mPoints.length - 1].mDescription = description;
else
mRoad.mDescription = description;
}
} else if (localName.equalsIgnoreCase("href")) {
if (isItemIcon) {
mRoad.mPoints[mRoad.mPoints.length - 1].mIconUrl = mString;
}
} else if (localName.equalsIgnoreCase("coordinates")) {
if (isPlacemark) {
if (!isRoute) {
String[] xyParsed = split(mString, ",");
double lon = Double.parseDouble(xyParsed[0]);
double lat = Double.parseDouble(xyParsed[1]);
mRoad.mPoints[mRoad.mPoints.length - 1].mLatitude = lat;
mRoad.mPoints[mRoad.mPoints.length - 1].mLongitude = lon;
} else {
String[] coodrinatesParsed = split(mString, " ");
int count = 0;
if(mRoad.mRoute.length < 2)
mRoad.mRoute = new double[coodrinatesParsed.length][2];
else {
double[][] mRouteTmp = mRoad.mRoute;
mRoad.mRoute = new double[mRouteTmp.length + coodrinatesParsed.length][2];
//for (int i = 0; i < mRouteTmp.length; i++) {
// mRoad.mRoute[i] = mRouteTmp[i];
// mRoad.mRoute[i][i] = mRouteTmp[i][i];
//}
System.arraycopy(mRouteTmp, 0, mRoad.mRoute, 0, mRouteTmp.length);
count = mRouteTmp.length;
}
for (int i = count; i < (mRoad.mRoute.length); i++) {
String[] xyParsed = split(coodrinatesParsed[i - count], ",");
for (int j = 0; j < 2 && j < xyParsed.length; j++)
mRoad.mRoute[i][j] = Double
.parseDouble(xyParsed[j]);
}
}
}
}
}
mCurrentElement.pop();
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = false;
if (isRoute)
isRoute = false;
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isItemIcon)
isItemIcon = false;
}
}
private String cleanup(String value) {
String remove = "<br/>";
int index = value.indexOf(remove);
if (index != -1)
value = value.substring(0, index);
remove = " ";
index = value.indexOf(remove);
int len = remove.length();
while (index != -1) {
value = value.substring(0, index).concat(
value.substring(index + len, value.length()));
index = value.indexOf(remove);
}
return value;
}
public Point[] addPoint(Point[] mPoints) {
Point[] result = new Point[mPoints.length + 1];
for (int i = 0; i < mPoints.length; i++)
result[i] = mPoints[i];
result[mPoints.length] = new Point();
return result;
}
private static String[] split(String strString, String strDelimiter) {
String[] strArray;
int iOccurrences = 0;
int iIndexOfInnerString = 0;
int iIndexOfDelimiter = 0;
int iCounter = 0;
if (strString == null) {
throw new IllegalArgumentException("Input string cannot be null.");
}
if (strDelimiter.length() <= 0 || strDelimiter == null) {
throw new IllegalArgumentException(
"Delimeter cannot be null or empty.");
}
if (strString.startsWith(strDelimiter)) {
strString = strString.substring(strDelimiter.length());
}
if (!strString.endsWith(strDelimiter)) {
strString += strDelimiter;
}
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
iOccurrences += 1;
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
}
strArray = new String[iOccurrences];
iIndexOfInnerString = 0;
iIndexOfDelimiter = 0;
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
strArray[iCounter] = strString.substring(iIndexOfInnerString,
iIndexOfDelimiter);
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
iCounter += 1;
}
return strArray;
}
}
MyItemizedOverlay.java :
package tvarwebu.projects.map;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class MyItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
private Context mContext;
public MyItemizedOverlay(Drawable defaultMarker, Context context) {
super(boundCenterBottom(defaultMarker));
mContext = context;
}
public void addOverlay(OverlayItem overlay) {
mOverlays.add(overlay);
populate();
}
#Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}
#Override
public int size() {
return mOverlays.size();
}
public void removeLast(){
mOverlays.remove(mOverlays.size()-1);
}
#Override
protected boolean onTap(int index) {
OverlayItem item = mOverlays.get(index);
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setTitle(item.getTitle());
dialog.setMessage(item.getSnippet());
dialog.show();
return true;
}
}
Hope that this article helps you with this problem :) See the comple source code of Drawing route on MapView.
Related
i have a google map problem in android.
i sucess to show map on android. but when i want to show the route direction it getting error.
the weird think is. my code is runing well a week ago. but when i run it today, it getting error. so i try to find new code , but it failed. this is my code.
this is my road class
public class Road {
public String mName;
public String mDescription;
public int mColor;
public int mWidth;
public double[][] mRoute = new double[][] {};
public Point[] mPoints = new Point[] {};}
this is my point class
public class Point {
String mName;
String mDescription;
String mIconUrl;
double mLatitude;
double mLongitude;}
this is my mapoverlay class
public class MapOverlay extends com.google.android.maps.Overlay {
Road mRoad;
ArrayList<GeoPoint> mPoints;
public MapOverlay(Road road, MapView mv) {
mRoad = road;
if (road.mRoute.length > 0) {
mPoints = new ArrayList<GeoPoint>();
for (int i = 0; i < road.mRoute.length; i++) {
mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000),
(int) (road.mRoute[i][0] * 1000000)));
}
int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
.getLatitudeE6()) / 2);
int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
mPoints.size() - 1).getLongitudeE6() - mPoints.get(0)
.getLongitudeE6()) / 2);
GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong);
MapController mapController = mv.getController();
mapController.animateTo(moveTo);
mapController.setZoom(7);
}
}
#Override
public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
super.draw(canvas, mv, shadow);
drawPath(mv, canvas);
return true;
}
public void drawPath(MapView mv, Canvas canvas) {
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
for (int i = 0; i < mPoints.size(); i++) {
Point point = new Point();
mv.getProjection().toPixels(mPoints.get(i), point);
x2 = point.x;
y2 = point.y;
if (i > 0) {
canvas.drawLine(x1, y1, x2, y2, paint);
}
x1 = x2;
y1 = y2;
}
}}
this is my roadprovider class
public class RoadProvider {
public static Road getRoute(InputStream is) {
KMLHandler handler = new KMLHandler();
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return handler.mRoad;
}
public static String getUrl(double fromLat, double fromLon, double toLat,
double toLon) {// connect to map web service
StringBuffer urlString = new StringBuffer();
urlString.append("http://maps.google.com/maps?f=d&hl=en");
urlString.append("&saddr=");// from
urlString.append(Double.toString(fromLat));
urlString.append(",");
urlString.append(Double.toString(fromLon));
urlString.append("&daddr=");// to
urlString.append(Double.toString(toLat));
urlString.append(",");
urlString.append(Double.toString(toLon));
urlString.append("&ie=UTF8&0&om=0&output=kml");
return urlString.toString();
}}
class KMLHandler extends DefaultHandler {
Road mRoad;
boolean isPlacemark;
boolean isRoute;
boolean isItemIcon;
private Stack mCurrentElement = new Stack();
private String mString;
public KMLHandler() {
mRoad = new Road();
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
mCurrentElement.push(localName);
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = true;
mRoad.mPoints = addPoint(mRoad.mPoints);
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isPlacemark)
isItemIcon = true;
}
mString = new String();
}
public void characters(char[] ch, int start, int length)
throws SAXException {
String chars = new String(ch, start, length).trim();
mString = mString.concat(chars);
}
public void endElement(String uri, String localName, String name)
throws SAXException {
if (mString.length() > 0) {
if (localName.equalsIgnoreCase("name")) {
if (isPlacemark) {
isRoute = mString.equalsIgnoreCase("Route");
if (!isRoute) {
mRoad.mPoints[mRoad.mPoints.length - 1].mName = mString;
}
} else {
mRoad.mName = mString;
}
} else if (localName.equalsIgnoreCase("color") && !isPlacemark) {
mRoad.mColor = Integer.parseInt(mString, 16);
} else if (localName.equalsIgnoreCase("width") && !isPlacemark) {
mRoad.mWidth = Integer.parseInt(mString);
} else if (localName.equalsIgnoreCase("description")) {
if (isPlacemark) {
String description = cleanup(mString);
if (!isRoute)
mRoad.mPoints[mRoad.mPoints.length - 1].mDescription = description;
else
mRoad.mDescription = description;
}
} else if (localName.equalsIgnoreCase("href")) {
if (isItemIcon) {
mRoad.mPoints[mRoad.mPoints.length - 1].mIconUrl = mString;
}
} else if (localName.equalsIgnoreCase("coordinates")) {
if (isPlacemark) {
if (!isRoute) {
String[] xyParsed = split(mString, ",");
double lon = Double.parseDouble(xyParsed[0]);
double lat = Double.parseDouble(xyParsed[1]);
mRoad.mPoints[mRoad.mPoints.length - 1].mLatitude = lat;
mRoad.mPoints[mRoad.mPoints.length - 1].mLongitude = lon;
} else {
String[] coodrinatesParsed = split(mString, " ");
int lenNew = coodrinatesParsed.length;
int lenOld = mRoad.mRoute.length;
double[][] temp = new double[lenOld + lenNew][2];
for (int i = 0; i < lenOld; i++) {
temp[i] = mRoad.mRoute[i];
}
for (int i = 0; i < lenNew; i++) {
String[] xyParsed = split(coodrinatesParsed[i], ",");
for (int j = 0; j < 2 && j < xyParsed.length; j++)
temp[lenOld + i][j] = Double
.parseDouble(xyParsed[j]);
}
mRoad.mRoute = temp;
}
}
}
}
mCurrentElement.pop();
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = false;
if (isRoute)
isRoute = false;
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isItemIcon)
isItemIcon = false;
}
}
private String cleanup(String value) {
String remove = "<br/>";
int index = value.indexOf(remove);
if (index != -1)
value = value.substring(0, index);
remove = " ";
index = value.indexOf(remove);
int len = remove.length();
while (index != -1) {
value = value.substring(0, index).concat(
value.substring(index + len, value.length()));
index = value.indexOf(remove);
}
return value;
}
public Point[] addPoint(Point[] points) {
Point[] result = new Point[points.length + 1];
for (int i = 0; i < points.length; i++)
result[i] = points[i];
result[points.length] = new Point();
return result;
}
private static String[] split(String strString, String strDelimiter) {
String[] strArray;
int iOccurrences = 0;
int iIndexOfInnerString = 0;
int iIndexOfDelimiter = 0;
int iCounter = 0;
if (strString == null) {
throw new IllegalArgumentException("Input string cannot be null.");
}
if (strDelimiter.length() <= 0 || strDelimiter == null) {
throw new IllegalArgumentException(
"Delimeter cannot be null or empty.");
}
if (strString.startsWith(strDelimiter)) {
strString = strString.substring(strDelimiter.length());
}
if (!strString.endsWith(strDelimiter)) {
strString += strDelimiter;
}
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
iOccurrences += 1;
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
}
strArray = new String[iOccurrences];
iIndexOfInnerString = 0;
iIndexOfDelimiter = 0;
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
strArray[iCounter] = strString.substring(iIndexOfInnerString,
iIndexOfDelimiter);
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
iCounter += 1;
}
return strArray;
}}
this is main activity
public class GoogleMap233Activity extends MapActivity {
LinearLayout linearLayout;
MapView mapView;
private Road mRoad;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
new Thread() {
#Override
public void run() {
double fromLat = 49.85, fromLon = 24.016667;
double toLat = 50.45, toLon = 30.523333;
String url = RoadProvider
.getUrl(fromLat, fromLon, toLat, toLon);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
Log.i("Road", mRoad.mRoute.length+"");
mHandler.sendEmptyMessage(0);
}
}.start();
}
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
TextView textView = (TextView) findViewById(R.id.description);
textView.setText(mRoad.mName + " " + mRoad.mDescription);
MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
};
};
private InputStream getConnection(String url) {
InputStream is = null;
try {
URLConnection conn = new URL(url).openConnection();
is = conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
this code show an error in class MapOverlay() in drawPath() method in mPoints.size(). this is because mPoints is null. based on mapOverlay()'s constuctor, mPoints null because road.mRoute.length ==0. when i check roadProvider the LOG says it eror on this part
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, handler);
can someone check it for me. thanks alot.
I want to draw a line in a route map. For that I use a code from here http://csie-tw.blogspot.com/2009/06/android-driving-direction-route-path.html . But It not works . It show this kind of error ((((java.lang.RuntimeException: Unable to start activity ComponentInfo{...............}: android.os.NetworkOnMainThreadException)))). My Manifest file is OK. What was the problem ?
THANK YOU for Advice.
Use Below Code for that.
MainActivity.java
public class MainActivity extends MapActivity {
LinearLayout linearLayout;
MapView mapView;
private Road mRoad;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
new Thread() {
#Override
public void run() {
double fromLat = 49.85, fromLon = 24.016667, toLat = 50.45, toLon = 30.523333;
String url = RoadProvider
.getUrl(fromLat, fromLon, toLat, toLon);
InputStream is = getConnection(url);
mRoad = RoadProvider.getRoute(is);
mHandler.sendEmptyMessage(0);
}
}.start();
}
Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
TextView textView = (TextView) findViewById(R.id.description);
textView.setText(mRoad.mName + " " + mRoad.mDescription);
MapOverlay mapOverlay = new MapOverlay(mRoad, mapView);
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
};
};
private InputStream getConnection(String url) {
InputStream is = null;
try {
URLConnection conn = new URL(url).openConnection();
is = conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
class MapOverlay extends com.google.android.maps.Overlay {
Road mRoad;
ArrayList<GeoPoint> mPoints;
public MapOverlay(Road road, MapView mv) {
mRoad = road;
if (road.mRoute.length > 0) {
mPoints = new ArrayList<GeoPoint>();
for (int i = 0; i < road.mRoute.length; i++) {
mPoints.add(new GeoPoint((int) (road.mRoute[i][1] * 1000000),
(int) (road.mRoute[i][0] * 1000000)));
}
int moveToLat = (mPoints.get(0).getLatitudeE6() + (mPoints.get(
mPoints.size() - 1).getLatitudeE6() - mPoints.get(0)
.getLatitudeE6()) / 2);
int moveToLong = (mPoints.get(0).getLongitudeE6() + (mPoints.get(
mPoints.size() - 1).getLongitudeE6() - mPoints.get(0)
.getLongitudeE6()) / 2);
GeoPoint moveTo = new GeoPoint(moveToLat, moveToLong);
MapController mapController = mv.getController();
mapController.animateTo(moveTo);
mapController.setZoom(7);
}
}
#Override
public boolean draw(Canvas canvas, MapView mv, boolean shadow, long when) {
super.draw(canvas, mv, shadow);
drawPath(mv, canvas);
return true;
}
public void drawPath(MapView mv, Canvas canvas) {
int x1 = -1, y1 = -1, x2 = -1, y2 = -1;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
for (int i = 0; i < mPoints.size(); i++) {
Point point = new Point();
mv.getProjection().toPixels(mPoints.get(i), point);
x2 = point.x;
y2 = point.y;
if (i > 0) {
canvas.drawLine(x1, y1, x2, y2, paint);
}
x1 = x2;
y1 = y2;
}
}
}
Add following classes
Point.java
public class Point {
String mName;
String mDescription;
String mIconUrl;
double mLatitude;
double mLongitude;
}
Road.java
public class Road {
public String mName;
public String mDescription;
public int mColor;
public int mWidth;
public double[][] mRoute = new double[][] {};
public Point[] mPoints = new Point[] {};
}
RoadProvider.java
public class RoadProvider {
public static Road getRoute(InputStream is) {
KMLHandler handler = new KMLHandler();
try {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(is, handler);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return handler.mRoad;
}
public static String getUrl(double fromLat, double fromLon, double toLat,
double toLon) {// connect to map web service
StringBuffer urlString = new StringBuffer();
urlString.append("http://maps.google.com/maps?f=d&hl=en");
urlString.append("&saddr=");// from
urlString.append(Double.toString(fromLat));
urlString.append(",");
urlString.append(Double.toString(fromLon));
urlString.append("&daddr=");// to
urlString.append(Double.toString(toLat));
urlString.append(",");
urlString.append(Double.toString(toLon));
urlString.append("&ie=UTF8&0&om=0&output=kml");
return urlString.toString();
}
}
class KMLHandler extends DefaultHandler {
Road mRoad;
boolean isPlacemark;
boolean isRoute;
boolean isItemIcon;
private Stack<String> mCurrentElement = new Stack<String>();
private String mString;
public KMLHandler() {
mRoad = new Road();
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
mCurrentElement.push(localName);
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = true;
mRoad.mPoints = addPoint(mRoad.mPoints);
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isPlacemark)
isItemIcon = true;
}
mString = new String();
}
public void characters(char[] ch, int start, int length)
throws SAXException {
String chars = new String(ch, start, length).trim();
mString = mString.concat(chars);
}
public void endElement(String uri, String localName, String name)
throws SAXException {
if (mString.length() > 0) {
if (localName.equalsIgnoreCase("name")) {
if (isPlacemark) {
isRoute = mString.equalsIgnoreCase("Route");
if (!isRoute) {
mRoad.mPoints[mRoad.mPoints.length - 1].mName = mString;
}
} else {
mRoad.mName = mString;
}
} else if (localName.equalsIgnoreCase("color") && !isPlacemark) {
mRoad.mColor = Integer.parseInt(mString, 16);
} else if (localName.equalsIgnoreCase("width") && !isPlacemark) {
mRoad.mWidth = Integer.parseInt(mString);
} else if (localName.equalsIgnoreCase("description")) {
if (isPlacemark) {
String description = cleanup(mString);
if (!isRoute)
mRoad.mPoints[mRoad.mPoints.length - 1].mDescription = description;
else
mRoad.mDescription = description;
}
} else if (localName.equalsIgnoreCase("href")) {
if (isItemIcon) {
mRoad.mPoints[mRoad.mPoints.length - 1].mIconUrl = mString;
}
} else if (localName.equalsIgnoreCase("coordinates")) {
if (isPlacemark) {
if (!isRoute) {
String[] xyParsed = split(mString, ",");
double lon = Double.parseDouble(xyParsed[0]);
double lat = Double.parseDouble(xyParsed[1]);
mRoad.mPoints[mRoad.mPoints.length - 1].mLatitude = lat;
mRoad.mPoints[mRoad.mPoints.length - 1].mLongitude = lon;
} else {
String[] coodrinatesParsed = split(mString, " ");
int lenNew = coodrinatesParsed.length;
int lenOld = mRoad.mRoute.length;
double[][] temp = new double[lenOld + lenNew][2];
for (int i = 0; i < lenOld; i++) {
temp[i] = mRoad.mRoute[i];
}
for (int i = 0; i < lenNew; i++) {
String[] xyParsed = split(coodrinatesParsed[i], ",");
for (int j = 0; j < 2 && j < xyParsed.length; j++)
temp[lenOld + i][j] = Double
.parseDouble(xyParsed[j]);
}
mRoad.mRoute = temp;
}
}
}
}
mCurrentElement.pop();
if (localName.equalsIgnoreCase("Placemark")) {
isPlacemark = false;
if (isRoute)
isRoute = false;
} else if (localName.equalsIgnoreCase("ItemIcon")) {
if (isItemIcon)
isItemIcon = false;
}
}
private String cleanup(String value) {
String remove = "<br/>";
int index = value.indexOf(remove);
if (index != -1)
value = value.substring(0, index);
remove = " ";
index = value.indexOf(remove);
int len = remove.length();
while (index != -1) {
value = value.substring(0, index).concat(
value.substring(index + len, value.length()));
index = value.indexOf(remove);
}
return value;
}
public Point[] addPoint(Point[] points) {
Point[] result = new Point[points.length + 1];
for (int i = 0; i < points.length; i++)
result[i] = points[i];
result[points.length] = new Point();
return result;
}
private static String[] split(String strString, String strDelimiter) {
String[] strArray;
int iOccurrences = 0;
int iIndexOfInnerString = 0;
int iIndexOfDelimiter = 0;
int iCounter = 0;
if (strString == null) {
throw new IllegalArgumentException("Input string cannot be null.");
}
if (strDelimiter.length() <= 0 || strDelimiter == null) {
throw new IllegalArgumentException(
"Delimeter cannot be null or empty.");
}
if (strString.startsWith(strDelimiter)) {
strString = strString.substring(strDelimiter.length());
}
if (!strString.endsWith(strDelimiter)) {
strString += strDelimiter;
}
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
iOccurrences += 1;
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
}
strArray = new String[iOccurrences];
iIndexOfInnerString = 0;
iIndexOfDelimiter = 0;
while ((iIndexOfDelimiter = strString.indexOf(strDelimiter,
iIndexOfInnerString)) != -1) {
strArray[iCounter] = strString.substring(iIndexOfInnerString,
iIndexOfDelimiter);
iIndexOfInnerString = iIndexOfDelimiter + strDelimiter.length();
iCounter += 1;
}
return strArray;
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/description"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<com.google.android.maps.MapView
android:id="#+id/mapview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:apiKey="Your API Key"
android:clickable="true" />
</LinearLayout>
Add below permissions into your android manifest file.
<uses-permission android:name="android.permission.INTERNET"/>
How to draw route path on MapView Google API. I have two ordinates. Please tell options to draw path between these two points
REFER THIS LINK
SharedData.java
package com.agarwal.route;
public class SharedData {
// this is a singleton class that provides a global data share for all of the
// activities and services in the MDWrapper application
private static SharedData instance = null;
private SharedData() {
//randomizeServers();
}
// data to be shared
private String APIKEY = "";
private double src_lat = -1;
private double src_lng = -1;
private double dest_lat = -1;
private double dest_lng = -1;
/**
* #return the aPIKEY
*/
public String getAPIKEY() {
return APIKEY;
}
/**
* #param aPIKEY the aPIKEY to set
*/
public void setAPIKEY(String aPIKEY) {
APIKEY = aPIKEY;
}
/**
* #return the src_lat
*/
public double getSrc_lat() {
return src_lat;
}
/**
* #param src_lat the src_lat to set
*/
public void setSrc_lat(double src_lat) {
this.src_lat = src_lat;
}
/**
* #return the src_lng
*/
public double getSrc_lng() {
return src_lng;
}
/**
* #param src_lng the src_lng to set
*/
public void setSrc_lng(double src_lng) {
this.src_lng = src_lng;
}
/**
* #return the dest_lat
*/
public double getDest_lat() {
return dest_lat;
}
/**
* #param dest_lat the dest_lat to set
*/
public void setDest_lat(double dest_lat) {
this.dest_lat = dest_lat;
}
/**
* #return the dest_lng
*/
public double getDest_lng() {
return dest_lng;
}
/**
* #param dest_lng the dest_lng to set
*/
public void setDest_lng(double dest_lng) {
this.dest_lng = dest_lng;
}
public static SharedData getInstance() {
if (null == instance) {
instance = new SharedData();
}
return instance;
}
}
CustomItemizedOverlay.java
package com.agarwal.route;
import java.util.ArrayList;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private final ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
public CustomItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
#Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
#Override
public int size() {
return mapOverlays.size();
}
public void addOverlay(OverlayItem overlay) {
mapOverlays.add(overlay);
this.populate();
}
}
MyOverLay.java
package com.agarwal.route;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
public class MyOverLay extends Overlay
{
private GeoPoint gp1;
private GeoPoint gp2;
private int mode=0;
private int defaultColor;
Context mContext;
public MyOverLay(Context context,GeoPoint gp1,GeoPoint gp2,int mode) // GeoPoint is a int. (6E)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.mContext = context;
defaultColor = 999; // no defaultColor
}
public MyOverLay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;
}
public int getMode()
{
return mode;
}
#Override
public boolean draw
(Canvas canvas, MapView mapView, boolean shadow, long when)
{
Projection projection = mapView.getProjection();
if (shadow == false)
{
Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(gp1, point);
// mode=1:start
if(mode==1)
{
if(defaultColor==999)
paint.setColor(Color.BLUE);
else
paint.setColor(defaultColor);
// start point
}
// mode=2:path
else if(mode==2)
{
if(defaultColor==999)
paint.setColor(Color.RED);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
/* mode=3:end */
else if(mode==3)
{
/* the last path */
if(defaultColor==999)
paint.setColor(Color.GREEN);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
/* end point */
}
}
return super.draw(canvas, mapView, shadow, when);
}
}
RoutePath.java
package com.agarwal.route;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class RoutePath extends MapActivity {
/** Called when the activity is first created. */
MapView mapView;
private RoutePath _activity;
GeoPoint srcGeoPoint,destGeoPoint;
private static List<Overlay> mOverlays;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedData data = SharedData.getInstance();
mapView = new MapView(this,data.getAPIKEY());
mapView.setClickable(true);
setContentView(mapView);
_activity = this;
double src_lat = data.getSrc_lat();
double src_long = data.getSrc_lng();
double dest_lat = data.getDest_lat();
double dest_long = data.getDest_lng();
if(src_lat == -1 || src_long == -1 || dest_lat == -1 || dest_long == -1){
showAlert("Please enter source and destination points");
}else{
srcGeoPoint = new GeoPoint((int) (src_lat * 1E6),(int) (src_long * 1E6));
destGeoPoint = new GeoPoint((int) (dest_lat * 1E6),(int) (dest_long * 1E6));
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable srcdrawable = this.getResources().getDrawable(R.drawable.pin_green);
CustomItemizedOverlay srcitemizedOverlay = new CustomItemizedOverlay(srcdrawable);
//CustomItemizedOverlay srcitemizedOverlay = new CustomItemizedOverlay(getDrawable("com/agarwal/route/pin_green.png"));
OverlayItem srcoverlayitem = new OverlayItem(srcGeoPoint, "Hello!", "This is your Location.");
Drawable destdrawable = this.getResources().getDrawable(R.drawable.pin_red);
CustomItemizedOverlay destitemizedOverlay = new CustomItemizedOverlay( destdrawable );
// CustomItemizedOverlay destitemizedOverlay = new CustomItemizedOverlay(getDrawable("com/agarwal/route/pin_red.png"));
OverlayItem destoverlayitem = new OverlayItem(destGeoPoint, "Hello!", "This is dest Location.");
srcitemizedOverlay.addOverlay(srcoverlayitem);
destitemizedOverlay.addOverlay(destoverlayitem);
mapOverlays.add(srcitemizedOverlay);
mapOverlays.add(destitemizedOverlay);
connectAsyncTask _connectAsyncTask = new connectAsyncTask();
_connectAsyncTask.execute();
mapView.setBuiltInZoomControls(true);
mapView.displayZoomControls(true);
mOverlays = mapView.getOverlays();
mapView.getController().animateTo(srcGeoPoint);
mapView.getController().setZoom(12);
}
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
private class connectAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(_activity);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
fetchData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(doc!=null){
Overlay ol = new MyOverLay(_activity,srcGeoPoint,srcGeoPoint,1);
mOverlays.add(ol);
NodeList _nodelist = doc.getElementsByTagName("status");
Node node1 = _nodelist.item(0);
String _status1 = node1.getChildNodes().item(0).getNodeValue();
if(_status1.equalsIgnoreCase("OK")){
NodeList _nodelist_path = doc.getElementsByTagName("overview_polyline");
Node node_path = _nodelist_path.item(0);
Element _status_path = (Element)node_path;
NodeList _nodelist_destination_path = _status_path.getElementsByTagName("points");
Node _nodelist_dest = _nodelist_destination_path.item(0);
String _path = _nodelist_dest.getChildNodes().item(0).getNodeValue();
List<GeoPoint> _geopoints = decodePoly(_path);
GeoPoint gp1;
GeoPoint gp2;
gp2 = _geopoints.get(0);
Log.d("_geopoints","::"+_geopoints.size());
for(int i=1;i<_geopoints.size();i++) // the last one would be crash
{
gp1 = gp2;
gp2 = _geopoints.get(i);
Overlay ol1 = new MyOverLay(gp1,gp2,2,Color.BLUE);
mOverlays.add(ol1);
}
Overlay ol2 = new MyOverLay(_activity,destGeoPoint,destGeoPoint,3);
mOverlays.add(ol2);
progressDialog.dismiss();
}else{
showAlert("Unable to find the route");
}
Overlay ol2 = new MyOverLay(_activity,destGeoPoint,destGeoPoint,3);
mOverlays.add(ol2);
progressDialog.dismiss();
mapView.scrollBy(-1,-1);
mapView.scrollBy(1,1);
}else{
showAlert("Unable to find the route");
}
}
}
Document doc = null;
private void fetchData()
{
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps/api/directions/xml?origin=");
urlString.append( Double.toString((double)srcGeoPoint.getLatitudeE6()/1.0E6 ));
urlString.append(",");
urlString.append( Double.toString((double)srcGeoPoint.getLongitudeE6()/1.0E6 ));
urlString.append("&destination=");//to
urlString.append( Double.toString((double)destGeoPoint.getLatitudeE6()/1.0E6 ));
urlString.append(",");
urlString.append( Double.toString((double)destGeoPoint.getLongitudeE6()/1.0E6 ));
urlString.append("&sensor=true&mode=driving");
Log.d("url","::"+urlString.toString());
HttpURLConnection urlConnection= null;
URL url = null;
try
{
url = new URL(urlString.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = (Document) db.parse(urlConnection.getInputStream());//Util.XMLfromString(response);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}catch (ParserConfigurationException e){
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private List<GeoPoint> decodePoly(String encoded) {
List<GeoPoint> poly = new ArrayList<GeoPoint>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
(int) (((double) lng / 1E5) * 1E6));
poly.add(p);
}
return poly;
}
private void showAlert(String message){
AlertDialog.Builder alert = new AlertDialog.Builder(_activity);
alert.setTitle("Error");
alert.setCancelable(false);
alert.setMessage(message);
alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
alert.show();
}
private Drawable getDrawable(String fileName){
return Drawable.createFromStream(_activity.getClass().getClassLoader().getResourceAsStream(fileName), "pin");
}
}
In Your Activity Just Paste the below few lines to draw routemap:
SharedData data = SharedData.getInstance();
data.setAPIKEY("0RUTLH7cqd6yrZ0FdS0NfQMO3lioiCbnH-BpNQQ");
data.setSrc_lat(17);
data.setSrc_lng(78);
data.setDest_lat(18);
data.setDest_lng(77);
startActivity(new Intent(YourActivity.this,RoutePath.class));
Note:: Need to RoutePath activity and permssions in your manifeast file
You can refer link Android Driving Direction.
Full description is given there with source that you can download from source link 1 or source link 2
Hi I'm using the code from below link to draw route between two points in map.
http://code.google.com/p/j2memaprouteprovider/source/browse/#svn/trunk/J2MEMapRouteAndroidEx/src/org/ci/geo/route
Also I'm using timer to update locations dynamically every 30 seconds. It works good. But the application freezes after 20 seconds. After the route is drawn between 2 points app becomes slow while zooming in or zooming out the map.
Is there any other efficient way to draw route between 2 points or in Async task??
Any help Appreciated.
Refer this LINK
SharedData.java
package com.agarwal.route;
public class SharedData {
// this is a singleton class that provides a global data share for all of the
// activities and services in the MDWrapper application
private static SharedData instance = null;
private SharedData() {
//randomizeServers();
}
// data to be shared
private String APIKEY = "";
private double src_lat = -1;
private double src_lng = -1;
private double dest_lat = -1;
private double dest_lng = -1;
/**
* #return the aPIKEY
*/
public String getAPIKEY() {
return APIKEY;
}
/**
* #param aPIKEY the aPIKEY to set
*/
public void setAPIKEY(String aPIKEY) {
APIKEY = aPIKEY;
}
/**
* #return the src_lat
*/
public double getSrc_lat() {
return src_lat;
}
/**
* #param src_lat the src_lat to set
*/
public void setSrc_lat(double src_lat) {
this.src_lat = src_lat;
}
/**
* #return the src_lng
*/
public double getSrc_lng() {
return src_lng;
}
/**
* #param src_lng the src_lng to set
*/
public void setSrc_lng(double src_lng) {
this.src_lng = src_lng;
}
/**
* #return the dest_lat
*/
public double getDest_lat() {
return dest_lat;
}
/**
* #param dest_lat the dest_lat to set
*/
public void setDest_lat(double dest_lat) {
this.dest_lat = dest_lat;
}
/**
* #return the dest_lng
*/
public double getDest_lng() {
return dest_lng;
}
/**
* #param dest_lng the dest_lng to set
*/
public void setDest_lng(double dest_lng) {
this.dest_lng = dest_lng;
}
public static SharedData getInstance() {
if (null == instance) {
instance = new SharedData();
}
return instance;
}
}
CustomItemizedOverlay.java
package com.agarwal.route;
import java.util.ArrayList;
import android.graphics.drawable.Drawable;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;
public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem> {
private final ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
public CustomItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}
#Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
#Override
public int size() {
return mapOverlays.size();
}
public void addOverlay(OverlayItem overlay) {
mapOverlays.add(overlay);
this.populate();
}
}
MyOverLay.java
package com.agarwal.route;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.Projection;
public class MyOverLay extends Overlay
{
private GeoPoint gp1;
private GeoPoint gp2;
private int mode=0;
private int defaultColor;
Context mContext;
public MyOverLay(Context context,GeoPoint gp1,GeoPoint gp2,int mode) // GeoPoint is a int. (6E)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.mContext = context;
defaultColor = 999; // no defaultColor
}
public MyOverLay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;
}
public int getMode()
{
return mode;
}
#Override
public boolean draw
(Canvas canvas, MapView mapView, boolean shadow, long when)
{
Projection projection = mapView.getProjection();
if (shadow == false)
{
Paint paint = new Paint();
paint.setAntiAlias(true);
Point point = new Point();
projection.toPixels(gp1, point);
// mode=1:start
if(mode==1)
{
if(defaultColor==999)
paint.setColor(Color.BLUE);
else
paint.setColor(defaultColor);
// start point
}
// mode=2:path
else if(mode==2)
{
if(defaultColor==999)
paint.setColor(Color.RED);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
/* mode=3:end */
else if(mode==3)
{
/* the last path */
if(defaultColor==999)
paint.setColor(Color.GREEN);
else
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
/* end point */
}
}
return super.draw(canvas, mapView, shadow, when);
}
}
RoutePath.java
package com.agarwal.route;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
public class RoutePath extends MapActivity {
/** Called when the activity is first created. */
MapView mapView;
private RoutePath _activity;
GeoPoint srcGeoPoint,destGeoPoint;
private static List<Overlay> mOverlays;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedData data = SharedData.getInstance();
mapView = new MapView(this,data.getAPIKEY());
mapView.setClickable(true);
setContentView(mapView);
_activity = this;
double src_lat = data.getSrc_lat();
double src_long = data.getSrc_lng();
double dest_lat = data.getDest_lat();
double dest_long = data.getDest_lng();
if(src_lat == -1 || src_long == -1 || dest_lat == -1 || dest_long == -1){
showAlert("Please enter source and destination points");
}else{
srcGeoPoint = new GeoPoint((int) (src_lat * 1E6),(int) (src_long * 1E6));
destGeoPoint = new GeoPoint((int) (dest_lat * 1E6),(int) (dest_long * 1E6));
List<Overlay> mapOverlays = mapView.getOverlays();
Drawable srcdrawable = this.getResources().getDrawable(R.drawable.pin_green);
//CustomItemizedOverlay srcitemizedOverlay = new CustomItemizedOverlay(getDrawable("com/agarwal/route/pin_green.png"));
OverlayItem srcoverlayitem = new OverlayItem(srcGeoPoint, "Hello!", "This is your Location.");
Drawable destdrawable = this.getResources().getDrawable(R.drawable.pin_red);
// CustomItemizedOverlay destitemizedOverlay = new CustomItemizedOverlay(getDrawable("com/agarwal/route/pin_red.png"));
OverlayItem destoverlayitem = new OverlayItem(destGeoPoint, "Hello!", "This is dest Location.");
srcitemizedOverlay.addOverlay(srcoverlayitem);
destitemizedOverlay.addOverlay(destoverlayitem);
mapOverlays.add(srcitemizedOverlay);
mapOverlays.add(destitemizedOverlay);
connectAsyncTask _connectAsyncTask = new connectAsyncTask();
_connectAsyncTask.execute();
mapView.setBuiltInZoomControls(true);
mapView.displayZoomControls(true);
mOverlays = mapView.getOverlays();
mapView.getController().animateTo(srcGeoPoint);
mapView.getController().setZoom(12);
}
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
private class connectAsyncTask extends AsyncTask<Void, Void, Void>{
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
progressDialog = new ProgressDialog(_activity);
progressDialog.setMessage("Fetching route, Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
fetchData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(doc!=null){
Overlay ol = new MyOverLay(_activity,srcGeoPoint,srcGeoPoint,1);
mOverlays.add(ol);
NodeList _nodelist = doc.getElementsByTagName("status");
Node node1 = _nodelist.item(0);
String _status1 = node1.getChildNodes().item(0).getNodeValue();
if(_status1.equalsIgnoreCase("OK")){
NodeList _nodelist_path = doc.getElementsByTagName("overview_polyline");
Node node_path = _nodelist_path.item(0);
Element _status_path = (Element)node_path;
NodeList _nodelist_destination_path = _status_path.getElementsByTagName("points");
Node _nodelist_dest = _nodelist_destination_path.item(0);
String _path = _nodelist_dest.getChildNodes().item(0).getNodeValue();
List<GeoPoint> _geopoints = decodePoly(_path);
GeoPoint gp1;
GeoPoint gp2;
gp2 = _geopoints.get(0);
Log.d("_geopoints","::"+_geopoints.size());
for(int i=1;i<_geopoints.size();i++) // the last one would be crash
{
gp1 = gp2;
gp2 = _geopoints.get(i);
Overlay ol1 = new MyOverLay(gp1,gp2,2,Color.BLUE);
mOverlays.add(ol1);
}
Overlay ol2 = new MyOverLay(_activity,destGeoPoint,destGeoPoint,3);
mOverlays.add(ol2);
progressDialog.dismiss();
}else{
showAlert("Unable to find the route");
}
Overlay ol2 = new MyOverLay(_activity,destGeoPoint,destGeoPoint,3);
mOverlays.add(ol2);
progressDialog.dismiss();
mapView.scrollBy(-1,-1);
mapView.scrollBy(1,1);
}else{
showAlert("Unable to find the route");
}
}
}
Document doc = null;
private void fetchData()
{
StringBuilder urlString = new StringBuilder();
urlString.append("http://maps.google.com/maps/api/directions/xml?origin=");
urlString.append( Double.toString((double)srcGeoPoint.getLatitudeE6()/1.0E6 ));
urlString.append(",");
urlString.append( Double.toString((double)srcGeoPoint.getLongitudeE6()/1.0E6 ));
urlString.append("&destination=");//to
urlString.append( Double.toString((double)destGeoPoint.getLatitudeE6()/1.0E6 ));
urlString.append(",");
urlString.append( Double.toString((double)destGeoPoint.getLongitudeE6()/1.0E6 ));
urlString.append("&sensor=true&mode=driving");
Log.d("url","::"+urlString.toString());
HttpURLConnection urlConnection= null;
URL url = null;
try
{
url = new URL(urlString.toString());
urlConnection=(HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.connect();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
doc = (Document) db.parse(urlConnection.getInputStream());//Util.XMLfromString(response);
}catch (MalformedURLException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}catch (ParserConfigurationException e){
e.printStackTrace();
}
catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private List<GeoPoint> decodePoly(String encoded) {
List<GeoPoint> poly = new ArrayList<GeoPoint>();
int index = 0, len = encoded.length();
int lat = 0, lng = 0;
while (index < len) {
int b, shift = 0, result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lat += dlat;
shift = 0;
result = 0;
do {
b = encoded.charAt(index++) - 63;
result |= (b & 0x1f) << shift;
shift += 5;
} while (b >= 0x20);
int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
lng += dlng;
GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
(int) (((double) lng / 1E5) * 1E6));
poly.add(p);
}
return poly;
}
private void showAlert(String message){
AlertDialog.Builder alert = new AlertDialog.Builder(_activity);
alert.setTitle("Error");
alert.setCancelable(false);
alert.setMessage(message);
alert.setPositiveButton("Ok",new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
});
alert.show();
}
private Drawable getDrawable(String fileName){
return Drawable.createFromStream(_activity.getClass().getClassLoader().getResourceAsStream(fileName), "pin");
}
}
In Your Activity Just Paste the below few lines to draw routemap:
SharedData data = SharedData.getInstance();
data.setAPIKEY("0RUTLH7cqd6yrZ0FdS0NfQMO3lioiCbnH-BpNQQ");
data.setSrc_lat(17);
data.setSrc_lng(78);
data.setDest_lat(18);
data.setDest_lng(77);
startActivity(new Intent(YourActivity.this,RoutePath.class));
Note:: Need to RoutePath activity and permssions in your manifeast file
How do I get points & draw the route on Google maps in Android OS?
An example URL you're going to parse is...
http://maps.googleapis.com/maps/api/directions/xml?origin=52.31,16.71&destination=51.27,6.75&sensor=false
change origin [lat,long] and destination[lat, long] for your purpose
--
points fetching
import java.io.StringReader;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import net.gynsoft.citydusseldorf.lib.HttpClient;
import android.os.Handler;
import com.google.android.maps.GeoPoint;
public class MapRoute
{
private GeoPoint gpSrc = null;
private GeoPoint gpDest = null;
private ArrayList<GeoPoint> alRoute = new ArrayList<GeoPoint>();
private Handler haRoute = new Handler();
public interface RouteListener
{
public void onDetermined(ArrayList<GeoPoint> alPoint);
public void onError();
}
private RouteListener oRoute = null;
public MapRoute(GeoPoint gpSrc,GeoPoint gpDest)
{
this.gpSrc = gpSrc;
this.gpDest = gpDest;
}
public void getPoints(RouteListener oRoute)
{
this.oRoute = oRoute;
new Thread(ruFetch).start();
}
private Runnable ruFetchOk = new Runnable()
{
public void run()
{
oRoute.onDetermined(alRoute);
}
};
private Runnable ruFetchError = new Runnable()
{
public void run()
{
oRoute.onDetermined(alRoute);
}
};
private Runnable ruFetch = new Runnable()
{
public void run()
{
String szUrl = "http://maps.googleapis.com/maps/api/directions/xml";
szUrl += "?origin=" + (gpSrc.getLatitudeE6()/1e6) + "," + (gpSrc.getLongitudeE6()/1e6);
szUrl += "&destination=" + (gpDest.getLatitudeE6()/1e6) + "," + (gpDest.getLongitudeE6()/1e6);
szUrl += "&sensor=true";
HttpClient oHttp = HttpClient.getInstance();
String szXml = oHttp.doGet(szUrl,"");
try
{
XmlPullParserFactory xppfFactory = XmlPullParserFactory.newInstance();
xppfFactory.setNamespaceAware(true);
XmlPullParser xppParses = xppfFactory.newPullParser();
xppParses.setInput(new StringReader(szXml));
int iEventType = xppParses.getEventType();
String szTag = "";
String szText = "";
boolean bStep = false;
int iLat = 0;
int iLong = 0;
while(iEventType != XmlPullParser.END_DOCUMENT)
{
iEventType = xppParses.next();
if(iEventType == XmlPullParser.START_TAG)
{
szTag = xppParses.getName();
if(szTag.equals("step"))
bStep = true;
}
else if(iEventType == XmlPullParser.TEXT)
{
if(szTag.equals("points"))
szText = "";
else
szText = xppParses.getText().trim();
}
else if(iEventType == XmlPullParser.END_TAG)
{
if(xppParses.getName().equals("step"))
{
bStep = false;
}
else if(bStep && xppParses.getName().equals("start_location") || xppParses.getName().equals("end_location"))
{
GeoPoint gpPoint = new GeoPoint(iLat,iLong);
alRoute.add(gpPoint);
}
else if(bStep && xppParses.getName().equals("lat"))
{
iLat = (int)(Double.parseDouble(szText) * 1e6);
}
else if(bStep && xppParses.getName().equals("lng"))
{
iLong = (int)(Double.parseDouble(szText) * 1e6);
}
}
}
}
catch(Exception e)
{
e.printStackTrace();
haRoute.post(ruFetchError);
}
if(alRoute.size() == 0)
haRoute.post(ruFetchError);
else
haRoute.post(ruFetchOk);
}
};
}
--
map overlay
public class MapRouteOverlay extends Overlay
{
private GeoPoint gp1;
private GeoPoint gp2;
private int mode=0;
private int defaultColor;
public MapRouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode) // GeoPoint is a int. (6E)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
defaultColor = 999; // no defaultColor
}
public MapRouteOverlay(GeoPoint gp1,GeoPoint gp2,int mode, int defaultColor)
{
this.gp1 = gp1;
this.gp2 = gp2;
this.mode = mode;
this.defaultColor = defaultColor;
}
public int getMode()
{
return mode;
}
public boolean draw (Canvas canvas, MapView mapView, boolean shadow, long when)
{
Projection projection = mapView.getProjection();
if (shadow == false)
{
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
Point point = new Point();
projection.toPixels(gp1, point);
if(mode==2)
{
if(defaultColor==999)
{
paint.setColor(Color.RED);
}
else
{
paint.setColor(defaultColor);
Point point2 = new Point();
projection.toPixels(gp2, point2);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(point.x, point.y, point2.x,point2.y, paint);
}
}
}
return super.draw(canvas, mapView, shadow, when);
}
}
--
how to use it... somewhere in my activity
dEmpty = new BitmapDrawable(Bitmap.createBitmap(1,1,Bitmap.Config.ARGB_8888));
dPin = getResources().getDrawable(R.drawable.pin_map);
private void doDrawPath(GeoPoint gpSrc,GeoPoint gpDest)
{
MapRoute oRoute = new MapRoute(gpSrc,gpDest);
oRoute.getPoints(new RouteListener()
{
#Override
public void onDetermined(ArrayList<GeoPoint> alPoint)
{
GeoPoint oPointA = null;
GeoPoint oPointB = null;
mvMap.getOverlays().clear();
for(int i=1; i<alPoint.size()-1; i++)
{
oPointA = alPoint.get(i-1);
oPointB = alPoint.get(i);
mvMap.getOverlays().add(new MapRouteOverlay(oPointA,oPointB,2,Color.RED));
}
mvMap.getOverlays().add(new MapRoutePinOverlay(alPoint.get(0),dPin));
mvMap.getOverlays().add(new MapRoutePinOverlay(alPoint.get(alPoint.size()-1),dPin));
mvMap.invalidate();
}
#Override
public void onError()
{
}
});
}