I am trying to draw a line between 2 geopoints on a google map. I am able to place markers, but not draw a line between them. I know I am missing something trivial.
//subscribedToMap is a MapView
subscribedToMap.getOverlays().add(new PathMarker(journey.getSourceGPSX(),
journey.getSourceGPSY(),
journey.getDestinationGPSX(),
journey.getDestinationGPSY())) ;
subscribedToMap.invalidate();
public class PathMarker extends Overlay {
private Double slat, slng, dlat, dlng;
public PathMarker(Double slat, Double slng, Double dlat, Double dlng) {
super();
this.slat = slat;
this.slng = slng;
this.dlat = dlat;
this.dlng = dlng;
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
canvas.drawLine(slat.intValue(), slng.intValue(), dlat.intValue(),
dlng.intValue(), new Paint());
super.draw(canvas, mapView, shadow);
}
#Override
public boolean onTouchEvent(MotionEvent event, MapView mapView) {
return (super.onTouchEvent(event, mapView));
}
}
Edit : I even tried
public void draw(Canvas canvas, MapView mapv, boolean shadow){
super.draw(canvas, mapv, shadow);
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(2);
GeoPoint gP1 = new GeoPoint(19240000,-99120000);
GeoPoint gP2 = new GeoPoint(37423157, -122085008);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
projection.toPixels(gP1, p1);
projection.toPixels(gP2, p2);
path.moveTo(p2.x, p2.y);
path.lineTo(p1.x,p1.y);
canvas.drawPath(path, mPaint);
}
Trivial Error, did not create GeoPoints correctly
GeoPoint gP1 = new GeoPoint((int)(slat * 1E6),(int) (slng * 1E6));
GeoPoint gP2 = new GeoPoint((int)(dlat * 1E6),(int) (dlng * 1E6));
Related
I have an app where an user is given a lot of points (100 or even more) and he has to physically go to those points and "check in". They have to go to those points in a certain order, so I need to display a route in the MapView which passes through all those points.
I've read a lot about getting the route between two points, but I can't find anything about drawing a complex route with a lot of points. Is this behavior possible?
public class RouteOverlay extends Overlay {
private GeoPoint gp1;
private GeoPoint gp2;
private int color;
public RouteOverlay(GeoPoint gp1, GeoPoint gp2, int color) {
this.gp1 = gp1;
this.gp2 = gp2;
this.color = color;
}
Now all that's left now for our Overlay is to override the draw() method and draw the line as we need it:
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Projection projection = mapView.getProjection();
Paint paint = new Paint();
Point point = new Point();
projection.toPixels(gp1, point);
paint.setColor(color);
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);
super.draw(canvas, mapView, shadow);
}
Back in the Activity, just iterate over the GeoPoints that you got from google maps and add each of them to the MapView:
private void drawPath(List geoPoints, int color) {
List overlays = mapView.getOverlays();
for (int i = 1; i < geoPoints.size(); i++) {
overlays.add(new RouteOverlay(geoPoints.get(i - 1), geoPoints.get(i), color));
}
}
Try something like this
if(DataSources.ActivitiesList.length >0)
{
String address = "http://maps.google.com/maps?daddr=" + DataSources.ActivitiesList[0].SiteLatitude.toString() + "," + DataSources.ActivitiesList[0].SiteLongitude.toString();
for (int i= 1 ;i < DataSources.ActivitiesList.length ; i++)
{
if(DataSources.ActivitiesList[i].SiteLatitude != null)
address += "+to:" + DataSources.ActivitiesList[i].SiteLatitude + "," + DataSources.ActivitiesList[i].SiteLongitude;
}
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(address));
startActivity(intent);
break;
}
My problem is that I want to create a method that when I invoke it giving it two GeoPoint's I want it to draw a line between the two points and I haven't been able to do this.
Thanks in advance.
public class MyOverlays extends ItemizedOverlay<OverlayItem> {
private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
private Context context;
private int lastestIndex;
private Projection projection;
private Canvas canvas;
private MapView mapv;
private boolean shadow;
public MyOverlays(Context context, Drawable defaultMarker, String player) {
super(boundCenterBottom(defaultMarker));
this.context = context;
}
#Override
protected OverlayItem createItem(int i) {
return mapOverlays.get(i);
}
#Override
public int size() {
return mapOverlays.size();
}
public void setPj(Projection projection) {
this.projection = projection;
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, shadow);
this.canvas = canvas;
this.mapv = mapv;
this.shadow = shadow;
// Configuring the paint brush
}
Test method ideally i would want to pass 2 geopoints to draw a line between them
public void test() {
super.draw(canvas, mapv, shadow);
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);
GeoPoint gP1 = new GeoPoint(34159000, 73220000);// starting point
GeoPoint gP2 = new GeoPoint(33695043, 73050000);// End point Islamabad
GeoPoint gP4 = new GeoPoint(33695043, 73050000);// Start point Islamabad
GeoPoint gP3 = new GeoPoint(33615043, 73050000);// End Point Rawalpindi
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
Point p3 = new Point();
Point p4 = new Point();
Path path2 = new Path();
projection.toPixels(gP2, p3);
projection.toPixels(gP1, p4);
path1.moveTo(p4.x, p4.y);// Moving to Abbottabad location
path1.lineTo(p3.x, p3.y);// Path till Islamabad
projection.toPixels(gP3, p1);
projection.toPixels(gP4, p2);
path2.moveTo(p2.x, p2.y);// Moving to Islamabad location
path2.lineTo(p1.x, p1.y);// Path to Rawalpindi
canvas.drawPath(path1, mPaint);// Actually drawing the path from
// Abbottabad to Islamabad
canvas.drawPath(path2, mPaint);// Actually drawing the path from
// Islamabad to Rawalpindi
this.populate();
}
Resolved my issue,
public void draw(Canvas canvas, MapView mapv, boolean shadow){
super.draw(canvas, mapv, shadow);
this.canvas=canvas;
this.mapv=mapv;
this.shadow=shadow;
if(line==1){
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);
GeoPoint gP1 = new GeoPoint(34159000,73220000);//starting point Abbottabad
GeoPoint gP2 = new GeoPoint(33695043,73050000);//End point Islamabad
GeoPoint gP4 = new GeoPoint(33695043, 73050000);//Start point Islamabad
GeoPoint gP3 = new GeoPoint(33615043, 73050000);//End Point Rawalpindi
Point p1 = new Point();
Point p2 = new Point();
Path path1 = new Path();
Point p3 = new Point();
Point p4 = new Point();
Path path2 = new Path();
projection.toPixels(gP2, p3);
projection.toPixels(gP1, p4);
path1.moveTo(p4.x, p4.y);//Moving to Abbottabad location
path1.lineTo(p3.x,p3.y);//Path till Islamabad
projection.toPixels(gP3, p1);
projection.toPixels(gP4, p2);
path2.moveTo(p2.x, p2.y);//Moving to Islamabad location
path2.lineTo(p1.x,p1.y);//Path to Rawalpindi
canvas.drawPath(path1, mPaint);//Actually drawing the path from Abbottabad to Islamabad
canvas.drawPath(path2, mPaint);//Actually drawing the path from Islamabad to Rawalpindi
}
//Configuring the paint brush
}
public void test(){
System.out.println("vim ao test");
line=1;
draw(canvas,mapv,shadow);
}
Now below is my code that draws path between geopoints in map. This works perfectly fine. What I'm trying to implement is instead of drawing a line,display this path with the dots(.) as in iPhone. I want it to be like this gp1.........gp2 instead of drawing in a single straight line like gp1______gp2.
I have tried almost all the options for doing this but still no success on this, any one can help me solving this?
private void drawPath(List geoPoints, int color) {
List overlays = objMapView.getOverlays();
int loopcount = geoPoints.size() - 1;
for (int i = 0; i < loopcount; i++) {
GeoPoint p1 = (GeoPoint) geoPoints.get(i);
GeoPoint p2 = (GeoPoint) geoPoints.get(i + 1);
MyPathOverLay p = null;
/**** Marking the start and end of the trailpath ****/
if (i == 0) {
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.drawable.greenflag);
p = new MyPathOverLay(p1, p2, 0xFFFF0000, true, false, bmp);
} else if (i == loopcount - 1) {
Bitmap bmp = BitmapFactory.decodeResource(this.getResources(),R.drawable.redflag);
p = new MyPathOverLay(p1, p2, 0xFFFF0000, false, true, bmp);
} else {
p = new MyPathOverLay(p1, p2, 0xFFFF0000, false, false, null);
}
overlays.add(p);
}
}
public class MyPathOverLay extends Overlay {
private GeoPoint gp1;
private GeoPoint gp2;
private int color;
Boolean isFirstPOI;
Boolean isLastPOI;
AudioMap audioMap;
Bitmap bmp;
public MyPathOverLay(GeoPoint gp1, GeoPoint gp2, int color,Boolean first, Boolean last,Bitmap bitMap) {
this.gp1 = gp1;
this.gp2 = gp2;
this.color = color;
this.isFirstPOI= first;
this.isLastPOI = last;
this.bmp = bitMap;
}
#Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) {
Projection projection = mapView.getProjection();
Paint paint = new Paint();
Point point = new Point();
projection.toPixels(gp1, point);
paint.setColor(color);
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);
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(gp1, screenPts);
//---translate the GeoPoint to screen pixels---
Point screenPts1 = new Point();
mapView.getProjection().toPixels(gp2, screenPts1);
if(isFirstPOI == true){
canvas.drawBitmap(bmp,screenPts.x-20,screenPts.y-40, null);
}
else if(isLastPOI == true) {
canvas.drawBitmap(bmp,screenPts1.x-20,screenPts1.y-35, null);
}
super.draw(canvas, mapView, shadow);
}
}
Thanks to this guy, I referred this example and it is working for me.
How do I make a dotted/dashed line in Android?
Just need to add these 2 lines,
paint.setPathEffect(new DashPathEffect(new float[] {10,10}, 5));
canvas.drawLine(point.x, point.y, point2.x, point2.y, paint);
after I set,
paint.setAlpha(120);
#Frankenstein, thank you
I am working on a project which is aboot drawing roads and displaying some informations about the roads. The issue is that I am using so many geopoints( 5.000-10.000 +) and drawing line points to points and showing the roads with different colors, so the map is too slow. I did some configurations about my application but still too slow.
Do you have any idea about solving my problem and being the performance better?
Here is the my code.
for (int t = 0; t < roads.size(); t++) {
for (int i = 0; i < roads.get(t).size() - 1; i++) {
//bounds up-bottom-right-left to draw roads
if (boundBox[0] >= roads.get(t).get(i)
.getLatitudeE6()
&& boundBox[1] >= roads.get(t).get(i)
.getLongitudeE6()
&& boundBox[2] <= roads.get(t).get(i)
.getLatitudeE6()
&& boundBox[3] <= roads.get(t).get(i)
.getLongitudeE6()) {
MyOverlay mOverlay = new MyOverlay();
mOverlay.setColor(Color.GREEN);
mOverlay.setWidth(4);
mOverlay.setPair(roads.get(t).get(i),
roads.get(t).get(i + 1));
mapOverlays.add(mOverlay);
}
}
}
class MyOverlay extends Overlay {
GeoPoint gp1 = new GeoPoint(0, 0);
GeoPoint gp2 = new GeoPoint(0, 0);
int colr=0,width=0;
public MyOverlay() {
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, false);
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(colr);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(width);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
Projection projection = mapv.getProjection();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path.moveTo((float) p2.x, (float) p2.y);
path.lineTo((float) p1.x, (float) p1.y);
// canvas.drawBitmap(markerBitmap, point.x, point.y, null);
canvas.drawPath(path, mPaint);
//canvas.drawBitmap(bitmap, src, dst, paint);
}
public void setPair(GeoPoint gpone, GeoPoint gptwo) {
gp1 = gpone;
gp2 = gptwo;
}
public void setColor(int clr)
{
colr=clr;
}
public void setWidth(int w)
{
width=w;
}
}
Is there anyone to solve my issue ?
There are a few things you can do to improve efficiency.
Your first block of code could be made slightly more efficient:
for (int t = 0, size = roads.size(); t < size; t++) { //Avoid calling '.size()' over and over
for (int i = 0; i < roads.get(t).size() - 1; i++) {//Avoid calling '.size()' over and over
final GeoPoint road = roads.get(t).get(i); //Reduce the number of get() calls.
if (boundBox[0] >= road.getLatitudeE6()
&& boundBox[1] >= road.getLongitudeE6()
&& boundBox[2] <= road.getLatitudeE6()
&& boundBox[3] <= road.getLongitudeE6()) {
MyOverlay mOverlay = new MyOverlay();
mOverlay.setColor(Color.GREEN);
mOverlay.setWidth(4);
mOverlay.setPair(road, roads.get(t).get(i + 1));
mapOverlays.add(mOverlay);
}
}
}
But most importantly, the biggest performance drain I can see in your code is that you are allocating a new rendering objects (Paint, Path, Point) every time draw() is called. This can be refactored so you reuse the same Paint instance:
class MyOverlay extends Overlay {
GeoPoint gp1 = new GeoPoint(0, 0);
GeoPoint gp2 = new GeoPoint(0, 0);
Point p1 = new Point();
Point p2 = new Point();
Path path = new Path();
int colr=0,width=0;
public MyOverlay() {
Paint mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(colr);
mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(width);
}
public void draw(Canvas canvas, MapView mapv, boolean shadow) {
super.draw(canvas, mapv, false);
path.reset();
Projection projection = mapv.getProjection();
projection.toPixels(gp1, p1);
projection.toPixels(gp2, p2);
path.moveTo((float) p2.x, (float) p2.y);
path.lineTo((float) p1.x, (float) p1.y);
canvas.drawPath(path, mPaint);
}
}
For more info see the 'Do's and Dont's section of the article here: http://android-developers.blogspot.com.au/2011/03/android-30-hardware-acceleration.html.
The relevant point from the article is: "Don't create render objects in draw methods: a common mistake is to create a new Paint, or a new Path, every time a rendering method is invoked. This is not only wasteful, forcing the system to run the GC more often, it also bypasses caches and optimizations in the hardware pipeline."
i am trying to draw a line between 2 geopoints. i am able to show to geopoints on the map.
Its working fine. but i am not able to draw a line between 2 points. program has no error but line is not getting displayed. can anyone tell me what i have to change.
public class HelloMapView extends MapActivity {
/** Called when the activity is first created. */
LinearLayout linearLayout;
MapView mapView;
MapController mc;
GeoPoint p,p1;
class MapOverlay extends com.google.android.maps.Overlay
{
#Override
public boolean draw(Canvas canvas, MapView mapView,
boolean shadow, long when)
{
super.draw(canvas, mapView, shadow);
//---translate the GeoPoint to screen pixels---
Point screenPts = new Point();
mapView.getProjection().toPixels(p, screenPts);
//---add the marker---
Bitmap bmp = BitmapFactory.decodeResource(
getResources(), R.drawable.a);
canvas.drawBitmap(bmp, screenPts.x, screenPts.y-50, null);
//Coordinates 2
//---translate the GeoPoint to screen pixels---
Point screenPts1 = new Point();
mapView.getProjection().toPixels(p1, screenPts1);
//---add the marker---
Bitmap bmp1 = BitmapFactory.decodeResource(
getResources(), R.drawable.b);
canvas.drawBitmap(bmp1, screenPts1.x, screenPts1.y-50, null);
//----------- Start--------------//
Projection projection = mapView.getProjection();
Path path = new Path();
Point from = new Point();
Point to = new Point();
projection.toPixels(p, from);
projection.toPixels(p1, to);
path.moveTo(from.x, from.y);
path.lineTo(to.x, to.y);
Paint mPaint = new Paint();
mPaint.setStyle(Style.FILL);
mPaint.setColor(0xFFFF0000);
mPaint.setAntiAlias(true);
canvas.drawPath(path,mPaint);
super.draw(canvas, mapView, shadow);
return true;
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.setBuiltInZoomControls(true);
mapView = (MapView) findViewById(R.id.mapview);
mapView.displayZoomControls(true);
mc = mapView.getController();
String coordinates[] = {"12.958998", "77.658998"};
double lat = Double.parseDouble(coordinates[0]);
double lng = Double.parseDouble(coordinates[1]);
p = new GeoPoint(
(int) (lat * 1E6),
(int) (lng * 1E6));
String coordinates1[] = {"12.95967","77.64918"};
double lat1 = Double.parseDouble(coordinates1[0]);
double lng1 = Double.parseDouble(coordinates1[1]);
p1 = new GeoPoint(
(int) (lat1 * 1E6),
(int) (lng1 * 1E6));
mc.animateTo(p);
mc.animateTo(p1);
mc.setZoom(16);
//---Add a location marker---
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = mapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
mapView.invalidate();
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
Forget all the Path stuff, just use the following line (it works for me):
canvas.drawLine(screenPts.x, screenPts.y, screenPts1.x, screenPts1.y, mPaint);
I suspect you need to change this line:
mPaint.setStyle(Style.FILL);
to:
mPaint.setStyle(Style.STROKE);
Also, while it's probably not related to your problem, it looks like you are calling super.draw twice, once at the beginning and once at the end. You probably just want to call it at the beginning.