OpenMap-java/openmap

Rotated OMScalingRaster rendered wrong when partially off edge of window

ianrenton opened this issue · 8 comments

I have come across an issue when using an OMScalingRaster object which has a rotation applied. The object sits on an OMGraphicHandlerLayer. When the image is fully in view, it renders correctly. However, when the image is partially off the left or right side of the window (Mercator projection), the shape of the image is distorted - it appears shrunk in one direction and enlarged in the other. If I do not rotate the OMScalingRaster, it works fine when placed partially off-screen, but unfortunately for my application the image needs to be rotated.

I notice in OMScalingRaster.java that there is a "clever bit" in the scaleTo(Projection) method which checks if some of the image is off-screen, and if so, draws only the visible subset of the image. In order to make this rotated image work properly for me, I have had to subclass OMScalingRaster and remove these lines:

        if (corners == null || corners.size() <= 2) {
            iRect = winRect.intersection(projRect);
        }

and also remove the if block that starts with if (!winRect.contains(projRect)) {.

This fixes the problem for me, but is obviously not ideal as it is removing a useful feature.

Do you know if this functionality has been tried before when using a rotated OMScalingRaster?

I'm not able to share an example direct from our code, but if necessary I will try to create a minimal example to demonstrate this problem.

Hi Ian,

I understand that the API will allow you to rotate an OMScalingRaster, but I don't quite get what it represents on the map - it's kind of unusual to anchor a projected image to two points on the map and then rotate it. What does the image represent? Is it an Icon image centered over location and you're trying to resize it for different zoom levels, or are you really trying to rotate a georeferenced image?

  • Don

I should probably explain what I'm doing, as I may be going about it wrong.

I have an image which is created and updated internally within the software. Currently I implement this as an AWT BufferedImage. The image is rectangular but corresponds to a geographical rectangle that could be at any angle relative to North.

(The maths that generates this image is complex, and I would rather keep the image internally as a plain rectangle and just rotate it for display, rather than internally handling an image that is orthogonal to North but with large transparent areas around a diagonal rectangle.)

When setting up my OMScalingRaster, I give it the BufferedImage, specify the rotation angle I would like, then supply the lat/lon of two corners of where I would like the image to display using setULLat() etc.

This does appear to work, and OpenMap renders my rectangular image in the right place at the right angle - unless the image would be partially off screen.

Is this a real bug, or is there another way of achieving what I'm trying to do that I should be using instead?

Thanks

I suspect we're just lucky that the image looks OK and is small enough that the projection doesn't show it distorted. I will look into OMWarpingImage, is there a guide / example anywhere of how to use this?

Thanks for your help! I now have an OMWarpingImage set up with the correct coordinate transforms to make it appear in the right place.

I have one more question, if I may:

I am updating my BufferedImage regularly and need to force the layer to show the new image. I am updating my OMWarpingImage with the new BufferedImage contents by calling the setWarp() method - so far so good. However, my layer isn't picking up that it needs to regenerate. So the user does not see any updates on screen. Changing the projection (e.g. zooming or panning the map) forces an update and the latest image data is shown.

What's the best way of forcing a repaint of the layer every time the OMWarpingImage behind it changes?

That's working great, thanks for your help!