Android GoogleMaps V2 MarkerDemo IllegalStateException no included points
Asked Answered
T

2

4

I am creating a customised implementation of the MarkerDemo provided for GoogleMaps V2. I have a strange error whereby I am providing LatLng values to a LatLngBounds.Builder instance and then passing it as a variable with .build. When I run the app in Debug mode through Eclipse, the Map loads. When I run it normally through Eclipse, there is an IllegalStateException thrown with "no included points" as a message. Can anyone help?

Here is some code to assist.

public class MyActivity extends android.support.v4.app.FragmentActivity
        implements OnMarkerClickListener, OnInfoWindowClickListener,
        OnMarkerDragListener {

    private HashMap<DataItem, ArrayList<DataItem>> mUserLocations = new
             HashMap<DataItem, ArrayList<DataItem>>();
    private ArrayList<DataItem> mFeedData;
    private NetworkingHandler mHandler = new NetworkingHandler("tag");
    private GoogleMap mMap;
    private final String DOWNLOAD_USER_LOCATIONS_URL =
               "http://www.myfeedurllocation.com/page.php";

    @Override
    public void onCreate(Bundle savedBundleInstance) {
        super.onCreate(savedBundleInstance);
        setContentView(R.layout.activity_myactivitylayout);
        downloadUserLocations();
        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the
        // map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        // Hide the zoom controls as the button panel will cover it.
        mMap.getUiSettings().setZoomControlsEnabled(false);
        mMap.getUiSettings().setRotateGesturesEnabled(true);
        mMap.getUiSettings().setCompassEnabled(true);
        // Add lots of markers to the map.
        addMarkersToMap();
        // Setting an info window adapter allows us to change the both the
        // contents and look of the
        // info window.
        mMap.setInfoWindowAdapter(new CustomInfoWindowAdapter());
        // Set listeners for marker events. See the bottom of this class for
        // their behavior.
        mMap.setOnMarkerClickListener(this);
        mMap.setOnInfoWindowClickListener(this);
        mMap.setOnMarkerDragListener(this);
        // Pan to see all markers in view.
        // Cannot zoom to bounds until the map has a size.
        final View mapView = getSupportFragmentManager().findFragmentById(
            R.id.map).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(
                new OnGlobalLayoutListener() {

                    @SuppressLint("NewApi")
                    // We check which build version we are using.
                    @Override
                    public void onGlobalLayout() {
                        LatLngBounds.Builder bounds = new LatLngBounds.Builder();
                        for (DataItem location : mUserLocations.keySet()) {
                            bounds.include(new LatLng(
                                    Double.parseDouble(location.mData
                                            .get("latitude")), Double
                                            .parseDouble(location.mData
                                                    .get("longitude"))));
                        }
                        mapView.getViewTreeObserver()
                                .removeGlobalOnLayoutListener(this);
                        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(
                            bounds.build(), 80));
                    }
                });
        }
    }

    private void addMarkersToMap() {
        for (DataItem location : mUserLocations.keySet()) {
            StringBuilder stringBuilder = new StringBuilder();
            for (DataItem user : mUserLocations.get(location)) {
                stringBuilder.append("\n" + user.mData.get("textToAdd"));
            }
            mMap.addMarker(new MarkerOptions()
                    .position(
                        new LatLng(Double.parseDouble(location.mData
                                .get("latitude")), Double
                                .parseDouble(location.mData.get("longitude"))))
                    .title(location.mData.get("textToAdd"))
                    .snippet(stringBuilder.toString())
                    .icon(
                        BitmapDescriptorFactory
                                .defaultMarker(BitmapDescriptorFactory.HUE_RED)));
        }
    }

    private void downloadUserLocations() {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                try {
                    mFeedData = mHandler
                            .returnDataArrayList(DOWNLOAD_USER_LOCATIONS_URL);
                    for (DataItem item : mFeedData) {
                        // create location
                        DataItem location = new DataItem();
                        location.mTags.add("locationText1");
                        location.mTags.add("latitude");
                        location.mTags.add("longitude");
                        location.mData.put("locationText1",
                            item.mData.get("locationText1"));
                        location.mData.put("latitude",
                            item.mData.get("latitude"));
                        location.mData.put("longitude",
                            item.mData.get("longitude"));
                        // create user
                        DataItem user = new DataItem();
                        user.mTags.add("userText1");
                        user.mTags.add("userText2");
                        user.mData
                                .put("userText1", item.mData.get("userText1"));
                        user.mData
                                .put("userText2", item.mData.get("userText2"));
                        if (mUserLocations.keySet().contains(location)) {
                            mUserLocations.get(location).add(user);
                        } else {
                            mUserLocations.put(location,
                                new ArrayList<DataItem>());
                            mUserLocations.get(location).add(user);
                        }
                    }
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (ParserConfigurationException e) {
                    e.printStackTrace();
                } catch (SAXException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(r).start();
    }

    @Override
    public void onMarkerDrag(Marker arg0) {}

    @Override
    public void onMarkerDragEnd(Marker arg0) {}

    @Override
    public void onMarkerDragStart(Marker arg0) {}

    @Override
    public void onInfoWindowClick(Marker arg0) {}

    @Override
    public boolean onMarkerClick(Marker arg0) {
        return false;
    }

    class CustomInfoWindowAdapter implements InfoWindowAdapter {

        private final RadioGroup mOptions;
        // These a both viewgroups containing an ImageView with id "badge" and
        // two TextViews with id
        // "title" and "snippet".
        private final View mWindow;
        private final View mContents;

        CustomInfoWindowAdapter() {
            mWindow = getLayoutInflater().inflate(R.layout.custom_info_window,
                null);
            mContents = getLayoutInflater().inflate(
                R.layout.custom_info_contents, null);
            mOptions = (RadioGroup) findViewById(R.id.custom_info_window_options);
        }

        @Override
        public View getInfoWindow(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_window) {
                // This means that getInfoContents will be called.
                return null;
            }
            render(marker, mWindow);
            return mWindow;
        }

        @Override
        public View getInfoContents(Marker marker) {
            if (mOptions.getCheckedRadioButtonId() != R.id.custom_info_contents) {
                // This means that the default info contents will be used.
                return null;
            }
            render(marker, mContents);
            return mContents;
        }

        private void render(Marker marker, View view) {
            int badge = R.drawable.map_pin;
            // Use the equals() method on a Marker to check for equals. Do not
            // use ==.
            ((ImageView) view.findViewById(R.id.badge)).setImageResource(badge);
            String title = marker.getTitle();
            TextView titleUi = ((TextView) view.findViewById(R.id.title));
            if (title != null) {
                // Spannable string allows us to edit the formatting of the
                // text.
                SpannableString titleText = new SpannableString(title);
                titleText.setSpan(new ForegroundColorSpan(Color.RED), 0,
                    titleText.length(), 0);
                titleUi.setText(titleText);
            } else {
                titleUi.setText("");
            }
            String snippet = marker.getSnippet();
            TextView snippetUi = ((TextView) view.findViewById(R.id.snippet));
            if (snippet != null) {
                SpannableString snippetText = new SpannableString(snippet);
                snippetText.setSpan(new ForegroundColorSpan(Color.MAGENTA), 0,
                    10, 0);
                snippetText.setSpan(new ForegroundColorSpan(Color.BLUE), 12,
                    21, 0);
                snippetUi.setText(snippetText);
            } else {
                snippetUi.setText("");
            }
        }
    }
}

Here is my stack trace.

02-14 15:23:50.219: E/AndroidRuntime(8952): FATAL EXCEPTION: main
02-14 15:23:50.219: E/AndroidRuntime(8952): java.lang.IllegalStateException: no included points
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.google.android.gms.internal.at.a(Unknown Source)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.google.android.gms.maps.model.LatLngBounds$Builder.build(Unknown Source)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.mypackage.MyActivity$1.onGlobalLayout(MyActivity.java:109)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:682)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1850)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1112)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4472)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer.doFrame(Choreographer.java:525)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Handler.handleCallback(Handler.java:615)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Handler.dispatchMessage(Handler.java:92)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.os.Looper.loop(Looper.java:137)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at android.app.ActivityThread.main(ActivityThread.java:4898)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at java.lang.reflect.Method.invokeNative(Native Method)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at java.lang.reflect.Method.invoke(Method.java:511)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
02-14 15:23:50.219: E/AndroidRuntime(8952):     at dalvik.system.NativeStart.main(Native Method)
Throve answered 14/2, 2013 at 15:19 Comment(0)
T
5

Don't bother with the builder just do.

LatLngBounds mapBounds;
for (DataItem location : mUserLocations.keySet()) {
    if (mapBounds==null) {
        LatLng point = new LatLng(Double.parseDouble(location.mData.get("latitude")), Double.parseDouble(location.mData.get("longitude")))
        mapBounds =new LatLngBounds(point, point);
    } else {
        mapBounds = mapBounds.including(new LatLng(Double.parseDouble(location.mData.get("latitude")), Double.parseDouble(location.mData.get("longitude"))));
    }
}
Trochee answered 14/2, 2013 at 15:44 Comment(12)
I wonder, could you explain why nothing is being drawn to the map?Throve
Also, Im not sure the logic of your code works quite as expected - mapBounds is only ever (point, point). It doesn't update so when the map displays, it is zoomed in on that point.Throve
Have updated answer check the else statement for the correct logic.Trochee
Ahh, much better. Thank you very much. Would you be able to assist in as to why no markers are being added to the map?Throve
hmmm. not sure your code looks good. step through the process make sure its doing what you think. Also take a look around the map in case they are getting plotted but in wrong locations.Trochee
Hmm, its not rendering elsewhere. Thanks anyway, you've been a massive help!Throve
"Exchanger.mMapMarkers.add(j, mMap.addMarker(new MarkerOptions() .position(point) .title(hsName) .snippet(siteType + " & "+siteTypeImageId) .draggable(false) .icon(BitmapDescriptorFactory.fromResource(R.drawable.map_pin)))); " this is how I draw markers on the map. Are you sure your data is correct before you render?Trochee
Hmm, drawing markers is again an issue of if I run it in debug and step through, it loads the markers, else it doesn't.Throve
are you using the emulator or real device? What spec?Trochee
sounds like it might be a timing issue. Log out your data as you try and add it to the map see if its all correct.Trochee
Sorry. Real device, Galaxy S3, Data has been checked for correctness. I will attempt the timing issue suggestion now, thanks.Throve
Fixed the issue now - was as you suggested.Throve
A
2

I get the same error.

In the Api, it is explained this:

public LatLngBounds (LatLng southwest, LatLng northeast): IllegalArgumentException if the latitude of the northeast corner is below the latitude of the southwest corner.

With the following code, the exception is launched when the list to compute the bounds is empty:

LatLngBounds.Builder builder = LatLngBounds.builder();
for(ModelLatLngDisplay p: list){
    builder = builder.include(p.latLng);
}
return builder.build();
Anselmi answered 24/3, 2013 at 10:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.