xitingTick / osmdroid

Automatically exported from code.google.com/p/osmdroid
0 stars 0 forks source link

Updated map rotation patch #396

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
I am attaching an updated map rotation patch that works with the 
SafeTranslatedCanvas and fixes a few other issues. Please test and report 
issues here!

Issues:

1. Scrolling the maps to a point doesn't work correctly.

Original issue reported on code.google.com by kurtzm...@gmail.com on 23 Jan 2013 at 3:34

Attachments:

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Hi kurtzmarc,

I try your rotation patch and study your changes.
It seems to rotate correctly concerning tiles presentation, taking care the 
possible empty screen corners by expanding the map size with hypot factor.
But I'll make more tests with overlays and touch, in order to be safe with my 
comments.

Till now I use the setUseSafeCanvas(false) because of the many problems that 
safe canvas has caused at my existing apps.
The most serious one is that I want to use android.graphics.Canvas at some of 
my draw methods (which are being used and by libraries that do not support safe 
canvas - so I cannot change it). For example to draw my own my location arrow 
icon, my own compass implementation etc. Which android.graphics.Canvas can I 
pass to those methods?
With setUseSafeCanvas(false) I pass getWrappedCanvas() in order to have visible 
results.
Now with setUseSafeCanvas(true) I see nothing trying getWrappedCanvas() or 
getSafeCanvas().

Any help?

Thanks!

Original comment by devemu...@gmail.com on 25 Jan 2013 at 11:23

GoogleCodeExporter commented 8 years ago
There is an issue getSafeCanvas() and calling native methods on that canvas. I 
need to write a proxy Canvas that you can use for passing to other libraries - 
getSafeCanvas can sometimes handle this already but some methods aren't covered.

If you have your own Overlays that require the regular canvas then you just 
need to extend Overlay rather than SafeDrawOverlay in your class and you will 
get the traditional Canvas. Regular Overlays will work side-by-side with 
SafeDrawOverlays.

Original comment by kurtzm...@gmail.com on 25 Jan 2013 at 3:08

GoogleCodeExporter commented 8 years ago
I understand your point for new created overlays.
But if I want to extend an existing overlay, like MyLocationNewOverlay, in 
order to retain the basic functionality but customize the draw process?

The functionality of the class is in the drawSafe and drawMyLocation methods 
which use safe canvas. I see 2 ways from there:
1. Override drawMyLocation and use getWrappedCanvas as normal canvas at my 
drawing process, which is what I do now with setUseSafeCanvas(false).
2. Override normal draw, but then have to copy in it the whole functionality of 
drawSafe and drawMyLocation to be able to modify it, as overridden draw is 
actually SafeDrawOverlay.draw

Original comment by devemu...@gmail.com on 25 Jan 2013 at 4:10

GoogleCodeExporter commented 8 years ago
Hello kurtzmarc,

I started playing with this library yesterday, researching for a future project 
my company is involved in. I got a clean trunk checkout and applied 3 patches 
on it: issue 209, 232 and this one.

The N/S scroll limiting works fine, didn't test the boundaries. The rotation 
works fine except for some flings when scrolling a rotated map. It seems to 
bounce and scroll in the opposite direction, didn't have time to look much into 
it.

What I did was to hook a multi-touch rotation listener to the dispatchEvent() 
method in MapView.java that gets instantiated when you enable multi-touch 
controls.

Could you take a look at my code and let me know if you see something utterly 
retarded or if I should change something in order for it to be useful to 
contribute back? I think I may have misplaced some code.

The rotation detector comes from: 
https://github.com/Almeros/android-gesture-detectors

Thanks!

Original comment by madsm...@gmail.com on 25 Jan 2013 at 4:13

Attachments:

GoogleCodeExporter commented 8 years ago
Updated map rotation patch. It has a more conservative bounding box calculation 
for TilesOverlay, and also adds invalidateMapCoordiates() which will invalidate 
the screen at the provided coordinates taking care of applied rotations and 
translations. In short - if you draw something at a Rect, then you can 
invalidate the screen at that same Rect using this method.

Original comment by kurtzm...@gmail.com on 6 Mar 2013 at 10:24

Attachments:

GoogleCodeExporter commented 8 years ago
Hi kurtzmarc,

Your rotation patch or your final implementation when it will be at main code 
branch, will it support both SafeCanvas and regular Canvas?
I speak for those that have problems using the SafeCanvas and prefer to have 
setUseSafeCanvas(false) in their code. Are they going to be able to use also 
your rotation solution?

I have already a working implementation based on Google instructions, but I'd 
prefer to use osmdroid native one.

Thanks!

Original comment by devemu...@gmail.com on 7 Mar 2013 at 7:24

GoogleCodeExporter commented 8 years ago
The idea is to definitely get it all working together including the 
SafeTranslatedCanvas. It's particularly difficult to anticipate every possible 
use so there will be bugs. Investigate, isolate, and report any bugs to this 
thread.

Original comment by kurtzm...@gmail.com on 11 Mar 2013 at 3:16

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Posting updated map rotation patch.

* Fixes issues with historical touch events not being rotated, but the fix only 
works in >= HONEYCOMB. If you are running < HONEYCOMB, then you should ignore 
historical touch events.
* Automatically increase the size rectangle returned by getScreenRect() to 
cover the entire visible screen. This is vital if you are doing things like 
clipping, hit-test, etc... It also makes it unnecessary to make changes to 
TilesOverlay since the new bounding box is increased to cover entire screen.
* Adds getIntrinsicScreenRect() which is useful when you want an unrotated 
screen rect. This is useful for offsetting MotionEvents for instance.

If you had a problem with "flinging" when rotated, please try this patch. I 
believe it fixes that issue!

Original comment by kurtzm...@gmail.com on 11 Mar 2013 at 3:56

Attachments:

GoogleCodeExporter commented 8 years ago
Well I tried testing your new rotation patch but there are many obstacles in 
the way, the major one being the safe canvas differences.

Using the setUseSafeCanvas(true) the tiles seem to rotate normally, but I 
cannot perform any more tests except view the tiles.
Using the setUseSafeCanvas(false) the rotation takes place with center not the 
center of the screen.

From your comment at #3: "There is an issue getSafeCanvas() and calling native 
methods on that canvas. I need to write a proxy Canvas that you can use for 
passing to other libraries - getSafeCanvas can sometimes handle this already 
but some methods aren't covered."
when can we have a better implementation of safe canvas so we can use/test it?

Original comment by devemu...@gmail.com on 13 Mar 2013 at 11:09

GoogleCodeExporter commented 8 years ago
devemux86: try this:

canvas.save();
canvas.setMatrix(canvas.getOriginalMatrix());
Canvas unsafeCanvas = canvas.getWrappedCanvas();
// Do your work with unsafeCanvas
canvas.restore();

Let me know if that works for you.

The big problem with my comment in #3 is that it's a maintenance nightmare to 
try to override every native Canvas method - there are differences in the 
methods based on API level and methods will be added as time goes on and the 
file will suffer from code rot. The only methods guaranteed to work are those 
in the ISafeCanvas interface. If we can just provide a workaround that works in 
a general sense then that would be ideal.

Original comment by kurtzm...@gmail.com on 13 Mar 2013 at 1:46

GoogleCodeExporter commented 8 years ago
Thanks kurtzmarc!

About my comment #4, I tried your code and it does the trick, canvas draws are 
visible again.
Ok now I can more thoroughly test your updated rotation patch.

Original comment by devemu...@gmail.com on 13 Mar 2013 at 5:08

GoogleCodeExporter commented 8 years ago
I re-read your comment in #4. If you want to extend a class like 
MyLocationNewOverlay and still use the "unsafe" canvas, then all you have to do 
is override the draw() method, and in there you will have the unsafe canvas. 
Just make sure you call through to super.draw() and it will do all the normal 
drawing code through the existing MyLocationNewOverlay. There is nothing 
special to do - in draw() you have a regular canvas just like before.

Original comment by kurtzm...@gmail.com on 13 Mar 2013 at 5:29

GoogleCodeExporter commented 8 years ago
Actually I want to override drawMyLocation in order to customize it. If I 
override draw() and call super.draw() then the original drawMyLocation will be 
called.

Maybe this discussion along with your code from #12 can be put at 
http://code.google.com/p/osmdroid/issues/detail?id=388 as more relevant and in 
order to help others with their problems with safe canvas?

Original comment by devemu...@gmail.com on 13 Mar 2013 at 6:34

GoogleCodeExporter commented 8 years ago
Hi kurtzmarc,

Continuing testing your updated rotation patch with both canvas types. So far 
very good. Two comments:

- With setUseSafeCanvas(false) the map rotation does not work correctly, the 
rotation takes place with center the lower right of screen. It would be 
convenient to implement this as well.
For now to be able to test it, at SafeDrawOverlay I use the code inside the "if 
(this.isUsingSafeCanvas()) {" for both types of canvas.

- I think that the degrees of map orientation are the negative one from what 
are supposed to be.
If I setMapOrientation(90) then at the upper side of screen I see the west side 
of map instead of east side.

Original comment by devemu...@gmail.com on 14 Mar 2013 at 2:01

GoogleCodeExporter commented 8 years ago
Well after more tests I can say that map rotation works very well.

Besides the 2 points I mentioned at #16, another comment is:

- It would be convenient an extra fromPixels method that uses getScreenRect 
along with getIntrinsicScreenRect.

Well done!
Are you planning to push rotation patch to main branch some time?

Original comment by devemu...@gmail.com on 15 Mar 2013 at 10:43

GoogleCodeExporter commented 8 years ago
The map rotation patch has been pushed to the trunk. I also added 
getUnsafeCanvas() as a simple way to get the original unsafe canvas from 
ISafeCanvas. We will be doing a new full release soon.

Original comment by kurtzm...@gmail.com on 21 Mar 2013 at 9:11

GoogleCodeExporter commented 8 years ago
I added some fixes for rotation when safe canvas is not being used.

Original comment by kurtzm...@gmail.com on 22 Mar 2013 at 9:09

GoogleCodeExporter commented 8 years ago
Hi kurtzmarc,

Thanks for the fixes.
Have you looked the 2nd issue I mentioned at comment #16?

I think that the rotation has to take place with degrees the -mapOrientation 
value.
Because right now the rotation is reverse from the expected one and I have to 
put at setMapOrientation the negative value from the sensor in order to fix it.

Greetings

Original comment by devemu...@gmail.com on 23 Mar 2013 at 6:22

GoogleCodeExporter commented 8 years ago
With regards to the orientation, I'd expect it to rotate clockwise. That is the 
behavior of the rotate() method for Android views and I would expect the maps 
to match that. Perhaps the use of the word "orientation" is misleading and 
should be changed to "rotation" (so, setMapsRotation()).

Original comment by kurtzm...@gmail.com on 25 Mar 2013 at 1:34

GoogleCodeExporter commented 8 years ago
The rotation patch has been integrated into the latest release and into the 
samples project. Any new issues should be put into their own ticket. Thanks for 
all the feedback!

Original comment by kurtzm...@gmail.com on 3 Apr 2013 at 9:25