У меня есть набор точек в текстовом файле, который я хочу построить на карте (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 в своем приложении, могут, возможно, пролить свет на правильный способ сделать это?
Если я делал это с «LocationListener», где бы я добавил эту строку? После 'onLocationChanged'? – Sriram