From e8e6ca2854055835c4efb174a74a8d75271847f0 Mon Sep 17 00:00:00 2001 From: Andrew Davie Date: Thu, 31 Mar 2016 20:04:00 +1100 Subject: [PATCH] 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. --- OsmAnd/src/net/osmand/plus/GPXUtilities.java | 11 --- .../src/net/osmand/plus/views/GPXLayer.java | 4 +- .../src/net/osmand/plus/views/Renderable.java | 73 ++++++++++--------- 3 files changed, 42 insertions(+), 46 deletions(-) diff --git a/OsmAnd/src/net/osmand/plus/GPXUtilities.java b/OsmAnd/src/net/osmand/plus/GPXUtilities.java index 8099f433d4..77879f33a6 100644 --- a/OsmAnd/src/net/osmand/plus/GPXUtilities.java +++ b/OsmAnd/src/net/osmand/plus/GPXUtilities.java @@ -204,14 +204,6 @@ public class GPXUtilities { public List points = new ArrayList(); 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 renders = new ArrayList<>(); public List splitByDistance(double meters) { @@ -239,9 +231,6 @@ public class GPXUtilities { rs.drawSingleSegment(p, c, tb); } } - - - } public static class Track extends GPXExtensions { diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index c8c18e30d5..d92d31d22d 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -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) && !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.Altitude(ts.points, 10, 180)); // TODO : enable these to see how the experimental conveyor, altitude, speed, waypoint renders work diff --git a/OsmAnd/src/net/osmand/plus/views/Renderable.java b/OsmAnd/src/net/osmand/plus/views/Renderable.java index 6763cc22dc..271d8ef50a 100644 --- a/OsmAnd/src/net/osmand/plus/views/Renderable.java +++ b/OsmAnd/src/net/osmand/plus/views/Renderable.java @@ -198,19 +198,11 @@ public class Renderable { 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; - public Altitude(List pt, double segmentSize, int alpha) { + public Altitude(List pt, double segmentSize) { super(pt); - this.segmentSize = segmentSize; - this.alpha = alpha; - alphaPaint = new Paint(); - alphaPaint.setStrokeCap(Paint.Cap.ROUND); - colorBandWidth = 32f; } @Override public void recalculateRenderScale(double zoom) { @@ -225,21 +217,21 @@ public class Renderable { if (culled != null && !culled.isEmpty() && 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); - Canvas canvas2 = new Canvas(newBitmap); - canvas2.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + Paint.Cap cap = p.getStrokeCap(); + float stroke = p.getStrokeWidth(); + int col = p.getColor(); - alphaPaint.setAlpha(255); + p.setStrokeCap(Paint.Cap.ROUND); - float stroke = (p.getStrokeWidth() + colorBandWidth)/2; - alphaPaint.setStrokeWidth(stroke*2); // colorBandWidth + float bandWidth = stroke * 3f; + p.setStrokeWidth(bandWidth); - float clipL = -stroke; - float clipB = -stroke; - float clipT = canvas.getHeight() + stroke; - float clipR = canvas.getWidth() + stroke; + float clipL = -bandWidth / 2f; + float clipB = -bandWidth / 2f; + float clipT = canvas.getHeight() + bandWidth / 2f; + float clipR = canvas.getWidth() + bandWidth / 2f; GPXUtilities.WptPt pt = culled.get(0); 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 && Math.min(y, lasty) < clipT && Math.max(y, lasty) > clipB) { - alphaPaint.setColor(pt.colourARGB); - canvas2.drawLine(lastx, lasty, x, y, alphaPaint); + p.setColor(pt.colourARGB); + canvas.drawLine(lastx, lasty, x, y, p); } lastx = x; lasty = y; } - canvas2.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); - alphaPaint.setAlpha(alpha); - canvas.drawBitmap(newBitmap, 0, 0, alphaPaint); + canvas.rotate(tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + + p.setStrokeCap(cap); + p.setStrokeWidth(stroke); + p.setColor(col); + } } } @@ -270,8 +265,8 @@ public class Renderable { public static class SpeedColours extends Altitude { - public SpeedColours(List pt, double segmentSize, int alpha) { - super(pt, segmentSize, alpha); + public SpeedColours(List pt, double segmentSize) { + super(pt, segmentSize); } @Override public void recalculateRenderScale(double zoom) { @@ -374,6 +369,7 @@ public class Renderable { } @Override public void recalculateRenderScale(double zoom) { + hashZoom = zoom; if (culled == null && culler == null) { culler = new AsynchronousResampler.GenericResampler(this, segmentSize); culler.execute(""); @@ -388,14 +384,18 @@ public class Renderable { @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)) { canvas.rotate(-tileBox.getRotate(), tileBox.getCenterPixelX(), tileBox.getCenterPixelY()); + float scale = 50; + float stroke = p.getStrokeWidth(); int col = p.getColor(); float ts = p.getTextSize(); + Paint.Style st = p.getStyle(); + p.setStyle(Paint.Style.FILL); for (int i = culled.size()-1; --i >= 0;) { @@ -403,7 +403,7 @@ public class Renderable { float x = tileBox.getPixXFromLatLon(pt.lat, pt.lon); float y = tileBox.getPixYFromLatLon(pt.lat, pt.lon); - p.setTextSize(50); + p.setTextSize(scale); p.setStrokeWidth(3); Rect bounds = new Rect(); @@ -413,15 +413,20 @@ public class Renderable { int rectH = bounds.height(); int rectW = bounds.width(); - if (x < canvas.getWidth() + rectW/2 +20 && x > -rectW/2 +20 && y < canvas.getHeight() + rectH/2f && y > -rectH/2f) { -// p.setColor(Color.WHITE); -// p.setStyle(Paint.Style.FILL); -// canvas.drawText(lab, x - rectW / 2+10+2, y + rectH / 2 + 2, p); + if (x < canvas.getWidth() + rectW/2 + scale && x > -rectW/2 + scale && y < canvas.getHeight() + rectH/2f && y > -rectH/2f) { + + p.setStyle(Paint.Style.FILL); 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()); } + + p.setStyle(st); p.setStrokeWidth(stroke); p.setColor(col); p.setTextSize(ts);