RVG
RVG

Reputation: 3576

Find if the current location is along a straight line, drawn between two points on a map.

I've draw a line on a map between two GeoPoints, and I have retrieved the current location. I want to know if the user's current position is along the drawn line or not?

If I get the latitude and longitude of the drawn line, how can I check the user is in the drawing path?

I've used below code to draw a line between geo points

import java.util.List;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Style;
import android.graphics.Point;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;

public class RouteSegmentOverlay extends Overlay {
    private GeoPoint locpoint;
    private Paint paint;
    // private GeoPoint routePoints [];
    private List<GeoPoint> routePoints;
    private List<Integer> routeMode;
    private boolean routeIsActive;  
    private Point pold, pnew, pp;
    private int numberRoutePoints;

    // Constructor permitting the route array to be passed as an argument.
    public RouteSegmentOverlay(List<GeoPoint> routePoints, List<Integer> routeMode) 
    {
        this.routePoints = routePoints;
        this.routeMode = routeMode;
        numberRoutePoints  = routePoints.size();
        routeIsActive = true;
        // If first time, set initial location to start of route
        locpoint = routePoints.get(0);
        pold = new Point(0, 0);
        pnew = new Point(0,0);
        pp = new Point(0,0);
        paint = new Paint();
    }

    // Method to turn route display on and off
    public void setRouteView(boolean routeIsActive){
        this.routeIsActive = routeIsActive;
    }

    @Override
    public void draw(Canvas canvas, MapView mapview, boolean shadow) {
        super.draw(canvas, mapview, shadow);
        if(! routeIsActive) return;

        mapview.getProjection().toPixels(locpoint, pp);       // Converts GeoPoint to screen pixels

        int xoff = 0;
        int yoff = 0;
        int oldx = pp.x;
        int oldy = pp.y;
        int newx = oldx + xoff;
        int newy = oldy + yoff;

        paint.setAntiAlias(true);
        paint.setDither(true);
        paint.setStrokeCap(Cap.ROUND);
        paint.setStrokeWidth(7);
            paint.setColor(Color.parseColor("#666666"));

        for(int i=0; i<numberRoutePoints-1; i++)
        {
            mapview.getProjection().toPixels(routePoints.get(i), pold);
            oldx = pold.x;
            oldy = pold.y;
            mapview.getProjection().toPixels(routePoints.get(i+1), pnew);
            newx = pnew.x;
            newy = pnew.y;

            canvas.drawLine(oldx, oldy, newx, newy, paint);
        }
    }
}

Upvotes: 2

Views: 3738

Answers (3)

Kalpesh Patel
Kalpesh Patel

Reputation: 1678

Is your concern to find whether the user moves on line or not? If so you can do it using slope and checking that the user is in between the two end points.

You can check betweeness by checking that user coordinates lies between your two line end points. You can find slope of line using below formula:

slope=(y2-y1)/(x2-x1)

First calculate the slope of your line and then calculate the slope between the user's current location and one of the two end points of your line. If the both condition satisfies then user is on the line if not then user is not on line.

Edit:

You can use Google Maps Android API Utility Library. Use PolyUtil.isLocationOnPath(LatLng point, List<LatLng> polyline, boolean geodesic, double tolerance)

Upvotes: 4

Chirag Patel
Chirag Patel

Reputation: 1611

    import java.util.ArrayList;
import java.util.List;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.util.Log;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;
import com.google.android.maps.Projection;
public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> {

    private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
    private Context mContext;
    public GeoPoint p1, p2 = null;
    int mode;
    Drawable drawable1;
    private Paint paint;
    private List<GeoPoint> points1;
    ArrayList<GeoPoint> middleGeoList1;

    public HelloItemizedOverlay(Drawable defaultMarker, Context context) {
        super(boundCenterBottom(defaultMarker));
        mContext = context;
    }

    public HelloItemizedOverlay(GeoPoint gp1, GeoPoint gp2, Drawable drawable,
            List<GeoPoint> poly) {
        super(boundCenterBottom(drawable));
        // TODO Auto-generated constructor stub
        this.p1 = gp1;
        this.p2 = gp2;
        this.points1 = poly;
        this.drawable1 = drawable;  
        paint = new Paint();
        paint.setColor(Color.BLUE);
        paint.setAlpha(150);
        paint.setAntiAlias(true);
        paint.setStyle(Paint.Style.FILL_AND_STROKE);
        paint.setStrokeWidth(5);
        populate();
    }

    public void addOverlay(OverlayItem overlay) {
        mOverlays.add(overlay);
        populate();
    }

    public void removeOverlay(OverlayItem overlay) {

        mOverlays.remove(overlay);
        populate();
    }

    @Override
    protected OverlayItem createItem(int i) {
        return mOverlays.get(i);
    }

    @Override
    public int size() {
        return mOverlays.size();
    }

    @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;
    }

    @Override
    public boolean draw(Canvas canvas, MapView mapView, boolean shadow,
            long when) {

        if (!shadow) {

            Projection projection = mapView.getProjection();
            if (points1 != null && points1.size() >= 2) {
                Point start = new Point();
                projection.toPixels(points1.get(0), start);
                for (int i = 1; i < points1.size(); i++) {
                    Point end = new Point();
                    projection.toPixels(points1.get(i), end);
                    canvas.drawLine(start.x, start.y, end.x, end.y, paint);
                    start = end;
                }

            } 
        }

        return super.draw(canvas, mapView, shadow, when);
    }
}

Its a Working Example In My Apps...Use ItemizedOverlay class for beter perfomance..All the Best

Upvotes: 0

Tomislav Novoselec
Tomislav Novoselec

Reputation: 4620

how good are you at mathematics?

basically, you could calculate equation for the line between each two points on your path, then calculate the distance between the line and user's location, and if that distance is small enough, you can claim that he is on that path

Upvotes: 2

Related Questions