3

Regarding positioning an image on a map giving its bounds, Google Maps' documentation states:

When the image is drawn on the map it will be rotated to fit the bounds. If the bounds do not match the original aspect ratio, the image will be skewed.

But in my code I have this:

    GroundOverlayOptions goo2 = new GroundOverlayOptions()
            .image(BitmapDescriptorFactory.fromResource(imgRes))
            .positionFromBounds(new LatLngBounds(
                    new LatLng(44.415, 8.937),
                    new LatLng(44.42, 8.942)
            ));
    mMap.addGroundOverlay(goo2);

The image is not rotated, but always drawn straight pointing north, and skewed. Changing the overlay corners just skews more and it never rotates a bit.

How can I set GMaps to rotate it, or does any external tool exist to rotate it?

Beppi's
  • 2,089
  • 1
  • 21
  • 38

2 Answers2

3

I solved this by myself. I think that Google's documentation is not very clear. It states that a GroundOverlay can be positioned using two possible methods:

There are two ways to specify the position of the ground overlay: Using a LatLng to center the overlay, and dimensions in meters to specify the size of the image. Using a LatLngBounds to specify the north east and south west corners of the image. You must specify the position of the ground overlay before it is added to the map.

I was using the second way, or giving it two geo-corners of the image I wanted to apply. What is not clear is that with the second method rotation is not possible, and every discrepancy in proportion will be rendered with a skewed image. Actually the idea I had was exactly that, given two points on a plain, we have exactly one image that can fit those two points without stratching, but just rotating, I was disappointed discovering that does not work.

However, if you have enough patience to calculate by your own size in meters and rotation of your image, you can determine one corner, or the center of the image, and use the first method, using LatLng and explicitly indicate an anchor, for example (0, 0) for upper left corner or (0.5, 0.5) for the center, a height of the picture in meters (here is a good way to find it: How to convert latitude or longitude to meters?), find a rotation by using trigonometry, and that's it.

A way to find the image size in pixels is indicated here.

That's my final code, for memory:

        BitmapFactory.Options dimensions = new BitmapFactory.Options();
        dimensions.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(getResources(), imgRes, dimensions);
        int imgHeightPixels = dimensions.outHeight;

        GroundOverlayOptions goo = new GroundOverlayOptions()
            .image(BitmapDescriptorFactory.fromResource(imgRes))
            .position(imgBottomLeftCorner, imgHeightInPixels)
            .anchor(0, 1)
            .bearing(imgRotation);
        mMap.addGroundOverlay(goo);

Watch out that the Y coordinates on the map grow bottom up, while on the image grow top down, so the anchor is (0,1).

Given two vectors, here's what I did to find their angle, and consequently the image rotation (using a vector made of two points coordinates on the image versus a vector made of the same two points geographic coordinates):

private static double calcDistance(double x1, double y1, double x2, double y2) {
    return (Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)));
}
private static double calcVectorRotation(double x1, double y1, double x2, double y2) {
    return Math.asin( (y1-y2) / calcDistance(x1, y1, x2, y2) );
}
Community
  • 1
  • 1
Beppi's
  • 2,089
  • 1
  • 21
  • 38
0

As you've already mentioned and based from the documentation, if the bounds do not match the original aspect ratio, the image will be skewed.

You should try using android:adjustViewBounds to preserve the aspect ratio.

Set this to true if you want the ImageView to adjust its bounds to preserve the aspect ratio of its drawable.

Please try adding the following into your XML:

android:adjustViewBounds="true"
android:scaleType="fitCenter"

You may also try the suggested code implementations in this SO post. Hope that helps!

Community
  • 1
  • 1
Teyam
  • 7,686
  • 3
  • 15
  • 22