I'm developing an app to draw a movement path from given GPS location from a text file. So far, i'm successfully be able to load the data and draw the path. My solution is, the path must be drawn to a rectangle because it contain data (e.g color and width) and clickable. A Line cannot do this. Furthermore, there are also a triangle gap between these rectangles when it took a turn, so i filled it with triangle shapes. And the path have to be double because i have another data to be displayed on that second layer. This means, lots of polygons to be drawn for a longer path.
I have tried this on 15 km journey, and it takes 1000 lines of gps data. When i parse the file, it draws total up to 5000 polygons for both layers.
My problem is, when it draws the shapes up to 1000 polygons, the app become laggy, not responding. If i let the thread sleeps for 1 seconds, it seems ok. but more speed, it became not responding.
I been reading the web for this solution and could find it. Fyi, i already create another thread to handle the text file. I also narrow down the problem by letting the app do the process without drawing down the polygons, and the process were smooth. I have read that there is no other way to handle the polygons outside the main thread.
UPDATED: I'm using Asynctask background to read a line from textfile, parse it into array which contains Latitude, Longitude, Value1, Value2. Then massive calculation happen there. Upon completionfor each row, i sent objects to onProgressUpdate to update UI thread with markers, polylines, and shapes.
Here is my Asynctask
private class DrawPathAsync extends AsyncTask<File, Object, Void>
{
FileInputStream is;
BufferedReader reader;
@Override
protected Void doInBackground(File... params) {
File sFile = params[0];
Integer count;
String line = "";
double radius = 8; //8 meter
double distance;
double Heading_y;
int kaler, gkaler;
double apprate, gi;
if (sFile.exists()) {
try {
is = new FileInputStream(sFile);
reader = new BufferedReader(new InputStreamReader(is));
reader.readLine(); // this will read the first line
while ((line = reader.readLine()) != null) {
String[] valuesArray = line.split("\\s*,\\s*");
Float bearing = (float) 0;
Double lat = Double.parseDouble(valuesArray[1]);
Double lng = Double.parseDouble(valuesArray[2]);
LatLng latlng = new LatLng(lat, lng);
LatLng center = latlng;
apprate = Double.parseDouble(valuesArray[3]);
if (apprate >=0 && apprate < 80) {
kaler = appcolor1;
} else if (apprate >=80 && apprate < 100) {
kaler = appcolor2;
} else if (apprate >=100 && apprate < 120) {
kaler = appcolor3;
} else if (apprate >=120 && apprate < 140) {
kaler = appcolor4;
} else if (apprate >=140 && apprate < 160) {
kaler = appcolor5;
} else if (apprate >=160 && apprate <= 200) {
kaler = appcolor6;
} else {
kaler = appcolor7;
}
if (points.size()== 2) {
points.remove(0);
points.add(latlng);
} else {
points.add(latlng);
}
//recheck
if (points.size() == 2) {
distance = SphericalUtil.computeDistanceBetween(center, points.get(0));
LatLng pt1 = points.get(0);
LatLng pt2 = latlng;
bearing = (float) SphericalUtil.computeHeading(pt1, pt2);
if (bearing < 0) {
bearing = bearing + 360;
}
LatLng x = SphericalUtil.computeOffset(center, radius, bearing - 90);
LatLng y = SphericalUtil.computeOffset(center, radius, bearing + 90);
LatLng a = SphericalUtil.computeOffset(x, distance, bearing + 180);
LatLng b = SphericalUtil.computeOffset(y, distance, bearing + 180);
MarkerPoint mp = new MarkerPoint();
mp.latlng = latlng;
mp.bearing = bearing;
Rect rc = new Rect();
rc.a = a;
rc.b = b;
rc.x = x;
rc.y = y;
rc.kaler = kaler;
rc.pt2 = pt2;
publishProgress(mp, rc);
}
Thread.sleep(50);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
@Override
protected void onProgressUpdate(Object... values) {
MarkerPoint mp = (MarkerPoint) values[0];
Rect rc = (Rect) values[1];
LatLng latlng = mp.latlng;
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.mipmap.pointer);
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latlng);
markerOptions.icon(icon);
markerOptions.rotation(mp.bearing);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
marker1.remove();
marker1 = mMap.addMarker(markerOptions);
if (points.size() > 1) {
path = mMap.addPolyline(new PolylineOptions().add(points.get(0)).add(points.get(1)).color(Color.BLUE).width(5));
lines.add(path);
}
PolygonOptions options = new PolygonOptions()
.fillColor(rc.kaler)
.strokeWidth(0)
.strokeColor(Color.TRANSPARENT);
options.add(rc.x);
options.add(rc.y);
options.add(rc.b);
options.add(rc.a);
rect = mMap.addPolygon(options);
rects.add(rect);
if (tripoints.size() == 3) {
tripoints.add(rc.a);
tripoints.add(rc.b);
} else {
tripoints.add(rc.pt2);
tripoints.add(rc.x);
tripoints.add(rc.y);
}
//check
//round 2, if triponts = 5 create triangle
if (tripoints.size() == 5) {
PolygonOptions options2 = new PolygonOptions()
.fillColor(rc.kaler)
.strokeWidth(0)
.strokeColor(Color.TRANSPARENT);
options2.add(tripoints.get(0));
options2.add(tripoints.get(2));
options2.add(tripoints.get(4));
t1 = mMap.addPolygon(options2);
tris.add(t1);
PolygonOptions options3 = new PolygonOptions()
.fillColor(rc.kaler)
.strokeWidth(0)
.strokeColor(Color.TRANSPARENT);
options3.add(tripoints.get(0));
options3.add(tripoints.get(1));
options3.add(tripoints.get(3));
t2 = mMap.addPolygon(options3);
tris.add(t2);
tripoints.clear();
tripoints.add(rc.pt2);
tripoints.add(rc.x);
tripoints.add(rc.y);
}
}
@Override
protected void onPostExecute(Void result) {
}
}
Hope someone can share some tips and solutions.