Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Limit Scrolling on offline maps, in Android

I got these piece of codes or patches from osmdroid, and I decided to ask for your help guys because i don't have the enough knowledge to combine these codes to come up with on a solution on my problem, Scrolling limit on an offline map. I searched across the web, and modified tutorials. Honestly I tried to modify these codes but i have not found any progress. Basically I have an offline map from mapnik, and a few overlays. I don't know where to properly place these set of codes. Your ideas and modification will be a great help and also helps me keep going with my project and I guess your answers will definitely help others with the same problem as mine in the future. I know this is to much. Thank you sirs for your time, and God Bless.

public void onCreate(Bundle savedInstanceState) {
        ...
        ...
        m_mapView = (MapView) findViewById(R.id.mapview);
        m_mapView.setTileSource(TileSourceFactory.MAPNIK);
    }

First: BoundingBox

BoundingBoxE6 bbox = new BoundingBoxE6(9.37398, 123.33761, 9.23948, 123.25035);
this.setScrollableAreaLimit(bbox);

Second: LimitScrollToGeographicArea.patch

Index: MapView.java
===================================================================
--- MapView.java    (revision 944)
+++ MapView.java    (working copy)
@@ -103,6 +103,8 @@

    protected MapListener mListener;

+   protected Rect mScrollableAreaLimit;
+
    // for speed (avoiding allocations)
    private final Matrix mMatrix = new Matrix();
    private final MapTileProviderBase mTileProvider;
@@ -505,6 +507,36 @@
        mMapOverlay.setUseDataConnection(aMode);
    }

+   /**
+    * Set the map to limit it's scrollable view to the specified BoundingBoxE6. Note that, like
+    * North/South bounds limiting, this allows an overscroll of half the screen size. This means
+    * each border can be scrolled to the center of the screen.
+    * 
+    * @param boundingBox
+    *            A lat/long bounding box to limit scrolling to, or null to remove any scrolling
+    *            limitations
+    */
+   public void setScrollableAreaLimit(BoundingBoxE6 boundingBox) {
+       final int worldSize_2 = TileSystem.MapSize(MapViewConstants.MAXIMUM_ZOOMLEVEL) / 2;
+
+       // Clear scrollable area limit if null passed.
+       if (boundingBox == null) {
+           mScrollableAreaLimit = null;
+           return;
+       }
+
+       // Get NW/upper-left
+       final Point upperLeft = TileSystem.LatLongToPixelXY(boundingBox.getLatNorthE6() / 1E6,
+               boundingBox.getLonWestE6() / 1E6, MapViewConstants.MAXIMUM_ZOOMLEVEL, null);
+       upperLeft.offset(-worldSize_2, -worldSize_2);
+
+       // Get SE/lower-right
+       final Point lowerRight = TileSystem.LatLongToPixelXY(boundingBox.getLatSouthE6() / 1E6,
+               boundingBox.getLonEastE6() / 1E6, MapViewConstants.MAXIMUM_ZOOMLEVEL, null);
+       lowerRight.offset(-worldSize_2, -worldSize_2);
+       mScrollableAreaLimit = new Rect(upperLeft.x, upperLeft.y, lowerRight.x, lowerRight.y);
+   }
+
    // ===========================================================
    // Methods from SuperClass/Interfaces
    // ===========================================================
@@ -772,10 +804,26 @@
    //I am confused with these codes below, where should I declare it? Int x, y in the          onCreate method?

            x += (worldSize_2 * 2);
        while (x > worldSize_2)
            x -= (worldSize_2 * 2);
-       while (y < -worldSize_2)
-           y += (worldSize_2 * 2);
-       while (y > worldSize_2)
-           y -= (worldSize_2 * 2);
+       if (y < -worldSize_2)
+           y = -worldSize_2;
+       if (y > worldSize_2)
+           y = worldSize_2;
+
+       if (mScrollableAreaLimit != null) {
+           final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - getZoomLevel();
+           final int minX = mScrollableAreaLimit.left >> zoomDiff;
+           final int minY = mScrollableAreaLimit.top >> zoomDiff;
+           final int maxX = mScrollableAreaLimit.right >> zoomDiff;
+           final int maxY = mScrollableAreaLimit.bottom >> zoomDiff;
+           if (x < minX)
+               x = minX;
+           else if (x > maxX)
+               x = maxX;
+           if (y < minY)
+               y = minY;
+           else if (y > maxY)
+               y = maxY;
+       }
        super.scrollTo(x, y);

        // do callback on listener

Another one:

 scrollToMethod
public void scrollTo(int x, int y) {
        int curZoomLevel = mZoomLevel;
        final int worldSize_2 = TileSystem.MapSize(curZoomLevel) / 2;
        Log.v("HELP", "Scrolling to X=" + x + " Y=" + y + " ZL=" + curZoomLevel + " - WW="+worldSize_2);

        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;

        if (mScrollableAreaLimit != null) {
                int targetZoomLevel = getZoomLevel();
                final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - targetZoomLevel;
                //final int zoomDiff = MapViewConstants.MAXIMUM_ZOOMLEVEL - mZoomLevel;
                final int minX = mScrollableAreaLimit.left >> zoomDiff;
                final int minY = mScrollableAreaLimit.top >> zoomDiff;
                final int maxX = mScrollableAreaLimit.right >> zoomDiff;
                final int maxY = mScrollableAreaLimit.bottom >> zoomDiff;

                Log.v("HELP", "Limit: minX=" + minX + " maxX=" + maxX + " minY=" + minY + " maxY=" + maxY + " ZL=" + curZoomLevel + " ZLTarget="+ targetZoomLevel + " ZD="+zoomDiff);

                if (x < minX) {
                    Log.v("HELP", "!!! X=" + x + " minX=" + minX + " CORRECTION:" + (minX-x));
                    x = minX;
                } else if (x > maxX) {
                    Log.v("HELP", "!!! X=" + x + " maxX=" + maxX + " CORRECTION:" + (maxX-x));
                    x = maxX;
                }

                if (y < minY) {
                    Log.v("HELP", "!!! Y=" + y + " minY=" + minY + " CORRECTION:" + (minY-y));
                    y = minY;
                } else if (y > maxY) {
                    Log.v("HELP", "!!! Y=" + y + " maxY=" + maxY + " CORRECTION:" + (maxY-y));
                    y = maxY;   
                }
        }

        super.scrollTo(x, y);

        // do callback on listener
        if (mListener != null) {
            final ScrollEvent event = new ScrollEvent(this, x, y);
            mListener.onScroll(event);
        }
    }
like image 866
rahstame Avatar asked Oct 26 '11 03:10

rahstame


1 Answers

First of all use this command on your terminal:

svn checkout http://osmdroid.googlecode.com/svn/branches/release_3_0_5

It will download a stable version

Then follow this to import contents of the folder you downloaded:

In Eclipse, right-click on the Package area, and select the following:

click on Import...
select General -> Existing Projects into Workspace
click Next
click Browse...
select the checked out projects' directories
    osmdroid-android (import as a java project)
    OSMMapTilePackager (import as a java project)
    OpenStreetMapViewer (mport as an android project) 
click OK
click Finish
  1. Now open this java file--> osmdroid-android/src/org/osmdroid/view/MapView.java
  2. Now as stated in this patch file, modify MapView.java ( add code wherever + , remove code wherever -)
  3. Also modify computeScroll() in MapView.java as stated here
  4. Now, to use this modified .java file, you need to create a new jar file that you can include in your project Here is a step by step process to create jar

  5. Add this newly created jar file to your project's build path and you are ready to use your modified jar

  6. Now use this in your activity class:

    BoundingBoxE6 bbox  = new BoundingBoxE6(limit north, limit east, limit south, limit west);          
    mapView.setScrollableAreaLimit(bbox);
    
like image 116
Pratik Bhat Avatar answered Sep 28 '22 04:09

Pratik Bhat