Review fixes

This commit is contained in:
cepprice 2021-04-13 10:40:31 +05:00
parent 9713d04c7f
commit 367b2bc27e
2 changed files with 106 additions and 90 deletions

View file

@ -340,6 +340,30 @@ public class OsmMapUtils {
} }
} }
public static void simplifyDouglasPeucker(List<Node> nodes, int start, int end, List<Node> survivedNodes, double epsilon) {
double dmax = Double.NEGATIVE_INFINITY;
int index = -1;
Node startPt = nodes.get(start);
Node endPt = nodes.get(end);
for (int i = start + 1; i < end; i++) {
Node pt = nodes.get(i);
double d = MapUtils.getOrthogonalDistance(pt.getLatitude(), pt.getLongitude(),
startPt.getLatitude(), startPt.getLongitude(), endPt.getLatitude(), endPt.getLongitude());
if (d > dmax) {
dmax = d;
index = i;
}
}
if (dmax > epsilon) {
simplifyDouglasPeucker(nodes, start, index, survivedNodes, epsilon);
simplifyDouglasPeucker(nodes, index, end, survivedNodes, epsilon);
} else {
survivedNodes.add(nodes.get(end));
}
}
private static double orthogonalDistance(int zoom, Node nodeLineStart, Node nodeLineEnd, Node node) { private static double orthogonalDistance(int zoom, Node nodeLineStart, Node nodeLineEnd, Node node) {
LatLon p = MapUtils.getProjection(node.getLatitude(), node.getLongitude(), nodeLineStart.getLatitude(), LatLon p = MapUtils.getProjection(node.getLatitude(), node.getLongitude(), nodeLineStart.getLatitude(),
nodeLineStart.getLongitude(), nodeLineEnd.getLatitude(), nodeLineEnd.getLongitude()); nodeLineStart.getLongitude(), nodeLineEnd.getLatitude(), nodeLineEnd.getLongitude());
@ -619,30 +643,6 @@ public class OsmMapUtils {
return new Cell(x / area, y / area, 0, rings); return new Cell(x / area, y / area, 0, rings);
} }
public static void simplifyDouglasPeucker(List<Node> nodes, int start, int end, List<Node> survivedNodes, double epsilon) {
double dmax = Double.NEGATIVE_INFINITY;
int index = -1;
Node startPt = nodes.get(start);
Node endPt = nodes.get(end);
for (int i = start + 1; i < end; i++) {
Node pt = nodes.get(i);
double d = MapUtils.getOrthogonalDistance(pt.getLatitude(), pt.getLongitude(),
startPt.getLatitude(), startPt.getLongitude(), endPt.getLatitude(), endPt.getLongitude());
if (d > dmax) {
dmax = d;
index = i;
}
}
if (dmax > epsilon) {
simplifyDouglasPeucker(nodes, start, index, survivedNodes, epsilon);
simplifyDouglasPeucker(nodes, index, end, survivedNodes, epsilon);
} else {
survivedNodes.add(nodes.get(end));
}
}
private static class CellComparator implements Comparator<Cell> { private static class CellComparator implements Comparator<Cell> {
@Override @Override
public int compare(Cell o1, Cell o2) { public int compare(Cell o1, Cell o2) {

View file

@ -118,8 +118,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
private MapMarkersHelper mapMarkersHelper; private MapMarkersHelper mapMarkersHelper;
private GpxSelectionHelper selectedGpxHelper; private GpxSelectionHelper selectedGpxHelper;
private final Map<String, Long> cachedModifiedTime = new HashMap<>(); private final Map<String, CachedTrack> segmentsCache = new HashMap<>();
private final Map<String, List<TrkSegment>> cachedZoomedSegments = new HashMap<>();
private List<WptPt> cache = new ArrayList<>(); private List<WptPt> cache = new ArrayList<>();
private Map<WptPt, SelectedGpxFile> pointFileMap = new HashMap<>(); private Map<WptPt, SelectedGpxFile> pointFileMap = new HashMap<>();
@ -688,7 +687,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
private void drawSelectedFileSegments(SelectedGpxFile selectedGpxFile, boolean currentTrack, Canvas canvas, private void drawSelectedFileSegments(SelectedGpxFile selectedGpxFile, boolean currentTrack, Canvas canvas,
RotatedTileBox tileBox, DrawSettings settings) { RotatedTileBox tileBox, DrawSettings settings) {
boolean visible = QuadRect.trivialOverlap(tileBox.getLatLonBounds(), GPXUtilities.calculateTrackBounds(selectedGpxFile.getModifiablePointsToDisplay())); boolean visible = QuadRect.trivialOverlap(tileBox.getLatLonBounds(), GPXUtilities.calculateTrackBounds(selectedGpxFile.getPointsToDisplay()));
if (!selectedGpxFile.getGpxFile().hasTrkPt() || !visible) { if (!selectedGpxFile.getGpxFile().hasTrkPt() || !visible) {
return; return;
} }
@ -698,7 +697,7 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
List<TrkSegment> segments = new ArrayList<>(); List<TrkSegment> segments = new ArrayList<>();
if (scaleType == null) { if (scaleType == null) {
segments.addAll(selectedGpxFile.getModifiablePointsToDisplay()); segments.addAll(selectedGpxFile.getPointsToDisplay());
} else { } else {
segments.addAll(getCachedSegments(selectedGpxFile, scaleType)); segments.addAll(getCachedSegments(selectedGpxFile, scaleType));
} }
@ -728,69 +727,14 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
private List<TrkSegment> getCachedSegments(SelectedGpxFile selectedGpxFile, GradientScaleType scaleType) { private List<TrkSegment> getCachedSegments(SelectedGpxFile selectedGpxFile, GradientScaleType scaleType) {
GPXFile gpxFile = selectedGpxFile.getGpxFile(); GPXFile gpxFile = selectedGpxFile.getGpxFile();
String fileName = gpxFile.path; String path = gpxFile.path;
String trackId = view.getZoom() + "_" + scaleType.toString() + "_" + fileName; long modifiedTime = gpxFile.modifiedTime;
CachedTrack cachedTrack = segmentsCache.get(path);
if (cachedModifiedTime.get(fileName) != null && cachedModifiedTime.get(fileName) == gpxFile.modifiedTime) { if (cachedTrack == null) {
List<TrkSegment> segments = cachedZoomedSegments.get(trackId); cachedTrack = new CachedTrack(view.getApplication(), modifiedTime);
if (segments == null) { segmentsCache.put(path, cachedTrack);
segments = calculateGradientTrack(selectedGpxFile, scaleType);
cachedZoomedSegments.put(trackId, segments);
}
return segments;
} else {
if (cachedModifiedTime.get(fileName) != null) {
for (String key : cachedZoomedSegments.keySet()) {
if (key.contains("_" + fileName)) {
cachedZoomedSegments.remove(key);
}
}
}
cachedModifiedTime.put(fileName, gpxFile.modifiedTime);
List<TrkSegment> segments = calculateGradientTrack(selectedGpxFile, scaleType);
cachedZoomedSegments.put(trackId, segments);
return segments;
} }
} return cachedTrack.getCachedSegments(selectedGpxFile, view.getZoom(), scaleType, getColorizationPalette(gpxFile, scaleType));
private List<TrkSegment> calculateGradientTrack(SelectedGpxFile selectedGpxFile, GradientScaleType scaleType) {
OsmandApplication app = view.getApplication();
GPXFile gpxFile = selectedGpxFile.getGpxFile();
RouteColorize colorize = new RouteColorize(view.getZoom(), gpxFile, selectedGpxFile.getTrackAnalysis(app),
scaleType.toColorizationType(), app.getSettings().getApplicationMode().getMaxSpeed());
colorize.setPalette(getColorizationPalette(gpxFile, scaleType));
List<RouteColorizationPoint> colorsOfPoints = colorize.getResult(true);
return createSimplifiedSegmentsFromColorizedPoints(selectedGpxFile.getGpxFile(), colorsOfPoints, scaleType);
}
private List<TrkSegment> createSimplifiedSegmentsFromColorizedPoints(GPXFile gpxFile,
List<RouteColorizationPoint> colorizationPoints,
GradientScaleType scaleType) {
List<TrkSegment> simplifiedSegments = new ArrayList<>();
ColorizationType colorizationType = scaleType.toColorizationType();
int id = 0;
int colorPointIdx = 0;
for (GPXUtilities.Track track : gpxFile.tracks) {
for (TrkSegment segment : track.segments) {
TrkSegment simplifiedSegment = new TrkSegment();
simplifiedSegments.add(simplifiedSegment);
for (WptPt pt : segment.points) {
if (colorPointIdx >= colorizationPoints.size()) {
return simplifiedSegments;
}
RouteColorizationPoint colorPoint = colorizationPoints.get(colorPointIdx);
if (colorPoint.id == id) {
simplifiedSegment.points.add(pt);
pt.setColor(colorizationType, colorPoint.color);
colorPointIdx++;
}
id++;
}
}
}
return simplifiedSegments;
} }
private float getTrackWidth(String width, float defaultTrackWidth) { private float getTrackWidth(String width, float defaultTrackWidth) {
@ -1238,4 +1182,76 @@ public class GPXLayer extends OsmandMapLayer implements IContextMenuProvider, IM
view.getApplication().getItineraryHelper().runSynchronization(group); view.getApplication().getItineraryHelper().runSynchronization(group);
} }
} }
private static class CachedTrack {
private OsmandApplication app;
private long modifiedTime;
private final Map<String, List<TrkSegment>> cache = new HashMap<>();
public CachedTrack(@NonNull OsmandApplication app, long modifiedTime) {
this.app = app;
this.modifiedTime = modifiedTime;
}
public List<TrkSegment> getCachedSegments(@NonNull SelectedGpxFile selectedGpxFile, int zoom,
@NonNull GradientScaleType scaleType,
int[] gradientPalette) {
GPXFile gpxFile = selectedGpxFile.getGpxFile();
String trackId = zoom + "_" + scaleType.toString();
if (modifiedTime == gpxFile.modifiedTime) {
List<TrkSegment> segments = cache.get(trackId);
if (segments == null) {
segments = calculateGradientTrack(selectedGpxFile, zoom, scaleType, gradientPalette);
cache.put(trackId, segments);
}
return segments;
} else {
cache.clear();
modifiedTime = gpxFile.modifiedTime;
List<TrkSegment> segments = calculateGradientTrack(selectedGpxFile, zoom, scaleType, gradientPalette);
cache.put(trackId, segments);
return segments;
}
}
private List<TrkSegment> calculateGradientTrack(SelectedGpxFile selectedGpxFile, int zoom,
GradientScaleType scaleType, int[] gradientPalette) {
GPXFile gpxFile = selectedGpxFile.getGpxFile();
RouteColorize colorize = new RouteColorize(zoom, gpxFile, selectedGpxFile.getTrackAnalysis(app),
scaleType.toColorizationType(), app.getSettings().getApplicationMode().getMaxSpeed());
colorize.setPalette(gradientPalette);
List<RouteColorizationPoint> colorsOfPoints = colorize.getResult(true);
return createSimplifiedSegments(selectedGpxFile.getGpxFile(), colorsOfPoints, scaleType);
}
private List<TrkSegment> createSimplifiedSegments(GPXFile gpxFile,
List<RouteColorizationPoint> colorizationPoints,
GradientScaleType scaleType) {
List<TrkSegment> simplifiedSegments = new ArrayList<>();
ColorizationType colorizationType = scaleType.toColorizationType();
int id = 0;
int colorPointIdx = 0;
for (TrkSegment segment : gpxFile.getNonEmptyTrkSegments(false)) {
TrkSegment simplifiedSegment = new TrkSegment();
simplifiedSegments.add(simplifiedSegment);
for (WptPt pt : segment.points) {
if (colorPointIdx >= colorizationPoints.size()) {
return simplifiedSegments;
}
RouteColorizationPoint colorPoint = colorizationPoints.get(colorPointIdx);
if (colorPoint.id == id) {
simplifiedSegment.points.add(pt);
pt.setColor(colorizationType, colorPoint.color);
colorPointIdx++;
}
id++;
}
}
return simplifiedSegments;
}
}
} }