So I have my mapview set up, and everything runs, but the overlays don't show up on the map. Any suggestions or help at all would be greatly appreciated.
My MapActivity extension class is the following:
public class trailInformation extends MapActivity {
public String trailName = "";
public loadMapDataTask mapTask = new loadMapDataTask();
public myObject inp = new myObject();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.trail_info_layout);
// General variable declarations
Intent intent = getIntent();
trailName = intent.getStringExtra(trailsActivity.EXTRA_MESSAGE);
// Sets map to satellite
final MapView map = (MapView) findViewById(R.id.infoMapView);
map.setSatellite(true);
// Setup map input
inp.setID(R.raw.nordhoff_peak_loop);
inp.setName("mapfile");
inp.setMap(map);
// Display Trail Name
Typeface font = Typeface.createFromAsset(getAssets(), "arial.ttf");
TextView trailNameTV = (TextView) findViewById(R.id.infoTitle);
trailNameTV.setText(trailName);
trailNameTV.setTypeface(font);
Display display = getWindowManager().getDefaultDisplay();
trailNameTV.setTextSize(findTextSize(trailNameTV, trailName,
GalleryPageActivity.getDisplaySize(display).x, font));
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
mapTask.execute(inp);
}
public class loadMapDataTask extends AsyncTask<myObject, Void, File> {
#Override
protected File doInBackground(myObject... params) {
File file = getApplicationContext().getFileStreamPath(
params[0].getName());
if (file.exists()) {
return file;
}
InputStream is;
FileOutputStream fos;
try {
is = getResources().openRawResource(params[0].getID());
byte[] buffer = new byte[is.available()];
is.read(buffer);
fos = openFileOutput(params[0].getName(), MODE_PRIVATE);
fos.write(buffer);
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
List<Location> gpsPoints = XMLParser.getPoints(file);
int i = 0;
int index = 0;
GeoPoint[] geoPoints = new GeoPoint[gpsPoints.size()];
ListIterator<Location> it = gpsPoints.listIterator();
while (it.hasNext()) {
index = it.nextIndex();
Location loc = gpsPoints.get(index);
geoPoints[i] = new GeoPoint((int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
it.next();
Log.i("DEBUG", "" + geoPoints[i]);
}
if (geoPoints.length > 1) {
mapOverlay[] overlays = new mapOverlay[(geoPoints.length - 1)];
MapController mc = params[0].getMap().getController();
mc.animateTo(geoPoints[0]);
mc.setZoom(17);
for (int z = 0; z < overlays.length; z++) {
List<Overlay> mapOverlays;
mapOverlays = params[0].getMap().getOverlays();
mapOverlays.add(overlays[z]);
}
} else {
Log.i("DEBUG", "Not drawing lines because " + geoPoints.length
+ " points exist in geopoints array.");
}
return file;
}
#Override
protected void onPostExecute(File result) {
Log.i("DEBUG", "Task executed");
}
}
public static String readRawTextFile(Context ctx, int resId) {
InputStream inputStream = ctx.getResources().openRawResource(resId);
InputStreamReader inputreader = new InputStreamReader(inputStream);
BufferedReader buffreader = new BufferedReader(inputreader);
String line;
StringBuilder text = new StringBuilder();
try {
while ((line = buffreader.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException e) {
return null;
}
return text.toString();
}
public float findTextSize(TextView tV, String text, float Width,
Typeface font) {
float textSize = 100;
float scaledPx = 0;
float densityMultiplier = getBaseContext().getResources()
.getDisplayMetrics().density;
TextPaint paint = tV.getPaint();
paint.setTypeface(font);
while (textSize > 20) {
scaledPx = textSize * densityMultiplier;
paint.setTextSize(scaledPx);
if (paint.measureText(text) < Width) {
return textSize;
} else {
textSize--;
}
}
return 0;
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
And my mapOverlay class is the following:
public class mapOverlay extends Overlay {
private Projection projection;
public mapOverlay(MapView map) {
super();
projection = map.getProjection();
}
public void draw(Canvas canvas, MapView mapv, boolean shadow, GeoPoint gp1,
GeoPoint gp2) {
super.draw(canvas, mapv, shadow);
// Configuring the paint brush
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(Color.RED);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path1.moveTo(p1.x, p1.y);
path1.lineTo(p2.x, p2.y);
canvas.drawPath(path1, mPaint);
}
}
I think I might just be missing something about MapView, and there also might be a problem with my Asynctask since it's my first time using it, but I don't think there is.
Related
I'm doing an app for directions on Google map. But when i run the app I have a problem 11-23 09:39:16.111: E/MapActivity(572): Couldn't get connection factory client and it doesn't show/draw des and source on Map. Can you help me!
source code
Main:
public class MainActivity extends MapActivity {
private MapView mapView;
#Override
protected boolean isRouteDisplayed() { return false; }
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView)findViewById(R.id.mapview);
//Example data
double latitudeFrom = 50.06469036372934;
double longitudeFrom = 19.944788217544556;
double latitudeTo = 50.06400165088368;
double longitudeTo = 19.920390844345093;
GeoPoint srcGeoPoint =
new GeoPoint((int)(latitudeFrom * 1E6), (int)(longitudeFrom * 1E6));
GeoPoint destGeoPoint =
new GeoPoint((int)(latitudeTo * 1E6), (int)(longitudeTo * 1E6));
drawPath(srcGeoPoint, destGeoPoint, mapView);
mapView.getController().animateTo(srcGeoPoint);
mapView.getController().setZoom(15);
}
private void drawPath(GeoPoint src, GeoPoint dest, MapView mapView) {
String strUrl = "http://maps.google.com/maps?f=d&hl=en";
//From
strUrl += "saddr=" +
(src.getLatitudeE6()/1.0E6) +
"," +
(src.getLongitudeE6()/1.0E6);
//To
strUrl += "&daddr=" +
(dest.getLatitudeE6()/1.0E6) +
"," +
(dest.getLongitudeE6()/1.0E6);
//Walk attribute (for walk path)
strUrl += "&dirflg=w";
//File format
strUrl += "&output=kml";
try {
//Parse KML
URL url = new URL(strUrl.toString());
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
SAXParser parser = saxFactory.newSAXParser();
XMLReader reader = parser.getXMLReader();
KMLHandler kmlHandler = new KMLHandler();
reader.setContentHandler(kmlHandler);
InputSource inputSource = new InputSource(url.openStream());
reader.parse(inputSource);
String path = kmlHandler.getPathCoordinates();
//Draw path
if(path != null) {
RouteOverlay routeOverlay = new RouteOverlay();
String pairs[] = path.split(" ");
for (String pair : pairs) {
String coordinates[] = pair.split(",");
GeoPoint geoPoint = new GeoPoint(
(int) (Double.parseDouble(coordinates[1]) * 1E6),
(int) (Double.parseDouble(coordinates[0]) * 1E6));
routeOverlay.addGeoPoint(geoPoint);
}
mapView.getOverlays().add(routeOverlay);
}
} catch (Exception e) {
Log.w("RoutePath", e.toString());
}
}
}
KMLHandler:
public class KMLHandler extends DefaultHandler {
private boolean inGeometryCollection = false;
private boolean inCoordinates = false;
private String pathCoordinates;
public String getPathCoordinates() { return pathCoordinates; }
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
if(inGeometryCollection && inCoordinates)
pathCoordinates = new String(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equals("GeometryCollection")) inGeometryCollection = false;
else if (localName.equals("coordinates")) inCoordinates = false;
}
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName.equals("GeometryCollection")) inGeometryCollection = true;
else if (localName.equals("coordinates")) inCoordinates = true;
}
}
RouteOverlay:
public class RouteOverlay extends Overlay {
private ArrayList<GeoPoint> geoPoints;
private int mRadius = 5;
public RouteOverlay() {
geoPoints = new ArrayList<GeoPoint>();
}
public void addGeoPoint(GeoPoint gp) {
geoPoints.add(gp);
}
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
if (shadow == false) {
Projection projection = mapView.getProjection();
Paint paint = new Paint();
paint.setAntiAlias(true);
GeoPoint geoPointFrom = null;
GeoPoint geoPointTo = null;
Point pointFrom = new Point();
Point pointTo = new Point();
//Route
for (GeoPoint geoPoint : geoPoints) {
if(geoPointFrom != null) {
geoPointTo = geoPoint;
projection.toPixels(geoPointFrom, pointFrom);
projection.toPixels(geoPointTo, pointTo);
paint.setColor(Color.GREEN);
paint.setStrokeWidth(5);
paint.setAlpha(120);
canvas.drawLine(pointFrom.x, pointFrom.y,
pointTo.x, pointTo.y,
paint);
geoPointFrom = geoPointTo;
} else {
geoPointFrom = geoPoint;
}
}
//Start point
paint.setColor(Color.BLUE);
projection.toPixels(geoPoints.get(0), pointFrom);
RectF ovalStart = new RectF(pointFrom.x - mRadius,
pointFrom.y - mRadius,
pointFrom.x + mRadius,
pointFrom.y + mRadius);
canvas.drawOval(ovalStart, paint);
//Stop point
paint.setColor(Color.RED);
RectF ovalStop = new RectF(pointTo.x - mRadius,
pointTo.y - mRadius,
pointTo.x + mRadius,
pointTo.y + mRadius);
canvas.drawOval(ovalStop, paint);
}
return super.draw(canvas, mapView, shadow, when);
}
}
I think you still need ItemizedOverlay as this is the way the MapActivity knows you have Overlay items. A route is an Overlay. See this SO question: Android draw route on a Mapview with twoo POI-s
i have a situation in my app where i should move my map from one location to another location....i am quite new to android..and i found out how to draw a line in between two locations..
public class Mapview extends MapActivity implements LocationListener{
MapController mc;
GeoPoint p,p1,p2;
LocationManager lm;
String provider;
class Mapoverlay extends com.google.android.maps.Overlay
{
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
// TODO Auto-generated method stub
super.draw(canvas, mapView, shadow);
Point screenpoints=new Point();
Point screenpoints1=new Point();
Point screenpoints2=new Point();
Paint paint;
paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setStyle(Style.FILL);
paint.setStrokeWidth(2);
paint.setAlpha(120);
Paint paint1;
paint1 = new Paint();
paint1.setColor(Color.BLUE);
paint1.setAntiAlias(true);
paint1.setStyle(Style.FILL);
paint1.setStrokeWidth(2);
paint1.setAlpha(120);
if(p != null)
{
mapView.getProjection().toPixels(p, screenpoints);
mapView.getProjection().toPixels(p1, screenpoints1);
mapView.getProjection().toPixels(p2, screenpoints2);
// Bitmap map=BitmapFactory.decodeResource(getResources(), R.drawable.pushpin1);
// canvas.drawBitmap(map, screenpoints.x, screenpoints.y-53, null);
canvas.drawLine(screenpoints.x,screenpoints.y,screenpoints1.x,screenpoints1.y, paint);
canvas.drawLine(screenpoints.x,screenpoints.y,screenpoints2.x,screenpoints2.y, paint);
}
return true;
}
}
#Override
protected void onCreate(Bundle icicle) {
// TODO Auto-generated method stub
super.onCreate(icicle);
setContentView(R.layout.mapview);
MapView map=(MapView)findViewById(R.id.mapView);
map.setBuiltInZoomControls(true);
mc=map.getController();
String[] coordinates={"51.4750766129036", "-3.15672342166522"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
p=new GeoPoint((int)(lat*1E6), (int)(lng*1E6));
String[] coordinates1={"17.453117" , "78.467586" };
double lat1 = Double.parseDouble(coordinates1[0]);
double lng1 = Double.parseDouble(coordinates1[1]);
p2=new GeoPoint((int)(lat1*1E6), (int)(lng1*1E6));
p1 = new GeoPoint(19240000,-99120000);
// p = new GeoPoint(19241000,-99121000);
lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
criteria.setCostAllowed(true);
criteria.setPowerRequirement(Criteria.POWER_LOW);
provider=lm.getBestProvider(criteria, true);
Location loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
List<String> lists=lm.getAllProviders();
// float f=loc.distanceTo(loc);
if (loc!=null){
System.out.println("Provider " + provider + " has been selected.");
onLocationChanged(loc);
}else{
Toast.makeText(getApplicationContext(), "Provider " + provider+ loc + lists+" has not been selected.", 5000).show();
// this.finish();
}
// Toast.makeText(getApplicationContext(), p.getLatitudeE6()+p.getLongitudeE6(), Toast.LENGTH_SHORT).show();
mc.animateTo(p);
mc.setZoom(1);
map.invalidate();
Mapoverlay mapOverlay = new Mapoverlay();
List<Overlay> listOfOverlays = map.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
}
i am stuck at moving map from one location to another without user activity
for example:when the app initiates location of newyork city is shown then the map should move to texas ...any help willl be grateful
Try This class just pass Activity act,GeoPoint src,GeoPoint dest, int color, MapView mMapView
To call this class do this
new getRoute().DrawPath(this,mGeoPoint,getGeoPoint,Color.RED,mMapView);
public class getRoute
{
/*Variable*/
double mIntentLatitude, mIntentLongitude;
double mCursorLatitude, mCursorLongitude, mStartLatitude, mStartLongitude, mEndLatitude, MEndLongitude;
String mJsonData;
String mEnd_Address, mStart_Address, mName;
int mLength;
GeoPoint mGeoPoint = new GeoPoint(220328269, 725588202);
double mLatitude_End[], mLongitude_End[], mLatitude_Start[], mLongitude_Start[];
Activity activity;
public getRoute
(){
}
boolean error = false;
public void DrawPath(Activity act,GeoPoint src,GeoPoint dest, int color, MapView mMapView01)
{
// connect to map web service
DrawPathBack draw = new DrawPathBack(act, src, dest, color, mMapView01);
draw.execute("Draw");
}
public class DrawPathBack extends AsyncTask<String, Integer,Void>
{
ProgressDialog bar;
List<Overlay> mListOverlay;
MapOverlay mapOverlay;
ItemizedOverlay<OverlayItem> mItemizedOverlay;
GeoPoint src,dest;
int color;
MapView mMapView;
CommonMethod mCommonMethod;
String [] pairs;
String[] lngLat;
public DrawPathBack(Activity act,GeoPoint gpsrc,GeoPoint gpdest, int c, MapView mMap)
{
activity =act;
src=gpsrc;
dest=gpdest;
color = c;
mMapView=mMap;
mListOverlay = mMapView.getOverlays();
mapOverlay = new MapOverlay(mGeoPoint);
mListOverlay.add(mapOverlay);
mMapView.invalidate();
}
#Override
protected Void doInBackground(String... params)
{
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setSoTimeout(httpParameters, 60000);
HttpClient client = new DefaultHttpClient();
try {
HttpPost httpPost = new HttpPost("http://maps.googleapis.com/maps/api/directions/json?origin="+ (Double.toString((double)src.getLatitudeE6()/1.0E6)) + "," +(Double.toString((double)src.getLongitudeE6()/1.0E6 ) + "&destination=" + (Double.toString((double)dest.getLatitudeE6()/1.0E6)) + ","+ (Double.toString((double)dest.getLongitudeE6()/1.0E6))+ "&sensor=false"));
mIntentLatitude=((double)src.getLatitudeE6()/1.0E6);
mIntentLongitude=((double)src.getLongitudeE6()/1.0E6);
//httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse httpResponse = client.execute(httpPost);
mJsonData = EntityUtils.toString(httpResponse.getEntity());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Integer... progress)
{
bar.setMessage("Time Progress "+progress[0]);
}
#Override
protected void onPostExecute(Void result)
{
try {
JSONObject jsonObj = new JSONObject(mJsonData);
// grabbing the routes object
JSONArray routes = jsonObj.getJSONArray("routes");
for (int i = 0; i < routes.length(); i++) {
JSONObject rout = routes.getJSONObject(i);
JSONObject bounds = rout.getJSONObject("bounds");
JSONObject northest = bounds.getJSONObject("northeast");
mStartLatitude = northest.getDouble("lat");
mStartLongitude = northest.getDouble("lng");
JSONObject southwest = bounds.getJSONObject("southwest");
mEndLatitude = southwest.getDouble("lat");
MEndLongitude = southwest.getDouble("lng");
System.out.println("get data from jeson" + mCursorLatitude + mCursorLongitude + mEndLatitude
+ MEndLongitude);
// grabbing the routes legs
JSONArray legs = rout.getJSONArray("legs");
System.out.println("length of legs array " + legs.length());
for (int j = 0; j < legs.length(); j++) {
JSONObject leg = legs.getJSONObject(j);
System.out.println("enter in second array");
JSONObject distance = leg.getJSONObject("distance");
String mTextDistent = distance.getString("text");
System.out.println("distances bitween two point" + mTextDistent);
JSONObject duration = leg.getJSONObject("duration");
String mTextDurestion = duration.getString("text");
mEnd_Address = leg.getString("end_address");
mStart_Address = leg.getString("start_address");
System.out.println("get data from jeson in second arry"
+ mTextDurestion + " " + mEnd_Address + " " + mStart_Address);
JSONArray step = leg.getJSONArray("steps");
mLength = step.length();
mLatitude_End = new double[mLength];
mLongitude_End = new double[mLength];
mLatitude_Start = new double[mLength];
mLongitude_Start = new double[mLength];
for (int k = 0; k < step.length(); k++) {
JSONObject st = step.getJSONObject(k);
System.out.println("enter in third array");
JSONObject end_lo = st.getJSONObject("end_location");
JSONObject start_lo = st
.getJSONObject("start_location");
mLatitude_End[k] = end_lo.getDouble("lat");
mLongitude_End[k] = end_lo.getDouble("lng");
mLatitude_Start[k] = start_lo.getDouble("lat");
mLongitude_Start[k] = start_lo.getDouble("lng");
}
for (int mDistanse = 0; mDistanse < mLength; mDistanse++) {
System.out.println("end location let" + mLatitude_End[mDistanse]);
System.out.println("end location long+"
+ mLongitude_End[mDistanse]);
System.out.println("Start location let"
+ mLatitude_Start[mDistanse]);
System.out.println("Start location long"
+ mLongitude_Start[mDistanse]);
}
}
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
public class MapOverlay extends com.google.android.maps.Overlay {
public MapOverlay(GeoPoint mGeoPoint) {
}
#Override
public boolean draw(final Canvas canvas, MapView mapView,
boolean shadow, long when) {
Point mpoint = new Point();
Point mpoint1 = new Point();
int let[] = new int[mLength];
int lon[] = new int[mLength];
int let_end[] = new int[mLength];
int lon_end[] = new int[mLength];
GeoPoint newGeoPoint = null;
GeoPoint newGeoPoint1;
for (int k = 0; k < mLength; k++) {
let[k] = (int) (mLatitude_Start[k] * 1E6);
lon[k] = (int) (mLongitude_Start[k] * 1E6);
let_end[k] = (int) (mLatitude_End[k] * 1E6);
lon_end[k] = (int) (mLongitude_End[k] * 1E6);
newGeoPoint1 = new GeoPoint(let_end[k], lon_end[k]);
newGeoPoint = new GeoPoint(let[k], lon[k]);
mapView.getProjection().toPixels(newGeoPoint, mpoint);
mapView.getProjection().toPixels(newGeoPoint1, mpoint1);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
paint.setStrokeWidth(5);
canvas.drawCircle(mpoint.x, mpoint.y, 5, paint);
paint.setColor(Color.BLUE);
canvas.drawLine(mpoint.x, mpoint.y, mpoint1.x, mpoint1.y, paint);
paint.setColor(Color.BLACK);
paint.setStrokeWidth(100);
paint.setStyle(Paint.Style.FILL);
if(k==mLength-1){
Bitmap bmp = BitmapFactory.decodeResource(activity.getResources(), R.drawable.green_pin);
canvas.drawBitmap(bmp,mpoint1.x ,mpoint1.y-30, null);
}
GeoPoint dumy=new GeoPoint((int)(mIntentLatitude * 1E6), (int)(mIntentLongitude * 1E6));
Point dumy1 = new Point();
mapView.getProjection().toPixels(dumy, dumy1);
Bitmap bmp = BitmapFactory.decodeResource(activity.getResources(), R.drawable.dest_pin);
canvas.drawBitmap(bmp,dumy1.x,dumy1.y - 25, null);
mapView.getController().animateTo(dumy);
mapView.invalidate();
}
return false;
}
}
}
Try this if you want to move map on particular position then get lat or long of that position and just pass in this :
MapController mMapController;
mMapController=mMapView.getController();
mMapController.setCenter(new GeoPoint((int)(lat * 1E6), (int)(lon * 1E6)));
and if you want to draw path between two location then just pass lat and lon in this :
Intent intent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse("http://maps.google.com/maps?saddr="+ String.valueOf(from_lattitude) +","+ String.valueOf(from_longitude) +"&daddr="+ String.valueOf(dest_lati) +","+ String.valueOf(dest_longi)));
startActivity(intent);
I paint a overlay on my Google maps view (closed polygon, filled). But now I don't know how to pop up a toast when I tap on the overlay. The most examples which I found work with marker and looks very different to my code.
Main Activity:
public class BOSLstItemDetail extends MapActivity{
ArrayList<HashMap<String, Object>> boslst;
MapView mapView;
MapController mapcontrol;
GeoPoint p;
Polygon polygon;
#Override
protected boolean isRouteDisplayed() {
return false;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.boslst_item_detail);
String coordinates[] = {"48.098056", "9.788611"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
p = new GeoPoint(
(int) (lat * 1E6),
(int) (lng * 1E6));
MapView mapView = (MapView) findViewById(R.id.mapview);
mapcontrol = mapView.getController();
mapcontrol.animateTo(p);
mapcontrol.setZoom(10);
mapView.setBuiltInZoomControls(true);
ArrayList<GeoPoint> points = new ArrayList<GeoPoint>();
try{
InputStream koord = getAssets().open("gps.txt");
if (koord != null) {
InputStreamReader input = new InputStreamReader(koord);
BufferedReader buffreader = new BufferedReader(input);
String line;
while (( line = buffreader.readLine()) != null) {
String[] point_t = line.split(",");
double y = Double.parseDouble(point_t[0]);
double x = Double.parseDouble(point_t[1]);
points.add(new GeoPoint((int)(x*1e6), (int)(y*1e6)));
}
koord.close();
polygon = new Polygon(points);
}
}catch (Exception e) {
Log.e("APP","Failed", e);
}
mapView.getOverlays().clear();
mapView.getOverlays().add(polygon);
mapView.invalidate();
}
}
Polygon.java
public class Polygon extends Overlay {
ArrayList<GeoPoint> geoPoints;
public Polygon(ArrayList<GeoPoint> points){
geoPoints = points;
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow){
//Set the color and style
Paint paint = new Paint();
paint.setColor(Color.parseColor("#88ff0000"));
paint.setAlpha(50);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
//Create path and add points
Path path = new Path();
Point firstPoint = new Point();
mapView.getProjection().toPixels(geoPoints.get(0), firstPoint);
path.moveTo(firstPoint.x, firstPoint.y);
for(int i = 1; i < geoPoints.size(); ++i){
Point nextPoint = new Point();
mapView.getProjection().toPixels(geoPoints.get(i), nextPoint);
path.lineTo(nextPoint.x, nextPoint.y);
}
//Close polygon
path.lineTo(firstPoint.x, firstPoint.y);
path.setLastPoint(firstPoint.x, firstPoint.y);
canvas.drawPath(path, paint);
super.draw(canvas, mapView, shadow);
}
}
gps.txt:
9.34669876098644,48.2405319213867
9.36384963989269,48.2296714782715
9.3639497756958,48.2259712219238
9.87827968597418,48.2786293029785
9.87261867523205,48.2822494506837
9.87254810333263,48.2859611511232
9.88368034362787,48.2898597717285
9.8835382461549,48.2972793579102
9.72781181335461,47.9827613830566
9.72225093841558,47.9826812744141
9.72232818603527,47.9789619445801
9.71129894256597,47.9750900268555
9.70574092864985,47.9750099182129
9.70557022094732,47.9824409484864
9.69992923736572,47.9860801696778
9.69436073303234,47.9860000610352
9.33546066284174,48.2403602600099
9.34669876098644,48.2405319213867
If you're extending Overlay, you can override the OnTap method:
protected boolean onTap(final int index)
{
OverlayItem item = mOverlays.get(index);
if(item != null){
Toast.makeText(mContext, textToShow, Toast.LENGTH_SHORT).show();
}
//return true to indicate we've taken care of it
return true;
}
So I've spent a good amount of time attempting to figure out how to speed this up, but I'm out of ideas now. I have a class, mapPopup in which a MapView is displayed over the entire screen. There is an array of an array of GeoPoint in mapPopup, and I want to draw lines between each GeoPoint in the 2nd dimensions of the array. I've accomplished this task already using a custom class, mapOverlay, that extends Overlay, but the problem I am having is that once all the map overlays are drawn, the map is extremely slow to zoom or pan. Once all the overlays are added to the map there are often over 2000, but they are all very small.
Thinking that the map would work more quickly if there were less overlays, I drew all the lines to three seperate overlays instead of a seperate overlay for each line. This actually resulted in SLOWER panning and zooming of the map, so I reverted back to the many small overlays.
I would appreciate some informative and easy to understand descriptions of a method that I could employ to make the map faster. Pseudocode or real code for the potential method would also help me to understand it better. My code is posted below. Once more, please note that my overlays and map display properly; I would just like a method that will allow faster panning and zooming.
mapOverlay class
public class mapOverlay extends Overlay {
private Projection projection;
private GeoPoint gp1;
private GeoPoint gp2;
private int color;
public mapOverlay(int color, MapView map, GeoPoint geo1, GeoPoint geo2) {
// super();
this.projection = map.getProjection();
this.gp1 = geo1;
this.gp2 = geo2;
this.color = color;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, false);
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(4);
mPaint.setColor(this.color);
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path1.moveTo(p1.x, p1.y);
path1.lineTo(p2.x, p2.y);
canvas.drawPath(path1, mPaint);
}
}
mapPopup class
public class mapPopup extends MapActivity {
public String[] trailNames;
public String tableName = "";
public int numTrails = 0;
public static GeoPoint[][] geoPoints;
public int[] colors = new int[] { Color.WHITE, Color.BLUE, Color.CYAN,
Color.RED, Color.YELLOW, Color.MAGENTA, Color.GRAY, Color.LTGRAY };
public int[] newColors;
// public Bitmap b;
public GeoPoint firstP;
public void loadMapData(Bitmap b, MapView map, int[] colors,
GeoPoint[][] GPAA, int ZoomLevel) {
// GPAA holds an array of an array of GeoPoint
Log.i("DEBUG", "starting loadMapDataTask");
map.setSatellite(true);
MapController mc = map.getController();
mapOverlay[][] mapOverlay = new mapOverlay[GPAA.length][];
Log.i("DEBUG", "length of GPAA is: " + GPAA.length);
// i cycles through the first dimension of GPAA
for (int i = 0; i < GPAA.length; i++) {
GeoPoint[] geoPoints = GPAA[i];
int length = geoPoints.length - 1;
mapOverlay[i] = new mapOverlay[length]; //
int pointCount = 0;
// z cycles through the second dimension of GPAA
for (int z = 0; z < length; z++) {
mapOverlay[i][z] = new mapOverlay(colors[i], map,
geoPoints[pointCount], geoPoints[pointCount + 1]);
pointCount++;
}
}
// Actually adds overlays to map
List<Overlay> mapOverlays = map.getOverlays();
for (int i = 0; i < mapOverlay.length; i++) {
int length = mapOverlay[i].length;
Log.i("DEBUG", "Adding map overlays for trail: " + i);
Log.i("DEBUG", "Length of mapOverlay[i] is: " + length);
for (int z = 0; z < length; z++) {
mapOverlays.add(mapOverlay[i][z]);
}
}
mc.animateTo(GPAA[0][0]);
mc.setZoom(ZoomLevel);
Rect r = new Rect();
map.getDrawingRect(r);
map.invalidate(r);
}
public static class runBGLoad extends
AsyncTask<bgLoadParam, Integer, GeoPoint[][]> {
public GeoPoint[][] geoPoints;
protected GeoPoint[] getGPa(Context context, String name, int ID) {
File file = context.getFileStreamPath(name);
if (file.exists() == false) {
Log.i("DEBUG", "Creating file");
InputStream is;
FileOutputStream fos;
try {
Log.i("DEBUG", "id is " + ID);
is = context.getResources().openRawResource(ID);
byte[] buffer = new byte[is.available()];
is.read(buffer);
fos = context.openFileOutput(name, Context.MODE_PRIVATE);
fos.write(buffer);
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.i("DEBUG", "File already exists");
}
// Log.i("DEBUG", "starting to get geopoints");
List<Location> gpsPoints = XMLParser.getPoints(file);
int i = 0;
int index = 0;
GeoPoint[] geoPoints = new GeoPoint[gpsPoints.size()];
// makes list of gpsPoints into GeoPoint[]
ListIterator<Location> it = gpsPoints.listIterator();
while (it.hasNext()) {
index = it.nextIndex();
Location loc = gpsPoints.get(index);
geoPoints[i] = new GeoPoint((int) (loc.getLatitude() * 1E6),
(int) (loc.getLongitude() * 1E6));
it.next();
i++;
}
return geoPoints;
}
#Override
protected GeoPoint[][] doInBackground(bgLoadParam... params) {
Context context = params[0].getContext();
int tNLength = params[0].getTNames().length;
geoPoints = new GeoPoint[tNLength][];
for (int i = 0; i < params[0].getTNames().length; i++) {
String modName = params[0].getTNames()[i].toLowerCase()
.replace(' ', '_');
int identifier = context.getResources().getIdentifier(modName,
"raw", context.getPackageName());
geoPoints[i] = getGPa(params[0].getContext(), modName
+ "_mapfile", identifier);
}
Log.i("DEBUG", "TEST");
mapPopup.geoPoints = geoPoints;
Log.i("DEBUG", "TEST2");
return geoPoints;
}
#Override
protected void onPostExecute(GeoPoint[][] result) {
Log.i("DEBUG", "The points are loaded.");
mapPopup.geoPoints = result;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
Intent intent = getIntent();
String[] extras = intent.getStringArrayExtra("strings");
tableName = extras[1];
numTrails = Integer.parseInt(extras[2]);
trailNames = intent.getStringArrayExtra("trailNamesA");
super.onCreate(savedInstanceState);
setContentView(R.layout.map_popup_layout);
newColors = new int[numTrails];
for (int i = 0; i < numTrails; i++) {
newColors[i] = colors[i];
}
ViewGroup layout = (ViewGroup) findViewById(R.id.map_popup);
TextView[] tVs = new TextView[numTrails];
for (int i = 0; i < numTrails; i++) {
LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
tVs[i] = new TextView(getApplicationContext());
tVs[i].setText(trailNames[i]);
tVs[i].setId(i + 700);
tVs[i].setTextColor(colors[i]);
tVs[i].setBackgroundColor(Color.BLACK);
if (i > 0) {
params.addRule(RelativeLayout.BELOW, (699 + i));
}
layout.addView(tVs[i], params);
}
}
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
MapView map = (MapView) findViewById(R.id.popupMV);
Bitmap b = Bitmap.createBitmap(map.getWidth(), map.getHeight(),
Bitmap.Config.RGB_565);
try {
trailsActivity.mapPreLoad.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
loadMapData(b, map, newColors, geoPoints, 17);
}
#Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
}
I'm currently facing the same problematic, and I just found a workaround : prevent the overlays from drawing when zooming or panning. That's not perfect and I'm still looking for a better solution, but at least the map is usable without waiting 5 seconds for each pan or zoom.
Here is the code I used in my Overlay extension. It's not Java but C# (using Monodroid) - but it should be easily understandable.
public override bool OnTouchEvent (MotionEvent e, Android.GoogleMaps.MapView mapView)
{
if (e.Action == MotionEventActions.Down)
_mustDraw = false;
else if (e.Action == MotionEventActions.Up)
_mustDraw = true;
return base.OnTouchEvent (e, mapView);
}
public override void Draw (Android.Graphics.Canvas canvas, Android.GoogleMaps.MapView mapView, bool shadow)
{
if (shadow || !_mustDraw)
return;
// ...
}
That solution works for every map-touch based action, and now performs with a good speed, I just lack implementation of the same behaviour when zooming in or out using built-in zoom controls, but I first need to fight some of my bugs before doing this part, I'll come back on this part later.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Drawing a line/path on Google Maps
How can i draw line beetween two points in google map?
public class DrivingDirection extends MapActivity implements
IDirectionsListener {
Button btnRedirectHome;
Vector<GeoPoint> mapData = new Vector<GeoPoint>();
Vector<GeoPoint> NearData = new Vector<GeoPoint>();
MapView mapView;
MapController mc;
GeoPoint p;
GeoPoint endpoint;
MapOverlay mapOverlay;
private AlertDialog.Builder alertDialog1, alertDialog;
boolean exception = false;
// ** Called when the activity is first created. *//*
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.courtdetaildetdirection_layout);
mapView = (MapView) findViewById(R.id.mapView);
mapView.setBuiltInZoomControls(true);
mc = mapView.getController();
Bundle extras = getIntent().getExtras();
String courtId = extras != null ? extras.getString("CourtId") : "";
if(GUIStatics.previousActivityNameFalg.equalsIgnoreCase("MatchDetailActivity"))
{
if (GUIStatiMethods
.connectionCheck(DrivingDirection.this)) {
Court_Player_LocationFatcher objectCourt_Player_LocationFatch = new Court_Player_LocationFatcher();
objectCourt_Player_LocationFatch.Court_Player_LocationFatch(GUIStatics.strUserID,courtId);
final CourtDetailFatcher myCourtDetailFatcher = new CourtDetailFatcher();
myCourtDetailFatcher.CourtDetailFatch(courtId);
}
}
else if(GUIStatics.previousActivityNameFalg.equalsIgnoreCase("FavoritesActivity"))
{
if (GUIStatiMethods
.connectionCheck(DrivingDirection.this)) {
Court_Player_LocationFatcher objectCourt_Player_LocationFatch = new Court_Player_LocationFatcher();
objectCourt_Player_LocationFatch.Court_Player_LocationFatch(GUIStatics.strUserID,courtId);
final CourtDetailFatcher myCourtDetailFatcher = new CourtDetailFatcher();
myCourtDetailFatcher.CourtDetailFatch(courtId);
}
}
else
{
if (GUIStatiMethods
.connectionCheck(DrivingDirection.this)) {
Court_Player_LocationFatcher objectCourt_Player_LocationFatch = new Court_Player_LocationFatcher();
objectCourt_Player_LocationFatch.Court_Player_LocationFatch(GUIStatics.strUserID,courtId);
final CourtDetailFatcher myCourtDetailFatcher = new CourtDetailFatcher();
myCourtDetailFatcher.CourtDetailFatch(courtId);
}
}
TextView TextViewCourtDetailHeader = (TextView) this
.findViewById(R.id.TextViewCourtDetailHeader);
TextView TextViewCourtDetailAddress = (TextView) this
.findViewById(R.id.TextViewCourtDetailAddress);
TextView TextViewCourtDetailNoOfCourtAndType = (TextView) this
.findViewById(R.id.TextViewCourtDetailNoOfCourtAndType);
TextView TextViewCourtDetailCourtType = (TextView) this
.findViewById(R.id.TextViewCourtDetailCourtType);
TextView TextViewCourtDetailLight = (TextView) this
.findViewById(R.id.TextViewCourtDetailLight);
TextViewCourtDetailHeader
.setText(CourtDetailDataHandler.object.COURTNAME);
TextViewCourtDetailAddress
.setText(CourtDetailDataHandler.object.COURTADDRESS);
TextViewCourtDetailNoOfCourtAndType
.setText(CourtDetailDataHandler.object.NUMBEROFCOURT);
TextViewCourtDetailCourtType
.setText(CourtDetailDataHandler.object.COURTTYPE);
TextViewCourtDetailLight.setText("Lights: "
+ CourtDetailDataHandler.object.COURTLIGHT);
String url = "http://maps.google.com/maps?f=d&hl=en&saddr="
+ Court_Player_LocationHandler.mCOURTLAT + ","
+ Court_Player_LocationHandler.mCOURTLON + "&daddr="
+ Court_Player_LocationHandler.mUSERLAT + ","
+ Court_Player_LocationHandler.mUSERLON
+ "&ie=UTF8&0&om=0&z=20&output=kml";
Document d = GetDataFromServer(url);
if (exception) {
exception = false;
GeoPoint source = new GeoPoint(
(int) (Double
.parseDouble(Court_Player_LocationHandler.mCOURTLAT) * 1E6),
(int) (Double
.parseDouble(Court_Player_LocationHandler.mCOURTLON) * 1E6));
mapData.add(source);
GeoPoint destination = new GeoPoint(
(int) (Double
.parseDouble(Court_Player_LocationHandler.mUSERLAT) * 1E6),
(int) (Double
.parseDouble(Court_Player_LocationHandler.mUSERLON) * 1E6));
mapData.add(destination);
} else {
ParseServerData(d);
}
LinearLayout zoomLayout = (LinearLayout) findViewById(R.id.zoom);
View zoomView = mapView.getZoomControls();
zoomLayout.addView(zoomView, new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mapView.displayZoomControls(true);
mc = mapView.getController();
for (int i = 0; i < mapData.size(); i++) {
GeoPoint gp = mapData.get(i);
mc.animateTo(gp);
}
for (int i = 0; i < NearData.size(); i++) {
GeoPoint gp = mapData.get(i);
mc.animateTo(gp);
}
mc.setZoom(18);
// ---Add a location marker---
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
}
class MapOverlay extends com.google.android.maps.Overlay {
Paint innerPaint;
int infoWindowOffsetX, infoWindowOffsetY, testX, testY, id;
boolean showWindow = false;
Bitmap bitmap, bmp, bitMoreInformation;
String argName;
boolean temp = true;
#Override
public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
long when) {
super.draw(canvas, mapView, shadow);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.marker);
// ---translate the GeoPoint to screen pixels---
Paint myPaintBlack1 = new Paint();
myPaintBlack1.setColor(Color.BLUE);
myPaintBlack1.setStyle(Style.STROKE);
myPaintBlack1.setStrokeWidth(4f);
Point screenPts[] = new Point[mapData.size()];
for (int i = 0; i < mapData.size(); i++) {
Point screenPt = new Point();
GeoPoint gp = mapData.get(i);
mapView.getProjection().toPixels(gp, screenPt);// screenPts[i]);
screenPts[i] = screenPt;
if (i == 0)
canvas.drawBitmap(bmp, screenPts[i].x - bmp.getWidth() / 2,
screenPts[i].y - bmp.getHeight(), null);
if (i == mapData.size() - 1)
canvas.drawBitmap(bmp, screenPts[i].x - bmp.getWidth() / 2,
screenPts[i].y - bmp.getHeight(), null);
}
for (int i = 0; i < NearData.size(); i++) {
Point screenPs = new Point();
GeoPoint gp = mapData.get(i);
mapView.getProjection().toPixels(gp, screenPs);// screenPts[i]);
canvas.drawBitmap(bmp, screenPs.x - bmp.getWidth() / 2,
screenPs.y - bmp.getHeight(), null);
}
for (int i = 1; i < screenPts.length; i++) {
canvas.drawLine(screenPts[i - 1].x, screenPts[i - 1].y,
screenPts[i].x, screenPts[i].y, myPaintBlack1);
}
return true;
}
public Paint getInnerPaint() {
if (innerPaint == null) {
innerPaint = new Paint();
innerPaint.setARGB(225, 75, 75, 75); // gray
innerPaint.setAntiAlias(true);
}
return innerPaint;
}
#Override
public boolean onTap(GeoPoint p, MapView mapView) {
return true;
}
}
public Document GetDataFromServer(String url) {
try {
URL updateURL = new URL(url);
URLConnection conn = updateURL.openConnection();
InputStream is = conn.getInputStream();
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(is);
is.close();
return document;
} catch (Exception e) {
exception = true;
System.out.print("Exception:-" + e);
}
exception = true;
return null;
}
private void ParseServerData(Document doc) {
Element rootElement = doc.getDocumentElement();
rootElement.normalize();
NodeList nodeLst = doc.getElementsByTagName("LookAt");
int c = nodeLst.getLength();
System.out.println("count= " + c);
for (int s = 0; s < nodeLst.getLength(); s++) {
Node fstNode = nodeLst.item(s);
if (fstNode.getNodeType() == Node.ELEMENT_NODE) {
// Points p = new Points();
Element Elmnt = (Element) fstNode;
double lat = Double
.parseDouble(getTextValue(Elmnt, "latitude"));
double lng = Double
.parseDouble(getTextValue(Elmnt, "longitude"));
GeoPoint gp = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
mapData.add(gp);
}
}
}
public String getTextValue(Element ele, String tagName) {
String textVal = "";
NodeList nl = ele.getElementsByTagName(tagName);
if (nl != null && nl.getLength() > 0) {
Element el = (Element) nl.item(0);
NodeList ndlist = el.getChildNodes();
Node node = ndlist.item(0);
if (node != null)
textVal = node.getNodeValue();
}
return textVal;
}
// handler for the background updating
Handler progressHandler = new Handler() {
public void handleMessage(Message msg) {
}
};
#Override
protected boolean isRouteDisplayed() {
return false;
}
public void onDirectionsAvailable(Route route,
com.cipl.Courts.DrivingDirections.Mode mode) {
}
public void onDirectionsNotAvailable() {
}
}
The above code draw line between two point on Map in android.