安卓Google地图V2标记演示 IllegalStateException无包含点

4

我正在创建一个自定义的MarkerDemo实现,为了GoogleMaps V2。我遇到一个奇怪的错误,我将LatLng值提供给了一个LatLngBounds.Builder实例,并将其作为变量传递给.build。当我通过Eclipse以Debug模式运行应用程序时,地图会加载。但是当我正常地通过Eclipse运行它时,会抛出一个IllegalStateException异常,其中包含“no included points”的消息。有人能帮忙吗?

以下是一些代码来帮助理解。

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("");
            }
        }
    }
}

这是我的堆栈跟踪信息。

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)
2个回答

5
不要担心构建器,直接开始操作。
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"))));
    }
}

1
已更新答案,请检查 else 语句以获取正确的逻辑。 - Aiden Fry
啊,好多了。非常感谢。您能帮忙解决为什么地图上没有添加标记的问题吗? - Anthaas
嗯,绘制标记又成了一个问题,如果我在调试模式下逐步执行,它会加载标记,否则就不会加载。 - Anthaas
听起来可能是时序问题。在尝试将数据添加到地图时,将其记录下来以查看是否全部正确。 - Aiden Fry
抱歉。真实设备,Galaxy S3,数据已经检查过了。我现在会尝试解决时间问题建议,谢谢。 - Anthaas
显示剩余7条评论

2

我遇到了同样的错误。

在 API 中,解释如下:

public LatLngBounds (LatLng southwest, LatLng northeast):如果东北角的纬度低于西南角的纬度,则会抛出 IllegalArgumentException 异常。

当计算边界的列表为空时,使用以下代码会引发异常:

LatLngBounds.Builder builder = LatLngBounds.builder();
for(ModelLatLngDisplay p: list){
    builder = builder.include(p.latLng);
}
return builder.build();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接