Found/fixed crash bug in Altitude renderer
Out of memory bug happened occasionally - now fixed by writing to original canvas instead of creating its own bitmap buffer. It's going to be a lot quicker, too. Since the altitude band is now solid, though, it should be in the renderer list before the standard track segment. I have also done some work on the distance/marker renderer, and that is enabled in this update. It draws the distance (km) as a marker and number over the top of each track. I went for a ride on my motorbike today to check out how some of the changes work. The "current track" stuff is hopeless, so that needs to be fixed. Basically I was trying to NOT resample the current track, as it causes all sorts of speed issues when points are continually added and resamples are continually fired. But my change clearly didn't work properly so I will revisit that shortly. I do urge anyone testing to try with a GPX track which has elevation data - the rainbow track backing is quite nice I think... I hope others like it. As a side note; I found out how to get the exception log - I have to setup an email account on my emulator to get it to work.
This commit is contained in:
parent
d99692e429
commit
e8e6ca2854
3 changed files with 42 additions and 46 deletions
|
@ -204,14 +204,6 @@ public class GPXUtilities {
|
||||||
public List<WptPt> points = new ArrayList<WptPt>();
|
public List<WptPt> points = new ArrayList<WptPt>();
|
||||||
private OsmandMapTileView view;
|
private OsmandMapTileView view;
|
||||||
|
|
||||||
// A list of renderables. A rendereable is 'a way of drawing' something related to a TrkSegment.
|
|
||||||
// For example, we could have several renderables drawing on top of each other;
|
|
||||||
// 1. rainbow coloured altitude indicator
|
|
||||||
// 2. base rendered segments
|
|
||||||
// 3. 'dot' 1km markers on top
|
|
||||||
// These are dimply enabled by adding new Renderable objects to this list
|
|
||||||
// Note; see addRenderers for a complete list of handled Renderables.
|
|
||||||
|
|
||||||
public List<Renderable.RenderableSegment> renders = new ArrayList<>();
|
public List<Renderable.RenderableSegment> renders = new ArrayList<>();
|
||||||
|
|
||||||
public List<GPXTrackAnalysis> splitByDistance(double meters) {
|
public List<GPXTrackAnalysis> splitByDistance(double meters) {
|
||||||
|
@ -239,9 +231,6 @@ public class GPXUtilities {
|
||||||
rs.drawSingleSegment(p, c, tb);
|
rs.drawSingleSegment(p, c, tb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Track extends GPXExtensions {
|
public static class Track extends GPXExtensions {
|
||||||
|
|
|
@ -330,8 +330,10 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex
|
||||||
if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD)
|
if (ts.renders.isEmpty() // only do once (CODE HERE NEEDS TO BE UI INSTEAD)
|
||||||
&& !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how?
|
&& !ts.points.isEmpty()) { // hmmm. 0-point tracks happen, but.... how?
|
||||||
|
|
||||||
|
boolean showCT = g.isShowCurrentTrack();
|
||||||
|
|
||||||
|
ts.renders.add(new Renderable.Altitude(ts.points, 10));
|
||||||
ts.renders.add(new Renderable.StandardTrack(ts.points, 18));
|
ts.renders.add(new Renderable.StandardTrack(ts.points, 18));
|
||||||
ts.renders.add(new Renderable.Altitude(ts.points, 10, 180));
|
|
||||||
|
|
||||||
// TODO : enable these to see how the experimental conveyor, altitude, speed, waypoint renders work
|
// TODO : enable these to see how the experimental conveyor, altitude, speed, waypoint renders work
|
||||||
|
|
||||||
|
|
|
@ -198,19 +198,11 @@ public class Renderable {
|
||||||
|
|
||||||
public static class Altitude extends RenderableSegment {
|
public static class Altitude extends RenderableSegment {
|
||||||
|
|
||||||
private Paint alphaPaint = null;
|
|
||||||
private int alpha;
|
|
||||||
protected float colorBandWidth; // width of speed/altitude colour band
|
|
||||||
protected double segmentSize;
|
protected double segmentSize;
|
||||||
|
|
||||||
public Altitude(List<GPXUtilities.WptPt> pt, double segmentSize, int alpha) {
|
public Altitude(List<GPXUtilities.WptPt> pt, double segmentSize) {
|
||||||
super(pt);
|
super(pt);
|
||||||
|
|
||||||
this.segmentSize = segmentSize;
|
this.segmentSize = segmentSize;
|
||||||
this.alpha = alpha;
|
|
||||||
alphaPaint = new Paint();
|
|
||||||
alphaPaint.setStrokeCap(Paint.Cap.ROUND);
|
|
||||||
colorBandWidth = 32f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void recalculateRenderScale(double zoom) {
|
@Override public void recalculateRenderScale(double zoom) {
|
||||||
|
@ -225,21 +217,21 @@ public class Renderable {
|
||||||
if (culled != null && !culled.isEmpty()
|
if (culled != null && !culled.isEmpty()
|
||||||
&& QuadRect.trivialOverlap(tileBox.getLatLonBounds(), trackBounds)) {
|
&& QuadRect.trivialOverlap(tileBox.getLatLonBounds(), trackBounds)) {
|
||||||
|
|
||||||
// Draws into a bitmap so that the lines can be drawn solid and the *ENTIRE* can be alpha-blended
|
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
||||||
|
|
||||||
Bitmap newBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Bitmap.Config.ARGB_8888);
|
Paint.Cap cap = p.getStrokeCap();
|
||||||
Canvas canvas2 = new Canvas(newBitmap);
|
float stroke = p.getStrokeWidth();
|
||||||
canvas2.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
int col = p.getColor();
|
||||||
|
|
||||||
alphaPaint.setAlpha(255);
|
p.setStrokeCap(Paint.Cap.ROUND);
|
||||||
|
|
||||||
float stroke = (p.getStrokeWidth() + colorBandWidth)/2;
|
float bandWidth = stroke * 3f;
|
||||||
alphaPaint.setStrokeWidth(stroke*2); // colorBandWidth
|
p.setStrokeWidth(bandWidth);
|
||||||
|
|
||||||
float clipL = -stroke;
|
float clipL = -bandWidth / 2f;
|
||||||
float clipB = -stroke;
|
float clipB = -bandWidth / 2f;
|
||||||
float clipT = canvas.getHeight() + stroke;
|
float clipT = canvas.getHeight() + bandWidth / 2f;
|
||||||
float clipR = canvas.getWidth() + stroke;
|
float clipR = canvas.getWidth() + bandWidth / 2f;
|
||||||
|
|
||||||
GPXUtilities.WptPt pt = culled.get(0);
|
GPXUtilities.WptPt pt = culled.get(0);
|
||||||
float lastx = tileBox.getPixXFromLatLon(pt.lat, pt.lon);
|
float lastx = tileBox.getPixXFromLatLon(pt.lat, pt.lon);
|
||||||
|
@ -253,15 +245,18 @@ public class Renderable {
|
||||||
|
|
||||||
if (Math.min(x, lastx) < clipR && Math.max(x, lastx) > clipL
|
if (Math.min(x, lastx) < clipR && Math.max(x, lastx) > clipL
|
||||||
&& Math.min(y, lasty) < clipT && Math.max(y, lasty) > clipB) {
|
&& Math.min(y, lasty) < clipT && Math.max(y, lasty) > clipB) {
|
||||||
alphaPaint.setColor(pt.colourARGB);
|
p.setColor(pt.colourARGB);
|
||||||
canvas2.drawLine(lastx, lasty, x, y, alphaPaint);
|
canvas.drawLine(lastx, lasty, x, y, p);
|
||||||
}
|
}
|
||||||
lastx = x;
|
lastx = x;
|
||||||
lasty = y;
|
lasty = y;
|
||||||
}
|
}
|
||||||
canvas2.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
||||||
alphaPaint.setAlpha(alpha);
|
|
||||||
canvas.drawBitmap(newBitmap, 0, 0, alphaPaint);
|
p.setStrokeCap(cap);
|
||||||
|
p.setStrokeWidth(stroke);
|
||||||
|
p.setColor(col);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,8 +265,8 @@ public class Renderable {
|
||||||
|
|
||||||
public static class SpeedColours extends Altitude {
|
public static class SpeedColours extends Altitude {
|
||||||
|
|
||||||
public SpeedColours(List<GPXUtilities.WptPt> pt, double segmentSize, int alpha) {
|
public SpeedColours(List<GPXUtilities.WptPt> pt, double segmentSize) {
|
||||||
super(pt, segmentSize, alpha);
|
super(pt, segmentSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void recalculateRenderScale(double zoom) {
|
@Override public void recalculateRenderScale(double zoom) {
|
||||||
|
@ -374,6 +369,7 @@ public class Renderable {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void recalculateRenderScale(double zoom) {
|
@Override public void recalculateRenderScale(double zoom) {
|
||||||
|
hashZoom = zoom;
|
||||||
if (culled == null && culler == null) {
|
if (culled == null && culler == null) {
|
||||||
culler = new AsynchronousResampler.GenericResampler(this, segmentSize);
|
culler = new AsynchronousResampler.GenericResampler(this, segmentSize);
|
||||||
culler.execute("");
|
culler.execute("");
|
||||||
|
@ -388,14 +384,18 @@ public class Renderable {
|
||||||
|
|
||||||
@Override public void drawSingleSegment(Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
@Override public void drawSingleSegment(Paint p, Canvas canvas, RotatedTileBox tileBox) {
|
||||||
|
|
||||||
if (culled != null && !culled.isEmpty()
|
if (culled != null && !culled.isEmpty() && hashZoom > 12
|
||||||
&& QuadRect.trivialOverlap(tileBox.getLatLonBounds(), trackBounds)) {
|
&& QuadRect.trivialOverlap(tileBox.getLatLonBounds(), trackBounds)) {
|
||||||
|
|
||||||
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
||||||
|
|
||||||
|
float scale = 50;
|
||||||
|
|
||||||
float stroke = p.getStrokeWidth();
|
float stroke = p.getStrokeWidth();
|
||||||
int col = p.getColor();
|
int col = p.getColor();
|
||||||
float ts = p.getTextSize();
|
float ts = p.getTextSize();
|
||||||
|
Paint.Style st = p.getStyle();
|
||||||
|
p.setStyle(Paint.Style.FILL);
|
||||||
|
|
||||||
for (int i = culled.size()-1; --i >= 0;) {
|
for (int i = culled.size()-1; --i >= 0;) {
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ public class Renderable {
|
||||||
float x = tileBox.getPixXFromLatLon(pt.lat, pt.lon);
|
float x = tileBox.getPixXFromLatLon(pt.lat, pt.lon);
|
||||||
float y = tileBox.getPixYFromLatLon(pt.lat, pt.lon);
|
float y = tileBox.getPixYFromLatLon(pt.lat, pt.lon);
|
||||||
|
|
||||||
p.setTextSize(50);
|
p.setTextSize(scale);
|
||||||
p.setStrokeWidth(3);
|
p.setStrokeWidth(3);
|
||||||
|
|
||||||
Rect bounds = new Rect();
|
Rect bounds = new Rect();
|
||||||
|
@ -413,15 +413,20 @@ public class Renderable {
|
||||||
int rectH = bounds.height();
|
int rectH = bounds.height();
|
||||||
int rectW = bounds.width();
|
int rectW = bounds.width();
|
||||||
|
|
||||||
if (x < canvas.getWidth() + rectW/2 +20 && x > -rectW/2 +20 && y < canvas.getHeight() + rectH/2f && y > -rectH/2f) {
|
if (x < canvas.getWidth() + rectW/2 + scale && x > -rectW/2 + scale && y < canvas.getHeight() + rectH/2f && y > -rectH/2f) {
|
||||||
// p.setColor(Color.WHITE);
|
|
||||||
// p.setStyle(Paint.Style.FILL);
|
p.setStyle(Paint.Style.FILL);
|
||||||
// canvas.drawText(lab, x - rectW / 2+10+2, y + rectH / 2 + 2, p);
|
|
||||||
p.setColor(Color.BLACK);
|
p.setColor(Color.BLACK);
|
||||||
canvas.drawText(lab,x-rectW/2+20,y+rectH/2,p);
|
p.setStrokeWidth(stroke);
|
||||||
|
canvas.drawPoint(x, y, p);
|
||||||
|
p.setStrokeWidth(4);
|
||||||
|
p.setColor(Color.BLACK);
|
||||||
|
canvas.drawText(lab,x-rectW/2+40,y+rectH/2,p);
|
||||||
}
|
}
|
||||||
canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p.setStyle(st);
|
||||||
p.setStrokeWidth(stroke);
|
p.setStrokeWidth(stroke);
|
||||||
p.setColor(col);
|
p.setColor(col);
|
||||||
p.setTextSize(ts);
|
p.setTextSize(ts);
|
||||||
|
|
Loading…
Reference in a new issue