1

У меня есть набор точек в текстовом файле, который я хочу построить на карте (API v2), и прочертить линию. Каждая из точек - <Lat, Lng>, и в текстовом файле имеется 7253 таких точки. Код выглядит следующим образом:Рисование маршрута в API Карт Google v2

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_map_my_route_mock); 

     //Step 0. Get google map instance. 
     map = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(); 

     if(map == null) { 
      Toast.makeText(getApplicationContext(), "Map is not available.", Toast.LENGTH_LONG).show(); 
     } else { 
      Toast.makeText(getApplicationContext(), "Map is available.", Toast.LENGTH_LONG).show(); 
     } 

     //Step 0.a. Load a type of map. 
     map.setMapType(GoogleMap.MAP_TYPE_TERRAIN); 

     //Step 0.b. Load your current location on the map. 
     map.setMyLocationEnabled(true); 
     if(po == null) { 
      po = new PolylineOptions(); 
     } 
     //Toast.makeText(getApplicationContext(), "Location lat = " + loc.getLatitude() + " and longitude = " + loc.getLongitude(), Toast.LENGTH_LONG).show(); 

     //Step 1. Set GPS to service provider. 
     locMgr = (LocationManager) getSystemService(LOCATION_SERVICE); 
     mocLocProvider = locMgr.GPS_PROVIDER; 
     locMgr.addTestProvider(mocLocProvider, false, false, true, false, true, false, false, 0, 5); 
     locMgr.setTestProviderEnabled(mocLocProvider, true); 
     //locMgr.requestLocationUpdates(mocLocProvider, 0, 0, locLstnr); 

     //Step 2. Open file for reading from. 
     try { 
      is = getAssets().open("locationLogs.txt"); 
      br = new BufferedReader(new InputStreamReader(is)); 
      String line = null; 
      try { 
       line = br.readLine(); 
       while(line != null) { 
       //while((line = br.readLine()) != null) { 
        //there is still a line in the file. parse for gps coordinates etc. 
        Location l = new Location(LocationManager.GPS_PROVIDER); 
        String[] details = line.split(","); //the array will contain date, time, lat, long, speed, altitude and accuracy. 
        l.setTime(System.currentTimeMillis()); 
        l.setLatitude(Double.parseDouble(details[2])); 
        l.setLongitude(Double.parseDouble(details[3])); 
        l.setSpeed((float) Double.parseDouble(details[4])); 
        l.setAltitude(Double.parseDouble(details[5])); 
        l.setAccuracy((float) Double.parseDouble(details[6])); 
        //Toast.makeText(getApplicationContext(), l.getLatitude() + "," + l.getLongitude() + "," + l.getSpeed() + "," + l.getAltitude() + "," + l.getAccuracy() + "\n", Toast.LENGTH_SHORT).show(); 
        locMgr.setTestProviderLocation(mocLocProvider, l); 
        po.add(new LatLng(l.getLatitude(), l.getLongitude())); 
        Log.v(this.toString(), "Number of po objects = " + po.getPoints().size()); 
        //pl = map.addPolyline(po); 
        //Log.v(this.toString(), "number of polyline objects added = " + pl.getPoints().size()); 
        line = br.readLine(); 
       } 
      } catch(FileNotFoundException e) { 
       Log.v(this.toString(), "File not found."); 
      } 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      Log.v(this.toString(), "Cannot open file for reading from."); 
     } 
} 

После прочтения около 1300 пунктов, приложение падает с OutOfMemory исключением. Несмотря на то, что в Google Maps API v2 имеется целый ряд потоков, связанных с утечкой памяти, более тщательный анализ с помощью MAT показывает, что линия: pl = map.addPolyline(po) является виновником, забирая большую часть памяти. Это оказывается правдой, так как после того, как эта строка закомментирована, объем памяти вышеприведенного кода очень мал ~ 8 МБ для чтения около 7 тыс. Точек.

Мой вопрос (ы):
1. Что-то не так с обращением Polylines объект используется для рисования на карте? Один раз для каждого обновления?
2. Если да, то как можно нарисовать линию, чтобы она не занимала слишком много памяти? С Canvas и т.п. или рисованием линии только после определенного количества точек (скажем, 10 или около того)?
3. Некоторые разработчики, которые использовали Maps API v2 в своем приложении, могут, возможно, пролить свет на правильный способ сделать это?

ответ

1

Позвоните pl = map.addPolyline(po); после цикла, чтобы создать одну полилинию и не пытаться создать 7000 полилиний, каждый из которых «на одну точку длиннее», чем раньше.

+0

Если я делал это с «LocationListener», где бы я добавил эту строку? После 'onLocationChanged'? – Sriram