Review fixes
This commit is contained in:
parent
9713d04c7f
commit
367b2bc27e
2 changed files with 106 additions and 90 deletions
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
return cachedTrack.getCachedSegments(selectedGpxFile, view.getZoom(), scaleType, getColorizationPalette(gpxFile, scaleType));
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue