Search code examples
androidgoogle-mapsdictionaryosmdroid

toPixels() returns the pixels of the tiles, instead of the screen


I have an Android application that showing maps using OSMDroid. I want to get the projection pixels of a GeoPoint on the screen, not on the tiles. Consider the following piece of code:

Projection projection = getProjection();
GeoPoint geoPoint1 = (GeoPoint)projection.fromPixels(0, 0);  
Point pixelsPoint = new Point();
projection.toPixels(geoPoint1, pixelsPoint);
GeoPoint geoPoint2 = (GeoPoint)projection.fromPixels(pixelsPoint.x, pixelsPoint.y);

I would like geoPoint1 to be equal to geoPoint2. Instead, I get 2 totally different `GeoPoint'. In my opininion, the problem is in this line:

projection.toPixels(geoPoint1, pixelsPoint);

The out variable pixelsPoint get filled with values much higher than the screen dimensions (I get 10,000+ for the x and y) and I suspect that this are the pixels on the tile, rather than the screen pixels.

How can I get from GeoPoint to screen pixels back and forth?


Solution

  • You need to compensate for the top left offset, these methods should work:

    /**
     * 
     * @param x  view coord relative to left
     * @param y  view coord relative to top
     * @param vw MapView
     * @return GeoPoint
     */
    
    private GeoPoint geoPointFromScreenCoords(int x, int y, MapView vw){
        if (x < 0 || y < 0 || x > vw.getWidth() || y > vw.getHeight()){
            return null; // coord out of bounds
        }
        // Get the top left GeoPoint
        Projection projection = vw.getProjection();
        GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0);
        Point topLeftPoint = new Point();
        // Get the top left Point (includes osmdroid offsets)
        projection.toPixels(geoPointTopLeft, topLeftPoint);
        // get the GeoPoint of any point on screen 
        GeoPoint rtnGeoPoint = (GeoPoint) projection.fromPixels(x, y);
        return rtnGeoPoint;
    }
    
    /**
     * 
     * @param gp GeoPoint
     * @param vw Mapview
     * @return a 'Point' in screen coords relative to top left
     */
    
    private Point pointFromGeoPoint(GeoPoint gp, MapView vw){
    
        Point rtnPoint = new Point();
        Projection projection = vw.getProjection();
        projection.toPixels(gp, rtnPoint);
        // Get the top left GeoPoint
        GeoPoint geoPointTopLeft = (GeoPoint) projection.fromPixels(0, 0);
        Point topLeftPoint = new Point();
        // Get the top left Point (includes osmdroid offsets)
        projection.toPixels(geoPointTopLeft, topLeftPoint);
        rtnPoint.x-= topLeftPoint.x; // remove offsets
        rtnPoint.y-= topLeftPoint.y;
        if (rtnPoint.x > vw.getWidth() || rtnPoint.y > vw.getHeight() || 
                rtnPoint.x < 0 || rtnPoint.y < 0){
            return null; // gp must be off the screen
        }
        return rtnPoint;
    }