6

Sometimes when trying to get the Latitude span or Longitude span of a mapview with getLatitudeSpan() and getLongitudeSpan() I get 0 and 360*1E6 respectively. This doesn't happen always but it is a problem, has anybody got this problem? Any workarounds? I tried using getProjection() too but I get the same problem. Here is the piece of code:

MapView mapView = (MapView) findViewById(R.id.mapview);
int lat = mapView.getLatitudeSpan(); // sometimes returns 0
int long = mapView.getLongitudeSpan(); // sometimes returns 360*1E6
Jan S.
  • 10,328
  • 3
  • 31
  • 36
  • When are you executing this code? You won't have a latitude or longitude span until you set a center point and zoom level and the map is rendered on the screen. – CommonsWare Apr 19 '10 at 13:14
  • I tried this code in onCreate, and inside an AsyncTask that I use to download some data. I set the zoom level and center on onCreate. I have noticed that this happens most of the time the first time I run my app, after when I use back and get to the activity again I normally don't run into this problem. – Jan S. Apr 19 '10 at 13:41

4 Answers4

8

I have gone through this exact same problem and the solutions stated above works. However I would like to present a more clear implementation for all the beginners out there.

Define a view variable for your map: private MapView mapView;

And assign the mapview:

mapView = (MapView) findViewById(R.id.mapview);

Add the following method:

    /**
     * Wait for mapview to become ready.
     */
    private Runnable waitForMapTimeTask = new Runnable() {
        public void run() {
            // If either is true we must wait.
            if(mapView.getLatitudeSpan() == 0 || mapView.getLongitudeSpan() == 360000000)
                mapView.postDelayed(this, TIME_TO_WAIT_IN_MS);
        }
    };

In your onCreate/onResume add the following prior to calling getLatitudeSpan:

mapView.postDelayed(waitForMapTimeTask, TIME_TO_WAIT_IN_MS);

And you are good to go :)

slott
  • 3,266
  • 1
  • 35
  • 30
3

I would detect the condition and schedule your work to try again after a few hundred milliseconds. AFAIK, those values will eventually become available, but they may be rather timing-dependent. In theory, they should be calculated after you have set the center and set the zoom, but I suspect that they really aren't being calculated until after the MapView is rendered, and possibly not until some map data from the Internet is downloaded.

So, isolate your code that depends on those spans into a method. Call that method from onCreate() and the AsyncTask, probably as you're doing today. But, add detection logic to find the invalid values, then call postDelayed() on your MapView (or some other View) to invoke your method again after a few hundred milliseconds if the values are invalid. You may also need to add some sort of counter so you don't do this postDelayed() stuff indefinitely.

This, of course, is a hack. But, with the Google Maps component not being open source, it is difficult to come up with something more solid.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • is this really the best solution to getting onscreen coordinates when a mapview first loads? seems like such a hack... Is there really no callback? – edthethird Apr 25 '13 at 19:25
  • @edthethird: Since Maps V1 is now deprecated, you should be looking at Maps V2. – CommonsWare Apr 25 '13 at 19:27
  • hmm I am, but I still have the same problem-- trying to call .getProjection() in onResume() and it is empty.. Looking for callback ideally but ended up waiting with async task – edthethird Apr 25 '13 at 21:08
2

I have been messing around with this... and having a mapview in a tabbed activity... the values are not initialized until onResume()... I verified this by putting:

        final Handler mHandler = new Handler();
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                latSpan = mapView.getLatitudeSpan();
                lngSpan = mapView.getLongitudeSpan();
                if ((latSpan == 0) && (lngSpan == 360000000)) {
                    count++;
                    System.out.println("here we go again! " + count);
                    mHandler.postDelayed(this, 100);
                }       
            }
        }, 100);

In Various locations... in onCreate() and onStart() it will go indefinitely (until I switch to that tab), in onResume() it gets correct values immediately.

ibash
  • 1,477
  • 17
  • 31
0

getLatitudeSpan and getLongitudeSpan only works to give you the spans for the visible portion of the map. So if you call them in onCreate() the map will not always have been displayed yet. Call them in onStart() instead and you should be fine.

TheContstruct
  • 514
  • 5
  • 4