Search code examples
androidandroid-studioosmdroid

OSMdroid draw rectangle


I am trying to draw a rectangle overlaying it on top of a road. I will get 3 geopoints. The first one represents the location of a car crash accident and it would be the center of the rectangle. The next geopoint is the beginning of the accident barricade or zone and the last geopoint is the end of the barricade or zone.

I have tackled this problem in two way using OSMdroid API. I have tried with Polygon using the pointAsRect() method. However in this way the rectangle drawn is not displayed correctly with the angle of the road, it should be parallel.

The other way i have tried is with buildRoadOverlay() method, but it stops right before the last point and if i create another zone farther down the road it does not distinguish.

How can i find the correct angle to draw the rectangle with these 3 points?

Using Polygon:

ArrayList<IGeoPoint>list = new ArrayList<>(5);    
private ArrayList<IGeoPoint> generateRectPoints(){
    Polygon poly = new Polygon();
    ArrayList<IGeoPoint> tempList = new ArrayList<>();        
        tempList = poly.pointsAsRect(points.get(1),5,15);
        for(IGeoPoint geo : tempList){
            GeoPoint p =new GeoPoint(geo.getLatitude(),geo.getLongitude());
            list.add(p);
        }
        IGeoPoint last = list.get(0);
        GeoPoint p =new GeoPoint(last.getLatitude(),last.getLongitude());
        list.add(p);

    return list;
}

Using buildRoadOverlay:

RoadManager roadManager = new OSRMRoadManager(getApplicationContext());

            Road road = roadManager.getRoad(points);

            Polyline roadOverlay = RoadManager.buildRoadOverlay(road, Color.argb(40, 100, 0, 255),140f);
            map.getOverlays().add(roadOverlay);
            map.invalidate();

Solution

  • Alright since no one answered this one I will share my own solution. Taking into account that I needed with 2 Geopoints draw a rectangle and angle it to be parallel to the specific map road. Note that points is the list of the 3 points i have.

    I customized one method :

    private ArrayList<GeoPoint> rotationMatrix(ArrayList<GeoPoint> lista){
        double a;
        double b;
        GeoPoint p ;
        ArrayList<Double> coord = new ArrayList<>();        
        ArrayList<GeoPoint> newList = new ArrayList<>();
        GeoPoint mid = midPoint(points.get(0).getLatitude(),points.get(0).getLongitude(), points.get(2).getLatitude(), points.get(2).getLongitude());
        //GeoPoint teste = new GeoPoint(points.get(2).getLatitude(), points.get(2).getLongitude());
        angle = points.get(0).bearingTo(mid);
        double angulo = Math.toRadians(angle);
        double cosa = Math.cos(angulo), sina=Math.sin(angulo);
    
        for (int i=0; i<lista.size();i++){
            coord.add(lista.get(i).getLatitude());
            coord.add(lista.get(i).getLongitude());
        }
    
        for(int j=0; j<coord.size(); j+=2){
            if(j+1 < coord.size()){
                p = new GeoPoint(0.0,0.0);                
                double dx = (coord.get(j) - mid.getLatitude());
                double dy = (coord.get(j+1) - mid.getLongitude());
                a = mid.getLatitude() +  (dx*cosa - dy*sina);
                b = mid.getLongitude() + (dx*sina + dy*cosa);
                p.setLatitude(a);
                p.setLongitude(b);
                newList.add(p);
    
            }else{
                break;
            }
    
        }
        return newList;
    }
    

    with this i got my matrix rotation. I applied it to this

    ArrayList<GeoPoint> temp = polygon.pointsAsRect(mid, 10.0, distanceAsDouble(mid, points.get(0))*2);
    ArrayList<GeoPoint> rotated = rotateMatrix(temp);