开发者

How to: plot a given latitude and longitude into still image map using four (4) coordinates of the image?

I have created this post -> plot a real world lat lon into different angle still image map

from that, I can successfully mark the given lat&lon given the two (2) coordinates (upper left, lower right) but due to incorrect angle of the still image map compare to real world map angle, my mark was displaced.

Now, I am thinking of using four (4) coordinates (upper left, lower left, upper right, lower right) of the image. So that, I could plot the given lat&lon without considering the angle.

I think, even without Android experience could answer this question. I just kinda slow with Mathematics matter.

It is possible to implement it? if yes, any guidance & code snippets are appreciated.

UPDATES1 Main goal is to mark the given lat&lon into image map which has different angle against to real world map.

UPDATES2 I am using the below codes to compute my angle. Would you check it if it is reliable for getting the angle. Then convert it to pixel. NOTE: this codes are using only two coordinates of the image plus target coordinate.

public static double[] calc_xy (double imageSize, Location target, Location upperLeft, Location upperRight) {
    double newAngle = -1;
    try {
        double angle = calc_radian(upperRight.getLongitude(), upperRight.getLatitude(), 
                upperLeft.getLongitude(), upperLeft.getLatitude(), 
                target.getLongitude(), target.getLatitude());
        newAngle = 180-angle;

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    double upperLeft_Target_dist = upperLeft.distanceTo(target);

    doub开发者_运维问答le upperLeft_Right_dist = upperLeft.distanceTo(upperRight);
    double distancePerPx = imageSize /upperLeft_Right_dist;

    double distance = upperLeft_Target_dist * distancePerPx;

    double radian = newAngle * Math.PI/180;

    double[] result = radToPixel(distance, radian);
    return result;
}

public static double[] radToPixel(double distance, double radian) {
    double[] result = {-1,-1};
    result[Functions.Location.PIXEL_X_LON] = distance * Math.cos(radian);
    result[Functions.Location.PIXEL_Y_LAT] = distance * Math.sin(radian);
    return result;
}

public static double calc_radian(Double x1, Double y1, Double x2, Double y2, Double x3, Double y3)
    throws Exception{

    double rad = 0.0;

    if((Double.compare(x1, x2) == 0 && Double.compare(y1, y2) == 0) ||
            (Double.compare(x3, x2) == 0 && Double.compare(y3, y2) == 0))
    {
        Log.d(tag, "Same place") ;
        return rad;
    }

    /* compute vector */
    double BAx = x2 - x1;
    double BAy = y2 - y1;

    double BCx = x3 - x2;
    double BCy = y3 - y2;

    double cosA =  BAx / Math.sqrt( BAx * BAx + BAy * BAy ) ;
    double cosC =  BCx / Math.sqrt( BCx * BCx + BCy * BCy ) ;

    double radA = Math.acos( cosA ) * 180.0 / Math.PI ;
    double radC = Math.acos( cosC ) * 180.0 / Math.PI ;
    if( BAy < 0.0 )
    {
        radA = radA * -1.0 ;
    }
    if( BCy < 0.0 )
    {
        radC = radC * -1.0 ;
    }

    rad = radC - radA ;


    if( rad > 180.0 )
    {
        rad = rad - 360;
    }

    if( rad < -180.0 )
    {
        rad = rad + 360;
    }

    return rad ;
}


This looks like you want to plot the user's current geo-location on an image of, say a building or campus. Assuming this, my approach would be to 'map' the still image to the screen which is likely to require a translation transform, a rotation transform and a scaling transform. In addition, you will need to know the actual geo-location coordinates of at least two points on your image. Given the image in your previous post, I would assume you have the geo coordinates of the bottom left corner and the bottom right corner. You already have the information to convert a geo coordinate into a screen coordinate so the image can be drawn matching up the bottom left corner of your image with the pixel coordinate which you've calculated. I will call this point your anchor point.

At this stage you probably have an image with one corner at the correct location but now it needs to be scaled down or up and then rotated about your anchor point. You can get the current zoom level from your mapView or you can get the latitudeSpan and you can calculate the scale factor to be applied to your image.

Lastly, if you have the geo coordinates of the two corners of the image, you can calculate the angle the image should be rotated. This can be calculated using pythagoras or you can convert from Cartesian coordinates to polar coordinates see here. This calculation doesn't have to be done by your app - it can be calculated separately and put in as a constant. Now you can apply the rotation transform around your fixed anchor point.

You may also want to make use of handy built-in functions such as mapController.zoomInFixing() which takes pixel coordinates or one of the other zoomTo() or animateTo() functions.

Edit: If you're not using a mapview to manage your geo-coordinates then you can apply the image transformations using code like this:

// create a matrix for the manipulation
    Matrix matrix = new Matrix();
    // resize the bit map
    matrix.postScale(scaleWidth, scaleHeight);
    // rotate the Bitmap
    matrix.postRotate(angle);

// recreate the new Bitmap
    Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0, 
                      width, height, matrix, true); 

    // make a Drawable from Bitmap to allow to set the BitMap 
    // to the ImageView, ImageButton or what ever
    BitmapDrawable bmd = new BitmapDrawable(resizedBitmap);

    ImageView imageView = new ImageView(this);

    // set the Drawable on the ImageView
    imageView.setImageDrawable(bmd);

Edit: With the upper left and lower right coordinates, you can calculate the angle as follows:

angle = sin-1((right.x - left.y)/sqrt((right.x - left.x)sq + (right.y - left.y)sq))

[Where sqrt = square root; sq = squared


If you know what is the angle, it is a simple Cartesian rotation of the axis.

Let x be the old longitude, y be the old latitude, and b be the angle

The new longitude x' = x*cos(b) - y*sin(b)

The new latitude y' = x*sin(b) + y*cos(b)


I'm not sure I understand but it seems to me like you want to calculate the angle of the image that you want using two points then rotate it and resize it based on the number of pixels between point a and b (two corners) using the method of changing from lat lon to pixels and the distance formula

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜