8

这是我asynctask将 pin 放在从 XML 解析的某个位置的部分。这对于小型位置数据集来说很好,但当位置数据集很大时需要很长时间。

private class MapLoader extends AsyncTask<Void, Void, Void> {
    ProgressDialog dialog;
    ArrayList<POI>[] mappoiList;

    @Override
    protected void onPreExecute() {
        mapOverlays = mapview.getOverlays();
        dialog = new ProgressDialog(MainActivity.this);
        dialog.show();
    }

    @Override
    protected Void doInBackground(Void... params) {

        try {

            URL url = new URL(MainActivity.baseUrl
                    + "latitude=40.9192799&longitude=-74.0657508&distance=20");
            
            SAXParserFactory spf = SAXParserFactory.newInstance();
            SAXParser sp = spf.newSAXParser();
            XMLReader xr = sp.getXMLReader();
            ParserHandler parserHandler = new ParserHandler();
            xr.setContentHandler(parserHandler);
            xr.parse(new InputSource(url.openStream()));
            Log.d("Thread", url.toString());
            basicItems = parserHandler.getBasicItems();
            featuredItems = parserHandler.getFeaturedItems();
            restaurants = parserHandler.getRestaurants();
            mapvisibleList = new ArrayList<POI>();
            mappoiList = new ArrayList[2];
            mappoiList[0] = new ArrayList<POI>();
            mappoiList[1] = new ArrayList<POI>();

            for (int i = 0; i < featuredItems.size(); i++) {

                POI poi = new POI(featuredItems.get(i), 1);
                mappoiList[0].add(poi);
            }
            for (int i = 0; i < restaurants.size(); i++) {

                POI poi = new POI(restaurants.get(i), 2);
                mappoiList[0].add(poi);
            }
            for (int i = 0; i < basicItems.size(); i++) {

                POI poi = new POI(basicItems.get(i), 0);
                mappoiList[1].add(poi);
            }

            for (int i = 0; i < mappoiList[0].size(); i++) {
                if (mappoiList[0] != null) {
                    mapvisibleList.add(mappoiList[0].get(i));
                }
            }

            for (int i = 0; i < mappoiList[1].size(); i++) {
                if (mappoiList[1] != null) {
                    mapvisibleList.add(mappoiList[1].get(i));
                }
            }
            for (FeaturedItem item : featuredItems) {
                Log.d("FEATURED",
                        item.getName() + "Distance: " + item.getDistance());
            }
            for (Restaurant item : restaurants) {
                Log.d("RESTAURANTS",
                        item.getName() + "Distance: " + item.getDistance());
            }
            for (BasicItem item : basicItems) {
                Log.d("BASIC",
                        item.getName() + "Distance: " + item.getDistance());
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
            showErrorDialog("Error", "Malformed URL Error Occurred");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
            showErrorDialog("Error",
                    "Parser Configuration Problem Occurred");
        } catch (SAXException e) {
            e.printStackTrace();
            showErrorDialog("Error", "SAX Parser Error Occurred");
        } catch (IOException e) {
            e.printStackTrace();
            showErrorDialog("Error", "IOException Occurred");
        } catch (Exception e) {
            e.printStackTrace();
        }

        GlobalData.gBasicItems = basicItems;
        GlobalData.gFeaturedItems = featuredItems;
        GlobalData.gRestaurants = restaurants;

        if (currentLocation != null) {
            int curLat = (int) (currentLocation.getLatitude() * 1e6);
            int curLon = (int) (currentLocation.getLongitude() * 1e6);
            GeoPoint gp = new GeoPoint(curLat, curLon);
            mapControl.animateTo(gp);

            mapControl.setZoom(14);
            OverlayItem item = new OverlayItem(gp, "My Location",
                    "My Location");

            itemizedOverlay1 = new MyItemizedOverlay(drawableFeature,
                    MainActivity.this, mappoiList[0]);
            itemizedOverlay2 = new MyItemizedOverlay(drawableBasic,
                    MainActivity.this, mappoiList[1]);
            itemizedOverlay3 = new MyItemizedOverlay(drawableCurrent,
                    MainActivity.this, mappoiList[0]);
            Log.i("asyncbasic", "" + basicItems.size());
            Log.i("asyncfeatured", "" + featuredItems.size());
            Log.i("asyncres", "" + restaurants.size());
            if (featuredItems != null) {
                int featuredLength = featuredItems.size();
                for (int i = 0; i < featuredLength; i++) {
                    FeaturedItem fItem = featuredItems.get(i);
                    int lat = (int) (Double
                            .parseDouble(fItem.getLatitude()) * 1e6);
                    int lon = (int) (Double.parseDouble(fItem
                            .getLongitude()) * 1e6);
                    OverlayItem oItem = new OverlayItem(new GeoPoint(lat,
                            lon), fItem.getName(), "Feature");
                    itemizedOverlay1.addOverlay(oItem);
                    Log.i("Map over lay", "Finished one featured");
                }
            }
            if (basicItems != null) {
                int basicLength = basicItems.size();
                for (int i = 0; i < basicLength; i++) {
                    BasicItem bItem = basicItems.get(i);
                    int lat = (int) (Double
                            .parseDouble(bItem.getLatitude()) * 1e6);
                    int lon = (int) (Double.parseDouble(bItem
                            .getLongitude()) * 1e6);
                    OverlayItem oItem = new OverlayItem(new GeoPoint(lat,
                            lon), bItem.getName(), "Basic");
                    itemizedOverlay2.addOverlay(oItem);
                    Log.i("Map over lay", "Finished one Basic");

                }
            }
            if (restaurants != null) {
                int resLength = restaurants.size();
                for (int i = 0; i < resLength; i++) {
                    Restaurant res = restaurants.get(i);
                    int lat = (int) (Double.parseDouble(res.getLatitude()) * 1e6);
                    int lon = (int) (Double.parseDouble(res.getLongitude()) * 1e6);
                    OverlayItem oItem = new OverlayItem(new GeoPoint(lat,
                            lon), res.getName(), "Restaurant");
                    itemizedOverlay1.addOverlay(oItem);
                    Log.i("Map over lay", "Finished one Restaurant");
                }
            }

            itemizedOverlay3.addOverlay(item);
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void result) {
        mapOverlays.clear();
        mapOverlays.add(itemizedOverlay1);
        mapOverlays.add(itemizedOverlay2);
        mapOverlays.add(itemizedOverlay3);
        mapview.postInvalidate();
        dialog.dismiss();

    }
}

我学会了使用getLatitudeSpangetLongitudeSpan摆脱这个问题,但我不太清楚在我的异步任务中在哪里以及如何使用它。有什么建议么?

4

4 回答 4

0

您正在使用一个非常耗时的sax 解析器,使用像 json 这样的对象模型代表,它可能很容易解析,因此可以绘制在地图上。

//很少有建议本身可以减少您面临的时间问题。

  1. 仅绘制引脚并单击打开一个弹出窗口以在其中显示更多详细信息。
于 2013-04-17T07:18:51.357 回答
0

请给出花费时间较长的确切数据大小,还可以尝试分析代码以查看每个代码块花费的时间。

但是看看代码,如果正在操作的数据增加,循环遍历所有这些变量会对时间产生重大影响,

尝试简化/组合循环,

例如这个循环

        for (int i = 0; i < featuredItems.size(); i++) {

                POI poi = new POI(featuredItems.get(i), 1);
                mappoiList[0].add(poi);
            }

和这个

       if (featuredItems != null) {
                  int featuredLength = featuredItems.size();
                   for (int i = 0; i < featuredLength; i++) {
                    FeaturedItem fItem = featuredItems.get(i);
                    int lat = (int) (Double
                            .parseDouble(fItem.getLatitude()) * 1e6);
                    int lon = (int) (Double.parseDouble(fItem
                            .getLongitude()) * 1e6);
                    OverlayItem oItem = new OverlayItem(new GeoPoint(lat,
                            lon), fItem.getName(), "Feature");
                    itemizedOverlay1.addOverlay(oItem);
                    Log.i("Map over lay", "Finished one featured");
                }
            }

不能合并吗?

还有这个循环

   for (int i = 0; i < basicItems.size(); i++) {

                POI poi = new POI(basicItems.get(i), 0);
                mappoiList[1].add(poi);
                }

和这个

        if (basicItems != null) {
                int basicLength = basicItems.size();
                for (int i = 0; i < basicLength; i++) {
                    BasicItem bItem = basicItems.get(i);
                    int lat = (int) (Double
                            .parseDouble(bItem.getLatitude()) * 1e6);
                    int lon = (int) (Double.parseDouble(bItem
                            .getLongitude()) * 1e6);
                    OverlayItem oItem = new OverlayItem(new GeoPoint(lat,
                            lon), bItem.getName(), "Basic");
                    itemizedOverlay2.addOverlay(oItem);
                    Log.i("Map over lay", "Finished one Basic");

                }
            }

也可以组合,

于 2013-02-19T18:46:08.537 回答
0

您可能想看看实现一个生产者-消费者模型,其中消费者将是地图本身,生产者将是为 pin 生成信息的逻辑。

于 2013-02-21T11:42:47.713 回答
0

我认为问题不在于覆盖。您正在使用 sax 解析器获取所有项目,这会花费您的时间。您试图获取所有元素,然后将其添加到地图中。如果您将代码修改为当您获得单个元素更新以覆盖和填充它时,这可能会加快您的执行速度。如果您仍然遇到同样的问题,请尝试使用覆盖的单独线程或画布对象(通过地理点的投影)添加元素。

于 2013-02-20T11:38:35.907 回答