liangzi7 / osmdroid

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

Map shakes at high zoom when mapOrientation isn't zero #437

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Register a sensor listener which will get device bearing
2. Rotate the map periodically with MapView.setMapOrientation
3. Zoom to a high zoom level (18-19+)

What is the expected output? What do you see instead?
I expect the rotation to be smooth. Instead, the map visibly shakes.

What version of the product are you using? On what operating system?
Experienced ever since I started using map rotation (~2 months back). Still 
present in rev 1240.

Please provide any additional information below.

Looking into it, it seems that the problem is that the drawing process is very 
sensitive to changes in bearing. Passing only an integer to setMapOrientation 
and rotating the map slowly will show that the map moves in all directions and 
doesn't stay properly centered.

My guess is that somewhere in the code the center of the drawing area is 
improperly determined (or is subject to rounding errors).

In MapView, if the canvas rotation part is commented out (lines 1045-1046) the 
map won't rotate, but will still shake.

Tried drawing a map with no Overlays - still happens.

SafeDraw is enabled.

Hardware acceleration is enabled, but the issue is present even with it 
disabled.

Original issue reported on code.google.com by RandomA...@gmail.com on 1 Jun 2013 at 3:53

GoogleCodeExporter commented 9 years ago
This is an interesting problem. It sounds like you are adjusting the maps so 
that they always face north, correct? So as I turn around the maps turn with 
me. This would make a great sample for the demo app.

Try turning off SafeDraw and see if that helps. I would leave hardware 
acceleration off too for testing. It does sound like a rounding error (which 
the SafeDraw essentially aims to fix) but it could be something else.

Original comment by kurtzm...@gmail.com on 1 Jun 2013 at 4:40

GoogleCodeExporter commented 9 years ago
Yes, the idea is that the map turns as the user rotates and it works and looks 
great (the speed of the Nexus makes for a great experience).

However, the illusion of smoothness gets completely ruined by the jerkiness.

Turning off SafeCanvas doesn't help. It actually makes things worse, as there 
are black lines between the tiles and all the tiles start to shake 
independently.

Hardware acceleration doesn't make a difference either, except the performance 
penalty when it's off.

As for the demo app sample, I can write one up once this is done, as the 
concept is pretty straightforward - you register your Activity as a 
SensorEventListener and simply pass the bearing received in onSensorChanged to 
the MapView.

I can't say I have an idea of where to look next. The issue isn't in the 
rotation of the canvas. It isn't in the overlays and it isn't in GeometryMath. 
I don't think it's in the Projection class either, as the values used in 
dispatchDraw are pretty much constant.

Original comment by RandomA...@gmail.com on 1 Jun 2013 at 4:50

GoogleCodeExporter commented 9 years ago
Hi,

Just a thought..
Is the compass sensor of your device working normally?

Only the map rotates abnormally or also the compass drawable is jumping to 
random orientations?

You can check this also by trying device's compass / map rotation with another 
map application e.g. Google Maps.

Because I have been seen devices where their compass / map was rotating 
randomly and the reason was that the sensor was sending wrong values all the 
time. Probably a compass calibration could help if this is the case.

Regards.

Original comment by devemu...@gmail.com on 1 Jun 2013 at 8:02

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
The app has been tested on around a dozen devices and they all exhibit the same 
behavior, so I don't think it's a compass issue. Although I use 
SENSOR_DELAY_FASTEST, filtering the input by trimming the decimal part will 
make the map less prone to random shake. However, when rotating it, the skips 
are noticeable.

Attached is a simple Activity which will reproduce the error. Keep in mind that 
the default tile provider doesn't support high zoom levels so the issue might 
not be obvious. However, if you pay close attention to the map at the highest 
zoom, you will notice that it is shaking.

I added a "toggle filter" button which will strip the decimal part from the 
orientation. When this is enabled, rotating the device will show that the pivot 
changes slightly when rotating.

Here is a video showing the issue in my app at zoom level 19 (much more 
obvious):
http://www.youtube.com/watch?v=8qqhqAdqrIg

The device and the camera weren't moved at all.

Original comment by RandomA...@gmail.com on 1 Jun 2013 at 4:09

Attachments:

GoogleCodeExporter commented 9 years ago
Can you update to the latest trunk and try it again? I made a change that may 
help this issue.

Original comment by kurtzm...@gmail.com on 11 Jun 2013 at 2:19

GoogleCodeExporter commented 9 years ago
Tried it out. The issue is still there, though the pattern seems to have 
changed.

Original comment by RandomA...@gmail.com on 11 Jun 2013 at 3:48

GoogleCodeExporter commented 9 years ago
Have the same problem with MyLocationNewOverlay at 21-22 zoom level. The person 
on map snakes even when i simply move map at any direction.

If I change canvas.drawBitmap(mPersonBitmap, mDirectionRotater, mPaint) to 
canvas.drawBitmap(mPersonBitmap, x, y, mPaint) then snaking stops.

Looks like sMatrix.postTranslate(xOffset, yOffset) does not work there because 
of insufficient precision of float matrices.

Original comment by ls.illar...@gmail.com on 29 Jun 2013 at 6:43

GoogleCodeExporter commented 9 years ago
We need to stop using the matrix and let the safe canvas handle the 
translation, rotation and scaling since it does it correctly.

Original comment by kurtzm...@gmail.com on 12 Jul 2013 at 8:35

GoogleCodeExporter commented 9 years ago
This issue was updated by revision r1252.

Use safe canvas to do all translation, rotation and scaling rather than the 
matrix. Fixes issues with shaking at high levels.
Fix rotation method in SafeTranslatedCanvas to do it in a "safe" way.
Update issue 447
Prevent location icon from scaling incorrectly with rotation.

Original comment by kurtzm...@gmail.com on 12 Jul 2013 at 8:37

GoogleCodeExporter commented 9 years ago
Please test and report back!

Original comment by kurtzm...@gmail.com on 12 Jul 2013 at 8:38

GoogleCodeExporter commented 9 years ago
Issue still (r1254) seems to persist in my project with the same symptoms - 
when rotation is enabled, the map shakes at high zoom levels. Might be worth 
mentioning that the whole canvas seems to translate, not just the overlays.

Not sure if the pattern of the shaking has changed, though.

Also, if it was fixed in an another component, shouldn't the changes in r1241 
eventually be reverted?

Original comment by RandomA...@gmail.com on 17 Jul 2013 at 12:57

GoogleCodeExporter commented 9 years ago
Okay will look into this again and try to reproduce.

Original comment by kurtzm...@gmail.com on 17 Jul 2013 at 12:21

GoogleCodeExporter commented 9 years ago
So the issue is that in MapView.dispatchDraw() where the rotation is applied it 
is using a rotate() method that takes floats. Maybe we have to re-apply 
rotation in the SafeDrawOverlay?

Original comment by kurtzm...@gmail.com on 18 Jul 2013 at 6:37

GoogleCodeExporter commented 9 years ago
This issue was updated by revision r1255.

Since unsafe canvas rotation occurs in MapView, then in SafeDrawOverlay we have 
to unsafely un-rotate the canvas, and then re-rotate using the safe canvas. 
This should fix map shaking at high zoom levels with rotation.

Original comment by kurtzm...@gmail.com on 18 Jul 2013 at 7:20

GoogleCodeExporter commented 9 years ago
Try it again and let me know what results you get. I can't tell if it's fixed 
or just not as bad.

Original comment by kurtzm...@gmail.com on 18 Jul 2013 at 7:21

GoogleCodeExporter commented 9 years ago
The changes in r1241 fix shaking in the maps without rotation at high zoom 
levels. That fix is still necessary and is separate from this issue.

Original comment by kurtzm...@gmail.com on 18 Jul 2013 at 7:22

GoogleCodeExporter commented 9 years ago
Looks much better now (doesn't shake randomly when standing still), but the 
pivot still changes slightly depending on angle.

My guess is that the center of the map gets determined wrong, as all elements 
get offset for the same amount. 

Original comment by RandomA...@gmail.com on 19 Jul 2013 at 11:36

GoogleCodeExporter commented 9 years ago
Hello!
I have same problems in my application. I use the RotationGestureOverlay from 
sample project.
If I rotate map with two fingers and then stop fingers - the map starts shaking 
on every zoomlevel.
I'm using the latest trunk snapshot.

Original comment by yuri.den...@gmail.com on 1 Nov 2013 at 5:42