2013-02-10 5 views
8

Hier ist mein asynctask Teil, wo ich Pin an einem Ort setze, der von einem XML-Code analysiert wird. Dies ist für einen kleinen Standortdatensatz in Ordnung, dauert jedoch lange, wenn der Standortdatensatz groß ist.Wie zeige ich den Standort-Pin des sichtbaren Teils einer MapView in Android?

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) { 
      // TODO Auto-generated method stub 

      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) { 
      // TODO Auto-generated method stub 

      mapOverlays.clear(); 

      mapOverlays.add(itemizedOverlay1); 
      mapOverlays.add(itemizedOverlay2); 
      mapOverlays.add(itemizedOverlay3); 
      mapview.postInvalidate(); 
      dialog.dismiss(); 

     } 

    } 

Ich lernte über getLatitudeSpan und getLongitudeSpan mit loszuwerden diesem Problem zu umgehen, aber ich bin nicht ganz klar, wo und wie es in meiner Asynchron-Aufgabe zu verwenden. Irgendwelche Vorschläge ?

+0

Kann jemand helfen? Ich habe keinen Grund, warum jemand nicht mindestens eine einzige Antwort gibt :( – Reyjohn

+0

versuchen Sie, Ihre Anwendung zu profilieren, um zu sehen, wo die Zeit aufgegessen wird. Und können Sie 'große Nummer' definieren? Ie ist das 10 oder 1000? –

+0

1) Vermeiden Sie es, so viele Loops zu verwenden, um sie zu kombinieren. 2) Optimiere deinen 'ParserHandler', um die Daten in der endgültigen Form (' ArrayList 'und' new ArrayList [2] ') zurückzugeben, um zu vermeiden, dass die DataSets so oft ausgeführt werden! – madlymad

Antwort

0

Bitte genaue Datengröße geben, wo die benötigte Zeit lang ist, finden Sie den Code Profilierungs Zeit für jeden Code-Block zu sehen.

Aber Blick auf den Code, würde die Schleife durch alle diese Variablen eine signifikante Auswirkung auf Zeit, wenn die Daten auf erhöhte betrieben wird,

versuchen Vereinfachung/die Schleifen Kombination

zB diese Schleife

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

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

und dieses

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

kann nicht kombiniert werden?

auch diese Schleife

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

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

und diese

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

       } 
      } 

auch kombiniert werden können,

0

Ich denke Problem nicht über Overlay ist. Du erhältst alle Gegenstände mit dem Sax Parser. Sie versuchen alle Elemente zu erhalten und fügen sie dann zur Karte hinzu. Wenn Sie Ihren Code ändern, während Sie ein einzelnes Elementupdate zum Überlagern und Füllen erhalten, kann dies die Ausführung beschleunigen. Wenn Sie immer noch unter dem gleichen Problem leiden, versuchen Sie, Elemente mit einem separaten Thread oder einem Canvas-Objekt der Überlagerung hinzuzufügen (durch Projektion des Geo-Punktes).

0

Sie vielleicht einen Blick auf die Implementierung eines Producer-Consumer-Modell nehmen wollen, wo der Verbraucher die Karte selbst sein wird, und der Produzent wird die Logik sein, die Informationen für einen Stift erzeugt.

0

Sie verwenden einen Sax Parser, das ist ziemlich zeitaufwendig, verwenden Sie ein Objektmodell Vertreter wie ein JSON, die leicht geparst werden kann und so auf einer Karte geplottet werden kann.

// Ein paar Vorschläge, die sich zum Zeitproblem reduzieren können Sie konfrontiert sind.

  1. Zeichnen Sie nur die Pins und klicken Sie auf ein Popup, um weitere Details anzuzeigen.