From f81cfbf8dfd1bee0b621fe952b019a3971870861 Mon Sep 17 00:00:00 2001 From: Victor Shcherb Date: Mon, 1 Sep 2014 01:18:23 +0200 Subject: [PATCH] Support gpx rendering and nav rendering --- .../src/net/osmand/RenderingContext.java | 2 +- .../plus/render/MapRenderRepositories.java | 4 + .../osmand/plus/render/OsmandRenderer.java | 5 +- .../src/net/osmand/plus/views/GPXLayer.java | 109 ++++++++++++------ .../src/net/osmand/plus/views/RouteLayer.java | 97 +++++++++------- 5 files changed, 137 insertions(+), 80 deletions(-) diff --git a/OsmAnd-java/src/net/osmand/RenderingContext.java b/OsmAnd-java/src/net/osmand/RenderingContext.java index f63c07e5b3..8e412e5a66 100644 --- a/OsmAnd-java/src/net/osmand/RenderingContext.java +++ b/OsmAnd-java/src/net/osmand/RenderingContext.java @@ -48,7 +48,7 @@ public class RenderingContext { // be aware field is using in C++ public float screenDensityRatio = 1; - public int shadowRenderingMode = ShadowRenderingMode.BLUR_SHADOW.value; + public int shadowRenderingMode = ShadowRenderingMode.SOLID_SHADOW.value; public int shadowRenderingColor = 0xff969696; public String renderingDebugInfo; public double polygonMinSizeToDisplay; diff --git a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java index bf0b98d993..acb2cee59b 100644 --- a/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java +++ b/OsmAnd/src/net/osmand/plus/render/MapRenderRepositories.java @@ -119,6 +119,10 @@ public class MapRenderRepositories { public Context getContext() { return context; } + + public OsmandRenderer getRenderer() { + return renderer; + } public void initializeNewResource(final IProgress progress, File file, BinaryMapIndexReader reader) { if (files.containsKey(file.getAbsolutePath())) { diff --git a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java index ade3541292..45506c1f40 100644 --- a/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java +++ b/OsmAnd/src/net/osmand/plus/render/OsmandRenderer.java @@ -92,7 +92,8 @@ public class OsmandRenderer { - /* package */static class RenderingContext extends net.osmand.RenderingContext { + /* package */ + public static class RenderingContext extends net.osmand.RenderingContext { List textToDraw = new ArrayList(); List iconsToDraw = new ArrayList(); Paint[] oneWay ; @@ -626,7 +627,7 @@ public class OsmandRenderer { } } - private boolean updatePaint(RenderingRuleSearchRequest req, Paint p, int ind, boolean area, RenderingContext rc){ + public boolean updatePaint(RenderingRuleSearchRequest req, Paint p, int ind, boolean area, RenderingContext rc){ RenderingRuleProperty rColor; RenderingRuleProperty rStrokeW; RenderingRuleProperty rCap; diff --git a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java index 754b1a9fb0..9508f09338 100644 --- a/OsmAnd/src/net/osmand/plus/views/GPXLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/GPXLayer.java @@ -1,13 +1,11 @@ package net.osmand.plus.views; import java.util.ArrayList; -import java.util.Collections; +import java.util.Arrays; import java.util.List; import net.osmand.access.AccessibleToast; -import net.osmand.data.FavouritePoint; import net.osmand.data.LatLon; -import net.osmand.data.LocationPoint; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.GPXUtilities.WptPt; @@ -17,20 +15,21 @@ import net.osmand.plus.GpxSelectionHelper.GpxDisplayItem; import net.osmand.plus.GpxSelectionHelper.SelectedGpxFile; import net.osmand.plus.R; import net.osmand.plus.base.FavoriteImageDrawable; -import net.osmand.plus.sherpafy.TourInformation.StageFavorite; +import net.osmand.plus.render.OsmandRenderer; +import net.osmand.plus.render.OsmandRenderer.RenderingContext; import net.osmand.plus.views.MapTextLayer.MapTextProvider; import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.DashPathEffect; +import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.Paint.Align; -import android.graphics.Paint.Cap; -import android.graphics.Paint.Join; import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.PointF; +import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffColorFilter; import android.widget.Toast; public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContextMenuProvider, @@ -39,21 +38,24 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex private OsmandMapTileView view; private Paint paint; + private Paint paint2; + private boolean isPaint2; + private Paint shadowPaint; + private boolean isShadowPaint; + private Paint paint_1; + private boolean isPaint_1; + private int cachedHash; + private int cachedColor; private Path path; private static final int startZoom = 7; + - private RenderingRulesStorage cachedRrs; - private boolean cachedNightMode; - private int cachedColor; - private GpxSelectionHelper selectedGpxHelper; - private Paint paintBmp; private List cache = new ArrayList(); private MapTextLayer textLayer; - private DashPathEffect pathEffect; private Paint paintOuter; @@ -61,16 +63,25 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex private Paint paintTextIcon; + private OsmandRenderer osmandRenderer; + // private Drawable favoriteIcon; private void initUI() { paint = new Paint(); paint.setStyle(Style.STROKE); - paint.setStrokeWidth(14); paint.setAntiAlias(true); - paint.setStrokeCap(Cap.ROUND); - paint.setStrokeJoin(Join.ROUND); + paint2 = new Paint(); + paint2.setStyle(Style.STROKE); + paint2.setAntiAlias(true); + shadowPaint = new Paint(); + shadowPaint.setStyle(Style.STROKE); + shadowPaint.setAntiAlias(true); + paint_1 = new Paint(); + paint_1.setStyle(Style.STROKE); + paint_1.setAntiAlias(true); + path = new Path(); @@ -104,30 +115,49 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex public void initLayer(OsmandMapTileView view) { this.view = view; selectedGpxHelper = view.getApplication().getSelectedGpxHelper(); - pathEffect = new DashPathEffect(new float[] { 5 * view.getDensity(), - 3 * view.getDensity()}, 3); + osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer(); initUI(); } - private int getColor(DrawSettings nightMode){ + private int updatePaints(int color, boolean routePoints, DrawSettings nightMode, RotatedTileBox tileBox){ RenderingRulesStorage rrs = view.getApplication().getRendererRegistry().getCurrentSelectedRenderer(); - boolean n = nightMode != null && nightMode.isNightMode(); - if (rrs != cachedRrs || cachedNightMode != n) { - cachedRrs = rrs; - cachedNightMode = n; + final boolean isNight = nightMode != null && nightMode.isNightMode(); + int hsh = calculateHash(rrs, routePoints, isNight, tileBox.getZoomScale()); + if (hsh != cachedHash) { + cachedHash = hsh; cachedColor = view.getResources().getColor(R.color.gpx_track); - if (cachedRrs != null) { + if (rrs != null) { RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs); - req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, cachedNightMode); - if (req.searchRenderingAttribute("gpxColor")) { - cachedColor = req.getIntPropertyValue(rrs.PROPS.R_ATTR_COLOR_VALUE); + req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, isNight); + if(routePoints) { + req.setStringFilter(rrs.PROPS.R_ADDITIONAL, "routePoints=true"); + } + if (req.searchRenderingAttribute("gpx")) { + RenderingContext rc = new OsmandRenderer.RenderingContext(view.getContext()); + rc.setDensityValue((float) Math.pow(2, tileBox.getZoomScale())); + cachedColor = req.getIntPropertyValue(rrs.PROPS.R_COLOR); + osmandRenderer.updatePaint(req, paint, 0, false, rc); + isPaint2 = osmandRenderer.updatePaint(req, paint2, 1, false, rc); + isPaint_1 = osmandRenderer.updatePaint(req, paint_1, -1, false, rc); + isShadowPaint = req.isSpecified(rrs.PROPS.R_SHADOW_RADIUS); + if(isShadowPaint) { + ColorFilter cf = new PorterDuffColorFilter(req.getIntPropertyValue(rrs.PROPS.R_SHADOW_COLOR), Mode.SRC_IN); + shadowPaint.setColorFilter(cf); + shadowPaint.setStrokeWidth(paint.getStrokeWidth() + 2 * rc.getComplexValue(req, rrs.PROPS.R_SHADOW_RADIUS)); + } } } } + paint.setColor(color == 0 ? cachedColor : color); return cachedColor; } + private int calculateHash(Object... o) { + return Arrays.hashCode(o); + } + + @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { List selectedGPXFiles = selectedGpxHelper.getSelectedGPXFiles(); @@ -224,16 +254,15 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex private void drawSelectedFilesSegments(Canvas canvas, RotatedTileBox tileBox, List selectedGPXFiles, DrawSettings settings) { - int clr = getColor(settings); for (SelectedGpxFile g : selectedGPXFiles) { List> points = g.getPointsToDisplay(); boolean routePoints = g.isRoutePoints(); - int fcolor = g.getColor() == 0 ? clr : g.getColor(); - paint.setColor(fcolor); - drawSegments(canvas, tileBox, points, routePoints); + updatePaints(g.getColor(), routePoints, settings, tileBox); + drawSegments(canvas, tileBox, points); } } + private boolean isPointVisited(WptPt o) { boolean visit = false; String visited = o.getExtensionsToRead().get("VISITED_KEY"); @@ -251,16 +280,10 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex return pts; } - private void drawSegments(Canvas canvas, RotatedTileBox tileBox, List> points, boolean routePoints) { + private void drawSegments(Canvas canvas, RotatedTileBox tileBox, List> points) { final QuadRect latLonBounds = tileBox.getLatLonBounds(); for (List l : points) { path.rewind(); - paint.setPathEffect(routePoints ? pathEffect : null); - if (routePoints){ - paint.setStrokeCap(Cap.BUTT); - } else { - paint.setStrokeCap(Cap.ROUND); - } int startIndex = -1; for (int i = 0; i < l.size(); i++) { @@ -301,7 +324,17 @@ public class GPXLayer extends OsmandMapLayer implements ContextMenuLayer.IContex int y = tb.getPixYFromLatNoRot(p.lat); path.lineTo(x, y); } + if(isPaint_1) { + canvas.drawPath(path, paint_1); + } + if(isShadowPaint) { + canvas.drawPath(path, shadowPaint); + } canvas.drawPath(path, paint); + if(isPaint2) { + canvas.drawPath(path, paint2); + } + } diff --git a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java index 7e52ee232c..5c07bd4a10 100644 --- a/OsmAnd/src/net/osmand/plus/views/RouteLayer.java +++ b/OsmAnd/src/net/osmand/plus/views/RouteLayer.java @@ -1,12 +1,15 @@ package net.osmand.plus.views; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import net.osmand.Location; import net.osmand.data.QuadRect; import net.osmand.data.RotatedTileBox; import net.osmand.plus.R; +import net.osmand.plus.render.OsmandRenderer; +import net.osmand.plus.render.OsmandRenderer.RenderingContext; import net.osmand.plus.routing.RoutingHelper; import net.osmand.render.RenderingRuleSearchRequest; import net.osmand.render.RenderingRulesStorage; @@ -14,8 +17,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; -import android.graphics.ColorMatrix; -import android.graphics.ColorMatrixColorFilter; +import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Cap; @@ -24,6 +26,8 @@ import android.graphics.Paint.Style; import android.graphics.Path; import android.graphics.PathMeasure; import android.graphics.PointF; +import android.graphics.PorterDuff.Mode; +import android.graphics.PorterDuffColorFilter; public class RouteLayer extends OsmandMapLayer { @@ -32,18 +36,23 @@ public class RouteLayer extends OsmandMapLayer { private final RoutingHelper helper; private List points = new ArrayList(); private Paint paint; + private Paint paint2; + private boolean isPaint2; + private Paint shadowPaint; + private boolean isShadowPaint; + private Paint paint_1; + private boolean isPaint_1; + private int cachedHash; private Path path; // cache - private RenderingRulesStorage cachedRrs; - private boolean cachedNightMode; - private int cachedColor; - private Bitmap coloredArrowUp; private Paint paintIcon; + private OsmandRenderer osmandRenderer; + public RouteLayer(RoutingHelper helper){ this.helper = helper; } @@ -53,7 +62,6 @@ public class RouteLayer extends OsmandMapLayer { paint = new Paint(); paint.setStyle(Style.STROKE); - paint.setStrokeWidth(14); paint.setAntiAlias(true); paint.setStrokeCap(Cap.ROUND); paint.setStrokeJoin(Join.ROUND); @@ -70,53 +78,55 @@ public class RouteLayer extends OsmandMapLayer { @Override public void initLayer(OsmandMapTileView view) { this.view = view; + osmandRenderer = view.getApplication().getResourceManager().getRenderer().getRenderer(); initUI(); } - private int updateColor(DrawSettings nightMode){ + private void updatePaints(DrawSettings nightMode, RotatedTileBox tileBox){ RenderingRulesStorage rrs = view.getApplication().getRendererRegistry().getCurrentSelectedRenderer(); - boolean n = nightMode != null && nightMode.isNightMode(); - if(coloredArrowUp == null) { - Bitmap originalArrowUp = BitmapFactory.decodeResource(view.getResources(), R.drawable.h_arrow, null); - coloredArrowUp = originalArrowUp; -// coloredArrowUp = Bitmap.createScaledBitmap(originalArrowUp, originalArrowUp.getWidth() * 3 / 4, -// originalArrowUp.getHeight() * 3 / 4, true); - } - if (rrs != cachedRrs || cachedNightMode != n) { - cachedRrs = rrs; - cachedNightMode = n; - cachedColor = view.getResources().getColor(cachedNightMode?R.color.nav_track_fluorescent : R.color.nav_track); - if (cachedRrs != null) { + final boolean isNight = nightMode != null && nightMode.isNightMode(); + int hsh = calculateHash(rrs, isNight, tileBox.getZoomScale()); + if (hsh != cachedHash) { + cachedHash = hsh; + // cachedColor = view.getResources().getColor(R.color.nav_track); + if (rrs != null) { RenderingRuleSearchRequest req = new RenderingRuleSearchRequest(rrs); - req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, cachedNightMode); - if (req.searchRenderingAttribute("routeColor")) { - cachedColor = req.getIntPropertyValue(rrs.PROPS.R_ATTR_COLOR_VALUE); + req.setBooleanFilter(rrs.PROPS.R_NIGHT_MODE, isNight); + if (req.searchRenderingAttribute("route")) { + RenderingContext rc = new OsmandRenderer.RenderingContext(view.getContext()); + rc.setDensityValue((float) Math.pow(2, tileBox.getZoomScale())); +// cachedColor = req.getIntPropertyValue(rrs.PROPS.R_COLOR); + osmandRenderer.updatePaint(req, paint, 0, false, rc); + isPaint2 = osmandRenderer.updatePaint(req, paint2, 1, false, rc); + isPaint_1 = osmandRenderer.updatePaint(req, paint_1, -1, false, rc); + isShadowPaint = req.isSpecified(rrs.PROPS.R_SHADOW_RADIUS); + if(isShadowPaint) { + ColorFilter cf = new PorterDuffColorFilter(req.getIntPropertyValue(rrs.PROPS.R_SHADOW_COLOR), Mode.SRC_IN); + shadowPaint.setColorFilter(cf); + shadowPaint.setStrokeWidth(paint.getStrokeWidth() + 2 * rc.getComplexValue(req, rrs.PROPS.R_SHADOW_RADIUS)); + } } } - paint.setColor(cachedColor); - int r = Color.red(cachedColor); - int g = Color.green(cachedColor); - int b = Color.blue(cachedColor); - ColorMatrix f = new ColorMatrix(new float[]{ - 0, 0, 0, 0, r, - 0, 0, 0, 0, g, - 0, 0, 0, 0, b, - 0, 0, 0, 1, 0 - }); - ColorMatrix sat = new ColorMatrix(); - sat.setSaturation(0.3f); - f.postConcat(sat); - paintIcon.setColorFilter(new ColorMatrixColorFilter(f)); } - return cachedColor; + } + + + private int calculateHash(Object... o) { + return Arrays.hashCode(o); } @Override public void onPrepareBufferImage(Canvas canvas, RotatedTileBox tileBox, DrawSettings settings) { path.reset(); if (helper.getFinalLocation() != null && helper.getRoute().isCalculated()) { - updateColor(settings); + updatePaints(settings, tileBox); + if(coloredArrowUp == null) { + Bitmap originalArrowUp = BitmapFactory.decodeResource(view.getResources(), R.drawable.h_arrow, null); + coloredArrowUp = originalArrowUp; +// coloredArrowUp = Bitmap.createScaledBitmap(originalArrowUp, originalArrowUp.getWidth() * 3 / 4, +// originalArrowUp.getHeight() * 3 / 4, true); + } int w = tileBox.getPixWidth(); int h = tileBox.getPixHeight(); Location lastProjection = helper.getLastProjection(); @@ -158,7 +168,16 @@ public class RouteLayer extends OsmandMapLayer { int y = tb.getPixYFromLatNoRot(o.getLatitude()); path.lineTo(x, y); } + if(isPaint_1) { + canvas.drawPath(path, paint_1); + } + if(isShadowPaint) { + canvas.drawPath(path, shadowPaint); + } canvas.drawPath(path, paint); + if(isPaint2) { + canvas.drawPath(path, paint2); + } if(tb.getZoomAnimation() == 0) { drawArrowsOverPath(canvas, path, coloredArrowUp); }