package net.osmand.plus.views; import android.os.AsyncTask; import net.osmand.plus.GPXUtilities.WptPt; import net.osmand.util.MapUtils; import java.util.ArrayList; import java.util.List; public abstract class AsynchronousResampler extends AsyncTask<String,Integer,String> { protected Renderable.RenderableSegment rs; protected List<WptPt> culled = null; AsynchronousResampler(Renderable.RenderableSegment rs) { assert rs != null; assert rs.points != null; this.rs = rs; } @Override protected void onPostExecute(String result) { if (!isCancelled()) { rs.setRDP(culled); } } public static class RamerDouglasPeucer extends AsynchronousResampler { private double epsilon; public RamerDouglasPeucer(Renderable.RenderableSegment rs, double epsilon) { super(rs); this.epsilon = epsilon; } @Override protected String doInBackground(String... params) { int nsize = rs.points.size(); if (nsize > 0) { boolean survivor[] = new boolean[nsize]; cullRamerDouglasPeucer(survivor, 0, nsize - 1); if (!isCancelled()) { culled = new ArrayList<>(); survivor[0] = true; for (int i = 0; i < nsize; i++) { if (survivor[i]) { culled.add(rs.points.get(i)); } } } } return null; } private void cullRamerDouglasPeucer(boolean survivor[], int start, int end) { double dmax = Double.NEGATIVE_INFINITY; int index = -1; WptPt startPt = rs.points.get(start); WptPt endPt = rs.points.get(end); for (int i = start + 1; i < end && !isCancelled(); i++) { WptPt pt = rs.points.get(i); double d = MapUtils.getOrthogonalDistance(pt.lat, pt.lon, startPt.lat, startPt.lon, endPt.lat, endPt.lon); if (d > dmax) { dmax = d; index = i; } } if (dmax > epsilon) { cullRamerDouglasPeucer(survivor, start, index); cullRamerDouglasPeucer(survivor, index, end); } else { survivor[end] = true; } } } }