peder61 / osmdroid

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

Limiting the view to an area, defined either by a rectangle or tile availability #209

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Cross posting this stackoverflow question: 
http://stackoverflow.com/questions/5403733/restricting-the-area-the-user-can-go-
to-on-mapview

Is there any facility to limit the scroll/fling behaviour to restrict the 
user's view to a specific area?

Attempting to overide MapView.scrollTo(int x, int y)  method. This successfully 
limits but fling breaks.

This feels like it should be done with more access to the MapView members.

Is this possible in the current implementation?

Original issue reported on code.google.com by gullcatc...@gmail.com on 27 Apr 2011 at 10:47

GoogleCodeExporter commented 9 years ago
See also issue 138.

Original comment by neilboyd on 28 Apr 2011 at 5:19

GoogleCodeExporter commented 9 years ago
How does fling break?

What about overriding getScrollX/getScrollY?

Original comment by kurtzm...@gmail.com on 15 May 2011 at 11:55

GoogleCodeExporter commented 9 years ago
Nevermind getScrollX/getScrollY (they're final).

However, this works:

    @Override
    protected void onScrollChanged(int pL, int pT, int pOldl, int pOldt) {
        if (pL < -500)
            scrollTo(-500, pT);
        super.onScrollChanged(pL, pT, pOldl, pOldt);
    }

So in onScrollChanged, we can catch when scrolls go outside the bounds, and 
then restrict it as we want. It appears that flinging works for me - when you 
fling and it hits the border it stops like a wall. The danger here is an 
infinite loop - calling scrollTo calls onScrollChanged.

I think it would be reasonable to include a way to set a boundingbox in the 
MapView that would restrict the map scrolling to a specific location. Patches 
welcome!

Original comment by kurtzm...@gmail.com on 16 May 2011 at 12:10

GoogleCodeExporter commented 9 years ago
Hi

I'm grappling with the similar issue. I want to restrict the viewable area on 
the map. Is there any way to set a boundingbox rectangle in the MapView?

Original comment by umer.ras...@gmail.com on 16 May 2011 at 9:45

GoogleCodeExporter commented 9 years ago
Someone had asked me to elaborate on my comment above. The code snippet I wrote 
is a just an example of how scrolling bounds could be limited. It is limited to 
an arbitrary and not realistic box, but it is designed to be a guide on how we 
can implement this.

I think being able to set a geographic bounding box is a good feature. To do 
this the bounds of that geographic area would have to be calculated for the 
current zoom level and converted into pixels and that would be the scrolling 
bounds. I would like to implement this at some point in the future, but I don't 
know when I will be able to. If someone wants to take a crack at it, then we 
welcome attaching a patch to this ticket!

Original comment by kurtzm...@gmail.com on 29 May 2011 at 5:53

GoogleCodeExporter commented 9 years ago
Update - it turns out that the better place to limit scrolling bounds is 
View.scrollTo(), and that is probably where we will put this functionality.

Original comment by kurtzm...@gmail.com on 27 Jun 2011 at 7:14

GoogleCodeExporter commented 9 years ago
See Issue 232

Original comment by kurtzm...@gmail.com on 27 Jun 2011 at 8:06

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Patch attached. Note this patch includes the N/S scrolling limit in Issue 232.

Also note, like the patch in Issue 232, this patch allows an overscroll of half 
the screen size. So each of your borders can still scroll to the center of the 
screen. Google Maps does the same thing. I believe the idea is that if you have 
something all the way in the corner of your screen, you want to be able to 
bring it to the center of the screen for interacting with it.

Original comment by kurtzm...@gmail.com on 27 Jun 2011 at 10:02

Attachments:

GoogleCodeExporter commented 9 years ago
Hello,
has anybody experienced a weird behavior of zoom with this patch? Sometimes 
when I am in one corner of the limited square and try to zoom out or zoom in 
the map is zoomed but also automatically scrolled to a different corner of the 
limited square. Have anybody seen this? I am trying to find out the reason but 
without success so far.

Original comment by VOu...@gmail.com on 17 Jul 2011 at 3:03

GoogleCodeExporter commented 9 years ago
Well, after two days of debugging all I have is this. I added a few logs into 
the toScroll() method - you can find it in the attached file. I applied the 
patch - currentyl working with 3.0.4 but also tried with trunk version and the 
effect is the same. I probably know where the bug is but don't know the project 
enough to efficiently fix it. So If somebody knows how to do it, please provide 
a fix.

As I described in my previous post, the map jumps from one side of the limiting 
square to another depending whether you are zooming in or zooming out. 

My bounding are is 
BoundingBoxE6 bbox = new BoundingBoxE6(48.922499, 14.765625, 48.458351, 
14.062500);
this.mOsmv.setScrollableAreaLimit(bbox);

Now I am in lower-left corner (ZOOM LEVEL 11) and I zoom in (to ZOOM LEVEL 12)
07-17 18:47:48.265: VERBOSE/HELP(10009): Scrolling to X=20487 Y=-80896 ZL=11 - 
WW=262144
07-17 18:47:48.265: VERBOSE/HELP(10009): Limit: minX=40960 maxX=43008 
minY=-163840 maxY=-161792 ZL=11 ZLTarget=12 ZD=10
07-17 18:47:48.265: VERBOSE/HELP(10009): !!! X=20487 minX=40960 CORRECTION:20473
07-17 18:47:48.265: VERBOSE/HELP(10009): !!! Y=-80896 maxY=-161792 
CORRECTION:-80896
07-17 18:47:48.415: VERBOSE/HELP(10009): Scrolling to X=20491 Y=-80895 ZL=11 - 
WW=262144
07-17 18:47:48.415: VERBOSE/HELP(10009): Limit: minX=40960 maxX=43008 
minY=-163840 maxY=-161792 ZL=11 ZLTarget=12 ZD=10
07-17 18:47:48.415: VERBOSE/HELP(10009): !!! X=20491 minX=40960 CORRECTION:20469
07-17 18:47:48.415: VERBOSE/HELP(10009): !!! Y=-80895 maxY=-161792 
CORRECTION:-80897
07-17 18:47:48.855: VERBOSE/HELP(10009): Scrolling to X=81920 Y=-323584 ZL=12 - 
WW=524288
07-17 18:47:48.855: VERBOSE/HELP(10009): Limit: minX=40960 maxX=43008 
minY=-163840 maxY=-161792 ZL=12 ZLTarget=12 ZD=10
07-17 18:47:48.855: VERBOSE/HELP(10009): !!! X=81920 maxX=43008 
CORRECTION:-38912
07-17 18:47:48.855: VERBOSE/HELP(10009): !!! Y=-323584 minY=-163840 
CORRECTION:159744
After the zoom the map is in upper-right corner.

Now when I do a little slide (map move without zooming) I am getting this log
07-17 18:56:24.805: VERBOSE/HELP(10009): Scrolling to X=43008 Y=-163836 ZL=12 - 
WW=524288
07-17 18:56:24.805: VERBOSE/HELP(10009): Limit: minX=40960 maxX=43008 
minY=-163840 maxY=-161792 ZL=12 ZLTarget=12 ZD=10
07-17 18:56:24.975: VERBOSE/HELP(10009): Scrolling to X=43008 Y=-163834 ZL=12 - 
WW=524288
07-17 18:56:24.975: VERBOSE/HELP(10009): Limit: minX=40960 maxX=43008 
minY=-163840 maxY=-161792 ZL=12 ZLTarget=12 ZD=10

I think the problem is following: at 18:47:48.855 I am getting very wierd 
coordinates to move to (X=81920 Y=-323584 ZL=12). Before the zoom it was 
(X=20491 Y=-80895 ZL=11) and after the move it is (Scrolling to X=43008 
Y=-163836 ZL=12). So the question is: why is it so high number, and why it is 
sent only once? This high numbers are exceeding boundaries of limiting square 
and that's why X and Y are corrected to maxX and minY - upper-right corner.

Does it make sense to anybody of you?
Thank you very much
Vojtech

Original comment by VOu...@gmail.com on 17 Jul 2011 at 5:30

Attachments:

GoogleCodeExporter commented 9 years ago
And I forgot something important - it is happening only sometimes. Usually it 
works correctly.

Original comment by VOu...@gmail.com on 17 Jul 2011 at 5:48

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Can we limit the no of tiles to be loaded. For example, if I need to load only 
a single tile( indoor map (.png) at zero zoom level) can I limit the no .of 
tiles?

Original comment by susheel....@gmail.com on 6 Aug 2011 at 2:46

GoogleCodeExporter commented 9 years ago
Issue 266 has been merged into this issue.

Original comment by neilboyd on 12 Oct 2011 at 9:27

GoogleCodeExporter commented 9 years ago
What is a patch sir? How can I use file patches? 

I have a small map of a city display on Android. When the user scrolls beyond 
the boundaries of the city map it will just display a grey empty screen. How do 
I get the total map size of my small map? What I see on my /tiles/Manpik 
directory are just .png images but when my program runs it shows the map.

What is the first step that I should do.

Original comment by lordzden...@gmail.com on 12 Oct 2011 at 2:23

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Sir, can you please modify your codes or patches that is understandable to us 
beginners. Where can I place the super.scrollTo(x,y) method, in the onCreate()? 
How do i get the values of x and y, should i declared it global int?

Sir, where should i place this code:
while (x < -worldSize_2)
            x += (worldSize_2 * 2);
        while (x > worldSize_2)
            x -= (worldSize_2 * 2);
        if (y < -worldSize_2)
            y = -worldSize_2;
        if (y > worldSize_2)
            y = worldSize_2;

I am using offline map. Thank you sir for your time.

Original comment by lordzden...@gmail.com on 25 Oct 2011 at 4:47

GoogleCodeExporter commented 9 years ago
The patch works but we need to limit the (x,y) based on pending zoom level, not 
on current zoom level.

Original comment by qbao.ngu...@gmail.com on 26 Oct 2011 at 8:27

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
As stated in comment #11 strange behavior, IMO that is occurring when user 
double taps. When that happens scrollTo is called 2 times. First time it is 
called from computeScroll because of redraw (problem) because the zoom level is 
not yet changed. Second call is from onAnimate and that one send the correct x 
and y parameters. I solved this by comparing current and target zoom level in 
computeScroll method.

@Override
public void computeScroll() {
    if (mScroller.computeScrollOffset()) {
        if (mScroller.isFinished()) {
            // This will facilitate snapping-to any Snappable points.
            setZoomLevel(mZoomLevel);
        } else {
            /* correction for double tap */
            int targetZoomLevel = getZoomLevel();
            if (targetZoomLevel == mZoomLevel)
                scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
        }
        postInvalidate(); // Keep on drawing until the animation has
        // finished.
    }
}

Home someone will find this helpful.

Original comment by zoran....@gmail.com on 18 Nov 2011 at 11:45

GoogleCodeExporter commented 9 years ago
after i applied the patch , it limits the scroll area, but when i scroll to 
left, after reaching scroll limit..it scrolls a bit upward, how do i prevent 
that behaviour???

Original comment by pra...@wcities.com on 11 Jan 2012 at 12:59

GoogleCodeExporter commented 9 years ago
For the comment #11 strange behavior on double tap, I solved the issue by 
changing the getZoomLevel() for the zoomDiff in the original patch of comment 
#9 to getZoomLevel(false)
final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - getZoomLevel(false);

Original comment by devemu...@gmail.com on 20 Jul 2012 at 9:04

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Hi everyone,

For those of use using the .jar or otherwise not that familiar with patches, I 
cobbled together a subclass of MapView that supports limiting the user's view 
to a specific area. Details on how to use it, if not obvious, can be found at 
http://www.sieswerda.net/2012/08/15/boundedmapview-a-mapview-with-limits/

Keep up the great work!

Regards,
melle

--
apparently I forgot to add the .java, so here goes again

Original comment by melle.si...@gmail.com on 16 Aug 2012 at 8:35

Attachments:

GoogleCodeExporter commented 9 years ago
Hey melle nice class thank you! It's working well appart from the zoom. I'm 
testing it and it's possible to zoom outside the area. Is this normal?

Original comment by romain.p...@gmail.com on 20 Aug 2012 at 1:34

GoogleCodeExporter commented 9 years ago
OMG, more than one year and still no solution ?
Your patch way is far too complicated.
The BoundedMapView class don't work with zoom.
So, what do we do ????

Original comment by exotic.e...@gmail.com on 10 Oct 2012 at 11:49

GoogleCodeExporter commented 9 years ago
I use now the 3.0.8.jar, but it still don't work.
It it the same for everybody ?

Original comment by exotic.e...@gmail.com on 10 Oct 2012 at 12:57

GoogleCodeExporter commented 9 years ago
Hi Romain, sorry for the delayed response. Your usecase is simply not yet 
handled by my code. I'll see if I can get around to fixing that the coming week.

Original comment by melle.si...@gmail.com on 27 Oct 2012 at 9:35

GoogleCodeExporter commented 9 years ago
Issue 250 has been merged into this issue.

Original comment by kurtzm...@gmail.com on 22 Jan 2013 at 3:42

GoogleCodeExporter commented 9 years ago
I am attaching an updated version of the patch. If applied against the trunk, 
all zooming issues should be resolved by now. Note that this patch does not 
contain the N/S scrolling patch in issue 232.

Original comment by kurtzm...@gmail.com on 22 Jan 2013 at 8:18

Attachments:

GoogleCodeExporter commented 9 years ago
Nice job with the updated patch!
In my opinion there is no need for overscroll of half the screen size as it was 
happened with the previous patch (which we had to change to stop overscroll).
Because if we make a custom map and set a view limit, then outside the limit 
there are no tiles to show, only gray area. At least if there is going to be an 
overscroll at the future let it be optional for those who don't need it.

Original comment by devemu...@gmail.com on 23 Jan 2013 at 8:49

GoogleCodeExporter commented 9 years ago
Does someone know how to limit the map without overscroll? I'm trying to 
understand Melle's code, but without any comment it's hard through.

Original comment by okaa....@gmail.com on 8 Mar 2013 at 8:54

GoogleCodeExporter commented 9 years ago
The patch for limited scroll area is now in the trunk. It does not include 
overscroll. Note that it does not limit zooming, so a user can zoom out to an 
area that is larger than the limited area but they can not scroll and the 
limited area always stays centered.

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

GoogleCodeExporter commented 9 years ago
Well done!
May be you can make mScrollableAreaLimit public or implement its public get 
method at MapView?
This rect is sometimes quite useful.

Original comment by devemu...@gmail.com on 4 Apr 2013 at 6:40

GoogleCodeExporter commented 9 years ago
What about returning the original BoundingBoxE6 since that will make more sense 
to users?

Original comment by kurtzm...@gmail.com on 4 Apr 2013 at 2:56

GoogleCodeExporter commented 9 years ago
The original BoundingBoxE6 isn't it the one the user sets with 
setScrollableAreaLimit? So he knows it already.
But the calculations made in setScrollableAreaLimit in order to produce the 
mScrollableAreaLimit are also useful. For example I use mScrollableAreaLimit to 
modify offline tilesource's min zoom depending screen resolution.

Original comment by devemu...@gmail.com on 4 Apr 2013 at 3:13

GoogleCodeExporter commented 9 years ago
As you probably know, we do those calculations to form the mScrollableAreaLimit 
to save CPU cycles later on and I'd like to hide that from the user. The 
average user doesn't have any need for the "intermediate" points that we 
calculate and wouldn't know what to do with them. Advanced users such as 
yourself can calculate these values easily and use them in their own classes. 
If you really want it, mScrollableAreaLimit is a protected field so you could 
subclass and get access to it that way.

Original comment by kurtzm...@gmail.com on 4 Apr 2013 at 3:57

GoogleCodeExporter commented 9 years ago
Note that in r1197 we added a simple way to set min/max zoom levels on-the-fly. 
See issue 418 for additional info.

Original comment by kurtzm...@gmail.com on 4 Apr 2013 at 6:31

GoogleCodeExporter commented 9 years ago
This issue is complete and can be closed.

Original comment by kurtzm...@gmail.com on 2 May 2013 at 1:09

GoogleCodeExporter commented 9 years ago
You can simply call the method mapView.setScrollableAreaLimit(BoundingBoxE6)
to set the scrollable area

Original comment by stenicod...@gmail.com on 16 Jun 2014 at 11:57